Hello community,
here is the log from the commit of package obs-service-tar_scm for openSUSE:Factory checked in at 2012-02-17 12:18:38
++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Comparing /work/SRC/openSUSE:Factory/obs-service-tar_scm (Old)
and /work/SRC/openSUSE:Factory/.obs-service-tar_scm.new (New)
++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Package is "obs-service-tar_scm", Maintainer is ""
Changes:
--------
--- /work/SRC/openSUSE:Factory/obs-service-tar_scm/obs-service-tar_scm.changes 2012-01-04 07:25:39.000000000 +0100
+++ /work/SRC/openSUSE:Factory/.obs-service-tar_scm.new/obs-service-tar_scm.changes 2012-02-17 12:18:39.000000000 +0100
@@ -1,0 +2,37 @@
+Thu Feb 16 15:23:35 GMT 2012 - aspiers@suse.com
+
+- When the cache is used, output location of repo in the cache
+
+-------------------------------------------------------------------
+Tue Feb 14 16:52:19 GMT 2012 - aspiers@suse.com
+
+- add new 'versionformat' option to determine how version is
+ extracted via git show --pretty=...
+- support caching of cloned repositories to speed up fetch
+ from upstream
+
+-------------------------------------------------------------------
+Mon Feb 13 15:52:19 GMT 2012 - aspiers@suse.com
+
+- Add test suite
+- Fix --subdir with --scm svn
+- Fix --scm bzr
+
+-------------------------------------------------------------------
+Mon Feb 13 10:51:19 UTC 2012 - coolo@suse.com
+
+- patch license to follow spdx.org standard
+
+-------------------------------------------------------------------
+Tue Jan 24 15:46:17 UTC 2012 - rschiele@gmail.com
+
+- add new option to specify a subset of files/subdirectories to
+ pack in the tar ball
+
+-------------------------------------------------------------------
+Tue Jan 24 13:26:19 UTC 2012 - rschiele@gmail.com
+
+- Checking out a specific revision cannot work when only the latest
+ version is cloned.
+
+-------------------------------------------------------------------
New:
----
bzrfixtures.py
bzrtests.py
commontests.py
fixtures.py
gitfixtures.py
githgtests.py
gittests.py
hgfixtures.py
hgtests.py
scm-wrapper
scmlogs.py
svnfixtures.py
svntests.py
tar_scm.rc
test.py
testassertions.py
testenv.py
utils.py
++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Other differences:
------------------
++++++ obs-service-tar_scm.spec ++++++
--- /var/tmp/diff_new_pack.G30PbZ/_old 2012-02-17 12:18:42.000000000 +0100
+++ /var/tmp/diff_new_pack.G30PbZ/_new 2012-02-17 12:18:42.000000000 +0100
@@ -1,7 +1,7 @@
#
# spec file for package obs-service-tar_scm
#
-# Copyright (c) 2011 SUSE LINUX Products GmbH, Nuernberg, Germany.
+# Copyright (c) 2012 SUSE LINUX Products GmbH, Nuernberg, Germany.
#
# All modifications and additions to the file contributed by third parties
# remain the property of their copyright owners, unless otherwise agreed
@@ -16,17 +16,44 @@
#
+%define service tar_scm
-Name: obs-service-tar_scm
-License: GPL v2 or later
-Group: Development/Tools/Building
+Name: obs-service-%{service}
Summary: An OBS source service: checkout or update a tar ball from svn/git/hg
-Url: https://build.opensuse.org/package/show?package=obs-service-tar_scm&project=openSUSE%3ATools
-Version: 0.2.1
-Release: 1
-Source: tar_scm
-Source1: tar_scm.service
-Requires: subversion git mercurial bzr
+License: GPL-2.0+
+Group: Development/Tools/Building
+Url: https://build.opensuse.org/package/show?package=obs-service-%{service}&project=openSUSE%3ATools
+Version: 0.2.3
+Release: 0
+Source: %{service}
+Source1: %{service}.service
+Source2: %{service}.rc
+
+# test suite files
+Source100: bzrfixtures.py
+Source101: bzrtests.py
+Source102: commontests.py
+Source103: fixtures.py
+Source104: gitfixtures.py
+Source105: githgtests.py
+Source106: gittests.py
+Source107: hgfixtures.py
+Source108: hgtests.py
+Source109: scmlogs.py
+Source110: svnfixtures.py
+Source111: svntests.py
+Source112: testassertions.py
+Source113: testenv.py
+Source114: test.py
+Source115: utils.py
+Source116: scm-wrapper
+
+Requires: bzr git mercurial subversion
+BuildRequires: bzr
+BuildRequires: git
+BuildRequires: mercurial
+BuildRequires: python >= 2.6
+BuildRequires: subversion
BuildRoot: %{_tmppath}/%{name}-%{version}-build
BuildArch: noarch
@@ -46,9 +73,20 @@
install -m 0755 %{SOURCE0} $RPM_BUILD_ROOT/usr/lib/obs/service
install -m 0644 %{SOURCE1} $RPM_BUILD_ROOT/usr/lib/obs/service
+mkdir -p $RPM_BUILD_ROOT/etc/obs/services
+install -m 0644 %{SOURCE2} $RPM_BUILD_ROOT/etc/obs/services/%{service}
+
+%check
+chmod +x $RPM_SOURCE_DIR/scm-wrapper
+: Running the test suite. Please be patient - this takes a few minutes ...
+python $RPM_SOURCE_DIR/test.py
+
%files
%defattr(-,root,root)
%dir /usr/lib/obs
/usr/lib/obs/service
+%dir /etc/obs
+%dir /etc/obs/services
+%config(noreplace) /etc/obs/services/*
%changelog
++++++ bzrfixtures.py ++++++
#!/usr/bin/python
import os
from fixtures import Fixtures
from utils import mkfreshdir, run_bzr
class BzrFixtures(Fixtures):
def init(self):
self.create_repo()
self.create_commits(2)
def run(self, cmd):
return run_bzr(self.repo_path, cmd)
def create_repo(self):
os.makedirs(self.repo_path)
os.chdir(self.repo_path)
self.run('init')
self.run('whoami "%s"' % self.name_and_email)
self.wd = self.repo_path
print "created repo", self.repo_path
def do_commit(self, newly_created):
self.run('add .')
self.run('commit -m%d' % self.next_commit_rev)
def record_rev(self, rev_num):
self.revs[rev_num] = str(rev_num)
self.scmlogs.annotate("Recorded rev %d" % rev_num)
++++++ bzrtests.py ++++++
#!/usr/bin/python
from commontests import CommonTests
from bzrfixtures import BzrFixtures
from utils import run_bzr
class BzrTests(CommonTests):
scm = 'bzr'
initial_clone_command = 'bzr checkout'
update_cache_command = 'bzr update'
fixtures_class = BzrFixtures
def default_version(self):
return self.rev(2)
def test_versionformat_rev(self):
self.tar_scm_std('--versionformat', 'myrev%r.svn')
self.assertTarOnly(self.basename(version = 'myrev2.svn'))
def test_version_versionformat(self):
self.tar_scm_std('--version', '3.0', '--versionformat', 'myrev%r.svn')
self.assertTarOnly(self.basename(version = 'myrev2.svn'))
def test_versionformat_revision(self):
self.fixtures.create_commits(4)
self.tar_scm_std('--versionformat', 'foo%r', '--revision', self.rev(2))
basename = self.basename(version = 'foo2')
th = self.assertTarOnly(basename)
self.assertTarMemberContains(th, basename + '/a', '2')
++++++ commontests.py ++++++
#!/usr/bin/python
from pprint import pprint, pformat
from testassertions import TestAssertions
from testenv import TestEnvironment
from utils import mkfreshdir
class CommonTests(TestEnvironment, TestAssertions):
def basename(self, name='repo', version=None):
if version is None:
version = self.default_version()
return '%s-%s' % (name, version)
def test_plain(self):
self.tar_scm_std()
self.assertTarOnly(self.basename())
def test_exclude(self):
self.tar_scm_std('--exclude', '.' + self.scm)
self.assertTarOnly(self.basename())
def test_subdir(self):
self.tar_scm_std('--subdir', self.fixtures.subdir)
self.assertTarOnly(self.basename(), tarchecker=self.assertSubdirTar)
def test_history_depth_obsolete(self):
(stdout, stderr, ret) = self.tar_scm_std('--history-depth', '1')
self.assertRegexpMatches(stdout, 'obsolete')
# self.assertTarOnly(self.basename())
# self.assertRegexpMatches(self.scmlogs.read()[0], '^%s clone --depth=1')
# def test_history_depth_full(self):
# self.tar_scm_std('--history-depth', 'full')
# self.assertTarOnly(self.basename())
# self.assertRegexpMatches(self.scmlogs.read()[0], '^git clone --depth=999999+')
def test_filename(self):
name = 'myfilename'
self.tar_scm_std('--filename', name)
self.assertTarOnly(self.basename(name=name))
def test_version(self):
version = '0.5'
self.tar_scm_std('--version', version)
self.assertTarOnly(self.basename(version=version))
def test_filename_version(self):
filename = 'myfilename'
version = '0.6'
self.tar_scm_std('--filename', filename, '--version', version)
self.assertTarOnly(self.basename(filename, version))
def test_revision_nop(self):
self.tar_scm_std('--revision', self.rev(2))
th = self.assertTarOnly(self.basename())
self.assertTarMemberContains(th, self.basename() + '/a', '2')
def test_revision(self):
self._revision()
def test_revision_no_cache(self):
self._revision(use_cache=False)
def test_revision_subdir(self):
self._revision(use_subdir=True)
def test_revision_subdir_no_cache(self):
self._revision(use_cache=False, use_subdir=True)
def _revision(self, use_cache=True, use_subdir=False):
version = '3.0'
args_tag2 = [
'--version', version,
'--revision', self.rev(2),
]
if use_subdir:
args_tag2 += [ '--subdir', self.fixtures.subdir ]
self._sequential_calls_with_revision(
version,
[
(0, args_tag2, '2', False),
(0, args_tag2, '2', use_cache),
(2, args_tag2, '2', use_cache),
(0, args_tag2, '2', use_cache),
(2, args_tag2, '2', use_cache),
(0, args_tag2, '2', use_cache),
],
use_cache
)
def test_revision_master_alternating(self):
self._revision_master_alternating()
def test_revision_master_alternating_no_cache(self):
self._revision_master_alternating(use_cache=False)
def test_revision_master_alternating_subdir(self):
self._revision_master_alternating(use_subdir=True)
def test_revision_master_alternating_subdir_no_cache(self):
self._revision_master_alternating(use_cache=False, use_subdir=True)
def _revision_master_alternating(self, use_cache=True, use_subdir=False):
version = '4.0'
args_head = [
'--version', version,
]
if use_subdir:
args_head += [ '--subdir', self.fixtures.subdir ]
args_tag2 = args_head + [ '--revision', self.rev(2) ]
self._sequential_calls_with_revision(
version,
[
(0, args_tag2, '2', False),
(0, args_head, '2', use_cache),
(2, args_tag2, '2', use_cache),
(0, args_head, '4', use_cache),
(2, args_tag2, '2', use_cache),
(0, args_head, '6', use_cache),
(0, args_tag2, '2', use_cache),
],
use_cache
)
def _sequential_calls_with_revision(self, version, calls, use_cache=True):
mkfreshdir(self.pkgdir)
basename = self.basename(version = version)
if not use_cache:
self.disableCache()
while calls:
new_commits, args, expected, expect_cache_hit = calls.pop(0)
if new_commits > 0:
self.fixtures.create_commits(new_commits)
self.scmlogs.annotate("about to run: " + pformat(args))
self.scmlogs.annotate("expecting tar to contain: " + expected)
self.tar_scm_std(*args)
logpath = self.scmlogs.current_log_path
loglines = self.scmlogs.read()
if expect_cache_hit:
self.assertRanUpdate(logpath, loglines)
else:
self.assertRanInitialClone(logpath, loglines)
if self.fixtures.subdir in args:
th = self.assertTarOnly(basename, tarchecker=self.assertSubdirTar)
tarent = 'b'
else:
th = self.assertTarOnly(basename)
tarent = 'a'
self.assertTarMemberContains(th, basename + '/' + tarent, expected)
self.scmlogs.next()
self.postRun()
def test_switch_revision_and_subdir(self):
self._switch_revision_and_subdir()
def test_switch_revision_and_subdir_no_cache(self):
self._switch_revision_and_subdir(use_cache=False)
def _switch_revision_and_subdir(self, use_cache=True):
version = '5.0'
args = [
'--version', version,
]
args_subdir = args+ [ '--subdir', self.fixtures.subdir ]
args_tag2 = args + [ '--revision', self.rev(2) ]
self._sequential_calls_with_revision(
version,
[
(0, args_tag2, '2', False),
(0, args_subdir, '2', use_cache and self.scm != 'svn'),
(2, args_tag2, '2', use_cache),
(0, args_subdir, '4', use_cache),
(2, args_tag2, '2', use_cache),
(0, args_subdir, '6', use_cache),
(0, args_tag2, '2', use_cache),
],
use_cache
)
++++++ fixtures.py ++++++
#!/usr/bin/python
import os
import shutil
class Fixtures:
name = 'tar_scm test suite'
email = 'root@localhost'
name_and_email = '%s <%s>' % (name, email)
subdir = 'subdir'
subdir1 = 'subdir1'
subdir2 = 'subdir2'
next_commit_rev = 1
def __init__(self, container_dir, scmlogs):
self.container_dir = container_dir
self.scmlogs = scmlogs
self.repo_path = self.container_dir + '/repo'
self.repo_url = 'file://' + self.repo_path
# Keys are stringified integers representing commit sequence numbers;
# values can be passed to --revision
self.revs = { }
def setup(self):
print self.__class__.__name__ + ": setting up fixtures"
self.init_fixtures_dir()
self.init()
def init_fixtures_dir(self):
if os.path.exists(self.repo_path):
shutil.rmtree(self.repo_path)
def init(self):
raise NotImplementedError, \
self.__class__.__name__ + " didn't implement init()"
def create_commits(self, num_commits):
self.scmlogs.annotate("Creating %d commits ..." % num_commits)
if num_commits == 0:
return
for i in xrange(0, num_commits):
new_rev = self.create_commit()
self.record_rev(new_rev)
self.scmlogs.annotate("Created %d commits; now at %s" % (num_commits, new_rev))
def create_commit(self):
os.chdir(self.wd)
newly_created = self.prep_commit()
self.do_commit(newly_created)
new_rev = self.next_commit_rev
self.next_commit_rev += 1
return new_rev
def prep_commit(self):
"""
Caller should ensure correct cwd.
Returns list of newly created files.
"""
newly_created = [ ]
if not os.path.exists('a'):
newly_created.append('a')
if not os.path.exists(self.subdir):
os.mkdir(self.subdir)
# This will take care of adding subdir/b too
newly_created.append(self.subdir)
for fn in ('a', self.subdir + '/b'):
f = open(fn, 'w')
f.write(str(self.next_commit_rev))
f.close()
return newly_created
++++++ gitfixtures.py ++++++
#!/usr/bin/python
import os
from fixtures import Fixtures
from utils import mkfreshdir, run_git
class GitFixtures(Fixtures):
def init(self):
self.create_repo()
self.timestamps = { }
self.sha1s = { }
self.create_commits(2)
def run(self, cmd):
return run_git(self.repo_path, cmd)
def create_repo(self):
os.makedirs(self.repo_path)
os.chdir(self.repo_path)
self.run('init')
self.run('config user.name test')
self.run('config user.email test@test.com')
self.wd = self.repo_path
print "created repo", self.repo_path
def do_commit(self, newly_created):
self.run('add .')
self.run('commit -m%d' % self.next_commit_rev)
def get_metadata(self, formatstr):
return self.run('log -n1 --pretty=format:"%s"' % formatstr)[0]
def record_rev(self, rev_num):
tag = 'tag' + str(rev_num)
self.run('tag ' + tag)
self.revs[rev_num] = tag
self.timestamps[tag] = self.get_metadata('%at')
self.sha1s[tag] = self.get_metadata('%h')
self.scmlogs.annotate(
"Recorded rev %d: id %s, timestamp %s, SHA1 %s" % \
(rev_num,
tag,
self.timestamps[tag],
self.sha1s[tag])
)
++++++ githgtests.py ++++++
#!/usr/bin/python
import os
from commontests import CommonTests
from utils import run_hg
class GitHgTests(CommonTests):
mixed_version_template = '%s.master.%s'
def test_versionformat_abbrevhash(self):
self.tar_scm_std('--versionformat', self.abbrev_hash_format)
self.assertTarOnly(self.basename(version = self.sha1s(self.rev(2))))
def test_versionformat_timestamp(self):
self.tar_scm_std('--versionformat', self.timestamp_format)
self.assertTarOnly(self.basename(version = self.timestamps(self.rev(2))))
def _mixed_version_format(self):
return self.mixed_version_template % (self.timestamp_format, self.abbrev_hash_format)
def _mixed_version(self):
return self.mixed_version_template % (self.timestamps(self.rev(2)), self.sha1s(self.rev(2)))
def test_versionformat_mixed(self):
self.tar_scm_std('--versionformat', self._mixed_version_format())
self.assertTarOnly(self.basename(version = self._mixed_version()))
def test_version_versionformat(self):
self.tar_scm_std('--version', '3.0', '--versionformat', self._mixed_version_format())
self.assertTarOnly(self.basename(version = self._mixed_version()))
def test_versionformat_revision(self):
self.fixtures.create_commits(4)
self.tar_scm_std('--versionformat', self.abbrev_hash_format, '--revision', self.rev(2))
basename = self.basename(version = self.sha1s(self.rev(2)))
th = self.assertTarOnly(basename)
self.assertTarMemberContains(th, basename + '/a', '2')
++++++ gittests.py ++++++
#!/usr/bin/python
from githgtests import GitHgTests
from gitfixtures import GitFixtures
from utils import run_git
class GitTests(GitHgTests):
scm = 'git'
initial_clone_command = 'git clone'
update_cache_command = 'git fetch'
fixtures_class = GitFixtures
abbrev_hash_format = '%h'
timestamp_format = '%at'
def default_version(self):
return self.timestamps(self.rev(2))
++++++ hgfixtures.py ++++++
#!/usr/bin/python
import os
from fixtures import Fixtures
from utils import mkfreshdir, run_hg
class HgFixtures(Fixtures):
def init(self):
self.create_repo()
self.timestamps = { }
self.sha1s = { }
self.create_commits(2)
def run(self, cmd):
return run_hg(self.repo_path, cmd)
def create_repo(self):
os.makedirs(self.repo_path)
os.chdir(self.repo_path)
self.run('init')
c = open('.hg/hgrc', 'w')
c.write("[ui]\nusername = %s\n" % self.name_and_email)
c.close()
self.wd = self.repo_path
print "created repo", self.repo_path
def do_commit(self, newly_created):
self.run('add .')
self.run('commit -m%d' % self.next_commit_rev)
def get_metadata(self, formatstr):
return self.run('log -l1 --template "%s"' % formatstr)[0]
def record_rev(self, rev_num):
tag = str(rev_num - 1) # hg starts counting changesets at 0
self.revs[rev_num] = tag
self.timestamps[tag] = self.get_metadata('{date}')
self.sha1s[tag] = self.get_metadata('{node|short}')
self.scmlogs.annotate(
"Recorded rev %d: id %s, timestamp %s, SHA1 %s" % \
(rev_num,
tag,
self.timestamps[tag],
self.sha1s[tag])
)
++++++ hgtests.py ++++++
#!/usr/bin/python
from githgtests import GitHgTests
from hgfixtures import HgFixtures
from utils import run_hg
class HgTests(GitHgTests):
scm = 'hg'
initial_clone_command = 'hg clone'
update_cache_command = 'hg pull'
fixtures_class = HgFixtures
abbrev_hash_format = '{node|short}'
timestamp_format = '{date}'
def default_version(self):
return self.rev(2)
++++++ scm-wrapper ++++++
#!/bin/bash
# Wrapper around SCM to enable behaviour verification testing
# on tar_scm's repository caching code. This is cleaner than
# writing tests which look inside the cache, because then they
# become coupled to the cache's implementation, and require
# knowledge of where the cache lives etc.
me=`basename $0`
if [ -z "$SCM_INVOCATION_LOG" ]; then
cat <<EOF >&2
\$SCM_INVOCATION_LOG must be set before calling $0.
It should be invoked from the test suite, not directly.
EOF
exit 1
fi
if [ "$me" = 'scm-wrapper' ]; then
echo "$me should not be invoked directly, only via symlink" >&2
exit 1
fi
echo "$me $*" >> "$SCM_INVOCATION_LOG"
/usr/bin/$me "$@"
++++++ scmlogs.py ++++++
#!/usr/bin/python
import glob
import os
class ScmInvocationLogs:
"""
Provides log files which tracks invocations of SCM binaries. The
tracking is done via a wrapper around SCM to enable behaviour
verification testing on tar_scm's repository caching code. This
is cleaner than writing tests which look inside the cache, because
then they become coupled to the cache's implementation, and
require knowledge of where the cache lives etc.
One instance should be constructed per unit test. If the test
invokes the SCM binary multiple times, invoke next() in between
each, so that a separate log file is used for each invocation -
this allows more accurate fine-grained assertions on the
invocation log.
"""
@classmethod
def setup_bin_wrapper(cls, scm, tmp_dir):
cls.wrapper_dir = tmp_dir + '/wrappers'
if not os.path.exists(cls.wrapper_dir):
os.makedirs(cls.wrapper_dir)
wrapper = cls.wrapper_dir + '/' + scm
if not os.path.exists(wrapper):
os.symlink('../../scm-wrapper', wrapper)
path = os.getenv('PATH')
prepend = cls.wrapper_dir + ':'
if not path.startswith(prepend):
new_path = prepend + path
os.environ['PATH'] = new_path
def __init__(self, scm, test_dir):
self.scm = scm
self.test_dir = test_dir
self.counter = 0
self.unlink_existing_logs()
def get_log_file_template(self):
return '%s-invocation-%%s.log' % self.scm
def get_log_path_template(self):
return os.path.join(self.test_dir, self.get_log_file_template())
def unlink_existing_logs(self):
pat = self.get_log_path_template() % '*'
for log in glob.glob(pat):
os.unlink(log)
def get_log_file(self, identifier):
if identifier:
identifier = '-' + identifier
return self.get_log_file_template() % ('%02d%s' % (self.counter, identifier))
def get_log_path(self, identifier):
return os.path.join(self.test_dir, self.get_log_file(identifier))
def next(self, identifier=''):
self.counter += 1
self.current_log_path = self.get_log_path(identifier)
if os.path.exists(self.current_log_path):
raise RuntimeError, "%s already existed?!" % self.current_log_path
os.putenv('SCM_INVOCATION_LOG', self.current_log_path)
def annotate(self, msg):
log = open(self.current_log_path, 'a')
log.write('# ' + msg + "\n")
print msg
log.close()
def read(self):
if not os.path.exists(self.current_log_path):
return '