From 4ebe0047c309d2ece13ab84ee63fd119f74e14f0 Mon Sep 17 00:00:00 2001 From: Rong Jinhui Date: Tue, 4 Aug 2015 09:03:42 +0800 Subject: Upgrade version to 0.6.25 Change-Id: I1d62032a98e91130c35ceccff576262709d806b3 Signed-off-by: Rong Jinhui --- debian/changelog | 6 ++++++ packaging/git-buildpackage.changes | 3 +++ packaging/git-buildpackage.spec | 4 ++-- 3 files changed, 11 insertions(+), 2 deletions(-) diff --git a/debian/changelog b/debian/changelog index ef2921ef..b16e152d 100644 --- a/debian/changelog +++ b/debian/changelog @@ -1,3 +1,9 @@ +git-buildpackage (0.6.25-tizen20150804) unstable; urgency=low + + * Upgrade version to 0.6.25 + + -- Rong Jinhui Thu, 04 Aug 2015 08:53:30 +0800 + git-buildpackage (0.6.15-tizen20140828) unstable; urgency=low [ Markus Lehtonen ] diff --git a/packaging/git-buildpackage.changes b/packaging/git-buildpackage.changes index 6a65a15a..b6b0eea4 100644 --- a/packaging/git-buildpackage.changes +++ b/packaging/git-buildpackage.changes @@ -1,3 +1,6 @@ +* Thu Aug 04 2015 Rong Jinhui tizen/0.6.25-20150804 +- Upgrade version to 0.6.25 + * Thu Aug 28 2014 Markus Lehtonen tizen/0.6.15-20140828 - Rebase on top of upstream version 0.6.15 - Changes in buildpackage-rpm diff --git a/packaging/git-buildpackage.spec b/packaging/git-buildpackage.spec index 3ff90288..be1a6826 100644 --- a/packaging/git-buildpackage.spec +++ b/packaging/git-buildpackage.spec @@ -3,7 +3,7 @@ Name: git-buildpackage Summary: Build packages from git -Version: 0.6.15 +Version: 0.6.25 Release: 0 Group: Development/Tools/Building License: GPLv2 @@ -111,7 +111,7 @@ Recommends: rpm-build %else Requires: rpm-build %endif -Provides: tizen-gbp-rpm = 20140828 +Provides: tizen-gbp-rpm = 20150804 %description rpm Set of tools from Debian that integrate the package build system with Git. -- cgit v1.2.3 From 7fb44ccf2f72ec14989a1913ba8971b0f6d195c3 Mon Sep 17 00:00:00 2001 From: "shuai.fu" Date: Thu, 12 Nov 2015 10:03:20 +0800 Subject: modify .gitmodule Signed-off-by: shuai.fu Change-Id: I93c6a4eccb8d62b0a164c13902726cf3c92ac039 --- .gitmodules | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/.gitmodules b/.gitmodules index 3b52b91f..6e177397 100644 --- a/.gitmodules +++ b/.gitmodules @@ -1,6 +1,6 @@ [submodule "tests/component/deb/data"] path = tests/component/deb/data - url = git://honk.sigxcpu.org/git/gbp/deb-testdata + url = ssh://fushuai1985@review.tizen.org:29418/tools/git-buildpackage-deb-testdata [submodule "tests/component/rpm/data"] path = tests/component/rpm/data - url = git://github.com/marquiz/git-buildpackage-rpm-testdata.git + url = ssh://fushuai1985@review.tizen.org:29418/tools/git-buildpackage-rpm-testdata -- cgit v1.2.3 From d444a992893fb800b5532b0ecd2cc4e13a4ec45f Mon Sep 17 00:00:00 2001 From: Markus Lehtonen Date: Thu, 12 Jan 2012 15:37:49 +0200 Subject: Introduce git-import-srpm tool Initial version of the git-import-srpm: a tool for importing source rpms. Signed-off-by: Markus Lehtonen Signed-off-by: Ed Bartosh Conflicts: .gitmodules gbp/config.py gbp/scripts/import_srpm.py tests/01_test_help.py tests/component/rpm/__init__.py tests/component/rpm/data tests/component/rpm/test_import_srpm.py --- .gitmodules | 3 -- gbp/config.py | 1 + gbp/scripts/import_srpm.py | 124 +++++++++++++++++++++++++++++++++++++++++++++ tests/component/rpm/data | 1 - 4 files changed, 125 insertions(+), 4 deletions(-) delete mode 160000 tests/component/rpm/data diff --git a/.gitmodules b/.gitmodules index 6e177397..29b4c390 100644 --- a/.gitmodules +++ b/.gitmodules @@ -1,6 +1,3 @@ [submodule "tests/component/deb/data"] path = tests/component/deb/data url = ssh://fushuai1985@review.tizen.org:29418/tools/git-buildpackage-deb-testdata -[submodule "tests/component/rpm/data"] - path = tests/component/rpm/data - url = ssh://fushuai1985@review.tizen.org:29418/tools/git-buildpackage-rpm-testdata diff --git a/gbp/config.py b/gbp/config.py index 90c5068d..6a93c3c5 100644 --- a/gbp/config.py +++ b/gbp/config.py @@ -672,4 +672,5 @@ class GbpOptionParserRpm(GbpOptionParser): "'%(meta-bts)s'"), } ) + # vim:et:ts=4:sw=4:et:sts=4:ai:set list listchars=tab\:»·,trail\:·: diff --git a/gbp/scripts/import_srpm.py b/gbp/scripts/import_srpm.py index 5a1d9d64..57003fa3 100755 --- a/gbp/scripts/import_srpm.py +++ b/gbp/scripts/import_srpm.py @@ -30,14 +30,19 @@ import urllib2 import gbp.tmpfile as tempfile import gbp.command_wrappers as gbpc from gbp.rpm import (parse_srpm, guess_spec, SpecFile, NoSpecError, +<<<<<<< HEAD RpmUpstreamSource) from gbp.rpm.policy import RpmPkgPolicy +======= + RpmUpstreamSource, compose_version_str) +>>>>>>> 736b9d8... Introduce git-import-srpm tool from gbp.rpm.git import (RpmGitRepository, GitRepositoryError) from gbp.git.modifier import GitModifier from gbp.config import (GbpOptionParserRpm, GbpOptionGroup, no_upstream_branch_msg) from gbp.errors import GbpError import gbp.log +<<<<<<< HEAD from gbp.scripts.pq_rpm import safe_patches, rm_patch_files, get_packager from gbp.scripts.common.pq import apply_and_commit_patch from gbp.pkg import parse_archive_filename @@ -53,16 +58,26 @@ Autoremove imported patches from packaging Removed all imported patches from %s and patch files from the packaging dir. +======= +from gbp.pkg import parse_archive_filename + +no_packaging_branch_msg = """ +Repository does not have branch '%s' for packaging/distribution sources. +You need to reate it or use --packaging-branch to specify it. +>>>>>>> 736b9d8... Introduce git-import-srpm tool """ class SkipImport(Exception): """Nothing imported""" pass +<<<<<<< HEAD class PatchImportError(Exception): """Patch import failed""" pass +======= +>>>>>>> 736b9d8... Introduce git-import-srpm tool def download_file(target_dir, url): """Download a remote file""" @@ -119,6 +134,7 @@ def set_bare_repo_options(options): if options.pristine_tar: gbp.log.info("Bare repository: setting %s option '--no-pristine-tar'") options.pristine_tar = False +<<<<<<< HEAD if options.patch_import: gbp.log.info("Bare repository: setting %s option '--no-patch-import')") options.patch_import = False @@ -162,6 +178,12 @@ def import_spec_patches(repo, spec, dirs): def force_to_branch_head(repo, branch): +======= + + +def force_to_branch_head(repo, branch): + """Checkout branch and reset --hard""" +>>>>>>> 736b9d8... Introduce git-import-srpm tool if repo.get_branch() == branch: # Update HEAD if we modified the checked out branch repo.force_head(branch, hard=True) @@ -199,15 +221,21 @@ def parse_args(argv): parser.add_config_file_option(option_name="tmp-dir", dest="tmp_dir") parser.add_option("--download", action="store_true", dest="download", default=False, help="download source package") +<<<<<<< HEAD parser.add_config_file_option(option_name="vendor", action="store", dest="vendor") +======= +>>>>>>> 736b9d8... Introduce git-import-srpm tool branch_group.add_config_file_option(option_name="packaging-branch", dest="packaging_branch") branch_group.add_config_file_option(option_name="upstream-branch", dest="upstream_branch") +<<<<<<< HEAD branch_group.add_option("--upstream-vcs-tag", dest="vcs_tag", help="Upstream VCS tag on top of which to import " "the orig sources") +======= +>>>>>>> 736b9d8... Introduce git-import-srpm tool branch_group.add_boolean_config_file_option( option_name="create-missing-branches", dest="create_missing_branches") @@ -240,8 +268,11 @@ def parse_args(argv): dest="author_is_committer") import_group.add_config_file_option(option_name="packaging-dir", dest="packaging_dir") +<<<<<<< HEAD import_group.add_boolean_config_file_option(option_name="patch-import", dest="patch_import") +======= +>>>>>>> 736b9d8... Introduce git-import-srpm tool (options, args) = parser.parse_args(argv[1:]) gbp.log.setup(options.color, options.verbose, options.color_scheme) return options, args @@ -355,6 +386,7 @@ def main(argv): # Unpack orig source archive if spec.orig_src: orig_tarball = os.path.join(dirs['src'], spec.orig_src['filename']) +<<<<<<< HEAD upstream = RpmUpstreamSource(orig_tarball) upstream = upstream.unpack(dirs['origsrc'], options.filters) else: @@ -371,6 +403,24 @@ def main(argv): if options.allow_same_version: gbp.log.info("Moving tag of version '%s' since import forced" % RpmPkgPolicy.compose_full_version(spec.version)) +======= + sources = RpmUpstreamSource(orig_tarball) + sources.unpack(dirs['origsrc'], options.filters) + else: + sources = None + + src_tag_format = options.packaging_tag if options.native \ + else options.upstream_tag + tag_str_fields = spec.version + src_tag = repo.version_to_tag(src_tag_format, tag_str_fields) + ver_str = compose_version_str(spec.version) + + if repo.find_version(options.packaging_tag, tag_str_fields): + gbp.log.warn("Version %s already imported." % ver_str) + if options.allow_same_version: + gbp.log.info("Moving tag of version '%s' since import forced" % + ver_str) +>>>>>>> 736b9d8... Introduce git-import-srpm tool move_tag_stamp(repo, options.packaging_tag, tag_str_fields) else: raise SkipImport @@ -379,10 +429,17 @@ def main(argv): options.create_missing_branches = True # Determine author and committer info, currently same info is used +<<<<<<< HEAD # for both upstream sources and packaging files author = None if spec.packager: match = re.match('(?P.*[^ ])\s*<(?P\S*)>', +======= + # for both sources and packaging files + author = None + if spec.packager: + match = re.match(r'(?P.*[^ ])\s*<(?P\S*)>', +>>>>>>> 736b9d8... Introduce git-import-srpm tool spec.packager.strip()) if match: author = GitModifier(match.group('name'), match.group('email')) @@ -391,12 +448,20 @@ def main(argv): gbp.log.debug("Couldn't determine packager info") committer = committer_from_author(author, options) +<<<<<<< HEAD # Import upstream sources if upstream: upstream_commit = repo.find_version(tag_format[0], tag_str_fields) if not upstream_commit: gbp.log.info("Tag %s not found, importing %s upstream sources" % (tag, tag_format[1])) +======= + # Import sources + if sources: + src_commit = repo.find_version(src_tag_format, tag_str_fields) + if not src_commit: + gbp.log.info("Tag %s not found, importing sources" % src_tag) +>>>>>>> 736b9d8... Introduce git-import-srpm tool branch = [options.upstream_branch, options.packaging_branch][options.native] @@ -408,6 +473,7 @@ def main(argv): gbp.log.err(no_upstream_branch_msg % branch + "\n" "Also check the --create-missing-branches option.") raise GbpError +<<<<<<< HEAD msg = "%s version %s" % (tag_format[1], spec.upstreamversion) if options.vcs_tag: @@ -424,6 +490,19 @@ def main(argv): repo.create_tag(name=tag, msg=msg, commit=upstream_commit, +======= + src_vendor = "Native" if options.native else "Upstream" + msg = "%s version %s" % (src_vendor, spec.upstreamversion) + src_commit = repo.commit_dir(sources.unpacked, + "Imported %s" % msg, + branch, + author=author, + committer=committer, + create_missing_branch=options.create_missing_branches) + repo.create_tag(name=src_tag, + msg=msg, + commit=src_commit, +>>>>>>> 736b9d8... Introduce git-import-srpm tool sign=options.sign_tags, keyid=options.keyid) @@ -442,7 +521,11 @@ def main(argv): # Import packaging files. For native packages we assume that also # packaging files are found in the source tarball +<<<<<<< HEAD if not options.native or not upstream: +======= + if not options.native or not sources: +>>>>>>> 736b9d8... Introduce git-import-srpm tool gbp.log.info("Importing packaging files") branch = options.packaging_branch if not repo.has_branch(branch): @@ -454,6 +537,7 @@ def main(argv): "option.") raise GbpError +<<<<<<< HEAD tag_str_fields = dict(spec.version, vendor=options.vendor) tag = repo.version_to_tag(options.packaging_tag, tag_str_fields) msg = "%s release %s" % (options.vendor, @@ -470,11 +554,29 @@ def main(argv): # Copy packaging files to the unpacked sources dir try: pkgsubdir = os.path.join(upstream.unpacked, +======= + tag = repo.version_to_tag(options.packaging_tag, tag_str_fields) + pkg_vendor = "Native" if options.native else "Downstrean" + msg = "%s release %s" % (pkg_vendor, ver_str) + + if options.orphan_packaging or not sources: + commit = repo.commit_dir(dirs['packaging_base'], + "Imported %s" % msg, + branch, + author=author, + committer=committer, + create_missing_branch=options.create_missing_branches) + else: + # Copy packaging files to the unpacked sources dir + try: + pkgsubdir = os.path.join(sources.unpacked, +>>>>>>> 736b9d8... Introduce git-import-srpm tool options.packaging_dir) os.mkdir(pkgsubdir) except OSError as err: if err.errno != errno.EEXIST: raise +<<<<<<< HEAD for fn in os.listdir(dirs['packaging']): shutil.copy2(os.path.join(dirs['packaging'], fn), pkgsubdir) @@ -493,6 +595,21 @@ def main(argv): options.packaging_dir, spec.specfile)) import_spec_patches(repo, spec, dirs) commit = options.packaging_branch +======= + for fname in os.listdir(dirs['packaging']): + shutil.copy2(os.path.join(dirs['packaging'], fname), + pkgsubdir) + commit = repo.commit_dir(sources.unpacked, + "Imported %s" % msg, + branch, + other_parents=[src_commit], + author=author, + committer=committer, + create_missing_branch=options.create_missing_branches) + # Import patches on top of the source tree + # (only for non-native packages with non-orphan packaging) + force_to_branch_head(repo, options.packaging_branch) +>>>>>>> 736b9d8... Introduce git-import-srpm tool # Create packaging tag repo.create_tag(name=tag, @@ -518,9 +635,12 @@ def main(argv): except NoSpecError as err: gbp.log.err("Failed determine spec file: %s" % err) ret = 1 +<<<<<<< HEAD except PatchImportError as err: gbp.log.err(err) ret = 2 +======= +>>>>>>> 736b9d8... Introduce git-import-srpm tool except SkipImport: skipped = True finally: @@ -528,9 +648,13 @@ def main(argv): gbpc.RemoveTree(dirs['tmp_base'])() if not ret and not skipped: +<<<<<<< HEAD gbp.log.info("Version '%s' imported under '%s'" % (RpmPkgPolicy.compose_full_version(spec.version), spec.name)) +======= + gbp.log.info("Version '%s' imported under '%s'" % (ver_str, spec.name)) +>>>>>>> 736b9d8... Introduce git-import-srpm tool return ret if __name__ == '__main__': diff --git a/tests/component/rpm/data b/tests/component/rpm/data deleted file mode 160000 index ff090c1c..00000000 --- a/tests/component/rpm/data +++ /dev/null @@ -1 +0,0 @@ -Subproject commit ff090c1cf946e3df67795ce3c1437ec6246dbf37 -- cgit v1.2.3 From 4003b825d2cc091df993021cf73cdbec32be3e27 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Guido=20G=C3=BCnther?= Date: Thu, 24 Jul 2014 21:37:58 +0200 Subject: Pass --no-pristine-tar to SRPM compnent tests to avoid pristine-tar showing up in the matched branches Conflicts: tests/component/rpm/test_import_srpm.py --- tests/component/rpm/test_import_srpm.py | 16 ++++++++-------- 1 file changed, 8 insertions(+), 8 deletions(-) diff --git a/tests/component/rpm/test_import_srpm.py b/tests/component/rpm/test_import_srpm.py index 4811794a..8c6408f3 100644 --- a/tests/component/rpm/test_import_srpm.py +++ b/tests/component/rpm/test_import_srpm.py @@ -51,7 +51,7 @@ class TestImportPacked(ComponentTestBase): def test_basic_import(self): """Test importing of non-native src.rpm""" srpm = os.path.join(DATA_DIR, 'gbp-test-1.0-1.src.rpm') - eq_(mock_import([srpm]), 0) + eq_(mock_import(['--no-pristine-tar', srpm]), 0) # Check repository state repo = GitRepository('gbp-test') files = set(['Makefile', 'README', 'bar.tar.gz', 'dummy.sh', 'foo.txt', @@ -64,7 +64,7 @@ class TestImportPacked(ComponentTestBase): def test_basic_import2(self): """Import package with multiple spec files and full url patch""" srpm = os.path.join(DATA_DIR, 'gbp-test2-2.0-0.src.rpm') - eq_(mock_import([srpm]), 0) + eq_(mock_import(['--no-pristine-tar', srpm]), 0) # Check repository state repo = GitRepository('gbp-test2') files = set(['Makefile', 'README', 'bar.tar.gz', 'dummy.sh', 'foo.txt', @@ -82,7 +82,7 @@ class TestImportPacked(ComponentTestBase): development branches """ srpm = os.path.join(DATA_DIR, 'gbp-test2-2.0-0.src.rpm') - eq_(mock_import(['--orphan-packaging', srpm]), 0) + eq_(mock_import(['--no-pristine-tar', '--orphan-packaging', srpm]), 0) # Check repository state repo = GitRepository('gbp-test2') files = set(['bar.tar.gz', 'foo.txt', 'gbp-test2.spec', @@ -132,7 +132,7 @@ class TestImportPacked(ComponentTestBase): srpms = [ os.path.join(DATA_DIR, 'gbp-test-1.0-1.src.rpm'), os.path.join(DATA_DIR, 'gbp-test-1.0-1.other.src.rpm'), os.path.join(DATA_DIR, 'gbp-test-1.1-1.src.rpm') ] - eq_(mock_import([srpms[0]]), 0) + eq_(mock_import(['--no-pristine-tar', srpms[0]]), 0) repo = GitRepository('gbp-test') self._check_repo_state(repo, 'master', ['master', 'upstream']) eq_(len(repo.get_commits()), 4) @@ -176,7 +176,7 @@ class TestImportPacked(ComponentTestBase): # The first import should fail because upstream branch is missing eq_(mock_import([srpm]), 1) self._check_log(-1, 'Also check the --create-missing-branches') - eq_(mock_import(['--create-missing', srpm]), 0) + eq_(mock_import(['--no-pristine-tar', '--create-missing', srpm]), 0) self._check_repo_state(repo, 'master', ['master', 'upstream']) # Four commits: our initial, upstream, packaging files, one patch, # and the removal of imported patches @@ -191,7 +191,7 @@ class TestImportPacked(ComponentTestBase): def test_filter(self): """Test filter option""" srpm = os.path.join(DATA_DIR, 'gbp-test-1.0-1.src.rpm') - eq_(mock_import(['--filter=README', '--filter=mydir', srpm]), 0) + eq_(mock_import(['--no-pristine-tar', '--filter=README', '--filter=mydir', srpm]), 0) # Check repository state repo = GitRepository('gbp-test') files = set(['Makefile', 'dummy.sh', 'bar.tar.gz', 'foo.txt', @@ -248,7 +248,7 @@ class TestImportUnPacked(ComponentTestBase): def test_import_dir(self): """Test importing of directories""" - eq_(mock_import(['gbp-test-1.0-1-unpack']), 0) + eq_(mock_import(['--no-pristine-tar', 'gbp-test-1.0-1-unpack']), 0) # Check repository state repo = GitRepository('gbp-test') self._check_repo_state(repo, 'master', ['master', 'upstream']) @@ -286,7 +286,7 @@ class TestDownloadImport(ComponentTestBase): urllib2.urlopen = Mock() urllib2.urlopen.return_value = open(local_fn, 'r') - eq_(mock_import(['--download', srpm]), 0) + eq_(mock_import(['--no-pristine-tar', '--download', srpm]), 0) # Check repository state repo = GitRepository('gbp-test') self._check_repo_state(repo, 'master', ['master', 'upstream']) -- cgit v1.2.3 From e597a15e8ffd04b2a1bac46d26732e8cff5bcea0 Mon Sep 17 00:00:00 2001 From: Markus Lehtonen Date: Thu, 12 Jan 2012 15:45:06 +0200 Subject: import-srpm: add 'vendor' config option Intended to represent the distribution vendor (e.g. 'Debian'). Currently, this can be used in tag format strings. NOTE: the vendor name is converted to lowercase when used in tag names. Signed-off-by: Markus Lehtonen Conflicts: gbp/config.py --- gbp/config.py | 1 + gbp/scripts/import_srpm.py | 7 ++++--- 2 files changed, 5 insertions(+), 3 deletions(-) diff --git a/gbp/config.py b/gbp/config.py index 6a93c3c5..820a4955 100644 --- a/gbp/config.py +++ b/gbp/config.py @@ -576,6 +576,7 @@ class GbpOptionParserRpm(GbpOptionParser): Handles commandline options and parsing of config files for rpm tools """ defaults = dict(GbpOptionParser.defaults) +<<<<<<< HEAD defaults.update( { 'vendor' : 'vendor', 'native' : 'auto', diff --git a/gbp/scripts/import_srpm.py b/gbp/scripts/import_srpm.py index 57003fa3..120dda74 100755 --- a/gbp/scripts/import_srpm.py +++ b/gbp/scripts/import_srpm.py @@ -219,6 +219,8 @@ def parse_args(argv): parser.add_config_file_option(option_name="color-scheme", dest="color_scheme") parser.add_config_file_option(option_name="tmp-dir", dest="tmp_dir") + parser.add_config_file_option(option_name="vendor", action="store", + dest="vendor") parser.add_option("--download", action="store_true", dest="download", default=False, help="download source package") <<<<<<< HEAD @@ -411,7 +413,7 @@ def main(argv): src_tag_format = options.packaging_tag if options.native \ else options.upstream_tag - tag_str_fields = spec.version + tag_str_fields = dict(spec.version, vendor=options.vendor.lower()) src_tag = repo.version_to_tag(src_tag_format, tag_str_fields) ver_str = compose_version_str(spec.version) @@ -556,8 +558,7 @@ def main(argv): pkgsubdir = os.path.join(upstream.unpacked, ======= tag = repo.version_to_tag(options.packaging_tag, tag_str_fields) - pkg_vendor = "Native" if options.native else "Downstrean" - msg = "%s release %s" % (pkg_vendor, ver_str) + msg = "%s release %s" % (options.vendor, ver_str) if options.orphan_packaging or not sources: commit = repo.commit_dir(dirs['packaging_base'], -- cgit v1.2.3 From 27760ed8111d27c4c34ffc2e392a1d4b3a67bcfc Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Guido=20G=C3=BCnther?= Date: Thu, 24 Jul 2014 23:12:30 +0200 Subject: Introduce git-buildpackage-rpm Currently only including "gbp import-srpm" Conflicts: debian/control debian/git-buildpackage-rpm.install debian/git-buildpackage.install --- .gitignore | 8 ++++---- debian/control | 3 +++ 2 files changed, 7 insertions(+), 4 deletions(-) diff --git a/.gitignore b/.gitignore index afc87fff..80960ac9 100644 --- a/.gitignore +++ b/.gitignore @@ -18,10 +18,10 @@ docs/manpage.links docs/manpage.refs docs/version.ent -debian/git-buildpackage.*.debhelper -debian/git-buildpackage.debhelper.* +debian/git-buildpackage*.debhelper* debian/python-module-stampdir/ debian/files -debian/git-buildpackage.substvars +debian/git-buildpackage*.substvars debian/git-buildpackage/ - +debian/git-buildpackage-rpm/ +debian/tmp/ diff --git a/debian/control b/debian/control index 705fd7cd..65987801 100644 --- a/debian/control +++ b/debian/control @@ -12,9 +12,12 @@ Build-Depends: pychecker, python (>> 2.6.6-3~), python-epydoc, + python-mock, python-nose, python-pkg-resources, + python-rpm, python-setuptools, + rpm, sgml2x, # For rpm (epydoc) python-rpm -- cgit v1.2.3 From e757609bc3d6b6e5c462becb69c2896182f5f4a6 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Guido=20G=C3=BCnther?= Date: Mon, 28 Jul 2014 15:35:01 +0200 Subject: linkeList: turn the bug printouts to debug level We don't take any action anyway so no need to confuse users. --- gbp/rpm/linkedlist.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/gbp/rpm/linkedlist.py b/gbp/rpm/linkedlist.py index ca000453..74d897bc 100644 --- a/gbp/rpm/linkedlist.py +++ b/gbp/rpm/linkedlist.py @@ -36,7 +36,7 @@ class LinkedListNode(object): def data(self): """Get data stored into node""" if self._data is None: - gbp.log.err("BUG: referencing a deleted node!") + gbp.log.debug("BUG: referencing a deleted node!") return("") return self._data @@ -55,7 +55,7 @@ class LinkedListNode(object): '' """ if data is None: - gbp.log.err("BUG: trying to store 'None', not allowed") + gbp.log.debug("BUG: trying to store 'None', not allowed") data = "" self._data = data -- cgit v1.2.3 From 9d8005cea62f5a1c56b0fa7c078235cd0195ddad Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Guido=20G=C3=BCnther?= Date: Mon, 28 Jul 2014 15:57:05 +0200 Subject: Remove all other log handlers when capturing logs This avoids spurious error messages during test runs. --- tests/component/__init__.py | 2 ++ 1 file changed, 2 insertions(+) diff --git a/tests/component/__init__.py b/tests/component/__init__.py index 31911e48..baabbbd3 100644 --- a/tests/component/__init__.py +++ b/tests/component/__init__.py @@ -183,6 +183,8 @@ class ComponentTestBase(object): self._loghandler = gbp.log.GbpStreamHandler(self._log, False) self._loghandler.addFilter(gbp.log.GbpFilter([gbp.log.WARNING, gbp.log.ERROR])) + for hdl in gbp.log.LOGGER.handlers: + gbp.log.LOGGER.removeHandler(hdl) gbp.log.LOGGER.addHandler(self._loghandler) elif self._log is not None: gbp.log.LOGGER.removeHandler(self._loghandler) -- cgit v1.2.3 From eadc7ab56f0d2056c632c6e7c7463288965c9727 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Guido=20G=C3=BCnther?= Date: Mon, 28 Jul 2014 16:00:12 +0200 Subject: Document changes and release 0.6.16 Conflicts: debian/changelog --- debian/changelog | 19 +++++++++++++++++++ 1 file changed, 19 insertions(+) diff --git a/debian/changelog b/debian/changelog index b16e152d..fdd8636b 100644 --- a/debian/changelog +++ b/debian/changelog @@ -54,6 +54,25 @@ git-buildpackage (0.6.15-tizen20140828) unstable; urgency=low * rpm packaging: use macro for python binary -- Markus Lehtonen Thu, 28 Aug 2014 11:40:05 +0300 +git-buildpackage (0.6.16) experimental; urgency=medium + + [ Markus Lehtonen ] + * Doc cleanups and reformatting + * [736b9d8] Introduce git-import-srpm tool. + * [ed228a2] import-srpm: add 'vendor' config option. + Intended to represent the distribution vendor (e.g. 'Debian'). + Currently, this can be used in tag format strings. + + [ Guido Günther ] + * [0b1fc0d] buildpackage: Also print tag name when tagging the Debian + release. Based on a patch by Kamal Mostafa + * [2bf944f] Pass --no-pristine-tar to SRPM compnent tests + to avoid pristine-tar showing up in the matched branches + * [23090c9] Introduce git-buildpackage-rpm. Currently only including "gbp + import-srpm". + * Remove newly introducted spurious log outputs from tests + + -- Guido Günther Mon, 28 Jul 2014 15:57:49 +0200 git-buildpackage (0.6.15) unstable; urgency=medium -- cgit v1.2.3 From 97802551b7d0c49b7f2be0e3645e159b617d8655 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Guido=20G=C3=BCnther?= Date: Mon, 11 Aug 2014 01:00:05 +0200 Subject: Make sure we fixup the changelog trailer with newer devscripts We don't change any mainttrailer options if already given. Thanks: James McCoy for the detailed explanation Closes: #740566 --- gbp/scripts/dch.py | 15 +++++++++++---- 1 file changed, 11 insertions(+), 4 deletions(-) diff --git a/gbp/scripts/dch.py b/gbp/scripts/dch.py index 0cf2e452..944e8280 100755 --- a/gbp/scripts/dch.py +++ b/gbp/scripts/dch.py @@ -70,11 +70,13 @@ def fixup_section(repo, git_author, options, dch_options): It might otherwise point to the last git committer instead of the person creating the changelog - This apply --distribution and --urgency options passed to git-dch + + This also applies --distribution and --urgency options passed to gbp dch """ author, email = get_author_email(repo, git_author) used_options = ['distribution', 'urgency'] - header_opts = [] + opts = [] + maintrailer_opts = [ '--nomainttrailer', '--mainttrailer', '-t' ] # This must not be done for snapshots or snapshots changelog entries # will not be concatenated @@ -83,11 +85,16 @@ def fixup_section(repo, git_author, options, dch_options): val = getattr(options, opt) if val: gbp.log.debug("Set header option '%s' to '%s'" % (opt, val)) - header_opts.append("--%s=%s" % (opt, val)) + opts.append("--%s=%s" % (opt, val)) else: gbp.log.debug("Snapshot enabled: do not fixup options in header") - ChangeLog.spawn_dch(msg='', author=author, email=email, dch_options=dch_options+header_opts) + for opt in mainttrailer_opts: + if opt in dch_options: + break + else: + opts.append(maintrailer_opts[0]) + ChangeLog.spawn_dch(msg='', author=author, email=email, dch_options=dch_options+opts) def snapshot_version(version): -- cgit v1.2.3 From 48533f68278cebcc96fb0a018a05f412001eac23 Mon Sep 17 00:00:00 2001 From: Bla Fasel Date: Mon, 11 Aug 2014 01:29:26 +0200 Subject: Brown paper bag, please Gbp-Dch: Ignore --- gbp/scripts/dch.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/gbp/scripts/dch.py b/gbp/scripts/dch.py index 944e8280..00e19f6b 100755 --- a/gbp/scripts/dch.py +++ b/gbp/scripts/dch.py @@ -76,7 +76,7 @@ def fixup_section(repo, git_author, options, dch_options): author, email = get_author_email(repo, git_author) used_options = ['distribution', 'urgency'] opts = [] - maintrailer_opts = [ '--nomainttrailer', '--mainttrailer', '-t' ] + mainttrailer_opts = [ '--nomainttrailer', '--mainttrailer', '-t' ] # This must not be done for snapshots or snapshots changelog entries # will not be concatenated @@ -93,7 +93,7 @@ def fixup_section(repo, git_author, options, dch_options): if opt in dch_options: break else: - opts.append(maintrailer_opts[0]) + opts.append(mainttrailer_opts[0]) ChangeLog.spawn_dch(msg='', author=author, email=email, dch_options=dch_options+opts) -- cgit v1.2.3 From f1ab6f1c8fbf3776cbd4adcf6116a078389e279c Mon Sep 17 00:00:00 2001 From: Bla Fasel Date: Mon, 11 Aug 2014 11:00:16 +0200 Subject: Use better variable name It's a boolean indicating wether we fetch the author information from git not the author information itself. Git-Dch: Ignore --- gbp/scripts/dch.py | 14 +++++++------- 1 file changed, 7 insertions(+), 7 deletions(-) diff --git a/gbp/scripts/dch.py b/gbp/scripts/dch.py index 00e19f6b..45d2b3ce 100755 --- a/gbp/scripts/dch.py +++ b/gbp/scripts/dch.py @@ -64,7 +64,7 @@ def get_author_email(repo, use_git_config): return author, email -def fixup_section(repo, git_author, options, dch_options): +def fixup_section(repo, use_git_author, options, dch_options): """ Fixup the changelog header and trailer's committer and email address @@ -73,7 +73,7 @@ def fixup_section(repo, git_author, options, dch_options): This also applies --distribution and --urgency options passed to gbp dch """ - author, email = get_author_email(repo, git_author) + author, email = get_author_email(repo, use_git_author) used_options = ['distribution', 'urgency'] opts = [] mainttrailer_opts = [ '--nomainttrailer', '--mainttrailer', '-t' ] @@ -160,9 +160,9 @@ def mangle_changelog(changelog, cp, snapshot=''): raise GbpError("Error mangling changelog %s" % e) -def do_release(changelog, repo, cp, git_author, dch_options): +def do_release(changelog, repo, cp, use_git_author, dch_options): """Remove the snapshot header and set the distribution""" - author, email = get_author_email(repo, git_author) + author, email = get_author_email(repo, use_git_author) (release, snapshot) = snapshot_version(cp['Version']) if snapshot: cp['MangledVersion'] = release @@ -350,7 +350,7 @@ def build_parser(name): help="Increment the Debian release number for a Debian Team upload, and add a Team upload changelog comment.") version_group.add_option("--security", dest="security", action="store_true", default=False, help="Increment the Debian release number for a security upload and add a security upload changelog comment.") - version_group.add_boolean_config_file_option(option_name="git-author", dest="git_author") + version_group.add_boolean_config_file_option(option_name="git-author", dest="use_git_author") commit_group.add_boolean_config_file_option(option_name="meta", dest="meta") commit_group.add_config_file_option(option_name="meta-closes", dest="meta_closes", help="Meta tags for the bts close commands, default is '%(meta-closes)s'") @@ -514,11 +514,11 @@ def main(argv): version=version_change, dch_options=dch_options) - fixup_section(repo, git_author=options.git_author, options=options, + fixup_section(repo, use_git_author=options.use_git_author, options=options, dch_options=dch_options) if options.release: - do_release(changelog, repo, cp, git_author=options.git_author, + do_release(changelog, repo, cp, use_git_author=options.use_git_author, dch_options=dch_options) elif options.snapshot: (snap, version) = do_snapshot(changelog, repo, options.snapshot_number) -- cgit v1.2.3 From 5bb4b1b1a8e4063673ed6352dd038700cc14266b Mon Sep 17 00:00:00 2001 From: Bla Fasel Date: Mon, 11 Aug 2014 11:09:32 +0200 Subject: dch: Only modify the mainttrailer when --git-author is in use --- gbp/scripts/dch.py | 11 ++++++----- 1 file changed, 6 insertions(+), 5 deletions(-) diff --git a/gbp/scripts/dch.py b/gbp/scripts/dch.py index 45d2b3ce..3a3d76e1 100755 --- a/gbp/scripts/dch.py +++ b/gbp/scripts/dch.py @@ -89,11 +89,12 @@ def fixup_section(repo, use_git_author, options, dch_options): else: gbp.log.debug("Snapshot enabled: do not fixup options in header") - for opt in mainttrailer_opts: - if opt in dch_options: - break - else: - opts.append(mainttrailer_opts[0]) + if use_git_author: + for opt in mainttrailer_opts: + if opt in dch_options: + break + else: + opts.append(mainttrailer_opts[0]) ChangeLog.spawn_dch(msg='', author=author, email=email, dch_options=dch_options+opts) -- cgit v1.2.3 From 3f8ffe4e0d762cd1c04d4e9cca2cefb68144b4aa Mon Sep 17 00:00:00 2001 From: Kamal Mostafa Date: Tue, 19 Aug 2014 17:14:47 +0200 Subject: buildpackage: Make debian-tag message configurable New config option --git-debian-tag-msg allows for the specification of the message format string for signed debian-tags. When left unset, the default debian-tag-msg format is still: %(pkg)s Debian release %(version)s Signed-off-by: Kamal Mostafa Conflicts: gbp/scripts/buildpackage.py --- docs/manpages/gbp-buildpackage.sgml | 13 +++++++++++-- gbp.conf | 1 + gbp/config.py | 4 ++++ gbp/scripts/buildpackage.py | 9 ++++++--- 4 files changed, 22 insertions(+), 5 deletions(-) diff --git a/docs/manpages/gbp-buildpackage.sgml b/docs/manpages/gbp-buildpackage.sgml index 150d5b6d..2a1729af 100644 --- a/docs/manpages/gbp-buildpackage.sgml +++ b/docs/manpages/gbp-buildpackage.sgml @@ -45,8 +45,9 @@ COMMAND - TAG-FORMAT - TAG-FORMAT + tag-format + tag-format + tag-msg-format [TAG|BRANCH|TREEISH] @@ -481,6 +482,14 @@ + + tag-msg-format + + + use this tag message format when signing Debian versions, + default is %(pkg)s Debian release %(version)s + + diff --git a/gbp.conf b/gbp.conf index aa9c35f8..435d9b0a 100644 --- a/gbp.conf +++ b/gbp.conf @@ -12,6 +12,7 @@ # the default tag formats used: #upstream-tag = upstream/%(version)s #debian-tag = debian/%(version)s +#debian-tag-msg = %(pkg)s Debian release %(version)s # use pristine-tar: #pristine-tar = True # don't check if debian-branch == current branch: diff --git a/gbp/config.py b/gbp/config.py index 820a4955..0b6c3b24 100644 --- a/gbp/config.py +++ b/gbp/config.py @@ -112,6 +112,7 @@ class GbpOptionParser(OptionParser): 'build' : 'True', 'hooks' : 'True', 'debian-tag' : 'debian/%(version)s', + 'debian-tag-msg' : '%(pkg)s Debian release %(version)s', 'upstream-tag' : 'upstream/%(version)s', 'import-msg' : 'Imported Upstream version %(version)s', 'commit-msg' : 'Update changelog for %(version)s release', @@ -177,6 +178,9 @@ class GbpOptionParser(OptionParser): 'debian-tag': ("Format string for debian tags, " "default is '%(debian-tag)s'"), + 'debian-tag-msg': + ("Format string for signed debian-tag messages, " + "default is '%(debian-tag-msg)s'"), 'upstream-tag': ("Format string for upstream tags, " "default is '%(upstream-tag)s'"), diff --git a/gbp/scripts/buildpackage.py b/gbp/scripts/buildpackage.py index da53fe92..01754e68 100755 --- a/gbp/scripts/buildpackage.py +++ b/gbp/scripts/buildpackage.py @@ -414,7 +414,8 @@ def build_parser(name, prefix=None): help="don't fail if the tag already exists") tag_group.add_boolean_config_file_option(option_name="sign-tags", dest="sign_tags") tag_group.add_config_file_option(option_name="keyid", dest="keyid") - tag_group.add_config_file_option(option_name="debian-tag", dest="packaging_tag") + tag_group.add_config_file_option(option_name="debian-tag", dest="debian_tag") + tag_group.add_config_file_option(option_name="debian-tag-msg", dest="debian_tag_msg") tag_group.add_config_file_option(option_name="upstream-tag", dest="upstream_tag") orig_group.add_config_file_option(option_name="upstream-tree", dest="upstream_tree") orig_group.add_boolean_config_file_option(option_name="pristine-tar", dest="pristine_tar") @@ -619,9 +620,11 @@ def main(argv): gbp.log.info("Tagging %s as %s" % (source.changelog.version, tag)) if options.retag and repo.has_tag(tag): repo.delete_tag(tag) + tag_msg=options.debian_tag_msg % dict( + pkg=source.sourcepkg, + version=source.changelog.version) repo.create_tag(name=tag, - msg="%s Debian release %s" % (source.sourcepkg, - source.changelog.version), + msg=tag_msg, sign=options.sign_tags, keyid=options.keyid) if options.posttag: sha = repo.rev_parse("%s^{}" % tag) -- cgit v1.2.3 From 6ee98632d2bee6b3b0ceb49bc86f03bfe21d5645 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Guido=20G=C3=BCnther?= Date: Tue, 19 Aug 2014 20:07:35 +0200 Subject: Improve error messages on formatting errors Make it easier for the user to detect misformated replacement strings in config files and command line options. Conflicts: debian/git-buildpackage.install gbp/scripts/import_orig.py --- gbp/deb/git.py | 3 ++- gbp/format.py | 44 ++++++++++++++++++++++++++++++++++++++++++++ gbp/scripts/buildpackage.py | 7 ++++--- gbp/scripts/import_orig.py | 3 ++- 4 files changed, 52 insertions(+), 5 deletions(-) create mode 100644 gbp/format.py diff --git a/gbp/deb/git.py b/gbp/deb/git.py index 6105fe7d..2a848d4f 100644 --- a/gbp/deb/git.py +++ b/gbp/deb/git.py @@ -19,6 +19,7 @@ import re from gbp.git import GitRepository, GitRepositoryError from gbp.deb.pristinetar import DebianPristineTar +from gbp.format import format_msg class DebianGitRepository(GitRepository): """A git repository that holds the source of a Debian package""" @@ -104,7 +105,7 @@ class DebianGitRepository(GitRepository): >>> DebianGitRepository.version_to_tag("debian/%(version)s", "0:0~0") 'debian/0%0_0' """ - return format % dict(version=DebianGitRepository._sanitize_version(version)) + return format_msg(format, dict(version=DebianGitRepository._sanitize_version(version))) @staticmethod def _sanitize_version(version): diff --git a/gbp/format.py b/gbp/format.py new file mode 100644 index 00000000..2a4af15c --- /dev/null +++ b/gbp/format.py @@ -0,0 +1,44 @@ +# vim: set fileencoding=utf-8 : +# +# (C) 2014 Guido Guenther +# This program is free software; you can redistribute it and/or modify +# it under the terms of the GNU General Public License as published by +# the Free Software Foundation; either version 2 of the License, or +# (at your option) any later version. +# +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with this program; if not, write to the Free Software +# Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA +"""Format a message""" + +from gbp.errors import GbpError + +def format_msg(msg, args): + """ + Format a strin with the given dict. Be a bit more verbose than + default python about the error cause. + + >>> format_msg("%(foo)", {}) + Traceback (most recent call last): + ... + GbpError: Failed to format %(foo): Missing value 'foo' in {} + >>> format_msg("%(foo)", {'foo': 'bar'}) + Traceback (most recent call last): + ... + GbpError: Failed to format %(foo) with {'foo': 'bar'}: incomplete format + >>> format_msg("A %(foo)s is a %(bar)s", {'foo': 'dog', 'bar': 'mamal'}) + 'A dog is a mamal' + """ + try: + return msg % args + except ValueError as e: + raise GbpError("Failed to format %s with %s: %s" % (msg, args, e)) + except KeyError as e: + raise GbpError("Failed to format %s: Missing value %s in %s" % (msg, e, args)) + + diff --git a/gbp/scripts/buildpackage.py b/gbp/scripts/buildpackage.py index 01754e68..dc850293 100755 --- a/gbp/scripts/buildpackage.py +++ b/gbp/scripts/buildpackage.py @@ -29,6 +29,7 @@ from gbp.command_wrappers import (Command, from gbp.config import (GbpOptionParserDebian, GbpOptionGroup) from gbp.deb.git import (GitRepositoryError, DebianGitRepository) from gbp.deb.source import DebianSource, DebianSourceError +from gbp.format import format_msg from gbp.git.vfs import GitVfs from gbp.deb.upstreamsource import DebianUpstreamSource from gbp.errors import GbpError @@ -620,9 +621,9 @@ def main(argv): gbp.log.info("Tagging %s as %s" % (source.changelog.version, tag)) if options.retag and repo.has_tag(tag): repo.delete_tag(tag) - tag_msg=options.debian_tag_msg % dict( - pkg=source.sourcepkg, - version=source.changelog.version) + tag_msg = format_msg(options.debian_tag_msg, + dict(pkg=source.sourcepkg, + version=source.changelog.version)) repo.create_tag(name=tag, msg=tag_msg, sign=options.sign_tags, keyid=options.keyid) diff --git a/gbp/scripts/import_orig.py b/gbp/scripts/import_orig.py index fb6070e9..a42a9eb1 100644 --- a/gbp/scripts/import_orig.py +++ b/gbp/scripts/import_orig.py @@ -29,6 +29,7 @@ from gbp.deb.changelog import ChangeLog, NoChangeLogError from gbp.deb.git import (GitRepositoryError, DebianGitRepository) from gbp.config import GbpOptionParserDebian, GbpOptionGroup, no_upstream_branch_msg from gbp.errors import GbpError +from gbp.format import format_msg import gbp.log from gbp.pkg import compressor_opts from gbp.scripts.common.import_orig import (orig_needs_repack, cleanup_tmp_tree, @@ -383,7 +384,7 @@ def main(argv): epoch = '%s:' % cp.epoch info = { 'version': "%s%s-1" % (epoch, version) } env = { 'GBP_BRANCH': options.packaging_branch } - gbpc.Command(options.postimport % info, extra_env=env, shell=True)() + gbpc.Command(format_msg(options.postimport, info), extra_env=env, shell=True)() # Update working copy and index if we've possibly updated the # checked out branch current_branch = repo.get_branch() -- cgit v1.2.3 From 3dbb0c9437e2067387750201a8f7f991aacc09f8 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Guido=20G=C3=BCnther?= Date: Sat, 23 Aug 2014 15:14:18 +0200 Subject: gbp: add --version option Closes: #758909 --- gbp/scripts/supercommand.py | 16 +++++++++++++++- 1 file changed, 15 insertions(+), 1 deletion(-) diff --git a/gbp/scripts/supercommand.py b/gbp/scripts/supercommand.py index 2eb64de2..e529b38c 100644 --- a/gbp/scripts/supercommand.py +++ b/gbp/scripts/supercommand.py @@ -17,6 +17,7 @@ # Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA """Supercommand for all gbp commands""" +import os import re import sys @@ -44,6 +45,13 @@ The most commonly used commands are: import-dscs - import multiple Debian source packages """ +def version(prog): + try: + from gbp.version import gbp_version + except ImportError: + gbp_version = '[Unknown version]' + print("%s %s" % (os.path.basename(prog), gbp_version)) + def import_command(cmd): """ Import the module that implements the given command @@ -63,12 +71,15 @@ def supercommand(argv=None): usage() return 1 - cmd = argv[1] + prg, cmd = argv[0:2] args = argv[1:] if cmd in ['--help', '-h']: usage() return 0 + elif cmd in [ '--version', 'version' ]: + version(argv[0]) + return 0 try: module = import_command(cmd) @@ -81,4 +92,7 @@ def supercommand(argv=None): return module.main(args) +if __name__ == '__main__': + sys.exit(supercommand()) + # vim:et:ts=4:sw=4:et:sts=4:ai:set list listchars=tab\:»·,trail\:·: -- cgit v1.2.3 From fc903c14ad29c6697d3e55f29e73beee3638d9d4 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Guido=20G=C3=BCnther?= Date: Sat, 23 Aug 2014 18:10:16 +0200 Subject: Allow to list all available commands --- docs/manpages/gbp.sgml | 16 ++++++++++++++++ gbp/scripts/supercommand.py | 43 ++++++++++++++++++++++++++++++++++++++++++- 2 files changed, 58 insertions(+), 1 deletion(-) diff --git a/docs/manpages/gbp.sgml b/docs/manpages/gbp.sgml index 00c9e77f..c0fdddc7 100644 --- a/docs/manpages/gbp.sgml +++ b/docs/manpages/gbp.sgml @@ -21,6 +21,8 @@ &gbp; + + @@ -41,6 +43,20 @@ Print help + + + + + Print the programs version + + + + + + + List all available commands + + diff --git a/gbp/scripts/supercommand.py b/gbp/scripts/supercommand.py index e529b38c..83c8446b 100644 --- a/gbp/scripts/supercommand.py +++ b/gbp/scripts/supercommand.py @@ -17,6 +17,7 @@ # Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA """Supercommand for all gbp commands""" +import glob import os import re import sys @@ -43,6 +44,8 @@ The most commonly used commands are: import-orig - import a new upstream tarball import-dsc - import a single Debian source package import-dscs - import multiple Debian source packages + +Use '--list-cmds' to list all available commands. """ def version(prog): @@ -52,6 +55,7 @@ def version(prog): gbp_version = '[Unknown version]' print("%s %s" % (os.path.basename(prog), gbp_version)) + def import_command(cmd): """ Import the module that implements the given command @@ -64,6 +68,40 @@ def import_command(cmd): return __import__('gbp.scripts.%s' % modulename, fromlist='main', level=0) +def pymod_to_cmd(mod): + """ + >>> pymod_to_cmd('/x/y/z/a_cmd.py') + 'a-cmd' + """ + return os.path.basename(mod.rsplit('.', 1)[0]).replace('_','-') + + +def get_available_commands(path): + cmds = [] + for f in glob.glob(os.path.join(path, '*.py')): + if os.path.basename(f) in ['__init__.py', 'supercommand.py']: + continue + cmds.append((pymod_to_cmd(f), f)) + return cmds + + +def list_available_commands(): + mod = __import__('gbp.scripts', fromlist='main', level=0) + path = os.path.dirname(mod.__file__) + maxlen = 0 + + print("Available commands in %s\n" % path) + cmds = sorted(get_available_commands(path)) + for cmd in cmds: + if len(cmd[0]) > maxlen: + maxlen = len(cmd[0]) + for cmd in cmds: + mod = import_command(cmd[0]) + doc = mod.__doc__ + print(" %s - %s" % (cmd[0].rjust(maxlen), doc)) + print('') + + def supercommand(argv=None): argv = argv or sys.argv @@ -74,12 +112,15 @@ def supercommand(argv=None): prg, cmd = argv[0:2] args = argv[1:] - if cmd in ['--help', '-h']: + if cmd in ['--help', '-h', 'help' ]: usage() return 0 elif cmd in [ '--version', 'version' ]: version(argv[0]) return 0 + elif cmd in [ '--list-cmds', 'list-cmds' ]: + list_available_commands() + return 0 try: module = import_command(cmd) -- cgit v1.2.3 From 3150bc895505f88834d6d3b1b072b44580c8df2a Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Guido=20G=C3=BCnther?= Date: Sat, 23 Aug 2014 18:18:10 +0200 Subject: Unify doc strings a bit since they now show up with --list-cmds --- gbp/scripts/buildpackage.py | 2 +- gbp/scripts/clone.py | 2 +- gbp/scripts/create_remote_repo.py | 2 +- gbp/scripts/dch.py | 2 +- gbp/scripts/import_dsc.py | 2 +- gbp/scripts/import_dscs.py | 2 +- gbp/scripts/import_orig.py | 2 +- gbp/scripts/import_srpm.py | 2 +- gbp/scripts/pq.py | 2 +- gbp/scripts/pull.py | 2 +- 10 files changed, 10 insertions(+), 10 deletions(-) diff --git a/gbp/scripts/buildpackage.py b/gbp/scripts/buildpackage.py index dc850293..484bec04 100755 --- a/gbp/scripts/buildpackage.py +++ b/gbp/scripts/buildpackage.py @@ -15,7 +15,7 @@ # along with this program; if not, write to the Free Software # Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA # -"""run commands to build a debian package out of a git repository""" +"""Build a debian package out of a GIT repository""" import ConfigParser import errno diff --git a/gbp/scripts/clone.py b/gbp/scripts/clone.py index 9dd0ae9c..2810a310 100755 --- a/gbp/scripts/clone.py +++ b/gbp/scripts/clone.py @@ -17,7 +17,7 @@ # # inspired by dom-git-checkout # -"""clone a repo and set it up for gbp""" +"""Clone a GIT repository and set it up for gbp""" import ConfigParser import sys diff --git a/gbp/scripts/create_remote_repo.py b/gbp/scripts/create_remote_repo.py index 0d2345cd..a9832a1d 100755 --- a/gbp/scripts/create_remote_repo.py +++ b/gbp/scripts/create_remote_repo.py @@ -16,7 +16,7 @@ # Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA # # Based on the aa-create-git-repo and dom-new-git-repo shell scripts -"""Create a remote repo based on the current one""" +"""Create a remote GIT repository based on the current one""" import ConfigParser import sys diff --git a/gbp/scripts/dch.py b/gbp/scripts/dch.py index 3a3d76e1..56185d32 100755 --- a/gbp/scripts/dch.py +++ b/gbp/scripts/dch.py @@ -15,7 +15,7 @@ # along with this program; if not, write to the Free Software # Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA # -"""Generate Debian changelog entries from git commit messages""" +"""Generate Debian changelog entries from GIT commit messages""" import ConfigParser import os.path diff --git a/gbp/scripts/import_dsc.py b/gbp/scripts/import_dsc.py index e6f72105..b19d95fc 100755 --- a/gbp/scripts/import_dsc.py +++ b/gbp/scripts/import_dsc.py @@ -14,7 +14,7 @@ # You should have received a copy of the GNU General Public License # along with this program; if not, write to the Free Software # Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA -"""Import a Debian source package into a git repository""" +"""Import a Debian source package into a GIT repository""" import ConfigParser import sys diff --git a/gbp/scripts/import_dscs.py b/gbp/scripts/import_dscs.py index f480fea4..5409ca11 100644 --- a/gbp/scripts/import_dscs.py +++ b/gbp/scripts/import_dscs.py @@ -14,7 +14,7 @@ # You should have received a copy of the GNU General Public License # along with this program; if not, write to the Free Software # Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA -"""Import multiple dsc files in one go""" +"""Import multiple dsc files into GIT in one go""" import glob import os diff --git a/gbp/scripts/import_orig.py b/gbp/scripts/import_orig.py index a42a9eb1..553fbdef 100644 --- a/gbp/scripts/import_orig.py +++ b/gbp/scripts/import_orig.py @@ -15,7 +15,7 @@ # along with this program; if not, write to the Free Software # Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA # -"""Import a new upstream version into a git repository""" +"""Import a new upstream version into a GIT repository""" import ConfigParser import os diff --git a/gbp/scripts/import_srpm.py b/gbp/scripts/import_srpm.py index 120dda74..8a4d6e89 100755 --- a/gbp/scripts/import_srpm.py +++ b/gbp/scripts/import_srpm.py @@ -15,7 +15,7 @@ # You should have received a copy of the GNU General Public License # along with this program; if not, write to the Free Software # Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA -"""Import an RPM source package into a git repository""" +"""Import an RPM source package into a GIT repository""" import ConfigParser import sys diff --git a/gbp/scripts/pq.py b/gbp/scripts/pq.py index 75348501..2445c70e 100755 --- a/gbp/scripts/pq.py +++ b/gbp/scripts/pq.py @@ -15,7 +15,7 @@ # along with this program; if not, write to the Free Software # Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA # -"""manage patches in a patch queue""" +"""Manage Debian patches on a patch queue branch""" import ConfigParser import errno diff --git a/gbp/scripts/pull.py b/gbp/scripts/pull.py index 12da8c5f..166955a9 100755 --- a/gbp/scripts/pull.py +++ b/gbp/scripts/pull.py @@ -17,7 +17,7 @@ # # heavily inspired by dom-safe-pull which is © 2009 Stéphane Glondu # -"""fast forward debian, upstream and pristine-tar branch""" +"""Pull remote changes and fast forward debian, upstream and pristine-tar branch""" import ConfigParser import sys -- cgit v1.2.3 From 30642ab56a62c4fba3d468b8209dbcfa0c3e9b6f Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Guido=20G=C3=BCnther?= Date: Sun, 24 Aug 2014 11:24:52 +0200 Subject: bash completion: make command list dynamic Use "gbp --list-cmds" so we don't have to hardcode the available commands and get support for the RPM ones as they show up. --- debian/git-buildpackage.bash-completion | 16 +++++++--------- 1 file changed, 7 insertions(+), 9 deletions(-) diff --git a/debian/git-buildpackage.bash-completion b/debian/git-buildpackage.bash-completion index c0127041..053b9332 100644 --- a/debian/git-buildpackage.bash-completion +++ b/debian/git-buildpackage.bash-completion @@ -27,6 +27,12 @@ _gbp_options () } +_gbp_commands () +{ + gbp --list-cmds | sed -ne 's/^ \+\([a-z\-]\+\) \-.*/\1/p' +} + + _gbp_comp () { local cur="${COMP_WORDS[COMP_CWORD]}" @@ -208,15 +214,7 @@ have gbp && _gbp () { local cur="${COMP_WORDS[COMP_CWORD]}" - local commands="buildpackage \ - clone \ - create-remote-repo \ - dch \ - import-dsc \ - import-dscs \ - import-orig \ - pq \ - pull" + local commands=$(_gbp_commands) local func command=$(_gbp_find_cmd_on_cmdline "$commands") -- cgit v1.2.3 From 1e93702c02eda708dbdfdd6b679ad1f8341637ef Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Guido=20G=C3=BCnther?= Date: Sun, 24 Aug 2014 11:31:57 +0200 Subject: Document changes and release 0.6.17 Conflicts: debian/changelog --- debian/changelog | 22 ++++++++++++++++++++++ 1 file changed, 22 insertions(+) diff --git a/debian/changelog b/debian/changelog index fdd8636b..f6ba5777 100644 --- a/debian/changelog +++ b/debian/changelog @@ -54,6 +54,28 @@ git-buildpackage (0.6.15-tizen20140828) unstable; urgency=low * rpm packaging: use macro for python binary -- Markus Lehtonen Thu, 28 Aug 2014 11:40:05 +0300 +git-buildpackage (0.6.17) experimental; urgency=medium + + [ Guido Günther ] + * [692e5da] Make sure we fixup the changelog trailer with newer devscripts. + We don't change any mainttrailer options already given. + Thanks to James McCoy for the detailed explanation (Closes: #740566) + * [ae5805e] Improve error messages on formatting errors to + make it easier for the user to detect misformated replacement strings in + config files and command line options. + * [5f82f44] gbp: add --version option (Closes: #758909) + * [04aa92f] Allow to list all available gbp subcommands + * [68c053f] Unify doc strings a bit since they now show up with --list-cmds + * [6d510ce] bash completion: make command list dynamic. + Use "gbp --list-cmds" so we don't have to hardcode the available + commands and get support for the RPM ones as they show up. + + [ Kamal Mostafa ] + * [6823e51] buildpackage: Make debian-tag message configurable via + --git-debian-tag-msg. + + -- Guido Günther Sun, 24 Aug 2014 11:31:28 +0200 + git-buildpackage (0.6.16) experimental; urgency=medium [ Markus Lehtonen ] -- cgit v1.2.3 From aa3b62e8d46eba092135fee55ac7187d7c2f4dd7 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Guido=20G=C3=BCnther?= Date: Tue, 26 Aug 2014 11:08:27 +0200 Subject: Don't delete *_source.changes on source only builds Closes: #758726 --- bin/git-pbuilder | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/bin/git-pbuilder b/bin/git-pbuilder index 4024d124..37ffe67b 100644 --- a/bin/git-pbuilder +++ b/bin/git-pbuilder @@ -265,6 +265,7 @@ fi # them from the shell since they'll undergo another round of shell expansion # when the pbuilder runs debbuild. for arg in "$@" ; do + [ "$arg" != "-S" ] || source_only=true DEBBUILDOPTS+=" $(shell_quote "$arg")" done @@ -278,7 +279,7 @@ else --debbuildopts "$DEBBUILDOPTS" -- "${OPTIONS[@]}" fi status="$?" -if [ -n "`ls ../*_source.changes`" ] ; then +if [ -n "`ls ../*_source.changes`" -a $source_only != 'true' ] ; then rm ../*_source.changes fi exit "$status" -- cgit v1.2.3 From d9a81f07b2f34778398d02e7aeb4f623e31240dc Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Guido=20G=C3=BCnther?= Date: Mon, 1 Sep 2014 09:36:11 +0200 Subject: Mention --no-merge Closes: #760091 --- docs/manpages/gbp-import-orig.sgml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs/manpages/gbp-import-orig.sgml b/docs/manpages/gbp-import-orig.sgml index f5326d37..db3433bc 100644 --- a/docs/manpages/gbp-import-orig.sgml +++ b/docs/manpages/gbp-import-orig.sgml @@ -77,7 +77,7 @@ - + Merge the upstream branch to the debian branch after import -- cgit v1.2.3 From 6b88e29e7147489c82e7d6d1298bc1d6b0f1b55f Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Guido=20G=C3=BCnther?= Date: Sat, 6 Sep 2014 13:41:27 +0200 Subject: Document changes and release 0.6.18 Conflicts: debian/changelog --- debian/changelog | 9 +++++++++ 1 file changed, 9 insertions(+) diff --git a/debian/changelog b/debian/changelog index f6ba5777..b73138f0 100644 --- a/debian/changelog +++ b/debian/changelog @@ -54,6 +54,15 @@ git-buildpackage (0.6.15-tizen20140828) unstable; urgency=low * rpm packaging: use macro for python binary -- Markus Lehtonen Thu, 28 Aug 2014 11:40:05 +0300 +git-buildpackage (0.6.18) unstable; urgency=medium + + * Upload to unstable + * [6edd836] Don't delete *_source.changes on source only builds + (Closes: #758726) + * [a37832e] Mention --no-merge (Closes: #760091) + + -- Guido Günther Sat, 06 Sep 2014 13:41:05 +0200 + git-buildpackage (0.6.17) experimental; urgency=medium [ Guido Günther ] -- cgit v1.2.3 From c18ec6cbca6513f8bfe0e03d7a51fb323a34b76f Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Guido=20G=C3=BCnther?= Date: Sun, 7 Sep 2014 09:25:30 +0200 Subject: Update to git-pbuilder 1.33 --- bin/git-pbuilder | 13 +++++++++---- 1 file changed, 9 insertions(+), 4 deletions(-) diff --git a/bin/git-pbuilder b/bin/git-pbuilder index 37ffe67b..a9104d7a 100644 --- a/bin/git-pbuilder +++ b/bin/git-pbuilder @@ -1,5 +1,5 @@ #!/bin/bash -# $Id: git-pbuilder,v 1.30 2013/11/05 18:17:09 eagle Exp $ +# $Id: git-pbuilder,v 1.33 2014/08/28 21:39:15 eagle Exp $ # # git-pbuilder -- Wrapper around pbuilder for git-buildpackage # @@ -10,6 +10,7 @@ # # Written by Russ Allbery # Based on the example in the git-buildpackage documentation +# Copyright 2014 Russ Allbery # Copyright 2008, 2009, 2010, 2011, 2012, 2013 # The Board of Trustees of the Leland Stanford Junior University # @@ -227,7 +228,8 @@ update|create|login) sudo "$BUILDER" --"$action" --distribution "$DIST" \ --othermirror "$OTHERMIRROR" "${OPTIONS[@]}" "$@" else - sudo "$BUILDER" --"$action" --distribution "$DIST" "${OPTIONS[@]}" "$@" + sudo "$BUILDER" --"$action" --distribution "$DIST" \ + "${OPTIONS[@]}" "$@" fi fi exit $? @@ -264,8 +266,11 @@ fi # Add all of the additional arguments we got on the command line, but quote # them from the shell since they'll undergo another round of shell expansion # when the pbuilder runs debbuild. +source_only=false for arg in "$@" ; do - [ "$arg" != "-S" ] || source_only=true + if [ x'-S' = x"$arg" ] ; then + source_only=true + fi DEBBUILDOPTS+=" $(shell_quote "$arg")" done @@ -279,7 +284,7 @@ else --debbuildopts "$DEBBUILDOPTS" -- "${OPTIONS[@]}" fi status="$?" -if [ -n "`ls ../*_source.changes`" -a $source_only != 'true' ] ; then +if [ -n "`ls ../*_source.changes`" ] && [ true != "$source_only" ] ; then rm ../*_source.changes fi exit "$status" -- cgit v1.2.3 From 1a36150b82dda766d4a1bbd4d2b277de01728a72 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Guido=20G=C3=BCnther?= Date: Sun, 7 Sep 2014 09:25:53 +0200 Subject: Document changes and release 0.6.19 Conflicts: debian/changelog --- debian/changelog | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/debian/changelog b/debian/changelog index b73138f0..5913e1e5 100644 --- a/debian/changelog +++ b/debian/changelog @@ -54,6 +54,12 @@ git-buildpackage (0.6.15-tizen20140828) unstable; urgency=low * rpm packaging: use macro for python binary -- Markus Lehtonen Thu, 28 Aug 2014 11:40:05 +0300 +git-buildpackage (0.6.19) unstable; urgency=medium + + * [5d4cb92] Update to git-pbuilder 1.33 + + -- Guido Günther Sun, 07 Sep 2014 09:25:48 +0200 + git-buildpackage (0.6.18) unstable; urgency=medium * Upload to unstable -- cgit v1.2.3 From 4e6bcb7dcd6ea1960af9ba77c0d25740c57d6de1 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Guido=20G=C3=BCnther?= Date: Fri, 12 Sep 2014 13:05:47 +0200 Subject: Allow to always drop pq branch after export Closes: #761160 Conflicts: gbp/config.py --- gbp/config.py | 4 ++++ gbp/scripts/pq.py | 4 ++++ tests/13_test_gbp_pq.py | 23 ++++++++++++++++++++++- 3 files changed, 30 insertions(+), 1 deletion(-) diff --git a/gbp/config.py b/gbp/config.py index 0b6c3b24..0c9f885c 100644 --- a/gbp/config.py +++ b/gbp/config.py @@ -161,6 +161,7 @@ class GbpOptionParser(OptionParser): 'symlink-orig': 'True', 'purge': 'True', 'tmp-dir' : '/var/tmp/gbp/', + 'drop': 'False', } help = { 'debian-branch': @@ -309,6 +310,9 @@ class GbpOptionParser(OptionParser): 'tmp-dir': ("Base directory under which temporary directories are " "created, default is '%(tmp-dir)s'"), + 'drop': + ("In case of 'export' drop the patch-queue branch " + "after export. Default is '%(drop)s'"), } def_config_files = [ '/etc/git-buildpackage/gbp.conf', diff --git a/gbp/scripts/pq.py b/gbp/scripts/pq.py index 2445c70e..5f899b81 100755 --- a/gbp/scripts/pq.py +++ b/gbp/scripts/pq.py @@ -117,6 +117,9 @@ def export_patches(repo, branch, options): else: gbp.log.info("No patches on '%s' - nothing to do." % pq_branch) + if options.drop: + drop_pq(repo, branch) + def safe_patches(series, tmpdir_base): """ @@ -257,6 +260,7 @@ def build_parser(name): help="verbose command execution") parser.add_option("--topic", dest="topic", help="in case of 'apply' topic (subdir) to put patch into") parser.add_config_file_option(option_name="time-machine", dest="time_machine", type="int") + parser.add_boolean_config_file_option("drop", dest='drop') parser.add_option("--force", dest="force", action="store_true", default=False, help="in case of import even import if the branch already exists") parser.add_config_file_option(option_name="color", dest="color", type='tristate') diff --git a/tests/13_test_gbp_pq.py b/tests/13_test_gbp_pq.py index 0b400c21..87bcd796 100644 --- a/tests/13_test_gbp_pq.py +++ b/tests/13_test_gbp_pq.py @@ -25,7 +25,7 @@ try: except ImportError: import unittest -from gbp.scripts.pq import generate_patches +from gbp.scripts.pq import generate_patches, switch_pq, export_patches import gbp.scripts.common.pq as pq import gbp.patch_series import tests.testutils as testutils @@ -137,5 +137,26 @@ class TestWritePatch(testutils.DebianGitTestRepo): # Branches must be identical afterwards self.assertEqual('', diff) +class TestExport(testutils.DebianGitTestRepo): + class Options(object): + drop = True + patch_numbers = False + + def setUp(self): + testutils.DebianGitTestRepo.setUp(self) + self.add_file('bar', 'bar') + + def test_drop(self): + """Test if we drop the patch-queue branch with --drop""" + repo = self.repo + start = repo.get_branch() + pq = os.path.join('patch-queue', start) + switch_pq(repo, start) + self.assertEqual(repo.get_branch(), pq) + export_patches(repo, pq, TestExport.Options) + self.assertEqual(repo.get_branch(), start) + self.assertFalse(repo.has_branch(pq)) + + def _patch_path(name): return os.path.join(context.projectdir, 'tests/data', name) -- cgit v1.2.3 From 6bbfb987eee4b9745487e10bef65bcd5b7478bee Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Guido=20G=C3=BCnther?= Date: Sat, 13 Sep 2014 12:53:15 +0200 Subject: pq: document --drop --- docs/manpages/gbp-pq.sgml | 8 ++++++++ gbp.conf | 2 ++ 2 files changed, 10 insertions(+) diff --git a/docs/manpages/gbp-pq.sgml b/docs/manpages/gbp-pq.sgml index 39bf0db4..cc31145f 100644 --- a/docs/manpages/gbp-pq.sgml +++ b/docs/manpages/gbp-pq.sgml @@ -23,6 +23,7 @@ topic num + @@ -157,6 +158,13 @@ + + + + Whether to drop (delete) the patch queue branch after + a succesful export + + diff --git a/gbp.conf b/gbp.conf index 435d9b0a..b97036df 100644 --- a/gbp.conf +++ b/gbp.conf @@ -106,6 +106,8 @@ # Options only affecting gbp pq [pq] #patch-numbers = False +# Whether to drop patch queue after export +#drop = False # Options only affecting gbp clone [clone] -- cgit v1.2.3 From d06b47422cef593efa57da0231182f67abfea0e4 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Guido=20G=C3=BCnther?= Date: Fri, 26 Sep 2014 10:31:48 +0200 Subject: meta-closes: Move help text to GbpOptionParser.help --- gbp/config.py | 2 ++ gbp/scripts/dch.py | 3 +-- 2 files changed, 3 insertions(+), 2 deletions(-) diff --git a/gbp/config.py b/gbp/config.py index 0c9f885c..da1808c4 100644 --- a/gbp/config.py +++ b/gbp/config.py @@ -211,6 +211,8 @@ class GbpOptionParser(OptionParser): "Include the full commit message instead of only the first line, default is '%(full)s'", 'meta': "Parse meta tags in commit messages, default is '%(meta)s'", + 'meta-closes': + "Meta tags for the bts close commands, default is '%(meta-closes)s'", 'ignore-new': "Build with uncommited changes in the source tree, default is '%(ignore-new)s'", 'ignore-branch': diff --git a/gbp/scripts/dch.py b/gbp/scripts/dch.py index 56185d32..b8a86a77 100755 --- a/gbp/scripts/dch.py +++ b/gbp/scripts/dch.py @@ -353,8 +353,7 @@ def build_parser(name): help="Increment the Debian release number for a security upload and add a security upload changelog comment.") version_group.add_boolean_config_file_option(option_name="git-author", dest="use_git_author") commit_group.add_boolean_config_file_option(option_name="meta", dest="meta") - commit_group.add_config_file_option(option_name="meta-closes", dest="meta_closes", - help="Meta tags for the bts close commands, default is '%(meta-closes)s'") + commit_group.add_config_file_option(option_name="meta-closes", dest="meta_closes") commit_group.add_boolean_config_file_option(option_name="full", dest="full") commit_group.add_config_file_option(option_name="id-length", dest="idlen", help="include N digits of the commit id in the changelog entry, default is '%(id-length)s'", -- cgit v1.2.3 From fb11877b15395f66aa4a265479606055f1559cb3 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Guido=20G=C3=BCnther?= Date: Sat, 6 Sep 2014 13:40:14 +0200 Subject: pq: Add "pq export --commit" option This commits the changes in the pq right away. This is currently experimental and subject to change. Conflicts: gbp/scripts/pq.py --- gbp/config.py | 3 +++ gbp/scripts/pq.py | 74 +++++++++++++++++++++++++++++++++++++++++++++++++++++-- 2 files changed, 75 insertions(+), 2 deletions(-) diff --git a/gbp/config.py b/gbp/config.py index da1808c4..40d52a83 100644 --- a/gbp/config.py +++ b/gbp/config.py @@ -162,6 +162,7 @@ class GbpOptionParser(OptionParser): 'purge': 'True', 'tmp-dir' : '/var/tmp/gbp/', 'drop': 'False', + 'commit': 'False', } help = { 'debian-branch': @@ -315,6 +316,8 @@ class GbpOptionParser(OptionParser): 'drop': ("In case of 'export' drop the patch-queue branch " "after export. Default is '%(drop)s'"), + 'commit': + "commit changes after export, Default is '%(commit)s'", } def_config_files = [ '/etc/git-buildpackage/gbp.conf', diff --git a/gbp/scripts/pq.py b/gbp/scripts/pq.py index 5f899b81..bf3fa9bb 100755 --- a/gbp/scripts/pq.py +++ b/gbp/scripts/pq.py @@ -1,6 +1,6 @@ # vim: set fileencoding=utf-8 : # -# (C) 2011 Guido Günther +# (C) 2011,2014 Guido Günther # This program is free software; you can redistribute it and/or modify # it under the terms of the GNU General Public License as published by # the Free Software Foundation; either version 2 of the License, or @@ -35,6 +35,7 @@ from gbp.scripts.common.pq import (is_pq_branch, pq_branch_name, pq_branch_base, switch_to_pq_branch, apply_single_patch, apply_and_commit_patch, drop_pq, get_maintainer_from_control) +from gbp.dch import extract_bts_cmds PATCH_DIR = "debian/patches/" SERIES_FILE = os.path.join(PATCH_DIR,"series") @@ -90,6 +91,66 @@ def generate_patches(repo, start, end, outdir, options): return patches +def compare_series(old, new): + """ + Compare new pathes to lists of patches already exported + + >>> compare_series(['a', 'b'], ['b', 'c']) + (['c'], ['a']) + >>> compare_series([], []) + ([], []) + """ + added = set(new).difference(old) + removed = set(old).difference(new) + return (list(added), list(removed)) + + +def format_series_diff(added, removed, options): + """ + Format the patch differences into a suitable commit message + + >>> format_series_diff(['a'], ['b'], None) + 'Rediff patches\\n\\nAdded a: \\nDropped b: \\n' + """ + if len(added) == 1 and not removed: + # Single patch added, create a more thorough commit message + patch = Patch(os.path.join('debian', 'patches', added[0])) + msg = patch.subject + bugs, dummy = extract_bts_cmds(patch.long_desc.split('\n'), options) + if bugs: + msg += '\n' + for k, v in bugs.items(): + msg += '\n%s: %s' % (k, ', '.join(v)) + else: + msg = "Rediff patches\n\n" + for p in added: + msg += 'Added %s: \n' % p + for p in removed: + msg += 'Dropped %s: \n' % p + return msg + + +def commit_patches(repo, branch, patches, options): + """ + Commit chanages exported from patch queue + """ + clean, dummy = repo.is_clean() + if clean: + return ([], []) + + vfs = gbp.git.vfs.GitVfs(repo, branch) + oldseries = vfs.open('debian/patches/series') + oldpatches = [ p.strip() for p in oldseries.readlines() ] + newpatches = [ p[len(PATCH_DIR):] for p in patches ] + + # FIXME: handle case were only the contents of the patches changed + added, removed = compare_series(oldpatches, newpatches) + msg = format_series_diff(added, removed, options) + repo.add_files(PATCH_DIR) + repo.commit_staged(msg=msg) + return added, removed + + def export_patches(repo, branch, options): """Export patches from the pq branch into a patch series""" if is_pq_branch(branch, options): @@ -113,7 +174,14 @@ def export_patches(repo, branch, options): with open(SERIES_FILE, 'w') as seriesfd: for patch in patches: seriesfd.write(os.path.relpath(patch, PATCH_DIR) + '\n') - GitCommand('status')(['--', PATCH_DIR]) + if options.commit: + added, removed = commit_patches(repo, branch, patches, options) + if added: + gbp.log.info("Added %s" % ', '.join(added)) + if removed: + gbp.log.info("Removed %s" % ', '.join(removed)) + else: + GitCommand('status')(['--', PATCH_DIR]) else: gbp.log.info("No patches on '%s' - nothing to do." % pq_branch) @@ -261,12 +329,14 @@ def build_parser(name): parser.add_option("--topic", dest="topic", help="in case of 'apply' topic (subdir) to put patch into") parser.add_config_file_option(option_name="time-machine", dest="time_machine", type="int") parser.add_boolean_config_file_option("drop", dest='drop') + parser.add_boolean_config_file_option(option_name="commit", dest="commit") parser.add_option("--force", dest="force", action="store_true", default=False, help="in case of import even import if the branch already exists") parser.add_config_file_option(option_name="color", dest="color", type='tristate') parser.add_config_file_option(option_name="color-scheme", dest="color_scheme") parser.add_config_file_option(option_name="tmp-dir", dest="tmp_dir") + parser.add_config_file_option(option_name="meta-closes", dest="meta_closes") return parser -- cgit v1.2.3 From e50f3a627f73a5f409eeac5cff52da78d5b10399 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Guido=20G=C3=BCnther?= Date: Sun, 12 Oct 2014 11:42:52 +0200 Subject: Document changes and release 0.6.20 Conflicts: debian/changelog --- debian/changelog | 11 +++++++++++ 1 file changed, 11 insertions(+) diff --git a/debian/changelog b/debian/changelog index 5913e1e5..c5f2efe7 100644 --- a/debian/changelog +++ b/debian/changelog @@ -54,6 +54,17 @@ git-buildpackage (0.6.15-tizen20140828) unstable; urgency=low * rpm packaging: use macro for python binary -- Markus Lehtonen Thu, 28 Aug 2014 11:40:05 +0300 +git-buildpackage (0.6.20) unstable; urgency=medium + + * [ee44479] Allow to always drop pq branch after export (Closes: #761160) + * [51ac0a5] pq: document --drop + * [90b283f] meta-closes: Move help text to GbpOptionParser.help + * [0afcd3d] pq: Add "pq export --commit" option. This commits the changes + in the pq right away. This options is currently experimental and subject + to change. + + -- Guido Günther Sun, 12 Oct 2014 11:42:27 +0200 + git-buildpackage (0.6.19) unstable; urgency=medium * [5d4cb92] Update to git-pbuilder 1.33 -- cgit v1.2.3 From a6babf007cbc1ec39213b3721e4ed27837462f94 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Guido=20G=C3=BCnther?= Date: Tue, 14 Oct 2014 19:18:20 +0200 Subject: pq: Don't fail commit if the series file is empty on the source branch --- gbp/scripts/pq.py | 9 +++++++-- 1 file changed, 7 insertions(+), 2 deletions(-) diff --git a/gbp/scripts/pq.py b/gbp/scripts/pq.py index bf3fa9bb..38d2d350 100755 --- a/gbp/scripts/pq.py +++ b/gbp/scripts/pq.py @@ -139,8 +139,13 @@ def commit_patches(repo, branch, patches, options): return ([], []) vfs = gbp.git.vfs.GitVfs(repo, branch) - oldseries = vfs.open('debian/patches/series') - oldpatches = [ p.strip() for p in oldseries.readlines() ] + try: + oldseries = vfs.open('debian/patches/series') + oldpatches = [ p.strip() for p in oldseries.readlines() ] + oldseries.close() + except IOError: + # No series file yet + oldpatches = [] newpatches = [ p[len(PATCH_DIR):] for p in patches ] # FIXME: handle case were only the contents of the patches changed -- cgit v1.2.3 From 197afecab06620dc92ac7efcadda69c8a9793376 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Guido=20G=C3=BCnther?= Date: Fri, 17 Oct 2014 13:01:34 +0200 Subject: man: fix option argument for --git-pbuilder-options --- docs/manpages/gbp-buildpackage.sgml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs/manpages/gbp-buildpackage.sgml b/docs/manpages/gbp-buildpackage.sgml index 2a1729af..59924880 100644 --- a/docs/manpages/gbp-buildpackage.sgml +++ b/docs/manpages/gbp-buildpackage.sgml @@ -36,7 +36,7 @@ DIST ARCH - + =PBUILDER_OPTIONS GPG-KEYID COMMAND -- cgit v1.2.3 From 45707a09054c3b2678b57a41c91d3f8fdb13a157 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Guido=20G=C3=BCnther?= Date: Fri, 17 Oct 2014 17:31:48 +0200 Subject: Improve change reporting a bit --- gbp/scripts/pq.py | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/gbp/scripts/pq.py b/gbp/scripts/pq.py index 38d2d350..af112917 100755 --- a/gbp/scripts/pq.py +++ b/gbp/scripts/pq.py @@ -182,9 +182,11 @@ def export_patches(repo, branch, options): if options.commit: added, removed = commit_patches(repo, branch, patches, options) if added: - gbp.log.info("Added %s" % ', '.join(added)) + what = 'patches' if len(added) > 1 else 'patch' + gbp.log.info("Added %s %s to patch series" % (what, ', '.join(added))) if removed: - gbp.log.info("Removed %s" % ', '.join(removed)) + what = 'patches' if len(removed) > 1 else 'patch' + gbp.log.info("Removed %s %s from patch series" % (what, ', '.join(removed))) else: GitCommand('status')(['--', PATCH_DIR]) else: -- cgit v1.2.3 From 40115b1d10c166ddddeaee68fd4f35901a4971d8 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Guido=20G=C3=BCnther?= Date: Fri, 17 Oct 2014 18:24:01 +0200 Subject: Complete setup.py for pypi --- setup.py | 15 +++++++++++++++ 1 file changed, 15 insertions(+) diff --git a/setup.py b/setup.py index e1159888..e733f9d7 100644 --- a/setup.py +++ b/setup.py @@ -42,10 +42,25 @@ def fetch_version(): return version + +def readme(): + with open('README') as file: + return file.read() + setup(name = "gbp", version = fetch_version(), author = u'Guido Günther', author_email = 'agx@sigxcpu.org', + url = 'https://honk.sigxcpu.org/piki/projects/git-buildpackage/', + description = 'Suite to help with Debian packages in Git repositories', + license = 'GPLv2+', + long_description = readme(), + classifiers = [ + 'Environment :: Console', + 'Programming Language :: Python :: 2', + 'Topic :: Software Development :: Version Control :: Git', + 'Operating System :: POSIX :: Linux', + ], scripts = [ 'bin/git-buildpackage', 'bin/git-import-dsc', 'bin/git-import-orig', -- cgit v1.2.3 From 9f3d054b30fc4c9d3bbeb6a2fb44dfab3125e87e Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Guido=20G=C3=BCnther?= Date: Fri, 17 Oct 2014 18:29:15 +0200 Subject: Update README a bit Git-Dch: Ignore Conflicts: README --- README | 13 ++++++++++--- 1 file changed, 10 insertions(+), 3 deletions(-) diff --git a/README b/README index 074b345b..26a155aa 100644 --- a/README +++ b/README @@ -1,10 +1,17 @@ +Git-buildpackage +---------------- This is a bunch of scripts to ease the development of Debian packages with git. -For more documentation see the manual. On Debian systems this can be found in +For more documentation on howto use these tools see the manual +online at: + + http://honk.sigxcpu.org/projects/git-buildpackage/manual-html/gbp.html + +On Debian systems this can be found in /usr/share/doc/git-buildpackage/manual-html. -It can be found online at +The API documentation of the gbp module can be found at: - http://honk.sigxcpu.org/projects/git-buildpackage/manual-html/gbp.html + http://honk.sigxcpu.org/projects/git-buildpackage/apidocs/ The limited documentation available for the RPM support can be found at -- cgit v1.2.3 From d2874ed7f11acb251eea9170c3389e2d8ac07c21 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Guido=20G=C3=BCnther?= Date: Fri, 17 Oct 2014 18:41:21 +0200 Subject: Document changes and release 0.6.21 Conflicts: debian/changelog --- debian/changelog | 10 ++++++++++ 1 file changed, 10 insertions(+) diff --git a/debian/changelog b/debian/changelog index c5f2efe7..c2b11cff 100644 --- a/debian/changelog +++ b/debian/changelog @@ -54,6 +54,16 @@ git-buildpackage (0.6.15-tizen20140828) unstable; urgency=low * rpm packaging: use macro for python binary -- Markus Lehtonen Thu, 28 Aug 2014 11:40:05 +0300 +git-buildpackage (0.6.21) unstable; urgency=medium + + * [81dab4b] pq: Don't fail commit if the series file is empty on the source + branch + * [740e431] man: fix option argument for --git-pbuilder-options + * [22a6987] Improve change reporting a bit + * [e08d64d] Complete setup.py for pypi + + -- Guido Günther Fri, 17 Oct 2014 18:41:14 +0200 + git-buildpackage (0.6.20) unstable; urgency=medium * [ee44479] Allow to always drop pq branch after export (Closes: #761160) -- cgit v1.2.3 From 637b6455e9759b387049a0f57a3b59fb09333181 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Guido=20G=C3=BCnther?= Date: Wed, 29 Oct 2014 07:46:35 +0100 Subject: git.vfs: fix close method Preventing a infinite recursion which can be triggered by gbp pq export --commit. --- gbp/git/vfs.py | 2 +- tests/test_GitVfs.py | 1 + 2 files changed, 2 insertions(+), 1 deletion(-) diff --git a/gbp/git/vfs.py b/gbp/git/vfs.py index 81649eb9..5d5e1323 100644 --- a/gbp/git/vfs.py +++ b/gbp/git/vfs.py @@ -41,7 +41,7 @@ class GitVfs(object): return self._data.read(size) def close(self): - return self.close() + return self._data.close() def __init__(self, repo, committish=None): """ diff --git a/tests/test_GitVfs.py b/tests/test_GitVfs.py index 7004db1f..8e049545 100644 --- a/tests/test_GitVfs.py +++ b/tests/test_GitVfs.py @@ -46,6 +46,7 @@ def test_read(): '' >>> gf.readline() '' + >>> gf.close() >>> gbp.git.vfs.GitVfs(repo, 'HEAD').open('foo.txt').read() == content True >>> gf = vfs.open('doesnotexist') -- cgit v1.2.3 From 0b47ebfeaebd2c05c5ecdbef87916e1b3cb6618e Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Guido=20G=C3=BCnther?= Date: Wed, 29 Oct 2014 07:47:29 +0100 Subject: Document changes and release 0.6.22 Conflicts: debian/changelog --- debian/changelog | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/debian/changelog b/debian/changelog index c2b11cff..fcac7dce 100644 --- a/debian/changelog +++ b/debian/changelog @@ -54,6 +54,13 @@ git-buildpackage (0.6.15-tizen20140828) unstable; urgency=low * rpm packaging: use macro for python binary -- Markus Lehtonen Thu, 28 Aug 2014 11:40:05 +0300 +git-buildpackage (0.6.22) unstable; urgency=medium + + * [3d8939d] git.vfs: fix close method. Preventing a infinite recursion + which can be triggered by gbp pq export --commit. + + -- Guido Günther Wed, 29 Oct 2014 07:47:21 +0100 + git-buildpackage (0.6.21) unstable; urgency=medium * [81dab4b] pq: Don't fail commit if the series file is empty on the source -- cgit v1.2.3 -- cgit v1.2.3 -- cgit v1.2.3 -- cgit v1.2.3 -- cgit v1.2.3 -- cgit v1.2.3 -- cgit v1.2.3 -- cgit v1.2.3 -- cgit v1.2.3 From 65b9eb3959d19300341922d631d96d0522aa5198 Mon Sep 17 00:00:00 2001 From: Markus Lehtonen Date: Thu, 6 Jun 2013 14:53:45 +0300 Subject: UpstreamSource.guess_version: recognise debian native tarballs Signed-off-by: Markus Lehtonen --- gbp/pkg/__init__.py | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/gbp/pkg/__init__.py b/gbp/pkg/__init__.py index 5a9e09cd..9c54c86d 100644 --- a/gbp/pkg/__init__.py +++ b/gbp/pkg/__init__.py @@ -242,6 +242,8 @@ class PkgPolicy(object): ('foo-bar', '0.2') >>> PkgPolicy.guess_upstream_src_version('foo-bar-0.2.tlz') ('foo-bar', '0.2') + >>> PkgPolicy.guess_upstream_src_version('foo-bar_0.2.tar.gz') + ('foo-bar', '0.2') """ version_chars = r'[a-zA-Z\d\.\~\-\:\+]' basename = parse_archive_filename(os.path.basename(filename))[0] @@ -249,8 +251,9 @@ class PkgPolicy(object): version_filters = map ( lambda x: x % version_chars, ( # Debian upstream tarball: package_'.orig.tar.gz' r'^(?P[a-z\d\.\+\-]+)_(?P%s+)\.orig', + # Debian native: 'package_.tar.gz' + r'^(?P[a-z\d\.\+\-]+)_(?P%s+)', # Upstream 'package-.tar.gz' - # or Debian native 'package_.tar.gz' # or directory 'package-': r'^(?P[a-zA-Z\d\.\+\-]+)(-)(?P[0-9]%s*)')) if extra_regex: -- cgit v1.2.3 -- cgit v1.2.3 From ba939cdf609837b6726a3e0869e456a463bbf0ab Mon Sep 17 00:00:00 2001 From: Markus Lehtonen Date: Thu, 30 May 2013 17:35:57 +0300 Subject: import-srpm: support --upstream-vcs-tag cmdline option Similar to the corresponding option in gbp import-orig. Signed-off-by: Markus Lehtonen Conflicts: gbp/scripts/import_srpm.py --- gbp/scripts/import_srpm.py | 123 --------------------------------------------- 1 file changed, 123 deletions(-) diff --git a/gbp/scripts/import_srpm.py b/gbp/scripts/import_srpm.py index 8a4d6e89..7a397fe9 100755 --- a/gbp/scripts/import_srpm.py +++ b/gbp/scripts/import_srpm.py @@ -30,19 +30,14 @@ import urllib2 import gbp.tmpfile as tempfile import gbp.command_wrappers as gbpc from gbp.rpm import (parse_srpm, guess_spec, SpecFile, NoSpecError, -<<<<<<< HEAD RpmUpstreamSource) from gbp.rpm.policy import RpmPkgPolicy -======= - RpmUpstreamSource, compose_version_str) ->>>>>>> 736b9d8... Introduce git-import-srpm tool from gbp.rpm.git import (RpmGitRepository, GitRepositoryError) from gbp.git.modifier import GitModifier from gbp.config import (GbpOptionParserRpm, GbpOptionGroup, no_upstream_branch_msg) from gbp.errors import GbpError import gbp.log -<<<<<<< HEAD from gbp.scripts.pq_rpm import safe_patches, rm_patch_files, get_packager from gbp.scripts.common.pq import apply_and_commit_patch from gbp.pkg import parse_archive_filename @@ -58,26 +53,16 @@ Autoremove imported patches from packaging Removed all imported patches from %s and patch files from the packaging dir. -======= -from gbp.pkg import parse_archive_filename - -no_packaging_branch_msg = """ -Repository does not have branch '%s' for packaging/distribution sources. -You need to reate it or use --packaging-branch to specify it. ->>>>>>> 736b9d8... Introduce git-import-srpm tool """ class SkipImport(Exception): """Nothing imported""" pass -<<<<<<< HEAD class PatchImportError(Exception): """Patch import failed""" pass -======= ->>>>>>> 736b9d8... Introduce git-import-srpm tool def download_file(target_dir, url): """Download a remote file""" @@ -134,7 +119,6 @@ def set_bare_repo_options(options): if options.pristine_tar: gbp.log.info("Bare repository: setting %s option '--no-pristine-tar'") options.pristine_tar = False -<<<<<<< HEAD if options.patch_import: gbp.log.info("Bare repository: setting %s option '--no-patch-import')") options.patch_import = False @@ -178,12 +162,6 @@ def import_spec_patches(repo, spec, dirs): def force_to_branch_head(repo, branch): -======= - - -def force_to_branch_head(repo, branch): - """Checkout branch and reset --hard""" ->>>>>>> 736b9d8... Introduce git-import-srpm tool if repo.get_branch() == branch: # Update HEAD if we modified the checked out branch repo.force_head(branch, hard=True) @@ -223,21 +201,15 @@ def parse_args(argv): dest="vendor") parser.add_option("--download", action="store_true", dest="download", default=False, help="download source package") -<<<<<<< HEAD parser.add_config_file_option(option_name="vendor", action="store", dest="vendor") -======= ->>>>>>> 736b9d8... Introduce git-import-srpm tool branch_group.add_config_file_option(option_name="packaging-branch", dest="packaging_branch") branch_group.add_config_file_option(option_name="upstream-branch", dest="upstream_branch") -<<<<<<< HEAD branch_group.add_option("--upstream-vcs-tag", dest="vcs_tag", help="Upstream VCS tag on top of which to import " "the orig sources") -======= ->>>>>>> 736b9d8... Introduce git-import-srpm tool branch_group.add_boolean_config_file_option( option_name="create-missing-branches", dest="create_missing_branches") @@ -270,11 +242,8 @@ def parse_args(argv): dest="author_is_committer") import_group.add_config_file_option(option_name="packaging-dir", dest="packaging_dir") -<<<<<<< HEAD import_group.add_boolean_config_file_option(option_name="patch-import", dest="patch_import") -======= ->>>>>>> 736b9d8... Introduce git-import-srpm tool (options, args) = parser.parse_args(argv[1:]) gbp.log.setup(options.color, options.verbose, options.color_scheme) return options, args @@ -388,7 +357,6 @@ def main(argv): # Unpack orig source archive if spec.orig_src: orig_tarball = os.path.join(dirs['src'], spec.orig_src['filename']) -<<<<<<< HEAD upstream = RpmUpstreamSource(orig_tarball) upstream = upstream.unpack(dirs['origsrc'], options.filters) else: @@ -405,24 +373,6 @@ def main(argv): if options.allow_same_version: gbp.log.info("Moving tag of version '%s' since import forced" % RpmPkgPolicy.compose_full_version(spec.version)) -======= - sources = RpmUpstreamSource(orig_tarball) - sources.unpack(dirs['origsrc'], options.filters) - else: - sources = None - - src_tag_format = options.packaging_tag if options.native \ - else options.upstream_tag - tag_str_fields = dict(spec.version, vendor=options.vendor.lower()) - src_tag = repo.version_to_tag(src_tag_format, tag_str_fields) - ver_str = compose_version_str(spec.version) - - if repo.find_version(options.packaging_tag, tag_str_fields): - gbp.log.warn("Version %s already imported." % ver_str) - if options.allow_same_version: - gbp.log.info("Moving tag of version '%s' since import forced" % - ver_str) ->>>>>>> 736b9d8... Introduce git-import-srpm tool move_tag_stamp(repo, options.packaging_tag, tag_str_fields) else: raise SkipImport @@ -431,17 +381,10 @@ def main(argv): options.create_missing_branches = True # Determine author and committer info, currently same info is used -<<<<<<< HEAD # for both upstream sources and packaging files author = None if spec.packager: match = re.match('(?P.*[^ ])\s*<(?P\S*)>', -======= - # for both sources and packaging files - author = None - if spec.packager: - match = re.match(r'(?P.*[^ ])\s*<(?P\S*)>', ->>>>>>> 736b9d8... Introduce git-import-srpm tool spec.packager.strip()) if match: author = GitModifier(match.group('name'), match.group('email')) @@ -450,20 +393,12 @@ def main(argv): gbp.log.debug("Couldn't determine packager info") committer = committer_from_author(author, options) -<<<<<<< HEAD # Import upstream sources if upstream: upstream_commit = repo.find_version(tag_format[0], tag_str_fields) if not upstream_commit: gbp.log.info("Tag %s not found, importing %s upstream sources" % (tag, tag_format[1])) -======= - # Import sources - if sources: - src_commit = repo.find_version(src_tag_format, tag_str_fields) - if not src_commit: - gbp.log.info("Tag %s not found, importing sources" % src_tag) ->>>>>>> 736b9d8... Introduce git-import-srpm tool branch = [options.upstream_branch, options.packaging_branch][options.native] @@ -475,7 +410,6 @@ def main(argv): gbp.log.err(no_upstream_branch_msg % branch + "\n" "Also check the --create-missing-branches option.") raise GbpError -<<<<<<< HEAD msg = "%s version %s" % (tag_format[1], spec.upstreamversion) if options.vcs_tag: @@ -492,19 +426,6 @@ def main(argv): repo.create_tag(name=tag, msg=msg, commit=upstream_commit, -======= - src_vendor = "Native" if options.native else "Upstream" - msg = "%s version %s" % (src_vendor, spec.upstreamversion) - src_commit = repo.commit_dir(sources.unpacked, - "Imported %s" % msg, - branch, - author=author, - committer=committer, - create_missing_branch=options.create_missing_branches) - repo.create_tag(name=src_tag, - msg=msg, - commit=src_commit, ->>>>>>> 736b9d8... Introduce git-import-srpm tool sign=options.sign_tags, keyid=options.keyid) @@ -523,11 +444,7 @@ def main(argv): # Import packaging files. For native packages we assume that also # packaging files are found in the source tarball -<<<<<<< HEAD if not options.native or not upstream: -======= - if not options.native or not sources: ->>>>>>> 736b9d8... Introduce git-import-srpm tool gbp.log.info("Importing packaging files") branch = options.packaging_branch if not repo.has_branch(branch): @@ -539,7 +456,6 @@ def main(argv): "option.") raise GbpError -<<<<<<< HEAD tag_str_fields = dict(spec.version, vendor=options.vendor) tag = repo.version_to_tag(options.packaging_tag, tag_str_fields) msg = "%s release %s" % (options.vendor, @@ -556,28 +472,11 @@ def main(argv): # Copy packaging files to the unpacked sources dir try: pkgsubdir = os.path.join(upstream.unpacked, -======= - tag = repo.version_to_tag(options.packaging_tag, tag_str_fields) - msg = "%s release %s" % (options.vendor, ver_str) - - if options.orphan_packaging or not sources: - commit = repo.commit_dir(dirs['packaging_base'], - "Imported %s" % msg, - branch, - author=author, - committer=committer, - create_missing_branch=options.create_missing_branches) - else: - # Copy packaging files to the unpacked sources dir - try: - pkgsubdir = os.path.join(sources.unpacked, ->>>>>>> 736b9d8... Introduce git-import-srpm tool options.packaging_dir) os.mkdir(pkgsubdir) except OSError as err: if err.errno != errno.EEXIST: raise -<<<<<<< HEAD for fn in os.listdir(dirs['packaging']): shutil.copy2(os.path.join(dirs['packaging'], fn), pkgsubdir) @@ -596,21 +495,6 @@ def main(argv): options.packaging_dir, spec.specfile)) import_spec_patches(repo, spec, dirs) commit = options.packaging_branch -======= - for fname in os.listdir(dirs['packaging']): - shutil.copy2(os.path.join(dirs['packaging'], fname), - pkgsubdir) - commit = repo.commit_dir(sources.unpacked, - "Imported %s" % msg, - branch, - other_parents=[src_commit], - author=author, - committer=committer, - create_missing_branch=options.create_missing_branches) - # Import patches on top of the source tree - # (only for non-native packages with non-orphan packaging) - force_to_branch_head(repo, options.packaging_branch) ->>>>>>> 736b9d8... Introduce git-import-srpm tool # Create packaging tag repo.create_tag(name=tag, @@ -636,12 +520,9 @@ def main(argv): except NoSpecError as err: gbp.log.err("Failed determine spec file: %s" % err) ret = 1 -<<<<<<< HEAD except PatchImportError as err: gbp.log.err(err) ret = 2 -======= ->>>>>>> 736b9d8... Introduce git-import-srpm tool except SkipImport: skipped = True finally: @@ -649,13 +530,9 @@ def main(argv): gbpc.RemoveTree(dirs['tmp_base'])() if not ret and not skipped: -<<<<<<< HEAD gbp.log.info("Version '%s' imported under '%s'" % (RpmPkgPolicy.compose_full_version(spec.version), spec.name)) -======= - gbp.log.info("Version '%s' imported under '%s'" % (ver_str, spec.name)) ->>>>>>> 736b9d8... Introduce git-import-srpm tool return ret if __name__ == '__main__': -- cgit v1.2.3 -- cgit v1.2.3 -- cgit v1.2.3 -- cgit v1.2.3 -- cgit v1.2.3 -- cgit v1.2.3 -- cgit v1.2.3 From eb681727b2c8712826ed3222895e5934393a7759 Mon Sep 17 00:00:00 2001 From: Markus Lehtonen Date: Tue, 15 May 2012 16:37:33 +0300 Subject: common/buildpackage: support for different archive formats Adds support for defining the archive format of the output of git_archive_single(), e.g. 'zip'. Defaults to 'tar', as before. Signed-off-by: Ed Bartosh Signed-off-by: Markus Lehtonen Conflicts: debian/control gbp/scripts/common/buildpackage.py --- gbp/scripts/common/buildpackage.py | 34 ++++++++++++++++++++++++++++++++++ 1 file changed, 34 insertions(+) diff --git a/gbp/scripts/common/buildpackage.py b/gbp/scripts/common/buildpackage.py index f95837c1..9be3f3fb 100644 --- a/gbp/scripts/common/buildpackage.py +++ b/gbp/scripts/common/buildpackage.py @@ -53,6 +53,7 @@ def sanitize_prefix(prefix): return '/' +<<<<<<< HEAD def compress(cmd, options, output, input_data=None): """ Filter data through a compressor cmd. @@ -75,6 +76,10 @@ def compress(cmd, options, output, input_data=None): def git_archive_submodules(repo, treeish, output, tmpdir_base, prefix, comp_type, comp_level, comp_opts, format='tar'): +======= +def git_archive_submodules(repo, treeish, output, prefix, comp_type, comp_level, + comp_opts, format='tar'): +>>>>>>> e6cea4d... common/buildpackage: support for different archive formats """ Create a source tree archive with submodules. @@ -84,7 +89,11 @@ def git_archive_submodules(repo, treeish, output, tmpdir_base, prefix, Exception handling is left to the caller. """ prefix = sanitize_prefix(prefix) +<<<<<<< HEAD tempdir = tempfile.mkdtemp(dir=tmpdir_base, prefix='git-archive_') +======= + tempdir = tempfile.mkdtemp() +>>>>>>> e6cea4d... common/buildpackage: support for different archive formats main_archive = os.path.join(tempdir, "main.%s" % format) submodule_archive = os.path.join(tempdir, "submodule.%s" % format) try: @@ -98,8 +107,13 @@ def git_archive_submodules(repo, treeish, output, tmpdir_base, prefix, subrepo = GitRepository(os.path.join(repo.path, subdir)) gbp.log.debug("Processing submodule %s (%s)" % (subdir, commit[0:8])) +<<<<<<< HEAD subrepo.archive(format=format, prefix='%s%s/' % (prefix, tarpath), output=submodule_archive, treeish=commit) +======= + repo.archive(format=format, prefix='%s%s/' % (prefix, tarpath), + output=submodule_archive, treeish=commit, cwd=subdir) +>>>>>>> e6cea4d... common/buildpackage: support for different archive formats if format == 'tar': CatenateTarArchive(main_archive)(submodule_archive) elif format == 'zip': @@ -107,22 +121,33 @@ def git_archive_submodules(repo, treeish, output, tmpdir_base, prefix, # compress the output if comp_type: +<<<<<<< HEAD compress(comp_type, ['--stdout', '-%s' % comp_level] + comp_opts + [main_archive], output) +======= + ret = os.system("%s --stdout -%s %s %s > %s" % (comp_type, comp_level, comp_opts, main_archive, output)) + if ret: + raise GbpError("Error creating %s: %d" % (output, ret)) +>>>>>>> e6cea4d... common/buildpackage: support for different archive formats else: shutil.move(main_archive, output) finally: shutil.rmtree(tempdir) +<<<<<<< HEAD def git_archive_single(repo, treeish, output, prefix, comp_type, comp_level, comp_opts, format='tar'): +======= +def git_archive_single(treeish, output, prefix, comp_type, comp_level, comp_opts, format='tar'): +>>>>>>> e6cea4d... common/buildpackage: support for different archive formats """ Create an archive without submodules Exception handling is left to the caller. """ prefix = sanitize_prefix(prefix) +<<<<<<< HEAD if comp_type: cmd = comp_type opts = ['--stdout', '-%s' % comp_level] + comp_opts @@ -141,6 +166,15 @@ def untar_data(outdir, data): popen.stdin.close() if popen.wait(): raise GbpError("Error extracting tar to %s" % outdir) +======= + pipe = pipes.Template() + pipe.prepend("git archive --format=%s --prefix=%s %s" % (format, prefix, treeish), '.-') + if comp_type: + pipe.append('%s -c -%s %s' % (comp_type, comp_level, comp_opts), '--') + ret = pipe.copy('', output) + if ret: + raise GbpError("Error creating %s: %d" % (output, ret)) +>>>>>>> e6cea4d... common/buildpackage: support for different archive formats #{ Functions to handle export-dir -- cgit v1.2.3 From 25985e8d15042cad86a80b610d8a8a9ad8078070 Mon Sep 17 00:00:00 2001 From: Markus Lehtonen Date: Tue, 18 Sep 2012 18:16:50 +0300 Subject: Change compressor cmdline opts in compressor_opts to a list Signed-off-by: Markus Lehtonen Conflicts: gbp/scripts/common/buildpackage.py --- gbp/scripts/common/buildpackage.py | 34 ---------------------------------- 1 file changed, 34 deletions(-) diff --git a/gbp/scripts/common/buildpackage.py b/gbp/scripts/common/buildpackage.py index 9be3f3fb..f95837c1 100644 --- a/gbp/scripts/common/buildpackage.py +++ b/gbp/scripts/common/buildpackage.py @@ -53,7 +53,6 @@ def sanitize_prefix(prefix): return '/' -<<<<<<< HEAD def compress(cmd, options, output, input_data=None): """ Filter data through a compressor cmd. @@ -76,10 +75,6 @@ def compress(cmd, options, output, input_data=None): def git_archive_submodules(repo, treeish, output, tmpdir_base, prefix, comp_type, comp_level, comp_opts, format='tar'): -======= -def git_archive_submodules(repo, treeish, output, prefix, comp_type, comp_level, - comp_opts, format='tar'): ->>>>>>> e6cea4d... common/buildpackage: support for different archive formats """ Create a source tree archive with submodules. @@ -89,11 +84,7 @@ def git_archive_submodules(repo, treeish, output, prefix, comp_type, comp_level, Exception handling is left to the caller. """ prefix = sanitize_prefix(prefix) -<<<<<<< HEAD tempdir = tempfile.mkdtemp(dir=tmpdir_base, prefix='git-archive_') -======= - tempdir = tempfile.mkdtemp() ->>>>>>> e6cea4d... common/buildpackage: support for different archive formats main_archive = os.path.join(tempdir, "main.%s" % format) submodule_archive = os.path.join(tempdir, "submodule.%s" % format) try: @@ -107,13 +98,8 @@ def git_archive_submodules(repo, treeish, output, prefix, comp_type, comp_level, subrepo = GitRepository(os.path.join(repo.path, subdir)) gbp.log.debug("Processing submodule %s (%s)" % (subdir, commit[0:8])) -<<<<<<< HEAD subrepo.archive(format=format, prefix='%s%s/' % (prefix, tarpath), output=submodule_archive, treeish=commit) -======= - repo.archive(format=format, prefix='%s%s/' % (prefix, tarpath), - output=submodule_archive, treeish=commit, cwd=subdir) ->>>>>>> e6cea4d... common/buildpackage: support for different archive formats if format == 'tar': CatenateTarArchive(main_archive)(submodule_archive) elif format == 'zip': @@ -121,33 +107,22 @@ def git_archive_submodules(repo, treeish, output, prefix, comp_type, comp_level, # compress the output if comp_type: -<<<<<<< HEAD compress(comp_type, ['--stdout', '-%s' % comp_level] + comp_opts + [main_archive], output) -======= - ret = os.system("%s --stdout -%s %s %s > %s" % (comp_type, comp_level, comp_opts, main_archive, output)) - if ret: - raise GbpError("Error creating %s: %d" % (output, ret)) ->>>>>>> e6cea4d... common/buildpackage: support for different archive formats else: shutil.move(main_archive, output) finally: shutil.rmtree(tempdir) -<<<<<<< HEAD def git_archive_single(repo, treeish, output, prefix, comp_type, comp_level, comp_opts, format='tar'): -======= -def git_archive_single(treeish, output, prefix, comp_type, comp_level, comp_opts, format='tar'): ->>>>>>> e6cea4d... common/buildpackage: support for different archive formats """ Create an archive without submodules Exception handling is left to the caller. """ prefix = sanitize_prefix(prefix) -<<<<<<< HEAD if comp_type: cmd = comp_type opts = ['--stdout', '-%s' % comp_level] + comp_opts @@ -166,15 +141,6 @@ def untar_data(outdir, data): popen.stdin.close() if popen.wait(): raise GbpError("Error extracting tar to %s" % outdir) -======= - pipe = pipes.Template() - pipe.prepend("git archive --format=%s --prefix=%s %s" % (format, prefix, treeish), '.-') - if comp_type: - pipe.append('%s -c -%s %s' % (comp_type, comp_level, comp_opts), '--') - ret = pipe.copy('', output) - if ret: - raise GbpError("Error creating %s: %d" % (output, ret)) ->>>>>>> e6cea4d... common/buildpackage: support for different archive formats #{ Functions to handle export-dir -- cgit v1.2.3 From 776d37c2d95da3cd992892b22e16bc117653cfd9 Mon Sep 17 00:00:00 2001 From: Markus Lehtonen Date: Tue, 15 May 2012 18:13:43 +0300 Subject: buildpackage/git_archive_single: use GitRepository.archive() Use GitRepository.archive() method like git_archive_submodules() does. This makes it possible to call git_archive_single() independent of the callers current working directory. Signed-off-by: Markus Lehtonen Conflicts: gbp/scripts/common/buildpackage.py --- gbp/scripts/common/buildpackage.py | 2 ++ 1 file changed, 2 insertions(+) diff --git a/gbp/scripts/common/buildpackage.py b/gbp/scripts/common/buildpackage.py index f95837c1..c34b491e 100644 --- a/gbp/scripts/common/buildpackage.py +++ b/gbp/scripts/common/buildpackage.py @@ -19,6 +19,8 @@ """Common functionality for Debian and RPM buildpackage scripts""" import os, os.path +import pipes +import tempfile import subprocess import shutil -- cgit v1.2.3 From ababb28fc2ffd6ff781a5f9e929ca5ef14b7388f Mon Sep 17 00:00:00 2001 From: Markus Lehtonen Date: Tue, 5 Jun 2012 15:18:24 +0300 Subject: buildpackage/dump_tree: use GitRepository.archive() Make dump_tree() utilize the GitRepository.archive() method - similarly to git_archive_submodules() - instead of ad-hoc Python pipes. This makes dump_tree() work independent of the callers current working directory. Signed-off-by: Markus Lehtonen Conflicts: gbp/scripts/common/buildpackage.py --- gbp/scripts/common/buildpackage.py | 13 +++---------- 1 file changed, 3 insertions(+), 10 deletions(-) diff --git a/gbp/scripts/common/buildpackage.py b/gbp/scripts/common/buildpackage.py index c34b491e..c2752929 100644 --- a/gbp/scripts/common/buildpackage.py +++ b/gbp/scripts/common/buildpackage.py @@ -19,7 +19,6 @@ """Common functionality for Debian and RPM buildpackage scripts""" import os, os.path -import pipes import tempfile import subprocess import shutil @@ -144,21 +143,15 @@ def untar_data(outdir, data): if popen.wait(): raise GbpError("Error extracting tar to %s" % outdir) - #{ Functions to handle export-dir -def dump_tree(repo, export_dir, treeish, with_submodules, recursive=True): +def dump_tree(repo, export_dir, treeish, with_submodules): """Dump a git tree-ish to output_dir""" if not os.path.exists(export_dir): os.makedirs(export_dir) - if recursive: - paths = '' - else: - paths = [nam for _mod, typ, _sha, nam in repo.list_tree(treeish) if - typ == 'blob'] try: - data = repo.archive('tar', '', None, treeish, paths) + data = repo.archive('tar', '', None, treeish) untar_data(export_dir, data) - if recursive and with_submodules and repo.has_submodules(): + if with_submodules and repo.has_submodules(): repo.update_submodules() for (subdir, commit) in repo.get_submodules(treeish): gbp.log.info("Processing submodule %s (%s)" % (subdir, -- cgit v1.2.3 -- cgit v1.2.3 From 2069fafe81d0cad68fd71b858b10c538694ccca9 Mon Sep 17 00:00:00 2001 From: Markus Lehtonen Date: Thu, 12 Sep 2013 13:36:08 +0300 Subject: GitRepository.archive: drop the '**kwargs' argument Unused and misleading. Signed-off-by: Markus Lehtonen Conflicts: gbp/git/repository.py --- gbp/git/repository.py | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/gbp/git/repository.py b/gbp/git/repository.py index 6b21c252..5d662227 100644 --- a/gbp/git/repository.py +++ b/gbp/git/repository.py @@ -1834,7 +1834,7 @@ class GitRepository(object): return result #} - def archive(self, format, prefix, output, treeish, paths=None): + def archive(self, format, prefix, output, treeish): """ Create an archive from a treeish @@ -1847,8 +1847,6 @@ class GitRepository(object): @type output: C{str} or C{None} @param treeish: the treeish to create the archive from @type treeish: C{str} - @param paths: List of paths to include in the archive - @type paths: C{list} of C{str} @return: archive data as a generator object @rtype: C{None} or C{generator} of C{str} -- cgit v1.2.3 From 8c4c1d48f00e69f2eb40995fd2e8f8f78f7cbcd1 Mon Sep 17 00:00:00 2001 From: Markus Lehtonen Date: Tue, 17 Sep 2013 14:47:21 +0300 Subject: GitRepository.archive: add 'paths' option Signed-off-by: Markus Lehtonen --- gbp/git/repository.py | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/gbp/git/repository.py b/gbp/git/repository.py index 5d662227..6b21c252 100644 --- a/gbp/git/repository.py +++ b/gbp/git/repository.py @@ -1834,7 +1834,7 @@ class GitRepository(object): return result #} - def archive(self, format, prefix, output, treeish): + def archive(self, format, prefix, output, treeish, paths=None): """ Create an archive from a treeish @@ -1847,6 +1847,8 @@ class GitRepository(object): @type output: C{str} or C{None} @param treeish: the treeish to create the archive from @type treeish: C{str} + @param paths: List of paths to include in the archive + @type paths: C{list} of C{str} @return: archive data as a generator object @rtype: C{None} or C{generator} of C{str} -- cgit v1.2.3 From 489da2b3f119088e85ade4b02963953c6025ba80 Mon Sep 17 00:00:00 2001 From: Markus Lehtonen Date: Tue, 17 Sep 2013 15:13:40 +0300 Subject: buildpackage/dump_tree: add 'recursive' option For selecting whether to dump all the files recursively or just the top level directory of the tree. Signed-off-by: Markus Lehtonen --- gbp/scripts/common/buildpackage.py | 11 ++++++++--- 1 file changed, 8 insertions(+), 3 deletions(-) diff --git a/gbp/scripts/common/buildpackage.py b/gbp/scripts/common/buildpackage.py index c2752929..be5b5444 100644 --- a/gbp/scripts/common/buildpackage.py +++ b/gbp/scripts/common/buildpackage.py @@ -144,14 +144,19 @@ def untar_data(outdir, data): raise GbpError("Error extracting tar to %s" % outdir) #{ Functions to handle export-dir -def dump_tree(repo, export_dir, treeish, with_submodules): +def dump_tree(repo, export_dir, treeish, with_submodules, recursive=True): """Dump a git tree-ish to output_dir""" if not os.path.exists(export_dir): os.makedirs(export_dir) + if recursive: + paths = '' + else: + paths = [nam for _mod, typ, _sha, nam in repo.list_tree(treeish) if + typ == 'blob'] try: - data = repo.archive('tar', '', None, treeish) + data = repo.archive('tar', '', None, treeish, paths) untar_data(export_dir, data) - if with_submodules and repo.has_submodules(): + if recursive and with_submodules and repo.has_submodules(): repo.update_submodules() for (subdir, commit) in repo.get_submodules(treeish): gbp.log.info("Processing submodule %s (%s)" % (subdir, -- cgit v1.2.3 -- cgit v1.2.3 -- cgit v1.2.3 -- cgit v1.2.3 From 1f608ccf5b46f40e13f716e536f577de02935fcc Mon Sep 17 00:00:00 2001 From: Markus Lehtonen Date: Thu, 10 Apr 2014 11:30:06 +0300 Subject: GitRepository: implement create_tree method New method for creating tree objects from a directory content. Signed-off-by: Markus Lehtonen --- gbp/git/repository.py | 18 ++++++++++++++++++ 1 file changed, 18 insertions(+) diff --git a/gbp/git/repository.py b/gbp/git/repository.py index 6b21c252..f52f3f2b 100644 --- a/gbp/git/repository.py +++ b/gbp/git/repository.py @@ -1511,6 +1511,24 @@ class GitRepository(object): work_tree=unpack_dir) return self.write_tree(git_index_file) + def create_tree(self, unpack_dir): + """ + Create a tree object out of a directory content + + @param unpack_dir: content to add + @type unpack_dir: C{str} + @return: the tree object hash + @rtype: C{str} + """ + git_index_file = os.path.join(self.path, self._git_dir, 'gbp_index') + try: + os.unlink(git_index_file) + except OSError: + pass + self.add_files('.', force=True, index_file=git_index_file, + work_tree=unpack_dir) + return self.write_tree(git_index_file) + def commit_dir(self, unpack_dir, msg, branch, other_parents=None, author={}, committer={}, create_missing_branch=False): """ -- cgit v1.2.3 -- cgit v1.2.3 -- cgit v1.2.3 -- cgit v1.2.3 -- cgit v1.2.3 -- cgit v1.2.3 -- cgit v1.2.3 -- cgit v1.2.3 -- cgit v1.2.3 -- cgit v1.2.3 -- cgit v1.2.3 -- cgit v1.2.3 -- cgit v1.2.3 -- cgit v1.2.3 -- cgit v1.2.3 -- cgit v1.2.3 -- cgit v1.2.3 -- cgit v1.2.3 -- cgit v1.2.3 From 179d2bd909791de3b134faa96e8183bc24ecd633 Mon Sep 17 00:00:00 2001 From: Markus Lehtonen Date: Fri, 15 Jun 2012 08:43:12 +0300 Subject: import-orig: simplify repack_source() and tmpdir handling Now a tmpdir is always created and sources are always unpacked into there. Signed-off-by: Markus Lehtonen Conflicts: gbp/scripts/common/import_orig.py gbp/scripts/import_orig.py --- gbp/scripts/import_orig.py | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/gbp/scripts/import_orig.py b/gbp/scripts/import_orig.py index 553fbdef..4cf96619 100644 --- a/gbp/scripts/import_orig.py +++ b/gbp/scripts/import_orig.py @@ -311,13 +311,14 @@ def main(argv): source, pkg_name, version, prepare_pristine, options.filters, options.filter_pristine_tar, None, tmpdir) if not source.is_dir(): - tmpdir = tempfile.mkdtemp(dir='../') - source.unpack(tmpdir, options.filters) + unpack_dir = tempfile.mkdtemp(prefix='unpack', dir=tmpdir) + source.unpack(unpack_dir, options.filters) gbp.log.debug("Unpacked '%s' to '%s'" % (source.path, source.unpacked)) if orig_needs_repack(source, options): gbp.log.debug("Filter pristine-tar: repacking '%s' from '%s'" % (source.path, source.unpacked)) - (source, tmpdir) = repack_source(source, sourcepackage, version, tmpdir, options.filters) + repack_dir = tempfile.mkdtemp(prefix='repack', dir=tmpdir) + source = repack_source(source, sourcepackage, version, repack_dir, options.filters) (pristine_orig, linked) = prepare_pristine_tar(source.path, sourcepackage, -- cgit v1.2.3 From d0323a07cd9a54058815f73b3e7f9107c74b47fb Mon Sep 17 00:00:00 2001 From: Markus Lehtonen Date: Fri, 15 Jun 2012 09:00:35 +0300 Subject: import-orig: move repacked_tarball_name() out from common Moves repacked_tarball_name() from scripts/common back to the Debian-specific script. The logic is too Debian-specific for RPM, after all. Signed-off-by: Markus Lehtonen Conflicts: gbp/scripts/common/import_orig.py gbp/scripts/import_orig.py --- gbp/scripts/import_orig.py | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/gbp/scripts/import_orig.py b/gbp/scripts/import_orig.py index 4cf96619..f31126af 100644 --- a/gbp/scripts/import_orig.py +++ b/gbp/scripts/import_orig.py @@ -318,7 +318,8 @@ def main(argv): if orig_needs_repack(source, options): gbp.log.debug("Filter pristine-tar: repacking '%s' from '%s'" % (source.path, source.unpacked)) repack_dir = tempfile.mkdtemp(prefix='repack', dir=tmpdir) - source = repack_source(source, sourcepackage, version, repack_dir, options.filters) + repack_name = repacked_tarball_name(source, sourcepackage, version) + source = repack_source(source, repack_name, repack_dir, options.filters) (pristine_orig, linked) = prepare_pristine_tar(source.path, sourcepackage, -- cgit v1.2.3 From 3763ee4e3f0a3160da0c531d534b07c186a74cc0 Mon Sep 17 00:00:00 2001 From: Markus Lehtonen Date: Thu, 14 Jun 2012 19:30:26 +0300 Subject: UpstreamSource.pack: support prefix mangling Add support for changing the prefix directory inside the tarball that is generated. Also, fixes a bug that caused a "prefix-less" tarball to get one, if unpacked and then repacked. Also, adds this support to repack_source() in common/import_orig. Signed-off-by: Markus Lehtonen Conflicts: gbp/pkg/__init__.py gbp/scripts/common/import_orig.py --- gbp/pkg/__init__.py | 11 +++++++++++ gbp/scripts/common/import_orig.py | 8 ++++++++ 2 files changed, 19 insertions(+) diff --git a/gbp/pkg/__init__.py b/gbp/pkg/__init__.py index 9c54c86d..0b20a9cc 100644 --- a/gbp/pkg/__init__.py +++ b/gbp/pkg/__init__.py @@ -495,6 +495,17 @@ class UpstreamSource(object): except gbpc.CommandExecFailed: raise GbpError("Unpacking of %s failed" % self.path) + def _unpacked_toplevel(self, dir): + """unpacked archives can contain a leading directory or not""" + unpacked = glob.glob('%s/*' % dir) + unpacked.extend(glob.glob("%s/.*" % dir)) # include hidden files and folders + # Check that dir contains nothing but a single folder: + if len(unpacked) == 1 and os.path.isdir(unpacked[0]): + return unpacked[0] + else: + # We can determine "no prefix" from this + return os.path.join(dir, ".") + def _unpack_tar(self, dir, filters): """ Unpack a tarball to I{dir} applying a list of I{filters}. Leave the diff --git a/gbp/scripts/common/import_orig.py b/gbp/scripts/common/import_orig.py index 3d01f9e9..576c7e5a 100644 --- a/gbp/scripts/common/import_orig.py +++ b/gbp/scripts/common/import_orig.py @@ -222,4 +222,12 @@ def prepare_sources(source, pkg_name, pkg_version, pristine_commit_name, tmpdir) pristine_path = pristine.path if pristine else '' return (filtered.unpacked, pristine_path) +def repack_source(source, new_name, unpack_dir, filters, new_prefix=None): + """Repack the source tree""" + repacked = source.pack(new_name, filters, new_prefix) + if source.is_orig(): # the tarball was filtered on unpack + repacked.unpacked = source.unpacked + else: # otherwise unpack the generated tarball get a filtered tree + repacked.unpack(unpack_dir, filters) + return repacked -- cgit v1.2.3 -- cgit v1.2.3 From 2b9e38b61bbc89d43c1241b930f77e4b485be64f Mon Sep 17 00:00:00 2001 From: Markus Lehtonen Date: Mon, 9 Jul 2012 17:16:21 +0300 Subject: UpstreamSource: add 'archive_fmt' and 'compression' properties New properties for easily getting the archive format (tar, zip, ...) and compression format (gzip, bzip2, ...) of the sources. Signed-off-by: Markus Lehtonen Conflicts: gbp/pkg/__init__.py --- gbp/pkg/__init__.py | 14 ++++++++++++++ 1 file changed, 14 insertions(+) diff --git a/gbp/pkg/__init__.py b/gbp/pkg/__init__.py index 0b20a9cc..2ed43d09 100644 --- a/gbp/pkg/__init__.py +++ b/gbp/pkg/__init__.py @@ -441,11 +441,25 @@ class UpstreamSource(object): @property def archive_fmt(self): """Archive format of the sources, e.g. 'tar'""" + """ + >>> UpstreamSource('foo/bar.tar.gz').archive_fmt + 'tar' + >>> UpstreamSource('foo.bar.zip').archive_fmt + 'zip' + >>> UpstreamSource('foo.bar.baz').archive_fmt + """ return self._archive_fmt @property def compression(self): """Compression format of the sources, e.g. 'gzip'""" + """ + >>> UpstreamSource('foo/bar.tar.gz').compression + 'gzip' + >>> UpstreamSource('foo.bar.zip').compression + >>> UpstreamSource('foo.bz2').compression + 'bzip2' + """ return self._compression @property -- cgit v1.2.3 From a6b97e34129efe6ae802af2019870352a8bdc93c Mon Sep 17 00:00:00 2001 From: Markus Lehtonen Date: Mon, 9 Jul 2012 17:19:27 +0300 Subject: UpstreamSource: introduce is_tarball() method New method for checking if the sources are a tarball (possibly for checking if the sources are committable by pristine-tar). Signed-off-by: Markus Lehtonen --- gbp/scripts/common/import_orig.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/gbp/scripts/common/import_orig.py b/gbp/scripts/common/import_orig.py index 576c7e5a..42c3d24d 100644 --- a/gbp/scripts/common/import_orig.py +++ b/gbp/scripts/common/import_orig.py @@ -47,7 +47,7 @@ def orig_needs_repack(upstream_source, options): """ if ((options.pristine_tar and options.filter_pristine_tar and len(options.filters) > 0)): return True - elif not upstream_source.is_orig(): + elif not upstream_source.is_tarball(): if len(options.filters): return True elif options.pristine_tar: @@ -225,7 +225,7 @@ def prepare_sources(source, pkg_name, pkg_version, pristine_commit_name, def repack_source(source, new_name, unpack_dir, filters, new_prefix=None): """Repack the source tree""" repacked = source.pack(new_name, filters, new_prefix) - if source.is_orig(): # the tarball was filtered on unpack + if source.is_tarball(): # the tarball was filtered on unpack repacked.unpacked = source.unpacked else: # otherwise unpack the generated tarball get a filtered tree repacked.unpack(unpack_dir, filters) -- cgit v1.2.3 -- cgit v1.2.3 -- cgit v1.2.3 -- cgit v1.2.3 -- cgit v1.2.3 From 6ce67cabbe2c379647acadd8c5105c76176023b5 Mon Sep 17 00:00:00 2001 From: Markus Lehtonen Date: Thu, 22 Aug 2013 16:24:13 +0300 Subject: UpstreamSource: implement prefix guessing MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Add a new attribure 'prefix', i.e. the "leading directory name" in an archive. For example, this usually is '-' in release tarballs. Signed-off-by: Markus Lehtonen Signed-off-by: Łukasz Stelmach Conflicts: gbp/pkg/__init__.py --- gbp/pkg/__init__.py | 11 ----------- 1 file changed, 11 deletions(-) diff --git a/gbp/pkg/__init__.py b/gbp/pkg/__init__.py index 2ed43d09..79067982 100644 --- a/gbp/pkg/__init__.py +++ b/gbp/pkg/__init__.py @@ -509,17 +509,6 @@ class UpstreamSource(object): except gbpc.CommandExecFailed: raise GbpError("Unpacking of %s failed" % self.path) - def _unpacked_toplevel(self, dir): - """unpacked archives can contain a leading directory or not""" - unpacked = glob.glob('%s/*' % dir) - unpacked.extend(glob.glob("%s/.*" % dir)) # include hidden files and folders - # Check that dir contains nothing but a single folder: - if len(unpacked) == 1 and os.path.isdir(unpacked[0]): - return unpacked[0] - else: - # We can determine "no prefix" from this - return os.path.join(dir, ".") - def _unpack_tar(self, dir, filters): """ Unpack a tarball to I{dir} applying a list of I{filters}. Leave the -- cgit v1.2.3 -- cgit v1.2.3 From 822c929448bf41341d9422d1afe065a70e12460e Mon Sep 17 00:00:00 2001 From: Markus Lehtonen Date: Thu, 6 Jun 2013 15:19:37 +0300 Subject: UpstreamSource.unpack: return UpstreamSource instance Trying to keep UpstreamSource in consistent state so that unpacked and packed sources are kept in sync. Signed-off-by: Markus Lehtonen Conflicts: gbp/scripts/import_srpm.py --- gbp/scripts/common/import_orig.py | 2 +- gbp/scripts/import_orig.py | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/gbp/scripts/common/import_orig.py b/gbp/scripts/common/import_orig.py index 42c3d24d..177ec324 100644 --- a/gbp/scripts/common/import_orig.py +++ b/gbp/scripts/common/import_orig.py @@ -228,6 +228,6 @@ def repack_source(source, new_name, unpack_dir, filters, new_prefix=None): if source.is_tarball(): # the tarball was filtered on unpack repacked.unpacked = source.unpacked else: # otherwise unpack the generated tarball get a filtered tree - repacked.unpack(unpack_dir, filters) + repacked.unpack(unpack_dir) return repacked diff --git a/gbp/scripts/import_orig.py b/gbp/scripts/import_orig.py index f31126af..fa6b2cba 100644 --- a/gbp/scripts/import_orig.py +++ b/gbp/scripts/import_orig.py @@ -312,7 +312,7 @@ def main(argv): options.filter_pristine_tar, None, tmpdir) if not source.is_dir(): unpack_dir = tempfile.mkdtemp(prefix='unpack', dir=tmpdir) - source.unpack(unpack_dir, options.filters) + source = source.unpack(unpack_dir, options.filters) gbp.log.debug("Unpacked '%s' to '%s'" % (source.path, source.unpacked)) if orig_needs_repack(source, options): -- cgit v1.2.3 From 80f83e1f066f7b98701dc40f0f068363bd724422 Mon Sep 17 00:00:00 2001 From: Markus Lehtonen Date: Mon, 26 Aug 2013 10:22:00 +0300 Subject: import-orig: new function for filtering/re-packing sources Introduces a new function prepare_sources() that prepares upstream sources for importing into upstream branch and pristine-tar. That includes unpacking, filtering and re-packing sources. What somewhat complicates the logic is that it tries to avoid excess unpacking/packing of the sources. Also fixes the unpacking / filtering / repacking logic which was broken with some parameter combinations. Signed-off-by: Markus Lehtonen Conflicts: tests/test_import_orig.py tests/testutils.py --- gbp/scripts/common/import_orig.py | 123 ++++++++++++++++++++++++++++++++++++++ 1 file changed, 123 insertions(+) diff --git a/gbp/scripts/common/import_orig.py b/gbp/scripts/common/import_orig.py index 177ec324..8eaf3904 100644 --- a/gbp/scripts/common/import_orig.py +++ b/gbp/scripts/common/import_orig.py @@ -231,3 +231,126 @@ def repack_source(source, new_name, unpack_dir, filters, new_prefix=None): repacked.unpack(unpack_dir) return repacked + +def prepare_pristine_tar(source, pkg_name, pkg_version, pristine_commit_name, + filters=None, prefix=None, tmpdir=None): + """ + Prepare the upstream sources for pristine-tar import + + @param source: original upstream sources + @type source: C{UpstreamSource} + @param pkg_name: package name + @type pkg_name: C{str} + @param pkg_version: upstream version of the package + @type pkg_version: C{str} + @param pristine_commit_name: archive filename to commit to pristine-tar + @type pristine_commit_name: C{str} or C{None} + @param filters: filter to exclude files + @type filters: C{list} of C{str} or C{None} + @param prefix: prefix (i.e. leading directory of files) to use in + pristine-tar, set to C{None} to not mangle orig archive + @type prefix: C{str} or C{None} + @param tmpdir: temporary working dir (cleanup left to caller) + @type tmpdir: C{str} + @return: prepared source archive + @rtype: C{UpstreamSource} + """ + need_repack = False + if source.is_dir(): + if prefix is None: + prefix = '%s-%s' % (pkg_name, pkg_version) + gbp.log.info("Using guessed prefix '%s/' for pristine-tar" % prefix) + need_repack = True + else: + if prefix is not None and prefix == source.prefix: + prefix = None + comp = parse_archive_filename(pristine_commit_name)[2] + if filters or prefix is not None or source.compression != comp: + if not source.unpacked: + unpack_dir = tempfile.mkdtemp(prefix='pristine_unpack_', + dir=tmpdir) + source.unpack(unpack_dir) + need_repack = True + pristine_path = os.path.join(tmpdir, pristine_commit_name) + if need_repack: + gbp.log.debug("Packing '%s' from '%s' for pristine-tar" % + (pristine_path, source.unpacked)) + pristine = source.pack(pristine_path, filters, prefix) + else: + # Just create symlink for mangling the pristine tarball name + os.symlink(source.path, pristine_path) + pristine = source.__class__(pristine_path) + + return pristine + + +def prepare_sources(source, pkg_name, pkg_version, pristine_commit_name, + filters, filter_pristine, prefix, tmpdir): + """ + Prepare upstream sources for importing + + Unpack, filter and repack sources for importing to git and to pristine-tar. + + @param source: original upstream sources + @type source: C{UpstreamSource} + @param pkg_name: package name + @type pkg_name: C{str} + @param pkg_version: upstream version of the package + @type pkg_version: C{str} + @param pristine_commit_name: archive filename to commit to pristine-tar + @type pristine_commit_name: C{str} or C{None} + @param filters: filter to exclude files + @type filters: C{list} of C{str} + @param filter_pristine: filter pristine-tar, too + @type filter_pristine: C{bool} + @param prefix: prefix (i.e. leading directory of files) to use in + pristine-tar, set to C{None} to not mangle orig archive + @type prefix: C{str} or C{None} + @param tmpdir: temporary working dir (cleanup left to caller) + @type tmpdir: C{str} + @return: path to prepared source tree and tarball to commit to pristine-tar + @rtype: C{tuple} of C{str} + """ + pristine = None + # Determine parameters for pristine tar + pristine_filters = filters if filters and filter_pristine else None + pristine_prefix = None + if prefix is not None and prefix != 'auto': + prefix_subst = {'name': pkg_name, + 'version': pkg_version, + 'upstreamversion': pkg_version} + pristine_prefix = prefix % prefix_subst + # Handle unpacked sources, i.e. importing a directory + if source.is_dir(): + if pristine_commit_name: + gbp.log.warn('Preparing unpacked sources for pristine-tar') + pristine = prepare_pristine_tar(source, pkg_name, pkg_version, + pristine_commit_name, + pristine_filters, pristine_prefix, + tmpdir) + if filters: + # Re-use sources packed for pristine-tar, if available + if pristine: + packed = pristine + else: + packed_fn = tempfile.mkstemp(prefix="packed_", dir=tmpdir, + suffix='.tar')[1] + gbp.log.debug("Packing '%s' to '%s'" % (source.path, packed_fn)) + packed = source.pack(packed_fn) + unpack_dir = tempfile.mkdtemp(prefix='filtered_', dir=tmpdir) + filtered = packed.unpack(unpack_dir, filters) + else: + filtered = source + # Handle source archives + else: + unpack_dir = tempfile.mkdtemp(prefix='filtered_', dir=tmpdir) + gbp.log.debug("Unpacking '%s' to '%s'" % (source.path, unpack_dir)) + filtered = source.unpack(unpack_dir, filters) + if pristine_commit_name: + pristine = prepare_pristine_tar(source, pkg_name, pkg_version, + pristine_commit_name, + pristine_filters, pristine_prefix, + tmpdir) + pristine_path = pristine.path if pristine else '' + return (filtered.unpacked, pristine_path) + -- cgit v1.2.3 From 7857202d44ae68f39516ca4c45982b6e5438a87c Mon Sep 17 00:00:00 2001 From: Markus Lehtonen Date: Wed, 14 Nov 2012 09:03:37 +0200 Subject: import-orig: rework sourcecode preparation and filtering Take in to use the newly added prepare_sources() function. Drop dead, unneeded code. Signed-off-by: Markus Lehtonen Conflicts: gbp/scripts/common/import_orig.py gbp/scripts/import_orig.py --- gbp/scripts/common/import_orig.py | 22 ---------------------- gbp/scripts/import_orig.py | 1 - 2 files changed, 23 deletions(-) diff --git a/gbp/scripts/common/import_orig.py b/gbp/scripts/common/import_orig.py index 8eaf3904..304dfd77 100644 --- a/gbp/scripts/common/import_orig.py +++ b/gbp/scripts/common/import_orig.py @@ -33,28 +33,6 @@ except ImportError: pass -def orig_needs_repack(upstream_source, options): - """ - Determine if the upstream sources needs to be repacked - - We repack if - 1. we want to filter out files and use pristine tar since we want - to make a filtered tarball available to pristine-tar - 2. when we don't have a suitable upstream tarball (e.g. zip archive or unpacked dir) - and want to use filters - 3. when we don't have a suitable upstream tarball (e.g. zip archive or unpacked dir) - and want to use pristine-tar - """ - if ((options.pristine_tar and options.filter_pristine_tar and len(options.filters) > 0)): - return True - elif not upstream_source.is_tarball(): - if len(options.filters): - return True - elif options.pristine_tar: - return True - return False - - def cleanup_tmp_tree(tree): """remove a tree of temporary files""" try: diff --git a/gbp/scripts/import_orig.py b/gbp/scripts/import_orig.py index fa6b2cba..6ec50021 100644 --- a/gbp/scripts/import_orig.py +++ b/gbp/scripts/import_orig.py @@ -74,7 +74,6 @@ def prepare_pristine_tar(archive, pkg, version): return (link, linked) else: return (archive, linked) ->>>>>>> dbfc6276c4aa50b79f1cf27cfc24badc0b18da8f def upstream_import_commit_msg(options, version): -- cgit v1.2.3 -- cgit v1.2.3 -- cgit v1.2.3 -- cgit v1.2.3 -- cgit v1.2.3 -- cgit v1.2.3 -- cgit v1.2.3 -- cgit v1.2.3 -- cgit v1.2.3 -- cgit v1.2.3 From 6cd371d08785515014669ca2bb353940ee4122bb Mon Sep 17 00:00:00 2001 From: Markus Lehtonen Date: Thu, 12 Jul 2012 09:07:47 +0300 Subject: Universal configurable base tmpdir for all gbp tools Adds support for a configurable tmpdir under which all gbp tools now create their temporary directories and files. NOTE: an exception is git-import-dscs which doesn't use the common configuration system. Signed-off-by: Markus Lehtonen Conflicts: gbp/scripts/common/buildpackage.py --- gbp/config.py | 4 ++++ gbp/scripts/common/buildpackage.py | 1 - gbp/scripts/pq.py | 1 + 3 files changed, 5 insertions(+), 1 deletion(-) diff --git a/gbp/config.py b/gbp/config.py index 40d52a83..cf25de84 100644 --- a/gbp/config.py +++ b/gbp/config.py @@ -163,6 +163,7 @@ class GbpOptionParser(OptionParser): 'tmp-dir' : '/var/tmp/gbp/', 'drop': 'False', 'commit': 'False', + 'tmp-dir' : '/var/tmp/gbp/', } help = { 'debian-branch': @@ -318,6 +319,9 @@ class GbpOptionParser(OptionParser): "after export. Default is '%(drop)s'"), 'commit': "commit changes after export, Default is '%(commit)s'", + 'tmp-dir': + ("Base directory under which temporary directories are " + "created, default is '%(tmp-dir)s'"), } def_config_files = [ '/etc/git-buildpackage/gbp.conf', diff --git a/gbp/scripts/common/buildpackage.py b/gbp/scripts/common/buildpackage.py index be5b5444..d089df5a 100644 --- a/gbp/scripts/common/buildpackage.py +++ b/gbp/scripts/common/buildpackage.py @@ -19,7 +19,6 @@ """Common functionality for Debian and RPM buildpackage scripts""" import os, os.path -import tempfile import subprocess import shutil diff --git a/gbp/scripts/pq.py b/gbp/scripts/pq.py index af112917..70adf6e9 100755 --- a/gbp/scripts/pq.py +++ b/gbp/scripts/pq.py @@ -344,6 +344,7 @@ def build_parser(name): dest="color_scheme") parser.add_config_file_option(option_name="tmp-dir", dest="tmp_dir") parser.add_config_file_option(option_name="meta-closes", dest="meta_closes") + parser.add_config_file_option(option_name="tmp-dir", dest="tmp_dir") return parser -- cgit v1.2.3 From 90f242f72805074b9e7d2c8980c5da27eaa7f1e5 Mon Sep 17 00:00:00 2001 From: Markus Lehtonen Date: Fri, 11 May 2012 10:56:17 +0300 Subject: gbp-pq: readiness to configure the pq branch name All other gbp branches have configurable names. This commit adds the readiness for user to configure/change the name of the patch-queue branches, as well. Patch-queue is defined in options as a format string, where '%(branch)s' refers to the debian/packaging branch. If the pq-branch format string does not contain '%(branch)s', there is only one patch-queue branch and the debian/packaging branch is used as its base branch. That is, e.g. a 'gbp-pq switch' operation from the patch-queue branch always switches to the debian/packaging branch. Signed-off-by: Markus Lehtonen Signed-off-by: Olev Kartau Conflicts: gbp/scripts/common/pq.py --- gbp/scripts/common/pq.py | 22 ++++++++++++++++++++++ gbp/scripts/pq.py | 2 +- tests/13_test_gbp_pq.py | 2 +- 3 files changed, 24 insertions(+), 2 deletions(-) diff --git a/gbp/scripts/common/pq.py b/gbp/scripts/common/pq.py index a91ec8e9..c2bc629e 100644 --- a/gbp/scripts/common/pq.py +++ b/gbp/scripts/common/pq.py @@ -88,6 +88,10 @@ def is_pq_branch(branch, options): return True return False + pq_re = re.compile(r'^%s$' % (pq_format_str % dict(branch="(?P\S+)"))) + if pq_re.match(branch): + return True + return False def pq_branch_name(branch, options, extra_keys=None): """ @@ -116,6 +120,8 @@ def pq_branch_name(branch, options, extra_keys=None): if not is_pq_branch(branch, options): return pq_format_str % format_fields + if not is_pq_branch(branch, options): + return pq_format_str % dict(branch=branch) def pq_branch_base(pq_branch, options): """ @@ -331,7 +337,11 @@ def get_maintainer_from_control(repo): return GitModifier() +<<<<<<< HEAD def switch_to_pq_branch(repo, branch, options, name_keys=None): +======= +def switch_to_pq_branch(repo, branch, options): +>>>>>>> 3ba82da... gbp-pq: readiness to configure the pq branch name """ Switch to patch-queue branch if not already there, create it if it doesn't exist yet @@ -339,7 +349,11 @@ def switch_to_pq_branch(repo, branch, options, name_keys=None): if is_pq_branch(branch, options): return +<<<<<<< HEAD pq_branch = pq_branch_name(branch, options, name_keys) +======= + pq_branch = pq_branch_name(branch, options) +>>>>>>> 3ba82da... gbp-pq: readiness to configure the pq branch name if not repo.has_branch(pq_branch): try: repo.create_branch(pq_branch) @@ -382,12 +396,20 @@ def apply_and_commit_patch(repo, patch, fallback_author, topic=None): repo.update_ref('HEAD', commit, msg="gbp-pq import %s" % patch.path) +<<<<<<< HEAD def drop_pq(repo, branch, options, name_keys=None): +======= +def drop_pq(repo, branch, options): +>>>>>>> 3ba82da... gbp-pq: readiness to configure the pq branch name if is_pq_branch(branch, options): gbp.log.err("On a patch-queue branch, can't drop it.") raise GbpError else: +<<<<<<< HEAD pq_branch = pq_branch_name(branch, options, name_keys) +======= + pq_branch = pq_branch_name(branch, options) +>>>>>>> 3ba82da... gbp-pq: readiness to configure the pq branch name if repo.has_branch(pq_branch): repo.delete_branch(pq_branch) diff --git a/gbp/scripts/pq.py b/gbp/scripts/pq.py index 70adf6e9..02b74e75 100755 --- a/gbp/scripts/pq.py +++ b/gbp/scripts/pq.py @@ -193,7 +193,7 @@ def export_patches(repo, branch, options): gbp.log.info("No patches on '%s' - nothing to do." % pq_branch) if options.drop: - drop_pq(repo, branch) + drop_pq(repo, branch, options) def safe_patches(series, tmpdir_base): diff --git a/tests/13_test_gbp_pq.py b/tests/13_test_gbp_pq.py index 87bcd796..f71c5420 100644 --- a/tests/13_test_gbp_pq.py +++ b/tests/13_test_gbp_pq.py @@ -151,7 +151,7 @@ class TestExport(testutils.DebianGitTestRepo): repo = self.repo start = repo.get_branch() pq = os.path.join('patch-queue', start) - switch_pq(repo, start) + switch_pq(repo, start, TestExport.Options) self.assertEqual(repo.get_branch(), pq) export_patches(repo, pq, TestExport.Options) self.assertEqual(repo.get_branch(), start) -- cgit v1.2.3 From fbcab811f1736b9286b50ade99d4dba3f9dd40fc Mon Sep 17 00:00:00 2001 From: Markus Lehtonen Date: Fri, 6 Sep 2013 14:23:03 +0300 Subject: common/pq: support more flexible pq-branch naming Now any string fields (e.g. '%(version)s') can be used in the pq-branch format strings - in addition to the '%(branch)s' supported before. Signed-off-by: Markus Lehtonen Conflicts: gbp/scripts/common/pq.py --- gbp/scripts/common/pq.py | 18 +----------------- 1 file changed, 1 insertion(+), 17 deletions(-) diff --git a/gbp/scripts/common/pq.py b/gbp/scripts/common/pq.py index c2bc629e..16868845 100644 --- a/gbp/scripts/common/pq.py +++ b/gbp/scripts/common/pq.py @@ -121,7 +121,7 @@ def pq_branch_name(branch, options, extra_keys=None): return pq_format_str % format_fields if not is_pq_branch(branch, options): - return pq_format_str % dict(branch=branch) + return pq_format_str % format_fields def pq_branch_base(pq_branch, options): """ @@ -337,11 +337,7 @@ def get_maintainer_from_control(repo): return GitModifier() -<<<<<<< HEAD def switch_to_pq_branch(repo, branch, options, name_keys=None): -======= -def switch_to_pq_branch(repo, branch, options): ->>>>>>> 3ba82da... gbp-pq: readiness to configure the pq branch name """ Switch to patch-queue branch if not already there, create it if it doesn't exist yet @@ -349,11 +345,7 @@ def switch_to_pq_branch(repo, branch, options): if is_pq_branch(branch, options): return -<<<<<<< HEAD pq_branch = pq_branch_name(branch, options, name_keys) -======= - pq_branch = pq_branch_name(branch, options) ->>>>>>> 3ba82da... gbp-pq: readiness to configure the pq branch name if not repo.has_branch(pq_branch): try: repo.create_branch(pq_branch) @@ -396,20 +388,12 @@ def apply_and_commit_patch(repo, patch, fallback_author, topic=None): repo.update_ref('HEAD', commit, msg="gbp-pq import %s" % patch.path) -<<<<<<< HEAD def drop_pq(repo, branch, options, name_keys=None): -======= -def drop_pq(repo, branch, options): ->>>>>>> 3ba82da... gbp-pq: readiness to configure the pq branch name if is_pq_branch(branch, options): gbp.log.err("On a patch-queue branch, can't drop it.") raise GbpError else: -<<<<<<< HEAD pq_branch = pq_branch_name(branch, options, name_keys) -======= - pq_branch = pq_branch_name(branch, options) ->>>>>>> 3ba82da... gbp-pq: readiness to configure the pq branch name if repo.has_branch(pq_branch): repo.delete_branch(pq_branch) -- cgit v1.2.3 From 3d0453b3a90d45275fb5c174b72c1ab6ff0d8278 Mon Sep 17 00:00:00 2001 From: Markus Lehtonen Date: Tue, 15 Jan 2013 16:28:24 +0200 Subject: gbp-pull: implement --all cmdline option This updates all remote-tracking branches (for the remote that is fetched from) whose local branch name is identical to the remote branch name. Signed-off-by: Markus Lehtonen Conflicts: docs/manpages/gbp-pull.sgml gbp/scripts/pull.py --- docs/manpages/gbp-pull.sgml | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/docs/manpages/gbp-pull.sgml b/docs/manpages/gbp-pull.sgml index 74ff37ce..775472bd 100644 --- a/docs/manpages/gbp-pull.sgml +++ b/docs/manpages/gbp-pull.sgml @@ -68,6 +68,13 @@ remote repository. + + + + Update all remote-tracking branches that have identical name in the + remote repository. + + -- cgit v1.2.3 -- cgit v1.2.3 -- cgit v1.2.3 -- cgit v1.2.3 -- cgit v1.2.3 From aa827afe18b2c48bc805c4c4d68a1c9bec17ec6b Mon Sep 17 00:00:00 2001 From: Markus Lehtonen Date: Thu, 12 Jan 2012 15:35:49 +0200 Subject: Rename internal var debian_tag -> packaging_tag This is done in sake of more general purpose naming, intended for enabling rpm support: to allow logical naming for rpm and to share as much code between debian and rpm tools as possible. Signed-off-by: Markus Lehtonen --- gbp/scripts/buildpackage.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/gbp/scripts/buildpackage.py b/gbp/scripts/buildpackage.py index 484bec04..cef0584f 100755 --- a/gbp/scripts/buildpackage.py +++ b/gbp/scripts/buildpackage.py @@ -415,7 +415,7 @@ def build_parser(name, prefix=None): help="don't fail if the tag already exists") tag_group.add_boolean_config_file_option(option_name="sign-tags", dest="sign_tags") tag_group.add_config_file_option(option_name="keyid", dest="keyid") - tag_group.add_config_file_option(option_name="debian-tag", dest="debian_tag") + tag_group.add_config_file_option(option_name="debian-tag", dest="packaging_tag") tag_group.add_config_file_option(option_name="debian-tag-msg", dest="debian_tag_msg") tag_group.add_config_file_option(option_name="upstream-tag", dest="upstream_tag") orig_group.add_config_file_option(option_name="upstream-tree", dest="upstream_tree") -- cgit v1.2.3 From efb2566d0322f7305c302c42ac1f9b24d00e0bc8 Mon Sep 17 00:00:00 2001 From: Markus Lehtonen Date: Thu, 12 Jan 2012 15:38:29 +0200 Subject: Introduce gbp-pq-rpm tool Initial version of gbp-pq-rpm: a tool for managing patch queues for rpm packages. Signed-off-by: Markus Lehtonen Signed-off-by: Olev Kartau Conflicts: gbp/config.py gbp/scripts/pq_rpm.py tests/01_test_help.py --- gbp/config.py | 1 - gbp/scripts/pq_rpm.py | 4 ---- 2 files changed, 5 deletions(-) diff --git a/gbp/config.py b/gbp/config.py index cf25de84..225ae65c 100644 --- a/gbp/config.py +++ b/gbp/config.py @@ -593,7 +593,6 @@ class GbpOptionParserRpm(GbpOptionParser): Handles commandline options and parsing of config files for rpm tools """ defaults = dict(GbpOptionParser.defaults) -<<<<<<< HEAD defaults.update( { 'vendor' : 'vendor', 'native' : 'auto', diff --git a/gbp/scripts/pq_rpm.py b/gbp/scripts/pq_rpm.py index 6380ee22..ac0d4f48 100755 --- a/gbp/scripts/pq_rpm.py +++ b/gbp/scripts/pq_rpm.py @@ -608,10 +608,6 @@ def main(argv): try: parser = GbpOptionParserRpm(command=os.path.basename(argv[0]), prefix='', usage=USAGE_STRING) - except ConfigParser.ParsingError as err: - gbp.log.err('Invalid config file: %s' % err) - return 1 - parser.add_boolean_config_file_option(option_name="patch-numbers", dest="patch_numbers") parser.add_option("-v", "--verbose", action="store_true", dest="verbose", -- cgit v1.2.3 From 723a92ce3016214172e50228f6770d16000cb954 Mon Sep 17 00:00:00 2001 From: Markus Lehtonen Date: Thu, 12 Jan 2012 15:44:43 +0200 Subject: gbp-pq-rpm: add 'export-rev' option This option allows generating patches from any git tree-ish (instead of the default that is HEAD of patch-queue branch). Signed-off-by: Markus Lehtonen Conflicts: gbp/scripts/pq_rpm.py --- gbp/scripts/pq_rpm.py | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/gbp/scripts/pq_rpm.py b/gbp/scripts/pq_rpm.py index ac0d4f48..06348b18 100755 --- a/gbp/scripts/pq_rpm.py +++ b/gbp/scripts/pq_rpm.py @@ -269,6 +269,8 @@ def export_patches(repo, options): upstream_commit = find_upstream_commit(repo, spec, options.upstream_tag) export_treeish = options.export_rev if options.export_rev else pq_branch + if not repo.has_treeish(export_treeish): + raise GbpError('Invalid treeish object %s' % export_treeish) update_patch_series(repo, spec, upstream_commit, export_treeish, options) @@ -655,6 +657,9 @@ def main(argv): dest="patch_export_squash_until") parser.add_config_file_option("patch-export-ignore-path", dest="patch_export_ignore_path") + parser.add_option("--export-rev", action="store", dest="export_rev", default="", + help="Export patches from treeish object TREEISH instead " + "of head of patch-queue branch", metavar="TREEISH") (options, args) = parser.parse_args(argv) gbp.log.setup(options.color, options.verbose, options.color_scheme) -- cgit v1.2.3 From 3c92e4edd80387294686f9351bfe43a6e6c72c98 Mon Sep 17 00:00:00 2001 From: Markus Lehtonen Date: Fri, 11 May 2012 11:29:24 +0300 Subject: pq-rpm: add new --pq-branch option Adds a new command line option '--pq-branch' to set the name of patch-queue branches. Changes the defaults pq-branch name for rpm tools to 'development/%(branch)s' (instead of the old 'patch-queue/%(branch)s'). Signed-off-by: Markus Lehtonen Conflicts: gbp/config.py gbp/scripts/pq_rpm.py --- gbp/scripts/pq_rpm.py | 1 + 1 file changed, 1 insertion(+) diff --git a/gbp/scripts/pq_rpm.py b/gbp/scripts/pq_rpm.py index 06348b18..f0e75749 100755 --- a/gbp/scripts/pq_rpm.py +++ b/gbp/scripts/pq_rpm.py @@ -627,6 +627,7 @@ def main(argv): parser.add_config_file_option(option_name="upstream-tag", dest="upstream_tag") parser.add_config_file_option(option_name="spec-file", dest="spec_file") +<<<<<<< HEAD parser.add_config_file_option(option_name="packaging-dir", dest="packaging_dir") parser.add_option("--new-packaging-dir", -- cgit v1.2.3 From 2d024bc03f8b8ab31bc477093e417d3d7a63e208 Mon Sep 17 00:00:00 2001 From: Markus Lehtonen Date: Wed, 8 May 2013 20:42:45 +0300 Subject: pq-rpm: support patch-export up to an arbitrary tree-ish If the end of the export range is not a commit "normal" patches are generated up to HEAD and finally a raw diff between HEAD and the end-tree-is generated. Signed-off-by: Markus Lehtonen Conflicts: gbp/scripts/pq_rpm.py --- gbp/scripts/pq_rpm.py | 13 +++++++++++++ 1 file changed, 13 insertions(+) diff --git a/gbp/scripts/pq_rpm.py b/gbp/scripts/pq_rpm.py index f0e75749..09ee9bc0 100755 --- a/gbp/scripts/pq_rpm.py +++ b/gbp/scripts/pq_rpm.py @@ -149,6 +149,19 @@ def generate_patches(repo, start, squash, end, outdir, options): start = merge_sha1 print start + try: + end_commit = end + end_commit_sha1 = repo.rev_parse("%s^0" % end_commit) + except GitRepositoryError: + # In case of plain tree-ish objects, assume current branch head is the + # last commit + end_commit = "HEAD" + end_commit_sha1 = repo.rev_parse("%s^0" % end_commit) + + start_sha1 = repo.rev_parse("%s^0" % start) + if repo.get_merge_base(start_sha1, end_commit_sha1) != start_sha1: + raise GbpError("Start commit '%s' not an ancestor of end commit " + "'%s'" % (start, end_commit)) # Generate patches for commit in reversed(repo.get_commits(start, end_commit)): info = repo.get_commit_info(commit) -- cgit v1.2.3 From fc39f361a853fc307bd4cee3576a314c99e4b549 Mon Sep 17 00:00:00 2001 From: Markus Lehtonen Date: Thu, 12 Jan 2012 15:45:06 +0200 Subject: rpm: add 'vendor' config option Intended to represent the distribution vendor (e.g. 'Debian'). This can be used in tag and branch name formatting. Signed-off-by: Markus Lehtonen Conflicts: gbp/scripts/buildpackage_rpm.py gbp/scripts/import_orig_rpm.py gbp/scripts/pq_rpm.py --- gbp/scripts/import_orig_rpm.py | 4 ++++ gbp/scripts/pq_rpm.py | 1 - 2 files changed, 4 insertions(+), 1 deletion(-) diff --git a/gbp/scripts/import_orig_rpm.py b/gbp/scripts/import_orig_rpm.py index b1247f1e..0dd7c013 100755 --- a/gbp/scripts/import_orig_rpm.py +++ b/gbp/scripts/import_orig_rpm.py @@ -299,8 +299,12 @@ def main(argv): gbp.log.info("Pristine-tar: commiting %s" % pristine_orig) repo.pristine_tar.commit(pristine_orig, options.upstream_branch) +<<<<<<< HEAD tag_str_fields = dict(upstreamversion=version, vendor="Upstream") tag = repo.version_to_tag(options.upstream_tag, tag_str_fields) +======= + tag = repo.version_to_tag(options.upstream_tag, version, vendor="Upstream") +>>>>>>> 1a96ba7... rpm: add 'vendor' config option repo.create_tag(name=tag, msg="Upstream version %s" % version, commit=commit, diff --git a/gbp/scripts/pq_rpm.py b/gbp/scripts/pq_rpm.py index 09ee9bc0..958185fb 100755 --- a/gbp/scripts/pq_rpm.py +++ b/gbp/scripts/pq_rpm.py @@ -640,7 +640,6 @@ def main(argv): parser.add_config_file_option(option_name="upstream-tag", dest="upstream_tag") parser.add_config_file_option(option_name="spec-file", dest="spec_file") -<<<<<<< HEAD parser.add_config_file_option(option_name="packaging-dir", dest="packaging_dir") parser.add_option("--new-packaging-dir", -- cgit v1.2.3 -- cgit v1.2.3 -- cgit v1.2.3 -- cgit v1.2.3 From dea4f78e3497a3080ad3069a1e0495d0a2544c25 Mon Sep 17 00:00:00 2001 From: Markus Lehtonen Date: Mon, 23 Apr 2012 12:51:08 +0300 Subject: rpm: add version parsing functions to pkg policy Adds functions for version string generation and parsing. These are intended for parsing version strings taken e.g. from rpm filename or changelogs. Also, take these new version parsing functions into use in the rpm gbp scripts. Signed-off-by: Markus Lehtonen Signed-off-by: Ed Bartosh Conflicts: gbp/rpm/policy.py gbp/scripts/buildpackage_rpm.py gbp/scripts/import_orig_rpm.py gbp/scripts/pq_rpm.py --- gbp/scripts/buildpackage_rpm.py | 10 +++++++ gbp/scripts/import_orig_rpm.py | 4 --- gbp/scripts/pq_rpm.py | 58 +++++++++++++++++++++++++++++++++++++++++ 3 files changed, 68 insertions(+), 4 deletions(-) diff --git a/gbp/scripts/buildpackage_rpm.py b/gbp/scripts/buildpackage_rpm.py index dcfa3ace..cb3c3437 100755 --- a/gbp/scripts/buildpackage_rpm.py +++ b/gbp/scripts/buildpackage_rpm.py @@ -655,9 +655,14 @@ def main(argv): # Tag (note: tags the exported version) if options.tag or options.tag_only: +<<<<<<< HEAD gbp.log.info("Tagging %s" % RpmPkgPolicy.compose_full_version(spec.version)) commit_info = repo.get_commit_info(tree) tag = packaging_tag_name(repo, spec, commit_info, options) +======= + gbp.log.info("Tagging %s" % spec.version) + tag = repo.version_to_tag(options.packaging_tag, dict(upstreamversion=spec.version), options.vendor) +>>>>>>> 96a8aae... rpm: add version parsing functions to pkg policy if options.retag and repo.has_tag(tag): repo.delete_tag(tag) create_packaging_tag(repo, tag, commit=tree, version=spec.version, @@ -698,8 +703,13 @@ def main(argv): if not options.tag_only: if spec and options.notify: summary = "Gbp-rpm %s" % ["failed", "successful"][not retval] + pkg_evr = {'upstreamversion': spec.version} message = ("Build of %s %s %s" % (spec.name, +<<<<<<< HEAD RpmPkgPolicy.compose_full_version(spec.version), +======= + RpmPkgPolicy.compose_full_version(pkg_evr), +>>>>>>> 96a8aae... rpm: add version parsing functions to pkg policy ["failed", "succeeded"][not retval])) if not gbp.notifications.notify(summary, message, options.notify): gbp.log.err("Failed to send notification") diff --git a/gbp/scripts/import_orig_rpm.py b/gbp/scripts/import_orig_rpm.py index 0dd7c013..b1247f1e 100755 --- a/gbp/scripts/import_orig_rpm.py +++ b/gbp/scripts/import_orig_rpm.py @@ -299,12 +299,8 @@ def main(argv): gbp.log.info("Pristine-tar: commiting %s" % pristine_orig) repo.pristine_tar.commit(pristine_orig, options.upstream_branch) -<<<<<<< HEAD tag_str_fields = dict(upstreamversion=version, vendor="Upstream") tag = repo.version_to_tag(options.upstream_tag, tag_str_fields) -======= - tag = repo.version_to_tag(options.upstream_tag, version, vendor="Upstream") ->>>>>>> 1a96ba7... rpm: add 'vendor' config option repo.create_tag(name=tag, msg="Upstream version %s" % version, commit=commit, diff --git a/gbp/scripts/pq_rpm.py b/gbp/scripts/pq_rpm.py index 958185fb..19050dac 100755 --- a/gbp/scripts/pq_rpm.py +++ b/gbp/scripts/pq_rpm.py @@ -242,6 +242,7 @@ def parse_spec(options, repo, treeish=None): else: spec = spec_from_repo(repo, treeish, options.spec_file) else: +<<<<<<< HEAD preferred_name = os.path.basename(repo.path) + '.spec' if not treeish: spec = guess_spec(options.packaging_dir, True, preferred_name) @@ -261,6 +262,17 @@ def find_upstream_commit(repo, spec, upstream_tag): tag_str_fields = {'upstreamversion': spec.upstreamversion, 'vendor': 'Upstream'} upstream_commit = repo.find_version(upstream_tag, tag_str_fields) +======= + specfilename = guess_spec(options.packaging_dir, + True, + os.path.basename(repo.path) + '.spec') + spec = SpecFile(specfilename) + except KeyError: + raise GbpError, "Can't parse spec" + + # Find upstream version + upstream_commit = repo.find_version(options.upstream_tag, dict(upstreamversion=spec.version), "Upstream") +>>>>>>> 96a8aae... rpm: add version parsing functions to pkg policy if not upstream_commit: raise GbpError("Couldn't find upstream version %s" % spec.upstreamversion) @@ -404,10 +416,26 @@ def import_spec_patches(repo, options): if repo.get_branch() == pq_branch: repo.force_head(upstream_commit, hard=True) else: +<<<<<<< HEAD repo.create_branch(pq_branch, upstream_commit, force=True) except GitRepositoryError as err: raise GbpError("Cannot create patch-queue branch '%s': %s" % (pq_branch, err)) +======= + specfilename = guess_spec(options.packaging_dir, + True, + os.path.basename(repo.path) + '.spec') + spec = SpecFile(specfilename) + except KeyError: + raise GbpError, "Can't parse spec" + + # Find upstream version + commit = repo.find_version(options.upstream_tag, dict(upstreamversion=spec.version), "Upstream") + if commit: + commits=[commit] + else: + raise GbpError, ("Couldn't find upstream version %s. Don't know on what base to import." % spec.version) +>>>>>>> 96a8aae... rpm: add version parsing functions to pkg policy # Put patches in a safe place if spec_treeish: @@ -440,6 +468,7 @@ def import_spec_patches(repo, options): pq_branch)) +<<<<<<< HEAD def rebase_pq(repo, options): """Rebase pq branch on the correct upstream version (from spec file).""" current = repo.get_branch() @@ -450,6 +479,35 @@ def rebase_pq(repo, options): base = current spec = parse_spec(options, repo) upstream_commit = find_upstream_commit(repo, spec, options.upstream_tag) +======= + return os.path.basename(spec.specfile) + + +def rebase_pq(repo, branch, options): + if is_pq_branch(branch, options): + base = pq_branch_base(branch, options) + gbp.log.info("On '%s', switching to '%s'" % (branch, base)) + branch = base + repo.set_branch(branch) + + # Find and parse .spec file + try: + if options.spec_file != 'auto': + specfilename = options.spec_file + options.packaging_dir = os.path.dirname(specfilename) + else: + specfilename = guess_spec(options.packaging_dir, + True, + os.path.basename(repo.path) + '.spec') + spec = SpecFile(specfilename) + except KeyError: + raise GbpError, "Can't parse spec" + + # Find upstream version + upstream_commit = repo.find_version(options.upstream_tag, dict(upstreamversion=spec.version), "Upstream") + if not upstream_commit: + raise GbpError, ("Couldn't find upstream version %s. Don't know on what base to import." % spec.version) +>>>>>>> 96a8aae... rpm: add version parsing functions to pkg policy switch_to_pq_branch(repo, base, options) GitCommand("rebase")([upstream_commit]) -- cgit v1.2.3 From d05fe193deace3ed3d45596bb9a3df1da8da3041 Mon Sep 17 00:00:00 2001 From: Markus Lehtonen Date: Wed, 4 Sep 2013 10:33:03 +0300 Subject: buildpackage-rpm: add more tagging options Add new possible keywords to be used in packaging-tag format string: 'nowtime', 'authortime', 'committime', 'nowtimenum', 'authortimenum' and 'committimenum'. The '*timenum' keyword denote the corresponding '*time' keyword appended with an additional incremental serial number. E.g. if 'nowtime' would produce '20120531', 'nowtimenum' would (the first time) produce '20120531.1'. What is completely missing is a way to support these new tag keywords in git-import-srpm tool. So, if you use these tags, git-import-srpm is not able to reproduce the tags, (and, it is not necessarily able to correctly tell if you've already imported a certain version of the package). Signed-off-by: Markus Lehtonen Conflicts: gbp/scripts/buildpackage_rpm.py --- gbp/scripts/buildpackage_rpm.py | 13 +++++++++++++ 1 file changed, 13 insertions(+) diff --git a/gbp/scripts/buildpackage_rpm.py b/gbp/scripts/buildpackage_rpm.py index cb3c3437..37f18196 100755 --- a/gbp/scripts/buildpackage_rpm.py +++ b/gbp/scripts/buildpackage_rpm.py @@ -359,6 +359,7 @@ def create_packaging_tag(repo, tag, commit, version, options): keyid=options.keyid, commit=commit) +<<<<<<< HEAD def disable_hooks(options): """Disable all hooks (except for builder)""" for hook in ['cleaner', 'postexport', 'prebuild', 'postbuild', 'posttag']: @@ -369,6 +370,9 @@ def disable_hooks(options): def parse_args(argv, prefix, git_treeish=None): """Parse config and command line arguments""" +======= +def parse_args(argv, prefix): +>>>>>>> 57b7a4e... buildpackage-rpm: add more tagging options args = [ arg for arg in argv[1:] if arg.find('--%s' % prefix) == 0 ] builder_args = [ arg for arg in argv[1:] if arg.find('--%s' % prefix) == -1 ] @@ -655,6 +659,7 @@ def main(argv): # Tag (note: tags the exported version) if options.tag or options.tag_only: +<<<<<<< HEAD <<<<<<< HEAD gbp.log.info("Tagging %s" % RpmPkgPolicy.compose_full_version(spec.version)) commit_info = repo.get_commit_info(tree) @@ -663,11 +668,19 @@ def main(argv): gbp.log.info("Tagging %s" % spec.version) tag = repo.version_to_tag(options.packaging_tag, dict(upstreamversion=spec.version), options.vendor) >>>>>>> 96a8aae... rpm: add version parsing functions to pkg policy +======= + gbp.log.info("Tagging %s" % RpmPkgPolicy.compose_full_version(spec.version)) + commit_info = repo.get_commit_info(tree) + tag = packaging_tag_name(repo, spec, commit_info, options) +>>>>>>> 57b7a4e... buildpackage-rpm: add more tagging options if options.retag and repo.has_tag(tag): repo.delete_tag(tag) create_packaging_tag(repo, tag, commit=tree, version=spec.version, options=options) +<<<<<<< HEAD vcs_info = get_vcs_info(repo, tag) +======= +>>>>>>> 57b7a4e... buildpackage-rpm: add more tagging options if options.posttag: sha = repo.rev_parse("%s^{}" % tag) Command(options.posttag, shell=True, -- cgit v1.2.3 From 6bfb90e2d1c4667907d1d9f3d79340872d7abdaa Mon Sep 17 00:00:00 2001 From: Markus Lehtonen Date: Thu, 7 Jun 2012 19:13:43 +0300 Subject: pq-rpm: support importing compressed patches Adds support for importing compressed patches. NOTE: Only gzip is supported, for the time being, other compression methods shouldn't be to hard to add, if needed. Signed-off-by: Markus Lehtonen Conflicts: gbp/scripts/pq_rpm.py --- gbp/scripts/pq_rpm.py | 58 --------------------------------------------------- 1 file changed, 58 deletions(-) diff --git a/gbp/scripts/pq_rpm.py b/gbp/scripts/pq_rpm.py index 19050dac..958185fb 100755 --- a/gbp/scripts/pq_rpm.py +++ b/gbp/scripts/pq_rpm.py @@ -242,7 +242,6 @@ def parse_spec(options, repo, treeish=None): else: spec = spec_from_repo(repo, treeish, options.spec_file) else: -<<<<<<< HEAD preferred_name = os.path.basename(repo.path) + '.spec' if not treeish: spec = guess_spec(options.packaging_dir, True, preferred_name) @@ -262,17 +261,6 @@ def find_upstream_commit(repo, spec, upstream_tag): tag_str_fields = {'upstreamversion': spec.upstreamversion, 'vendor': 'Upstream'} upstream_commit = repo.find_version(upstream_tag, tag_str_fields) -======= - specfilename = guess_spec(options.packaging_dir, - True, - os.path.basename(repo.path) + '.spec') - spec = SpecFile(specfilename) - except KeyError: - raise GbpError, "Can't parse spec" - - # Find upstream version - upstream_commit = repo.find_version(options.upstream_tag, dict(upstreamversion=spec.version), "Upstream") ->>>>>>> 96a8aae... rpm: add version parsing functions to pkg policy if not upstream_commit: raise GbpError("Couldn't find upstream version %s" % spec.upstreamversion) @@ -416,26 +404,10 @@ def import_spec_patches(repo, options): if repo.get_branch() == pq_branch: repo.force_head(upstream_commit, hard=True) else: -<<<<<<< HEAD repo.create_branch(pq_branch, upstream_commit, force=True) except GitRepositoryError as err: raise GbpError("Cannot create patch-queue branch '%s': %s" % (pq_branch, err)) -======= - specfilename = guess_spec(options.packaging_dir, - True, - os.path.basename(repo.path) + '.spec') - spec = SpecFile(specfilename) - except KeyError: - raise GbpError, "Can't parse spec" - - # Find upstream version - commit = repo.find_version(options.upstream_tag, dict(upstreamversion=spec.version), "Upstream") - if commit: - commits=[commit] - else: - raise GbpError, ("Couldn't find upstream version %s. Don't know on what base to import." % spec.version) ->>>>>>> 96a8aae... rpm: add version parsing functions to pkg policy # Put patches in a safe place if spec_treeish: @@ -468,7 +440,6 @@ def import_spec_patches(repo, options): pq_branch)) -<<<<<<< HEAD def rebase_pq(repo, options): """Rebase pq branch on the correct upstream version (from spec file).""" current = repo.get_branch() @@ -479,35 +450,6 @@ def rebase_pq(repo, options): base = current spec = parse_spec(options, repo) upstream_commit = find_upstream_commit(repo, spec, options.upstream_tag) -======= - return os.path.basename(spec.specfile) - - -def rebase_pq(repo, branch, options): - if is_pq_branch(branch, options): - base = pq_branch_base(branch, options) - gbp.log.info("On '%s', switching to '%s'" % (branch, base)) - branch = base - repo.set_branch(branch) - - # Find and parse .spec file - try: - if options.spec_file != 'auto': - specfilename = options.spec_file - options.packaging_dir = os.path.dirname(specfilename) - else: - specfilename = guess_spec(options.packaging_dir, - True, - os.path.basename(repo.path) + '.spec') - spec = SpecFile(specfilename) - except KeyError: - raise GbpError, "Can't parse spec" - - # Find upstream version - upstream_commit = repo.find_version(options.upstream_tag, dict(upstreamversion=spec.version), "Upstream") - if not upstream_commit: - raise GbpError, ("Couldn't find upstream version %s. Don't know on what base to import." % spec.version) ->>>>>>> 96a8aae... rpm: add version parsing functions to pkg policy switch_to_pq_branch(repo, base, options) GitCommand("rebase")([upstream_commit]) -- cgit v1.2.3 From 010b7546b3dc6b55e97fff08c1e7831077737bc5 Mon Sep 17 00:00:00 2001 From: Markus Lehtonen Date: Tue, 12 Jun 2012 10:42:41 +0300 Subject: rpm: support squashing commits in patch generation Implements an option for git-buildpackage-rpm and gbp-pq to squash commits (from upstream) up to certain tree-ish into one monolithic diff. Useful e.g. if you wan't to auto-generate a stable update patch. The new format of the cmdline option filename is commit-ish followed by (optionally) a colon and the desired diff filename base. Suffix '.diff' is added by GBP. Magic word 'HEAD' translates to the end-commit when given as the squash-point. This allows one to configure gbp to always squash all commits into one monolithic diff. Signed-off-by: Markus Lehtonen Conflicts: gbp/config.py gbp/scripts/pq_rpm.py --- gbp/scripts/pq_rpm.py | 22 +++++++++++++++++++++- 1 file changed, 21 insertions(+), 1 deletion(-) diff --git a/gbp/scripts/pq_rpm.py b/gbp/scripts/pq_rpm.py index 958185fb..9ba5028f 100755 --- a/gbp/scripts/pq_rpm.py +++ b/gbp/scripts/pq_rpm.py @@ -27,7 +27,6 @@ import re import gzip import bz2 import subprocess - import gbp.tmpfile as tempfile from gbp.config import GbpOptionParserRpm from gbp.rpm.git import GitRepositoryError, RpmGitRepository @@ -149,6 +148,7 @@ def generate_patches(repo, start, squash, end, outdir, options): start = merge_sha1 print start + start_sha1 = repo.rev_parse("%s^0" % start) try: end_commit = end end_commit_sha1 = repo.rev_parse("%s^0" % end_commit) @@ -162,6 +162,26 @@ def generate_patches(repo, start, squash, end, outdir, options): if repo.get_merge_base(start_sha1, end_commit_sha1) != start_sha1: raise GbpError("Start commit '%s' not an ancestor of end commit " "'%s'" % (start, end_commit)) + # Squash commits, if requested + if squash[0]: + if squash[0] == 'HEAD': + squash[0] = end_commit + squash_sha1 = repo.rev_parse("%s^0" % squash[0]) + if start_sha1 != squash_sha1: + if not squash_sha1 in repo.get_commits(start, end_commit): + raise GbpError("Given squash point '%s' not in the history " + "of end commit '%s'" % (squash[0], end_commit)) + # Shorten SHA1s + squash_sha1 = repo.rev_parse(squash_sha1, short=7) + start_sha1 = repo.rev_parse(start_sha1, short=7) + gbp.log.info("Squashing commits %s..%s into one monolithic diff" % + (start_sha1, squash_sha1)) + patch_fn = format_diff(outdir, squash[1], repo, + start_sha1, squash_sha1) + if patch_fn: + patches.append(patch_fn) + start = squash_sha1 + # Generate patches for commit in reversed(repo.get_commits(start, end_commit)): info = repo.get_commit_info(commit) -- cgit v1.2.3 From fd386963e93287654225aa97dcb0c36c7767e347 Mon Sep 17 00:00:00 2001 From: Markus Lehtonen Date: Fri, 24 Aug 2012 16:32:44 +0300 Subject: buildpackage-rpm: support special tree-ish names in --git-upstream-tree Support special 'WC*' and 'INDEX' values for the --git-upstream-tree option. Signed-off-by: Markus Lehtonen Conflicts: gbp/scripts/buildpackage_rpm.py --- gbp/scripts/buildpackage_rpm.py | 22 ---------------------- 1 file changed, 22 deletions(-) diff --git a/gbp/scripts/buildpackage_rpm.py b/gbp/scripts/buildpackage_rpm.py index 37f18196..7e10c463 100755 --- a/gbp/scripts/buildpackage_rpm.py +++ b/gbp/scripts/buildpackage_rpm.py @@ -359,7 +359,6 @@ def create_packaging_tag(repo, tag, commit, version, options): keyid=options.keyid, commit=commit) -<<<<<<< HEAD def disable_hooks(options): """Disable all hooks (except for builder)""" for hook in ['cleaner', 'postexport', 'prebuild', 'postbuild', 'posttag']: @@ -370,9 +369,6 @@ def disable_hooks(options): def parse_args(argv, prefix, git_treeish=None): """Parse config and command line arguments""" -======= -def parse_args(argv, prefix): ->>>>>>> 57b7a4e... buildpackage-rpm: add more tagging options args = [ arg for arg in argv[1:] if arg.find('--%s' % prefix) == 0 ] builder_args = [ arg for arg in argv[1:] if arg.find('--%s' % prefix) == -1 ] @@ -659,28 +655,14 @@ def main(argv): # Tag (note: tags the exported version) if options.tag or options.tag_only: -<<<<<<< HEAD -<<<<<<< HEAD gbp.log.info("Tagging %s" % RpmPkgPolicy.compose_full_version(spec.version)) commit_info = repo.get_commit_info(tree) tag = packaging_tag_name(repo, spec, commit_info, options) -======= - gbp.log.info("Tagging %s" % spec.version) - tag = repo.version_to_tag(options.packaging_tag, dict(upstreamversion=spec.version), options.vendor) ->>>>>>> 96a8aae... rpm: add version parsing functions to pkg policy -======= - gbp.log.info("Tagging %s" % RpmPkgPolicy.compose_full_version(spec.version)) - commit_info = repo.get_commit_info(tree) - tag = packaging_tag_name(repo, spec, commit_info, options) ->>>>>>> 57b7a4e... buildpackage-rpm: add more tagging options if options.retag and repo.has_tag(tag): repo.delete_tag(tag) create_packaging_tag(repo, tag, commit=tree, version=spec.version, options=options) -<<<<<<< HEAD vcs_info = get_vcs_info(repo, tag) -======= ->>>>>>> 57b7a4e... buildpackage-rpm: add more tagging options if options.posttag: sha = repo.rev_parse("%s^{}" % tag) Command(options.posttag, shell=True, @@ -718,11 +700,7 @@ def main(argv): summary = "Gbp-rpm %s" % ["failed", "successful"][not retval] pkg_evr = {'upstreamversion': spec.version} message = ("Build of %s %s %s" % (spec.name, -<<<<<<< HEAD RpmPkgPolicy.compose_full_version(spec.version), -======= - RpmPkgPolicy.compose_full_version(pkg_evr), ->>>>>>> 96a8aae... rpm: add version parsing functions to pkg policy ["failed", "succeeded"][not retval])) if not gbp.notifications.notify(summary, message, options.notify): gbp.log.err("Failed to send notification") -- cgit v1.2.3 -- cgit v1.2.3 -- cgit v1.2.3 From ce5770ce49cb468ccb67edad7503144db611b12f Mon Sep 17 00:00:00 2001 From: Markus Lehtonen Date: Tue, 2 Apr 2013 10:50:08 +0300 Subject: buildpackage-rpm: listen to --no-create-orig option for native packages, too Signed-off-by: Markus Lehtonen --- gbp/scripts/buildpackage_rpm.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/gbp/scripts/buildpackage_rpm.py b/gbp/scripts/buildpackage_rpm.py index 7e10c463..802ac3f6 100755 --- a/gbp/scripts/buildpackage_rpm.py +++ b/gbp/scripts/buildpackage_rpm.py @@ -611,7 +611,7 @@ def main(argv): # Get/build the orig tarball if is_native(repo, options): - if spec.orig_src: + if spec.orig_src and not options.no_create_orig: # Just build source archive from the exported tree gbp.log.info("Creating (native) source archive %s from '%s'" % (spec.orig_src['filename'], tree)) if spec.orig_src['compression']: -- cgit v1.2.3 From 5223ef064358011bcebd986cd13257bae01459b0 Mon Sep 17 00:00:00 2001 From: Markus Lehtonen Date: Fri, 13 Jun 2014 13:31:48 +0300 Subject: buildpackage-rpm: always create tarball for native packages If the package is native, always (re-)create the source tarball, even if --git-no-create-orig is used. Not creating the tarball does not make much sense (and most probably just causes problems and confusion): for native packages there is no place for external tarball and no patches so we need to always have the correct sources (i.e. the exported revision) in the tarball. Signed-off-by: Markus Lehtonen --- gbp/scripts/buildpackage_rpm.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/gbp/scripts/buildpackage_rpm.py b/gbp/scripts/buildpackage_rpm.py index 802ac3f6..7e10c463 100755 --- a/gbp/scripts/buildpackage_rpm.py +++ b/gbp/scripts/buildpackage_rpm.py @@ -611,7 +611,7 @@ def main(argv): # Get/build the orig tarball if is_native(repo, options): - if spec.orig_src and not options.no_create_orig: + if spec.orig_src: # Just build source archive from the exported tree gbp.log.info("Creating (native) source archive %s from '%s'" % (spec.orig_src['filename'], tree)) if spec.orig_src['compression']: -- cgit v1.2.3 From 62e5707e312b5b9a6f96ab2330ea6fbd63161cca Mon Sep 17 00:00:00 2001 From: Markus Lehtonen Date: Thu, 4 Sep 2014 15:00:28 +0300 Subject: pq-rpm: better error message Change-Id: Iaadc614e9ed5df2e943eed71511559d0b76e0227 Signed-off-by: Markus Lehtonen --- gbp/scripts/pq_rpm.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/gbp/scripts/pq_rpm.py b/gbp/scripts/pq_rpm.py index 9ba5028f..2f4f42c4 100755 --- a/gbp/scripts/pq_rpm.py +++ b/gbp/scripts/pq_rpm.py @@ -419,7 +419,7 @@ def import_spec_patches(repo, options): # Create pq-branch if repo.has_branch(pq_branch) and not options.force: raise GbpError("Patch-queue branch '%s' already exists. " - "Try 'rebase' instead." % pq_branch) + "Try 'switch' instead." % pq_branch) try: if repo.get_branch() == pq_branch: repo.force_head(upstream_commit, hard=True) -- cgit v1.2.3 From 3911ff348f73dc60ad0b4fb5a4619e67198e0393 Mon Sep 17 00:00:00 2001 From: Markus Lehtonen Date: Fri, 12 Sep 2014 15:48:20 +0300 Subject: GitRepository/__git_inout: correctly handle input error Change-Id: I3c9b8851490c05719f77a9519418a98f572d68e3 Signed-off-by: Markus Lehtonen --- gbp/git/repository.py | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/gbp/git/repository.py b/gbp/git/repository.py index f52f3f2b..fa3ed520 100644 --- a/gbp/git/repository.py +++ b/gbp/git/repository.py @@ -252,7 +252,12 @@ class GitRepository(object): ready = select.select(out_fds, in_fds, []) # Write in chunks of 512 bytes if ready[1]: - popen.stdin.write(stdin[w_ind:w_ind+512]) + try: + popen.stdin.write(stdin[w_ind:w_ind+512]) + except IOError: + # Ignore, we want to read buffers to e.g. get error message + # Git should give an error code so that we catch an error + pass w_ind += 512 if w_ind > len(stdin): rm_polled_fd(popen.stdin, in_fds) -- cgit v1.2.3 From e726b74fee57fcc78282f1ad700fa16095798fa8 Mon Sep 17 00:00:00 2001 From: Markus Lehtonen Date: Fri, 12 Sep 2014 16:31:20 +0300 Subject: rpm packaging: enable CentOS 7 Fix dependencies and enable git-buildpackage(-deb) subpackage for CentOS 7. Also fixes one excess dependency for Fedora: no need for dpkg-devel, dpkg-dev is enough. Change-Id: I2c3929ae623c9694aa9afcb8a4e3155696179f05 Signed-off-by: Markus Lehtonen --- packaging/git-buildpackage.spec | 12 ++++++++---- 1 file changed, 8 insertions(+), 4 deletions(-) diff --git a/packaging/git-buildpackage.spec b/packaging/git-buildpackage.spec index be1a6826..ad8f0e5e 100644 --- a/packaging/git-buildpackage.spec +++ b/packaging/git-buildpackage.spec @@ -12,11 +12,15 @@ URL: https://honk.sigxcpu.org/piki/projects/git-buildpackage/ Source0: %{name}_%{version}.tar.gz # Conditional package names for requirements -%if 0%{?fedora} || 0%{?centos_ver} +%if 0%{?fedora} || 0%{?centos_ver} > 7 +%define dpkg_pkg_name dpkg-dev +%else +%if 0%{?centos_version} %define dpkg_pkg_name dpkg-devel %else %define dpkg_pkg_name dpkg %endif +%endif %if 0%{?suse_version} && 0%{?suse_version} < 1230 %define devscripts_pkg_name devscripts-fixes @@ -30,7 +34,7 @@ Source0: %{name}_%{version}.tar.gz %define man_pkg_name man %endif -%if 0%{?fedora} || 0%{?centos_ver} || 0%{?tizen_version:1} +%if 0%{?fedora} || 0%{?centos_version} || 0%{?centos_ver} || 0%{?tizen_version:1} %define python_pkg_name python %else %define python_pkg_name python-base @@ -205,8 +209,8 @@ cat >> files.list << EOF EOF %endif -# Disable the debian tools for CentOS -%if 0%{?centos_version} +# Disable the debian tools for old CentOS +%if 0%{?centos_version} && 0%{?centos_ver} < 7 for f in `cat files.list`; do rm -rfv %{buildroot}/$f done -- cgit v1.2.3 From 27e2f111b74ef7b4ca19ee1248087453e78e1b37 Mon Sep 17 00:00:00 2001 From: Markus Lehtonen Date: Thu, 25 Sep 2014 12:02:56 +0300 Subject: log: don't propagate to ancestor loggers Change-Id: I6548dcfe5ba2f779b9d9244ad1eb88fa92c2180e Signed-off-by: Markus Lehtonen --- gbp/log.py | 2 ++ 1 file changed, 2 insertions(+) diff --git a/gbp/log.py b/gbp/log.py index 17cd680d..a8e420a8 100644 --- a/gbp/log.py +++ b/gbp/log.py @@ -105,6 +105,8 @@ class GbpLogger(logging.Logger): CRITICAL])) for hdlr in self._default_handlers: self.addHandler(hdlr) + # We don't want to propagate as we add our own handlers + self.propagate = False def set_color(self, color): """Set/unset colorized output of the default handlers""" -- cgit v1.2.3 From 2e7b25212f54b4c9b503b4abe3acc79613752bda Mon Sep 17 00:00:00 2001 From: Markus Lehtonen Date: Mon, 24 Nov 2014 19:12:37 +0200 Subject: patchseries: strip numbering when guessing subject from filename Change-Id: I58c4f8871411dae15d0e0e4246f0eebe65e3967d Signed-off-by: Markus Lehtonen --- gbp/patch_series.py | 8 +++++++- 1 file changed, 7 insertions(+), 1 deletion(-) diff --git a/gbp/patch_series.py b/gbp/patch_series.py index 10fccfc6..327997f5 100644 --- a/gbp/patch_series.py +++ b/gbp/patch_series.py @@ -95,6 +95,12 @@ class Patch(object): >>> p = Patch('debian/patches/foo') >>> p._get_subject_from_filename() 'foo' + >>> Patch('0123-foo.patch')._get_subject_from_filename() + 'foo' + >>> Patch('0123.patch')._get_subject_from_filename() + '0123' + >>> Patch('0123-foo-0123.patch')._get_subject_from_filename() + 'foo-0123' @return: the patch's subject @rtype: C{str} @@ -107,7 +113,7 @@ class Patch(object): subject = base except ValueError: pass # No ext so keep subject as is - return subject + return subject.lstrip('0123456789-') or subject def _get_info_field(self, key, get_val=None): """ -- cgit v1.2.3 From dbb711361a44f913247a0e2baa9d0c54e0b21078 Mon Sep 17 00:00:00 2001 From: Markus Lehtonen Date: Thu, 18 Dec 2014 13:55:08 +0200 Subject: rpm packaging: include python egg-info in -common We need this for the Python pkg_resources. Change-Id: I74c7d466040279b8f34ec357b6947fa2f7c29a15 Signed-off-by: Markus Lehtonen --- packaging/git-buildpackage.spec | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/packaging/git-buildpackage.spec b/packaging/git-buildpackage.spec index ad8f0e5e..a9a034df 100644 --- a/packaging/git-buildpackage.spec +++ b/packaging/git-buildpackage.spec @@ -163,7 +163,6 @@ GIT_CEILING_DIRECTORIES=%{_builddir} \ %install rm -rf %{buildroot} WITHOUT_NOSETESTS=1 %{__python} ./setup.py install --root=%{buildroot} --prefix=/usr -rm -rf %{buildroot}%{python_sitelib}/*info %if %{with docs} # Install man pages @@ -231,6 +230,7 @@ done %dir %{python_sitelib}/gbp/pkg %dir %{python_sitelib}/gbp/scripts %dir %{python_sitelib}/gbp/scripts/common +%{python_sitelib}/gbp-* %{python_sitelib}/gbp/*.py* %{python_sitelib}/gbp/scripts/__init__.py* %{python_sitelib}/gbp/scripts/clone.py* -- cgit v1.2.3 From f442e71ff26ed716b74010e5d4e46e9532d15b4c Mon Sep 17 00:00:00 2001 From: Markus Lehtonen Date: Thu, 11 Sep 2014 15:25:00 +0300 Subject: log: don't initialize handlers in GbpLogger init Better compatibility with 3rd party modules that have their own logging initializations. Change-Id: Ic91ab54c70537061c3e76dd6317ceeec888fab36 Signed-off-by: Markus Lehtonen --- gbp/log.py | 30 +++++++++++++++++++----------- 1 file changed, 19 insertions(+), 11 deletions(-) diff --git a/gbp/log.py b/gbp/log.py index a8e420a8..a508b677 100644 --- a/gbp/log.py +++ b/gbp/log.py @@ -96,31 +96,35 @@ class GbpStreamHandler(logging.StreamHandler): class GbpLogger(logging.Logger): """Logger class for git-buildpackage""" - def __init__(self, name, color='auto', *args, **kwargs): + def __init__(self, name, *args, **kwargs): logging.Logger.__init__(self, name, *args, **kwargs) - self._default_handlers = [GbpStreamHandler(sys.stdout, color), - GbpStreamHandler(sys.stderr, color)] - self._default_handlers[0].addFilter(GbpFilter([DEBUG, INFO])) - self._default_handlers[1].addFilter(GbpFilter([WARNING, ERROR, - CRITICAL])) - for hdlr in self._default_handlers: + self.default_handlers = [] + + def init_default_handlers(self, color='auto'): + """Initialize and set default handlers to logger""" + self.default_handlers = [GbpStreamHandler(sys.stdout, color), + GbpStreamHandler(sys.stderr, color)] + self.default_handlers[0].addFilter(GbpFilter([DEBUG, INFO])) + self.default_handlers[1].addFilter(GbpFilter([WARNING, ERROR, + CRITICAL])) + for hdlr in self.default_handlers: self.addHandler(hdlr) # We don't want to propagate as we add our own handlers self.propagate = False def set_color(self, color): """Set/unset colorized output of the default handlers""" - for hdlr in self._default_handlers: + for hdlr in self.default_handlers: hdlr.set_color(color) def set_color_scheme(self, color_scheme={}): """Set the color scheme of the default handlers""" - for hdlr in self._default_handlers: + for hdlr in self.default_handlers: hdlr.set_color_scheme(color_scheme) def set_format(self, fmt): """Set the format of the default handlers""" - for hdlr in self._default_handlers: + for hdlr in self.default_handlers: hdlr.set_format(fmt) @@ -170,7 +174,11 @@ def getLogger(*args, **kwargs): """Gbp-specific function""" if not issubclass(logging.getLoggerClass(), GbpLogger): logging.setLoggerClass(GbpLogger) - return logging.getLogger(*args, **kwargs) + color = kwargs.pop('color') if 'color' in kwargs else 'auto' + logger = logging.getLogger(*args, **kwargs) + if not logger.default_handlers: + logger.init_default_handlers(color) + return logger def setup(color, verbose, color_scheme=""): """Basic logger setup""" -- cgit v1.2.3 From 1a36070b9e6e8284f3c20c86b169a936fba58abb Mon Sep 17 00:00:00 2001 From: Markus Lehtonen Date: Wed, 17 Dec 2014 17:37:27 +0200 Subject: GitRepository.create_tag: use GitArgs class Change-Id: I8ead4dda504152bde4c35ee0c03d6e3295820fd6 Signed-off-by: Markus Lehtonen --- gbp/git/repository.py | 14 +++++++------- 1 file changed, 7 insertions(+), 7 deletions(-) diff --git a/gbp/git/repository.py b/gbp/git/repository.py index fa3ed520..25fef0aa 100644 --- a/gbp/git/repository.py +++ b/gbp/git/repository.py @@ -716,14 +716,14 @@ class GitRepository(object): @param keyid: the GPG keyid used to sign the tag @type keyid: C{str} """ - args = [] - args += [ '-m', msg ] if msg else [] + args = GitArgs() + args.add_true(msg, ['-m', msg]) if sign: - args += [ '-s' ] - args += [ '-u', keyid ] if keyid else [] - args += [ name ] - args += [ commit ] if commit else [] - self._git_command("tag", args) + args.add('-s') + args.add_true(keyid, ['-u', keyid]) + args.add(name) + args.add_true(commit, commit) + self._git_command("tag", args.args) def delete_tag(self, tag): """ -- cgit v1.2.3 From 789036d60a55bb7251084589dfea6f330c485751 Mon Sep 17 00:00:00 2001 From: Markus Lehtonen Date: Wed, 17 Dec 2014 17:39:59 +0200 Subject: GitRepository.create_tag: add 'annotate' argument For forcing the creation of annotated tags. Causes the an editor to be spawned if no message is given. Change-Id: I8ec7e195cf7ae997606af1d887f04e84a14b2abc Signed-off-by: Markus Lehtonen --- gbp/git/repository.py | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-) diff --git a/gbp/git/repository.py b/gbp/git/repository.py index 25fef0aa..4d7b24dc 100644 --- a/gbp/git/repository.py +++ b/gbp/git/repository.py @@ -700,7 +700,8 @@ class GitRepository(object): #{ Tags - def create_tag(self, name, msg=None, commit=None, sign=False, keyid=None): + def create_tag(self, name, msg=None, commit=None, sign=False, keyid=None, + annotate=False): """ Create a new tag. @@ -715,15 +716,18 @@ class GitRepository(object): @type sign: C{bool} @param keyid: the GPG keyid used to sign the tag @type keyid: C{str} + @param annotate: Create an annotated tag + @type annotate: C{bool} """ args = GitArgs() args.add_true(msg, ['-m', msg]) if sign: args.add('-s') args.add_true(keyid, ['-u', keyid]) + args.add_true(annotate, '-a') args.add(name) args.add_true(commit, commit) - self._git_command("tag", args.args) + self._git_command("tag", args.args, interactive=True) def delete_tag(self, tag): """ -- cgit v1.2.3 From 84c67ab58e4bb5e7d9dae77cf8251ed0a45ff017 Mon Sep 17 00:00:00 2001 From: Markus Lehtonen Date: Tue, 17 Feb 2015 12:51:34 +0200 Subject: log: don't crash getLogger if getting the root logger The root logger won't have the gbp-specific default_handlers attribute. Change-Id: I0b81fdfbe70fe16ce3fd226248b83a4f6a17fc7f Signed-off-by: Markus Lehtonen --- gbp/log.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/gbp/log.py b/gbp/log.py index a508b677..7b9a4aa8 100644 --- a/gbp/log.py +++ b/gbp/log.py @@ -176,7 +176,7 @@ def getLogger(*args, **kwargs): logging.setLoggerClass(GbpLogger) color = kwargs.pop('color') if 'color' in kwargs else 'auto' logger = logging.getLogger(*args, **kwargs) - if not logger.default_handlers: + if hasattr(logger, 'default_handlers') and not logger.default_handlers: logger.init_default_handlers(color) return logger -- cgit v1.2.3 From 745a0eca470a22efa96ed2cf762daa583cb172ed Mon Sep 17 00:00:00 2001 From: Jun Wang Date: Thu, 28 Jan 2016 04:32:24 +0800 Subject: Fix some errors of merging Change-Id: I4441fb369aa88598f238c41710edeba01cd537b6 --- .gitignore | 8 ++++---- .gitmodules | 3 +++ debian/control | 3 --- gbp/scripts/common/pq.py | 6 ------ gbp/scripts/import_srpm.py | 2 -- gbp/scripts/pq_rpm.py | 3 --- 6 files changed, 7 insertions(+), 18 deletions(-) diff --git a/.gitignore b/.gitignore index 80960ac9..afc87fff 100644 --- a/.gitignore +++ b/.gitignore @@ -18,10 +18,10 @@ docs/manpage.links docs/manpage.refs docs/version.ent -debian/git-buildpackage*.debhelper* +debian/git-buildpackage.*.debhelper +debian/git-buildpackage.debhelper.* debian/python-module-stampdir/ debian/files -debian/git-buildpackage*.substvars +debian/git-buildpackage.substvars debian/git-buildpackage/ -debian/git-buildpackage-rpm/ -debian/tmp/ + diff --git a/.gitmodules b/.gitmodules index 29b4c390..6e177397 100644 --- a/.gitmodules +++ b/.gitmodules @@ -1,3 +1,6 @@ [submodule "tests/component/deb/data"] path = tests/component/deb/data url = ssh://fushuai1985@review.tizen.org:29418/tools/git-buildpackage-deb-testdata +[submodule "tests/component/rpm/data"] + path = tests/component/rpm/data + url = ssh://fushuai1985@review.tizen.org:29418/tools/git-buildpackage-rpm-testdata diff --git a/debian/control b/debian/control index 65987801..705fd7cd 100644 --- a/debian/control +++ b/debian/control @@ -12,12 +12,9 @@ Build-Depends: pychecker, python (>> 2.6.6-3~), python-epydoc, - python-mock, python-nose, python-pkg-resources, - python-rpm, python-setuptools, - rpm, sgml2x, # For rpm (epydoc) python-rpm diff --git a/gbp/scripts/common/pq.py b/gbp/scripts/common/pq.py index 16868845..a91ec8e9 100644 --- a/gbp/scripts/common/pq.py +++ b/gbp/scripts/common/pq.py @@ -88,10 +88,6 @@ def is_pq_branch(branch, options): return True return False - pq_re = re.compile(r'^%s$' % (pq_format_str % dict(branch="(?P\S+)"))) - if pq_re.match(branch): - return True - return False def pq_branch_name(branch, options, extra_keys=None): """ @@ -120,8 +116,6 @@ def pq_branch_name(branch, options, extra_keys=None): if not is_pq_branch(branch, options): return pq_format_str % format_fields - if not is_pq_branch(branch, options): - return pq_format_str % format_fields def pq_branch_base(pq_branch, options): """ diff --git a/gbp/scripts/import_srpm.py b/gbp/scripts/import_srpm.py index 7a397fe9..85f1225f 100755 --- a/gbp/scripts/import_srpm.py +++ b/gbp/scripts/import_srpm.py @@ -197,8 +197,6 @@ def parse_args(argv): parser.add_config_file_option(option_name="color-scheme", dest="color_scheme") parser.add_config_file_option(option_name="tmp-dir", dest="tmp_dir") - parser.add_config_file_option(option_name="vendor", action="store", - dest="vendor") parser.add_option("--download", action="store_true", dest="download", default=False, help="download source package") parser.add_config_file_option(option_name="vendor", action="store", diff --git a/gbp/scripts/pq_rpm.py b/gbp/scripts/pq_rpm.py index 2f4f42c4..c33e67b2 100755 --- a/gbp/scripts/pq_rpm.py +++ b/gbp/scripts/pq_rpm.py @@ -690,9 +690,6 @@ def main(argv): dest="patch_export_squash_until") parser.add_config_file_option("patch-export-ignore-path", dest="patch_export_ignore_path") - parser.add_option("--export-rev", action="store", dest="export_rev", default="", - help="Export patches from treeish object TREEISH instead " - "of head of patch-queue branch", metavar="TREEISH") (options, args) = parser.parse_args(argv) gbp.log.setup(options.color, options.verbose, options.color_scheme) -- cgit v1.2.3 From 38515059ba0a0747de0945b8a9e8902dbb87ad31 Mon Sep 17 00:00:00 2001 From: Jun Wang Date: Thu, 28 Jan 2016 17:47:15 +0800 Subject: Add tests/component/rpm/data/ Change-Id: I83de13c6695a7a7c6d14500fc5c608d621f7bb21 --- tests/component/rpm/data/.gitignore | 0 1 file changed, 0 insertions(+), 0 deletions(-) create mode 100644 tests/component/rpm/data/.gitignore diff --git a/tests/component/rpm/data/.gitignore b/tests/component/rpm/data/.gitignore new file mode 100644 index 00000000..e69de29b -- cgit v1.2.3 From bf7d95036efbeddcb7483c1e009e916240c5261d Mon Sep 17 00:00:00 2001 From: Jun Wang Date: Thu, 28 Jan 2016 18:22:05 +0800 Subject: Change .gitmodules address to local gerrit Change-Id: I87aad5e51e209dcd6bbe03b25be558600453b34d --- .gitmodules | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/.gitmodules b/.gitmodules index 6e177397..be12d77b 100644 --- a/.gitmodules +++ b/.gitmodules @@ -1,6 +1,6 @@ [submodule "tests/component/deb/data"] path = tests/component/deb/data - url = ssh://fushuai1985@review.tizen.org:29418/tools/git-buildpackage-deb-testdata + url = ssh://jenkins@109.123.100.123:29418/tools/git-buildpackage-deb-testdata [submodule "tests/component/rpm/data"] path = tests/component/rpm/data - url = ssh://fushuai1985@review.tizen.org:29418/tools/git-buildpackage-rpm-testdata + url = ssh://jenkins@r109.123.100.123:29418/tools/git-buildpackage-rpm-testdata -- cgit v1.2.3 From 7a956e92d7fc86ed44cbf468115cd43dac08d792 Mon Sep 17 00:00:00 2001 From: Jun Wang Date: Thu, 28 Jan 2016 18:41:32 +0800 Subject: Change .gitmodules address url to local gerrit Change-Id: Ic27e2b5cd4ba3aacb651568e4b351666f16af176 --- .gitmodules | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/.gitmodules b/.gitmodules index be12d77b..02d21b87 100644 --- a/.gitmodules +++ b/.gitmodules @@ -1,6 +1,6 @@ [submodule "tests/component/deb/data"] path = tests/component/deb/data - url = ssh://jenkins@109.123.100.123:29418/tools/git-buildpackage-deb-testdata + url = ssh://jenkins@109.123.100.123:29418/tizen.org-tools/git-buildpackage-deb-testdata [submodule "tests/component/rpm/data"] path = tests/component/rpm/data - url = ssh://jenkins@r109.123.100.123:29418/tools/git-buildpackage-rpm-testdata + url = ssh://jenkins@109.123.100.123:29418/tizen.org-tools/git-buildpackage-rpm-testdata -- cgit v1.2.3 From 0eae33b7dff9b06aade2ac401416cb67a368250d Mon Sep 17 00:00:00 2001 From: Jun Wang Date: Thu, 28 Jan 2016 19:09:59 +0800 Subject: deleted: tests/component/rpm/data/.gitignore Change-Id: Ib0b50f55c146e8a2f365dc10d3af51fd66f2e5a5 --- tests/component/rpm/data/.gitignore | 0 1 file changed, 0 insertions(+), 0 deletions(-) delete mode 100644 tests/component/rpm/data/.gitignore diff --git a/tests/component/rpm/data/.gitignore b/tests/component/rpm/data/.gitignore deleted file mode 100644 index e69de29b..00000000 -- cgit v1.2.3 From 27761b16936562b0d6d9ce71de948091b1cf229d Mon Sep 17 00:00:00 2001 From: Jun Wang Date: Thu, 28 Jan 2016 22:50:55 +0800 Subject: fix merge errors Change-Id: I4419bb8322f341f92db7e9e19f60ffaa93af2171 --- bin/git-pbuilder | 3 +- gbp/pkg/__init__.py | 61 ------------------- gbp/scripts/common/import_orig.py | 124 +------------------------------------- gbp/scripts/import_orig.py | 27 +++------ gbp/scripts/pq_rpm.py | 4 ++ packaging/git-buildpackage.spec | 1 + 6 files changed, 16 insertions(+), 204 deletions(-) diff --git a/bin/git-pbuilder b/bin/git-pbuilder index a9104d7a..a003b266 100644 --- a/bin/git-pbuilder +++ b/bin/git-pbuilder @@ -228,8 +228,7 @@ update|create|login) sudo "$BUILDER" --"$action" --distribution "$DIST" \ --othermirror "$OTHERMIRROR" "${OPTIONS[@]}" "$@" else - sudo "$BUILDER" --"$action" --distribution "$DIST" \ - "${OPTIONS[@]}" "$@" + sudo "$BUILDER" --"$action" --distribution "$DIST" "${OPTIONS[@]}" "$@" fi fi exit $? diff --git a/gbp/pkg/__init__.py b/gbp/pkg/__init__.py index 79067982..941b0f63 100644 --- a/gbp/pkg/__init__.py +++ b/gbp/pkg/__init__.py @@ -142,67 +142,6 @@ class PkgPolicy(object): return True return False - @classmethod - def guess_upstream_src_version(cls, filename, extra_regex=r''): - """ - Guess the package name and version from the filename of an upstream - archive. - - @param filename: filename (archive or directory) from which to guess - @type filename: C{string} - @param extra_regex: additional regex to apply, needs a 'package' and a - 'version' group - @return: (package name, version) or ('', '') - @rtype: tuple - - >>> PkgPolicy.guess_upstream_src_version('foo-bar_0.2.orig.tar.gz') - ('foo-bar', '0.2') - >>> PkgPolicy.guess_upstream_src_version('foo-Bar_0.2.orig.tar.gz') - ('foo-Bar', '0.2.orig') - >>> PkgPolicy.guess_upstream_src_version('git-bar-0.2.tar.gz') - ('git-bar', '0.2') - >>> PkgPolicy.guess_upstream_src_version('git-bar-0.2-rc1.tar.gz') - ('git-bar', '0.2-rc1') - >>> PkgPolicy.guess_upstream_src_version('git-bar-0.2:~-rc1.tar.gz') - ('git-bar', '0.2:~-rc1') - >>> PkgPolicy.guess_upstream_src_version('git-Bar-0A2d:rc1.tar.bz2') - ('git-Bar', '0A2d:rc1') - >>> PkgPolicy.guess_upstream_src_version('git-1.tar.bz2') - ('git', '1') - >>> PkgPolicy.guess_upstream_src_version('kvm_87+dfsg.orig.tar.gz') - ('kvm', '87+dfsg') - >>> PkgPolicy.guess_upstream_src_version('foo-Bar-a.b.tar.gz') - ('', '') - >>> PkgPolicy.guess_upstream_src_version('foo-bar_0.2.orig.tar.xz') - ('foo-bar', '0.2') - >>> PkgPolicy.guess_upstream_src_version('foo-bar_0.2.tar.gz') - ('foo-bar', '0.2') - >>> PkgPolicy.guess_upstream_src_version('foo-bar_0.2.orig.tar.lzma') - ('foo-bar', '0.2') - >>> PkgPolicy.guess_upstream_src_version('foo-bar-0.2.zip') - ('foo-bar', '0.2') - >>> PkgPolicy.guess_upstream_src_version('foo-bar-0.2.tlz') - ('foo-bar', '0.2') - """ - version_chars = r'[a-zA-Z\d\.\~\-\:\+]' - basename = parse_archive_filename(os.path.basename(filename))[0] - - version_filters = map ( lambda x: x % version_chars, - ( # Debian upstream tarball: package_'.orig.tar.gz' - r'^(?P[a-z\d\.\+\-]+)_(?P%s+)\.orig', - # Upstream 'package-.tar.gz' - # or Debian native 'package_.tar.gz' - # or directory 'package-': - r'^(?P[a-zA-Z\d\.\+\-]+)(-|_)(?P[0-9]%s*)')) - if extra_regex: - version_filters = extra_regex + version_filters - - for filter in version_filters: - m = re.match(filter, basename) - if m: - return (m.group('package'), m.group('version')) - return ('', '') - @staticmethod def guess_upstream_src_version(filename, extra_regex=r''): """ diff --git a/gbp/scripts/common/import_orig.py b/gbp/scripts/common/import_orig.py index 304dfd77..45e71c57 100644 --- a/gbp/scripts/common/import_orig.py +++ b/gbp/scripts/common/import_orig.py @@ -78,59 +78,6 @@ def ask_package_version(default, ver_validator_func, err_msg): # bit clearer. gbp.log.warn("\nNot a valid upstream version: '%s'.\n%s" % (version, err_msg)) - -def prepare_pristine_tar(source, pkg_name, pkg_version, pristine_commit_name, - filters=None, prefix=None, tmpdir=None): - """ - Prepare the upstream sources for pristine-tar import - - @param source: original upstream sources - @type source: C{UpstreamSource} - @param pkg_name: package name - @type pkg_name: C{str} - @param pkg_version: upstream version of the package - @type pkg_version: C{str} - @param pristine_commit_name: archive filename to commit to pristine-tar - @type pristine_commit_name: C{str} or C{None} - @param filters: filter to exclude files - @type filters: C{list} of C{str} or C{None} - @param prefix: prefix (i.e. leading directory of files) to use in - pristine-tar, set to C{None} to not mangle orig archive - @type prefix: C{str} or C{None} - @param tmpdir: temporary working dir (cleanup left to caller) - @type tmpdir: C{str} - @return: prepared source archive - @rtype: C{UpstreamSource} - """ - need_repack = False - if source.is_dir(): - if prefix is None: - prefix = '%s-%s' % (pkg_name, pkg_version) - gbp.log.info("Using guessed prefix '%s/' for pristine-tar" % prefix) - need_repack = True - else: - if prefix is not None and prefix == source.prefix: - prefix = None - comp = parse_archive_filename(pristine_commit_name)[2] - if filters or prefix is not None or source.compression != comp: - if not source.unpacked: - unpack_dir = tempfile.mkdtemp(prefix='pristine_unpack_', - dir=tmpdir) - source.unpack(unpack_dir) - need_repack = True - pristine_path = os.path.join(tmpdir, pristine_commit_name) - if need_repack: - gbp.log.debug("Packing '%s' from '%s' for pristine-tar" % - (pristine_path, source.unpacked)) - pristine = source.pack(pristine_path, filters, prefix) - else: - # Just create symlink for mangling the pristine tarball name - os.symlink(source.path, pristine_path) - pristine = source.__class__(pristine_path) - - return pristine - - def prepare_sources(source, pkg_name, pkg_version, pristine_commit_name, filters, filter_pristine, prefix, tmpdir): """ @@ -200,6 +147,7 @@ def prepare_sources(source, pkg_name, pkg_version, pristine_commit_name, tmpdir) pristine_path = pristine.path if pristine else '' return (filtered.unpacked, pristine_path) + def repack_source(source, new_name, unpack_dir, filters, new_prefix=None): """Repack the source tree""" repacked = source.pack(new_name, filters, new_prefix) @@ -262,73 +210,3 @@ def prepare_pristine_tar(source, pkg_name, pkg_version, pristine_commit_name, return pristine -def prepare_sources(source, pkg_name, pkg_version, pristine_commit_name, - filters, filter_pristine, prefix, tmpdir): - """ - Prepare upstream sources for importing - - Unpack, filter and repack sources for importing to git and to pristine-tar. - - @param source: original upstream sources - @type source: C{UpstreamSource} - @param pkg_name: package name - @type pkg_name: C{str} - @param pkg_version: upstream version of the package - @type pkg_version: C{str} - @param pristine_commit_name: archive filename to commit to pristine-tar - @type pristine_commit_name: C{str} or C{None} - @param filters: filter to exclude files - @type filters: C{list} of C{str} - @param filter_pristine: filter pristine-tar, too - @type filter_pristine: C{bool} - @param prefix: prefix (i.e. leading directory of files) to use in - pristine-tar, set to C{None} to not mangle orig archive - @type prefix: C{str} or C{None} - @param tmpdir: temporary working dir (cleanup left to caller) - @type tmpdir: C{str} - @return: path to prepared source tree and tarball to commit to pristine-tar - @rtype: C{tuple} of C{str} - """ - pristine = None - # Determine parameters for pristine tar - pristine_filters = filters if filters and filter_pristine else None - pristine_prefix = None - if prefix is not None and prefix != 'auto': - prefix_subst = {'name': pkg_name, - 'version': pkg_version, - 'upstreamversion': pkg_version} - pristine_prefix = prefix % prefix_subst - # Handle unpacked sources, i.e. importing a directory - if source.is_dir(): - if pristine_commit_name: - gbp.log.warn('Preparing unpacked sources for pristine-tar') - pristine = prepare_pristine_tar(source, pkg_name, pkg_version, - pristine_commit_name, - pristine_filters, pristine_prefix, - tmpdir) - if filters: - # Re-use sources packed for pristine-tar, if available - if pristine: - packed = pristine - else: - packed_fn = tempfile.mkstemp(prefix="packed_", dir=tmpdir, - suffix='.tar')[1] - gbp.log.debug("Packing '%s' to '%s'" % (source.path, packed_fn)) - packed = source.pack(packed_fn) - unpack_dir = tempfile.mkdtemp(prefix='filtered_', dir=tmpdir) - filtered = packed.unpack(unpack_dir, filters) - else: - filtered = source - # Handle source archives - else: - unpack_dir = tempfile.mkdtemp(prefix='filtered_', dir=tmpdir) - gbp.log.debug("Unpacking '%s' to '%s'" % (source.path, unpack_dir)) - filtered = source.unpack(unpack_dir, filters) - if pristine_commit_name: - pristine = prepare_pristine_tar(source, pkg_name, pkg_version, - pristine_commit_name, - pristine_filters, pristine_prefix, - tmpdir) - pristine_path = pristine.path if pristine else '' - return (filtered.unpacked, pristine_path) - diff --git a/gbp/scripts/import_orig.py b/gbp/scripts/import_orig.py index 6ec50021..65ff7c4a 100644 --- a/gbp/scripts/import_orig.py +++ b/gbp/scripts/import_orig.py @@ -32,10 +32,9 @@ from gbp.errors import GbpError from gbp.format import format_msg import gbp.log from gbp.pkg import compressor_opts -from gbp.scripts.common.import_orig import (orig_needs_repack, cleanup_tmp_tree, - ask_package_name, ask_package_version, - repack_source, is_link_target) - +from gbp.scripts.common.import_orig import (cleanup_tmp_tree, ask_package_name, + sk_package_version, + prepare_sources) def prepare_pristine_tar(archive, pkg, version): """ @@ -309,21 +308,13 @@ def main(argv): unpacked_orig, pristine_orig = prepare_sources( source, pkg_name, version, prepare_pristine, options.filters, options.filter_pristine_tar, None, tmpdir) - if not source.is_dir(): - unpack_dir = tempfile.mkdtemp(prefix='unpack', dir=tmpdir) - source = source.unpack(unpack_dir, options.filters) - gbp.log.debug("Unpacked '%s' to '%s'" % (source.path, source.unpacked)) - - if orig_needs_repack(source, options): - gbp.log.debug("Filter pristine-tar: repacking '%s' from '%s'" % (source.path, source.unpacked)) - repack_dir = tempfile.mkdtemp(prefix='repack', dir=tmpdir) - repack_name = repacked_tarball_name(source, sourcepackage, version) - source = repack_source(source, repack_name, repack_dir, options.filters) - - (pristine_orig, linked) = prepare_pristine_tar(source.path, - sourcepackage, - version) + # Prepare sources for importing + pristine_name = pristine_tarball_name(source, pkg_name, version) + prepare_pristine = pristine_name if options.pristine_tar else None + unpacked_orig, pristine_orig = prepare_sources( + source, pkg_name, version, prepare_pristine, options.filters, + options.filter_pristine_tar, None, tmpdir) # Don't mess up our repo with git metadata from an upstream tarball try: if os.path.isdir(os.path.join(unpacked_orig, '.git/')): diff --git a/gbp/scripts/pq_rpm.py b/gbp/scripts/pq_rpm.py index c33e67b2..a329edd5 100755 --- a/gbp/scripts/pq_rpm.py +++ b/gbp/scripts/pq_rpm.py @@ -643,6 +643,10 @@ def main(argv): try: parser = GbpOptionParserRpm(command=os.path.basename(argv[0]), prefix='', usage=USAGE_STRING) + except ConfigParser.ParsingError as err: + gbp.log.err('Invalid config file: %s' % err) + return 1 + parser.add_boolean_config_file_option(option_name="patch-numbers", dest="patch_numbers") parser.add_option("-v", "--verbose", action="store_true", dest="verbose", diff --git a/packaging/git-buildpackage.spec b/packaging/git-buildpackage.spec index a9a034df..f44750ac 100644 --- a/packaging/git-buildpackage.spec +++ b/packaging/git-buildpackage.spec @@ -163,6 +163,7 @@ GIT_CEILING_DIRECTORIES=%{_builddir} \ %install rm -rf %{buildroot} WITHOUT_NOSETESTS=1 %{__python} ./setup.py install --root=%{buildroot} --prefix=/usr +rm -rf %{buildroot}%{python_sitelib}/*info %if %{with docs} # Install man pages -- cgit v1.2.3 From be551641d5e1b5fc72d6b3cda897f6ff8a52cc1e Mon Sep 17 00:00:00 2001 From: Jun Wang Date: Thu, 28 Jan 2016 23:01:09 +0800 Subject: fix import error Change-Id: I97a7737cf643f20b6e7b30b77c6d6987fe0b7235 --- gbp/scripts/import_orig.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/gbp/scripts/import_orig.py b/gbp/scripts/import_orig.py index 65ff7c4a..e9b6a653 100644 --- a/gbp/scripts/import_orig.py +++ b/gbp/scripts/import_orig.py @@ -33,7 +33,7 @@ from gbp.format import format_msg import gbp.log from gbp.pkg import compressor_opts from gbp.scripts.common.import_orig import (cleanup_tmp_tree, ask_package_name, - sk_package_version, + ask_package_version, prepare_sources) def prepare_pristine_tar(archive, pkg, version): -- cgit v1.2.3 From d193574974241cfa4e8b223b06a385abb5d2ecbc Mon Sep 17 00:00:00 2001 From: Jun Wang Date: Fri, 29 Jan 2016 00:28:34 +0800 Subject: fix bugs Change-Id: I406d49bdbfb8b978b62a6bb1fb770df37043f81c --- gbp/git/repository.py | 18 ------------------ packaging/git-buildpackage.spec | 2 +- 2 files changed, 1 insertion(+), 19 deletions(-) diff --git a/gbp/git/repository.py b/gbp/git/repository.py index 4d7b24dc..20251a00 100644 --- a/gbp/git/repository.py +++ b/gbp/git/repository.py @@ -1520,24 +1520,6 @@ class GitRepository(object): work_tree=unpack_dir) return self.write_tree(git_index_file) - def create_tree(self, unpack_dir): - """ - Create a tree object out of a directory content - - @param unpack_dir: content to add - @type unpack_dir: C{str} - @return: the tree object hash - @rtype: C{str} - """ - git_index_file = os.path.join(self.path, self._git_dir, 'gbp_index') - try: - os.unlink(git_index_file) - except OSError: - pass - self.add_files('.', force=True, index_file=git_index_file, - work_tree=unpack_dir) - return self.write_tree(git_index_file) - def commit_dir(self, unpack_dir, msg, branch, other_parents=None, author={}, committer={}, create_missing_branch=False): """ diff --git a/packaging/git-buildpackage.spec b/packaging/git-buildpackage.spec index f44750ac..134f0315 100644 --- a/packaging/git-buildpackage.spec +++ b/packaging/git-buildpackage.spec @@ -231,7 +231,7 @@ done %dir %{python_sitelib}/gbp/pkg %dir %{python_sitelib}/gbp/scripts %dir %{python_sitelib}/gbp/scripts/common -%{python_sitelib}/gbp-* +#%{python_sitelib}/gbp-* %{python_sitelib}/gbp/*.py* %{python_sitelib}/gbp/scripts/__init__.py* %{python_sitelib}/gbp/scripts/clone.py* -- cgit v1.2.3 From f5e0a3befc8c182a316ae0ae67ccb110a74a65a0 Mon Sep 17 00:00:00 2001 From: Jun Wang Date: Fri, 29 Jan 2016 00:51:48 +0800 Subject: backup docs Change-Id: I8fd630aa2a260d6516cc5fa4d82edde45e419c6a --- docs/manpages/gbp-buildpackage.sgml | 55 ++----------------------------------- docs/manpages/gbp-dch.sgml | 11 -------- docs/manpages/gbp-import-orig.sgml | 11 +------- docs/manpages/gbp-pq.sgml | 9 ------ docs/manpages/gbp-pull.sgml | 7 ----- docs/manpages/gbp.sgml | 16 ----------- packaging/git-buildpackage.spec | 13 +++------ 7 files changed, 8 insertions(+), 114 deletions(-) diff --git a/docs/manpages/gbp-buildpackage.sgml b/docs/manpages/gbp-buildpackage.sgml index 59924880..d0b5a134 100644 --- a/docs/manpages/gbp-buildpackage.sgml +++ b/docs/manpages/gbp-buildpackage.sgml @@ -36,7 +36,7 @@ DIST ARCH - =PBUILDER_OPTIONS + GPG-KEYID COMMAND @@ -45,9 +45,8 @@ COMMAND - tag-format - tag-format - tag-msg-format + TAG-FORMAT + TAG-FORMAT [TAG|BRANCH|TREEISH] @@ -276,21 +275,6 @@ - - =BRANCH_NAME - =COLOR_SCHEME - - - Colors to use in output (when color is enabled). The format for - COLOR_SCHEME is - '<debug>:<info>:<warning>:<error>'. - Numerical values and color names are accepted, empty fields imply - the default color. For example --git-color-scheme='cyan:34::' would - show debug messages in cyan, info messages in blue and other messages - in default (i.e. warning and error messages in red). - - - =BRANCH_NAME @@ -353,27 +337,6 @@ - - GPG-KEYID - - - - use this keyid for gpg signing tags - COMMAND - - - - excecute COMMAND after tagging a new - version. - - - Exported environment variables are: GBP_TAG (the name - of the generated tag), GBP_BRANCH (the branch the - package was build from) and GBP_SHA1 (the sha1 of the - commit the tag was created at). - - - COMMAND @@ -408,10 +371,6 @@ COMMAND - - - COMMAND - execute COMMAND after exporting the source @@ -482,14 +441,6 @@ - - tag-msg-format - - - use this tag message format when signing Debian versions, - default is %(pkg)s Debian release %(version)s - - diff --git a/docs/manpages/gbp-dch.sgml b/docs/manpages/gbp-dch.sgml index 0959ca22..8ffdc4f6 100644 --- a/docs/manpages/gbp-dch.sgml +++ b/docs/manpages/gbp-dch.sgml @@ -372,17 +372,6 @@ - - customization-file - - - - Load Python code from customization-file. - At the moment, the only useful thing the code can do is define a - custom format_changelog_entry() function. - - - diff --git a/docs/manpages/gbp-import-orig.sgml b/docs/manpages/gbp-import-orig.sgml index db3433bc..714a5340 100644 --- a/docs/manpages/gbp-import-orig.sgml +++ b/docs/manpages/gbp-import-orig.sgml @@ -77,7 +77,7 @@ - + Merge the upstream branch to the debian branch after import @@ -232,15 +232,6 @@ - - - - - Run command interactively, i.e. ask package name and version if - needed. - - - diff --git a/docs/manpages/gbp-pq.sgml b/docs/manpages/gbp-pq.sgml index cc31145f..e0942083 100644 --- a/docs/manpages/gbp-pq.sgml +++ b/docs/manpages/gbp-pq.sgml @@ -23,7 +23,6 @@ topic num - @@ -127,7 +126,6 @@ &man.common.options.description; - =COLOR_SCHEME @@ -158,13 +156,6 @@ - - - - Whether to drop (delete) the patch queue branch after - a succesful export - - diff --git a/docs/manpages/gbp-pull.sgml b/docs/manpages/gbp-pull.sgml index 775472bd..74ff37ce 100644 --- a/docs/manpages/gbp-pull.sgml +++ b/docs/manpages/gbp-pull.sgml @@ -68,13 +68,6 @@ remote repository. - - - - Update all remote-tracking branches that have identical name in the - remote repository. - - diff --git a/docs/manpages/gbp.sgml b/docs/manpages/gbp.sgml index c0fdddc7..00c9e77f 100644 --- a/docs/manpages/gbp.sgml +++ b/docs/manpages/gbp.sgml @@ -21,8 +21,6 @@ &gbp; - - @@ -43,20 +41,6 @@ Print help - - - - - Print the programs version - - - - - - - List all available commands - - diff --git a/packaging/git-buildpackage.spec b/packaging/git-buildpackage.spec index 134f0315..be1a6826 100644 --- a/packaging/git-buildpackage.spec +++ b/packaging/git-buildpackage.spec @@ -12,15 +12,11 @@ URL: https://honk.sigxcpu.org/piki/projects/git-buildpackage/ Source0: %{name}_%{version}.tar.gz # Conditional package names for requirements -%if 0%{?fedora} || 0%{?centos_ver} > 7 -%define dpkg_pkg_name dpkg-dev -%else -%if 0%{?centos_version} +%if 0%{?fedora} || 0%{?centos_ver} %define dpkg_pkg_name dpkg-devel %else %define dpkg_pkg_name dpkg %endif -%endif %if 0%{?suse_version} && 0%{?suse_version} < 1230 %define devscripts_pkg_name devscripts-fixes @@ -34,7 +30,7 @@ Source0: %{name}_%{version}.tar.gz %define man_pkg_name man %endif -%if 0%{?fedora} || 0%{?centos_version} || 0%{?centos_ver} || 0%{?tizen_version:1} +%if 0%{?fedora} || 0%{?centos_ver} || 0%{?tizen_version:1} %define python_pkg_name python %else %define python_pkg_name python-base @@ -209,8 +205,8 @@ cat >> files.list << EOF EOF %endif -# Disable the debian tools for old CentOS -%if 0%{?centos_version} && 0%{?centos_ver} < 7 +# Disable the debian tools for CentOS +%if 0%{?centos_version} for f in `cat files.list`; do rm -rfv %{buildroot}/$f done @@ -231,7 +227,6 @@ done %dir %{python_sitelib}/gbp/pkg %dir %{python_sitelib}/gbp/scripts %dir %{python_sitelib}/gbp/scripts/common -#%{python_sitelib}/gbp-* %{python_sitelib}/gbp/*.py* %{python_sitelib}/gbp/scripts/__init__.py* %{python_sitelib}/gbp/scripts/clone.py* -- cgit v1.2.3 From 7c4bfa8856371bba2ef9da4fddf8d3d7abbff9c8 Mon Sep 17 00:00:00 2001 From: Jun Wang Date: Fri, 29 Jan 2016 16:30:03 +0800 Subject: fix build problem on Debian_8 Change-Id: I145928ae1416f7847b4d8e6729c1daf07e2ab757 --- debian/control | 1 + 1 file changed, 1 insertion(+) diff --git a/debian/control b/debian/control index 705fd7cd..827c2e16 100644 --- a/debian/control +++ b/debian/control @@ -16,6 +16,7 @@ Build-Depends: python-pkg-resources, python-setuptools, sgml2x, + librpm-tizen, # For rpm (epydoc) python-rpm Standards-Version: 3.9.4 -- cgit v1.2.3 From a7a9620bcf43c5c14e0205b3fd9ee190df5c0439 Mon Sep 17 00:00:00 2001 From: Markus Lehtonen Date: Wed, 19 Nov 2014 17:19:20 +0200 Subject: buildpackage-rpm: look for remote upstream branches Consider remote branches, too, while looking for the upstream branch when trying to guess if a package is native or not. Change-Id: I3dbbb49816d1d294d81209ea5ab5870e053fd66a Signed-off-by: Markus Lehtonen --- gbp/scripts/buildpackage_rpm.py | 12 +++++++++++- tests/component/rpm/test_buildpackage_rpm.py | 8 +++++++- 2 files changed, 18 insertions(+), 2 deletions(-) diff --git a/gbp/scripts/buildpackage_rpm.py b/gbp/scripts/buildpackage_rpm.py index 7e10c463..56db5e13 100755 --- a/gbp/scripts/buildpackage_rpm.py +++ b/gbp/scripts/buildpackage_rpm.py @@ -288,7 +288,17 @@ def export_patches(repo, spec, export_treeish, options): def is_native(repo, options): """Determine whether a package is native or non-native""" if options.native.is_auto(): - return not repo.has_branch(options.upstream_branch) + if repo.has_branch(options.upstream_branch): + return False + # Check remotes, too + for remote_branch in repo.get_remote_branches(): + remote, branch = remote_branch.split('/', 1) + if branch == options.upstream_branch: + gbp.log.debug("Found upstream branch '%s' from remote '%s'" % + (remote, branch)) + return False + return True + return options.native.is_on() diff --git a/tests/component/rpm/test_buildpackage_rpm.py b/tests/component/rpm/test_buildpackage_rpm.py index 3060f84b..88a66fc0 100644 --- a/tests/component/rpm/test_buildpackage_rpm.py +++ b/tests/component/rpm/test_buildpackage_rpm.py @@ -139,10 +139,16 @@ class TestGbpRpm(RpmRepoTestBase): def test_non_native_build(self): """Basic test of non-native pkg""" - self.init_test_repo('gbp-test') + repo = self.init_test_repo('gbp-test') eq_(mock_gbp([]), 0) self.check_rpms('../rpmbuild/RPMS/*') + # Test nativity guessing from remote branches by creating a dummy + # remote branch + repo.update_ref('refs/remotes/fooremote/foobranch', + 'srcdata/gbp-test/upstream') + eq_(mock_gbp(['--git-upstream-branch=foobranch']), 0) + def test_option_native(self): """Test the --git-native option""" self.init_test_repo('gbp-test2') -- cgit v1.2.3 From 1c254a3f1c525d5eb6d0cb85341f4ac14573f7dc Mon Sep 17 00:00:00 2001 From: Markus Lehtonen Date: Wed, 3 Dec 2014 16:40:46 +0200 Subject: rpm: suppress stderr when unpacking src.rpm Change-Id: I055e94f905048141268ceb9172b4e10fcb5cdc58 Signed-off-by: Markus Lehtonen --- gbp/rpm/__init__.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/gbp/rpm/__init__.py b/gbp/rpm/__init__.py index 0e04b4df..4c5c22bf 100644 --- a/gbp/rpm/__init__.py +++ b/gbp/rpm/__init__.py @@ -100,7 +100,7 @@ class SrcRpmFile(object): """ gbpc.RunAtCommand('rpm2cpio', [self.srpmfile, '|', 'cpio', '-id'], - shell=True)(dir=dest_dir) + shell=True, capture_stderr=True)(dir=dest_dir) class SpecFile(object): -- cgit v1.2.3 From 35b806b7964bbeafe460d9bb707825adc6e6e346 Mon Sep 17 00:00:00 2001 From: Markus Lehtonen Date: Wed, 3 Dec 2014 17:37:51 +0200 Subject: UpstreamSource: suppress stderr from tar in _determine_prefix() Change-Id: I3a0e51de2114e2aa9f9a12c41a9ed4c242fa2127 Signed-off-by: Markus Lehtonen --- gbp/pkg/__init__.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/gbp/pkg/__init__.py b/gbp/pkg/__init__.py index 941b0f63..8162286b 100644 --- a/gbp/pkg/__init__.py +++ b/gbp/pkg/__init__.py @@ -359,7 +359,7 @@ class UpstreamSource(object): files.append((typ, info.filename)) elif self._archive_fmt == 'tar': popen = subprocess.Popen(['tar', '-t', '-v', '-f', self.path], - stdout=subprocess.PIPE) + stdout=subprocess.PIPE, stderr=subprocess.PIPE) out, _err = popen.communicate() if popen.returncode: raise GbpError("Listing tar archive content failed") -- cgit v1.2.3 From 98ff9a7e1ff2acf91e03ce6bbb0a88c5b72603d6 Mon Sep 17 00:00:00 2001 From: Jun Wang Date: Mon, 1 Feb 2016 21:43:27 +0800 Subject: fix errors in pq_rpm.py Change-Id: Ie8acc86904b75387bf3fbe203ba3b62eeec74c5b --- gbp/scripts/pq_rpm.py | 36 +----------------------------------- 1 file changed, 1 insertion(+), 35 deletions(-) diff --git a/gbp/scripts/pq_rpm.py b/gbp/scripts/pq_rpm.py index a329edd5..e19218a9 100755 --- a/gbp/scripts/pq_rpm.py +++ b/gbp/scripts/pq_rpm.py @@ -30,7 +30,7 @@ import subprocess import gbp.tmpfile as tempfile from gbp.config import GbpOptionParserRpm from gbp.rpm.git import GitRepositoryError, RpmGitRepository -from gbp.git.modifier import GitModifier +from gbp.git.modifier import GitModifier, GitTz from gbp.command_wrappers import GitCommand, CommandExecFailed from gbp.errors import GbpError import gbp.log @@ -148,40 +148,6 @@ def generate_patches(repo, start, squash, end, outdir, options): start = merge_sha1 print start - start_sha1 = repo.rev_parse("%s^0" % start) - try: - end_commit = end - end_commit_sha1 = repo.rev_parse("%s^0" % end_commit) - except GitRepositoryError: - # In case of plain tree-ish objects, assume current branch head is the - # last commit - end_commit = "HEAD" - end_commit_sha1 = repo.rev_parse("%s^0" % end_commit) - - start_sha1 = repo.rev_parse("%s^0" % start) - if repo.get_merge_base(start_sha1, end_commit_sha1) != start_sha1: - raise GbpError("Start commit '%s' not an ancestor of end commit " - "'%s'" % (start, end_commit)) - # Squash commits, if requested - if squash[0]: - if squash[0] == 'HEAD': - squash[0] = end_commit - squash_sha1 = repo.rev_parse("%s^0" % squash[0]) - if start_sha1 != squash_sha1: - if not squash_sha1 in repo.get_commits(start, end_commit): - raise GbpError("Given squash point '%s' not in the history " - "of end commit '%s'" % (squash[0], end_commit)) - # Shorten SHA1s - squash_sha1 = repo.rev_parse(squash_sha1, short=7) - start_sha1 = repo.rev_parse(start_sha1, short=7) - gbp.log.info("Squashing commits %s..%s into one monolithic diff" % - (start_sha1, squash_sha1)) - patch_fn = format_diff(outdir, squash[1], repo, - start_sha1, squash_sha1) - if patch_fn: - patches.append(patch_fn) - start = squash_sha1 - # Generate patches for commit in reversed(repo.get_commits(start, end_commit)): info = repo.get_commit_info(commit) -- cgit v1.2.3 From 686db8d36d7a9195abb4c503651feea44e2c50d5 Mon Sep 17 00:00:00 2001 From: Jun Wang Date: Tue, 2 Feb 2016 23:16:52 +0800 Subject: Update the version to 0.6.26 Change-Id: Ia8f0e526da0ecc9d765614fe5b3daf37c08e9171 --- packaging/git-buildpackage.spec | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/packaging/git-buildpackage.spec b/packaging/git-buildpackage.spec index be1a6826..6f1becc8 100644 --- a/packaging/git-buildpackage.spec +++ b/packaging/git-buildpackage.spec @@ -3,7 +3,7 @@ Name: git-buildpackage Summary: Build packages from git -Version: 0.6.25 +Version: 0.6.26 Release: 0 Group: Development/Tools/Building License: GPLv2 -- cgit v1.2.3 From 1fa96204fc005cfca9c056386aab8631dee2efbe Mon Sep 17 00:00:00 2001 From: Jun Wang Date: Wed, 3 Feb 2016 23:40:55 +0800 Subject: fix gbp.log error in opensuse Change-Id: I1fc96948cbd8da9a6325b67ab511ae2c6a199c6e --- gbp/log.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/gbp/log.py b/gbp/log.py index 7b9a4aa8..5f8ae107 100644 --- a/gbp/log.py +++ b/gbp/log.py @@ -172,8 +172,8 @@ def _parse_color_scheme(color_scheme=""): def getLogger(*args, **kwargs): """Gbp-specific function""" - if not issubclass(logging.getLoggerClass(), GbpLogger): - logging.setLoggerClass(GbpLogger) +# if not issubclass(logging.getLoggerClass(), GbpLogger): + logging.setLoggerClass(GbpLogger) color = kwargs.pop('color') if 'color' in kwargs else 'auto' logger = logging.getLogger(*args, **kwargs) if hasattr(logger, 'default_handlers') and not logger.default_handlers: -- cgit v1.2.3 From 0c8db0ce4d200a09cf15e7a34ab1776fb11efdb4 Mon Sep 17 00:00:00 2001 From: Jun Wang Date: Thu, 4 Feb 2016 23:05:20 +0800 Subject: Fix errors logs when __import__ faild,like "No handlers could be found fo logger" Change-Id: I785e402e13879c6010780d3a453ea78956833fe1 --- gbp/log.py | 4 ++-- gbp/rpm/lib_rpm.py | 1 + 2 files changed, 3 insertions(+), 2 deletions(-) diff --git a/gbp/log.py b/gbp/log.py index 5f8ae107..7b9a4aa8 100644 --- a/gbp/log.py +++ b/gbp/log.py @@ -172,8 +172,8 @@ def _parse_color_scheme(color_scheme=""): def getLogger(*args, **kwargs): """Gbp-specific function""" -# if not issubclass(logging.getLoggerClass(), GbpLogger): - logging.setLoggerClass(GbpLogger) + if not issubclass(logging.getLoggerClass(), GbpLogger): + logging.setLoggerClass(GbpLogger) color = kwargs.pop('color') if 'color' in kwargs else 'auto' logger = logging.getLogger(*args, **kwargs) if hasattr(logger, 'default_handlers') and not logger.default_handlers: diff --git a/gbp/rpm/lib_rpm.py b/gbp/rpm/lib_rpm.py index 4bad44e7..da914207 100644 --- a/gbp/rpm/lib_rpm.py +++ b/gbp/rpm/lib_rpm.py @@ -25,6 +25,7 @@ try: # Try to load special RPM lib to be used for GBP (only) librpm = __import__(RpmPkgPolicy.python_rpmlib_module_name) except ImportError: + gbp.log.getLogger("gbp") gbp.log.warn("Failed to import '%s' as rpm python module, using host's " "default rpm library instead" % RpmPkgPolicy.python_rpmlib_module_name) -- cgit v1.2.3 From d4009ccff5959c7903270e00ff94b0041f9321ff Mon Sep 17 00:00:00 2001 From: Jun Wang Date: Wed, 2 Mar 2016 18:33:22 +0800 Subject: change version files to match 0.6.27 Change-Id: I6dc3023b4bccffef4f0113229ae0eaf4ddcfc74f --- debian/changelog | 64 +++++++++++++++++++++++++++++++++++++- packaging/git-buildpackage.changes | 57 +++++++++++++++++++++++++++++++++ packaging/git-buildpackage.spec | 4 +-- 3 files changed, 122 insertions(+), 3 deletions(-) diff --git a/debian/changelog b/debian/changelog index fcac7dce..ee6ad668 100644 --- a/debian/changelog +++ b/debian/changelog @@ -1,4 +1,66 @@ -git-buildpackage (0.6.25-tizen20150804) unstable; urgency=low +git-buildpackage (0.6.27-tizen20160302) unstable; urgency=medium + + * Fix error logs when __import__ faild,like "No handlers could be found fo logger" + * Fix build problem on Debian 8 + + -- Jun Wang Wed, 02 Mar 2016 07:47:21 +0100 + +git-buildpackage (0.6.22-tizen20150206) unstable; urgency=low + + * Rebase on top of upstream version 0.6.22 + * Experimental support for BitBake + - Introduce import-bb tool. + This is the first tool in an effort of enabling gbp in the BitBake build + environment. Gbp-import-bb is a tool for importing packages from a + BitBake-based "combined" distro repository into individual per-package + Git repositories. + - Introduce pq-bb tool. + This is a tool for managing patch-queues for packages maintained in the + BitBake packaging format (.bb recipes). + - Introduce buildpackage-bb tool. + Initial version of the tool for building BitBake packages from Git. + NOTE: The buildpackage-bb tool itself is able to operate even without an + initialized BitBake build environment although the build likely fails in + this case. However, this makes it possible to export the packaging meta + data, for example. + - Introcude clone-bb tool. + This is a new tool for helping to clone remote per-package Git + repositories when working in BitBake-based "full distro" build + environment. This is useful in the case that individual packages are + actually maintained in per-package Git repositories (like Tizen). That + is, the full distro repository that the developer operates in is + composed of the packaging meta data from the individual per-package + repositories. When willing to contribute to a package the developer + would use clone-bb to clone the correct per-package repository and make + his changes there. + NOTE: clone-bb uses GBP_PACKAGING_REPO variable to determine the remote + repository URI. This variable should be defined in the package recipes + in order to make clone-bb usable. + - Introduce submit-bb tool. + This is a Tizen-specific tool for creating and pushing special submit + tags. + * pq-rpm: better error message + * buildpackage-rpm: look for remote upstream branches. + Consider remote branches, too, while looking for the upstream branch + when trying to guess if a package is native or not. + * rpm packaging changes + - enable CentOS 7. + - include python egg-info in -common. + * rpm: suppress stderr when unpacking src.rpm + * UpstreamSource: suppress stderr from tar in _determine_prefix() + * patchseries: strip numbering when guessing subject from filename + * Changes in logging + - don't propagate to ancestor loggers + - don't initialize handlers in GbpLogger init. + Better compatibility with 3rd party modules that have their own logging + initializations. + * Features/fixes in GitRepository + - GitRepository/__git_inout: correctly handle input error + - GitRepository.create_tag: add 'annotate' argument. + For forcing the creation of annotated tags. Causes the an editor to be + spawned if no message is given. + + -- Markus Lehtonen Fri, 06 Feb 2015 10:36:26 +0200 * Upgrade version to 0.6.25 diff --git a/packaging/git-buildpackage.changes b/packaging/git-buildpackage.changes index b6b0eea4..517e5ad2 100644 --- a/packaging/git-buildpackage.changes +++ b/packaging/git-buildpackage.changes @@ -1,6 +1,63 @@ * Thu Aug 04 2015 Rong Jinhui tizen/0.6.25-20150804 - Upgrade version to 0.6.25 +* Wed Mar 02 2016 Jun Wang tizen/0.6.27-20160302 +- Upgrade version to 0.6.27 + +* Fri Feb 06 2015 Markus Lehtonen tizen/0.6.22-20150206 +- Rebase on top of upstream version 0.6.22 +- Experimental support for BitBake + * Introduce import-bb tool. + This is the first tool in an effort of enabling gbp in the BitBake build + environment. Gbp-import-bb is a tool for importing packages from a + BitBake-based "combined" distro repository into individual per-package + Git repositories. + * Introduce pq-bb tool. + This is a tool for managing patch-queues for packages maintained in the + BitBake packaging format (.bb recipes). + * Introduce buildpackage-bb tool. + Initial version of the tool for building BitBake packages from Git. + NOTE: The buildpackage-bb tool itself is able to operate even without an + initialized BitBake build environment although the build likely fails in + this case. However, this makes it possible to export the packaging meta + data, for example. + * Introcude clone-bb tool. + This is a new tool for helping to clone remote per-package Git + repositories when working in BitBake-based "full distro" build + environment. This is useful in the case that individual packages are + actually maintained in per-package Git repositories (like Tizen). That + is, the full distro repository that the developer operates in is + composed of the packaging meta data from the individual per-package + repositories. When willing to contribute to a package the developer + would use clone-bb to clone the correct per-package repository and make + his changes there. + NOTE: clone-bb uses GBP_PACKAGING_REPO variable to determine the remote + repository URI. This variable should be defined in the package recipes + in order to make clone-bb usable. + * Introduce submit-bb tool. + This is a Tizen-specific tool for creating and pushing special submit + tags. +- pq-rpm: better error message +- buildpackage-rpm: look for remote upstream branches. + Consider remote branches, too, while looking for the upstream branch + when trying to guess if a package is native or not. +- rpm packaging changes + * enable CentOS 7. + * include python egg-info in -common. +- rpm: suppress stderr when unpacking src.rpm +- UpstreamSource: suppress stderr from tar in _determine_prefix() +- patchseries: strip numbering when guessing subject from filename +- Changes in logging + * don't propagate to ancestor loggers + * don't initialize handlers in GbpLogger init. + Better compatibility with 3rd party modules that have their own logging + initializations. +- Features/fixes in GitRepository + * GitRepository/__git_inout: correctly handle input error + * GitRepository.create_tag: add 'annotate' argument. + For forcing the creation of annotated tags. Causes the an editor to be + spawned if no message is given. + * Thu Aug 28 2014 Markus Lehtonen tizen/0.6.15-20140828 - Rebase on top of upstream version 0.6.15 - Changes in buildpackage-rpm diff --git a/packaging/git-buildpackage.spec b/packaging/git-buildpackage.spec index 6f1becc8..1a2f49b8 100644 --- a/packaging/git-buildpackage.spec +++ b/packaging/git-buildpackage.spec @@ -3,7 +3,7 @@ Name: git-buildpackage Summary: Build packages from git -Version: 0.6.26 +Version: 0.6.27 Release: 0 Group: Development/Tools/Building License: GPLv2 @@ -111,7 +111,7 @@ Recommends: rpm-build %else Requires: rpm-build %endif -Provides: tizen-gbp-rpm = 20150804 +Provides: tizen-gbp-rpm = 20160302 %description rpm Set of tools from Debian that integrate the package build system with Git. -- cgit v1.2.3 From 96d866bdb1fa0516ca92613eef871ce46e506d84 Mon Sep 17 00:00:00 2001 From: Jun Wang Date: Fri, 4 Mar 2016 23:24:24 +0800 Subject: change the log Change-Id: Iddd56c43056a5c020c33ef73e9f4ccbdbf6d0f20 --- packaging/git-buildpackage.changes | 3 --- 1 file changed, 3 deletions(-) diff --git a/packaging/git-buildpackage.changes b/packaging/git-buildpackage.changes index 517e5ad2..5f8ecf55 100644 --- a/packaging/git-buildpackage.changes +++ b/packaging/git-buildpackage.changes @@ -1,6 +1,3 @@ -* Thu Aug 04 2015 Rong Jinhui tizen/0.6.25-20150804 -- Upgrade version to 0.6.25 - * Wed Mar 02 2016 Jun Wang tizen/0.6.27-20160302 - Upgrade version to 0.6.27 -- cgit v1.2.3 From 94dcd48a9a36c23c0442b6b986dd0514ab94ebd5 Mon Sep 17 00:00:00 2001 From: Jun Wang Date: Fri, 4 Mar 2016 23:45:41 +0800 Subject: change log to debian/0.6.27 tag Change-Id: I37c3fd08ba9286212aa333d79becbb67de97a35c --- packaging/git-buildpackage.changes | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/packaging/git-buildpackage.changes b/packaging/git-buildpackage.changes index 5f8ecf55..8376e383 100644 --- a/packaging/git-buildpackage.changes +++ b/packaging/git-buildpackage.changes @@ -1,4 +1,4 @@ -* Wed Mar 02 2016 Jun Wang tizen/0.6.27-20160302 +* Wed Mar 02 2016 Jun Wang debian/0.6.27 - Upgrade version to 0.6.27 * Fri Feb 06 2015 Markus Lehtonen tizen/0.6.22-20150206 -- cgit v1.2.3 From fd8cbaa93985a1a59fc01a5b894af2fc2d4d094a Mon Sep 17 00:00:00 2001 From: Jun Wang Date: Sat, 5 Mar 2016 00:04:47 +0800 Subject: Add tests/component/rpm/data Change-Id: Id44fcc89fd290ec821a981294a3f4b78d3a17fe6 --- tests/component/rpm/data/.keep | 0 1 file changed, 0 insertions(+), 0 deletions(-) create mode 100644 tests/component/rpm/data/.keep diff --git a/tests/component/rpm/data/.keep b/tests/component/rpm/data/.keep new file mode 100644 index 00000000..e69de29b -- cgit v1.2.3 From 238b58e662a090051e0bd21abd829cdd912dc8ff Mon Sep 17 00:00:00 2001 From: Jun Wang Date: Mon, 7 Mar 2016 19:25:33 +0800 Subject: change tag name to tizen/0.6.27-20160302 Change-Id: I30395761b89947673da8b71d850f8e6e3ae3f6b0 --- packaging/git-buildpackage.changes | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/packaging/git-buildpackage.changes b/packaging/git-buildpackage.changes index 8376e383..5f8ecf55 100644 --- a/packaging/git-buildpackage.changes +++ b/packaging/git-buildpackage.changes @@ -1,4 +1,4 @@ -* Wed Mar 02 2016 Jun Wang debian/0.6.27 +* Wed Mar 02 2016 Jun Wang tizen/0.6.27-20160302 - Upgrade version to 0.6.27 * Fri Feb 06 2015 Markus Lehtonen tizen/0.6.22-20150206 -- cgit v1.2.3 From 6ade3397d26c8869f93189b9143289bd865f8fbb Mon Sep 17 00:00:00 2001 From: Jun Wang Date: Mon, 7 Mar 2016 21:59:57 +0800 Subject: change PKGBUILD to new version Change-Id: Ib0d8662ee02d4e62560aec54c64304faaf9ea5cc --- packaging/PKGBUILD | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/packaging/PKGBUILD b/packaging/PKGBUILD index dbe4b00b..60ffa9f6 100644 --- a/packaging/PKGBUILD +++ b/packaging/PKGBUILD @@ -1,6 +1,6 @@ pkgbase='git-buildpackage' pkgname=('git-buildpackage-rpm' 'git-buildpackage-common' 'git-buildpackage-doc') -pkgver=0.6.15 +pkgver=0.6.27 pkgrel=0 pkgdesc="Tools from Debian to integrate the package build system with Git" arch=(any) @@ -53,7 +53,7 @@ package_git-buildpackage-common() { package_git-buildpackage-rpm() { depends=("git-buildpackage-common=$pkgver-$pkgrel" "rpm") - provides=("tizen-gbp-rpm=20140605") + provides=("tizen-gbp-rpm=20160302") cd $srcdir/$pkgbase-$pkgver WITHOUT_NOSETESTS=1 \ python2 setup.py install \ -- cgit v1.2.3 From b31114407f241f6735f7f2348cf9b32d2209f8ca Mon Sep 17 00:00:00 2001 From: Jun Wang Date: Mon, 7 Mar 2016 23:22:54 +0800 Subject: Remove unused functions and multiple defines Change-Id: I36c7b6d9c0b03b9d4659cc0b531bc371f77049e4 --- gbp/config.py | 4 ---- gbp/scripts/common/import_orig.py | 10 ---------- gbp/scripts/import_orig.py | 39 --------------------------------------- gbp/scripts/pq.py | 1 - 4 files changed, 54 deletions(-) diff --git a/gbp/config.py b/gbp/config.py index 225ae65c..9fd31b73 100644 --- a/gbp/config.py +++ b/gbp/config.py @@ -160,7 +160,6 @@ class GbpOptionParser(OptionParser): 'allow-unauthenticated': 'False', 'symlink-orig': 'True', 'purge': 'True', - 'tmp-dir' : '/var/tmp/gbp/', 'drop': 'False', 'commit': 'False', 'tmp-dir' : '/var/tmp/gbp/', @@ -311,9 +310,6 @@ class GbpOptionParser(OptionParser): "'%(symlink-orig)s'"), 'purge': "Purge exported package build directory. Default is '%(purge)s'", - 'tmp-dir': - ("Base directory under which temporary directories are " - "created, default is '%(tmp-dir)s'"), 'drop': ("In case of 'export' drop the patch-queue branch " "after export. Default is '%(drop)s'"), diff --git a/gbp/scripts/common/import_orig.py b/gbp/scripts/common/import_orig.py index 45e71c57..16244423 100644 --- a/gbp/scripts/common/import_orig.py +++ b/gbp/scripts/common/import_orig.py @@ -148,16 +148,6 @@ def prepare_sources(source, pkg_name, pkg_version, pristine_commit_name, pristine_path = pristine.path if pristine else '' return (filtered.unpacked, pristine_path) -def repack_source(source, new_name, unpack_dir, filters, new_prefix=None): - """Repack the source tree""" - repacked = source.pack(new_name, filters, new_prefix) - if source.is_tarball(): # the tarball was filtered on unpack - repacked.unpacked = source.unpacked - else: # otherwise unpack the generated tarball get a filtered tree - repacked.unpack(unpack_dir) - return repacked - - def prepare_pristine_tar(source, pkg_name, pkg_version, pristine_commit_name, filters=None, prefix=None, tmpdir=None): """ diff --git a/gbp/scripts/import_orig.py b/gbp/scripts/import_orig.py index e9b6a653..9d183b6d 100644 --- a/gbp/scripts/import_orig.py +++ b/gbp/scripts/import_orig.py @@ -36,45 +36,6 @@ from gbp.scripts.common.import_orig import (cleanup_tmp_tree, ask_package_name, ask_package_version, prepare_sources) -def prepare_pristine_tar(archive, pkg, version): - """ - Prepare the upstream source for pristine tar import. - - This checks if the upstream source is actually a tarball - and creates a symlink from I{archive} - to I{_.orig.tar.} so pristine-tar will - see the correct basename. - - @param archive: the upstream source's name - @type archive: C{str} - @param pkg: the source package's name - @type pkg: C{str} - @param version: the upstream version number - @type version: C{str} - @rtype: C{str} - """ - linked = False - if os.path.isdir(archive): - return None - - ext = os.path.splitext(archive)[1] - if ext in ['.tgz', '.tbz2', '.tlz', '.txz' ]: - ext = ".%s" % ext[2:] - - link = "../%s_%s.orig.tar%s" % (pkg, version, ext) - - if os.path.basename(archive) != os.path.basename(link): - try: - if not is_link_target(archive, link): - os.symlink(os.path.abspath(archive), link) - linked = True - except OSError as err: - raise GbpError("Cannot symlink '%s' to '%s': %s" % (archive, link, err[1])) - return (link, linked) - else: - return (archive, linked) - - def upstream_import_commit_msg(options, version): return options.import_msg % dict(version=version) diff --git a/gbp/scripts/pq.py b/gbp/scripts/pq.py index 02b74e75..7053d0af 100755 --- a/gbp/scripts/pq.py +++ b/gbp/scripts/pq.py @@ -342,7 +342,6 @@ def build_parser(name): parser.add_config_file_option(option_name="color", dest="color", type='tristate') parser.add_config_file_option(option_name="color-scheme", dest="color_scheme") - parser.add_config_file_option(option_name="tmp-dir", dest="tmp_dir") parser.add_config_file_option(option_name="meta-closes", dest="meta_closes") parser.add_config_file_option(option_name="tmp-dir", dest="tmp_dir") return parser -- cgit v1.2.3 From a50feeb6821e25201121997e214c237d9210152a Mon Sep 17 00:00:00 2001 From: Jun Wang Date: Fri, 18 Mar 2016 21:49:38 +0800 Subject: Modify unit test cases which called 'assert_raises' function to fix pre-review test bugs on CentOS_6. Change-Id: Ibb930eb107c18526876fc58428db359f9d31e716 --- tests/component/rpm/test_buildpackage_rpm.py | 4 ++ tests/component/rpm/test_import_orig_rpm.py | 4 ++ tests/component/rpm/test_import_srpm.py | 4 ++ tests/component/rpm/test_pq_rpm.py | 4 ++ tests/component/rpm/test_rpm_ch.py | 4 ++ tests/test_rpm.py | 56 ++++++++++++++++++++++++++++ tests/test_rpm_changelog.py | 20 ++++++++++ 7 files changed, 96 insertions(+) diff --git a/tests/component/rpm/test_buildpackage_rpm.py b/tests/component/rpm/test_buildpackage_rpm.py index 88a66fc0..652b1528 100644 --- a/tests/component/rpm/test_buildpackage_rpm.py +++ b/tests/component/rpm/test_buildpackage_rpm.py @@ -101,8 +101,12 @@ class TestGbpRpm(RpmRepoTestBase): def test_invalid_args(self): """Check graceful exit when called with invalid args""" GitRepository.create('.') + assert_raises(SystemExit, mock_gbp, ['--git-invalid-arg']) + + """ with assert_raises(SystemExit): mock_gbp(['--git-invalid-arg']) + """ def test_outside_repo(self): """Run outside a git repository""" diff --git a/tests/component/rpm/test_import_orig_rpm.py b/tests/component/rpm/test_import_orig_rpm.py index a85366b1..ebf592a0 100644 --- a/tests/component/rpm/test_import_orig_rpm.py +++ b/tests/component/rpm/test_import_orig_rpm.py @@ -142,8 +142,12 @@ class TestImportOrig(ImportOrigTestBase): self._check_repo_state(repo, None, []) # Test invalid cmdline options + assert_raises(SystemExit, mock_import, ['--invalid-arg=123']) + + """ with assert_raises(SystemExit): mock_import(['--invalid-arg=123']) + """ def test_import_outside_repo(self): """Test importing when not in a git repository""" diff --git a/tests/component/rpm/test_import_srpm.py b/tests/component/rpm/test_import_srpm.py index 8c6408f3..6635400b 100644 --- a/tests/component/rpm/test_import_srpm.py +++ b/tests/component/rpm/test_import_srpm.py @@ -45,8 +45,12 @@ class TestImportPacked(ComponentTestBase): def test_invalid_args(self): """See that import-srpm fails gracefully if called with invalid args""" eq_(mock_import([]), 1) + assert_raises(SystemExit, mock_import, ['--invalid-arg=123']) + + """ with assert_raises(SystemExit): mock_import(['--invalid-arg=123']) + """ def test_basic_import(self): """Test importing of non-native src.rpm""" diff --git a/tests/component/rpm/test_pq_rpm.py b/tests/component/rpm/test_pq_rpm.py index 293244be..c14ea681 100644 --- a/tests/component/rpm/test_pq_rpm.py +++ b/tests/component/rpm/test_pq_rpm.py @@ -52,8 +52,12 @@ class TestPqRpm(RpmRepoTestBase): self._clear_log() # Test invalid cmdline options + assert_raises(SystemExit, mock_pq, ['--invalid-arg=123']) + + """ with assert_raises(SystemExit): mock_pq(['--invalid-arg=123']) + """ def test_import_outside_repo(self): """Run pq-rpm when not in a git repository""" diff --git a/tests/component/rpm/test_rpm_ch.py b/tests/component/rpm/test_rpm_ch.py index db03c845..4b3354b7 100644 --- a/tests/component/rpm/test_rpm_ch.py +++ b/tests/component/rpm/test_rpm_ch.py @@ -56,8 +56,12 @@ class TestRpmCh(RpmRepoTestBase): """See that git-rpm-ch fails gracefully when called with invalid args""" GitRepository.create('.') + assert_raises(SystemExit, mock_ch, ['--invalid-opt']) + + """ with assert_raises(SystemExit): mock_ch(['--invalid-opt']) + """ def test_import_outside_repo(self): """Run git-rpm-ch when not in a git repository""" diff --git a/tests/test_rpm.py b/tests/test_rpm.py index 13799266..3150acbb 100644 --- a/tests/test_rpm.py +++ b/tests/test_rpm.py @@ -154,10 +154,15 @@ class TestSpecFile(object): def test_parse_raw(self): """Test parsing of a valid spec file""" + assert_raises(NoSpecError, SpecFile, None, None) + assert_raises(NoSpecError, SpecFile, 'filename', 'filedata') + + """ with assert_raises(NoSpecError): SpecFile(None, None) with assert_raises(NoSpecError): SpecFile('filename', 'filedata') + """ spec_filepath = os.path.join(SPEC_DIR, 'gbp-test.spec') with open(spec_filepath, 'r') as spec_fd: @@ -229,22 +234,36 @@ class TestSpecFile(object): assert spec.protected('_patches')() == {} prev = spec.protected('_delete_tag')('invalidtag', None) + assert_raises(GbpError, spec.protected('_set_tag'), + 'Version', None, '', prev) + assert_raises(GbpError, spec.set_tag, + 'invalidtag', None, 'value') + + """ with assert_raises(GbpError): # Check that setting empty value fails spec.protected('_set_tag')('Version', None, '', prev) with assert_raises(GbpError): # Check that setting invalid tag with public method fails spec.set_tag('invalidtag', None, 'value') + """ # Mangle macros prev = spec.protected('_delete_special_macro')('patch', -1) spec.protected('_delete_special_macro')('patch', 123) spec.protected('_set_special_macro')('patch', 0, 'my new args', prev) + assert_raises(GbpError, spec.protected('_delete_special_macro'), + 'invalidmacro', 0) + assert_raises(GbpError, spec.protected('_set_special_macro'), + 'invalidmacro', 0, 'args', prev) + + """ with assert_raises(GbpError): spec.protected('_delete_special_macro')('invalidmacro', 0) with assert_raises(GbpError): spec.protected('_set_special_macro')('invalidmacro', 0, 'args', prev) + """ # Check resulting spec file spec.write_spec_file() @@ -256,12 +275,21 @@ class TestSpecFile(object): spec = SpecFileTester(spec_filepath) # Unknown/invalid section name + assert_raises(GbpError, spec.protected('_set_section'), + 'patch', 'new content\n') + """ with assert_raises(GbpError): spec.protected('_set_section')('patch', 'new content\n') + """ # Multiple sections with the same name + assert_raises(GbpError, spec.protected('_set_section'), + 'files', '%{_sysconfdir}/foo\n') + + """ with assert_raises(GbpError): spec.protected('_set_section')('files', '%{_sysconfdir}/foo\n') + """ def test_changelog(self): """Test changelog methods""" @@ -370,13 +398,27 @@ class TestUtilityFunctions(object): def test_guess_spec(self): """Test guess_spec() function""" # Spec not found + assert_raises(NoSpecError, guess_spec, + DATA_DIR, recursive=False) + + """ with assert_raises(NoSpecError): guess_spec(DATA_DIR, recursive=False) + """ + # Multiple spec files + assert_raises(NoSpecError, guess_spec, + DATA_DIR, recursive=True) + assert_raises(NoSpecError, guess_spec, + SPEC_DIR, recursive=False) + + """ with assert_raises(NoSpecError): guess_spec(DATA_DIR, recursive=True) with assert_raises(NoSpecError): guess_spec(SPEC_DIR, recursive=False) + """ + # Spec found spec = guess_spec(SPEC_DIR, recursive=False, preferred_name = 'gbp-test2.spec') @@ -398,10 +440,18 @@ class TestUtilityFunctions(object): repo.commit_all('Add spec file') # Spec not found + assert_raises(NoSpecError, guess_spec_repo, + repo, 'HEAD~1', recursive=True) + assert_raises(NoSpecError, guess_spec_repo, + repo, 'HEAD', recursive=False) + + """ with assert_raises(NoSpecError): guess_spec_repo(repo, 'HEAD~1', recursive=True) with assert_raises(NoSpecError): guess_spec_repo(repo, 'HEAD', recursive=False) + """ + # Spec found spec = guess_spec_repo(repo, 'HEAD', 'packaging', recursive=False) spec = guess_spec_repo(repo, 'HEAD', recursive=True) @@ -410,8 +460,14 @@ class TestUtilityFunctions(object): assert spec.specpath == 'packaging/gbp-test.spec' # Test spec_from_repo() + assert_raises(NoSpecError, spec_from_repo, + repo, 'HEAD~1', 'packaging/gbp-test.spec') + + """ with assert_raises(NoSpecError): spec_from_repo(repo, 'HEAD~1', 'packaging/gbp-test.spec') + """ + spec = spec_from_repo(repo, 'HEAD', 'packaging/gbp-test.spec') assert spec.specfile == 'gbp-test.spec' diff --git a/tests/test_rpm_changelog.py b/tests/test_rpm_changelog.py index 29732936..22739f0e 100644 --- a/tests/test_rpm_changelog.py +++ b/tests/test_rpm_changelog.py @@ -40,8 +40,12 @@ class TestChangelogHeader(object): """Test missing properties""" time = datetime(2014, 01, 29, 12, 13, 14) header = _ChangelogHeader(RpmPkgPolicy, time, name="John", revision="1") + assert_raises(ChangelogError, str, header) + + """ with assert_raises(ChangelogError): str(header) + """ def test_container(self): """Test the container methods of the class""" @@ -190,6 +194,16 @@ class TestChangelogParser(object): def test_parse_section_fail(self): """Basic tests for failures of changelog section parsing""" + assert_raises(ChangelogError, self.parser.parse_section, + self.cl_broken_header_1) + assert_raises(ChangelogError, self.parser.parse_section, + self.cl_broken_header_2) + assert_raises(ChangelogError, self.parser.parse_section, + self.cl_broken_header_3) + assert_raises(ChangelogError, self.parser.parse_section, + self.cl_broken_header_4) + + """ with assert_raises(ChangelogError): self.parser.parse_section(self.cl_broken_header_1) @@ -201,11 +215,17 @@ class TestChangelogParser(object): with assert_raises(ChangelogError): self.parser.parse_section(self.cl_broken_header_4) + """ def test_parse_changelog_fail(self): """Basic tests for changelog parsing failures""" + assert_raises(ChangelogError, self.parser.raw_parse_string, + self.cl_broken_header_5) + + """ with assert_raises(ChangelogError): self.parser.raw_parse_string(self.cl_broken_header_5) + """ class TestChangelog(object): -- cgit v1.2.3 From f3302570006b449997aa0125d7db3536989d8716 Mon Sep 17 00:00:00 2001 From: Jun Wang Date: Sat, 19 Mar 2016 00:05:21 +0800 Subject: fix test case in fun test_parse_srpm Change-Id: I71af697a54d2a03f34f9a341d39b1c18e3bb5bb0 --- tests/test_rpm.py | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/tests/test_rpm.py b/tests/test_rpm.py index 3150acbb..97390465 100644 --- a/tests/test_rpm.py +++ b/tests/test_rpm.py @@ -390,10 +390,15 @@ class TestUtilityFunctions(object): def test_parse_srpm(self): """Test parse_srpm() function""" parse_srpm(os.path.join(SRPM_DIR, 'gbp-test-1.0-1.src.rpm')) + assert_raises(GbpError, parse_srpm, + os.path.join(DATA_DIR, 'notexists.src.rpm')) + + """ with assert_raises(GbpError): parse_srpm(os.path.join(DATA_DIR, 'notexists.src.rpm')) with assert_raises(GbpError): parse_srpm(os.path.join(SPEC_DIR, 'gbp-test.spec')) + """ def test_guess_spec(self): """Test guess_spec() function""" -- cgit v1.2.3 From 35eb5072a0939dc0166611383f7dd57c6c6b1973 Mon Sep 17 00:00:00 2001 From: "admin@123.33" Date: Mon, 25 Feb 2013 14:10:01 +0800 Subject: change gerrit server IP to HQ's --- .gitmodules | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/.gitmodules b/.gitmodules index 02d21b87..cb63fcb6 100644 --- a/.gitmodules +++ b/.gitmodules @@ -1,6 +1,6 @@ [submodule "tests/component/deb/data"] path = tests/component/deb/data - url = ssh://jenkins@109.123.100.123:29418/tizen.org-tools/git-buildpackage-deb-testdata + url = ssh://jenkins@10.113.136.109:29418/tools/git-buildpackage-deb-testdata [submodule "tests/component/rpm/data"] path = tests/component/rpm/data - url = ssh://jenkins@109.123.100.123:29418/tizen.org-tools/git-buildpackage-rpm-testdata + url = ssh://jenkins@10.113.136.109:29418/tools/git-buildpackage-rpm-testdata -- cgit v1.2.3 From 43a7b9c787f85075917a01b989b347d7b7d03507 Mon Sep 17 00:00:00 2001 From: Markus Lehtonen Date: Wed, 2 Oct 2013 16:35:32 +0300 Subject: ComponentTestBase: add a per-class toplevel temp dir Signed-off-by: Markus Lehtonen --- tests/component/__init__.py | 9 ++++++++- 1 file changed, 8 insertions(+), 1 deletion(-) diff --git a/tests/component/__init__.py b/tests/component/__init__.py index 4ef22563..f029eb28 100644 --- a/tests/component/__init__.py +++ b/tests/component/__init__.py @@ -85,6 +85,9 @@ class ComponentTestBase(object): # Don't let git see that we're (possibly) under a git directory cls.orig_env = os.environ.copy() os.environ['GIT_CEILING_DIRECTORIES'] = os.getcwd() + # Create a top-level tmpdir for the test + cls._tmproot = tempfile.mkdtemp(prefix='gbp_%s_' % cls.__name__, + dir='.') @classmethod def teardown_class(cls): @@ -92,6 +95,9 @@ class ComponentTestBase(object): # Return original environment os.environ.clear() os.environ.update(cls.orig_env) + # Remove top-level tmpdir + if not os.getenv("GBP_TESTS_NOCLEAN"): + shutil.rmtree(cls._tmproot) def __init__(self): """Object initialization""" @@ -104,7 +110,8 @@ class ComponentTestBase(object): """Test case setup""" # Change to a temporary directory self._orig_dir = os.getcwd() - self._tmpdir = tempfile.mkdtemp(prefix='gbp_%s_' % __name__, dir='.') + self._tmpdir = tempfile.mkdtemp(prefix='gbp_%s_' % __name__, + dir=self._tmproot) os.chdir(self._tmpdir) self._capture_log(True) -- cgit v1.2.3 From b5326c48c3c65cc48955da476f11c1ed6dd22a99 Mon Sep 17 00:00:00 2001 From: Markus Lehtonen Date: Wed, 4 Sep 2013 16:16:59 +0300 Subject: pq: deprecate the usage of 'gbp-pq-topic:' Replaced by the "Gbp[-Pq]: Topic " command. Signed-off-by: Markus Lehtonen --- gbp/scripts/common/pq.py | 19 +++---------------- gbp/scripts/pq.py | 28 +++++++++++++++++++++++++--- 2 files changed, 28 insertions(+), 19 deletions(-) diff --git a/gbp/scripts/common/pq.py b/gbp/scripts/common/pq.py index d3c07d17..332c28b9 100644 --- a/gbp/scripts/common/pq.py +++ b/gbp/scripts/common/pq.py @@ -155,21 +155,8 @@ def write_patch_file(filename, commit_info, diff): def format_patch(outdir, repo, commit_info, series, numbered=True, - topic_regex=None, path_exclude_regex=None, topic=''): + path_exclude_regex=None, topic=''): """Create patch of a single commit""" - commit = commit_info['id'] - - # Parse and filter commit message body - mangled_body = "" - for line in commit_info['body'].splitlines(): - if topic_regex: - match = re.match(topic_regex, line, flags=re.I) - if match: - topic = match.group('topic') - gbp.log.debug("Topic %s found for %s" % (topic, commit)) - continue - mangled_body += line + '\n' - commit_info['body'] = mangled_body # Determine filename and path outdir = os.path.join(outdir, topic) @@ -194,8 +181,8 @@ def format_patch(outdir, repo, commit_info, series, numbered=True, # Finally, create the patch patch = None if paths: - diff = repo.diff('%s^!' % commit, paths=paths, stat=80, summary=True, - text=True) + diff = repo.diff('%s^!' % commit_info['id'], paths=paths, stat=80, + summary=True, text=True) patch = write_patch_file(filepath, commit_info, diff) if patch: series.append(patch) diff --git a/gbp/scripts/pq.py b/gbp/scripts/pq.py index ea33c26c..9a031b87 100755 --- a/gbp/scripts/pq.py +++ b/gbp/scripts/pq.py @@ -40,6 +40,27 @@ PATCH_DIR = "debian/patches/" SERIES_FILE = os.path.join(PATCH_DIR,"series") +def parse_old_style_topic(commit_info): + """Parse 'gbp-pq-topic:' line(s) from commit info""" + + commit = commit_info['id'] + topic_regex = 'gbp-pq-topic:\s*(?P\S.*)' + mangled_body = '' + topic = '' + # Parse and filter commit message body + for line in commit_info['body'].splitlines(): + match = re.match(topic_regex, line, flags=re.I) + if match: + topic = match.group('topic') + gbp.log.debug("Topic %s found for %s" % (topic, commit)) + gbp.log.warn("Deprecated 'gbp-pq-topic: ' in %s, please " + "use 'Gbp[-Pq]: Topic ' instead" % commit) + continue + mangled_body += line + '\n' + commit_info['body'] = mangled_body + return topic + + def generate_patches(repo, start, end, outdir, options): """ Generate patch files from git @@ -52,15 +73,16 @@ def generate_patches(repo, start, end, outdir, options): # Generate patches rev_list = reversed(repo.get_commits(start, end)) - topic_regex = 'gbp-pq-topic:\s*(?P\S.*)' for commit in rev_list: info = repo.get_commit_info(commit) + topic = parse_old_style_topic(info) cmds = parse_gbp_commands(info, 'gbp', ('ignore'), ('topic')) cmds.update(parse_gbp_commands(info, 'gbp-pq', ('ignore'), ('topic'))) if not 'ignore' in cmds: - topic = cmds['topic'] if 'topic' in cmds else '' + if 'topic' in cmds: + topic = cmds['topic'] format_patch(outdir, repo, info, patches, options.patch_numbers, - topic_regex=topic_regex, topic=topic) + topic=topic) else: gbp.log.info('Ignoring commit %s' % info['id']) -- cgit v1.2.3 From ecf1b23ddfede5f3439fb91f9ad6cfcb5724ebe3 Mon Sep 17 00:00:00 2001 From: Markus Lehtonen Date: Tue, 29 Apr 2014 14:07:37 +0300 Subject: pq: make sure we always get a sane author Prevent a crash when the author (for a raw diff) was None because no name/email could be determined from git config or environment variables. Signed-off-by: Markus Lehtonen --- gbp/scripts/common/pq.py | 26 +++++++++++++++++++++++++- 1 file changed, 25 insertions(+), 1 deletion(-) diff --git a/gbp/scripts/common/pq.py b/gbp/scripts/common/pq.py index 332c28b9..75ce526d 100644 --- a/gbp/scripts/common/pq.py +++ b/gbp/scripts/common/pq.py @@ -22,6 +22,8 @@ import re import os import subprocess import datetime +import pwd +import socket import time from email.message import Message from email.header import Header @@ -192,7 +194,7 @@ def format_patch(outdir, repo, commit_info, series, numbered=True, def format_diff(outdir, filename, repo, start, end, path_exclude_regex=None): """Create a patch of diff between two repository objects""" - info = {'author': repo.get_author_info()} + info = {'author': get_author(repo)} now = datetime.datetime.now().replace(tzinfo=GitTz(-time.timezone)) info['author'].set_date(now) info['subject'] = "Raw diff %s..%s" % (start, end) @@ -212,6 +214,28 @@ def format_diff(outdir, filename, repo, start, end, path_exclude_regex=None): return None +def get_author(repo): + """Determine author name and email""" + author = GitModifier() + if repo: + author = repo.get_author_info() + + passwd_data = pwd.getpwuid(os.getuid()) + if not author.name: + # On some distros (Ubuntu, at least) the gecos field has it's own + # internal structure of comma-separated fields + author.name = passwd_data.pw_gecos.split(',')[0].strip() + if not author.name: + author.name = passwd_data.pw_name + if not author.email: + if 'EMAIL' in os.environ: + author.email = os.environ['EMAIL'] + else: + author.email = "%s@%s" % (passwd_data.pw_name, socket.getfqdn()) + + return author + + def get_maintainer_from_control(repo): """Get the maintainer from the control file""" control = os.path.join(repo.path, 'debian', 'control') -- cgit v1.2.3 From a644da27a5b3c925fef60431fc2bf9404ade14fa Mon Sep 17 00:00:00 2001 From: Markus Lehtonen Date: Tue, 13 May 2014 16:41:32 +0300 Subject: notifications: make notify() more generic In order to be able to re-use it in other tools than git-buildpackage. Signed-off-by: Markus Lehtonen --- gbp/notifications.py | 5 ++--- gbp/scripts/buildpackage.py | 11 ++++++----- 2 files changed, 8 insertions(+), 8 deletions(-) diff --git a/gbp/notifications.py b/gbp/notifications.py index 95c4bf41..d60450e5 100644 --- a/gbp/notifications.py +++ b/gbp/notifications.py @@ -53,7 +53,7 @@ def send_notification(summary, msg): return True -def notify(cp, success, notify_opt): +def notify(summary, message, notify_opt): """ Send a notifications @return: False on error @@ -66,6 +66,5 @@ def notify(cp, success, notify_opt): if not enable: return [True, False][notify_opt.is_on()] - summary, msg = build_msg(cp, success) - return notify_opt.do(send_notification, summary, msg) + return notify_opt.do(send_notification, summary, message) diff --git a/gbp/scripts/buildpackage.py b/gbp/scripts/buildpackage.py index 54e66bd2..21424755 100755 --- a/gbp/scripts/buildpackage.py +++ b/gbp/scripts/buildpackage.py @@ -628,11 +628,12 @@ def main(argv): if options.export_dir and options.purge and not retval: RemoveTree(export_dir)() - if source and not gbp.notifications.notify(source.changelog, - not retval, - options.notify): - gbp.log.err("Failed to send notification") - retval = 1 + if source: + summary, msg = gbp.notifications.build_msg(source.changelog, + not retval) + if not gbp.notifications.notify(summary, msg, options.notify): + gbp.log.err("Failed to send notification") + retval = 1 return retval -- cgit v1.2.3 From 62b4b81528a12192ce2ac690636204f60305268c Mon Sep 17 00:00:00 2001 From: Markus Lehtonen Date: Wed, 30 Apr 2014 13:40:12 +0300 Subject: docs: add some missing commas to manpages Signed-off-by: Markus Lehtonen --- docs/manpages/gbp-buildpackage.sgml | 2 +- docs/manpages/gbp.conf.sgml | 2 +- docs/manpages/gbp.sgml | 2 +- 3 files changed, 3 insertions(+), 3 deletions(-) diff --git a/docs/manpages/gbp-buildpackage.sgml b/docs/manpages/gbp-buildpackage.sgml index 37d2c313..c5bc50bb 100644 --- a/docs/manpages/gbp-buildpackage.sgml +++ b/docs/manpages/gbp-buildpackage.sgml @@ -494,7 +494,7 @@ gbp.conf &dhconfsection; - + , &man.seealso.common; diff --git a/docs/manpages/gbp.conf.sgml b/docs/manpages/gbp.conf.sgml index a580220a..9284ce9f 100644 --- a/docs/manpages/gbp.conf.sgml +++ b/docs/manpages/gbp.conf.sgml @@ -226,7 +226,7 @@ the above list of configuration files. gbp-pq 1 - + , gbp-pull 1 diff --git a/docs/manpages/gbp.sgml b/docs/manpages/gbp.sgml index 2b570d4d..9608a969 100644 --- a/docs/manpages/gbp.sgml +++ b/docs/manpages/gbp.sgml @@ -173,7 +173,7 @@ gbp.conf &dhconfsection; - + , &man.seealso.common; -- cgit v1.2.3 From 9956ef39bd4ce06614273d144627eceebb689451 Mon Sep 17 00:00:00 2001 From: Markus Lehtonen Date: Wed, 30 Apr 2014 11:30:11 +0300 Subject: docs: hyperlink references to other manpages Change references to other gbp manpages to linked refs so that we get hyperlinks in the html manpages. Signed-off-by: Markus Lehtonen --- docs/manpages/gbp-buildpackage.sgml | 25 ++++--------------- docs/manpages/gbp-clone.sgml | 15 +++--------- docs/manpages/gbp-config.sgml | 5 +--- docs/manpages/gbp-create-remote-repo.sgml | 15 +++--------- docs/manpages/gbp-dch.sgml | 25 ++++--------------- docs/manpages/gbp-import-dsc.sgml | 25 ++++--------------- docs/manpages/gbp-import-dscs.sgml | 25 ++++--------------- docs/manpages/gbp-import-orig.sgml | 25 ++++--------------- docs/manpages/gbp-pq.sgml | 10 ++------ docs/manpages/gbp-pull.sgml | 20 ++++------------ docs/manpages/gbp.conf.sgml | 40 +++++++------------------------ docs/manpages/gbp.sgml | 40 +++++++------------------------ 12 files changed, 54 insertions(+), 216 deletions(-) diff --git a/docs/manpages/gbp-buildpackage.sgml b/docs/manpages/gbp-buildpackage.sgml index c5bc50bb..ea578e25 100644 --- a/docs/manpages/gbp-buildpackage.sgml +++ b/docs/manpages/gbp-buildpackage.sgml @@ -467,22 +467,10 @@ SEE ALSO - - gbp-import-dsc - 1 - , - - gbp-import-dscs - 1 - , - - gbp-import-orig - 1 - , - - gbp-dch - 1 - , + , + , + , + , git-pbuilder 1 @@ -491,10 +479,7 @@ cowbuilder 8 , - - gbp.conf - &dhconfsection; - , + , &man.seealso.common; diff --git a/docs/manpages/gbp-clone.sgml b/docs/manpages/gbp-clone.sgml index c63db2f5..2dec88dd 100644 --- a/docs/manpages/gbp-clone.sgml +++ b/docs/manpages/gbp-clone.sgml @@ -96,18 +96,9 @@ SEE ALSO - - gbp-buildpackage - 1 - , - - gbp-pull - 1 - , - - gbp.conf - &dhconfsection; - + , + , + diff --git a/docs/manpages/gbp-config.sgml b/docs/manpages/gbp-config.sgml index d68ac643..f63410b3 100644 --- a/docs/manpages/gbp-config.sgml +++ b/docs/manpages/gbp-config.sgml @@ -104,10 +104,7 @@ SEE ALSO - - gbp.conf - &dhconfsection; - + diff --git a/docs/manpages/gbp-create-remote-repo.sgml b/docs/manpages/gbp-create-remote-repo.sgml index 08c621a5..a874b004 100644 --- a/docs/manpages/gbp-create-remote-repo.sgml +++ b/docs/manpages/gbp-create-remote-repo.sgml @@ -141,18 +141,9 @@ SEE ALSO - - gbp-buildpackage - 1 - , - - gbp-pull - 1 - , - - gbp.conf - &dhconfsection; - + , + , + diff --git a/docs/manpages/gbp-dch.sgml b/docs/manpages/gbp-dch.sgml index 177f45dd..082597a7 100644 --- a/docs/manpages/gbp-dch.sgml +++ b/docs/manpages/gbp-dch.sgml @@ -407,26 +407,11 @@ SEE ALSO - - gbp-buildpackage - 1 - , - - gbp-import-dsc - 1 - , - - gbp-import-dscs - 1 - , - - gbp-import-orig - 1 - , - - gbp.conf - &dhconfsection; - , + , + , + , + , + , &man.seealso.common; Cl2vcs, diff --git a/docs/manpages/gbp-import-dsc.sgml b/docs/manpages/gbp-import-dsc.sgml index 2d186ed8..6efb1c51 100644 --- a/docs/manpages/gbp-import-dsc.sgml +++ b/docs/manpages/gbp-import-dsc.sgml @@ -198,22 +198,10 @@ SEE ALSO - - gbp-import-dscs - 1 - , - - gbp-buildpackage - 1 - , - - gbp-import-orig - 1 - , - - gbp-dch - 1 - , + , + , + , + , apt-get 1 @@ -222,10 +210,7 @@ dget 1 , - - gbp.conf - &dhconfsection; - , + , &man.seealso.common; diff --git a/docs/manpages/gbp-import-dscs.sgml b/docs/manpages/gbp-import-dscs.sgml index 71ae883a..c288b138 100644 --- a/docs/manpages/gbp-import-dscs.sgml +++ b/docs/manpages/gbp-import-dscs.sgml @@ -80,26 +80,11 @@ options shipped in the package source. SEE ALSO - - gbp-import-dsc - 1 - , - - gbp-buildpackage - 1 - , - - gbp-import-orig - 1 - , - - gbp-dch - 1 - , - - gbp.conf - &dhconfsection; - , + , + , + , + , + , &man.seealso.common; diff --git a/docs/manpages/gbp-import-orig.sgml b/docs/manpages/gbp-import-orig.sgml index f6df6659..838db3c3 100644 --- a/docs/manpages/gbp-import-orig.sgml +++ b/docs/manpages/gbp-import-orig.sgml @@ -214,26 +214,11 @@ SEE ALSO - - gbp-buildpackage - 1 - , - - gbp-import-dsc - 1 - , - - gbp-import-dscs - 1 - , - - gbp-dch - 1 - , - - gbp.conf - &dhconfsection; - , + , + , + , + , + , &man.seealso.common; diff --git a/docs/manpages/gbp-pq.sgml b/docs/manpages/gbp-pq.sgml index fa86ff2b..9e47b1a5 100644 --- a/docs/manpages/gbp-pq.sgml +++ b/docs/manpages/gbp-pq.sgml @@ -210,10 +210,7 @@ SEE ALSO - - gbp-buildpackage - 1 - , + , dpkg-source 1 @@ -222,10 +219,7 @@ quilt 1 , - - gbp.conf - &dhconfsection; - + diff --git a/docs/manpages/gbp-pull.sgml b/docs/manpages/gbp-pull.sgml index d223228e..e328b3d7 100644 --- a/docs/manpages/gbp-pull.sgml +++ b/docs/manpages/gbp-pull.sgml @@ -137,22 +137,10 @@ SEE ALSO - - gbp-buildpackage - 1 - , - - gbp-clone - 1 - , - - gbp-pq - 1 - , - - gbp.conf - &dhconfsection; - + , + , + , + diff --git a/docs/manpages/gbp.conf.sgml b/docs/manpages/gbp.conf.sgml index 9284ce9f..a0228759 100644 --- a/docs/manpages/gbp.conf.sgml +++ b/docs/manpages/gbp.conf.sgml @@ -215,38 +215,14 @@ the above list of configuration files. SEE ALSO - - gbp-clone - 1 - , - - gbp-create-remote-repo - 1 - , - - gbp-pq - 1 - , - - gbp-pull - 1 - , - - gbp-dch - 1 - , - - gbp-import-dsc - 1 - , - - gbp-import-orig - 1 - , - - gbp-buildpackage - 1 - , + , + , + , + , + , + , + , + , The Git-Buildpackage Manual diff --git a/docs/manpages/gbp.sgml b/docs/manpages/gbp.sgml index 9608a969..fdb6f483 100644 --- a/docs/manpages/gbp.sgml +++ b/docs/manpages/gbp.sgml @@ -138,42 +138,18 @@ SEE ALSO - - gbp-import-dsc - 1 - , - - gbp-import-dscs - 1 - , - - gbp-import-orig - 1 - , - - gbp-dch - 1 - , - - gbp-create-remote-repo - 1 - , - - gbp-pull - 1 - , - - gbp-clone - 1 - , + , + , + , + , + , + , + , git-pbuilder 1 , - - gbp.conf - &dhconfsection; - , + , &man.seealso.common; -- cgit v1.2.3 From d1637d62a05cf0316a1c4ae12ed671cc94dd267b Mon Sep 17 00:00:00 2001 From: Markus Lehtonen Date: Wed, 30 Apr 2014 13:21:22 +0300 Subject: docs: reference buildpackage and pq in the gbp (supercommand) manpage Signed-off-by: Markus Lehtonen --- docs/manpages/gbp.sgml | 2 ++ 1 file changed, 2 insertions(+) diff --git a/docs/manpages/gbp.sgml b/docs/manpages/gbp.sgml index fdb6f483..00c9e77f 100644 --- a/docs/manpages/gbp.sgml +++ b/docs/manpages/gbp.sgml @@ -138,10 +138,12 @@ SEE ALSO + , , , , , + , , , , -- cgit v1.2.3 From 7d5d13fc17a8de772a41aab56405bf72f017755b Mon Sep 17 00:00:00 2001 From: Markus Lehtonen Date: Mon, 5 May 2014 15:14:45 +0300 Subject: docs: sgml syntax fix, add missing semicolons Signed-off-by: Markus Lehtonen --- docs/manpages/gbp-config.sgml | 2 +- docs/manpages/gbp-pq.sgml | 2 +- docs/manpages/gbp-pull.sgml | 2 +- 3 files changed, 3 insertions(+), 3 deletions(-) diff --git a/docs/manpages/gbp-config.sgml b/docs/manpages/gbp-config.sgml index f63410b3..b281597a 100644 --- a/docs/manpages/gbp-config.sgml +++ b/docs/manpages/gbp-config.sgml @@ -59,7 +59,7 @@ EXIT CODES - When &gbp-config finishes it indicates success or failure with its exit code: + When &gbp-config; finishes it indicates success or failure with its exit code: diff --git a/docs/manpages/gbp-pq.sgml b/docs/manpages/gbp-pq.sgml index 9e47b1a5..6251ab39 100644 --- a/docs/manpages/gbp-pq.sgml +++ b/docs/manpages/gbp-pq.sgml @@ -38,7 +38,7 @@ DESCRIPTION - &gbp-pq helps one to manage quilt patches in Debian packages that are maintained + &gbp-pq; helps one to manage quilt patches in Debian packages that are maintained with &gbp;. This is especially useful with packages using the 3.0 (quilt) source format. With &gbp-pq; you can maintain the quilt patches that should be applied to a package on a separate branch called patch-queue diff --git a/docs/manpages/gbp-pull.sgml b/docs/manpages/gbp-pull.sgml index e328b3d7..7a9d235f 100644 --- a/docs/manpages/gbp-pull.sgml +++ b/docs/manpages/gbp-pull.sgml @@ -108,7 +108,7 @@ EXIT CODES - When &gbp-pull finishes it indicates success or failure with it's exit code: + When &gbp-pull; finishes it indicates success or failure with it's exit code: -- cgit v1.2.3 From 61b29501dfa9347bf5c91e5f96d36073df5aa927 Mon Sep 17 00:00:00 2001 From: Markus Lehtonen Date: Thu, 8 May 2014 16:19:19 +0300 Subject: docs: document the --color-scheme option Signed-off-by: Markus Lehtonen --- docs/manpages/gbp-buildpackage.sgml | 15 +++++++++++++++ docs/manpages/gbp-config.sgml | 15 +++++++++++++++ docs/manpages/gbp-pq.sgml | 15 +++++++++++++++ 3 files changed, 45 insertions(+) diff --git a/docs/manpages/gbp-buildpackage.sgml b/docs/manpages/gbp-buildpackage.sgml index ea578e25..79fb81db 100644 --- a/docs/manpages/gbp-buildpackage.sgml +++ b/docs/manpages/gbp-buildpackage.sgml @@ -24,6 +24,7 @@ [auto|on|off] + =COLOR_SCHEME [auto|on|off] treeish branch_name @@ -203,6 +204,20 @@ Whether to send a desktop notification after the build. + + =COLOR_SCHEME + + + Colors to use in output (when color is enabled). The format for + COLOR_SCHEME is + '<debug>:<info>:<warning>:<error>'. + Numerical values and color names are accepted, empty fields imply + the default color. For example --git-color-scheme='cyan:34::' would + show debug messages in cyan, info messages in blue and other messages + in default (i.e. warning and error messages in red). + + + =branch_name diff --git a/docs/manpages/gbp-config.sgml b/docs/manpages/gbp-config.sgml index b281597a..599d1168 100644 --- a/docs/manpages/gbp-config.sgml +++ b/docs/manpages/gbp-config.sgml @@ -23,6 +23,7 @@ [auto|on|off] + =COLOR_SCHEME command.option command @@ -54,6 +55,20 @@ Whether to use colored output. + + =COLOR_SCHEME + + + Colors to use in output (when color is enabled). The format for + COLOR_SCHEME is + '<debug>:<info>:<warning>:<error>'. + Numerical values and color names are accepted, empty fields imply + the default color. For example --git-color-scheme='cyan:34::' would + show debug messages in cyan, info messages in blue and other messages + in default (i.e. warning and error messages in red). + + + diff --git a/docs/manpages/gbp-pq.sgml b/docs/manpages/gbp-pq.sgml index 6251ab39..697916ca 100644 --- a/docs/manpages/gbp-pq.sgml +++ b/docs/manpages/gbp-pq.sgml @@ -22,6 +22,7 @@ &gbp-pq; [auto|on|off] + =COLOR_SCHEME topic num @@ -137,6 +138,20 @@ Whether to use colored output. + + =COLOR_SCHEME + + + Colors to use in output (when color is enabled). The format for + COLOR_SCHEME is + '<debug>:<info>:<warning>:<error>'. + Numerical values and color names are accepted, empty fields imply + the default color. For example --git-color-scheme='cyan:34::' would + show debug messages in cyan, info messages in blue and other messages + in default (i.e. warning and error messages in red). + + + -- cgit v1.2.3 From f79f492b414b698f67ecfea546b0df9816cb5560 Mon Sep 17 00:00:00 2001 From: Markus Lehtonen Date: Thu, 8 May 2014 17:40:16 +0300 Subject: docs: document the --git-[no-]submodules option Signed-off-by: Markus Lehtonen --- docs/manpages/gbp-buildpackage.sgml | 10 ++++++++++ 1 file changed, 10 insertions(+) diff --git a/docs/manpages/gbp-buildpackage.sgml b/docs/manpages/gbp-buildpackage.sgml index 79fb81db..f382634f 100644 --- a/docs/manpages/gbp-buildpackage.sgml +++ b/docs/manpages/gbp-buildpackage.sgml @@ -29,6 +29,7 @@ treeish branch_name + BUILD_CMD CLEAN_CMD @@ -254,6 +255,15 @@ GPG sign all created tags + + + + + + Include git submodules in the orig tarball. + + + gpg-keyid -- cgit v1.2.3 From 49599815f75c26d10bd3cb0362ae703ee5b84ab2 Mon Sep 17 00:00:00 2001 From: Markus Lehtonen Date: Wed, 21 May 2014 13:57:52 +0300 Subject: docs: document the --interactive option of gbp-import-orig Signed-off-by: Markus Lehtonen --- docs/manpages/gbp-import-orig.sgml | 9 +++++++++ 1 file changed, 9 insertions(+) diff --git a/docs/manpages/gbp-import-orig.sgml b/docs/manpages/gbp-import-orig.sgml index 838db3c3..74a0f634 100644 --- a/docs/manpages/gbp-import-orig.sgml +++ b/docs/manpages/gbp-import-orig.sgml @@ -194,6 +194,15 @@ Use uscan to fetch new upstream version. + + + + + Run command interactively, i.e. ask package name and version if + needed. + + + -- cgit v1.2.3 From 178b1cd37b8004755e649409f41d3aa4bfa9c159 Mon Sep 17 00:00:00 2001 From: Markus Lehtonen Date: Mon, 26 May 2014 13:24:23 +0300 Subject: docs: document the --customizations option of gbp dch Signed-off-by: Markus Lehtonen --- docs/manpages/gbp-dch.sgml | 13 ++++++++++++- 1 file changed, 12 insertions(+), 1 deletion(-) diff --git a/docs/manpages/gbp-dch.sgml b/docs/manpages/gbp-dch.sgml index 082597a7..94a535ac 100644 --- a/docs/manpages/gbp-dch.sgml +++ b/docs/manpages/gbp-dch.sgml @@ -56,7 +56,7 @@ msg-format - customization-file + customization-file [path1 path2] @@ -313,6 +313,17 @@ Commit the generated changelog. + + customization-file + + + + Load Python code from customization-file. + At the moment, the only useful thing the code can do is define a + custom format_changelog_entry() function. + + + -- cgit v1.2.3 From d84d6dab2aabc06277f05e591e9681615f8f0be3 Mon Sep 17 00:00:00 2001 From: Markus Lehtonen Date: Thu, 8 May 2014 15:35:26 +0300 Subject: docs: more flexible version parsing in Makefile Add dash to the list of valid version characters. Signed-off-by: Markus Lehtonen --- docs/Makefile | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs/Makefile b/docs/Makefile index 594126a6..91c3b0ad 100644 --- a/docs/Makefile +++ b/docs/Makefile @@ -22,7 +22,7 @@ POD_MANPAGES=git-pbuilder.1 MANPAGES=$(SGML_MANPAGES) $(POD_MANPAGES) VERSION_ENT=version.ent GBP_VERSION=../gbp/version.py -DEB_VERSION=$(shell sed -ne 's/^gbp_version="\([.a-z0-9~]\+\)"/\1/p' $(GBP_VERSION)) +DEB_VERSION=$(shell sed -ne 's/^gbp_version="\([.a-z0-9~-]\+\)"/\1/p' $(GBP_VERSION)) CHANGELOG=../debian/changelog all: $(MANUAL) $(MANPAGES) -- cgit v1.2.3 From e65441a6d8b3475049c5b26f2f4f9a734eab97c9 Mon Sep 17 00:00:00 2001 From: Markus Lehtonen Date: Fri, 9 May 2014 14:40:25 +0300 Subject: docs: cosmetic reformat of buildpackage manpage sgml source In order to make the sgml source more readable. Fix indentation, tab to space, wrap lines. Signed-off-by: Markus Lehtonen --- docs/manpages/gbp-buildpackage.sgml | 482 +++++++++++++++++++++++------------- 1 file changed, 306 insertions(+), 176 deletions(-) diff --git a/docs/manpages/gbp-buildpackage.sgml b/docs/manpages/gbp-buildpackage.sgml index f382634f..d099e415 100644 --- a/docs/manpages/gbp-buildpackage.sgml +++ b/docs/manpages/gbp-buildpackage.sgml @@ -8,8 +8,7 @@ &dhsurname; - - gbp-buildpackage + gbp-buildpackage &dhsection; @@ -66,147 +65,203 @@ DESCRIPTION - &gbp-buildpackage; is used to build Debian source and .deb packages from a &git; repository. + &gbp-buildpackage; is used to build Debian source and .deb packages from + a &git; repository. - &gbp-buildpackage; will, in order: - + &gbp-buildpackage; will, in order: + - Verify that it is being executed from the - proper location. - - Verify that the repository doesn't contain any - uncommitted source changes. - - Verify that it is being executed from the - correct branch. - - - (Optionally) export the source tree to a separate build area - - Build an orig tarball if it doesn't exist. - - Call debuild(1) - (or the application specified via ) - with arguments instructing it to ignore &git; meta-data in - the diff.gz, passing along all arguments given to - &gbp-buildpackage; that don't start with --git-. - - - - (Optionally) tag the tree after a successful build - - - (Optionally) call a post build hook - e.g. to run &lintian; - - - (Optionally) call a post tag hook - e.g. to push the results to a remote - repository after creating the tag - + + + Verify that it is being executed from the proper location. + + + + + Verify that the repository doesn't contain any uncommitted source + changes. + + + + + Verify that it is being executed from the correct branch. + + + + + (Optionally) export the source tree to a separate build area + + + + + Build an orig tarball if it doesn't exist. + + + + + Call debuild(1) (or the application + specified via ) with arguments + instructing it to ignore &git; meta-data in the diff.gz, passing along + all arguments given to &gbp-buildpackage; that don't start with --git-. + + + + + (Optionally) tag the tree after a successful build + + + + + (Optionally) call a post build hook - e.g. to run &lintian; + + + + + (Optionally) call a post tag hook - e.g. to push the results to a + remote repository after creating the tag + + OPTIONS - - Don't abort if there are uncommitted changes in the source tree - or the current branch doesn't match the - debian-branch. + + Don't abort if there are uncommitted changes in the source tree or + the current branch doesn't match the + debian-branch. + - Add a git tag after a successful build. + + Add a git tag after a successful build. + - + + - Use BUILD_CMD instead of debuild -i -I + + Use BUILD_CMD instead of + debuild -i -I + - + + - Use CLEAN_CMD instead of debuild clean + + Use CLEAN_CMD instead of + debuild clean + - + + - Build package using git-pbuilder. Note that - this overwrites any and - options. + + Build package using git-pbuilder. Note that this + overwrites any and + options. + - + + - Build package using git-pbuilder with - qemubuilder. Note that this overwrites any - and - options. + + Build package using git-pbuilder with + qemubuilder. Note that this overwrites any + and + options. + - + + - Build for distribution DIST when - using --git-pbuilder. If unset build for the - unstable distribution. + + Build for distribution DIST when using + --git-pbuilder. If unset build for the unstable + distribution. + - + + - Build for architecture ARCH when - using --git-pbuilder. If unset no architecture is - passed to git-pbuilder. + + Build for architecture ARCH when using + --git-pbuilder. If unset no architecture is passed + to git-pbuilder. + - + + - Whether to try to autoconfigure - git-pbuilder or to rely on the settings in - .pbuilderrc. See the git-pbuilder - manpage for details. + + Whether to try to autoconfigure git-pbuilder or to + rely on the settings in .pbuilderrc. See the + git-pbuilder manpage for details. + + - + + - Options to pass to pbuilder + + Options to pass to pbuilder + - verbose execution + + verbose execution + [auto|on|off] - Whether to use colored output. + + Whether to use colored output. + [auto|on|off] - Whether to send a desktop notification after the build. + + Whether to send a desktop notification after the build. + - =COLOR_SCHEME + =COLOR_SCHEME + Colors to use in output (when color is enabled). The format for @@ -223,36 +278,44 @@ =branch_name - Branch to build the orig tarball from if - is set to BRANCH. Default is - upstream. + + Branch to build the orig tarball from if + is set to + BRANCH. Default is + upstream. + =branch_name - If you're not on this branch when invoking &gbp-buildpackage; - it will fail. Default is master. This is - done to make sure you don't accidentally release from a topic branch. - Not being on this branch will be ignored when using - . - + + If you're not on this branch when invoking &gbp-buildpackage; it will + fail. Default is master. This is done to + make sure you don't accidentally release from a topic branch. Not + being on this branch will be ignored when using + . + - Don't check if the current branch matches - debian-branch. + + Don't check if the current branch matches + debian-branch. + - GPG sign all created tags + + GPG sign all created tags + @@ -268,218 +331,283 @@ gpg-keyid - use this keyid for gpg signing tags + + use this keyid for gpg signing tags + command - excecute command after tagging a new - version.Exported environment variables are: - GBP_TAG (the name of the generated tag), - GBP_BRANCH (the branch the package was build from) and - GBP_SHA1 (the sha1 of the commit the tag was created - at). + + excecute command after tagging a new + version. + + + Exported environment variables are: GBP_TAG (the name + of the generated tag), GBP_BRANCH (the branch the + package was build from) and GBP_SHA1 (the sha1 of the + commit the tag was created at). + command - execute command after successful - build. Exported environment variables are: - GBP_CHANGES_FILE (the name of the generated changes - file), GBP_BUILD_DIR (the build dir). + + execute command after successful + build. + + + Exported environment variables are: GBP_CHANGES_FILE + (the name of the generated changes file), + GBP_BUILD_DIR (the build dir). + command - execute command after exporting the source - tree - valid only if --git-export-dir has been specified. - Exported environment variables are: - GBP_GIT_DIR (the repository the package is being built - from), GBP_TMP_DIR (the temporary directory where the - sources have been initially exported). + + execute command after exporting the source + tree - valid only if --git-export-dir has been specified. + + + Exported environment variables are: GBP_GIT_DIR (the + repository the package is being built from), + GBP_TMP_DIR (the temporary directory where the sources + have been initially exported). + command - execute command from the build - directory before calling debuild - or the application specified via . - Exported environment variables are: - GBP_GIT_DIR (the repository the package is being built from), - GBP_BUILD_DIR (the build dir). + + execute command from the build directory + before calling debuild or the application + specified via . + + + Exported environment variables are: GBP_GIT_DIR (the + repository the package is being built from), + GBP_BUILD_DIR (the build dir). + - + + - Enable running all (cleaner, postexport, prebuild, postbuild, - and posttag) hooks. Note: the command is - not affected by this option. + + Enable running all (cleaner, postexport, prebuild, postbuild, and + posttag) hooks. Note: the command is + not affected by this option. + tag-format - use this tag format when tagging Debian versions, - default is debian/%(version)s + + use this tag format when tagging Debian versions, default is + debian/%(version)s + tag-format - use this tag format when looking for tags of upstream versions, - default is upstream/%(version)s. + + use this tag format when looking for tags of upstream versions, + default is upstream/%(version)s. + - Force creation of an orig tarball (overwriting a pre-existing one if present) + + Force creation of an orig tarball (overwriting a pre-existing one if + present) + - Don't try to create any orig tarball + + Don't try to create any orig tarball + - Extract orig tarball when using export-dir option (analog to mergeWithUpstream in svn-bp) + + Extract orig tarball when using export-dir option (analog to + mergeWithUpstream in svn-bp) + directory - Export the current branch head (or the treeish object given via - to directory - before building. + + Export the current branch head (or the treeish object given via + to directory + before building. + treeish - - Instead of exporting the current branch head, export the - treeish object treeish. The special name - INDEX exports the current index whereas - the special name WC exports the current working - copy as is. + + + Instead of exporting the current branch head, export the treeish + object treeish. The special name + INDEX exports the current index whereas + the special name WC exports the current + working copy as is. + [tag|branch] - How to find the upstream sources used to generate the tarball. - TAG looks at a tag corresponding to the - version in the changelog. BRANCH looks at - the upstream branch given via the - option. Other values are interpreted as treeishs. - - This doesn't have any effect if - is being used. - + + How to find the upstream sources used to generate the tarball. + TAG looks at a tag corresponding to the + version in the changelog. BRANCH looks at + the upstream branch given via the + option. Other values are + interpreted as treeishs. + + + This doesn't have any effect if + is being used. + directory - Search for original tarballs in directory instead of generating them + + Search for original tarballs in directory + instead of generating them + type - Specifies the upstream tarball compression type. This will be - used to locate and build the upstream tarball if necessary. The - default is auto which derives the - compression type from the pristine-tar branch if available and falls - back to gzip otherwise. Other options are - gzip, bzip2, - lzma and xz. - + + Specifies the upstream tarball compression type. This will be used to + locate and build the upstream tarball if necessary. The default is + auto which derives the compression type + from the pristine-tar branch if available and falls back to gzip + otherwise. Other options are gzip, + bzip2, lzma and + xz. + level - Specifies the upstream tarball compression level if an upstream tarball needs to be built. + + Specifies the upstream tarball compression level if an upstream + tarball needs to be built. + - Purge (remove) temporary build directory after build + + Purge (remove) temporary build directory after build + - Deprecated, use --git-no-purge instead. + + Deprecated, use --git-no-purge instead. + - don't build, only tag and run post-tag hooks + + don't build, only tag and run post-tag hooks + - don't fail tag operations if a tag with the same version - already exists + + don't fail tag operations if a tag with the same version already + exists + - Use pristine-tar when generating the upstream tarball if it doesn't exist. + + Use pristine-tar when generating the upstream tarball if it doesn't + exist. + - Commit the pristine-tar delta to the pristine-tar branch if a new tarball was - generated and the pristine-tar data isn't already there. + + Commit the pristine-tar delta to the pristine-tar branch if a new + tarball was generated and the pristine-tar data isn't already there. + EXAMPLES - Build a Debian package using &git-pbuilder; which in turn invokes &cowbuildercmd;. - Instruct cowbuilder to build within a Wheezy chroot for i386. + + Build a Debian package using &git-pbuilder; which in turn invokes + &cowbuildercmd;. Instruct cowbuilder to build within a Wheezy chroot for + i386. + &gbp-buildpackage; --git-pbuilder --git-arch=i386 --git-dist=wheezy - Note that the above needs a &cowbuildercmd; chroot already. This can be created using: + Note that the above needs a &cowbuildercmd; chroot already. This can be + created using: DIST=wheezy ARCH=i386 &git-pbuilder; create @@ -487,31 +615,33 @@ &man.gbp.config-files; - All options in the config files are specified without the 'git-' prefix. + + All options in the config files are specified without the 'git-' prefix. + SEE ALSO - , - , - , - , - - git-pbuilder - 1 - , - - cowbuilder - 8 - , - , - &man.seealso.common; + , + , + , + , + + git-pbuilder + 1 + , + + cowbuilder + 8 + , + , + &man.seealso.common; AUTHOR - - &dhusername; &dhemail; - + + &dhusername; &dhemail; + -- cgit v1.2.3 From ee53516a70f3b6628f8e2180ba384753abe1485d Mon Sep 17 00:00:00 2001 From: Markus Lehtonen Date: Fri, 9 May 2014 15:04:20 +0300 Subject: docs: change option argument names to uppercase in buildpackage man For the sake of consistency. Signed-off-by: Markus Lehtonen --- docs/manpages/gbp-buildpackage.sgml | 78 ++++++++++++++++++------------------- 1 file changed, 39 insertions(+), 39 deletions(-) diff --git a/docs/manpages/gbp-buildpackage.sgml b/docs/manpages/gbp-buildpackage.sgml index d099e415..d0d68bc6 100644 --- a/docs/manpages/gbp-buildpackage.sgml +++ b/docs/manpages/gbp-buildpackage.sgml @@ -25,8 +25,8 @@ [auto|on|off] =COLOR_SCHEME [auto|on|off] - treeish - branch_name + TREEISH + BRANCH_NAME BUILD_CMD @@ -38,22 +38,22 @@ - gpg-keyid - command - command - command - command + GPG-KEYID + COMMAND + COMMAND + COMMAND + COMMAND - tag-format - tag-format + TAG-FORMAT + TAG-FORMAT - [TAG|BRANCH|treeish] - directory - type - level - directory - treeish + [TAG|BRANCH|TREEISH] + DIRECTORY + TYPE + LEVEL + DIRECTORY + TREEISH @@ -134,7 +134,7 @@ Don't abort if there are uncommitted changes in the source tree or the current branch doesn't match the - debian-branch. + DEBIAN-BRANCH. @@ -275,7 +275,7 @@ - =branch_name + =BRANCH_NAME @@ -287,7 +287,7 @@ - =branch_name + =BRANCH_NAME @@ -305,7 +305,7 @@ Don't check if the current branch matches - debian-branch. + DEBIAN-BRANCH. @@ -328,7 +328,7 @@ - gpg-keyid + GPG-KEYID @@ -337,11 +337,11 @@ - command + COMMAND - excecute command after tagging a new + excecute COMMAND after tagging a new version. @@ -353,11 +353,11 @@ - command + COMMAND - execute command after successful + execute COMMAND after successful build. @@ -368,11 +368,11 @@ - command + COMMAND - execute command after exporting the source + execute COMMAND after exporting the source tree - valid only if --git-export-dir has been specified. @@ -384,11 +384,11 @@ - command + COMMAND - execute command from the build directory + execute COMMAND from the build directory before calling debuild or the application specified via . @@ -411,7 +411,7 @@ - tag-format + TAG-FORMAT @@ -421,7 +421,7 @@ - tag-format + TAG-FORMAT @@ -460,23 +460,23 @@ - directory + DIRECTORY Export the current branch head (or the treeish object given via - to directory + to DIRECTORY before building. - treeish + TREEISH Instead of exporting the current branch head, export the treeish - object treeish. The special name + object TREEISH. The special name INDEX exports the current index whereas the special name WC exports the current working copy as is. @@ -484,7 +484,7 @@ - [tag|branch] + [TAG|BRANCH|TREEISH] @@ -502,17 +502,17 @@ - directory + DIRECTORY - Search for original tarballs in directory + Search for original tarballs in DIRECTORY instead of generating them - type + TYPE @@ -527,7 +527,7 @@ - level + LEVEL -- cgit v1.2.3 From 90a9323dd42510d1ac2dfc1fb84eab69533c75d8 Mon Sep 17 00:00:00 2001 From: Markus Lehtonen Date: Fri, 9 May 2014 14:40:25 +0300 Subject: docs: cosmetic reformat of import-orig manpage sgml source Makes the sgml source more readable. Fix indentation, tab to space, wrap lines. Signed-off-by: Markus Lehtonen --- docs/manpages/gbp-import-orig.sgml | 143 ++++++++++++++++++++++--------------- 1 file changed, 85 insertions(+), 58 deletions(-) diff --git a/docs/manpages/gbp-import-orig.sgml b/docs/manpages/gbp-import-orig.sgml index 74a0f634..967afc8c 100644 --- a/docs/manpages/gbp-import-orig.sgml +++ b/docs/manpages/gbp-import-orig.sgml @@ -9,7 +9,7 @@ - gbp-import-orig + gbp-import-orig &dhsection; @@ -37,8 +37,8 @@ - upstream-source - + upstream-source + @@ -50,148 +50,174 @@ be a gzip, bzip2, lzma or xz compressed tar archive, a zip archive or an already unpacked source tree. If it is already of the form package-name_version.orig.tar.gz, the version - information is read from the tarball's filename otherwise it can be - given on the command line via . - If the source package name or version can't be determined - &gbp-import-orig; will prompt for it unless - is given. - - The sources are placed on the upstream branch (default: + information is read from the tarball's filename otherwise it can be given + on the command line via . If the source + package name or version can't be determined &gbp-import-orig; will prompt + for it unless is given. + + + The sources are placed on the upstream branch (default: upstream), tagged and merged onto the debian branch (default: master). OPTIONS - =version version - The upstream version number + + The upstream version number + - Merge the upstream branch to the debian branch after import + + Merge the upstream branch to the debian branch after import + - =branch_name - The branch in the Git repository the upstream sources are put - onto. Default is upstream. + + The branch in the Git repository the upstream sources are put + onto. Default is upstream. + =branch_name - The branch in the Git repository the Debian package is being - developed on, default is master. After - importing the new sources on the upstream branch, &gbp-import-orig; - will try to merge the new version onto this branch. + + The branch in the Git repository the Debian package is being + developed on, default is master. After + importing the new sources on the upstream branch, &gbp-import-orig; + will try to merge the new version onto this branch. + =tag_name - - Add tag_name as additional parent to the commit - of the upstream tarball. Useful when upstream uses git and you want to - link to it's revision history. - + + Add tag_name as additional parent to the + commit of the upstream tarball. Useful when upstream uses git and you + want to link to it's revision history. + - + - verbose execution + + verbose execution + - GPG sign all created tags + + GPG sign all created tags + gpg-keyid - use this keyid for gpg signing tags + + use this keyid for gpg signing tags + tag-format - use this tag format when tagging upstream versions, - default is upstream/%(version)s + + use this tag format when tagging upstream versions, + default is upstream/%(version)s + msg-format - use this format string for the commit message when - importing upstream versions, default is Imported - Upstream version %(version)s + + use this format string for the commit message when importing upstream + versions, default is + Imported Upstream version %(version)s + pattern - filter out files glob-matching pattern. Can be given multiple times. + + filter out files glob-matching pattern. Can be given multiple times. + - generate pristine-tar delta file + + generate pristine-tar delta file + - if using a filter also filter the files out of the tarball - passed to pristine-tar + + if using a filter also filter the files out of the tarball + passed to pristine-tar + - - Whether to create and keep a symlink from the upstream tarball - to a Debian policy conformant upstream tarball name located in - ../. - - - This is a good idea if not using pristine-tar - since it avoids creating a new tarball with a different md5sum. - + + Whether to create and keep a symlink from the upstream tarball + to a Debian policy conformant upstream tarball name located in + ../. + + + This is a good idea if not using pristine-tar + since it avoids creating a new tarball with a different md5sum. + - run cmd after the import. + + run cmd after the import. + - Use uscan to fetch new upstream version. + + Use uscan to fetch new upstream version. + @@ -207,21 +233,24 @@ EXAMPLES - Download and import a new upstream version using the informantion from debian/watch + + Download and import a new upstream version using the informantion from debian/watch + &gbp-import-orig; --uscan - After downloading an upstream tarball by hand import it + + After downloading an upstream tarball by hand import it + &gbp-import-orig; ../upstream-tarball-0.1.tar.gz - &man.gbp.config-files; + &man.gbp.config-files; SEE ALSO - , , @@ -230,15 +259,13 @@ , &man.seealso.common; - AUTHOR - - &dhusername; &dhemail; - + + &dhusername; &dhemail; + - -- cgit v1.2.3 From 606f7d671cde8b9e70c154ca13cd706df2609b51 Mon Sep 17 00:00:00 2001 From: Markus Lehtonen Date: Fri, 9 May 2014 14:40:25 +0300 Subject: docs: cosmetic reformat of import-dsc manpage sgml source Makes the sgml source more readable. Fix indentation, tab to space, wrap lines. Signed-off-by: Markus Lehtonen --- docs/manpages/gbp-import-dsc.sgml | 117 ++++++++++++++++++++++++-------------- 1 file changed, 75 insertions(+), 42 deletions(-) diff --git a/docs/manpages/gbp-import-dsc.sgml b/docs/manpages/gbp-import-dsc.sgml index 6efb1c51..5549defd 100644 --- a/docs/manpages/gbp-import-dsc.sgml +++ b/docs/manpages/gbp-import-dsc.sgml @@ -20,7 +20,6 @@ &gbp-import-dsc; - @@ -40,13 +39,12 @@ &gbp-import-dsc; - - URL - source-package + URL + source-package @@ -61,135 +59,170 @@ OPTIONS - =branch_name - The branch in the &git; repository the upstream sources are put - onto. Default is upstream. + + The branch in the &git; repository the upstream sources are put + onto. Default is upstream. + =branch_name - The branch in the &git; repository the debian sources are put - onto. Default is master. + + The branch in the &git; repository the debian sources are put + onto. Default is master. + - + - verbose execution + + verbose execution + - GPG sign all created tags + + GPG sign all created tags + gpg-keyid - use this keyid for gpg signing tags + + use this keyid for gpg signing tags + tag-format - use this tag format when tagging Debian versions, - default is debian/%(version)s + + use this tag format when tagging Debian versions, + default is debian/%(version)s + tag-format - use this tag format when tagging upstream versions, - default is upstream/%(version)s + + use this tag format when tagging upstream versions, + default is upstream/%(version)s + - + + - Don't create Debian tag after importing the Debian patch. This can be useful - if you already created a package but want to further work on it after importing it - into git. + + Don't create Debian tag after importing the Debian patch. This can be + useful if you already created a package but want to further work on + it after importing it into git. + pattern - filter out files glob-matching pattern. Can be given multiple times. + + filter out files glob-matching pattern. Can be given multiple times. + - generate pristine-tar delta file + + generate pristine-tar delta file + - Download the source package instead of looking for it in the local - file system. The argument can either be a - source-package name or an - URL. The former uses &apt-get; to download - the source while the later uses &dget;. - + + Download the source package instead of looking for it in the local + file system. The argument can either be a + source-package name or an + URL. The former uses &apt-get; to download + the source while the later uses &dget;. + - Whether to skip signature verification on downloads. + + Whether to skip signature verification on downloads. + - Allow to import a package with the same debian version. + + Allow to import a package with the same debian version. + - When importing the Debian patch, use the author identity as - committer identity. + + When importing the Debian patch, use the author identity as + committer identity. + - When importing the Debian patch, use the author date as - committer date. Git will subtly misbehave if the - committer date of a commit is not later than or equal to all - its parents. + + When importing the Debian patch, use the author date as + committer date. + + + Git will subtly misbehave if the committer date of a commit is not + later than or equal to all its parents. + + + - Create missing upstream and debian branch if missing. + + Create missing upstream and debian branch if missing. + - + &man.gbp.config-files; @@ -216,8 +249,8 @@ AUTHOR - - &dhusername; &dhemail; - + + &dhusername; &dhemail; + -- cgit v1.2.3 From 1182964783ba8d681429f9880c7b29bb9173870a Mon Sep 17 00:00:00 2001 From: Markus Lehtonen Date: Fri, 9 May 2014 14:40:25 +0300 Subject: docs: cosmetic reformat of pq manpage sgml source Makes the sgml source more readable. Fix indentation, tab to space, wrap lines. Signed-off-by: Markus Lehtonen --- docs/manpages/gbp-pq.sgml | 155 +++++++++++++++++++++++++--------------------- 1 file changed, 85 insertions(+), 70 deletions(-) diff --git a/docs/manpages/gbp-pq.sgml b/docs/manpages/gbp-pq.sgml index 697916ca..07781893 100644 --- a/docs/manpages/gbp-pq.sgml +++ b/docs/manpages/gbp-pq.sgml @@ -14,7 +14,6 @@ gbp-pq - Manage quilt patches on patch queue branches in git @@ -28,27 +27,28 @@ num - - - - - + + + + + DESCRIPTION - &gbp-pq; helps one to manage quilt patches in Debian packages that are maintained - with &gbp;. This is especially useful with packages using the - 3.0 (quilt) source format. With &gbp-pq; you can maintain the quilt patches - that should be applied to a package on a separate branch called patch-queue - branch. So if your Debian package lives on master - the associated patch-queue branch will be called - patch-queue/master. + &gbp-pq; helps one to manage quilt patches in Debian packages that are + maintained with &gbp;. This is especially useful with packages using the + 3.0 (quilt) source format. With &gbp-pq; you can maintain the quilt patches + that should be applied to a package on a separate branch called patch-queue + branch. So if your Debian package lives on + master the associated patch-queue branch will be + called patch-queue/master. - See for example workflows. + See + for example workflows. @@ -58,65 +58,66 @@ - - Create a patch queue branch from quilt patches in - debian/patches/ that are listed in debian/patches/series. The - patches must apply without fuzz. - + + Create a patch queue branch from quilt patches in debian/patches/ + that are listed in debian/patches/series. The patches must apply + without fuzz. + - - Export the patches on the patch-queue branch associated to the current - branch into a quilt patch series in debian/patches/ and update the - series file. - + + Export the patches on the patch-queue branch associated to the + current branch into a quilt patch series in debian/patches/ and + update the series file. + - - Switch to the patch-queue branch associated to the current branch and - rebase it against the current branch. - + + Switch to the patch-queue branch associated to the current branch and + rebase it against the current branch. + - - Drop (delete) the patch queue associated to the current branch. So if - you're on branch foo this would drop branch - patch-queue/foo. - + + Drop (delete) the patch queue associated to the current branch. So if + you're on branch foo this would drop + branch patch-queue/foo. + - - Add a single patch to the patch-queue similar to using - git-am. Use if you want - the patch to appear in a separate subdir when exporting the patch queue - using . This can be used to separate upstream - pathes from debian specific patches. + + Add a single patch to the patch-queue similar to using + git-am. Use if you want + the patch to appear in a separate subdir when exporting the patch queue + using . This can be used to separate upstream + pathes from debian specific patches. + - - Switch to the patch-queue branch if on the base branch and switch - to base branch if on patch-queue branch. - + + Switch to the patch-queue branch if on the base branch and switch + to base branch if on patch-queue branch. + @@ -126,16 +127,20 @@ - + - verbose execution + + verbose execution + [auto|on|off] - Whether to use colored output. + + Whether to use colored output. + @@ -156,26 +161,31 @@ - Whether the patch files should start with a number or not. + + Whether the patch files should start with a number or not. + topic - Topic to use when importing a single patch + + Topic to use when importing a single patch + NUM - When importing a patch queue fails, go back commit by - commit on the current branch to check if the patch-queue applies - there. Do this at most NUM times. This can - be useful if the patch-queue doesn't apply to the current branch HEAD - anymore, e.g. after importing a new upstream version. - + + When importing a patch queue fails, go back commit by commit on the + current branch to check if the patch-queue applies there. Do this at + most NUM times. This can be useful if the + patch-queue doesn't apply to the current branch HEAD anymore, e.g. + after importing a new upstream version. + @@ -196,28 +206,33 @@ - + + - Ignores the commit, no patch is generated out of it. + + Ignores the commit, no patch is generated out of it. + - topic + topic + - Moves the patch into a subdir called - topic when running - &gbp-pq; export - This allows for some structure below - debian/patches. - + + Moves the patch into a subdir called topic + when running &gbp-pq; export This allows for some + structure below debian/patches. + - topic + topic + - Deprecated: use - topic instead. - + + Deprecated: use + topic instead. + @@ -239,8 +254,8 @@ AUTHOR - - &dhusername; &dhemail; - + + &dhusername; &dhemail; + -- cgit v1.2.3 From 8d0e82339ffddac23ad38047bb5adc201cc50167 Mon Sep 17 00:00:00 2001 From: Markus Lehtonen Date: Fri, 9 May 2014 14:40:25 +0300 Subject: docs: cosmetic reformat of git-dch manpage sgml source Makes the sgml source more readable. Fix indentation, tab to space, wrap lines. Signed-off-by: Markus Lehtonen --- docs/manpages/gbp-dch.sgml | 354 ++++++++++++++++++++++++++------------------- 1 file changed, 207 insertions(+), 147 deletions(-) diff --git a/docs/manpages/gbp-dch.sgml b/docs/manpages/gbp-dch.sgml index 94a535ac..5d539949 100644 --- a/docs/manpages/gbp-dch.sgml +++ b/docs/manpages/gbp-dch.sgml @@ -9,7 +9,7 @@ - gbp-dch + gbp-dch &dhsection; @@ -20,7 +20,6 @@ &gbp-dch; - branch_name tag-format @@ -28,18 +27,18 @@ - + - - commitish + + commitish version - - - - + + + + name @@ -69,11 +68,14 @@ distribution of the topmost section in debian/changelog is UNRELEASED the changelog entries will be inserted into this section. Otherwise a new - section will be created. - If is given &gbp-dch; tries to guess the + section will be created. + + + If is given &gbp-dch; tries to guess the last &git; commit documented in the changelog - this only works in snapshot mode. Otherwise can be used to tell &gbp-dch; - at which point it should start in the &git; history. + at which point it should start in the &git; history. + The additional path arguments can be used to restrict the repository paths &gbp-dch; looks at. Setting path to @@ -81,106 +83,131 @@ all Debian packaging changes are restricted to the debian/ subdir. In more sophisticated cases (like backports) you can use to restrict the - generated changelog entries further. E.g. by using - "--author=Foo Bar". + generated changelog entries further. E.g. by using + "--author=Foo Bar". + OPTIONS - =branch_name - The branch in the Git repository the Debian package is being - developed on, default is master. + + The branch in the Git repository the Debian package is being + developed on, default is master. + - Don't check if the current branch matches - debian-branch. + + Don't check if the current branch matches + debian-branch. + - - + + - verbose execution + + verbose execution + tag-format - tag format used, when tagging debian versions, - default is debian/%(version)s + + tag format used, when tagging debian versions, + default is debian/%(version)s + committish - Start reading commit messages at committish. + + Start reading commit messages at + committish. + , - + - Guess the last commit documented in the changelog from the - snapshot banner (or from the last tag if no snapshot banner exists). - + + Guess the last commit documented in the changelog from the + snapshot banner (or from the last tag if no snapshot banner exists). + - Parse meta tags like , - and . See META TAGS below. + + Parse meta tags like , + and . See META TAGS + below. + bug-close-tags - What meta tags to look for to generate bug-closing changelog - entries. The default is 'Closes|LP' to support Debian and - Launchpad. + + What meta tags to look for to generate bug-closing changelog entries. + The default is 'Closes|LP' to support Debian and Launchpad. + - + + - Include the full commit message in the changelog output. + + Include the full commit message in the changelog output. + , - Create a snapshot release entry. This adds a snapshot release - number and a warning banner to the changelog entry. The release - version number is being auto incremented with every new snapshot - release to avoid packages downgrades during snapshot testing. + + Create a snapshot release entry. This adds a snapshot release + number and a warning banner to the changelog entry. The release + version number is being auto incremented with every new snapshot + release to avoid packages downgrades during snapshot testing. + expression - Python expression that gets eval()ed to the new snapshot number. + + Python expression that gets eval()ed to the new snapshot number. + , - Remove any snapshot release banners and version suffixes, set - the current distribution to unstable and - open the changelog for final tweaking. + + Remove any snapshot release banners and version suffixes, set + the current distribution to unstable and + open the changelog for final tweaking. + @@ -188,129 +215,157 @@ version - Add a new changelog section with version - newversion. Together with - the snapshot number will be appended to - newversion. + + Add a new changelog section with version + newversion. Together with + the snapshot number will be appended to + newversion. + - + + - Create a Team upload changelog entry. + + Create a Team upload changelog entry. + - Increment the Debian release number for an upload to - backports, and add a backport upload changelog comment. + + Increment the Debian release number for an upload to backports, and + add a backport upload changelog comment. + - Increment the Debian release number for a non-maintainer upload. + + Increment the Debian release number for a non-maintainer upload. + - Increment the Debian release number for a Debian QA Team - upload, and add a QA upload changelog comment. + + Increment the Debian release number for a Debian QA Team upload, and + add a QA upload changelog comment. + - name - - - Set the distribution field - to name. - + name + + + + Set the distribution field to name. + + - - - - Force the distribution specified - with to be used, even if it - doesn't match the list of known distributions. - + + + + + Force the distribution specified with + to be used, even if it doesn't match the list of known distributions. + + - level - - - Set the urgency field - to level. - + level + + + + Set the urgency field to level. + + git-log-options - Options passed on verbatim to git-log(1). + + Options passed on verbatim to git-log(1). + N - Include N digits of the commit id in - the changelog entry. Default is to not include any commit ids at - all. + + Include N digits of the commit id in the + changelog entry. Default is to not include any commit ids at all. + regex - Ignore commit lines matching regex - when generating the changelog. - + + Ignore commit lines matching regex + when generating the changelog. + - Use user.name and user.email from git-config(1) for changelog trailer. + + Use user.name and user.email from + git-config(1) for changelog trailer. + - Merge commits by maintainer. + + Merge commits by maintainer. + - Whether to spawn an editor: always, when doing snapshots or - when doing a release. + + Whether to spawn an editor: always, when doing snapshots or when + doing a release. + msg-format - use this format string for the commit message when - committing the generated changelog file (when - is given). Default is - Update changelog for %(version)s - release + + use this format string for the commit message when committing the + generated changelog file (when is given). + Default is + Update changelog for %(version)s release + - Commit the generated changelog. + + Commit the generated changelog. + @@ -327,27 +382,29 @@ - Snapshot mode - - Snapshot mode can be used for quick test and install cycles without - having to worry about version numbers or changelog entries. - - When using or &gbp-dch; - uses a pseudo header in the Debian changelog to remember the last git - commit it added a changelog entry for. It also sets a version number - ending in - ~<snaspshotnumber>.gbp<commitid>. - It automatically increments the snapshot number on subsequent invocations - of &gbp-dch; so that later snapshots automatically - have a higher version number. To leave snapshot mode invoke &gbp-dch; - with the option. This removes the pseudo - header and unmangles the version number so the released version has a - higher version number than the snapshots. - + Snapshot mode + + Snapshot mode can be used for quick test and install cycles without + having to worry about version numbers or changelog entries. + + + When using or &gbp-dch; + uses a pseudo header in the Debian changelog to remember the last git + commit it added a changelog entry for. It also sets a version number + ending in + ~<snaspshotnumber>.gbp<commitid>. + It automatically increments the snapshot number on subsequent invocations + of &gbp-dch; so that later snapshots automatically + have a higher version number. To leave snapshot mode invoke &gbp-dch; + with the option. This removes the pseudo + header and unmangles the version number so the released version has a + higher version number than the snapshots. + META TAGS - Additional to the above options the formatting of the commit message + + Additional to the above options the formatting of the commit message in debian/changelog can be modified by special tags (called Meta Tags) given in the git commit message. Meta Tag processing can be activated via @@ -360,40 +417,44 @@ : action - - Supported actions are: Ignore which will ignore - this commit when generating debian/changelog, - Short which will only use the - description (the first line) of the commit message when - generating the changelog entry (useful when - is given) and - Full which will use the full commit - message when generating the changelog entry (useful when - is not given). - - - - : msg - - - - Add a thanks message after the commit message. - - - - - : bugnumber - - - - Indicate in the debian/changelog that the bug was - closed by this commit. See the - on how to extend this for other bugtrackers. - - + + + Supported actions are: Ignore which will + ignore this commit when generating + debian/changelog, + Short which will only use the description + (the first line) of the commit message when generating the changelog + entry (useful when is given) and + Full which will use the full commit + message when generating the changelog entry (useful when + is not given). + + + + + : msg + + + + Add a thanks message after the commit message. + + + + + : bugnumber + + + + Indicate in the debian/changelog that the bug + was closed by this commit. See the on + how to extend this for other bugtrackers. + + - The following git commit message: + + The following git commit message: + Document meta tags @@ -404,7 +465,7 @@ Thanks: Raphaël Hertzog for the suggestion - Results in this debian/changelog entry: + Results in this debian/changelog entry: * Document meta tags. @@ -412,11 +473,10 @@ - &man.gbp.config-files; + &man.gbp.config-files; SEE ALSO - , , @@ -430,8 +490,8 @@ AUTHOR - - &dhusername; &dhemail; - + + &dhusername; &dhemail; + -- cgit v1.2.3 From 45df3f62b26867589f6a23b3f65e39a137695dd2 Mon Sep 17 00:00:00 2001 From: Markus Lehtonen Date: Wed, 21 May 2014 10:24:21 +0300 Subject: docs: document common options in one place Move the documentation of command line options common to all tools into one file. This unifies the manpage documentation and should make its maintenance easier. Also, this change adds missing options to several manpages. Signed-off-by: Markus Lehtonen --- docs/manpages/gbp-clone.sgml | 11 ++---- docs/manpages/gbp-config.sgml | 33 +--------------- docs/manpages/gbp-create-remote-repo.sgml | 19 ++------- docs/manpages/gbp-dch.sgml | 13 ++----- docs/manpages/gbp-import-dsc.sgml | 13 ++----- docs/manpages/gbp-import-orig.sgml | 13 ++----- docs/manpages/gbp-pq.sgml | 38 ++---------------- docs/manpages/gbp-pull.sgml | 11 ++---- docs/manpages/man.common-options.ent | 65 +++++++++++++++++++++++++++++++ docs/manpages/manpages.ent | 2 + 10 files changed, 90 insertions(+), 128 deletions(-) create mode 100644 docs/manpages/man.common-options.ent diff --git a/docs/manpages/gbp-clone.sgml b/docs/manpages/gbp-clone.sgml index 2dec88dd..20e61472 100644 --- a/docs/manpages/gbp-clone.sgml +++ b/docs/manpages/gbp-clone.sgml @@ -21,7 +21,7 @@ &gbp-clone; - + &man.common.options.synopsis; branch_name @@ -43,6 +43,8 @@ OPTIONS + &man.common.options.description; + @@ -74,13 +76,6 @@ Git history depth, for creating shallow git clones. - - - - - verbose execution - - diff --git a/docs/manpages/gbp-config.sgml b/docs/manpages/gbp-config.sgml index 599d1168..9b3d7edd 100644 --- a/docs/manpages/gbp-config.sgml +++ b/docs/manpages/gbp-config.sgml @@ -21,9 +21,7 @@ &gbp-config; - - [auto|on|off] - =COLOR_SCHEME + &man.common.options.synopsis; command.option command @@ -41,34 +39,7 @@ OPTIONS - - - - - verbose execution - - - - [auto|on|off] - - - Whether to use colored output. - - - - =COLOR_SCHEME - - - Colors to use in output (when color is enabled). The format for - COLOR_SCHEME is - '<debug>:<info>:<warning>:<error>'. - Numerical values and color names are accepted, empty fields imply - the default color. For example --git-color-scheme='cyan:34::' would - show debug messages in cyan, info messages in blue and other messages - in default (i.e. warning and error messages in red). - - - + &man.common.options.description; diff --git a/docs/manpages/gbp-create-remote-repo.sgml b/docs/manpages/gbp-create-remote-repo.sgml index a874b004..e8f6a092 100644 --- a/docs/manpages/gbp-create-remote-repo.sgml +++ b/docs/manpages/gbp-create-remote-repo.sgml @@ -20,8 +20,7 @@ &gbp-create-remote-repo; - - [auto|on|off] + &man.common.options.synopsis; url-pattern name directory @@ -52,6 +51,8 @@ OPTIONS + &man.common.options.description; + =pattern @@ -111,20 +112,6 @@ Whether to push the pristine tar branch. - - - - - verbose execution - - - - [auto|on|off] - - - Whether to use colored output. - - diff --git a/docs/manpages/gbp-dch.sgml b/docs/manpages/gbp-dch.sgml index 5d539949..8ffdc4f6 100644 --- a/docs/manpages/gbp-dch.sgml +++ b/docs/manpages/gbp-dch.sgml @@ -20,7 +20,7 @@ &gbp-dch; - + &man.common.options.synopsis; branch_name tag-format tag-format @@ -90,6 +90,8 @@ OPTIONS + &man.common.options.description; + =branch_name @@ -110,15 +112,6 @@ - - - - - - verbose execution - - - tag-format diff --git a/docs/manpages/gbp-import-dsc.sgml b/docs/manpages/gbp-import-dsc.sgml index 5549defd..e635a3d9 100644 --- a/docs/manpages/gbp-import-dsc.sgml +++ b/docs/manpages/gbp-import-dsc.sgml @@ -20,6 +20,7 @@ &gbp-import-dsc; + &man.common.options.synopsis; @@ -34,7 +35,6 @@ branch_name tag-format - debian-source.dsc @@ -60,6 +60,8 @@ OPTIONS + &man.common.options.description; + =branch_name @@ -80,15 +82,6 @@ - - - - - - verbose execution - - - diff --git a/docs/manpages/gbp-import-orig.sgml b/docs/manpages/gbp-import-orig.sgml index 967afc8c..b744752a 100644 --- a/docs/manpages/gbp-import-orig.sgml +++ b/docs/manpages/gbp-import-orig.sgml @@ -21,7 +21,7 @@ &gbp-import-orig; - + &man.common.options.synopsis; version branch_name @@ -64,6 +64,8 @@ OPTIONS + &man.common.options.description; + =version version @@ -114,15 +116,6 @@ - - - - - - verbose execution - - - diff --git a/docs/manpages/gbp-pq.sgml b/docs/manpages/gbp-pq.sgml index 07781893..e0942083 100644 --- a/docs/manpages/gbp-pq.sgml +++ b/docs/manpages/gbp-pq.sgml @@ -19,9 +19,7 @@ &gbp-pq; - - [auto|on|off] - =COLOR_SCHEME + &man.common.options.synopsis; topic num @@ -125,38 +123,8 @@ OPTIONS - - - - - - verbose execution - - - - - [auto|on|off] - - - - Whether to use colored output. - - - - - =COLOR_SCHEME - - - Colors to use in output (when color is enabled). The format for - COLOR_SCHEME is - '<debug>:<info>:<warning>:<error>'. - Numerical values and color names are accepted, empty fields imply - the default color. For example --git-color-scheme='cyan:34::' would - show debug messages in cyan, info messages in blue and other messages - in default (i.e. warning and error messages in red). - - - + &man.common.options.description; + diff --git a/docs/manpages/gbp-pull.sgml b/docs/manpages/gbp-pull.sgml index 7a9d235f..fd658c8d 100644 --- a/docs/manpages/gbp-pull.sgml +++ b/docs/manpages/gbp-pull.sgml @@ -21,7 +21,7 @@ &gbp-pull; - + &man.common.options.synopsis; @@ -44,6 +44,8 @@ OPTIONS + &man.common.options.description; + @@ -89,13 +91,6 @@ Git history depth, for deepening shallow git clones. - - - - - verbose execution - - diff --git a/docs/manpages/man.common-options.ent b/docs/manpages/man.common-options.ent new file mode 100644 index 00000000..74bd9f0d --- /dev/null +++ b/docs/manpages/man.common-options.ent @@ -0,0 +1,65 @@ + + + + [auto|on|off] + COLOR_SCHEME +" +> + + + + + Print version of the program, i.e. version of the git-buildpackage + suite + + + + + + + + + Verbose execution + + + + + + + + + Print help and exit + + + + + [auto|on|off] + + + + Whether to use colored output. + + + + + COLOR_SCHEME + + + + Colors to use in output (when color is enabled). The format for + COLOR_SCHEME is + '<debug>:<info>:<warning>:<error>'. + Numerical values and color names are accepted, empty fields imply + the default color. For example --git-color-scheme='cyan:34::' would + show debug messages in cyan, info messages in blue and other messages + in default (i.e. warning and error messages in red). + + + +" +> + diff --git a/docs/manpages/manpages.ent b/docs/manpages/manpages.ent index d5882548..6b8ea95f 100644 --- a/docs/manpages/manpages.ent +++ b/docs/manpages/manpages.ent @@ -12,3 +12,5 @@ + +%COMMON.OPTIONS; -- cgit v1.2.3 From bd4997fa96b66b0639258e38060cabea8e7fd0e0 Mon Sep 17 00:00:00 2001 From: Markus Lehtonen Date: Tue, 10 Sep 2013 15:29:31 +0300 Subject: GitRepository: new method for getting git output as generator Add a new _git_inout2() helper method that returns the git output (stdout) as a generator - instead of all stdout data in one string. Useful for handling git commands that are expected to have a lot of stdout data, like git-archive. Also, changes the private __git_inout() method to return a generator. Signed-off-by: Markus Lehtonen --- gbp/git/repository.py | 111 ++++++++++++++++++++++++++++++++++++++------------ 1 file changed, 86 insertions(+), 25 deletions(-) diff --git a/gbp/git/repository.py b/gbp/git/repository.py index 23f9482a..db9659ba 100644 --- a/gbp/git/repository.py +++ b/gbp/git/repository.py @@ -20,6 +20,7 @@ import subprocess import os.path import re from collections import defaultdict +import select import gbp.log as log from gbp.errors import GbpError @@ -160,28 +161,86 @@ class GitRepository(object): """ if not cwd: cwd = self.path - return self.__git_inout(command, args, input, extra_env, cwd, capture_stderr) + ret = 0 + stdout = '' + stderr = '' + try: + for outdata in self.__git_inout(command, args, input, extra_env, + cwd, capture_stderr): + stdout += outdata[0] + stderr += outdata[1] + except GitRepositoryError as err: + ret = err.returncode + return stdout, stderr, ret + + def _git_inout2(self, command, args, stdin=None, extra_env=None, cwd=None, + capture_stderr=False): + """ + Quite similar to C{_git_inout()} but returns stdout output of the git + command as a Python generator object, instead. Also, stderr is not + returned. + + @note: The caller must consume the iterator that is returned, in order + to make sure that the git command runs and terminates. + """ + if not cwd: + cwd = self.path + stderr = '' + try: + for outdata in self.__git_inout(command, args, stdin, extra_env, + cwd, capture_stderr): + stderr += outdata[1] + yield outdata[0] + except GitRepositoryError as err: + err.stderr = stderr + raise err @classmethod - def __git_inout(cls, command, args, input, extra_env, cwd, capture_stderr): + def __git_inout(cls, command, args, stdin, extra_env, cwd, capture_stderr): """ - As _git_inout but can be used without an instance + Run a git command without a a GitRepostitory instance. + + Returns the git command output (stdout, stderr) as a Python generator + object. + + @note: The caller must consume the iterator that is returned, in order + to make sure that the git command runs and terminates. """ + def rm_polled_fd(file_obj, select_list): + file_obj.close() + select_list.remove(file_obj) + cmd = ['git', command] + args env = cls.__build_env(extra_env) stderr_arg = subprocess.PIPE if capture_stderr else None - stdin_arg = subprocess.PIPE if input else None log.debug(cmd) popen = subprocess.Popen(cmd, - stdin=stdin_arg, + stdin=subprocess.PIPE, stdout=subprocess.PIPE, stderr=stderr_arg, env=env, close_fds=True, cwd=cwd) - (stdout, stderr) = popen.communicate(input) - return stdout, stderr, popen.returncode + if stdin: + popen.stdin.write(stdin) + popen.stdin.close() + out_fds = [popen.stdout] + ([popen.stderr] if capture_stderr else []) + while out_fds: + ready = select.select(out_fds, [], []) + # Read in chunks of 4k + stdout = popen.stdout.read(4096) if popen.stdout in ready[0] else '' + stderr = popen.stderr.read(4096) if popen.stderr in ready[0] else '' + if popen.stdout in ready[0] and not stdout: + rm_polled_fd(popen.stdout, out_fds) + if popen.stderr in ready[0] and not stderr: + rm_polled_fd(popen.stderr, out_fds) + yield stdout, stderr + + if popen.wait(): + err = GitRepositoryError('git-%s failed' % command) + err.returncode = popen.returncode + raise err def _git_command(self, command, args=[], extra_env=None): """ @@ -1776,18 +1835,19 @@ class GitRepository(object): try: if not os.path.exists(abspath): os.makedirs(abspath) + stderr = '' try: - stdout, stderr, ret = klass.__git_inout(command='init', - args=args.args, - input=None, - extra_env=None, - cwd=abspath, - capture_stderr=True) + for out in klass.__git_inout(command='init', + args=args.args, + stdin=None, + extra_env=None, + cwd=abspath, + capture_stderr=True): + stderr += out[1] + except GitRepositoryError: + raise GitRepositoryError("Error running git init: %s" % stderr) except Exception as excobj: raise GitRepositoryError("Error running git init: %s" % excobj) - if ret: - raise GitRepositoryError("Error running git init: %s" % stderr) - if description: with open(os.path.join(abspath, git_dir, "description"), 'w') as f: description += '\n' if description[-1] != '\n' else '' @@ -1838,18 +1898,19 @@ class GitRepository(object): try: if not os.path.exists(abspath): os.makedirs(abspath) - + stderr = '' try: - stdout, stderr, ret = klass.__git_inout(command='clone', - args=args.args, - input=None, - extra_env=None, - cwd=abspath, - capture_stderr=True) + for out in klass.__git_inout(command='clone', + args=args.args, + stdin=None, + extra_env=None, + cwd=abspath, + capture_stderr=True): + stderr += out[1] + except GitRepositoryError: + raise GitRepositoryError("Error running git clone: %s" % stderr) except Exception as excobj: raise GitRepositoryError("Error running git clone: %s" % excobj) - if ret: - raise GitRepositoryError("Error running git clone: %s" % stderr) if not name: try: -- cgit v1.2.3 From 570c282965df5d1aae7c3f7a6ef42b2705858f76 Mon Sep 17 00:00:00 2001 From: Markus Lehtonen Date: Wed, 18 Sep 2013 17:20:41 +0300 Subject: GitRepository.__git_inout: prevent blocking of stdin Signed-off-by: Markus Lehtonen --- gbp/git/repository.py | 18 ++++++++++++------ 1 file changed, 12 insertions(+), 6 deletions(-) diff --git a/gbp/git/repository.py b/gbp/git/repository.py index db9659ba..0522ecbb 100644 --- a/gbp/git/repository.py +++ b/gbp/git/repository.py @@ -212,22 +212,28 @@ class GitRepository(object): cmd = ['git', command] + args env = cls.__build_env(extra_env) + stdin_arg = subprocess.PIPE if stdin else None stderr_arg = subprocess.PIPE if capture_stderr else None log.debug(cmd) popen = subprocess.Popen(cmd, - stdin=subprocess.PIPE, + stdin=stdin_arg, stdout=subprocess.PIPE, stderr=stderr_arg, env=env, close_fds=True, cwd=cwd) - if stdin: - popen.stdin.write(stdin) - popen.stdin.close() out_fds = [popen.stdout] + ([popen.stderr] if capture_stderr else []) - while out_fds: - ready = select.select(out_fds, [], []) + in_fds = [popen.stdin] if stdin else [] + w_ind = 0 + while out_fds or in_fds: + ready = select.select(out_fds, in_fds, []) + # Write in chunks of 512 bytes + if ready[1]: + popen.stdin.write(stdin[w_ind:w_ind+512]) + w_ind += 512 + if w_ind > len(stdin): + rm_polled_fd(popen.stdin, in_fds) # Read in chunks of 4k stdout = popen.stdout.read(4096) if popen.stdout in ready[0] else '' stderr = popen.stderr.read(4096) if popen.stderr in ready[0] else '' -- cgit v1.2.3 From 8cca0f69e3960d694d8bbb87d0cb9aab0858f8c4 Mon Sep 17 00:00:00 2001 From: Markus Lehtonen Date: Thu, 12 Sep 2013 10:47:35 +0300 Subject: GitRepository.archive: support getting tar data as return value Return tar data as a generator object, if the 'output' option is not defined. Signed-off-by: Markus Lehtonen --- gbp/git/repository.py | 24 +++++++++++++++++------- tests/test_PristineTar.py | 2 +- 2 files changed, 18 insertions(+), 8 deletions(-) diff --git a/gbp/git/repository.py b/gbp/git/repository.py index 0522ecbb..db863dcc 100644 --- a/gbp/git/repository.py +++ b/gbp/git/repository.py @@ -1714,17 +1714,27 @@ class GitRepository(object): @type format: C{str} @param prefix: prefix to prepend to each filename in the archive @type prefix: C{str} - @param output: the name of the archive to create - @type output: C{str} + @param output: the name of the archive to create, empty string or + C{None} gives data as return value + @type output: C{str} or C{None} @param treeish: the treeish to create the archive from @type treeish: C{str} @param kwargs: additional commandline options passed to git-archive + + @return: archive data as a generator object + @rtype: C{None} or C{generator} of C{str} """ - args = [ '--format=%s' % format, '--prefix=%s' % prefix, - '--output=%s' % output, treeish ] - out, ret = self._git_getoutput('archive', args, **kwargs) - if ret: - raise GitRepositoryError("Unable to archive %s" % treeish) + args = GitArgs('--format=%s' % format, '--prefix=%s' % prefix) + args.add_true(output, '--output=%s' % output) + args.add(treeish) + + if output: + out, err, ret = self._git_inout('archive', args.args, **kwargs) + if ret: + raise GitRepositoryError("Unable to archive %s: %s" % (treeish, + err)) + else: + return self._git_inout2('archive', args.args, **kwargs) def collect_garbage(self, auto=False): """ diff --git a/tests/test_PristineTar.py b/tests/test_PristineTar.py index e837ef88..61fb9a9a 100644 --- a/tests/test_PristineTar.py +++ b/tests/test_PristineTar.py @@ -72,7 +72,7 @@ def test_create_tarball(): >>> import gbp.deb.git >>> repo = gbp.deb.git.DebianGitRepository(repo_dir) - >>> repo.archive('tar', 'upstream/', '../upstream_1.0.orig.tar', 'upstream') + >>> repo.archive('tar', 'upstream/', '%s/../upstream_1.0.orig.tar' % repo_dir, 'upstream') >>> gbp.command_wrappers.Command('gzip', [ '-n', '%s/../upstream_1.0.orig.tar' % repo_dir])() """ -- cgit v1.2.3 From 10be2a2cd01869409458039080ee86e7b0031dee Mon Sep 17 00:00:00 2001 From: Markus Lehtonen Date: Tue, 15 May 2012 16:37:33 +0300 Subject: common/buildpackage: support for different archive formats Adds support for defining the archive format of the output of git_archive_single(), e.g. 'zip'. Defaults to 'tar', as before. Signed-off-by: Ed Bartosh Signed-off-by: Markus Lehtonen --- gbp/command_wrappers.py | 10 ++++++++ gbp/scripts/common/buildpackage.py | 48 ++++++++++++++++++++++---------------- 2 files changed, 38 insertions(+), 20 deletions(-) diff --git a/gbp/command_wrappers.py b/gbp/command_wrappers.py index b8bd21f7..f1312e4c 100644 --- a/gbp/command_wrappers.py +++ b/gbp/command_wrappers.py @@ -233,6 +233,16 @@ class UnpackZipArchive(Command): self.run_error = 'Couldn\'t unpack "%s"' % self.archive +class CatenateZipArchive(Command): + """Wrap zipmerge tool to catenate a zip file with the next""" + def __init__(self, archive, **kwargs): + self.archive = archive + Command.__init__(self, 'zipmerge', [archive], **kwargs) + + def __call__(self, target): + Command.__call__(self, [target]) + + class GitCommand(Command): "Mother/Father of all git commands" def __init__(self, cmd, args=[], **kwargs): diff --git a/gbp/scripts/common/buildpackage.py b/gbp/scripts/common/buildpackage.py index 0522cd6b..e293c333 100644 --- a/gbp/scripts/common/buildpackage.py +++ b/gbp/scripts/common/buildpackage.py @@ -22,7 +22,7 @@ import os, os.path import pipes import tempfile import shutil -from gbp.command_wrappers import (CatenateTarArchive) +from gbp.command_wrappers import (CatenateTarArchive, CatenateZipArchive) from gbp.errors import GbpError import gbp.log @@ -50,51 +50,59 @@ def sanitize_prefix(prefix): return '/' -def git_archive_submodules(repo, treeish, output, prefix, comp_type, comp_level, comp_opts): +def git_archive_submodules(repo, treeish, output, prefix, comp_type, comp_level, + comp_opts, format='tar'): """ - Create tar.gz of an archive with submodules + Create a source tree archive with submodules. - since git-archive always writes an end of tarfile trailer we concatenate + Since git-archive always writes an end of tarfile trailer we concatenate the generated archives using tar and compress the result. Exception handling is left to the caller. """ prefix = sanitize_prefix(prefix) - tarfile = output.rsplit('.', 1)[0] tempdir = tempfile.mkdtemp() - submodule_tarfile = os.path.join(tempdir, "submodule.tar") + main_archive = os.path.join(tempdir, "main.%s" % format) + submodule_archive = os.path.join(tempdir, "submodule.%s" % format) try: - # generate main tarfile - repo.archive(format='tar', prefix=prefix, - output=tarfile, treeish=treeish) + # generate main (tmp) archive + repo.archive(format=format, prefix=prefix, + output=main_archive, treeish=treeish) - # generate each submodule's tarfile and append it to the main archive + # generate each submodule's arhive and append it to the main archive for (subdir, commit) in repo.get_submodules(treeish): tarpath = [subdir, subdir[2:]][subdir.startswith("./")] gbp.log.debug("Processing submodule %s (%s)" % (subdir, commit[0:8])) - repo.archive(format='tar', prefix='%s%s/' % (prefix, tarpath), - output=submodule_tarfile, treeish=commit, cwd=subdir) - CatenateTarArchive(tarfile)(submodule_tarfile) + repo.archive(format=format, prefix='%s%s/' % (prefix, tarpath), + output=submodule_archive, treeish=commit, cwd=subdir) + if format == 'tar': + CatenateTarArchive(main_archive)(submodule_archive) + elif format == 'zip': + CatenateZipArchive(main_archive)(submodule_archive) # compress the output - ret = os.system("%s -%s %s %s" % (comp_type, comp_level, comp_opts, tarfile)) - if ret: - raise GbpError("Error creating %s: %d" % (output, ret)) + if comp_type: + ret = os.system("%s --stdout -%s %s %s > %s" % (comp_type, comp_level, comp_opts, main_archive, output)) + if ret: + raise GbpError("Error creating %s: %d" % (output, ret)) + else: + shutil.move(main_archive, output) finally: shutil.rmtree(tempdir) -def git_archive_single(treeish, output, prefix, comp_type, comp_level, comp_opts): +def git_archive_single(treeish, output, prefix, comp_type, comp_level, comp_opts, format='tar'): """ - Create tar.gz of an archive without submodules + Create an archive without submodules Exception handling is left to the caller. """ prefix = sanitize_prefix(prefix) pipe = pipes.Template() - pipe.prepend("git archive --format=tar --prefix=%s %s" % (prefix, treeish), '.-') - pipe.append('%s -c -%s %s' % (comp_type, comp_level, comp_opts), '--') + pipe.prepend("git archive --format=%s --prefix=%s %s" % (format, prefix, treeish), '.-') + if comp_type: + pipe.append('%s -c -%s %s' % (comp_type, comp_level, comp_opts), '--') ret = pipe.copy('', output) if ret: raise GbpError("Error creating %s: %d" % (output, ret)) -- cgit v1.2.3 From 083118a02df87f284ccabcb582e6a32140579464 Mon Sep 17 00:00:00 2001 From: Markus Lehtonen Date: Tue, 18 Sep 2012 18:16:50 +0300 Subject: Change compressor cmdline opts in compressor_opts to a list Signed-off-by: Markus Lehtonen --- gbp/pkg/__init__.py | 8 ++++---- gbp/scripts/common/buildpackage.py | 7 +++++-- 2 files changed, 9 insertions(+), 6 deletions(-) diff --git a/gbp/pkg/__init__.py b/gbp/pkg/__init__.py index e68fc61a..40e20dde 100644 --- a/gbp/pkg/__init__.py +++ b/gbp/pkg/__init__.py @@ -25,10 +25,10 @@ import gbp.command_wrappers as gbpc from gbp.errors import GbpError # compression types, extra options and extensions -compressor_opts = { 'gzip' : [ '-n', 'gz' ], - 'bzip2' : [ '', 'bz2' ], - 'lzma' : [ '', 'lzma' ], - 'xz' : [ '', 'xz' ] } +compressor_opts = { 'gzip' : [ ['-n'], 'gz' ], + 'bzip2' : [ [], 'bz2' ], + 'lzma' : [ [], 'lzma' ], + 'xz' : [ [], 'xz' ] } # Map frequently used names of compression types to the internal ones: compressor_aliases = { 'bz2' : 'bzip2', diff --git a/gbp/scripts/common/buildpackage.py b/gbp/scripts/common/buildpackage.py index e293c333..6e5fa65f 100644 --- a/gbp/scripts/common/buildpackage.py +++ b/gbp/scripts/common/buildpackage.py @@ -83,7 +83,9 @@ def git_archive_submodules(repo, treeish, output, prefix, comp_type, comp_level, # compress the output if comp_type: - ret = os.system("%s --stdout -%s %s %s > %s" % (comp_type, comp_level, comp_opts, main_archive, output)) + ret = os.system("%s --stdout -%s %s %s > %s" % \ + (comp_type, comp_level, " ".join(comp_opts), + main_archive, output)) if ret: raise GbpError("Error creating %s: %d" % (output, ret)) else: @@ -102,7 +104,8 @@ def git_archive_single(treeish, output, prefix, comp_type, comp_level, comp_opts pipe = pipes.Template() pipe.prepend("git archive --format=%s --prefix=%s %s" % (format, prefix, treeish), '.-') if comp_type: - pipe.append('%s -c -%s %s' % (comp_type, comp_level, comp_opts), '--') + pipe.append('%s -c -%s %s' % (comp_type, comp_level, + " ".join(comp_opts)), '--') ret = pipe.copy('', output) if ret: raise GbpError("Error creating %s: %d" % (output, ret)) -- cgit v1.2.3 From 6a0896527eefeba8108269e2d6e9f42319921104 Mon Sep 17 00:00:00 2001 From: Markus Lehtonen Date: Tue, 15 May 2012 18:13:43 +0300 Subject: buildpackage/git_archive_single: use GitRepository.archive() Use GitRepository.archive() method like git_archive_submodules() does. This makes it possible to call git_archive_single() independent of the callers current working directory. Signed-off-by: Markus Lehtonen --- gbp/scripts/buildpackage.py | 2 +- gbp/scripts/common/buildpackage.py | 24 +++++++++++++++--------- 2 files changed, 16 insertions(+), 10 deletions(-) diff --git a/gbp/scripts/buildpackage.py b/gbp/scripts/buildpackage.py index 21424755..23136858 100755 --- a/gbp/scripts/buildpackage.py +++ b/gbp/scripts/buildpackage.py @@ -56,7 +56,7 @@ def git_archive(repo, cp, output_dir, treeish, comp_type, comp_level, with_submo comp_type, comp_level, comp_opts) else: - git_archive_single(treeish, output, prefix, + git_archive_single(repo, treeish, output, prefix, comp_type, comp_level, comp_opts) except (GitRepositoryError, CommandExecFailed): gbp.log.err("Error generating submodules' archives") diff --git a/gbp/scripts/common/buildpackage.py b/gbp/scripts/common/buildpackage.py index 6e5fa65f..a38eaf74 100644 --- a/gbp/scripts/common/buildpackage.py +++ b/gbp/scripts/common/buildpackage.py @@ -21,6 +21,7 @@ import os, os.path import pipes import tempfile +import subprocess import shutil from gbp.command_wrappers import (CatenateTarArchive, CatenateZipArchive) from gbp.errors import GbpError @@ -94,21 +95,26 @@ def git_archive_submodules(repo, treeish, output, prefix, comp_type, comp_level, shutil.rmtree(tempdir) -def git_archive_single(treeish, output, prefix, comp_type, comp_level, comp_opts, format='tar'): +def git_archive_single(repo, treeish, output, prefix, comp_type, comp_level, + comp_opts, format='tar'): """ Create an archive without submodules Exception handling is left to the caller. """ prefix = sanitize_prefix(prefix) - pipe = pipes.Template() - pipe.prepend("git archive --format=%s --prefix=%s %s" % (format, prefix, treeish), '.-') - if comp_type: - pipe.append('%s -c -%s %s' % (comp_type, comp_level, - " ".join(comp_opts)), '--') - ret = pipe.copy('', output) - if ret: - raise GbpError("Error creating %s: %d" % (output, ret)) + with open(output, 'w') as archive_fd: + if comp_type: + cmd = [comp_type, '--stdout', '-%s' % comp_level] + comp_opts + else: + cmd = ['cat'] + + popen = subprocess.Popen(cmd, stdin=subprocess.PIPE, stdout=archive_fd) + for chunk in repo.archive(format, prefix, None, treeish): + popen.stdin.write(chunk) + popen.stdin.close() + if popen.wait(): + raise GbpError("Error creating %s: compressor cmd failed" % output) #{ Functions to handle export-dir -- cgit v1.2.3 From a4a489cbf79aa80644d07597962016e7c05611be Mon Sep 17 00:00:00 2001 From: Markus Lehtonen Date: Tue, 5 Jun 2012 15:18:24 +0300 Subject: buildpackage/dump_tree: use GitRepository.archive() Make dump_tree() utilize the GitRepository.archive() method - similarly to git_archive_submodules() - instead of ad-hoc Python pipes. This makes dump_tree() work independent of the callers current working directory. Signed-off-by: Markus Lehtonen --- gbp/scripts/common/buildpackage.py | 65 ++++++++++++++++---------------------- 1 file changed, 28 insertions(+), 37 deletions(-) diff --git a/gbp/scripts/common/buildpackage.py b/gbp/scripts/common/buildpackage.py index a38eaf74..41c50ca3 100644 --- a/gbp/scripts/common/buildpackage.py +++ b/gbp/scripts/common/buildpackage.py @@ -19,11 +19,12 @@ """Common functionality for Debian and RPM buildpackage scripts""" import os, os.path -import pipes import tempfile import subprocess import shutil + from gbp.command_wrappers import (CatenateTarArchive, CatenateZipArchive) +from gbp.git.repository import GitRepository, GitRepositoryError from gbp.errors import GbpError import gbp.log @@ -117,47 +118,37 @@ def git_archive_single(repo, treeish, output, prefix, comp_type, comp_level, raise GbpError("Error creating %s: compressor cmd failed" % output) +def untar_data(outdir, data): + """Extract tar provided as an iterable""" + popen = subprocess.Popen(['tar', '-C', outdir, '-x'], + stdin=subprocess.PIPE) + for chunk in data: + popen.stdin.write(chunk) + popen.stdin.close() + if popen.wait(): + raise GbpError("Error extracting tar to %s" % outdir) + + #{ Functions to handle export-dir def dump_tree(repo, export_dir, treeish, with_submodules): - "dump a tree to output_dir" - output_dir = os.path.dirname(export_dir) - prefix = sanitize_prefix(os.path.basename(export_dir)) - - pipe = pipes.Template() - pipe.prepend('git archive --format=tar --prefix=%s %s' % (prefix, treeish), '.-') - pipe.append('tar -C %s -xf -' % output_dir, '-.') - top = os.path.abspath(os.path.curdir) + """Dump a git tree-ish to output_dir""" + if not os.path.exists(export_dir): + os.makedirs(export_dir) try: - ret = pipe.copy('', '') - if ret: - raise GbpError("Error in dump_tree archive pipe") - - if with_submodules: - if repo.has_submodules(): - repo.update_submodules() + data = repo.archive('tar', '', None, treeish) + untar_data(export_dir, data) + if with_submodules and repo.has_submodules(): + repo.update_submodules() for (subdir, commit) in repo.get_submodules(treeish): - gbp.log.info("Processing submodule %s (%s)" % (subdir, commit[0:8])) - tarpath = [subdir, subdir[2:]][subdir.startswith("./")] - os.chdir(subdir) - pipe = pipes.Template() - pipe.prepend('git archive --format=tar --prefix=%s%s/ %s' % - (prefix, tarpath, commit), '.-') - pipe.append('tar -C %s -xf -' % output_dir, '-.') - ret = pipe.copy('', '') - os.chdir(top) - if ret: - raise GbpError("Error in dump_tree archive pipe in submodule %s" % subdir) - except OSError as err: - gbp.log.err("Error dumping tree to %s: %s" % (output_dir, err[0])) + gbp.log.info("Processing submodule %s (%s)" % (subdir, + commit[0:8])) + subrepo = GitRepository(os.path.join(repo.path, subdir)) + prefix = [subdir, subdir[2:]][subdir.startswith("./")] + '/' + data = subrepo.archive('tar', prefix, None, treeish) + untar_data(export_dir, data) + except GitRepositoryError as err: + gbp.log.err("Git error when dumping tree: %s" % err) return False - except GbpError as err: - gbp.log.err(err) - return False - except Exception as e: - gbp.log.err("Error dumping tree to %s: %s" % (output_dir, e)) - return False - finally: - os.chdir(top) return True -- cgit v1.2.3 From 4e98ad1247911bd73daca07b3c0410600e5d8bba Mon Sep 17 00:00:00 2001 From: Markus Lehtonen Date: Thu, 12 Sep 2013 13:30:36 +0300 Subject: common/buildpackage: use GitRepository for submodules Initialize a GitRepository object for each submodule in git_archive_submodules(). Signed-off-by: Markus Lehtonen --- gbp/scripts/common/buildpackage.py | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/gbp/scripts/common/buildpackage.py b/gbp/scripts/common/buildpackage.py index 41c50ca3..56e4cb0f 100644 --- a/gbp/scripts/common/buildpackage.py +++ b/gbp/scripts/common/buildpackage.py @@ -74,10 +74,11 @@ def git_archive_submodules(repo, treeish, output, prefix, comp_type, comp_level, # generate each submodule's arhive and append it to the main archive for (subdir, commit) in repo.get_submodules(treeish): tarpath = [subdir, subdir[2:]][subdir.startswith("./")] + subrepo = GitRepository(os.path.join(repo.path, subdir)) gbp.log.debug("Processing submodule %s (%s)" % (subdir, commit[0:8])) - repo.archive(format=format, prefix='%s%s/' % (prefix, tarpath), - output=submodule_archive, treeish=commit, cwd=subdir) + subrepo.archive(format=format, prefix='%s%s/' % (prefix, tarpath), + output=submodule_archive, treeish=commit) if format == 'tar': CatenateTarArchive(main_archive)(submodule_archive) elif format == 'zip': -- cgit v1.2.3 From 5065e9ff23752081a0655458aa77667b31dd8356 Mon Sep 17 00:00:00 2001 From: Markus Lehtonen Date: Tue, 17 Sep 2013 15:13:40 +0300 Subject: buildpackage/dump_tree: add 'recursive' option For selecting whether to dump all the files recursively or just the top level directory of the tree. Signed-off-by: Markus Lehtonen --- gbp/scripts/common/buildpackage.py | 11 ++++++++--- 1 file changed, 8 insertions(+), 3 deletions(-) diff --git a/gbp/scripts/common/buildpackage.py b/gbp/scripts/common/buildpackage.py index 56e4cb0f..898f6752 100644 --- a/gbp/scripts/common/buildpackage.py +++ b/gbp/scripts/common/buildpackage.py @@ -131,14 +131,19 @@ def untar_data(outdir, data): #{ Functions to handle export-dir -def dump_tree(repo, export_dir, treeish, with_submodules): +def dump_tree(repo, export_dir, treeish, with_submodules, recursive=True): """Dump a git tree-ish to output_dir""" if not os.path.exists(export_dir): os.makedirs(export_dir) + if recursive: + paths = '' + else: + paths = [nam for _mod, typ, _sha, nam in repo.list_tree(treeish) if + typ == 'blob'] try: - data = repo.archive('tar', '', None, treeish) + data = repo.archive('tar', '', None, treeish, paths) untar_data(export_dir, data) - if with_submodules and repo.has_submodules(): + if recursive and with_submodules and repo.has_submodules(): repo.update_submodules() for (subdir, commit) in repo.get_submodules(treeish): gbp.log.info("Processing submodule %s (%s)" % (subdir, -- cgit v1.2.3 From 3fc2071cc8ef89d26c2b236bb7029df357a05102 Mon Sep 17 00:00:00 2001 From: Markus Lehtonen Date: Thu, 6 Feb 2014 09:17:56 +0200 Subject: GitRepository: allow interactive commands Make it possible for git commands to output directly to stdout without redirection (i.e. capturing their stdout stream). Signed-off-by: Markus Lehtonen --- gbp/git/repository.py | 29 +++++++++++++++++++---------- 1 file changed, 19 insertions(+), 10 deletions(-) diff --git a/gbp/git/repository.py b/gbp/git/repository.py index db863dcc..1db24094 100644 --- a/gbp/git/repository.py +++ b/gbp/git/repository.py @@ -142,7 +142,7 @@ class GitRepository(object): return output, popen.returncode def _git_inout(self, command, args, input=None, extra_env=None, cwd=None, - capture_stderr=False): + capture_stderr=False, capture_stdout=True): """ Run a git command with input and return output @@ -166,7 +166,8 @@ class GitRepository(object): stderr = '' try: for outdata in self.__git_inout(command, args, input, extra_env, - cwd, capture_stderr): + cwd, capture_stderr, + capture_stdout): stdout += outdata[0] stderr += outdata[1] except GitRepositoryError as err: @@ -188,7 +189,7 @@ class GitRepository(object): stderr = '' try: for outdata in self.__git_inout(command, args, stdin, extra_env, - cwd, capture_stderr): + cwd, capture_stderr, True): stderr += outdata[1] yield outdata[0] except GitRepositoryError as err: @@ -196,7 +197,8 @@ class GitRepository(object): raise err @classmethod - def __git_inout(cls, command, args, stdin, extra_env, cwd, capture_stderr): + def __git_inout(cls, command, args, stdin, extra_env, cwd, capture_stderr, + capture_stdout): """ Run a git command without a a GitRepostitory instance. @@ -212,18 +214,21 @@ class GitRepository(object): cmd = ['git', command] + args env = cls.__build_env(extra_env) + stdout_arg = subprocess.PIPE if capture_stdout else None stdin_arg = subprocess.PIPE if stdin else None stderr_arg = subprocess.PIPE if capture_stderr else None log.debug(cmd) popen = subprocess.Popen(cmd, stdin=stdin_arg, - stdout=subprocess.PIPE, + stdout=stdout_arg, stderr=stderr_arg, env=env, close_fds=True, cwd=cwd) - out_fds = [popen.stdout] + ([popen.stderr] if capture_stderr else []) + out_fds = [popen.stdout] if capture_stdout else [] + if capture_stderr: + out_fds.append(popen.stderr) in_fds = [popen.stdin] if stdin else [] w_ind = 0 while out_fds or in_fds: @@ -248,7 +253,7 @@ class GitRepository(object): err.returncode = popen.returncode raise err - def _git_command(self, command, args=[], extra_env=None): + def _git_command(self, command, args=[], extra_env=None, interactive=False): """ Execute git command with arguments args and environment env at path. @@ -260,12 +265,14 @@ class GitRepository(object): @param extra_env: extra environment variables to set when running command @type extra_env: C{dict} """ + capture_stdout = not interactive try: stdout, stderr, ret = self._git_inout(command=command, args=args, input=None, extra_env=extra_env, - capture_stderr=True) + capture_stderr=True, + capture_stdout=capture_stdout) except Exception as excobj: raise GitRepositoryError("Error running git %s: %s" % (command, excobj)) if ret: @@ -1858,7 +1865,8 @@ class GitRepository(object): stdin=None, extra_env=None, cwd=abspath, - capture_stderr=True): + capture_stderr=True, + capture_stdout=True): stderr += out[1] except GitRepositoryError: raise GitRepositoryError("Error running git init: %s" % stderr) @@ -1921,7 +1929,8 @@ class GitRepository(object): stdin=None, extra_env=None, cwd=abspath, - capture_stderr=True): + capture_stderr=True, + capture_stdout=True): stderr += out[1] except GitRepositoryError: raise GitRepositoryError("Error running git clone: %s" % stderr) -- cgit v1.2.3 From aceb23693b1ecda418676d7f799764694a20d150 Mon Sep 17 00:00:00 2001 From: Markus Lehtonen Date: Thu, 6 Feb 2014 09:22:59 +0200 Subject: GitRepository: fix the 'edit' mode in commit methods Previously the editor would not show in the shell because stdout was captured. Signed-off-by: Markus Lehtonen --- gbp/git/repository.py | 14 ++++++-------- 1 file changed, 6 insertions(+), 8 deletions(-) diff --git a/gbp/git/repository.py b/gbp/git/repository.py index 1db24094..9e720039 100644 --- a/gbp/git/repository.py +++ b/gbp/git/repository.py @@ -1363,9 +1363,11 @@ class GitRepository(object): #{ Comitting - def _commit(self, msg, args=[], author_info=None): + def _commit(self, msg, args=[], author_info=None, edit=False): extra_env = author_info.get_author_env() if author_info else None - self._git_command("commit", ['-q', '-m', msg] + args, extra_env=extra_env) + default_args = ['-q', '-m', msg] + (['--edit'] if edit else []) + self._git_command("commit", default_args + args, extra_env=extra_env, + interactive=edit) def commit_staged(self, msg, author_info=None, edit=False): """ @@ -1378,9 +1380,7 @@ class GitRepository(object): @param edit: whether to spawn an editor to edit the commit info @type edit: C{bool} """ - args = GitArgs() - args.add_true(edit, '--edit') - self._commit(msg=msg, args=args.args, author_info=author_info) + self._commit(msg=msg, author_info=author_info, edit=edit) def commit_all(self, msg, author_info=None, edit=False): """ @@ -1390,9 +1390,7 @@ class GitRepository(object): @param author_info: authorship information @type author_info: L{GitModifier} """ - args = GitArgs('-a') - args.add_true(edit, '--edit') - self._commit(msg=msg, args=args.args, author_info=author_info) + self._commit(msg=msg, args=['-a'], author_info=author_info, edit=edit) def commit_files(self, files, msg, author_info=None): """ -- cgit v1.2.3 From 751426f9d5012a3e4631b3558ae7c758399c2879 Mon Sep 17 00:00:00 2001 From: Markus Lehtonen Date: Thu, 12 Sep 2013 13:36:08 +0300 Subject: GitRepository.archive: drop the '**kwargs' argument Unused and misleading. Signed-off-by: Markus Lehtonen --- gbp/git/repository.py | 7 +++---- 1 file changed, 3 insertions(+), 4 deletions(-) diff --git a/gbp/git/repository.py b/gbp/git/repository.py index 9e720039..b95cad3b 100644 --- a/gbp/git/repository.py +++ b/gbp/git/repository.py @@ -1711,7 +1711,7 @@ class GitRepository(object): return output #} - def archive(self, format, prefix, output, treeish, **kwargs): + def archive(self, format, prefix, output, treeish): """ Create an archive from a treeish @@ -1724,7 +1724,6 @@ class GitRepository(object): @type output: C{str} or C{None} @param treeish: the treeish to create the archive from @type treeish: C{str} - @param kwargs: additional commandline options passed to git-archive @return: archive data as a generator object @rtype: C{None} or C{generator} of C{str} @@ -1734,12 +1733,12 @@ class GitRepository(object): args.add(treeish) if output: - out, err, ret = self._git_inout('archive', args.args, **kwargs) + out, err, ret = self._git_inout('archive', args.args) if ret: raise GitRepositoryError("Unable to archive %s: %s" % (treeish, err)) else: - return self._git_inout2('archive', args.args, **kwargs) + return self._git_inout2('archive', args.args) def collect_garbage(self, auto=False): """ -- cgit v1.2.3 From 215b1444b50c2cd55aac2066496071c0edb73a37 Mon Sep 17 00:00:00 2001 From: Markus Lehtonen Date: Thu, 10 Apr 2014 11:30:06 +0300 Subject: GitRepository: implement create_tree method New method for creating tree objects from a directory content. Signed-off-by: Markus Lehtonen --- gbp/git/repository.py | 28 +++++++++++++++++++--------- 1 file changed, 19 insertions(+), 9 deletions(-) diff --git a/gbp/git/repository.py b/gbp/git/repository.py index b95cad3b..2b1e4605 100644 --- a/gbp/git/repository.py +++ b/gbp/git/repository.py @@ -1407,6 +1407,24 @@ class GitRepository(object): files = [ files ] self._commit(msg=msg, args=files, author_info=author_info) + def create_tree(self, unpack_dir): + """ + Create a tree object out of a directory content + + @param unpack_dir: content to add + @type unpack_dir: C{str} + @return: the tree object hash + @rtype: C{str} + """ + git_index_file = os.path.join(self.path, self._git_dir, 'gbp_index') + try: + os.unlink(git_index_file) + except OSError: + pass + self.add_files('.', force=True, index_file=git_index_file, + work_tree=unpack_dir) + return self.write_tree(git_index_file) + def commit_dir(self, unpack_dir, msg, branch, other_parents=None, author={}, committer={}, create_missing_branch=False): """ @@ -1429,15 +1447,7 @@ class GitRepository(object): doesn't already exist. @type create_missing_branch: C{bool} """ - - git_index_file = os.path.join(self.path, self._git_dir, 'gbp_index') - try: - os.unlink(git_index_file) - except OSError: - pass - self.add_files('.', force=True, index_file=git_index_file, - work_tree=unpack_dir) - tree = self.write_tree(git_index_file) + tree = self.create_tree(unpack_dir) if branch: try: -- cgit v1.2.3 From d276ea51e567520e395393eae04a93bff0d91188 Mon Sep 17 00:00:00 2001 From: Markus Lehtonen Date: Mon, 20 May 2013 11:28:51 +0300 Subject: GbpOptionParser: allow using the default 'dest' attribute Make it possible to add options without explicitly defining the 'dest' attribute - in which case the default of OptionParser is used. Signed-off-by: Markus Lehtonen --- gbp/config.py | 8 +++----- 1 file changed, 3 insertions(+), 5 deletions(-) diff --git a/gbp/config.py b/gbp/config.py index 3fa59186..2eb6330f 100644 --- a/gbp/config.py +++ b/gbp/config.py @@ -449,23 +449,21 @@ class GbpOptionParser(OptionParser): return default @safe_option - def add_config_file_option(self, option_name, dest, help=None, **kwargs): + def add_config_file_option(self, option_name, help=None, **kwargs): """ set a option for the command line parser, the default is read from the config file param option_name: name of the option type option_name: string - param dest: where to store this option - type dest: string param help: help text type help: string """ if not help: help = self.help[option_name] - OptionParser.add_option(self, "--%s%s" % (self.prefix, option_name), dest=dest, + OptionParser.add_option(self, "--%s%s" % (self.prefix, option_name), default=self.get_default(option_name, **kwargs), help=help % self.config, **kwargs) - def add_boolean_config_file_option(self, option_name, dest): + def add_boolean_config_file_option(self, option_name, dest=None): self.add_config_file_option(option_name=option_name, dest=dest, action="store_true") neg_help = "negates '--%s%s'" % (self.prefix, option_name) self.add_config_file_option(option_name="no-%s" % option_name, dest=dest, help=neg_help, action="store_false") -- cgit v1.2.3 From ed4f98fb213dd5600ffd5b128f935c65a5ebb29b Mon Sep 17 00:00:00 2001 From: Markus Lehtonen Date: Wed, 5 Feb 2014 16:11:42 +0200 Subject: GitRepository.commit_files: add committer_info argument For setting the committer name/email/date - similarly to author_info. Signed-off-by: Markus Lehtonen --- gbp/git/repository.py | 12 +++++++++--- 1 file changed, 9 insertions(+), 3 deletions(-) diff --git a/gbp/git/repository.py b/gbp/git/repository.py index 2b1e4605..f705f616 100644 --- a/gbp/git/repository.py +++ b/gbp/git/repository.py @@ -1363,8 +1363,11 @@ class GitRepository(object): #{ Comitting - def _commit(self, msg, args=[], author_info=None, edit=False): + def _commit(self, msg, args=[], author_info=None, + committer_info=None, edit=False): extra_env = author_info.get_author_env() if author_info else None + if committer_info: + extra_env.update(committer_info.get_committer_env()) default_args = ['-q', '-m', msg] + (['--edit'] if edit else []) self._git_command("commit", default_args + args, extra_env=extra_env, interactive=edit) @@ -1392,7 +1395,7 @@ class GitRepository(object): """ self._commit(msg=msg, args=['-a'], author_info=author_info, edit=edit) - def commit_files(self, files, msg, author_info=None): + def commit_files(self, files, msg, author_info=None, committer_info=None): """ Commit the given files to the repository @@ -1402,10 +1405,13 @@ class GitRepository(object): @type msg: C{str} @param author_info: authorship information @type author_info: L{GitModifier} + @param committer_info: committer information + @type committer_info: L{GitModifier} """ if isinstance(files, basestring): files = [ files ] - self._commit(msg=msg, args=files, author_info=author_info) + self._commit(msg=msg, args=files, author_info=author_info, + committer_info=committer_info) def create_tree(self, unpack_dir): """ -- cgit v1.2.3 From f3b923c486d20a8cb70c63e23c87fa67537b2245 Mon Sep 17 00:00:00 2001 From: Markus Lehtonen Date: Wed, 5 Feb 2014 16:11:42 +0200 Subject: GitRepository.commit_all: add committer_info argument For setting the committer name/email/date - similarly to author_info. Signed-off-by: Markus Lehtonen --- gbp/git/repository.py | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-) diff --git a/gbp/git/repository.py b/gbp/git/repository.py index f705f616..61ed500e 100644 --- a/gbp/git/repository.py +++ b/gbp/git/repository.py @@ -1372,7 +1372,8 @@ class GitRepository(object): self._git_command("commit", default_args + args, extra_env=extra_env, interactive=edit) - def commit_staged(self, msg, author_info=None, edit=False): + def commit_staged(self, msg, author_info=None, edit=False, + committer_info=None): """ Commit currently staged files to the repository @@ -1382,8 +1383,11 @@ class GitRepository(object): @type author_info: L{GitModifier} @param edit: whether to spawn an editor to edit the commit info @type edit: C{bool} + @param committer_info: committer information + @type committer_info: L{GitModifier} """ - self._commit(msg=msg, author_info=author_info, edit=edit) + self._commit(msg=msg, author_info=author_info, + committer_info=committer_info, edit=edit) def commit_all(self, msg, author_info=None, edit=False): """ -- cgit v1.2.3 From edd12bc8d2bba682ebbae807dfcb428b2d6f4c4e Mon Sep 17 00:00:00 2001 From: Markus Lehtonen Date: Wed, 5 Feb 2014 16:11:42 +0200 Subject: GitRepository.commit_files: add edit argument In order to be able to spawn an editor, similarly to other commitX methods in GitRepository. Signed-off-by: Markus Lehtonen --- gbp/git/repository.py | 13 ++++++++----- 1 file changed, 8 insertions(+), 5 deletions(-) diff --git a/gbp/git/repository.py b/gbp/git/repository.py index 61ed500e..b6456954 100644 --- a/gbp/git/repository.py +++ b/gbp/git/repository.py @@ -1399,7 +1399,8 @@ class GitRepository(object): """ self._commit(msg=msg, args=['-a'], author_info=author_info, edit=edit) - def commit_files(self, files, msg, author_info=None, committer_info=None): + def commit_files(self, files, msg, author_info=None, committer_info=None, + edit=False): """ Commit the given files to the repository @@ -1411,11 +1412,13 @@ class GitRepository(object): @type author_info: L{GitModifier} @param committer_info: committer information @type committer_info: L{GitModifier} + @param edit: whether to spawn an editor to edit the commit info + @type edit: C{bool} """ - if isinstance(files, basestring): - files = [ files ] - self._commit(msg=msg, args=files, author_info=author_info, - committer_info=committer_info) + args = GitArgs('--') + args.add(files) + self._commit(msg=msg, args=args.args, author_info=author_info, + committer_info=committer_info, edit=edit) def create_tree(self, unpack_dir): """ -- cgit v1.2.3 From 25f9da0715500858c62389de76fe9d1e07e3dc3a Mon Sep 17 00:00:00 2001 From: Markus Lehtonen Date: Fri, 13 Sep 2013 09:53:16 +0300 Subject: GitRepository.create_branch: add 'force' option Signed-off-by: Markus Lehtonen --- gbp/git/repository.py | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/gbp/git/repository.py b/gbp/git/repository.py index b6456954..760f891e 100644 --- a/gbp/git/repository.py +++ b/gbp/git/repository.py @@ -367,16 +367,18 @@ class GitRepository(object): args = GitArgs("-m", branch, newbranch) self._git_command("branch", args.args) - def create_branch(self, branch, rev=None): + def create_branch(self, branch, rev=None, force=False): """ Create a new branch @param branch: the branch's name @param rev: where to start the branch from + @param force: reset branch HEAD to start point, if it already exists If rev is None the branch starts form the current HEAD. """ args = GitArgs(branch) + args.add_true(force, '--force') args.add_true(rev, rev) self._git_command("branch", args.args) -- cgit v1.2.3 From 144b034ee8a1d300ca99826094e5060dc2288809 Mon Sep 17 00:00:00 2001 From: Markus Lehtonen Date: Tue, 17 Sep 2013 14:47:21 +0300 Subject: GitRepository.archive: add 'paths' option Signed-off-by: Markus Lehtonen --- gbp/git/repository.py | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/gbp/git/repository.py b/gbp/git/repository.py index 760f891e..1b696406 100644 --- a/gbp/git/repository.py +++ b/gbp/git/repository.py @@ -1736,7 +1736,7 @@ class GitRepository(object): return output #} - def archive(self, format, prefix, output, treeish): + def archive(self, format, prefix, output, treeish, paths=None): """ Create an archive from a treeish @@ -1749,6 +1749,8 @@ class GitRepository(object): @type output: C{str} or C{None} @param treeish: the treeish to create the archive from @type treeish: C{str} + @param paths: List of paths to include in the archive + @type paths: C{list} of C{str} @return: archive data as a generator object @rtype: C{None} or C{generator} of C{str} @@ -1756,6 +1758,8 @@ class GitRepository(object): args = GitArgs('--format=%s' % format, '--prefix=%s' % prefix) args.add_true(output, '--output=%s' % output) args.add(treeish) + args.add("--") + args.add_cond(paths, paths) if output: out, err, ret = self._git_inout('archive', args.args) -- cgit v1.2.3 From f7c0314950309af62f819f0eaf50a6d48c10afd0 Mon Sep 17 00:00:00 2001 From: Markus Lehtonen Date: Wed, 11 Dec 2013 15:50:13 +0200 Subject: GitRepository/git_command: strip stderr output in case of error In order to get rid of extra line feeds in exception message. Signed-off-by: Markus Lehtonen --- gbp/git/repository.py | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/gbp/git/repository.py b/gbp/git/repository.py index 1b696406..ec36ea01 100644 --- a/gbp/git/repository.py +++ b/gbp/git/repository.py @@ -276,7 +276,8 @@ class GitRepository(object): except Exception as excobj: raise GitRepositoryError("Error running git %s: %s" % (command, excobj)) if ret: - raise GitRepositoryError("Error running git %s: %s" % (command, stderr)) + raise GitRepositoryError("Error running git %s: %s" % + (command, stderr.strip())) def _cmd_has_feature(self, command, feature): -- cgit v1.2.3 From 59b3563bb1acd23b4db688601daa3a3b2c76d0bd Mon Sep 17 00:00:00 2001 From: Markus Lehtonen Date: Tue, 11 Sep 2012 15:08:13 +0300 Subject: GitRepository/rev_parse: use _git_inout() instead of the deprecated _git_getoutput() method. Signed-off-by: Markus Lehtonen --- gbp/git/repository.py | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/gbp/git/repository.py b/gbp/git/repository.py index ec36ea01..67ad2288 100644 --- a/gbp/git/repository.py +++ b/gbp/git/repository.py @@ -918,10 +918,11 @@ class GitRepository(object): args = GitArgs("--quiet", "--verify") args.add_cond(short, '--short=%d' % short) args.add(name) - sha, ret = self._git_getoutput('rev-parse', args.args) + sha, stderr, ret = self._git_inout('rev-parse', args.args, + capture_stderr=True) if ret: raise GitRepositoryError("revision '%s' not found" % name) - return self.strip_sha1(sha[0], short) + return self.strip_sha1(sha.splitlines()[0], short) @staticmethod def strip_sha1(sha1, length=0): -- cgit v1.2.3 From 1bfc8c3fe172e612a56d764b1894e885851f4596 Mon Sep 17 00:00:00 2001 From: Markus Lehtonen Date: Mon, 25 Mar 2013 15:57:24 +0200 Subject: GitRepository: raise GitRepositoryError instead of GbpError Signed-off-by: Markus Lehtonen --- gbp/git/repository.py | 6 +++--- gbp/scripts/import_orig.py | 2 +- tests/09_test_write_tree.py | 2 +- 3 files changed, 5 insertions(+), 5 deletions(-) diff --git a/gbp/git/repository.py b/gbp/git/repository.py index 67ad2288..b8952ed4 100644 --- a/gbp/git/repository.py +++ b/gbp/git/repository.py @@ -23,7 +23,6 @@ from collections import defaultdict import select import gbp.log as log -from gbp.errors import GbpError from gbp.git.modifier import GitModifier from gbp.git.commit import GitCommit from gbp.git.errors import GitError @@ -1362,7 +1361,8 @@ class GitRepository(object): if not ret: return self.strip_sha1(sha1) else: - raise GbpError("Failed to hash %s: %s" % (filename, stderr)) + raise GitRepositoryError("Failed to hash %s: %s" % (filename, + stderr)) #} #{ Comitting @@ -1527,7 +1527,7 @@ class GitRepository(object): if not ret: return self.strip_sha1(sha1) else: - raise GbpError("Failed to commit tree: %s" % stderr) + raise GitRepositoryError("Failed to commit tree: %s" % stderr) #{ Commit Information diff --git a/gbp/scripts/import_orig.py b/gbp/scripts/import_orig.py index 542896ef..3061994c 100644 --- a/gbp/scripts/import_orig.py +++ b/gbp/scripts/import_orig.py @@ -382,7 +382,7 @@ def main(argv): except (gbpc.CommandExecFailed, GitRepositoryError) as err: msg = err.__str__() if len(err.__str__()) else '' raise GbpError("Import of %s failed: %s" % (source.path, msg)) - except GbpError as err: + except (GbpError, GitRepositoryError) as err: if len(err.__str__()): gbp.log.err(err) ret = 1 diff --git a/tests/09_test_write_tree.py b/tests/09_test_write_tree.py index 7147da50..55a1da60 100644 --- a/tests/09_test_write_tree.py +++ b/tests/09_test_write_tree.py @@ -62,7 +62,7 @@ class TestWriteTree(testutils.DebianGitTestRepo): # commit the same tree again using the previous commit as parent self.repo.commit_tree(sha1, "second commit", parents=[commit]) # commit the same tree again using a non existant parent - self.assertRaises(gbp.errors.GbpError, + self.assertRaises(gbp.git.GitRepositoryError, self.repo.commit_tree, sha1, "failed commit", -- cgit v1.2.3 From 493ea58243c5423154802b8f7a3730392a86f0fa Mon Sep 17 00:00:00 2001 From: Ed Bartosh Date: Wed, 6 Jun 2012 14:45:44 +0300 Subject: GitRepository: Implement status method Simple wrapper to the git-status command. Signed-off-by: Ed Bartosh Signed-off-by: Markus Lehtonen --- gbp/git/repository.py | 33 +++++++++++++++++++++++++++++++++ tests/test_GitRepository.py | 22 ++++++++++++++++++++++ 2 files changed, 55 insertions(+) diff --git a/gbp/git/repository.py b/gbp/git/repository.py index b8952ed4..8b27ef51 100644 --- a/gbp/git/repository.py +++ b/gbp/git/repository.py @@ -892,6 +892,39 @@ class GitRepository(object): if ret: raise GitRepositoryError("Can't execute repository clean: %s" % err) + def status(self, pathlist=None): + """ + Check status of repository. + + @param pathlist: List of paths to check status for + @type pathlist: C{list} + @return C{dict} of C{lists} of paths, where key is a git status flag. + @rtype C{dict} + """ + options = GitArgs('--porcelain', '-z') + if pathlist: + for path in pathlist: + options.add(path) + + out, err, ret = self._git_inout('status', options.args, + extra_env={'LC_ALL': 'C'}) + if ret: + raise GitRepositoryError("Can't get repository status: %s" % err) + + elements = out.split('\x00') + result = defaultdict(list) + + while elements[0] != '': + element = elements.pop(0) + status = element[:2] + filepath = element[3:] + # Expect to have two filenames for renames and copies + if status[0] in ['R', 'C']: + filepath = elements.pop(0) + '\x00' + filepath + result[status].append(filepath) + + return result + def is_empty(self): """ Is the repository empty? diff --git a/tests/test_GitRepository.py b/tests/test_GitRepository.py index 427370da..dadcee72 100644 --- a/tests/test_GitRepository.py +++ b/tests/test_GitRepository.py @@ -868,6 +868,28 @@ def test_get_merge_base(): GitRepositoryError: Failed to get common ancestor: fatal: Not a valid object name doesnotexist """ +def test_status(): + r""" + Methods tested: + - L{gbp.git.GitRepository.status} + + >>> import gbp.git, os, shutil + >>> repo = gbp.git.GitRepository(repo_dir) + >>> fname = os.path.join(repo.path, "test_status") + >>> shutil.copy(os.path.join(repo.path, ".git/HEAD"), fname) + >>> repo.status().items() + [('??', ['test_status'])] + >>> repo.status(['bla*']).items() + [] + >>> repo.status(['te*']).items() + [('??', ['test_status'])] + >>> repo.add_files(repo.path, force=True) + >>> repo.commit_all(msg='added %s' % fname) + >>> _ = repo._git_inout('mv', [fname, fname + 'new']) + >>> repo.status().items() + [('R ', ['test_status\x00test_statusnew'])] + """ + def test_cmd_has_feature(): r""" Methods tested: -- cgit v1.2.3 From b2a53d5669cec130b29120d4b0a5be097165707a Mon Sep 17 00:00:00 2001 From: Markus Lehtonen Date: Tue, 5 Jun 2012 14:55:19 +0300 Subject: GitRepository: allow repo inititialization from subdir This allows initialization of a GitRepository object, even if the current working directory (or path given to GitRepository) is not the top level directory of the git repository. Don't guess the git meta data dir, but, take it as reported by git itself. Signed-off-by: Markus Lehtonen --- gbp/git/repository.py | 42 ++++++++++++++++++++++++++++++------------ tests/test_GitRepository.py | 4 ++-- 2 files changed, 32 insertions(+), 14 deletions(-) diff --git a/gbp/git/repository.py b/gbp/git/repository.py index 8b27ef51..110553a9 100644 --- a/gbp/git/repository.py +++ b/gbp/git/repository.py @@ -76,29 +76,47 @@ class GitRepository(object): all methods. """ - def _check_bare(self): - """Check whether this is a bare repository""" - out, dummy, ret = self._git_inout('rev-parse', ['--is-bare-repository'], - capture_stderr=True) + def _check_dirs(self): + """Get top level dir and git meta data dir""" + out, dummy, ret = self._git_inout('rev-parse', ['--git-dir'], + capture_stderr=True) if ret: raise GitRepositoryError( - "Failed to get repository state at '%s'" % self.path) - self._bare = False if out.strip() != 'true' else True - self._git_dir = '' if self._bare else '.git' + "Failed to get repository git dir at '%s'" % self.path) + + # Set git meta data dir + git_dir = out.strip() + if os.path.isabs(git_dir): + self._git_dir = git_dir + else: + self._git_dir = os.path.abspath(os.path.join(self.path, git_dir)) + + # Set top level dir correctly (in case repo was initialized + # from a subdir, for example) + if self.bare: + self._path = self._git_dir + else: + out, dummy, ret = self._git_inout('rev-parse', ['--show-toplevel'], + capture_stderr=True) + self._path = os.path.abspath(out.strip()) def __init__(self, path): self._path = os.path.abspath(path) - self._bare = False try: - out, dummy, ret = self._git_inout('rev-parse', ['--show-cdup'], + # Check for bare repository + out, dummy, ret = self._git_inout('rev-parse', ['--is-bare-repository'], capture_stderr=True) - if ret or out.strip(): + if ret: raise GitRepositoryError("No Git repository at '%s': '%s'" % (self.path, out)) + self._bare = False if out.strip() != 'true' else True + + self._check_dirs() + except GitRepositoryError: raise # We already have a useful error message except: - raise GitRepositoryError("No Git repository at '%s'" % self.path) - self._check_bare() + raise GitRepositoryError("No Git repository at '%s' (or any parent dir)" % self.path) + @staticmethod def __build_env(extra_env): diff --git a/tests/test_GitRepository.py b/tests/test_GitRepository.py index dadcee72..69974cf0 100644 --- a/tests/test_GitRepository.py +++ b/tests/test_GitRepository.py @@ -664,7 +664,7 @@ def test_create_bare(): >>> bare = gbp.git.GitRepository.create(bare_dir, bare=True, description="msg") >>> bare.path == bare_dir True - >>> bare.git_dir[:-1] == bare_dir + >>> bare.git_dir == bare_dir True >>> type(bare) == gbp.git.GitRepository True @@ -685,7 +685,7 @@ def test_nonexistant(): >>> bare = gbp.git.GitRepository("/does/not/exist") Traceback (most recent call last): ... - GitRepositoryError: No Git repository at '/does/not/exist' + GitRepositoryError: No Git repository at '/does/not/exist' (or any parent dir) """ def test_create_noperm(): -- cgit v1.2.3 From 2fea77aa4101d8bd310ca974241a035935bb6400 Mon Sep 17 00:00:00 2001 From: Markus Lehtonen Date: Fri, 6 Jul 2012 15:51:14 +0300 Subject: GitRepository.add_files: use GitArgs Signed-off-by: Markus Lehtonen --- gbp/git/repository.py | 9 ++++----- 1 file changed, 4 insertions(+), 5 deletions(-) diff --git a/gbp/git/repository.py b/gbp/git/repository.py index 110553a9..d53566a7 100644 --- a/gbp/git/repository.py +++ b/gbp/git/repository.py @@ -1336,10 +1336,9 @@ class GitRepository(object): """ extra_env = {} - if isinstance(paths, basestring): - paths = [ paths ] - - args = [ '-f' ] if force else [] + args = GitArgs() + args.add_true(force, '-f') + args.add(paths) if index_file: extra_env['GIT_INDEX_FILE'] = index_file @@ -1347,7 +1346,7 @@ class GitRepository(object): if work_tree: extra_env['GIT_WORK_TREE'] = work_tree - self._git_command("add", args + paths, extra_env) + self._git_command("add", args.args, extra_env) def remove_files(self, paths, verbose=False): """ -- cgit v1.2.3 From 493a55c3a6d71ff9fbbdc154633e1dc40ec4dd5b Mon Sep 17 00:00:00 2001 From: Markus Lehtonen Date: Tue, 3 Sep 2013 16:09:11 +0300 Subject: GitRepository.add_files: consistently update ALL tracked files Use the --all option of git-add so that all tracked files are updated in all conditions. Previously deletion of tracked files was not staged, for example. Signed-off-by: Markus Lehtonen --- gbp/git/repository.py | 1 + 1 file changed, 1 insertion(+) diff --git a/gbp/git/repository.py b/gbp/git/repository.py index d53566a7..5e7eb410 100644 --- a/gbp/git/repository.py +++ b/gbp/git/repository.py @@ -1338,6 +1338,7 @@ class GitRepository(object): args = GitArgs() args.add_true(force, '-f') + args.add('-A') args.add(paths) if index_file: -- cgit v1.2.3 From 928dff6759a633cb2445be3da5801c90079104f4 Mon Sep 17 00:00:00 2001 From: Markus Lehtonen Date: Thu, 30 Jan 2014 17:46:18 +0200 Subject: pq/parse_gbp_commands: return non-matched lines In order to make it easy to re-use this function in changelog generation. Signed-off-by: Markus Lehtonen --- gbp/scripts/common/pq.py | 5 ++++- gbp/scripts/pq.py | 5 +++-- 2 files changed, 7 insertions(+), 3 deletions(-) diff --git a/gbp/scripts/common/pq.py b/gbp/scripts/common/pq.py index 75ce526d..8d92a170 100644 --- a/gbp/scripts/common/pq.py +++ b/gbp/scripts/common/pq.py @@ -78,6 +78,7 @@ def parse_gbp_commands(info, cmd_tag, noarg_cmds, arg_cmds): cmd_re = re.compile(r'^%s:\s*(?P[a-z-]+)(\s+(?P\S.*))?' % cmd_tag, flags=re.I) commands = {} + other_lines = [] for line in info['body'].splitlines(): match = re.match(cmd_re, line) if match: @@ -93,7 +94,9 @@ def parse_gbp_commands(info, cmd_tag, noarg_cmds, arg_cmds): else: gbp.log.warn("Ignoring unknown gbp-command '%s' in commit %s" % (line, info['id'])) - return commands + else: + other_lines.append(line) + return commands, other_lines def patch_path_filter(file_status, exclude_regex=None): diff --git a/gbp/scripts/pq.py b/gbp/scripts/pq.py index 9a031b87..38e21d84 100755 --- a/gbp/scripts/pq.py +++ b/gbp/scripts/pq.py @@ -76,8 +76,9 @@ def generate_patches(repo, start, end, outdir, options): for commit in rev_list: info = repo.get_commit_info(commit) topic = parse_old_style_topic(info) - cmds = parse_gbp_commands(info, 'gbp', ('ignore'), ('topic')) - cmds.update(parse_gbp_commands(info, 'gbp-pq', ('ignore'), ('topic'))) + cmds = parse_gbp_commands(info, 'gbp', ('ignore'), ('topic'))[0] + cmds.update(parse_gbp_commands(info, 'gbp-pq', ('ignore'), + ('topic'))[0]) if not 'ignore' in cmds: if 'topic' in cmds: topic = cmds['topic'] -- cgit v1.2.3 From ee94de66091a2f9bc1ecfe6f50768937d7581061 Mon Sep 17 00:00:00 2001 From: Ed Bartosh Date: Wed, 30 May 2012 09:02:55 +0300 Subject: gbp.git: Reimplement rfc822 date parsing without dateutil In order to get rid of dependency to dateutil. Signed-off-by: Ed Bartosh Signed-off-by: Markus Lehtonen --- debian/control | 2 -- gbp/git/__init__.py | 29 ++++++++++++++++++++++++----- 2 files changed, 24 insertions(+), 7 deletions(-) diff --git a/debian/control b/debian/control index a5dad37b..f8e44a3e 100644 --- a/debian/control +++ b/debian/control @@ -12,7 +12,6 @@ Build-Depends: pychecker, python (>> 2.6.6-3~), python-coverage, - python-dateutil, python-epydoc, python-nose, python-nosexcover, @@ -39,7 +38,6 @@ Depends: ${python:Depends}, devscripts (>= 2.13.5~), git (>= 1:1.7.9.1-1~), man-db, - python-dateutil, python-pkg-resources, Recommends: pristine-tar (>= 0.5), cowbuilder Suggests: python-notify, unzip diff --git a/gbp/git/__init__.py b/gbp/git/__init__.py index 55dc3a82..cbd84cb5 100644 --- a/gbp/git/__init__.py +++ b/gbp/git/__init__.py @@ -17,7 +17,8 @@ """Accessing Git from python""" import calendar -import dateutil.parser +import datetime +import rfc822 from gbp.git.modifier import GitModifier from gbp.git.commit import GitCommit @@ -28,6 +29,23 @@ from gbp.git.args import GitArgs from gbp.git.vfs import GitVfs +class FixedOffset(datetime.tzinfo): + """Fixed offset in seconds east from UTC.""" + + ZERO = datetime.timedelta(0) + + def __init__(self, offset): + datetime.tzinfo.__init__(self) + self._offset = datetime.timedelta(seconds=offset) + + def utcoffset(self, dtime): + return self._offset + self.dst(dtime) + + def dst(self, dtime): + assert dtime.tzinfo is self + return self.ZERO + + def rfc822_date_to_git(rfc822_date): """Parse a date in RFC822 format, and convert to a 'seconds tz' C{str}ing. @@ -38,9 +56,10 @@ def rfc822_date_to_git(rfc822_date): >>> rfc822_date_to_git('Sat, 5 Apr 2008 17:01:32 +0200') '1207407692 +0200' """ - d = dateutil.parser.parse(rfc822_date) - seconds = calendar.timegm(d.utctimetuple()) - tz = d.strftime("%z") - return '%d %s' % (seconds, tz) + parsed = rfc822.parsedate_tz(rfc822_date) + date = datetime.datetime(*parsed[:6], tzinfo=FixedOffset(parsed[-1])) + seconds = calendar.timegm(date.utctimetuple()) + tzone = date.strftime("%z") + return '%d %s' % (seconds, tzone) # vim:et:ts=4:sw=4:et:sts=4:ai:set list listchars=tab\:»·,trail\:·: -- cgit v1.2.3 From 4fdad3ee0dcace6bdeed3f0cc70ed9df63b21035 Mon Sep 17 00:00:00 2001 From: Markus Lehtonen Date: Fri, 14 Sep 2012 13:40:14 +0300 Subject: GitRepository: add diff_status method This is a method of getting the filename and status information of a diff. That is, a list of files that changed and their status, "added", "modified" etc. Signed-off-by: Markus Lehtonen --- gbp/git/repository.py | 27 +++++++++++++++++++++++++++ tests/test_GitRepository.py | 13 +++++++++++++ 2 files changed, 40 insertions(+) diff --git a/gbp/git/repository.py b/gbp/git/repository.py index 5e7eb410..02476722 100644 --- a/gbp/git/repository.py +++ b/gbp/git/repository.py @@ -1787,6 +1787,33 @@ class GitRepository(object): if ret: raise GitRepositoryError("Git diff failed") return output + + def diff_status(self, obj1, obj2): + """ + Get file-status of two git repository objects + + @param obj1: first object + @type obj1: C{str} + @param obj2: second object + @type obj2: C{str} + @return: name-status + @rtype: C{defaultdict} of C{str} + """ + options = GitArgs('--name-status', '-z', obj1, obj2) + output, stderr, ret = self._git_inout('diff', options.args) + + elements = output.split('\x00') + result = defaultdict(list) + + while elements[0] != '': + status = elements.pop(0)[0] + filepath = elements.pop(0) + # Expect to have two filenames for renames and copies + if status in ['R', 'C']: + filepath = elements.pop(0) + '\x00' + filepath + result[status].append(filepath) + + return result #} def archive(self, format, prefix, output, treeish, paths=None): diff --git a/tests/test_GitRepository.py b/tests/test_GitRepository.py index 69974cf0..f3a83ff3 100644 --- a/tests/test_GitRepository.py +++ b/tests/test_GitRepository.py @@ -493,6 +493,19 @@ def test_diff(): True """ +def test_diff_status(): + """ + Methods tested: + - L{gbp.git.GitRepository.diff_status} + + >>> import gbp.git + >>> repo = gbp.git.GitRepository(repo_dir) + >>> repo.diff_status("HEAD", "HEAD") + defaultdict(, {}) + >>> repo.diff_status("HEAD~1", "HEAD") + defaultdict(, {'M': ['testfile']}) + """ + def test_mirror_clone(): """ Mirror a repository -- cgit v1.2.3 From 57e48a4aae9154d4a457119fd96b1b55e71ca0d7 Mon Sep 17 00:00:00 2001 From: Markus Lehtonen Date: Mon, 13 Feb 2012 12:28:13 +0200 Subject: docs: enable building html docs with docbook2html This is useful if sgml2x package is not available. Signed-off-by: Markus Lehtonen --- docs/Makefile | 8 ++++++++ docs/local-nosgml2x.dsl | 34 ++++++++++++++++++++++++++++++++++ 2 files changed, 42 insertions(+) create mode 100644 docs/local-nosgml2x.dsl diff --git a/docs/Makefile b/docs/Makefile index 91c3b0ad..f1dac586 100644 --- a/docs/Makefile +++ b/docs/Makefile @@ -25,10 +25,18 @@ GBP_VERSION=../gbp/version.py DEB_VERSION=$(shell sed -ne 's/^gbp_version="\([.a-z0-9~-]\+\)"/\1/p' $(GBP_VERSION)) CHANGELOG=../debian/changelog +# Stuff to build docs outside Debian +HAVE_SGML2X ?= 1 +GTK_DOC_CATALOG_FILE ?= /usr/share/sgml/gtk-doc/gtk-doc.cat + all: $(MANUAL) $(MANPAGES) $(MANUAL): manual.sgml chapters/*.sgml manpages/*.sgml +ifeq ($(HAVE_SGML2X),1) docbook-2-html -s local $< +else + docbook2html -d local-nosgml2x.dsl -c $(GTK_DOC_CATALOG_FILE) -o $(MANUAL) $< +endif cp /usr/share/gtk-doc/data/*.png $(MANUAL) # We build manpages under 'buildxref/' just to get an updated cross-reference diff --git a/docs/local-nosgml2x.dsl b/docs/local-nosgml2x.dsl new file mode 100644 index 00000000..f9faab62 --- /dev/null +++ b/docs/local-nosgml2x.dsl @@ -0,0 +1,34 @@ + +]> + + + + + +;; Don't split up the doc as much. +(define (chunk-element-list) + (list (normalize "preface") + (normalize "chapter") + (normalize "appendix") + (normalize "article") + (normalize "glossary") + (normalize "bibliography") + (normalize "index") + (normalize "colophon") + (normalize "setindex") + (normalize "reference") + (normalize "refentry") + (normalize "part") + (normalize "book") ;; just in case nothing else matches... + (normalize "set") ;; sets are definitely chunks... + )) + + + + + + + -- cgit v1.2.3 From 6f63ebe002ac577d6f2dfb43f4721c999ceb8847 Mon Sep 17 00:00:00 2001 From: Markus Lehtonen Date: Tue, 15 May 2012 10:02:40 +0300 Subject: Move get_compression() out of pkg.PkgPolicy class Renames the function to parse_archive_filename() and changes it's return values. Filename parsing is merely generic functionality, not tied to any packaging policy. The function now returns the base name of the file (that is, filename without, archive and compression extensions), archive format and compression method. Adds supported archive formats 'tar' and 'zip' and file extension aliases, e.g. 'tgz'. Signed-off-by: Markus Lehtonen --- gbp/pkg/__init__.py | 81 +++++++++++++++++++++++++++++++++------------ gbp/scripts/buildpackage.py | 5 +-- 2 files changed, 63 insertions(+), 23 deletions(-) diff --git a/gbp/pkg/__init__.py b/gbp/pkg/__init__.py index 40e20dde..f63052f4 100644 --- a/gbp/pkg/__init__.py +++ b/gbp/pkg/__init__.py @@ -34,6 +34,66 @@ compressor_opts = { 'gzip' : [ ['-n'], 'gz' ], compressor_aliases = { 'bz2' : 'bzip2', 'gz' : 'gzip', } +# Supported archive formats +arhive_formats = [ 'tar', 'zip' ] + +# Map combined file extensions to arhive and compression format +archive_ext_aliases = { 'tgz' : ('tar', 'gzip'), + 'tbz2' : ('tar', 'bzip2'), + 'tlz' : ('tar', 'lzma'), + 'txz' : ('tar', 'xz')} + +def parse_archive_filename(filename): + """ + Given an filename return the basename (i.e. filename without the + archive and compression extensions), archive format and compression + method used. + + @param filename: the name of the file + @type filename: string + @return: tuple containing basename, archive format and compression method + @rtype: C{tuple} of C{str} + + >>> parse_archive_filename("abc.tar.gz") + ('abc', 'tar', 'gzip') + >>> parse_archive_filename("abc.tar.bz2") + ('abc', 'tar', 'bzip2') + >>> parse_archive_filename("abc.def.tbz2") + ('abc.def', 'tar', 'bzip2') + >>> parse_archive_filename("abc.def.tar.xz") + ('abc.def', 'tar', 'xz') + >>> parse_archive_filename("abc.zip") + ('abc', 'zip', None) + >>> parse_archive_filename("abc.lzma") + ('abc', None, 'lzma') + >>> parse_archive_filename("abc.tar.foo") + ('abc.tar.foo', None, None) + >>> parse_archive_filename("abc") + ('abc', None, None) + """ + (base_name, archive_fmt, compression) = (filename, None, None) + + # Split filename to pieces + split = filename.split(".") + if len(split) > 1: + if split[-1] in archive_ext_aliases: + base_name = ".".join(split[:-1]) + (archive_fmt, compression) = archive_ext_aliases[split[-1]] + elif split[-1] in arhive_formats: + base_name = ".".join(split[:-1]) + (archive_fmt, compression) = (split[-1], None) + else: + for (c, o) in compressor_opts.iteritems(): + if o[1] == split[-1]: + base_name = ".".join(split[:-1]) + compression = c + if len(split) > 2 and split[-2] in arhive_formats: + base_name = ".".join(split[:-2]) + archive_fmt = split[-2] + + return (base_name, archive_fmt, compression) + + class PkgPolicy(object): """ Common helpers for packaging policy. @@ -71,27 +131,6 @@ class PkgPolicy(object): raise NotImplementedError("Class needs to provide upstreamversion_re") return True if cls.upstreamversion_re.match(version) else False - @staticmethod - def get_compression(orig_file): - """ - Given an orig file return the compression used - - >>> PkgPolicy.get_compression("abc.tar.gz") - 'gzip' - >>> PkgPolicy.get_compression("abc.tar.bz2") - 'bzip2' - >>> PkgPolicy.get_compression("abc.tar.foo") - >>> PkgPolicy.get_compression("abc") - """ - try: - ext = orig_file.rsplit('.',1)[1] - except IndexError: - return None - for (c, o) in compressor_opts.iteritems(): - if o[1] == ext: - return c - return None - @staticmethod def has_orig(orig_file, dir): "Check if orig tarball exists in dir" diff --git a/gbp/scripts/buildpackage.py b/gbp/scripts/buildpackage.py index 23136858..9340f8ab 100755 --- a/gbp/scripts/buildpackage.py +++ b/gbp/scripts/buildpackage.py @@ -37,7 +37,8 @@ from gbp.scripts.common.buildpackage import (index_name, wc_name, git_archive_submodules, git_archive_single, dump_tree, write_wc, drop_index) -from gbp.pkg import (UpstreamSource, compressor_opts, compressor_aliases) +from gbp.pkg import (UpstreamSource, compressor_opts, compressor_aliases, + parse_archive_filename) def git_archive(repo, cp, output_dir, treeish, comp_type, comp_level, with_submodules): "create a compressed orig tarball in output_dir using git_archive" @@ -318,7 +319,7 @@ def guess_comp_type(repo, comp_type, cp, tarball_dir): else: commit = repo.pristine_tar_branch tarball = repo.get_commit_info(commit)['subject'] - comp_type = du.DebianPkgPolicy.get_compression(tarball) + (base_name, archive_fmt, comp_type) = parse_archive_filename(tarball) gbp.log.debug("Determined compression type '%s'" % comp_type) if not comp_type: comp_type = 'gzip' -- cgit v1.2.3 From 2401253c3b3d135dacd85a91aabc7008edeb38dc Mon Sep 17 00:00:00 2001 From: Markus Lehtonen Date: Wed, 12 Feb 2014 15:11:30 +0200 Subject: import-orig: implement --create-missing-branches option Create the upstream branch if it does not exist. Use the same option name that import-dsc has. Signed-off-by: Markus Lehtonen --- docs/manpages/gbp-import-orig.sgml | 10 ++++++++++ gbp/config.py | 3 ++- gbp/scripts/import_orig.py | 17 ++++++++++++----- 3 files changed, 24 insertions(+), 6 deletions(-) diff --git a/docs/manpages/gbp-import-orig.sgml b/docs/manpages/gbp-import-orig.sgml index b744752a..714a5340 100644 --- a/docs/manpages/gbp-import-orig.sgml +++ b/docs/manpages/gbp-import-orig.sgml @@ -26,6 +26,7 @@ branch_name branch_name + tag_name gpg-keyid @@ -105,6 +106,15 @@ + + + + + + Create missing upstream branch if it does not exist. + + + =tag_name diff --git a/gbp/config.py b/gbp/config.py index 2eb6330f..67c9921b 100644 --- a/gbp/config.py +++ b/gbp/config.py @@ -29,7 +29,8 @@ import gbp.tristate no_upstream_branch_msg = """ Repository does not have branch '%s' for upstream sources. If there is none see file:///usr/share/doc/git-buildpackage/manual-html/gbp.import.html#GBP.IMPORT.CONVERT -on howto create it otherwise use --upstream-branch to specify it. +on howto create it or check the --create-missing-branches option. Otherwise, +use --upstream-branch to specify it. """ def expand_path(option, opt, value): diff --git a/gbp/scripts/import_orig.py b/gbp/scripts/import_orig.py index 3061994c..baa0ab3b 100644 --- a/gbp/scripts/import_orig.py +++ b/gbp/scripts/import_orig.py @@ -209,6 +209,9 @@ def build_parser(name): branch_group.add_option("--upstream-vcs-tag", dest="vcs_tag", help="Upstream VCS tag add to the merge commit") branch_group.add_boolean_config_file_option(option_name="merge", dest="merge") + branch_group.add_boolean_config_file_option( + option_name="create-missing-branches", + dest="create_missing_branches") tag_group.add_boolean_config_file_option(option_name="sign-tags", dest="sign_tags") @@ -283,7 +286,11 @@ def main(argv): is_empty = False if initial_branch else True if not repo.has_branch(options.upstream_branch) and not is_empty: - raise GbpError(no_upstream_branch_msg % options.upstream_branch) + if options.create_missing_branches: + gbp.log.info("Will create missing branch '%s'" % + options.upstream_branch) + else: + raise GbpError(no_upstream_branch_msg % options.upstream_branch) (sourcepackage, version) = detect_name_and_version(repo, source, options) @@ -334,10 +341,10 @@ def main(argv): parents = None commit = repo.commit_dir(source.unpacked, - msg=msg, - branch=import_branch, - other_parents=parents, - ) + msg=msg, + branch=import_branch, + other_parents=parents, + create_missing_branch=options.create_missing_branches) if options.pristine_tar: if pristine_orig: -- cgit v1.2.3 From 22d77d9df9dc52ce512b0f351a10fdea54502c1a Mon Sep 17 00:00:00 2001 From: Markus Lehtonen Date: Fri, 15 Jun 2012 08:43:12 +0300 Subject: import-orig: simplify repack_source() and tmpdir handling Now a tmpdir is always created and sources are always unpacked into there. Signed-off-by: Markus Lehtonen --- gbp/scripts/common/import_orig.py | 9 +++------ gbp/scripts/import_orig.py | 9 +++++---- 2 files changed, 8 insertions(+), 10 deletions(-) diff --git a/gbp/scripts/common/import_orig.py b/gbp/scripts/common/import_orig.py index c2c53a64..573ae937 100644 --- a/gbp/scripts/common/import_orig.py +++ b/gbp/scripts/common/import_orig.py @@ -126,16 +126,13 @@ def repacked_tarball_name(source, name, version): return name -def repack_source(source, name, version, tmpdir, filters): +def repack_source(source, name, version, unpack_dir, filters): """Repack the source tree""" name = repacked_tarball_name(source, name, version) repacked = source.pack(name, filters) if source.is_orig(): # the tarball was filtered on unpack repacked.unpacked = source.unpacked else: # otherwise unpack the generated tarball get a filtered tree - if tmpdir: - cleanup_tmp_tree(tmpdir) - tmpdir = tempfile.mkdtemp(dir='../') - repacked.unpack(tmpdir, filters) - return (repacked, tmpdir) + repacked.unpack(unpack_dir, filters) + return repacked diff --git a/gbp/scripts/import_orig.py b/gbp/scripts/import_orig.py index baa0ab3b..1d427283 100644 --- a/gbp/scripts/import_orig.py +++ b/gbp/scripts/import_orig.py @@ -263,7 +263,7 @@ def parse_args(argv): def main(argv): ret = 0 - tmpdir = '' + tmpdir = tempfile.mkdtemp(dir='../') pristine_orig = None linked = False @@ -303,13 +303,14 @@ def main(argv): set_bare_repo_options(options) if not source.is_dir(): - tmpdir = tempfile.mkdtemp(dir='../') - source.unpack(tmpdir, options.filters) + unpack_dir = tempfile.mkdtemp(prefix='unpack', dir=tmpdir) + source.unpack(unpack_dir, options.filters) gbp.log.debug("Unpacked '%s' to '%s'" % (source.path, source.unpacked)) if source.needs_repack(options): gbp.log.debug("Filter pristine-tar: repacking '%s' from '%s'" % (source.path, source.unpacked)) - (source, tmpdir) = repack_source(source, sourcepackage, version, tmpdir, options.filters) + repack_dir = tempfile.mkdtemp(prefix='repack', dir=tmpdir) + source = repack_source(source, sourcepackage, version, repack_dir, options.filters) (pristine_orig, linked) = prepare_pristine_tar(source.path, sourcepackage, -- cgit v1.2.3 From 21206526b9a3afe14ec311141e00c04f1ab5be8c Mon Sep 17 00:00:00 2001 From: Markus Lehtonen Date: Fri, 15 Jun 2012 09:00:35 +0300 Subject: import-orig: move repacked_tarball_name() out from common Moves repacked_tarball_name() from scripts/common back to the Debian-specific script. The logic is too Debian-specific for RPM, after all. Signed-off-by: Markus Lehtonen --- gbp/scripts/common/import_orig.py | 20 ++------------------ gbp/scripts/import_orig.py | 18 +++++++++++++++++- 2 files changed, 19 insertions(+), 19 deletions(-) diff --git a/gbp/scripts/common/import_orig.py b/gbp/scripts/common/import_orig.py index 573ae937..874ff1c9 100644 --- a/gbp/scripts/common/import_orig.py +++ b/gbp/scripts/common/import_orig.py @@ -111,25 +111,9 @@ def ask_package_version(default, ver_validator_func, err_msg): gbp.log.warn("\nNot a valid upstream version: '%s'.\n%s" % (version, err_msg)) -def repacked_tarball_name(source, name, version): - if source.is_orig(): - # Repacked orig tarball needs a different name since there's already - # one with that name - name = os.path.join( - os.path.dirname(source.path), - os.path.basename(source.path).replace(".tar", ".gbp.tar")) - else: - # Repacked sources or other archives get canonical name - name = os.path.join( - os.path.dirname(source.path), - "%s_%s.orig.tar.bz2" % (name, version)) - return name - - -def repack_source(source, name, version, unpack_dir, filters): +def repack_source(source, new_name, unpack_dir, filters): """Repack the source tree""" - name = repacked_tarball_name(source, name, version) - repacked = source.pack(name, filters) + repacked = source.pack(new_name, filters) if source.is_orig(): # the tarball was filtered on unpack repacked.unpacked = source.unpacked else: # otherwise unpack the generated tarball get a filtered tree diff --git a/gbp/scripts/import_orig.py b/gbp/scripts/import_orig.py index 1d427283..d51e1409 100644 --- a/gbp/scripts/import_orig.py +++ b/gbp/scripts/import_orig.py @@ -171,6 +171,21 @@ def find_source(use_uscan, args): return archive +def repacked_tarball_name(source, name, version): + if source.is_orig(): + # Repacked orig tarball needs a different name since there's already + # one with that name + name = os.path.join( + os.path.dirname(source.path), + os.path.basename(source.path).replace(".tar", ".gbp.tar")) + else: + # Repacked sources or other archives get canonical name + name = os.path.join( + os.path.dirname(source.path), + "%s_%s.orig.tar.bz2" % (name, version)) + return name + + def set_bare_repo_options(options): """Modify options for import into a bare repository""" if options.pristine_tar or options.merge: @@ -310,7 +325,8 @@ def main(argv): if source.needs_repack(options): gbp.log.debug("Filter pristine-tar: repacking '%s' from '%s'" % (source.path, source.unpacked)) repack_dir = tempfile.mkdtemp(prefix='repack', dir=tmpdir) - source = repack_source(source, sourcepackage, version, repack_dir, options.filters) + repack_name = repacked_tarball_name(source, sourcepackage, version) + source = repack_source(source, repack_name, repack_dir, options.filters) (pristine_orig, linked) = prepare_pristine_tar(source.path, sourcepackage, -- cgit v1.2.3 From 238e317437e56cb9a43b744682cef66cbeb83d31 Mon Sep 17 00:00:00 2001 From: Markus Lehtonen Date: Thu, 14 Jun 2012 19:30:26 +0300 Subject: UpstreamSource.pack: support prefix mangling Add support for changing the prefix directory inside the tarball that is generated. Also, fixes a bug that caused a "prefix-less" tarball to get one, if unpacked and then repacked. Also, adds this support to repack_source() in common/import_orig. Signed-off-by: Markus Lehtonen --- gbp/command_wrappers.py | 13 ++++++++++--- gbp/pkg/__init__.py | 24 ++++++++++++++++++------ gbp/scripts/common/import_orig.py | 4 ++-- tests/06_test_upstream_source.py | 9 +++++++++ 4 files changed, 39 insertions(+), 11 deletions(-) diff --git a/gbp/command_wrappers.py b/gbp/command_wrappers.py index f1312e4c..0d29af17 100644 --- a/gbp/command_wrappers.py +++ b/gbp/command_wrappers.py @@ -169,7 +169,8 @@ class UnpackTarArchive(Command): class PackTarArchive(Command): """Wrap tar to pack a compressed tar archive""" - def __init__(self, archive, dir, dest, filters=[], compression=None): + def __init__(self, archive, dir, dest, filters=[], compression=None, + transform=None): self.archive = archive self.dir = dir exclude = [("--exclude=%s" % _filter) for _filter in filters] @@ -177,8 +178,14 @@ class PackTarArchive(Command): if not compression: compression = '-a' - Command.__init__(self, 'tar', exclude + - ['-C', dir, compression, '-cf', archive, dest]) + args = exclude + ['-C', dir, compression, '-cf', archive ] + + if transform != None: + args.append('--transform=%s' % transform) + + args.append(dest) + + Command.__init__(self, 'tar', args) self.run_error = 'Couldn\'t repack "%s"' % self.archive diff --git a/gbp/pkg/__init__.py b/gbp/pkg/__init__.py index f63052f4..a7a37c1a 100644 --- a/gbp/pkg/__init__.py +++ b/gbp/pkg/__init__.py @@ -273,7 +273,8 @@ class UpstreamSource(object): if len(unpacked) == 1 and os.path.isdir(unpacked[0]): return unpacked[0] else: - return dir + # We can determine "no prefix" from this + return os.path.join(dir, ".") def _unpack_tar(self, dir, filters): """ @@ -287,7 +288,7 @@ class UpstreamSource(object): # unpackArchive already printed an error message raise GbpError - def pack(self, newarchive, filters=[]): + def pack(self, newarchive, filters=[], newprefix=None): """ Recreate a new archive from the current one @@ -295,6 +296,8 @@ class UpstreamSource(object): @type newarchive: string @param filters: tar filters to apply @type filters: array of strings + @param newprefix: new prefix, None implies that prefix is not mangled + @type newprefix: string or None @return: the new upstream source @rtype: UpstreamSource """ @@ -307,12 +310,21 @@ class UpstreamSource(object): if type(filters) != type([]): raise GbpError("Filters must be a list") + run_dir = os.path.dirname(self.unpacked.rstrip('/')) + pack_this = os.path.basename(self.unpacked.rstrip('/')) + transform = None + if newprefix is not None: + newprefix = newprefix.strip('/.') + if newprefix: + transform = 's!%s!%s!' % (pack_this, newprefix) + else: + transform = 's!%s!%s!' % (pack_this, '.') try: - unpacked = self.unpacked.rstrip('/') repackArchive = gbpc.PackTarArchive(newarchive, - os.path.dirname(unpacked), - os.path.basename(unpacked), - filters) + run_dir, + pack_this, + filters, + transform=transform) repackArchive() except gbpc.CommandExecFailed: # repackArchive already printed an error diff --git a/gbp/scripts/common/import_orig.py b/gbp/scripts/common/import_orig.py index 874ff1c9..cf74eb36 100644 --- a/gbp/scripts/common/import_orig.py +++ b/gbp/scripts/common/import_orig.py @@ -111,9 +111,9 @@ def ask_package_version(default, ver_validator_func, err_msg): gbp.log.warn("\nNot a valid upstream version: '%s'.\n%s" % (version, err_msg)) -def repack_source(source, new_name, unpack_dir, filters): +def repack_source(source, new_name, unpack_dir, filters, new_prefix=None): """Repack the source tree""" - repacked = source.pack(new_name, filters) + repacked = source.pack(new_name, filters, new_prefix) if source.is_orig(): # the tarball was filtered on unpack repacked.unpacked = source.unpacked else: # otherwise unpack the generated tarball get a filtered tree diff --git a/tests/06_test_upstream_source.py b/tests/06_test_upstream_source.py index 967c4fa0..af64a73b 100644 --- a/tests/06_test_upstream_source.py +++ b/tests/06_test_upstream_source.py @@ -71,6 +71,15 @@ class TestTar(unittest.TestCase): self._check_tar(repacked, ["gbp/errors.py"], ["gbp/__init__.py"]) + def test_pack_mangle_prefix(self): + """Check if mangling prefix works""" + source = UpstreamSource(os.path.abspath("gbp/")) + target = self.tmpdir.join("gbp_0.1.tar.bz2") + repacked = source.pack(target, newprefix="foobar") + self._check_tar(repacked, ["foobar/errors.py", "foobar/__init__.py"]) + repacked2 = source.pack(target, newprefix="") + self._check_tar(repacked2, ["./errors.py", "./__init__.py"]) + class TestZip(unittest.TestCase): """Test if unpacking zip archives works""" -- cgit v1.2.3 From 64ed0b157a3d157c7851b425c67fb0fdea4f4648 Mon Sep 17 00:00:00 2001 From: Markus Lehtonen Date: Mon, 9 Jul 2012 15:17:24 +0300 Subject: Change UpstreamSource to have PkgPolicy The UpstreamSource class now gets a PkgPolicy in it's initialization. Also, introduces new DebiaUpstreamSource class which is taken in use in the scripts. The PkgPolicy is not yet used for anything in UpstreamSource. Signed-off-by: Markus Lehtonen --- gbp/deb/dscfile.py | 4 ++-- gbp/deb/upstreamsource.py | 28 ++++++++++++++++++++++++++ gbp/pkg/__init__.py | 5 +++-- gbp/scripts/buildpackage.py | 6 +++--- gbp/scripts/common/import_orig.py | 41 ++++++++++++++++++--------------------- gbp/scripts/import_dsc.py | 4 ++-- gbp/scripts/import_orig.py | 7 ++++--- 7 files changed, 61 insertions(+), 34 deletions(-) create mode 100644 gbp/deb/upstreamsource.py diff --git a/gbp/deb/dscfile.py b/gbp/deb/dscfile.py index e2492dcc..06713288 100644 --- a/gbp/deb/dscfile.py +++ b/gbp/deb/dscfile.py @@ -20,12 +20,12 @@ import os import re from gbp.errors import GbpError -from gbp.pkg import UpstreamSource +from gbp.deb.upstreamsource import DebianUpstreamSource from gbp.deb.policy import DebianPkgPolicy class DscFile(object): """Keeps all needed data read from a dscfile""" - compressions = r"(%s)" % '|'.join(UpstreamSource.known_compressions()) + compressions = r"(%s)" % '|'.join(DebianUpstreamSource.known_compressions()) pkg_re = re.compile(r'Source:\s+(?P.+)\s*') version_re = re.compile(r'Version:\s((?P\d+)\:)?' '(?P[%s]+)\s*$' diff --git a/gbp/deb/upstreamsource.py b/gbp/deb/upstreamsource.py new file mode 100644 index 00000000..7eb555ae --- /dev/null +++ b/gbp/deb/upstreamsource.py @@ -0,0 +1,28 @@ +# vim: set fileencoding=utf-8 : +# +# (C) 2013 Intel Corporation +# This program is free software; you can redistribute it and/or modify +# it under the terms of the GNU General Public License as published by +# the Free Software Foundation; either version 2 of the License, or +# (at your option) any later version. +# +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with this program; if not, write to the Free Software +# Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA +"""Debian-specific upstream sources""" + +from gbp.pkg import UpstreamSource +from gbp.deb.policy import DebianPkgPolicy + + +class DebianUpstreamSource(UpstreamSource): + """Upstream source class for Debian""" + def __init__(self, name, unpacked=None): + super(DebianUpstreamSource, self).__init__(name, + unpacked, + DebianPkgPolicy) diff --git a/gbp/pkg/__init__.py b/gbp/pkg/__init__.py index a7a37c1a..28cd4219 100644 --- a/gbp/pkg/__init__.py +++ b/gbp/pkg/__init__.py @@ -179,8 +179,9 @@ class UpstreamSource(object): @cvar _unpacked: path to the unpacked source tree @type _unpacked: string """ - def __init__(self, name, unpacked=None): + def __init__(self, name, unpacked=None, pkg_policy=PkgPolicy): self._orig = False + self._pkg_policy = pkg_policy self._path = name self.unpacked = unpacked @@ -329,7 +330,7 @@ class UpstreamSource(object): except gbpc.CommandExecFailed: # repackArchive already printed an error raise GbpError - return UpstreamSource(newarchive) + return type(self)(newarchive) @staticmethod def known_compressions(): diff --git a/gbp/scripts/buildpackage.py b/gbp/scripts/buildpackage.py index 9340f8ab..af0f34be 100755 --- a/gbp/scripts/buildpackage.py +++ b/gbp/scripts/buildpackage.py @@ -30,6 +30,7 @@ from gbp.config import (GbpOptionParserDebian, GbpOptionGroup) from gbp.deb.git import (GitRepositoryError, DebianGitRepository) from gbp.deb.source import DebianSource, DebianSourceError from gbp.git.vfs import GitVfs +from gbp.deb.upstreamsource import DebianUpstreamSource from gbp.errors import GbpError import gbp.log import gbp.notifications @@ -37,8 +38,7 @@ from gbp.scripts.common.buildpackage import (index_name, wc_name, git_archive_submodules, git_archive_single, dump_tree, write_wc, drop_index) -from gbp.pkg import (UpstreamSource, compressor_opts, compressor_aliases, - parse_archive_filename) +from gbp.pkg import compressor_opts, compressor_aliases, parse_archive_filename def git_archive(repo, cp, output_dir, treeish, comp_type, comp_level, with_submodules): "create a compressed orig tarball in output_dir using git_archive" @@ -172,7 +172,7 @@ def extract_orig(orig_tarball, dest_dir): gbp.log.info("Extracting %s to '%s'" % (os.path.basename(orig_tarball), dest_dir)) move_old_export(dest_dir) - upstream = UpstreamSource(orig_tarball) + upstream = DebianUpstreamSource(orig_tarball) upstream.unpack(dest_dir) # Check if tarball extracts into a single folder or not: diff --git a/gbp/scripts/common/import_orig.py b/gbp/scripts/common/import_orig.py index cf74eb36..d2490b39 100644 --- a/gbp/scripts/common/import_orig.py +++ b/gbp/scripts/common/import_orig.py @@ -32,29 +32,26 @@ except ImportError: pass -class OrigUpstreamSource(UpstreamSource): - """Upstream source that will be imported""" - - def needs_repack(self, options): - """ - Determine if the upstream sources needs to be repacked - - We repack if - 1. we want to filter out files and use pristine tar since we want - to make a filtered tarball available to pristine-tar - 2. when we don't have a suitable upstream tarball (e.g. zip archive or unpacked dir) - and want to use filters - 3. when we don't have a suitable upstream tarball (e.g. zip archive or unpacked dir) - and want to use pristine-tar - """ - if ((options.pristine_tar and options.filter_pristine_tar and len(options.filters) > 0)): +def orig_needs_repack(upstream_source, options): + """ + Determine if the upstream sources needs to be repacked + + We repack if + 1. we want to filter out files and use pristine tar since we want + to make a filtered tarball available to pristine-tar + 2. when we don't have a suitable upstream tarball (e.g. zip archive or unpacked dir) + and want to use filters + 3. when we don't have a suitable upstream tarball (e.g. zip archive or unpacked dir) + and want to use pristine-tar + """ + if ((options.pristine_tar and options.filter_pristine_tar and len(options.filters) > 0)): + return True + elif not upstream_source.is_orig(): + if len(options.filters): return True - elif not self.is_orig(): - if len(options.filters): - return True - elif options.pristine_tar: - return True - return False + elif options.pristine_tar: + return True + return False def cleanup_tmp_tree(tree): diff --git a/gbp/scripts/import_dsc.py b/gbp/scripts/import_dsc.py index 600b394d..ce97fcb0 100644 --- a/gbp/scripts/import_dsc.py +++ b/gbp/scripts/import_dsc.py @@ -26,8 +26,8 @@ import glob import pipes import time import gbp.command_wrappers as gbpc -from gbp.pkg import UpstreamSource from gbp.deb.dscfile import DscFile +from gbp.deb.upstreamsource import DebianUpstreamSource from gbp.deb.git import (DebianGitRepository, GitRepositoryError) from gbp.deb.changelog import ChangeLog from gbp.git import rfc822_date_to_git @@ -328,7 +328,7 @@ def main(argv): set_bare_repo_options(options) dirs['tmp'] = os.path.abspath(tempfile.mkdtemp(dir='..')) - upstream = UpstreamSource(src.tgz) + upstream = DebianUpstreamSource(src.tgz) upstream.unpack(dirs['tmp'], options.filters) format = [(options.upstream_tag, "Upstream"), (options.debian_tag, "Debian")][src.native] diff --git a/gbp/scripts/import_orig.py b/gbp/scripts/import_orig.py index d51e1409..23c0921a 100644 --- a/gbp/scripts/import_orig.py +++ b/gbp/scripts/import_orig.py @@ -23,13 +23,14 @@ import sys import tempfile import gbp.command_wrappers as gbpc from gbp.deb import (DebianPkgPolicy, parse_changelog_repo) +from gbp.deb.upstreamsource import DebianUpstreamSource from gbp.deb.uscan import (Uscan, UscanError) from gbp.deb.changelog import ChangeLog, NoChangeLogError from gbp.deb.git import (GitRepositoryError, DebianGitRepository) from gbp.config import GbpOptionParserDebian, GbpOptionGroup, no_upstream_branch_msg from gbp.errors import GbpError import gbp.log -from gbp.scripts.common.import_orig import (OrigUpstreamSource, cleanup_tmp_tree, +from gbp.scripts.common.import_orig import (orig_needs_repack, cleanup_tmp_tree, ask_package_name, ask_package_version, repack_source, is_link_target) @@ -167,7 +168,7 @@ def find_source(use_uscan, args): elif len(args) == 0: raise GbpError("No archive to import specified. Try --help.") else: - archive = OrigUpstreamSource(args[0]) + archive = DebianUpstreamSource(args[0]) return archive @@ -322,7 +323,7 @@ def main(argv): source.unpack(unpack_dir, options.filters) gbp.log.debug("Unpacked '%s' to '%s'" % (source.path, source.unpacked)) - if source.needs_repack(options): + if orig_needs_repack(source, options): gbp.log.debug("Filter pristine-tar: repacking '%s' from '%s'" % (source.path, source.unpacked)) repack_dir = tempfile.mkdtemp(prefix='repack', dir=tmpdir) repack_name = repacked_tarball_name(source, sourcepackage, version) -- cgit v1.2.3 From 303d00181de6199bd67e678af1584a6d985f82cf Mon Sep 17 00:00:00 2001 From: Markus Lehtonen Date: Mon, 9 Jul 2012 16:10:37 +0300 Subject: Introduce PkgPolicy.is_valid_orig_archive() A new method for checking if the given filename is usable as a orig (upstream) source archive. Also, takes this method into use in the UpstreamSource class. Signed-off-by: Markus Lehtonen --- gbp/pkg/__init__.py | 19 +++++++++---------- 1 file changed, 9 insertions(+), 10 deletions(-) diff --git a/gbp/pkg/__init__.py b/gbp/pkg/__init__.py index 28cd4219..0c3f4aeb 100644 --- a/gbp/pkg/__init__.py +++ b/gbp/pkg/__init__.py @@ -131,6 +131,14 @@ class PkgPolicy(object): raise NotImplementedError("Class needs to provide upstreamversion_re") return True if cls.upstreamversion_re.match(version) else False + @classmethod + def is_valid_orig_archive(cls, filename): + "Is this a valid orig source archive" + (base, arch_fmt, compression) = parse_archive_filename(filename) + if arch_fmt == 'tar' and compression: + return True + return False + @staticmethod def has_orig(orig_file, dir): "Check if orig tarball exists in dir" @@ -202,16 +210,7 @@ class UpstreamSource(object): self._orig = False return - parts = self._path.split('.') - try: - if parts[-1] == 'tgz': - self._orig = True - elif parts[-2] == 'tar': - if (parts[-1] in compressor_opts or - parts[-1] in compressor_aliases): - self._orig = True - except IndexError: - self._orig = False + self._orig = self._pkg_policy.is_valid_orig_archive(os.path.basename(self.path)) def is_orig(self): """ -- cgit v1.2.3 From ce9cad5875a6f97c52b426082a9f90795b09f755 Mon Sep 17 00:00:00 2001 From: Markus Lehtonen Date: Mon, 9 Jul 2012 17:16:21 +0300 Subject: UpstreamSource: add 'archive_fmt' and 'compression' properties New properties for easily getting the archive format (tar, zip, ...) and compression format (gzip, bzip2, ...) of the sources. Signed-off-by: Markus Lehtonen --- gbp/pkg/__init__.py | 25 +++++++++++++++++++++++++ 1 file changed, 25 insertions(+) diff --git a/gbp/pkg/__init__.py b/gbp/pkg/__init__.py index 0c3f4aeb..7be1fd22 100644 --- a/gbp/pkg/__init__.py +++ b/gbp/pkg/__init__.py @@ -192,6 +192,9 @@ class UpstreamSource(object): self._pkg_policy = pkg_policy self._path = name self.unpacked = unpacked + self._filename_base, \ + self._archive_fmt, \ + self._compression = parse_archive_filename(os.path.basename(self.path)) self._check_orig() if self.is_dir(): @@ -232,6 +235,28 @@ class UpstreamSource(object): def path(self): return self._path.rstrip('/') + @property + def archive_fmt(self): + """ + >>> UpstreamSource('foo/bar.tar.gz').archive_fmt + 'tar' + >>> UpstreamSource('foo.bar.zip').archive_fmt + 'zip' + >>> UpstreamSource('foo.bar.baz').archive_fmt + """ + return self._archive_fmt + + @property + def compression(self): + """ + >>> UpstreamSource('foo/bar.tar.gz').compression + 'gzip' + >>> UpstreamSource('foo.bar.zip').compression + >>> UpstreamSource('foo.bz2').compression + 'bzip2' + """ + return self._compression + def unpack(self, dir, filters=[]): """ Unpack packed upstream sources into a given directory -- cgit v1.2.3 From 9d0e6700951a9631396c5ef8b87a30aa562b143a Mon Sep 17 00:00:00 2001 From: Markus Lehtonen Date: Mon, 9 Jul 2012 17:19:27 +0300 Subject: UpstreamSource: introduce is_tarball() method New method for checking if the sources are a tarball (possibly for checking if the sources are committable by pristine-tar). Signed-off-by: Markus Lehtonen --- gbp/pkg/__init__.py | 10 ++++++++++ gbp/scripts/common/import_orig.py | 4 ++-- tests/06_test_upstream_source.py | 4 ++++ 3 files changed, 16 insertions(+), 2 deletions(-) diff --git a/gbp/pkg/__init__.py b/gbp/pkg/__init__.py index 7be1fd22..3e9e4099 100644 --- a/gbp/pkg/__init__.py +++ b/gbp/pkg/__init__.py @@ -189,6 +189,7 @@ class UpstreamSource(object): """ def __init__(self, name, unpacked=None, pkg_policy=PkgPolicy): self._orig = False + self._tarball = False self._pkg_policy = pkg_policy self._path = name self.unpacked = unpacked @@ -211,8 +212,10 @@ class UpstreamSource(object): """ if self.is_dir(): self._orig = False + self._tarball = False return + self._tarball = True if self.archive_fmt == 'tar' else False self._orig = self._pkg_policy.is_valid_orig_archive(os.path.basename(self.path)) def is_orig(self): @@ -223,6 +226,13 @@ class UpstreamSource(object): """ return self._orig + def is_tarball(self): + """ + @return: C{True} if source is a tarball, C{False} otherwise + @rtype: C{bool} + """ + return self._tarball + def is_dir(self): """ @return: C{True} if if upstream sources are an unpacked directory, diff --git a/gbp/scripts/common/import_orig.py b/gbp/scripts/common/import_orig.py index d2490b39..80807a62 100644 --- a/gbp/scripts/common/import_orig.py +++ b/gbp/scripts/common/import_orig.py @@ -46,7 +46,7 @@ def orig_needs_repack(upstream_source, options): """ if ((options.pristine_tar and options.filter_pristine_tar and len(options.filters) > 0)): return True - elif not upstream_source.is_orig(): + elif not upstream_source.is_tarball(): if len(options.filters): return True elif options.pristine_tar: @@ -111,7 +111,7 @@ def ask_package_version(default, ver_validator_func, err_msg): def repack_source(source, new_name, unpack_dir, filters, new_prefix=None): """Repack the source tree""" repacked = source.pack(new_name, filters, new_prefix) - if source.is_orig(): # the tarball was filtered on unpack + if source.is_tarball(): # the tarball was filtered on unpack repacked.unpacked = source.unpacked else: # otherwise unpack the generated tarball get a filtered tree repacked.unpack(unpack_dir, filters) diff --git a/tests/06_test_upstream_source.py b/tests/06_test_upstream_source.py index af64a73b..bf4baa19 100644 --- a/tests/06_test_upstream_source.py +++ b/tests/06_test_upstream_source.py @@ -24,6 +24,7 @@ class TestDir(unittest.TestCase): """Upstream source is a directory""" source = UpstreamSource(self.upstream_dir) self.assertEqual(source.is_orig(), False) + self.assertEqual(source.is_tarball(), False) self.assertEqual(source.path, self.upstream_dir) self.assertEqual(source.unpacked, self.upstream_dir) self.assertEqual(source.guess_version(), ('test', '1.0')) @@ -59,6 +60,7 @@ class TestTar(unittest.TestCase): target = self.tmpdir.join("gbp_0.1.tar.bz2") repacked = self.source.pack(target) self.assertEqual(repacked.is_orig(), True) + self.assertEqual(repacked.is_tarball(), True) self.assertEqual(repacked.is_dir(), False) self._check_tar(repacked, ["gbp/errors.py", "gbp/__init__.py"]) @@ -67,6 +69,7 @@ class TestTar(unittest.TestCase): target = self.tmpdir.join("gbp_0.1.tar.bz2") repacked = self.source.pack(target, ["__init__.py"]) self.assertEqual(repacked.is_orig(), True) + self.assertEqual(repacked.is_tarball(), True) self.assertEqual(repacked.is_dir(), False) self._check_tar(repacked, ["gbp/errors.py"], ["gbp/__init__.py"]) @@ -97,6 +100,7 @@ class TestZip(unittest.TestCase): def test_unpack(self): source = UpstreamSource(self.zipfile) self.assertEqual(source.is_orig(), False) + self.assertEqual(source.is_tarball(), False) self.assertEqual(source.is_dir(), False) self.assertEqual(source.unpacked, None) source.unpack(str(self.tmpdir)) -- cgit v1.2.3 From 5ecc57cff2e4cbed986719783e804370abf782fe Mon Sep 17 00:00:00 2001 From: Markus Lehtonen Date: Thu, 27 Sep 2012 10:24:28 +0300 Subject: UpstreamSource/guess_version: detect more compression formats By utilizing the parse_archive_filename() function that detects e.g. "alias suffixes" such as 'tgz'. Signed-off-by: Markus Lehtonen --- gbp/pkg/__init__.py | 16 ++++++++++------ 1 file changed, 10 insertions(+), 6 deletions(-) diff --git a/gbp/pkg/__init__.py b/gbp/pkg/__init__.py index 3e9e4099..f516834e 100644 --- a/gbp/pkg/__init__.py +++ b/gbp/pkg/__init__.py @@ -399,6 +399,10 @@ class UpstreamSource(object): ('foo-bar', '0.2') >>> UpstreamSource('foo-bar_0.2.orig.tar.lzma').guess_version() ('foo-bar', '0.2') + >>> UpstreamSource('foo-bar-0.2.zip').guess_version() + ('foo-bar', '0.2') + >>> UpstreamSource('foo-bar-0.2.tlz').guess_version() + ('foo-bar', '0.2') @param extra_regex: additional regex to apply, needs a 'package' and a 'version' group @@ -407,20 +411,20 @@ class UpstreamSource(object): """ version_chars = r'[a-zA-Z\d\.\~\-\:\+]' if self.is_dir(): - extensions = '' + basename = os.path.basename(self.path) else: - extensions = r'\.tar\.(%s)' % "|".join(self.known_compressions()) + basename = parse_archive_filename(os.path.basename(self.path))[0] - version_filters = map ( lambda x: x % (version_chars, extensions), + version_filters = map ( lambda x: x % version_chars, ( # Debian upstream tarball: package_'.orig.tar.gz' - r'^(?P[a-z\d\.\+\-]+)_(?P%s+)\.orig%s', + r'^(?P[a-z\d\.\+\-]+)_(?P%s+)\.orig', # Upstream 'package-.tar.gz' # or directory 'package-': - r'^(?P[a-zA-Z\d\.\+\-]+)-(?P[0-9]%s*)%s')) + r'^(?P[a-zA-Z\d\.\+\-]+)-(?P[0-9]%s*)')) if extra_regex: version_filters = extra_regex + version_filters for filter in version_filters: - m = re.match(filter, os.path.basename(self.path)) + m = re.match(filter, basename) if m: return (m.group('package'), m.group('version')) -- cgit v1.2.3 From c22e056be6e400a0a0e37007b6af21f3b271832f Mon Sep 17 00:00:00 2001 From: Markus Lehtonen Date: Thu, 6 Jun 2013 14:53:45 +0300 Subject: UpstreamSource.guess_version: recognise debian native tarballs Signed-off-by: Markus Lehtonen --- gbp/pkg/__init__.py | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) diff --git a/gbp/pkg/__init__.py b/gbp/pkg/__init__.py index f516834e..dd4ca7f5 100644 --- a/gbp/pkg/__init__.py +++ b/gbp/pkg/__init__.py @@ -381,6 +381,7 @@ class UpstreamSource(object): >>> UpstreamSource('foo-bar_0.2.orig.tar.gz').guess_version() ('foo-bar', '0.2') >>> UpstreamSource('foo-Bar_0.2.orig.tar.gz').guess_version() + ('foo-Bar', '0.2.orig') >>> UpstreamSource('git-bar-0.2.tar.gz').guess_version() ('git-bar', '0.2') >>> UpstreamSource('git-bar-0.2-rc1.tar.gz').guess_version() @@ -393,10 +394,11 @@ class UpstreamSource(object): ('git', '1') >>> UpstreamSource('kvm_87+dfsg.orig.tar.gz').guess_version() ('kvm', '87+dfsg') - >>> UpstreamSource('foo-Bar_0.2.orig.tar.gz').guess_version() >>> UpstreamSource('foo-Bar-a.b.tar.gz').guess_version() >>> UpstreamSource('foo-bar_0.2.orig.tar.xz').guess_version() ('foo-bar', '0.2') + >>> UpstreamSource('foo-bar_0.2.tar.gz').guess_version() + ('foo-bar', '0.2') >>> UpstreamSource('foo-bar_0.2.orig.tar.lzma').guess_version() ('foo-bar', '0.2') >>> UpstreamSource('foo-bar-0.2.zip').guess_version() @@ -419,8 +421,9 @@ class UpstreamSource(object): ( # Debian upstream tarball: package_'.orig.tar.gz' r'^(?P[a-z\d\.\+\-]+)_(?P%s+)\.orig', # Upstream 'package-.tar.gz' + # or Debian native 'package_.tar.gz' # or directory 'package-': - r'^(?P[a-zA-Z\d\.\+\-]+)-(?P[0-9]%s*)')) + r'^(?P[a-zA-Z\d\.\+\-]+)(-|_)(?P[0-9]%s*)')) if extra_regex: version_filters = extra_regex + version_filters -- cgit v1.2.3 From eadf749249fba912be28c1cc61aad3b1518e4e68 Mon Sep 17 00:00:00 2001 From: Markus Lehtonen Date: Mon, 26 Aug 2013 16:47:57 +0300 Subject: UpstreamSource.guess_version: don't check for directories Directories are not recognized anyway, if guess_version() is called for non-existent sources. And, parse_archive_filename() works fine for directory names, too. Signed-off-by: Markus Lehtonen --- gbp/pkg/__init__.py | 16 +++++----------- 1 file changed, 5 insertions(+), 11 deletions(-) diff --git a/gbp/pkg/__init__.py b/gbp/pkg/__init__.py index dd4ca7f5..e5daa838 100644 --- a/gbp/pkg/__init__.py +++ b/gbp/pkg/__init__.py @@ -375,8 +375,10 @@ class UpstreamSource(object): Guess the package name and version from the filename of an upstream archive. - @param extra_regex: extra regular expression to check - @type extra_regex: raw C{string} + @param extra_regex: additional regex to apply, needs a 'package' and a + 'version' group + @return: (package name, version) or None. + @rtype: tuple >>> UpstreamSource('foo-bar_0.2.orig.tar.gz').guess_version() ('foo-bar', '0.2') @@ -405,17 +407,9 @@ class UpstreamSource(object): ('foo-bar', '0.2') >>> UpstreamSource('foo-bar-0.2.tlz').guess_version() ('foo-bar', '0.2') - - @param extra_regex: additional regex to apply, needs a 'package' and a - 'version' group - @return: (package name, version) or None. - @rtype: tuple """ version_chars = r'[a-zA-Z\d\.\~\-\:\+]' - if self.is_dir(): - basename = os.path.basename(self.path) - else: - basename = parse_archive_filename(os.path.basename(self.path))[0] + basename = parse_archive_filename(os.path.basename(self.path))[0] version_filters = map ( lambda x: x % version_chars, ( # Debian upstream tarball: package_'.orig.tar.gz' -- cgit v1.2.3 From a8f89faa2eebe750f22e341ee54054ede084ec1c Mon Sep 17 00:00:00 2001 From: Markus Lehtonen Date: Fri, 23 Aug 2013 13:39:19 +0300 Subject: UpstreamSource: move version guessing logic to PkgPolicy PkgPolicy is more logical context, for example if guessing version from a plain filename and not a real file. Also, changes guess_version() to always return a tuple to simplify checking its return value. Signed-off-by: Markus Lehtonen --- gbp/pkg/__init__.py | 133 +++++++++++++++++++-------------------- gbp/scripts/import_orig.py | 2 +- tests/06_test_upstream_source.py | 6 ++ 3 files changed, 72 insertions(+), 69 deletions(-) diff --git a/gbp/pkg/__init__.py b/gbp/pkg/__init__.py index e5daa838..b926c789 100644 --- a/gbp/pkg/__init__.py +++ b/gbp/pkg/__init__.py @@ -139,6 +139,67 @@ class PkgPolicy(object): return True return False + @classmethod + def guess_upstream_src_version(cls, filename, extra_regex=r''): + """ + Guess the package name and version from the filename of an upstream + archive. + + @param filename: filename (archive or directory) from which to guess + @type filename: C{string} + @param extra_regex: additional regex to apply, needs a 'package' and a + 'version' group + @return: (package name, version) or ('', '') + @rtype: tuple + + >>> PkgPolicy.guess_upstream_src_version('foo-bar_0.2.orig.tar.gz') + ('foo-bar', '0.2') + >>> PkgPolicy.guess_upstream_src_version('foo-Bar_0.2.orig.tar.gz') + ('foo-Bar', '0.2.orig') + >>> PkgPolicy.guess_upstream_src_version('git-bar-0.2.tar.gz') + ('git-bar', '0.2') + >>> PkgPolicy.guess_upstream_src_version('git-bar-0.2-rc1.tar.gz') + ('git-bar', '0.2-rc1') + >>> PkgPolicy.guess_upstream_src_version('git-bar-0.2:~-rc1.tar.gz') + ('git-bar', '0.2:~-rc1') + >>> PkgPolicy.guess_upstream_src_version('git-Bar-0A2d:rc1.tar.bz2') + ('git-Bar', '0A2d:rc1') + >>> PkgPolicy.guess_upstream_src_version('git-1.tar.bz2') + ('git', '1') + >>> PkgPolicy.guess_upstream_src_version('kvm_87+dfsg.orig.tar.gz') + ('kvm', '87+dfsg') + >>> PkgPolicy.guess_upstream_src_version('foo-Bar-a.b.tar.gz') + ('', '') + >>> PkgPolicy.guess_upstream_src_version('foo-bar_0.2.orig.tar.xz') + ('foo-bar', '0.2') + >>> PkgPolicy.guess_upstream_src_version('foo-bar_0.2.tar.gz') + ('foo-bar', '0.2') + >>> PkgPolicy.guess_upstream_src_version('foo-bar_0.2.orig.tar.lzma') + ('foo-bar', '0.2') + >>> PkgPolicy.guess_upstream_src_version('foo-bar-0.2.zip') + ('foo-bar', '0.2') + >>> PkgPolicy.guess_upstream_src_version('foo-bar-0.2.tlz') + ('foo-bar', '0.2') + """ + version_chars = r'[a-zA-Z\d\.\~\-\:\+]' + basename = parse_archive_filename(os.path.basename(filename))[0] + + version_filters = map ( lambda x: x % version_chars, + ( # Debian upstream tarball: package_'.orig.tar.gz' + r'^(?P[a-z\d\.\+\-]+)_(?P%s+)\.orig', + # Upstream 'package-.tar.gz' + # or Debian native 'package_.tar.gz' + # or directory 'package-': + r'^(?P[a-zA-Z\d\.\+\-]+)(-|_)(?P[0-9]%s*)')) + if extra_regex: + version_filters = extra_regex + version_filters + + for filter in version_filters: + m = re.match(filter, basename) + if m: + return (m.group('package'), m.group('version')) + return ('', '') + @staticmethod def has_orig(orig_file, dir): "Check if orig tarball exists in dir" @@ -247,24 +308,12 @@ class UpstreamSource(object): @property def archive_fmt(self): - """ - >>> UpstreamSource('foo/bar.tar.gz').archive_fmt - 'tar' - >>> UpstreamSource('foo.bar.zip').archive_fmt - 'zip' - >>> UpstreamSource('foo.bar.baz').archive_fmt - """ + """Archive format of the sources, e.g. 'tar'""" return self._archive_fmt @property def compression(self): - """ - >>> UpstreamSource('foo/bar.tar.gz').compression - 'gzip' - >>> UpstreamSource('foo.bar.zip').compression - >>> UpstreamSource('foo.bz2').compression - 'bzip2' - """ + """Compression format of the sources, e.g. 'gzip'""" return self._compression def unpack(self, dir, filters=[]): @@ -371,57 +420,5 @@ class UpstreamSource(object): return [ args[1][-1] for args in compressor_opts.items() ] def guess_version(self, extra_regex=r''): - """ - Guess the package name and version from the filename of an upstream - archive. - - @param extra_regex: additional regex to apply, needs a 'package' and a - 'version' group - @return: (package name, version) or None. - @rtype: tuple - - >>> UpstreamSource('foo-bar_0.2.orig.tar.gz').guess_version() - ('foo-bar', '0.2') - >>> UpstreamSource('foo-Bar_0.2.orig.tar.gz').guess_version() - ('foo-Bar', '0.2.orig') - >>> UpstreamSource('git-bar-0.2.tar.gz').guess_version() - ('git-bar', '0.2') - >>> UpstreamSource('git-bar-0.2-rc1.tar.gz').guess_version() - ('git-bar', '0.2-rc1') - >>> UpstreamSource('git-bar-0.2:~-rc1.tar.gz').guess_version() - ('git-bar', '0.2:~-rc1') - >>> UpstreamSource('git-Bar-0A2d:rc1.tar.bz2').guess_version() - ('git-Bar', '0A2d:rc1') - >>> UpstreamSource('git-1.tar.bz2').guess_version() - ('git', '1') - >>> UpstreamSource('kvm_87+dfsg.orig.tar.gz').guess_version() - ('kvm', '87+dfsg') - >>> UpstreamSource('foo-Bar-a.b.tar.gz').guess_version() - >>> UpstreamSource('foo-bar_0.2.orig.tar.xz').guess_version() - ('foo-bar', '0.2') - >>> UpstreamSource('foo-bar_0.2.tar.gz').guess_version() - ('foo-bar', '0.2') - >>> UpstreamSource('foo-bar_0.2.orig.tar.lzma').guess_version() - ('foo-bar', '0.2') - >>> UpstreamSource('foo-bar-0.2.zip').guess_version() - ('foo-bar', '0.2') - >>> UpstreamSource('foo-bar-0.2.tlz').guess_version() - ('foo-bar', '0.2') - """ - version_chars = r'[a-zA-Z\d\.\~\-\:\+]' - basename = parse_archive_filename(os.path.basename(self.path))[0] - - version_filters = map ( lambda x: x % version_chars, - ( # Debian upstream tarball: package_'.orig.tar.gz' - r'^(?P[a-z\d\.\+\-]+)_(?P%s+)\.orig', - # Upstream 'package-.tar.gz' - # or Debian native 'package_.tar.gz' - # or directory 'package-': - r'^(?P[a-zA-Z\d\.\+\-]+)(-|_)(?P[0-9]%s*)')) - if extra_regex: - version_filters = extra_regex + version_filters - - for filter in version_filters: - m = re.match(filter, basename) - if m: - return (m.group('package'), m.group('version')) + return self._pkg_policy.guess_upstream_src_version(self.path, + extra_regex) diff --git a/gbp/scripts/import_orig.py b/gbp/scripts/import_orig.py index 23c0921a..8372e5e2 100644 --- a/gbp/scripts/import_orig.py +++ b/gbp/scripts/import_orig.py @@ -81,7 +81,7 @@ def upstream_import_commit_msg(options, version): def detect_name_and_version(repo, source, options): # Guess defaults for the package name and version from the # original tarball. - (guessed_package, guessed_version) = source.guess_version() or ('', '') + guessed_package, guessed_version = source.guess_version() # Try to find the source package name try: diff --git a/tests/06_test_upstream_source.py b/tests/06_test_upstream_source.py index bf4baa19..b5989725 100644 --- a/tests/06_test_upstream_source.py +++ b/tests/06_test_upstream_source.py @@ -62,6 +62,9 @@ class TestTar(unittest.TestCase): self.assertEqual(repacked.is_orig(), True) self.assertEqual(repacked.is_tarball(), True) self.assertEqual(repacked.is_dir(), False) + self.assertEqual(repacked.guess_version(), ('gbp', '0.1')) + self.assertEqual(repacked.archive_fmt, 'tar') + self.assertEqual(repacked.compression, 'bzip2') self._check_tar(repacked, ["gbp/errors.py", "gbp/__init__.py"]) def test_pack_filtered(self): @@ -103,6 +106,9 @@ class TestZip(unittest.TestCase): self.assertEqual(source.is_tarball(), False) self.assertEqual(source.is_dir(), False) self.assertEqual(source.unpacked, None) + self.assertEqual(source.guess_version(), ('gbp', '0.1')) + self.assertEqual(source.archive_fmt, 'zip') + self.assertEqual(source.compression, None) source.unpack(str(self.tmpdir)) self.assertNotEqual(source.unpacked, None) -- cgit v1.2.3 From 7bdc489da3e84bfe66383f14a725e3e3145579a4 Mon Sep 17 00:00:00 2001 From: Markus Lehtonen Date: Fri, 23 Aug 2013 14:01:39 +0300 Subject: UpstreamSource: store the absolute path This is more robust and reliable, e.g. in case cwd is changed. Signed-off-by: Markus Lehtonen --- gbp/pkg/__init__.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/gbp/pkg/__init__.py b/gbp/pkg/__init__.py index b926c789..f14a0b05 100644 --- a/gbp/pkg/__init__.py +++ b/gbp/pkg/__init__.py @@ -252,7 +252,7 @@ class UpstreamSource(object): self._orig = False self._tarball = False self._pkg_policy = pkg_policy - self._path = name + self._path = os.path.abspath(name) self.unpacked = unpacked self._filename_base, \ self._archive_fmt, \ -- cgit v1.2.3 From 45b0ea49dee0732fe07435b5d2394b0c305d7e19 Mon Sep 17 00:00:00 2001 From: Markus Lehtonen Date: Mon, 13 Jan 2014 18:39:05 +0200 Subject: tests: test find_source() with unittest Change doctests to unittests in order to have more flexibility in testing. Signed-off-by: Markus Lehtonen --- gbp/scripts/import_orig.py | 15 ----------- tests/test_import_orig.py | 64 ++++++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 64 insertions(+), 15 deletions(-) create mode 100644 tests/test_import_orig.py diff --git a/gbp/scripts/import_orig.py b/gbp/scripts/import_orig.py index 8372e5e2..e5b0419d 100644 --- a/gbp/scripts/import_orig.py +++ b/gbp/scripts/import_orig.py @@ -127,21 +127,6 @@ def find_source(use_uscan, args): @return: upstream source filename or None if nothing to import @rtype: string @raise GbpError: raised on all detected errors - - >>> find_source(False, ['too', 'much']) - Traceback (most recent call last): - ... - GbpError: More than one archive specified. Try --help. - >>> find_source(False, []) - Traceback (most recent call last): - ... - GbpError: No archive to import specified. Try --help. - >>> find_source(True, ['tarball']) - Traceback (most recent call last): - ... - GbpError: you can't pass both --uscan and a filename. - >>> find_source(False, ['tarball']).path - 'tarball' """ if use_uscan: if args: diff --git a/tests/test_import_orig.py b/tests/test_import_orig.py new file mode 100644 index 00000000..ce697c03 --- /dev/null +++ b/tests/test_import_orig.py @@ -0,0 +1,64 @@ +# vim: set fileencoding=utf-8 : +# +# (C) 2013 Intel Corporation +# This program is free software; you can redistribute it and/or modify +# it under the terms of the GNU General Public License as published by +# the Free Software Foundation; either version 2 of the License, or +# (at your option) any later version. +# +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with this program; if not, write to the Free Software +# Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA +"""Test import-orig functions""" +from . import context + +import os +import tarfile +import unittest + +from gbp.errors import GbpError +from gbp.scripts.import_orig import find_source + + +class TestImportOrigBase(unittest.TestCase): + """Base class for handling context""" + @classmethod + def setup_class(cls): + """Class set-up, run only once""" + cls._tmpdir = str(context.new_tmpdir(__name__)) + + @classmethod + def teardown_class(cls): + """Class teardown, run only once""" + context.teardown() + + +class TestFindSource(TestImportOrigBase): + """Test the Debian-specific find_source() function""" + + def test_failure(self): + """Test failure modes""" + with self.assertRaisesRegexp(GbpError, + "More than one archive specified"): + find_source(False, ['too', 'much']) + + with self.assertRaisesRegexp(GbpError, + "No archive to import specified"): + find_source(False, []) + + with self.assertRaisesRegexp(GbpError, + "you can't pass both --uscan and a filename"): + find_source(True, ['tarball']) + + def test_success(self): + """Successfully get source archive""" + tar_fn = 'tarball.tar' + # Create dummy (empty) tarball + tarfile.open(tar_fn, 'w' ).close() + self.assertEqual(os.path.abspath(tar_fn), + find_source(False, [tar_fn]).path) -- cgit v1.2.3 From e969596f97043d7cca08b00bac1b877db03c9241 Mon Sep 17 00:00:00 2001 From: Markus Lehtonen Date: Fri, 23 Aug 2013 14:04:12 +0300 Subject: UpstreamSource: check that the sources exist Signed-off-by: Markus Lehtonen --- gbp/pkg/__init__.py | 2 ++ 1 file changed, 2 insertions(+) diff --git a/gbp/pkg/__init__.py b/gbp/pkg/__init__.py index f14a0b05..dd8735af 100644 --- a/gbp/pkg/__init__.py +++ b/gbp/pkg/__init__.py @@ -253,6 +253,8 @@ class UpstreamSource(object): self._tarball = False self._pkg_policy = pkg_policy self._path = os.path.abspath(name) + if not os.path.exists(self._path): + raise GbpError('UpstreamSource: unable to find %s' % self._path) self.unpacked = unpacked self._filename_base, \ self._archive_fmt, \ -- cgit v1.2.3 From e5ff67f24351feb71417a0de673170c591f9acb1 Mon Sep 17 00:00:00 2001 From: Markus Lehtonen Date: Thu, 22 Aug 2013 16:24:13 +0300 Subject: UpstreamSource: implement prefix guessing MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Add a new attribure 'prefix', i.e. the "leading directory name" in an archive. For example, this usually is '-' in release tarballs. Signed-off-by: Markus Lehtonen Signed-off-by: Łukasz Stelmach --- gbp/deb/upstreamsource.py | 5 ++- gbp/pkg/__init__.py | 89 ++++++++++++++++++++++++++++++++++------ tests/06_test_upstream_source.py | 6 ++- 3 files changed, 84 insertions(+), 16 deletions(-) diff --git a/gbp/deb/upstreamsource.py b/gbp/deb/upstreamsource.py index 7eb555ae..6d1bc60d 100644 --- a/gbp/deb/upstreamsource.py +++ b/gbp/deb/upstreamsource.py @@ -22,7 +22,8 @@ from gbp.deb.policy import DebianPkgPolicy class DebianUpstreamSource(UpstreamSource): """Upstream source class for Debian""" - def __init__(self, name, unpacked=None): + def __init__(self, name, unpacked=None, **kwargs): super(DebianUpstreamSource, self).__init__(name, unpacked, - DebianPkgPolicy) + DebianPkgPolicy, + **kwargs) diff --git a/gbp/pkg/__init__.py b/gbp/pkg/__init__.py index dd8735af..4759e3ea 100644 --- a/gbp/pkg/__init__.py +++ b/gbp/pkg/__init__.py @@ -20,6 +20,9 @@ import os import re import glob +import stat +import subprocess +import zipfile import gbp.command_wrappers as gbpc from gbp.errors import GbpError @@ -248,7 +251,7 @@ class UpstreamSource(object): @cvar _unpacked: path to the unpacked source tree @type _unpacked: string """ - def __init__(self, name, unpacked=None, pkg_policy=PkgPolicy): + def __init__(self, name, unpacked=None, pkg_policy=PkgPolicy, prefix=None): self._orig = False self._tarball = False self._pkg_policy = pkg_policy @@ -259,6 +262,9 @@ class UpstreamSource(object): self._filename_base, \ self._archive_fmt, \ self._compression = parse_archive_filename(os.path.basename(self.path)) + self._prefix = prefix + if self._prefix is None: + self._determine_prefix() self._check_orig() if self.is_dir(): @@ -308,6 +314,68 @@ class UpstreamSource(object): def path(self): return self._path.rstrip('/') + + @staticmethod + def _get_topdir_files(file_list): + """Parse content of the top directory from a file list + + >>> UpstreamSource._get_topdir_files([]) + set([]) + >>> UpstreamSource._get_topdir_files([('-', 'foo/bar')]) + set([('d', 'foo')]) + >>> UpstreamSource._get_topdir_files([('d', 'foo/'), ('-', 'foo/bar')]) + set([('d', 'foo')]) + >>> UpstreamSource._get_topdir_files([('d', 'foo'), ('-', 'foo/bar')]) + set([('d', 'foo')]) + >>> UpstreamSource._get_topdir_files([('-', 'fob'), ('d', 'foo'), ('d', 'foo/bar'), ('-', 'foo/bar/baz')]) + set([('-', 'fob'), ('d', 'foo')]) + >>> UpstreamSource._get_topdir_files([('-', './foo/bar')]) + set([('d', 'foo')]) + >>> UpstreamSource._get_topdir_files([('-', 'foo/bar'), ('-', '.foo/bar')]) + set([('d', '.foo'), ('d', 'foo')]) + """ + topdir_files = set() + for typ, path in file_list: + split = re.sub('^(?:./|../)*', '', path).split('/') + if len(split) == 1: + topdir_files.add((typ, path)) + else: + topdir_files.add(('d', split[0])) + return topdir_files + + def _determine_prefix(self): + """Determine the prefix, i.e. the "leading directory name""" + self._prefix = '' + if self.is_dir(): + # For directories we presume that the prefix is just the dirname + self._prefix = os.path.basename(self.path.rstrip('/')) + else: + files = [] + if self._archive_fmt == 'zip': + archive = zipfile.ZipFile(self.path) + for info in archive.infolist(): + typ = 'd' if stat.S_ISDIR(info.external_attr >> 16) else '?' + files.append((typ, info.filename)) + elif self._archive_fmt == 'tar': + popen = subprocess.Popen(['tar', '-t', '-v', '-f', self.path], + stdout=subprocess.PIPE) + out, _err = popen.communicate() + if popen.returncode: + raise GbpError("Listing tar archive content failed") + for line in out.splitlines(): + fields = line.split(None, 5) + files.append((fields[0][0], fields[-1])) + else: + raise GbpError("Unsupported archive format %s, unable to " + "determine prefix for '%s'" % + (self._archive_fmt, self.path)) + # Determine prefix from the archive content + topdir_files = self._get_topdir_files(files) + if len(topdir_files) == 1: + typ, name = topdir_files.pop() + if typ == 'd': + self._prefix = name + @property def archive_fmt(self): """Archive format of the sources, e.g. 'tar'""" @@ -318,6 +386,11 @@ class UpstreamSource(object): """Compression format of the sources, e.g. 'gzip'""" return self._compression + @property + def prefix(self): + """Prefix, i.e. the 'leading directory name' of the sources""" + return self._prefix + def unpack(self, dir, filters=[]): """ Unpack packed upstream sources into a given directory @@ -333,7 +406,8 @@ class UpstreamSource(object): raise GbpError("Filters must be a list") self._unpack_archive(dir, filters) - self.unpacked = self._unpacked_toplevel(dir) + src_dir = os.path.join(dir, self._prefix) + self.unpacked = src_dir if os.path.isdir(src_dir) else dir def _unpack_archive(self, dir, filters): """ @@ -351,17 +425,6 @@ class UpstreamSource(object): except gbpc.CommandExecFailed: raise GbpError("Unpacking of %s failed" % self.path) - def _unpacked_toplevel(self, dir): - """unpacked archives can contain a leading directory or not""" - unpacked = glob.glob('%s/*' % dir) - unpacked.extend(glob.glob("%s/.*" % dir)) # include hidden files and folders - # Check that dir contains nothing but a single folder: - if len(unpacked) == 1 and os.path.isdir(unpacked[0]): - return unpacked[0] - else: - # We can determine "no prefix" from this - return os.path.join(dir, ".") - def _unpack_tar(self, dir, filters): """ Unpack a tarball to I{dir} applying a list of I{filters}. Leave the diff --git a/tests/06_test_upstream_source.py b/tests/06_test_upstream_source.py index b5989725..c6df6f14 100644 --- a/tests/06_test_upstream_source.py +++ b/tests/06_test_upstream_source.py @@ -28,6 +28,7 @@ class TestDir(unittest.TestCase): self.assertEqual(source.path, self.upstream_dir) self.assertEqual(source.unpacked, self.upstream_dir) self.assertEqual(source.guess_version(), ('test', '1.0')) + self.assertEqual(source.prefix, 'test-1.0') def tearDown(self): context.teardown() @@ -65,6 +66,7 @@ class TestTar(unittest.TestCase): self.assertEqual(repacked.guess_version(), ('gbp', '0.1')) self.assertEqual(repacked.archive_fmt, 'tar') self.assertEqual(repacked.compression, 'bzip2') + self.assertEqual(repacked.prefix, 'gbp') self._check_tar(repacked, ["gbp/errors.py", "gbp/__init__.py"]) def test_pack_filtered(self): @@ -94,7 +96,8 @@ class TestZip(unittest.TestCase): self.zipfile = self.tmpdir.join("gbp-0.1.zip") z = zipfile.ZipFile(self.zipfile, "w") for f in glob.glob(os.path.join(context.projectdir, "gbp/*.py")): - z.write(f, f, zipfile.ZIP_DEFLATED) + arcname = os.path.relpath(f, context.projectdir) + z.write(f, arcname, zipfile.ZIP_DEFLATED) z.close() def tearDown(self): @@ -109,6 +112,7 @@ class TestZip(unittest.TestCase): self.assertEqual(source.guess_version(), ('gbp', '0.1')) self.assertEqual(source.archive_fmt, 'zip') self.assertEqual(source.compression, None) + self.assertEqual(source.prefix, 'gbp') source.unpack(str(self.tmpdir)) self.assertNotEqual(source.unpacked, None) -- cgit v1.2.3 From 1316d56c0e91d26d50fbdfc09d1a2dc0bc5260c9 Mon Sep 17 00:00:00 2001 From: Markus Lehtonen Date: Thu, 6 Jun 2013 15:21:48 +0300 Subject: UpstreamSource.pack: reuse unpacked dir if no filter is used Set the unpacked attribute to the source dir if the content is not filtered. Signed-off-by: Markus Lehtonen --- gbp/pkg/__init__.py | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/gbp/pkg/__init__.py b/gbp/pkg/__init__.py index 4759e3ea..ffaf0fba 100644 --- a/gbp/pkg/__init__.py +++ b/gbp/pkg/__init__.py @@ -478,7 +478,11 @@ class UpstreamSource(object): except gbpc.CommandExecFailed: # repackArchive already printed an error raise GbpError - return type(self)(newarchive) + new = type(self)(newarchive) + # Reuse the same unpacked dir if the content matches + if not filters: + new.unpacked = self.unpacked + return new @staticmethod def known_compressions(): -- cgit v1.2.3 From 536df9ab1c21cdffa3f7c32eed0bbbbf38409f5b Mon Sep 17 00:00:00 2001 From: Markus Lehtonen Date: Thu, 6 Jun 2013 15:19:37 +0300 Subject: UpstreamSource.unpack: return UpstreamSource instance Trying to keep UpstreamSource in consistent state so that unpacked and packed sources are kept in sync. Signed-off-by: Markus Lehtonen --- gbp/pkg/__init__.py | 14 +++++++++++--- gbp/scripts/common/import_orig.py | 2 +- gbp/scripts/import_dsc.py | 2 +- gbp/scripts/import_orig.py | 2 +- 4 files changed, 14 insertions(+), 6 deletions(-) diff --git a/gbp/pkg/__init__.py b/gbp/pkg/__init__.py index ffaf0fba..f02caf01 100644 --- a/gbp/pkg/__init__.py +++ b/gbp/pkg/__init__.py @@ -405,19 +405,27 @@ class UpstreamSource(object): if type(filters) != type([]): raise GbpError("Filters must be a list") - self._unpack_archive(dir, filters) + if self._unpack_archive(dir, filters): + ret = type(self)(dir, prefix=self._prefix) + else: + ret = self src_dir = os.path.join(dir, self._prefix) - self.unpacked = src_dir if os.path.isdir(src_dir) else dir + ret.unpacked = src_dir if os.path.isdir(src_dir) else dir + return ret def _unpack_archive(self, dir, filters): """ - Unpack packed upstream sources into a given directory. + Unpack packed upstream sources into a given directory. Return True if + the output was filtered, otherwise False. """ ext = os.path.splitext(self.path)[1] if ext in [ ".zip", ".xpi" ]: self._unpack_zip(dir) else: self._unpack_tar(dir, filters) + if filters: + return True + return False def _unpack_zip(self, dir): try: diff --git a/gbp/scripts/common/import_orig.py b/gbp/scripts/common/import_orig.py index 80807a62..f110216a 100644 --- a/gbp/scripts/common/import_orig.py +++ b/gbp/scripts/common/import_orig.py @@ -114,6 +114,6 @@ def repack_source(source, new_name, unpack_dir, filters, new_prefix=None): if source.is_tarball(): # the tarball was filtered on unpack repacked.unpacked = source.unpacked else: # otherwise unpack the generated tarball get a filtered tree - repacked.unpack(unpack_dir, filters) + repacked.unpack(unpack_dir) return repacked diff --git a/gbp/scripts/import_dsc.py b/gbp/scripts/import_dsc.py index ce97fcb0..91c4745e 100644 --- a/gbp/scripts/import_dsc.py +++ b/gbp/scripts/import_dsc.py @@ -329,7 +329,7 @@ def main(argv): dirs['tmp'] = os.path.abspath(tempfile.mkdtemp(dir='..')) upstream = DebianUpstreamSource(src.tgz) - upstream.unpack(dirs['tmp'], options.filters) + upstream = upstream.unpack(dirs['tmp'], options.filters) format = [(options.upstream_tag, "Upstream"), (options.debian_tag, "Debian")][src.native] tag = repo.version_to_tag(format[0], src.upstream_version) diff --git a/gbp/scripts/import_orig.py b/gbp/scripts/import_orig.py index e5b0419d..e4df29e4 100644 --- a/gbp/scripts/import_orig.py +++ b/gbp/scripts/import_orig.py @@ -305,7 +305,7 @@ def main(argv): if not source.is_dir(): unpack_dir = tempfile.mkdtemp(prefix='unpack', dir=tmpdir) - source.unpack(unpack_dir, options.filters) + source = source.unpack(unpack_dir, options.filters) gbp.log.debug("Unpacked '%s' to '%s'" % (source.path, source.unpacked)) if orig_needs_repack(source, options): -- cgit v1.2.3 From c203f35e994dd686cc63e6217ad4b0151faacba5 Mon Sep 17 00:00:00 2001 From: Markus Lehtonen Date: Mon, 26 Aug 2013 10:22:00 +0300 Subject: import-orig: new function for filtering/re-packing sources Introduces a new function prepare_sources() that prepares upstream sources for importing into upstream branch and pristine-tar. That includes unpacking, filtering and re-packing sources. What somewhat complicates the logic is that it tries to avoid excess unpacking/packing of the sources. Also fixes the unpacking / filtering / repacking logic which was broken with some parameter combinations. Signed-off-by: Markus Lehtonen --- gbp/scripts/common/import_orig.py | 126 +++++++++++++++++++++++++++++++++++++- tests/test_import_orig.py | 126 ++++++++++++++++++++++++++++++++++++++ tests/testutils.py | 22 +++++++ 3 files changed, 273 insertions(+), 1 deletion(-) diff --git a/gbp/scripts/common/import_orig.py b/gbp/scripts/common/import_orig.py index f110216a..964e400a 100644 --- a/gbp/scripts/common/import_orig.py +++ b/gbp/scripts/common/import_orig.py @@ -19,8 +19,9 @@ """Common functionality for import-orig scripts""" import os import tempfile + import gbp.command_wrappers as gbpc -from gbp.pkg import UpstreamSource +from gbp.pkg import parse_archive_filename import gbp.log # Try to import readline, since that will cause raw_input to get fancy @@ -117,3 +118,126 @@ def repack_source(source, new_name, unpack_dir, filters, new_prefix=None): repacked.unpack(unpack_dir) return repacked + +def prepare_pristine_tar(source, pkg_name, pkg_version, pristine_commit_name, + filters=None, prefix=None, tmpdir=None): + """ + Prepare the upstream sources for pristine-tar import + + @param source: original upstream sources + @type source: C{UpstreamSource} + @param pkg_name: package name + @type pkg_name: C{str} + @param pkg_version: upstream version of the package + @type pkg_version: C{str} + @param pristine_commit_name: archive filename to commit to pristine-tar + @type pristine_commit_name: C{str} or C{None} + @param filters: filter to exclude files + @type filters: C{list} of C{str} or C{None} + @param prefix: prefix (i.e. leading directory of files) to use in + pristine-tar, set to C{None} to not mangle orig archive + @type prefix: C{str} or C{None} + @param tmpdir: temporary working dir (cleanup left to caller) + @type tmpdir: C{str} + @return: prepared source archive + @rtype: C{UpstreamSource} + """ + need_repack = False + if source.is_dir(): + if prefix is None: + prefix = '%s-%s' % (pkg_name, pkg_version) + gbp.log.info("Using guessed prefix '%s/' for pristine-tar" % prefix) + need_repack = True + else: + if prefix is not None and prefix == source.prefix: + prefix = None + comp = parse_archive_filename(pristine_commit_name)[2] + if filters or prefix is not None or source.compression != comp: + if not source.unpacked: + unpack_dir = tempfile.mkdtemp(prefix='pristine_unpack_', + dir=tmpdir) + source.unpack(unpack_dir) + need_repack = True + pristine_path = os.path.join(tmpdir, pristine_commit_name) + if need_repack: + gbp.log.debug("Packing '%s' from '%s' for pristine-tar" % + (pristine_path, source.unpacked)) + pristine = source.pack(pristine_path, filters, prefix) + else: + # Just create symlink for mangling the pristine tarball name + os.symlink(source.path, pristine_path) + pristine = source.__class__(pristine_path) + + return pristine + + +def prepare_sources(source, pkg_name, pkg_version, pristine_commit_name, + filters, filter_pristine, prefix, tmpdir): + """ + Prepare upstream sources for importing + + Unpack, filter and repack sources for importing to git and to pristine-tar. + + @param source: original upstream sources + @type source: C{UpstreamSource} + @param pkg_name: package name + @type pkg_name: C{str} + @param pkg_version: upstream version of the package + @type pkg_version: C{str} + @param pristine_commit_name: archive filename to commit to pristine-tar + @type pristine_commit_name: C{str} or C{None} + @param filters: filter to exclude files + @type filters: C{list} of C{str} + @param filter_pristine: filter pristine-tar, too + @type filter_pristine: C{bool} + @param prefix: prefix (i.e. leading directory of files) to use in + pristine-tar, set to C{None} to not mangle orig archive + @type prefix: C{str} or C{None} + @param tmpdir: temporary working dir (cleanup left to caller) + @type tmpdir: C{str} + @return: path to prepared source tree and tarball to commit to pristine-tar + @rtype: C{tuple} of C{str} + """ + pristine = None + # Determine parameters for pristine tar + pristine_filters = filters if filters and filter_pristine else None + pristine_prefix = None + if prefix is not None and prefix != 'auto': + prefix_subst = {'name': pkg_name, + 'version': pkg_version, + 'upstreamversion': pkg_version} + pristine_prefix = prefix % prefix_subst + # Handle unpacked sources, i.e. importing a directory + if source.is_dir(): + if pristine_commit_name: + gbp.log.warn('Preparing unpacked sources for pristine-tar') + pristine = prepare_pristine_tar(source, pkg_name, pkg_version, + pristine_commit_name, + pristine_filters, pristine_prefix, + tmpdir) + if filters: + # Re-use sources packed for pristine-tar, if available + if pristine: + packed = pristine + else: + packed_fn = tempfile.mkstemp(prefix="packed_", dir=tmpdir, + suffix='.tar')[1] + gbp.log.debug("Packing '%s' to '%s'" % (source.path, packed_fn)) + packed = source.pack(packed_fn) + unpack_dir = tempfile.mkdtemp(prefix='filtered_', dir=tmpdir) + filtered = packed.unpack(unpack_dir, filters) + else: + filtered = source + # Handle source archives + else: + unpack_dir = tempfile.mkdtemp(prefix='filtered_', dir=tmpdir) + gbp.log.debug("Unpacking '%s' to '%s'" % (source.path, unpack_dir)) + filtered = source.unpack(unpack_dir, filters) + if pristine_commit_name: + pristine = prepare_pristine_tar(source, pkg_name, pkg_version, + pristine_commit_name, + pristine_filters, pristine_prefix, + tmpdir) + pristine_path = pristine.path if pristine else '' + return (filtered.unpacked, pristine_path) + diff --git a/tests/test_import_orig.py b/tests/test_import_orig.py index ce697c03..d596d1df 100644 --- a/tests/test_import_orig.py +++ b/tests/test_import_orig.py @@ -17,12 +17,17 @@ """Test import-orig functions""" from . import context +import glob import os import tarfile +import tempfile import unittest from gbp.errors import GbpError +from gbp.pkg import UpstreamSource +from gbp.scripts.common.import_orig import prepare_sources from gbp.scripts.import_orig import find_source +from tests.testutils import ls_dir, ls_tar class TestImportOrigBase(unittest.TestCase): @@ -62,3 +67,124 @@ class TestFindSource(TestImportOrigBase): tarfile.open(tar_fn, 'w' ).close() self.assertEqual(os.path.abspath(tar_fn), find_source(False, [tar_fn]).path) + + +class TestPrepareSources(TestImportOrigBase): + """Test the prepare_sources() function""" + test_pkg_name = 'test' + test_pkg_ver = '1.0' + + @staticmethod + def _create_test_sources(destdir): + """Create dummy source archives""" + destdir = os.path.abspath(destdir) + origs = {} + + # "Normall" gzipped tarball + archive_fn = os.path.join(destdir, 'test-1.0.tar.gz') + src_dir = os.path.join(context.projectdir, 'gbp') + tarobj = tarfile.open(archive_fn, mode='w:gz') + for fname in (glob.glob('%s/*.py' % src_dir) + + glob.glob('%s/pkg/*.py' % src_dir)): + arcname = 'test-1.0/' + os.path.relpath(fname, src_dir) + tarobj.add(fname, arcname=arcname) + tarobj.close() + origs['tar'] = archive_fn + + # Unpacked sources + tarobj = tarfile.open(origs['tar'], 'r') + tarobj.extractall(destdir) + tarobj.close() + origs['dir'] = os.path.join(destdir,'test-1.0') + return origs + + @classmethod + def setup_class(cls): + """Class set-up, run only once""" + super(TestPrepareSources, cls).setup_class() + # Different source archives + cls._origs = cls._create_test_sources(cls._tmpdir) + + def test_dir(self): + """Basic test for unpacked sources, no filtering etc""" + tmpdir = tempfile.mkdtemp(dir=self._tmpdir, prefix='dir_basic_') + source = UpstreamSource(self._origs['dir']) + orig, prist = prepare_sources(source, 'test', '1.0', None, + None, False, None, tmpdir) + self.assertEqual(ls_dir(self._origs['dir']), ls_dir(orig)) + self.assertEqual(prist, '') + + def test_dir_filter(self): + """Test filtering of unpacked sources""" + tmpdir = tempfile.mkdtemp(dir=self._tmpdir, prefix='dir_filter_') + source = UpstreamSource(self._origs['dir']) + orig, prist = prepare_sources(source, 'test', '1.0', None, + ['pkg'], False, None, tmpdir) + orig_filt_ref = set([fname for fname in ls_dir(self._origs['dir']) + if not fname.startswith('pkg')]) + self.assertEqual(orig_filt_ref, ls_dir(orig)) + self.assertEqual(prist, '') + + def test_dir_pristine_nofilter(self): + """Test filtering of unpacked sources, not filtering pristine-tar""" + tmpdir = tempfile.mkdtemp(dir=self._tmpdir, prefix='dir_filter2_') + source = UpstreamSource(self._origs['dir']) + orig, prist = prepare_sources(source, 'test', '1.0', 'test.tar.gz', + ['pkg'], False, None, tmpdir) + src_ls = ls_dir(self._origs['dir']) + orig_filt_ref = set([fname for fname in src_ls + if not fname.startswith('pkg')]) + prist_ref = set(['test-1.0/%s' % fname for fname in src_ls] + + ['test-1.0']) + self.assertEqual(orig_filt_ref, ls_dir(orig)) + self.assertEqual(prist_ref, ls_tar(prist)) + + def test_dir_pristine_filter(self): + """Test filtering pristine-tar and mangling prefix""" + tmpdir = tempfile.mkdtemp(dir=self._tmpdir, prefix='dir_filter3_') + source = UpstreamSource(self._origs['dir']) + orig, prist = prepare_sources(source, 'test', '1.0', 'test.tar.gz', + ['pkg'], True, 'newpref', tmpdir) + src_ls = ls_dir(self._origs['dir']) + orig_filt_ref = set([fname for fname in src_ls + if not fname.startswith('pkg')]) + prist_ref = set(['newpref/%s' % fname for fname in orig_filt_ref] + + ['newpref']) + self.assertEqual(orig_filt_ref, ls_dir(orig)) + self.assertEqual(prist_ref, ls_tar(prist)) + + def test_tar(self): + """Basic test for tarball sources, with pristine-tar""" + tmpdir = tempfile.mkdtemp(dir=self._tmpdir, prefix='tar_basic_') + source = UpstreamSource(self._origs['tar']) + orig, prist = prepare_sources(source, 'test', '1.0', 'test.tgz', + None, False, 'test-1.0', tmpdir) + src_ls = ls_tar(self._origs['tar']) + orig_ref = set([fname.replace('test-1.0/', '') for fname in src_ls + if fname != 'test-1.0']) + self.assertEqual(orig_ref, ls_dir(orig)) + self.assertEqual(src_ls, ls_tar(prist)) + + def test_tar_pristine_prefix(self): + """Test tarball import with prefix mangling""" + tmpdir = tempfile.mkdtemp(dir=self._tmpdir, prefix='tar_prefix_') + source = UpstreamSource(self._origs['tar']) + _orig, prist = prepare_sources(source, 'test', '1.0', 'test.tgz', + None, False, 'np', tmpdir) + src_ls = ls_tar(self._origs['tar']) + prist_ref = set([fname.replace('test-1.0', 'np') for fname in src_ls]) + self.assertEqual(prist_ref, ls_tar(prist)) + + def test_tar_filter_pristine_prefix(self): + """Filter tarball, pristine-tar prefix mangling but not filter""" + tmpdir = tempfile.mkdtemp(dir=self._tmpdir, prefix='tar_filter_') + source = UpstreamSource(self._origs['tar']) + orig, prist = prepare_sources(source, 'test', '1.0', 'test.tgz', + ['pkg'], False, 'newp', tmpdir) + src_ls = ls_tar(self._origs['tar']) + orig_ref = set([fname.replace('test-1.0/', '') for fname in src_ls + if fname != 'test-1.0' and not fname.startswith('test-1.0/pkg')]) + prist_ref = set([fname.replace('test-1.0', 'newp') for fname in src_ls]) + self.assertEqual(orig_ref, ls_dir(orig)) + self.assertEqual(prist_ref, ls_tar(prist)) + diff --git a/tests/testutils.py b/tests/testutils.py index e161dbe5..96a164da 100644 --- a/tests/testutils.py +++ b/tests/testutils.py @@ -5,6 +5,7 @@ from . import context import os import shutil import subprocess +import tarfile import tempfile import unittest @@ -113,3 +114,24 @@ def get_dch_default_urgency(): shutil.rmtree(tempdir) return urgency +def ls_dir(directory): + """List the contents of directory, recurse to subdirectories""" + contents = set() + for root, dirs, files in os.walk(directory): + prefix = '' + if root != directory: + prefix = os.path.relpath(root, directory) + '/' + contents.update(['%s%s' % (prefix, fname) for fname in files] + + ['%s%s' % (prefix, dname) for dname in dirs]) + return contents + +def ls_tar(tarball): + """List the contents of tar archive""" + tmpdir = tempfile.mkdtemp() + try: + tarobj = tarfile.open(tarball, 'r') + tarobj.extractall(tmpdir) + return ls_dir(tmpdir) + finally: + shutil.rmtree(tmpdir) + -- cgit v1.2.3 From e0324a9d8127b949b27fe2f1d0b4b4e76368ffda Mon Sep 17 00:00:00 2001 From: Markus Lehtonen Date: Wed, 14 Nov 2012 09:03:37 +0200 Subject: import-orig: rework sourcecode preparation and filtering Take in to use the newly added prepare_sources() function. Drop dead, unneeded code. Signed-off-by: Markus Lehtonen --- gbp/scripts/common/import_orig.py | 40 ------------- gbp/scripts/import_orig.py | 119 ++++++++++++-------------------------- 2 files changed, 37 insertions(+), 122 deletions(-) diff --git a/gbp/scripts/common/import_orig.py b/gbp/scripts/common/import_orig.py index 964e400a..adbfff5e 100644 --- a/gbp/scripts/common/import_orig.py +++ b/gbp/scripts/common/import_orig.py @@ -33,28 +33,6 @@ except ImportError: pass -def orig_needs_repack(upstream_source, options): - """ - Determine if the upstream sources needs to be repacked - - We repack if - 1. we want to filter out files and use pristine tar since we want - to make a filtered tarball available to pristine-tar - 2. when we don't have a suitable upstream tarball (e.g. zip archive or unpacked dir) - and want to use filters - 3. when we don't have a suitable upstream tarball (e.g. zip archive or unpacked dir) - and want to use pristine-tar - """ - if ((options.pristine_tar and options.filter_pristine_tar and len(options.filters) > 0)): - return True - elif not upstream_source.is_tarball(): - if len(options.filters): - return True - elif options.pristine_tar: - return True - return False - - def cleanup_tmp_tree(tree): """remove a tree of temporary files""" try: @@ -63,14 +41,6 @@ def cleanup_tmp_tree(tree): gbp.log.err("Removal of tmptree %s failed." % tree) -def is_link_target(target, link): - """does symlink link already point to target?""" - if os.path.exists(link): - if os.path.samefile(target, link): - return True - return False - - def ask_package_name(default, name_validator_func, err_msg): """ Ask the user for the source package name. @@ -109,16 +79,6 @@ def ask_package_version(default, ver_validator_func, err_msg): gbp.log.warn("\nNot a valid upstream version: '%s'.\n%s" % (version, err_msg)) -def repack_source(source, new_name, unpack_dir, filters, new_prefix=None): - """Repack the source tree""" - repacked = source.pack(new_name, filters, new_prefix) - if source.is_tarball(): # the tarball was filtered on unpack - repacked.unpacked = source.unpacked - else: # otherwise unpack the generated tarball get a filtered tree - repacked.unpack(unpack_dir) - return repacked - - def prepare_pristine_tar(source, pkg_name, pkg_version, pristine_commit_name, filters=None, prefix=None, tmpdir=None): """ diff --git a/gbp/scripts/import_orig.py b/gbp/scripts/import_orig.py index e4df29e4..dfc5e2ae 100644 --- a/gbp/scripts/import_orig.py +++ b/gbp/scripts/import_orig.py @@ -30,48 +30,10 @@ from gbp.deb.git import (GitRepositoryError, DebianGitRepository) from gbp.config import GbpOptionParserDebian, GbpOptionGroup, no_upstream_branch_msg from gbp.errors import GbpError import gbp.log -from gbp.scripts.common.import_orig import (orig_needs_repack, cleanup_tmp_tree, - ask_package_name, ask_package_version, - repack_source, is_link_target) - - -def prepare_pristine_tar(archive, pkg, version): - """ - Prepare the upstream source for pristine tar import. - - This checks if the upstream source is actually a tarball - and creates a symlink from I{archive} - to I{_.orig.tar.} so pristine-tar will - see the correct basename. - - @param archive: the upstream source's name - @type archive: C{str} - @param pkg: the source package's name - @type pkg: C{str} - @param version: the upstream version number - @type version: C{str} - @rtype: C{str} - """ - linked = False - if os.path.isdir(archive): - return None - - ext = os.path.splitext(archive)[1] - if ext in ['.tgz', '.tbz2', '.tlz', '.txz' ]: - ext = ".%s" % ext[2:] - - link = "../%s_%s.orig.tar%s" % (pkg, version, ext) - - if os.path.basename(archive) != os.path.basename(link): - try: - if not is_link_target(archive, link): - os.symlink(os.path.abspath(archive), link) - linked = True - except OSError as err: - raise GbpError("Cannot symlink '%s' to '%s': %s" % (archive, link, err[1])) - return (link, linked) - else: - return (archive, linked) +from gbp.pkg import compressor_opts +from gbp.scripts.common.import_orig import (cleanup_tmp_tree, ask_package_name, + ask_package_version, + prepare_sources) def upstream_import_commit_msg(options, version): @@ -157,19 +119,17 @@ def find_source(use_uscan, args): return archive -def repacked_tarball_name(source, name, version): - if source.is_orig(): - # Repacked orig tarball needs a different name since there's already - # one with that name - name = os.path.join( - os.path.dirname(source.path), - os.path.basename(source.path).replace(".tar", ".gbp.tar")) +def pristine_tarball_name(source, pkg_name, pkg_version): + if source.is_tarball(): + if source.compression: + comp_ext = '.' + compressor_opts[source.compression][1] + else: + comp_ext = '' else: - # Repacked sources or other archives get canonical name - name = os.path.join( - os.path.dirname(source.path), - "%s_%s.orig.tar.bz2" % (name, version)) - return name + # Need to repack and/or mangle filename if the archive is not + # pristine-tar-compatible -> we decide to create gz compressed tarball + comp_ext = '.gz' + return '%s_%s.orig.tar%s' % (pkg_name, pkg_version, comp_ext) def set_bare_repo_options(options): @@ -265,8 +225,6 @@ def parse_args(argv): def main(argv): ret = 0 tmpdir = tempfile.mkdtemp(dir='../') - pristine_orig = None - linked = False (options, args) = parse_args(argv) if not options: @@ -293,7 +251,7 @@ def main(argv): else: raise GbpError(no_upstream_branch_msg % options.upstream_branch) - (sourcepackage, version) = detect_name_and_version(repo, source, options) + (pkg_name, version) = detect_name_and_version(repo, source, options) (clean, out) = repo.is_clean() if not clean and not is_empty: @@ -303,24 +261,16 @@ def main(argv): if repo.bare: set_bare_repo_options(options) - if not source.is_dir(): - unpack_dir = tempfile.mkdtemp(prefix='unpack', dir=tmpdir) - source = source.unpack(unpack_dir, options.filters) - gbp.log.debug("Unpacked '%s' to '%s'" % (source.path, source.unpacked)) - - if orig_needs_repack(source, options): - gbp.log.debug("Filter pristine-tar: repacking '%s' from '%s'" % (source.path, source.unpacked)) - repack_dir = tempfile.mkdtemp(prefix='repack', dir=tmpdir) - repack_name = repacked_tarball_name(source, sourcepackage, version) - source = repack_source(source, repack_name, repack_dir, options.filters) - - (pristine_orig, linked) = prepare_pristine_tar(source.path, - sourcepackage, - version) + # Prepare sources for importing + pristine_name = pristine_tarball_name(source, pkg_name, version) + prepare_pristine = pristine_name if options.pristine_tar else None + unpacked_orig, pristine_orig = prepare_sources( + source, pkg_name, version, prepare_pristine, options.filters, + options.filter_pristine_tar, None, tmpdir) # Don't mess up our repo with git metadata from an upstream tarball try: - if os.path.isdir(os.path.join(source.unpacked, '.git/')): + if os.path.isdir(os.path.join(unpacked_orig, '.git/')): raise GbpError("The orig tarball contains .git metadata - giving up.") except OSError: pass @@ -332,7 +282,7 @@ def main(argv): gbp.log.info("Importing '%s' to branch '%s'%s..." % (source.path, upstream_branch, filter_msg)) - gbp.log.info("Source package is %s" % sourcepackage) + gbp.log.info("Source package is %s" % pkg_name) gbp.log.info("Upstream version is %s" % version) import_branch = [ options.upstream_branch, None ][is_empty] @@ -343,17 +293,14 @@ def main(argv): else: parents = None - commit = repo.commit_dir(source.unpacked, + commit = repo.commit_dir(unpacked_orig, msg=msg, branch=import_branch, other_parents=parents, create_missing_branch=options.create_missing_branches) - if options.pristine_tar: - if pristine_orig: - repo.pristine_tar.commit(pristine_orig, upstream_branch) - else: - gbp.log.warn("'%s' not an archive, skipping pristine-tar" % source.path) + if options.pristine_tar and pristine_orig: + repo.pristine_tar.commit(pristine_orig, upstream_branch) tag = repo.version_to_tag(options.upstream_tag, version) repo.create_tag(name=tag, @@ -389,6 +336,17 @@ def main(argv): if current_branch in [ options.upstream_branch, repo.pristine_tar_branch]: repo.force_head(current_branch, hard=True) + # Create symlink, if requested + if options.symlink_orig: + if source.is_tarball(): + link = os.path.join('..', pristine_name) + if not (os.path.exists(link) and + os.path.samefile(link, source.path)): + gbp.log.info('Creating symlink to %s' % source.path) + os.symlink(source.path, link) + else: + gbp.log.warn('Orig source not a tarball, not symlinked') + except (gbpc.CommandExecFailed, GitRepositoryError) as err: msg = err.__str__() if len(err.__str__()) else '' raise GbpError("Import of %s failed: %s" % (source.path, msg)) @@ -397,9 +355,6 @@ def main(argv): gbp.log.err(err) ret = 1 - if pristine_orig and linked and not options.symlink_orig: - os.unlink(pristine_orig) - if tmpdir: cleanup_tmp_tree(tmpdir) -- cgit v1.2.3 From bbbd618eaf6518f2f2bb2b1ac3909d180512dda8 Mon Sep 17 00:00:00 2001 From: Markus Lehtonen Date: Thu, 29 Aug 2013 10:37:56 +0300 Subject: tests.testutils: add ls_zip() helper For listing zip contents. Signed-off-by: Markus Lehtonen --- tests/testutils.py | 11 +++++++++++ 1 file changed, 11 insertions(+) diff --git a/tests/testutils.py b/tests/testutils.py index 96a164da..ce0c20c8 100644 --- a/tests/testutils.py +++ b/tests/testutils.py @@ -8,6 +8,7 @@ import subprocess import tarfile import tempfile import unittest +import zipfile import gbp.log import gbp.deb.git @@ -135,3 +136,13 @@ def ls_tar(tarball): finally: shutil.rmtree(tmpdir) +def ls_zip(archive): + """List the contents of zip file""" + tmpdir = tempfile.mkdtemp() + try: + zipobj = zipfile.ZipFile(archive, 'r') + zipobj.extractall(tmpdir) + return ls_dir(tmpdir) + finally: + shutil.rmtree(tmpdir) + -- cgit v1.2.3 From 89f5f0f03fb52994d192ee53afb1a3ee37904b09 Mon Sep 17 00:00:00 2001 From: Markus Lehtonen Date: Fri, 6 Jul 2012 09:58:06 +0300 Subject: config: read the right config if run from subdir A step towards being able to run GBP tools from subdirectories. Now expands '%(top_dir)s' and '%(git_dir)s' in config file path to root of the working directory and git metadata directory, respectively. Also, adds a new method _read_config_file() in preparation for supporting per-tree config files. Fixes tests.test_Config: currently the only correct way to define the config file(s) to be parsed is by using the GBP_CONF_FILES environment variable. Signed-off-by: Markus Lehtonen --- gbp/config.py | 54 +++++++++++++++++++++++++++++++++++----------- gbp/scripts/import_dscs.py | 3 +-- tests/test_Config.py | 8 +++---- 3 files changed, 46 insertions(+), 19 deletions(-) diff --git a/gbp/config.py b/gbp/config.py index 67c9921b..166f5537 100644 --- a/gbp/config.py +++ b/gbp/config.py @@ -25,6 +25,7 @@ try: except ImportError: gbp_version = "[Unknown version]" import gbp.tristate +from gbp.git import GitRepositoryError, GitRepository no_upstream_branch_msg = """ Repository does not have branch '%s' for upstream sources. If there is none see @@ -295,28 +296,32 @@ class GbpOptionParser(OptionParser): def_config_files = [ '/etc/git-buildpackage/gbp.conf', '~/.gbp.conf', - '.gbp.conf', - 'debian/gbp.conf', - '.git/gbp.conf' ] + '%(top_dir)s/.gbp.conf', + '%(top_dir)s/debian/gbp.conf', + '%(git_dir)s/gbp.conf' ] @classmethod - def get_config_files(klass): + def get_config_files(klass, no_local=False): """ Get list of config files from the I{GBP_CONF_FILES} environment variable. + @param no_local: don't return the per-repo configuration files + @type no_local: C{str} @return: list of config files we need to parse @rtype: C{list} >>> conf_backup = os.getenv('GBP_CONF_FILES') >>> if conf_backup is not None: del os.environ['GBP_CONF_FILES'] + >>> homedir = os.path.expanduser("~") >>> files = GbpOptionParser.get_config_files() - - # Remove the ~-expanded one - >>> del files[1] - >>> files - ['/etc/git-buildpackage/gbp.conf', '.gbp.conf', 'debian/gbp.conf', '.git/gbp.conf'] - + >>> files_mangled = [file.replace(homedir, 'HOME') for file in files] + >>> files_mangled + ['/etc/git-buildpackage/gbp.conf', 'HOME/.gbp.conf', '%(top_dir)s/.gbp.conf', '%(top_dir)s/debian/gbp.conf', '%(git_dir)s/gbp.conf'] + >>> files = GbpOptionParser.get_config_files(no_local=True) + >>> files_mangled = [file.replace(homedir, 'HOME') for file in files] + >>> files_mangled + ['/etc/git-buildpackage/gbp.conf', 'HOME/.gbp.conf'] >>> os.environ['GBP_CONF_FILES'] = 'test1:test2' >>> GbpOptionParser.get_config_files() ['test1', 'test2'] @@ -325,7 +330,24 @@ class GbpOptionParser(OptionParser): """ envvar = os.environ.get('GBP_CONF_FILES') files = envvar.split(':') if envvar else klass.def_config_files - return [ os.path.expanduser(f) for f in files ] + files = [os.path.expanduser(fname) for fname in files] + if no_local: + files = [fname for fname in files if fname.startswith('/')] + return files + + def _read_config_file(self, parser, repo, filename): + """Read config file""" + str_fields = {} + if repo: + str_fields['git_dir'] = repo.git_dir + if not repo.bare: + str_fields['top_dir'] = repo.path + try: + filename = filename % str_fields + except KeyError: + # Skip if filename wasn't expanded, i.e. we're not in git repo + return + parser.read(filename) def parse_config_files(self): """ @@ -337,7 +359,14 @@ class GbpOptionParser(OptionParser): self.config = dict(self.__class__.defaults) # Update with the values from the defaults section. This is needed # in case the config file doesn't have a [] section at all - parser.read(self.config_files) + config_files = self.get_config_files() + try: + repo = GitRepository(".") + except GitRepositoryError: + repo = None + # Read all config files + for filename in config_files: + self._read_config_file(parser, repo, filename) self.config.update(dict(parser.defaults())) # Make sure we read any legacy sections prior to the real subcommands @@ -393,7 +422,6 @@ class GbpOptionParser(OptionParser): self.sections = sections self.prefix = prefix self.config = {} - self.config_files = self.get_config_files() self.parse_config_files() self.valid_options = [] diff --git a/gbp/scripts/import_dscs.py b/gbp/scripts/import_dscs.py index 28413faf..f480fea4 100644 --- a/gbp/scripts/import_dscs.py +++ b/gbp/scripts/import_dscs.py @@ -73,8 +73,7 @@ def set_gbp_conf_files(): Filter out all gbp.conf files that are local to the git repository and set GBP_CONF_FILES accordingly so gbp import-dsc will only use these. """ - files = GbpOptionParser.get_config_files() - global_config = [ f for f in files if f.startswith('/') ] + global_config = GbpOptionParser.get_config_files(no_local=True) gbp_conf_files = ':'.join(global_config) os.environ['GBP_CONF_FILES'] = gbp_conf_files gbp.log.debug("Setting GBP_CONF_FILES to '%s'" % gbp_conf_files) diff --git a/tests/test_Config.py b/tests/test_Config.py index 046af278..6750d844 100644 --- a/tests/test_Config.py +++ b/tests/test_Config.py @@ -65,21 +65,21 @@ def test_filter(): The filter option should always parse as a list >>> import os >>> from gbp.config import GbpOptionParser - >>> parser = GbpOptionParser('bar') >>> tmpdir = str(context.new_tmpdir('bar')) >>> confname = os.path.join(tmpdir, 'gbp.conf') - >>> parser.config_files = [confname] >>> f = open(confname, 'w') >>> f.write('[bar]\\nfilter = asdf\\n') >>> f.close() - >>> parser.parse_config_files() + >>> os.environ['GBP_CONF_FILES'] = confname + >>> parser = GbpOptionParser('bar') >>> parser.config['filter'] ['asdf'] >>> f = open(confname, 'w') >>> f.write("[bar]\\nfilter = ['this', 'is', 'a', 'list']\\n") >>> f.close() - >>> parser.parse_config_files() + >>> parser = GbpOptionParser('bar') >>> parser.config['filter'] ['this', 'is', 'a', 'list'] + >>> del os.environ['GBP_CONF_FILES'] """ -- cgit v1.2.3 From 45e9e6771288f0021eadcf87ea08f0a9c4e19063 Mon Sep 17 00:00:00 2001 From: Markus Lehtonen Date: Mon, 25 Mar 2013 10:56:47 +0200 Subject: config: support for per-tree config files Add support for reading the local config file(s) from a given git tree-ish. Signed-off-by: Markus Lehtonen --- gbp/config.py | 26 +++++++++++++++++++++----- 1 file changed, 21 insertions(+), 5 deletions(-) diff --git a/gbp/config.py b/gbp/config.py index 166f5537..43d37a18 100644 --- a/gbp/config.py +++ b/gbp/config.py @@ -20,6 +20,8 @@ from optparse import OptionParser, OptionGroup, Option, OptionValueError from ConfigParser import SafeConfigParser, NoSectionError from copy import copy import os.path +import tempfile + try: from gbp.version import gbp_version except ImportError: @@ -335,13 +337,26 @@ class GbpOptionParser(OptionParser): files = [fname for fname in files if fname.startswith('/')] return files - def _read_config_file(self, parser, repo, filename): + def _read_config_file(self, parser, repo, filename, git_treeish): """Read config file""" str_fields = {} if repo: str_fields['git_dir'] = repo.git_dir if not repo.bare: str_fields['top_dir'] = repo.path + + # Read per-tree config file + if repo and git_treeish and filename.startswith('%(top_dir)s/'): + with tempfile.TemporaryFile() as tmp: + relpath = filename.replace('%(top_dir)s/', '') + try: + config = repo.show('%s:%s' % (git_treeish, relpath)) + tmp.writelines(config) + except GitRepositoryError: + pass + tmp.seek(0) + parser.readfp(tmp) + return try: filename = filename % str_fields except KeyError: @@ -349,7 +364,7 @@ class GbpOptionParser(OptionParser): return parser.read(filename) - def parse_config_files(self): + def parse_config_files(self, git_treeish=None): """ Parse the possible config files and set appropriate values default values @@ -366,7 +381,7 @@ class GbpOptionParser(OptionParser): repo = None # Read all config files for filename in config_files: - self._read_config_file(parser, repo, filename) + self._read_config_file(parser, repo, filename, git_treeish) self.config.update(dict(parser.defaults())) # Make sure we read any legacy sections prior to the real subcommands @@ -406,7 +421,8 @@ class GbpOptionParser(OptionParser): else: self.config['filter'] = [] - def __init__(self, command, prefix='', usage=None, sections=[]): + def __init__(self, command, prefix='', usage=None, sections=[], + git_treeish=None): """ @param command: the command to build the config parser for @type command: C{str} @@ -422,7 +438,7 @@ class GbpOptionParser(OptionParser): self.sections = sections self.prefix = prefix self.config = {} - self.parse_config_files() + self.parse_config_files(git_treeish) self.valid_options = [] if self.command.startswith('git-') or self.command.startswith('gbp-'): -- cgit v1.2.3 From f000c937523a083c85df55736cb58c8da57b4d69 Mon Sep 17 00:00:00 2001 From: Markus Lehtonen Date: Fri, 6 Jul 2012 15:55:19 +0300 Subject: GitRepository/add_files: add new option 'untracked' With this option you can either only update already tracked files to index the (untracked=False) or add new files, too. Signed-off-by: Markus Lehtonen --- gbp/git/repository.py | 6 ++++-- tests/test_GitRepository.py | 6 ++++++ 2 files changed, 10 insertions(+), 2 deletions(-) diff --git a/gbp/git/repository.py b/gbp/git/repository.py index 02476722..6f10081f 100644 --- a/gbp/git/repository.py +++ b/gbp/git/repository.py @@ -1323,7 +1323,7 @@ class GitRepository(object): #{ Files - def add_files(self, paths, force=False, index_file=None, work_tree=None): + def add_files(self, paths, force=False, untracked=True, index_file=None, work_tree=None): """ Add files to a the repository @@ -1331,6 +1331,8 @@ class GitRepository(object): @type paths: list or C{str} @param force: add files even if they would be ignored by .gitignore @type force: C{bool} + @param untracked: add also previously untracked files + @type untracked: C{bool} @param index_file: alternative index file to use @param work_tree: alternative working tree to use """ @@ -1338,7 +1340,7 @@ class GitRepository(object): args = GitArgs() args.add_true(force, '-f') - args.add('-A') + args.add_cond(untracked, '-A', '-u') args.add(paths) if index_file: diff --git a/tests/test_GitRepository.py b/tests/test_GitRepository.py index f3a83ff3..b1a14326 100644 --- a/tests/test_GitRepository.py +++ b/tests/test_GitRepository.py @@ -68,6 +68,7 @@ def test_add_files(): - L{gbp.git.GitRepository.add_files} - L{gbp.git.GitRepository.commit_all} - L{gbp.git.GitRepository.is_clean} + - L{gbp.git.GitRepository.status} Properties tested: - L{gbp.git.GitRepository.head} @@ -80,7 +81,12 @@ def test_add_files(): False >>> repo.is_clean(ignore_untracked=True)[0] True + >>> repo.add_files('testfile', force=True, untracked=False) + >>> repo.status().items() + [('??', ['testfile'])] >>> repo.add_files(repo.path, force=True) + >>> repo.status().items() + [('A ', ['testfile'])] >>> repo.commit_all(msg="foo") >>> repo.is_clean()[0] True -- cgit v1.2.3 From ad9c249803ab550ff81ab9edd3802416122b75c6 Mon Sep 17 00:00:00 2001 From: Markus Lehtonen Date: Fri, 6 Jul 2012 16:45:54 +0300 Subject: buildpackage: add 'untracked' option to write_wc() Whether to ignore untracked files (untracked=False) or not (untracked=True). Now, clones the temporary index file from the actual index, in order to correctly update files. Signed-off-by: Markus Lehtonen Signed-off-by: Ed Bartosh --- gbp/scripts/common/buildpackage.py | 11 +++++++++-- 1 file changed, 9 insertions(+), 2 deletions(-) diff --git a/gbp/scripts/common/buildpackage.py b/gbp/scripts/common/buildpackage.py index 898f6752..dc15eea9 100644 --- a/gbp/scripts/common/buildpackage.py +++ b/gbp/scripts/common/buildpackage.py @@ -158,9 +158,10 @@ def dump_tree(repo, export_dir, treeish, with_submodules, recursive=True): return True -def write_wc(repo, force=True): +def write_wc(repo, force=True, untracked=True): """write out the current working copy as a treeish object""" - repo.add_files(repo.path, force=force, index_file=wc_index) + clone_index() + repo.add_files(repo.path, force=force, untracked=untracked, index_file=wc_index) tree = repo.write_tree(index_file=wc_index) return tree @@ -169,3 +170,9 @@ def drop_index(): """drop our custom index""" if os.path.exists(wc_index): os.unlink(wc_index) + +def clone_index(): + """Copy the current index file to our custom index file""" + indexfn = ".git/index" + if os.path.exists(indexfn): + shutil.copy2(indexfn, wc_index) -- cgit v1.2.3 From f440810e850d3dcadcd7fc855ee3f6bea06ce303 Mon Sep 17 00:00:00 2001 From: Markus Lehtonen Date: Mon, 9 Jul 2012 10:52:36 +0300 Subject: buildpackage: new "working copy" choices for --git-export Add support for building different kind of "working copies", when using the --git-export option: - 'WC.TRACKED': only use files that are already tracked - 'WC.UNTRACKED': use untracked files, too - 'WC.IGNORED': also add files that'd normally be ignored Using '--git-export=WC' beaves like before. Signed-off-by: Markus Lehtonen --- gbp/scripts/buildpackage.py | 8 +++++--- gbp/scripts/common/buildpackage.py | 5 ++++- 2 files changed, 9 insertions(+), 4 deletions(-) diff --git a/gbp/scripts/buildpackage.py b/gbp/scripts/buildpackage.py index af0f34be..56e2afd2 100755 --- a/gbp/scripts/buildpackage.py +++ b/gbp/scripts/buildpackage.py @@ -34,7 +34,7 @@ from gbp.deb.upstreamsource import DebianUpstreamSource from gbp.errors import GbpError import gbp.log import gbp.notifications -from gbp.scripts.common.buildpackage import (index_name, wc_name, +from gbp.scripts.common.buildpackage import (index_name, wc_names, git_archive_submodules, git_archive_single, dump_tree, write_wc, drop_index) @@ -121,8 +121,10 @@ def write_tree(repo, options): if options.export_dir: if options.export == index_name: tree = repo.write_tree() - elif options.export == wc_name: - tree = write_wc(repo) + elif options.export in wc_names: + tree = write_wc(repo, + force=wc_names[options.export]['force'], + untracked=wc_names[options.export]['untracked']) else: tree = options.export if not repo.has_treeish(tree): diff --git a/gbp/scripts/common/buildpackage.py b/gbp/scripts/common/buildpackage.py index dc15eea9..1b03293c 100644 --- a/gbp/scripts/common/buildpackage.py +++ b/gbp/scripts/common/buildpackage.py @@ -31,7 +31,10 @@ import gbp.log # when we want to reference the index in a treeish context we call it: index_name = "INDEX" # when we want to reference the working copy in treeish context we call it: -wc_name = "WC" +wc_names = {'WC': {'force': True, 'untracked': True}, + 'WC.TRACKED': {'force': False, 'untracked': False}, + 'WC.UNTRACKED': {'force': False, 'untracked': True}, + 'WC.IGNORED': {'force': True, 'untracked': True}} # index file name used to export working copy wc_index = ".git/gbp_index" -- cgit v1.2.3 From 9b3bc9416579b24d9f9ce0c1019369efe860efa2 Mon Sep 17 00:00:00 2001 From: Markus Lehtonen Date: Thu, 25 Oct 2012 09:25:25 +0300 Subject: buildpackage: fix exporting of working copy when run from a subdir Exporting sources failed when git-buildpackage was run from a subdirectory of the git working directory because the path of the custom index file was not handled correctly. Signed-off-by: Markus Lehtonen --- gbp/scripts/buildpackage.py | 2 +- gbp/scripts/common/buildpackage.py | 24 +++++++++++++----------- 2 files changed, 14 insertions(+), 12 deletions(-) diff --git a/gbp/scripts/buildpackage.py b/gbp/scripts/buildpackage.py index 56e2afd2..b9f385b4 100755 --- a/gbp/scripts/buildpackage.py +++ b/gbp/scripts/buildpackage.py @@ -625,7 +625,7 @@ def main(argv): source = None retval = 1 finally: - drop_index() + drop_index(repo) if not options.tag_only: if options.export_dir and options.purge and not retval: diff --git a/gbp/scripts/common/buildpackage.py b/gbp/scripts/common/buildpackage.py index 1b03293c..f621e6c5 100644 --- a/gbp/scripts/common/buildpackage.py +++ b/gbp/scripts/common/buildpackage.py @@ -35,8 +35,6 @@ wc_names = {'WC': {'force': True, 'untracked': True}, 'WC.TRACKED': {'force': False, 'untracked': False}, 'WC.UNTRACKED': {'force': False, 'untracked': True}, 'WC.IGNORED': {'force': True, 'untracked': True}} -# index file name used to export working copy -wc_index = ".git/gbp_index" def sanitize_prefix(prefix): @@ -161,21 +159,25 @@ def dump_tree(repo, export_dir, treeish, with_submodules, recursive=True): return True +def wc_index(repo): + """Get path of the temporary index file used for exporting working copy""" + return os.path.join(repo.git_dir, "gbp_index") + def write_wc(repo, force=True, untracked=True): """write out the current working copy as a treeish object""" - clone_index() - repo.add_files(repo.path, force=force, untracked=untracked, index_file=wc_index) - tree = repo.write_tree(index_file=wc_index) + clone_index(repo) + repo.add_files(repo.path, force=force, untracked=untracked, index_file=wc_index(repo)) + tree = repo.write_tree(index_file=wc_index(repo)) return tree -def drop_index(): +def drop_index(repo): """drop our custom index""" - if os.path.exists(wc_index): - os.unlink(wc_index) + if os.path.exists(wc_index(repo)): + os.unlink(wc_index(repo)) -def clone_index(): +def clone_index(repo): """Copy the current index file to our custom index file""" - indexfn = ".git/index" + indexfn = os.path.join(repo.git_dir, "index") if os.path.exists(indexfn): - shutil.copy2(indexfn, wc_index) + shutil.copy2(indexfn, wc_index(repo)) -- cgit v1.2.3 From 5cf3503a5f9830b9c73fe9cc8c527b2f2dccefd8 Mon Sep 17 00:00:00 2001 From: Markus Lehtonen Date: Fri, 26 Apr 2013 11:20:11 +0300 Subject: buildpackage: implement --[no-]build cmdline option For enabling/disabling the builder script. The option is a bit asymmetric: --git-no-build automatically disables the 'postbuild' hook whereas --git-build does not enable it (e.g. if --git-no-hooks is given). Signed-off-by: Markus Lehtonen --- docs/manpages/gbp-buildpackage.sgml | 11 +++++++++++ gbp/config.py | 3 +++ gbp/scripts/buildpackage.py | 13 +++++++++++++ 3 files changed, 27 insertions(+) diff --git a/docs/manpages/gbp-buildpackage.sgml b/docs/manpages/gbp-buildpackage.sgml index d0d68bc6..d0b5a134 100644 --- a/docs/manpages/gbp-buildpackage.sgml +++ b/docs/manpages/gbp-buildpackage.sgml @@ -43,6 +43,7 @@ COMMAND COMMAND COMMAND + TAG-FORMAT TAG-FORMAT @@ -399,6 +400,16 @@ + + + + + + Enable builder. Note: causes the + postbuild hook to be disabled, too. + + + diff --git a/gbp/config.py b/gbp/config.py index 43d37a18..c1b98130 100644 --- a/gbp/config.py +++ b/gbp/config.py @@ -108,6 +108,7 @@ class GbpOptionParser(OptionParser): 'prebuild' : '', 'postexport' : '', 'postimport' : '', + 'build' : 'True', 'hooks' : 'True', 'debian-tag' : 'debian/%(version)s', 'upstream-tag' : 'upstream/%(version)s', @@ -267,6 +268,8 @@ class GbpOptionParser(OptionParser): 'postimport': ("hook run after a successful import, " "default is '%(postimport)s'"), + 'build': + ("Enable running builder, default is %(build)s"), 'hooks': ("Enable running all hooks, default is %(hooks)s"), 'time-machine': diff --git a/gbp/scripts/buildpackage.py b/gbp/scripts/buildpackage.py index b9f385b4..f166b5c6 100755 --- a/gbp/scripts/buildpackage.py +++ b/gbp/scripts/buildpackage.py @@ -345,6 +345,15 @@ def setup_pbuilder(options): os.environ['GIT_PBUILDER_OPTIONS'] = options.pbuilder_options +def disable_builder(options): + """Disable builder (and postbuild hook)""" + gbp.log.info("Disabling builder and postbuild hook") + options.builder = '' + options.postbuild = '' + options.pbuilder = None + options.qemubuilder = None + + def disable_hooks(options): """Disable all hooks (except for builder)""" for hook in ['cleaner', 'postexport', 'prebuild', 'postbuild', 'posttag']: @@ -441,6 +450,7 @@ def build_parser(name, prefix=None): cmd_group.add_config_file_option(option_name="arch", dest="pbuilder_arch") cmd_group.add_boolean_config_file_option(option_name = "pbuilder-autoconf", dest="pbuilder_autoconf") cmd_group.add_config_file_option(option_name="pbuilder-options", dest="pbuilder_options") + cmd_group.add_boolean_config_file_option(option_name="build", dest="build") cmd_group.add_boolean_config_file_option(option_name="hooks", dest="hooks") export_group.add_config_file_option(option_name="export-dir", dest="export_dir", type="path", help="before building the package export the source into EXPORT_DIR, default is '%(export-dir)s'") @@ -468,6 +478,9 @@ def parse_args(argv, prefix): options, args = parser.parse_args(args) gbp.log.setup(options.color, options.verbose, options.color_scheme) + if not options.build: + disable_builder(options) + dpkg_args = [] if not options.hooks: disable_hooks(options) if options.retag: -- cgit v1.2.3 From dbe33d8c60d63598a02cccef14ee005df17112e0 Mon Sep 17 00:00:00 2001 From: Markus Lehtonen Date: Wed, 11 Jul 2012 16:03:56 +0300 Subject: Add gbp specific tempfile module Minimal initial implementation that only adds tempdir parent directory creation. Signed-off-by: Markus Lehtonen Signed-off-by: Olev Kartau --- gbp/tmpfile.py | 38 ++++++++++++++++++++++++++++++++++++++ 1 file changed, 38 insertions(+) create mode 100644 gbp/tmpfile.py diff --git a/gbp/tmpfile.py b/gbp/tmpfile.py new file mode 100644 index 00000000..e1ad3084 --- /dev/null +++ b/gbp/tmpfile.py @@ -0,0 +1,38 @@ +# vim: set fileencoding=utf-8 : +# +# (C) 2012 Intel Corporation +# This program is free software; you can redistribute it and/or modify +# it under the terms of the GNU General Public License as published by +# the Free Software Foundation; either version 2 of the License, or +# (at your option) any later version. +# +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with this program; if not, write to the Free Software +# Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA +"""Temporary directory handling""" + +import os +import tempfile + +from gbp.errors import GbpError + +def mkdtemp(dir, **kwargs): + """Create temporary directory""" + try: + if not os.path.exists(dir): + os.makedirs(dir) + except OSError as (dummy_e, msg): + raise GbpError, "Unable to create dir %s (%s)" % (dir, msg) + + try: + return os.path.abspath(tempfile.mkdtemp(dir=dir, **kwargs)) + except OSError as (dummy_e, msg): + raise GbpError, "Unable to create tmpdir under %s (%s)" % (dir, msg) + +# vim:et:ts=4:sw=4:et:sts=4:ai:set list listchars=tab\:»·,trail\:·: + -- cgit v1.2.3 From b3d964ebbc7b55aa692f03ed98a592ee775f6f83 Mon Sep 17 00:00:00 2001 From: Markus Lehtonen Date: Thu, 12 Jul 2012 09:07:47 +0300 Subject: Universal configurable base tmpdir for all gbp tools Adds support for a configurable tmpdir under which all gbp tools now create their temporary directories and files. NOTE: an exception is git-import-dscs which doesn't use the common configuration system. Signed-off-by: Markus Lehtonen --- gbp/config.py | 4 ++++ gbp/scripts/buildpackage.py | 10 ++++++---- gbp/scripts/common/buildpackage.py | 8 ++++---- gbp/scripts/import_dsc.py | 14 +++++++++----- gbp/scripts/import_orig.py | 6 ++++-- gbp/scripts/pq.py | 9 +++++---- tests/04_test_submodules.py | 8 ++++---- 7 files changed, 36 insertions(+), 23 deletions(-) diff --git a/gbp/config.py b/gbp/config.py index c1b98130..c8f2f803 100644 --- a/gbp/config.py +++ b/gbp/config.py @@ -159,6 +159,7 @@ class GbpOptionParser(OptionParser): 'allow-unauthenticated': 'False', 'symlink-orig': 'True', 'purge': 'True', + 'tmp-dir' : '/var/tmp/gbp/', } help = { 'debian-branch': @@ -297,6 +298,9 @@ class GbpOptionParser(OptionParser): "'%(symlink-orig)s'"), 'purge': "Purge exported package build directory. Default is '%(purge)s'", + 'tmp-dir': + ("Base directory under which temporary directories are " + "created, default is '%(tmp-dir)s'"), } def_config_files = [ '/etc/git-buildpackage/gbp.conf', diff --git a/gbp/scripts/buildpackage.py b/gbp/scripts/buildpackage.py index f166b5c6..83181dcc 100755 --- a/gbp/scripts/buildpackage.py +++ b/gbp/scripts/buildpackage.py @@ -40,7 +40,8 @@ from gbp.scripts.common.buildpackage import (index_name, wc_names, write_wc, drop_index) from gbp.pkg import compressor_opts, compressor_aliases, parse_archive_filename -def git_archive(repo, cp, output_dir, treeish, comp_type, comp_level, with_submodules): +def git_archive(repo, cp, output_dir, tmpdir_base, treeish, comp_type, + comp_level, with_submodules): "create a compressed orig tarball in output_dir using git_archive" try: comp_opts = compressor_opts[comp_type][0] @@ -53,8 +54,8 @@ def git_archive(repo, cp, output_dir, treeish, comp_type, comp_level, with_submo try: if repo.has_submodules() and with_submodules: repo.update_submodules() - git_archive_submodules(repo, treeish, output, prefix, - comp_type, comp_level, comp_opts) + git_archive_submodules(repo, treeish, output, tmpdir_base, + prefix, comp_type, comp_level, comp_opts) else: git_archive_single(repo, treeish, output, prefix, @@ -278,7 +279,7 @@ def git_archive_build_orig(repo, cp, output_dir, options): upstream_tree)) gbp.log.debug("Building upstream tarball with compression '%s -%s'" % (options.comp_type, options.comp_level)) - if not git_archive(repo, cp, output_dir, upstream_tree, + if not git_archive(repo, cp, output_dir, options.tmp_dir, upstream_tree, options.comp_type, options.comp_level, options.with_submodules): @@ -404,6 +405,7 @@ def build_parser(name, prefix=None): parser.add_config_file_option(option_name="color-scheme", dest="color_scheme") parser.add_config_file_option(option_name="notify", dest="notify", type='tristate') + parser.add_config_file_option(option_name="tmp-dir", dest="tmp_dir") tag_group.add_option("--git-tag", action="store_true", dest="tag", default=False, help="create a tag after a successful build") tag_group.add_option("--git-tag-only", action="store_true", dest="tag_only", default=False, diff --git a/gbp/scripts/common/buildpackage.py b/gbp/scripts/common/buildpackage.py index f621e6c5..c49375d6 100644 --- a/gbp/scripts/common/buildpackage.py +++ b/gbp/scripts/common/buildpackage.py @@ -19,10 +19,10 @@ """Common functionality for Debian and RPM buildpackage scripts""" import os, os.path -import tempfile import subprocess import shutil +import gbp.tmpfile as tempfile from gbp.command_wrappers import (CatenateTarArchive, CatenateZipArchive) from gbp.git.repository import GitRepository, GitRepositoryError from gbp.errors import GbpError @@ -53,8 +53,8 @@ def sanitize_prefix(prefix): return '/' -def git_archive_submodules(repo, treeish, output, prefix, comp_type, comp_level, - comp_opts, format='tar'): +def git_archive_submodules(repo, treeish, output, tmpdir_base, prefix, + comp_type, comp_level, comp_opts, format='tar'): """ Create a source tree archive with submodules. @@ -64,7 +64,7 @@ def git_archive_submodules(repo, treeish, output, prefix, comp_type, comp_level, Exception handling is left to the caller. """ prefix = sanitize_prefix(prefix) - tempdir = tempfile.mkdtemp() + tempdir = tempfile.mkdtemp(dir=tmpdir_base, prefix='git-archive_') main_archive = os.path.join(tempdir, "main.%s" % format) submodule_archive = os.path.join(tempdir, "submodule.%s" % format) try: diff --git a/gbp/scripts/import_dsc.py b/gbp/scripts/import_dsc.py index 91c4745e..ffb8a084 100644 --- a/gbp/scripts/import_dsc.py +++ b/gbp/scripts/import_dsc.py @@ -21,10 +21,10 @@ import sys import re import os import shutil -import tempfile import glob import pipes import time +import gbp.tmpfile as tempfile import gbp.command_wrappers as gbpc from gbp.deb.dscfile import DscFile from gbp.deb.upstreamsource import DebianUpstreamSource @@ -41,7 +41,7 @@ class SkipImport(Exception): pass -def download_source(pkg, dirs, unauth): +def download_source(pkg, dirs, unauth, tmpdir_base): opts = [ '--download-only' ] if unauth: opts.append('--allow-unauthenticated') @@ -53,7 +53,8 @@ def download_source(pkg, dirs, unauth): cmd = 'apt-get' opts += ['-qq', 'source', pkg] - dirs['download'] = os.path.abspath(tempfile.mkdtemp()) + dirs['download'] = tempfile.mkdtemp(dir=tmpdir_base, + prefix='import-dsc_download_') gbp.log.info("Downloading '%s' using '%s'..." % (pkg, cmd)) gbpc.RunAtCommand(cmd, opts, shell=False)(dir=dirs['download']) @@ -227,6 +228,7 @@ def build_parser(name): parser.add_config_file_option(option_name="color", dest="color", type='tristate') parser.add_config_file_option(option_name="color-scheme", dest="color_scheme") + parser.add_config_file_option(option_name="tmp-dir", dest="tmp_dir") parser.add_option("--download", action="store_true", dest="download", default=False, help="download source package") branch_group.add_config_file_option(option_name="debian-branch", @@ -295,7 +297,8 @@ def main(argv): if options.download: dsc = download_source(pkg, dirs=dirs, - unauth=options.allow_unauthenticated) + unauth=options.allow_unauthenticated, + tmpdir_base=options.tmp_dir) else: dsc = pkg @@ -327,7 +330,8 @@ def main(argv): if repo.bare: set_bare_repo_options(options) - dirs['tmp'] = os.path.abspath(tempfile.mkdtemp(dir='..')) + dirs['tmp'] = tempfile.mkdtemp(dir=options.tmp_dir, + prefix='import-dsc_') upstream = DebianUpstreamSource(src.tgz) upstream = upstream.unpack(dirs['tmp'], options.filters) diff --git a/gbp/scripts/import_orig.py b/gbp/scripts/import_orig.py index dfc5e2ae..7cebd1c8 100644 --- a/gbp/scripts/import_orig.py +++ b/gbp/scripts/import_orig.py @@ -20,7 +20,7 @@ import ConfigParser import os import sys -import tempfile +import gbp.tmpfile as tempfile import gbp.command_wrappers as gbpc from gbp.deb import (DebianPkgPolicy, parse_changelog_repo) from gbp.deb.upstreamsource import DebianUpstreamSource @@ -199,6 +199,7 @@ def build_parser(name): parser.add_config_file_option(option_name="color", dest="color", type='tristate') parser.add_config_file_option(option_name="color-scheme", dest="color_scheme") + parser.add_config_file_option(option_name="tmp-dir", dest="tmp_dir") # Accepted for compatibility parser.add_option("--no-dch", dest='no_dch', action="store_true", @@ -224,12 +225,13 @@ def parse_args(argv): def main(argv): ret = 0 - tmpdir = tempfile.mkdtemp(dir='../') (options, args) = parse_args(argv) if not options: return 1 + tmpdir = tempfile.mkdtemp(dir=options.tmp_dir, prefix='import-orig_') + try: source = find_source(options.uscan, args) if not source: diff --git a/gbp/scripts/pq.py b/gbp/scripts/pq.py index 38e21d84..7ac5d00f 100755 --- a/gbp/scripts/pq.py +++ b/gbp/scripts/pq.py @@ -22,8 +22,8 @@ import errno import os import shutil import sys -import tempfile import re +import gbp.tmpfile as tempfile from gbp.config import GbpOptionParserDebian from gbp.git import (GitRepositoryError, GitRepository) from gbp.command_wrappers import (GitCommand, CommandExecFailed) @@ -118,7 +118,7 @@ def export_patches(repo, branch, options): gbp.log.info("No patches on '%s' - nothing to do." % pq_branch) -def safe_patches(series): +def safe_patches(series, tmpdir_base): """ Safe the current patches in a temporary directory below .git/ @@ -131,7 +131,7 @@ def safe_patches(series): src = os.path.dirname(series) name = os.path.basename(series) - tmpdir = tempfile.mkdtemp(dir='.git/', prefix='gbp-pq') + tmpdir = tempfile.mkdtemp(dir=tmpdir_base, prefix='gbp-pq_') patches = os.path.join(tmpdir, 'patches') series = os.path.join(patches, name) @@ -178,7 +178,7 @@ def import_quilt_patches(repo, branch, series, tries, force): # If we go back in history we have to safe our pq so we always try to apply # the latest one if len(commits) > 1: - tmpdir, series = safe_patches(series) + tmpdir, series = safe_patches(series, options.tmp_dir) queue = PatchSeries.read_series_file(series) @@ -262,6 +262,7 @@ def build_parser(name): parser.add_config_file_option(option_name="color", dest="color", type='tristate') parser.add_config_file_option(option_name="color-scheme", dest="color_scheme") + parser.add_config_file_option(option_name="tmp-dir", dest="tmp_dir") return parser diff --git a/tests/04_test_submodules.py b/tests/04_test_submodules.py index 4b072201..1b45c86f 100644 --- a/tests/04_test_submodules.py +++ b/tests/04_test_submodules.py @@ -107,12 +107,12 @@ def test_create_tarballs(): """Create an upstream tarball""" # Tarball with submodules changelog = { "Source": "test", "Upstream-Version": "0.1" } - ok_(buildpackage.git_archive(REPO, changelog, str(TMPDIR), "HEAD", "bzip2", - "9", True)) + ok_(buildpackage.git_archive(REPO, changelog, str(TMPDIR), str(TMPDIR), + "HEAD", "bzip2", "9", True)) # Tarball without submodules changelog = { "Source": "test", "Upstream-Version": "0.2" } - ok_(buildpackage.git_archive(REPO, changelog, str(TMPDIR), "HEAD", "bzip2", - "9", False)) + ok_(buildpackage.git_archive(REPO, changelog, str(TMPDIR), str(TMPDIR), + "HEAD", "bzip2", "9", False)) def test_check_tarfiles(): """Check the contents of the created tarfile""" -- cgit v1.2.3 From 2674486b099317fb5db314bc8743614998af63bd Mon Sep 17 00:00:00 2001 From: Markus Lehtonen Date: Fri, 11 May 2012 10:56:17 +0300 Subject: gbp-pq: readiness to configure the pq branch name All other gbp branches have configurable names. This commit adds the readiness for user to configure/change the name of the patch-queue branches, as well. Patch-queue is defined in options as a format string, where '%(branch)s' refers to the debian/packaging branch. If the pq-branch format string does not contain '%(branch)s', there is only one patch-queue branch and the debian/packaging branch is used as its base branch. That is, e.g. a 'gbp-pq switch' operation from the patch-queue branch always switches to the debian/packaging branch. Signed-off-by: Markus Lehtonen Signed-off-by: Olev Kartau --- gbp/scripts/common/pq.py | 107 ++++++++++++++++++++++++++++++++++++----------- gbp/scripts/pq.py | 50 +++++++++++----------- tests/13_test_gbp_pq.py | 3 +- 3 files changed, 109 insertions(+), 51 deletions(-) diff --git a/gbp/scripts/common/pq.py b/gbp/scripts/common/pq.py index 8d92a170..89683dd7 100644 --- a/gbp/scripts/common/pq.py +++ b/gbp/scripts/common/pq.py @@ -34,43 +34,99 @@ from gbp.git.modifier import GitModifier, GitTz from gbp.errors import GbpError import gbp.log -PQ_BRANCH_PREFIX = "patch-queue/" +DEFAULT_PQ_BRANCH_NAME = "patch-queue/%(branch)s" -def is_pq_branch(branch): +def is_pq_branch(branch, options): """ is branch a patch-queue branch? - >>> is_pq_branch("foo") + >>> from optparse import OptionParser + >>> (opts, args) = OptionParser().parse_args([]) + >>> is_pq_branch("foo", opts) False - >>> is_pq_branch("patch-queue/foo") + >>> is_pq_branch("patch-queue/foo", opts) + True + >>> opts.pq_branch = "%(branch)s/development" + >>> is_pq_branch("foo/development/bar", opts) + False + >>> is_pq_branch("bar/foo/development", opts) + True + >>> opts.pq_branch = "development" + >>> is_pq_branch("development", opts) + True + >>> opts.pq_branch = "my/%(branch)s/pq" + >>> is_pq_branch("my/foo/pqb", opts) + False + >>> is_pq_branch("my/foo/pq", opts) True """ - return [False, True][branch.startswith(PQ_BRANCH_PREFIX)] + pq_format_str = DEFAULT_PQ_BRANCH_NAME + if hasattr(options, 'pq_branch'): + pq_format_str = options.pq_branch + pq_re = re.compile(r'^%s$' % (pq_format_str % dict(branch="(?P\S+)"))) + if pq_re.match(branch): + return True + return False -def pq_branch_name(branch): + +def pq_branch_name(branch, options): """ get the patch queue branch corresponding to branch - >>> pq_branch_name("patch-queue/master") - >>> pq_branch_name("foo") + >>> from optparse import OptionParser + >>> (opts, args) = OptionParser().parse_args([]) + >>> pq_branch_name("patch-queue/master", opts) + >>> pq_branch_name("foo", opts) 'patch-queue/foo' + >>> opts.pq_branch = "%(branch)s/development" + >>> pq_branch_name("foo", opts) + 'foo/development' + >>> opts.pq_branch = "development" + >>> pq_branch_name("foo", opts) + 'development' """ - if not is_pq_branch(branch): - return PQ_BRANCH_PREFIX + branch + pq_format_str = DEFAULT_PQ_BRANCH_NAME + if hasattr(options, 'pq_branch'): + pq_format_str = options.pq_branch + if not is_pq_branch(branch, options): + return pq_format_str % dict(branch=branch) -def pq_branch_base(pq_branch): - """ - get the branch corresponding to the given patch queue branch - >>> pq_branch_base("patch-queue/master") +def pq_branch_base(pq_branch, options): + """ + Get the branch corresponding to the given patch queue branch. + Returns the packaging/debian branch if pq format string doesn't contain + '%(branch)s' key. + + >>> from optparse import OptionParser + >>> (opts, args) = OptionParser().parse_args([]) + >>> opts.packaging_branch = "packaging" + >>> pq_branch_base("patch-queue/master", opts) 'master' - >>> pq_branch_base("foo") + >>> pq_branch_base("foo", opts) + >>> opts.pq_branch = "my/%(branch)s/development" + >>> pq_branch_base("foo/development", opts) + >>> pq_branch_base("my/foo/development/bar", opts) + >>> pq_branch_base("my/foo/development", opts) + 'foo' + >>> opts.pq_branch = "development" + >>> pq_branch_base("foo/development", opts) + >>> pq_branch_base("development", opts) + 'packaging' """ - if is_pq_branch(pq_branch): - return pq_branch[len(PQ_BRANCH_PREFIX):] + pq_format_str = DEFAULT_PQ_BRANCH_NAME + if hasattr(options, 'pq_branch'): + pq_format_str = options.pq_branch + + pq_re = re.compile(r'^%s$' % (pq_format_str % dict(branch="(?P\S+)"))) + m = pq_re.match(pq_branch) + if m: + if 'base' in m.groupdict(): + return m.group('base') + return options.packaging_branch def parse_gbp_commands(info, cmd_tag, noarg_cmds, arg_cmds): @@ -256,15 +312,15 @@ def get_maintainer_from_control(repo): return GitModifier() -def switch_to_pq_branch(repo, branch): +def switch_to_pq_branch(repo, branch, options): """ Switch to patch-queue branch if not already there, create it if it doesn't exist yet """ - if is_pq_branch(branch): + if is_pq_branch(branch, options): return - pq_branch = pq_branch_name(branch) + pq_branch = pq_branch_name(branch, options) if not repo.has_branch(pq_branch): try: repo.create_branch(pq_branch) @@ -276,8 +332,9 @@ def switch_to_pq_branch(repo, branch): repo.set_branch(pq_branch) -def apply_single_patch(repo, branch, patch, fallback_author, topic=None): - switch_to_pq_branch(repo, branch) +def apply_single_patch(repo, branch, patch, fallback_author, options): + switch_to_pq_branch(repo, branch, options) + topic = None if not hasattr(options, 'topic') else options.topic apply_and_commit_patch(repo, patch, fallback_author, topic) @@ -306,12 +363,12 @@ def apply_and_commit_patch(repo, patch, fallback_author, topic=None): repo.update_ref('HEAD', commit, msg="gbp-pq import %s" % patch.path) -def drop_pq(repo, branch): - if is_pq_branch(branch): +def drop_pq(repo, branch, options): + if is_pq_branch(branch, options): gbp.log.err("On a patch-queue branch, can't drop it.") raise GbpError else: - pq_branch = pq_branch_name(branch) + pq_branch = pq_branch_name(branch, options) if repo.has_branch(pq_branch): repo.delete_branch(pq_branch) diff --git a/gbp/scripts/pq.py b/gbp/scripts/pq.py index 7ac5d00f..75348501 100755 --- a/gbp/scripts/pq.py +++ b/gbp/scripts/pq.py @@ -92,13 +92,13 @@ def generate_patches(repo, start, end, outdir, options): def export_patches(repo, branch, options): """Export patches from the pq branch into a patch series""" - if is_pq_branch(branch): - base = pq_branch_base(branch) + if is_pq_branch(branch, options): + base = pq_branch_base(branch, options) gbp.log.info("On '%s', switching to '%s'" % (branch, base)) branch = base repo.set_branch(branch) - pq_branch = pq_branch_name(branch) + pq_branch = pq_branch_name(branch, options) try: shutil.rmtree(PATCH_DIR) except OSError as (e, msg): @@ -141,7 +141,7 @@ def safe_patches(series, tmpdir_base): return (tmpdir, series) -def import_quilt_patches(repo, branch, series, tries, force): +def import_quilt_patches(repo, branch, series, tries, options): """ apply a series of quilt patches in the series file 'series' to branch the patch-queue branch for 'branch' @@ -151,24 +151,24 @@ def import_quilt_patches(repo, branch, series, tries, force): @param series; series file to read patches from @param tries: try that many times to apply the patches going back one commit in the branches history after each failure. - @param force: import the patch series even if the branch already exists + @param options: gbp-pq command options """ tmpdir = None - if is_pq_branch(branch): - if force: - branch = pq_branch_base(branch) - pq_branch = pq_branch_name(branch) + if is_pq_branch(branch, options): + if options.force: + branch = pq_branch_base(branch, options) + pq_branch = pq_branch_name(branch, options) repo.checkout(branch) else: gbp.log.err("Already on a patch-queue branch '%s' - doing nothing." % branch) raise GbpError else: - pq_branch = pq_branch_name(branch) + pq_branch = pq_branch_name(branch, options) if repo.has_branch(pq_branch): - if force: - drop_pq(repo, branch) + if options.force: + drop_pq(repo, branch, options) else: raise GbpError("Patch queue branch '%s'. already exists. Try 'rebase' instead." % pq_branch) @@ -215,23 +215,23 @@ def import_quilt_patches(repo, branch, series, tries, force): shutil.rmtree(tmpdir) -def rebase_pq(repo, branch): - if is_pq_branch(branch): - base = pq_branch_base(branch) +def rebase_pq(repo, branch, options): + if is_pq_branch(branch, options): + base = pq_branch_base(branch, options) else: - switch_to_pq_branch(repo, branch) + switch_to_pq_branch(repo, branch, options) base = branch GitCommand("rebase")([base]) -def switch_pq(repo, current): +def switch_pq(repo, current, options): """Switch to patch-queue branch if on base branch and vice versa""" - if is_pq_branch(current): - base = pq_branch_base(current) + if is_pq_branch(current, options): + base = pq_branch_base(current, options) gbp.log.info("Switching to %s" % base) repo.checkout(base) else: - switch_to_pq_branch(repo, current) + switch_to_pq_branch(repo, current, options) def build_parser(name): @@ -313,20 +313,20 @@ def main(argv): elif action == "import": series = SERIES_FILE tries = options.time_machine if (options.time_machine > 0) else 1 - import_quilt_patches(repo, current, series, tries, options.force) + import_quilt_patches(repo, current, series, tries, options) current = repo.get_branch() gbp.log.info("Patches listed in '%s' imported on '%s'" % (series, current)) elif action == "drop": - drop_pq(repo, current) + drop_pq(repo, current, options) elif action == "rebase": - rebase_pq(repo, current) + rebase_pq(repo, current, options) elif action == "apply": patch = Patch(patchfile) maintainer = get_maintainer_from_control(repo) - apply_single_patch(repo, current, patch, maintainer, options.topic) + apply_single_patch(repo, current, patch, maintainer, options) elif action == "switch": - switch_pq(repo, current) + switch_pq(repo, current, options) except CommandExecFailed: retval = 1 except (GbpError, GitRepositoryError) as err: diff --git a/tests/13_test_gbp_pq.py b/tests/13_test_gbp_pq.py index 753143d3..7e78b153 100644 --- a/tests/13_test_gbp_pq.py +++ b/tests/13_test_gbp_pq.py @@ -91,7 +91,8 @@ class TestApplySinglePatch(testutils.DebianGitTestRepo): patch = gbp.patch_series.Patch(_patch_path('foo.patch')) - pq.apply_single_patch(self.repo, 'master', patch, None) + dummy_opts = object() + pq.apply_single_patch(self.repo, 'master', patch, None, dummy_opts) self.assertIn('foo', self.repo.list_files()) class TestWritePatch(testutils.DebianGitTestRepo): -- cgit v1.2.3 From 9220fa81b8c3c2e0b09de9958e1ba5df82d96436 Mon Sep 17 00:00:00 2001 From: Markus Lehtonen Date: Fri, 6 Sep 2013 14:23:03 +0300 Subject: common/pq: support more flexible pq-branch naming Now any string fields (e.g. '%(version)s') can be used in the pq-branch format strings - in addition to the '%(branch)s' supported before. Signed-off-by: Markus Lehtonen --- gbp/scripts/common/pq.py | 67 +++++++++++++++++++++++++++++++----------------- 1 file changed, 43 insertions(+), 24 deletions(-) diff --git a/gbp/scripts/common/pq.py b/gbp/scripts/common/pq.py index 89683dd7..a91ec8e9 100644 --- a/gbp/scripts/common/pq.py +++ b/gbp/scripts/common/pq.py @@ -37,6 +37,22 @@ import gbp.log DEFAULT_PQ_BRANCH_NAME = "patch-queue/%(branch)s" +def pq_branch_match(branch, pq_fmt_str): + """ + Match branch name with pq branch name pattern + + >>> pq_branch_match('patch-queue/foo', 'patch-queue/%(br)s').groupdict() + {'br': 'foo'} + >>> pq_branch_match('pq/foo/bar', 'pq/%(br)s/baz') + >>> pq_branch_match('pq/foo/bar', 'pq/%(br)s/bar').groupdict() + {'br': 'foo'} + >>> pq_branch_match('foo/bar/1.0/pq', 'foo/%(br)s/%(ver)s/pq').groupdict() + {'ver': '1.0', 'br': 'bar'} + """ + pq_re = '^%s$' % re.sub('%\(([a-z_\-]+)\)s', r'(?P<\1>\S+)', pq_fmt_str) + return re.match(pq_re, branch) + + def is_pq_branch(branch, options): """ is branch a patch-queue branch? @@ -60,18 +76,20 @@ def is_pq_branch(branch, options): False >>> is_pq_branch("my/foo/pq", opts) True + >>> opts.pq_branch = "my/%(branch)s/%(version)s" + >>> is_pq_branch("my/foo", opts) + False + >>> is_pq_branch("my/foo/1.0", opts) + True """ - pq_format_str = DEFAULT_PQ_BRANCH_NAME - if hasattr(options, 'pq_branch'): - pq_format_str = options.pq_branch - - pq_re = re.compile(r'^%s$' % (pq_format_str % dict(branch="(?P\S+)"))) - if pq_re.match(branch): + pq_format_str = (options.pq_branch if hasattr(options, 'pq_branch') + else DEFAULT_PQ_BRANCH_NAME) + if pq_branch_match(branch, pq_format_str): return True return False -def pq_branch_name(branch, options): +def pq_branch_name(branch, options, extra_keys=None): """ get the patch queue branch corresponding to branch @@ -86,13 +104,17 @@ def pq_branch_name(branch, options): >>> opts.pq_branch = "development" >>> pq_branch_name("foo", opts) 'development' + >>> opts.pq_branch = "pq/%(branch)s/%(ver)s" + >>> pq_branch_name("foo", opts, {'ver': '1.0'}) + 'pq/foo/1.0' """ - pq_format_str = DEFAULT_PQ_BRANCH_NAME - if hasattr(options, 'pq_branch'): - pq_format_str = options.pq_branch - + pq_format_str = (options.pq_branch if hasattr(options, 'pq_branch') + else DEFAULT_PQ_BRANCH_NAME) + format_fields = {'branch': branch} + if extra_keys: + format_fields.update(extra_keys) if not is_pq_branch(branch, options): - return pq_format_str % dict(branch=branch) + return pq_format_str % format_fields def pq_branch_base(pq_branch, options): @@ -117,15 +139,12 @@ def pq_branch_base(pq_branch, options): >>> pq_branch_base("development", opts) 'packaging' """ - pq_format_str = DEFAULT_PQ_BRANCH_NAME - if hasattr(options, 'pq_branch'): - pq_format_str = options.pq_branch - - pq_re = re.compile(r'^%s$' % (pq_format_str % dict(branch="(?P\S+)"))) - m = pq_re.match(pq_branch) + pq_format_str = (options.pq_branch if hasattr(options, 'pq_branch') + else DEFAULT_PQ_BRANCH_NAME) + m = pq_branch_match(pq_branch, pq_format_str) if m: - if 'base' in m.groupdict(): - return m.group('base') + if 'branch' in m.groupdict(): + return m.group('branch') return options.packaging_branch @@ -312,7 +331,7 @@ def get_maintainer_from_control(repo): return GitModifier() -def switch_to_pq_branch(repo, branch, options): +def switch_to_pq_branch(repo, branch, options, name_keys=None): """ Switch to patch-queue branch if not already there, create it if it doesn't exist yet @@ -320,7 +339,7 @@ def switch_to_pq_branch(repo, branch, options): if is_pq_branch(branch, options): return - pq_branch = pq_branch_name(branch, options) + pq_branch = pq_branch_name(branch, options, name_keys) if not repo.has_branch(pq_branch): try: repo.create_branch(pq_branch) @@ -363,12 +382,12 @@ def apply_and_commit_patch(repo, patch, fallback_author, topic=None): repo.update_ref('HEAD', commit, msg="gbp-pq import %s" % patch.path) -def drop_pq(repo, branch, options): +def drop_pq(repo, branch, options, name_keys=None): if is_pq_branch(branch, options): gbp.log.err("On a patch-queue branch, can't drop it.") raise GbpError else: - pq_branch = pq_branch_name(branch, options) + pq_branch = pq_branch_name(branch, options, name_keys) if repo.has_branch(pq_branch): repo.delete_branch(pq_branch) -- cgit v1.2.3 From aa07483494eacee826ce6e250fe29d4b74c3b32d Mon Sep 17 00:00:00 2001 From: Markus Lehtonen Date: Thu, 12 Jan 2012 15:29:03 +0200 Subject: Introduce rpm helpers Preparation for RPM support. Signed-off-by: Markus Lehtonen Signed-off-by: Ed Bartosh Signed-off-by: Zhang Qiang Signed-off-by: Huang Hao --- gbp/rpm/__init__.py | 526 ++++++++++++++++++++++++++++++++++++++++++++++++++++ gbp/rpm/git.py | 90 +++++++++ gbp/rpm/policy.py | 69 +++++++ 3 files changed, 685 insertions(+) create mode 100644 gbp/rpm/__init__.py create mode 100644 gbp/rpm/git.py create mode 100644 gbp/rpm/policy.py diff --git a/gbp/rpm/__init__.py b/gbp/rpm/__init__.py new file mode 100644 index 00000000..00582d72 --- /dev/null +++ b/gbp/rpm/__init__.py @@ -0,0 +1,526 @@ +# vim: set fileencoding=utf-8 : +# +# (C) 2006,2007 Guido Guenther +# (C) 2012 Intel Corporation +# This program is free software; you can redistribute it and/or modify +# it under the terms of the GNU General Public License as published by +# the Free Software Foundation; either version 2 of the License, or +# (at your option) any later version. +# +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with this program; if not, write to the Free Software +# Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA +"""provides some rpm source package related helpers""" + +import commands +import sys +import os +import re +import tempfile +import rpm +import glob +import shutil as shutil +from optparse import OptionParser + +import gbp.command_wrappers as gbpc +from gbp.errors import GbpError +from gbp.git import GitRepositoryError +from gbp.patch_series import (PatchSeries, Patch) +import gbp.log +from gbp.pkg import (UpstreamSource, compressor_opts, parse_archive_filename) +from gbp.rpm.policy import RpmPkgPolicy + +# define a large number to check the valid id of source file +MAX_SOURCE_NUMBER = 99999 + + +class NoSpecError(Exception): + """Spec file parsing error""" + pass + + +class RpmUpstreamSource(UpstreamSource): + """Upstream source class for RPM packages""" + def __init__(self, name, unpacked=None, **kwargs): + super(RpmUpstreamSource, self).__init__(name, + unpacked, + RpmPkgPolicy, + **kwargs) + + +class SrcRpmFile(object): + """Keeps all needed data read from a source rpm""" + def __init__(self, srpmfile): + # Do not required signed packages to be able to import + ts_vsflags = (rpm.RPMVSF_NOMD5HEADER | rpm.RPMVSF_NORSAHEADER | + rpm.RPMVSF_NOSHA1HEADER | rpm.RPMVSF_NODSAHEADER | + rpm.RPMVSF_NOMD5 | rpm.RPMVSF_NORSA | rpm.RPMVSF_NOSHA1 | + rpm.RPMVSF_NODSA) + srpmfp = open(srpmfile) + self.rpmhdr = rpm.ts(vsflags=ts_vsflags).hdrFromFdno(srpmfp.fileno()) + srpmfp.close() + self.srpmfile = os.path.abspath(srpmfile) + (self.orig_file, self.orig_base, self.orig_archive_fmt, self.orig_comp) = self.guess_orig_file() + + def _get_version(self): + """ + Get the (downstream) version of the RPM + """ + version = self.rpmhdr[rpm.RPMTAG_EPOCH] + ":" if self.rpmhdr[rpm.RPMTAG_EPOCH] else "" + version += self.rpmhdr[rpm.RPMTAG_VERSION]+"-"+self.rpmhdr[rpm.RPMTAG_RELEASE] + return version + + version = property(_get_version) + + def _get_name(self): + """ + Get the name of the RPM package + """ + return self.rpmhdr[rpm.RPMTAG_NAME] + name = property(_get_name) + + def _get_upstream_version(self): + """ + Get the upstream version of the package + """ + return self.rpmhdr[rpm.RPMTAG_VERSION] + upstream_version = property(_get_upstream_version) + + def _get_packager(self): + """ + Get the packager of the RPM package + """ + return self.rpmhdr[rpm.RPMTAG_PACKAGER] + packager = property(_get_packager) + + def unpack(self, dest_dir, srctarballdir=None): + """ + Unpack the source rpm to tmpdir, move source tarball to srctallbardir. + Leave the cleanup to the caller in case of an error + """ + gbpc.RunAtCommand('rpm2cpio', + [self.srpmfile, '|', 'cpio', '-id'], + shell=True)(dir=dest_dir) + + # Unpack source tarball + if self.orig_file: + orig_tarball = os.path.join(dest_dir, self.orig_file) + if srctarballdir: + if os.path.isdir(srctarballdir): + shutil.move(orig_tarball, srctarballdir) + else: + raise GbpError, "Src tarball destination dir not found or not a directory" + else: + gbp.log.warn("Failed to detect source tarball. Import may be incorrect") + #raise GbpError, "Failed to detect source tarball" + + def guess_orig_file(self): + """ + Try to guess the name of the primary upstream/source archive + returns a tuple with full file path, filename base, archive format and + compression method. + """ + full_path, base, archive_fmt, comp = None, None, None, None + + for _full_path in self.rpmhdr[rpm.RPMTAG_SOURCE]: + filename = os.path.basename(_full_path) + _base, _archive_fmt, _comp = parse_archive_filename(filename) + if RpmPkgPolicy.is_valid_orig_archive(filename): + if filename.startswith(self.name): + # Take the first archive that starts with pkg name + full_path, base, archive_fmt, comp = _full_path, _base, _archive_fmt, _comp + break + # otherwise we take the first archive + elif not full_path: + full_path, base, archive_fmt, comp = _full_path, _base, _archive_fmt, _comp + # else don't accept + return (full_path, base, archive_fmt, comp) + + +class SpecFile(object): + """Class for parsing/modifying spec files""" + source_re = re.compile(r'^Source(?P[0-9]+)?\s*:\s*(?P[^\s].*[^\s])\s*$', flags=re.I) + patchtag_re = re.compile(r'^Patch(?P[0-9]+)?\s*:\s*(?P\S.*)$', flags=re.I) + patchmacro_re = re.compile(r'^%patch(?P[0-9]+)?(\s+(?P.*))?$') + marker_re = re.compile(r'^#\s+(?P>>|<<)\s+(?Pgbp-[^\s]+)\s*(?P.*)$') + gbptag_re = re.compile(r'^\s*#\s*gbp(?P[a-z]+)\s*:\s*(?P\S.*)\s*$', flags=re.I) + + def __init__(self, specfile, skip_tags=("ExcludeArch", "ExcludeOS", + "ExclusiveArch", "ExclusiveOS", + "BuildArch")): + with tempfile.NamedTemporaryFile(prefix='gbp') as temp: + try: + with open(specfile) as specf: + with open(temp.name, 'w') as filtered: + filtered.writelines(line for line in specf \ + if line.split(":")[0].strip() not in skip_tags) + filtered.flush() + try: + self.specinfo = rpm.spec(temp.name) + except ValueError as err: + raise GbpError("RPM error while parsing spec: %s" % err) + except IOError as err: + raise NoSpecError("Unable to read spec file: %s" % err) + + source_header = self.specinfo.packages[0].header + self.name = source_header[rpm.RPMTAG_NAME] + self.version = source_header[rpm.RPMTAG_VERSION] + self.release = source_header[rpm.RPMTAG_RELEASE] + # rpm-python returns epoch as 'long', convert that to string + self.epoch = str(source_header[rpm.RPMTAG_EPOCH]) \ + if source_header[rpm.RPMTAG_EPOCH] != None else None + self.packager = source_header[rpm.RPMTAG_PACKAGER] + self.specfile = os.path.abspath(specfile) + self.specdir = os.path.dirname(self.specfile) + self.patches = {} + self.sources = {} + + # Load and parse extra info from spec file + f = file(self.specfile) + self.content = f.readlines() + f.close() + loc = self.parse_content() + + # Update sources info (basically possible macros expanded by spec.__init__() + # And, double-check that we parsed spec content correctly + for (name, num, typ) in self.specinfo.sources: + # workaround rpm parsing bug + if num >= MAX_SOURCE_NUMBER: + num = 0 + if typ == 1: + if num in self.sources: + self.sources[num]['filename'] = name + else: + gbp.log.err("BUG: we didn't correctly parse all 'Source' tags!") + if typ == 2: + if num in self.patches: + self.patches[num]['filename'] = name + else: + gbp.log.err("BUG: we didn't correctly parse all 'Patch' tags!") + + (self.orig_file, self.orig_base, self.orig_archive_fmt, self.orig_comp) = self.guess_orig_file() + + @property + def specpath(self): + """Get the dir/filename""" + return os.path.join(self.specdir, self.specfile) + + def write_spec_file(self): + """ + Write, possibly updated, spec to disk + """ + tmpffd, tmpfpath = tempfile.mkstemp(suffix='.spec', dir='.') + tmpf = os.fdopen(tmpffd, 'w') + tmpf.writelines(self.content) + tmpf.close() + + shutil.move(tmpfpath, self.specfile) + + + def parse_content(self): + """ + Go through spec file content line-by-line and (re-)parse info from it + """ + # Check location of "interesting" tags and macros + ret = {'nametag': None, + 'setupmacro': None, + 'prepmacro': None} + + # First, we parse the spec for special git-buildpackage tags, only + ignorepatch = [] + for line in self.content: + m = self.gbptag_re.match(line) + if m: + if m.group('tagname').lower() == 'ignorepatch': + dataitems = m.group('data').strip().split() + ignorepatch = sorted([int(num) for num in dataitems]) + else: + gbp.log.info("Found unrecognized Gbp tag on line %s: '%'" % (i, line)) + + # Remove all autoupdate patches to be sure we're in sync + for n in self.patches.keys(): + if not n in ignorepatch: + del self.patches[n] + + # Parser for patch macros + patchparser = OptionParser() + patchparser.add_option("-p", dest="strip") + patchparser.add_option("-s", dest="silence") + patchparser.add_option("-P", dest="patchnum") + patchparser.add_option("-b", dest="backup") + patchparser.add_option("-E", dest="removeempty") + + numlines = len(self.content) + for i in range(numlines): + line = self.content[i] + + # Find special git-buildpackage tags + m = self.gbptag_re.match(line) + if m: + if m.group('tagname').lower() == 'ignorepatch': + dataitems = m.group('data').strip().split() + ignorepatch = set([int(num) for num in dataitems]) + else: + gbp.log.info("Found unrecognized Gbp tag on line %s: '%'" % (i, line)) + + # Find 'Source' tags + m = self.source_re.match(line) + if m: + if m.group('srcnum'): + srcnum = int(m.group('srcnum')) + else: + srcnum = 0 + if srcnum in self.sources: + self.sources[srcnum]['tag_linenum'] = i + else: + self.sources[srcnum] = {'name': m.group('name'), 'filename': m.group('name'), 'tag_linenum': i} + continue + + # Find 'Patch' tags + m = self.patchtag_re.match(line) + if m: + if m.group('patchnum'): + patchnum = int(m.group('patchnum')) + else: + patchnum = 0 + if patchnum in self.patches: + # For non-autoupdate patches, we only update the line number + if patchnum in ignorepatch: + self.patches[patchnum]['tag_linenum'] = i + else: + gbp.log.err("Patch%s found multiple times, aborting as gbp spec/patch autoupdate likely fails" % patchnum) + raise GbpError, "RPM error while parsing spec, duplicate patches found" + else: + new_patch = {'name': m.group('name').strip(), 'filename': m.group('name'), 'apply': False, 'strip': '0', 'macro_linenum': None, 'autoupdate': not patchnum in ignorepatch, 'tag_linenum': i} + self.patches[patchnum] = new_patch + continue + + # Find patch macros + m = self.patchmacro_re.match(line) + if m: + (options, args) = patchparser.parse_args(m.group('args').split()) + if m.group('patchnum'): + patchnum = int(m.group('patchnum')) + elif options.patchnum: + patchnum = int(options.patchnum) + else: + patchnum = 0 + + if options.strip: + self.patches[patchnum]['strip'] = options.strip + self.patches[patchnum]['macro_linenum'] = i + self.patches[patchnum]['apply'] = True + continue + + # Only search for the last occurrence of the following + if re.match("^\s*Name:.*$", line, flags=re.I): + ret['setupmacro'] = i + if re.match("^%setup(\s.*)?$", line): + ret['setupmacro'] = i + if re.match("^%prep(\s.*)?$", line): + ret['prepmacro'] = i + continue + + return ret + + + def update_patches(self, patchfilenames): + """ + Update spec with new patch tags and patch macros. + """ + loc = self.parse_content() + + # Remove updatable patches and check the max patchnumber of non-autoupdate patches + start_patch_tag_num = 0 + last_ignored_patch_tag_line = 0 + last_ignored_patch_macro_line = 0 + rm_tag_lines = [] + rm_macro_lines = [] + for n in self.patches.keys(): + p = self.patches[n] + if p['autoupdate']: + rm_tag_lines.append(p['tag_linenum']) + # Remove a preceding comment line if it seems to originate from GBP + if re.match("^\s*#.*patch.*auto-generated", self.content[p['tag_linenum']-1], flags=re.I): + rm_tag_lines.append(p['tag_linenum']-1) + if p['macro_linenum']: + rm_macro_lines.append(p['macro_linenum']) + # Take a preceding comment line if it ends with '.patch' or '.diff' + if re.match("^\s*#.+(patch|diff)(\.(gz|bz2|xz|lzma))?\s*$", self.content[p['macro_linenum']-1], flags=re.I): + rm_macro_lines.append(p['macro_linenum']-1) + # Remove autoupdate patches from list of patches + del self.patches[n] + else: + if n >= start_patch_tag_num: + start_patch_tag_num = n + 1 + if p['tag_linenum'] >= last_ignored_patch_tag_line: + last_ignored_patch_tag_line = p['tag_linenum'] + if p['macro_linenum'] and p['macro_linenum'] > last_ignored_patch_macro_line: + last_ignored_patch_macro_line = p['macro_linenum'] + gbp.log.debug("Starting autoupdate patch macro numbering from %s" % start_patch_tag_num) + + rm_tag_lines.sort() + rm_macro_lines.sort() + + # Add new patches + patchnum = start_patch_tag_num + for p in patchfilenames: + self.patches[patchnum] = {'name': p, 'filename': p, 'apply': True, 'strip': '1', 'macro_linenum': None, 'autoupdate': True, 'tag_linenum': None} + patchnum += 1 + + # Determine where to add %patch macro lines + if len(rm_macro_lines): + gbp.log.debug("Will remove patch macro lines %s from spec file" % rm_macro_lines) + linenum = rm_macro_lines[-1] + 1 + elif last_ignored_patch_macro_line: + linenum = last_ignored_patch_macro_line + 1 + elif 'setupmacro' in loc: + gbp.log.info("Didn't find any old '%patch' macros, adding new patches after the last '%setup' macro at line %s") + linenum = loc['setupmacro'] + 1 + else: + gbp.log.warn("Didn't find any old '%patch' macros or %setup macro, adding new patches directly after '%prep' macro at %s.") + linenum = loc['prepmacro'] + 1 + + # Add all patch macro lines to content, in reversed order + for n in reversed(sorted(self.patches.keys())): + patch = self.patches[n] + if patch['autoupdate'] and patch['apply']: + # We're adding from bottom to top... + self.content.insert(linenum, "%%patch%d -p%s\n" % (n, patch['strip'])) + # Use 'name', that is filename with macros not expanded + self.content.insert(linenum, "# %s\n" % patch['name']) + # Remove all old patch macro lines + for l in reversed(rm_macro_lines): + gbp.log.debug("Removing line #%s from spec: '%s'" % (l, self.content[l].strip())) + self.content.pop(l) + + # Determine where to add Patch tag lines + if len(rm_tag_lines): + gbp.log.debug("Will remove patch tag lines %s from spec file" % rm_tag_lines) + linenum = rm_tag_lines[-1] + 1 + elif last_ignored_patch_tag_line: + linenum = last_ignored_patch_tag_line + 1 + elif len(self.sources): + gbp.log.info("Didn't find any old 'Patch' tags, adding new patches after the last 'Source' tag.") + lastsource = sorted(self.sources.keys())[-1] + linenum = self.sources[lastsource]['tag_linenum'] + 1 + else: + gbp.log.info("Didn't find any old 'Patch' or 'Source' tags, adding new patches after the last 'Name' tag.") + linenum = loc['nametag'] + 1 + + # Add all patch tag lines to content, in reversed order + for n in reversed(sorted(self.patches.keys())): + patch = self.patches[n] + if patch['autoupdate']: + # "PatchXYZ:" text 12 chars wide, left aligned + text = "%-12s%s" % ("Patch%d:" % n, patch['name']) + self.content.insert(linenum, text + "\n") + # Finally, add a comment indicating gbp generated patches + self.content.insert(linenum, "# Patches auto-generated by git-buildpackage:\n") + # Remove all old patch tag lines + for l in reversed(rm_tag_lines): + gbp.log.debug("Removing line #%s from spec: '%s'" % (l, self.content[l].strip())) + self.content.pop(l) + + + def patchseries(self): + """ + Return patches of the RPM as a gbp patchseries + """ + series = PatchSeries() + patchdir = os.path.dirname(self.specfile) + for n, p in sorted(self.patches.iteritems()): + if p['autoupdate'] and p['apply']: + series.append(Patch(os.path.join(patchdir, p['filename']), strip = int(p['strip']))) + return series + + + def guess_orig_file(self): + """ + Try to guess the name of the primary upstream/source archive + returns a tuple with full file path, filename base, archive format and + compression method. + """ + full_path, base, archive_fmt, comp = None, None, None, None + + for (num, src) in sorted(self.sources.iteritems()): + _full_path = src['filename'] + filename = os.path.basename(_full_path) + _base, _archive_fmt, _comp = parse_archive_filename(filename) + if filename.startswith(self.name): + # Take the first archive that starts with pkg name + if _archive_fmt: + full_path, base, archive_fmt, comp = _full_path, _base, _archive_fmt, _comp + break + # otherwise we take the first archive + elif not full_path and _archive_fmt: + full_path, base, archive_fmt, comp = _full_path, _base, _archive_fmt, _comp + # else don't accept + + return (full_path, base, archive_fmt, comp) + + +def parse_srpm(srpmfile): + """parse srpm by creating a SrcRpmFile object""" + try: + srcrpm = SrcRpmFile(srpmfile) + except IOError, err: + raise GbpError, "Error reading src.rpm file: %s" % err + except rpm.error, err: + raise GbpError, "RPM error while reading src.rpm: %s" % err + + return srcrpm + + +def parse_spec(specfile): + try: + return SpecFile(specfile) + except IOError, err: + raise GbpError, "Error reading spec file: %s" % err + + +def guess_spec(topdir, recursive=True, preferred_name=None): + """Guess a spec file""" + specs = [] + abstop = os.path.abspath(topdir) + for (root, dirs, files) in os.walk(abstop): + for f in files: + # Stop at the first file matching the preferred name + if f == preferred_name: + gbp.log.debug("Found a preferred spec file: %s in %s" % (f, root)) + specs = [os.path.join(root,f)] + recursive = False + break + if f.endswith(".spec"): + gbp.log.debug("Found spec file: %s in %s" % (f, root)) + specs.append(os.path.join(root,f)) + + if not recursive: + del dirs[:] + # Skip .git dir in any case + if '.git' in dirs: + dirs.remove('.git') + + if len(specs) == 0: + raise NoSpecError("No spec file found.") + elif len(specs) > 1: + filenames = [os.path.relpath(spec, abstop) for spec in specs] + raise NoSpecError("Multiple spec files found (%s), don't know which " + "to use." % ', '.join(filenames)) + return specs[0] + +def guess_spec_repo(repo, branch, packaging_dir): + """ + @todo: implement this + Try to find/parse the spec file from given branch in the git + repository. + """ + raise NoSpecError, "Searching spec from other branch not implemented yet" + + +# vim:et:ts=4:sw=4:et:sts=4:ai:set list listchars=tab\:»·,trail\:·: diff --git a/gbp/rpm/git.py b/gbp/rpm/git.py new file mode 100644 index 00000000..ca1a241b --- /dev/null +++ b/gbp/rpm/git.py @@ -0,0 +1,90 @@ +# vim: set fileencoding=utf-8 : +# +# (C) 2011 Guido Günther +# (C) 2012 Intel Corporation +# This program is free software; you can redistribute it and/or modify +# it under the terms of the GNU General Public License as published by +# the Free Software Foundation; either version 2 of the License, or +# (at your option) any later version. +# +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with this program; if not, write to the Free Software +# Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA +import re + +from gbp.git import GitRepository, GitRepositoryError +from gbp.pkg.pristinetar import PristineTar + +class RpmGitRepository(GitRepository): + """A git repository that holds the source of an RPM package""" + + def __init__(self, path): + super(RpmGitRepository, self).__init__(path) + self.pristine_tar = PristineTar(self) + + def find_version(self, format, version): + """ + Check if a certain version is stored in this repo and return the SHA1 + of the related commit. That is, an annotated tag is dereferenced to the + commit object it points to. + + @param format: tag pattern + @type format: C{str} + @param version: rpm version number + @type version: C{str} + @return: sha1 of the commit the tag references to + """ + tag = self.version_to_tag(format, version) + if self.has_tag(tag): # new tags are injective + # dereference to a commit object + return self.rev_parse("%s^0" % tag) + return None + + @staticmethod + def version_to_tag(format, version): + """Generate a tag from a given format and a version + + >>> RpmGitRepository.version_to_tag("packaging/%(version)s", "0:0~0") + 'packaging/0%0_0' + """ + return format % dict(version=RpmGitRepository._sanitize_version(version)) + + @staticmethod + def _sanitize_version(version): + """sanitize a version so git accepts it as a tag + + >>> RpmGitRepository._sanitize_version("0.0.0") + '0.0.0' + >>> RpmGitRepository._sanitize_version("0.0~0") + '0.0_0' + >>> RpmGitRepository._sanitize_version("0:0.0") + '0%0.0' + >>> RpmGitRepository._sanitize_version("0%0~0") + '0%0_0' + """ + return version.replace('~', '_').replace(':', '%') + + @property + def pristine_tar_branch(self): + """ + The name of the pristine-tar branch, whether it already exists or + not. + """ + return PristineTar.branch + + def has_pristine_tar_branch(self): + """ + Wheter the repo has a I{pristine-tar} branch. + + @return: C{True} if the repo has pristine-tar commits already, C{False} + otherwise + @rtype: C{Bool} + """ + return True if self.has_branch(self.pristine_tar_branch) else False + +# vim:et:ts=4:sw=4:et:sts=4:ai:set list listchars=tab\:»·,trail\:·: diff --git a/gbp/rpm/policy.py b/gbp/rpm/policy.py new file mode 100644 index 00000000..e61a4972 --- /dev/null +++ b/gbp/rpm/policy.py @@ -0,0 +1,69 @@ +# vim: set fileencoding=utf-8 : +# +# (C) 2012 Intel Corporation +# This program is free software; you can redistribute it and/or modify +# it under the terms of the GNU General Public License as published by +# the Free Software Foundation; either version 2 of the License, or +# (at your option) any later version. +# +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with this program; if not, write to the Free Software +# Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA +"""Default packaging policy for RPM""" + +import re +from gbp.pkg import PkgPolicy, parse_archive_filename + +class RpmPkgPolicy(PkgPolicy): + """Packaging policy for RPM""" + + alnum = 'a-zA-Z0-9' + # Valid characters for RPM pkg name + name_whitelist_chars = '._+%{}\-' + # Valid characters for RPM pkg version + version_whitelist_chars = '._+%{}~' + + # Regexp for checking the validity of package name + packagename_re = re.compile("^[%s][%s%s]+$" % + (alnum, alnum, name_whitelist_chars)) + packagename_msg = ("Package names must be at least two characters long, " + "start with an alphanumeric and can only contain " + "alphanumerics or characters in %s" % + list(name_whitelist_chars)) + + # Regexp for checking the validity of package (upstream) version + upstreamversion_re = re.compile("^[0-9][%s%s]*$" % + (alnum, version_whitelist_chars)) + upstreamversion_msg = ("Upstream version numbers must start with a digit " + "and can only containg alphanumerics or characters " + "in %s" % list(version_whitelist_chars)) + + @classmethod + def is_valid_orig_archive(cls, filename): + """ + Is this a valid orig source archive + + @param filename: upstream source archive filename + @type filename: C{str} + @return: true if valid upstream source archive filename + @rtype: C{bool} + + >>> RpmPkgPolicy.is_valid_orig_archive("foo/bar_baz.tar.gz") + True + >>> RpmPkgPolicy.is_valid_orig_archive("foo.bar.tar") + True + >>> RpmPkgPolicy.is_valid_orig_archive("foo.bar") + False + >>> RpmPkgPolicy.is_valid_orig_archive("foo.gz") + False + """ + _base, arch_fmt, _compression = parse_archive_filename(filename) + if arch_fmt: + return True + return False + -- cgit v1.2.3 From 416170b246aea84823f39c5fba3cf0f5d27812d0 Mon Sep 17 00:00:00 2001 From: Markus Lehtonen Date: Mon, 13 Feb 2012 15:01:22 +0200 Subject: config: add rpm-specific option parser class Adds a new GbpOptionParserRpm class for handling rpm-specific options. Signed-off-by: Markus Lehtonen --- gbp/config.py | 12 ++++++++++++ 1 file changed, 12 insertions(+) diff --git a/gbp/config.py b/gbp/config.py index c8f2f803..004befa5 100644 --- a/gbp/config.py +++ b/gbp/config.py @@ -566,4 +566,16 @@ class GbpOptionParserDebian(GbpOptionParser): 'cleaner' : '/bin/true', } ) +class GbpOptionParserRpm(GbpOptionParser): + """ + Handles commandline options and parsing of config files for rpm tools + """ + defaults = dict(GbpOptionParser.defaults) + defaults.update( { + 'builder' : '', + 'cleaner' : '', + } ) + + help = dict(GbpOptionParser.help) + # vim:et:ts=4:sw=4:et:sts=4:ai:set list listchars=tab\:»·,trail\:·: -- cgit v1.2.3 From 04e8876aec4044eddae13cc4f887383943aad2ae Mon Sep 17 00:00:00 2001 From: Markus Lehtonen Date: Tue, 15 Jan 2013 16:28:24 +0200 Subject: gbp-pull: implement --all cmdline option This updates all remote-tracking branches (for the remote that is fetched from) whose local branch name is identical to the remote branch name. Signed-off-by: Markus Lehtonen --- docs/manpages/gbp-pull.sgml | 8 ++++++++ gbp/scripts/pull.py | 25 +++++++++++++++++++++---- 2 files changed, 29 insertions(+), 4 deletions(-) diff --git a/docs/manpages/gbp-pull.sgml b/docs/manpages/gbp-pull.sgml index fd658c8d..de076b7f 100644 --- a/docs/manpages/gbp-pull.sgml +++ b/docs/manpages/gbp-pull.sgml @@ -23,6 +23,7 @@ &man.common.options.synopsis; + @@ -54,6 +55,13 @@ makes you lose your modifications. + + + + Update all remote-tracking branches that have identical name in the + remote repository. + + diff --git a/gbp/scripts/pull.py b/gbp/scripts/pull.py index fb0d8271..b5f79ce3 100755 --- a/gbp/scripts/pull.py +++ b/gbp/scripts/pull.py @@ -56,7 +56,8 @@ def fast_forward_branch(branch, repo, options): gbp.log.info("Non-fast forwarding '%s' due to --force" % branch) update = True else: - gbp.log.warn("Skipping non-fast forward of '%s' - use --force" % branch) + gbp.log.warn("Skipping non-fast forward of '%s' - use --force or " + "update manually" % branch) if update: gbp.log.info("Updating '%s'" % branch) @@ -82,6 +83,9 @@ def build_parser(name): branch_group.add_boolean_config_file_option(option_name = "ignore-branch", dest="ignore_branch") branch_group.add_option("--force", action="store_true", dest="force", default=False, help="force a branch update even if it can't be fast forwarded") + branch_group.add_option("--all", action="store_true", default=False, + help="update all remote-tracking branches that " + "have identical name in the remote") branch_group.add_option("--redo-pq", action="store_true", dest="redo_pq", default=False, help="redo the patch queue branch after a pull. Warning: this drops the old patch-queue branch") branch_group.add_config_file_option(option_name="upstream-branch", dest="upstream_branch") @@ -121,7 +125,7 @@ def main(argv): return 1 try: - branches = [] + branches = set() try: current = repo.get_branch() except GitRepositoryError: @@ -134,10 +138,23 @@ def main(argv): for branch in [ options.debian_branch, options.upstream_branch ]: if repo.has_branch(branch): - branches += [ branch ] + branches.add(branch) if repo.has_pristine_tar_branch() and options.pristine_tar: - branches += [ repo.pristine_tar_branch ] + branches.add(repo.pristine_tar_branch) + + if options.all: + current_remote = repo.get_merge_branch(current) + if current_remote: + fetch_remote = current_remote.split('/')[0] + else: + fetch_remote = 'origin' + for branch in repo.get_local_branches(): + merge_branch = repo.get_merge_branch(branch) + if merge_branch: + rem, rem_br = merge_branch.split('/', 1) + if rem == fetch_remote and branch == rem_br: + branches.add(branch) (ret, out) = repo.is_clean() if not ret: -- cgit v1.2.3 From 581b186b1cf701d0b3681d9a9bca50f9b75c4d52 Mon Sep 17 00:00:00 2001 From: Markus Lehtonen Date: Thu, 12 Jan 2012 15:25:57 +0200 Subject: gbp-pull: similar update strategy for all branches Treat non-checked-out branches similarly to the current branch when forcing update. That is, do git merge, instead of just setting the ref. Also, renames fast_forward_branch() to update_branch() to better match the functionality. Signed-off-by: Markus Lehtonen --- gbp/scripts/pull.py | 13 ++++++++++--- 1 file changed, 10 insertions(+), 3 deletions(-) diff --git a/gbp/scripts/pull.py b/gbp/scripts/pull.py index b5f79ce3..ac2b2cee 100755 --- a/gbp/scripts/pull.py +++ b/gbp/scripts/pull.py @@ -29,7 +29,7 @@ from gbp.git import GitRepositoryError from gbp.deb.git import DebianGitRepository import gbp.log -def fast_forward_branch(branch, repo, options): +def update_branch(branch, repo, options): """ update branch to its remote branch, fail on non fast forward updates unless --force is given @@ -63,10 +63,17 @@ def fast_forward_branch(branch, repo, options): gbp.log.info("Updating '%s'" % branch) if repo.branch == branch: repo.merge(remote) - else: + elif can_fast_forward: sha1 = repo.rev_parse(remote) repo.update_ref("refs/heads/%s" % branch, sha1, msg="gbp: forward %s to %s" % (branch, remote)) + else: + # Merge other branch, if it cannot be fast-forwarded + current_branch=repo.branch + repo.set_branch(branch) + repo.merge(remote) + repo.set_branch(current_branch) + return update @@ -165,7 +172,7 @@ def main(argv): repo.fetch(depth=options.depth) repo.fetch(depth=options.depth, tags=True) for branch in branches: - if not fast_forward_branch(branch, repo, options): + if not update_branch(branch, repo, options): retval = 2 if options.redo_pq: -- cgit v1.2.3 From 61822139169652af0abee3d789d0c4798debe7a0 Mon Sep 17 00:00:00 2001 From: Markus Lehtonen Date: Thu, 12 Jan 2012 15:26:55 +0200 Subject: gbp-pull: two modes for --force The 'force' option now has two possible values: 'merge': upstream branch is merged, even if fast-forward is not possible. 'clean': check out a clean copy from the upstream if fast-forward is not possible (i.e. no merge). Local changes are lost in this case. Signed-off-by: Markus Lehtonen --- docs/manpages/gbp-pull.sgml | 13 ++++++----- gbp/scripts/pull.py | 55 ++++++++++++++++++++++++++++++--------------- 2 files changed, 45 insertions(+), 23 deletions(-) diff --git a/docs/manpages/gbp-pull.sgml b/docs/manpages/gbp-pull.sgml index de076b7f..5c7f258f 100644 --- a/docs/manpages/gbp-pull.sgml +++ b/docs/manpages/gbp-pull.sgml @@ -22,7 +22,7 @@ &gbp-pull; &man.common.options.synopsis; - + [merge|clean] @@ -48,11 +48,14 @@ &man.common.options.description; - + [merge|clean] - force a branch update even if this results in a non fast - forward update. Forcing a branch update - makes you lose your modifications. + Force a branch update even if this results in a non fast + forward update. + merge does a git-merge. + clean checks out a clean copy from upstream. + using clean + makes you lose your modifications. diff --git a/gbp/scripts/pull.py b/gbp/scripts/pull.py index ac2b2cee..b505e6d6 100755 --- a/gbp/scripts/pull.py +++ b/gbp/scripts/pull.py @@ -36,7 +36,7 @@ def update_branch(branch, repo, options): @return: branch updated or already up to date @rtype: boolean """ - update = False + update = None remote = repo.get_merge_branch(branch) if not remote: @@ -50,11 +50,14 @@ def update_branch(branch, repo, options): return True if can_fast_forward: - update = True + update = 'merge' else: - if options.force: - gbp.log.info("Non-fast forwarding '%s' due to --force" % branch) - update = True + if options.force == 'merge': + gbp.log.info("Non-fast forwarding '%s' due to --force=merge" % branch) + update = 'merge' + elif options.force == 'clean': + gbp.log.info("Checking out clean copy of '%s' due to --force=clean" % branch) + update = 'clean' else: gbp.log.warn("Skipping non-fast forward of '%s' - use --force or " "update manually" % branch) @@ -62,19 +65,32 @@ def update_branch(branch, repo, options): if update: gbp.log.info("Updating '%s'" % branch) if repo.branch == branch: - repo.merge(remote) - elif can_fast_forward: - sha1 = repo.rev_parse(remote) - repo.update_ref("refs/heads/%s" % branch, sha1, - msg="gbp: forward %s to %s" % (branch, remote)) + if update == 'merge': + repo.merge(remote) + elif update == 'clean': + # Have to drop our current branch + tmpbranch = "_gbptmp-"+branch + gbp.log.debug("Checking out '%s' to '%s'" % (remote, tmpbranch)) + repo.create_branch(tmpbranch, remote) + gbp.log.debug("Switching current branch to '%s'" % (tmpbranch)) + repo.set_branch(tmpbranch) + gbp.log.debug("Dropping branch '%s'" % branch) + repo.delete_branch(branch) + gbp.log.info("Renaming branch '%s' to '%s'" % (tmpbranch, branch)) + repo.rename_branch(tmpbranch, branch) else: - # Merge other branch, if it cannot be fast-forwarded - current_branch=repo.branch - repo.set_branch(branch) - repo.merge(remote) - repo.set_branch(current_branch) + if can_fast_forward or (update == 'clean'): + sha1 = repo.rev_parse(remote) + repo.update_ref("refs/heads/%s" % branch, sha1, + msg="gbp: forward %s to %s" % (branch, remote)) + elif update == 'merge': + # Merge other branch, if it cannot be fast-forwarded + current_branch=repo.branch + repo.set_branch(branch) + repo.merge(remote) + repo.set_branch(current_branch) - return update + return (update != None) def build_parser(name): @@ -88,8 +104,11 @@ def build_parser(name): branch_group = GbpOptionGroup(parser, "branch options", "branch update and layout options") parser.add_option_group(branch_group) branch_group.add_boolean_config_file_option(option_name = "ignore-branch", dest="ignore_branch") - branch_group.add_option("--force", action="store_true", dest="force", default=False, - help="force a branch update even if it can't be fast forwarded") + branch_group.add_option("--force", action="store", dest="force", + default=None, + help="force a branch update even if it can't be fast " + "forwarded (valid ACTIONs are 'merge', 'clean')", + metavar='ACTION') branch_group.add_option("--all", action="store_true", default=False, help="update all remote-tracking branches that " "have identical name in the remote") -- cgit v1.2.3 From 4c5e0a2ccca453968e7c83b7a3ceca4441241885 Mon Sep 17 00:00:00 2001 From: Markus Lehtonen Date: Thu, 12 Jan 2012 15:35:05 +0200 Subject: Add 'packaging-dir' option to config.py Needed by the upcoming rpm tools. Signed-off-by: Markus Lehtonen --- gbp/config.py | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/gbp/config.py b/gbp/config.py index 004befa5..f64e7908 100644 --- a/gbp/config.py +++ b/gbp/config.py @@ -574,8 +574,13 @@ class GbpOptionParserRpm(GbpOptionParser): defaults.update( { 'builder' : '', 'cleaner' : '', + 'packaging-dir' : '', } ) help = dict(GbpOptionParser.help) + help.update( { + 'packaging-dir': + "subdir where packaging files are stored, default is '%(packaging-dir)s'", + } ) # vim:et:ts=4:sw=4:et:sts=4:ai:set list listchars=tab\:»·,trail\:·: -- cgit v1.2.3 From 127fa79a4189828e528fbbe0b5ac9892cf259c4c Mon Sep 17 00:00:00 2001 From: Markus Lehtonen Date: Thu, 12 Jan 2012 15:35:20 +0200 Subject: Rename internal var debian_branch -> packaging_branch This is done in sake of more general purpose naming, intended for enabling rpm support. Signed-off-by: Markus Lehtonen --- gbp/scripts/buildpackage.py | 6 +++--- gbp/scripts/clone.py | 6 +++--- gbp/scripts/create_remote_repo.py | 4 ++-- gbp/scripts/dch.py | 10 ++++++---- gbp/scripts/import_dsc.py | 16 ++++++++-------- gbp/scripts/import_orig.py | 10 +++++----- gbp/scripts/pull.py | 6 +++--- 7 files changed, 30 insertions(+), 28 deletions(-) mode change 100644 => 100755 gbp/scripts/create_remote_repo.py mode change 100644 => 100755 gbp/scripts/dch.py mode change 100644 => 100755 gbp/scripts/import_dsc.py diff --git a/gbp/scripts/buildpackage.py b/gbp/scripts/buildpackage.py index 83181dcc..9ef37949 100755 --- a/gbp/scripts/buildpackage.py +++ b/gbp/scripts/buildpackage.py @@ -431,7 +431,7 @@ def build_parser(name, prefix=None): orig_group.add_config_file_option(option_name="compression-level", dest="comp_level", help="Compression level, default is '%(compression-level)s'") branch_group.add_config_file_option(option_name="upstream-branch", dest="upstream_branch") - branch_group.add_config_file_option(option_name="debian-branch", dest="debian_branch") + branch_group.add_config_file_option(option_name="debian-branch", dest="packaging_branch") branch_group.add_boolean_config_file_option(option_name = "ignore-branch", dest="ignore_branch") branch_group.add_boolean_config_file_option(option_name = "submodules", dest="with_submodules") cmd_group.add_config_file_option(option_name="builder", dest="builder", @@ -545,8 +545,8 @@ def main(argv): raise if not options.ignore_new and not options.ignore_branch: - if branch != options.debian_branch: - gbp.log.err("You are not on branch '%s' but on '%s'" % (options.debian_branch, branch)) + if branch != options.packaging_branch: + gbp.log.err("You are not on branch '%s' but on '%s'" % (options.packaging_branch, branch)) raise GbpError("Use --git-ignore-branch to ignore or --git-debian-branch to set the branch name.") tree = write_tree(repo, options) diff --git a/gbp/scripts/clone.py b/gbp/scripts/clone.py index 62d0dcc2..209af13b 100755 --- a/gbp/scripts/clone.py +++ b/gbp/scripts/clone.py @@ -43,7 +43,7 @@ def build_parser(name): branch_group.add_option("--all", action="store_true", dest="all", default=False, help="track all branches, not only debian and upstream") branch_group.add_config_file_option(option_name="upstream-branch", dest="upstream_branch") - branch_group.add_config_file_option(option_name="debian-branch", dest="debian_branch") + branch_group.add_config_file_option(option_name="debian-branch", dest="packaging_branch") branch_group.add_boolean_config_file_option(option_name="pristine-tar", dest="pristine_tar") branch_group.add_option("--depth", action="store", dest="depth", default=0, help="git history depth (for creating shallow clones)") @@ -105,7 +105,7 @@ def main(argv): local != "HEAD": repo.create_branch(local, remote) else: # only track gbp's default branches - branches = [ options.debian_branch, options.upstream_branch ] + branches = [ options.packaging_branch, options.upstream_branch ] if options.pristine_tar: branches += [ repo.pristine_tar_branch ] gbp.log.debug('Will track branches: %s' % branches) @@ -115,7 +115,7 @@ def main(argv): not repo.has_branch(branch): repo.create_branch(branch, remote) - repo.set_branch(options.debian_branch) + repo.set_branch(options.packaging_branch) except GitRepositoryError as err: gbp.log.err("Git command failed: %s" % err) diff --git a/gbp/scripts/create_remote_repo.py b/gbp/scripts/create_remote_repo.py old mode 100644 new mode 100755 index f0e680b4..0d2345cd --- a/gbp/scripts/create_remote_repo.py +++ b/gbp/scripts/create_remote_repo.py @@ -245,7 +245,7 @@ def build_parser(name, sections=[]): branch_group.add_config_file_option(option_name="upstream-branch", dest="upstream_branch") branch_group.add_config_file_option(option_name="debian-branch", - dest="debian_branch") + dest="packaging_branch") branch_group.add_boolean_config_file_option(option_name="pristine-tar", dest="pristine_tar") branch_group.add_boolean_config_file_option(option_name="track", @@ -319,7 +319,7 @@ def main(argv): try: branches = [] - for branch in [ options.debian_branch, options.upstream_branch ]: + for branch in [ options.packaging_branch, options.upstream_branch ]: if repo.has_branch(branch): branches += [ branch ] diff --git a/gbp/scripts/dch.py b/gbp/scripts/dch.py old mode 100644 new mode 100755 index c0344805..b5882e62 --- a/gbp/scripts/dch.py +++ b/gbp/scripts/dch.py @@ -308,7 +308,7 @@ def build_parser(name): parser.add_option_group(custom_group) parser.add_boolean_config_file_option(option_name = "ignore-branch", dest="ignore_branch") - naming_group.add_config_file_option(option_name="debian-branch", dest="debian_branch") + naming_group.add_config_file_option(option_name="debian-branch", dest="packaging_branch") naming_group.add_config_file_option(option_name="upstream-tag", dest="upstream_tag") naming_group.add_config_file_option(option_name="debian-tag", dest="debian_tag") naming_group.add_config_file_option(option_name="snapshot-number", dest="snapshot_number", @@ -407,9 +407,11 @@ def main(argv): if not options.ignore_branch: raise - if options.debian_branch != branch and not options.ignore_branch: - gbp.log.err("You are not on branch '%s' but on '%s'" % (options.debian_branch, branch)) - raise GbpError("Use --ignore-branch to ignore or --debian-branch to set the branch name.") + if options.packaging_branch != branch and not options.ignore_branch: + gbp.log.err("You are not on branch '%s' but on '%s'" % + (options.packaging_branch, branch)) + raise GbpError("Use --ignore-branch to ignore or --debian-branch " + "to set the branch name.") source = DebianSource('.') cp = source.changelog diff --git a/gbp/scripts/import_dsc.py b/gbp/scripts/import_dsc.py old mode 100644 new mode 100755 index ffb8a084..1c61dc4d --- a/gbp/scripts/import_dsc.py +++ b/gbp/scripts/import_dsc.py @@ -148,14 +148,14 @@ def apply_debian_patch(repo, unpack_dir, src, options, tag): os.chdir(repo.path) parents = check_parents(repo, - options.debian_branch, + options.packaging_branch, tag) author = get_author_from_changelog(unpack_dir) committer = get_committer_from_author(author, options) commit = repo.commit_dir(unpack_dir, "Imported Debian patch %s" % src.version, - branch = options.debian_branch, + branch = options.packaging_branch, other_parents = parents, author=author, committer=committer) @@ -232,7 +232,7 @@ def build_parser(name): parser.add_option("--download", action="store_true", dest="download", default=False, help="download source package") branch_group.add_config_file_option(option_name="debian-branch", - dest="debian_branch") + dest="packaging_branch") branch_group.add_config_file_option(option_name="upstream-branch", dest="upstream_branch") branch_group.add_boolean_config_file_option(option_name="create-missing-branches", @@ -353,7 +353,7 @@ def main(argv): branch = None else: branch = [options.upstream_branch, - options.debian_branch][src.native] + options.packaging_branch][src.native] if not repo.has_branch(branch): if options.create_missing_branches: gbp.log.info("Creating missing branch '%s'" % branch) @@ -386,18 +386,18 @@ def main(argv): repo.create_branch(options.upstream_branch, commit) if options.pristine_tar: repo.pristine_tar.commit(src.tgz, options.upstream_branch) - if (not repo.has_branch(options.debian_branch) + if (not repo.has_branch(options.packaging_branch) and (is_empty or options.create_missing_branches)): - repo.create_branch(options.debian_branch, commit) + repo.create_branch(options.packaging_branch, commit) if not src.native: if src.diff or src.deb_tgz: apply_debian_patch(repo, upstream.unpacked, src, options, tag) else: gbp.log.warn("Didn't find a diff to apply.") - if repo.get_branch() == options.debian_branch or is_empty: + if repo.get_branch() == options.packaging_branch or is_empty: # Update HEAD if we modified the checked out branch - repo.force_head(options.debian_branch, hard=True) + repo.force_head(options.packaging_branch, hard=True) except KeyboardInterrupt: ret = 1 gbp.log.err("Interrupted. Aborting.") diff --git a/gbp/scripts/import_orig.py b/gbp/scripts/import_orig.py index 7cebd1c8..78bbf476 100644 --- a/gbp/scripts/import_orig.py +++ b/gbp/scripts/import_orig.py @@ -54,7 +54,7 @@ def detect_name_and_version(repo, source, options): # Check the changelog file from the repository, in case # we're not on the debian-branch (but upstream, for # example). - cp = parse_changelog_repo(repo, options.debian_branch, 'debian/changelog') + cp = parse_changelog_repo(repo, options.packaging_branch, 'debian/changelog') sourcepackage = cp['Source'] except NoChangeLogError: if options.interactive: @@ -164,7 +164,7 @@ def build_parser(name): branch_group.add_option("-u", "--upstream-version", dest="version", help="Upstream Version") branch_group.add_config_file_option(option_name="debian-branch", - dest="debian_branch") + dest="packaging_branch") branch_group.add_config_file_option(option_name="upstream-branch", dest="upstream_branch") branch_group.add_option("--upstream-vcs-tag", dest="vcs_tag", @@ -314,8 +314,8 @@ def main(argv): repo.create_branch(options.upstream_branch, rev=commit) repo.force_head(options.upstream_branch, hard=True) elif options.merge: - gbp.log.info("Merging to '%s'" % options.debian_branch) - repo.set_branch(options.debian_branch) + gbp.log.info("Merging to '%s'" % options.packaging_branch) + repo.set_branch(options.packaging_branch) try: repo.merge(tag) except GitRepositoryError: @@ -330,7 +330,7 @@ def main(argv): if cp.has_epoch(): epoch = '%s:' % cp.epoch info = { 'version': "%s%s-1" % (epoch, version) } - env = { 'GBP_BRANCH': options.debian_branch } + env = { 'GBP_BRANCH': options.packaging_branch } gbpc.Command(options.postimport % info, extra_env=env, shell=True)() # Update working copy and index if we've possibly updated the # checked out branch diff --git a/gbp/scripts/pull.py b/gbp/scripts/pull.py index b505e6d6..85328b4e 100755 --- a/gbp/scripts/pull.py +++ b/gbp/scripts/pull.py @@ -115,7 +115,7 @@ def build_parser(name): branch_group.add_option("--redo-pq", action="store_true", dest="redo_pq", default=False, help="redo the patch queue branch after a pull. Warning: this drops the old patch-queue branch") branch_group.add_config_file_option(option_name="upstream-branch", dest="upstream_branch") - branch_group.add_config_file_option(option_name="debian-branch", dest="debian_branch") + branch_group.add_config_file_option(option_name="debian-branch", dest="packaging_branch") branch_group.add_boolean_config_file_option(option_name="pristine-tar", dest="pristine_tar") branch_group.add_option("--depth", action="store", dest="depth", default=0, help="git history depth (for deepening shallow clones)") @@ -162,7 +162,7 @@ def main(argv): else: raise - for branch in [ options.debian_branch, options.upstream_branch ]: + for branch in [ options.packaging_branch, options.upstream_branch ]: if repo.has_branch(branch): branches.add(branch) @@ -195,7 +195,7 @@ def main(argv): retval = 2 if options.redo_pq: - repo.set_branch(options.debian_branch) + repo.set_branch(options.packaging_branch) Command("gbp-pq")(["drop"]) Command("gbp-pq")(["import"]) -- cgit v1.2.3 From 73e41dcc18c07f017a67e3c4bf8fa085d866d565 Mon Sep 17 00:00:00 2001 From: Markus Lehtonen Date: Thu, 12 Jan 2012 15:35:37 +0200 Subject: Add 'packaging-branch' cmdline option This is the counterpart of 'debian-branch' (basically identical to that) to not confuse rpm maintainers. Also, adds this option to gbp-clone and gbp-pull commands (as an alternative to the 'debian-branch option), which are usable for RPM in their current form. Signed-off-by: Markus Lehtonen --- docs/manpages/gbp-clone.sgml | 13 ++++++++++++- docs/manpages/gbp-pull.sgml | 13 ++++++++++++- gbp/config.py | 5 +++++ gbp/scripts/clone.py | 1 + gbp/scripts/pull.py | 1 + 5 files changed, 31 insertions(+), 2 deletions(-) diff --git a/docs/manpages/gbp-clone.sgml b/docs/manpages/gbp-clone.sgml index 20e61472..49418ac7 100644 --- a/docs/manpages/gbp-clone.sgml +++ b/docs/manpages/gbp-clone.sgml @@ -24,7 +24,10 @@ &man.common.options.synopsis; - branch_name + + branch_name + branch_name + branch_name depth remote_uri @@ -61,6 +64,14 @@ developed on, default is master. + + =branch_name + + + The branch the packaging is being maintained on. + Alternative to the --debian-branch option. + + =branch_name diff --git a/docs/manpages/gbp-pull.sgml b/docs/manpages/gbp-pull.sgml index 5c7f258f..74ff37ce 100644 --- a/docs/manpages/gbp-pull.sgml +++ b/docs/manpages/gbp-pull.sgml @@ -27,7 +27,10 @@ - branch_name + + branch_name + branch_name + branch_name depth @@ -87,6 +90,14 @@ developed on, default is master. + + =branch_name + + + The branch the packaging is being maintained on. + Alternative to the --debian-branch option. + + =branch_name diff --git a/gbp/config.py b/gbp/config.py index f64e7908..9da847fd 100644 --- a/gbp/config.py +++ b/gbp/config.py @@ -94,6 +94,7 @@ class GbpOptionParser(OptionParser): @type def_config_files: list """ defaults = { 'debian-branch' : 'master', + 'packaging-branch' : 'master', 'upstream-branch' : 'upstream', 'upstream-tree' : 'TAG', 'pristine-tar' : 'False', @@ -165,6 +166,10 @@ class GbpOptionParser(OptionParser): 'debian-branch': ("Branch the Debian package is being developed on, " "default is '%(debian-branch)s'"), + 'packaging-branch': + ("Branch the packaging is being maintained on, " + "rpm counterpart of the 'debian-branch' option, " + "default is '%(packaging-branch)s'"), 'upstream-branch': "Upstream branch, default is '%(upstream-branch)s'", 'upstream-tree': diff --git a/gbp/scripts/clone.py b/gbp/scripts/clone.py index 209af13b..e903810c 100755 --- a/gbp/scripts/clone.py +++ b/gbp/scripts/clone.py @@ -44,6 +44,7 @@ def build_parser(name): help="track all branches, not only debian and upstream") branch_group.add_config_file_option(option_name="upstream-branch", dest="upstream_branch") branch_group.add_config_file_option(option_name="debian-branch", dest="packaging_branch") + branch_group.add_config_file_option(option_name="packaging-branch", dest="packaging_branch") branch_group.add_boolean_config_file_option(option_name="pristine-tar", dest="pristine_tar") branch_group.add_option("--depth", action="store", dest="depth", default=0, help="git history depth (for creating shallow clones)") diff --git a/gbp/scripts/pull.py b/gbp/scripts/pull.py index 85328b4e..45718053 100755 --- a/gbp/scripts/pull.py +++ b/gbp/scripts/pull.py @@ -116,6 +116,7 @@ def build_parser(name): help="redo the patch queue branch after a pull. Warning: this drops the old patch-queue branch") branch_group.add_config_file_option(option_name="upstream-branch", dest="upstream_branch") branch_group.add_config_file_option(option_name="debian-branch", dest="packaging_branch") + branch_group.add_config_file_option(option_name="packaging-branch", dest="packaging_branch") branch_group.add_boolean_config_file_option(option_name="pristine-tar", dest="pristine_tar") branch_group.add_option("--depth", action="store", dest="depth", default=0, help="git history depth (for deepening shallow clones)") -- cgit v1.2.3 From ea44812a7ccf06abcbecdb034004a13f627aabce Mon Sep 17 00:00:00 2001 From: Markus Lehtonen Date: Thu, 12 Jan 2012 15:35:49 +0200 Subject: Rename internal var debian_tag -> packaging_tag This is done in sake of more general purpose naming, intended for enabling rpm support: to allow logical naming for rpm and to share as much code between debian and rpm tools as possible. Signed-off-by: Markus Lehtonen --- gbp/scripts/buildpackage.py | 4 ++-- gbp/scripts/dch.py | 6 +++--- gbp/scripts/import_dsc.py | 16 ++++++++-------- 3 files changed, 13 insertions(+), 13 deletions(-) diff --git a/gbp/scripts/buildpackage.py b/gbp/scripts/buildpackage.py index 9ef37949..a92e7ca8 100755 --- a/gbp/scripts/buildpackage.py +++ b/gbp/scripts/buildpackage.py @@ -414,7 +414,7 @@ def build_parser(name, prefix=None): help="don't fail if the tag already exists") tag_group.add_boolean_config_file_option(option_name="sign-tags", dest="sign_tags") tag_group.add_config_file_option(option_name="keyid", dest="keyid") - tag_group.add_config_file_option(option_name="debian-tag", dest="debian_tag") + tag_group.add_config_file_option(option_name="debian-tag", dest="packaging_tag") tag_group.add_config_file_option(option_name="upstream-tag", dest="upstream_tag") orig_group.add_config_file_option(option_name="upstream-tree", dest="upstream_tree") orig_group.add_boolean_config_file_option(option_name="pristine-tar", dest="pristine_tar") @@ -616,7 +616,7 @@ def main(argv): 'GBP_BUILD_DIR': build_dir})() if options.tag or options.tag_only: gbp.log.info("Tagging %s" % source.changelog.version) - tag = repo.version_to_tag(options.debian_tag, source.changelog.version) + tag = repo.version_to_tag(options.packaging_tag, source.changelog.version) if options.retag and repo.has_tag(tag): repo.delete_tag(tag) repo.create_tag(name=tag, diff --git a/gbp/scripts/dch.py b/gbp/scripts/dch.py index b5882e62..0cf2e452 100755 --- a/gbp/scripts/dch.py +++ b/gbp/scripts/dch.py @@ -310,7 +310,7 @@ def build_parser(name): parser.add_boolean_config_file_option(option_name = "ignore-branch", dest="ignore_branch") naming_group.add_config_file_option(option_name="debian-branch", dest="packaging_branch") naming_group.add_config_file_option(option_name="upstream-tag", dest="upstream_tag") - naming_group.add_config_file_option(option_name="debian-tag", dest="debian_tag") + naming_group.add_config_file_option(option_name="debian-tag", dest="packaging_tag") naming_group.add_config_file_option(option_name="snapshot-number", dest="snapshot_number", help="expression to determine the next snapshot number, default is '%(snapshot-number)s'") parser.add_config_file_option(option_name="git-log", dest="git_log", @@ -421,7 +421,7 @@ def main(argv): else: since = '' if options.auto: - since = guess_documented_commit(cp, repo, options.debian_tag) + since = guess_documented_commit(cp, repo, options.packaging_tag) if since: msg = "Continuing from commit '%s'" % since else: @@ -429,7 +429,7 @@ def main(argv): gbp.log.info(msg) found_snapshot_banner = has_snapshot_banner(cp) else: # Fallback: continue from last tag - since = repo.find_version(options.debian_tag, cp['Version']) + since = repo.find_version(options.packaging_tag, cp['Version']) if not since: raise GbpError("Version %s not found" % cp['Version']) diff --git a/gbp/scripts/import_dsc.py b/gbp/scripts/import_dsc.py index 1c61dc4d..e6f72105 100755 --- a/gbp/scripts/import_dsc.py +++ b/gbp/scripts/import_dsc.py @@ -159,8 +159,8 @@ def apply_debian_patch(repo, unpack_dir, src, options, tag): other_parents = parents, author=author, committer=committer) - if not options.skip_debian_tag: - repo.create_tag(repo.version_to_tag(options.debian_tag, src.version), + if not options.skip_packaging_tag: + repo.create_tag(repo.version_to_tag(options.packaging_tag, src.version), msg="Debian release %s" % src.version, commit=commit, sign=options.sign_tags, @@ -243,10 +243,10 @@ def build_parser(name): tag_group.add_config_file_option(option_name="keyid", dest="keyid") tag_group.add_config_file_option(option_name="debian-tag", - dest="debian_tag") + dest="packaging_tag") tag_group.add_config_file_option(option_name="upstream-tag", dest="upstream_tag") - tag_group.add_option("--skip-debian-tag",dest="skip_debian_tag", + tag_group.add_option("--skip-debian-tag",dest="skip_packaging_tag", action="store_true", default=False, help="Don't add a tag after importing the Debian patch") @@ -335,15 +335,15 @@ def main(argv): upstream = DebianUpstreamSource(src.tgz) upstream = upstream.unpack(dirs['tmp'], options.filters) - format = [(options.upstream_tag, "Upstream"), (options.debian_tag, "Debian")][src.native] + format = [(options.upstream_tag, "Upstream"), (options.packaging_tag, "Debian")][src.native] tag = repo.version_to_tag(format[0], src.upstream_version) msg = "%s version %s" % (format[1], src.upstream_version) - if repo.find_version(options.debian_tag, src.version): + if repo.find_version(options.packaging_tag, src.version): gbp.log.warn("Version %s already imported." % src.version) if options.allow_same_version: gbp.log.info("Moving tag of version '%s' since import forced" % src.version) - move_tag_stamp(repo, options.debian_tag, src.version) + move_tag_stamp(repo, options.packaging_tag, src.version) else: raise SkipImport @@ -375,7 +375,7 @@ def main(argv): author=author, committer=committer) - if not (src.native and options.skip_debian_tag): + if not (src.native and options.skip_packaging_tag): repo.create_tag(name=tag, msg=msg, commit=commit, -- cgit v1.2.3 From cc11663d913ff75777686b52d7759c6805199b82 Mon Sep 17 00:00:00 2001 From: Markus Lehtonen Date: Thu, 12 Jan 2012 15:36:10 +0200 Subject: Add 'packaging-tag' option to config.py This is the counterpart of 'debian-tag' (basically identical to that) to not confuse rpm maintainers. Signed-off-by: Markus Lehtonen --- gbp/config.py | 3 +++ 1 file changed, 3 insertions(+) diff --git a/gbp/config.py b/gbp/config.py index 9da847fd..27fe6288 100644 --- a/gbp/config.py +++ b/gbp/config.py @@ -580,12 +580,15 @@ class GbpOptionParserRpm(GbpOptionParser): 'builder' : '', 'cleaner' : '', 'packaging-dir' : '', + 'packaging-tag' : 'packaging/%(version)s', } ) help = dict(GbpOptionParser.help) help.update( { 'packaging-dir': "subdir where packaging files are stored, default is '%(packaging-dir)s'", + 'packaging-tag': + "format string for packaging tags, rpm counterpart of the 'debian-tag' option, default is '%(packaging-tag)s'", } ) # vim:et:ts=4:sw=4:et:sts=4:ai:set list listchars=tab\:»·,trail\:·: -- cgit v1.2.3 From 103d54aa93faaa47f6dbef28e9a794b0c1255e1b Mon Sep 17 00:00:00 2001 From: Markus Lehtonen Date: Thu, 12 Jan 2012 15:37:49 +0200 Subject: Introduce git-import-srpm tool Initial version of the git-import-srpm: a tool for importing source rpms. Unit tests: created a separate method in TestHelp for RPM-specific commands. Signed-off-by: Markus Lehtonen Signed-off-by: Ed Bartosh --- bin/git-import-srpm | 5 + gbp/scripts/import_srpm.py | 425 +++++++++++++++++++++++++++++++++++++++++++++ setup.py | 3 +- tests/01_test_help.py | 9 + 4 files changed, 441 insertions(+), 1 deletion(-) create mode 100755 bin/git-import-srpm create mode 100755 gbp/scripts/import_srpm.py diff --git a/bin/git-import-srpm b/bin/git-import-srpm new file mode 100755 index 00000000..721741b7 --- /dev/null +++ b/bin/git-import-srpm @@ -0,0 +1,5 @@ +#! /usr/bin/python -u +import sys +from gbp.scripts.import_srpm import main + +sys.exit(main(sys.argv)) diff --git a/gbp/scripts/import_srpm.py b/gbp/scripts/import_srpm.py new file mode 100755 index 00000000..999373eb --- /dev/null +++ b/gbp/scripts/import_srpm.py @@ -0,0 +1,425 @@ +# vim: set fileencoding=utf-8 : +# +# (C) 2006,2007,2011 Guido Guenther +# (C) 2012 Intel Corporation +# This program is free software; you can redistribute it and/or modify +# it under the terms of the GNU General Public License as published by +# the Free Software Foundation; either version 2 of the License, or +# (at your option) any later version. +# +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with this program; if not, write to the Free Software +# Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA +"""Import an RPM source package into a git repository""" + +import ConfigParser +import sys +import re +import os +import tempfile +import glob +import pipes +import time +import shutil +import errno +import urllib2 + +import gbp.command_wrappers as gbpc +from gbp.rpm import (parse_srpm, SrcRpmFile, SpecFile, guess_spec, NoSpecError, + parse_spec, RpmUpstreamSource) +from gbp.rpm.git import (RpmGitRepository, GitRepositoryError) +from gbp.git.modifier import GitModifier +from gbp.config import GbpOptionParserRpm, GbpOptionGroup, no_upstream_branch_msg +from gbp.errors import GbpError +import gbp.log + +no_packaging_branch_msg = """ +Repository does not have branch '%s' for packaging/distribution sources. If there is none see +file:///usr/share/doc/git-buildpackage/manual-html/gbp.import.html#GBP.IMPORT.CONVERT +on howto create it otherwise use --packaging-branch to specify it. +""" + + +class SkipImport(Exception): + pass + + +def download_file(target_dir, url): + """Download a remote file""" + gbp.log.info("Downloading '%s'..." % url) + try: + urlobj = urllib2.urlopen(url) + local_fn = os.path.join(target_dir, os.path.basename(url)) + with open(local_fn, "wb") as local_file: + local_file.write(urlobj.read()) + except urllib2.HTTPError as err: + raise GbpError("Download failed: %s" % err) + except urllib2.URLError as err: + raise GbpError("Download failed: %s" % err.reason) + return local_fn + +def download_source(pkg, dirs): + if re.match(r'[a-z]{1,5}://', pkg): + mode = 'python urllib2' + else: + mode = 'yumdownloader' + + dirs['download'] = os.path.abspath(tempfile.mkdtemp()) + gbp.log.info("Trying to download '%s' using '%s'..." % (pkg, mode)) + if mode == 'yumdownloader': + gbpc.RunAtCommand('yumdownloader', + ['--source', '--destdir=', '.', pkg], + shell=False)(dir=dirs['download']) + else: + download_file(dirs['download'], pkg) + srpm = glob.glob(os.path.join(dirs['download'], '*.src.rpm'))[0] + return srpm + + +def committer_from_author(author, options): + """Get committer info based on options""" + committer = GitModifier() + if options.author_is_committer: + committer.name = author.name + committer.email = author.email + return committer + + +def move_tag_stamp(repo, format, version): + "Move tag out of the way appending the current timestamp" + old = repo.version_to_tag(format, version) + timestamped = "%s~%s" % (version, int(time.time())) + new = repo.version_to_tag(format, timestamped) + repo.move_tag(old, new) + + +def set_bare_repo_options(options): + """Modify options for import into a bare repository""" + if options.pristine_tar: + gbp.log.info("Bare repository: setting %s option" + % (["", " '--no-pristine-tar'"][options.pristine_tar], )) + options.pristine_tar = False + + +def parse_args(argv): + try: + parser = GbpOptionParserRpm(command=os.path.basename(argv[0]), prefix='', + usage='%prog [options] /path/to/package.src.rpm') + except ConfigParser.ParsingError, err: + gbp.log.err(err) + return None, None + + import_group = GbpOptionGroup(parser, "import options", + "pristine-tar and filtering") + tag_group = GbpOptionGroup(parser, "tag options", + "options related to git tag creation") + branch_group = GbpOptionGroup(parser, "version and branch naming options", + "version number and branch layout options") + + for group in [import_group, branch_group, tag_group ]: + parser.add_option_group(group) + + parser.add_option("-v", "--verbose", action="store_true", dest="verbose", default=False, + help="verbose command execution") + parser.add_config_file_option(option_name="color", dest="color", type='tristate') + parser.add_option("--download", action="store_true", dest="download", default=False, + help="download source package") + branch_group.add_config_file_option(option_name="packaging-branch", + dest="packaging_branch") + branch_group.add_config_file_option(option_name="upstream-branch", + dest="upstream_branch") + branch_group.add_boolean_config_file_option(option_name="create-missing-branches", + dest="create_missing_branches") + branch_group.add_option("--orphan-packaging", action="store_true", + dest="orphan_packaging", default=False, + help="The packaging branch doesn't base on upstream") + branch_group.add_option("--native", action="store_true", + dest="native", default=False, + help="This is a dist native package, no separate upstream branch") + + tag_group.add_boolean_config_file_option(option_name="sign-tags", + dest="sign_tags") + tag_group.add_config_file_option(option_name="keyid", + dest="keyid") + tag_group.add_config_file_option(option_name="packaging-tag", + dest="packaging_tag") + tag_group.add_config_file_option(option_name="upstream-tag", + dest="upstream_tag") + + import_group.add_config_file_option(option_name="filter", + dest="filters", action="append") + import_group.add_boolean_config_file_option(option_name="pristine-tar", + dest="pristine_tar") + import_group.add_option("--allow-same-version", action="store_true", + dest="allow_same_version", default=False, + help="allow to import already imported version") + import_group.add_boolean_config_file_option(option_name="author-is-committer", + dest="author_is_committer") + import_group.add_config_file_option(option_name="packaging-dir", + dest="packaging_dir") + (options, args) = parser.parse_args(argv[1:]) + gbp.log.setup(options.color, options.verbose) + return options, args + + +def main(argv): + dirs = dict(top=os.path.abspath(os.curdir)) + needs_repo = False + ret = 0 + skipped = False + parents = None + + options, args = parse_args(argv) + + try: + if len(args) != 1: + gbp.log.err("Need to give exactly one package to import. Try --help.") + raise GbpError + else: + pkg = args[0] + if options.download: + srpm = download_source(pkg, dirs=dirs) + else: + srpm = pkg + + if os.path.isdir(pkg) or pkg.endswith(".spec"): + if os.path.isdir(pkg): + gbp.log.debug("Trying to import an unpacked srpm from '%s'" % pkg) + dirs['src'] = os.path.abspath(pkg) + spec = parse_spec(guess_spec(pkg, True)) + else: + gbp.log.debug("Trying to import an srpm from '%s' with spec file '%s'" % (os.path.dirname(pkg), pkg)) + dirs['src'] = os.path.abspath(os.path.dirname(pkg)) + spec = parse_spec(pkg) + + pkgname = spec.name + pkgver = "%s-%s" % (spec.version, spec.release) + upstream_version = spec.version + packager = spec.packager + unpacked = True + else: + gbp.log.debug("Trying to import an source rpm '%s'" % srpm) + dirs['src'] = os.path.abspath(os.path.dirname(pkg)) + src = parse_srpm(srpm) + pkgname = src.name + pkgver = src.version + upstream_version = src.upstream_version + packager = src.packager + unpacked = False + + try: + repo = RpmGitRepository('.') + is_empty = repo.is_empty() + + (clean, out) = repo.is_clean() + if not clean and not is_empty: + gbp.log.err("Repository has uncommitted changes, commit these first: ") + raise GbpError, out + + except GitRepositoryError: + # no repo found, create one + needs_repo = True + is_empty = True + + if needs_repo: + gbp.log.info("No git repository found, creating one.") + repo = RpmGitRepository.create(pkgname) + os.chdir(repo.path) + + if repo.bare: + set_bare_repo_options(options) + + dirs['pkgextract'] = os.path.abspath(tempfile.mkdtemp(dir='..')) + dirs['pkgextract-packaging'] = os.path.join(dirs['pkgextract'], options.packaging_dir) + try: + os.mkdir(dirs['pkgextract-packaging']) + except OSError, (e, emsg): + if e == errno.EEXIST: + pass + dirs['srctarball'] = os.path.abspath(tempfile.mkdtemp(dir='..')) + dirs['srcunpack'] = os.path.abspath(tempfile.mkdtemp(dir='..')) + + orig_tarball = None + if unpacked: + files = [os.path.basename(patch['filename']) for patch in spec.patches.itervalues()] + for src in spec.sources.itervalues(): + if src['filename'] != spec.orig_file: + files.append(src['filename']) + files.append(spec.specfile) + for fname in files: + fpath = os.path.join(dirs['src'], fname) + if os.path.exists(fpath): + shutil.copy2(fpath, dirs['pkgextract-packaging']) + else: + gbp.log.err("File '%s' listed in spec not found" % fname) + raise GbpError + if spec.orig_base: + orig_tarball=os.path.join(dirs['src'], os.path.basename(spec.orig_file)) + else: + gbp.log.info("Extracting src rpm...") + src.unpack(dirs['pkgextract-packaging'], dirs['srctarball']) + if src.orig_file: + orig_tarball = os.path.join(dirs['srctarball'], src.orig_file) + + if orig_tarball: + upstream = RpmUpstreamSource(orig_tarball) + upstream = upstream.unpack(dirs['srcunpack'], options.filters) + else: + upstream = None + + format = [(options.upstream_tag, "Upstream"), (options.packaging_tag, "Distribution")][options.native] + tag = repo.version_to_tag(format[0], upstream_version) + + if repo.find_version(options.packaging_tag, pkgver): + gbp.log.warn("Version %s already imported." % pkgver) + if options.allow_same_version: + gbp.log.info("Moving tag of version '%s' since import forced" % pkgver) + move_tag_stamp(repo, options.packaging_tag, pkgver) + else: + raise SkipImport + + if is_empty: + options.create_missing_branches = True + + # Determine author and committer info, currently same info is used + # for both upstream sources and packaging files + author=None + if packager: + match = re.match('(?P.*[^ ])\s*<(?P\S*)>', packager.strip()) + if match: + author=GitModifier(match.group('name'), match.group('email')) + if not author: + author=GitModifier() + gbp.log.debug("Couldn't determine packager info") + committer = committer_from_author(author, options) + + # Import upstream sources + if upstream: + upstream_commit = repo.find_version(format[0], upstream_version) + if not upstream_commit: + gbp.log.info("Tag %s not found, importing %s tarball" % (tag, format[1])) + + branch = [options.upstream_branch, + options.packaging_branch][options.native] + if not repo.has_branch(branch): + if options.create_missing_branches: + gbp.log.info("Will create missing branch '%s'" % branch) + else: + gbp.log.err(no_upstream_branch_msg % branch + + "\nAlso check the --create-missing-branches option.") + raise GbpError + + msg = "%s version %s" % (format[1], upstream_version) + upstream_commit = repo.commit_dir(upstream.unpacked, + "Imported %s" % msg, + branch, + author=author, + committer=committer, + create_missing_branch=options.create_missing_branches) + repo.create_tag(name=tag, + msg=msg, + commit=upstream_commit, + sign=options.sign_tags, + keyid=options.keyid) + + if not options.native: + if options.pristine_tar: + repo.pristine_tar.commit(orig_tarball, 'refs/heads/%s' % options.upstream_branch) + parents = [ options.upstream_branch ] + else: + gbp.log.info("No source tarball imported") + + if not options.native or not upstream: + # Import packaging files + gbp.log.info("Importing packaging files...") + branch = options.packaging_branch + if not repo.has_branch(branch): + if options.create_missing_branches: + gbp.log.info("Will create missing branch '%s'" % branch) + else: + gbp.log.err(no_packaging_branch_msg % branch + + "\nAlso check the --create-missing-branches option.") + raise GbpError + + tag = repo.version_to_tag(options.packaging_tag, pkgver) + msg = "Distribution release %s" % pkgver + + if options.orphan_packaging or not upstream: + parents = [] + commit = repo.commit_dir(dirs['pkgextract'], + "Imported %s" % msg, + branch, + author=author, + committer=committer, + create_missing_branch=options.create_missing_branches) + else: + # Copy packaging files to the unpacked sources dir + try: + pkgsubdir = os.path.join(upstream.unpacked, options.packaging_dir) + os.mkdir(pkgsubdir) + except OSError, (e, emsg): + if e == errno.EEXIST: + pass + else: + raise + for f in os.listdir(dirs['pkgextract-packaging']): + shutil.copy2(os.path.join(dirs['pkgextract-packaging'], f), + pkgsubdir) + commit = repo.commit_dir(upstream.unpacked, + "Imported %s" % msg, + branch, + other_parents=[upstream_commit], + author=author, + committer=committer, + create_missing_branch=options.create_missing_branches) + + repo.create_tag(name=tag, + msg=msg, + commit=commit, + sign=options.sign_tags, + keyid=options.keyid) + + if repo.get_branch() == options.packaging_branch: + # Update HEAD if we modified the checked out branch + repo.force_head(options.packaging_branch, hard=True) + # Checkout packaging branch + repo.set_branch(options.packaging_branch) + + + except KeyboardInterrupt: + ret = 1 + gbp.log.err("Interrupted. Aborting.") + except gbpc.CommandExecFailed: + ret = 1 + except GitRepositoryError, msg: + gbp.log.err("Git command failed: %s" % msg) + ret = 1 + except GbpError, err: + if len(err.__str__()): + gbp.log.err(err) + ret = 1 + except NoSpecError, err: + gbp.log.err("Failed determine spec file (%s)" % err) + ret = 1 + except SkipImport: + skipped = True + finally: + os.chdir(dirs['top']) + + for d in [ 'pkgextract', 'srctarball', 'srcunpack', 'download' ]: + if dirs.has_key(d): + gbpc.RemoveTree(dirs[d])() + + if not ret and not skipped: + gbp.log.info("Version '%s' imported under '%s'" % (pkgver, pkgname)) + return ret + +if __name__ == '__main__': + sys.exit(main(sys.argv)) + +# vim:et:ts=4:sw=4:et:sts=4:ai:set list listchars=tab\:»·,trail\:·: diff --git a/setup.py b/setup.py index fb6f6245..fdbb1e56 100644 --- a/setup.py +++ b/setup.py @@ -55,7 +55,8 @@ setup(name = "gbp", 'bin/gbp-pull', 'bin/gbp-clone', 'bin/gbp-create-remote-repo', - 'bin/git-pbuilder'], + 'bin/git-pbuilder', + 'bin/git-import-srpm'], packages = find_packages(exclude=['tests', 'tests.*']), data_files = [("/etc/git-buildpackage/", ["gbp.conf"]),], setup_requires=['nose>=0.11.1', 'coverage>=2.85', 'nosexcover>=1.0.7'] if \ diff --git a/tests/01_test_help.py b/tests/01_test_help.py index 673d8708..331d7cc6 100644 --- a/tests/01_test_help.py +++ b/tests/01_test_help.py @@ -25,4 +25,13 @@ class TestHelp(unittest.TestCase): m.main, ['doesnotmatter', '--help']) + """Test help output of RPM-specific commands""" + def testHelpRpm(self): + for script in ['import_srpm']: + module = 'gbp.scripts.%s' % script + m = __import__(module, globals(), locals(), ['main'], -1) + self.assertRaises(SystemExit, + m.main, + ['doesnotmatter', '--help']) + # vim:et:ts=4:sw=4:et:sts=4:ai:set list listchars=tab\:»·,trail\:·: -- cgit v1.2.3 From fa1041859e7d382a0c7a26d09236202a3663524b Mon Sep 17 00:00:00 2001 From: Markus Lehtonen Date: Thu, 12 Jan 2012 15:38:29 +0200 Subject: Introduce gbp-pq-rpm tool Initial version of gbp-pq-rpm: a tool for managing patch queues for rpm packages. Signed-off-by: Markus Lehtonen Signed-off-by: Olev Kartau --- bin/gbp-pq-rpm | 5 + gbp/config.py | 3 + gbp/scripts/pq_rpm.py | 386 ++++++++++++++++++++++++++++++++++++++++++++++++++ setup.py | 3 +- tests/01_test_help.py | 3 +- 5 files changed, 398 insertions(+), 2 deletions(-) create mode 100755 bin/gbp-pq-rpm create mode 100755 gbp/scripts/pq_rpm.py diff --git a/bin/gbp-pq-rpm b/bin/gbp-pq-rpm new file mode 100755 index 00000000..528020df --- /dev/null +++ b/bin/gbp-pq-rpm @@ -0,0 +1,5 @@ +#! /usr/bin/python -u +import sys +from gbp.scripts.pq_rpm import main + +sys.exit(main(sys.argv)) diff --git a/gbp/config.py b/gbp/config.py index 27fe6288..50568a38 100644 --- a/gbp/config.py +++ b/gbp/config.py @@ -581,6 +581,7 @@ class GbpOptionParserRpm(GbpOptionParser): 'cleaner' : '', 'packaging-dir' : '', 'packaging-tag' : 'packaging/%(version)s', + 'spec-file' : 'auto', } ) help = dict(GbpOptionParser.help) @@ -589,6 +590,8 @@ class GbpOptionParserRpm(GbpOptionParser): "subdir where packaging files are stored, default is '%(packaging-dir)s'", 'packaging-tag': "format string for packaging tags, rpm counterpart of the 'debian-tag' option, default is '%(packaging-tag)s'", + 'spec-file': + "Spec file to use, 'auto' makes gbp to guess, other values make the packaging-dir option to be ignored, default is '%(spec-file)s'", } ) # vim:et:ts=4:sw=4:et:sts=4:ai:set list listchars=tab\:»·,trail\:·: diff --git a/gbp/scripts/pq_rpm.py b/gbp/scripts/pq_rpm.py new file mode 100755 index 00000000..4287cdc0 --- /dev/null +++ b/gbp/scripts/pq_rpm.py @@ -0,0 +1,386 @@ +# vim: set fileencoding=utf-8 : +# +# (C) 2011 Guido Günther +# (C) 2012 Intel Corporation +# This program is free software; you can redistribute it and/or modify +# it under the terms of the GNU General Public License as published by +# the Free Software Foundation; either version 2 of the License, or +# (at your option) any later version. +# +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with this program; if not, write to the Free Software +# Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA +# +"""manage patches in a patch queue""" + +import ConfigParser +import errno +import os +import shutil +import sys +import tempfile +import re +from gbp.config import (GbpOptionParserRpm, GbpOptionGroup) +from gbp.rpm.git import (GitRepositoryError, RpmGitRepository) +from gbp.git import GitModifier +from gbp.command_wrappers import (Command, GitCommand, RunAtCommand, + CommandExecFailed) +from gbp.errors import GbpError +import gbp.log +from gbp.patch_series import (PatchSeries, Patch) +from gbp.rpm import (SpecFile, guess_spec) +from gbp.scripts.common.pq import (is_pq_branch, pq_branch_name, pq_branch_base, + parse_gbp_commands, format_patch, + switch_to_pq_branch, apply_single_patch, + apply_and_commit_patch, drop_pq) + + +def generate_patches(repo, start, end, outdir, options): + """ + Generate patch files from git + """ + gbp.log.info("Generating patches from git (%s..%s)" % (start, end)) + patches = [] + commands = {} + for treeish in [start, end]: + if not repo.has_treeish(treeish): + raise GbpError('%s not a valid tree-ish' % treeish) + + # Generate patches + for commit in reversed(repo.get_commits(start, end)): + info = repo.get_commit_info(commit) + cmds = parse_gbp_commands(info, 'gbp-rpm', ('ignore'), None)[0] + if not 'ignore' in cmds: + patch_fn = format_patch(outdir, repo, info, patches, + options.patch_numbers) + if patch_fn: + commands[os.path.basename(patch_fn)] = cmds + else: + gbp.log.info('Ignoring commit %s' % info['id']) + + return patches, commands + + +def rm_patch_files(spec): + """ + Delete the patch files listed in the spec files. Doesn't delete patches + marked as not maintained by gbp. + """ + # Remove all old patches from the spec dir + for n, p in spec.patches.iteritems(): + if p['autoupdate']: + f = os.path.join(spec.specdir, p['filename']) + gbp.log.debug("Removing '%s'" % f) + try: + os.unlink(f) + except OSError, (e, msg): + if e != errno.ENOENT: + raise GbpError, "Failed to remove patch: %s" % msg + else: + gbp.log.debug("%s does not exist." % f) + + +def update_patch_series(repo, spec, start, end, options): + """ + Export patches to packaging directory and update spec file accordingly. + """ + # Unlink old patch files and generate new patches + rm_patch_files(spec) + + patches, _commands = generate_patches(repo, start, end, + spec.specdir, options) + spec.update_patches(patches) + spec.write_spec_file() + + +def export_patches(repo, branch, options): + """Export patches from the pq branch into a packaging branch""" + if is_pq_branch(branch, options): + base = pq_branch_base(branch, options) + gbp.log.info("On '%s', switching to '%s'" % (branch, base)) + branch = base + repo.set_branch(branch) + + pq_branch = pq_branch_name(branch, options) + + # Find and parse .spec file + try: + if options.spec_file != 'auto': + specfilename = options.spec_file + options.packaging_dir = os.path.dirname(specfilename) + else: + specfilename = guess_spec(options.packaging_dir, + True, + os.path.basename(repo.path) + '.spec') + spec = SpecFile(specfilename) + except KeyError: + raise GbpError, "Can't parse spec" + + # Find upstream version + upstream_commit = repo.find_version(options.upstream_tag, spec.version) + if not upstream_commit: + raise GbpError, ("Couldn't find upstream version %s. Don't know on what base to import." % spec.version) + + update_patch_series(repo, spec, upstream_commit, pq_branch, options) + + GitCommand('status')(['--', spec.specdir]) + + +def safe_patches(queue, tmpdir_base): + """ + Safe the current patches in a temporary directory + below 'tmpdir_base' + + @param queue: an existing patch queue + @param tmpdir_base: base under which to create tmpdir + @return: tmpdir and a safed queue (with patches in tmpdir) + @rtype: tuple + """ + + tmpdir = tempfile.mkdtemp(dir=tmpdir_base, prefix='gbp-pq') + safequeue=PatchSeries() + + if len(queue) > 0: + gbp.log.debug("Safeing patches '%s' in '%s'" % (os.path.dirname(queue[0].path), tmpdir)) + for p in queue: + dst = os.path.join(tmpdir, os.path.basename(p.path)) + shutil.copy(p.path, dst) + safequeue.append(p) + safequeue[-1].path = dst; + + return (tmpdir, safequeue) + + +def get_packager(spec): + """Get packager information from spec""" + if spec.packager: + match = re.match(r'(?P.*[^ ])\s*<(?P\S*)>', + spec.packager.strip()) + if match: + return GitModifier(match.group('name'), match.group('email')) + return GitModifier() + + +def import_spec_patches(repo, branch, options): + """ + apply a series of patches in a spec/packaging dir to branch + the patch-queue branch for 'branch' + + @param repo: git repository to work on + @param branch: branch to base pqtch queue on + @param options: command options + """ + tmpdir = None + + if is_pq_branch(branch, options): + if options.force: + branch = pq_branch_base(branch, options) + pq_branch = pq_branch_name(branch, options) + repo.checkout(branch) + else: + gbp.log.err("Already on a patch-queue branch '%s' - doing nothing." % branch) + raise GbpError + else: + pq_branch = pq_branch_name(branch, options) + + if repo.has_branch(pq_branch): + if options.force: + drop_pq(repo, branch, options) + else: + raise GbpError, ("Patch queue branch '%s'. already exists. Try 'rebase' instead." + % pq_branch) + + # Find and parse .spec file + try: + if options.spec_file != 'auto': + specfilename = options.spec_file + options.packaging_dir = os.path.dirname(specfilename) + else: + specfilename = guess_spec(options.packaging_dir, + True, + os.path.basename(repo.path) + '.spec') + spec = SpecFile(specfilename) + except KeyError: + raise GbpError, "Can't parse spec" + + # Find upstream version + commit = repo.find_version(options.upstream_tag, spec.version) + if commit: + commits=[commit] + else: + raise GbpError, ("Couldn't find upstream version %s. Don't know on what base to import." % spec.version) + + queue = spec.patchseries() + packager = get_packager(spec) + # Put patches in a safe place + tmpdir, queue = safe_patches(queue, repo.path) + for commit in commits: + try: + gbp.log.info("Trying to apply patches at '%s'" % commit) + repo.create_branch(pq_branch, commit) + except GitRepositoryError: + raise GbpError, ("Cannot create patch-queue branch '%s'." % pq_branch) + + repo.set_branch(pq_branch) + for patch in queue: + gbp.log.debug("Applying %s" % patch.path) + try: + apply_and_commit_patch(repo, patch, packager) + except (GbpError, GitRepositoryError): + repo.set_branch(branch) + repo.delete_branch(pq_branch) + break + else: + # All patches applied successfully + break + else: + raise GbpError, "Couldn't apply patches" + + if tmpdir: + gbp.log.debug("Remove temporary patch safe '%s'" % tmpdir) + shutil.rmtree(tmpdir) + + repo.set_branch(branch) + + return os.path.basename(spec.specfile) + + +def rebase_pq(repo, branch, options): + if is_pq_branch(branch, options): + base = pq_branch_base(branch, options) + gbp.log.info("On '%s', switching to '%s'" % (branch, base)) + branch = base + repo.set_branch(branch) + + # Find and parse .spec file + try: + if options.spec_file != 'auto': + specfilename = options.spec_file + options.packaging_dir = os.path.dirname(specfilename) + else: + specfilename = guess_spec(options.packaging_dir, + True, + os.path.basename(repo.path) + '.spec') + spec = SpecFile(specfilename) + except KeyError: + raise GbpError, "Can't parse spec" + + # Find upstream version + upstream_commit = repo.find_version(options.upstream_tag, spec.version) + if not upstream_commit: + raise GbpError, ("Couldn't find upstream version %s. Don't know on what base to import." % spec.version) + + switch_to_pq_branch(repo, branch) + GitCommand("rebase")([upstream_commit]) + + +def switch_pq(repo, current, options): + """Switch to patch-queue branch if on base branch and vice versa""" + if is_pq_branch(current, options): + base = pq_branch_base(current, options) + gbp.log.info("Switching to branch '%s'" % base) + repo.checkout(base) + else: + switch_to_pq_branch(repo, current, options) + + +def main(argv): + retval = 0 + + try: + parser = GbpOptionParserRpm(command=os.path.basename(argv[0]), prefix='', + usage="%prog [options] action - maintain patches on a patch queue branch\n" + "Actions:\n" + " export Export the patch queue / devel branch associated to the\n" + " current branch into a patch series in and update the spec file\n" + " import Create a patch queue / devel branch from spec file\n" + " and patches in current dir.\n" + " rebase Switch to patch queue / devel branch associated to the current\n" + " branch and rebase against upstream.\n" + " drop Drop (delete) the patch queue /devel branch associated to\n" + " the current branch.\n" + " apply Apply a patch\n" + " switch Switch to patch-queue branch and vice versa") + except ConfigParser.ParsingError as err: + gbp.log.err('Invalid config file: %s' % err) + return 1 + + parser.add_boolean_config_file_option(option_name="patch-numbers", dest="patch_numbers") + parser.add_option("-v", "--verbose", action="store_true", dest="verbose", default=False, + help="Verbose command execution") + parser.add_option("--force", dest="force", action="store_true", default=False, + help="In case of import even import if the branch already exists") + parser.add_config_file_option(option_name="color", dest="color", type='tristate') + parser.add_config_file_option(option_name="upstream-tag", dest="upstream_tag") + parser.add_config_file_option(option_name="spec-file", dest="spec_file") + parser.add_config_file_option(option_name="packaging-dir", dest="packaging_dir") + + (options, args) = parser.parse_args(argv) + gbp.log.setup(options.color, options.verbose) + + if len(args) < 2: + gbp.log.err("No action given.") + return 1 + else: + action = args[1] + + if args[1] in ["export", "import", "rebase", "drop", "switch"]: + pass + elif args[1] in ["apply"]: + if len(args) != 3: + gbp.log.err("No patch name given.") + return 1 + else: + patchfile = args[2] + else: + gbp.log.err("Unknown action '%s'." % args[1]) + return 1 + + try: + repo = RpmGitRepository(os.path.curdir) + except GitRepositoryError: + gbp.log.err("%s is not a git repository" % (os.path.abspath('.'))) + return 1 + + if os.path.abspath('.') != repo.path: + gbp.log.warn("Switching to topdir before running commands") + os.chdir(repo.path) + + try: + current = repo.get_branch() + if action == "export": + export_patches(repo, current, options) + elif action == "import": + specfile=import_spec_patches(repo, current, options) + current = repo.get_branch() + gbp.log.info("Patches listed in '%s' imported on '%s'" % + (specfile, current)) + elif action == "drop": + drop_pq(repo, current, options) + elif action == "rebase": + rebase_pq(repo, current, options) + elif action == "apply": + patch = Patch(patchfile) + apply_single_patch(repo, current, patch, None, options) + elif action == "switch": + switch_pq(repo, current, options) + except CommandExecFailed: + retval = 1 + except GitRepositoryError as err: + gbp.log.err("Git command failed: %s" % err) + retval = 1 + except GbpError, err: + if len(err.__str__()): + gbp.log.err(err) + retval = 1 + + return retval + +if __name__ == '__main__': + sys.exit(main(sys.argv)) + diff --git a/setup.py b/setup.py index fdbb1e56..3902575d 100644 --- a/setup.py +++ b/setup.py @@ -56,7 +56,8 @@ setup(name = "gbp", 'bin/gbp-clone', 'bin/gbp-create-remote-repo', 'bin/git-pbuilder', - 'bin/git-import-srpm'], + 'bin/git-import-srpm', + 'bin/gbp-pq-rpm'], packages = find_packages(exclude=['tests', 'tests.*']), data_files = [("/etc/git-buildpackage/", ["gbp.conf"]),], setup_requires=['nose>=0.11.1', 'coverage>=2.85', 'nosexcover>=1.0.7'] if \ diff --git a/tests/01_test_help.py b/tests/01_test_help.py index 331d7cc6..d0266a66 100644 --- a/tests/01_test_help.py +++ b/tests/01_test_help.py @@ -27,7 +27,8 @@ class TestHelp(unittest.TestCase): """Test help output of RPM-specific commands""" def testHelpRpm(self): - for script in ['import_srpm']: + for script in ['import_srpm', + 'pq_rpm']: module = 'gbp.scripts.%s' % script m = __import__(module, globals(), locals(), ['main'], -1) self.assertRaises(SystemExit, -- cgit v1.2.3 From b0f31c9d48e5356edb20afdd9b87764286f5a1f7 Mon Sep 17 00:00:00 2001 From: Markus Lehtonen Date: Thu, 12 Jan 2012 15:44:43 +0200 Subject: gbp-pq-rpm: add 'export-rev' option This option allows generating patches from any git tree-ish (instead of the default that is HEAD of patch-queue branch). Signed-off-by: Markus Lehtonen --- gbp/scripts/pq_rpm.py | 9 ++++++++- 1 file changed, 8 insertions(+), 1 deletion(-) diff --git a/gbp/scripts/pq_rpm.py b/gbp/scripts/pq_rpm.py index 4287cdc0..e1fda713 100755 --- a/gbp/scripts/pq_rpm.py +++ b/gbp/scripts/pq_rpm.py @@ -126,7 +126,11 @@ def export_patches(repo, branch, options): if not upstream_commit: raise GbpError, ("Couldn't find upstream version %s. Don't know on what base to import." % spec.version) - update_patch_series(repo, spec, upstream_commit, pq_branch, options) + export_treeish = options.export_rev if options.export_rev else pq_branch + if not repo.has_treeish(export_treeish): + raise GbpError('Invalid treeish object %s' % export_treeish) + + update_patch_series(repo, spec, upstream_commit, export_treeish, options) GitCommand('status')(['--', spec.specdir]) @@ -319,6 +323,9 @@ def main(argv): parser.add_config_file_option(option_name="upstream-tag", dest="upstream_tag") parser.add_config_file_option(option_name="spec-file", dest="spec_file") parser.add_config_file_option(option_name="packaging-dir", dest="packaging_dir") + parser.add_option("--export-rev", action="store", dest="export_rev", default="", + help="Export patches from treeish object TREEISH instead " + "of head of patch-queue branch", metavar="TREEISH") (options, args) = parser.parse_args(argv) gbp.log.setup(options.color, options.verbose) -- cgit v1.2.3 From 55c42219e10be5cc08cf0f35e770a45a3bff4d09 Mon Sep 17 00:00:00 2001 From: Markus Lehtonen Date: Fri, 11 May 2012 11:29:24 +0300 Subject: pq-rpm: add new --pq-branch option Adds a new command line option '--pq-branch' to set the name of patch-queue branches. Changes the defaults pq-branch name for rpm tools to 'development/%(branch)s' (instead of the old 'patch-queue/%(branch)s'). Signed-off-by: Markus Lehtonen --- gbp/config.py | 3 +++ gbp/scripts/pq_rpm.py | 6 +++++- 2 files changed, 8 insertions(+), 1 deletion(-) diff --git a/gbp/config.py b/gbp/config.py index 50568a38..ca64b620 100644 --- a/gbp/config.py +++ b/gbp/config.py @@ -581,6 +581,7 @@ class GbpOptionParserRpm(GbpOptionParser): 'cleaner' : '', 'packaging-dir' : '', 'packaging-tag' : 'packaging/%(version)s', + 'pq-branch' : 'development/%(branch)s', 'spec-file' : 'auto', } ) @@ -590,6 +591,8 @@ class GbpOptionParserRpm(GbpOptionParser): "subdir where packaging files are stored, default is '%(packaging-dir)s'", 'packaging-tag': "format string for packaging tags, rpm counterpart of the 'debian-tag' option, default is '%(packaging-tag)s'", + 'pq-branch': + "format string for the patch-queue branch name, default is '%(pq-branch)s'", 'spec-file': "Spec file to use, 'auto' makes gbp to guess, other values make the packaging-dir option to be ignored, default is '%(spec-file)s'", } ) diff --git a/gbp/scripts/pq_rpm.py b/gbp/scripts/pq_rpm.py index e1fda713..267357be 100755 --- a/gbp/scripts/pq_rpm.py +++ b/gbp/scripts/pq_rpm.py @@ -279,7 +279,7 @@ def rebase_pq(repo, branch, options): if not upstream_commit: raise GbpError, ("Couldn't find upstream version %s. Don't know on what base to import." % spec.version) - switch_to_pq_branch(repo, branch) + switch_to_pq_branch(repo, branch, options) GitCommand("rebase")([upstream_commit]) @@ -323,6 +323,10 @@ def main(argv): parser.add_config_file_option(option_name="upstream-tag", dest="upstream_tag") parser.add_config_file_option(option_name="spec-file", dest="spec_file") parser.add_config_file_option(option_name="packaging-dir", dest="packaging_dir") + parser.add_config_file_option(option_name="packaging-branch", + dest="packaging_branch", + help="Branch the packaging is being maintained on. Only relevant if a invariable/single pq-branch is defined, in which case this is used as the 'base' branch. Default is '%(packaging-branch)s'") + parser.add_config_file_option(option_name="pq-branch", dest="pq_branch") parser.add_option("--export-rev", action="store", dest="export_rev", default="", help="Export patches from treeish object TREEISH instead " "of head of patch-queue branch", metavar="TREEISH") -- cgit v1.2.3 From 8aaf27ee955584f40a022af9dc4dd5a1b3aecfed Mon Sep 17 00:00:00 2001 From: Markus Lehtonen Date: Wed, 8 May 2013 20:42:45 +0300 Subject: pq-rpm: support patch-export up to an arbitrary tree-ish If the end of the export range is not a commit "normal" patches are generated up to HEAD and finally a raw diff between HEAD and the end-tree-is generated. Signed-off-by: Markus Lehtonen --- gbp/scripts/pq_rpm.py | 23 ++++++++++++++++++++++- 1 file changed, 22 insertions(+), 1 deletion(-) diff --git a/gbp/scripts/pq_rpm.py b/gbp/scripts/pq_rpm.py index 267357be..1e3c44a9 100755 --- a/gbp/scripts/pq_rpm.py +++ b/gbp/scripts/pq_rpm.py @@ -36,6 +36,7 @@ from gbp.patch_series import (PatchSeries, Patch) from gbp.rpm import (SpecFile, guess_spec) from gbp.scripts.common.pq import (is_pq_branch, pq_branch_name, pq_branch_base, parse_gbp_commands, format_patch, + format_diff, switch_to_pq_branch, apply_single_patch, apply_and_commit_patch, drop_pq) @@ -51,8 +52,21 @@ def generate_patches(repo, start, end, outdir, options): if not repo.has_treeish(treeish): raise GbpError('%s not a valid tree-ish' % treeish) + try: + end_commit = end + end_commit_sha1 = repo.rev_parse("%s^0" % end_commit) + except GitRepositoryError: + # In case of plain tree-ish objects, assume current branch head is the + # last commit + end_commit = "HEAD" + end_commit_sha1 = repo.rev_parse("%s^0" % end_commit) + + start_sha1 = repo.rev_parse("%s^0" % start) + if repo.get_merge_base(start_sha1, end_commit_sha1) != start_sha1: + raise GbpError("Start commit '%s' not an ancestor of end commit " + "'%s'" % (start, end_commit)) # Generate patches - for commit in reversed(repo.get_commits(start, end)): + for commit in reversed(repo.get_commits(start, end_commit)): info = repo.get_commit_info(commit) cmds = parse_gbp_commands(info, 'gbp-rpm', ('ignore'), None)[0] if not 'ignore' in cmds: @@ -63,6 +77,13 @@ def generate_patches(repo, start, end, outdir, options): else: gbp.log.info('Ignoring commit %s' % info['id']) + # Generate diff to the tree-ish object + if end_commit != end: + gbp.log.info("Generating diff file %s..%s" % (end_commit, end)) + patch_fn = format_diff(outdir, None, repo, end_commit, end) + if patch_fn: + patches.append(patch_fn) + return patches, commands -- cgit v1.2.3 From cfeff769b658cc5879b31d9a95e38279f13a32d9 Mon Sep 17 00:00:00 2001 From: Markus Lehtonen Date: Thu, 12 Jan 2012 15:39:12 +0200 Subject: Introduce git-buildpackage-rpm tool Initial version of git-buildpackage-rpm: git-buildpackage tool for rpms. Also adds some new options to config.py that are exclusively used in this tool. Signed-off-by: Markus Lehtonen Signed-off-by: Ed Bartosh Signed-off-by: Zhang Qiang --- bin/git-buildpackage-rpm | 5 + gbp/config.py | 16 +- gbp/scripts/buildpackage_rpm.py | 516 ++++++++++++++++++++++++++++++++++++++++ setup.py | 3 +- tests/01_test_help.py | 3 +- 5 files changed, 538 insertions(+), 5 deletions(-) create mode 100755 bin/git-buildpackage-rpm create mode 100755 gbp/scripts/buildpackage_rpm.py diff --git a/bin/git-buildpackage-rpm b/bin/git-buildpackage-rpm new file mode 100755 index 00000000..393f1ae1 --- /dev/null +++ b/bin/git-buildpackage-rpm @@ -0,0 +1,5 @@ +#! /usr/bin/python -u +import sys +from gbp.scripts.buildpackage_rpm import main + +sys.exit(main(sys.argv)) diff --git a/gbp/config.py b/gbp/config.py index ca64b620..cb07cf1c 100644 --- a/gbp/config.py +++ b/gbp/config.py @@ -119,7 +119,6 @@ class GbpOptionParser(OptionParser): 'snapshot-number' : 'snapshot + 1', 'git-log' : '--no-merges', 'export' : 'HEAD', - 'export-dir' : '', 'overlay' : 'False', 'tarball-dir' : '', 'ignore-new' : 'False', @@ -569,6 +568,7 @@ class GbpOptionParserDebian(GbpOptionParser): defaults.update( { 'builder' : 'debuild -i -I', 'cleaner' : '/bin/true', + 'export-dir' : '', } ) class GbpOptionParserRpm(GbpOptionParser): @@ -577,12 +577,20 @@ class GbpOptionParserRpm(GbpOptionParser): """ defaults = dict(GbpOptionParser.defaults) defaults.update( { - 'builder' : '', - 'cleaner' : '', + 'builder' : 'rpmbuild', + 'cleaner' : '/bin/true', 'packaging-dir' : '', 'packaging-tag' : 'packaging/%(version)s', 'pq-branch' : 'development/%(branch)s', 'spec-file' : 'auto', + 'export-dir' : '../rpmbuild', + 'rpmbuild-builddir' : 'BUILD', + 'rpmbuild-rpmdir' : 'RPMS', + 'rpmbuild-sourcedir' : 'SOURCES', + 'rpmbuild-specdir' : 'SPECS', + 'rpmbuild-srpmdir' : 'SRPMS', + 'rpmbuild-buildrootdir' : 'BUILDROOT', + 'patch-export' : 'False', } ) help = dict(GbpOptionParser.help) @@ -595,6 +603,8 @@ class GbpOptionParserRpm(GbpOptionParser): "format string for the patch-queue branch name, default is '%(pq-branch)s'", 'spec-file': "Spec file to use, 'auto' makes gbp to guess, other values make the packaging-dir option to be ignored, default is '%(spec-file)s'", + 'patch-export': + "Create patches between upstream and export-treeish, default is '%(patch-export)s'", } ) # vim:et:ts=4:sw=4:et:sts=4:ai:set list listchars=tab\:»·,trail\:·: diff --git a/gbp/scripts/buildpackage_rpm.py b/gbp/scripts/buildpackage_rpm.py new file mode 100755 index 00000000..a3c75d63 --- /dev/null +++ b/gbp/scripts/buildpackage_rpm.py @@ -0,0 +1,516 @@ +# vim: set fileencoding=utf-8 : +# +# (C) 2006-2011 Guido Guenther +# (C) 2012 Intel Corporation +# This program is free software; you can redistribute it and/or modify +# it under the terms of the GNU General Public License as published by +# the Free Software Foundation; either version 2 of the License, or +# (at your option) any later version. +# +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with this program; if not, write to the Free Software +# Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA +# +"""run commands to build an RPM package out of a git repository""" + +import ConfigParser +import errno +import os, os.path +import sys +import tempfile +import shutil +import re + +import gbp.rpm as rpm +from gbp.rpm.policy import RpmPkgPolicy +from gbp.command_wrappers import (Command, + RunAtCommand, CommandExecFailed, + RemoveTree) +from gbp.config import (GbpOptionParserRpm, GbpOptionGroup) +from gbp.rpm.git import (GitRepositoryError, RpmGitRepository) +from gbp.errors import GbpError +import gbp.log +import gbp.notifications +from gbp.scripts.common.buildpackage import (index_name, wc_names, + git_archive_submodules, + git_archive_single, dump_tree, + write_wc, drop_index) +from gbp.pkg import (compressor_opts, compressor_aliases) +from gbp.scripts.pq_rpm import update_patch_series + + +def git_archive(repo, spec, output_dir, treeish, comp_level, with_submodules): + "create a compressed orig tarball in output_dir using git_archive" + comp_opts = '' + if spec.orig_comp: + comp_opts = compressor_opts[spec.orig_comp][0] + + output = os.path.join(output_dir, os.path.basename(spec.orig_file)) + prefix = spec.orig_base + + try: + if repo.has_submodules() and with_submodules: + repo.update_submodules() + git_archive_submodules(repo, treeish, output, prefix, + spec.orig_comp, comp_level, comp_opts, + spec.orig_archive_fmt) + + else: + git_archive_single(repo, treeish, output, prefix, + spec.orig_comp, comp_level, comp_opts, + spec.orig_archive_fmt) + except (GitRepositoryError, CommandExecFailed): + gbp.log.err("Error generating submodules' archives") + return False + except OSError, err: + gbp.log.err("Error creating %s: %s" % (output, err[0])) + return False + except GbpError: + raise + except Exception as e: + gbp.log.err("Error creating %s: %s" % (output, e)) + return False + return True + + +def prepare_upstream_tarball(repo, spec, options, output_dir): + """ + Make sure we have an upstream tarball. This involves loooking in + tarball_dir, symlinking or building it. + """ + # look in tarball_dir first, if found force a symlink to it + orig_file = os.path.basename(spec.orig_file) + if options.tarball_dir: + gbp.log.debug("Looking for orig tarball '%s' at '%s'" % (orig_file, options.tarball_dir)) + if not RpmPkgPolicy.symlink_orig(orig_file, options.tarball_dir, output_dir, force=True): + gbp.log.info("Orig tarball '%s' not found at '%s'" % (orig_file, options.tarball_dir)) + else: + gbp.log.info("Orig tarball '%s' found at '%s'" % (orig_file, options.tarball_dir)) + # build an orig unless the user forbids it, always build (and overwrite pre-existing) if user forces it + if options.force_create or (not options.no_create_orig and not RpmPkgPolicy.has_orig(orig_file, output_dir)): + if not pristine_tar_build_orig(repo, orig_file, output_dir, options): + upstream_tree = git_archive_build_orig(repo, spec, output_dir, options) + if options.pristine_tar_commit: + if repo.pristine_tar.has_commit(orig_file): + gbp.log.debug("%s already on pristine tar branch" % + orig_file) + else: + archive = os.path.join(output_dir, orig_file) + gbp.log.debug("Adding %s to pristine-tar branch" % + archive) + repo.pristine_tar.commit(archive, upstream_tree) + + +def makedir(dir): + output_dir = os.path.abspath(dir) + + try: + os.mkdir(dir) + except OSError, (e, msg): + if e != errno.EEXIST: + raise GbpError, "Cannot create dir %s" % dir + return dir + + +def prepare_export_dir(dir): + if not dir: + dir = 'rpmbuild' + return makedir(dir) + + +def pristine_tar_build_orig(repo, orig_file, output_dir, options): + """ + build orig using pristine-tar + @return: True: orig tarball build, False: noop + """ + if options.pristine_tar: + if not repo.has_branch(repo.pristine_tar_branch): + gbp.log.warn('Pristine-tar branch "%s" not found' % + repo.pristine_tar.branch) + try: + repo.pristine_tar.checkout(os.path.join(output_dir, orig_file)) + return True + except CommandExecFailed: + if options.pristine_tar_commit: + gbp.log.debug("pristine-tar checkout failed, " + "will commit tarball due to " + "'--pristine-tar-commit'") + elif not options.force_create: + raise + return False + +def get_upstream_tree(repo, spec, options): + """Determine the upstream tree from the given options""" + if options.upstream_tree.upper() == 'TAG': + upstream_tree = repo.version_to_tag(options.upstream_tag, spec.version) + elif options.upstream_tree.upper() == 'BRANCH': + if not repo.has_branch(options.upstream_branch): + raise GbpError("%s is not a valid branch" % options.upstream_branch) + upstream_tree = options.upstream_branch + else: + upstream_tree = options.upstream_tree + if not repo.has_treeish(upstream_tree): + raise GbpError('Invalid upstream treeish %s' % upstream_tree) + return upstream_tree + + +def git_archive_build_orig(repo, spec, output_dir, options): + """ + Build orig tarball using git-archive + + @param repo: our git repository + @type repo: L{RpmGitRepository} + @param spec: spec file of the package + @type spec: L{SpecFile} + @param output_dir: where to put the tarball + @type output_dir: C{Str} + @param options: the parsed options + @type options: C{dict} of options + @return: the tree we built the tarball from + @rtype: C{str} + """ + upstream_tree = get_upstream_tree(repo, spec, options) + gbp.log.info("%s does not exist, creating from '%s'" % (spec.orig_file, + upstream_tree)) + if spec.orig_comp: + gbp.log.debug("Building upstream source archive with compression '%s -%s'" % + (spec.orig_comp, options.comp_level)) + if not git_archive(repo, spec, output_dir, upstream_tree, + options.comp_level, + options.with_submodules): + raise GbpError("Cannot create upstream tarball at '%s'" % output_dir) + return upstream_tree + + +def export_patches(repo, spec, export_treeish, options): + """ + Generate patches and update spec file + """ + upstream_tree = get_upstream_tree(repo, spec, options) + update_patch_series(repo, spec, upstream_tree, export_treeish, options) + + +def is_native(repo, options): + if repo.has_branch(options.upstream_branch): + return False + return True + + +def setup_builder(options, builder_args): + """setup everything to use git-pbuilder""" + if options.builder.startswith('rpmbuild'): + if len(builder_args) == 0: + builder_args.append('-ba') + builder_args.extend(['--define "_topdir %s"' % os.path.abspath(options.export_dir), + '--define "_builddir %%_topdir/%s"' % options.build_dir, + '--define "_rpmdir %%_topdir/%s"' % options.rpm_dir, + '--define "_sourcedir %%_topdir/%s"' % options.source_dir, + '--define "_specdir %%_topdir/%s"' % options.spec_dir, + '--define "_srcrpmdir %%_topdir/%s"' % options.srpm_dir, + '--define "_buildrootdir %%_topdir/%s"' % options.buildroot_dir]) + elif options.builder.startswith('osc'): + builder_args.insert(0, 'build') + options.source_dir = '' + options.spec_dir = '' + + +def parse_args(argv, prefix): + args = [ arg for arg in argv[1:] if arg.find('--%s' % prefix) == 0 ] + builder_args = [ arg for arg in argv[1:] if arg.find('--%s' % prefix) == -1 ] + + # We handle these although they don't have a --git- prefix + for arg in [ "--help", "-h", "--version" ]: + if arg in builder_args: + args.append(arg) + + try: + parser = GbpOptionParserRpm(command=os.path.basename(argv[0]), prefix=prefix) + except ConfigParser.ParsingError, err: + gbp.log.err(err) + return None, None, None + + tag_group = GbpOptionGroup(parser, "tag options", "options related to git tag creation") + branch_group = GbpOptionGroup(parser, "branch options", "branch layout options") + cmd_group = GbpOptionGroup(parser, "external command options", "how and when to invoke external commands and hooks") + orig_group = GbpOptionGroup(parser, "orig tarball options", "options related to the creation of the orig tarball") + export_group = GbpOptionGroup(parser, "export build-tree options", "alternative build tree related options") + parser.add_option_group(tag_group) + parser.add_option_group(orig_group) + parser.add_option_group(branch_group) + parser.add_option_group(cmd_group) + parser.add_option_group(export_group) + + parser.add_boolean_config_file_option(option_name = "ignore-new", dest="ignore_new") + parser.add_option("--git-verbose", action="store_true", dest="verbose", default=False, + help="verbose command execution") + parser.add_config_file_option(option_name="color", dest="color", type='tristate') + parser.add_config_file_option(option_name="notify", dest="notify", type='tristate') + tag_group.add_option("--git-tag", action="store_true", dest="tag", default=False, + help="create a tag after a successful build") + tag_group.add_option("--git-tag-only", action="store_true", dest="tag_only", default=False, + help="don't build, only tag and run the posttag hook") + tag_group.add_option("--git-retag", action="store_true", dest="retag", default=False, + help="don't fail if the tag already exists") + tag_group.add_boolean_config_file_option(option_name="sign-tags", dest="sign_tags") + tag_group.add_config_file_option(option_name="keyid", dest="keyid") + tag_group.add_config_file_option(option_name="packaging-tag", dest="packaging_tag") + tag_group.add_config_file_option(option_name="upstream-tag", dest="upstream_tag") + orig_group.add_config_file_option(option_name="upstream-tree", dest="upstream_tree") + orig_group.add_boolean_config_file_option(option_name="pristine-tar", dest="pristine_tar") + orig_group.add_boolean_config_file_option(option_name="pristine-tar-commit", + dest="pristine_tar_commit") + orig_group.add_config_file_option(option_name="force-create", dest="force_create", + help="force creation of upstream source tarball", action="store_true") + orig_group.add_config_file_option(option_name="no-create-orig", dest="no_create_orig", + help="don't create upstream source tarball", action="store_true") + orig_group.add_config_file_option(option_name="tarball-dir", dest="tarball_dir", type="path", + help="location to look for external tarballs") + orig_group.add_config_file_option(option_name="compression-level", dest="comp_level", + help="Compression level, default is '%(compression-level)s'") + branch_group.add_config_file_option(option_name="upstream-branch", dest="upstream_branch") + branch_group.add_config_file_option(option_name="packaging-branch", dest="packaging_branch") + branch_group.add_boolean_config_file_option(option_name = "ignore-branch", dest="ignore_branch") + branch_group.add_boolean_config_file_option(option_name = "submodules", dest="with_submodules") + cmd_group.add_config_file_option(option_name="builder", dest="builder", + help="command to build the package, default is '%(builder)s'") + cmd_group.add_config_file_option(option_name="cleaner", dest="cleaner", + help="command to clean the working copy, default is '%(cleaner)s'") + cmd_group.add_config_file_option(option_name="prebuild", dest="prebuild", + help="command to run before a build, default is '%(prebuild)s'") + cmd_group.add_config_file_option(option_name="postexport", dest="postexport", + help="command to run after exporting the source tree, default is '%(postexport)s'") + cmd_group.add_config_file_option(option_name="postbuild", dest="postbuild", + help="hook run after a successful build, default is '%(postbuild)s'") + cmd_group.add_config_file_option(option_name="posttag", dest="posttag", + help="hook run after a successful tag operation, default is '%(posttag)s'") + export_group.add_config_file_option(option_name="export-dir", dest="export_dir", type="path", + help="Build topdir, also export the sources under EXPORT_DIR, default is '%(export-dir)s'") + export_group.add_config_file_option(option_name="rpmbuild-builddir", dest="build_dir", type="path", + help="subdir where package is built (under EXPORT_DIR), i.e. rpmbuild builddir, default is '%(rpmbuild-builddir)s'") + export_group.add_config_file_option(option_name="rpmbuild-rpmdir", dest="rpm_dir", type="path", + help="subdir where ready binary packages are stored (under EXPORT_DIR), i.e. rpmbuild builddir, default is '%(rpmbuild-rpmdir)s'") + export_group.add_config_file_option(option_name="rpmbuild-sourcedir", dest="source_dir", type="path", + help="subdir where package sources are stored (under EXPORT_DIR), i.e. rpmbuild sourcedir, default is '%(rpmbuild-sourcedir)s'") + export_group.add_config_file_option(option_name="rpmbuild-specdir", dest="spec_dir", type="path", + help="subdir where package spec file is stored (under EXPORT_DIR), i.e. rpmbuild specdir, default is '%(rpmbuild-specdir)s'") + export_group.add_config_file_option(option_name="rpmbuild-srpmdir", dest="srpm_dir", type="path", + help="subdir where ready sources package is stored (under EXPORT_DIR), i.e. rpmbuild srpmdir, default is '%(rpmbuild-srpmdir)s'") + export_group.add_config_file_option(option_name="rpmbuild-buildrootdir", dest="buildroot_dir", type="path", + help="subdir for build-time alternative root (under EXPORT_DIR), i.e. rpmbuild buildrootdir, default is '%(rpmbuild-buildrootdir)s'") + export_group.add_config_file_option("export", dest="export", + help="export treeish object TREEISH, default is '%(export)s'", metavar="TREEISH") + export_group.add_config_file_option(option_name="packaging-dir", + dest="packaging_dir") + export_group.add_config_file_option(option_name="spec-file", dest="spec_file") + export_group.add_option("--git-export-only", action="store_true", dest="export_only", default=False, + help="only export packaging files, don't build") + export_group.add_boolean_config_file_option("patch-export", dest="patch_export") + export_group.add_boolean_config_file_option(option_name="patch-numbers", dest="patch_numbers") + options, args = parser.parse_args(args) + + gbp.log.setup(options.color, options.verbose) + if options.retag: + if not options.tag and not options.tag_only: + gbp.log.err("'--%sretag' needs either '--%stag' or '--%stag-only'" % (prefix, prefix, prefix)) + return None, None, None + + return options, args, builder_args + + +def main(argv): + retval = 0 + prefix = "git-" + spec = None + dump_dir = None + + options, gbp_args, builder_args = parse_args(argv, prefix) + if not options: + return 1 + + try: + repo = RpmGitRepository(os.path.curdir) + except GitRepositoryError: + gbp.log.err("%s is not a git repository" % (os.path.abspath('.'))) + return 1 + else: + repo_dir = os.path.abspath(os.path.curdir) + + try: + branch = repo.get_branch() + except GitRepositoryError: + branch = None + + try: + if not options.export_only: + Command(options.cleaner, shell=True)() + if not options.ignore_new: + (ret, out) = repo.is_clean() + if not ret: + gbp.log.err("You have uncommitted changes in your source tree:") + gbp.log.err(out) + raise GbpError, "Use --git-ignore-new to ignore." + + if not options.ignore_new and not options.ignore_branch: + if branch != options.packaging_branch: + gbp.log.err("You are not on branch '%s' but on '%s'" % (options.packaging_branch, branch)) + raise GbpError, "Use --git-ignore-branch to ignore or --git-packaging-branch to set the branch name." + + # Determine tree-ish to be exported + if options.export == index_name: + # Write a tree of the index + tree = repo.write_tree() + elif options.export in wc_names: + # Write a tree of the working copy + tree = write_wc(repo, + force=wc_names[options.export]['force'], + untracked=wc_names[options.export]['untracked']) + else: + tree = options.export + if not repo.has_treeish(tree): + raise GbpError('Invalid treeish object %s' % tree) + + # Dump from git to a temporary directory: + dump_dir = tempfile.mkdtemp(dir=".") + gbp.log.debug("Dumping tree '%s' to '%s'" % (options.export, dump_dir)) + if not dump_tree(repo, dump_dir, tree, options.with_submodules): + raise GbpError + # Find and parse spec from dump dir to get version etc. + if options.spec_file != 'auto': + specfile = os.path.join(dump_dir, options.spec_file) + options.packaging_dir = os.path.dirname(specfile) + if not os.path.exists(specfile): + raise rpm.NoSpecError("Failed to export specfile: %s" % options.spec_file) + else: + specfile = rpm.guess_spec(os.path.join(dump_dir, options.packaging_dir), + True, + os.path.basename(repo.path) + '.spec') + spec = rpm.SpecFile(specfile) + gbp.log.debug("Using spec file '%s'" % specfile) + + if not options.tag_only: + # Setup builder opts + setup_builder(options, builder_args) + + # Generate patches, if requested + if options.patch_export and not is_native(repo, options): + export_patches(repo, spec, tree, options) + + # Prepare final export dirs + export_dir = prepare_export_dir(options.export_dir) + source_dir = makedir(os.path.join(export_dir, options.source_dir)) + spec_dir = makedir(os.path.join(export_dir, options.spec_dir)) + + # Move packaging files + gbp.log.debug("Exporting packaging files in '%s' to '%s'" % (spec.specdir, export_dir)) + pkgfiles = os.listdir(spec.specdir) + for f in pkgfiles: + src = os.path.join(spec.specdir, f) + if f == os.path.basename(spec.specfile): + dst = os.path.join(spec_dir, f) + spec.specfile = os.path.abspath(dst) + else: + dst = os.path.join(source_dir, f) + try: + if os.path.isdir(src): + # dir is not packaging files, skip it + continue + else: + shutil.copy2(src, dst) + except IOError, err: + raise GbpError, "Error exporting files: %s" % err + spec.specdir = spec_dir + + # Get/build the orig tarball + if is_native(repo, options): + if spec.orig_file: + # Just build source archive from the exported tree + gbp.log.info("Creating (native) source archive %s from '%s'" % (spec.orig_file, tree)) + if spec.orig_comp: + gbp.log.debug("Building source archive with compression '%s -%s'" % (spec.orig_comp, options.comp_level)) + if not git_archive(repo, spec, source_dir, tree, + options.comp_level, options.with_submodules): + raise GbpError, "Cannot create source tarball at '%s'" % export_dir + # Non-native packages: create orig tarball from upstream + elif spec.orig_file: + prepare_upstream_tarball(repo, spec, options, source_dir) + + # Run postexport hook + if options.postexport: + RunAtCommand(options.postexport, shell=True, + extra_env={'GBP_GIT_DIR': repo.git_dir, + 'GBP_TMP_DIR': export_dir})(dir=export_dir) + # Do actual build + if not options.export_only and not options.tag_only: + if options.prebuild: + RunAtCommand(options.prebuild, shell=True, + extra_env={'GBP_GIT_DIR': repo.git_dir(), + 'GBP_BUILD_DIR': export_dir})(dir=export_dir) + + # Finally build the package: + if options.builder.startswith("rpmbuild"): + builder_args.extend([spec.specfile]) + else: + builder_args.extend([os.path.basename(spec.specfile)]) + RunAtCommand(options.builder, builder_args, shell=True, + extra_env={'GBP_BUILD_DIR': export_dir})(dir=export_dir) + if options.postbuild: + changes = os.path.abspath("%s/%s.changes" % (source_dir, spec.name)) + gbp.log.debug("Looking for changes file %s" % changes) + Command(options.postbuild, shell=True, + extra_env={'GBP_CHANGES_FILE': changes, + 'GBP_BUILD_DIR': export_dir})() + + # Tag (note: tags the exported version) + if options.tag or options.tag_only: + gbp.log.info("Tagging %s" % spec.version) + tag = repo.version_to_tag(options.packaging_tag, spec.version) + if options.retag and repo.has_tag(tag): + repo.delete_tag(tag) + repo.create_tag(name=tag, msg="Distribution release %s" % spec.version, + sign=options.sign_tags, keyid=options.keyid, commit=tree) + if options.posttag: + sha = repo.rev_parse("%s^{}" % tag) + Command(options.posttag, shell=True, + extra_env={'GBP_TAG': tag, + 'GBP_BRANCH': branch, + 'GBP_SHA1': sha})() + except CommandExecFailed: + retval = 1 + except GitRepositoryError as err: + gbp.log.err("Git command failed: %s" % err) + ret = 1 + except GbpError, err: + if len(err.__str__()): + gbp.log.err(err) + retval = 1 + except rpm.NoSpecError, err: + gbp.log.err(err) + retval = 1 + finally: + drop_index(repo) + + # Clean temporary dumpdir + if dump_dir and retval == 0: + shutil.rmtree(dump_dir) + + if not options.tag_only: + if spec and options.notify: + summary = "Gbp-rpm %s" % ["failed", "successful"][not retval] + message = ("Build of %s %s %s" % (spec.name, + spec.version, + ["failed", "succeeded"][not retval])) + if not gbp.notifications.notify(summary, message, options.notify): + gbp.log.err("Failed to send notification") + retval = 1 + + return retval + +if __name__ == '__main__': + sys.exit(main(sys.argv)) + +# vim:et:ts=4:sw=4:et:sts=4:ai:set list listchars=tab\:»·,trail\:·: diff --git a/setup.py b/setup.py index 3902575d..2aabf60c 100644 --- a/setup.py +++ b/setup.py @@ -57,7 +57,8 @@ setup(name = "gbp", 'bin/gbp-create-remote-repo', 'bin/git-pbuilder', 'bin/git-import-srpm', - 'bin/gbp-pq-rpm'], + 'bin/gbp-pq-rpm', + 'bin/git-buildpackage-rpm'], packages = find_packages(exclude=['tests', 'tests.*']), data_files = [("/etc/git-buildpackage/", ["gbp.conf"]),], setup_requires=['nose>=0.11.1', 'coverage>=2.85', 'nosexcover>=1.0.7'] if \ diff --git a/tests/01_test_help.py b/tests/01_test_help.py index d0266a66..d1e96f21 100644 --- a/tests/01_test_help.py +++ b/tests/01_test_help.py @@ -28,7 +28,8 @@ class TestHelp(unittest.TestCase): """Test help output of RPM-specific commands""" def testHelpRpm(self): for script in ['import_srpm', - 'pq_rpm']: + 'pq_rpm', + 'buildpackage_rpm']: module = 'gbp.scripts.%s' % script m = __import__(module, globals(), locals(), ['main'], -1) self.assertRaises(SystemExit, -- cgit v1.2.3 From ecb143f953352a2b293503de642e3c21bbd614d2 Mon Sep 17 00:00:00 2001 From: Markus Lehtonen Date: Thu, 12 Jan 2012 15:39:55 +0200 Subject: Introduce git-import-orig-rpm tool Initial version of the git-import-orig-rpm: version of git-import-orig intended for maintaining rpm packages. Signed-off-by: Markus Lehtonen --- bin/git-import-orig-rpm | 5 + gbp/config.py | 4 + gbp/scripts/import_orig_rpm.py | 315 +++++++++++++++++++++++++++++++++++++++++ setup.py | 3 +- tests/01_test_help.py | 3 +- 5 files changed, 328 insertions(+), 2 deletions(-) create mode 100755 bin/git-import-orig-rpm create mode 100755 gbp/scripts/import_orig_rpm.py diff --git a/bin/git-import-orig-rpm b/bin/git-import-orig-rpm new file mode 100755 index 00000000..9e760c00 --- /dev/null +++ b/bin/git-import-orig-rpm @@ -0,0 +1,5 @@ +#! /usr/bin/python -u +import sys +from gbp.scripts.import_orig_rpm import main + +sys.exit(main(sys.argv)) diff --git a/gbp/config.py b/gbp/config.py index cb07cf1c..b5a85a3f 100644 --- a/gbp/config.py +++ b/gbp/config.py @@ -579,6 +579,7 @@ class GbpOptionParserRpm(GbpOptionParser): defaults.update( { 'builder' : 'rpmbuild', 'cleaner' : '/bin/true', + 'merge' : 'False', 'packaging-dir' : '', 'packaging-tag' : 'packaging/%(version)s', 'pq-branch' : 'development/%(branch)s', @@ -591,6 +592,7 @@ class GbpOptionParserRpm(GbpOptionParser): 'rpmbuild-srpmdir' : 'SRPMS', 'rpmbuild-buildrootdir' : 'BUILDROOT', 'patch-export' : 'False', + 'pristine-tarball-name' : 'auto', } ) help = dict(GbpOptionParser.help) @@ -605,6 +607,8 @@ class GbpOptionParserRpm(GbpOptionParser): "Spec file to use, 'auto' makes gbp to guess, other values make the packaging-dir option to be ignored, default is '%(spec-file)s'", 'patch-export': "Create patches between upstream and export-treeish, default is '%(patch-export)s'", + 'pristine-tarball-name': + "Filename to record to pristine-tar, set to 'auto' to not mangle the file name, default is '%(pristine-tarball-name)s'", } ) # vim:et:ts=4:sw=4:et:sts=4:ai:set list listchars=tab\:»·,trail\:·: diff --git a/gbp/scripts/import_orig_rpm.py b/gbp/scripts/import_orig_rpm.py new file mode 100755 index 00000000..0a99a086 --- /dev/null +++ b/gbp/scripts/import_orig_rpm.py @@ -0,0 +1,315 @@ +# vim: set fileencoding=utf-8 : +# +# (C) 2006, 2007, 2009, 2011 Guido Guenther +# (C) 2012 Intel Corporation +# This program is free software; you can redistribute it and/or modify +# it under the terms of the GNU General Public License as published by +# the Free Software Foundation; either version 2 of the License, or +# (at your option) any later version. +# +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with this program; if not, write to the Free Software +# Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA +# +"""Import a new upstream version into a git repository""" + +import ConfigParser +import os +import sys +import tempfile +import gbp.command_wrappers as gbpc +import string +from gbp.pkg import parse_archive_filename +from gbp.rpm import (RpmUpstreamSource, SpecFile, NoSpecError, parse_spec, + guess_spec, guess_spec_repo) +from gbp.rpm.policy import RpmPkgPolicy +from gbp.rpm.git import (GitRepositoryError, RpmGitRepository) +from gbp.config import GbpOptionParserRpm, GbpOptionGroup, no_upstream_branch_msg +from gbp.errors import GbpError +import gbp.log +from gbp.scripts.common.import_orig import (cleanup_tmp_tree, ask_package_name, + ask_package_version, + prepare_sources) + + +def upstream_import_commit_msg(options, version): + return options.import_msg % dict(version=version) + + +def detect_name_and_version(repo, source, options): + # Guess defaults for the package name and version from the + # original tarball. + (guessed_package, guessed_version) = source.guess_version() or ('', '') + + # Try to find the source package name + try: + spec = parse_spec(guess_spec(os.path.join(repo.path, options.packaging_dir), + True, + os.path.basename(repo.path) + '.spec')) + sourcepackage = spec.name + except NoSpecError: + try: + # Check the spec file from the repository, in case + # we're not on the packaging-branch (but upstream, for + # example). + specfile = guess_spec_repo(repo, options.packaging_branch, options.packaging_dir) + spec = SpecFile(specfile) + sourcepackage = spec.name + except NoSpecError: + if options.interactive: + sourcepackage = ask_package_name(guessed_package, + RpmPkgPolicy.is_valid_packagename, + RpmPkgPolicy.packagename_msg) + else: + if guessed_package: + sourcepackage = guessed_package + else: + raise GbpError, "Couldn't determine upstream package name. Use --interactive." + + # Try to find the version. + if options.version: + version = options.version + else: + if options.interactive: + version = ask_package_version(guessed_version, + RpmPkgPolicy.is_valid_upstreamversion, + RpmPkgPolicy.upstreamversion_msg) + else: + if guessed_version: + version = guessed_version + else: + raise GbpError, "Couldn't determine upstream version. Use '-u' or --interactive." + + return (sourcepackage, version) + + +def find_source(options, args): + """Find the tarball to import + @return: upstream source filename or None if nothing to import + @rtype: string + @raise GbpError: raised on all detected errors + """ + if len(args) > 1: # source specified + raise GbpError, "More than one archive specified. Try --help." + elif len(args) == 0: + raise GbpError, "No archive to import specified. Try --help." + else: + return RpmUpstreamSource(args[0]) + + +def pristine_tarball_name(source, pkg_name, pkg_version, pristine_name): + old_filename = os.path.basename(source.path) + base_name, _fmt, _comp = parse_archive_filename(old_filename) + if pristine_name != 'auto': + ext = string.replace(old_filename, base_name, '', 1) + return pristine_name % {'name': pkg_name, + 'version': pkg_version, + 'upstreamversion': pkg_version, + 'filename_base': base_name, + 'filename_ext': ext} + # Need to repack and mangle filename if the archive is not + # pristine-tar-compatible -> we decide to create gz compressed tarball + elif not source.is_tarball(): + return "%s.tar.gz" % base_name + return old_filename + + +def set_bare_repo_options(options): + """Modify options for import into a bare repository""" + if options.pristine_tar or options.merge: + gbp.log.info("Bare repository: setting %s%s options" + % (["", " '--no-pristine-tar'"][options.pristine_tar], + ["", " '--no-merge'"][options.merge])) + options.pristine_tar = False + options.merge = False + + +def parse_args(argv): + try: + parser = GbpOptionParserRpm(command=os.path.basename(argv[0]), + prefix='', + usage='%prog [options] /path/to/upstream-version.tar.gz') + except ConfigParser.ParsingError, err: + gbp.log.err(err) + return None, None + + import_group = GbpOptionGroup(parser, "import options", + "pristine-tar and filtering") + tag_group = GbpOptionGroup(parser, "tag options", + "options related to git tag creation") + branch_group = GbpOptionGroup(parser, "version and branch naming options", + "version number and branch layout options") + cmd_group = GbpOptionGroup(parser, "external command options", "how and when to invoke external commands and hooks") + + for group in [import_group, branch_group, tag_group, cmd_group ]: + parser.add_option_group(group) + + branch_group.add_option("-u", "--upstream-version", dest="version", + help="Upstream Version") + branch_group.add_config_file_option(option_name="packaging-branch", + dest="packaging_branch") + branch_group.add_config_file_option(option_name="upstream-branch", + dest="upstream_branch") + branch_group.add_option("--upstream-vcs-tag", dest="vcs_tag", + help="Upstream VCS tag add to the merge commit") + branch_group.add_boolean_config_file_option(option_name="merge", dest="merge") + branch_group.add_config_file_option(option_name="packaging-dir", dest="packaging_dir") + + tag_group.add_boolean_config_file_option(option_name="sign-tags", + dest="sign_tags") + tag_group.add_config_file_option(option_name="keyid", + dest="keyid") + tag_group.add_config_file_option(option_name="upstream-tag", + dest="upstream_tag") + import_group.add_config_file_option(option_name="filter", + dest="filters", action="append") + import_group.add_boolean_config_file_option(option_name="pristine-tar", + dest="pristine_tar") + import_group.add_boolean_config_file_option(option_name="filter-pristine-tar", + dest="filter_pristine_tar") + import_group.add_config_file_option(option_name="pristine-tarball-name", + dest="pristine_tarball_name") + import_group.add_config_file_option(option_name="import-msg", + dest="import_msg") + cmd_group.add_config_file_option(option_name="postimport", dest="postimport") + + parser.add_boolean_config_file_option(option_name="interactive", + dest='interactive') + parser.add_option("-v", "--verbose", action="store_true", dest="verbose", default=False, + help="verbose command execution") + parser.add_config_file_option(option_name="color", dest="color", type='tristate') + + (options, args) = parser.parse_args(argv[1:]) + gbp.log.setup(options.color, options.verbose) + + return options, args + + +def main(argv): + ret = 0 + + (options, args) = parse_args(argv) + if not options: + return 1 + + tmpdir = tempfile.mkdtemp(dir='../') + try: + source = find_source(options, args) + try: + repo = RpmGitRepository('.') + except GitRepositoryError: + raise GbpError, "%s is not a git repository" % (os.path.abspath('.')) + + # an empty repo has now branches: + initial_branch = repo.get_branch() + is_empty = False if initial_branch else True + + if not repo.has_branch(options.upstream_branch) and not is_empty: + gbp.log.err(no_upstream_branch_msg % options.upstream_branch) + raise GbpError + + (sourcepackage, version) = detect_name_and_version(repo, source, options) + + (clean, out) = repo.is_clean() + if not clean and not is_empty: + gbp.log.err("Repository has uncommitted changes, commit these first: ") + raise GbpError, out + + if repo.bare: + set_bare_repo_options(options) + + # Prepare sources for importing + if options.pristine_tar: + prepare_pristine = pristine_tarball_name(source, sourcepackage, + version, + options.pristine_tarball_name) + else: + prepare_pristine = None + unpacked_orig, pristine_orig = \ + prepare_sources(source, sourcepackage, version, + prepare_pristine, options.filters, + options.filter_pristine_tar, + None, tmpdir) + + # Don't mess up our repo with git metadata from an upstream tarball + if os.path.isdir(os.path.join(unpacked_orig, '.git/')): + raise GbpError("The orig tarball contains .git metadata - " + "giving up.") + try: + filter_msg = ["", " (filtering out %s)" + % options.filters][len(options.filters) > 0] + gbp.log.info("Importing '%s' to branch '%s'%s..." % (source.path, + options.upstream_branch, + filter_msg)) + gbp.log.info("Source package is %s" % sourcepackage) + gbp.log.info("Upstream version is %s" % version) + + msg = upstream_import_commit_msg(options, version) + + if options.vcs_tag: + parents = [repo.rev_parse("%s^{}" % options.vcs_tag)] + else: + parents = None + + commit = repo.commit_dir(unpacked_orig, + msg=msg, + branch=options.upstream_branch, + other_parents=parents, + create_missing_branch=True, + ) + if options.pristine_tar and pristine_orig: + gbp.log.info("Pristine-tar: commiting %s" % pristine_orig) + repo.pristine_tar.commit(pristine_orig, options.upstream_branch) + + tag = repo.version_to_tag(options.upstream_tag, version) + repo.create_tag(name=tag, + msg="Upstream version %s" % version, + commit=commit, + sign=options.sign_tags, + keyid=options.keyid) + if options.merge: + gbp.log.info("Merging to '%s'" % options.packaging_branch) + if repo.has_branch(options.packaging_branch): + repo.set_branch(options.packaging_branch) + try: + repo.merge(tag) + except GitRepositoryError: + raise GbpError, """Merge failed, please resolve.""" + else: + repo.create_branch(options.packaging_branch, rev=options.upstream_branch) + if repo.get_branch() == options.packaging_branch: + repo.force_head(options.packaging_branch, hard=True) + if options.postimport: + info = { 'upstreamversion': version } + env = { 'GBP_BRANCH': options.packaging_branch } + gbpc.Command(options.postimport % info, extra_env=env, + shell=True)() + # Update working copy and index if we've possibly updated the + # checked out branch + current_branch = repo.get_branch() + if (current_branch == options.upstream_branch or + current_branch == repo.pristine_tar_branch): + repo.force_head(current_branch, hard=True) + except (GitRepositoryError, gbpc.CommandExecFailed): + raise GbpError, "Import of %s failed" % source.path + except GbpError, err: + if len(err.__str__()): + gbp.log.err(err) + ret = 1 + + if tmpdir: + cleanup_tmp_tree(tmpdir) + + if not ret: + gbp.log.info("Successfully imported version %s of %s" % (version, source.path)) + return ret + +if __name__ == "__main__": + sys.exit(main(sys.argv)) + +# vim:et:ts=4:sw=4:et:sts=4:ai:set list listchars=tab\:»·,trail\:·: diff --git a/setup.py b/setup.py index 2aabf60c..4579d025 100644 --- a/setup.py +++ b/setup.py @@ -58,7 +58,8 @@ setup(name = "gbp", 'bin/git-pbuilder', 'bin/git-import-srpm', 'bin/gbp-pq-rpm', - 'bin/git-buildpackage-rpm'], + 'bin/git-buildpackage-rpm', + 'bin/git-import-orig-rpm'], packages = find_packages(exclude=['tests', 'tests.*']), data_files = [("/etc/git-buildpackage/", ["gbp.conf"]),], setup_requires=['nose>=0.11.1', 'coverage>=2.85', 'nosexcover>=1.0.7'] if \ diff --git a/tests/01_test_help.py b/tests/01_test_help.py index d1e96f21..6a4810bb 100644 --- a/tests/01_test_help.py +++ b/tests/01_test_help.py @@ -29,7 +29,8 @@ class TestHelp(unittest.TestCase): def testHelpRpm(self): for script in ['import_srpm', 'pq_rpm', - 'buildpackage_rpm']: + 'buildpackage_rpm', + 'import_orig_rpm']: module = 'gbp.scripts.%s' % script m = __import__(module, globals(), locals(), ['main'], -1) self.assertRaises(SystemExit, -- cgit v1.2.3 From 89dfa12e6d196cf7d6f28487c20d4e64887f5760 Mon Sep 17 00:00:00 2001 From: Markus Lehtonen Date: Thu, 12 Jan 2012 15:40:18 +0200 Subject: rpm: add rpm-specific example config file Signed-off-by: Markus Lehtonen --- gbp-rpm.conf | 126 +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 126 insertions(+) create mode 100644 gbp-rpm.conf diff --git a/gbp-rpm.conf b/gbp-rpm.conf new file mode 100644 index 00000000..927b6ecd --- /dev/null +++ b/gbp-rpm.conf @@ -0,0 +1,126 @@ +# Configuration file for git-buildpackage rpm tools + +[DEFAULT] +# Default build command +#builder = rpmbuild -ba +# Default clean command: +#cleaner = git clean -fd +# Default branch for upstream sources +#upstream-branch = upstream +# Default branch for the packaging files +#packaging-branch = master +# Default tag formats to be used +#upstream-tag = upstream/%(version)s +#packaging-tag = packaging/%(version)s +# Use pristine-tar +#pristine-tar = True +# Don't check if packaging-branch == current branch +#ignore-branch = True +# Use color when on a terminal, alternatives: on/true, off/false or auto +#color = auto +# Directory containing rpm packaging files +#packaging-dir=rpm +# Spec file to be used +#spec-file = gbp.spec +# Export patches with numbering in filenames +#patch-numbers = False + +### +### Options only affecting git-buildpackage-rpm +### +[git-buildpackage-rpm] +# Look for a tag matching the upstream version when creating a tarball +#upstream-tree = tag +# Uncomment this to automatically GPG sign tags +#sign-tags = True +# Keyid to GPG sign tags with +#keyid = 0xdeadbeef +# Push to a remote repository after a successful tag +#posttag = git-push git.example.com +# Run rpmlint after a successful build (for all rpm's found under build dir) +#postbuild = find $GBP_BUILD_DIR -name '*rpm' -exec rpmlint -i {} \; +# Run a script before build +#prebuild = GIT_DIR=$GBP_GIT_DIR my_prebuild.sh +# Build/export in a non-default directory +#export-dir = ../build-area/ +# Special directory to look for pre-built orig source archives +#tarball-dir = ../tarballs/ +# Build even if uncommited local changes are present +#ignore-new = True +# Commit-ish to build +#export = HEAD +# Use best compression +#compression-level = best +# Don't send notifications, alternatives: on/true, off/false or auto +#notify = off +# Transparently handle submodules +#submodules = True +# Rpmbuild related options +#rpmbuild-builddir=BUILD_DIR +#rpmbuild-rpmdir=RPM_DIR +#rpmbuild-sourcedir=SOURCE_DIR +#rpmbuild-specdir=SPEC_DIR +#rpmbuild-srpmdir=SRPM_DIR +#rpmbuild-buildrootdir=BUILDROOT_DIR +# Generate patches against upstream +#patch-export = True + +### +### Options only affecting git-import-orig-rpm +### +[git-import-orig-rpm] +# Set a different upstream branch to import to: +#upstream-branch = newupstream +# Set a different branch to merge to: +#packaging-branch = pkgclean +# Don't merge new upstream to packaging branch by default: +#merge = False +# Filter out files when importing +#filter = .svn +# Filter out files from tarball passed to pristine tar: +#filter-pristine-tar = True +# Name used in storing tarballs in pristine-tar branch +#pristine-tarball-name = %(name)s_%(version)s%(filename_ext)s +# Run hook after the import +#postimport = my_postimport.sh +# Commit message for new upstream version +#import-msg = New upstream version %(version)s + +### +### Options only affecting git-import-srpm +### +[git-import-srpm] +# Set a different upstream branch +#upstream-branch = svn-upstream +# Filter out files when importing +#filter = [ 'CVS', '.cvsignore' ] +# Force committer of upstream source / packaging to be the same as author +#author-is-committer = True + +### +### Options only affecting gbp-pq-rpm +### +[gbp-pq-rpm] +# Name of the patch-queue / development branch +pq-branch = %(branch)s-devel + +### +### Options only affecting gbp-clone +### +[gbp-clone] +# Track pristine-tar branch +#pristine-tar = True + +### +### Options only affecting gbp-pull +### +[gbp-pull] +# Pull pristine-tar branch +#pristine-tar = True + +### +### Options only affecting gbp-create-remote-repo +### +[gbp-create-remote-repo] +# Disable remote branch tracking +#track = False -- cgit v1.2.3 From c81cd93af3723277351900c70cdf640188cbb1e4 Mon Sep 17 00:00:00 2001 From: Markus Lehtonen Date: Thu, 12 Jan 2012 15:45:06 +0200 Subject: rpm: add 'vendor' config option Intended to represent the distribution vendor (e.g. 'Debian'). This can be used in tag and branch name formatting. Signed-off-by: Markus Lehtonen --- gbp-rpm.conf | 2 ++ gbp/config.py | 5 ++++- gbp/rpm/git.py | 11 +++++++---- gbp/scripts/buildpackage_rpm.py | 7 ++++--- gbp/scripts/import_orig_rpm.py | 2 +- gbp/scripts/import_srpm.py | 21 +++++++++++---------- gbp/scripts/pq_rpm.py | 7 ++++--- 7 files changed, 33 insertions(+), 22 deletions(-) diff --git a/gbp-rpm.conf b/gbp-rpm.conf index 927b6ecd..99eac632 100644 --- a/gbp-rpm.conf +++ b/gbp-rpm.conf @@ -9,6 +9,8 @@ #upstream-branch = upstream # Default branch for the packaging files #packaging-branch = master +# Name of the distribution vendor +#vendor=myvendor # Default tag formats to be used #upstream-tag = upstream/%(version)s #packaging-tag = packaging/%(version)s diff --git a/gbp/config.py b/gbp/config.py index b5a85a3f..8a4fd009 100644 --- a/gbp/config.py +++ b/gbp/config.py @@ -577,11 +577,12 @@ class GbpOptionParserRpm(GbpOptionParser): """ defaults = dict(GbpOptionParser.defaults) defaults.update( { + 'vendor' : 'vendor', 'builder' : 'rpmbuild', 'cleaner' : '/bin/true', 'merge' : 'False', 'packaging-dir' : '', - 'packaging-tag' : 'packaging/%(version)s', + 'packaging-tag' : '%(vendor)s/%(version)s', 'pq-branch' : 'development/%(branch)s', 'spec-file' : 'auto', 'export-dir' : '../rpmbuild', @@ -597,6 +598,8 @@ class GbpOptionParserRpm(GbpOptionParser): help = dict(GbpOptionParser.help) help.update( { + 'vendor': + "Distribution vendor name", 'packaging-dir': "subdir where packaging files are stored, default is '%(packaging-dir)s'", 'packaging-tag': diff --git a/gbp/rpm/git.py b/gbp/rpm/git.py index ca1a241b..dac555cf 100644 --- a/gbp/rpm/git.py +++ b/gbp/rpm/git.py @@ -27,7 +27,7 @@ class RpmGitRepository(GitRepository): super(RpmGitRepository, self).__init__(path) self.pristine_tar = PristineTar(self) - def find_version(self, format, version): + def find_version(self, format, version, vendor="vendor"): """ Check if a certain version is stored in this repo and return the SHA1 of the related commit. That is, an annotated tag is dereferenced to the @@ -39,20 +39,23 @@ class RpmGitRepository(GitRepository): @type version: C{str} @return: sha1 of the commit the tag references to """ - tag = self.version_to_tag(format, version) + tag = self.version_to_tag(format, version, vendor) if self.has_tag(tag): # new tags are injective # dereference to a commit object return self.rev_parse("%s^0" % tag) return None @staticmethod - def version_to_tag(format, version): + def version_to_tag(format, version, vendor="vendor"): """Generate a tag from a given format and a version >>> RpmGitRepository.version_to_tag("packaging/%(version)s", "0:0~0") 'packaging/0%0_0' + >>> RpmGitRepository.version_to_tag("%(vendor)s/v%(version)s", "1.0", "myvendor") + 'myvendor/v1.0' """ - return format % dict(version=RpmGitRepository._sanitize_version(version)) + return format % dict(version=RpmGitRepository._sanitize_version(version), + vendor=vendor) @staticmethod def _sanitize_version(version): diff --git a/gbp/scripts/buildpackage_rpm.py b/gbp/scripts/buildpackage_rpm.py index a3c75d63..786228f7 100755 --- a/gbp/scripts/buildpackage_rpm.py +++ b/gbp/scripts/buildpackage_rpm.py @@ -147,7 +147,7 @@ def pristine_tar_build_orig(repo, orig_file, output_dir, options): def get_upstream_tree(repo, spec, options): """Determine the upstream tree from the given options""" if options.upstream_tree.upper() == 'TAG': - upstream_tree = repo.version_to_tag(options.upstream_tag, spec.version) + upstream_tree = repo.version_to_tag(options.upstream_tag, spec.version, vendor="Upstream") elif options.upstream_tree.upper() == 'BRANCH': if not repo.has_branch(options.upstream_branch): raise GbpError("%s is not a valid branch" % options.upstream_branch) @@ -250,6 +250,7 @@ def parse_args(argv, prefix): help="verbose command execution") parser.add_config_file_option(option_name="color", dest="color", type='tristate') parser.add_config_file_option(option_name="notify", dest="notify", type='tristate') + parser.add_config_file_option(option_name="vendor", action="store", dest="vendor") tag_group.add_option("--git-tag", action="store_true", dest="tag", default=False, help="create a tag after a successful build") tag_group.add_option("--git-tag-only", action="store_true", dest="tag_only", default=False, @@ -468,10 +469,10 @@ def main(argv): # Tag (note: tags the exported version) if options.tag or options.tag_only: gbp.log.info("Tagging %s" % spec.version) - tag = repo.version_to_tag(options.packaging_tag, spec.version) + tag = repo.version_to_tag(options.packaging_tag, spec.version, vendor=options.vendor) if options.retag and repo.has_tag(tag): repo.delete_tag(tag) - repo.create_tag(name=tag, msg="Distribution release %s" % spec.version, + repo.create_tag(name=tag, msg="%s release %s" % (options.vendor, spec.version), sign=options.sign_tags, keyid=options.keyid, commit=tree) if options.posttag: sha = repo.rev_parse("%s^{}" % tag) diff --git a/gbp/scripts/import_orig_rpm.py b/gbp/scripts/import_orig_rpm.py index 0a99a086..3978eff2 100755 --- a/gbp/scripts/import_orig_rpm.py +++ b/gbp/scripts/import_orig_rpm.py @@ -266,7 +266,7 @@ def main(argv): gbp.log.info("Pristine-tar: commiting %s" % pristine_orig) repo.pristine_tar.commit(pristine_orig, options.upstream_branch) - tag = repo.version_to_tag(options.upstream_tag, version) + tag = repo.version_to_tag(options.upstream_tag, version, vendor="Upstream") repo.create_tag(name=tag, msg="Upstream version %s" % version, commit=commit, diff --git a/gbp/scripts/import_srpm.py b/gbp/scripts/import_srpm.py index 999373eb..9519df57 100755 --- a/gbp/scripts/import_srpm.py +++ b/gbp/scripts/import_srpm.py @@ -90,11 +90,11 @@ def committer_from_author(author, options): return committer -def move_tag_stamp(repo, format, version): +def move_tag_stamp(repo, format, version, vendor): "Move tag out of the way appending the current timestamp" - old = repo.version_to_tag(format, version) + old = repo.version_to_tag(format, version, vendor) timestamped = "%s~%s" % (version, int(time.time())) - new = repo.version_to_tag(format, timestamped) + new = repo.version_to_tag(format, timestamped, vendor) repo.move_tag(old, new) @@ -129,6 +129,7 @@ def parse_args(argv): parser.add_config_file_option(option_name="color", dest="color", type='tristate') parser.add_option("--download", action="store_true", dest="download", default=False, help="download source package") + parser.add_config_file_option(option_name="vendor", action="store", dest="vendor") branch_group.add_config_file_option(option_name="packaging-branch", dest="packaging_branch") branch_group.add_config_file_option(option_name="upstream-branch", @@ -272,14 +273,14 @@ def main(argv): else: upstream = None - format = [(options.upstream_tag, "Upstream"), (options.packaging_tag, "Distribution")][options.native] - tag = repo.version_to_tag(format[0], upstream_version) + format = [(options.upstream_tag, "Upstream"), (options.packaging_tag, options.vendor)][options.native] + tag = repo.version_to_tag(format[0], upstream_version, options.vendor) - if repo.find_version(options.packaging_tag, pkgver): + if repo.find_version(options.packaging_tag, pkgver, options.vendor): gbp.log.warn("Version %s already imported." % pkgver) if options.allow_same_version: gbp.log.info("Moving tag of version '%s' since import forced" % pkgver) - move_tag_stamp(repo, options.packaging_tag, pkgver) + move_tag_stamp(repo, options.packaging_tag, pkgver, options.vendor) else: raise SkipImport @@ -300,7 +301,7 @@ def main(argv): # Import upstream sources if upstream: - upstream_commit = repo.find_version(format[0], upstream_version) + upstream_commit = repo.find_version(format[0], upstream_version, options.vendor) if not upstream_commit: gbp.log.info("Tag %s not found, importing %s tarball" % (tag, format[1])) @@ -346,8 +347,8 @@ def main(argv): "\nAlso check the --create-missing-branches option.") raise GbpError - tag = repo.version_to_tag(options.packaging_tag, pkgver) - msg = "Distribution release %s" % pkgver + tag = repo.version_to_tag(options.packaging_tag, pkgver, options.vendor) + msg = "%s release %s" % (options.vendor, pkgver) if options.orphan_packaging or not upstream: parents = [] diff --git a/gbp/scripts/pq_rpm.py b/gbp/scripts/pq_rpm.py index 1e3c44a9..b1a10ca1 100755 --- a/gbp/scripts/pq_rpm.py +++ b/gbp/scripts/pq_rpm.py @@ -143,7 +143,7 @@ def export_patches(repo, branch, options): raise GbpError, "Can't parse spec" # Find upstream version - upstream_commit = repo.find_version(options.upstream_tag, spec.version) + upstream_commit = repo.find_version(options.upstream_tag, spec.version, vendor="Upstream") if not upstream_commit: raise GbpError, ("Couldn't find upstream version %s. Don't know on what base to import." % spec.version) @@ -234,7 +234,7 @@ def import_spec_patches(repo, branch, options): raise GbpError, "Can't parse spec" # Find upstream version - commit = repo.find_version(options.upstream_tag, spec.version) + commit = repo.find_version(options.upstream_tag, spec.version, vendor="Upstream") if commit: commits=[commit] else: @@ -296,7 +296,7 @@ def rebase_pq(repo, branch, options): raise GbpError, "Can't parse spec" # Find upstream version - upstream_commit = repo.find_version(options.upstream_tag, spec.version) + upstream_commit = repo.find_version(options.upstream_tag, spec.version, vendor="Upstream") if not upstream_commit: raise GbpError, ("Couldn't find upstream version %s. Don't know on what base to import." % spec.version) @@ -340,6 +340,7 @@ def main(argv): help="Verbose command execution") parser.add_option("--force", dest="force", action="store_true", default=False, help="In case of import even import if the branch already exists") + parser.add_config_file_option(option_name="vendor", action="store", dest="vendor") parser.add_config_file_option(option_name="color", dest="color", type='tristate') parser.add_config_file_option(option_name="upstream-tag", dest="upstream_tag") parser.add_config_file_option(option_name="spec-file", dest="spec_file") -- cgit v1.2.3 From 510e8170e3029f818fecce5af372747b113a7064 Mon Sep 17 00:00:00 2001 From: Markus Lehtonen Date: Thu, 12 Apr 2012 16:37:37 +0300 Subject: README: mention RPM support Signed-off-by: Markus Lehtonen --- README | 9 +++++++++ 1 file changed, 9 insertions(+) diff --git a/README b/README index 3301ae61..074b345b 100644 --- a/README +++ b/README @@ -5,3 +5,12 @@ For more documentation see the manual. On Debian systems this can be found in It can be found online at http://honk.sigxcpu.org/projects/git-buildpackage/manual-html/gbp.html + + +The limited documentation available for the RPM support can be found at + + http://marquiz.github.com/git-buildpackage-rpm/ + +Unfortunately, the manpages for RPM tools are still missing. Refer to +--help option of the commands, for the most detailed description of different +options. -- cgit v1.2.3 From 2dadc257460c6ae3b122c3f6da25d9eff934272a Mon Sep 17 00:00:00 2001 From: Markus Lehtonen Date: Mon, 23 Apr 2012 15:29:53 +0300 Subject: Add rpm packaging files Signed-off-by: Ed Bartosh Signed-off-by: Olev Kartau Signed-off-by: Zhang Qiang Signed-off-by: Markus Lehtonen --- .gbp.conf | 17 +++ packaging/git-buildpackage.spec | 223 ++++++++++++++++++++++++++++++++++++++++ 2 files changed, 240 insertions(+) create mode 100644 .gbp.conf create mode 100644 packaging/git-buildpackage.spec diff --git a/.gbp.conf b/.gbp.conf new file mode 100644 index 00000000..6f74162f --- /dev/null +++ b/.gbp.conf @@ -0,0 +1,17 @@ +[DEFAULT] +# Do not merge to packaging (after update) +merge=False +# Vendor/Distro name +vendor=MyDistro +# Package is from Debian +upstream-tag=debian/%(version)s +# Don't use pristine-tar +pristine-tar=False +# Branch naming +packaging-branch=experimental-rpm +upstream-branch=master +# Subdir for RPM packaging data +packaging-dir=packaging +# Auto-generate patches against upstream +patch-export = True +patch-numbers = True diff --git a/packaging/git-buildpackage.spec b/packaging/git-buildpackage.spec new file mode 100644 index 00000000..3a193fdd --- /dev/null +++ b/packaging/git-buildpackage.spec @@ -0,0 +1,223 @@ +# Add --without docs rpmbuild option, i.e. docs are enabled by default +%bcond_without docs + +Name: git-buildpackage +Summary: Build packages from git +Version: 0.6.6 +Release: 0 +Group: Development/Tools/Building +License: GPLv2 +BuildArch: noarch +URL: https://honk.sigxcpu.org/piki/projects/git-buildpackage/ +Source0: %{name}_%{version}.tar.gz + +# Conditional package names for requirements +%if 0%{?fedora} || 0%{?centos_ver} +%define dpkg_pkg_name dpkg-devel +%else +%define dpkg_pkg_name dpkg +%endif + +%if 0%{?fedora} +%define man_pkg_name man-db +%else +%define man_pkg_name man +%endif + +%if 0%{?fedora} || 0%{?centos_ver} || 0%{?tizen_version:1} +%define python_pkg_name python +%else +%define python_pkg_name python-base +%endif + +%if 0%{?tizen_version:1} +%define rpm_python_pkg_name python-rpm +%else +%define rpm_python_pkg_name rpm-python +%endif + +Requires: %{name}-common = %{version}-%{release} +Requires: %{dpkg_pkg_name} +BuildRequires: python +BuildRequires: python-setuptools + +%if %{with docs} +BuildRequires: docbook-utils +BuildRequires: gtk-doc +BuildRequires: epydoc +%if 0%{?fedora} +BuildRequires: perl-podlators +%endif +%endif + +%if 0%{?do_unittests} +BuildRequires: python-coverage +BuildRequires: python-nose +BuildRequires: git-core +BuildRequires: %{man_pkg_name} +BuildRequires: %{dpkg_pkg_name} +BuildRequires: %{rpm_python_pkg_name} +BuildRequires: pristine-tar +BuildRequires: unzip +BuildRequires: gnupg +# Missing dep of dpkg in openSUSE +%if 0%{?suse_version} +BuildRequires: perl-TimeDate +%endif +%endif + +%description +Set of tools from Debian that integrate the package build system with Git. +This package contains the original Debian tools. + + +%package common +Summary: Common files for git-buildpackage debian and rpm tools +Group: Development/Tools/Building +Requires: git-core +Requires: %{man_pkg_name} +Requires: %{python_pkg_name} + +%description common +Common files and documentation, used by both git-buildpackage debian and rpm tools + + +%package rpm +Summary: Build RPM packages from git +Group: Development/Tools/Building +Requires: %{name}-common = %{version}-%{release} +Requires: rpm +Requires: %{rpm_python_pkg_name} + +%description rpm +Set of tools from Debian that integrate the package build system with Git. +This package contains the tools for building RPM packages. + + +%if %{with docs} +%package doc +Summary: Documentation for the git-buildpackage suite +Group: Development/Tools/Building + +%description doc +This package contains documentation for the git-buildpackage suite - both the +Debian and the RPM tool set. +%endif + + +%prep +%setup -q -n %{name}-%{version} + + + +%build +WITHOUT_NOSETESTS=1 python ./setup.py build + +%if %{with docs} +# Prepare apidocs +epydoc -n git-buildpackage --no-sourcecode -o docs/apidocs/ \ + gbp*.py git*.py gbp/ + +# HTML docs +HAVE_SGML2X=0 make -C docs/ +%endif + + +%if 0%{?do_unittests} +%check +GIT_CEILING_DIRECTORIES=%{_builddir} \ + GIT_AUTHOR_EMAIL=rpmbuild@example.com GIT_AUTHOR_NAME=rpmbuild \ + GIT_COMMITTER_NAME=$GIT_AUTHOR_NAME GIT_COMMITTER_EMAIL=$GIT_AUTHOR_EMAIL \ + python setup.py nosetests +%endif + + +%install +rm -rf %{buildroot} +WITHOUT_NOSETESTS=1 python ./setup.py install --root=%{buildroot} --prefix=/usr +rm -rf %{buildroot}%{python_sitelib}/*info + +%if %{with docs} +# Install man pages +install -d %{buildroot}%{_mandir}/man1 %{buildroot}%{_mandir}/man5 +install docs/*.1 %{buildroot}%{_mandir}/man1/ +install docs/*.5 %{buildroot}%{_mandir}/man5/ + +# Install html documentation +mkdir -p %{buildroot}%{_docdir}/%{name} +cp -r docs/manual-html %{buildroot}%{_docdir}/%{name} +cp -r docs/apidocs %{buildroot}%{_docdir}/%{name} +%endif + + +%files +%defattr(-,root,root,-) +%{_bindir}/gbp-pq +%{_bindir}/git-buildpackage +%{_bindir}/git-dch +%{_bindir}/git-import-dsc +%{_bindir}/git-import-dscs +%{_bindir}/git-import-orig +%{_bindir}/git-pbuilder +%{_bindir}/gbp-create-remote-repo +%{python_sitelib}/gbp/deb +%{python_sitelib}/gbp/scripts/pq.py* +%{python_sitelib}/gbp/scripts/buildpackage.py* +%{python_sitelib}/gbp/scripts/dch.py* +%{python_sitelib}/gbp/scripts/import_dsc.py* +%{python_sitelib}/gbp/scripts/import_dscs.py* +%{python_sitelib}/gbp/scripts/import_orig.py* +%{python_sitelib}/gbp/scripts/create_remote_repo.py* +%if %{with docs} +%{_mandir}/man1/gbp-buildpackage.1* +%{_mandir}/man1/gbp-create-remote-repo.1* +%{_mandir}/man1/gbp-dch.1* +%{_mandir}/man1/gbp-import-dsc.1* +%{_mandir}/man1/gbp-import-dscs.1* +%{_mandir}/man1/gbp-import-orig.1* +%{_mandir}/man1/gbp-pq.1* +%{_mandir}/man1/git-pbuilder.1* +%endif + +%files common +%defattr(-,root,root,-) +%{_bindir}/gbp +%{_bindir}/gbp-clone +%{_bindir}/gbp-pull +%dir %{python_sitelib}/gbp +%dir %{python_sitelib}/gbp/git +%dir %{python_sitelib}/gbp/pkg +%dir %{python_sitelib}/gbp/scripts +%dir %{python_sitelib}/gbp/scripts/common +%{python_sitelib}/gbp/*.py* +%{python_sitelib}/gbp/scripts/__init__.py* +%{python_sitelib}/gbp/scripts/clone.py* +%{python_sitelib}/gbp/scripts/config.py* +%{python_sitelib}/gbp/scripts/pull.py* +%{python_sitelib}/gbp/scripts/supercommand.py* +%{python_sitelib}/gbp/scripts/common/*.py* +%{python_sitelib}/gbp/git/*.py* +%{python_sitelib}/gbp/pkg/*.py* +%config %{_sysconfdir}/git-buildpackage +%if %{with docs} +%{_mandir}/man1/gbp.1* +%{_mandir}/man1/gbp-clone.1* +%{_mandir}/man1/gbp-config.1* +%{_mandir}/man1/gbp-pull.1* +%{_mandir}/man5/*.5* +%endif + + +%files rpm +%defattr(-,root,root,-) +%dir %{python_sitelib}/gbp/rpm +%{_bindir}/*rpm* +%{python_sitelib}/gbp/scripts/*rpm*.py* +%{python_sitelib}/gbp/rpm/*py* + + +%if %{with docs} +%files doc +%defattr(-,root,root,-) +%{_docdir}/%{name}/ +%endif -- cgit v1.2.3 From 9f1a9e6a421f7c1d7543764b7e43d254df5b6205 Mon Sep 17 00:00:00 2001 From: Markus Lehtonen Date: Thu, 25 Apr 2013 17:23:18 +0300 Subject: debian packaging: support for RPM tools Add requirements for git-buildpackage-rpm and other rpm tools. Signed-off-by: Markus Lehtonen --- debian/control | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/debian/control b/debian/control index f8e44a3e..c29d6ebc 100644 --- a/debian/control +++ b/debian/control @@ -24,6 +24,8 @@ Build-Depends: git (>= 1:1.7.9.1-1~), pristine-tar, unzip, +# For rpm (epydoc) + python-rpm Standards-Version: 3.9.4 Vcs-Git: git://honk.sigxcpu.org/git/git-buildpackage.git Vcs-Browser: https://honk.sigxcpu.org/gitweb/?p=git-buildpackage.git @@ -39,6 +41,9 @@ Depends: ${python:Depends}, git (>= 1:1.7.9.1-1~), man-db, python-pkg-resources, +# For rpm + python-rpm, + rpm2cpio Recommends: pristine-tar (>= 0.5), cowbuilder Suggests: python-notify, unzip Description: Suite to help with Debian packages in Git repositories -- cgit v1.2.3 From bb0241a66d6f2d46bf990bec48fc7728df2ef8b4 Mon Sep 17 00:00:00 2001 From: Ed Bartosh Date: Thu, 24 May 2012 16:16:12 +0300 Subject: debian packaging: split Debian package into subpackages Split Debian package into three packages, following the introduction of RPM tools. Now the Debian packaging resembles the default RPM packaging: - git-buildpackage-common contains the common code for Deb and RPM tools - git-buildpackage contains the Debian-specific modules/tools - git-buildpackage-rpm contains the RPM-specific modules/tools Signed-off-by: Zhang Qiang Signed-off-by: Ed Bartosh Signed-off-by: Markus Lehtonen --- debian/control | 39 +++++++++++++++++++++++++++------ debian/doc-base | 11 ---------- debian/docs | 3 --- debian/examples | 1 - debian/git-buildpackage-common.doc-base | 11 ++++++++++ debian/git-buildpackage-common.docs | 3 +++ debian/git-buildpackage-common.examples | 1 + debian/git-buildpackage-common.install | 13 +++++++++++ debian/git-buildpackage-common.links | 1 + debian/git-buildpackage-common.manpages | 5 +++++ debian/git-buildpackage-rpm.install | 3 +++ debian/git-buildpackage.install | 16 ++++++++++++++ debian/git-buildpackage.manpages | 8 +++++++ debian/manpages | 2 -- debian/rules | 5 +++++ 15 files changed, 98 insertions(+), 24 deletions(-) delete mode 100644 debian/doc-base delete mode 100644 debian/docs delete mode 100644 debian/examples create mode 100644 debian/git-buildpackage-common.doc-base create mode 100644 debian/git-buildpackage-common.docs create mode 100644 debian/git-buildpackage-common.examples create mode 100644 debian/git-buildpackage-common.install create mode 100644 debian/git-buildpackage-common.links create mode 100644 debian/git-buildpackage-common.manpages create mode 100644 debian/git-buildpackage-rpm.install create mode 100644 debian/git-buildpackage.install create mode 100644 debian/git-buildpackage.manpages delete mode 100644 debian/manpages diff --git a/debian/control b/debian/control index c29d6ebc..7964b5c3 100644 --- a/debian/control +++ b/debian/control @@ -32,20 +32,28 @@ Vcs-Browser: https://honk.sigxcpu.org/gitweb/?p=git-buildpackage.git Homepage: https://honk.sigxcpu.org/piki/projects/git-buildpackage/ X-Python-Version: >= 2.6 -Package: git-buildpackage + +Package: git-buildpackage-common Architecture: all Depends: ${python:Depends}, ${shlibs:Depends}, ${misc:Depends}, - devscripts (>= 2.13.5~), git (>= 1:1.7.9.1-1~), man-db, - python-pkg-resources, -# For rpm - python-rpm, - rpm2cpio -Recommends: pristine-tar (>= 0.5), cowbuilder + python-pkg-resources +Recommends: pristine-tar (>= 0.5) Suggests: python-notify, unzip +Description: Suite to help with packaging in Git repositories + This package contains the common API and scripts for Debian and rpm packaging + +Package: git-buildpackage +Architecture: all +Depends: ${python:Depends}, + ${shlibs:Depends}, + ${misc:Depends}, + devscripts (>= 2.13.5~), + git-buildpackage-common (= ${binary:Version}) +Recommends: cowbuilder Description: Suite to help with Debian packages in Git repositories This package contains the following tools: * gbp import-{dsc,dscs}: import existing Debian source packages into a git @@ -57,3 +65,20 @@ Description: Suite to help with Debian packages in Git repositories * gbp {pull,clone}: clone and pull from remote repos * gbp pq: manage debian/patches easily * gbp create-remote-repo: create remote repositories + +Package: git-buildpackage-rpm +Architecture: all +Depends: ${python:Depends}, + ${shlibs:Depends}, + ${misc:Depends}, + python-rpm, + rpm2cpio, + git-buildpackage-common (= ${binary:Version}) +Description: Suite to help with rpm packages in Git repositories + This package contains the following tools: + * git-import-srpm: import existing rpm source packages into a git + repository + * git-import-orig-rpm: import a new upstream version into the git repository + * git-buildpackage-rpm: build a package out of a git repository, check for local + modifications and tag appropriately + * gbp-pq-rpm: manage separate development and packaging branches diff --git a/debian/doc-base b/debian/doc-base deleted file mode 100644 index a7d60d01..00000000 --- a/debian/doc-base +++ /dev/null @@ -1,11 +0,0 @@ -Document: git-buildpackage -Title: Git-Buildpackage Manual -Author: Guido Guenther -Abstract: git-buildpackage is a suite to help with Debian packages in Git - repositories. This manual describes the utilities in this package, their - configuration and possible workflows. -Section: Programming - -Format: HTML -Index: /usr/share/doc/git-buildpackage/manual-html/index.html -Files: /usr/share/doc/git-buildpackage/manual-html/*.html diff --git a/debian/docs b/debian/docs deleted file mode 100644 index ce06068d..00000000 --- a/debian/docs +++ /dev/null @@ -1,3 +0,0 @@ -README -docs/manual-html/ -build/apidocs/ diff --git a/debian/examples b/debian/examples deleted file mode 100644 index e39721e2..00000000 --- a/debian/examples +++ /dev/null @@ -1 +0,0 @@ -examples/* diff --git a/debian/git-buildpackage-common.doc-base b/debian/git-buildpackage-common.doc-base new file mode 100644 index 00000000..b377b272 --- /dev/null +++ b/debian/git-buildpackage-common.doc-base @@ -0,0 +1,11 @@ +Document: git-buildpackage +Title: Git-Buildpackage Manual +Author: Guido Guenther +Abstract: git-buildpackage is a suite to help with Debian packages in Git + repositories. This manual describes the utilities in this package, their + configuration and possible workflows. +Section: Programming + +Format: HTML +Index: /usr/share/doc/git-buildpackage-common/manual-html/index.html +Files: /usr/share/doc/git-buildpackage-common/manual-html/*.html diff --git a/debian/git-buildpackage-common.docs b/debian/git-buildpackage-common.docs new file mode 100644 index 00000000..ce06068d --- /dev/null +++ b/debian/git-buildpackage-common.docs @@ -0,0 +1,3 @@ +README +docs/manual-html/ +build/apidocs/ diff --git a/debian/git-buildpackage-common.examples b/debian/git-buildpackage-common.examples new file mode 100644 index 00000000..e39721e2 --- /dev/null +++ b/debian/git-buildpackage-common.examples @@ -0,0 +1 @@ +examples/* diff --git a/debian/git-buildpackage-common.install b/debian/git-buildpackage-common.install new file mode 100644 index 00000000..5283d546 --- /dev/null +++ b/debian/git-buildpackage-common.install @@ -0,0 +1,13 @@ +usr/bin/gbp +usr/bin/gbp-clone +usr/bin/gbp-pull +usr/lib/python*/dist-packages/gbp/*.py* +usr/lib/python*/dist-packages/gbp/scripts/__init__.py* +usr/lib/python*/dist-packages/gbp/scripts/clone.py* +usr/lib/python*/dist-packages/gbp/scripts/config.py* +usr/lib/python*/dist-packages/gbp/scripts/pull.py* +usr/lib/python*/dist-packages/gbp/scripts/supercommand.py* +usr/lib/python*/dist-packages/gbp/scripts/common/*.py* +usr/lib/python*/dist-packages/gbp/git/*.py* +usr/lib/python*/dist-packages/gbp/pkg/*.py* +etc/git-buildpackage/gbp.conf diff --git a/debian/git-buildpackage-common.links b/debian/git-buildpackage-common.links new file mode 100644 index 00000000..e74ac0b9 --- /dev/null +++ b/debian/git-buildpackage-common.links @@ -0,0 +1 @@ +/usr/share/doc/git-buildpackage-common/manual-html/gbp.html /usr/share/doc/git-buildpackage-common/manual-html/index.html diff --git a/debian/git-buildpackage-common.manpages b/debian/git-buildpackage-common.manpages new file mode 100644 index 00000000..3280f63c --- /dev/null +++ b/debian/git-buildpackage-common.manpages @@ -0,0 +1,5 @@ +docs/gbp.1 +docs/gbp-clone.1 +docs/gbp-config.1 +docs/gbp-pull.1 +docs/*.5 diff --git a/debian/git-buildpackage-rpm.install b/debian/git-buildpackage-rpm.install new file mode 100644 index 00000000..8c49491e --- /dev/null +++ b/debian/git-buildpackage-rpm.install @@ -0,0 +1,3 @@ +usr/bin/*rpm* +usr/lib/python*/dist-packages/gbp/rpm/*.py* +usr/lib/python*/dist-packages/gbp/scripts/*rpm*.py* diff --git a/debian/git-buildpackage.install b/debian/git-buildpackage.install new file mode 100644 index 00000000..7a276d7e --- /dev/null +++ b/debian/git-buildpackage.install @@ -0,0 +1,16 @@ +usr/bin/gbp-pq +usr/bin/git-buildpackage +usr/bin/git-dch +usr/bin/git-import-dsc +usr/bin/git-import-dscs +usr/bin/git-import-orig +usr/bin/git-pbuilder +usr/bin/gbp-create-remote-repo +usr/lib/python*/dist-packages/gbp/deb/*.py* +usr/lib/python*/dist-packages/gbp/scripts/pq.py* +usr/lib/python*/dist-packages/gbp/scripts/buildpackage.py* +usr/lib/python*/dist-packages/gbp/scripts/dch.py* +usr/lib/python*/dist-packages/gbp/scripts/import_dsc.py* +usr/lib/python*/dist-packages/gbp/scripts/import_dscs.py* +usr/lib/python*/dist-packages/gbp/scripts/import_orig.py* +usr/lib/python*/dist-packages/gbp/scripts/create_remote_repo.py* diff --git a/debian/git-buildpackage.manpages b/debian/git-buildpackage.manpages new file mode 100644 index 00000000..fc937453 --- /dev/null +++ b/debian/git-buildpackage.manpages @@ -0,0 +1,8 @@ +docs/gbp-buildpackage.1 +docs/gbp-create-remote-repo.1 +docs/gbp-dch.1 +docs/gbp-import-dsc.1 +docs/gbp-import-dscs.1 +docs/gbp-import-orig.1 +docs/gbp-pq.1 +docs/git-pbuilder.1 diff --git a/debian/manpages b/debian/manpages deleted file mode 100644 index 09c93b1d..00000000 --- a/debian/manpages +++ /dev/null @@ -1,2 +0,0 @@ -docs/*.1 -docs/*.5 diff --git a/debian/rules b/debian/rules index a80bd520..3584c7a4 100755 --- a/debian/rules +++ b/debian/rules @@ -46,6 +46,11 @@ override_dh_auto_install: override_dh_auto_clean: dh_auto_clean + # Remove renamed files - renames are not correctly expressed in debian.diff + rm -f debian/doc-base + rm -f debian/docs + rm -f debian/examples + rm -f debian/manpages rm -rf build/ make -C docs/ clean -rm gbp/version.py -- cgit v1.2.3 From c91c2d9a64e40b3bd78550f896d5f5c98650eac1 Mon Sep 17 00:00:00 2001 From: Markus Lehtonen Date: Tue, 14 Jan 2014 09:39:12 +0200 Subject: debian packaging: relax requirements on devscripts No need to depend on the latest version. Signed-off-by: Markus Lehtonen --- debian/control | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/debian/control b/debian/control index 7964b5c3..a706b8ef 100644 --- a/debian/control +++ b/debian/control @@ -51,7 +51,7 @@ Architecture: all Depends: ${python:Depends}, ${shlibs:Depends}, ${misc:Depends}, - devscripts (>= 2.13.5~), + devscripts, git-buildpackage-common (= ${binary:Version}) Recommends: cowbuilder Description: Suite to help with Debian packages in Git repositories -- cgit v1.2.3 From 8162bcc433bd7882cfc24d96f317ef83e6333e47 Mon Sep 17 00:00:00 2001 From: Markus Lehtonen Date: Wed, 30 May 2012 09:23:46 +0300 Subject: buildpackage-rpm: add option --git-ignore-untracked Adds a new commandline option to ignore untracked files, when running git-buildpackage-rpm. When this option is given, the git-buildpackage-rpm command fails if there are changes to tracked files, but, succeeds if there are untracked files present. Normally it fails in either case. Signed-off-by: Markus Lehtonen --- gbp-rpm.conf | 4 +++- gbp/config.py | 3 +++ gbp/scripts/buildpackage_rpm.py | 5 +++-- 3 files changed, 9 insertions(+), 3 deletions(-) diff --git a/gbp-rpm.conf b/gbp-rpm.conf index 99eac632..15529f14 100644 --- a/gbp-rpm.conf +++ b/gbp-rpm.conf @@ -47,7 +47,9 @@ #export-dir = ../build-area/ # Special directory to look for pre-built orig source archives #tarball-dir = ../tarballs/ -# Build even if uncommited local changes are present +# Build despite of unclean repository, i.e. untracked files are present +#ignore-untracked = True +# Ignore all local changes (i.e. build despite of modified files) #ignore-new = True # Commit-ish to build #export = HEAD diff --git a/gbp/config.py b/gbp/config.py index 8a4fd009..0146f840 100644 --- a/gbp/config.py +++ b/gbp/config.py @@ -586,6 +586,7 @@ class GbpOptionParserRpm(GbpOptionParser): 'pq-branch' : 'development/%(branch)s', 'spec-file' : 'auto', 'export-dir' : '../rpmbuild', + 'ignore-untracked' : 'False', 'rpmbuild-builddir' : 'BUILD', 'rpmbuild-rpmdir' : 'RPMS', 'rpmbuild-sourcedir' : 'SOURCES', @@ -608,6 +609,8 @@ class GbpOptionParserRpm(GbpOptionParser): "format string for the patch-queue branch name, default is '%(pq-branch)s'", 'spec-file': "Spec file to use, 'auto' makes gbp to guess, other values make the packaging-dir option to be ignored, default is '%(spec-file)s'", + 'ignore-untracked': + "build with untracked files in the source tree, default is '%(ignore-untracked)s'", 'patch-export': "Create patches between upstream and export-treeish, default is '%(patch-export)s'", 'pristine-tarball-name': diff --git a/gbp/scripts/buildpackage_rpm.py b/gbp/scripts/buildpackage_rpm.py index 786228f7..724922cf 100755 --- a/gbp/scripts/buildpackage_rpm.py +++ b/gbp/scripts/buildpackage_rpm.py @@ -245,6 +245,7 @@ def parse_args(argv, prefix): parser.add_option_group(cmd_group) parser.add_option_group(export_group) + parser.add_boolean_config_file_option(option_name = "ignore-untracked", dest="ignore_untracked") parser.add_boolean_config_file_option(option_name = "ignore-new", dest="ignore_new") parser.add_option("--git-verbose", action="store_true", dest="verbose", default=False, help="verbose command execution") @@ -350,11 +351,11 @@ def main(argv): if not options.export_only: Command(options.cleaner, shell=True)() if not options.ignore_new: - (ret, out) = repo.is_clean() + (ret, out) = repo.is_clean(options.ignore_untracked) if not ret: gbp.log.err("You have uncommitted changes in your source tree:") gbp.log.err(out) - raise GbpError, "Use --git-ignore-new to ignore." + raise GbpError, "Use --git-ignore-new or --git-ignore-untracked to ignore." if not options.ignore_new and not options.ignore_branch: if branch != options.packaging_branch: -- cgit v1.2.3 From fa18be06e5bc6c40f6d5d29c3f7a4be8bb9ad77c Mon Sep 17 00:00:00 2001 From: Markus Lehtonen Date: Mon, 23 Apr 2012 12:51:08 +0300 Subject: rpm: add version parsing functions to pkg policy Adds functions for version string generation and parsing. These are intended for parsing version strings taken e.g. from rpm filename or changelogs. Also, take these new version parsing functions into use in the rpm gbp scripts. Signed-off-by: Markus Lehtonen Signed-off-by: Ed Bartosh --- gbp/rpm/git.py | 42 ++++++++++++++++--------- gbp/rpm/policy.py | 70 +++++++++++++++++++++++++++++++++++++++++ gbp/scripts/buildpackage_rpm.py | 7 +++-- gbp/scripts/import_orig_rpm.py | 2 +- gbp/scripts/import_srpm.py | 21 +++++++------ gbp/scripts/pq_rpm.py | 6 ++-- 6 files changed, 117 insertions(+), 31 deletions(-) diff --git a/gbp/rpm/git.py b/gbp/rpm/git.py index dac555cf..55a412b3 100644 --- a/gbp/rpm/git.py +++ b/gbp/rpm/git.py @@ -19,6 +19,7 @@ import re from gbp.git import GitRepository, GitRepositoryError from gbp.pkg.pristinetar import PristineTar +from gbp.rpm.policy import RpmPkgPolicy class RpmGitRepository(GitRepository): """A git repository that holds the source of an RPM package""" @@ -35,8 +36,10 @@ class RpmGitRepository(GitRepository): @param format: tag pattern @type format: C{str} - @param version: rpm version number - @type version: C{str} + @param version: rpm version components ('epoch', 'upstreamversion', 'release',...) + @type version: C{dict} of C{str} + @param vendor: distribution vendor + @type vendor: C{str} @return: sha1 of the commit the tag references to """ tag = self.version_to_tag(format, version, vendor) @@ -47,30 +50,41 @@ class RpmGitRepository(GitRepository): @staticmethod def version_to_tag(format, version, vendor="vendor"): - """Generate a tag from a given format and a version + """ + Generate a tag from a given format and a version + + @param format: tag pattern + @type format: C{str} + @param version: rpm version components ('epoch', 'upstreamversion', 'release',...) + @type version: C{dict} of C{str} + @param vendor: distribution vendor + @type vendor: C{str} + @return: version tag - >>> RpmGitRepository.version_to_tag("packaging/%(version)s", "0:0~0") + >>> RpmGitRepository.version_to_tag("packaging/%(version)s", dict(epoch='0', upstreamversion='0~0')) 'packaging/0%0_0' - >>> RpmGitRepository.version_to_tag("%(vendor)s/v%(version)s", "1.0", "myvendor") - 'myvendor/v1.0' + >>> RpmGitRepository.version_to_tag("%(vendor)s/v%(version)s", dict(upstreamversion='1.0', release='2'), "myvendor") + 'myvendor/v1.0-2' """ - return format % dict(version=RpmGitRepository._sanitize_version(version), - vendor=vendor) + version_tag = format % dict(version, + version=RpmPkgPolicy.compose_full_version(version), + vendor=vendor) + return RpmGitRepository._sanitize_tag(version_tag) @staticmethod - def _sanitize_version(version): + def _sanitize_tag(tag): """sanitize a version so git accepts it as a tag - >>> RpmGitRepository._sanitize_version("0.0.0") + >>> RpmGitRepository._sanitize_tag("0.0.0") '0.0.0' - >>> RpmGitRepository._sanitize_version("0.0~0") + >>> RpmGitRepository._sanitize_tag("0.0~0") '0.0_0' - >>> RpmGitRepository._sanitize_version("0:0.0") + >>> RpmGitRepository._sanitize_tag("0:0.0") '0%0.0' - >>> RpmGitRepository._sanitize_version("0%0~0") + >>> RpmGitRepository._sanitize_tag("0%0~0") '0%0_0' """ - return version.replace('~', '_').replace(':', '%') + return tag.replace('~', '_').replace(':', '%') @property def pristine_tar_branch(self): diff --git a/gbp/rpm/policy.py b/gbp/rpm/policy.py index e61a4972..9fbf5632 100644 --- a/gbp/rpm/policy.py +++ b/gbp/rpm/policy.py @@ -67,3 +67,73 @@ class RpmPkgPolicy(PkgPolicy): return True return False + @classmethod + def split_full_version(cls, version): + """ + Parse full version string and split it into individual "version + components", i.e. upstreamversion, epoch and release + + @param version: full version of a package + @type version: C{str} + @return: individual version components + @rtype: C{dict} + + >>> RpmPkgPolicy.split_full_version("1") + {'release': None, 'epoch': None, 'upstreamversion': '1'} + >>> RpmPkgPolicy.split_full_version("1.2.3-5.3") + {'release': '5.3', 'epoch': None, 'upstreamversion': '1.2.3'} + >>> RpmPkgPolicy.split_full_version("3:1.2.3") + {'release': None, 'epoch': '3', 'upstreamversion': '1.2.3'} + >>> RpmPkgPolicy.split_full_version("3:1-0") + {'release': '0', 'epoch': '3', 'upstreamversion': '1'} + """ + epoch = None + upstreamversion = None + release = None + + e_vr = version.split(":", 1) + if len(e_vr) == 1: + v_r = e_vr[0].split("-", 1) + else: + epoch = e_vr[0] + v_r = e_vr[1].split("-", 1) + upstreamversion = v_r[0] + if len(v_r) > 1: + release = v_r[1] + + return {'epoch': epoch, + 'upstreamversion': upstreamversion, + 'release': release} + + @classmethod + def compose_full_version(cls, evr): + """ + Compose a full version string from individual "version components", + i.e. epoch, version and release + + @param evr: dict of version components + @type evr: C{dict} of C{str} + @return: full version + @rtype: C{str} + + >>> RpmPkgPolicy.compose_full_version({'epoch': '', 'upstreamversion': '1.0'}) + '1.0' + >>> RpmPkgPolicy.compose_full_version({'epoch': '2', 'upstreamversion': '1.0', 'release': None}) + '2:1.0' + >>> RpmPkgPolicy.compose_full_version({'epoch': None, 'upstreamversion': '1', 'release': '0'}) + '1-0' + >>> RpmPkgPolicy.compose_full_version({'epoch': '2', 'upstreamversion': '1.0', 'release': '2.3'}) + '2:1.0-2.3' + >>> RpmPkgPolicy.compose_full_version({'epoch': '2', 'upstreamversion': '', 'release': '2.3'}) + """ + if 'upstreamversion' in evr and evr['upstreamversion']: + version = "" + if 'epoch' in evr and evr['epoch']: + version += "%s:" % evr['epoch'] + version += evr['upstreamversion'] + if 'release' in evr and evr['release']: + version += "-%s" % evr['release'] + if version: + return version + return None + diff --git a/gbp/scripts/buildpackage_rpm.py b/gbp/scripts/buildpackage_rpm.py index 724922cf..028f6127 100755 --- a/gbp/scripts/buildpackage_rpm.py +++ b/gbp/scripts/buildpackage_rpm.py @@ -147,7 +147,7 @@ def pristine_tar_build_orig(repo, orig_file, output_dir, options): def get_upstream_tree(repo, spec, options): """Determine the upstream tree from the given options""" if options.upstream_tree.upper() == 'TAG': - upstream_tree = repo.version_to_tag(options.upstream_tag, spec.version, vendor="Upstream") + upstream_tree = repo.version_to_tag(options.upstream_tag, dict(upstreamversion=spec.version), "Upstream") elif options.upstream_tree.upper() == 'BRANCH': if not repo.has_branch(options.upstream_branch): raise GbpError("%s is not a valid branch" % options.upstream_branch) @@ -470,7 +470,7 @@ def main(argv): # Tag (note: tags the exported version) if options.tag or options.tag_only: gbp.log.info("Tagging %s" % spec.version) - tag = repo.version_to_tag(options.packaging_tag, spec.version, vendor=options.vendor) + tag = repo.version_to_tag(options.packaging_tag, dict(upstreamversion=spec.version), options.vendor) if options.retag and repo.has_tag(tag): repo.delete_tag(tag) repo.create_tag(name=tag, msg="%s release %s" % (options.vendor, spec.version), @@ -503,8 +503,9 @@ def main(argv): if not options.tag_only: if spec and options.notify: summary = "Gbp-rpm %s" % ["failed", "successful"][not retval] + pkg_evr = {'upstreamversion': spec.version} message = ("Build of %s %s %s" % (spec.name, - spec.version, + RpmPkgPolicy.compose_full_version(pkg_evr), ["failed", "succeeded"][not retval])) if not gbp.notifications.notify(summary, message, options.notify): gbp.log.err("Failed to send notification") diff --git a/gbp/scripts/import_orig_rpm.py b/gbp/scripts/import_orig_rpm.py index 3978eff2..e6306fdf 100755 --- a/gbp/scripts/import_orig_rpm.py +++ b/gbp/scripts/import_orig_rpm.py @@ -266,7 +266,7 @@ def main(argv): gbp.log.info("Pristine-tar: commiting %s" % pristine_orig) repo.pristine_tar.commit(pristine_orig, options.upstream_branch) - tag = repo.version_to_tag(options.upstream_tag, version, vendor="Upstream") + tag = repo.version_to_tag(options.upstream_tag, dict(upstreamversion=version), "Upstream") repo.create_tag(name=tag, msg="Upstream version %s" % version, commit=commit, diff --git a/gbp/scripts/import_srpm.py b/gbp/scripts/import_srpm.py index 9519df57..b1f4d727 100755 --- a/gbp/scripts/import_srpm.py +++ b/gbp/scripts/import_srpm.py @@ -32,6 +32,7 @@ import urllib2 import gbp.command_wrappers as gbpc from gbp.rpm import (parse_srpm, SrcRpmFile, SpecFile, guess_spec, NoSpecError, parse_spec, RpmUpstreamSource) +from gbp.rpm.policy import RpmPkgPolicy from gbp.rpm.git import (RpmGitRepository, GitRepositoryError) from gbp.git.modifier import GitModifier from gbp.config import GbpOptionParserRpm, GbpOptionGroup, no_upstream_branch_msg @@ -93,8 +94,8 @@ def committer_from_author(author, options): def move_tag_stamp(repo, format, version, vendor): "Move tag out of the way appending the current timestamp" old = repo.version_to_tag(format, version, vendor) - timestamped = "%s~%s" % (version, int(time.time())) - new = repo.version_to_tag(format, timestamped, vendor) + new = repo.version_to_tag('%s~%d' % (format, int(time.time())), + version, vendor) repo.move_tag(old, new) @@ -199,7 +200,7 @@ def main(argv): spec = parse_spec(pkg) pkgname = spec.name - pkgver = "%s-%s" % (spec.version, spec.release) + pkgver = dict(upstreamversion=spec.version, release=spec.release) upstream_version = spec.version packager = spec.packager unpacked = True @@ -208,7 +209,7 @@ def main(argv): dirs['src'] = os.path.abspath(os.path.dirname(pkg)) src = parse_srpm(srpm) pkgname = src.name - pkgver = src.version + pkgver = dict(upstreamversion=src.version) upstream_version = src.upstream_version packager = src.packager unpacked = False @@ -274,12 +275,12 @@ def main(argv): upstream = None format = [(options.upstream_tag, "Upstream"), (options.packaging_tag, options.vendor)][options.native] - tag = repo.version_to_tag(format[0], upstream_version, options.vendor) + tag = repo.version_to_tag(format[0], dict(upstreamversion=upstream_version), options.vendor) if repo.find_version(options.packaging_tag, pkgver, options.vendor): - gbp.log.warn("Version %s already imported." % pkgver) + gbp.log.warn("Version %s already imported." % RpmPkgPolicy.compose_full_version(pkgver)) if options.allow_same_version: - gbp.log.info("Moving tag of version '%s' since import forced" % pkgver) + gbp.log.info("Moving tag of version '%s' since import forced" % RpmPkgPolicy.compose_full_version(pkgver)) move_tag_stamp(repo, options.packaging_tag, pkgver, options.vendor) else: raise SkipImport @@ -301,7 +302,7 @@ def main(argv): # Import upstream sources if upstream: - upstream_commit = repo.find_version(format[0], upstream_version, options.vendor) + upstream_commit = repo.find_version(format[0], dict(upstreamversion=upstream_version), options.vendor) if not upstream_commit: gbp.log.info("Tag %s not found, importing %s tarball" % (tag, format[1])) @@ -348,7 +349,7 @@ def main(argv): raise GbpError tag = repo.version_to_tag(options.packaging_tag, pkgver, options.vendor) - msg = "%s release %s" % (options.vendor, pkgver) + msg = "%s release %s" % (options.vendor, RpmPkgPolicy.compose_full_version(pkgver)) if options.orphan_packaging or not upstream: parents = [] @@ -417,7 +418,7 @@ def main(argv): gbpc.RemoveTree(dirs[d])() if not ret and not skipped: - gbp.log.info("Version '%s' imported under '%s'" % (pkgver, pkgname)) + gbp.log.info("Version '%s' imported under '%s'" % (RpmPkgPolicy.compose_full_version(pkgver), pkgname)) return ret if __name__ == '__main__': diff --git a/gbp/scripts/pq_rpm.py b/gbp/scripts/pq_rpm.py index b1a10ca1..0e5ac6da 100755 --- a/gbp/scripts/pq_rpm.py +++ b/gbp/scripts/pq_rpm.py @@ -143,7 +143,7 @@ def export_patches(repo, branch, options): raise GbpError, "Can't parse spec" # Find upstream version - upstream_commit = repo.find_version(options.upstream_tag, spec.version, vendor="Upstream") + upstream_commit = repo.find_version(options.upstream_tag, dict(upstreamversion=spec.version), "Upstream") if not upstream_commit: raise GbpError, ("Couldn't find upstream version %s. Don't know on what base to import." % spec.version) @@ -234,7 +234,7 @@ def import_spec_patches(repo, branch, options): raise GbpError, "Can't parse spec" # Find upstream version - commit = repo.find_version(options.upstream_tag, spec.version, vendor="Upstream") + commit = repo.find_version(options.upstream_tag, dict(upstreamversion=spec.version), "Upstream") if commit: commits=[commit] else: @@ -296,7 +296,7 @@ def rebase_pq(repo, branch, options): raise GbpError, "Can't parse spec" # Find upstream version - upstream_commit = repo.find_version(options.upstream_tag, spec.version, vendor="Upstream") + upstream_commit = repo.find_version(options.upstream_tag, dict(upstreamversion=spec.version), "Upstream") if not upstream_commit: raise GbpError, ("Couldn't find upstream version %s. Don't know on what base to import." % spec.version) -- cgit v1.2.3 From b4b62db9f4379693d483ca2c2db1ddf6c08e3581 Mon Sep 17 00:00:00 2001 From: Markus Lehtonen Date: Wed, 30 May 2012 20:02:39 +0300 Subject: rpm helpers: make SpecFile and SrcRpmFile give (full) version as dict. The Dictionary contains different "version components", such as upstreamversion, release and epoch. Makes e.g. tag creation consistent, now. Signed-off-by: Markus Lehtonen --- gbp/config.py | 1 + gbp/rpm/__init__.py | 20 +++++++++++++++----- gbp/scripts/buildpackage_rpm.py | 12 ++++++------ gbp/scripts/import_srpm.py | 8 ++++---- gbp/scripts/pq_rpm.py | 12 ++++++------ 5 files changed, 32 insertions(+), 21 deletions(-) diff --git a/gbp/config.py b/gbp/config.py index 0146f840..dc73b840 100644 --- a/gbp/config.py +++ b/gbp/config.py @@ -583,6 +583,7 @@ class GbpOptionParserRpm(GbpOptionParser): 'merge' : 'False', 'packaging-dir' : '', 'packaging-tag' : '%(vendor)s/%(version)s', + 'upstream-tag' : 'upstream/%(upstreamversion)s', 'pq-branch' : 'development/%(branch)s', 'spec-file' : 'auto', 'export-dir' : '../rpmbuild', diff --git a/gbp/rpm/__init__.py b/gbp/rpm/__init__.py index 00582d72..6875221a 100644 --- a/gbp/rpm/__init__.py +++ b/gbp/rpm/__init__.py @@ -71,10 +71,11 @@ class SrcRpmFile(object): """ Get the (downstream) version of the RPM """ - version = self.rpmhdr[rpm.RPMTAG_EPOCH] + ":" if self.rpmhdr[rpm.RPMTAG_EPOCH] else "" - version += self.rpmhdr[rpm.RPMTAG_VERSION]+"-"+self.rpmhdr[rpm.RPMTAG_RELEASE] + version = dict(upstreamversion = self.rpmhdr[rpm.RPMTAG_VERSION], + release = self.rpmhdr[rpm.RPMTAG_RELEASE]) + if self.rpmhdr[rpm.RPMTAG_EPOCH] is not None: + version['epoch'] = str(self.rpmhdr[rpm.RPMTAG_EPOCH]) return version - version = property(_get_version) def _get_name(self): @@ -89,7 +90,7 @@ class SrcRpmFile(object): Get the upstream version of the package """ return self.rpmhdr[rpm.RPMTAG_VERSION] - upstream_version = property(_get_upstream_version) + upstreamversion = property(_get_upstream_version) def _get_packager(self): """ @@ -169,7 +170,7 @@ class SpecFile(object): source_header = self.specinfo.packages[0].header self.name = source_header[rpm.RPMTAG_NAME] - self.version = source_header[rpm.RPMTAG_VERSION] + self.upstreamversion = source_header[rpm.RPMTAG_VERSION] self.release = source_header[rpm.RPMTAG_RELEASE] # rpm-python returns epoch as 'long', convert that to string self.epoch = str(source_header[rpm.RPMTAG_EPOCH]) \ @@ -205,6 +206,15 @@ class SpecFile(object): (self.orig_file, self.orig_base, self.orig_archive_fmt, self.orig_comp) = self.guess_orig_file() + @property + def version(self): + """Get the (downstream) version""" + version = dict(upstreamversion = self.upstreamversion, + release = self.release) + if self.epoch != None: + version['epoch'] = self.epoch + return version + @property def specpath(self): """Get the dir/filename""" diff --git a/gbp/scripts/buildpackage_rpm.py b/gbp/scripts/buildpackage_rpm.py index 028f6127..8cfe1e18 100755 --- a/gbp/scripts/buildpackage_rpm.py +++ b/gbp/scripts/buildpackage_rpm.py @@ -147,7 +147,7 @@ def pristine_tar_build_orig(repo, orig_file, output_dir, options): def get_upstream_tree(repo, spec, options): """Determine the upstream tree from the given options""" if options.upstream_tree.upper() == 'TAG': - upstream_tree = repo.version_to_tag(options.upstream_tag, dict(upstreamversion=spec.version), "Upstream") + upstream_tree = repo.version_to_tag(options.upstream_tag, dict(upstreamversion=spec.upstreamversion), "Upstream") elif options.upstream_tree.upper() == 'BRANCH': if not repo.has_branch(options.upstream_branch): raise GbpError("%s is not a valid branch" % options.upstream_branch) @@ -469,11 +469,12 @@ def main(argv): # Tag (note: tags the exported version) if options.tag or options.tag_only: - gbp.log.info("Tagging %s" % spec.version) - tag = repo.version_to_tag(options.packaging_tag, dict(upstreamversion=spec.version), options.vendor) + gbp.log.info("Tagging %s" % rpm.RpmPkgPolicy.compose_full_version(spec.version)) + tag = repo.version_to_tag(options.packaging_tag, spec.version, options.vendor) if options.retag and repo.has_tag(tag): repo.delete_tag(tag) - repo.create_tag(name=tag, msg="%s release %s" % (options.vendor, spec.version), + repo.create_tag(name=tag, msg="%s release %s" % (options.vendor, + rpm.RpmPkgPolicy.compose_full_version(spec.version)), sign=options.sign_tags, keyid=options.keyid, commit=tree) if options.posttag: sha = repo.rev_parse("%s^{}" % tag) @@ -503,9 +504,8 @@ def main(argv): if not options.tag_only: if spec and options.notify: summary = "Gbp-rpm %s" % ["failed", "successful"][not retval] - pkg_evr = {'upstreamversion': spec.version} message = ("Build of %s %s %s" % (spec.name, - RpmPkgPolicy.compose_full_version(pkg_evr), + RpmPkgPolicy.compose_full_version(spec.version), ["failed", "succeeded"][not retval])) if not gbp.notifications.notify(summary, message, options.notify): gbp.log.err("Failed to send notification") diff --git a/gbp/scripts/import_srpm.py b/gbp/scripts/import_srpm.py index b1f4d727..b8cf5ecd 100755 --- a/gbp/scripts/import_srpm.py +++ b/gbp/scripts/import_srpm.py @@ -200,8 +200,8 @@ def main(argv): spec = parse_spec(pkg) pkgname = spec.name - pkgver = dict(upstreamversion=spec.version, release=spec.release) - upstream_version = spec.version + pkgver = spec.version + upstream_version = spec.upstreamversion packager = spec.packager unpacked = True else: @@ -209,8 +209,8 @@ def main(argv): dirs['src'] = os.path.abspath(os.path.dirname(pkg)) src = parse_srpm(srpm) pkgname = src.name - pkgver = dict(upstreamversion=src.version) - upstream_version = src.upstream_version + pkgver = src.version + upstream_version = src.upstreamversion packager = src.packager unpacked = False diff --git a/gbp/scripts/pq_rpm.py b/gbp/scripts/pq_rpm.py index 0e5ac6da..e09eb629 100755 --- a/gbp/scripts/pq_rpm.py +++ b/gbp/scripts/pq_rpm.py @@ -143,9 +143,9 @@ def export_patches(repo, branch, options): raise GbpError, "Can't parse spec" # Find upstream version - upstream_commit = repo.find_version(options.upstream_tag, dict(upstreamversion=spec.version), "Upstream") + upstream_commit = repo.find_version(options.upstream_tag, dict(upstreamversion=spec.upstreamversion), "Upstream") if not upstream_commit: - raise GbpError, ("Couldn't find upstream version %s. Don't know on what base to import." % spec.version) + raise GbpError, ("Couldn't find upstream version %s. Don't know on what base to import." % spec.upstreamversion) export_treeish = options.export_rev if options.export_rev else pq_branch if not repo.has_treeish(export_treeish): @@ -234,11 +234,11 @@ def import_spec_patches(repo, branch, options): raise GbpError, "Can't parse spec" # Find upstream version - commit = repo.find_version(options.upstream_tag, dict(upstreamversion=spec.version), "Upstream") + commit = repo.find_version(options.upstream_tag, dict(upstreamversion=spec.upstreamversion), "Upstream") if commit: commits=[commit] else: - raise GbpError, ("Couldn't find upstream version %s. Don't know on what base to import." % spec.version) + raise GbpError, ("Couldn't find upstream version %s. Don't know on what base to import." % spec.upstreamversion) queue = spec.patchseries() packager = get_packager(spec) @@ -296,9 +296,9 @@ def rebase_pq(repo, branch, options): raise GbpError, "Can't parse spec" # Find upstream version - upstream_commit = repo.find_version(options.upstream_tag, dict(upstreamversion=spec.version), "Upstream") + upstream_commit = repo.find_version(options.upstream_tag, dict(upstreamversion=spec.upstreamversion), "Upstream") if not upstream_commit: - raise GbpError, ("Couldn't find upstream version %s. Don't know on what base to import." % spec.version) + raise GbpError, ("Couldn't find upstream version %s. Don't know on what base to import." % spec.upstreamversion) switch_to_pq_branch(repo, branch, options) GitCommand("rebase")([upstream_commit]) -- cgit v1.2.3 From 386608bb879ae9a272e2a75f9c9319ecf3bcacce Mon Sep 17 00:00:00 2001 From: Markus Lehtonen Date: Thu, 31 May 2012 09:48:50 +0300 Subject: RpmGitRepository: make version-tag methods more flexible Simplifies version_to_tag() and find_version() so that all string fields (for the format string) are given in one dict. Now it's easier to add support for new string fields (e.g. commitdate etc). Signed-off-by: Markus Lehtonen Signed-off-by: Ed Bartosh --- gbp/rpm/git.py | 28 +++++++++++++--------------- gbp/scripts/buildpackage_rpm.py | 6 ++++-- gbp/scripts/import_orig_rpm.py | 3 ++- gbp/scripts/import_srpm.py | 18 ++++++++++-------- gbp/scripts/pq_rpm.py | 9 ++++++--- 5 files changed, 35 insertions(+), 29 deletions(-) diff --git a/gbp/rpm/git.py b/gbp/rpm/git.py index 55a412b3..92f8b2e0 100644 --- a/gbp/rpm/git.py +++ b/gbp/rpm/git.py @@ -28,7 +28,7 @@ class RpmGitRepository(GitRepository): super(RpmGitRepository, self).__init__(path) self.pristine_tar = PristineTar(self) - def find_version(self, format, version, vendor="vendor"): + def find_version(self, format, str_fields): """ Check if a certain version is stored in this repo and return the SHA1 of the related commit. That is, an annotated tag is dereferenced to the @@ -36,39 +36,37 @@ class RpmGitRepository(GitRepository): @param format: tag pattern @type format: C{str} - @param version: rpm version components ('epoch', 'upstreamversion', 'release',...) - @type version: C{dict} of C{str} - @param vendor: distribution vendor - @type vendor: C{str} + @param str_fields: arguments for format string ('upstreamversion', 'release', 'vendor'...) + @type str_fields: C{dict} of C{str} @return: sha1 of the commit the tag references to """ - tag = self.version_to_tag(format, version, vendor) + try: + tag = self.version_to_tag(format, str_fields) + except KeyError: + return None if self.has_tag(tag): # new tags are injective # dereference to a commit object return self.rev_parse("%s^0" % tag) return None @staticmethod - def version_to_tag(format, version, vendor="vendor"): + def version_to_tag(format, str_fields): """ Generate a tag from a given format and a version @param format: tag pattern @type format: C{str} - @param version: rpm version components ('epoch', 'upstreamversion', 'release',...) - @type version: C{dict} of C{str} - @param vendor: distribution vendor - @type vendor: C{str} + @param str_fields: arguments for format string ('upstreamversion', 'release', 'vendor'...) + @type str_fields: C{dict} of C{str} @return: version tag >>> RpmGitRepository.version_to_tag("packaging/%(version)s", dict(epoch='0', upstreamversion='0~0')) 'packaging/0%0_0' - >>> RpmGitRepository.version_to_tag("%(vendor)s/v%(version)s", dict(upstreamversion='1.0', release='2'), "myvendor") + >>> RpmGitRepository.version_to_tag("%(vendor)s/v%(version)s", dict(upstreamversion='1.0', release='2', vendor="myvendor")) 'myvendor/v1.0-2' """ - version_tag = format % dict(version, - version=RpmPkgPolicy.compose_full_version(version), - vendor=vendor) + version_tag = format % dict(str_fields, + version=RpmPkgPolicy.compose_full_version(str_fields)) return RpmGitRepository._sanitize_tag(version_tag) @staticmethod diff --git a/gbp/scripts/buildpackage_rpm.py b/gbp/scripts/buildpackage_rpm.py index 8cfe1e18..562e135c 100755 --- a/gbp/scripts/buildpackage_rpm.py +++ b/gbp/scripts/buildpackage_rpm.py @@ -147,7 +147,8 @@ def pristine_tar_build_orig(repo, orig_file, output_dir, options): def get_upstream_tree(repo, spec, options): """Determine the upstream tree from the given options""" if options.upstream_tree.upper() == 'TAG': - upstream_tree = repo.version_to_tag(options.upstream_tag, dict(upstreamversion=spec.upstreamversion), "Upstream") + tag_str_fields = dict(upstreamversion=spec.upstreamversion, vendor="Upstream") + upstream_tree = repo.version_to_tag(options.upstream_tag, tag_str_fields) elif options.upstream_tree.upper() == 'BRANCH': if not repo.has_branch(options.upstream_branch): raise GbpError("%s is not a valid branch" % options.upstream_branch) @@ -470,7 +471,8 @@ def main(argv): # Tag (note: tags the exported version) if options.tag or options.tag_only: gbp.log.info("Tagging %s" % rpm.RpmPkgPolicy.compose_full_version(spec.version)) - tag = repo.version_to_tag(options.packaging_tag, spec.version, options.vendor) + tag_str_fields = dict(spec.version, vendor=options.vendor) + tag = repo.version_to_tag(options.packaging_tag, tag_str_fields) if options.retag and repo.has_tag(tag): repo.delete_tag(tag) repo.create_tag(name=tag, msg="%s release %s" % (options.vendor, diff --git a/gbp/scripts/import_orig_rpm.py b/gbp/scripts/import_orig_rpm.py index e6306fdf..3d204b2c 100755 --- a/gbp/scripts/import_orig_rpm.py +++ b/gbp/scripts/import_orig_rpm.py @@ -266,7 +266,8 @@ def main(argv): gbp.log.info("Pristine-tar: commiting %s" % pristine_orig) repo.pristine_tar.commit(pristine_orig, options.upstream_branch) - tag = repo.version_to_tag(options.upstream_tag, dict(upstreamversion=version), "Upstream") + tag_str_fields = dict(upstreamversion=version, vendor="Upstream") + tag = repo.version_to_tag(options.upstream_tag, tag_str_fields) repo.create_tag(name=tag, msg="Upstream version %s" % version, commit=commit, diff --git a/gbp/scripts/import_srpm.py b/gbp/scripts/import_srpm.py index b8cf5ecd..e58d3fd9 100755 --- a/gbp/scripts/import_srpm.py +++ b/gbp/scripts/import_srpm.py @@ -91,11 +91,11 @@ def committer_from_author(author, options): return committer -def move_tag_stamp(repo, format, version, vendor): +def move_tag_stamp(repo, format, tag_str_fields): "Move tag out of the way appending the current timestamp" - old = repo.version_to_tag(format, version, vendor) + old = repo.version_to_tag(format, tag_str_fields) new = repo.version_to_tag('%s~%d' % (format, int(time.time())), - version, vendor) + tag_str_fields) repo.move_tag(old, new) @@ -275,13 +275,14 @@ def main(argv): upstream = None format = [(options.upstream_tag, "Upstream"), (options.packaging_tag, options.vendor)][options.native] - tag = repo.version_to_tag(format[0], dict(upstreamversion=upstream_version), options.vendor) + tag_str_fields = dict(pkgver, vendor=options.vendor) + tag = repo.version_to_tag(format[0], tag_str_fields) - if repo.find_version(options.packaging_tag, pkgver, options.vendor): + if repo.find_version(options.packaging_tag, tag_str_fields): gbp.log.warn("Version %s already imported." % RpmPkgPolicy.compose_full_version(pkgver)) if options.allow_same_version: gbp.log.info("Moving tag of version '%s' since import forced" % RpmPkgPolicy.compose_full_version(pkgver)) - move_tag_stamp(repo, options.packaging_tag, pkgver, options.vendor) + move_tag_stamp(repo, options.packaging_tag, tag_str_fields) else: raise SkipImport @@ -302,7 +303,7 @@ def main(argv): # Import upstream sources if upstream: - upstream_commit = repo.find_version(format[0], dict(upstreamversion=upstream_version), options.vendor) + upstream_commit = repo.find_version(format[0], tag_str_fields) if not upstream_commit: gbp.log.info("Tag %s not found, importing %s tarball" % (tag, format[1])) @@ -348,7 +349,8 @@ def main(argv): "\nAlso check the --create-missing-branches option.") raise GbpError - tag = repo.version_to_tag(options.packaging_tag, pkgver, options.vendor) + tag_str_fields = dict(pkgver, vendor=options.vendor) + tag = repo.version_to_tag(options.packaging_tag, tag_str_fields) msg = "%s release %s" % (options.vendor, RpmPkgPolicy.compose_full_version(pkgver)) if options.orphan_packaging or not upstream: diff --git a/gbp/scripts/pq_rpm.py b/gbp/scripts/pq_rpm.py index e09eb629..b6ded2cc 100755 --- a/gbp/scripts/pq_rpm.py +++ b/gbp/scripts/pq_rpm.py @@ -143,7 +143,8 @@ def export_patches(repo, branch, options): raise GbpError, "Can't parse spec" # Find upstream version - upstream_commit = repo.find_version(options.upstream_tag, dict(upstreamversion=spec.upstreamversion), "Upstream") + tag_str_fields = dict(upstreamversion=spec.upstreamversion, vendor="Upstream") + upstream_commit = repo.find_version(options.upstream_tag, tag_str_fields) if not upstream_commit: raise GbpError, ("Couldn't find upstream version %s. Don't know on what base to import." % spec.upstreamversion) @@ -234,7 +235,8 @@ def import_spec_patches(repo, branch, options): raise GbpError, "Can't parse spec" # Find upstream version - commit = repo.find_version(options.upstream_tag, dict(upstreamversion=spec.upstreamversion), "Upstream") + tag_str_fields = dict(upstreamversion=spec.upstreamversion, vendor="Upstream") + commit = repo.find_version(options.upstream_tag, tag_str_fields) if commit: commits=[commit] else: @@ -296,7 +298,8 @@ def rebase_pq(repo, branch, options): raise GbpError, "Can't parse spec" # Find upstream version - upstream_commit = repo.find_version(options.upstream_tag, dict(upstreamversion=spec.upstreamversion), "Upstream") + tag_str_fields = dict(upstreamversion=spec.upstreamversion, vendor="Upstream") + upstream_commit = repo.find_version(options.upstream_tag, tag_str_fields) if not upstream_commit: raise GbpError, ("Couldn't find upstream version %s. Don't know on what base to import." % spec.upstreamversion) -- cgit v1.2.3 From c2249b1b28fda860c0ad8bd66bd4df012410b6a7 Mon Sep 17 00:00:00 2001 From: Markus Lehtonen Date: Wed, 4 Sep 2013 10:33:03 +0300 Subject: buildpackage-rpm: add more tagging options Add new possible keywords to be used in packaging-tag format string: 'nowtime', 'authortime', 'committime', 'nowtimenum', 'authortimenum' and 'committimenum'. The '*timenum' keyword denote the corresponding '*time' keyword appended with an additional incremental serial number. E.g. if 'nowtime' would produce '20120531', 'nowtimenum' would (the first time) produce '20120531.1'. What is completely missing is a way to support these new tag keywords in git-import-srpm tool. So, if you use these tags, git-import-srpm is not able to reproduce the tags, (and, it is not necessarily able to correctly tell if you've already imported a certain version of the package). Signed-off-by: Markus Lehtonen --- gbp/rpm/policy.py | 3 ++ gbp/scripts/buildpackage_rpm.py | 61 +++++++++++++++++++++++++++++++++++++---- 2 files changed, 58 insertions(+), 6 deletions(-) diff --git a/gbp/rpm/policy.py b/gbp/rpm/policy.py index 9fbf5632..231f7ead 100644 --- a/gbp/rpm/policy.py +++ b/gbp/rpm/policy.py @@ -43,6 +43,9 @@ class RpmPkgPolicy(PkgPolicy): "and can only containg alphanumerics or characters " "in %s" % list(version_whitelist_chars)) + # Time stamp format to be used in tagging + tag_timestamp_format = "%Y%m%d" + @classmethod def is_valid_orig_archive(cls, filename): """ diff --git a/gbp/scripts/buildpackage_rpm.py b/gbp/scripts/buildpackage_rpm.py index 562e135c..bef4623f 100755 --- a/gbp/scripts/buildpackage_rpm.py +++ b/gbp/scripts/buildpackage_rpm.py @@ -25,6 +25,7 @@ import sys import tempfile import shutil import re +from datetime import datetime import gbp.rpm as rpm from gbp.rpm.policy import RpmPkgPolicy @@ -220,6 +221,55 @@ def setup_builder(options, builder_args): options.spec_dir = '' +def update_tag_str_fields(fields, tag_format_str, repo, commit_info): + """Update string format fields for packaging tag""" + fields['nowtime'] = datetime.now().strftime(RpmPkgPolicy.tag_timestamp_format) + + fields['authortime'] = datetime.fromtimestamp(int(commit_info['author'].date.split()[0])).strftime(RpmPkgPolicy.tag_timestamp_format) + fields['committime'] = datetime.fromtimestamp(int(commit_info['committer'].date.split()[0])).strftime(RpmPkgPolicy.tag_timestamp_format) + fields['version'] = version=RpmPkgPolicy.compose_full_version(fields) + + # Parse tags with incremental numbering + re_fields = dict(fields, + nowtimenum=fields['nowtime'] + ".(?P[0-9]+)", + authortimenum=fields['authortime'] + ".(?P[0-9]+)", + committimenum=fields['committime'] + ".(?P[0-9]+)") + try: + tag_re = re.compile("^%s$" % (tag_format_str % re_fields)) + except KeyError, err: + raise GbpError, "Unknown field '%s' in packaging-tag format string" % err + + fields['nowtimenum'] = fields['nowtime'] + ".1" + fields['authortimenum'] = fields['authortime'] + ".1" + fields['committimenum'] = fields['committime'] + ".1" + for t in reversed(repo.get_tags()): + m = tag_re.match(t) + if m: + if 'nownum' in m.groupdict(): + fields['nowtimenum'] = "%s.%s" % (fields['nowtime'], int(m.group('nownum'))+1) + if 'authornum' in m.groupdict(): + fields['authortimenum'] = "%s.%s" % (fields['authortime'], int(m.group('authornum'))+1) + if 'commitnum' in m.groupdict(): + fields['committimenum'] = "%s.%s" % (fields['committime'], int(m.group('commitnum'))+1) + break + + +def packaging_tag_name(repo, spec, commit_info, options): + """Compose packaging tag as string""" + tag_str_fields = dict(spec.version, vendor=options.vendor) + update_tag_str_fields(tag_str_fields, options.packaging_tag, repo, + commit_info) + return repo.version_to_tag(options.packaging_tag, tag_str_fields) + + +def create_packaging_tag(repo, tag, commit, version, options): + """Create a packaging/release Git tag""" + msg = "%s release %s" % (options.vendor, + RpmPkgPolicy.compose_full_version(version)) + repo.create_tag(name=tag, msg=msg, sign=options.sign_tags, + keyid=options.keyid, commit=commit) + + def parse_args(argv, prefix): args = [ arg for arg in argv[1:] if arg.find('--%s' % prefix) == 0 ] builder_args = [ arg for arg in argv[1:] if arg.find('--%s' % prefix) == -1 ] @@ -470,14 +520,13 @@ def main(argv): # Tag (note: tags the exported version) if options.tag or options.tag_only: - gbp.log.info("Tagging %s" % rpm.RpmPkgPolicy.compose_full_version(spec.version)) - tag_str_fields = dict(spec.version, vendor=options.vendor) - tag = repo.version_to_tag(options.packaging_tag, tag_str_fields) + gbp.log.info("Tagging %s" % RpmPkgPolicy.compose_full_version(spec.version)) + commit_info = repo.get_commit_info(tree) + tag = packaging_tag_name(repo, spec, commit_info, options) if options.retag and repo.has_tag(tag): repo.delete_tag(tag) - repo.create_tag(name=tag, msg="%s release %s" % (options.vendor, - rpm.RpmPkgPolicy.compose_full_version(spec.version)), - sign=options.sign_tags, keyid=options.keyid, commit=tree) + create_packaging_tag(repo, tag, commit=tree, version=spec.version, + options=options) if options.posttag: sha = repo.rev_parse("%s^{}" % tag) Command(options.posttag, shell=True, -- cgit v1.2.3 From 01376e9e79b53d041b4b1afcd992500978cdb452 Mon Sep 17 00:00:00 2001 From: Markus Lehtonen Date: Fri, 1 Jun 2012 11:19:36 +0300 Subject: rpm helpers: add support for gbp-specific rpmlib Adds support to use a special rpmlib, defined by rpm packaging policy. This makes it possible to use the target distro's rpmlib. That is, parse spec files for target distros (and architectures) incompatible with your host system. With the default RpmPkgPolicy, GBP tries to import "rpmlibgbp". Signed-off-by: Markus Lehtonen --- gbp/rpm/__init__.py | 8 +++++++- gbp/rpm/policy.py | 3 +++ 2 files changed, 10 insertions(+), 1 deletion(-) diff --git a/gbp/rpm/__init__.py b/gbp/rpm/__init__.py index 6875221a..ca7eb38f 100644 --- a/gbp/rpm/__init__.py +++ b/gbp/rpm/__init__.py @@ -22,7 +22,6 @@ import sys import os import re import tempfile -import rpm import glob import shutil as shutil from optparse import OptionParser @@ -35,6 +34,13 @@ import gbp.log from gbp.pkg import (UpstreamSource, compressor_opts, parse_archive_filename) from gbp.rpm.policy import RpmPkgPolicy +try: + # Try to load special RPM lib to be used for GBP (only) + rpm = __import__(RpmPkgPolicy.python_rpmlib_module_name) +except ImportError: + gbp.log.debug("Failed to import '%s' as rpm python module, using host's default rpm library instead" % RpmPkgPolicy.python_rpmlib_module_name) + import rpm + # define a large number to check the valid id of source file MAX_SOURCE_NUMBER = 99999 diff --git a/gbp/rpm/policy.py b/gbp/rpm/policy.py index 231f7ead..f73f1d92 100644 --- a/gbp/rpm/policy.py +++ b/gbp/rpm/policy.py @@ -22,6 +22,9 @@ from gbp.pkg import PkgPolicy, parse_archive_filename class RpmPkgPolicy(PkgPolicy): """Packaging policy for RPM""" + # Special rpmlib python module for GBP (only) + python_rpmlib_module_name = "rpmlibgbp" + alnum = 'a-zA-Z0-9' # Valid characters for RPM pkg name name_whitelist_chars = '._+%{}\-' -- cgit v1.2.3 From 2947a7d97abb73f29c7f2e1fd90e5cea61827d3f Mon Sep 17 00:00:00 2001 From: Markus Lehtonen Date: Thu, 7 Jun 2012 19:13:43 +0300 Subject: pq-rpm: support importing compressed patches Adds support for importing compressed patches. NOTE: Only gzip is supported, for the time being, other compression methods shouldn't be to hard to add, if needed. Signed-off-by: Markus Lehtonen --- gbp/scripts/pq_rpm.py | 24 ++++++++++++++++++++---- 1 file changed, 20 insertions(+), 4 deletions(-) diff --git a/gbp/scripts/pq_rpm.py b/gbp/scripts/pq_rpm.py index b6ded2cc..480e382b 100755 --- a/gbp/scripts/pq_rpm.py +++ b/gbp/scripts/pq_rpm.py @@ -25,6 +25,7 @@ import shutil import sys import tempfile import re +import gzip from gbp.config import (GbpOptionParserRpm, GbpOptionGroup) from gbp.rpm.git import (GitRepositoryError, RpmGitRepository) from gbp.git import GitModifier @@ -33,6 +34,7 @@ from gbp.command_wrappers import (Command, GitCommand, RunAtCommand, from gbp.errors import GbpError import gbp.log from gbp.patch_series import (PatchSeries, Patch) +from gbp.pkg import parse_archive_filename from gbp.rpm import (SpecFile, guess_spec) from gbp.scripts.common.pq import (is_pq_branch, pq_branch_name, pq_branch_base, parse_gbp_commands, format_patch, @@ -160,7 +162,7 @@ def export_patches(repo, branch, options): def safe_patches(queue, tmpdir_base): """ Safe the current patches in a temporary directory - below 'tmpdir_base' + below 'tmpdir_base'. Also, uncompress compressed patches here. @param queue: an existing patch queue @param tmpdir_base: base under which to create tmpdir @@ -174,10 +176,24 @@ def safe_patches(queue, tmpdir_base): if len(queue) > 0: gbp.log.debug("Safeing patches '%s' in '%s'" % (os.path.dirname(queue[0].path), tmpdir)) for p in queue: - dst = os.path.join(tmpdir, os.path.basename(p.path)) - shutil.copy(p.path, dst) + (base, archive_fmt, comp) = parse_archive_filename(p.path) + if comp == 'gzip': + gbp.log.debug("Uncompressing '%s'" % os.path.basename(p.path)) + src = gzip.open(p.path, 'r') + dst_name = os.path.join(tmpdir, os.path.basename(base)) + elif comp: + raise GbpError, ("Unsupported compression of a patch, giving up") + else: + src = open(p.path, 'r') + dst_name = os.path.join(tmpdir, os.path.basename(p.path)) + + dst = open(dst_name, 'w') + dst.writelines(src) + src.close() + dst.close() + safequeue.append(p) - safequeue[-1].path = dst; + safequeue[-1].path = dst_name; return (tmpdir, safequeue) -- cgit v1.2.3 From ff39644538b0eeabecb3e0620c3acabfb9fa26c3 Mon Sep 17 00:00:00 2001 From: Markus Lehtonen Date: Thu, 7 Jun 2012 17:20:21 +0300 Subject: rpm: support generating compressed patches This patch adds the support to generate compressed patches. User can define the patch file size limit after which patches gzipped. Re-writes the write_patch() function(s) and now uses the same-and-only write_patch() for buildpackage-rpm and pq-rpm. Signed-off-by: Markus Lehtonen --- gbp-rpm.conf | 2 ++ gbp/config.py | 3 +++ gbp/rpm/__init__.py | 29 +++++++++++++++++++++++++++++ gbp/scripts/buildpackage_rpm.py | 4 ++++ gbp/scripts/pq_rpm.py | 26 +++++++++++++++++++++++++- 5 files changed, 63 insertions(+), 1 deletion(-) diff --git a/gbp-rpm.conf b/gbp-rpm.conf index 15529f14..2e31a685 100644 --- a/gbp-rpm.conf +++ b/gbp-rpm.conf @@ -24,6 +24,8 @@ #packaging-dir=rpm # Spec file to be used #spec-file = gbp.spec +# Compress auto-generated patches +#patch-export-compress=100k # Export patches with numbering in filenames #patch-numbers = False diff --git a/gbp/config.py b/gbp/config.py index dc73b840..a012335f 100644 --- a/gbp/config.py +++ b/gbp/config.py @@ -595,6 +595,7 @@ class GbpOptionParserRpm(GbpOptionParser): 'rpmbuild-srpmdir' : 'SRPMS', 'rpmbuild-buildrootdir' : 'BUILDROOT', 'patch-export' : 'False', + 'patch-export-compress' : '0', 'pristine-tarball-name' : 'auto', } ) @@ -614,6 +615,8 @@ class GbpOptionParserRpm(GbpOptionParser): "build with untracked files in the source tree, default is '%(ignore-untracked)s'", 'patch-export': "Create patches between upstream and export-treeish, default is '%(patch-export)s'", + 'patch-export-compress': + "Compress (auto-generated) patches larger than given number of bytes, 0 never compresses, default is '%(patch-export-compress)s'", 'pristine-tarball-name': "Filename to record to pristine-tar, set to 'auto' to not mangle the file name, default is '%(pristine-tarball-name)s'", } ) diff --git a/gbp/rpm/__init__.py b/gbp/rpm/__init__.py index ca7eb38f..dcc919c3 100644 --- a/gbp/rpm/__init__.py +++ b/gbp/rpm/__init__.py @@ -539,4 +539,33 @@ def guess_spec_repo(repo, branch, packaging_dir): raise NoSpecError, "Searching spec from other branch not implemented yet" +def string_to_int(val_str): + """ + Convert string of possible unit identifier to int. + + @param val_str: value to be converted + @type val_str: C{str} + @return: value as integer + @rtype: C{int} + + >>> string_to_int("1234") + 1234 + >>> string_to_int("123k") + 125952 + >>> string_to_int("1234K") + 1263616 + >>> string_to_int("1M") + 1048576 + """ + units = {'k': 1024, + 'm': 1024**2, + 'g': 1024**3, + 't': 1024**4} + + if val_str[-1].lower() in units: + return int(val_str[:-1]) * units[val_str[-1].lower()] + else: + return int(val_str) + + # vim:et:ts=4:sw=4:et:sts=4:ai:set list listchars=tab\:»·,trail\:·: diff --git a/gbp/scripts/buildpackage_rpm.py b/gbp/scripts/buildpackage_rpm.py index bef4623f..f6c72f20 100755 --- a/gbp/scripts/buildpackage_rpm.py +++ b/gbp/scripts/buildpackage_rpm.py @@ -26,6 +26,7 @@ import tempfile import shutil import re from datetime import datetime +import gzip import gbp.rpm as rpm from gbp.rpm.policy import RpmPkgPolicy @@ -363,9 +364,12 @@ def parse_args(argv, prefix): export_group.add_option("--git-export-only", action="store_true", dest="export_only", default=False, help="only export packaging files, don't build") export_group.add_boolean_config_file_option("patch-export", dest="patch_export") + export_group.add_config_file_option("patch-export-compress", dest="patch_export_compress") export_group.add_boolean_config_file_option(option_name="patch-numbers", dest="patch_numbers") options, args = parser.parse_args(args) + options.patch_export_compress = rpm.string_to_int(options.patch_export_compress) + gbp.log.setup(options.color, options.verbose) if options.retag: if not options.tag and not options.tag_only: diff --git a/gbp/scripts/pq_rpm.py b/gbp/scripts/pq_rpm.py index 480e382b..204091e8 100755 --- a/gbp/scripts/pq_rpm.py +++ b/gbp/scripts/pq_rpm.py @@ -26,6 +26,7 @@ import sys import tempfile import re import gzip +import subprocess from gbp.config import (GbpOptionParserRpm, GbpOptionGroup) from gbp.rpm.git import (GitRepositoryError, RpmGitRepository) from gbp.git import GitModifier @@ -35,7 +36,7 @@ from gbp.errors import GbpError import gbp.log from gbp.patch_series import (PatchSeries, Patch) from gbp.pkg import parse_archive_filename -from gbp.rpm import (SpecFile, guess_spec) +from gbp.rpm import (SpecFile, guess_spec, string_to_int) from gbp.scripts.common.pq import (is_pq_branch, pq_branch_name, pq_branch_base, parse_gbp_commands, format_patch, format_diff, @@ -43,6 +44,23 @@ from gbp.scripts.common.pq import (is_pq_branch, pq_branch_name, pq_branch_base, apply_and_commit_patch, drop_pq) +def compress_patches(patches, compress_size=0): + """ + Rename and/or compress patches + """ + ret_patches = [] + for patch in patches: + # Compress if patch file is larger than "threshold" value + suffix = '' + if compress_size and os.path.getsize(patch) > compress_size: + gbp.log.debug("Compressing %s" % os.path.basename(patch)) + subprocess.Popen(['gzip', '-n', patch]).communicate() + suffix = '.gz' + + ret_patches.append(os.path.basename(patch) + suffix) + return ret_patches + + def generate_patches(repo, start, end, outdir, options): """ Generate patch files from git @@ -86,6 +104,9 @@ def generate_patches(repo, start, end, outdir, options): if patch_fn: patches.append(patch_fn) + # Compress + patches = compress_patches(patches, options.patch_export_compress) + return patches, commands @@ -371,9 +392,12 @@ def main(argv): parser.add_option("--export-rev", action="store", dest="export_rev", default="", help="Export patches from treeish object TREEISH instead " "of head of patch-queue branch", metavar="TREEISH") + parser.add_config_file_option("patch-export-compress", + dest="patch_export_compress") (options, args) = parser.parse_args(argv) gbp.log.setup(options.color, options.verbose) + options.patch_export_compress = string_to_int(options.patch_export_compress) if len(args) < 2: gbp.log.err("No action given.") -- cgit v1.2.3 From 5383a19130a051fe22d3b1a68555282e20d61da3 Mon Sep 17 00:00:00 2001 From: Markus Lehtonen Date: Fri, 8 Jun 2012 10:20:12 +0300 Subject: rpm: enhance logic in guessing the prefix of source archives Now a prefix is guessed for all source archives (not for the one and only "orig archive"). By default it is '-/' if name and version can be determined from the filename. If not, the archive basename (i.e. filename less archive and compression extensions) is used. In addition, more logic is applied to the "orig archive": gbp examines the setup macro (if found) for the source and takes the prefix from there. If some macros (in the '-n' option of the setup macro) cannot be expanded archive basename us used as the prefix. Signed-off-by: Markus Lehtonen --- gbp/rpm/__init__.py | 130 +++++++++++++++++++++++++++++++++++----- gbp/scripts/buildpackage_rpm.py | 34 +++++------ gbp/scripts/import_srpm.py | 8 +-- 3 files changed, 135 insertions(+), 37 deletions(-) diff --git a/gbp/rpm/__init__.py b/gbp/rpm/__init__.py index dcc919c3..0164ad2f 100644 --- a/gbp/rpm/__init__.py +++ b/gbp/rpm/__init__.py @@ -49,6 +49,10 @@ class NoSpecError(Exception): """Spec file parsing error""" pass +class MacroExpandError(Exception): + """Macro expansion in spec file failed""" + pass + class RpmUpstreamSource(UpstreamSource): """Upstream source class for RPM packages""" @@ -154,6 +158,7 @@ class SpecFile(object): source_re = re.compile(r'^Source(?P[0-9]+)?\s*:\s*(?P[^\s].*[^\s])\s*$', flags=re.I) patchtag_re = re.compile(r'^Patch(?P[0-9]+)?\s*:\s*(?P\S.*)$', flags=re.I) patchmacro_re = re.compile(r'^%patch(?P[0-9]+)?(\s+(?P.*))?$') + setupmacro_re = re.compile(r'^%setup(\s+(?P.*))?$') marker_re = re.compile(r'^#\s+(?P>>|<<)\s+(?Pgbp-[^\s]+)\s*(?P.*)$') gbptag_re = re.compile(r'^\s*#\s*gbp(?P[a-z]+)\s*:\s*(?P\S.*)\s*$', flags=re.I) @@ -201,7 +206,18 @@ class SpecFile(object): num = 0 if typ == 1: if num in self.sources: - self.sources[num]['filename'] = name + self.sources[num]['full_path'] = name + self.sources[num]['filename'] = os.path.basename(name) + self.sources[num]['filename_base'],\ + self.sources[num]['archive_fmt'],\ + self.sources[num]['compression'] = parse_archive_filename(os.path.basename(name)) + # Make a guess about the prefix in the archive + if self.sources[num]['archive_fmt']: + _name, _version = RpmPkgPolicy.guess_upstream_src_version(name) + if _name and _version: + self.sources[num]['prefix'] = "%s-%s/" % (_name, _version) + else: + self.sources[num]['prefix'] = self.sources[num]['filename_base'] + "/" else: gbp.log.err("BUG: we didn't correctly parse all 'Source' tags!") if typ == 2: @@ -210,7 +226,7 @@ class SpecFile(object): else: gbp.log.err("BUG: we didn't correctly parse all 'Patch' tags!") - (self.orig_file, self.orig_base, self.orig_archive_fmt, self.orig_comp) = self.guess_orig_file() + self.orig_src_num = self.guess_orig_file() @property def version(self): @@ -226,6 +242,35 @@ class SpecFile(object): """Get the dir/filename""" return os.path.join(self.specdir, self.specfile) + @property + def orig_src(self): + """ Get the orig src""" + if self.orig_src_num != None: + return self.sources[self.orig_src_num] + return None + + def _macro_replace(self, matchobj): + macro_dict = {'name': self.name, + 'version': self.upstreamversion, + 'release': self.release} + + if matchobj.group(2) in macro_dict: + return macro_dict[matchobj.group(2)] + raise MacroExpandError("Unknown macro '%s'" % matchobj.group(0)) + + def macro_expand(self, text): + """ + Expand the rpm macros (that gbp knows of) in the given text. + + @param text: text to check for macros + @type text: C{str} + @return: text with macros expanded + @rtype: C{str} + """ + # regexp to match '%{macro}' and '%macro' + macro_re = re.compile(r'%({)?(?P[a-z_][a-z0-9_]*)(?(1)})', flags=re.I) + return macro_re.sub(self._macro_replace, text) + def write_spec_file(self): """ Write, possibly updated, spec to disk @@ -271,6 +316,16 @@ class SpecFile(object): patchparser.add_option("-b", dest="backup") patchparser.add_option("-E", dest="removeempty") + # Parser for patch macros + setupparser = OptionParser() + setupparser.add_option("-n", dest="name") + setupparser.add_option("-c", dest="create_dir", action="store_true") + setupparser.add_option("-D", dest="no_delete_dir", action="store_true") + setupparser.add_option("-T", dest="no_unpack_default", action="store_true") + setupparser.add_option("-b", dest="unpack_before") + setupparser.add_option("-a", dest="unpack_after") + setupparser.add_option("-q", dest="quiet", action="store_true") + numlines = len(self.content) for i in range(numlines): line = self.content[i] @@ -294,7 +349,11 @@ class SpecFile(object): if srcnum in self.sources: self.sources[srcnum]['tag_linenum'] = i else: - self.sources[srcnum] = {'name': m.group('name'), 'filename': m.group('name'), 'tag_linenum': i} + self.sources[srcnum] = {'full_path': m.group('name'), + 'filename': os.path.basename(m.group('name')), + 'tag_linenum': i, + 'prefix': None, + 'setup_options': None, } continue # Find 'Patch' tags @@ -312,7 +371,13 @@ class SpecFile(object): gbp.log.err("Patch%s found multiple times, aborting as gbp spec/patch autoupdate likely fails" % patchnum) raise GbpError, "RPM error while parsing spec, duplicate patches found" else: - new_patch = {'name': m.group('name').strip(), 'filename': m.group('name'), 'apply': False, 'strip': '0', 'macro_linenum': None, 'autoupdate': not patchnum in ignorepatch, 'tag_linenum': i} + new_patch = {'name': m.group('name').strip(), + 'filename': m.group('name'), + 'apply': False, + 'strip': '0', + 'macro_linenum': None, + 'autoupdate': not patchnum in ignorepatch, + 'tag_linenum': i} self.patches[patchnum] = new_patch continue @@ -333,11 +398,27 @@ class SpecFile(object): self.patches[patchnum]['apply'] = True continue + # Find setup macros + m = self.setupmacro_re.match(line) + if m: + (options, args) = setupparser.parse_args(m.group('args').split()) + srcnum = None + if options.no_unpack_default: + if options.unpack_before: + srcnum = int(options.unpack_before) + elif options.unpack_after: + srcnum = int(options.unpack_after) + else: + srcnum = 0 + if srcnum != None and srcnum in self.sources: + self.sources[srcnum]['setup_options'] = options + # Save the occurrence of last setup macro + ret['setupmacro'] = i + continue + # Only search for the last occurrence of the following if re.match("^\s*Name:.*$", line, flags=re.I): ret['setupmacro'] = i - if re.match("^%setup(\s.*)?$", line): - ret['setupmacro'] = i if re.match("^%prep(\s.*)?$", line): ret['prepmacro'] = i continue @@ -462,23 +543,40 @@ class SpecFile(object): returns a tuple with full file path, filename base, archive format and compression method. """ - full_path, base, archive_fmt, comp = None, None, None, None - + orig_num = None for (num, src) in sorted(self.sources.iteritems()): - _full_path = src['filename'] - filename = os.path.basename(_full_path) - _base, _archive_fmt, _comp = parse_archive_filename(filename) + filename = os.path.basename(src['filename']) if filename.startswith(self.name): # Take the first archive that starts with pkg name - if _archive_fmt: - full_path, base, archive_fmt, comp = _full_path, _base, _archive_fmt, _comp + if src['archive_fmt']: + orig_num = num break # otherwise we take the first archive - elif not full_path and _archive_fmt: - full_path, base, archive_fmt, comp = _full_path, _base, _archive_fmt, _comp + elif orig_num == None and src['archive_fmt']: + orig_num = num # else don't accept - return (full_path, base, archive_fmt, comp) + # Refine our guess about the prefix + if orig_num != None: + orig = self.sources[orig_num] + setup_opts = orig['setup_options'] + if setup_opts: + if setup_opts.create_dir: + orig['prefix'] = '' + elif setup_opts.name: + try: + orig['prefix'] = self.macro_expand(setup_opts.name) + \ + '/' + except MacroExpandError as err: + gbp.log.warn("Couldn't determine prefix from %%setup "\ + "macro (%s). Using filename base as a " \ + "fallback" % err) + orig['prefix'] = orig['filename_base'] + '/' + else: + # RPM default + orig['prefix'] = "%s-%s/" % (self.name, + self.upstreamversion) + return orig_num def parse_srpm(srpmfile): diff --git a/gbp/scripts/buildpackage_rpm.py b/gbp/scripts/buildpackage_rpm.py index f6c72f20..3fff4e95 100755 --- a/gbp/scripts/buildpackage_rpm.py +++ b/gbp/scripts/buildpackage_rpm.py @@ -49,23 +49,23 @@ from gbp.scripts.pq_rpm import update_patch_series def git_archive(repo, spec, output_dir, treeish, comp_level, with_submodules): "create a compressed orig tarball in output_dir using git_archive" comp_opts = '' - if spec.orig_comp: - comp_opts = compressor_opts[spec.orig_comp][0] + if spec.orig_src['compression']: + comp_opts = compressor_opts[spec.orig_src['compression']][0] - output = os.path.join(output_dir, os.path.basename(spec.orig_file)) - prefix = spec.orig_base + output = os.path.join(output_dir, spec.orig_src['filename']) + prefix = spec.orig_src['prefix'] try: if repo.has_submodules() and with_submodules: repo.update_submodules() git_archive_submodules(repo, treeish, output, prefix, - spec.orig_comp, comp_level, comp_opts, - spec.orig_archive_fmt) + spec.orig_src['compression'], comp_level, comp_opts, + spec.orig_src['archive_fmt']) else: git_archive_single(repo, treeish, output, prefix, - spec.orig_comp, comp_level, comp_opts, - spec.orig_archive_fmt) + spec.orig_src['compression'], comp_level, comp_opts, + spec.orig_src['archive_fmt']) except (GitRepositoryError, CommandExecFailed): gbp.log.err("Error generating submodules' archives") return False @@ -86,7 +86,7 @@ def prepare_upstream_tarball(repo, spec, options, output_dir): tarball_dir, symlinking or building it. """ # look in tarball_dir first, if found force a symlink to it - orig_file = os.path.basename(spec.orig_file) + orig_file = spec.orig_src['filename'] if options.tarball_dir: gbp.log.debug("Looking for orig tarball '%s' at '%s'" % (orig_file, options.tarball_dir)) if not RpmPkgPolicy.symlink_orig(orig_file, options.tarball_dir, output_dir, force=True): @@ -178,11 +178,11 @@ def git_archive_build_orig(repo, spec, output_dir, options): @rtype: C{str} """ upstream_tree = get_upstream_tree(repo, spec, options) - gbp.log.info("%s does not exist, creating from '%s'" % (spec.orig_file, + gbp.log.info("%s does not exist, creating from '%s'" % (spec.orig_src['filename'], upstream_tree)) - if spec.orig_comp: + if spec.orig_src['compression']: gbp.log.debug("Building upstream source archive with compression '%s -%s'" % - (spec.orig_comp, options.comp_level)) + (spec.orig_src['compression'], options.comp_level)) if not git_archive(repo, spec, output_dir, upstream_tree, options.comp_level, options.with_submodules): @@ -484,16 +484,16 @@ def main(argv): # Get/build the orig tarball if is_native(repo, options): - if spec.orig_file: + if spec.orig_src: # Just build source archive from the exported tree - gbp.log.info("Creating (native) source archive %s from '%s'" % (spec.orig_file, tree)) - if spec.orig_comp: - gbp.log.debug("Building source archive with compression '%s -%s'" % (spec.orig_comp, options.comp_level)) + gbp.log.info("Creating (native) source archive %s from '%s'" % (spec.orig_src['filename'], tree)) + if spec.orig_src['compression']: + gbp.log.debug("Building source archive with compression '%s -%s'" % (spec.orig_src['compression'], options.comp_level)) if not git_archive(repo, spec, source_dir, tree, options.comp_level, options.with_submodules): raise GbpError, "Cannot create source tarball at '%s'" % export_dir # Non-native packages: create orig tarball from upstream - elif spec.orig_file: + elif spec.orig_src: prepare_upstream_tarball(repo, spec, options, source_dir) # Run postexport hook diff --git a/gbp/scripts/import_srpm.py b/gbp/scripts/import_srpm.py index e58d3fd9..0b4fbec9 100755 --- a/gbp/scripts/import_srpm.py +++ b/gbp/scripts/import_srpm.py @@ -249,8 +249,8 @@ def main(argv): orig_tarball = None if unpacked: files = [os.path.basename(patch['filename']) for patch in spec.patches.itervalues()] - for src in spec.sources.itervalues(): - if src['filename'] != spec.orig_file: + for num, src in spec.sources.iteritems(): + if num != spec.orig_src_num: files.append(src['filename']) files.append(spec.specfile) for fname in files: @@ -260,8 +260,8 @@ def main(argv): else: gbp.log.err("File '%s' listed in spec not found" % fname) raise GbpError - if spec.orig_base: - orig_tarball=os.path.join(dirs['src'], os.path.basename(spec.orig_file)) + if spec.orig_src: + orig_tarball=os.path.join(dirs['src'], spec.orig_src['filename']) else: gbp.log.info("Extracting src rpm...") src.unpack(dirs['pkgextract-packaging'], dirs['srctarball']) -- cgit v1.2.3 From c5db1293b6ad24f065ed738b023a4710132a2d81 Mon Sep 17 00:00:00 2001 From: Markus Lehtonen Date: Thu, 14 Jun 2012 19:34:09 +0300 Subject: rpm: add --orig-prefix option Adds a new option --orig-prefix that affects the prefix of the generated/imported orig tarballs. For git-buildpackage-rpm, it defines the prefix of tarballs generated by the tool, 'auto' (default) makes gbp to guess the prefix, as before. NOTE: this doesn't affect the tarballs checked out from pristine-tar (i.e. if --pristine-tar is defined) or tarballs that are already present (see --git-tarball-dir option). For git-import-orig, this new option affects the prefix of tarballs imported into pristine-tar branch. If set to 'auto' (default) gbp doesn't mangle the prefix. Other tools (e.g. git-import-srpm) are not affected. Signed-off-by: Markus Lehtonen --- gbp/config.py | 3 +++ gbp/scripts/buildpackage_rpm.py | 17 ++++++++++++++--- gbp/scripts/import_orig_rpm.py | 4 +++- 3 files changed, 20 insertions(+), 4 deletions(-) diff --git a/gbp/config.py b/gbp/config.py index a012335f..6d403d20 100644 --- a/gbp/config.py +++ b/gbp/config.py @@ -597,6 +597,7 @@ class GbpOptionParserRpm(GbpOptionParser): 'patch-export' : 'False', 'patch-export-compress' : '0', 'pristine-tarball-name' : 'auto', + 'orig-prefix' : 'auto', } ) help = dict(GbpOptionParser.help) @@ -619,6 +620,8 @@ class GbpOptionParserRpm(GbpOptionParser): "Compress (auto-generated) patches larger than given number of bytes, 0 never compresses, default is '%(patch-export-compress)s'", 'pristine-tarball-name': "Filename to record to pristine-tar, set to 'auto' to not mangle the file name, default is '%(pristine-tarball-name)s'", + 'orig-prefix': + "Prefix (dir) to be used when generating/importing tarballs, default is '%(orig-prefix)s'", } ) # vim:et:ts=4:sw=4:et:sts=4:ai:set list listchars=tab\:»·,trail\:·: diff --git a/gbp/scripts/buildpackage_rpm.py b/gbp/scripts/buildpackage_rpm.py index 3fff4e95..5e71caa4 100755 --- a/gbp/scripts/buildpackage_rpm.py +++ b/gbp/scripts/buildpackage_rpm.py @@ -46,15 +46,16 @@ from gbp.pkg import (compressor_opts, compressor_aliases) from gbp.scripts.pq_rpm import update_patch_series -def git_archive(repo, spec, output_dir, treeish, comp_level, with_submodules): +def git_archive(repo, spec, output_dir, treeish, prefix, comp_level, with_submodules): "create a compressed orig tarball in output_dir using git_archive" comp_opts = '' if spec.orig_src['compression']: comp_opts = compressor_opts[spec.orig_src['compression']][0] output = os.path.join(output_dir, spec.orig_src['filename']) - prefix = spec.orig_src['prefix'] + # Remove extra slashes from prefix, will be added by git_archive_x funcs + prefix = prefix.strip('/') try: if repo.has_submodules() and with_submodules: repo.update_submodules() @@ -184,6 +185,7 @@ def git_archive_build_orig(repo, spec, output_dir, options): gbp.log.debug("Building upstream source archive with compression '%s -%s'" % (spec.orig_src['compression'], options.comp_level)) if not git_archive(repo, spec, output_dir, upstream_tree, + options.orig_prefix, options.comp_level, options.with_submodules): raise GbpError("Cannot create upstream tarball at '%s'" % output_dir) @@ -326,6 +328,7 @@ def parse_args(argv, prefix): help="location to look for external tarballs") orig_group.add_config_file_option(option_name="compression-level", dest="comp_level", help="Compression level, default is '%(compression-level)s'") + orig_group.add_config_file_option(option_name="orig-prefix", dest="orig_prefix") branch_group.add_config_file_option(option_name="upstream-branch", dest="upstream_branch") branch_group.add_config_file_option(option_name="packaging-branch", dest="packaging_branch") branch_group.add_boolean_config_file_option(option_name = "ignore-branch", dest="ignore_branch") @@ -482,6 +485,14 @@ def main(argv): raise GbpError, "Error exporting files: %s" % err spec.specdir = spec_dir + if options.orig_prefix != 'auto': + options.orig_prefix = options.orig_prefix % dict(spec.version, + version=RpmPkgPolicy.compose_full_version(spec.version), + name=spec.name, + vendor=options.vendor) + elif spec.orig_src: + options.orig_prefix = spec.orig_src['prefix'] + # Get/build the orig tarball if is_native(repo, options): if spec.orig_src: @@ -489,7 +500,7 @@ def main(argv): gbp.log.info("Creating (native) source archive %s from '%s'" % (spec.orig_src['filename'], tree)) if spec.orig_src['compression']: gbp.log.debug("Building source archive with compression '%s -%s'" % (spec.orig_src['compression'], options.comp_level)) - if not git_archive(repo, spec, source_dir, tree, + if not git_archive(repo, spec, source_dir, tree, options.orig_prefix, options.comp_level, options.with_submodules): raise GbpError, "Cannot create source tarball at '%s'" % export_dir # Non-native packages: create orig tarball from upstream diff --git a/gbp/scripts/import_orig_rpm.py b/gbp/scripts/import_orig_rpm.py index 3d204b2c..1653fa68 100755 --- a/gbp/scripts/import_orig_rpm.py +++ b/gbp/scripts/import_orig_rpm.py @@ -174,6 +174,8 @@ def parse_args(argv): dest="filter_pristine_tar") import_group.add_config_file_option(option_name="pristine-tarball-name", dest="pristine_tarball_name") + import_group.add_config_file_option(option_name="orig-prefix", + dest="orig_prefix") import_group.add_config_file_option(option_name="import-msg", dest="import_msg") cmd_group.add_config_file_option(option_name="postimport", dest="postimport") @@ -234,7 +236,7 @@ def main(argv): prepare_sources(source, sourcepackage, version, prepare_pristine, options.filters, options.filter_pristine_tar, - None, tmpdir) + options.orig_prefix, tmpdir) # Don't mess up our repo with git metadata from an upstream tarball if os.path.isdir(os.path.join(unpacked_orig, '.git/')): -- cgit v1.2.3 From 9bb77228ca9c6015bc9b897ba04e5355fe541492 Mon Sep 17 00:00:00 2001 From: Markus Lehtonen Date: Tue, 12 Jun 2012 10:42:41 +0300 Subject: rpm: support squashing commits in patch generation Implements an option for git-buildpackage-rpm and gbp-pq to squash commits (from upstream) up to certain tree-ish into one monolithic diff. Useful e.g. if you wan't to auto-generate a stable update patch. The new format of the cmdline option filename is commit-ish followed by (optionally) a colon and the desired diff filename base. Suffix '.diff' is added by GBP. Magic word 'HEAD' translates to the end-commit when given as the squash-point. This allows one to configure gbp to always squash all commits into one monolithic diff. Signed-off-by: Markus Lehtonen --- gbp-rpm.conf | 4 +++- gbp/config.py | 6 ++++++ gbp/scripts/buildpackage_rpm.py | 1 + gbp/scripts/pq_rpm.py | 34 +++++++++++++++++++++++++++++++--- 4 files changed, 41 insertions(+), 4 deletions(-) diff --git a/gbp-rpm.conf b/gbp-rpm.conf index 2e31a685..27f80257 100644 --- a/gbp-rpm.conf +++ b/gbp-rpm.conf @@ -26,6 +26,8 @@ #spec-file = gbp.spec # Compress auto-generated patches #patch-export-compress=100k +# Squash commits until certain tree-ish into one diff +#patch-export-squash-until = stable-updates:stable # Export patches with numbering in filenames #patch-numbers = False @@ -108,7 +110,7 @@ ### [gbp-pq-rpm] # Name of the patch-queue / development branch -pq-branch = %(branch)s-devel +#pq-branch = %(branch)s-devel ### ### Options only affecting gbp-clone diff --git a/gbp/config.py b/gbp/config.py index 6d403d20..c326348f 100644 --- a/gbp/config.py +++ b/gbp/config.py @@ -596,6 +596,7 @@ class GbpOptionParserRpm(GbpOptionParser): 'rpmbuild-buildrootdir' : 'BUILDROOT', 'patch-export' : 'False', 'patch-export-compress' : '0', + 'patch-export-squash-until' : '', 'pristine-tarball-name' : 'auto', 'orig-prefix' : 'auto', } ) @@ -618,6 +619,11 @@ class GbpOptionParserRpm(GbpOptionParser): "Create patches between upstream and export-treeish, default is '%(patch-export)s'", 'patch-export-compress': "Compress (auto-generated) patches larger than given number of bytes, 0 never compresses, default is '%(patch-export-compress)s'", + 'patch-export-squash-until': + ("Squash commits (from upstream) until given tree-ish " + "into one big diff, format is " + "'[:]'. " + "Default is '%(patch-export-squash-until)s'"), 'pristine-tarball-name': "Filename to record to pristine-tar, set to 'auto' to not mangle the file name, default is '%(pristine-tarball-name)s'", 'orig-prefix': diff --git a/gbp/scripts/buildpackage_rpm.py b/gbp/scripts/buildpackage_rpm.py index 5e71caa4..a84c378f 100755 --- a/gbp/scripts/buildpackage_rpm.py +++ b/gbp/scripts/buildpackage_rpm.py @@ -368,6 +368,7 @@ def parse_args(argv, prefix): help="only export packaging files, don't build") export_group.add_boolean_config_file_option("patch-export", dest="patch_export") export_group.add_config_file_option("patch-export-compress", dest="patch_export_compress") + export_group.add_config_file_option("patch-export-squash-until", dest="patch_export_squash_until") export_group.add_boolean_config_file_option(option_name="patch-numbers", dest="patch_numbers") options, args = parser.parse_args(args) diff --git a/gbp/scripts/pq_rpm.py b/gbp/scripts/pq_rpm.py index 204091e8..377ae9f7 100755 --- a/gbp/scripts/pq_rpm.py +++ b/gbp/scripts/pq_rpm.py @@ -29,7 +29,7 @@ import gzip import subprocess from gbp.config import (GbpOptionParserRpm, GbpOptionGroup) from gbp.rpm.git import (GitRepositoryError, RpmGitRepository) -from gbp.git import GitModifier +from gbp.git.modifier import GitModifier, GitTz from gbp.command_wrappers import (Command, GitCommand, RunAtCommand, CommandExecFailed) from gbp.errors import GbpError @@ -61,7 +61,7 @@ def compress_patches(patches, compress_size=0): return ret_patches -def generate_patches(repo, start, end, outdir, options): +def generate_patches(repo, start, squash, end, outdir, options): """ Generate patch files from git """ @@ -72,6 +72,7 @@ def generate_patches(repo, start, end, outdir, options): if not repo.has_treeish(treeish): raise GbpError('%s not a valid tree-ish' % treeish) + start_sha1 = repo.rev_parse("%s^0" % start) try: end_commit = end end_commit_sha1 = repo.rev_parse("%s^0" % end_commit) @@ -85,6 +86,26 @@ def generate_patches(repo, start, end, outdir, options): if repo.get_merge_base(start_sha1, end_commit_sha1) != start_sha1: raise GbpError("Start commit '%s' not an ancestor of end commit " "'%s'" % (start, end_commit)) + # Squash commits, if requested + if squash[0]: + if squash[0] == 'HEAD': + squash[0] = end_commit + squash_sha1 = repo.rev_parse("%s^0" % squash[0]) + if start_sha1 != squash_sha1: + if not squash_sha1 in repo.get_commits(start, end_commit): + raise GbpError("Given squash point '%s' not in the history " + "of end commit '%s'" % (squash[0], end_commit)) + # Shorten SHA1s + squash_sha1 = repo.rev_parse(squash_sha1, short=7) + start_sha1 = repo.rev_parse(start_sha1, short=7) + gbp.log.info("Squashing commits %s..%s into one monolithic diff" % + (start_sha1, squash_sha1)) + patch_fn = format_diff(outdir, squash[1], repo, + start_sha1, squash_sha1) + if patch_fn: + patches.append(patch_fn) + start = squash_sha1 + # Generate patches for commit in reversed(repo.get_commits(start, end_commit)): info = repo.get_commit_info(commit) @@ -133,10 +154,16 @@ def update_patch_series(repo, spec, start, end, options): """ Export patches to packaging directory and update spec file accordingly. """ + squash = options.patch_export_squash_until.split(':', 1) + if len(squash) == 1: + squash.append(None) + else: + squash[1] += '.diff' + # Unlink old patch files and generate new patches rm_patch_files(spec) - patches, _commands = generate_patches(repo, start, end, + patches, _commands = generate_patches(repo, start, squash, end, spec.specdir, options) spec.update_patches(patches) spec.write_spec_file() @@ -394,6 +421,7 @@ def main(argv): "of head of patch-queue branch", metavar="TREEISH") parser.add_config_file_option("patch-export-compress", dest="patch_export_compress") + parser.add_config_file_option("patch-export-squash-until", dest="patch_export_squash_until") (options, args) = parser.parse_args(argv) gbp.log.setup(options.color, options.verbose) -- cgit v1.2.3 From 45d5f7a090c0a7b20c7d8a73ba21272a3c81e45c Mon Sep 17 00:00:00 2001 From: Markus Lehtonen Date: Thu, 28 Jun 2012 11:01:25 +0300 Subject: rpm: bigger refactor of import-srpm Import source rpms in the same way as unpacked sources: that is, first unpack the srpm and then use the same code for importing. Also, tries to make tmpdir handling a bit better: all temporary directories are created under one "base tmpdir". Also, get rid of the orig tarball guessing and unpackging in SrcRpmFile class in gbp.rpm. Signed-off-by: Markus Lehtonen --- gbp/rpm/__init__.py | 41 +---- gbp/scripts/import_srpm.py | 394 +++++++++++++++++++++------------------------ 2 files changed, 191 insertions(+), 244 deletions(-) diff --git a/gbp/rpm/__init__.py b/gbp/rpm/__init__.py index 0164ad2f..1ffefbf9 100644 --- a/gbp/rpm/__init__.py +++ b/gbp/rpm/__init__.py @@ -75,7 +75,6 @@ class SrcRpmFile(object): self.rpmhdr = rpm.ts(vsflags=ts_vsflags).hdrFromFdno(srpmfp.fileno()) srpmfp.close() self.srpmfile = os.path.abspath(srpmfile) - (self.orig_file, self.orig_base, self.orig_archive_fmt, self.orig_comp) = self.guess_orig_file() def _get_version(self): """ @@ -109,49 +108,15 @@ class SrcRpmFile(object): return self.rpmhdr[rpm.RPMTAG_PACKAGER] packager = property(_get_packager) - def unpack(self, dest_dir, srctarballdir=None): + def unpack(self, dest_dir): """ - Unpack the source rpm to tmpdir, move source tarball to srctallbardir. - Leave the cleanup to the caller in case of an error + Unpack the source rpm to tmpdir. + Leave the cleanup to the caller in case of an error. """ gbpc.RunAtCommand('rpm2cpio', [self.srpmfile, '|', 'cpio', '-id'], shell=True)(dir=dest_dir) - # Unpack source tarball - if self.orig_file: - orig_tarball = os.path.join(dest_dir, self.orig_file) - if srctarballdir: - if os.path.isdir(srctarballdir): - shutil.move(orig_tarball, srctarballdir) - else: - raise GbpError, "Src tarball destination dir not found or not a directory" - else: - gbp.log.warn("Failed to detect source tarball. Import may be incorrect") - #raise GbpError, "Failed to detect source tarball" - - def guess_orig_file(self): - """ - Try to guess the name of the primary upstream/source archive - returns a tuple with full file path, filename base, archive format and - compression method. - """ - full_path, base, archive_fmt, comp = None, None, None, None - - for _full_path in self.rpmhdr[rpm.RPMTAG_SOURCE]: - filename = os.path.basename(_full_path) - _base, _archive_fmt, _comp = parse_archive_filename(filename) - if RpmPkgPolicy.is_valid_orig_archive(filename): - if filename.startswith(self.name): - # Take the first archive that starts with pkg name - full_path, base, archive_fmt, comp = _full_path, _base, _archive_fmt, _comp - break - # otherwise we take the first archive - elif not full_path: - full_path, base, archive_fmt, comp = _full_path, _base, _archive_fmt, _comp - # else don't accept - return (full_path, base, archive_fmt, comp) - class SpecFile(object): """Class for parsing/modifying spec files""" diff --git a/gbp/scripts/import_srpm.py b/gbp/scripts/import_srpm.py index 0b4fbec9..444689d8 100755 --- a/gbp/scripts/import_srpm.py +++ b/gbp/scripts/import_srpm.py @@ -70,7 +70,7 @@ def download_source(pkg, dirs): else: mode = 'yumdownloader' - dirs['download'] = os.path.abspath(tempfile.mkdtemp()) + dirs['download'] = tempfile.mkdtemp(prefix='download', dir=dirs['tmp_base']) gbp.log.info("Trying to download '%s' using '%s'..." % (pkg, mode)) if mode == 'yumdownloader': gbpc.RunAtCommand('yumdownloader', @@ -171,229 +171,214 @@ def parse_args(argv): def main(argv): dirs = dict(top=os.path.abspath(os.curdir)) - needs_repo = False + ret = 0 skipped = False parents = None options, args = parse_args(argv) + if len(args) != 1: + gbp.log.err("Need to give exactly one package to import. Try --help.") + return 1 + try: + dirs['tmp_base'] = os.path.abspath(tempfile.mkdtemp()) + except GbpError as err: + gbp.log.err(err) + return 1 try: - if len(args) != 1: - gbp.log.err("Need to give exactly one package to import. Try --help.") - raise GbpError + srpm = args[0] + if options.download: + srpm = download_source(srpm, dirs) + + # Real srpm, we need to unpack, first + if not os.path.isdir(srpm) and not srpm.endswith(".spec"): + src = parse_srpm(srpm) + dirs['pkgextract'] = tempfile.mkdtemp(prefix='pkgextract', dir=dirs['tmp_base']) + gbp.log.info("Extracting src rpm to '%s'" % dirs['pkgextract']) + src.unpack(dirs['pkgextract']) + srpm = dirs['pkgextract'] + + # Find and parse spec file + if os.path.isdir(srpm): + gbp.log.debug("Trying to import an unpacked srpm from '%s'" % srpm) + dirs['src'] = os.path.abspath(srpm) + spec = parse_spec(guess_spec(srpm, True)) else: - pkg = args[0] - if options.download: - srpm = download_source(pkg, dirs=dirs) - else: - srpm = pkg - - if os.path.isdir(pkg) or pkg.endswith(".spec"): - if os.path.isdir(pkg): - gbp.log.debug("Trying to import an unpacked srpm from '%s'" % pkg) - dirs['src'] = os.path.abspath(pkg) - spec = parse_spec(guess_spec(pkg, True)) - else: - gbp.log.debug("Trying to import an srpm from '%s' with spec file '%s'" % (os.path.dirname(pkg), pkg)) - dirs['src'] = os.path.abspath(os.path.dirname(pkg)) - spec = parse_spec(pkg) - - pkgname = spec.name - pkgver = spec.version - upstream_version = spec.upstreamversion - packager = spec.packager - unpacked = True + gbp.log.debug("Trying to import an srpm from '%s' with spec file '%s'" % (os.path.dirname(srpm), srpm)) + dirs['src'] = os.path.abspath(os.path.dirname(srpm)) + spec = parse_spec(srpm) + + # Check the repository state + try: + repo = RpmGitRepository('.') + is_empty = repo.is_empty() + + (clean, out) = repo.is_clean() + if not clean and not is_empty: + gbp.log.err("Repository has uncommitted changes, commit these first: ") + raise GbpError, out + + except GitRepositoryError: + gbp.log.info("No git repository found, creating one.") + is_empty = True + repo = RpmGitRepository.create(spec.name) + os.chdir(repo.path) + + if repo.bare: + set_bare_repo_options(options) + + # Create more tempdirs + dirs['origsrc'] = tempfile.mkdtemp(prefix='origsrc', dir=dirs['tmp_base']) + dirs['packaging_base'] = tempfile.mkdtemp(prefix='packaging', dir=dirs['tmp_base']) + dirs['packaging'] = os.path.join(dirs['packaging_base'], options.packaging_dir) + try: + os.mkdir(dirs['packaging']) + except OSError, (e, emsg): + if e != errno.EEXIST: + raise + + # Need to copy files to the packaging directory given by caller + files = [os.path.basename(patch['filename']) for patch in spec.patches.itervalues()] + for num, src in spec.sources.iteritems(): + if num != spec.orig_src_num: + files.append(src['filename']) + files.append(spec.specfile) + for fname in files: + fpath = os.path.join(dirs['src'], fname) + if os.path.exists(fpath): + shutil.copy2(fpath, dirs['packaging']) else: - gbp.log.debug("Trying to import an source rpm '%s'" % srpm) - dirs['src'] = os.path.abspath(os.path.dirname(pkg)) - src = parse_srpm(srpm) - pkgname = src.name - pkgver = src.version - upstream_version = src.upstreamversion - packager = src.packager - unpacked = False - - try: - repo = RpmGitRepository('.') - is_empty = repo.is_empty() - - (clean, out) = repo.is_clean() - if not clean and not is_empty: - gbp.log.err("Repository has uncommitted changes, commit these first: ") - raise GbpError, out - - except GitRepositoryError: - # no repo found, create one - needs_repo = True - is_empty = True - - if needs_repo: - gbp.log.info("No git repository found, creating one.") - repo = RpmGitRepository.create(pkgname) - os.chdir(repo.path) - - if repo.bare: - set_bare_repo_options(options) - - dirs['pkgextract'] = os.path.abspath(tempfile.mkdtemp(dir='..')) - dirs['pkgextract-packaging'] = os.path.join(dirs['pkgextract'], options.packaging_dir) - try: - os.mkdir(dirs['pkgextract-packaging']) - except OSError, (e, emsg): - if e == errno.EEXIST: - pass - dirs['srctarball'] = os.path.abspath(tempfile.mkdtemp(dir='..')) - dirs['srcunpack'] = os.path.abspath(tempfile.mkdtemp(dir='..')) - - orig_tarball = None - if unpacked: - files = [os.path.basename(patch['filename']) for patch in spec.patches.itervalues()] - for num, src in spec.sources.iteritems(): - if num != spec.orig_src_num: - files.append(src['filename']) - files.append(spec.specfile) - for fname in files: - fpath = os.path.join(dirs['src'], fname) - if os.path.exists(fpath): - shutil.copy2(fpath, dirs['pkgextract-packaging']) - else: - gbp.log.err("File '%s' listed in spec not found" % fname) - raise GbpError - if spec.orig_src: - orig_tarball=os.path.join(dirs['src'], spec.orig_src['filename']) - else: - gbp.log.info("Extracting src rpm...") - src.unpack(dirs['pkgextract-packaging'], dirs['srctarball']) - if src.orig_file: - orig_tarball = os.path.join(dirs['srctarball'], src.orig_file) - - if orig_tarball: - upstream = RpmUpstreamSource(orig_tarball) - upstream = upstream.unpack(dirs['srcunpack'], options.filters) - else: - upstream = None + gbp.log.err("File '%s' listed in spec not found" % fname) + raise GbpError + + # Unpack orig source archive + if spec.orig_src: + orig_tarball=os.path.join(dirs['src'], spec.orig_src['filename']) + upstream = RpmUpstreamSource(orig_tarball) + upstream = upstream.unpack(dirs['origsrc'], options.filters) + else: + upstream = None - format = [(options.upstream_tag, "Upstream"), (options.packaging_tag, options.vendor)][options.native] - tag_str_fields = dict(pkgver, vendor=options.vendor) - tag = repo.version_to_tag(format[0], tag_str_fields) + format = [(options.upstream_tag, "Upstream"), (options.packaging_tag, options.vendor)][options.native] + tag_str_fields = dict(spec.version, vendor=options.vendor) + tag = repo.version_to_tag(format[0], tag_str_fields) - if repo.find_version(options.packaging_tag, tag_str_fields): - gbp.log.warn("Version %s already imported." % RpmPkgPolicy.compose_full_version(pkgver)) - if options.allow_same_version: - gbp.log.info("Moving tag of version '%s' since import forced" % RpmPkgPolicy.compose_full_version(pkgver)) - move_tag_stamp(repo, options.packaging_tag, tag_str_fields) - else: - raise SkipImport - - if is_empty: - options.create_missing_branches = True - - # Determine author and committer info, currently same info is used - # for both upstream sources and packaging files - author=None - if packager: - match = re.match('(?P.*[^ ])\s*<(?P\S*)>', packager.strip()) - if match: - author=GitModifier(match.group('name'), match.group('email')) - if not author: - author=GitModifier() - gbp.log.debug("Couldn't determine packager info") - committer = committer_from_author(author, options) - - # Import upstream sources - if upstream: - upstream_commit = repo.find_version(format[0], tag_str_fields) - if not upstream_commit: - gbp.log.info("Tag %s not found, importing %s tarball" % (tag, format[1])) - - branch = [options.upstream_branch, - options.packaging_branch][options.native] - if not repo.has_branch(branch): - if options.create_missing_branches: - gbp.log.info("Will create missing branch '%s'" % branch) - else: - gbp.log.err(no_upstream_branch_msg % branch + - "\nAlso check the --create-missing-branches option.") - raise GbpError - - msg = "%s version %s" % (format[1], upstream_version) - upstream_commit = repo.commit_dir(upstream.unpacked, - "Imported %s" % msg, - branch, - author=author, - committer=committer, - create_missing_branch=options.create_missing_branches) - repo.create_tag(name=tag, - msg=msg, - commit=upstream_commit, - sign=options.sign_tags, - keyid=options.keyid) - - if not options.native: - if options.pristine_tar: - repo.pristine_tar.commit(orig_tarball, 'refs/heads/%s' % options.upstream_branch) - parents = [ options.upstream_branch ] + if repo.find_version(options.packaging_tag, tag_str_fields): + gbp.log.warn("Version %s already imported." % RpmPkgPolicy.compose_full_version(spec.version)) + if options.allow_same_version: + gbp.log.info("Moving tag of version '%s' since import forced" % RpmPkgPolicy.compose_full_version(spec.version)) + move_tag_stamp(repo, options.packaging_tag, tag_str_fields) else: - gbp.log.info("No source tarball imported") - - if not options.native or not upstream: - # Import packaging files - gbp.log.info("Importing packaging files...") - branch = options.packaging_branch + raise SkipImport + + if is_empty: + options.create_missing_branches = True + + # Determine author and committer info, currently same info is used + # for both upstream sources and packaging files + author=None + if spec.packager: + match = re.match('(?P.*[^ ])\s*<(?P\S*)>', spec.packager.strip()) + if match: + author=GitModifier(match.group('name'), match.group('email')) + if not author: + author=GitModifier() + gbp.log.debug("Couldn't determine packager info") + committer = committer_from_author(author, options) + + # Import upstream sources + if upstream: + upstream_commit = repo.find_version(format[0], tag_str_fields) + if not upstream_commit: + gbp.log.info("Tag %s not found, importing %s upstream sources" % (tag, format[1])) + + branch = [options.upstream_branch, + options.packaging_branch][options.native] if not repo.has_branch(branch): if options.create_missing_branches: gbp.log.info("Will create missing branch '%s'" % branch) else: - gbp.log.err(no_packaging_branch_msg % branch + - "\nAlso check the --create-missing-branches option.") + gbp.log.err(no_upstream_branch_msg % branch + + "\nAlso check the --create-missing-branches option.") raise GbpError - tag_str_fields = dict(pkgver, vendor=options.vendor) - tag = repo.version_to_tag(options.packaging_tag, tag_str_fields) - msg = "%s release %s" % (options.vendor, RpmPkgPolicy.compose_full_version(pkgver)) - - if options.orphan_packaging or not upstream: - parents = [] - commit = repo.commit_dir(dirs['pkgextract'], - "Imported %s" % msg, - branch, - author=author, - committer=committer, - create_missing_branch=options.create_missing_branches) - else: - # Copy packaging files to the unpacked sources dir - try: - pkgsubdir = os.path.join(upstream.unpacked, options.packaging_dir) - os.mkdir(pkgsubdir) - except OSError, (e, emsg): - if e == errno.EEXIST: - pass - else: - raise - for f in os.listdir(dirs['pkgextract-packaging']): - shutil.copy2(os.path.join(dirs['pkgextract-packaging'], f), - pkgsubdir) - commit = repo.commit_dir(upstream.unpacked, - "Imported %s" % msg, - branch, - other_parents=[upstream_commit], - author=author, - committer=committer, - create_missing_branch=options.create_missing_branches) - + msg = "%s version %s" % (format[1], spec.upstreamversion) + upstream_commit = repo.commit_dir(upstream.unpacked, + "Imported %s" % msg, + branch, + author=author, + committer=committer, + create_missing_branch=options.create_missing_branches) repo.create_tag(name=tag, msg=msg, - commit=commit, + commit=upstream_commit, sign=options.sign_tags, keyid=options.keyid) - if repo.get_branch() == options.packaging_branch: - # Update HEAD if we modified the checked out branch - repo.force_head(options.packaging_branch, hard=True) - # Checkout packaging branch - repo.set_branch(options.packaging_branch) - + if not options.native: + if options.pristine_tar: + repo.pristine_tar.commit(orig_tarball, 'refs/heads/%s' % options.upstream_branch) + parents = [ options.upstream_branch ] + else: + gbp.log.info("No orig source archive imported") + + # Import packaging files. For native packages we assume that also + # packaging files are found in the source tarball + if not options.native or not upstream: + gbp.log.info("Importing packaging files") + branch = options.packaging_branch + if not repo.has_branch(branch): + if options.create_missing_branches: + gbp.log.info("Will create missing branch '%s'" % branch) + else: + gbp.log.err(no_packaging_branch_msg % branch + + "\nAlso check the --create-missing-branches option.") + raise GbpError + + tag_str_fields = dict(spec.version, vendor=options.vendor) + tag = repo.version_to_tag(options.packaging_tag, tag_str_fields) + msg = "%s release %s" % (options.vendor, RpmPkgPolicy.compose_full_version(spec.version)) + + if options.orphan_packaging or not upstream: + parents = [] + commit = repo.commit_dir(dirs['packaging_base'], + "Imported %s" % msg, + branch, + author=author, + committer=committer, + create_missing_branch=options.create_missing_branches) + else: + # Copy packaging files to the unpacked sources dir + try: + pkgsubdir = os.path.join(upstream.unpacked, options.packaging_dir) + os.mkdir(pkgsubdir) + except OSError, (e, emsg): + if e != errno.EEXIST: + raise + for f in os.listdir(dirs['packaging']): + shutil.copy2(os.path.join(dirs['packaging'], f), + pkgsubdir) + commit = repo.commit_dir(upstream.unpacked, + "Imported %s" % msg, + branch, + other_parents=[upstream_commit], + author=author, + committer=committer, + create_missing_branch=options.create_missing_branches) + + # Create packaging tag + repo.create_tag(name=tag, + msg=msg, + commit=commit, + sign=options.sign_tags, + keyid=options.keyid) + + if repo.get_branch() == options.packaging_branch: + # Update HEAD if we modified the checked out branch + repo.force_head(options.packaging_branch, hard=True) + # Checkout packaging branch + repo.set_branch(options.packaging_branch) except KeyboardInterrupt: ret = 1 @@ -414,13 +399,10 @@ def main(argv): skipped = True finally: os.chdir(dirs['top']) - - for d in [ 'pkgextract', 'srctarball', 'srcunpack', 'download' ]: - if dirs.has_key(d): - gbpc.RemoveTree(dirs[d])() + gbpc.RemoveTree(dirs['tmp_base'])() if not ret and not skipped: - gbp.log.info("Version '%s' imported under '%s'" % (RpmPkgPolicy.compose_full_version(pkgver), pkgname)) + gbp.log.info("Version '%s' imported under '%s'" % (RpmPkgPolicy.compose_full_version(spec.version), spec.name)) return ret if __name__ == '__main__': -- cgit v1.2.3 From f2eb4c8868661732bb672db1146d914ca4447d54 Mon Sep 17 00:00:00 2001 From: Markus Lehtonen Date: Wed, 27 Jun 2012 18:12:01 +0300 Subject: import-srpm: support for patch import Adds a new commandline option '--patch-import' for importing patches into the source tree in packaging branch. When enabled, gbp applies and commits all patches (not marked for manual maintenance) into the packaging branch. If this succeeds, it also removes all imported patch files from the packaging directory and the spec file. Currently only supported for non-orphan-packaging. This setting is true by default which should make more sense as the developer wants to do code development in the packaging branch (if he/she selects to use non-orphan packaging). However, patch-import is force-disabled if in bare git repository. We cannot support this, currently. Signed-off-by: Markus Lehtonen --- gbp/config.py | 3 ++ gbp/rpm/__init__.py | 8 +++-- gbp/scripts/import_srpm.py | 79 ++++++++++++++++++++++++++++++++++++++++++---- 3 files changed, 81 insertions(+), 9 deletions(-) diff --git a/gbp/config.py b/gbp/config.py index c326348f..8c2921ad 100644 --- a/gbp/config.py +++ b/gbp/config.py @@ -599,6 +599,7 @@ class GbpOptionParserRpm(GbpOptionParser): 'patch-export-squash-until' : '', 'pristine-tarball-name' : 'auto', 'orig-prefix' : 'auto', + 'patch-import' : 'True', } ) help = dict(GbpOptionParser.help) @@ -628,6 +629,8 @@ class GbpOptionParserRpm(GbpOptionParser): "Filename to record to pristine-tar, set to 'auto' to not mangle the file name, default is '%(pristine-tarball-name)s'", 'orig-prefix': "Prefix (dir) to be used when generating/importing tarballs, default is '%(orig-prefix)s'", + 'patch-import': + "Import patches to the packaging branch, default is '%(patch-import)s'", } ) # vim:et:ts=4:sw=4:et:sts=4:ai:set list listchars=tab\:»·,trail\:·: diff --git a/gbp/rpm/__init__.py b/gbp/rpm/__init__.py index 1ffefbf9..63cd7689 100644 --- a/gbp/rpm/__init__.py +++ b/gbp/rpm/__init__.py @@ -476,14 +476,18 @@ class SpecFile(object): linenum = loc['nametag'] + 1 # Add all patch tag lines to content, in reversed order + patch_tags_added = 0 for n in reversed(sorted(self.patches.keys())): patch = self.patches[n] if patch['autoupdate']: # "PatchXYZ:" text 12 chars wide, left aligned text = "%-12s%s" % ("Patch%d:" % n, patch['name']) self.content.insert(linenum, text + "\n") - # Finally, add a comment indicating gbp generated patches - self.content.insert(linenum, "# Patches auto-generated by git-buildpackage:\n") + patch_tags_added += 1 + if patch_tags_added > 0: + # Finally, add a comment indicating gbp generated patches + self.content.insert(linenum, "# Patches auto-generated by " + "git-buildpackage:\n") # Remove all old patch tag lines for l in reversed(rm_tag_lines): gbp.log.debug("Removing line #%s from spec: '%s'" % (l, self.content[l].strip())) diff --git a/gbp/scripts/import_srpm.py b/gbp/scripts/import_srpm.py index 444689d8..d5cf4328 100755 --- a/gbp/scripts/import_srpm.py +++ b/gbp/scripts/import_srpm.py @@ -38,6 +38,8 @@ from gbp.git.modifier import GitModifier from gbp.config import GbpOptionParserRpm, GbpOptionGroup, no_upstream_branch_msg from gbp.errors import GbpError import gbp.log +from gbp.scripts.pq_rpm import safe_patches, rm_patch_files, get_packager +from gbp.scripts.common.pq import apply_and_commit_patch no_packaging_branch_msg = """ Repository does not have branch '%s' for packaging/distribution sources. If there is none see @@ -45,6 +47,12 @@ file:///usr/share/doc/git-buildpackage/manual-html/gbp.import.html#GBP.IMPORT.CO on howto create it otherwise use --packaging-branch to specify it. """ +PATCH_AUTODELETE_COMMIT_MSG = """ +Autoremove imported patches from packaging + +Removed all imported patches from %s +and patch files from the packaging dir. +""" class SkipImport(Exception): pass @@ -102,9 +110,59 @@ def move_tag_stamp(repo, format, tag_str_fields): def set_bare_repo_options(options): """Modify options for import into a bare repository""" if options.pristine_tar: - gbp.log.info("Bare repository: setting %s option" - % (["", " '--no-pristine-tar'"][options.pristine_tar], )) + gbp.log.info("Bare repository: setting %s option '--no-pristine-tar'") options.pristine_tar = False + if options.patch_import: + gbp.log.info("Bare repository: setting %s option '--no-patch-import')") + options.patch_import = False + + +def import_spec_patches(repo, spec): + """ + Import patches from a spec file to the current branch + """ + queue = spec.patchseries() + if len(queue) == 0: + return + + gbp.log.info("Importing patches to '%s' branch" % repo.get_branch()) + tmpdir = tempfile.mkdtemp() + orig_head = repo.rev_parse("HEAD") + packager = get_packager(spec) + + try: + # Put patches in a safe place + safedir, queue = safe_patches(queue, tmpdir) + for patch in queue: + gbp.log.debug("Applying %s" % patch.path) + try: + apply_and_commit_patch(repo, patch, packager) + except (GbpError, GitRepositoryError): + repo.force_head(orig_head, hard=True) + raise GbpError, "Couldn't import patches, you need to apply and commit manually" + finally: + shutil.rmtree(tmpdir) + + # Remove patches from spec and packaging directory + gbp.log.info("Removing imported patch files from spec and packaging dir") + rm_patch_files(spec) + try: + spec.update_patches([]) + spec.write_spec_file() + except GbpError: + repo.force_head('HEAD', hard=True) + raise GbpError("Unable to update spec file, you need to edit and " + "commit it manually") + repo.commit_all(msg=PATCH_AUTODELETE_COMMIT_MSG % + os.path.basename(spec.specfile)) + + +def force_to_branch_head(repo, branch): + if repo.get_branch() == branch: + # Update HEAD if we modified the checked out branch + repo.force_head(branch, hard=True) + # Checkout packaging branch + repo.set_branch(branch) def parse_args(argv): @@ -164,6 +222,8 @@ def parse_args(argv): dest="author_is_committer") import_group.add_config_file_option(option_name="packaging-dir", dest="packaging_dir") + import_group.add_boolean_config_file_option(option_name="patch-import", + dest="patch_import") (options, args) = parser.parse_args(argv[1:]) gbp.log.setup(options.color, options.verbose) return options, args @@ -366,6 +426,15 @@ def main(argv): author=author, committer=committer, create_missing_branch=options.create_missing_branches) + # Import patches on top of the source tree + # (only for non-native packages with non-orphan packaging) + force_to_branch_head(repo, options.packaging_branch) + if options.patch_import: + spec = parse_spec(os.path.join(repo.path, + options.packaging_dir, + os.path.basename(spec.specfile))) + import_spec_patches(repo, spec) + commit = options.packaging_branch # Create packaging tag repo.create_tag(name=tag, @@ -374,11 +443,7 @@ def main(argv): sign=options.sign_tags, keyid=options.keyid) - if repo.get_branch() == options.packaging_branch: - # Update HEAD if we modified the checked out branch - repo.force_head(options.packaging_branch, hard=True) - # Checkout packaging branch - repo.set_branch(options.packaging_branch) + force_to_branch_head(repo, options.packaging_branch) except KeyboardInterrupt: ret = 1 -- cgit v1.2.3 From f8bc6e520ea33fda7d8df3f6b690549b695e3d23 Mon Sep 17 00:00:00 2001 From: Markus Lehtonen Date: Thu, 12 Jul 2012 09:07:47 +0300 Subject: Universal configurable base tmpdir for all gbp rpm tools Signed-off-by: Markus Lehtonen --- gbp/scripts/buildpackage_rpm.py | 36 ++++++++++++++++++----------- gbp/scripts/import_orig_rpm.py | 5 +++-- gbp/scripts/import_srpm.py | 50 +++++++++++++++++++++-------------------- gbp/scripts/pq_rpm.py | 16 +++++++------ 4 files changed, 61 insertions(+), 46 deletions(-) diff --git a/gbp/scripts/buildpackage_rpm.py b/gbp/scripts/buildpackage_rpm.py index a84c378f..22f1eeaf 100755 --- a/gbp/scripts/buildpackage_rpm.py +++ b/gbp/scripts/buildpackage_rpm.py @@ -22,12 +22,12 @@ import ConfigParser import errno import os, os.path import sys -import tempfile import shutil import re from datetime import datetime import gzip +import gbp.tmpfile as tempfile import gbp.rpm as rpm from gbp.rpm.policy import RpmPkgPolicy from gbp.command_wrappers import (Command, @@ -46,7 +46,8 @@ from gbp.pkg import (compressor_opts, compressor_aliases) from gbp.scripts.pq_rpm import update_patch_series -def git_archive(repo, spec, output_dir, treeish, prefix, comp_level, with_submodules): +def git_archive(repo, spec, output_dir, tmpdir_base, treeish, prefix, + comp_level, with_submodules): "create a compressed orig tarball in output_dir using git_archive" comp_opts = '' if spec.orig_src['compression']: @@ -59,8 +60,9 @@ def git_archive(repo, spec, output_dir, treeish, prefix, comp_level, with_submod try: if repo.has_submodules() and with_submodules: repo.update_submodules() - git_archive_submodules(repo, treeish, output, prefix, - spec.orig_src['compression'], comp_level, comp_opts, + git_archive_submodules(repo, treeish, output, tmpdir_base, + prefix, spec.orig_src['compression'], + comp_level, comp_opts, spec.orig_src['archive_fmt']) else: @@ -184,7 +186,7 @@ def git_archive_build_orig(repo, spec, output_dir, options): if spec.orig_src['compression']: gbp.log.debug("Building upstream source archive with compression '%s -%s'" % (spec.orig_src['compression'], options.comp_level)) - if not git_archive(repo, spec, output_dir, upstream_tree, + if not git_archive(repo, spec, output_dir, options.tmp_dir, upstream_tree, options.orig_prefix, options.comp_level, options.with_submodules): @@ -303,6 +305,7 @@ def parse_args(argv, prefix): parser.add_boolean_config_file_option(option_name = "ignore-new", dest="ignore_new") parser.add_option("--git-verbose", action="store_true", dest="verbose", default=False, help="verbose command execution") + parser.add_config_file_option(option_name="tmp-dir", dest="tmp_dir") parser.add_config_file_option(option_name="color", dest="color", type='tristate') parser.add_config_file_option(option_name="notify", dest="notify", type='tristate') parser.add_config_file_option(option_name="vendor", action="store", dest="vendor") @@ -387,7 +390,6 @@ def main(argv): retval = 0 prefix = "git-" spec = None - dump_dir = None options, gbp_args, builder_args = parse_args(argv, prefix) if not options: @@ -401,6 +403,14 @@ def main(argv): else: repo_dir = os.path.abspath(os.path.curdir) + try: + # Create base temporary directory for this run + options.tmp_dir = tempfile.mkdtemp(dir=options.tmp_dir, + prefix='buildpackage-rpm_') + except GbpError, err: + gbp.log.err(err) + return 1 + try: branch = repo.get_branch() except GitRepositoryError: @@ -436,7 +446,8 @@ def main(argv): raise GbpError('Invalid treeish object %s' % tree) # Dump from git to a temporary directory: - dump_dir = tempfile.mkdtemp(dir=".") + dump_dir = tempfile.mkdtemp(dir=options.tmp_dir, + prefix='dump_tree_') gbp.log.debug("Dumping tree '%s' to '%s'" % (options.export, dump_dir)) if not dump_tree(repo, dump_dir, tree, options.with_submodules): raise GbpError @@ -501,8 +512,10 @@ def main(argv): gbp.log.info("Creating (native) source archive %s from '%s'" % (spec.orig_src['filename'], tree)) if spec.orig_src['compression']: gbp.log.debug("Building source archive with compression '%s -%s'" % (spec.orig_src['compression'], options.comp_level)) - if not git_archive(repo, spec, source_dir, tree, options.orig_prefix, - options.comp_level, options.with_submodules): + if not git_archive(repo, spec, source_dir, options.tmp_dir, + tree, options.orig_prefix, + options.comp_level, + options.with_submodules): raise GbpError, "Cannot create source tarball at '%s'" % export_dir # Non-native packages: create orig tarball from upstream elif spec.orig_src: @@ -563,10 +576,7 @@ def main(argv): retval = 1 finally: drop_index(repo) - - # Clean temporary dumpdir - if dump_dir and retval == 0: - shutil.rmtree(dump_dir) + shutil.rmtree(options.tmp_dir) if not options.tag_only: if spec and options.notify: diff --git a/gbp/scripts/import_orig_rpm.py b/gbp/scripts/import_orig_rpm.py index 1653fa68..d1ec57af 100755 --- a/gbp/scripts/import_orig_rpm.py +++ b/gbp/scripts/import_orig_rpm.py @@ -21,7 +21,7 @@ import ConfigParser import os import sys -import tempfile +import gbp.tmpfile as tempfile import gbp.command_wrappers as gbpc import string from gbp.pkg import parse_archive_filename @@ -185,6 +185,7 @@ def parse_args(argv): parser.add_option("-v", "--verbose", action="store_true", dest="verbose", default=False, help="verbose command execution") parser.add_config_file_option(option_name="color", dest="color", type='tristate') + parser.add_config_file_option(option_name="tmp-dir", dest="tmp_dir") (options, args) = parser.parse_args(argv[1:]) gbp.log.setup(options.color, options.verbose) @@ -199,7 +200,7 @@ def main(argv): if not options: return 1 - tmpdir = tempfile.mkdtemp(dir='../') + tmpdir = tempfile.mkdtemp(dir=options.tmp_dir, prefix='import-orig-rpm_') try: source = find_source(options, args) try: diff --git a/gbp/scripts/import_srpm.py b/gbp/scripts/import_srpm.py index d5cf4328..82508922 100755 --- a/gbp/scripts/import_srpm.py +++ b/gbp/scripts/import_srpm.py @@ -21,7 +21,6 @@ import ConfigParser import sys import re import os -import tempfile import glob import pipes import time @@ -29,6 +28,7 @@ import shutil import errno import urllib2 +import gbp.tmpfile as tempfile import gbp.command_wrappers as gbpc from gbp.rpm import (parse_srpm, SrcRpmFile, SpecFile, guess_spec, NoSpecError, parse_spec, RpmUpstreamSource) @@ -78,15 +78,15 @@ def download_source(pkg, dirs): else: mode = 'yumdownloader' - dirs['download'] = tempfile.mkdtemp(prefix='download', dir=dirs['tmp_base']) + tmpdir = tempfile.mkdtemp(dir=dirs['tmp_base'], prefix='download_') gbp.log.info("Trying to download '%s' using '%s'..." % (pkg, mode)) if mode == 'yumdownloader': gbpc.RunAtCommand('yumdownloader', ['--source', '--destdir=', '.', pkg], - shell=False)(dir=dirs['download']) + shell=False)(dir=tmpdir) else: - download_file(dirs['download'], pkg) - srpm = glob.glob(os.path.join(dirs['download'], '*.src.rpm'))[0] + download_file(tmpdir, pkg) + srpm = glob.glob(os.path.join(tmpdir, '*.src.rpm'))[0] return srpm @@ -117,7 +117,7 @@ def set_bare_repo_options(options): options.patch_import = False -def import_spec_patches(repo, spec): +def import_spec_patches(repo, spec, dirs): """ Import patches from a spec file to the current branch """ @@ -126,22 +126,19 @@ def import_spec_patches(repo, spec): return gbp.log.info("Importing patches to '%s' branch" % repo.get_branch()) - tmpdir = tempfile.mkdtemp() + tmpdir = tempfile.mkdtemp(dir=dirs['tmp_base'], prefix='import_') orig_head = repo.rev_parse("HEAD") packager = get_packager(spec) - try: - # Put patches in a safe place - safedir, queue = safe_patches(queue, tmpdir) - for patch in queue: - gbp.log.debug("Applying %s" % patch.path) - try: - apply_and_commit_patch(repo, patch, packager) - except (GbpError, GitRepositoryError): - repo.force_head(orig_head, hard=True) - raise GbpError, "Couldn't import patches, you need to apply and commit manually" - finally: - shutil.rmtree(tmpdir) + # Put patches in a safe place + safedir, queue = safe_patches(queue, tmpdir) + for patch in queue: + gbp.log.debug("Applying %s" % patch.path) + try: + apply_and_commit_patch(repo, patch, packager) + except (GbpError, GitRepositoryError): + repo.force_head(orig_head, hard=True) + raise GbpError, "Couldn't import patches, you need to apply and commit manually" # Remove patches from spec and packaging directory gbp.log.info("Removing imported patch files from spec and packaging dir") @@ -186,6 +183,7 @@ def parse_args(argv): parser.add_option("-v", "--verbose", action="store_true", dest="verbose", default=False, help="verbose command execution") parser.add_config_file_option(option_name="color", dest="color", type='tristate') + parser.add_config_file_option(option_name="tmp-dir", dest="tmp_dir") parser.add_option("--download", action="store_true", dest="download", default=False, help="download source package") parser.add_config_file_option(option_name="vendor", action="store", dest="vendor") @@ -242,7 +240,8 @@ def main(argv): gbp.log.err("Need to give exactly one package to import. Try --help.") return 1 try: - dirs['tmp_base'] = os.path.abspath(tempfile.mkdtemp()) + dirs['tmp_base'] = tempfile.mkdtemp(dir=options.tmp_dir, + prefix='import-srpm') except GbpError as err: gbp.log.err(err) return 1 @@ -254,7 +253,8 @@ def main(argv): # Real srpm, we need to unpack, first if not os.path.isdir(srpm) and not srpm.endswith(".spec"): src = parse_srpm(srpm) - dirs['pkgextract'] = tempfile.mkdtemp(prefix='pkgextract', dir=dirs['tmp_base']) + dirs['pkgextract'] = tempfile.mkdtemp(dir=dirs['tmp_base'], + prefix='pkgextract_') gbp.log.info("Extracting src rpm to '%s'" % dirs['pkgextract']) src.unpack(dirs['pkgextract']) srpm = dirs['pkgextract'] @@ -289,8 +289,10 @@ def main(argv): set_bare_repo_options(options) # Create more tempdirs - dirs['origsrc'] = tempfile.mkdtemp(prefix='origsrc', dir=dirs['tmp_base']) - dirs['packaging_base'] = tempfile.mkdtemp(prefix='packaging', dir=dirs['tmp_base']) + dirs['origsrc'] = tempfile.mkdtemp(dir=dirs['tmp_base'], + prefix='origsrc_') + dirs['packaging_base'] = tempfile.mkdtemp(dir=dirs['tmp_base'], + prefix='packaging_') dirs['packaging'] = os.path.join(dirs['packaging_base'], options.packaging_dir) try: os.mkdir(dirs['packaging']) @@ -433,7 +435,7 @@ def main(argv): spec = parse_spec(os.path.join(repo.path, options.packaging_dir, os.path.basename(spec.specfile))) - import_spec_patches(repo, spec) + import_spec_patches(repo, spec, dirs) commit = options.packaging_branch # Create packaging tag diff --git a/gbp/scripts/pq_rpm.py b/gbp/scripts/pq_rpm.py index 377ae9f7..9c1493bf 100755 --- a/gbp/scripts/pq_rpm.py +++ b/gbp/scripts/pq_rpm.py @@ -23,10 +23,10 @@ import errno import os import shutil import sys -import tempfile import re import gzip import subprocess +import gbp.tmpfile as tempfile from gbp.config import (GbpOptionParserRpm, GbpOptionGroup) from gbp.rpm.git import (GitRepositoryError, RpmGitRepository) from gbp.git.modifier import GitModifier, GitTz @@ -218,7 +218,7 @@ def safe_patches(queue, tmpdir_base): @rtype: tuple """ - tmpdir = tempfile.mkdtemp(dir=tmpdir_base, prefix='gbp-pq') + tmpdir = tempfile.mkdtemp(dir=tmpdir_base, prefix='patchimport_') safequeue=PatchSeries() if len(queue) > 0: @@ -309,7 +309,7 @@ def import_spec_patches(repo, branch, options): queue = spec.patchseries() packager = get_packager(spec) # Put patches in a safe place - tmpdir, queue = safe_patches(queue, repo.path) + tmpdir, queue = safe_patches(queue, options.tmp_dir) for commit in commits: try: gbp.log.info("Trying to apply patches at '%s'" % commit) @@ -332,10 +332,6 @@ def import_spec_patches(repo, branch, options): else: raise GbpError, "Couldn't apply patches" - if tmpdir: - gbp.log.debug("Remove temporary patch safe '%s'" % tmpdir) - shutil.rmtree(tmpdir) - repo.set_branch(branch) return os.path.basename(spec.specfile) @@ -409,6 +405,7 @@ def main(argv): help="In case of import even import if the branch already exists") parser.add_config_file_option(option_name="vendor", action="store", dest="vendor") parser.add_config_file_option(option_name="color", dest="color", type='tristate') + parser.add_config_file_option(option_name="tmp-dir", dest="tmp_dir") parser.add_config_file_option(option_name="upstream-tag", dest="upstream_tag") parser.add_config_file_option(option_name="spec-file", dest="spec_file") parser.add_config_file_option(option_name="packaging-dir", dest="packaging_dir") @@ -456,6 +453,9 @@ def main(argv): os.chdir(repo.path) try: + # Create base temporary directory for this run + options.tmp_dir = tempfile.mkdtemp(dir=options.tmp_dir, + prefix='gbp-pq-rpm_') current = repo.get_branch() if action == "export": export_patches(repo, current, options) @@ -482,6 +482,8 @@ def main(argv): if len(err.__str__()): gbp.log.err(err) retval = 1 + finally: + shutil.rmtree(options.tmp_dir, ignore_errors=True) return retval -- cgit v1.2.3 From f9774ad026f3e68e6e4bb6f7644f28f633155aa0 Mon Sep 17 00:00:00 2001 From: Markus Lehtonen Date: Fri, 24 Aug 2012 16:32:44 +0300 Subject: buildpackage-rpm: support special tree-ish names in --git-upstream-tree Support special 'WC*' and 'INDEX' values for the --git-upstream-tree option. Signed-off-by: Markus Lehtonen --- gbp/scripts/buildpackage_rpm.py | 36 +++++++++++++++++++++++------------- 1 file changed, 23 insertions(+), 13 deletions(-) diff --git a/gbp/scripts/buildpackage_rpm.py b/gbp/scripts/buildpackage_rpm.py index 22f1eeaf..44e01efa 100755 --- a/gbp/scripts/buildpackage_rpm.py +++ b/gbp/scripts/buildpackage_rpm.py @@ -159,12 +159,33 @@ def get_upstream_tree(repo, spec, options): raise GbpError("%s is not a valid branch" % options.upstream_branch) upstream_tree = options.upstream_branch else: - upstream_tree = options.upstream_tree + upstream_tree = get_tree(repo, options.upstream_tree) if not repo.has_treeish(upstream_tree): raise GbpError('Invalid upstream treeish %s' % upstream_tree) return upstream_tree +def get_tree(repo, tree_name): + """ + Get/create a tree-ish to be used for exporting and diffing. Accepts + special keywords for git index and working copies. + """ + if tree_name == index_name: + # Write a tree of the index + tree = repo.write_tree() + elif tree_name in wc_names: + # Write a tree of the working copy + tree = write_wc(repo, + force=wc_names[tree_name]['force'], + untracked=wc_names[tree_name]['untracked']) + else: + tree = tree_name + if not repo.has_treeish(tree): + raise GbpError('Invalid treeish object %s' % tree) + + return tree + + def git_archive_build_orig(repo, spec, output_dir, options): """ Build orig tarball using git-archive @@ -432,18 +453,7 @@ def main(argv): raise GbpError, "Use --git-ignore-branch to ignore or --git-packaging-branch to set the branch name." # Determine tree-ish to be exported - if options.export == index_name: - # Write a tree of the index - tree = repo.write_tree() - elif options.export in wc_names: - # Write a tree of the working copy - tree = write_wc(repo, - force=wc_names[options.export]['force'], - untracked=wc_names[options.export]['untracked']) - else: - tree = options.export - if not repo.has_treeish(tree): - raise GbpError('Invalid treeish object %s' % tree) + tree = get_tree(repo, options.export) # Dump from git to a temporary directory: dump_dir = tempfile.mkdtemp(dir=options.tmp_dir, -- cgit v1.2.3 From d23bf900c9963d2d3fa6ddd7cc4ab5b1523d97c2 Mon Sep 17 00:00:00 2001 From: Markus Lehtonen Date: Fri, 14 Sep 2012 17:21:09 +0300 Subject: rpm: implement file path filters in patch export Implements a filter option allows one to filter out changes to certain files/paths in the patch-generation. A commit is totally ignored if all files would be filtered out. The path filter is given as a Python regexp. This option is useful for example in filtering out the changes to packaging files when maintaining packaging and sources in the same branch. Signed-off-by: Markus Lehtonen --- gbp/config.py | 4 ++++ gbp/scripts/buildpackage_rpm.py | 2 ++ gbp/scripts/pq_rpm.py | 10 +++++++--- 3 files changed, 13 insertions(+), 3 deletions(-) diff --git a/gbp/config.py b/gbp/config.py index 8c2921ad..2b2c8cb4 100644 --- a/gbp/config.py +++ b/gbp/config.py @@ -595,6 +595,7 @@ class GbpOptionParserRpm(GbpOptionParser): 'rpmbuild-srpmdir' : 'SRPMS', 'rpmbuild-buildrootdir' : 'BUILDROOT', 'patch-export' : 'False', + 'patch-export-ignore-path' : '', 'patch-export-compress' : '0', 'patch-export-squash-until' : '', 'pristine-tarball-name' : 'auto', @@ -618,6 +619,9 @@ class GbpOptionParserRpm(GbpOptionParser): "build with untracked files in the source tree, default is '%(ignore-untracked)s'", 'patch-export': "Create patches between upstream and export-treeish, default is '%(patch-export)s'", + 'patch-export-ignore-path': + ("Exclude changes to path(s) matching regex, default " + "is '%(patch-export-ignore-path)s'"), 'patch-export-compress': "Compress (auto-generated) patches larger than given number of bytes, 0 never compresses, default is '%(patch-export-compress)s'", 'patch-export-squash-until': diff --git a/gbp/scripts/buildpackage_rpm.py b/gbp/scripts/buildpackage_rpm.py index 44e01efa..aeb7759f 100755 --- a/gbp/scripts/buildpackage_rpm.py +++ b/gbp/scripts/buildpackage_rpm.py @@ -391,6 +391,8 @@ def parse_args(argv, prefix): export_group.add_option("--git-export-only", action="store_true", dest="export_only", default=False, help="only export packaging files, don't build") export_group.add_boolean_config_file_option("patch-export", dest="patch_export") + export_group.add_config_file_option("patch-export-ignore-path", + dest="patch_export_ignore_path") export_group.add_config_file_option("patch-export-compress", dest="patch_export_compress") export_group.add_config_file_option("patch-export-squash-until", dest="patch_export_squash_until") export_group.add_boolean_config_file_option(option_name="patch-numbers", dest="patch_numbers") diff --git a/gbp/scripts/pq_rpm.py b/gbp/scripts/pq_rpm.py index 9c1493bf..ee932540 100755 --- a/gbp/scripts/pq_rpm.py +++ b/gbp/scripts/pq_rpm.py @@ -101,7 +101,8 @@ def generate_patches(repo, start, squash, end, outdir, options): gbp.log.info("Squashing commits %s..%s into one monolithic diff" % (start_sha1, squash_sha1)) patch_fn = format_diff(outdir, squash[1], repo, - start_sha1, squash_sha1) + start_sha1, squash_sha1, + options.patch_export_ignore_path) if patch_fn: patches.append(patch_fn) start = squash_sha1 @@ -112,7 +113,8 @@ def generate_patches(repo, start, squash, end, outdir, options): cmds = parse_gbp_commands(info, 'gbp-rpm', ('ignore'), None)[0] if not 'ignore' in cmds: patch_fn = format_patch(outdir, repo, info, patches, - options.patch_numbers) + options.patch_numbers, + options.patch_export_ignore_path) if patch_fn: commands[os.path.basename(patch_fn)] = cmds else: @@ -121,7 +123,8 @@ def generate_patches(repo, start, squash, end, outdir, options): # Generate diff to the tree-ish object if end_commit != end: gbp.log.info("Generating diff file %s..%s" % (end_commit, end)) - patch_fn = format_diff(outdir, None, repo, end_commit, end) + patch_fn = format_diff(outdir, None, repo, end_commit, end, + options.patch_export_ignore_path) if patch_fn: patches.append(patch_fn) @@ -419,6 +422,7 @@ def main(argv): parser.add_config_file_option("patch-export-compress", dest="patch_export_compress") parser.add_config_file_option("patch-export-squash-until", dest="patch_export_squash_until") + parser.add_config_file_option("patch-export-ignore-path", dest="patch_export_ignore_path") (options, args) = parser.parse_args(argv) gbp.log.setup(options.color, options.verbose) -- cgit v1.2.3 From af861f138e3b57e0384d8eca54f7e5ef6a9d40c6 Mon Sep 17 00:00:00 2001 From: Markus Lehtonen Date: Fri, 21 Sep 2012 08:38:57 +0300 Subject: buildpackage-rpm: return 2 for patch-export or tarball generation errors Signed-off-by: Markus Lehtonen --- gbp/scripts/buildpackage_rpm.py | 43 +++++++++++++++++++++++++++-------------- 1 file changed, 29 insertions(+), 14 deletions(-) diff --git a/gbp/scripts/buildpackage_rpm.py b/gbp/scripts/buildpackage_rpm.py index aeb7759f..8d9a9b85 100755 --- a/gbp/scripts/buildpackage_rpm.py +++ b/gbp/scripts/buildpackage_rpm.py @@ -46,6 +46,10 @@ from gbp.pkg import (compressor_opts, compressor_aliases) from gbp.scripts.pq_rpm import update_patch_series +class GbpAutoGenerateError(GbpError): + pass + + def git_archive(repo, spec, output_dir, tmpdir_base, treeish, prefix, comp_level, with_submodules): "create a compressed orig tarball in output_dir using git_archive" @@ -201,26 +205,33 @@ def git_archive_build_orig(repo, spec, output_dir, options): @return: the tree we built the tarball from @rtype: C{str} """ - upstream_tree = get_upstream_tree(repo, spec, options) - gbp.log.info("%s does not exist, creating from '%s'" % (spec.orig_src['filename'], - upstream_tree)) - if spec.orig_src['compression']: - gbp.log.debug("Building upstream source archive with compression '%s -%s'" % - (spec.orig_src['compression'], options.comp_level)) - if not git_archive(repo, spec, output_dir, options.tmp_dir, upstream_tree, - options.orig_prefix, - options.comp_level, - options.with_submodules): - raise GbpError("Cannot create upstream tarball at '%s'" % output_dir) - return upstream_tree + try: + upstream_tree = get_upstream_tree(repo, spec, options) + gbp.log.info("%s does not exist, creating from '%s'" % \ + (spec.orig_src['filename'], upstream_tree)) + if spec.orig_src['compression']: + gbp.log.debug("Building upstream source archive with compression "\ + "'%s -%s'" % (spec.orig_src['compression'], + options.comp_level)) + if not git_archive(repo, spec, output_dir, options.tmp_dir, + upstream_tree, options.orig_prefix, + options.comp_level, options.with_submodules): + raise GbpError("Cannot create upstream tarball at '%s'" % \ + output_dir) + return upstream_tree + except (GitRepositoryError, GbpError) as err: + raise GbpAutoGenerateError(str(err)) def export_patches(repo, spec, export_treeish, options): """ Generate patches and update spec file """ - upstream_tree = get_upstream_tree(repo, spec, options) - update_patch_series(repo, spec, upstream_tree, export_treeish, options) + try: + upstream_tree = get_upstream_tree(repo, spec, options) + update_patch_series(repo, spec, upstream_tree, export_treeish, options) + except (GitRepositoryError, GbpError) as err: + raise GbpAutoGenerateError(str(err)) def is_native(repo, options): @@ -579,6 +590,10 @@ def main(argv): except GitRepositoryError as err: gbp.log.err("Git command failed: %s" % err) ret = 1 + except GbpAutoGenerateError as err: + if len(err.__str__()): + gbp.log.err(err) + retval = 2 except GbpError, err: if len(err.__str__()): gbp.log.err(err) -- cgit v1.2.3 From 65fb64f622eb0db17ed4da3464426d30b76e50e1 Mon Sep 17 00:00:00 2001 From: Markus Lehtonen Date: Tue, 30 Oct 2012 17:20:55 +0200 Subject: import-srpm: suppress some pylint warnings Signed-off-by: Markus Lehtonen --- gbp/scripts/import_srpm.py | 152 ++++++++++++++++++++++++++------------------- 1 file changed, 89 insertions(+), 63 deletions(-) diff --git a/gbp/scripts/import_srpm.py b/gbp/scripts/import_srpm.py index 82508922..7ba2290c 100755 --- a/gbp/scripts/import_srpm.py +++ b/gbp/scripts/import_srpm.py @@ -22,7 +22,6 @@ import sys import re import os import glob -import pipes import time import shutil import errno @@ -30,12 +29,13 @@ import urllib2 import gbp.tmpfile as tempfile import gbp.command_wrappers as gbpc -from gbp.rpm import (parse_srpm, SrcRpmFile, SpecFile, guess_spec, NoSpecError, - parse_spec, RpmUpstreamSource) +from gbp.rpm import (parse_srpm, guess_spec, NoSpecError, parse_spec, + RpmUpstreamSource) from gbp.rpm.policy import RpmPkgPolicy from gbp.rpm.git import (RpmGitRepository, GitRepositoryError) from gbp.git.modifier import GitModifier -from gbp.config import GbpOptionParserRpm, GbpOptionGroup, no_upstream_branch_msg +from gbp.config import (GbpOptionParserRpm, GbpOptionGroup, + no_upstream_branch_msg) from gbp.errors import GbpError import gbp.log from gbp.scripts.pq_rpm import safe_patches, rm_patch_files, get_packager @@ -55,6 +55,7 @@ and patch files from the packaging dir. """ class SkipImport(Exception): + """Nothing imported""" pass @@ -73,6 +74,7 @@ def download_file(target_dir, url): return local_fn def download_source(pkg, dirs): + """Download package from a remote location""" if re.match(r'[a-z]{1,5}://', pkg): mode = 'python urllib2' else: @@ -99,10 +101,10 @@ def committer_from_author(author, options): return committer -def move_tag_stamp(repo, format, tag_str_fields): +def move_tag_stamp(repo, tag_format, tag_str_fields): "Move tag out of the way appending the current timestamp" - old = repo.version_to_tag(format, tag_str_fields) - new = repo.version_to_tag('%s~%d' % (format, int(time.time())), + old = repo.version_to_tag(tag_format, tag_str_fields) + new = repo.version_to_tag('%s~%d' % (tag_format, int(time.time())), tag_str_fields) repo.move_tag(old, new) @@ -131,14 +133,15 @@ def import_spec_patches(repo, spec, dirs): packager = get_packager(spec) # Put patches in a safe place - safedir, queue = safe_patches(queue, tmpdir) + queue = safe_patches(queue, tmpdir)[1] for patch in queue: gbp.log.debug("Applying %s" % patch.path) try: apply_and_commit_patch(repo, patch, packager) except (GbpError, GitRepositoryError): repo.force_head(orig_head, hard=True) - raise GbpError, "Couldn't import patches, you need to apply and commit manually" + raise GbpError, "Couldn't import patches, you need to apply and "\ + "commit manually" # Remove patches from spec and packaging directory gbp.log.info("Removing imported patch files from spec and packaging dir") @@ -163,9 +166,12 @@ def force_to_branch_head(repo, branch): def parse_args(argv): + """Parse commandline arguments""" try: - parser = GbpOptionParserRpm(command=os.path.basename(argv[0]), prefix='', - usage='%prog [options] /path/to/package.src.rpm') + parser = GbpOptionParserRpm(command=os.path.basename(argv[0]), + prefix='', + usage='%prog [options] /path/to/package' + '.src.rpm') except ConfigParser.ParsingError, err: gbp.log.err(err) return None, None @@ -180,25 +186,29 @@ def parse_args(argv): for group in [import_group, branch_group, tag_group ]: parser.add_option_group(group) - parser.add_option("-v", "--verbose", action="store_true", dest="verbose", default=False, - help="verbose command execution") - parser.add_config_file_option(option_name="color", dest="color", type='tristate') + parser.add_option("-v", "--verbose", action="store_true", dest="verbose", + default=False, help="verbose command execution") + parser.add_config_file_option(option_name="color", dest="color", + type='tristate') parser.add_config_file_option(option_name="tmp-dir", dest="tmp_dir") - parser.add_option("--download", action="store_true", dest="download", default=False, - help="download source package") - parser.add_config_file_option(option_name="vendor", action="store", dest="vendor") + parser.add_option("--download", action="store_true", dest="download", + default=False, help="download source package") + parser.add_config_file_option(option_name="vendor", action="store", + dest="vendor") branch_group.add_config_file_option(option_name="packaging-branch", dest="packaging_branch") branch_group.add_config_file_option(option_name="upstream-branch", dest="upstream_branch") - branch_group.add_boolean_config_file_option(option_name="create-missing-branches", + branch_group.add_boolean_config_file_option( + option_name="create-missing-branches", dest="create_missing_branches") branch_group.add_option("--orphan-packaging", action="store_true", dest="orphan_packaging", default=False, help="The packaging branch doesn't base on upstream") branch_group.add_option("--native", action="store_true", dest="native", default=False, - help="This is a dist native package, no separate upstream branch") + help="This is a dist native package, no separate " + "upstream branch") tag_group.add_boolean_config_file_option(option_name="sign-tags", dest="sign_tags") @@ -216,7 +226,8 @@ def parse_args(argv): import_group.add_option("--allow-same-version", action="store_true", dest="allow_same_version", default=False, help="allow to import already imported version") - import_group.add_boolean_config_file_option(option_name="author-is-committer", + import_group.add_boolean_config_file_option( + option_name="author-is-committer", dest="author_is_committer") import_group.add_config_file_option(option_name="packaging-dir", dest="packaging_dir") @@ -228,11 +239,11 @@ def parse_args(argv): def main(argv): + """Main function of the git-import-srpm script""" dirs = dict(top=os.path.abspath(os.curdir)) ret = 0 skipped = False - parents = None options, args = parse_args(argv) @@ -265,7 +276,8 @@ def main(argv): dirs['src'] = os.path.abspath(srpm) spec = parse_spec(guess_spec(srpm, True)) else: - gbp.log.debug("Trying to import an srpm from '%s' with spec file '%s'" % (os.path.dirname(srpm), srpm)) + gbp.log.debug("Trying to import an srpm from '%s' with spec "\ + "file '%s'" % (os.path.dirname(srpm), srpm)) dirs['src'] = os.path.abspath(os.path.dirname(srpm)) spec = parse_spec(srpm) @@ -276,7 +288,8 @@ def main(argv): (clean, out) = repo.is_clean() if not clean and not is_empty: - gbp.log.err("Repository has uncommitted changes, commit these first: ") + gbp.log.err("Repository has uncommitted changes, commit " + "these first: ") raise GbpError, out except GitRepositoryError: @@ -293,15 +306,17 @@ def main(argv): prefix='origsrc_') dirs['packaging_base'] = tempfile.mkdtemp(dir=dirs['tmp_base'], prefix='packaging_') - dirs['packaging'] = os.path.join(dirs['packaging_base'], options.packaging_dir) + dirs['packaging'] = os.path.join(dirs['packaging_base'], + options.packaging_dir) try: os.mkdir(dirs['packaging']) - except OSError, (e, emsg): - if e != errno.EEXIST: + except OSError as err: + if err.errno != errno.EEXIST: raise # Need to copy files to the packaging directory given by caller - files = [os.path.basename(patch['filename']) for patch in spec.patches.itervalues()] + files = [os.path.basename(patch['filename']) \ + for patch in spec.patches.itervalues()] for num, src in spec.sources.iteritems(): if num != spec.orig_src_num: files.append(src['filename']) @@ -316,20 +331,23 @@ def main(argv): # Unpack orig source archive if spec.orig_src: - orig_tarball=os.path.join(dirs['src'], spec.orig_src['filename']) + orig_tarball = os.path.join(dirs['src'], spec.orig_src['filename']) upstream = RpmUpstreamSource(orig_tarball) upstream = upstream.unpack(dirs['origsrc'], options.filters) else: upstream = None - format = [(options.upstream_tag, "Upstream"), (options.packaging_tag, options.vendor)][options.native] + tag_format = [(options.upstream_tag, "Upstream"), + (options.packaging_tag, options.vendor)][options.native] tag_str_fields = dict(spec.version, vendor=options.vendor) - tag = repo.version_to_tag(format[0], tag_str_fields) + tag = repo.version_to_tag(tag_format[0], tag_str_fields) if repo.find_version(options.packaging_tag, tag_str_fields): - gbp.log.warn("Version %s already imported." % RpmPkgPolicy.compose_full_version(spec.version)) + gbp.log.warn("Version %s already imported." % + RpmPkgPolicy.compose_full_version(spec.version)) if options.allow_same_version: - gbp.log.info("Moving tag of version '%s' since import forced" % RpmPkgPolicy.compose_full_version(spec.version)) + gbp.log.info("Moving tag of version '%s' since import forced" % + RpmPkgPolicy.compose_full_version(spec.version)) move_tag_stamp(repo, options.packaging_tag, tag_str_fields) else: raise SkipImport @@ -339,39 +357,42 @@ def main(argv): # Determine author and committer info, currently same info is used # for both upstream sources and packaging files - author=None + author = None if spec.packager: - match = re.match('(?P.*[^ ])\s*<(?P\S*)>', spec.packager.strip()) + match = re.match('(?P.*[^ ])\s*<(?P\S*)>', + spec.packager.strip()) if match: - author=GitModifier(match.group('name'), match.group('email')) + author = GitModifier(match.group('name'), match.group('email')) if not author: - author=GitModifier() + author = GitModifier() gbp.log.debug("Couldn't determine packager info") committer = committer_from_author(author, options) # Import upstream sources if upstream: - upstream_commit = repo.find_version(format[0], tag_str_fields) + upstream_commit = repo.find_version(tag_format[0], tag_str_fields) if not upstream_commit: - gbp.log.info("Tag %s not found, importing %s upstream sources" % (tag, format[1])) + gbp.log.info("Tag %s not found, importing %s upstream sources" + % (tag, tag_format[1])) branch = [options.upstream_branch, options.packaging_branch][options.native] if not repo.has_branch(branch): if options.create_missing_branches: - gbp.log.info("Will create missing branch '%s'" % branch) + gbp.log.info("Will create missing branch '%s'" % + branch) else: - gbp.log.err(no_upstream_branch_msg % branch + - "\nAlso check the --create-missing-branches option.") + gbp.log.err(no_upstream_branch_msg % branch + "\n" + "Also check the --create-missing-branches option.") raise GbpError - msg = "%s version %s" % (format[1], spec.upstreamversion) + msg = "%s version %s" % (tag_format[1], spec.upstreamversion) upstream_commit = repo.commit_dir(upstream.unpacked, "Imported %s" % msg, - branch, - author=author, - committer=committer, - create_missing_branch=options.create_missing_branches) + branch, + author=author, + committer=committer, + create_missing_branch=options.create_missing_branches) repo.create_tag(name=tag, msg=msg, commit=upstream_commit, @@ -380,8 +401,9 @@ def main(argv): if not options.native: if options.pristine_tar: - repo.pristine_tar.commit(orig_tarball, 'refs/heads/%s' % options.upstream_branch) - parents = [ options.upstream_branch ] + repo.pristine_tar.commit(orig_tarball, + 'refs/heads/%s' % + options.upstream_branch) else: gbp.log.info("No orig source archive imported") @@ -394,16 +416,17 @@ def main(argv): if options.create_missing_branches: gbp.log.info("Will create missing branch '%s'" % branch) else: - gbp.log.err(no_packaging_branch_msg % branch + - "\nAlso check the --create-missing-branches option.") + gbp.log.err(no_packaging_branch_msg % branch + "\n" + "Also check the --create-missing-branches " + "option.") raise GbpError tag_str_fields = dict(spec.version, vendor=options.vendor) tag = repo.version_to_tag(options.packaging_tag, tag_str_fields) - msg = "%s release %s" % (options.vendor, RpmPkgPolicy.compose_full_version(spec.version)) + msg = "%s release %s" % (options.vendor, + RpmPkgPolicy.compose_full_version(spec.version)) if options.orphan_packaging or not upstream: - parents = [] commit = repo.commit_dir(dirs['packaging_base'], "Imported %s" % msg, branch, @@ -413,13 +436,14 @@ def main(argv): else: # Copy packaging files to the unpacked sources dir try: - pkgsubdir = os.path.join(upstream.unpacked, options.packaging_dir) + pkgsubdir = os.path.join(upstream.unpacked, + options.packaging_dir) os.mkdir(pkgsubdir) - except OSError, (e, emsg): - if e != errno.EEXIST: + except OSError as err: + if err.errno != errno.EEXIST: raise - for f in os.listdir(dirs['packaging']): - shutil.copy2(os.path.join(dirs['packaging'], f), + for fn in os.listdir(dirs['packaging']): + shutil.copy2(os.path.join(dirs['packaging'], fn), pkgsubdir) commit = repo.commit_dir(upstream.unpacked, "Imported %s" % msg, @@ -452,15 +476,15 @@ def main(argv): gbp.log.err("Interrupted. Aborting.") except gbpc.CommandExecFailed: ret = 1 - except GitRepositoryError, msg: - gbp.log.err("Git command failed: %s" % msg) + except GitRepositoryError as err: + gbp.log.err("Git command failed: %s" % err) ret = 1 - except GbpError, err: + except GbpError as err: if len(err.__str__()): gbp.log.err(err) ret = 1 - except NoSpecError, err: - gbp.log.err("Failed determine spec file (%s)" % err) + except NoSpecError as err: + gbp.log.err("Failed determine spec file: %s" % err) ret = 1 except SkipImport: skipped = True @@ -469,7 +493,9 @@ def main(argv): gbpc.RemoveTree(dirs['tmp_base'])() if not ret and not skipped: - gbp.log.info("Version '%s' imported under '%s'" % (RpmPkgPolicy.compose_full_version(spec.version), spec.name)) + gbp.log.info("Version '%s' imported under '%s'" % + (RpmPkgPolicy.compose_full_version(spec.version), + spec.name)) return ret if __name__ == '__main__': -- cgit v1.2.3 From 92c419368bf27aa790ef97477d26e5ff4d83fdfd Mon Sep 17 00:00:00 2001 From: Markus Lehtonen Date: Thu, 1 Nov 2012 16:36:16 +0200 Subject: rpm: circumvent a bug in python-rpm Which caused the packager tag to be incorrect in some cases. Rpm-python doesn't seem to reset spec.sourceHeader[rpm.RPMTAG_PACKAGER] if no packager tag is defined in the spec file. Thus, if we (in the same context) first parse spec A (which has a packager tag) and then spec B (which doesn't have a packager tag) python-rpm will give the packager of A for B as well. Signed-off-by: Markus Lehtonen --- gbp/rpm/__init__.py | 19 ++++++++++++++++--- 1 file changed, 16 insertions(+), 3 deletions(-) diff --git a/gbp/rpm/__init__.py b/gbp/rpm/__init__.py index 63cd7689..a74db9bc 100644 --- a/gbp/rpm/__init__.py +++ b/gbp/rpm/__init__.py @@ -120,6 +120,7 @@ class SrcRpmFile(object): class SpecFile(object): """Class for parsing/modifying spec files""" + tag_re = re.compile(r'^(?P[a-z][a-z0-9]*)\s*:\s*(?P\S(.*\S)?)\s*$', flags=re.I) source_re = re.compile(r'^Source(?P[0-9]+)?\s*:\s*(?P[^\s].*[^\s])\s*$', flags=re.I) patchtag_re = re.compile(r'^Patch(?P[0-9]+)?\s*:\s*(?P\S.*)$', flags=re.I) patchmacro_re = re.compile(r'^%patch(?P[0-9]+)?(\s+(?P.*))?$') @@ -163,6 +164,13 @@ class SpecFile(object): f.close() loc = self.parse_content() + + # Find 'Packager' tag. Needed to circumvent a bug in python-rpm where + # spec.sourceHeader[rpm.RPMTAG_PACKAGER] is not reset when a new spec + # file is parsed + if loc['packagertag'] is None: + self.packager = None + # Update sources info (basically possible macros expanded by spec.__init__() # And, double-check that we parsed spec content correctly for (name, num, typ) in self.specinfo.sources: @@ -254,6 +262,7 @@ class SpecFile(object): """ # Check location of "interesting" tags and macros ret = {'nametag': None, + 'packagertag': None, 'setupmacro': None, 'prepmacro': None} @@ -382,12 +391,16 @@ class SpecFile(object): continue # Only search for the last occurrence of the following - if re.match("^\s*Name:.*$", line, flags=re.I): - ret['setupmacro'] = i + m = self.tag_re.match(line) + if m: + if m.group('name').lower() == 'name': + ret['nametag'] = i + if m.group('name').lower() == 'packager': + ret['packagertag'] = i + continue if re.match("^%prep(\s.*)?$", line): ret['prepmacro'] = i continue - return ret -- cgit v1.2.3 From 89dd7594600b05c8457c65fa56e04cb985446ba3 Mon Sep 17 00:00:00 2001 From: Markus Lehtonen Date: Tue, 30 Oct 2012 11:48:24 +0200 Subject: tests: add unittests for gbp.rpm Signed-off-by: Markus Lehtonen --- tests/test_rpm.py | 201 +++++++++++++++++++++ tests/test_rpm_data/rpmbuild/SOURCES/bar.tar.gz | Bin 0 -> 177 bytes tests/test_rpm_data/rpmbuild/SOURCES/foo.txt | 3 + .../rpmbuild/SOURCES/gbp-test-1.0.tar.bz2 | Bin 0 -> 383 bytes .../rpmbuild/SOURCES/gbp-test-native-1.0.zip | Bin 0 -> 656 bytes .../rpmbuild/SOURCES/gbp-test2-3.0.tar.gz | Bin 0 -> 328 bytes tests/test_rpm_data/rpmbuild/SOURCES/my.patch | 9 + tests/test_rpm_data/rpmbuild/SOURCES/my2.patch | 7 + tests/test_rpm_data/rpmbuild/SOURCES/my3.patch | 7 + .../rpmbuild/SPECS/gbp-test-native.spec | 34 ++++ .../rpmbuild/SPECS/gbp-test-native2.spec | 35 ++++ tests/test_rpm_data/rpmbuild/SPECS/gbp-test.spec | 42 +++++ tests/test_rpm_data/rpmbuild/SPECS/gbp-test2.spec | 43 +++++ tests/test_rpm_data/specs/gbp-test-native.spec | 1 + tests/test_rpm_data/specs/gbp-test-native2.spec | 1 + tests/test_rpm_data/specs/gbp-test-quirks.spec | 18 ++ tests/test_rpm_data/specs/gbp-test-reference.spec | 43 +++++ tests/test_rpm_data/specs/gbp-test.spec | 1 + tests/test_rpm_data/specs/gbp-test2.spec | 1 + tests/test_rpm_data/srpms/gbp-test-1.0-1.src.rpm | Bin 0 -> 3427 bytes .../srpms/gbp-test-native-1.0-1.src.rpm | Bin 0 -> 2187 bytes .../srpms/gbp-test-native2-2.0-0.src.rpm | Bin 0 -> 2008 bytes tests/test_rpm_data/srpms/gbp-test2-3.0-0.src.rpm | Bin 0 -> 3507 bytes 23 files changed, 446 insertions(+) create mode 100644 tests/test_rpm.py create mode 100644 tests/test_rpm_data/rpmbuild/SOURCES/bar.tar.gz create mode 100644 tests/test_rpm_data/rpmbuild/SOURCES/foo.txt create mode 100644 tests/test_rpm_data/rpmbuild/SOURCES/gbp-test-1.0.tar.bz2 create mode 100644 tests/test_rpm_data/rpmbuild/SOURCES/gbp-test-native-1.0.zip create mode 100644 tests/test_rpm_data/rpmbuild/SOURCES/gbp-test2-3.0.tar.gz create mode 100644 tests/test_rpm_data/rpmbuild/SOURCES/my.patch create mode 100644 tests/test_rpm_data/rpmbuild/SOURCES/my2.patch create mode 100644 tests/test_rpm_data/rpmbuild/SOURCES/my3.patch create mode 100644 tests/test_rpm_data/rpmbuild/SPECS/gbp-test-native.spec create mode 100644 tests/test_rpm_data/rpmbuild/SPECS/gbp-test-native2.spec create mode 100644 tests/test_rpm_data/rpmbuild/SPECS/gbp-test.spec create mode 100644 tests/test_rpm_data/rpmbuild/SPECS/gbp-test2.spec create mode 120000 tests/test_rpm_data/specs/gbp-test-native.spec create mode 120000 tests/test_rpm_data/specs/gbp-test-native2.spec create mode 100644 tests/test_rpm_data/specs/gbp-test-quirks.spec create mode 100644 tests/test_rpm_data/specs/gbp-test-reference.spec create mode 120000 tests/test_rpm_data/specs/gbp-test.spec create mode 120000 tests/test_rpm_data/specs/gbp-test2.spec create mode 100644 tests/test_rpm_data/srpms/gbp-test-1.0-1.src.rpm create mode 100644 tests/test_rpm_data/srpms/gbp-test-native-1.0-1.src.rpm create mode 100644 tests/test_rpm_data/srpms/gbp-test-native2-2.0-0.src.rpm create mode 100644 tests/test_rpm_data/srpms/gbp-test2-3.0-0.src.rpm diff --git a/tests/test_rpm.py b/tests/test_rpm.py new file mode 100644 index 00000000..d57ea575 --- /dev/null +++ b/tests/test_rpm.py @@ -0,0 +1,201 @@ +# vim: set fileencoding=utf-8 : +# +# (C) 2012 Intel Corporation +# This program is free software; you can redistribute it and/or modify +# it under the terms of the GNU General Public License as published by +# the Free Software Foundation; either version 2 of the License, or +# (at your option) any later version. +# +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with this program; if not, write to the Free Software +# Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA +"""Test the classes under L{gbp.rpm}""" + +import filecmp +import os +import shutil +import tempfile +from nose.tools import assert_raises + +from gbp.errors import GbpError +from gbp.rpm import (SrcRpmFile, SpecFile, parse_srpm, parse_spec, guess_spec, + NoSpecError) + +DATA_DIR = os.path.abspath(os.path.splitext(__file__)[0] + '_data') +SRPM_DIR = os.path.join(DATA_DIR, 'srpms') +SPEC_DIR = os.path.join(DATA_DIR, 'specs') + +class TestSrcRpmFile(object): + """Test L{gbp.rpm.SrcRpmFile}""" + + def setup(self): + self.tmpdir = tempfile.mkdtemp(prefix='gbp_%s_' % __name__, dir='.') + + def teardown(self): + shutil.rmtree(self.tmpdir) + + def test_srpm(self): + """Test parsing of a source rpm""" + srpm = SrcRpmFile(os.path.join(SRPM_DIR, 'gbp-test-1.0-1.src.rpm')) + assert srpm.version == {'release': '1', 'upstreamversion': '1.0'} + assert srpm.name == 'gbp-test' + assert srpm.upstreamversion == '1.0' + assert srpm.packager is None + + def test_srpm_2(self): + """Test parsing of another source rpm""" + srpm = SrcRpmFile(os.path.join(SRPM_DIR, 'gbp-test2-3.0-0.src.rpm')) + assert srpm.version == {'release': '0', 'upstreamversion': '3.0', + 'epoch': '2'} + assert srpm.packager == 'Markus Lehtonen '\ + '' + + def test_unpack_srpm(self): + """Test unpacking of a source rpm""" + srpm = SrcRpmFile(os.path.join(SRPM_DIR, 'gbp-test-1.0-1.src.rpm')) + srpm.unpack(self.tmpdir) + for fn in ['gbp-test-1.0.tar.bz2', 'foo.txt', 'bar.tar.gz', 'my.patch', + 'my2.patch', 'my3.patch']: + assert os.path.exists(os.path.join(self.tmpdir, fn)), \ + "%s not found" % fn + + +class TestSpecFile(object): + """Test L{gbp.rpm.SpecFile}""" + + def setup(self): + self.tmpdir = tempfile.mkdtemp(prefix='gbp_%s_' % __name__, dir='.') + + def teardown(self): + shutil.rmtree(self.tmpdir) + + def test_spec(self): + """Test parsing of a valid spec file""" + spec_filepath = os.path.join(SPEC_DIR, 'gbp-test.spec') + spec = SpecFile(spec_filepath) + + # Test basic properties + assert spec.specfile == spec_filepath + assert spec.specdir == os.path.dirname(spec_filepath) + assert spec.specpath == spec_filepath + + assert spec.name == 'gbp-test' + assert spec.packager is None + + assert spec.upstreamversion == '1.0' + assert spec.release == '1' + assert spec.epoch is None + assert spec.version == {'release': '1', 'upstreamversion': '1.0'} + + orig = spec.orig_src + assert orig['filename'] == 'gbp-test-1.0.tar.bz2' + assert orig['filename_base'] == 'gbp-test-1.0' + assert orig['archive_fmt'] == 'tar' + assert orig['compression'] == 'bzip2' + assert orig['prefix'] == 'gbp-test/' + + def test_spec_2(self): + """Test parsing of another valid spec file""" + spec_filepath = os.path.join(SPEC_DIR, 'gbp-test2.spec') + spec = SpecFile(spec_filepath) + + # Test basic properties + assert spec.name == 'gbp-test2' + assert spec.packager == 'Markus Lehtonen ' \ + '' + + assert spec.epoch == '2' + assert spec.version == {'release': '0', 'upstreamversion': '3.0', + 'epoch': '2'} + + orig = spec.orig_src + assert orig['filename'] == 'gbp-test2-3.0.tar.gz' + assert orig['full_path'] == 'ftp://ftp.host.com/gbp-test2-3.0.tar.gz' + assert orig['archive_fmt'] == 'tar' + assert orig['compression'] == 'gzip' + assert orig['prefix'] == '' + + def test_spec_3(self): + """Test parsing of yet another valid spec file""" + spec_filepath = os.path.join(SPEC_DIR, 'gbp-test-native.spec') + spec = SpecFile(spec_filepath) + + # Test basic properties + assert spec.name == 'gbp-test-native' + orig = spec.orig_src + assert orig['filename'] == 'gbp-test-native-1.0.zip' + assert orig['archive_fmt'] == 'zip' + assert orig['compression'] == None + assert orig['prefix'] == 'gbp-test-native-1.0/' + + def test_spec_4(self): + """Test parsing of spec without orig tarball""" + spec_filepath = os.path.join(SPEC_DIR, 'gbp-test-native2.spec') + spec = SpecFile(spec_filepath) + + # Test basic properties + assert spec.name == 'gbp-test-native2' + assert spec.orig_src is None + + def test_update_spec(self): + """Test spec autoupdate functionality""" + # Create temporary spec file + tmp_spec = os.path.join(self.tmpdir, 'gbp-test.spec') + shutil.copy2(os.path.join(SPEC_DIR, 'gbp-test.spec'), tmp_spec) + + reference_spec = os.path.join(SPEC_DIR, 'gbp-test-reference.spec') + spec = SpecFile(tmp_spec) + spec.update_patches(['new.patch']) + spec.write_spec_file() + + assert filecmp.cmp(tmp_spec, reference_spec) is True + + def test_quirks(self): + """Test spec that is broken/has anomalities""" + spec_filepath = os.path.join(SPEC_DIR, 'gbp-test-quirks.spec') + spec = SpecFile(spec_filepath) + + # Check that we quess orig source and prefix correctly + assert spec.orig_src['prefix'] == 'foobar/' + + +class TestUtilityFunctions(object): + """Test utility functions of L{gbp.rpm}""" + + def test_parse_spec(self): + """Test parse_spec() function""" + parse_spec(os.path.join(SPEC_DIR, 'gbp-test.spec')) + with assert_raises(NoSpecError): + parse_spec(os.path.join(DATA_DIR, 'notexists.spec')) + with assert_raises(GbpError): + parse_spec(os.path.join(SRPM_DIR, 'gbp-test-1.0-1.src.rpm')) + + def test_parse_srpm(self): + """Test parse_srpm() function""" + parse_srpm(os.path.join(SRPM_DIR, 'gbp-test-1.0-1.src.rpm')) + with assert_raises(GbpError): + parse_srpm(os.path.join(DATA_DIR, 'notexists.src.rpm')) + with assert_raises(GbpError): + parse_srpm(os.path.join(SPEC_DIR, 'gbp-test.spec')) + + def test_guess_spec(self): + """Test guess_spec() function""" + # Spec not found + with assert_raises(NoSpecError): + guess_spec(DATA_DIR, recursive=False) + # Multiple spec files + with assert_raises(NoSpecError): + guess_spec(DATA_DIR, recursive=True) + with assert_raises(NoSpecError): + guess_spec(SPEC_DIR, recursive=False) + # Spec found + spec_fn = guess_spec(SPEC_DIR, recursive=False, + preferred_name = 'gbp-test2.spec') + assert spec_fn == os.path.join(SPEC_DIR, 'gbp-test2.spec') + +# vim:et:ts=4:sw=4:et:sts=4:ai:set list listchars=tab\:»·,trail\:·: diff --git a/tests/test_rpm_data/rpmbuild/SOURCES/bar.tar.gz b/tests/test_rpm_data/rpmbuild/SOURCES/bar.tar.gz new file mode 100644 index 00000000..f5dae803 Binary files /dev/null and b/tests/test_rpm_data/rpmbuild/SOURCES/bar.tar.gz differ diff --git a/tests/test_rpm_data/rpmbuild/SOURCES/foo.txt b/tests/test_rpm_data/rpmbuild/SOURCES/foo.txt new file mode 100644 index 00000000..25ed442f --- /dev/null +++ b/tests/test_rpm_data/rpmbuild/SOURCES/foo.txt @@ -0,0 +1,3 @@ +FOO: + +file for testing rpm support of git-buildpackage. diff --git a/tests/test_rpm_data/rpmbuild/SOURCES/gbp-test-1.0.tar.bz2 b/tests/test_rpm_data/rpmbuild/SOURCES/gbp-test-1.0.tar.bz2 new file mode 100644 index 00000000..7d0759fe Binary files /dev/null and b/tests/test_rpm_data/rpmbuild/SOURCES/gbp-test-1.0.tar.bz2 differ diff --git a/tests/test_rpm_data/rpmbuild/SOURCES/gbp-test-native-1.0.zip b/tests/test_rpm_data/rpmbuild/SOURCES/gbp-test-native-1.0.zip new file mode 100644 index 00000000..22a273d1 Binary files /dev/null and b/tests/test_rpm_data/rpmbuild/SOURCES/gbp-test-native-1.0.zip differ diff --git a/tests/test_rpm_data/rpmbuild/SOURCES/gbp-test2-3.0.tar.gz b/tests/test_rpm_data/rpmbuild/SOURCES/gbp-test2-3.0.tar.gz new file mode 100644 index 00000000..7b3eaf3c Binary files /dev/null and b/tests/test_rpm_data/rpmbuild/SOURCES/gbp-test2-3.0.tar.gz differ diff --git a/tests/test_rpm_data/rpmbuild/SOURCES/my.patch b/tests/test_rpm_data/rpmbuild/SOURCES/my.patch new file mode 100644 index 00000000..50870df2 --- /dev/null +++ b/tests/test_rpm_data/rpmbuild/SOURCES/my.patch @@ -0,0 +1,9 @@ +diff --git a/dummy.sh b/dummy.sh +index 8c33db6..6f04268 100755 +--- dummy.sh ++++ dummy.sh +@@ -1,3 +1,3 @@ + #!/bin/sh + +-echo "Hello world" ++echo "Hello GBP" diff --git a/tests/test_rpm_data/rpmbuild/SOURCES/my2.patch b/tests/test_rpm_data/rpmbuild/SOURCES/my2.patch new file mode 100644 index 00000000..ad5ca2d2 --- /dev/null +++ b/tests/test_rpm_data/rpmbuild/SOURCES/my2.patch @@ -0,0 +1,7 @@ +diff --git a/mydir/myfile.txt b/mydir/myfile.txt +new file mode 100644 +index 0000000..2cdad29 +--- /dev/null ++++ b/mydir/myfile.txt +@@ -0,0 +1 @@ ++Dummy diff --git a/tests/test_rpm_data/rpmbuild/SOURCES/my3.patch b/tests/test_rpm_data/rpmbuild/SOURCES/my3.patch new file mode 100644 index 00000000..9fee859d --- /dev/null +++ b/tests/test_rpm_data/rpmbuild/SOURCES/my3.patch @@ -0,0 +1,7 @@ +diff --git a/README b/README +index a1311cb..a59f1b9 100644 +--- a/README ++++ b/README +@@ -1 +1 @@ +-Just for testing git-buildpackage. ++Just for testing GBP. diff --git a/tests/test_rpm_data/rpmbuild/SPECS/gbp-test-native.spec b/tests/test_rpm_data/rpmbuild/SPECS/gbp-test-native.spec new file mode 100644 index 00000000..38b07e48 --- /dev/null +++ b/tests/test_rpm_data/rpmbuild/SPECS/gbp-test-native.spec @@ -0,0 +1,34 @@ +Name: gbp-test-native +Summary: Test package for git-buildpackage +Version: 1.0 +Release: 1 +Group: Development/Libraries +License: GPLv2 +Source1: %{name}-%{version}.zip +BuildRequires: unzip + +%description +Package for testing the RPM functionality of git-buildpackage. +Mimics a "native" package + + +%prep +unzip %{SOURCE1} +%setup -T -D + + +%build +make + + +%install +rm -rf %{buildroot} +mkdir -p %{buildroot}/%{_datadir}/%{name} +cp -R * %{buildroot}/%{_datadir}/%{name} + + + +%files +%defattr(-,root,root,-) +%dir %{_datadir}/%{name} +%{_datadir}/%{name} diff --git a/tests/test_rpm_data/rpmbuild/SPECS/gbp-test-native2.spec b/tests/test_rpm_data/rpmbuild/SPECS/gbp-test-native2.spec new file mode 100644 index 00000000..34fd33dc --- /dev/null +++ b/tests/test_rpm_data/rpmbuild/SPECS/gbp-test-native2.spec @@ -0,0 +1,35 @@ +Name: gbp-test-native2 +Summary: Test package for git-buildpackage +Version: 2.0 +Release: 0 +Group: Development/Libraries +License: GPLv2 +Source: foo.txt +BuildRequires: unzip + +%description +Package for testing the RPM functionality of git-buildpackage. +Mimics a "native" package that doesn't have any source tarball. + + +%prep +# Just create build dir +%setup -T -c +cp %{SOURCE0} . + + +%build +# Nothing to do + + +%install +rm -rf %{buildroot} +mkdir -p %{buildroot}/%{_datadir}/%{name} +cp -R * %{buildroot}/%{_datadir}/%{name} + + + +%files +%defattr(-,root,root,-) +%dir %{_datadir}/%{name} +%{_datadir}/%{name} diff --git a/tests/test_rpm_data/rpmbuild/SPECS/gbp-test.spec b/tests/test_rpm_data/rpmbuild/SPECS/gbp-test.spec new file mode 100644 index 00000000..8a07d662 --- /dev/null +++ b/tests/test_rpm_data/rpmbuild/SPECS/gbp-test.spec @@ -0,0 +1,42 @@ +Name: gbp-test +Summary: Test package for git-buildpackage +Version: 1.0 +Release: 1 +Group: Development/Libraries +License: GPLv2 +Source: %{name}-%{version}.tar.bz2 +Source1: foo.txt +Source20: bar.tar.gz +# GbpIgnorePatch: 0 +Patch0: my.patch +Patch10: my2.patch +Patch20: my3.patch + + +%description +Package for testing the RPM functionality of git-buildpackage. + + +%prep +%setup -n %{name} -a 20 + +%patch0 +%patch10 -p1 + + +%build +make + + +%install +rm -rf %{buildroot} +mkdir -p %{buildroot}/%{_datadir}/%{name} +cp -R * %{buildroot}/%{_datadir}/%{name} +install %{SOURCE0} %{buildroot}/%{_datadir}/%{name} + + + +%files +%defattr(-,root,root,-) +%dir %{_datadir}/%{name} +%{_datadir}/%{name} diff --git a/tests/test_rpm_data/rpmbuild/SPECS/gbp-test2.spec b/tests/test_rpm_data/rpmbuild/SPECS/gbp-test2.spec new file mode 100644 index 00000000..932b8e8f --- /dev/null +++ b/tests/test_rpm_data/rpmbuild/SPECS/gbp-test2.spec @@ -0,0 +1,43 @@ +Name: gbp-test2 +Summary: Test package 2 for git-buildpackage +Epoch: 2 +Version: 3.0 +Release: 0 +Group: Development/Libraries +License: GPLv2 +Source10: ftp://ftp.host.com/%{name}-%{version}.tar.gz +Source: foo.txt +Source20: bar.tar.gz +# GbpIgnorePatch: 0 +Patch: my.patch +Patch10: my2.patch +Patch20: my3.patch +Packager: Markus Lehtonen + +%description +Package for testing the RPM functionality of git-buildpackage. + + +%prep +%setup -T -n %{name}-%{version} -c -a 10 + +%patch +%patch -P 10 -p1 + + +%build +make + + +%install +rm -rf %{buildroot} +mkdir -p %{buildroot}/%{_datadir}/%{name} +cp -R * %{buildroot}/%{_datadir}/%{name} +install %{SOURCE0} %{buildroot}/%{_datadir}/%{name} + + + +%files +%defattr(-,root,root,-) +%dir %{_datadir}/%{name} +%{_datadir}/%{name} diff --git a/tests/test_rpm_data/specs/gbp-test-native.spec b/tests/test_rpm_data/specs/gbp-test-native.spec new file mode 120000 index 00000000..60de36f2 --- /dev/null +++ b/tests/test_rpm_data/specs/gbp-test-native.spec @@ -0,0 +1 @@ +../rpmbuild/SPECS/gbp-test-native.spec \ No newline at end of file diff --git a/tests/test_rpm_data/specs/gbp-test-native2.spec b/tests/test_rpm_data/specs/gbp-test-native2.spec new file mode 120000 index 00000000..ad13ad6a --- /dev/null +++ b/tests/test_rpm_data/specs/gbp-test-native2.spec @@ -0,0 +1 @@ +../rpmbuild/SPECS/gbp-test-native2.spec \ No newline at end of file diff --git a/tests/test_rpm_data/specs/gbp-test-quirks.spec b/tests/test_rpm_data/specs/gbp-test-quirks.spec new file mode 100644 index 00000000..64db07fb --- /dev/null +++ b/tests/test_rpm_data/specs/gbp-test-quirks.spec @@ -0,0 +1,18 @@ +# +# Spec for testing some quirks of spec parsing +# + +Name: pkg_name +Summary: Spec for testing some quirks of spec parsing +Version: 0.1 +Release: 1.2 +License: GPLv2 +Source1: foobar.tar.gz + +%description +Spec for testing some quirks of spec parsing. No intended for building an RPM. + +%prep +# We don't have Source0 so rpmbuild would fail, but gbp shouldn't crash +%setup -q + diff --git a/tests/test_rpm_data/specs/gbp-test-reference.spec b/tests/test_rpm_data/specs/gbp-test-reference.spec new file mode 100644 index 00000000..884a64ca --- /dev/null +++ b/tests/test_rpm_data/specs/gbp-test-reference.spec @@ -0,0 +1,43 @@ +Name: gbp-test +Summary: Test package for git-buildpackage +Version: 1.0 +Release: 1 +Group: Development/Libraries +License: GPLv2 +Source: %{name}-%{version}.tar.bz2 +Source1: foo.txt +Source20: bar.tar.gz +# GbpIgnorePatch: 0 +Patch0: my.patch +# Patches auto-generated by git-buildpackage: +Patch1: new.patch + + +%description +Package for testing the RPM functionality of git-buildpackage. + + +%prep +%setup -n %{name} -a 20 + +%patch0 +# new.patch +%patch1 -p1 + + +%build +make + + +%install +rm -rf %{buildroot} +mkdir -p %{buildroot}/%{_datadir}/%{name} +cp -R * %{buildroot}/%{_datadir}/%{name} +install %{SOURCE0} %{buildroot}/%{_datadir}/%{name} + + + +%files +%defattr(-,root,root,-) +%dir %{_datadir}/%{name} +%{_datadir}/%{name} diff --git a/tests/test_rpm_data/specs/gbp-test.spec b/tests/test_rpm_data/specs/gbp-test.spec new file mode 120000 index 00000000..30ae2845 --- /dev/null +++ b/tests/test_rpm_data/specs/gbp-test.spec @@ -0,0 +1 @@ +../rpmbuild/SPECS/gbp-test.spec \ No newline at end of file diff --git a/tests/test_rpm_data/specs/gbp-test2.spec b/tests/test_rpm_data/specs/gbp-test2.spec new file mode 120000 index 00000000..af4080cb --- /dev/null +++ b/tests/test_rpm_data/specs/gbp-test2.spec @@ -0,0 +1 @@ +../rpmbuild/SPECS/gbp-test2.spec \ No newline at end of file diff --git a/tests/test_rpm_data/srpms/gbp-test-1.0-1.src.rpm b/tests/test_rpm_data/srpms/gbp-test-1.0-1.src.rpm new file mode 100644 index 00000000..74afbd6c Binary files /dev/null and b/tests/test_rpm_data/srpms/gbp-test-1.0-1.src.rpm differ diff --git a/tests/test_rpm_data/srpms/gbp-test-native-1.0-1.src.rpm b/tests/test_rpm_data/srpms/gbp-test-native-1.0-1.src.rpm new file mode 100644 index 00000000..1002aaea Binary files /dev/null and b/tests/test_rpm_data/srpms/gbp-test-native-1.0-1.src.rpm differ diff --git a/tests/test_rpm_data/srpms/gbp-test-native2-2.0-0.src.rpm b/tests/test_rpm_data/srpms/gbp-test-native2-2.0-0.src.rpm new file mode 100644 index 00000000..880b3100 Binary files /dev/null and b/tests/test_rpm_data/srpms/gbp-test-native2-2.0-0.src.rpm differ diff --git a/tests/test_rpm_data/srpms/gbp-test2-3.0-0.src.rpm b/tests/test_rpm_data/srpms/gbp-test2-3.0-0.src.rpm new file mode 100644 index 00000000..1cf12c7a Binary files /dev/null and b/tests/test_rpm_data/srpms/gbp-test2-3.0-0.src.rpm differ -- cgit v1.2.3 From 16ad55ed4633c1542d41194368705f9f2573a61e Mon Sep 17 00:00:00 2001 From: Markus Lehtonen Date: Wed, 22 Feb 2012 12:48:57 +0200 Subject: docs: add initial RPM documentation Signed-off-by: Markus Lehtonen --- docs/Makefile | 6 +- docs/chapters/building-rpm.sgml | 132 +++++++++++++++++++++++++++++++++ docs/chapters/chapters-rpm.ent | 3 + docs/chapters/development-rpm.sgml | 146 +++++++++++++++++++++++++++++++++++++ docs/chapters/intro-rpm.sgml | 104 ++++++++++++++++++++++++++ docs/common.ent | 6 ++ docs/main.sgml | 27 +++++++ docs/manual-rpm.sgml | 18 +++++ docs/manual.sgml | 12 --- 9 files changed, 440 insertions(+), 14 deletions(-) create mode 100644 docs/chapters/building-rpm.sgml create mode 100644 docs/chapters/chapters-rpm.ent create mode 100644 docs/chapters/development-rpm.sgml create mode 100644 docs/chapters/intro-rpm.sgml create mode 100644 docs/main.sgml create mode 100644 docs/manual-rpm.sgml diff --git a/docs/Makefile b/docs/Makefile index f1dac586..5cd83a05 100644 --- a/docs/Makefile +++ b/docs/Makefile @@ -31,9 +31,11 @@ GTK_DOC_CATALOG_FILE ?= /usr/share/sgml/gtk-doc/gtk-doc.cat all: $(MANUAL) $(MANPAGES) -$(MANUAL): manual.sgml chapters/*.sgml manpages/*.sgml +$(MANUAL): main.sgml manual.sgml manual-rpm.sgml chapters/*.sgml manpages/*.sgml ifeq ($(HAVE_SGML2X),1) docbook-2-html -s local $< + rm -rf $(MANUAL) + mv main-html $(MANUAL) else docbook2html -d local-nosgml2x.dsl -c $(GTK_DOC_CATALOG_FILE) -o $(MANUAL) $< endif @@ -55,7 +57,7 @@ manpage.refs: $(BUILD_MAN_XREF_PAGES) git-pbuilder.1: ../bin/git-pbuilder pod2man $< $@ -manual.sgml: $(VERSION_ENT) +main.sgml: $(VERSION_ENT) $(VERSION_ENT): $(GBP_VERSION) echo '' > $(VERSION_ENT) diff --git a/docs/chapters/building-rpm.sgml b/docs/chapters/building-rpm.sgml new file mode 100644 index 00000000..866cd3f9 --- /dev/null +++ b/docs/chapters/building-rpm.sgml @@ -0,0 +1,132 @@ + + Building RPM packages from the &git; repository + + The &gbp-buildpackage-rpm; tool is used for building. + The tool creates the source tarball and copies it and the packaging files + to a separate build directory and builds the package there. By default, + &rpmbuild; is used as the builder command. You can define a different + builder command with the option. + + + + To build the (non-native) package when on packaging-branch, + using pristine-tar to create upstream tarball: + + $ &gbp-buildpackage-rpm; --pristine-tar + + During development, if you have unclean git tree (untracked files and/or + uncommitted changes) you may use: + + $ &gbp-buildpackage-rpm; --git-ignore-untracked + + or: + + $ &gbp-buildpackage-rpm; --git-ignore-new + + + + + Git-buildpackage-rpm always builds in a separate build directory + (./rpmbuild/ by default). You may change that and also + build a different revision that your current branch HEAD. The revision can + be any git "commit-ish", i.e. branch or tag name or a commit sha1. + Git-buildpackage also supports some "special revisions", i.e. + INDEX refer to the current index, + WC or WC.IGNORED refer to the current working + copy with all (even untracked and ignored) files, + WC.TRACKED refers to the current working copy of the files + tracked by git, + WC.UNTRACKED refers to the current working copy of all files + excluding ignore files. + Some examples: + + $ &gbp-buildpackage-rpm; --git-export-dir=/home/user/rpmbuild + $ &gbp-buildpackage-rpm; --git-export-dir=/home/user/rpmbuild --git-export=v1.2.3 + $ &gbp-buildpackage-rpm; --git-export=WC.UNTRACKED + $ &gbp-buildpackage-rpm; --git-export=INDEX + $ &gbp-buildpackage-rpm; --git-export=feature/cool-new-thing + $ &gbp-buildpackage-rpm; --git-export=8d55173610f + + + + + Automatic patch generation + + When developing a non-native package with packaging and sources + in the same branch + (see ) + you usually want for &gbp-buildpackage-rpm; to automatically generate + patches. In this mode, &gbp-buildpackage-rpm; generates the upstream + tarball and copies packaging files to the build dir. After that it + generates patches from commits between + + + + Working with separate development branch + + When developing a non-native package with packaging data and source + code in separate branches + (see ) + you use the &gbp-pq-rpm; tool to handle the patches. You work on the + source code on the development branch and then export + the patches to the packaging branch when building the RPM package. + + + + Create a development (or patch-queue) branch + by applying the patches in current packaging branch on top of the + upstream version. This will create a new branch, e.g. + development/master assuming your current branch is + master. Simply: + + $ &gbp-pq-rpm; import + + Now you can develop normally on the development branch (add, remove, + rebase, amend commits). Just make sure you stay based on the correct + upstream version, if doing git-rebase. After you're happy with your + changes and you're ready to build an RPM package, you have to + export the patches with &gbp-pq-rpm;. This will change + back to you packaging branch, generate patches from commits between + between upstream and the HEAD of the development branch + and update the spec file with the new patches: + + $ &gbp-pq-rpm; export + + Commit the changes to packaging branch, and build. For example: + + $ git add *patch *spec + $ git commit -a + $ &gbp-buildpackage-rpm; + + Of course you can build even without committing by using the + + + + Moving to a new upstream version is basically simple. Assuming you + have imported/pulled new upstream version to your git-tree, just: + + $ git checkout master + # Edit the spec file and change the 'Version:' tag to new upstream version + $ vim *spec + $ git commit *spec + $ &gbp-pq-rpm; rebase + + However, if the patches do not apply cleanly, you have to manually + apply and resolve the patches. + + + + diff --git a/docs/chapters/chapters-rpm.ent b/docs/chapters/chapters-rpm.ent new file mode 100644 index 00000000..165e0c02 --- /dev/null +++ b/docs/chapters/chapters-rpm.ent @@ -0,0 +1,3 @@ + + + diff --git a/docs/chapters/development-rpm.sgml b/docs/chapters/development-rpm.sgml new file mode 100644 index 00000000..1ae51251 --- /dev/null +++ b/docs/chapters/development-rpm.sgml @@ -0,0 +1,146 @@ + + Development flow + + + Development models + + The &gbp-buildpackage-rpm; toolset basically supports three different + models of package maintenance. + + + + Native package + + This means that you are the upstream, there is no separate + upstream with which you have to sync. Basically, only + + + + + Upstream package, alternative 1: packaging and sources in + the same branch + + This represents somewhat Debian-style package maintenance. + All changes (packaging and source code) are done to the same + branch, i.e., the + + + + Upstream package, alternative 2: packaging and sources in + separate branches + + In this model packaging files (spec and patches) are held in + + + + + + Starting from scratch with a non-native package + + In this case, you most probably want to package software not yet + found in your distro. First, create an empty repository: + + $ mkdir mypackage + $ cd mypackage + $ git init + + Then, import the upstream sources, create the packaging/development + branch and add the rpm packaging files. You have two choices: + + + + + packaging files and development sources in the same branch + + $ git-import-orig-rpm ../mypackage.tar.gz + # Optionally (recommended): add gbp.conf + $ vim .gbp.conf && git add .gbp.conf && git commit -m"Add gbp.conf" + # Add packaging files to source tree under subdir 'packaging' + $ mkdir packaging && cd packaging + $ vim mypackage.spec + $ git add . + $ git commit -m"Add packaging files" + + + + + development sources and packaging files in separate branches + + $ git-import-orig-rpm --no-merge ../mypackage.tar.gz + # Optionally (recommended): add gbp.conf + $ vim .gbp.conf && git add .gbp.conf && git commit -m"Add gbp.conf" + # Add packaging files (to root of master branch) + $ vim mypackage.spec + $ git add . + $ git commit -m"Add packaging files" + + + + + + + Converting an existing git repository of a non-native package</> + <para> + In this case, you already have a git repository containing the + upstream source, but it was created neither with &gbp-clone; nor + &gbp-import-srpm;. + You need to have a separate branch for upstream sources. + If you already have that, you can simply rename that branch to the + default upstream-branch: + <screen> + $ <command>git branch</> -m my-old-upstream-branch upstream + </screen> + OR just add the name of your upstream branch to gbp.conf. + Then, you just create a packaging/development branch(es) with git and + add packaging files to the packaging branch. If you want to maintain + sources and packaging in the same branch + (<xref linkend="gbp.rpm.development.models.nonnative1">) + do something like: + <screen> + $ <command>git checkout</> -b master upstream + # Optionally (recommended): add gbp.conf + $ <command>vim</> .gbp.conf && <command>git add</> .gbp.conf && <command>git commit</> -m"Add gbp.conf" + # Add packaging files to source tree, add and commit the packaging files + # ... + </screen> + If you want to maintain development sources and packaging in separate + branches + (<xref linkend="gbp.rpm.development.models.nonnative2">): + <screen> + $ <command>git checkout</> --orphan master + $ <command>rm</> .git/index + $ <command>git commit</> --allow-empty -m"Create packaging branch" + # Optionally (recommended): add gbp.conf + $ <command>vim</> .gbp.conf && <command>git add</> .gbp.conf && <command>git commit</> -m"Add gbp.conf" + # Next, add and commit the packaging files (.spec etc) + $ <command>vim</> mypackage.spec && <command>git add</> mypackage.spec && <command>git commit</> -m"Add packaging files" + # Now, you can create the development branch (and import possible patches) + $ &gbp-pq-rpm; import + </screen> + </para> + </sect1> +</chapter> + diff --git a/docs/chapters/intro-rpm.sgml b/docs/chapters/intro-rpm.sgml new file mode 100644 index 00000000..8cc04719 --- /dev/null +++ b/docs/chapters/intro-rpm.sgml @@ -0,0 +1,104 @@ +<chapter id="gbp.rpm.intro"> + <title>Introduction + + + Git-buildpackage is a Debian + toolset for maintaining and building packages in/from git repositories. + The still experimental RPM variants of the tool, extend the support + from Debian-only to building and maintaining RPM packages, too. + The documentation of git-buildpackage-rpm here reflects the the + Debian git-buildpackage documentation + + + + + The RPM versions of the tools can in their current state + do basically all the same tasks as the Debian versions, except for changelog generation. + However, the philosophy is somewhat different in some parts. The RPM tools + read the .spec file instead of changelog in determining packaging + information (version number, name etc). Another clear difference is + that &gbp-buildpackage-rpm; will always build in a separate build + directory whereas &gbp-buildpackage; (the Debian) tool builds in the + git working dir, by default. + Third, conceptual, difference (for non-native packages) is that you may + have packaging files in an orphan branch, without development sources: + i.e. you develop code in 'patch-queue' branch that doesn't contain any + packaging files, and, do 'pq-rpm export' to 'packaging' branch that only + contains packaging files (.spec file, patches etc.) but no sources. + The Debian/RPM tool equivalence is: + + &gbp-buildpackage; -> RPM: &gbp-buildpackage-rpm; + &gbp-import-dsc; -> RPM: &gbp-import-srpm; + &gbp-import-orig; -> RPM: &gbp-import-orig-rpm; + &gbp-pq; -> RPM: &gbp-pq-rpm; + &gbp-clone; -> RPM: &gbp-clone; (the same tool) + &gbp-pull; -> RPM: &gbp-pull; (the same tool) + &gbp-dch; -> RPM: not available + &gbp-import-dscs; -> RPM: not available + + + + + RPM Repository Layout + + + The required repository layout is similar to Debian: basically the only + requirement is that non-native packages must have clean upstream sources + in a separate branch. Other branches are: + + + + + + + + + + + + + + + + + + + RPM Workflow + + + The basic workflow is very similar to Debian: + + + + + Import a package via &gbp-import-srpm; OR clone from the + distro git with &gbp-clone; if the package is already maintained with + &gbp-buildpackage-rpm;. + + + + Develop, test, commit changes. + Once satisfied you can build the final package with + &gbp-buildpackage-rpm; (optionally with --git-tag to create a tag in + git) and push it to git server. + + + + + diff --git a/docs/common.ent b/docs/common.ent index 005d6746..69a703f6 100644 --- a/docs/common.ent +++ b/docs/common.ent @@ -24,6 +24,12 @@ debuild"> gbp.conf"> + gbp buildpackage-rpm"> + gbp import-orig-rpm"> + gbp import-srpm"> + gbp pq-rpm"> + rpmbuild"> + Debian"> Git"> dch"> diff --git a/docs/main.sgml b/docs/main.sgml new file mode 100644 index 00000000..bd1d97d7 --- /dev/null +++ b/docs/main.sgml @@ -0,0 +1,27 @@ + + %COMMON; + + %VERSION; + + %MANPAGES; + + %CHAPTERS; + + %CHAPTERS.RPM; + + + +]> + + + + Building Packages with git-buildpackage suite + Version: &gbp-version; + + + &book.debian; + &book.rpm; + + diff --git a/docs/manual-rpm.sgml b/docs/manual-rpm.sgml new file mode 100644 index 00000000..2e587306 --- /dev/null +++ b/docs/manual-rpm.sgml @@ -0,0 +1,18 @@ + + + Building RPM Packages with git-buildpackage-rpm + Markus Lehtonen +
markus.lehtonen@linux.intel.com
+ Version: &gbp-version; +
+ + &ch.intro-rpm; + &ch.development-rpm; + &ch.building-rpm; + + + Copyright + &gbp.copyright; + +
+ diff --git a/docs/manual.sgml b/docs/manual.sgml index af5e12fd..c79af07b 100644 --- a/docs/manual.sgml +++ b/docs/manual.sgml @@ -1,15 +1,3 @@ - - %COMMON; - - %VERSION; - - %MANPAGES; - - %CHAPTERS; - -]> - Building Debian Packages with git-buildpackage -- cgit v1.2.3 From a770a734019865ab8687b73cf9bfd33d9b283c20 Mon Sep 17 00:00:00 2001 From: Markus Lehtonen Date: Fri, 9 Nov 2012 08:40:36 +0200 Subject: import-srpm: return 2 if patch import fails A new return value for failed patch import. If the patch import fails the repo is left in clean and buildable state so one might want to distinguish that from other failures. Signed-off-by: Markus Lehtonen --- gbp/scripts/import_srpm.py | 15 +++++++++++---- 1 file changed, 11 insertions(+), 4 deletions(-) diff --git a/gbp/scripts/import_srpm.py b/gbp/scripts/import_srpm.py index 7ba2290c..a9828991 100755 --- a/gbp/scripts/import_srpm.py +++ b/gbp/scripts/import_srpm.py @@ -58,6 +58,10 @@ class SkipImport(Exception): """Nothing imported""" pass +class PatchImportError(Exception): + """Patch import failed""" + pass + def download_file(target_dir, url): """Download a remote file""" @@ -140,8 +144,8 @@ def import_spec_patches(repo, spec, dirs): apply_and_commit_patch(repo, patch, packager) except (GbpError, GitRepositoryError): repo.force_head(orig_head, hard=True) - raise GbpError, "Couldn't import patches, you need to apply and "\ - "commit manually" + raise PatchImportError("Patch(es) didn't apply, you need apply " + "and commit manually") # Remove patches from spec and packaging directory gbp.log.info("Removing imported patch files from spec and packaging dir") @@ -151,8 +155,8 @@ def import_spec_patches(repo, spec, dirs): spec.write_spec_file() except GbpError: repo.force_head('HEAD', hard=True) - raise GbpError("Unable to update spec file, you need to edit and " - "commit it manually") + raise PatchImportError("Unable to update spec file, you need to edit" + "and commit it manually") repo.commit_all(msg=PATCH_AUTODELETE_COMMIT_MSG % os.path.basename(spec.specfile)) @@ -486,6 +490,9 @@ def main(argv): except NoSpecError as err: gbp.log.err("Failed determine spec file: %s" % err) ret = 1 + except PatchImportError as err: + gbp.log.err(err) + ret = 2 except SkipImport: skipped = True finally: -- cgit v1.2.3 From aaa24a74dc929d58b0cd6c430ff90e65ee660559 Mon Sep 17 00:00:00 2001 From: Markus Lehtonen Date: Thu, 8 Nov 2012 12:27:43 +0200 Subject: buildpackage-rpm: fail patch-export if local patches found Make patch export fail if local patch files (not marked for manual maintenance) exist. Signed-off-by: Markus Lehtonen --- gbp/scripts/buildpackage_rpm.py | 9 +++++++++ 1 file changed, 9 insertions(+) diff --git a/gbp/scripts/buildpackage_rpm.py b/gbp/scripts/buildpackage_rpm.py index 8d9a9b85..0add68e0 100755 --- a/gbp/scripts/buildpackage_rpm.py +++ b/gbp/scripts/buildpackage_rpm.py @@ -227,6 +227,15 @@ def export_patches(repo, spec, export_treeish, options): """ Generate patches and update spec file """ + # Fail if we have local patch files not marked for manual maintenance. + # Ignore patches listed in spec but not found in packaging dir + for patch in spec.patchseries(): + if os.path.exists(patch.path): + raise GbpAutoGenerateError( + 'Patches not marked for manual maintenance found, ' + 'refusing to overwrite! Fix by applying them to packaging ' + 'branch and removing the files.') + try: upstream_tree = get_upstream_tree(repo, spec, options) update_patch_series(repo, spec, upstream_tree, export_treeish, options) -- cgit v1.2.3 From 271440fc415b588514144891eb6124a5dc2391e9 Mon Sep 17 00:00:00 2001 From: Markus Lehtonen Date: Fri, 13 Jan 2012 15:01:28 +0200 Subject: TODO: add rpm todo Signed-off-by: Markus Lehtonen --- TODO | 17 +++++++++++++++++ 1 file changed, 17 insertions(+) diff --git a/TODO b/TODO index baaa055c..295398a5 100644 --- a/TODO +++ b/TODO @@ -1 +1,18 @@ See https://honk.sigxcpu.org/piki/projects/git-buildpackage/ + +RPM-related things: +- unit tests: + - add unit tests for the rpm command line tools +- manpages for rpm tools + - git-buildpackage-rpm + - git-import-srpm + - git-import-orig-rpm + - gbp-pq-rpm +- better html-documentation for rpm support +- write a tool for automatic changelog creation/updating +- bare-repo support + - buildpackage-rpm + - import-orig + - import-srpm + - pristine-tar + - gbp-pq (very limited, if any) -- cgit v1.2.3 From 631a215989261b1fed801c626d0a7ddd3dec8cc0 Mon Sep 17 00:00:00 2001 From: Markus Lehtonen Date: Mon, 10 Sep 2012 13:05:07 +0300 Subject: debian packaging: HACK: disable test in Debian builds Signed-off-by: Markus Lehtonen --- debian/control | 7 ------- debian/rules | 6 +++++- 2 files changed, 5 insertions(+), 8 deletions(-) diff --git a/debian/control b/debian/control index a706b8ef..2e71b798 100644 --- a/debian/control +++ b/debian/control @@ -11,19 +11,12 @@ Build-Depends: perl, pychecker, python (>> 2.6.6-3~), - python-coverage, python-epydoc, python-nose, python-nosexcover, python-pkg-resources, python-setuptools, sgml2x, -# For the testsuite - bzip2, - devscripts (>= 2.13.8~), - git (>= 1:1.7.9.1-1~), - pristine-tar, - unzip, # For rpm (epydoc) python-rpm Standards-Version: 3.9.4 diff --git a/debian/rules b/debian/rules index 3584c7a4..a81edb1f 100755 --- a/debian/rules +++ b/debian/rules @@ -1,5 +1,9 @@ #!/usr/bin/make -f - + +# HACK: disable checks, i.e. unit tests +DEB_BUILD_OPTIONS += nocheck +export WITHOUT_NOSETESTS := 1 + EXAMPLE_SCRIPTS=\ gbp-add-patch \ gbp-cowbuilder-sid \ -- cgit v1.2.3 From 555fcb2b7c2fe8d681bac1b8ef8d53bb66909eda Mon Sep 17 00:00:00 2001 From: Markus Lehtonen Date: Tue, 13 Nov 2012 11:50:34 +0200 Subject: rpm: configuration option for setting the output color scheme Adds the new 'color-scheme' option to the rpm tools. Signed-off-by: Markus Lehtonen --- gbp/scripts/buildpackage_rpm.py | 4 +++- gbp/scripts/import_orig_rpm.py | 4 +++- gbp/scripts/import_srpm.py | 4 +++- gbp/scripts/pq_rpm.py | 4 +++- 4 files changed, 12 insertions(+), 4 deletions(-) diff --git a/gbp/scripts/buildpackage_rpm.py b/gbp/scripts/buildpackage_rpm.py index 0add68e0..f1b31f77 100755 --- a/gbp/scripts/buildpackage_rpm.py +++ b/gbp/scripts/buildpackage_rpm.py @@ -348,6 +348,8 @@ def parse_args(argv, prefix): help="verbose command execution") parser.add_config_file_option(option_name="tmp-dir", dest="tmp_dir") parser.add_config_file_option(option_name="color", dest="color", type='tristate') + parser.add_config_file_option(option_name="color-scheme", + dest="color_scheme") parser.add_config_file_option(option_name="notify", dest="notify", type='tristate') parser.add_config_file_option(option_name="vendor", action="store", dest="vendor") tag_group.add_option("--git-tag", action="store_true", dest="tag", default=False, @@ -420,7 +422,7 @@ def parse_args(argv, prefix): options.patch_export_compress = rpm.string_to_int(options.patch_export_compress) - gbp.log.setup(options.color, options.verbose) + gbp.log.setup(options.color, options.verbose, options.color_scheme) if options.retag: if not options.tag and not options.tag_only: gbp.log.err("'--%sretag' needs either '--%stag' or '--%stag-only'" % (prefix, prefix, prefix)) diff --git a/gbp/scripts/import_orig_rpm.py b/gbp/scripts/import_orig_rpm.py index d1ec57af..62edd145 100755 --- a/gbp/scripts/import_orig_rpm.py +++ b/gbp/scripts/import_orig_rpm.py @@ -185,10 +185,12 @@ def parse_args(argv): parser.add_option("-v", "--verbose", action="store_true", dest="verbose", default=False, help="verbose command execution") parser.add_config_file_option(option_name="color", dest="color", type='tristate') + parser.add_config_file_option(option_name="color-scheme", + dest="color_scheme") parser.add_config_file_option(option_name="tmp-dir", dest="tmp_dir") (options, args) = parser.parse_args(argv[1:]) - gbp.log.setup(options.color, options.verbose) + gbp.log.setup(options.color, options.verbose, options.color_scheme) return options, args diff --git a/gbp/scripts/import_srpm.py b/gbp/scripts/import_srpm.py index a9828991..574d01e8 100755 --- a/gbp/scripts/import_srpm.py +++ b/gbp/scripts/import_srpm.py @@ -194,6 +194,8 @@ def parse_args(argv): default=False, help="verbose command execution") parser.add_config_file_option(option_name="color", dest="color", type='tristate') + parser.add_config_file_option(option_name="color-scheme", + dest="color_scheme") parser.add_config_file_option(option_name="tmp-dir", dest="tmp_dir") parser.add_option("--download", action="store_true", dest="download", default=False, help="download source package") @@ -238,7 +240,7 @@ def parse_args(argv): import_group.add_boolean_config_file_option(option_name="patch-import", dest="patch_import") (options, args) = parser.parse_args(argv[1:]) - gbp.log.setup(options.color, options.verbose) + gbp.log.setup(options.color, options.verbose, options.color_scheme) return options, args diff --git a/gbp/scripts/pq_rpm.py b/gbp/scripts/pq_rpm.py index ee932540..ba34054c 100755 --- a/gbp/scripts/pq_rpm.py +++ b/gbp/scripts/pq_rpm.py @@ -408,6 +408,8 @@ def main(argv): help="In case of import even import if the branch already exists") parser.add_config_file_option(option_name="vendor", action="store", dest="vendor") parser.add_config_file_option(option_name="color", dest="color", type='tristate') + parser.add_config_file_option(option_name="color-scheme", + dest="color_scheme") parser.add_config_file_option(option_name="tmp-dir", dest="tmp_dir") parser.add_config_file_option(option_name="upstream-tag", dest="upstream_tag") parser.add_config_file_option(option_name="spec-file", dest="spec_file") @@ -425,7 +427,7 @@ def main(argv): parser.add_config_file_option("patch-export-ignore-path", dest="patch_export_ignore_path") (options, args) = parser.parse_args(argv) - gbp.log.setup(options.color, options.verbose) + gbp.log.setup(options.color, options.verbose, options.color_scheme) options.patch_export_compress = string_to_int(options.patch_export_compress) if len(args) < 2: -- cgit v1.2.3 From 739f34d73333c11750356bd53e8d9180e550a877 Mon Sep 17 00:00:00 2001 From: Markus Lehtonen Date: Mon, 19 Nov 2012 13:56:31 +0200 Subject: rpm: circumvent an rpm-python macro expansion problem Parse the spec file two times to circumvent a rpm-python problem which causes macros not to be correctly expanded if used before their definition. Signed-off-by: Markus Lehtonen --- gbp/rpm/__init__.py | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/gbp/rpm/__init__.py b/gbp/rpm/__init__.py index a74db9bc..44be82db 100644 --- a/gbp/rpm/__init__.py +++ b/gbp/rpm/__init__.py @@ -139,6 +139,10 @@ class SpecFile(object): if line.split(":")[0].strip() not in skip_tags) filtered.flush() try: + # Parse two times to circumvent a rpm-python + # problem where macros are not expanded if used + # before their definition + rpm.spec(temp.name) self.specinfo = rpm.spec(temp.name) except ValueError as err: raise GbpError("RPM error while parsing spec: %s" % err) -- cgit v1.2.3 From b3a0bb1a99899d40089988b3b7adeda5d9577a20 Mon Sep 17 00:00:00 2001 From: Markus Lehtonen Date: Wed, 21 Nov 2012 09:45:46 +0200 Subject: rpm: implement a simple doubly linked list This class is intended to store the spec file content, needed for modifying the spec file. Signed-off-by: Markus Lehtonen --- gbp/rpm/linkedlist.py | 211 ++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 211 insertions(+) create mode 100644 gbp/rpm/linkedlist.py diff --git a/gbp/rpm/linkedlist.py b/gbp/rpm/linkedlist.py new file mode 100644 index 00000000..f1321776 --- /dev/null +++ b/gbp/rpm/linkedlist.py @@ -0,0 +1,211 @@ +# vim: set fileencoding=utf-8 : +# +# (C) 2012 Intel Corporation +# This program is free software; you can redistribute it and/or modify +# it under the terms of the GNU General Public License as published by +# the Free Software Foundation; either version 2 of the License, or +# (at your option) any later version. +# +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with this program; if not, write to the Free Software +# Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA +"""Simple implementation of a doubly linked list""" + +import collections + +import gbp.log + + +class LinkedListNode(object): + """Node of the linked list""" + + def __init__(self, data="", prev_node=None, next_node=None): + self.prev = prev_node + self.next = next_node + self._data = data + + def __str__(self): + return str(self.data) + + @property + def data(self): + """Get data stored into node""" + if self._data is None: + gbp.log.err("BUG: referencing a deleted node!") + return("") + return self._data + + def set_data(self, data): + """ + Set data stored into node + + >>> node = LinkedListNode('foo') + >>> node.data + 'foo' + >>> node.set_data('bar') + >>> node.data + 'bar' + >>> node.set_data(None) + >>> node.data + '' + """ + if data is None: + gbp.log.err("BUG: trying to store 'None', not allowed") + data = "" + self._data = data + + + def delete(self): + """Delete node""" + if self.prev: + self.prev.next = self.next + if self.next: + self.next.prev = self.prev + self._data = None + + +class LinkedListIterator(collections.Iterator): + """Iterator for the linked list""" + + def __init__(self, obj): + self._next = obj.first + + def next(self): + ret = self._next + if ret: + self._next = ret.next + else: + raise StopIteration + return ret + + +class LinkedList(collections.Iterable): + """Doubly linked list""" + + def __init__(self): + self._first = None + self._last = None + + def __iter__(self): + return LinkedListIterator(self) + + def __len__(self): + for num, data in enumerate(self): + pass + return num + 1 + + @property + def first(self): + """Get the first node of the list""" + return self._first + + def prepend(self, data): + """ + Insert to the beginning of list + + >>> list = LinkedList() + >>> [str(data) for data in list] + [] + >>> node = list.prepend("foo") + >>> len(list) + 1 + >>> node = list.prepend("bar") + >>> [str(data) for data in list] + ['bar', 'foo'] + """ + if self._first is None: + new = self._first = self._last = LinkedListNode(data) + else: + new = self.insert_before(self._first, data) + return new + + def append(self, data): + """ + Insert to the end of list + + >>> list = LinkedList() + >>> node = list.append('foo') + >>> len(list) + 1 + >>> node = list.append('bar') + >>> [str(data) for data in list] + ['foo', 'bar'] + """ + if self._last is None: + return self.prepend(data) + else: + return self.insert_after(self._last, data) + + def insert_before(self, node, data=""): + """ + Insert before a node + + >>> list = LinkedList() + >>> node1 = list.append('foo') + >>> node2 = list.insert_before(node1, 'bar') + >>> node3 = list.insert_before(node1, 'baz') + >>> [str(data) for data in list] + ['bar', 'baz', 'foo'] + """ + new = LinkedListNode(data, prev_node=node.prev, next_node=node) + if node.prev: + node.prev.next = new + else: + self._first = new + node.prev = new + return new + + def insert_after(self, node, data=""): + """ + Insert after a node + + >>> list = LinkedList() + >>> node1 = list.prepend('foo') + >>> node2 = list.insert_after(node1, 'bar') + >>> node3 = list.insert_after(node1, 'baz') + >>> [str(data) for data in list] + ['foo', 'baz', 'bar'] + """ + new = LinkedListNode(data, prev_node=node, next_node=node.next) + if node.next: + node.next.prev = new + else: + self._last = new + node.next = new + return new + + def delete(self, node): + """ + Delete node + + >>> list = LinkedList() + >>> node1 = list.prepend('foo') + >>> node2 = list.insert_after(node1, 'bar') + >>> node3 = list.insert_before(node2, 'baz') + >>> [str(data) for data in list] + ['foo', 'baz', 'bar'] + >>> list.delete(node3) + >>> [str(data) for data in list] + ['foo', 'bar'] + >>> print "%s" % node3 + + >>> list.delete(node1) + >>> [str(data) for data in list] + ['bar'] + >>> list.delete(node2) + >>> [str(data) for data in list] + [] + """ + if node is self._first: + self._first = self._first.next + if node is self._last: + self._last = self._last.prev + node.delete() + + +# vim:et:ts=4:sw=4:et:sts=4:ai:set list listchars=tab\:»·,trail\:·: -- cgit v1.2.3 From 2609a912e14a0cdb3e1e698c3d50d35fa199b2fc Mon Sep 17 00:00:00 2001 From: Markus Lehtonen Date: Fri, 16 Nov 2012 11:12:40 +0200 Subject: rpm: use linked list to store spec content Tries to make spec parsing and updating more robust by using a linked list to represent spec content, instead of using normal list and trying to track line numbers. Deleting and adding lines should be safer, now. Also, consolidates the regexp usage of spec parsing a bit. Signed-off-by: Markus Lehtonen --- gbp/rpm/__init__.py | 396 +++++++++++++++++++++++++--------------------------- 1 file changed, 187 insertions(+), 209 deletions(-) diff --git a/gbp/rpm/__init__.py b/gbp/rpm/__init__.py index 44be82db..ad6c96de 100644 --- a/gbp/rpm/__init__.py +++ b/gbp/rpm/__init__.py @@ -33,6 +33,7 @@ from gbp.patch_series import (PatchSeries, Patch) import gbp.log from gbp.pkg import (UpstreamSource, compressor_opts, parse_archive_filename) from gbp.rpm.policy import RpmPkgPolicy +from gbp.rpm.linkedlist import LinkedList try: # Try to load special RPM lib to be used for GBP (only) @@ -120,13 +121,12 @@ class SrcRpmFile(object): class SpecFile(object): """Class for parsing/modifying spec files""" - tag_re = re.compile(r'^(?P[a-z][a-z0-9]*)\s*:\s*(?P\S(.*\S)?)\s*$', flags=re.I) - source_re = re.compile(r'^Source(?P[0-9]+)?\s*:\s*(?P[^\s].*[^\s])\s*$', flags=re.I) - patchtag_re = re.compile(r'^Patch(?P[0-9]+)?\s*:\s*(?P\S.*)$', flags=re.I) - patchmacro_re = re.compile(r'^%patch(?P[0-9]+)?(\s+(?P.*))?$') - setupmacro_re = re.compile(r'^%setup(\s+(?P.*))?$') - marker_re = re.compile(r'^#\s+(?P>>|<<)\s+(?Pgbp-[^\s]+)\s*(?P.*)$') - gbptag_re = re.compile(r'^\s*#\s*gbp(?P[a-z]+)\s*:\s*(?P\S.*)\s*$', flags=re.I) + tag_re = re.compile(r'^(?P[a-z]+)(?P[0-9]+)?\s*:\s*' + '(?P\S(.*\S)?)\s*$', flags=re.I) + macro_re = re.compile(r'^%(?P[a-z]+)(?P[0-9]+)?' + '(\s+(?P.*))?$') + gbptag_re = re.compile(r'^\s*#\s*gbp(?P[a-z-]+)' + '(\s*:\s*(?P\S.*))?$', flags=re.I) def __init__(self, specfile, skip_tags=("ExcludeArch", "ExcludeOS", "ExclusiveArch", "ExclusiveOS", @@ -163,16 +163,17 @@ class SpecFile(object): self.sources = {} # Load and parse extra info from spec file - f = file(self.specfile) - self.content = f.readlines() - f.close() + self.content = LinkedList() + with open(self.specfile) as spec_file: + for line in spec_file.readlines(): + self.content.append(line) loc = self.parse_content() # Find 'Packager' tag. Needed to circumvent a bug in python-rpm where # spec.sourceHeader[rpm.RPMTAG_PACKAGER] is not reset when a new spec # file is parsed - if loc['packagertag'] is None: + if 'packagertag' not in loc: self.packager = None # Update sources info (basically possible macros expanded by spec.__init__() @@ -252,39 +253,34 @@ class SpecFile(object): """ Write, possibly updated, spec to disk """ - tmpffd, tmpfpath = tempfile.mkstemp(suffix='.spec', dir='.') - tmpf = os.fdopen(tmpffd, 'w') - tmpf.writelines(self.content) - tmpf.close() - - shutil.move(tmpfpath, self.specfile) + with open(self.specfile, 'w') as spec_file: + for line in self.content: + spec_file.write(str(line)) def parse_content(self): """ Go through spec file content line-by-line and (re-)parse info from it """ - # Check location of "interesting" tags and macros - ret = {'nametag': None, - 'packagertag': None, - 'setupmacro': None, - 'prepmacro': None} - + # Location of "interesting" tags and macros + ret = {} # First, we parse the spec for special git-buildpackage tags, only ignorepatch = [] - for line in self.content: + for i, lineobj in enumerate(self.content): + line = str(lineobj) m = self.gbptag_re.match(line) if m: - if m.group('tagname').lower() == 'ignorepatch': - dataitems = m.group('data').strip().split() + if m.group('name').lower() == 'ignorepatch': + dataitems = m.group('args').strip().split() ignorepatch = sorted([int(num) for num in dataitems]) else: - gbp.log.info("Found unrecognized Gbp tag on line %s: '%'" % (i, line)) + gbp.log.info("Found unrecognized Gbp tag on line %s: " + "'%s'" % (i, line)) # Remove all autoupdate patches to be sure we're in sync - for n in self.patches.keys(): - if not n in ignorepatch: - del self.patches[n] + for patch in self.patches.keys(): + if not patch in ignorepatch: + self.patches.pop(patch) # Parser for patch macros patchparser = OptionParser() @@ -304,211 +300,193 @@ class SpecFile(object): setupparser.add_option("-a", dest="unpack_after") setupparser.add_option("-q", dest="quiet", action="store_true") - numlines = len(self.content) - for i in range(numlines): - line = self.content[i] + for linenum, lineobj in enumerate(self.content): + line = str(lineobj) - # Find special git-buildpackage tags - m = self.gbptag_re.match(line) - if m: - if m.group('tagname').lower() == 'ignorepatch': - dataitems = m.group('data').strip().split() - ignorepatch = set([int(num) for num in dataitems]) - else: - gbp.log.info("Found unrecognized Gbp tag on line %s: '%'" % (i, line)) - - # Find 'Source' tags - m = self.source_re.match(line) - if m: - if m.group('srcnum'): - srcnum = int(m.group('srcnum')) - else: - srcnum = 0 - if srcnum in self.sources: - self.sources[srcnum]['tag_linenum'] = i - else: - self.sources[srcnum] = {'full_path': m.group('name'), - 'filename': os.path.basename(m.group('name')), - 'tag_linenum': i, - 'prefix': None, - 'setup_options': None, } - continue - - # Find 'Patch' tags - m = self.patchtag_re.match(line) + # Parse tags + m = self.tag_re.match(line) if m: - if m.group('patchnum'): - patchnum = int(m.group('patchnum')) + tagname = m.group('name').lower() + if m.group('num'): + tagnum = int(m.group('num')) else: - patchnum = 0 - if patchnum in self.patches: - # For non-autoupdate patches, we only update the line number - if patchnum in ignorepatch: - self.patches[patchnum]['tag_linenum'] = i + tagnum = 0 + # 'Source:' tags + if tagname == 'source': + if tagnum in self.sources: + self.sources[tagnum]['tag_line'] = lineobj else: - gbp.log.err("Patch%s found multiple times, aborting as gbp spec/patch autoupdate likely fails" % patchnum) - raise GbpError, "RPM error while parsing spec, duplicate patches found" - else: - new_patch = {'name': m.group('name').strip(), - 'filename': m.group('name'), - 'apply': False, - 'strip': '0', - 'macro_linenum': None, - 'autoupdate': not patchnum in ignorepatch, - 'tag_linenum': i} - self.patches[patchnum] = new_patch - continue - - # Find patch macros - m = self.patchmacro_re.match(line) - if m: - (options, args) = patchparser.parse_args(m.group('args').split()) - if m.group('patchnum'): - patchnum = int(m.group('patchnum')) - elif options.patchnum: - patchnum = int(options.patchnum) - else: - patchnum = 0 - - if options.strip: - self.patches[patchnum]['strip'] = options.strip - self.patches[patchnum]['macro_linenum'] = i - self.patches[patchnum]['apply'] = True - continue - - # Find setup macros - m = self.setupmacro_re.match(line) - if m: - (options, args) = setupparser.parse_args(m.group('args').split()) - srcnum = None - if options.no_unpack_default: - if options.unpack_before: - srcnum = int(options.unpack_before) - elif options.unpack_after: - srcnum = int(options.unpack_after) - else: - srcnum = 0 - if srcnum != None and srcnum in self.sources: - self.sources[srcnum]['setup_options'] = options - # Save the occurrence of last setup macro - ret['setupmacro'] = i + self.sources[tagnum] = { + 'full_path': m.group('name'), + 'filename': os.path.basename(m.group('name')), + 'tag_line': line, + 'prefix': None, + 'setup_options': None, } + ret['lastsourcetag'] = lineobj + # 'Patch:' tags + elif tagname == 'patch': + if tagnum in self.patches: + # For non-autoupdate patches we only update the lineobj + if tagnum in ignorepatch: + self.patches[tagnum]['tag_line'] = lineobj + else: + gbp.log.err("Patch%s found multiple times, " + "aborting as gbp spec/patch " + "autoupdate likely fails" % tagnum) + raise GbpError("RPM error while parsing spec, " + "duplicate patches found") + else: + new_patch = {'name': m.group('name').strip(), + 'filename': m.group('name'), + 'apply': False, + 'strip': '0', + 'macro_line': None, + 'autoupdate': not tagnum in ignorepatch, + 'tag_line': lineobj} + self.patches[tagnum] = new_patch + ret['lastpatchtag'] = lineobj + # 'Name:' and 'Packager:' tags + elif tagname == 'name': + ret['nametag'] = lineobj + elif tagname == 'packager': + ret['packagertag'] = lineobj continue - # Only search for the last occurrence of the following - m = self.tag_re.match(line) + # Parse special macros + m = self.macro_re.match(line) if m: - if m.group('name').lower() == 'name': - ret['nametag'] = i - if m.group('name').lower() == 'packager': - ret['packagertag'] = i - continue - if re.match("^%prep(\s.*)?$", line): - ret['prepmacro'] = i - continue + # '%patch' macro + if m.group('name') == 'patch': + (opts, args) = patchparser.parse_args(m.group('args').split()) + if m.group('num'): + patchnum = int(m.group('num')) + elif opts.patchnum: + patchnum = int(opts.patchnum) + else: + patchnum = 0 + + if opts.strip: + self.patches[patchnum]['strip'] = opts.strip + self.patches[patchnum]['macro_line'] = lineobj + self.patches[patchnum]['apply'] = True + ret['lastpatchmacro'] = lineobj + + # '%setup' macros + if m.group('name') == 'setup': + (opts, args) = setupparser.parse_args(m.group('args').split()) + srcnum = None + if opts.no_unpack_default: + if opts.unpack_before: + srcnum = int(opts.unpack_before) + elif opts.unpack_after: + srcnum = int(opts.unpack_after) + else: + srcnum = 0 + if srcnum != None and srcnum in self.sources: + self.sources[srcnum]['setup_options'] = opts + # Save the occurrence of last setup macro + ret['setupmacro'] = lineobj + + # '%prep' macro + if m.group('name') == 'prep': + ret['prepmacro'] = lineobj return ret - def update_patches(self, patchfilenames): """ Update spec with new patch tags and patch macros. """ loc = self.parse_content() - # Remove updatable patches and check the max patchnumber of non-autoupdate patches - start_patch_tag_num = 0 - last_ignored_patch_tag_line = 0 - last_ignored_patch_macro_line = 0 - rm_tag_lines = [] - rm_macro_lines = [] - for n in self.patches.keys(): - p = self.patches[n] - if p['autoupdate']: - rm_tag_lines.append(p['tag_linenum']) - # Remove a preceding comment line if it seems to originate from GBP - if re.match("^\s*#.*patch.*auto-generated", self.content[p['tag_linenum']-1], flags=re.I): - rm_tag_lines.append(p['tag_linenum']-1) - if p['macro_linenum']: - rm_macro_lines.append(p['macro_linenum']) - # Take a preceding comment line if it ends with '.patch' or '.diff' - if re.match("^\s*#.+(patch|diff)(\.(gz|bz2|xz|lzma))?\s*$", self.content[p['macro_linenum']-1], flags=re.I): - rm_macro_lines.append(p['macro_linenum']-1) - # Remove autoupdate patches from list of patches - del self.patches[n] - else: - if n >= start_patch_tag_num: - start_patch_tag_num = n + 1 - if p['tag_linenum'] >= last_ignored_patch_tag_line: - last_ignored_patch_tag_line = p['tag_linenum'] - if p['macro_linenum'] and p['macro_linenum'] > last_ignored_patch_macro_line: - last_ignored_patch_macro_line = p['macro_linenum'] - gbp.log.debug("Starting autoupdate patch macro numbering from %s" % start_patch_tag_num) - - rm_tag_lines.sort() - rm_macro_lines.sort() - - # Add new patches - patchnum = start_patch_tag_num - for p in patchfilenames: - self.patches[patchnum] = {'name': p, 'filename': p, 'apply': True, 'strip': '1', 'macro_linenum': None, 'autoupdate': True, 'tag_linenum': None} - patchnum += 1 + # Remove non-ignored patches + last_removed_tag_line = None + last_removed_macro_line = None + for num, patch in self.patches.items(): + if patch['autoupdate']: + # Remove a preceding comment if it seems to originate from GBP + prev_line = patch['tag_line'].prev + if re.match("^\s*#.*patch.*auto-generated", + str(prev_line), flags=re.I): + self.content.delete(prev_line) + last_removed_tag_line = patch['tag_line'].prev + self.content.delete(patch['tag_line']) + if patch['macro_line']: + # Remove a preceding comment line if it ends with + # '.patch' or '.diff' plus an optional compression suffix + prev_line = patch['macro_line'].prev + if re.match("^\s*#.+(patch|diff)(\.(gz|bz2|xz|lzma))?\s*$", + str(prev_line), flags=re.I): + self.content.delete(prev_line) + last_removed_macro_line = patch['macro_line'].prev + self.content.delete(patch['macro_line']) + # Remove from the patch list + self.patches.pop(num) + + if len(patchfilenames) == 0: + return + + # Add new patches to the patch list + patchnum = sorted(self.patches.keys())[-1] + 1 if self.patches else 0 + gbp.log.debug("Starting autoupdate patch numbering from %s" % patchnum) + for ind, name in enumerate(patchfilenames): + self.patches[patchnum + ind] = { + 'name': name, 'filename': name, 'apply': True, 'strip': '1', + 'macro_line': None, 'autoupdate': True, 'tag_line': None} + + # Determine where to add Patch tag lines + if last_removed_tag_line: + gbp.log.debug("Adding 'Patch' tags in place of the removed tags") + line = last_removed_tag_line + elif 'lastpatchtag' in loc: + gbp.log.debug("Adding new 'Patch' tags after the last 'Patch' tag") + line = loc['lastpatchtag'] + elif 'lastsourcetag' in loc: + gbp.log.debug("Didn't find any old 'Patch' tags, adding new " + "patches after the last 'Source' tag.") + line = loc['lastsourcetag'] + else: + gbp.log.debug("Didn't find any old 'Patch' or 'Source' tags, " + "adding new patches after the last 'Name' tag.") + line = loc['nametag'] + + # Add all patch tag lines to content, in reversed order + for n in reversed(sorted(self.patches.keys())): + patch = self.patches[n] + if patch['autoupdate']: + # "PatchXYZ:" text 12 chars wide, left aligned + text = "%-12s%s\n" % ("Patch%d:" % n, patch['name']) + patch['tag_line'] = self.content.insert_after(line, text) + # Finally, add a comment indicating gbp generated patches + self.content.insert_after(line, "# Patches auto-generated by " + "git-buildpackage:\n") # Determine where to add %patch macro lines - if len(rm_macro_lines): - gbp.log.debug("Will remove patch macro lines %s from spec file" % rm_macro_lines) - linenum = rm_macro_lines[-1] + 1 - elif last_ignored_patch_macro_line: - linenum = last_ignored_patch_macro_line + 1 + if last_removed_macro_line: + gbp.log.debug("Adding patch macros in place of the removed macros") + line = last_removed_macro_line + elif 'lastpatchmacro' in loc: + gbp.log.debug("Adding new patch macros after the last %patch macro") + line = loc['lastpatchmacro'] elif 'setupmacro' in loc: - gbp.log.info("Didn't find any old '%patch' macros, adding new patches after the last '%setup' macro at line %s") - linenum = loc['setupmacro'] + 1 + gbp.log.debug("Didn't find any old '%patch' macros, adding new " + "patches after the last '%setup' macro") + line = loc['setupmacro'] + elif 'prepmacro' in loc: + gbp.log.warn("Didn't find any old '%patch' macros or %setup macro," + " adding new patches directly after %prep macro") + line = loc['prepmacro'] else: - gbp.log.warn("Didn't find any old '%patch' macros or %setup macro, adding new patches directly after '%prep' macro at %s.") - linenum = loc['prepmacro'] + 1 + raise GbpError("Couldn't find location where to add patch macros") # Add all patch macro lines to content, in reversed order for n in reversed(sorted(self.patches.keys())): patch = self.patches[n] if patch['autoupdate'] and patch['apply']: # We're adding from bottom to top... - self.content.insert(linenum, "%%patch%d -p%s\n" % (n, patch['strip'])) + text = "%%patch%d -p%s\n" % (n, patch['strip']) + patch['macro_line'] = self.content.insert_after(line, text) # Use 'name', that is filename with macros not expanded - self.content.insert(linenum, "# %s\n" % patch['name']) - # Remove all old patch macro lines - for l in reversed(rm_macro_lines): - gbp.log.debug("Removing line #%s from spec: '%s'" % (l, self.content[l].strip())) - self.content.pop(l) - - # Determine where to add Patch tag lines - if len(rm_tag_lines): - gbp.log.debug("Will remove patch tag lines %s from spec file" % rm_tag_lines) - linenum = rm_tag_lines[-1] + 1 - elif last_ignored_patch_tag_line: - linenum = last_ignored_patch_tag_line + 1 - elif len(self.sources): - gbp.log.info("Didn't find any old 'Patch' tags, adding new patches after the last 'Source' tag.") - lastsource = sorted(self.sources.keys())[-1] - linenum = self.sources[lastsource]['tag_linenum'] + 1 - else: - gbp.log.info("Didn't find any old 'Patch' or 'Source' tags, adding new patches after the last 'Name' tag.") - linenum = loc['nametag'] + 1 - - # Add all patch tag lines to content, in reversed order - patch_tags_added = 0 - for n in reversed(sorted(self.patches.keys())): - patch = self.patches[n] - if patch['autoupdate']: - # "PatchXYZ:" text 12 chars wide, left aligned - text = "%-12s%s" % ("Patch%d:" % n, patch['name']) - self.content.insert(linenum, text + "\n") - patch_tags_added += 1 - if patch_tags_added > 0: - # Finally, add a comment indicating gbp generated patches - self.content.insert(linenum, "# Patches auto-generated by " - "git-buildpackage:\n") - # Remove all old patch tag lines - for l in reversed(rm_tag_lines): - gbp.log.debug("Removing line #%s from spec: '%s'" % (l, self.content[l].strip())) - self.content.pop(l) + self.content.insert_after(line, "# %s\n" % patch['name']) def patchseries(self): -- cgit v1.2.3 From 5010e367f9ef63c9bb627109287d593f4c1f9b8e Mon Sep 17 00:00:00 2001 From: Markus Lehtonen Date: Wed, 21 Nov 2012 12:51:53 +0200 Subject: rpm: rename the 'GbpIgnorePatch' special key in spec parsing to 'Gbp-Ignore-Patches' for better readability. All the special keys (or "gbp-tags") now have to start with the "Gbp-" prefix. Signed-off-by: Markus Lehtonen --- gbp/rpm/__init__.py | 4 ++-- tests/test_rpm_data/rpmbuild/SPECS/gbp-test.spec | 2 +- tests/test_rpm_data/rpmbuild/SPECS/gbp-test2.spec | 2 +- tests/test_rpm_data/specs/gbp-test-reference.spec | 2 +- 4 files changed, 5 insertions(+), 5 deletions(-) diff --git a/gbp/rpm/__init__.py b/gbp/rpm/__init__.py index ad6c96de..91b270cf 100644 --- a/gbp/rpm/__init__.py +++ b/gbp/rpm/__init__.py @@ -125,7 +125,7 @@ class SpecFile(object): '(?P\S(.*\S)?)\s*$', flags=re.I) macro_re = re.compile(r'^%(?P[a-z]+)(?P[0-9]+)?' '(\s+(?P.*))?$') - gbptag_re = re.compile(r'^\s*#\s*gbp(?P[a-z-]+)' + gbptag_re = re.compile(r'^\s*#\s*gbp-(?P[a-z-]+)' '(\s*:\s*(?P\S.*))?$', flags=re.I) def __init__(self, specfile, skip_tags=("ExcludeArch", "ExcludeOS", @@ -270,7 +270,7 @@ class SpecFile(object): line = str(lineobj) m = self.gbptag_re.match(line) if m: - if m.group('name').lower() == 'ignorepatch': + if m.group('name').lower() == 'ignore-patches': dataitems = m.group('args').strip().split() ignorepatch = sorted([int(num) for num in dataitems]) else: diff --git a/tests/test_rpm_data/rpmbuild/SPECS/gbp-test.spec b/tests/test_rpm_data/rpmbuild/SPECS/gbp-test.spec index 8a07d662..c46a734e 100644 --- a/tests/test_rpm_data/rpmbuild/SPECS/gbp-test.spec +++ b/tests/test_rpm_data/rpmbuild/SPECS/gbp-test.spec @@ -7,7 +7,7 @@ License: GPLv2 Source: %{name}-%{version}.tar.bz2 Source1: foo.txt Source20: bar.tar.gz -# GbpIgnorePatch: 0 +# Gbp-Ignore-Patches: 0 Patch0: my.patch Patch10: my2.patch Patch20: my3.patch diff --git a/tests/test_rpm_data/rpmbuild/SPECS/gbp-test2.spec b/tests/test_rpm_data/rpmbuild/SPECS/gbp-test2.spec index 932b8e8f..d5a228fd 100644 --- a/tests/test_rpm_data/rpmbuild/SPECS/gbp-test2.spec +++ b/tests/test_rpm_data/rpmbuild/SPECS/gbp-test2.spec @@ -8,7 +8,7 @@ License: GPLv2 Source10: ftp://ftp.host.com/%{name}-%{version}.tar.gz Source: foo.txt Source20: bar.tar.gz -# GbpIgnorePatch: 0 +# Gbp-Ignore-Patches: 0 Patch: my.patch Patch10: my2.patch Patch20: my3.patch diff --git a/tests/test_rpm_data/specs/gbp-test-reference.spec b/tests/test_rpm_data/specs/gbp-test-reference.spec index 884a64ca..050d1398 100644 --- a/tests/test_rpm_data/specs/gbp-test-reference.spec +++ b/tests/test_rpm_data/specs/gbp-test-reference.spec @@ -7,7 +7,7 @@ License: GPLv2 Source: %{name}-%{version}.tar.bz2 Source1: foo.txt Source20: bar.tar.gz -# GbpIgnorePatch: 0 +# Gbp-Ignore-Patches: 0 Patch0: my.patch # Patches auto-generated by git-buildpackage: Patch1: new.patch -- cgit v1.2.3 From 7ea7f2754cd26f709c66e57f705cd21a47223092 Mon Sep 17 00:00:00 2001 From: Markus Lehtonen Date: Wed, 21 Nov 2012 12:54:04 +0200 Subject: rpm: introduce new 'Gbp-Patch-Macros' special key in spec parsing This can be used to mark location where to add new patch macros when updating the spec. Signed-off-by: Markus Lehtonen --- gbp/rpm/__init__.py | 7 +++- tests/test_rpm.py | 7 ++++ tests/test_rpm_data/rpmbuild/SPECS/gbp-test2.spec | 3 ++ tests/test_rpm_data/specs/gbp-test2-reference.spec | 47 ++++++++++++++++++++++ 4 files changed, 63 insertions(+), 1 deletion(-) create mode 100644 tests/test_rpm_data/specs/gbp-test2-reference.spec diff --git a/gbp/rpm/__init__.py b/gbp/rpm/__init__.py index 91b270cf..8be38590 100644 --- a/gbp/rpm/__init__.py +++ b/gbp/rpm/__init__.py @@ -273,6 +273,8 @@ class SpecFile(object): if m.group('name').lower() == 'ignore-patches': dataitems = m.group('args').strip().split() ignorepatch = sorted([int(num) for num in dataitems]) + elif m.group('name').lower() == 'patch-macros': + ret['patchmacrostart'] = lineobj else: gbp.log.info("Found unrecognized Gbp tag on line %s: " "'%s'" % (i, line)) @@ -461,7 +463,10 @@ class SpecFile(object): "git-buildpackage:\n") # Determine where to add %patch macro lines - if last_removed_macro_line: + if 'patchmacrostart' in loc: + gbp.log.debug("Adding patch macros after the start marker") + line = loc['patchmacrostart'] + elif last_removed_macro_line: gbp.log.debug("Adding patch macros in place of the removed macros") line = last_removed_macro_line elif 'lastpatchmacro' in loc: diff --git a/tests/test_rpm.py b/tests/test_rpm.py index d57ea575..a04bce3e 100644 --- a/tests/test_rpm.py +++ b/tests/test_rpm.py @@ -152,7 +152,14 @@ class TestSpecFile(object): spec = SpecFile(tmp_spec) spec.update_patches(['new.patch']) spec.write_spec_file() + assert filecmp.cmp(tmp_spec, reference_spec) is True + # Test a second spec file + shutil.copy2(os.path.join(SPEC_DIR, 'gbp-test2.spec'), tmp_spec) + reference_spec = os.path.join(SPEC_DIR, 'gbp-test2-reference.spec') + spec = SpecFile(tmp_spec) + spec.update_patches(['new.patch']) + spec.write_spec_file() assert filecmp.cmp(tmp_spec, reference_spec) is True def test_quirks(self): diff --git a/tests/test_rpm_data/rpmbuild/SPECS/gbp-test2.spec b/tests/test_rpm_data/rpmbuild/SPECS/gbp-test2.spec index d5a228fd..ffae7e99 100644 --- a/tests/test_rpm_data/rpmbuild/SPECS/gbp-test2.spec +++ b/tests/test_rpm_data/rpmbuild/SPECS/gbp-test2.spec @@ -24,6 +24,9 @@ Package for testing the RPM functionality of git-buildpackage. %patch %patch -P 10 -p1 +echo "Do things" + +# Gbp-Patch-Macros %build make diff --git a/tests/test_rpm_data/specs/gbp-test2-reference.spec b/tests/test_rpm_data/specs/gbp-test2-reference.spec new file mode 100644 index 00000000..fbb7ad82 --- /dev/null +++ b/tests/test_rpm_data/specs/gbp-test2-reference.spec @@ -0,0 +1,47 @@ +Name: gbp-test2 +Summary: Test package 2 for git-buildpackage +Epoch: 2 +Version: 3.0 +Release: 0 +Group: Development/Libraries +License: GPLv2 +Source10: ftp://ftp.host.com/%{name}-%{version}.tar.gz +Source: foo.txt +Source20: bar.tar.gz +# Gbp-Ignore-Patches: 0 +Patch: my.patch +# Patches auto-generated by git-buildpackage: +Patch1: new.patch +Packager: Markus Lehtonen + +%description +Package for testing the RPM functionality of git-buildpackage. + + +%prep +%setup -T -n %{name}-%{version} -c -a 10 + +%patch + +echo "Do things" + +# Gbp-Patch-Macros +# new.patch +%patch1 -p1 + +%build +make + + +%install +rm -rf %{buildroot} +mkdir -p %{buildroot}/%{_datadir}/%{name} +cp -R * %{buildroot}/%{_datadir}/%{name} +install %{SOURCE0} %{buildroot}/%{_datadir}/%{name} + + + +%files +%defattr(-,root,root,-) +%dir %{_datadir}/%{name} +%{_datadir}/%{name} -- cgit v1.2.3 From 50ee2dd2251a9ad31f1e4069d8993b2211668719 Mon Sep 17 00:00:00 2001 From: Markus Lehtonen Date: Wed, 21 Nov 2012 13:42:33 +0200 Subject: rpm: simplify the SrcRpmFile class a bit Get rid of the unnecessary private methods. Signed-off-by: Markus Lehtonen --- gbp/rpm/__init__.py | 32 ++++++++++++-------------------- 1 file changed, 12 insertions(+), 20 deletions(-) diff --git a/gbp/rpm/__init__.py b/gbp/rpm/__init__.py index 8be38590..5418976a 100644 --- a/gbp/rpm/__init__.py +++ b/gbp/rpm/__init__.py @@ -77,37 +77,29 @@ class SrcRpmFile(object): srpmfp.close() self.srpmfile = os.path.abspath(srpmfile) - def _get_version(self): - """ - Get the (downstream) version of the RPM - """ + @property + def version(self): + """Get the (downstream) version of the RPM package""" version = dict(upstreamversion = self.rpmhdr[rpm.RPMTAG_VERSION], release = self.rpmhdr[rpm.RPMTAG_RELEASE]) if self.rpmhdr[rpm.RPMTAG_EPOCH] is not None: version['epoch'] = str(self.rpmhdr[rpm.RPMTAG_EPOCH]) return version - version = property(_get_version) - def _get_name(self): - """ - Get the name of the RPM package - """ + @property + def name(self): + """Get the name of the RPM package""" return self.rpmhdr[rpm.RPMTAG_NAME] - name = property(_get_name) - def _get_upstream_version(self): - """ - Get the upstream version of the package - """ + @property + def upstreamversion(self): + """Get the upstream version of the RPM package""" return self.rpmhdr[rpm.RPMTAG_VERSION] - upstreamversion = property(_get_upstream_version) - def _get_packager(self): - """ - Get the packager of the RPM package - """ + @property + def packager(self): + """Get the packager of the RPM package""" return self.rpmhdr[rpm.RPMTAG_PACKAGER] - packager = property(_get_packager) def unpack(self, dest_dir): """ -- cgit v1.2.3 From 3dd4673d739c9b088881074028df3de4791a209a Mon Sep 17 00:00:00 2001 From: Markus Lehtonen Date: Thu, 17 Jan 2013 10:23:57 +0200 Subject: tests: add more comprehensive tests for import-srpm Basic tests for virtually all features of import-srpm. Adds a new python module to include all (upcoming) git-buildpackage rpm commandline tool tests. Also, adds a separate git submodule for the rpm test data. Signed-off-by: Markus Lehtonen --- .gitmodules | 3 + tests/component/rpm/__init__.py | 30 ++++ tests/component/rpm/data | 1 + tests/component/rpm/test_import_srpm.py | 305 ++++++++++++++++++++++++++++++++ 4 files changed, 339 insertions(+) create mode 100644 tests/component/rpm/__init__.py create mode 160000 tests/component/rpm/data create mode 100644 tests/component/rpm/test_import_srpm.py diff --git a/.gitmodules b/.gitmodules index 98279cc0..3b52b91f 100644 --- a/.gitmodules +++ b/.gitmodules @@ -1,3 +1,6 @@ [submodule "tests/component/deb/data"] path = tests/component/deb/data url = git://honk.sigxcpu.org/git/gbp/deb-testdata +[submodule "tests/component/rpm/data"] + path = tests/component/rpm/data + url = git://github.com/marquiz/git-buildpackage-rpm-testdata.git diff --git a/tests/component/rpm/__init__.py b/tests/component/rpm/__init__.py new file mode 100644 index 00000000..e84fca94 --- /dev/null +++ b/tests/component/rpm/__init__.py @@ -0,0 +1,30 @@ +# vim: set fileencoding=utf-8 : +# +# (C) 2012 Intel Corporation +# This program is free software; you can redistribute it and/or modify +# it under the terms of the GNU General Public License as published by +# the Free Software Foundation; either version 2 of the License, or +# (at your option) any later version. +# +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with this program; if not, write to the Free Software +# Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA +"""Test module for RPM command line tools of the git-buildpackage suite""" + +import os + +from tests.component import ComponentTestGitRepository + +RPM_TEST_DATA_SUBMODULE = os.path.join('tests', 'component', 'rpm', 'data') +RPM_TEST_DATA_DIR = os.path.abspath(RPM_TEST_DATA_SUBMODULE) + +def setup(): + """Test Module setup""" + ComponentTestGitRepository.check_testdata(RPM_TEST_DATA_SUBMODULE) + +# vim:et:ts=4:sw=4:et:sts=4:ai:set list listchars=tab\:»·,trail\:·: diff --git a/tests/component/rpm/data b/tests/component/rpm/data new file mode 160000 index 00000000..4aa7e290 --- /dev/null +++ b/tests/component/rpm/data @@ -0,0 +1 @@ +Subproject commit 4aa7e2901ab84bd91c1d2289dd4138c531c19376 diff --git a/tests/component/rpm/test_import_srpm.py b/tests/component/rpm/test_import_srpm.py new file mode 100644 index 00000000..0f1ffeba --- /dev/null +++ b/tests/component/rpm/test_import_srpm.py @@ -0,0 +1,305 @@ +# vim: set fileencoding=utf-8 : +# +# (C) 2012 Intel Corporation +# This program is free software; you can redistribute it and/or modify +# it under the terms of the GNU General Public License as published by +# the Free Software Foundation; either version 2 of the License, or +# (at your option) any later version. +# +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with this program; if not, write to the Free Software +# Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA +"""Basic tests for the git-import-srpm tool""" + +import os +import shutil +import urllib2 +from nose.plugins.skip import SkipTest +from nose.tools import assert_raises # pylint: disable=E0611 +from mock import Mock + +from gbp.scripts.import_srpm import main as import_srpm +from gbp.git import GitRepository +from gbp.rpm import SrcRpmFile + +from tests.component import ComponentTestBase +from tests.component.rpm import RPM_TEST_DATA_DIR as DATA_DIR + +# Disable "Method could be a function warning" +# pylint: disable=R0201 + +class TestImportPacked(ComponentTestBase): + """Test importing of src.rpm files""" + + def test_invalid_args(self): + """See that import-srpm fails gracefully if called with invalid args""" + assert import_srpm(['arg0']) == 1 + with assert_raises(SystemExit): + import_srpm(['arg0', '--invalid-arg=123']) + + def test_basic_import(self): + """Test importing of non-native src.rpm""" + srpm = os.path.join(DATA_DIR, 'gbp-test-1.0-1.src.rpm') + assert import_srpm(['arg0', srpm]) == 0 + # Check repository state + repo = GitRepository('gbp-test') + self._check_repo_state(repo, 'master', ['master', 'upstream']) + # Four commits: upstream, packaging files, one patch and the removal + # of imported patches + assert len(repo.get_commits()) == 4 + + def test_basic_import_orphan(self): + """ + Test importing of non-native src.rpm to separate packaging and + development branches + """ + srpm = os.path.join(DATA_DIR, 'gbp-test2-2.0-0.src.rpm') + assert import_srpm(['arg0', '--orphan-packaging', srpm]) == 0 + # Check repository state + repo = GitRepository('gbp-test2') + self._check_repo_state(repo, 'master', ['master', 'upstream']) + # Only one commit: the packaging files + assert len(repo.get_commits()) == 1 + + def test_basic_native_import(self): + """Test importing of native src.rpm""" + srpm = os.path.join(DATA_DIR, 'gbp-test2-2.0-0.src.rpm') + assert import_srpm(['arg0', '--native', srpm]) == 0 + # Check repository state + repo = GitRepository('gbp-test2') + self._check_repo_state(repo, 'master', ['master']) + # Only one commit: the imported source tarball + assert len(repo.get_commits()) == 1 + + def test_import_no_orig_src(self): + """Test importing of (native) srpm without orig tarball""" + srpm = os.path.join(DATA_DIR, 'gbp-test-native2-2.0-0.src.rpm') + assert import_srpm(['arg0', srpm]) == 0 + # Check repository state + repo = GitRepository('gbp-test-native2') + self._check_repo_state(repo, 'master', ['master']) + # Only one commit: packaging files + assert len(repo.get_commits()) == 1 + + def test_multiple_versions(self): + """Test importing of multiple versions""" + srpms = [ os.path.join(DATA_DIR, 'gbp-test-1.0-1.src.rpm'), + os.path.join(DATA_DIR, 'gbp-test-1.0-1.other.src.rpm'), + os.path.join(DATA_DIR, 'gbp-test-1.1-1.src.rpm') ] + assert import_srpm(['arg0', srpms[0]]) == 0 + repo = GitRepository('gbp-test') + self._check_repo_state(repo, 'master', ['master', 'upstream']) + assert len(repo.get_commits()) == 4 + # Try to import same version again + assert import_srpm(['arg0', srpms[1]]) == 0 + assert len(repo.get_commits()) == 4 + assert len(repo.get_commits(until='upstream')) == 1 + assert import_srpm(['arg0', '--allow-same-version', srpms[1]]) == 0 + # Added new versio packaging plus one patch + assert len(repo.get_commits()) == 7 + assert len(repo.get_commits(until='upstream')) == 1 + # Import new version + assert import_srpm(['arg0', srpms[2]]) == 0 + assert len(repo.get_commits()) == 11 + assert len(repo.get_commits(until='upstream')) == 2 + # Check number of tags + assert len(repo.get_tags('upstream/*')) == 2 + assert len(repo.get_tags('vendor/*')) == 3 + + def test_import_to_existing(self): + """Test importing to an existing repo""" + srpm = os.path.join(DATA_DIR, 'gbp-test-1.0-1.src.rpm') + + # Create new repo + repo = GitRepository.create('myrepo') + os.chdir('myrepo') + shutil.copy2('.git/HEAD', 'foobar') + repo.add_files('.') + repo.commit_all('First commit') + + # Test importing to non-clean repo + shutil.copy2('.git/HEAD', 'foobaz') + assert import_srpm(['arg0', '--create-missing', srpm]) == 1 + self._check_log(0, 'gbp:error: Repository has uncommitted changes') + self._clear_log() + os.unlink('foobaz') + + # The first import should fail because upstream branch is missing + assert import_srpm(['arg0', srpm]) == 1 + self._check_log(-1, 'Also check the --create-missing-branches') + assert import_srpm(['arg0', '--create-missing', srpm]) == 0 + self._check_repo_state(repo, 'master', ['master', 'upstream']) + # Four commits: our initial, upstream, packaging files, one patch, + # and the removal of imported patches + assert len(repo.get_commits()) == 5 + + # The import should fail because missing packaging-branch + srpm = os.path.join(DATA_DIR, 'gbp-test-1.1-1.src.rpm') + assert import_srpm(['arg0', '--packaging-branch=foo', srpm]) == 1 + self._check_log(-1, 'Also check the --create-missing-branches') + + + def test_filter(self): + """Test filter option""" + srpm = os.path.join(DATA_DIR, 'gbp-test-1.0-1.src.rpm') + assert import_srpm(['arg0', '--filter=README', '--filter=mydir', + srpm]) == 0 + # Check repository state + repo = GitRepository('gbp-test') + files = set(['Makefile', 'dummy.sh', 'bar.tar.gz', 'foo.txt', + 'gbp-test.spec', 'my.patch', 'mydir/', 'mydir/myfile.txt']) + self._check_repo_state(repo, 'master', ['master', 'upstream'], files) + + def test_misc_options(self): + """Test various options of git-import-srpm""" + srpm = os.path.join(DATA_DIR, 'gbp-test2-2.0-0.src.rpm') + + assert import_srpm([ + 'arg0', + '--no-patch-import', + '--packaging-branch=pack', + '--upstream-branch=orig', + '--packaging-dir=packaging', + '--packaging-tag=ver_%(upstreamversion)s-rel_%(release)s', + '--upstream-tag=orig/%(upstreamversion)s', + '--author-is-committer', + srpm]) == 0 + # Check repository state + repo = GitRepository('gbp-test2') + self._check_repo_state(repo, 'pack', ['pack', 'orig']) + assert len(repo.get_commits()) == 2 + # Check packaging dir + assert len(repo.get_commits(paths='packaging')) == 1 + # Check tags + tags = repo.get_tags() + assert set(tags) == set(['orig/2.0', 'ver_2.0-rel_0']) + # Check git committer/author + info = repo.get_commit_info('pack') + assert info['author'].name == 'Markus Lehtonen' + assert info['author'].email == 'markus.lehtonen@linux.intel.com' + assert info['author'].name == info['committer'].name + assert info['author'].email == info['committer'].email + + +class TestImportUnPacked(ComponentTestBase): + """Test importing of unpacked source rpms""" + + def setup(self): + super(TestImportUnPacked, self).setup() + # Unpack some source rpms + os.mkdir('multi-unpack') + for pkg in ['gbp-test-1.0-1.src.rpm', 'gbp-test2-2.0-0.src.rpm']: + unpack_dir = pkg.replace('.src.rpm', '-unpack') + os.mkdir(unpack_dir) + pkg_path = os.path.join(DATA_DIR, pkg) + SrcRpmFile(pkg_path).unpack(unpack_dir) + SrcRpmFile(pkg_path).unpack('multi-unpack') + + def test_import_dir(self): + """Test importing of directories""" + assert import_srpm(['arg0', 'gbp-test-1.0-1-unpack']) == 0 + # Check repository state + repo = GitRepository('gbp-test') + self._check_repo_state(repo, 'master', ['master', 'upstream']) + + # Check that importing dir with multiple spec files fails + assert import_srpm(['arg0', 'multi-unpack']) == 1 + self._check_log(-1, 'gbp:error: Failed determine spec file: ' + 'Multiple spec files found') + + def test_import_spec(self): + """Test importing of spec file""" + specfile = 'gbp-test2-2.0-0-unpack/gbp-test2.spec' + assert import_srpm(['arg0', specfile]) == 0 + # Check repository state + assert GitRepository('gbp-test2').is_clean() + + def test_missing_files(self): + """Test importing of directory with missing packaging files""" + + os.unlink('gbp-test2-2.0-0-unpack/my.patch') + assert import_srpm(['arg0', 'gbp-test2-2.0-0-unpack']) == 1 + self._check_log(-1, "gbp:error: File 'my.patch' listed in spec " + "not found") + + +class TestDownloadImport(ComponentTestBase): + """Test download functionality""" + + def test_urldownload(self): + """Test downloading and importing src.rpm from remote url""" + srpm = 'http://raw.github.com/marquiz/git-buildpackage-rpm-testdata/'\ + 'master/gbp-test-1.0-1.src.rpm' + # Mock to use local files instead of really downloading + local_fn = os.path.join(DATA_DIR, os.path.basename(srpm)) + urllib2.urlopen = Mock() + urllib2.urlopen.return_value = open(local_fn, 'r') + + assert import_srpm(['arg0', '--download', srpm]) == 0 + # Check repository state + repo = GitRepository('gbp-test') + self._check_repo_state(repo, 'master', ['master', 'upstream']) + + def test_nonexistent_url(self): + """Test graceful failure when trying download from nonexistent url""" + srpm = 'http://url.does.not.exist.com/foo.src.rpm' + # Do not connect to remote, mock failure + urllib2.urlopen = Mock() + urllib2.urlopen.side_effect = urllib2.HTTPError(srpm, 404, "Not found", + None, None) + + assert import_srpm(['arg0', '--download', srpm]) == 1 + self._check_log(-1, "gbp:error: Download failed: HTTP Error 404") + self._clear_log() + + def test_invalid_url(self): + """Test graceful failure when trying download from invalid url""" + srpm = 'foob://url.does.not.exist.com/foo.src.rpm' + assert import_srpm(['arg0', '--download', srpm]) == 1 + self._check_log(-1, "gbp:error: Download failed: unknown url type:") + self._clear_log() + + +class TestPristineTar(ComponentTestBase): + """Test importing with pristine-tar""" + + @classmethod + def setup_class(cls): + if not os.path.exists('/usr/bin/pristine-tar'): + raise SkipTest('Skipping %s:%s as pristine-tar tool is not ' + 'available' % (__name__, cls.__name__)) + super(TestPristineTar, cls).setup_class() + + def test_basic_import_pristine_tar(self): + """Test importing of non-native src.rpm, with pristine-tar""" + srpm = os.path.join(DATA_DIR, 'gbp-test-1.0-1.src.rpm') + assert import_srpm(['arg0', '--pristine-tar', srpm]) == 0 + # Check repository state + repo = GitRepository('gbp-test') + self._check_repo_state(repo, 'master', ['master', 'upstream', + 'pristine-tar']) + # Four commits: upstream, packaging files, one patch and the removal + # of imported patches + assert len(repo.get_commits()) == 4 + + +class TestBareRepo(ComponentTestBase): + """Test importing to a bare repository""" + + def test_basic_import_to_bare_repo(self): + """Test importing of srpm to a bare git repository""" + srpm = os.path.join(DATA_DIR, 'gbp-test-1.0-1.src.rpm') + # Create new repo + repo = GitRepository.create('myrepo', bare=True) + os.chdir('myrepo') + assert import_srpm(['arg0', srpm]) == 0 + self._check_repo_state(repo, 'master', ['master', 'upstream']) + # Patch import to bare repos not supported -> only 2 commits + assert len(repo.get_commits(until='master')) == 2 + +# vim:et:ts=4:sw=4:et:sts=4:ai:set list listchars=tab\:»·,trail\:·: -- cgit v1.2.3 From 88af0cfd3fc0ea99a4dc8140563aa9db3dc26c5c Mon Sep 17 00:00:00 2001 From: Markus Lehtonen Date: Fri, 30 Nov 2012 19:11:35 +0200 Subject: rpm helpers: support updating tags in the spec file Currently only the 'VCS' tag is supported. Signed-off-by: Markus Lehtonen --- gbp/rpm/__init__.py | 26 +++++++++++- tests/test_rpm.py | 20 ++++++++- tests/test_rpm_data/rpmbuild/SPECS/gbp-test2.spec | 1 + .../rpmbuild/SPECS/gbp-test2.spec.orig | 46 +++++++++++++++++++++ tests/test_rpm_data/specs/gbp-test-reference2.spec | 44 ++++++++++++++++++++ .../test_rpm_data/specs/gbp-test2-reference2.spec | 48 ++++++++++++++++++++++ 6 files changed, 182 insertions(+), 3 deletions(-) create mode 100644 tests/test_rpm_data/rpmbuild/SPECS/gbp-test2.spec.orig create mode 100644 tests/test_rpm_data/specs/gbp-test-reference2.spec create mode 100644 tests/test_rpm_data/specs/gbp-test2-reference2.spec diff --git a/gbp/rpm/__init__.py b/gbp/rpm/__init__.py index 5418976a..05b40e3c 100644 --- a/gbp/rpm/__init__.py +++ b/gbp/rpm/__init__.py @@ -339,11 +339,15 @@ class SpecFile(object): 'tag_line': lineobj} self.patches[tagnum] = new_patch ret['lastpatchtag'] = lineobj - # 'Name:' and 'Packager:' tags + # Other tags elif tagname == 'name': ret['nametag'] = lineobj elif tagname == 'packager': ret['packagertag'] = lineobj + elif tagname == 'vcs': + ret['vcstag'] = lineobj + elif tagname == 'release': + ret['releasetag'] = lineobj continue # Parse special macros @@ -386,6 +390,26 @@ class SpecFile(object): ret['prepmacro'] = lineobj return ret + def set_tag(self, tag, value): + """Update a tag in spec file content""" + loc = self.parse_content() + + key = tag.lower() + "tag" + if tag.lower() == 'vcs': + if value: + text = '%-12s%s\n' % ('VCS:', value) + if key in loc: + gbp.log.info("Updating '%s' tag in spec" % tag) + loc[key].set_data(text) + else: + gbp.log.info("Adding '%s' tag to spec" % tag) + self.content.insert_after(loc['releasetag'], text) + elif key in loc: + gbp.log.info("Removing '%s' tag from spec" % tag) + self.content.delete(loc[key]) + else: + raise GbpError("Setting '%s:' tag not supported") + def update_patches(self, patchfilenames): """ Update spec with new patch tags and patch macros. diff --git a/tests/test_rpm.py b/tests/test_rpm.py index a04bce3e..7f018195 100644 --- a/tests/test_rpm.py +++ b/tests/test_rpm.py @@ -154,11 +154,27 @@ class TestSpecFile(object): spec.write_spec_file() assert filecmp.cmp(tmp_spec, reference_spec) is True - # Test a second spec file + # Test adding the VCS tag + reference_spec = os.path.join(SPEC_DIR, 'gbp-test-reference2.spec') + spec.set_tag('vcs', 'myvcstag') + spec.write_spec_file() + assert filecmp.cmp(tmp_spec, reference_spec) is True + + def test_update_spec2(self): + """Another test for spec autoupdate functionality""" + tmp_spec = os.path.join(self.tmpdir, 'gbp-test.spec') shutil.copy2(os.path.join(SPEC_DIR, 'gbp-test2.spec'), tmp_spec) - reference_spec = os.path.join(SPEC_DIR, 'gbp-test2-reference.spec') + + reference_spec = os.path.join(SPEC_DIR, 'gbp-test2-reference2.spec') spec = SpecFile(tmp_spec) spec.update_patches(['new.patch']) + spec.set_tag('vcs', 'myvcstag') + spec.write_spec_file() + assert filecmp.cmp(tmp_spec, reference_spec) is True + + # Test removing the VCS tag + reference_spec = os.path.join(SPEC_DIR, 'gbp-test2-reference.spec') + spec.set_tag('vcs', '') spec.write_spec_file() assert filecmp.cmp(tmp_spec, reference_spec) is True diff --git a/tests/test_rpm_data/rpmbuild/SPECS/gbp-test2.spec b/tests/test_rpm_data/rpmbuild/SPECS/gbp-test2.spec index ffae7e99..4180a877 100644 --- a/tests/test_rpm_data/rpmbuild/SPECS/gbp-test2.spec +++ b/tests/test_rpm_data/rpmbuild/SPECS/gbp-test2.spec @@ -13,6 +13,7 @@ Patch: my.patch Patch10: my2.patch Patch20: my3.patch Packager: Markus Lehtonen +VCS: myoldvcstag %description Package for testing the RPM functionality of git-buildpackage. diff --git a/tests/test_rpm_data/rpmbuild/SPECS/gbp-test2.spec.orig b/tests/test_rpm_data/rpmbuild/SPECS/gbp-test2.spec.orig new file mode 100644 index 00000000..ffae7e99 --- /dev/null +++ b/tests/test_rpm_data/rpmbuild/SPECS/gbp-test2.spec.orig @@ -0,0 +1,46 @@ +Name: gbp-test2 +Summary: Test package 2 for git-buildpackage +Epoch: 2 +Version: 3.0 +Release: 0 +Group: Development/Libraries +License: GPLv2 +Source10: ftp://ftp.host.com/%{name}-%{version}.tar.gz +Source: foo.txt +Source20: bar.tar.gz +# Gbp-Ignore-Patches: 0 +Patch: my.patch +Patch10: my2.patch +Patch20: my3.patch +Packager: Markus Lehtonen + +%description +Package for testing the RPM functionality of git-buildpackage. + + +%prep +%setup -T -n %{name}-%{version} -c -a 10 + +%patch +%patch -P 10 -p1 + +echo "Do things" + +# Gbp-Patch-Macros + +%build +make + + +%install +rm -rf %{buildroot} +mkdir -p %{buildroot}/%{_datadir}/%{name} +cp -R * %{buildroot}/%{_datadir}/%{name} +install %{SOURCE0} %{buildroot}/%{_datadir}/%{name} + + + +%files +%defattr(-,root,root,-) +%dir %{_datadir}/%{name} +%{_datadir}/%{name} diff --git a/tests/test_rpm_data/specs/gbp-test-reference2.spec b/tests/test_rpm_data/specs/gbp-test-reference2.spec new file mode 100644 index 00000000..f006fc77 --- /dev/null +++ b/tests/test_rpm_data/specs/gbp-test-reference2.spec @@ -0,0 +1,44 @@ +Name: gbp-test +Summary: Test package for git-buildpackage +Version: 1.0 +Release: 1 +VCS: myvcstag +Group: Development/Libraries +License: GPLv2 +Source: %{name}-%{version}.tar.bz2 +Source1: foo.txt +Source20: bar.tar.gz +# Gbp-Ignore-Patches: 0 +Patch0: my.patch +# Patches auto-generated by git-buildpackage: +Patch1: new.patch + + +%description +Package for testing the RPM functionality of git-buildpackage. + + +%prep +%setup -n %{name} -a 20 + +%patch0 +# new.patch +%patch1 -p1 + + +%build +make + + +%install +rm -rf %{buildroot} +mkdir -p %{buildroot}/%{_datadir}/%{name} +cp -R * %{buildroot}/%{_datadir}/%{name} +install %{SOURCE0} %{buildroot}/%{_datadir}/%{name} + + + +%files +%defattr(-,root,root,-) +%dir %{_datadir}/%{name} +%{_datadir}/%{name} diff --git a/tests/test_rpm_data/specs/gbp-test2-reference2.spec b/tests/test_rpm_data/specs/gbp-test2-reference2.spec new file mode 100644 index 00000000..02356d0a --- /dev/null +++ b/tests/test_rpm_data/specs/gbp-test2-reference2.spec @@ -0,0 +1,48 @@ +Name: gbp-test2 +Summary: Test package 2 for git-buildpackage +Epoch: 2 +Version: 3.0 +Release: 0 +Group: Development/Libraries +License: GPLv2 +Source10: ftp://ftp.host.com/%{name}-%{version}.tar.gz +Source: foo.txt +Source20: bar.tar.gz +# Gbp-Ignore-Patches: 0 +Patch: my.patch +# Patches auto-generated by git-buildpackage: +Patch1: new.patch +Packager: Markus Lehtonen +VCS: myvcstag + +%description +Package for testing the RPM functionality of git-buildpackage. + + +%prep +%setup -T -n %{name}-%{version} -c -a 10 + +%patch + +echo "Do things" + +# Gbp-Patch-Macros +# new.patch +%patch1 -p1 + +%build +make + + +%install +rm -rf %{buildroot} +mkdir -p %{buildroot}/%{_datadir}/%{name} +cp -R * %{buildroot}/%{_datadir}/%{name} +install %{SOURCE0} %{buildroot}/%{_datadir}/%{name} + + + +%files +%defattr(-,root,root,-) +%dir %{_datadir}/%{name} +%{_datadir}/%{name} -- cgit v1.2.3 From f521ffaf513e58a0607b2e4e1645449e2e648393 Mon Sep 17 00:00:00 2001 From: Markus Lehtonen Date: Thu, 17 Jan 2013 10:41:18 +0200 Subject: buildpackage-rpm: support setting/updating the 'VCS:' tag Git-buildpackage-rpm now always updates the 'VCS:' tag in the exported spec file. A new config option 'spec-vcs-tag' controls the format: - if empty, no 'VCS' tag is inserted and possible old 'VCS' tag is removed - otherwise, a 'VCS' tag is inserted or the old 'VCS' tag is updated - '%(tag)s' expands to the long tag name (from git-describe) Signed-off-by: Markus Lehtonen --- gbp/config.py | 5 +++++ gbp/scripts/buildpackage_rpm.py | 19 +++++++++++++++++++ tests/component/rpm/data | 2 +- 3 files changed, 25 insertions(+), 1 deletion(-) diff --git a/gbp/config.py b/gbp/config.py index 2b2c8cb4..77c36745 100644 --- a/gbp/config.py +++ b/gbp/config.py @@ -601,6 +601,7 @@ class GbpOptionParserRpm(GbpOptionParser): 'pristine-tarball-name' : 'auto', 'orig-prefix' : 'auto', 'patch-import' : 'True', + 'spec-vcs-tag' : '', } ) help = dict(GbpOptionParser.help) @@ -635,6 +636,10 @@ class GbpOptionParserRpm(GbpOptionParser): "Prefix (dir) to be used when generating/importing tarballs, default is '%(orig-prefix)s'", 'patch-import': "Import patches to the packaging branch, default is '%(patch-import)s'", + 'spec-vcs-tag': + ("Set/update the 'VCS:' tag in the spec file, empty " + "value removes the tag entirely, default is " + "'%(spec-vcs-tag)s'"), } ) # vim:et:ts=4:sw=4:et:sts=4:ai:set list listchars=tab\:»·,trail\:·: diff --git a/gbp/scripts/buildpackage_rpm.py b/gbp/scripts/buildpackage_rpm.py index f1b31f77..187e6b28 100755 --- a/gbp/scripts/buildpackage_rpm.py +++ b/gbp/scripts/buildpackage_rpm.py @@ -418,6 +418,7 @@ def parse_args(argv, prefix): export_group.add_config_file_option("patch-export-compress", dest="patch_export_compress") export_group.add_config_file_option("patch-export-squash-until", dest="patch_export_squash_until") export_group.add_boolean_config_file_option(option_name="patch-numbers", dest="patch_numbers") + export_group.add_config_file_option("spec-vcs-tag", dest="spec_vcs_tag") options, args = parser.parse_args(args) options.patch_export_compress = rpm.string_to_int(options.patch_export_compress) @@ -590,12 +591,30 @@ def main(argv): repo.delete_tag(tag) create_packaging_tag(repo, tag, commit=tree, version=spec.version, options=options) + tree_name = tag + commit_sha1 = repo.rev_parse('%s^0' % tag) if options.posttag: sha = repo.rev_parse("%s^{}" % tag) Command(options.posttag, shell=True, extra_env={'GBP_TAG': tag, 'GBP_BRANCH': branch, 'GBP_SHA1': sha})() + else: + try: + tree_name = repo.describe(tree, longfmt=True, always=True, + abbrev=40) + commit_sha1 = repo.rev_parse('%s^0' % tree) + except GitRepositoryError: + # If tree is not commit-ish, expect it to be from current HEAD + tree_name = repo.describe('HEAD', longfmt=True, always=True, + abbrev=40) + '-dirty' + commit_sha1 = repo.rev_parse('HEAD') + '-dirty' + # Put 'VCS:' tag to .spec + spec.set_tag('vcs', + options.spec_vcs_tag % {'tagname': tree_name, + 'commit': commit_sha1}) + spec.write_spec_file() + except CommandExecFailed: retval = 1 except GitRepositoryError as err: diff --git a/tests/component/rpm/data b/tests/component/rpm/data index 4aa7e290..aec4222c 160000 --- a/tests/component/rpm/data +++ b/tests/component/rpm/data @@ -1 +1 @@ -Subproject commit 4aa7e2901ab84bd91c1d2289dd4138c531c19376 +Subproject commit aec4222cbd9e2efbd60c56ee4e9cc4d8eb7265b3 -- cgit v1.2.3 From 9f0acd1e691518cb031707bc4affdd262a5e5335 Mon Sep 17 00:00:00 2001 From: Markus Lehtonen Date: Wed, 9 Jan 2013 14:44:36 +0200 Subject: rpm.SpecFile: return correct patch file path in patchseries() Fixes importing patches when the 'Patch:' tag contains an URI. Signed-off-by: Markus Lehtonen --- gbp/rpm/__init__.py | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/gbp/rpm/__init__.py b/gbp/rpm/__init__.py index 05b40e3c..88ccea32 100644 --- a/gbp/rpm/__init__.py +++ b/gbp/rpm/__init__.py @@ -518,7 +518,9 @@ class SpecFile(object): patchdir = os.path.dirname(self.specfile) for n, p in sorted(self.patches.iteritems()): if p['autoupdate'] and p['apply']: - series.append(Patch(os.path.join(patchdir, p['filename']), strip = int(p['strip']))) + fname = os.path.basename(p['filename']) + series.append(Patch(os.path.join(patchdir, fname), + strip = int(p['strip']))) return series -- cgit v1.2.3 From 4e02c93cb50774ac0f6f553f7857efb20f456a5c Mon Sep 17 00:00:00 2001 From: Markus Lehtonen Date: Wed, 9 Jan 2013 14:06:39 +0200 Subject: import-srpm: enhance spec guessing Use package name (in case of src.rpm) or directory name (in case of dir) as the preferred name of the spec file. Signed-off-by: Markus Lehtonen --- gbp/scripts/import_srpm.py | 7 ++++++- tests/component/rpm/test_import_srpm.py | 15 +++++++++++++-- 2 files changed, 19 insertions(+), 3 deletions(-) diff --git a/gbp/scripts/import_srpm.py b/gbp/scripts/import_srpm.py index 574d01e8..269101d9 100755 --- a/gbp/scripts/import_srpm.py +++ b/gbp/scripts/import_srpm.py @@ -274,13 +274,18 @@ def main(argv): prefix='pkgextract_') gbp.log.info("Extracting src rpm to '%s'" % dirs['pkgextract']) src.unpack(dirs['pkgextract']) + preferred_spec = src.name + '.spec' srpm = dirs['pkgextract'] + elif os.path.isdir(srpm): + preferred_spec = os.path.basename(srpm.rstrip('/')) + '.spec' + else: + preferred_spec = None # Find and parse spec file if os.path.isdir(srpm): gbp.log.debug("Trying to import an unpacked srpm from '%s'" % srpm) dirs['src'] = os.path.abspath(srpm) - spec = parse_spec(guess_spec(srpm, True)) + spec = parse_spec(guess_spec(srpm, True, preferred_spec)) else: gbp.log.debug("Trying to import an srpm from '%s' with spec "\ "file '%s'" % (os.path.dirname(srpm), srpm)) diff --git a/tests/component/rpm/test_import_srpm.py b/tests/component/rpm/test_import_srpm.py index 0f1ffeba..e2458a74 100644 --- a/tests/component/rpm/test_import_srpm.py +++ b/tests/component/rpm/test_import_srpm.py @@ -53,6 +53,17 @@ class TestImportPacked(ComponentTestBase): # of imported patches assert len(repo.get_commits()) == 4 + def test_basic_import2(self): + """Import package with multiple spec files and full url patch""" + srpm = os.path.join(DATA_DIR, 'gbp-test2-2.0-0.src.rpm') + assert import_srpm(['arg0', srpm]) == 0 + # Check repository state + repo = GitRepository('gbp-test2') + self._check_repo_state(repo, 'master', ['master', 'upstream']) + # Four commits: upstream, packaging files, one patch and the removal + # of imported patches + assert len(repo.get_commits()) == 4 + def test_basic_import_orphan(self): """ Test importing of non-native src.rpm to separate packaging and @@ -221,9 +232,9 @@ class TestImportUnPacked(ComponentTestBase): def test_missing_files(self): """Test importing of directory with missing packaging files""" - + specfile = 'gbp-test2-2.0-0-unpack/gbp-test2.spec' os.unlink('gbp-test2-2.0-0-unpack/my.patch') - assert import_srpm(['arg0', 'gbp-test2-2.0-0-unpack']) == 1 + assert import_srpm(['arg0', specfile]) == 1 self._check_log(-1, "gbp:error: File 'my.patch' listed in spec " "not found") -- cgit v1.2.3 From 0daa5b049e799612d65757cef4f7e54779c37efa Mon Sep 17 00:00:00 2001 From: Markus Lehtonen Date: Mon, 3 Dec 2012 19:12:56 +0200 Subject: rpm refactor: move spec file filtering into a separate function Also, remove the skip_tags option from the init as it's currently not used anywhere and it'd be better parse the spec file similarly in every place. The option can be re-added in the future if really needed. Signed-off-by: Markus Lehtonen --- gbp/rpm/__init__.py | 68 +++++++++++++++++++++++++++++------------------------ 1 file changed, 37 insertions(+), 31 deletions(-) diff --git a/gbp/rpm/__init__.py b/gbp/rpm/__init__.py index 88ccea32..db570f47 100644 --- a/gbp/rpm/__init__.py +++ b/gbp/rpm/__init__.py @@ -120,28 +120,25 @@ class SpecFile(object): gbptag_re = re.compile(r'^\s*#\s*gbp-(?P[a-z-]+)' '(\s*:\s*(?P\S.*))?$', flags=re.I) - def __init__(self, specfile, skip_tags=("ExcludeArch", "ExcludeOS", - "ExclusiveArch", "ExclusiveOS", - "BuildArch")): - with tempfile.NamedTemporaryFile(prefix='gbp') as temp: - try: - with open(specfile) as specf: - with open(temp.name, 'w') as filtered: - filtered.writelines(line for line in specf \ - if line.split(":")[0].strip() not in skip_tags) - filtered.flush() - try: - # Parse two times to circumvent a rpm-python - # problem where macros are not expanded if used - # before their definition - rpm.spec(temp.name) - self.specinfo = rpm.spec(temp.name) - except ValueError as err: - raise GbpError("RPM error while parsing spec: %s" % err) - except IOError as err: - raise NoSpecError("Unable to read spec file: %s" % err) - - source_header = self.specinfo.packages[0].header + def __init__(self, specfile): + # Load spec file into our special data structure + self.specfile = os.path.abspath(specfile) + self.specdir = os.path.dirname(self.specfile) + self.content = LinkedList() + try: + with open(specfile) as spec_file: + for line in spec_file.readlines(): + self.content.append(line) + except IOError as err: + raise NoSpecError("Unable to read spec file: %s" % err) + + # Use rpm-python to parse the spec file content + self._filtertags = ("excludearch", "excludeos", "exclusivearch", + "exclusiveos","buildarch") + self._specinfo = self._parse_filtered_spec(self._filtertags) + + # Other initializations + source_header = self._specinfo.packages[0].header self.name = source_header[rpm.RPMTAG_NAME] self.upstreamversion = source_header[rpm.RPMTAG_VERSION] self.release = source_header[rpm.RPMTAG_RELEASE] @@ -149,19 +146,12 @@ class SpecFile(object): self.epoch = str(source_header[rpm.RPMTAG_EPOCH]) \ if source_header[rpm.RPMTAG_EPOCH] != None else None self.packager = source_header[rpm.RPMTAG_PACKAGER] - self.specfile = os.path.abspath(specfile) - self.specdir = os.path.dirname(self.specfile) self.patches = {} self.sources = {} - # Load and parse extra info from spec file - self.content = LinkedList() - with open(self.specfile) as spec_file: - for line in spec_file.readlines(): - self.content.append(line) + # Parse extra info from spec file loc = self.parse_content() - # Find 'Packager' tag. Needed to circumvent a bug in python-rpm where # spec.sourceHeader[rpm.RPMTAG_PACKAGER] is not reset when a new spec # file is parsed @@ -170,7 +160,7 @@ class SpecFile(object): # Update sources info (basically possible macros expanded by spec.__init__() # And, double-check that we parsed spec content correctly - for (name, num, typ) in self.specinfo.sources: + for (name, num, typ) in self._specinfo.sources: # workaround rpm parsing bug if num >= MAX_SOURCE_NUMBER: num = 0 @@ -198,6 +188,22 @@ class SpecFile(object): self.orig_src_num = self.guess_orig_file() + def _parse_filtered_spec(self, skip_tags): + """Parse a filtered spec file in rpm-python""" + skip_tags = [tag.lower() for tag in skip_tags] + with tempfile.NamedTemporaryFile(prefix='gbp') as filtered: + filtered.writelines(str(line) for line in self.content + if str(line).split(":")[0].strip().lower() not in skip_tags) + filtered.flush() + try: + # Parse two times to circumvent a rpm-python problem where + # macros are not expanded if used before their definition + rpm.spec(filtered.name) + return rpm.spec(filtered.name) + except ValueError as err: + raise GbpError("RPM error while parsing %s: %s" % + (self.specfile, err)) + @property def version(self): """Get the (downstream) version""" -- cgit v1.2.3 From 9ab7ac8a2f392e7933194f8f64749f17b754a6b4 Mon Sep 17 00:00:00 2001 From: Markus Lehtonen Date: Tue, 4 Dec 2012 12:00:52 +0200 Subject: rpm refactor: split spec parsing into multiple methods Also, record all tags, macros and other "section" directives from the spec in separate internal structures. Here "section" stands for all scripts, scriptlets and other directives, i.e. "%prep", "%post", "%files" etc. Signed-off-by: Markus Lehtonen --- gbp/rpm/__init__.py | 436 ++++++++++++++++++++++++++++------------------------ tests/test_rpm.py | 4 +- 2 files changed, 241 insertions(+), 199 deletions(-) diff --git a/gbp/rpm/__init__.py b/gbp/rpm/__init__.py index db570f47..c23169c1 100644 --- a/gbp/rpm/__init__.py +++ b/gbp/rpm/__init__.py @@ -25,6 +25,7 @@ import tempfile import glob import shutil as shutil from optparse import OptionParser +from collections import defaultdict import gbp.command_wrappers as gbpc from gbp.errors import GbpError @@ -115,20 +116,27 @@ class SpecFile(object): """Class for parsing/modifying spec files""" tag_re = re.compile(r'^(?P[a-z]+)(?P[0-9]+)?\s*:\s*' '(?P\S(.*\S)?)\s*$', flags=re.I) - macro_re = re.compile(r'^%(?P[a-z]+)(?P[0-9]+)?' - '(\s+(?P.*))?$') + directive_re = re.compile(r'^%(?P[a-z]+)(?P[0-9]+)?' + '(\s+(?P.*))?$', flags=re.I) gbptag_re = re.compile(r'^\s*#\s*gbp-(?P[a-z-]+)' '(\s*:\s*(?P\S.*))?$', flags=re.I) + # Here "sections" stand for all scripts, scriptlets and other directives, + # but not macros + section_identifiers = ('package', 'description', 'prep', 'build', 'install', + 'clean', 'check', 'pre', 'preun', 'post', 'postun', 'verifyscript', + 'files', 'changelog', 'triggerin', 'triggerpostin', 'triggerun', + 'triggerpostun') def __init__(self, specfile): + # Load spec file into our special data structure self.specfile = os.path.abspath(specfile) self.specdir = os.path.dirname(self.specfile) - self.content = LinkedList() + self._content = LinkedList() try: with open(specfile) as spec_file: for line in spec_file.readlines(): - self.content.append(line) + self._content.append(line) except IOError as err: raise NoSpecError("Unable to read spec file: %s" % err) @@ -148,51 +156,26 @@ class SpecFile(object): self.packager = source_header[rpm.RPMTAG_PACKAGER] self.patches = {} self.sources = {} + self._tags = {} + self._special_directives = defaultdict(list) + self._gbp_tags = defaultdict(list) # Parse extra info from spec file - loc = self.parse_content() + self._parse_content() # Find 'Packager' tag. Needed to circumvent a bug in python-rpm where # spec.sourceHeader[rpm.RPMTAG_PACKAGER] is not reset when a new spec # file is parsed - if 'packagertag' not in loc: + if 'packager' not in self._tags: self.packager = None - # Update sources info (basically possible macros expanded by spec.__init__() - # And, double-check that we parsed spec content correctly - for (name, num, typ) in self._specinfo.sources: - # workaround rpm parsing bug - if num >= MAX_SOURCE_NUMBER: - num = 0 - if typ == 1: - if num in self.sources: - self.sources[num]['full_path'] = name - self.sources[num]['filename'] = os.path.basename(name) - self.sources[num]['filename_base'],\ - self.sources[num]['archive_fmt'],\ - self.sources[num]['compression'] = parse_archive_filename(os.path.basename(name)) - # Make a guess about the prefix in the archive - if self.sources[num]['archive_fmt']: - _name, _version = RpmPkgPolicy.guess_upstream_src_version(name) - if _name and _version: - self.sources[num]['prefix'] = "%s-%s/" % (_name, _version) - else: - self.sources[num]['prefix'] = self.sources[num]['filename_base'] + "/" - else: - gbp.log.err("BUG: we didn't correctly parse all 'Source' tags!") - if typ == 2: - if num in self.patches: - self.patches[num]['filename'] = name - else: - gbp.log.err("BUG: we didn't correctly parse all 'Patch' tags!") - self.orig_src_num = self.guess_orig_file() def _parse_filtered_spec(self, skip_tags): """Parse a filtered spec file in rpm-python""" skip_tags = [tag.lower() for tag in skip_tags] with tempfile.NamedTemporaryFile(prefix='gbp') as filtered: - filtered.writelines(str(line) for line in self.content + filtered.writelines(str(line) for line in self._content if str(line).split(":")[0].strip().lower() not in skip_tags) filtered.flush() try: @@ -225,6 +208,14 @@ class SpecFile(object): return self.sources[self.orig_src_num] return None + @property + def ignorepatches(self): + """Get numbers of ignored patches as a sorted list""" + if 'ignore-patches' in self._gbp_tags: + data = self._gbp_tags['ignore-patches'][-1]['args'].split() + return sorted([int(num) for num in data]) + return [] + def _macro_replace(self, matchobj): macro_dict = {'name': self.name, 'version': self.upstreamversion, @@ -252,37 +243,72 @@ class SpecFile(object): Write, possibly updated, spec to disk """ with open(self.specfile, 'w') as spec_file: - for line in self.content: + for line in self._content: spec_file.write(str(line)) + def _parse_tag(self, lineobj): + """Parse tag line""" + + line = str(lineobj) + + matchobj = self.tag_re.match(line) + if not matchobj: + return False + + tagname = matchobj.group('name').lower() + tagnum = int(matchobj.group('num')) if matchobj.group('num') else None + # 'Source:' tags + if tagname == 'source': + tagnum = 0 if tagnum is None else tagnum + if tagnum in self.sources: + self.sources[tagnum]['tag_line'] = lineobj + else: + self.sources[tagnum] = { + 'filename': os.path.basename(matchobj.group('name')), + 'tag_line': line, + 'prefix': None, + 'setup_options': None, } + # 'Patch:' tags + elif tagname == 'patch': + tagnum = 0 if tagnum is None else tagnum + new_patch = {'name': matchobj.group('name').strip(), + 'filename': matchobj.group('name'), + 'apply': False, + 'strip': '0', + 'macro_line': None, + 'autoupdate': True, + 'tag_line': lineobj} + self.patches[tagnum] = new_patch + + # Record all tag locations + try: + header = self._specinfo.packages[0].header + tagvalue = header[getattr(rpm, 'RPMTAG_%s' % tagname.upper())] + except AttributeError: + tagvalue = None + # We don't support "multivalue" tags like "Provides:" or "SourceX:" + if type(tagvalue) is list: + tagvalue = None + elif not tagvalue: + # Rpm python doesn't give BuildRequires, for some reason + if tagname not in ('buildrequires',) + self._filtertags: + gbp.log.warn("BUG: '%s:' tag not found by rpm" % tagname) + tagvalue = matchobj.group('value') + linerecord = {'line': lineobj, + 'num': tagnum, + 'linevalue': matchobj.group('value')} + if tagname in self._tags: + self._tags[tagname]['value'] = tagvalue + self._tags[tagname]['lines'].append(linerecord) + else: + self._tags[tagname] = {'value': tagvalue, 'lines': [linerecord]} - def parse_content(self): - """ - Go through spec file content line-by-line and (re-)parse info from it - """ - # Location of "interesting" tags and macros - ret = {} - # First, we parse the spec for special git-buildpackage tags, only - ignorepatch = [] - for i, lineobj in enumerate(self.content): - line = str(lineobj) - m = self.gbptag_re.match(line) - if m: - if m.group('name').lower() == 'ignore-patches': - dataitems = m.group('args').strip().split() - ignorepatch = sorted([int(num) for num in dataitems]) - elif m.group('name').lower() == 'patch-macros': - ret['patchmacrostart'] = lineobj - else: - gbp.log.info("Found unrecognized Gbp tag on line %s: " - "'%s'" % (i, line)) + return tagname - # Remove all autoupdate patches to be sure we're in sync - for patch in self.patches.keys(): - if not patch in ignorepatch: - self.patches.pop(patch) + def _parse_directive(self, lineobj): + """Parse special directive/scriptlet/macro lines""" - # Parser for patch macros + # Parser for '%patch' macros patchparser = OptionParser() patchparser.add_option("-p", dest="strip") patchparser.add_option("-s", dest="silence") @@ -290,138 +316,153 @@ class SpecFile(object): patchparser.add_option("-b", dest="backup") patchparser.add_option("-E", dest="removeempty") - # Parser for patch macros + # Parser for '%setup' macros setupparser = OptionParser() setupparser.add_option("-n", dest="name") setupparser.add_option("-c", dest="create_dir", action="store_true") setupparser.add_option("-D", dest="no_delete_dir", action="store_true") - setupparser.add_option("-T", dest="no_unpack_default", action="store_true") + setupparser.add_option("-T", dest="no_unpack_default", + action="store_true") setupparser.add_option("-b", dest="unpack_before") setupparser.add_option("-a", dest="unpack_after") setupparser.add_option("-q", dest="quiet", action="store_true") - for linenum, lineobj in enumerate(self.content): - line = str(lineobj) + line = str(lineobj) + matchobj = self.directive_re.match(line) + if not matchobj: + return None + + directivename = matchobj.group('name') + # '%patch' macros + directiveid = None + if directivename == 'patch': + arglist = matchobj.group('args').split() + (opts, args) = patchparser.parse_args(arglist) + if matchobj.group('num'): + directiveid = int(matchobj.group('num')) + elif opts.patchnum: + directiveid = int(opts.patchnum) + else: + directiveid = 0 + + if opts.strip: + self.patches[directiveid]['strip'] = opts.strip + self.patches[directiveid]['macro_line'] = lineobj + self.patches[directiveid]['apply'] = True + # '%setup' macros + elif directivename == 'setup': + arglist = matchobj.group('args').split() + (opts, args) = setupparser.parse_args(arglist) + srcnum = None + if opts.no_unpack_default: + if opts.unpack_before: + srcnum = int(opts.unpack_before) + elif opts.unpack_after: + srcnum = int(opts.unpack_after) + else: + srcnum = 0 + if srcnum != None and srcnum in self.sources: + self.sources[srcnum]['setup_options'] = opts + + # Record special directive/scriptlet/macro locations + if directivename in self.section_identifiers + ('setup', 'patch'): + linerecord = {'line': lineobj, + 'id': directiveid, + 'args': matchobj.group('args')} + self._special_directives[directivename].append(linerecord) + return directivename + + def _parse_gbp_tag(self, linenum, lineobj): + """Parse special git-buildpackage tags""" + + line = str(lineobj) + matchobj = self.gbptag_re.match(line) + if matchobj: + gbptagname = matchobj.group('name').lower() + if gbptagname not in ('ignore-patches', 'patch-macros'): + gbp.log.info("Found unrecognized Gbp tag on line %s: '%s'" % + (linenum, line)) + if matchobj.group('args'): + args = matchobj.group('args').strip() + else: + args = None + record = {'line': lineobj, 'args': args} + self._gbp_tags[gbptagname].append(record) + return gbptagname - # Parse tags - m = self.tag_re.match(line) - if m: - tagname = m.group('name').lower() - if m.group('num'): - tagnum = int(m.group('num')) - else: - tagnum = 0 - # 'Source:' tags - if tagname == 'source': - if tagnum in self.sources: - self.sources[tagnum]['tag_line'] = lineobj - else: - self.sources[tagnum] = { - 'full_path': m.group('name'), - 'filename': os.path.basename(m.group('name')), - 'tag_line': line, - 'prefix': None, - 'setup_options': None, } - ret['lastsourcetag'] = lineobj - # 'Patch:' tags - elif tagname == 'patch': - if tagnum in self.patches: - # For non-autoupdate patches we only update the lineobj - if tagnum in ignorepatch: - self.patches[tagnum]['tag_line'] = lineobj - else: - gbp.log.err("Patch%s found multiple times, " - "aborting as gbp spec/patch " - "autoupdate likely fails" % tagnum) - raise GbpError("RPM error while parsing spec, " - "duplicate patches found") - else: - new_patch = {'name': m.group('name').strip(), - 'filename': m.group('name'), - 'apply': False, - 'strip': '0', - 'macro_line': None, - 'autoupdate': not tagnum in ignorepatch, - 'tag_line': lineobj} - self.patches[tagnum] = new_patch - ret['lastpatchtag'] = lineobj - # Other tags - elif tagname == 'name': - ret['nametag'] = lineobj - elif tagname == 'packager': - ret['packagertag'] = lineobj - elif tagname == 'vcs': - ret['vcstag'] = lineobj - elif tagname == 'release': - ret['releasetag'] = lineobj + return None + + def _parse_content(self): + """ + Go through spec file content line-by-line and (re-)parse info from it + """ + in_preamble = True + for linenum, lineobj in enumerate(self._content): + matched = False + if in_preamble: + if self._parse_tag(lineobj): + continue + matched = self._parse_directive(lineobj) + if matched: + if matched in self.section_identifiers: + in_preamble = False continue + self._parse_gbp_tag(linenum, lineobj) - # Parse special macros - m = self.macro_re.match(line) - if m: - # '%patch' macro - if m.group('name') == 'patch': - (opts, args) = patchparser.parse_args(m.group('args').split()) - if m.group('num'): - patchnum = int(m.group('num')) - elif opts.patchnum: - patchnum = int(opts.patchnum) - else: - patchnum = 0 - - if opts.strip: - self.patches[patchnum]['strip'] = opts.strip - self.patches[patchnum]['macro_line'] = lineobj - self.patches[patchnum]['apply'] = True - ret['lastpatchmacro'] = lineobj - - # '%setup' macros - if m.group('name') == 'setup': - (opts, args) = setupparser.parse_args(m.group('args').split()) - srcnum = None - if opts.no_unpack_default: - if opts.unpack_before: - srcnum = int(opts.unpack_before) - elif opts.unpack_after: - srcnum = int(opts.unpack_after) - else: - srcnum = 0 - if srcnum != None and srcnum in self.sources: - self.sources[srcnum]['setup_options'] = opts - # Save the occurrence of last setup macro - ret['setupmacro'] = lineobj - - # '%prep' macro - if m.group('name') == 'prep': - ret['prepmacro'] = lineobj - return ret + # Update sources info (basically possible macros expanded by rpm) + # And, double-check that we parsed spec content correctly + for (name, num, typ) in self._specinfo.sources: + # workaround rpm parsing bug + if num >= MAX_SOURCE_NUMBER: + num = 0 + if typ == 1: + if num in self.sources: + self.sources[num]['filename'] = os.path.basename(name) + self.sources[num]['filename_base'],\ + self.sources[num]['archive_fmt'],\ + self.sources[num]['compression'] =\ + parse_archive_filename(os.path.basename(name)) + # Make a guess about the prefix in the archive + if self.sources[num]['archive_fmt']: + _name, _version = RpmPkgPolicy.guess_upstream_src_version(name) + if _name and _version: + self.sources[num]['prefix'] = "%s-%s/" % (_name, _version) + else: + self.sources[num]['prefix'] = self.sources[num]['filename_base'] + "/" + else: + gbp.log.err("BUG: we didn't correctly parse all 'Source' tags!") + if typ == 2: + if num in self.patches: + self.patches[num]['filename'] = name + else: + gbp.log.err("BUG: we didn't correctly parse all 'Patch' tags!") + + # Mark ignored patches + for patchnum in self.patches: + if patchnum in self.ignorepatches: + self.patches[patchnum]['autoupdate'] = False def set_tag(self, tag, value): """Update a tag in spec file content""" - loc = self.parse_content() - - key = tag.lower() + "tag" - if tag.lower() == 'vcs': + key = tag.lower() + if key == 'vcs': if value: text = '%-12s%s\n' % ('VCS:', value) - if key in loc: + if key in self._tags: gbp.log.info("Updating '%s' tag in spec" % tag) - loc[key].set_data(text) + self._tags[key]['lines'][-1]['line'].set_data(text) else: gbp.log.info("Adding '%s' tag to spec" % tag) - self.content.insert_after(loc['releasetag'], text) - elif key in loc: + self._content.insert_after( + self._tags['release']['lines'][-1]['line'], text) + elif key in self._tags: gbp.log.info("Removing '%s' tag from spec" % tag) - self.content.delete(loc[key]) + self._content.delete(self._tags[key]['lines'][-1]['line']) else: raise GbpError("Setting '%s:' tag not supported") def update_patches(self, patchfilenames): - """ - Update spec with new patch tags and patch macros. - """ - loc = self.parse_content() - + """Update spec with new patch tags and patch macros""" # Remove non-ignored patches last_removed_tag_line = None last_removed_macro_line = None @@ -431,18 +472,18 @@ class SpecFile(object): prev_line = patch['tag_line'].prev if re.match("^\s*#.*patch.*auto-generated", str(prev_line), flags=re.I): - self.content.delete(prev_line) + self._content.delete(prev_line) last_removed_tag_line = patch['tag_line'].prev - self.content.delete(patch['tag_line']) + self._content.delete(patch['tag_line']) if patch['macro_line']: # Remove a preceding comment line if it ends with # '.patch' or '.diff' plus an optional compression suffix prev_line = patch['macro_line'].prev if re.match("^\s*#.+(patch|diff)(\.(gz|bz2|xz|lzma))?\s*$", str(prev_line), flags=re.I): - self.content.delete(prev_line) + self._content.delete(prev_line) last_removed_macro_line = patch['macro_line'].prev - self.content.delete(patch['macro_line']) + self._content.delete(patch['macro_line']) # Remove from the patch list self.patches.pop(num) @@ -461,17 +502,17 @@ class SpecFile(object): if last_removed_tag_line: gbp.log.debug("Adding 'Patch' tags in place of the removed tags") line = last_removed_tag_line - elif 'lastpatchtag' in loc: + elif 'patch' in self._tags: gbp.log.debug("Adding new 'Patch' tags after the last 'Patch' tag") - line = loc['lastpatchtag'] - elif 'lastsourcetag' in loc: + line = self._tags['patch']['lines'][-1]['line'] + elif 'source' in self._tags: gbp.log.debug("Didn't find any old 'Patch' tags, adding new " "patches after the last 'Source' tag.") - line = loc['lastsourcetag'] + line = self._tags['source']['lines'][-1]['line'] else: gbp.log.debug("Didn't find any old 'Patch' or 'Source' tags, " "adding new patches after the last 'Name' tag.") - line = loc['nametag'] + line = self._tags['name']['lines'][-1]['line'] # Add all patch tag lines to content, in reversed order for n in reversed(sorted(self.patches.keys())): @@ -479,31 +520,33 @@ class SpecFile(object): if patch['autoupdate']: # "PatchXYZ:" text 12 chars wide, left aligned text = "%-12s%s\n" % ("Patch%d:" % n, patch['name']) - patch['tag_line'] = self.content.insert_after(line, text) + patch['tag_line'] = self._content.insert_after(line, text) # Finally, add a comment indicating gbp generated patches - self.content.insert_after(line, "# Patches auto-generated by " + self._content.insert_after(line, "# Patches auto-generated by " "git-buildpackage:\n") # Determine where to add %patch macro lines - if 'patchmacrostart' in loc: - gbp.log.debug("Adding patch macros after the start marker") - line = loc['patchmacrostart'] + if 'patch-macros' in self._gbp_tags: + gbp.log.debug("Adding '%patch' macros after the start marker") + line = self._gbp_tags['patch-macros'][-1]['line'] elif last_removed_macro_line: - gbp.log.debug("Adding patch macros in place of the removed macros") + gbp.log.debug("Adding '%patch' macros in place of the removed " + "macros") line = last_removed_macro_line - elif 'lastpatchmacro' in loc: - gbp.log.debug("Adding new patch macros after the last %patch macro") - line = loc['lastpatchmacro'] - elif 'setupmacro' in loc: + elif self._special_directives['patch']: + gbp.log.debug("Adding new '%patch' macros after the last existing" + "'%patch' macro") + line = self._special_directives['patch'][-1]['line'] + elif self._special_directives['setup']: gbp.log.debug("Didn't find any old '%patch' macros, adding new " "patches after the last '%setup' macro") - line = loc['setupmacro'] - elif 'prepmacro' in loc: - gbp.log.warn("Didn't find any old '%patch' macros or %setup macro," - " adding new patches directly after %prep macro") - line = loc['prepmacro'] + line = self._special_directives['setup'][-1]['line'] + elif self._special_directives['prep']: + gbp.log.warn("Didn't find any old '%patch' or '%setup' macros, " + "adding new patches directly after '%prep' directive") + line = self._special_directives['prep'][-1]['line'] else: - raise GbpError("Couldn't find location where to add patch macros") + raise GbpError("Couldn't determine where to add '%patch' macros") # Add all patch macro lines to content, in reversed order for n in reversed(sorted(self.patches.keys())): @@ -511,10 +554,9 @@ class SpecFile(object): if patch['autoupdate'] and patch['apply']: # We're adding from bottom to top... text = "%%patch%d -p%s\n" % (n, patch['strip']) - patch['macro_line'] = self.content.insert_after(line, text) + patch['macro_line'] = self._content.insert_after(line, text) # Use 'name', that is filename with macros not expanded - self.content.insert_after(line, "# %s\n" % patch['name']) - + self._content.insert_after(line, "# %s\n" % patch['name']) def patchseries(self): """ diff --git a/tests/test_rpm.py b/tests/test_rpm.py index 7f018195..33f9e00d 100644 --- a/tests/test_rpm.py +++ b/tests/test_rpm.py @@ -115,7 +115,6 @@ class TestSpecFile(object): orig = spec.orig_src assert orig['filename'] == 'gbp-test2-3.0.tar.gz' - assert orig['full_path'] == 'ftp://ftp.host.com/gbp-test2-3.0.tar.gz' assert orig['archive_fmt'] == 'tar' assert orig['compression'] == 'gzip' assert orig['prefix'] == '' @@ -167,8 +166,9 @@ class TestSpecFile(object): reference_spec = os.path.join(SPEC_DIR, 'gbp-test2-reference2.spec') spec = SpecFile(tmp_spec) - spec.update_patches(['new.patch']) + spec.update_patches(['1.patch', '2.patch']) spec.set_tag('vcs', 'myvcstag') + spec.update_patches(['new.patch']) spec.write_spec_file() assert filecmp.cmp(tmp_spec, reference_spec) is True -- cgit v1.2.3 From 73494bd84323cf0615ac37914f6fc095624fce0c Mon Sep 17 00:00:00 2001 From: Markus Lehtonen Date: Fri, 4 Jan 2013 14:37:13 +0200 Subject: rpm/LinkedList.delete: return the previous node The preceding node of the deleted node. However, return the next (i.e. the new first node) of the list if deleting the first node, and, return None if the list is empty after deletion. Signed-off-by: Markus Lehtonen --- gbp/rpm/linkedlist.py | 11 +++++++---- 1 file changed, 7 insertions(+), 4 deletions(-) diff --git a/gbp/rpm/linkedlist.py b/gbp/rpm/linkedlist.py index f1321776..ca000453 100644 --- a/gbp/rpm/linkedlist.py +++ b/gbp/rpm/linkedlist.py @@ -189,23 +189,26 @@ class LinkedList(collections.Iterable): >>> node3 = list.insert_before(node2, 'baz') >>> [str(data) for data in list] ['foo', 'baz', 'bar'] - >>> list.delete(node3) + >>> str(list.delete(node3)) + 'foo' >>> [str(data) for data in list] ['foo', 'bar'] >>> print "%s" % node3 - >>> list.delete(node1) + >>> str(list.delete(node1)) + 'bar' >>> [str(data) for data in list] ['bar'] >>> list.delete(node2) >>> [str(data) for data in list] [] """ + ret = node.prev if node is self._first: - self._first = self._first.next + ret = self._first = self._first.next if node is self._last: self._last = self._last.prev node.delete() - + return ret # vim:et:ts=4:sw=4:et:sts=4:ai:set list listchars=tab\:»·,trail\:·: -- cgit v1.2.3 From 216a420ffdeafd2ac65f12348290bea3327a00ab Mon Sep 17 00:00:00 2001 From: Markus Lehtonen Date: Thu, 3 Jan 2013 12:43:08 +0200 Subject: rpm refactor: rewrite set_tag functionality In addition to refactoring, make sure that we keep the internal _tags structure in sync. Changes the default place for new tags: add new tags after the 'Name:' tag instead of 'Release:'. Signed-off-by: Markus Lehtonen --- gbp/rpm/__init__.py | 87 ++++++++++++++++++---- gbp/scripts/buildpackage_rpm.py | 2 +- tests/test_rpm.py | 43 ++++++++++- tests/test_rpm_data/specs/gbp-test-reference2.spec | 2 +- .../specs/gbp-test-updates-reference.spec | 39 ++++++++++ tests/test_rpm_data/specs/gbp-test-updates.spec | 43 +++++++++++ 6 files changed, 197 insertions(+), 19 deletions(-) create mode 100644 tests/test_rpm_data/specs/gbp-test-updates-reference.spec create mode 100644 tests/test_rpm_data/specs/gbp-test-updates.spec diff --git a/gbp/rpm/__init__.py b/gbp/rpm/__init__.py index c23169c1..3c2454c7 100644 --- a/gbp/rpm/__init__.py +++ b/gbp/rpm/__init__.py @@ -442,24 +442,85 @@ class SpecFile(object): if patchnum in self.ignorepatches: self.patches[patchnum]['autoupdate'] = False - def set_tag(self, tag, value): + def _delete_tag(self, tag, num): + """Delete a tag""" + key = tag.lower() + tagname = '%s%s' % (tag, num) if num is not None else tag + if key not in self._tags: + gbp.log.warn("Trying to delete non-existent tag '%s:'" % tag) + return None + + sparedlines = [] + prev = None + for line in self._tags[key]['lines']: + if line['num'] == num: + gbp.log.debug("Removing '%s:' tag from spec" % tagname) + prev = self._content.delete(line['line']) + else: + sparedlines.append(line) + self._tags[key]['lines'] = sparedlines + if not self._tags[key]['lines']: + self._tags.pop(key) + return prev + + def _set_tag(self, tag, num, value, insertafter): + """Set a tag value""" + key = tag.lower() + tagname = '%s%s' % (tag, num) if num is not None else tag + value = value.strip() + if not value: + raise GbpError("Cannot set empty value to '%s:' tag" % tag) + + # Check type of tag, we don't support values for 'multivalue' tags + try: + header = self._specinfo.packages[0].header + tagvalue = header[getattr(rpm, 'RPMTAG_%s' % tagname.upper())] + except AttributeError: + tagvalue = None + tagvalue = None if type(tagvalue) is list else value + + # Try to guess the correct indentation from the previous or next tag + indent_re = re.compile(r'^([a-z]+([0-9]+)?\s*:\s*)', flags=re.I) + match = indent_re.match(str(insertafter)) + if not match: + match = indent_re.match(str(insertafter.next)) + indent = 12 if not match else len(match.group(1)) + text = '%-*s%s\n' % (indent, '%s:' % tagname, value) + if key in self._tags: + self._tags[key]['value'] = tagvalue + for line in reversed(self._tags[key]['lines']): + if line['num'] == num: + gbp.log.debug("Updating '%s:' tag in spec" % tagname) + line['line'].set_data(text) + line['linevalue'] = value + return line['line'] + + gbp.log.debug("Adding '%s:' tag after '%s...' line in spec" % + (tagname, str(insertafter)[0:20])) + line = self._content.insert_after(insertafter, text) + linerec = {'line': line, 'num': num, 'linevalue': value} + if key in self._tags: + self._tags[key]['lines'].append(linerec) + else: + self._tags[key] = {'value': tagvalue, 'lines': [linerec]} + return line + + def set_tag(self, tag, num, value, insertafter=None): """Update a tag in spec file content""" key = tag.lower() - if key == 'vcs': + tagname = '%s%s' % (tag, num) if num is not None else tag + if key in ('patch', 'vcs'): + if key in self._tags: + insertafter = key + elif not insertafter in self._tags: + insertafter = 'name' + after_line = self._tags[insertafter]['lines'][-1]['line'] if value: - text = '%-12s%s\n' % ('VCS:', value) - if key in self._tags: - gbp.log.info("Updating '%s' tag in spec" % tag) - self._tags[key]['lines'][-1]['line'].set_data(text) - else: - gbp.log.info("Adding '%s' tag to spec" % tag) - self._content.insert_after( - self._tags['release']['lines'][-1]['line'], text) + self._set_tag(tag, num, value, after_line) elif key in self._tags: - gbp.log.info("Removing '%s' tag from spec" % tag) - self._content.delete(self._tags[key]['lines'][-1]['line']) + self._delete_tag(tag, num) else: - raise GbpError("Setting '%s:' tag not supported") + raise GbpError("Setting '%s:' tag not supported" % tagname) def update_patches(self, patchfilenames): """Update spec with new patch tags and patch macros""" diff --git a/gbp/scripts/buildpackage_rpm.py b/gbp/scripts/buildpackage_rpm.py index 187e6b28..338350c9 100755 --- a/gbp/scripts/buildpackage_rpm.py +++ b/gbp/scripts/buildpackage_rpm.py @@ -610,7 +610,7 @@ def main(argv): abbrev=40) + '-dirty' commit_sha1 = repo.rev_parse('HEAD') + '-dirty' # Put 'VCS:' tag to .spec - spec.set_tag('vcs', + spec.set_tag('VCS', None, options.spec_vcs_tag % {'tagname': tree_name, 'commit': commit_sha1}) spec.write_spec_file() diff --git a/tests/test_rpm.py b/tests/test_rpm.py index 33f9e00d..957c22db 100644 --- a/tests/test_rpm.py +++ b/tests/test_rpm.py @@ -30,6 +30,14 @@ DATA_DIR = os.path.abspath(os.path.splitext(__file__)[0] + '_data') SRPM_DIR = os.path.join(DATA_DIR, 'srpms') SPEC_DIR = os.path.join(DATA_DIR, 'specs') +class SpecFileTester(SpecFile): + """Helper class for testing""" + + def protected(self, name): + """Get a protected member""" + return super(SpecFileTester, self).__getattribute__(name) + + class TestSrcRpmFile(object): """Test L{gbp.rpm.SrcRpmFile}""" @@ -77,7 +85,7 @@ class TestSpecFile(object): def test_spec(self): """Test parsing of a valid spec file""" spec_filepath = os.path.join(SPEC_DIR, 'gbp-test.spec') - spec = SpecFile(spec_filepath) + spec = SpecFileTester(spec_filepath) # Test basic properties assert spec.specfile == spec_filepath @@ -155,7 +163,7 @@ class TestSpecFile(object): # Test adding the VCS tag reference_spec = os.path.join(SPEC_DIR, 'gbp-test-reference2.spec') - spec.set_tag('vcs', 'myvcstag') + spec.set_tag('VCS', None, 'myvcstag') spec.write_spec_file() assert filecmp.cmp(tmp_spec, reference_spec) is True @@ -167,14 +175,41 @@ class TestSpecFile(object): reference_spec = os.path.join(SPEC_DIR, 'gbp-test2-reference2.spec') spec = SpecFile(tmp_spec) spec.update_patches(['1.patch', '2.patch']) - spec.set_tag('vcs', 'myvcstag') + spec.set_tag('VCS', None, 'myvcstag') spec.update_patches(['new.patch']) spec.write_spec_file() assert filecmp.cmp(tmp_spec, reference_spec) is True # Test removing the VCS tag reference_spec = os.path.join(SPEC_DIR, 'gbp-test2-reference.spec') - spec.set_tag('vcs', '') + spec.set_tag('VCS', None, '') + spec.write_spec_file() + assert filecmp.cmp(tmp_spec, reference_spec) is True + + def test_modifying(self): + """Test updating/deleting of tags and macros""" + tmp_spec = os.path.join(self.tmpdir, 'gbp-test.spec') + shutil.copy2(os.path.join(SPEC_DIR, 'gbp-test-updates.spec'), tmp_spec) + reference_spec = os.path.join(SPEC_DIR, + 'gbp-test-updates-reference.spec') + spec = SpecFileTester(tmp_spec) + + # Mangle tags + prev = spec.protected('_delete_tag')('Vendor', None) + spec.protected('_set_tag')('License', None, 'new license', prev) + spec.protected('_delete_tag')('source', 0) + spec.protected('_delete_tag')('patch', 0) + spec.protected('_delete_tag')('patch', -1) + prev = spec.protected('_delete_tag')('invalidtag', None) + + with assert_raises(GbpError): + # Check that setting empty value fails + spec.protected('_set_tag')('Version', None, '', prev) + with assert_raises(GbpError): + # Check that setting invalid tag with public method fails + spec.set_tag('invalidtag', None, 'value') + + # Check resulting spec file spec.write_spec_file() assert filecmp.cmp(tmp_spec, reference_spec) is True diff --git a/tests/test_rpm_data/specs/gbp-test-reference2.spec b/tests/test_rpm_data/specs/gbp-test-reference2.spec index f006fc77..1cd922b2 100644 --- a/tests/test_rpm_data/specs/gbp-test-reference2.spec +++ b/tests/test_rpm_data/specs/gbp-test-reference2.spec @@ -1,8 +1,8 @@ Name: gbp-test +VCS: myvcstag Summary: Test package for git-buildpackage Version: 1.0 Release: 1 -VCS: myvcstag Group: Development/Libraries License: GPLv2 Source: %{name}-%{version}.tar.bz2 diff --git a/tests/test_rpm_data/specs/gbp-test-updates-reference.spec b/tests/test_rpm_data/specs/gbp-test-updates-reference.spec new file mode 100644 index 00000000..557f8b77 --- /dev/null +++ b/tests/test_rpm_data/specs/gbp-test-updates-reference.spec @@ -0,0 +1,39 @@ +# +# Spec file for testing deleting/adding/updating tags and macros +# + +# Gbp-Undefined-Tag: foobar + +# Test that we accept different cases +Name: my_name +Version: 0 +Release: 1 +Summary: my_summary +License: new license +Distribution: my_distribution +Group: my_group +Packager: my_packager +Url: my_url +Vcs: my_vcs +BuildRoot: my_buildroot +Provides: my_provides +Requires: my_requires +Conflicts: my_conflicts +Obsoletes: my_obsoletes +BuildConflicts: my_buildconflicts +BuildRequires: my_buildrequires +AutoReqProv: No +AutoReq: No +AutoProv: No +DistTag: my_disttag +BugUrl: my_bugurl +Collections: my_collections + +%description +Package for testing GBP. + +%prep + +%build + +%install diff --git a/tests/test_rpm_data/specs/gbp-test-updates.spec b/tests/test_rpm_data/specs/gbp-test-updates.spec new file mode 100644 index 00000000..1cdcb212 --- /dev/null +++ b/tests/test_rpm_data/specs/gbp-test-updates.spec @@ -0,0 +1,43 @@ +# +# Spec file for testing deleting/adding/updating tags and macros +# + +# Gbp-Undefined-Tag: foobar + +# Test that we accept different cases +Name: my_name +Version: 0 +Release: 1 +Summary: my_summary +License: my_license +Distribution: my_distribution +Vendor: my_vendor +Group: my_group +Packager: my_packager +Url: my_url +Vcs: my_vcs +Source: my_source +Patch: my_%patch_fn_base +Patch0: my_%{patch_fn_base}0 +BuildRoot: my_buildroot +Provides: my_provides +Requires: my_requires +Conflicts: my_conflicts +Obsoletes: my_obsoletes +BuildConflicts: my_buildconflicts +BuildRequires: my_buildrequires +AutoReqProv: No +AutoReq: No +AutoProv: No +DistTag: my_disttag +BugUrl: my_bugurl +Collections: my_collections + +%description +Package for testing GBP. + +%prep + +%build + +%install -- cgit v1.2.3 From 4672c356dc7f3a541c7dddcf28a81cc5c70e84d5 Mon Sep 17 00:00:00 2001 From: Markus Lehtonen Date: Fri, 11 Jan 2013 16:28:05 +0200 Subject: rpm helpers: implement _set/delete_special_macro() methods Currently intended for updating '%patch' macros. Signed-off-by: Markus Lehtonen --- gbp/rpm/__init__.py | 44 ++++++++++++++++++++++ tests/test_rpm.py | 12 +++++- .../specs/gbp-test-updates-reference.spec | 3 ++ tests/test_rpm_data/specs/gbp-test-updates.spec | 6 ++- 4 files changed, 63 insertions(+), 2 deletions(-) diff --git a/gbp/rpm/__init__.py b/gbp/rpm/__init__.py index 3c2454c7..1453f24b 100644 --- a/gbp/rpm/__init__.py +++ b/gbp/rpm/__init__.py @@ -522,6 +522,50 @@ class SpecFile(object): else: raise GbpError("Setting '%s:' tag not supported" % tagname) + def _delete_special_macro(self, name, identifier): + """Delete a special macro line in spec file content""" + if name != 'patch': + raise GbpError("Deleting '%s:' macro not supported" % name) + + key = name.lower() + fullname = '%%%s%s' % (name, identifier) + sparedlines = [] + prev = None + for line in self._special_directives[key]: + if line['id'] == identifier: + gbp.log.debug("Removing '%s' macro from spec" % fullname) + prev = self._content.delete(line['line']) + else: + sparedlines.append(line) + self._special_directives[key] = sparedlines + if not prev: + gbp.log.warn("Tried to delete non-existent macro '%s'" % fullname) + return prev + + def _set_special_macro(self, name, identifier, args, insertafter): + """Update a special macro line in spec file content""" + key = name.lower() + fullname = '%%%s%s' % (name, identifier) + if key != 'patch': + raise GbpError("Setting '%s' macro not supported" % name) + + updated = 0 + text = "%%%s%d %s\n" % (name, identifier, args) + for line in self._special_directives[key]: + if line['id'] == identifier: + gbp.log.debug("Updating '%s' macro in spec" % fullname) + line['args'] = args + line['line'].set_data(text) + ret = line['line'] + updated += 1 + if not updated: + gbp.log.debug("Adding '%s' macro after '%s...' line in spec" % + (fullname, str(insertafter)[0:20])) + ret = self._content.insert_after(insertafter, text) + linerec = {'line': ret, 'id': identifier, 'args': args} + self._special_directives[key].append(linerec) + return ret + def update_patches(self, patchfilenames): """Update spec with new patch tags and patch macros""" # Remove non-ignored patches diff --git a/tests/test_rpm.py b/tests/test_rpm.py index 957c22db..709713d9 100644 --- a/tests/test_rpm.py +++ b/tests/test_rpm.py @@ -198,8 +198,8 @@ class TestSpecFile(object): prev = spec.protected('_delete_tag')('Vendor', None) spec.protected('_set_tag')('License', None, 'new license', prev) spec.protected('_delete_tag')('source', 0) + spec.protected('_delete_tag')('patch', 1) spec.protected('_delete_tag')('patch', 0) - spec.protected('_delete_tag')('patch', -1) prev = spec.protected('_delete_tag')('invalidtag', None) with assert_raises(GbpError): @@ -209,6 +209,16 @@ class TestSpecFile(object): # Check that setting invalid tag with public method fails spec.set_tag('invalidtag', None, 'value') + # Mangle macros + prev = spec.protected('_delete_special_macro')('patch', 0) + spec.protected('_delete_special_macro')('patch', 123) + spec.protected('_set_special_macro')('patch', 1, 'my new args', prev) + with assert_raises(GbpError): + spec.protected('_delete_special_macro')('invalidmacro', 0) + with assert_raises(GbpError): + spec.protected('_set_special_macro')('invalidmacro', 0, 'args', + prev) + # Check resulting spec file spec.write_spec_file() assert filecmp.cmp(tmp_spec, reference_spec) is True diff --git a/tests/test_rpm_data/specs/gbp-test-updates-reference.spec b/tests/test_rpm_data/specs/gbp-test-updates-reference.spec index 557f8b77..e6e6846c 100644 --- a/tests/test_rpm_data/specs/gbp-test-updates-reference.spec +++ b/tests/test_rpm_data/specs/gbp-test-updates-reference.spec @@ -33,6 +33,9 @@ Collections: my_collections Package for testing GBP. %prep +%setup -n my_prefix + +%patch1 my new args %build diff --git a/tests/test_rpm_data/specs/gbp-test-updates.spec b/tests/test_rpm_data/specs/gbp-test-updates.spec index 1cdcb212..19912442 100644 --- a/tests/test_rpm_data/specs/gbp-test-updates.spec +++ b/tests/test_rpm_data/specs/gbp-test-updates.spec @@ -18,7 +18,7 @@ Url: my_url Vcs: my_vcs Source: my_source Patch: my_%patch_fn_base -Patch0: my_%{patch_fn_base}0 +Patch1: my_%{patch_fn_base}1 BuildRoot: my_buildroot Provides: my_provides Requires: my_requires @@ -37,6 +37,10 @@ Collections: my_collections Package for testing GBP. %prep +%setup -n my_prefix + +%patch -b my_patch +%patch -P1 -b my_patch0 %build -- cgit v1.2.3 From e48816d3a3e175b64aca5dcc168739847f44cbe5 Mon Sep 17 00:00:00 2001 From: Markus Lehtonen Date: Thu, 3 Jan 2013 16:03:23 +0200 Subject: rpm helpers: parse 'nosource' and 'nopatch' sources correctly Signed-off-by: Markus Lehtonen --- gbp/rpm/__init__.py | 4 ++-- tests/test_rpm_data/specs/gbp-test-updates-reference.spec | 2 ++ tests/test_rpm_data/specs/gbp-test-updates.spec | 2 ++ 3 files changed, 6 insertions(+), 2 deletions(-) diff --git a/gbp/rpm/__init__.py b/gbp/rpm/__init__.py index 1453f24b..b179605e 100644 --- a/gbp/rpm/__init__.py +++ b/gbp/rpm/__init__.py @@ -415,7 +415,7 @@ class SpecFile(object): # workaround rpm parsing bug if num >= MAX_SOURCE_NUMBER: num = 0 - if typ == 1: + if typ == 1 or typ == 9: if num in self.sources: self.sources[num]['filename'] = os.path.basename(name) self.sources[num]['filename_base'],\ @@ -431,7 +431,7 @@ class SpecFile(object): self.sources[num]['prefix'] = self.sources[num]['filename_base'] + "/" else: gbp.log.err("BUG: we didn't correctly parse all 'Source' tags!") - if typ == 2: + if typ == 2 or typ == 10: if num in self.patches: self.patches[num]['filename'] = name else: diff --git a/tests/test_rpm_data/specs/gbp-test-updates-reference.spec b/tests/test_rpm_data/specs/gbp-test-updates-reference.spec index e6e6846c..eae2739a 100644 --- a/tests/test_rpm_data/specs/gbp-test-updates-reference.spec +++ b/tests/test_rpm_data/specs/gbp-test-updates-reference.spec @@ -15,6 +15,8 @@ Group: my_group Packager: my_packager Url: my_url Vcs: my_vcs +Nosource: 0 +Nopatch: 1 BuildRoot: my_buildroot Provides: my_provides Requires: my_requires diff --git a/tests/test_rpm_data/specs/gbp-test-updates.spec b/tests/test_rpm_data/specs/gbp-test-updates.spec index 19912442..0bc15712 100644 --- a/tests/test_rpm_data/specs/gbp-test-updates.spec +++ b/tests/test_rpm_data/specs/gbp-test-updates.spec @@ -19,6 +19,8 @@ Vcs: my_vcs Source: my_source Patch: my_%patch_fn_base Patch1: my_%{patch_fn_base}1 +Nosource: 0 +Nopatch: 1 BuildRoot: my_buildroot Provides: my_provides Requires: my_requires -- cgit v1.2.3 From e5dda623f7428175004fb8cffe4b669f19cd4132 Mon Sep 17 00:00:00 2001 From: Markus Lehtonen Date: Thu, 3 Jan 2013 17:08:36 +0200 Subject: rpm helpers: support all tags Support all 'non-list' tags that we know of. Signed-off-by: Markus Lehtonen --- gbp/rpm/__init__.py | 18 +++++-- gbp/rpm/policy.py | 2 +- tests/test_rpm.py | 19 ++++++++ tests/test_rpm_data/specs/gbp-test-tags.spec | 70 ++++++++++++++++++++++++++++ 4 files changed, 105 insertions(+), 4 deletions(-) create mode 100644 tests/test_rpm_data/specs/gbp-test-tags.spec diff --git a/gbp/rpm/__init__.py b/gbp/rpm/__init__.py index b179605e..cc42b530 100644 --- a/gbp/rpm/__init__.py +++ b/gbp/rpm/__init__.py @@ -143,6 +143,14 @@ class SpecFile(object): # Use rpm-python to parse the spec file content self._filtertags = ("excludearch", "excludeos", "exclusivearch", "exclusiveos","buildarch") + self._listtags = self._filtertags + ('source', 'patch', + 'requires', 'conflicts', 'recommends', + 'suggests', 'supplements', 'enhances', + 'provides', 'obsoletes', 'buildrequires', + 'buildconflicts', 'buildrecommends', + 'buildsuggests', 'buildsupplements', + 'buildenhances', 'collections', + 'nosource', 'nopatch') self._specinfo = self._parse_filtered_spec(self._filtertags) # Other initializations @@ -287,11 +295,15 @@ class SpecFile(object): except AttributeError: tagvalue = None # We don't support "multivalue" tags like "Provides:" or "SourceX:" - if type(tagvalue) is list: + # Rpm python doesn't support many of these, thus the explicit list + if type(tagvalue) is int or type(tagvalue) is long: + tagvalue = str(tagvalue) + elif type(tagvalue) is list or tagname in self._listtags: tagvalue = None elif not tagvalue: - # Rpm python doesn't give BuildRequires, for some reason - if tagname not in ('buildrequires',) + self._filtertags: + # Rpm python doesn't give the following, for reason or another + if tagname not in ('buildroot', 'autoprov', 'autoreq', + 'autoreqprov') + self._filtertags: gbp.log.warn("BUG: '%s:' tag not found by rpm" % tagname) tagvalue = matchobj.group('value') linerecord = {'line': lineobj, diff --git a/gbp/rpm/policy.py b/gbp/rpm/policy.py index f73f1d92..d5b096ba 100644 --- a/gbp/rpm/policy.py +++ b/gbp/rpm/policy.py @@ -23,7 +23,7 @@ class RpmPkgPolicy(PkgPolicy): """Packaging policy for RPM""" # Special rpmlib python module for GBP (only) - python_rpmlib_module_name = "rpmlibgbp" + python_rpmlib_module_name = "rpm_tizen" alnum = 'a-zA-Z0-9' # Valid characters for RPM pkg name diff --git a/tests/test_rpm.py b/tests/test_rpm.py index 709713d9..7124c991 100644 --- a/tests/test_rpm.py +++ b/tests/test_rpm.py @@ -231,6 +231,25 @@ class TestSpecFile(object): # Check that we quess orig source and prefix correctly assert spec.orig_src['prefix'] == 'foobar/' + def test_tags(self): + """Test parsing of all the different tags of spec file""" + spec_filepath = os.path.join(SPEC_DIR, 'gbp-test-tags.spec') + spec = SpecFileTester(spec_filepath) + + # Check all the tags + for name, val in spec.protected('_tags').iteritems(): + rval = None + if name in ('version', 'release', 'epoch'): + rval = '0' + elif name in ('autoreq', 'autoprov', 'autoreqprov'): + rval = 'No' + elif name not in spec.protected('_listtags'): + rval = 'my_%s' % name + if rval: + assert val['value'] == rval, ("'%s:' is '%s', expecting '%s'" % + (name, val['value'], rval)) + assert spec.ignorepatches == [] + class TestUtilityFunctions(object): """Test utility functions of L{gbp.rpm}""" diff --git a/tests/test_rpm_data/specs/gbp-test-tags.spec b/tests/test_rpm_data/specs/gbp-test-tags.spec new file mode 100644 index 00000000..9841a39e --- /dev/null +++ b/tests/test_rpm_data/specs/gbp-test-tags.spec @@ -0,0 +1,70 @@ +# +# Spec file for testing all RPM tags (that we know of +# + +%define suse_release %(test -e /etc/SuSE-release && head -n1 /etc/SuSE-release | cut -d ' ' -f2 | cut --output-delimiter=0 -d. -f1,2 || echo 0) +%if "%{suse_release}" >= "1201" +%define test_weak_dep_tags 1 +%endif + +%define test_arch_os_tags %(test -n "$GBP_SKIP_ARCH_OS_TAGS" && echo 0 || echo 1) + +# Gbp-Undefined-Tag: foobar + +# Test that we accept different cases +NAME: my_name +version: 0 +ReLeasE: 0 + +# Rest of the tags +Epoch: 0 +Summary: my_summary +License: my_license +Distribution: my_distribution +Vendor: my_vendor +Group: my_group +Packager: my_packager +Url: my_url +Vcs: my_vcs +Source: my_source +Patch0: my_patch +Nosource: 0 +Nopatch: 0 +#Icon: my_icon +BuildRoot: my_buildroot +Provides: my_provides +Requires: my_requires +Conflicts: my_conflicts +Obsoletes: my_obsoletes +BuildConflicts: my_buildconflicts +BuildRequires: my_buildrequires +AutoReqProv: No +AutoReq: No +AutoProv: No +DistTag: my_disttag +BugUrl: my_bugurl +Collections: my_collections + +%if 0%{?test_weak_dep_tags} +Recommends: my_recommends +Suggests: my_suggests +Supplements: my_supplements +Enhances: my_enhances +BuildRecommends:my_buildrecommends +BuildSuggests: my_buildsuggests +BuildSupplements:my_buildsupplements +BuildEnhances: my_buildenhances +%endif + +# These should be filtered out by GBP +%if "%{test_arch_os_tags}" != "0" +BuildArch: my_buildarch +ExcludeArch: my_excludearch +ExclusiveArch: my_exclusivearch +ExcludeOs: my_excludeos +ExclusiveOs: my_exclusiveos +%endif + +%description +Package for testing GBP. + -- cgit v1.2.3 From 0d8b168f3ccdde42d0e0dea8e69643da67d8bf61 Mon Sep 17 00:00:00 2001 From: Markus Lehtonen Date: Fri, 11 Jan 2013 16:36:28 +0200 Subject: rpm helpers: yet another fix to patch numbering 'Patch:' does not indicate "patch number 0". Patch: and 'Patch0:' can both be present in the same spec file. Signed-off-by: Markus Lehtonen --- gbp/rpm/__init__.py | 13 ++++++------- tests/test_rpm.py | 8 +++++--- tests/test_rpm_data/rpmbuild/SPECS/gbp-test2.spec | 2 +- tests/test_rpm_data/specs/gbp-test-tags.spec | 3 ++- tests/test_rpm_data/specs/gbp-test-updates-reference.spec | 4 ++-- tests/test_rpm_data/specs/gbp-test-updates.spec | 6 +++--- tests/test_rpm_data/specs/gbp-test2-reference.spec | 6 +++--- tests/test_rpm_data/specs/gbp-test2-reference2.spec | 6 +++--- 8 files changed, 25 insertions(+), 23 deletions(-) diff --git a/gbp/rpm/__init__.py b/gbp/rpm/__init__.py index cc42b530..c01b44c5 100644 --- a/gbp/rpm/__init__.py +++ b/gbp/rpm/__init__.py @@ -43,9 +43,6 @@ except ImportError: gbp.log.debug("Failed to import '%s' as rpm python module, using host's default rpm library instead" % RpmPkgPolicy.python_rpmlib_module_name) import rpm -# define a large number to check the valid id of source file -MAX_SOURCE_NUMBER = 99999 - class NoSpecError(Exception): """Spec file parsing error""" @@ -278,7 +275,7 @@ class SpecFile(object): 'setup_options': None, } # 'Patch:' tags elif tagname == 'patch': - tagnum = 0 if tagnum is None else tagnum + tagnum = -1 if tagnum is None else tagnum new_patch = {'name': matchobj.group('name').strip(), 'filename': matchobj.group('name'), 'apply': False, @@ -355,7 +352,7 @@ class SpecFile(object): elif opts.patchnum: directiveid = int(opts.patchnum) else: - directiveid = 0 + directiveid = -1 if opts.strip: self.patches[directiveid]['strip'] = opts.strip @@ -425,8 +422,6 @@ class SpecFile(object): # And, double-check that we parsed spec content correctly for (name, num, typ) in self._specinfo.sources: # workaround rpm parsing bug - if num >= MAX_SOURCE_NUMBER: - num = 0 if typ == 1 or typ == 9: if num in self.sources: self.sources[num]['filename'] = os.path.basename(name) @@ -444,6 +439,10 @@ class SpecFile(object): else: gbp.log.err("BUG: we didn't correctly parse all 'Source' tags!") if typ == 2 or typ == 10: + # Patch tag without any number defined is treated by RPM as + # having number (2^31-1), we use number -1 + if num >= pow(2,30): + num = -1 if num in self.patches: self.patches[num]['filename'] = name else: diff --git a/tests/test_rpm.py b/tests/test_rpm.py index 7124c991..29ecb56c 100644 --- a/tests/test_rpm.py +++ b/tests/test_rpm.py @@ -198,8 +198,8 @@ class TestSpecFile(object): prev = spec.protected('_delete_tag')('Vendor', None) spec.protected('_set_tag')('License', None, 'new license', prev) spec.protected('_delete_tag')('source', 0) - spec.protected('_delete_tag')('patch', 1) spec.protected('_delete_tag')('patch', 0) + spec.protected('_delete_tag')('patch', -1) prev = spec.protected('_delete_tag')('invalidtag', None) with assert_raises(GbpError): @@ -210,9 +210,9 @@ class TestSpecFile(object): spec.set_tag('invalidtag', None, 'value') # Mangle macros - prev = spec.protected('_delete_special_macro')('patch', 0) + prev = spec.protected('_delete_special_macro')('patch', -1) spec.protected('_delete_special_macro')('patch', 123) - spec.protected('_set_special_macro')('patch', 1, 'my new args', prev) + spec.protected('_set_special_macro')('patch', 0, 'my new args', prev) with assert_raises(GbpError): spec.protected('_delete_special_macro')('invalidmacro', 0) with assert_raises(GbpError): @@ -250,6 +250,8 @@ class TestSpecFile(object): (name, val['value'], rval)) assert spec.ignorepatches == [] + assert spec.patches.keys() == [0, -1] + class TestUtilityFunctions(object): """Test utility functions of L{gbp.rpm}""" diff --git a/tests/test_rpm_data/rpmbuild/SPECS/gbp-test2.spec b/tests/test_rpm_data/rpmbuild/SPECS/gbp-test2.spec index 4180a877..dd9e2ec2 100644 --- a/tests/test_rpm_data/rpmbuild/SPECS/gbp-test2.spec +++ b/tests/test_rpm_data/rpmbuild/SPECS/gbp-test2.spec @@ -8,7 +8,7 @@ License: GPLv2 Source10: ftp://ftp.host.com/%{name}-%{version}.tar.gz Source: foo.txt Source20: bar.tar.gz -# Gbp-Ignore-Patches: 0 +# Gbp-Ignore-Patches: -1 Patch: my.patch Patch10: my2.patch Patch20: my3.patch diff --git a/tests/test_rpm_data/specs/gbp-test-tags.spec b/tests/test_rpm_data/specs/gbp-test-tags.spec index 9841a39e..47421a9d 100644 --- a/tests/test_rpm_data/specs/gbp-test-tags.spec +++ b/tests/test_rpm_data/specs/gbp-test-tags.spec @@ -27,7 +27,8 @@ Packager: my_packager Url: my_url Vcs: my_vcs Source: my_source -Patch0: my_patch +Patch: my_patch +Patch0: my_patch0 Nosource: 0 Nopatch: 0 #Icon: my_icon diff --git a/tests/test_rpm_data/specs/gbp-test-updates-reference.spec b/tests/test_rpm_data/specs/gbp-test-updates-reference.spec index eae2739a..ff56f589 100644 --- a/tests/test_rpm_data/specs/gbp-test-updates-reference.spec +++ b/tests/test_rpm_data/specs/gbp-test-updates-reference.spec @@ -16,7 +16,7 @@ Packager: my_packager Url: my_url Vcs: my_vcs Nosource: 0 -Nopatch: 1 +Nopatch: 0 BuildRoot: my_buildroot Provides: my_provides Requires: my_requires @@ -37,7 +37,7 @@ Package for testing GBP. %prep %setup -n my_prefix -%patch1 my new args +%patch0 my new args %build diff --git a/tests/test_rpm_data/specs/gbp-test-updates.spec b/tests/test_rpm_data/specs/gbp-test-updates.spec index 0bc15712..dc8ffbf9 100644 --- a/tests/test_rpm_data/specs/gbp-test-updates.spec +++ b/tests/test_rpm_data/specs/gbp-test-updates.spec @@ -18,9 +18,9 @@ Url: my_url Vcs: my_vcs Source: my_source Patch: my_%patch_fn_base -Patch1: my_%{patch_fn_base}1 +Patch0: my_%{patch_fn_base}0 Nosource: 0 -Nopatch: 1 +Nopatch: 0 BuildRoot: my_buildroot Provides: my_provides Requires: my_requires @@ -42,7 +42,7 @@ Package for testing GBP. %setup -n my_prefix %patch -b my_patch -%patch -P1 -b my_patch0 +%patch -P0 -b my_patch0 %build diff --git a/tests/test_rpm_data/specs/gbp-test2-reference.spec b/tests/test_rpm_data/specs/gbp-test2-reference.spec index fbb7ad82..e31930d7 100644 --- a/tests/test_rpm_data/specs/gbp-test2-reference.spec +++ b/tests/test_rpm_data/specs/gbp-test2-reference.spec @@ -8,10 +8,10 @@ License: GPLv2 Source10: ftp://ftp.host.com/%{name}-%{version}.tar.gz Source: foo.txt Source20: bar.tar.gz -# Gbp-Ignore-Patches: 0 +# Gbp-Ignore-Patches: -1 Patch: my.patch # Patches auto-generated by git-buildpackage: -Patch1: new.patch +Patch0: new.patch Packager: Markus Lehtonen %description @@ -27,7 +27,7 @@ echo "Do things" # Gbp-Patch-Macros # new.patch -%patch1 -p1 +%patch0 -p1 %build make diff --git a/tests/test_rpm_data/specs/gbp-test2-reference2.spec b/tests/test_rpm_data/specs/gbp-test2-reference2.spec index 02356d0a..095600d3 100644 --- a/tests/test_rpm_data/specs/gbp-test2-reference2.spec +++ b/tests/test_rpm_data/specs/gbp-test2-reference2.spec @@ -8,10 +8,10 @@ License: GPLv2 Source10: ftp://ftp.host.com/%{name}-%{version}.tar.gz Source: foo.txt Source20: bar.tar.gz -# Gbp-Ignore-Patches: 0 +# Gbp-Ignore-Patches: -1 Patch: my.patch # Patches auto-generated by git-buildpackage: -Patch1: new.patch +Patch0: new.patch Packager: Markus Lehtonen VCS: myvcstag @@ -28,7 +28,7 @@ echo "Do things" # Gbp-Patch-Macros # new.patch -%patch1 -p1 +%patch0 -p1 %build make -- cgit v1.2.3 From ea21b59f810bcf29cbdc68e2d866887022f3ee1f Mon Sep 17 00:00:00 2001 From: Markus Lehtonen Date: Fri, 4 Jan 2013 14:42:25 +0200 Subject: rpm: make SpecFile.update_patches() use new tag/macro methods Use new set/delete methods for updating the patches in the spec file. The internal patches structure is not updated and now only used when importing patches. Signed-off-by: Markus Lehtonen --- gbp/rpm/__init__.py | 102 ++++++++++++++++++++++------------------------------ 1 file changed, 43 insertions(+), 59 deletions(-) diff --git a/gbp/rpm/__init__.py b/gbp/rpm/__init__.py index c01b44c5..1000302b 100644 --- a/gbp/rpm/__init__.py +++ b/gbp/rpm/__init__.py @@ -580,99 +580,83 @@ class SpecFile(object): def update_patches(self, patchfilenames): """Update spec with new patch tags and patch macros""" # Remove non-ignored patches - last_removed_tag_line = None - last_removed_macro_line = None - for num, patch in self.patches.items(): - if patch['autoupdate']: + tag_prev = None + macro_prev = None + ignored = self.ignorepatches + # Remove 'Patch:̈́' tags + for tag in self._tags['patch']['lines']: + if not tag['num'] in ignored: + tag_prev = self._delete_tag('patch', tag['num']) # Remove a preceding comment if it seems to originate from GBP - prev_line = patch['tag_line'].prev if re.match("^\s*#.*patch.*auto-generated", - str(prev_line), flags=re.I): - self._content.delete(prev_line) - last_removed_tag_line = patch['tag_line'].prev - self._content.delete(patch['tag_line']) - if patch['macro_line']: - # Remove a preceding comment line if it ends with - # '.patch' or '.diff' plus an optional compression suffix - prev_line = patch['macro_line'].prev - if re.match("^\s*#.+(patch|diff)(\.(gz|bz2|xz|lzma))?\s*$", - str(prev_line), flags=re.I): - self._content.delete(prev_line) - last_removed_macro_line = patch['macro_line'].prev - self._content.delete(patch['macro_line']) - # Remove from the patch list - self.patches.pop(num) + str(tag_prev), flags=re.I): + tag_prev = self._content.delete(tag_prev) + + # Remove '%patch:' macros + for macro in self._special_directives['patch']: + if not macro['id'] in ignored: + # Remove a preceding comment line if it ends with '.patch' or + # '.diff' plus an optional compression suffix + macro_prev = self._delete_special_macro('patch', macro['id']) + if re.match("^\s*#.+(patch|diff)(\.(gz|bz2|xz|lzma))?\s*$", + str(macro_prev), flags=re.I): + macro_prev = self._content.delete(macro_prev) if len(patchfilenames) == 0: return - # Add new patches to the patch list - patchnum = sorted(self.patches.keys())[-1] + 1 if self.patches else 0 - gbp.log.debug("Starting autoupdate patch numbering from %s" % patchnum) - for ind, name in enumerate(patchfilenames): - self.patches[patchnum + ind] = { - 'name': name, 'filename': name, 'apply': True, 'strip': '1', - 'macro_line': None, 'autoupdate': True, 'tag_line': None} - # Determine where to add Patch tag lines - if last_removed_tag_line: + if tag_prev: gbp.log.debug("Adding 'Patch' tags in place of the removed tags") - line = last_removed_tag_line + tag_line = tag_prev elif 'patch' in self._tags: gbp.log.debug("Adding new 'Patch' tags after the last 'Patch' tag") - line = self._tags['patch']['lines'][-1]['line'] + tag_line = self._tags['patch']['lines'][-1]['line'] elif 'source' in self._tags: gbp.log.debug("Didn't find any old 'Patch' tags, adding new " "patches after the last 'Source' tag.") - line = self._tags['source']['lines'][-1]['line'] + tag_line = self._tags['source']['lines'][-1]['line'] else: gbp.log.debug("Didn't find any old 'Patch' or 'Source' tags, " "adding new patches after the last 'Name' tag.") - line = self._tags['name']['lines'][-1]['line'] - - # Add all patch tag lines to content, in reversed order - for n in reversed(sorted(self.patches.keys())): - patch = self.patches[n] - if patch['autoupdate']: - # "PatchXYZ:" text 12 chars wide, left aligned - text = "%-12s%s\n" % ("Patch%d:" % n, patch['name']) - patch['tag_line'] = self._content.insert_after(line, text) - # Finally, add a comment indicating gbp generated patches - self._content.insert_after(line, "# Patches auto-generated by " - "git-buildpackage:\n") + tag_line = self._tags['name']['lines'][-1]['line'] # Determine where to add %patch macro lines if 'patch-macros' in self._gbp_tags: gbp.log.debug("Adding '%patch' macros after the start marker") - line = self._gbp_tags['patch-macros'][-1]['line'] - elif last_removed_macro_line: + macro_line = self._gbp_tags['patch-macros'][-1]['line'] + elif macro_prev: gbp.log.debug("Adding '%patch' macros in place of the removed " "macros") - line = last_removed_macro_line + macro_line = macro_prev elif self._special_directives['patch']: gbp.log.debug("Adding new '%patch' macros after the last existing" "'%patch' macro") - line = self._special_directives['patch'][-1]['line'] + macro_line = self._special_directives['patch'][-1]['line'] elif self._special_directives['setup']: gbp.log.debug("Didn't find any old '%patch' macros, adding new " "patches after the last '%setup' macro") - line = self._special_directives['setup'][-1]['line'] + macro_line = self._special_directives['setup'][-1]['line'] elif self._special_directives['prep']: gbp.log.warn("Didn't find any old '%patch' or '%setup' macros, " "adding new patches directly after '%prep' directive") - line = self._special_directives['prep'][-1]['line'] + macro_line = self._special_directives['prep'][-1]['line'] else: raise GbpError("Couldn't determine where to add '%patch' macros") - # Add all patch macro lines to content, in reversed order - for n in reversed(sorted(self.patches.keys())): - patch = self.patches[n] - if patch['autoupdate'] and patch['apply']: - # We're adding from bottom to top... - text = "%%patch%d -p%s\n" % (n, patch['strip']) - patch['macro_line'] = self._content.insert_after(line, text) - # Use 'name', that is filename with macros not expanded - self._content.insert_after(line, "# %s\n" % patch['name']) + startnum = sorted(ignored)[-1] + 1 if ignored else 0 + gbp.log.debug("Starting autoupdate patch numbering from %s" % startnum) + # Add a comment indicating gbp generated patch tags + comment_text = "# Patches auto-generated by git-buildpackage:\n" + tag_line = self._content.insert_after(tag_line, comment_text) + for ind, name in enumerate(patchfilenames): + patchnum = startnum + ind + tag_line = self._set_tag("Patch", patchnum, name, tag_line) + # Add '%patch' macro and a preceding comment line + comment_text = "# %s\n" % name + macro_line = self._content.insert_after(macro_line, comment_text) + macro_line = self._set_special_macro('patch', patchnum, '-p1', + macro_line) def patchseries(self): """ -- cgit v1.2.3 From aecfc649d6825acc147f3009577bfeb688bdc874 Mon Sep 17 00:00:00 2001 From: Markus Lehtonen Date: Fri, 4 Jan 2013 15:10:02 +0200 Subject: rpm.SpecFile: change specfile attribute to represent filename There is specdir to get the (absolute) directory path. Signed-off-by: Markus Lehtonen --- gbp/rpm/__init__.py | 8 ++++---- gbp/scripts/buildpackage_rpm.py | 10 +++++----- gbp/scripts/import_srpm.py | 7 +++---- gbp/scripts/pq_rpm.py | 2 +- tests/test_rpm.py | 2 +- 5 files changed, 14 insertions(+), 15 deletions(-) diff --git a/gbp/rpm/__init__.py b/gbp/rpm/__init__.py index 1000302b..46cea28a 100644 --- a/gbp/rpm/__init__.py +++ b/gbp/rpm/__init__.py @@ -127,8 +127,8 @@ class SpecFile(object): def __init__(self, specfile): # Load spec file into our special data structure - self.specfile = os.path.abspath(specfile) - self.specdir = os.path.dirname(self.specfile) + self.specfile = os.path.basename(specfile) + self.specdir = os.path.dirname(os.path.abspath(specfile)) self._content = LinkedList() try: with open(specfile) as spec_file: @@ -247,7 +247,7 @@ class SpecFile(object): """ Write, possibly updated, spec to disk """ - with open(self.specfile, 'w') as spec_file: + with open(os.path.join(self.specdir, self.specfile), 'w') as spec_file: for line in self._content: spec_file.write(str(line)) @@ -663,7 +663,7 @@ class SpecFile(object): Return patches of the RPM as a gbp patchseries """ series = PatchSeries() - patchdir = os.path.dirname(self.specfile) + patchdir = self.specdir for n, p in sorted(self.patches.iteritems()): if p['autoupdate'] and p['apply']: fname = os.path.basename(p['filename']) diff --git a/gbp/scripts/buildpackage_rpm.py b/gbp/scripts/buildpackage_rpm.py index 338350c9..3c6b7c1c 100755 --- a/gbp/scripts/buildpackage_rpm.py +++ b/gbp/scripts/buildpackage_rpm.py @@ -517,9 +517,8 @@ def main(argv): pkgfiles = os.listdir(spec.specdir) for f in pkgfiles: src = os.path.join(spec.specdir, f) - if f == os.path.basename(spec.specfile): + if f == spec.specfile: dst = os.path.join(spec_dir, f) - spec.specfile = os.path.abspath(dst) else: dst = os.path.join(source_dir, f) try: @@ -530,7 +529,7 @@ def main(argv): shutil.copy2(src, dst) except IOError, err: raise GbpError, "Error exporting files: %s" % err - spec.specdir = spec_dir + spec.specdir = os.path.abspath(spec_dir) if options.orig_prefix != 'auto': options.orig_prefix = options.orig_prefix % dict(spec.version, @@ -570,9 +569,10 @@ def main(argv): # Finally build the package: if options.builder.startswith("rpmbuild"): - builder_args.extend([spec.specfile]) + builder_args.append(os.path.join(spec.specdir, + spec.specfile)) else: - builder_args.extend([os.path.basename(spec.specfile)]) + builder_args.append(spec.specfile) RunAtCommand(options.builder, builder_args, shell=True, extra_env={'GBP_BUILD_DIR': export_dir})(dir=export_dir) if options.postbuild: diff --git a/gbp/scripts/import_srpm.py b/gbp/scripts/import_srpm.py index 269101d9..bbaa4328 100755 --- a/gbp/scripts/import_srpm.py +++ b/gbp/scripts/import_srpm.py @@ -157,8 +157,7 @@ def import_spec_patches(repo, spec, dirs): repo.force_head('HEAD', hard=True) raise PatchImportError("Unable to update spec file, you need to edit" "and commit it manually") - repo.commit_all(msg=PATCH_AUTODELETE_COMMIT_MSG % - os.path.basename(spec.specfile)) + repo.commit_all(msg=PATCH_AUTODELETE_COMMIT_MSG % spec.specfile) def force_to_branch_head(repo, branch): @@ -331,7 +330,7 @@ def main(argv): for num, src in spec.sources.iteritems(): if num != spec.orig_src_num: files.append(src['filename']) - files.append(spec.specfile) + files.append(os.path.join(spec.specdir, spec.specfile)) for fname in files: fpath = os.path.join(dirs['src'], fname) if os.path.exists(fpath): @@ -469,7 +468,7 @@ def main(argv): if options.patch_import: spec = parse_spec(os.path.join(repo.path, options.packaging_dir, - os.path.basename(spec.specfile))) + spec.specfile)) import_spec_patches(repo, spec, dirs) commit = options.packaging_branch diff --git a/gbp/scripts/pq_rpm.py b/gbp/scripts/pq_rpm.py index ba34054c..8a938fa3 100755 --- a/gbp/scripts/pq_rpm.py +++ b/gbp/scripts/pq_rpm.py @@ -337,7 +337,7 @@ def import_spec_patches(repo, branch, options): repo.set_branch(branch) - return os.path.basename(spec.specfile) + return spec.specfile def rebase_pq(repo, branch, options): diff --git a/tests/test_rpm.py b/tests/test_rpm.py index 29ecb56c..68886e86 100644 --- a/tests/test_rpm.py +++ b/tests/test_rpm.py @@ -88,7 +88,7 @@ class TestSpecFile(object): spec = SpecFileTester(spec_filepath) # Test basic properties - assert spec.specfile == spec_filepath + assert spec.specfile == os.path.basename(spec_filepath) assert spec.specdir == os.path.dirname(spec_filepath) assert spec.specpath == spec_filepath -- cgit v1.2.3 From 821251cbd8d7076e49729ac88eabd92265caedec Mon Sep 17 00:00:00 2001 From: Markus Lehtonen Date: Fri, 11 Jan 2013 16:41:38 +0200 Subject: rpm.SpecFile: drop the internal 'patches' structure To get rid of duplicate data tracking. Also, add test for testing the macro expansion of patch and source names. Also add tests for SpecFile.patchseries. Signed-off-by: Markus Lehtonen --- gbp/rpm/__init__.py | 74 ++++++++++++++-------------- gbp/scripts/import_srpm.py | 4 +- gbp/scripts/pq_rpm.py | 20 ++++---- tests/test_rpm.py | 23 ++++++++- tests/test_rpm_data/specs/gbp-test-tags.spec | 7 ++- 5 files changed, 74 insertions(+), 54 deletions(-) diff --git a/gbp/rpm/__init__.py b/gbp/rpm/__init__.py index 46cea28a..693fe1a6 100644 --- a/gbp/rpm/__init__.py +++ b/gbp/rpm/__init__.py @@ -159,7 +159,6 @@ class SpecFile(object): self.epoch = str(source_header[rpm.RPMTAG_EPOCH]) \ if source_header[rpm.RPMTAG_EPOCH] != None else None self.packager = source_header[rpm.RPMTAG_PACKAGER] - self.patches = {} self.sources = {} self._tags = {} self._special_directives = defaultdict(list) @@ -221,6 +220,12 @@ class SpecFile(object): return sorted([int(num) for num in data]) return [] + def _patches(self): + """Get all patch tags as a dict""" + if 'patch' not in self._tags: + return {} + return {patch['num']: patch for patch in self._tags['patch']['lines']} + def _macro_replace(self, matchobj): macro_dict = {'name': self.name, 'version': self.upstreamversion, @@ -276,14 +281,6 @@ class SpecFile(object): # 'Patch:' tags elif tagname == 'patch': tagnum = -1 if tagnum is None else tagnum - new_patch = {'name': matchobj.group('name').strip(), - 'filename': matchobj.group('name'), - 'apply': False, - 'strip': '0', - 'macro_line': None, - 'autoupdate': True, - 'tag_line': lineobj} - self.patches[tagnum] = new_patch # Record all tag locations try: @@ -314,16 +311,21 @@ class SpecFile(object): return tagname - def _parse_directive(self, lineobj): - """Parse special directive/scriptlet/macro lines""" + @staticmethod + def _patch_macro_opts(args): + """Parse arguments of the '%patch' macro""" - # Parser for '%patch' macros patchparser = OptionParser() patchparser.add_option("-p", dest="strip") patchparser.add_option("-s", dest="silence") patchparser.add_option("-P", dest="patchnum") patchparser.add_option("-b", dest="backup") patchparser.add_option("-E", dest="removeempty") + arglist = args.split() + return patchparser.parse_args(arglist)[0] + + def _parse_directive(self, lineobj): + """Parse special directive/scriptlet/macro lines""" # Parser for '%setup' macros setupparser = OptionParser() @@ -345,19 +347,13 @@ class SpecFile(object): # '%patch' macros directiveid = None if directivename == 'patch': - arglist = matchobj.group('args').split() - (opts, args) = patchparser.parse_args(arglist) + opts = self._patch_macro_opts(matchobj.group('args')) if matchobj.group('num'): directiveid = int(matchobj.group('num')) elif opts.patchnum: directiveid = int(opts.patchnum) else: directiveid = -1 - - if opts.strip: - self.patches[directiveid]['strip'] = opts.strip - self.patches[directiveid]['macro_line'] = lineobj - self.patches[directiveid]['apply'] = True # '%setup' macros elif directivename == 'setup': arglist = matchobj.group('args').split() @@ -420,6 +416,7 @@ class SpecFile(object): # Update sources info (basically possible macros expanded by rpm) # And, double-check that we parsed spec content correctly + patches = self._patches() for (name, num, typ) in self._specinfo.sources: # workaround rpm parsing bug if typ == 1 or typ == 9: @@ -443,16 +440,11 @@ class SpecFile(object): # having number (2^31-1), we use number -1 if num >= pow(2,30): num = -1 - if num in self.patches: - self.patches[num]['filename'] = name + if num in patches: + patches[num]['linevalue'] = name else: gbp.log.err("BUG: we didn't correctly parse all 'Patch' tags!") - # Mark ignored patches - for patchnum in self.patches: - if patchnum in self.ignorepatches: - self.patches[patchnum]['autoupdate'] = False - def _delete_tag(self, tag, num): """Delete a tag""" key = tag.lower() @@ -584,7 +576,7 @@ class SpecFile(object): macro_prev = None ignored = self.ignorepatches # Remove 'Patch:̈́' tags - for tag in self._tags['patch']['lines']: + for tag in self._patches().values(): if not tag['num'] in ignored: tag_prev = self._delete_tag('patch', tag['num']) # Remove a preceding comment if it seems to originate from GBP @@ -658,20 +650,26 @@ class SpecFile(object): macro_line = self._set_special_macro('patch', patchnum, '-p1', macro_line) - def patchseries(self): - """ - Return patches of the RPM as a gbp patchseries - """ + def patchseries(self, unapplied=False, ignored=False): + """Return non-ignored patches of the RPM as a gbp patchseries""" series = PatchSeries() - patchdir = self.specdir - for n, p in sorted(self.patches.iteritems()): - if p['autoupdate'] and p['apply']: - fname = os.path.basename(p['filename']) - series.append(Patch(os.path.join(patchdir, fname), - strip = int(p['strip']))) + if 'patch' in self._tags: + tags = self._patches() + macros = {macro['id']: macro['args'] + for macro in self._special_directives['patch']} + ignored = [] if ignored else self.ignorepatches + + for num, tag in sorted(tags.iteritems()): + strip = 0 + if num in macros: + opts = self._patch_macro_opts(macros[num]) + strip = int(opts.strip) if opts.strip else 0 + if (unapplied or (num in macros)) and num not in ignored: + filename = os.path.basename(tag['linevalue']) + series.append(Patch(os.path.join(self.specdir, filename), + strip=strip)) return series - def guess_orig_file(self): """ Try to guess the name of the primary upstream/source archive diff --git a/gbp/scripts/import_srpm.py b/gbp/scripts/import_srpm.py index bbaa4328..92bb022b 100755 --- a/gbp/scripts/import_srpm.py +++ b/gbp/scripts/import_srpm.py @@ -325,8 +325,8 @@ def main(argv): raise # Need to copy files to the packaging directory given by caller - files = [os.path.basename(patch['filename']) \ - for patch in spec.patches.itervalues()] + files = [os.path.basename(patch.path) \ + for patch in spec.patchseries(unapplied=True, ignored=True)] for num, src in spec.sources.iteritems(): if num != spec.orig_src_num: files.append(src['filename']) diff --git a/gbp/scripts/pq_rpm.py b/gbp/scripts/pq_rpm.py index 8a938fa3..d3da13a8 100755 --- a/gbp/scripts/pq_rpm.py +++ b/gbp/scripts/pq_rpm.py @@ -140,17 +140,15 @@ def rm_patch_files(spec): marked as not maintained by gbp. """ # Remove all old patches from the spec dir - for n, p in spec.patches.iteritems(): - if p['autoupdate']: - f = os.path.join(spec.specdir, p['filename']) - gbp.log.debug("Removing '%s'" % f) - try: - os.unlink(f) - except OSError, (e, msg): - if e != errno.ENOENT: - raise GbpError, "Failed to remove patch: %s" % msg - else: - gbp.log.debug("%s does not exist." % f) + for patch in spec.patchseries(unapplied=True): + gbp.log.debug("Removing '%s'" % patch.path) + try: + os.unlink(patch.path) + except OSError as err: + if err.errno != errno.ENOENT: + raise GbpError("Failed to remove patch: %s" % err) + else: + gbp.log.debug("Patch %s does not exist." % patch.path) def update_patch_series(repo, spec, start, end, options): diff --git a/tests/test_rpm.py b/tests/test_rpm.py index 68886e86..728c8872 100644 --- a/tests/test_rpm.py +++ b/tests/test_rpm.py @@ -200,6 +200,7 @@ class TestSpecFile(object): spec.protected('_delete_tag')('source', 0) spec.protected('_delete_tag')('patch', 0) spec.protected('_delete_tag')('patch', -1) + assert spec.protected('_patches')() == {} prev = spec.protected('_delete_tag')('invalidtag', None) with assert_raises(GbpError): @@ -249,8 +250,28 @@ class TestSpecFile(object): assert val['value'] == rval, ("'%s:' is '%s', expecting '%s'" % (name, val['value'], rval)) assert spec.ignorepatches == [] + # Check patch numbers and patch filenames + patches = {patch['num']: patch['linevalue'] for patch in + spec.protected('_tags')['patch']['lines']} + assert patches == {0: 'my_patch0', -1: 'my_patch'} - assert spec.patches.keys() == [0, -1] + def test_patch_series(self): + """Test the getting the patches as a patchseries""" + spec_filepath = os.path.join(SPEC_DIR, 'gbp-test-native.spec') + spec = SpecFileTester(spec_filepath) + + assert len(spec.patchseries()) == 0 + spec.update_patches(['1.patch', '2.patch', '3.patch']) + assert len(spec.patchseries()) == 3 + spec.protected('_gbp_tags')['ignore-patches'].append({'args': "0"}) + spec.update_patches(['4.patch']) + assert len(spec.patchseries()) == 1 + assert len(spec.patchseries(ignored=True)) == 2 + spec.protected('_delete_special_macro')('patch', 0) + assert len(spec.patchseries(ignored=True)) == 1 + series = spec.patchseries(unapplied=True, ignored=True) + assert len(series) == 2 + assert os.path.basename(series[-1].path) == '4.patch' class TestUtilityFunctions(object): diff --git a/tests/test_rpm_data/specs/gbp-test-tags.spec b/tests/test_rpm_data/specs/gbp-test-tags.spec index 47421a9d..ee4c2b94 100644 --- a/tests/test_rpm_data/specs/gbp-test-tags.spec +++ b/tests/test_rpm_data/specs/gbp-test-tags.spec @@ -9,6 +9,9 @@ %define test_arch_os_tags %(test -n "$GBP_SKIP_ARCH_OS_TAGS" && echo 0 || echo 1) +%define source_fn_base source +%define patch_fn_base patch + # Gbp-Undefined-Tag: foobar # Test that we accept different cases @@ -27,8 +30,8 @@ Packager: my_packager Url: my_url Vcs: my_vcs Source: my_source -Patch: my_patch -Patch0: my_patch0 +Patch: my_%patch_fn_base +Patch0: my_%{patch_fn_base}0 Nosource: 0 Nopatch: 0 #Icon: my_icon -- cgit v1.2.3 From a27a9f9c173bf2a41ef0675a4b9f6d3e8dee263d Mon Sep 17 00:00:00 2001 From: Markus Lehtonen Date: Fri, 11 Jan 2013 16:43:32 +0200 Subject: rpm.SpecFile: drop the internal sources structure Get rid of duplicate data tracking. Signed-off-by: Markus Lehtonen Signed-off-by: Yigang Wen --- gbp/rpm/__init__.py | 164 ++++++++++++++++++++++----------------------- gbp/scripts/import_srpm.py | 6 +- tests/test_rpm.py | 3 + 3 files changed, 88 insertions(+), 85 deletions(-) diff --git a/gbp/rpm/__init__.py b/gbp/rpm/__init__.py index 693fe1a6..94297445 100644 --- a/gbp/rpm/__init__.py +++ b/gbp/rpm/__init__.py @@ -159,7 +159,6 @@ class SpecFile(object): self.epoch = str(source_header[rpm.RPMTAG_EPOCH]) \ if source_header[rpm.RPMTAG_EPOCH] != None else None self.packager = source_header[rpm.RPMTAG_PACKAGER] - self.sources = {} self._tags = {} self._special_directives = defaultdict(list) self._gbp_tags = defaultdict(list) @@ -173,7 +172,7 @@ class SpecFile(object): if 'packager' not in self._tags: self.packager = None - self.orig_src_num = self.guess_orig_file() + self.orig_src = self._guess_orig_file() def _parse_filtered_spec(self, skip_tags): """Parse a filtered spec file in rpm-python""" @@ -205,13 +204,6 @@ class SpecFile(object): """Get the dir/filename""" return os.path.join(self.specdir, self.specfile) - @property - def orig_src(self): - """ Get the orig src""" - if self.orig_src_num != None: - return self.sources[self.orig_src_num] - return None - @property def ignorepatches(self): """Get numbers of ignored patches as a sorted list""" @@ -226,6 +218,17 @@ class SpecFile(object): return {} return {patch['num']: patch for patch in self._tags['patch']['lines']} + def _sources(self): + """Get all source tags as a dict""" + if 'source' not in self._tags: + return {} + return {src['num']: src for src in self._tags['source']['lines']} + + def sources(self): + """Get all source tags as a dict""" + return {src['num']: src['linevalue'] + for src in self._sources().values()} + def _macro_replace(self, matchobj): macro_dict = {'name': self.name, 'version': self.upstreamversion, @@ -270,14 +273,6 @@ class SpecFile(object): # 'Source:' tags if tagname == 'source': tagnum = 0 if tagnum is None else tagnum - if tagnum in self.sources: - self.sources[tagnum]['tag_line'] = lineobj - else: - self.sources[tagnum] = { - 'filename': os.path.basename(matchobj.group('name')), - 'tag_line': line, - 'prefix': None, - 'setup_options': None, } # 'Patch:' tags elif tagname == 'patch': tagnum = -1 if tagnum is None else tagnum @@ -324,10 +319,10 @@ class SpecFile(object): arglist = args.split() return patchparser.parse_args(arglist)[0] - def _parse_directive(self, lineobj): - """Parse special directive/scriptlet/macro lines""" + @staticmethod + def _setup_macro_opts(args): + """Parse arguments of the '%setup' macro""" - # Parser for '%setup' macros setupparser = OptionParser() setupparser.add_option("-n", dest="name") setupparser.add_option("-c", dest="create_dir", action="store_true") @@ -337,6 +332,11 @@ class SpecFile(object): setupparser.add_option("-b", dest="unpack_before") setupparser.add_option("-a", dest="unpack_after") setupparser.add_option("-q", dest="quiet", action="store_true") + arglist = args.split() + return setupparser.parse_args(arglist)[0] + + def _parse_directive(self, lineobj): + """Parse special directive/scriptlet/macro lines""" line = str(lineobj) matchobj = self.directive_re.match(line) @@ -354,20 +354,6 @@ class SpecFile(object): directiveid = int(opts.patchnum) else: directiveid = -1 - # '%setup' macros - elif directivename == 'setup': - arglist = matchobj.group('args').split() - (opts, args) = setupparser.parse_args(arglist) - srcnum = None - if opts.no_unpack_default: - if opts.unpack_before: - srcnum = int(opts.unpack_before) - elif opts.unpack_after: - srcnum = int(opts.unpack_after) - else: - srcnum = 0 - if srcnum != None and srcnum in self.sources: - self.sources[srcnum]['setup_options'] = opts # Record special directive/scriptlet/macro locations if directivename in self.section_identifiers + ('setup', 'patch'): @@ -417,25 +403,15 @@ class SpecFile(object): # Update sources info (basically possible macros expanded by rpm) # And, double-check that we parsed spec content correctly patches = self._patches() - for (name, num, typ) in self._specinfo.sources: + sources = self._sources() + for name, num, typ in self._specinfo.sources: # workaround rpm parsing bug if typ == 1 or typ == 9: - if num in self.sources: - self.sources[num]['filename'] = os.path.basename(name) - self.sources[num]['filename_base'],\ - self.sources[num]['archive_fmt'],\ - self.sources[num]['compression'] =\ - parse_archive_filename(os.path.basename(name)) - # Make a guess about the prefix in the archive - if self.sources[num]['archive_fmt']: - _name, _version = RpmPkgPolicy.guess_upstream_src_version(name) - if _name and _version: - self.sources[num]['prefix'] = "%s-%s/" % (_name, _version) - else: - self.sources[num]['prefix'] = self.sources[num]['filename_base'] + "/" + if num in sources: + sources[num]['linevalue'] = name else: - gbp.log.err("BUG: we didn't correctly parse all 'Source' tags!") - if typ == 2 or typ == 10: + gbp.log.err("BUG: failed to parse all 'Source' tags!") + elif typ == 2 or typ == 10: # Patch tag without any number defined is treated by RPM as # having number (2^31-1), we use number -1 if num >= pow(2,30): @@ -443,7 +419,7 @@ class SpecFile(object): if num in patches: patches[num]['linevalue'] = name else: - gbp.log.err("BUG: we didn't correctly parse all 'Patch' tags!") + gbp.log.err("BUG: failed to parse all 'Patch' tags!") def _delete_tag(self, tag, num): """Delete a tag""" @@ -670,46 +646,70 @@ class SpecFile(object): strip=strip)) return series - def guess_orig_file(self): - """ - Try to guess the name of the primary upstream/source archive - returns a tuple with full file path, filename base, archive format and - compression method. - """ - orig_num = None - for (num, src) in sorted(self.sources.iteritems()): - filename = os.path.basename(src['filename']) - if filename.startswith(self.name): - # Take the first archive that starts with pkg name - if src['archive_fmt']: - orig_num = num - break - # otherwise we take the first archive - elif orig_num == None and src['archive_fmt']: - orig_num = num - # else don't accept + def _guess_orig_prefix(self, orig): + """Guess prefix for the orig file""" + # Make initial guess about the prefix in the archive + filename = orig['filename'] + name, version = RpmPkgPolicy.guess_upstream_src_version(filename) + if name and version: + prefix = "%s-%s/" % (name, version) + else: + prefix = orig['filename_base'] + "/" # Refine our guess about the prefix - if orig_num != None: - orig = self.sources[orig_num] - setup_opts = orig['setup_options'] - if setup_opts: - if setup_opts.create_dir: - orig['prefix'] = '' - elif setup_opts.name: + for macro in self._special_directives['setup']: + args = macro['args'] + opts = self._setup_macro_opts(args) + srcnum = None + if opts.no_unpack_default: + if opts.unpack_before: + srcnum = int(opts.unpack_before) + elif opts.unpack_after: + srcnum = int(opts.unpack_after) + else: + srcnum = 0 + if srcnum == orig['num']: + if opts.create_dir: + prefix = '' + elif opts.name: try: - orig['prefix'] = self.macro_expand(setup_opts.name) + \ - '/' + prefix = self.macro_expand(opts.name) + '/' except MacroExpandError as err: gbp.log.warn("Couldn't determine prefix from %%setup "\ "macro (%s). Using filename base as a " \ "fallback" % err) - orig['prefix'] = orig['filename_base'] + '/' + prefix = orig['filename_base'] + '/' else: # RPM default - orig['prefix'] = "%s-%s/" % (self.name, - self.upstreamversion) - return orig_num + prefix = "%s-%s/" % (self.name, self.upstreamversion) + break + return prefix + + def _guess_orig_file(self): + """ + Try to guess the name of the primary upstream/source archive. + Returns a dict with all the relevant information. + """ + orig = None + sources = self.sources() + for num, filename in sorted(sources.iteritems()): + src = {'num': num, 'filename': os.path.basename(filename), + 'uri': filename} + src['filename_base'], src['archive_fmt'], src['compression'] = \ + parse_archive_filename(os.path.basename(filename)) + if (src['filename_base'].startswith(self.name) and + src['archive_fmt']): + # Take the first archive that starts with pkg name + orig = src + break + # otherwise we take the first archive + elif not orig and src['archive_fmt']: + orig = src + # else don't accept + if orig: + orig['prefix'] = self._guess_orig_prefix(orig) + + return orig def parse_srpm(srpmfile): diff --git a/gbp/scripts/import_srpm.py b/gbp/scripts/import_srpm.py index 92bb022b..be03d187 100755 --- a/gbp/scripts/import_srpm.py +++ b/gbp/scripts/import_srpm.py @@ -327,9 +327,9 @@ def main(argv): # Need to copy files to the packaging directory given by caller files = [os.path.basename(patch.path) \ for patch in spec.patchseries(unapplied=True, ignored=True)] - for num, src in spec.sources.iteritems(): - if num != spec.orig_src_num: - files.append(src['filename']) + for num, filename in spec.sources().iteritems(): + if not spec.orig_src or num != spec.orig_src['num']: + files.append(os.path.basename(filename)) files.append(os.path.join(spec.specdir, spec.specfile)) for fname in files: fpath = os.path.join(dirs['src'], fname) diff --git a/tests/test_rpm.py b/tests/test_rpm.py index 728c8872..b065db4d 100644 --- a/tests/test_rpm.py +++ b/tests/test_rpm.py @@ -102,6 +102,7 @@ class TestSpecFile(object): orig = spec.orig_src assert orig['filename'] == 'gbp-test-1.0.tar.bz2' + assert orig['uri'] == 'gbp-test-1.0.tar.bz2' assert orig['filename_base'] == 'gbp-test-1.0' assert orig['archive_fmt'] == 'tar' assert orig['compression'] == 'bzip2' @@ -123,6 +124,7 @@ class TestSpecFile(object): orig = spec.orig_src assert orig['filename'] == 'gbp-test2-3.0.tar.gz' + assert orig['uri'] == 'ftp://ftp.host.com/gbp-test2-3.0.tar.gz' assert orig['archive_fmt'] == 'tar' assert orig['compression'] == 'gzip' assert orig['prefix'] == '' @@ -198,6 +200,7 @@ class TestSpecFile(object): prev = spec.protected('_delete_tag')('Vendor', None) spec.protected('_set_tag')('License', None, 'new license', prev) spec.protected('_delete_tag')('source', 0) + assert spec.sources() == {} spec.protected('_delete_tag')('patch', 0) spec.protected('_delete_tag')('patch', -1) assert spec.protected('_patches')() == {} -- cgit v1.2.3 From aa6b21f14a350599e577b9ba0326db5278b9bed2 Mon Sep 17 00:00:00 2001 From: Markus Lehtonen Date: Fri, 4 Jan 2013 18:40:51 +0200 Subject: test_import_srpm: add checks for files in repo Enhance some tests by checking that the correct files are present in the working directory of the repo. Signed-off-by: Markus Lehtonen --- tests/component/rpm/test_import_srpm.py | 32 +++++++++++++++++++++++++------- 1 file changed, 25 insertions(+), 7 deletions(-) diff --git a/tests/component/rpm/test_import_srpm.py b/tests/component/rpm/test_import_srpm.py index e2458a74..fe9062dc 100644 --- a/tests/component/rpm/test_import_srpm.py +++ b/tests/component/rpm/test_import_srpm.py @@ -48,7 +48,9 @@ class TestImportPacked(ComponentTestBase): assert import_srpm(['arg0', srpm]) == 0 # Check repository state repo = GitRepository('gbp-test') - self._check_repo_state(repo, 'master', ['master', 'upstream']) + files = {'Makefile', 'README', 'bar.tar.gz', 'dummy.sh', 'foo.txt', + 'gbp-test.spec', 'my.patch', 'mydir/', 'mydir/myfile.txt'} + self._check_repo_state(repo, 'master', ['master', 'upstream'], files) # Four commits: upstream, packaging files, one patch and the removal # of imported patches assert len(repo.get_commits()) == 4 @@ -59,7 +61,11 @@ class TestImportPacked(ComponentTestBase): assert import_srpm(['arg0', srpm]) == 0 # Check repository state repo = GitRepository('gbp-test2') - self._check_repo_state(repo, 'master', ['master', 'upstream']) + files = {'Makefile', 'README', 'bar.tar.gz', 'dummy.sh', 'foo.txt', + 'gbp-test2.spec', 'gbp-test2-alt.spec', 'my.patch', 'mydir/', + 'mydir/myfile.txt'} + self._check_repo_state(repo, 'master', ['master', 'upstream'], files) + # Four commits: upstream, packaging files, one patch and the removal # of imported patches assert len(repo.get_commits()) == 4 @@ -73,17 +79,21 @@ class TestImportPacked(ComponentTestBase): assert import_srpm(['arg0', '--orphan-packaging', srpm]) == 0 # Check repository state repo = GitRepository('gbp-test2') - self._check_repo_state(repo, 'master', ['master', 'upstream']) + files = {'bar.tar.gz', 'foo.txt', 'gbp-test2.spec', + 'gbp-test2-alt.spec', 'my.patch', 'my2.patch', 'my3.patch'} + self._check_repo_state(repo, 'master', ['master', 'upstream'], files) # Only one commit: the packaging files assert len(repo.get_commits()) == 1 def test_basic_native_import(self): """Test importing of native src.rpm""" - srpm = os.path.join(DATA_DIR, 'gbp-test2-2.0-0.src.rpm') + srpm = os.path.join(DATA_DIR, 'gbp-test-native-1.0-1.src.rpm') assert import_srpm(['arg0', '--native', srpm]) == 0 # Check repository state - repo = GitRepository('gbp-test2') - self._check_repo_state(repo, 'master', ['master']) + files = {'.gbp.conf', 'Makefile', 'README', 'dummy.sh', 'packaging/', + 'packaging/gbp-test-native.spec'} + repo = GitRepository('gbp-test-native') + self._check_repo_state(repo, 'master', ['master'], files) # Only one commit: the imported source tarball assert len(repo.get_commits()) == 1 @@ -116,6 +126,9 @@ class TestImportPacked(ComponentTestBase): assert len(repo.get_commits(until='upstream')) == 1 # Import new version assert import_srpm(['arg0', srpms[2]]) == 0 + files = {'Makefile', 'README', 'bar.tar.gz', 'dummy.sh', 'foo.txt', + 'gbp-test.spec', 'my.patch', 'mydir/', 'mydir/myfile.txt'} + self._check_repo_state(repo, 'master', ['master', 'upstream'], files) assert len(repo.get_commits()) == 11 assert len(repo.get_commits(until='upstream')) == 2 # Check number of tags @@ -182,7 +195,12 @@ class TestImportPacked(ComponentTestBase): srpm]) == 0 # Check repository state repo = GitRepository('gbp-test2') - self._check_repo_state(repo, 'pack', ['pack', 'orig']) + files = {'Makefile', 'README', 'dummy.sh', 'packaging/', + 'packaging/bar.tar.gz', 'packaging/foo.txt', + 'packaging/gbp-test2.spec', 'packaging/gbp-test2-alt.spec', + 'packaging/my.patch', 'packaging/my2.patch', + 'packaging/my3.patch'} + self._check_repo_state(repo, 'pack', ['pack', 'orig'], files) assert len(repo.get_commits()) == 2 # Check packaging dir assert len(repo.get_commits(paths='packaging')) == 1 -- cgit v1.2.3 From 7d9267624731c4a36b595bb088e7b06ab31240fe Mon Sep 17 00:00:00 2001 From: Zhang Qiang Date: Wed, 23 Jan 2013 22:41:25 -0500 Subject: Import RpmGitRepository if DebianGitRepository is not available This is just a workaround, this should be fixed in nicer way by refactoring the code. Signed-off-by: Zhang Qiang --- gbp/scripts/clone.py | 11 +++++++---- gbp/scripts/pull.py | 7 +++++-- 2 files changed, 12 insertions(+), 6 deletions(-) diff --git a/gbp/scripts/clone.py b/gbp/scripts/clone.py index e903810c..9dd0ae9c 100755 --- a/gbp/scripts/clone.py +++ b/gbp/scripts/clone.py @@ -23,10 +23,13 @@ import ConfigParser import sys import os, os.path from gbp.config import (GbpOptionParser, GbpOptionGroup) -from gbp.deb.git import DebianGitRepository -from gbp.git import (GitRepository, GitRepositoryError) +from gbp.git import GitRepositoryError from gbp.errors import GbpError import gbp.log +try: + from gbp.deb.git import DebianGitRepository as GitRepository +except ImportError: + from gbp.rpm.git import RpmGitRepository as GitRepository def build_parser(name): @@ -89,8 +92,8 @@ def main(argv): pass try: - repo = DebianGitRepository.clone(clone_to, source, options.depth, - auto_name=auto_name) + repo = GitRepository.clone(clone_to, source, options.depth, + auto_name=auto_name) os.chdir(repo.path) # Reparse the config files of the cloned repository so we pick up the diff --git a/gbp/scripts/pull.py b/gbp/scripts/pull.py index 45718053..12da8c5f 100755 --- a/gbp/scripts/pull.py +++ b/gbp/scripts/pull.py @@ -26,8 +26,11 @@ from gbp.command_wrappers import (Command, CommandExecFailed) from gbp.config import (GbpOptionParser, GbpOptionGroup) from gbp.errors import GbpError from gbp.git import GitRepositoryError -from gbp.deb.git import DebianGitRepository import gbp.log +try: + from gbp.deb.git import DebianGitRepository as GitRepository +except ImportError: + from gbp.rpm.git import RpmGitRepository as GitRepository def update_branch(branch, repo, options): """ @@ -146,7 +149,7 @@ def main(argv): gbp.log.setup(options.color, options.verbose, options.color_scheme) try: - repo = DebianGitRepository(os.path.curdir) + repo = GitRepository(os.path.curdir) except GitRepositoryError: gbp.log.err("%s is not a git repository" % (os.path.abspath('.'))) return 1 -- cgit v1.2.3 From 0a6b9b734df3adf02a4208e10a2acf87c19a4dbd Mon Sep 17 00:00:00 2001 From: Markus Lehtonen Date: Tue, 26 Feb 2013 12:01:32 +0200 Subject: import-srpm: skip pristine-tar for non-tar sources archives Don't even try to import non-tar archives to pristine-tar because that fails. Instead, print a warning and continue without using pristine-tar. Signed-off-by: Markus Lehtonen --- gbp/scripts/import_srpm.py | 12 +++++++++--- tests/component/rpm/test_import_srpm.py | 10 ++++++++++ 2 files changed, 19 insertions(+), 3 deletions(-) diff --git a/gbp/scripts/import_srpm.py b/gbp/scripts/import_srpm.py index be03d187..2fcd6326 100755 --- a/gbp/scripts/import_srpm.py +++ b/gbp/scripts/import_srpm.py @@ -40,6 +40,7 @@ from gbp.errors import GbpError import gbp.log from gbp.scripts.pq_rpm import safe_patches, rm_patch_files, get_packager from gbp.scripts.common.pq import apply_and_commit_patch +from gbp.pkg import parse_archive_filename no_packaging_branch_msg = """ Repository does not have branch '%s' for packaging/distribution sources. If there is none see @@ -411,9 +412,14 @@ def main(argv): if not options.native: if options.pristine_tar: - repo.pristine_tar.commit(orig_tarball, - 'refs/heads/%s' % - options.upstream_branch) + archive_fmt = parse_archive_filename(orig_tarball)[1] + if archive_fmt == 'tar': + repo.pristine_tar.commit(orig_tarball, + 'refs/heads/%s' % + options.upstream_branch) + else: + gbp.log.warn('Ignoring pristine-tar, %s archives ' + 'not supported' % archive_fmt) else: gbp.log.info("No orig source archive imported") diff --git a/tests/component/rpm/test_import_srpm.py b/tests/component/rpm/test_import_srpm.py index fe9062dc..c9a1a429 100644 --- a/tests/component/rpm/test_import_srpm.py +++ b/tests/component/rpm/test_import_srpm.py @@ -316,6 +316,16 @@ class TestPristineTar(ComponentTestBase): # of imported patches assert len(repo.get_commits()) == 4 + def test_unsupported_archive(self): + """Test importing of src.rpm with a zip source archive""" + srpm = os.path.join(DATA_DIR, 'gbp-test-native-1.0-1.src.rpm') + assert import_srpm(['arg0', '--pristine-tar', srpm]) == 0 + # Check repository state + repo = GitRepository('gbp-test-native') + self._check_repo_state(repo, 'master', ['master', 'upstream']) + # Check that a warning is printed + self._check_log(-1, "gbp:warning: Ignoring pristine-tar") + class TestBareRepo(ComponentTestBase): """Test importing to a bare repository""" -- cgit v1.2.3 From 2bc3492ff418a567a703bea1bb6ba6ee455d6167 Mon Sep 17 00:00:00 2001 From: Markus Lehtonen Date: Wed, 27 Feb 2013 15:53:52 +0200 Subject: import-srpm: import all packaging files from src.rpm Don't try to be too clever when importing an (true) src.rpm - just import all files from there without trying to guess file list from spec. Signed-off-by: Markus Lehtonen --- gbp/scripts/import_srpm.py | 21 +++++++++++++++------ 1 file changed, 15 insertions(+), 6 deletions(-) diff --git a/gbp/scripts/import_srpm.py b/gbp/scripts/import_srpm.py index 2fcd6326..1a120c97 100755 --- a/gbp/scripts/import_srpm.py +++ b/gbp/scripts/import_srpm.py @@ -268,8 +268,10 @@ def main(argv): srpm = download_source(srpm, dirs) # Real srpm, we need to unpack, first + true_srcrpm = False if not os.path.isdir(srpm) and not srpm.endswith(".spec"): src = parse_srpm(srpm) + true_srcrpm = True dirs['pkgextract'] = tempfile.mkdtemp(dir=dirs['tmp_base'], prefix='pkgextract_') gbp.log.info("Extracting src rpm to '%s'" % dirs['pkgextract']) @@ -325,13 +327,20 @@ def main(argv): if err.errno != errno.EEXIST: raise - # Need to copy files to the packaging directory given by caller - files = [os.path.basename(patch.path) \ - for patch in spec.patchseries(unapplied=True, ignored=True)] - for num, filename in spec.sources().iteritems(): - if not spec.orig_src or num != spec.orig_src['num']: + if true_srcrpm: + # For true src.rpm we just take everything + files = os.listdir(dirs['src']) + else: + # Need to copy files to the packaging directory given by caller + files = [os.path.basename(patch.path) \ + for patch in spec.patchseries(unapplied=True, ignored=True)] + for filename in spec.sources().values(): files.append(os.path.basename(filename)) - files.append(os.path.join(spec.specdir, spec.specfile)) + files.append(os.path.join(spec.specdir, spec.specfile)) + # Don't copy orig source archive, though + if spec.orig_src and spec.orig_src['filename'] in files: + files.remove(spec.orig_src['filename']) + for fname in files: fpath = os.path.join(dirs['src'], fname) if os.path.exists(fpath): -- cgit v1.2.3 From 3a5198aead28e4fe0742035f651736080b20d13f Mon Sep 17 00:00:00 2001 From: Markus Lehtonen Date: Mon, 25 Feb 2013 12:11:14 +0200 Subject: rpm: support conditionals in patch-export One can now define conditional patches that are enclosed in '%if' or '%ifarch' when the spec file is updated. One can do this by defining 'Gbp-Rpm-If: ' and 'Gbp-Rpm-IfArch: ' in the commit message. Only one conditional per patch is supported, i.e. you cannot define 'IfArch' and 'If' for the same patch. Signed-off-by: Markus Lehtonen --- gbp/rpm/__init__.py | 28 +++++++++++++++++----- gbp/scripts/import_srpm.py | 2 +- gbp/scripts/pq_rpm.py | 9 +++---- tests/test_rpm.py | 14 ++++++----- tests/test_rpm_data/specs/gbp-test2-reference.spec | 2 ++ .../test_rpm_data/specs/gbp-test2-reference2.spec | 11 +++++++-- 6 files changed, 47 insertions(+), 19 deletions(-) diff --git a/gbp/rpm/__init__.py b/gbp/rpm/__init__.py index 94297445..b797e98a 100644 --- a/gbp/rpm/__init__.py +++ b/gbp/rpm/__init__.py @@ -545,7 +545,7 @@ class SpecFile(object): self._special_directives[key].append(linerec) return ret - def update_patches(self, patchfilenames): + def update_patches(self, patches, commands): """Update spec with new patch tags and patch macros""" # Remove non-ignored patches tag_prev = None @@ -563,14 +563,21 @@ class SpecFile(object): # Remove '%patch:' macros for macro in self._special_directives['patch']: if not macro['id'] in ignored: + macro_prev = self._delete_special_macro('patch', macro['id']) + # Remove surrounding if-else + macro_next = macro_prev.next + if (str(macro_prev).startswith('%if') and + str(macro_next).startswith('%endif')): + self._content.delete(macro_next) + macro_prev = self._content.delete(macro_prev) + # Remove a preceding comment line if it ends with '.patch' or # '.diff' plus an optional compression suffix - macro_prev = self._delete_special_macro('patch', macro['id']) if re.match("^\s*#.+(patch|diff)(\.(gz|bz2|xz|lzma))?\s*$", str(macro_prev), flags=re.I): macro_prev = self._content.delete(macro_prev) - if len(patchfilenames) == 0: + if len(patches) == 0: return # Determine where to add Patch tag lines @@ -617,14 +624,23 @@ class SpecFile(object): # Add a comment indicating gbp generated patch tags comment_text = "# Patches auto-generated by git-buildpackage:\n" tag_line = self._content.insert_after(tag_line, comment_text) - for ind, name in enumerate(patchfilenames): + for ind, patch in enumerate(patches): + cmds = commands[patch] if patch in commands else {} patchnum = startnum + ind - tag_line = self._set_tag("Patch", patchnum, name, tag_line) + tag_line = self._set_tag("Patch", patchnum, patch, tag_line) # Add '%patch' macro and a preceding comment line - comment_text = "# %s\n" % name + comment_text = "# %s\n" % patch macro_line = self._content.insert_after(macro_line, comment_text) macro_line = self._set_special_macro('patch', patchnum, '-p1', macro_line) + for cmd, args in cmds.iteritems(): + if cmd in ('if', 'ifarch'): + self._content.insert_before(macro_line, '%%%s %s\n' % + (cmd, args)) + macro_line = self._content.insert_after(macro_line, + '%endif\n') + # We only support one command per patch, for now + break def patchseries(self, unapplied=False, ignored=False): """Return non-ignored patches of the RPM as a gbp patchseries""" diff --git a/gbp/scripts/import_srpm.py b/gbp/scripts/import_srpm.py index 1a120c97..3ef4b110 100755 --- a/gbp/scripts/import_srpm.py +++ b/gbp/scripts/import_srpm.py @@ -152,7 +152,7 @@ def import_spec_patches(repo, spec, dirs): gbp.log.info("Removing imported patch files from spec and packaging dir") rm_patch_files(spec) try: - spec.update_patches([]) + spec.update_patches([], {}) spec.write_spec_file() except GbpError: repo.force_head('HEAD', hard=True) diff --git a/gbp/scripts/pq_rpm.py b/gbp/scripts/pq_rpm.py index d3da13a8..edb327f6 100755 --- a/gbp/scripts/pq_rpm.py +++ b/gbp/scripts/pq_rpm.py @@ -110,7 +110,8 @@ def generate_patches(repo, start, squash, end, outdir, options): # Generate patches for commit in reversed(repo.get_commits(start, end_commit)): info = repo.get_commit_info(commit) - cmds = parse_gbp_commands(info, 'gbp-rpm', ('ignore'), None)[0] + cmds = parse_gbp_commands(info, 'gbp-rpm', ('ignore'), + ('if', 'ifarch'))[0] if not 'ignore' in cmds: patch_fn = format_patch(outdir, repo, info, patches, options.patch_numbers, @@ -164,9 +165,9 @@ def update_patch_series(repo, spec, start, end, options): # Unlink old patch files and generate new patches rm_patch_files(spec) - patches, _commands = generate_patches(repo, start, squash, end, - spec.specdir, options) - spec.update_patches(patches) + patches, commands = generate_patches(repo, start, squash, end, + spec.specdir, options) + spec.update_patches(patches, commands) spec.write_spec_file() diff --git a/tests/test_rpm.py b/tests/test_rpm.py index b065db4d..2542f126 100644 --- a/tests/test_rpm.py +++ b/tests/test_rpm.py @@ -159,7 +159,7 @@ class TestSpecFile(object): reference_spec = os.path.join(SPEC_DIR, 'gbp-test-reference.spec') spec = SpecFile(tmp_spec) - spec.update_patches(['new.patch']) + spec.update_patches(['new.patch'], {}) spec.write_spec_file() assert filecmp.cmp(tmp_spec, reference_spec) is True @@ -176,14 +176,16 @@ class TestSpecFile(object): reference_spec = os.path.join(SPEC_DIR, 'gbp-test2-reference2.spec') spec = SpecFile(tmp_spec) - spec.update_patches(['1.patch', '2.patch']) + spec.update_patches(['1.patch', '2.patch'], + {'1.patch': {'if': 'true'}, + '2.patch': {'ifarch': '%ix86'}}) spec.set_tag('VCS', None, 'myvcstag') - spec.update_patches(['new.patch']) spec.write_spec_file() assert filecmp.cmp(tmp_spec, reference_spec) is True - # Test removing the VCS tag + # Test updating patches again and removing the VCS tag reference_spec = os.path.join(SPEC_DIR, 'gbp-test2-reference.spec') + spec.update_patches(['new.patch'], {'new.patch': {'if': '1'}}) spec.set_tag('VCS', None, '') spec.write_spec_file() assert filecmp.cmp(tmp_spec, reference_spec) is True @@ -264,10 +266,10 @@ class TestSpecFile(object): spec = SpecFileTester(spec_filepath) assert len(spec.patchseries()) == 0 - spec.update_patches(['1.patch', '2.patch', '3.patch']) + spec.update_patches(['1.patch', '2.patch', '3.patch'], {}) assert len(spec.patchseries()) == 3 spec.protected('_gbp_tags')['ignore-patches'].append({'args': "0"}) - spec.update_patches(['4.patch']) + spec.update_patches(['4.patch'], {}) assert len(spec.patchseries()) == 1 assert len(spec.patchseries(ignored=True)) == 2 spec.protected('_delete_special_macro')('patch', 0) diff --git a/tests/test_rpm_data/specs/gbp-test2-reference.spec b/tests/test_rpm_data/specs/gbp-test2-reference.spec index e31930d7..dfd4b91f 100644 --- a/tests/test_rpm_data/specs/gbp-test2-reference.spec +++ b/tests/test_rpm_data/specs/gbp-test2-reference.spec @@ -27,7 +27,9 @@ echo "Do things" # Gbp-Patch-Macros # new.patch +%if 1 %patch0 -p1 +%endif %build make diff --git a/tests/test_rpm_data/specs/gbp-test2-reference2.spec b/tests/test_rpm_data/specs/gbp-test2-reference2.spec index 095600d3..0b93f0fa 100644 --- a/tests/test_rpm_data/specs/gbp-test2-reference2.spec +++ b/tests/test_rpm_data/specs/gbp-test2-reference2.spec @@ -11,7 +11,8 @@ Source20: bar.tar.gz # Gbp-Ignore-Patches: -1 Patch: my.patch # Patches auto-generated by git-buildpackage: -Patch0: new.patch +Patch0: 1.patch +Patch1: 2.patch Packager: Markus Lehtonen VCS: myvcstag @@ -27,8 +28,14 @@ Package for testing the RPM functionality of git-buildpackage. echo "Do things" # Gbp-Patch-Macros -# new.patch +# 1.patch +%if true %patch0 -p1 +%endif +# 2.patch +%ifarch %ix86 +%patch1 -p1 +%endif %build make -- cgit v1.2.3 From 04cf2a51306bebf5c3df369be76d8e5281a0cfbc Mon Sep 17 00:00:00 2001 From: Markus Lehtonen Date: Mon, 25 Mar 2013 11:34:45 +0200 Subject: buildpackage-rpm: use config file(s) from exported tree-ish Use the local per-tree/per-branch config file(s) from the exported tree-ish instead of the current working copy. Signed-off-by: Markus Lehtonen --- gbp/scripts/buildpackage_rpm.py | 41 ++++++++++++++++++++++++++--------------- 1 file changed, 26 insertions(+), 15 deletions(-) diff --git a/gbp/scripts/buildpackage_rpm.py b/gbp/scripts/buildpackage_rpm.py index 3c6b7c1c..9c86c072 100755 --- a/gbp/scripts/buildpackage_rpm.py +++ b/gbp/scripts/buildpackage_rpm.py @@ -174,16 +174,19 @@ def get_tree(repo, tree_name): Get/create a tree-ish to be used for exporting and diffing. Accepts special keywords for git index and working copies. """ - if tree_name == index_name: - # Write a tree of the index - tree = repo.write_tree() - elif tree_name in wc_names: - # Write a tree of the working copy - tree = write_wc(repo, - force=wc_names[tree_name]['force'], - untracked=wc_names[tree_name]['untracked']) - else: - tree = tree_name + try: + if tree_name == index_name: + # Write a tree of the index + tree = repo.write_tree() + elif tree_name in wc_names: + # Write a tree of the working copy + tree = write_wc(repo, + force=wc_names[tree_name]['force'], + untracked=wc_names[tree_name]['untracked']) + else: + tree = tree_name + except GitRepositoryError as err: + raise GbpError(err) if not repo.has_treeish(tree): raise GbpError('Invalid treeish object %s' % tree) @@ -316,7 +319,7 @@ def create_packaging_tag(repo, tag, commit, version, options): keyid=options.keyid, commit=commit) -def parse_args(argv, prefix): +def parse_args(argv, prefix, git_treeish=None): args = [ arg for arg in argv[1:] if arg.find('--%s' % prefix) == 0 ] builder_args = [ arg for arg in argv[1:] if arg.find('--%s' % prefix) == -1 ] @@ -326,7 +329,8 @@ def parse_args(argv, prefix): args.append(arg) try: - parser = GbpOptionParserRpm(command=os.path.basename(argv[0]), prefix=prefix) + parser = GbpOptionParserRpm(command=os.path.basename(argv[0]), + prefix=prefix, git_treeish=git_treeish) except ConfigParser.ParsingError, err: gbp.log.err(err) return None, None, None @@ -449,6 +453,16 @@ def main(argv): else: repo_dir = os.path.abspath(os.path.curdir) + # Determine tree-ish to be exported + try: + tree = get_tree(repo, options.export) + except GbpError as err: + gbp.log.err('Failed to determine export treeish: %s' % err) + return 1 + # Re-parse config options with using the per-tree config file(s) from the + # exported tree-ish + options, gbp_args, builder_args = parse_args(argv, prefix, tree) + try: # Create base temporary directory for this run options.tmp_dir = tempfile.mkdtemp(dir=options.tmp_dir, @@ -477,9 +491,6 @@ def main(argv): gbp.log.err("You are not on branch '%s' but on '%s'" % (options.packaging_branch, branch)) raise GbpError, "Use --git-ignore-branch to ignore or --git-packaging-branch to set the branch name." - # Determine tree-ish to be exported - tree = get_tree(repo, options.export) - # Dump from git to a temporary directory: dump_dir = tempfile.mkdtemp(dir=options.tmp_dir, prefix='dump_tree_') -- cgit v1.2.3 From 7cb6e19ef67ba8df6278c46cac1fc7474ae61025 Mon Sep 17 00:00:00 2001 From: Markus Lehtonen Date: Tue, 26 Mar 2013 10:53:30 +0200 Subject: .gbp.conf: Tizen specific changes Signed-off-by: Markus Lehtonen --- .gbp.conf | 14 +++++++++++--- 1 file changed, 11 insertions(+), 3 deletions(-) diff --git a/.gbp.conf b/.gbp.conf index 6f74162f..6ef7f6d2 100644 --- a/.gbp.conf +++ b/.gbp.conf @@ -2,16 +2,24 @@ # Do not merge to packaging (after update) merge=False # Vendor/Distro name -vendor=MyDistro +vendor=Tizen # Package is from Debian upstream-tag=debian/%(version)s # Don't use pristine-tar pristine-tar=False # Branch naming -packaging-branch=experimental-rpm -upstream-branch=master +packaging-branch=master +upstream-branch=upstream +# Tag format for releases +packaging-tag = tizen/%(upstreamversion)s-%(nowtime)s # Subdir for RPM packaging data packaging-dir=packaging # Auto-generate patches against upstream patch-export = True patch-numbers = True +patch-export-ignore-path = (.gbp.conf|packaging/.*) +# Don't fail if the current branch does not match the main packaging branch +ignore-branch = True + +[git-rpm-ch] +changelog-revision=%(tagname)s -- cgit v1.2.3 From 532c7d990143ea6329bbd5d6d8573a89b3709fdf Mon Sep 17 00:00:00 2001 From: Markus Lehtonen Date: Tue, 2 Apr 2013 10:50:08 +0300 Subject: buildpackage-rpm: listen to --no-create-orig option for native packages, too Signed-off-by: Markus Lehtonen --- gbp/scripts/buildpackage_rpm.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/gbp/scripts/buildpackage_rpm.py b/gbp/scripts/buildpackage_rpm.py index 9c86c072..ae4e494c 100755 --- a/gbp/scripts/buildpackage_rpm.py +++ b/gbp/scripts/buildpackage_rpm.py @@ -552,7 +552,7 @@ def main(argv): # Get/build the orig tarball if is_native(repo, options): - if spec.orig_src: + if spec.orig_src and not options.no_create_orig: # Just build source archive from the exported tree gbp.log.info("Creating (native) source archive %s from '%s'" % (spec.orig_src['filename'], tree)) if spec.orig_src['compression']: -- cgit v1.2.3 From 736353f6181ae39982ea687baaf57d4f39886d4d Mon Sep 17 00:00:00 2001 From: Markus Lehtonen Date: Mon, 22 Apr 2013 14:11:32 +0300 Subject: Disable xcover support for nose Signed-off-by: Markus Lehtonen --- debian/control | 1 - setup.cfg | 2 +- setup.py | 2 +- 3 files changed, 2 insertions(+), 3 deletions(-) diff --git a/debian/control b/debian/control index 2e71b798..3b3cca0c 100644 --- a/debian/control +++ b/debian/control @@ -13,7 +13,6 @@ Build-Depends: python (>> 2.6.6-3~), python-epydoc, python-nose, - python-nosexcover, python-pkg-resources, python-setuptools, sgml2x, diff --git a/setup.cfg b/setup.cfg index 82471592..1dcb4115 100644 --- a/setup.cfg +++ b/setup.cfg @@ -1,6 +1,6 @@ [nosetests] with-doctest=1 -with-xcoverage=1 +#with-xcoverage=1 with-xunit=1 cover-package=gbp cover-erase=1 diff --git a/setup.py b/setup.py index 4579d025..9506a5d1 100644 --- a/setup.py +++ b/setup.py @@ -62,7 +62,7 @@ setup(name = "gbp", 'bin/git-import-orig-rpm'], packages = find_packages(exclude=['tests', 'tests.*']), data_files = [("/etc/git-buildpackage/", ["gbp.conf"]),], - setup_requires=['nose>=0.11.1', 'coverage>=2.85', 'nosexcover>=1.0.7'] if \ + setup_requires=['nose>=0.11.1', 'coverage>=2.85'] if \ os.getenv('WITHOUT_NOSETESTS') is None else [], entry_points = { 'console_scripts': [ 'gbp = gbp.scripts.supercommand:supercommand' ], -- cgit v1.2.3 From 3342605fc2e4846360c0128c1ceff84be1502806 Mon Sep 17 00:00:00 2001 From: Markus Lehtonen Date: Tue, 23 Apr 2013 15:45:38 +0300 Subject: buildpackage-rpm: implement --[no-]hooks option For enabling/disabling all hooks, similar to git-buildpackage (the Debian tool). Does not affedt the builder. Signed-off-by: Markus Lehtonen --- gbp/scripts/buildpackage_rpm.py | 11 +++++++++++ 1 file changed, 11 insertions(+) diff --git a/gbp/scripts/buildpackage_rpm.py b/gbp/scripts/buildpackage_rpm.py index ae4e494c..56c6b893 100755 --- a/gbp/scripts/buildpackage_rpm.py +++ b/gbp/scripts/buildpackage_rpm.py @@ -319,6 +319,14 @@ def create_packaging_tag(repo, tag, commit, version, options): keyid=options.keyid, commit=commit) +def disable_hooks(options): + """Disable all hooks (except for builder)""" + for hook in ['cleaner', 'postexport', 'prebuild', 'postbuild', 'posttag']: + if getattr(options, hook): + gbp.log.info("Disabling '%s' hook" % hook) + setattr(options, hook, '') + + def parse_args(argv, prefix, git_treeish=None): args = [ arg for arg in argv[1:] if arg.find('--%s' % prefix) == 0 ] builder_args = [ arg for arg in argv[1:] if arg.find('--%s' % prefix) == -1 ] @@ -395,6 +403,7 @@ def parse_args(argv, prefix, git_treeish=None): help="hook run after a successful build, default is '%(postbuild)s'") cmd_group.add_config_file_option(option_name="posttag", dest="posttag", help="hook run after a successful tag operation, default is '%(posttag)s'") + cmd_group.add_boolean_config_file_option(option_name="hooks", dest="hooks") export_group.add_config_file_option(option_name="export-dir", dest="export_dir", type="path", help="Build topdir, also export the sources under EXPORT_DIR, default is '%(export-dir)s'") export_group.add_config_file_option(option_name="rpmbuild-builddir", dest="build_dir", type="path", @@ -428,6 +437,8 @@ def parse_args(argv, prefix, git_treeish=None): options.patch_export_compress = rpm.string_to_int(options.patch_export_compress) gbp.log.setup(options.color, options.verbose, options.color_scheme) + if not options.hooks: + disable_hooks(options) if options.retag: if not options.tag and not options.tag_only: gbp.log.err("'--%sretag' needs either '--%stag' or '--%stag-only'" % (prefix, prefix, prefix)) -- cgit v1.2.3 From b86dc269f3ef0cfbf720a66db0bade64b71c036d Mon Sep 17 00:00:00 2001 From: Zhang Qiang Date: Fri, 8 Feb 2013 14:09:26 +0800 Subject: CentOS compatibility: make GBP work with older python2.6 - use loops to generate dict/list - Called logging.Logger.__init__ instead of using super(). In python 2.6 logging.Logger is not new-style class, therefore supper() is failing. Signed-off-by: Ed Bartosh Signed-off-by: Zhang Qiang Signed-off-by: Markus Lehtonen --- gbp/log.py | 6 +++--- gbp/rpm/__init__.py | 21 +++++++++++++++------ 2 files changed, 18 insertions(+), 9 deletions(-) diff --git a/gbp/log.py b/gbp/log.py index f21e2bbd..1e177d41 100644 --- a/gbp/log.py +++ b/gbp/log.py @@ -52,7 +52,7 @@ class GbpStreamHandler(logging.StreamHandler): OFF_SEQ = "\033[0m" def __init__(self, stream=None, color='auto'): - super(GbpStreamHandler, self).__init__(stream) + logging.StreamHandler.__init__(self, stream) self._color = gbp.tristate.Tristate(color) self._color_scheme = DEFAULT_COLOR_SCHEME.copy() msg_fmt = "%(color)s%(name)s:%(levelname)s: %(message)s%(coloroff)s" @@ -88,14 +88,14 @@ class GbpStreamHandler(logging.StreamHandler): record.color = self.COLOR_SEQ % self._color_scheme[record.levelno] record.coloroff = self.OFF_SEQ record.levelname = record.levelname.lower() - return super(GbpStreamHandler, self).format(record) + return logging.StreamHandler.format(self, record) class GbpLogger(logging.Logger): """Logger class for git-buildpackage""" def __init__(self, name, color='auto', *args, **kwargs): - super(GbpLogger, self).__init__(name, *args, **kwargs) + logging.Logger.__init__(self, name, *args, **kwargs) self._default_handlers = [GbpStreamHandler(sys.stdout, color), GbpStreamHandler(sys.stderr, color)] self._default_handlers[0].addFilter(GbpFilter([DEBUG, INFO])) diff --git a/gbp/rpm/__init__.py b/gbp/rpm/__init__.py index b797e98a..3d11d0db 100644 --- a/gbp/rpm/__init__.py +++ b/gbp/rpm/__init__.py @@ -214,20 +214,28 @@ class SpecFile(object): def _patches(self): """Get all patch tags as a dict""" + patches = {} if 'patch' not in self._tags: return {} - return {patch['num']: patch for patch in self._tags['patch']['lines']} + for patch in self._tags['patch']['lines']: + patches[patch['num']] = patch + return patches def _sources(self): """Get all source tags as a dict""" + sources = {} if 'source' not in self._tags: return {} - return {src['num']: src for src in self._tags['source']['lines']} + for src in self._tags['source']['lines']: + sources[src['num']] = src + return sources def sources(self): """Get all source tags as a dict""" - return {src['num']: src['linevalue'] - for src in self._sources().values()} + sources = {} + for src in self._sources().values(): + sources[src['num']] = src['linevalue'] + return sources def _macro_replace(self, matchobj): macro_dict = {'name': self.name, @@ -647,8 +655,9 @@ class SpecFile(object): series = PatchSeries() if 'patch' in self._tags: tags = self._patches() - macros = {macro['id']: macro['args'] - for macro in self._special_directives['patch']} + macros = {} + for macro in self._special_directives['patch']: + macros[macro['id']] = macro['args'] ignored = [] if ignored else self.ignorepatches for num, tag in sorted(tags.iteritems()): -- cgit v1.2.3 From 90d94d86a75c5ae093cc47b0836de2ebf4da88cd Mon Sep 17 00:00:00 2001 From: Markus Lehtonen Date: Tue, 5 Mar 2013 17:49:56 +0200 Subject: CentOS compatibility: fix tests Signed-off-by: Markus Lehtonen --- tests/01_test_help.py | 6 +++++- tests/02_test_upstream_source_tar_unpack.py | 6 +++++- tests/05_test_detection.py | 6 +++++- tests/06_test_upstream_source.py | 6 +++++- tests/08_test_patch.py | 6 +++++- tests/11_test_dch_main.py | 6 +++++- tests/12_test_deb.py | 7 ++++++- tests/13_test_gbp_pq.py | 6 +++++- tests/16_test_supercommand.py | 6 +++++- tests/18_test_Config.py | 6 +++++- tests/19_test_gbp_scripts_config.py | 6 +++++- tests/component/rpm/test_import_srpm.py | 24 ++++++++++++------------ tests/test_import_orig.py | 6 +++++- tests/test_rpm.py | 6 ++++-- tests/testutils.py | 6 +++++- 15 files changed, 82 insertions(+), 27 deletions(-) diff --git a/tests/01_test_help.py b/tests/01_test_help.py index 6a4810bb..a421eb8d 100644 --- a/tests/01_test_help.py +++ b/tests/01_test_help.py @@ -4,7 +4,11 @@ from . import context -import unittest +# Try unittest2 for CentOS +try: + import unittest2 as unittest +except ImportError: + import unittest class TestHelp(unittest.TestCase): """Test help output of gbp commands""" diff --git a/tests/02_test_upstream_source_tar_unpack.py b/tests/02_test_upstream_source_tar_unpack.py index 97bf76bb..e6147abd 100644 --- a/tests/02_test_upstream_source_tar_unpack.py +++ b/tests/02_test_upstream_source_tar_unpack.py @@ -8,7 +8,11 @@ import os import shutil import tarfile import tempfile -import unittest +# Try unittest2 for CentOS +try: + import unittest2 as unittest +except ImportError: + import unittest import gbp.pkg diff --git a/tests/05_test_detection.py b/tests/05_test_detection.py index 126a2992..c3f729ba 100644 --- a/tests/05_test_detection.py +++ b/tests/05_test_detection.py @@ -4,7 +4,11 @@ from . import context -import unittest +# Try unittest2 for CentOS +try: + import unittest2 as unittest +except ImportError: + import unittest from gbp.scripts import buildpackage from gbp.deb import (DebianPkgPolicy, orig_file) diff --git a/tests/06_test_upstream_source.py b/tests/06_test_upstream_source.py index c6df6f14..6b2a1a1e 100644 --- a/tests/06_test_upstream_source.py +++ b/tests/06_test_upstream_source.py @@ -9,7 +9,11 @@ import os import shutil import tarfile import tempfile -import unittest +# Try unittest2 for CentOS +try: + import unittest2 as unittest +except ImportError: + import unittest import zipfile from gbp.pkg import UpstreamSource diff --git a/tests/08_test_patch.py b/tests/08_test_patch.py index df1d43d4..dd1532e2 100644 --- a/tests/08_test_patch.py +++ b/tests/08_test_patch.py @@ -5,7 +5,11 @@ from . import context import os -import unittest +# Try unittest2 for CentOS +try: + import unittest2 as unittest +except ImportError: + import unittest from gbp.patch_series import Patch diff --git a/tests/11_test_dch_main.py b/tests/11_test_dch_main.py index dbfc25cd..9bdc5c5b 100644 --- a/tests/11_test_dch_main.py +++ b/tests/11_test_dch_main.py @@ -4,7 +4,11 @@ from . import context -import unittest +# Try unittest2 for CentOS +try: + import unittest2 as unittest +except ImportError: + import unittest from tests.testutils import (DebianGitTestRepo, OsReleaseFile, get_dch_default_urgency) diff --git a/tests/12_test_deb.py b/tests/12_test_deb.py index d46f987c..2be30976 100644 --- a/tests/12_test_deb.py +++ b/tests/12_test_deb.py @@ -4,7 +4,12 @@ from . import context -import os, tempfile, unittest +import os, tempfile +# Try unittest2 for CentOS +try: + import unittest2 as unittest +except ImportError: + import unittest import gbp.deb diff --git a/tests/13_test_gbp_pq.py b/tests/13_test_gbp_pq.py index 7e78b153..0b400c21 100644 --- a/tests/13_test_gbp_pq.py +++ b/tests/13_test_gbp_pq.py @@ -19,7 +19,11 @@ from . import context import os import logging -import unittest +# Try unittest2 for CentOS +try: + import unittest2 as unittest +except ImportError: + import unittest from gbp.scripts.pq import generate_patches import gbp.scripts.common.pq as pq diff --git a/tests/16_test_supercommand.py b/tests/16_test_supercommand.py index f72bb562..296ef8ed 100644 --- a/tests/16_test_supercommand.py +++ b/tests/16_test_supercommand.py @@ -16,7 +16,11 @@ """Test L{gbp} command wrapper""" import sys -import unittest +# Try unittest2 for CentOS +try: + import unittest2 as unittest +except ImportError: + import unittest import gbp.scripts.supercommand class TestSuperCommand(unittest.TestCase): diff --git a/tests/18_test_Config.py b/tests/18_test_Config.py index f7ba8c9c..0bb7354e 100644 --- a/tests/18_test_Config.py +++ b/tests/18_test_Config.py @@ -1,7 +1,11 @@ # vim: set fileencoding=utf-8 : import os -import unittest +# Try unittest2 for CentOS +try: + import unittest2 as unittest +except ImportError: + import unittest from gbp.config import GbpOptionParser, GbpOptionGroup from . import context diff --git a/tests/19_test_gbp_scripts_config.py b/tests/19_test_gbp_scripts_config.py index f503ef54..c984329a 100644 --- a/tests/19_test_gbp_scripts_config.py +++ b/tests/19_test_gbp_scripts_config.py @@ -17,7 +17,11 @@ import os import sys -import unittest +# Try unittest2 for CentOS +try: + import unittest2 as unittest +except ImportError: + import unittest import gbp.scripts.config class TestGbpConfigCommand(unittest.TestCase): diff --git a/tests/component/rpm/test_import_srpm.py b/tests/component/rpm/test_import_srpm.py index c9a1a429..f6ee0ed0 100644 --- a/tests/component/rpm/test_import_srpm.py +++ b/tests/component/rpm/test_import_srpm.py @@ -48,8 +48,8 @@ class TestImportPacked(ComponentTestBase): assert import_srpm(['arg0', srpm]) == 0 # Check repository state repo = GitRepository('gbp-test') - files = {'Makefile', 'README', 'bar.tar.gz', 'dummy.sh', 'foo.txt', - 'gbp-test.spec', 'my.patch', 'mydir/', 'mydir/myfile.txt'} + files = set(['Makefile', 'README', 'bar.tar.gz', 'dummy.sh', 'foo.txt', + 'gbp-test.spec', 'my.patch', 'mydir/', 'mydir/myfile.txt']) self._check_repo_state(repo, 'master', ['master', 'upstream'], files) # Four commits: upstream, packaging files, one patch and the removal # of imported patches @@ -61,9 +61,9 @@ class TestImportPacked(ComponentTestBase): assert import_srpm(['arg0', srpm]) == 0 # Check repository state repo = GitRepository('gbp-test2') - files = {'Makefile', 'README', 'bar.tar.gz', 'dummy.sh', 'foo.txt', + files = set(['Makefile', 'README', 'bar.tar.gz', 'dummy.sh', 'foo.txt', 'gbp-test2.spec', 'gbp-test2-alt.spec', 'my.patch', 'mydir/', - 'mydir/myfile.txt'} + 'mydir/myfile.txt']) self._check_repo_state(repo, 'master', ['master', 'upstream'], files) # Four commits: upstream, packaging files, one patch and the removal @@ -79,8 +79,8 @@ class TestImportPacked(ComponentTestBase): assert import_srpm(['arg0', '--orphan-packaging', srpm]) == 0 # Check repository state repo = GitRepository('gbp-test2') - files = {'bar.tar.gz', 'foo.txt', 'gbp-test2.spec', - 'gbp-test2-alt.spec', 'my.patch', 'my2.patch', 'my3.patch'} + files = set(['bar.tar.gz', 'foo.txt', 'gbp-test2.spec', + 'gbp-test2-alt.spec', 'my.patch', 'my2.patch', 'my3.patch']) self._check_repo_state(repo, 'master', ['master', 'upstream'], files) # Only one commit: the packaging files assert len(repo.get_commits()) == 1 @@ -90,8 +90,8 @@ class TestImportPacked(ComponentTestBase): srpm = os.path.join(DATA_DIR, 'gbp-test-native-1.0-1.src.rpm') assert import_srpm(['arg0', '--native', srpm]) == 0 # Check repository state - files = {'.gbp.conf', 'Makefile', 'README', 'dummy.sh', 'packaging/', - 'packaging/gbp-test-native.spec'} + files = set(['.gbp.conf', 'Makefile', 'README', 'dummy.sh', + 'packaging/', 'packaging/gbp-test-native.spec']) repo = GitRepository('gbp-test-native') self._check_repo_state(repo, 'master', ['master'], files) # Only one commit: the imported source tarball @@ -126,8 +126,8 @@ class TestImportPacked(ComponentTestBase): assert len(repo.get_commits(until='upstream')) == 1 # Import new version assert import_srpm(['arg0', srpms[2]]) == 0 - files = {'Makefile', 'README', 'bar.tar.gz', 'dummy.sh', 'foo.txt', - 'gbp-test.spec', 'my.patch', 'mydir/', 'mydir/myfile.txt'} + files = set(['Makefile', 'README', 'bar.tar.gz', 'dummy.sh', 'foo.txt', + 'gbp-test.spec', 'my.patch', 'mydir/', 'mydir/myfile.txt']) self._check_repo_state(repo, 'master', ['master', 'upstream'], files) assert len(repo.get_commits()) == 11 assert len(repo.get_commits(until='upstream')) == 2 @@ -195,11 +195,11 @@ class TestImportPacked(ComponentTestBase): srpm]) == 0 # Check repository state repo = GitRepository('gbp-test2') - files = {'Makefile', 'README', 'dummy.sh', 'packaging/', + files = set(['Makefile', 'README', 'dummy.sh', 'packaging/', 'packaging/bar.tar.gz', 'packaging/foo.txt', 'packaging/gbp-test2.spec', 'packaging/gbp-test2-alt.spec', 'packaging/my.patch', 'packaging/my2.patch', - 'packaging/my3.patch'} + 'packaging/my3.patch']) self._check_repo_state(repo, 'pack', ['pack', 'orig'], files) assert len(repo.get_commits()) == 2 # Check packaging dir diff --git a/tests/test_import_orig.py b/tests/test_import_orig.py index d596d1df..aa39e380 100644 --- a/tests/test_import_orig.py +++ b/tests/test_import_orig.py @@ -21,7 +21,11 @@ import glob import os import tarfile import tempfile -import unittest +# Try unittest2 for CentOS +try: + import unittest2 as unittest +except ImportError: + import unittest from gbp.errors import GbpError from gbp.pkg import UpstreamSource diff --git a/tests/test_rpm.py b/tests/test_rpm.py index 2542f126..a85f41f9 100644 --- a/tests/test_rpm.py +++ b/tests/test_rpm.py @@ -256,8 +256,10 @@ class TestSpecFile(object): (name, val['value'], rval)) assert spec.ignorepatches == [] # Check patch numbers and patch filenames - patches = {patch['num']: patch['linevalue'] for patch in - spec.protected('_tags')['patch']['lines']} + patches = {} + for patch in spec.protected('_tags')['patch']['lines']: + patches[patch['num']] = patch['linevalue'] + assert patches == {0: 'my_patch0', -1: 'my_patch'} def test_patch_series(self): diff --git a/tests/testutils.py b/tests/testutils.py index ce0c20c8..587c273b 100644 --- a/tests/testutils.py +++ b/tests/testutils.py @@ -7,7 +7,11 @@ import shutil import subprocess import tarfile import tempfile -import unittest +# Try unittest2 for CentOS +try: + import unittest2 as unittest +except ImportError: + import unittest import zipfile import gbp.log -- cgit v1.2.3 From c7d83ad6f25e76341d4b579370def6e13281630c Mon Sep 17 00:00:00 2001 From: Markus Lehtonen Date: Mon, 4 Mar 2013 13:17:24 +0200 Subject: CentOS compatibility: fix GitRepository._cmd_has_feature() Make it work in CentOS 6.3 with older git by removing backspace characters when examining man page section names. Signed-off-by: Markus Lehtonen --- gbp/git/repository.py | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/gbp/git/repository.py b/gbp/git/repository.py index 6f10081f..b4588e3d 100644 --- a/gbp/git/repository.py +++ b/gbp/git/repository.py @@ -321,6 +321,7 @@ class GitRepository(object): section_re = re.compile(r'^(?P
[A-Z].*)') option_re = re.compile(r'--?(?P[a-zA-Z\-]+).*') optopt_re = re.compile(r'--\[(?P[a-zA-Z\-]+)\]-?') + backspace_re = re.compile(".\b") man_section = None for line in help.splitlines(): if man_section == "OPTIONS" and line.startswith(' -'): @@ -338,7 +339,7 @@ class GitRepository(object): # Check man section match = section_re.match(line) if match: - man_section = match.group('section') + man_section = backspace_re.sub('', match.group('section')) return False @property -- cgit v1.2.3 From f2b3ffb3474e0154c24802bb2e543dba17e507a3 Mon Sep 17 00:00:00 2001 From: Markus Lehtonen Date: Wed, 24 Apr 2013 14:08:19 +0300 Subject: CentOS compatibility: disable Debian tools Signed-off-by: Markus Lehtonen --- packaging/git-buildpackage.spec | 20 +++++++++++++++++--- 1 file changed, 17 insertions(+), 3 deletions(-) diff --git a/packaging/git-buildpackage.spec b/packaging/git-buildpackage.spec index 3a193fdd..26f1f439 100644 --- a/packaging/git-buildpackage.spec +++ b/packaging/git-buildpackage.spec @@ -149,9 +149,7 @@ cp -r docs/manual-html %{buildroot}%{_docdir}/%{name} cp -r docs/apidocs %{buildroot}%{_docdir}/%{name} %endif - -%files -%defattr(-,root,root,-) +cat > files.list << EOF %{_bindir}/gbp-pq %{_bindir}/git-buildpackage %{_bindir}/git-dch @@ -168,7 +166,10 @@ cp -r docs/apidocs %{buildroot}%{_docdir}/%{name} %{python_sitelib}/gbp/scripts/import_dscs.py* %{python_sitelib}/gbp/scripts/import_orig.py* %{python_sitelib}/gbp/scripts/create_remote_repo.py* +EOF + %if %{with docs} +cat >> files.list << EOF %{_mandir}/man1/gbp-buildpackage.1* %{_mandir}/man1/gbp-create-remote-repo.1* %{_mandir}/man1/gbp-dch.1* @@ -177,6 +178,19 @@ cp -r docs/apidocs %{buildroot}%{_docdir}/%{name} %{_mandir}/man1/gbp-import-orig.1* %{_mandir}/man1/gbp-pq.1* %{_mandir}/man1/git-pbuilder.1* +EOF +%endif + +# Disable the debian tools for CentOS +%if 0%{?centos_version} +for f in `cat files.list`; do + rm -rfv %{buildroot}/$f +done + +%else + +%files -f files.list +%defattr(-,root,root,-) %endif %files common -- cgit v1.2.3 From b6e27c088fe0914e371af93d9018e2416b61571f Mon Sep 17 00:00:00 2001 From: Markus Lehtonen Date: Fri, 8 Nov 2013 12:37:51 +0200 Subject: CentOS compatibility: fix GitRepository.diff Remove the "all" parameter from --ignore-submodules which is not supported by the old Git version of CentOS 6 (besides, it's the default, anyway) Signed-off-by: Markus Lehtonen --- gbp/git/repository.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/gbp/git/repository.py b/gbp/git/repository.py index b4588e3d..04ba849a 100644 --- a/gbp/git/repository.py +++ b/gbp/git/repository.py @@ -1781,7 +1781,7 @@ class GitRepository(object): options.add('--stat=%s' % stat) options.add_true(summary, '--summary') options.add_true(text, '--text') - options.add_true(ignore_submodules, '--ignore-submodules=all') + options.add_true(ignore_submodules, '--ignore-submodules') options.add(obj1) options.add_true(obj2, obj2) if paths: -- cgit v1.2.3 From 1001e81d36b952750916cf28871f5a8d01270ffb Mon Sep 17 00:00:00 2001 From: Markus Lehtonen Date: Tue, 23 Apr 2013 16:41:52 +0300 Subject: packaging: git-buildpackage (Debian) tool requires devscripts Signed-off-by: Markus Lehtonen --- packaging/git-buildpackage.spec | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/packaging/git-buildpackage.spec b/packaging/git-buildpackage.spec index 26f1f439..45d02bb7 100644 --- a/packaging/git-buildpackage.spec +++ b/packaging/git-buildpackage.spec @@ -18,6 +18,12 @@ Source0: %{name}_%{version}.tar.gz %define dpkg_pkg_name dpkg %endif +%if 0%{?suse_version} && 0%{?suse_version} < 1230 +%define devscripts_pkg_name devscripts-fixes +%else +%define devscripts_pkg_name devscripts +%endif + %if 0%{?fedora} %define man_pkg_name man-db %else @@ -38,6 +44,7 @@ Source0: %{name}_%{version}.tar.gz Requires: %{name}-common = %{version}-%{release} Requires: %{dpkg_pkg_name} +Requires: %{devscripts_pkg_name} BuildRequires: python BuildRequires: python-setuptools -- cgit v1.2.3 From 3390dfd69a598d78286d7d87c8c042eb55139bd7 Mon Sep 17 00:00:00 2001 From: Markus Lehtonen Date: Mon, 13 May 2013 15:05:31 +0300 Subject: rpm packaging: depend on pristine-tar In practice, it is a weak dependency but upstream RPM doesn't support weak dependencies so we put it to 'Requires:' for everything else than openSUSE or Tizen (which do support weak deps). Signed-off-by: Markus Lehtonen --- packaging/git-buildpackage.spec | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/packaging/git-buildpackage.spec b/packaging/git-buildpackage.spec index 45d02bb7..1b0fab79 100644 --- a/packaging/git-buildpackage.spec +++ b/packaging/git-buildpackage.spec @@ -84,6 +84,11 @@ Group: Development/Tools/Building Requires: git-core Requires: %{man_pkg_name} Requires: %{python_pkg_name} +%if 0%{?suse_version} || 0%{?tizen_version:1} +Recommends: pristine-tar +%else +Requires: pristine-tar +%endif %description common Common files and documentation, used by both git-buildpackage debian and rpm tools -- cgit v1.2.3 From 19b8bb4fe3b348e14badba7b5bf26d7b89199f1b Mon Sep 17 00:00:00 2001 From: Markus Lehtonen Date: Wed, 15 May 2013 09:51:54 +0300 Subject: rpm: give patches in the order they are applied in the spec Fixes patch importing in situations when patch tag numbering in the spec differs from the order they are applied. Signed-off-by: Markus Lehtonen --- gbp/rpm/__init__.py | 29 +++++++++++++++++--------- tests/test_rpm.py | 24 ++++++++++++++++++++- tests/test_rpm_data/specs/gbp-test-quirks.spec | 12 +++++++++++ 3 files changed, 54 insertions(+), 11 deletions(-) diff --git a/gbp/rpm/__init__.py b/gbp/rpm/__init__.py index 3d11d0db..16cec8e4 100644 --- a/gbp/rpm/__init__.py +++ b/gbp/rpm/__init__.py @@ -655,20 +655,29 @@ class SpecFile(object): series = PatchSeries() if 'patch' in self._tags: tags = self._patches() - macros = {} + applied = [] for macro in self._special_directives['patch']: - macros[macro['id']] = macro['args'] - ignored = [] if ignored else self.ignorepatches - - for num, tag in sorted(tags.iteritems()): - strip = 0 - if num in macros: - opts = self._patch_macro_opts(macros[num]) + if macro['id'] in tags: + applied.append((macro['id'], macro['args'])) + ignored = set() if ignored else set(self.ignorepatches) + + # Put all patches that are applied first in the series + for num, args in applied: + if num not in ignored: + opts = self._patch_macro_opts(args) strip = int(opts.strip) if opts.strip else 0 - if (unapplied or (num in macros)) and num not in ignored: - filename = os.path.basename(tag['linevalue']) + filename = os.path.basename(tags[num]['linevalue']) series.append(Patch(os.path.join(self.specdir, filename), strip=strip)) + # Finally, append all unapplied patches to the series, if requested + if unapplied: + applied_nums = set([num for num, _args in applied]) + unapplied = set(tags.keys()).difference(applied_nums) + for num in sorted(unapplied): + if num not in ignored: + filename = os.path.basename(tags[num]['linevalue']) + series.append(Patch(os.path.join(self.specdir, + filename), strip=0)) return series def _guess_orig_prefix(self, orig): diff --git a/tests/test_rpm.py b/tests/test_rpm.py index a85f41f9..ca1cc6a7 100644 --- a/tests/test_rpm.py +++ b/tests/test_rpm.py @@ -278,7 +278,29 @@ class TestSpecFile(object): assert len(spec.patchseries(ignored=True)) == 1 series = spec.patchseries(unapplied=True, ignored=True) assert len(series) == 2 - assert os.path.basename(series[-1].path) == '4.patch' + assert os.path.basename(series[-1].path) == '1.patch' + + def test_patch_series_quirks(self): + """Patches are applied in order different from the patch numbering""" + spec_filepath = os.path.join(SPEC_DIR, 'gbp-test-quirks.spec') + spec = SpecFileTester(spec_filepath) + + # Check series is returned in the order the patches are applied + files = [os.path.basename(patch.path) for patch in spec.patchseries()] + assert files == ['05.patch', '01.patch'] + # Also ignored patches are returned in the correct order + files = [os.path.basename(patch.path) for patch in + spec.patchseries(ignored=True)] + assert files == ['05.patch', '02.patch', '01.patch'] + # Unapplied patches are added to the end of the series + files = [os.path.basename(patch.path) for patch in + spec.patchseries(unapplied=True)] + assert files == ['05.patch', '01.patch', '03.patch'] + # Return all patches (for which tag is found) + files = [os.path.basename(patch.path) for patch in + spec.patchseries(unapplied=True, ignored=True)] + assert files == ['05.patch', '02.patch', '01.patch', '03.patch', + '04.patch'] class TestUtilityFunctions(object): diff --git a/tests/test_rpm_data/specs/gbp-test-quirks.spec b/tests/test_rpm_data/specs/gbp-test-quirks.spec index 64db07fb..bb56b008 100644 --- a/tests/test_rpm_data/specs/gbp-test-quirks.spec +++ b/tests/test_rpm_data/specs/gbp-test-quirks.spec @@ -8,6 +8,12 @@ Version: 0.1 Release: 1.2 License: GPLv2 Source1: foobar.tar.gz +# Gbp-Ignore-Patches: 2 4 888 +Patch1: 01.patch +Patch2: 02.patch +Patch3: 03.patch +Patch4: 04.patch +Patch5: 05.patch %description Spec for testing some quirks of spec parsing. No intended for building an RPM. @@ -16,3 +22,9 @@ Spec for testing some quirks of spec parsing. No intended for building an RPM. # We don't have Source0 so rpmbuild would fail, but gbp shouldn't crash %setup -q +# Patches are applied out-of-order wrt. numbering +%patch5 +%patch2 +%patch1 +# Patch 999 does not exist, rpmbuild would fail but GBP should not +%patch999 -- cgit v1.2.3 From 757ab802648d5f5b5ca81fb2695a80c8dd15927e Mon Sep 17 00:00:00 2001 From: Markus Lehtonen Date: Mon, 20 May 2013 10:45:25 +0300 Subject: rpm: support importing bzip2 compressed patches Signed-off-by: Markus Lehtonen --- gbp/scripts/pq_rpm.py | 9 ++++++--- tests/component/rpm/data | 2 +- tests/component/rpm/test_import_srpm.py | 14 ++++++++++++++ 3 files changed, 21 insertions(+), 4 deletions(-) diff --git a/gbp/scripts/pq_rpm.py b/gbp/scripts/pq_rpm.py index edb327f6..cf7b29ad 100755 --- a/gbp/scripts/pq_rpm.py +++ b/gbp/scripts/pq_rpm.py @@ -25,6 +25,7 @@ import shutil import sys import re import gzip +import bz2 import subprocess import gbp.tmpfile as tempfile from gbp.config import (GbpOptionParserRpm, GbpOptionGroup) @@ -227,12 +228,14 @@ def safe_patches(queue, tmpdir_base): gbp.log.debug("Safeing patches '%s' in '%s'" % (os.path.dirname(queue[0].path), tmpdir)) for p in queue: (base, archive_fmt, comp) = parse_archive_filename(p.path) - if comp == 'gzip': + uncompressors = {'gzip': gzip.open, 'bzip2': bz2.BZ2File} + if comp in uncompressors: gbp.log.debug("Uncompressing '%s'" % os.path.basename(p.path)) - src = gzip.open(p.path, 'r') + src = uncompressors[comp](p.path, 'r') dst_name = os.path.join(tmpdir, os.path.basename(base)) elif comp: - raise GbpError, ("Unsupported compression of a patch, giving up") + raise GbpError("Unsupported patch compression '%s', giving up" + % comp) else: src = open(p.path, 'r') dst_name = os.path.join(tmpdir, os.path.basename(p.path)) diff --git a/tests/component/rpm/data b/tests/component/rpm/data index aec4222c..90bf36d7 160000 --- a/tests/component/rpm/data +++ b/tests/component/rpm/data @@ -1 +1 @@ -Subproject commit aec4222cbd9e2efbd60c56ee4e9cc4d8eb7265b3 +Subproject commit 90bf36d7981fdd1677cf7e734d9e1056a5fced1c diff --git a/tests/component/rpm/test_import_srpm.py b/tests/component/rpm/test_import_srpm.py index f6ee0ed0..efc4204f 100644 --- a/tests/component/rpm/test_import_srpm.py +++ b/tests/component/rpm/test_import_srpm.py @@ -107,6 +107,20 @@ class TestImportPacked(ComponentTestBase): # Only one commit: packaging files assert len(repo.get_commits()) == 1 + def test_import_compressed_patches(self): + """Test importing of non-native src.rpm with compressed patches""" + srpm = os.path.join(DATA_DIR, 'gbp-test-1.1-2.src.rpm') + assert import_srpm(['arg0', srpm]) == 0 + # Check repository state + repo = GitRepository('gbp-test') + files = set(['Makefile', 'README', 'AUTHORS', 'NEWS', 'bar.tar.gz', + 'dummy.sh', 'foo.txt', 'gbp-test.spec', 'my.patch', + 'mydir/', 'mydir/myfile.txt']) + self._check_repo_state(repo, 'master', ['master', 'upstream'], files) + # Four commits: upstream, packaging files, three patches and the removal + # of imported patches + assert len(repo.get_commits()) == 6 + def test_multiple_versions(self): """Test importing of multiple versions""" srpms = [ os.path.join(DATA_DIR, 'gbp-test-1.0-1.src.rpm'), -- cgit v1.2.3 From e2739d24252ea3651deba9fd6ff1ec9f6f86a245 Mon Sep 17 00:00:00 2001 From: Markus Lehtonen Date: Thu, 30 May 2013 17:35:57 +0300 Subject: import-srpm: support --upstream-vcs-tag cmdline option Similar to what the option does in git-import-orig-[rpm]. Signed-off-by: Markus Lehtonen --- gbp/scripts/import_srpm.py | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/gbp/scripts/import_srpm.py b/gbp/scripts/import_srpm.py index 3ef4b110..bf661027 100755 --- a/gbp/scripts/import_srpm.py +++ b/gbp/scripts/import_srpm.py @@ -205,6 +205,9 @@ def parse_args(argv): dest="packaging_branch") branch_group.add_config_file_option(option_name="upstream-branch", dest="upstream_branch") + branch_group.add_option("--upstream-vcs-tag", dest="vcs_tag", + help="Upstream VCS tag on top of which to import " + "the orig sources") branch_group.add_boolean_config_file_option( option_name="create-missing-branches", dest="create_missing_branches") @@ -407,9 +410,14 @@ def main(argv): raise GbpError msg = "%s version %s" % (tag_format[1], spec.upstreamversion) + if options.vcs_tag: + parents = [repo.rev_parse("%s^{}" % options.vcs_tag)] + else: + parents = None upstream_commit = repo.commit_dir(upstream.unpacked, "Imported %s" % msg, branch, + other_parents=parents, author=author, committer=committer, create_missing_branch=options.create_missing_branches) -- cgit v1.2.3 From 365ca88ab6e5d64ab381348b33a4b88abd04bd2c Mon Sep 17 00:00:00 2001 From: Markus Lehtonen Date: Fri, 16 Aug 2013 13:26:54 +0300 Subject: rpm: implement a wrapper module for rpm lib Intended for capturing the rpm lib logging output. NOTE! The new module is named 'lib_rpm.py' (and not 'librpm.py') because of a bug in python-nose: some name clash makes nosetests --with-xunit fail in this case. Signed-off-by: Markus Lehtonen --- gbp/rpm/__init__.py | 56 ++++++++++++++++++++++++----------------------------- gbp/rpm/lib_rpm.py | 47 ++++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 72 insertions(+), 31 deletions(-) create mode 100644 gbp/rpm/lib_rpm.py diff --git a/gbp/rpm/__init__.py b/gbp/rpm/__init__.py index 16cec8e4..2290bc32 100644 --- a/gbp/rpm/__init__.py +++ b/gbp/rpm/__init__.py @@ -35,13 +35,7 @@ import gbp.log from gbp.pkg import (UpstreamSource, compressor_opts, parse_archive_filename) from gbp.rpm.policy import RpmPkgPolicy from gbp.rpm.linkedlist import LinkedList - -try: - # Try to load special RPM lib to be used for GBP (only) - rpm = __import__(RpmPkgPolicy.python_rpmlib_module_name) -except ImportError: - gbp.log.debug("Failed to import '%s' as rpm python module, using host's default rpm library instead" % RpmPkgPolicy.python_rpmlib_module_name) - import rpm +from gbp.rpm.lib_rpm import librpm class NoSpecError(Exception): @@ -66,38 +60,38 @@ class SrcRpmFile(object): """Keeps all needed data read from a source rpm""" def __init__(self, srpmfile): # Do not required signed packages to be able to import - ts_vsflags = (rpm.RPMVSF_NOMD5HEADER | rpm.RPMVSF_NORSAHEADER | - rpm.RPMVSF_NOSHA1HEADER | rpm.RPMVSF_NODSAHEADER | - rpm.RPMVSF_NOMD5 | rpm.RPMVSF_NORSA | rpm.RPMVSF_NOSHA1 | - rpm.RPMVSF_NODSA) + ts_vsflags = (librpm.RPMVSF_NOMD5HEADER | librpm.RPMVSF_NORSAHEADER | + librpm.RPMVSF_NOSHA1HEADER | librpm.RPMVSF_NODSAHEADER | + librpm.RPMVSF_NOMD5 | librpm.RPMVSF_NORSA | + librpm.RPMVSF_NOSHA1 | librpm.RPMVSF_NODSA) srpmfp = open(srpmfile) - self.rpmhdr = rpm.ts(vsflags=ts_vsflags).hdrFromFdno(srpmfp.fileno()) + self.rpmhdr = librpm.ts(vsflags=ts_vsflags).hdrFromFdno(srpmfp.fileno()) srpmfp.close() self.srpmfile = os.path.abspath(srpmfile) @property def version(self): """Get the (downstream) version of the RPM package""" - version = dict(upstreamversion = self.rpmhdr[rpm.RPMTAG_VERSION], - release = self.rpmhdr[rpm.RPMTAG_RELEASE]) - if self.rpmhdr[rpm.RPMTAG_EPOCH] is not None: - version['epoch'] = str(self.rpmhdr[rpm.RPMTAG_EPOCH]) + version = dict(upstreamversion = self.rpmhdr[librpm.RPMTAG_VERSION], + release = self.rpmhdr[librpm.RPMTAG_RELEASE]) + if self.rpmhdr[librpm.RPMTAG_EPOCH] is not None: + version['epoch'] = str(self.rpmhdr[librpm.RPMTAG_EPOCH]) return version @property def name(self): """Get the name of the RPM package""" - return self.rpmhdr[rpm.RPMTAG_NAME] + return self.rpmhdr[librpm.RPMTAG_NAME] @property def upstreamversion(self): """Get the upstream version of the RPM package""" - return self.rpmhdr[rpm.RPMTAG_VERSION] + return self.rpmhdr[librpm.RPMTAG_VERSION] @property def packager(self): """Get the packager of the RPM package""" - return self.rpmhdr[rpm.RPMTAG_PACKAGER] + return self.rpmhdr[librpm.RPMTAG_PACKAGER] def unpack(self, dest_dir): """ @@ -152,13 +146,13 @@ class SpecFile(object): # Other initializations source_header = self._specinfo.packages[0].header - self.name = source_header[rpm.RPMTAG_NAME] - self.upstreamversion = source_header[rpm.RPMTAG_VERSION] - self.release = source_header[rpm.RPMTAG_RELEASE] + self.name = source_header[librpm.RPMTAG_NAME] + self.upstreamversion = source_header[librpm.RPMTAG_VERSION] + self.release = source_header[librpm.RPMTAG_RELEASE] # rpm-python returns epoch as 'long', convert that to string - self.epoch = str(source_header[rpm.RPMTAG_EPOCH]) \ - if source_header[rpm.RPMTAG_EPOCH] != None else None - self.packager = source_header[rpm.RPMTAG_PACKAGER] + self.epoch = str(source_header[librpm.RPMTAG_EPOCH]) \ + if source_header[librpm.RPMTAG_EPOCH] != None else None + self.packager = source_header[librpm.RPMTAG_PACKAGER] self._tags = {} self._special_directives = defaultdict(list) self._gbp_tags = defaultdict(list) @@ -167,7 +161,7 @@ class SpecFile(object): self._parse_content() # Find 'Packager' tag. Needed to circumvent a bug in python-rpm where - # spec.sourceHeader[rpm.RPMTAG_PACKAGER] is not reset when a new spec + # spec.sourceHeader[librpm.RPMTAG_PACKAGER] is not reset when a new spec # file is parsed if 'packager' not in self._tags: self.packager = None @@ -184,8 +178,8 @@ class SpecFile(object): try: # Parse two times to circumvent a rpm-python problem where # macros are not expanded if used before their definition - rpm.spec(filtered.name) - return rpm.spec(filtered.name) + librpm.spec(filtered.name) + return librpm.spec(filtered.name) except ValueError as err: raise GbpError("RPM error while parsing %s: %s" % (self.specfile, err)) @@ -288,7 +282,7 @@ class SpecFile(object): # Record all tag locations try: header = self._specinfo.packages[0].header - tagvalue = header[getattr(rpm, 'RPMTAG_%s' % tagname.upper())] + tagvalue = header[getattr(librpm, 'RPMTAG_%s' % tagname.upper())] except AttributeError: tagvalue = None # We don't support "multivalue" tags like "Provides:" or "SourceX:" @@ -461,7 +455,7 @@ class SpecFile(object): # Check type of tag, we don't support values for 'multivalue' tags try: header = self._specinfo.packages[0].header - tagvalue = header[getattr(rpm, 'RPMTAG_%s' % tagname.upper())] + tagvalue = header[getattr(librpm, 'RPMTAG_%s' % tagname.upper())] except AttributeError: tagvalue = None tagvalue = None if type(tagvalue) is list else value @@ -752,7 +746,7 @@ def parse_srpm(srpmfile): srcrpm = SrcRpmFile(srpmfile) except IOError, err: raise GbpError, "Error reading src.rpm file: %s" % err - except rpm.error, err: + except librpm.error, err: raise GbpError, "RPM error while reading src.rpm: %s" % err return srcrpm diff --git a/gbp/rpm/lib_rpm.py b/gbp/rpm/lib_rpm.py new file mode 100644 index 00000000..72a7671e --- /dev/null +++ b/gbp/rpm/lib_rpm.py @@ -0,0 +1,47 @@ +# vim: set fileencoding=utf-8 : +# +# (C) 2012 Intel Corporation +# This program is free software; you can redistribute it and/or modify +# it under the terms of the GNU General Public License as published by +# the Free Software Foundation; either version 2 of the License, or +# (at your option) any later version. +# +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with this program; if not, write to the Free Software +# Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA +"""Wrapper module for librpm""" + +import tempfile + +import gbp.log +from gbp.rpm.policy import RpmPkgPolicy + +try: + # Try to load special RPM lib to be used for GBP (only) + librpm = __import__(RpmPkgPolicy.python_rpmlib_module_name) +except ImportError: + gbp.log.debug("Failed to import '%s' as rpm python module, using host's " + "default rpm library instead" % + RpmPkgPolicy.python_rpmlib_module_name) + import rpm as librpm + +# Module initialization +_rpmlog = tempfile.NamedTemporaryFile(prefix='gbp_rpmlog') +_rpmlogfd = _rpmlog.file +librpm.setVerbosity(librpm.RPMLOG_INFO) +librpm.setLogFile(_rpmlogfd) + + +def get_log(truncate=True): + """Get rpmlib log output""" + _rpmlogfd.seek(0) + log = [line.strip() for line in _rpmlogfd.readlines()] + if truncate: + _rpmlogfd.truncate(0) + return log + -- cgit v1.2.3 From 825593b0469c57fbe194bb9a93a9b763dafe9bfc Mon Sep 17 00:00:00 2001 From: Markus Lehtonen Date: Mon, 19 Aug 2013 10:00:35 +0300 Subject: rpm: print a warning if importing gbp-specific librpm fails Fixes: #1177 Signed-off-by: Markus Lehtonen --- gbp/rpm/lib_rpm.py | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/gbp/rpm/lib_rpm.py b/gbp/rpm/lib_rpm.py index 72a7671e..adf40d1b 100644 --- a/gbp/rpm/lib_rpm.py +++ b/gbp/rpm/lib_rpm.py @@ -25,9 +25,9 @@ try: # Try to load special RPM lib to be used for GBP (only) librpm = __import__(RpmPkgPolicy.python_rpmlib_module_name) except ImportError: - gbp.log.debug("Failed to import '%s' as rpm python module, using host's " - "default rpm library instead" % - RpmPkgPolicy.python_rpmlib_module_name) + gbp.log.warn("Failed to import '%s' as rpm python module, using host's " + "default rpm library instead" % + RpmPkgPolicy.python_rpmlib_module_name) import rpm as librpm # Module initialization -- cgit v1.2.3 From 0009c1362cc78886c96b4236cad9599a8b48bee2 Mon Sep 17 00:00:00 2001 From: Markus Lehtonen Date: Fri, 16 Aug 2013 13:51:13 +0300 Subject: rpm: Improve logging in case of rpmlib error Signed-off-by: Markus Lehtonen --- gbp/rpm/__init__.py | 9 ++++++--- gbp/rpm/lib_rpm.py | 2 +- 2 files changed, 7 insertions(+), 4 deletions(-) diff --git a/gbp/rpm/__init__.py b/gbp/rpm/__init__.py index 2290bc32..e62ae2d2 100644 --- a/gbp/rpm/__init__.py +++ b/gbp/rpm/__init__.py @@ -35,7 +35,7 @@ import gbp.log from gbp.pkg import (UpstreamSource, compressor_opts, parse_archive_filename) from gbp.rpm.policy import RpmPkgPolicy from gbp.rpm.linkedlist import LinkedList -from gbp.rpm.lib_rpm import librpm +from gbp.rpm.lib_rpm import librpm, get_librpm_log class NoSpecError(Exception): @@ -181,8 +181,11 @@ class SpecFile(object): librpm.spec(filtered.name) return librpm.spec(filtered.name) except ValueError as err: - raise GbpError("RPM error while parsing %s: %s" % - (self.specfile, err)) + rpmlog = get_librpm_log() + gbp.log.debug("librpm log:\n %s" % + "\n ".join(rpmlog)) + raise GbpError("RPM error while parsing %s: %s (%s)" % + (self.specfile, err, rpmlog[-1])) @property def version(self): diff --git a/gbp/rpm/lib_rpm.py b/gbp/rpm/lib_rpm.py index adf40d1b..4bad44e7 100644 --- a/gbp/rpm/lib_rpm.py +++ b/gbp/rpm/lib_rpm.py @@ -37,7 +37,7 @@ librpm.setVerbosity(librpm.RPMLOG_INFO) librpm.setLogFile(_rpmlogfd) -def get_log(truncate=True): +def get_librpm_log(truncate=True): """Get rpmlib log output""" _rpmlogfd.seek(0) log = [line.strip() for line in _rpmlogfd.readlines()] -- cgit v1.2.3 From 3e2ae9f9f1c3dd56e7432ca2992c7b5dd2fed454 Mon Sep 17 00:00:00 2001 From: Markus Lehtonen Date: Wed, 31 Oct 2012 17:27:58 +0200 Subject: tests: add tests for git-import-orig-rpm Basic tests for virtually all features of import-orig-rpm. Signed-off-by: Markus Lehtonen --- tests/component/rpm/data | 2 +- tests/component/rpm/test_import_orig_rpm.py | 577 ++++++++++++++++++++++++++++ 2 files changed, 578 insertions(+), 1 deletion(-) create mode 100644 tests/component/rpm/test_import_orig_rpm.py diff --git a/tests/component/rpm/data b/tests/component/rpm/data index 90bf36d7..d32d64fe 160000 --- a/tests/component/rpm/data +++ b/tests/component/rpm/data @@ -1 +1 @@ -Subproject commit 90bf36d7981fdd1677cf7e734d9e1056a5fced1c +Subproject commit d32d64fec32e36d911a9d9a4d6d583554cce8113 diff --git a/tests/component/rpm/test_import_orig_rpm.py b/tests/component/rpm/test_import_orig_rpm.py new file mode 100644 index 00000000..e2de8b64 --- /dev/null +++ b/tests/component/rpm/test_import_orig_rpm.py @@ -0,0 +1,577 @@ +# vim: set fileencoding=utf-8 : +# +# (C) 2012 Intel Corporation +# This program is free software; you can redistribute it and/or modify +# it under the terms of the GNU General Public License as published by +# the Free Software Foundation; either version 2 of the License, or +# (at your option) any later version. +# +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with this program; if not, write to the Free Software +# Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA +"""Tests for the git-import-orig-rpm tool""" + +import os +import shutil +import sys +import subprocess +import tarfile +import tempfile +from nose.plugins.skip import SkipTest +from nose.tools import assert_raises, eq_ # pylint: disable=E0611 +from StringIO import StringIO + +from gbp.scripts.import_orig_rpm import main as import_orig_rpm +from gbp.git import GitRepository + +from tests.testutils import ls_dir, ls_tar, ls_zip +from tests.component import ComponentTestBase +from tests.component.rpm import RPM_TEST_DATA_DIR + +# Disable "Method could be a function warning" +# pylint: disable=R0201 + +DATA_DIR = os.path.join(RPM_TEST_DATA_DIR, 'orig') + + +def mock_import(args, stdin_data="\n\n", cwd=None): + """Wrapper for import-orig-rpm for feeding mock stdin data to it""" + old_cwd = os.path.abspath(os.path.curdir) + if cwd: + os.chdir(cwd) + + # Create stub file with mock data + mock_stdin = StringIO() + mock_stdin.write(stdin_data) + mock_stdin.seek(0) + + # Call import-orig-rpm with mock data + sys.stdin = mock_stdin + ret = import_orig_rpm(['arg0'] + args) + sys.stdin = sys.__stdin__ + mock_stdin.close() + + # Return to original working directory + if cwd: + os.chdir(old_cwd) + return ret + + +class ImportOrigTestBase(ComponentTestBase): + """Base class for all import-orig-rpm unit tests""" + + @classmethod + def setup_class(cls): + """Class setup, common for all test cases""" + super(ImportOrigTestBase, cls).setup_class() + + def __init__(self, *args, **kwargs): + super(ImportOrigTestBase, self).__init__(*args, **kwargs) + + def setup(self): + """Test case setup""" + super(ImportOrigTestBase, self).setup() + + @staticmethod + def ls_tree(repo, treeish): + """List contents (blobs) in a git treeish""" + objs = repo.list_tree(treeish, True) + blobs = [obj[3] for obj in objs if obj[1] == 'blob'] + return set(blobs) + + @staticmethod + def check_files(reference, filelist): + """Compare two file lists""" + extra = set(filelist) - set(reference) + assert not extra, "Unexpected files: %s" % list(extra) + missing = set(reference) - set(filelist) + assert not missing, "Missing files: %s" % list(missing) + + @classmethod + def check_tree(cls, repo, treeish, filelist): + """Check the contents (list of files) in a git treeish""" + treeish_files = ImportOrigTestBase.ls_tree(repo, treeish) + ImportOrigTestBase.check_files(treeish_files, filelist) + + +class TestImportOrig(ImportOrigTestBase): + """Basic tests for git-import-orig-rpm""" + + def test_invalid_args(self): + """ + See that import-orig-rpm fails gracefully when called with invalid args + """ + repo = GitRepository.create('.') + origs = [os.path.join(DATA_DIR, 'gbp-test-1.0.tar.bz2'), + os.path.join(DATA_DIR, 'gbp-test-1.1.tar.bz2')] + # Test empty args + eq_(mock_import([]), 1) + self._clear_log() + + # Test multiple archives + eq_(mock_import([] + origs), 1) + self._check_log(0, 'gbp:error: More than one archive specified') + self._clear_log() + + # Test invalid archive + false_orig = os.path.join(RPM_TEST_DATA_DIR, 'gbp-test-1.0-1.src.rpm') + eq_(mock_import([false_orig], 'foo\n1\n'), 1) + self._check_log(0, "gbp:error: Unsupported archive format") + self._clear_log() + + # Test non-existing archive + eq_(mock_import(['none.tar.bz2'], 'foo\n1\n'), 1) + self._check_log(0, "gbp:error: UpstreamSource: unable to find") + self._clear_log() + + # Check that nothing is in the repo + self._check_repo_state(repo, None, []) + + # Test invalid cmdline options + with assert_raises(SystemExit): + mock_import(['--invalid-arg=123']) + + def test_import_outside_repo(self): + """Test importing when not in a git repository""" + orig = os.path.join(DATA_DIR, 'gbp-test-1.0.tar.bz2') + # Import should fail + eq_(mock_import([orig]), 1) + self._check_log(0, 'gbp:error: %s is not a git repository' % + os.path.abspath(os.getcwd())) + + def test_invalid_config_file(self): + """Test invalid config file""" + # Create dummy invalid config file and try to import (should fail) + GitRepository.create('.') + with open('.gbp.conf', 'w') as conffd: + conffd.write('foobar\n') + eq_(mock_import(['foo']), 1) + self._check_log(0, 'gbp:error: File contains no section headers.') + + def test_import_tars(self): + """Test importing of tarballs, with and without merging""" + repo = GitRepository.create('.') + # Import first version, with --merge + orig = os.path.join(DATA_DIR, 'gbp-test-1.0.tar.bz2') + eq_(mock_import(['--merge', orig]), 0) + files = ['Makefile', 'README', 'dummy.sh'] + self._check_repo_state(repo, 'master', ['master', 'upstream'], files) + eq_(len(repo.get_commits(until='master')), 1) + eq_(len(repo.get_commits(until='upstream')), 1) + eq_(repo.get_tags(), ['upstream/1.0']) + + # Import second version, don't merge to master branch + orig = os.path.join(DATA_DIR, 'gbp-test-1.1.tar.bz2') + eq_(mock_import([orig]), 0) + self._check_repo_state(repo, 'master', ['master', 'upstream'], files) + eq_(len(repo.get_commits(until='master')), 1) + eq_(len(repo.get_commits(until='upstream')), 2) + eq_(repo.get_tags(), ['upstream/1.0', 'upstream/1.1']) + # Check that master is based on v1.0 + sha1 = repo.rev_parse("%s^0" % 'upstream/1.0') + eq_(repo.get_merge_base('master', 'upstream'), sha1) + + def test_import_zip(self): + """Test importing of zip archive""" + repo = GitRepository.create('.') + # Import zip with, no master branch should be present + orig = os.path.join(DATA_DIR, 'gbp-test-native-1.0.zip') + eq_(mock_import([orig]), 0) + self._check_repo_state(repo, None, ['upstream'], []) + eq_(repo.get_tags(), ['upstream/1.0']) + + def test_import_to_existing(self): + """Test importing of to an existing repo""" + # Create new repo and add dummy files + repo = GitRepository.create('.') + shutil.copy2('.git/HEAD', 'foobar') + repo.add_files('.') + repo.commit_all('First commit') + sha1 = repo.rev_parse('HEAD^0') + + # Test missing upstream branch + orig = os.path.join(DATA_DIR, 'gbp-test2-2.0.tar.gz') + eq_(mock_import([orig]), 1) + self._check_log(1, 'Repository does not have branch') + + # Create orphan, empty, 'usptream' branch + tree = repo.write_tree('.git/_empty_index') + commit = repo.commit_tree(tree=tree, msg='Initial upstream', parents=[]) + repo.update_ref("refs/heads/upstream", commit) + + # Test importing to non-clean repo + files = ['foobar'] + self._check_repo_state(repo, 'master', ['master', 'upstream'], files) + shutil.copy2('.git/HEAD', 'foobaz') + self._clear_log() + eq_(mock_import([orig]), 1) + self._check_log(0, 'gbp:error: Repository has uncommitted changes') + os.unlink('foobaz') + + # Create new branch + repo.create_branch('mytopic') + repo.set_branch('mytopic') + + # Finally, import should succeed + eq_(mock_import([orig, '--merge']), 0) + files = ['Makefile', 'README', 'dummy.sh', 'foobar'] + self._check_repo_state(repo, 'master', + ['master', 'mytopic', 'upstream'], files) + eq_(repo.get_tags(), ['upstream/2.0']) + # Our topic branch shouldn't have changed, unlike master + eq_(repo.rev_parse('mytopic^0'), sha1) + eq_(len(repo.get_commits(until='mytopic')), 1) + # One commit from topic branch, two from upstream, one merge commit + eq_(len(repo.get_commits(until='master')), 4) + + def test_branch_update(self): + """Check that the working copy is kept in sync with branch HEAD""" + repo = GitRepository.create('.') + orig1 = os.path.join(DATA_DIR, 'gbp-test-1.0.tar.bz2') + orig2 = os.path.join(DATA_DIR, 'gbp-test-1.1.tar.bz2') + eq_(mock_import(['--merge', orig1]), 0) + repo.set_branch('upstream') + eq_(mock_import([orig2]), 0) + files = ['Makefile', 'README', 'dummy.sh'] + self._check_repo_state(repo, 'upstream', ['master', 'upstream'], files) + eq_(len(repo.get_commits(until='upstream')), 2) + + def test_import_dir(self): + """Test importing of unpacked sources""" + # Unpack sources and create repo + orig = os.path.join(DATA_DIR, 'gbp-test-1.0.tar.bz2') + subprocess.Popen(['tar', 'xf', orig]) + repo = GitRepository.create('myrepo') + os.chdir('myrepo') + + # Import dir first, fool the version to be 0.9 + eq_(mock_import(['../gbp-test'], 'gbp-test\n0.9\n'), 0) + files = ['Makefile', 'README', 'dummy.sh'] + self.check_tree(repo, 'upstream', files) + self._check_repo_state(repo, None, ['upstream'], []) + + # Import from unpacked and check that the contents is the same + eq_(mock_import([orig]), 0) + eq_(len(repo.diff('upstream/0.9', 'upstream/1.0')), 0) + + def test_basic_filtering(self): + """Basic test for import filter""" + repo = GitRepository.create('.') + orig = os.path.join(DATA_DIR, 'gbp-test-1.1.with_dotgit.tar.bz2') + # Try importing a tarball with git metadata + eq_(mock_import([orig], 'gbp-test\n1.0\n'), 1) + self._check_log(0, 'gbp:error: The orig tarball contains .git') + + # Try filtering out .git directory and shell scripts + eq_(mock_import(['--filter=.git', '--filter=*.sh', '--merge', orig], + 'gbp-test\n1.0\n'), 0) + self._check_repo_state(repo, 'master', ['master', 'upstream']) + eq_(len(repo.get_commits(until='master')), 1) + eq_(len(repo.get_commits(until='upstream')), 1) + eq_(repo.get_tags(), ['upstream/1.0']) + added_files = repo.get_commit_info('upstream')['files']['A'] + eq_(set(added_files), set(['Makefile', 'README'])) + + def test_noninteractive(self): + """Test non-interactive mode""" + repo = GitRepository.create('testrepo') + orig = os.path.join(DATA_DIR, 'gbp-test-native-1.0.zip') + orig_renamed = os.path.join(os.path.abspath('.'), 'foo.zip') + shutil.copy(orig, orig_renamed) + os.chdir('testrepo') + + # Guessing name and version should fail + eq_(mock_import(['--no-interactive', orig_renamed]), 1) + self._check_log(-1, "gbp:error: Couldn't determine upstream package") + + # Guessing from the original archive should succeed + eq_(mock_import(['--no-interactive', '--merge', orig], + stdin_data=''), 0) + files = ['.gbp.conf', 'Makefile', 'README', 'dummy.sh', 'packaging/', + 'packaging/gbp-test-native.spec'] + self._check_repo_state(repo, 'master', ['master', 'upstream'], files) + eq_(len(repo.get_commits(until='master')), 1) + + # Import "new" version, this time package name should be taken from spec + eq_(mock_import(['--no-interactive', orig_renamed], stdin_data=''), 1) + self._check_log(-1, "gbp:error: Couldn't determine upstream version") + + def test_misc_options(self): + """Test various options of git-import-orig-rpm""" + repo = GitRepository.create('.') + # Import one orig with default options to get 'upstream' branch + orig = os.path.join(DATA_DIR, 'gbp-test-1.0.tar.bz2') + eq_(mock_import(['-u0.8', orig]), 0) + + # Import the "native" zip to get packaging files + orig = os.path.join(DATA_DIR, 'gbp-test-native-1.0.zip') + base_args = ['--packaging-branch=pack', '--upstream-branch=orig', + '--upstream-tag=orig/%(upstreamversion)s', '--merge'] + # Fake version to be 0.9 + extra_args = ['-u0.9', '--upstream-vcs-tag=upstream/0.8', orig] + eq_(mock_import(base_args + extra_args), 0) + # Check repository state + files = [] + self._check_repo_state(repo, None, ['pack', 'orig', 'upstream'], files) + eq_(len(repo.get_commits(until='pack')), 2) + # Check tags + tags = repo.get_tags() + eq_(set(tags), set(['upstream/0.8', 'orig/0.9'])) + + # Change to packaging branch and create new commit + repo.set_branch('pack') + shutil.copy2('.git/HEAD', 'my_new_file') + repo.add_files('.') + repo.commit_all('My new commit') + # Import a new version, name should be taken from spec + orig = os.path.join(DATA_DIR, 'gbp-test-1.1.tar.bz2') + extra_args = ['--packaging-dir=packaging', '--no-interactive', '-u1.1', + orig] + eq_(mock_import(base_args + extra_args, ''), 0) + # Threeupstream versions, "my new" commit and one merge commit + eq_(len(repo.get_commits(until='pack')), 5) + tags = repo.get_tags() + eq_(set(tags), set(['upstream/0.8', 'orig/0.9', 'orig/1.1'])) + + def test_import_hooks(self): + """Basic test for postimport hook""" + repo = GitRepository.create('.') + orig = os.path.join(DATA_DIR, 'gbp-test-1.0.tar.bz2') + + script = ("echo -n branch: $GBP_BRANCH, version: %(upstreamversion)s" + " > hook.txt") + eq_(mock_import(['--postimport', script, '--merge', orig]), 0) + self._check_repo_state(repo, 'master', ['master', 'upstream']) + eq_(repo.get_tags(), ['upstream/1.0']) + with open('hook.txt', 'r') as hookout: + data = hookout.read() + eq_(data, 'branch: master, version: 1.0') + + def test_hook_error(self): + """Test postimport hook failure""" + repo = GitRepository.create('.') + orig = os.path.join(DATA_DIR, 'gbp-test-1.0.tar.bz2') + eq_(mock_import(['--postimport=_notexist.sh', '--merge', orig]), 1) + self._check_log(-2, "gbp:error: '_notexist.sh' failed:") + self._check_log(-1, 'gbp:error: Import of %s failed' % orig) + # Other parts of the import should've succeeded + self._check_repo_state(repo, 'master', ['master', 'upstream']) + + +class TestPristineTar(ImportOrigTestBase): + """ + Test importing with pristine-tar + + Especially, tests different options for mangling the tarball. We basically + have these mostly independent options: + - filter + - filter-pristine-tar + - pristine-tarball-name + - orig-prefix + And, these options can be used in importing directories and tarballs and zip + files. + """ + + @classmethod + def setup_class(cls): + """Class setup, common for all test cases""" + if not os.path.exists('/usr/bin/pristine-tar'): + raise SkipTest('Skipping %s:%s as pristine-tar tool is not ' + 'available' % (__name__, cls.__name__)) + super(TestPristineTar, cls).setup_class() + + def __init__(self, *args, **kwargs): + super(TestPristineTar, self).__init__(*args, **kwargs) + self.repo = None + + def setup(self): + """Test case setup""" + super(TestPristineTar, self).setup() + self.repo = GitRepository.create('repo') + + def check_repo(self, current_branch, branches=None, files=None): + """Check the state of repo""" + if branches is None: + # Default branches + branches = ['upstream', 'pristine-tar'] + return self._check_repo_state(self.repo, current_branch, branches, + files) + + def check_tree(self, treeish, filelist): + """Check treeish content""" + return super(TestPristineTar, self).check_tree(self.repo, treeish, + filelist) + + @staticmethod + def unpack_tar(archive): + """Unpack tarball, return directory containing sources""" + tarobj = tarfile.open(archive, 'r') + os.mkdir('unpacked') + tarobj.extractall('unpacked') + tarobj.close() + dirlist = os.listdir('unpacked') + if len(dirlist) == 1: + return os.path.abspath(os.path.join('unpacked', dirlist[0])) + else: + return os.path.abspath('unpacked') + + def mock_import(self, args, stdin_data="\n\n"): + """Import helper for pristine-tar""" + return mock_import(args, stdin_data, self.repo.path) + + def ls_pristine_tar(self, archive): + """List contents of the tarball committed into pristine-tar""" + tmpdir = os.path.abspath(tempfile.mkdtemp(dir='.')) + tarball = os.path.join(tmpdir, archive) + try: + popen = subprocess.Popen(['pristine-tar', 'checkout', tarball], + cwd=self.repo.path) + popen.wait() + if popen.returncode: + raise Exception('Pristine-tar checkout failed!') + return ls_tar(tarball) + finally: + shutil.rmtree(tmpdir) + + def test_basic_import_pristine_tar(self): + """Test importing with pristine-tar""" + orig = os.path.join(DATA_DIR, 'gbp-test-1.0.tar.bz2') + eq_(self.mock_import(['--pristine-tar', '--merge', orig]), 0) + files = ['Makefile', 'README', 'dummy.sh'] + branches = ['master', 'upstream', 'pristine-tar'] + self.check_repo('master', branches, files) + subject = self.repo.get_commit_info('pristine-tar')['subject'] + eq_(subject, 'pristine-tar data for %s' % os.path.basename(orig)) + self.check_files(ls_tar(orig), + self.ls_pristine_tar('gbp-test-1.0.tar.bz2')) + + def test_rename(self): + """Renaming orig archive""" + orig = os.path.join(DATA_DIR, 'gbp-test-1.0.tar.bz2') + args = ['--pristine-tar', '--pristine-tarball-name=my.tgz', orig] + eq_(self.mock_import(args), 0) + self.check_repo(None, None, []) + self.check_files(ls_tar(orig), self.ls_pristine_tar('my.tgz')) + + def test_branch_update(self): + """Check that the working copy is kept in sync with branch HEAD""" + orig1 = os.path.join(DATA_DIR, 'gbp-test-1.0.tar.bz2') + orig2 = os.path.join(DATA_DIR, 'gbp-test-1.1.tar.bz2') + eq_(self.mock_import(['--pristine-tar', orig1]), 0) + self.repo.set_branch('pristine-tar') + eq_(self.mock_import(['--pristine-tar', orig2]), 0) + self.check_repo('pristine-tar', None) + eq_(len(self.repo.get_commits(until='pristine-tar')), 2) + + def test_zip(self): + """Importing zip file""" + orig = os.path.join(DATA_DIR, 'gbp-test-native-1.0.zip') + eq_(self.mock_import(['--pristine-tar', orig]), 0) + files = ['.gbp.conf', 'Makefile', 'README', 'dummy.sh', + 'packaging/gbp-test-native.spec'] + self.check_repo(None, None, []) + self.check_tree('upstream', files) + self.check_files(ls_zip(orig), + self.ls_pristine_tar('gbp-test-native-1.0.tar.gz')) + +#{ Test tarball mangling + def test_nopristinefilter(self): + """Test --no-pristine-tar-filter""" + orig = os.path.join(DATA_DIR, 'gbp-test-1.0.tar.bz2') + eq_(self.mock_import(['--pristine-tar', '--filter=README', orig]), 0) + self.check_repo(None, None, []) + self.check_tree('upstream', ['Makefile', 'dummy.sh']) + self.check_files(ls_tar(orig), + self.ls_pristine_tar('gbp-test-1.0.tar.bz2')) + + def test_nofilter_prefix(self): + """Test prefix mangling without any filtering""" + orig = os.path.join(DATA_DIR, 'gbp-test-1.0.tar.bz2') + eq_(self.mock_import(['--pristine-tar', '--orig-prefix=new', orig]), 0) + self.check_repo(None, None, None) + self.check_tree('upstream', ['Makefile', 'dummy.sh', 'README']) + prist_ref = set([fname.replace('gbp-test', 'new') for + fname in ls_tar(orig)]) + self.check_files(prist_ref, + self.ls_pristine_tar('gbp-test-1.0.tar.bz2')) + + def test_nopristinefilter_prefix(self): + """Test --no-pristine-tar-filter with prefix mangling""" + orig = os.path.join(DATA_DIR, 'gbp-test-1.0.tar.bz2') + args = ['--pristine-tar', '--filter=README', '--orig-prefix=new', orig] + eq_(self.mock_import(args), 0) + self.check_repo(None, None, None) + self.check_tree('upstream', ['Makefile', 'dummy.sh']) + prist_ref = set([fname.replace('gbp-test', 'new') for + fname in ls_tar(orig)]) + self.check_files(prist_ref, + self.ls_pristine_tar('gbp-test-1.0.tar.bz2')) + + def test_filter_prefix_rename(self): + """Test --no-pristine-tar-filter with prefix mangling""" + orig = os.path.join(DATA_DIR, 'gbp-test2-2.0.tar.gz') + args = ['--pristine-tar', '--filter=README', '--orig-prefix=new', + '--pristine-tarball-name=new.tbz2', '--filter-pristine-tar', + orig] + eq_(self.mock_import(args), 0) + self.check_repo(None, None, []) + self.check_tree('upstream', ['Makefile', 'dummy.sh']) + prist_ref = set(['new', 'new/Makefile', 'new/dummy.sh']) + self.check_files(prist_ref, self.ls_pristine_tar('new.tbz2')) + + def test_dir_nopristinefilter(self): + """Test importing directory with --no-pristine-tar-filter""" + orig = self.unpack_tar(os.path.join(DATA_DIR, 'gbp-test-1.0.tar.bz2')) + args = ['--pristine-tar', '--filter=README', orig] + eq_(self.mock_import(args, 'gbp-test\n1.0\n'), 0) + files = ['Makefile', 'dummy.sh'] + self.check_repo(None, None, []) + self.check_tree('upstream', ['Makefile', 'dummy.sh']) + prist_ref = set(['gbp-test-1.0/%s' % fname for fname in ls_dir(orig)] + + ['gbp-test-1.0']) + self.check_files(prist_ref, self.ls_pristine_tar('gbp-test.tar.gz')) + + def test_dir_filter_prefix(self): + """Test importing directory with prefix mangling""" + orig = self.unpack_tar(os.path.join(DATA_DIR, 'gbp-test-1.0.tar.bz2')) + args = ['--pristine-tar', '--filter=README', '--filter-pristine-tar', + '--orig-prefix=', '--pristine-tarball-name=my.tgz', orig] + eq_(self.mock_import(args, 'gbp-test\n1.0\n'), 0) + files = ['Makefile', 'dummy.sh'] + self.check_repo(None, None, []) + self.check_tree('upstream', files) + self.check_files(set(files), self.ls_pristine_tar('my.tgz')) + + +class TestBareRepo(ImportOrigTestBase): + """Test importing to a bare repository""" + + def test_basic_import_to_bare_repo(self): + """Test importing inside bare git repository""" + repo = GitRepository.create('.', bare=True) + orig = os.path.join(DATA_DIR, 'gbp-test-1.0.tar.bz2') + eq_(mock_import([orig]), 0) + self._check_repo_state(repo, None, ['upstream']) + eq_(len(repo.get_commits(until='upstream')), 1) + eq_(repo.get_tags(), ['upstream/1.0']) + + # Import another version + repo.set_branch('upstream') + orig = os.path.join(DATA_DIR, 'gbp-test-1.1.tar.bz2') + eq_(mock_import([orig]), 0) + self._check_repo_state(repo, 'upstream', ['upstream']) + eq_(len(repo.get_commits(until='upstream')), 2) + + def test_pristine_import_to_bare(self): + """Test importing inside bare git repository""" + repo = GitRepository.create('.', bare=True) + orig = os.path.join(DATA_DIR, 'gbp-test-1.0.tar.bz2') + eq_(mock_import([orig]), 0) + # No pristine-tar branch should be present + self._check_repo_state(repo, None, ['upstream']) + -- cgit v1.2.3 From b7f98f4875138c59655eeedf0e625803c2b6ac68 Mon Sep 17 00:00:00 2001 From: Markus Lehtonen Date: Tue, 3 Sep 2013 10:32:13 +0300 Subject: rpm tests: slight modificatin of import-srpm tests Use eq_() and ok() from nose.tools for better assert messages. Signed-off-by: Markus Lehtonen --- tests/component/rpm/test_import_srpm.py | 120 +++++++++++++++++--------------- 1 file changed, 62 insertions(+), 58 deletions(-) diff --git a/tests/component/rpm/test_import_srpm.py b/tests/component/rpm/test_import_srpm.py index efc4204f..69933912 100644 --- a/tests/component/rpm/test_import_srpm.py +++ b/tests/component/rpm/test_import_srpm.py @@ -20,7 +20,7 @@ import os import shutil import urllib2 from nose.plugins.skip import SkipTest -from nose.tools import assert_raises # pylint: disable=E0611 +from nose.tools import assert_raises, eq_, ok_ # pylint: disable=E0611 from mock import Mock from gbp.scripts.import_srpm import main as import_srpm @@ -33,19 +33,25 @@ from tests.component.rpm import RPM_TEST_DATA_DIR as DATA_DIR # Disable "Method could be a function warning" # pylint: disable=R0201 +def mock_import(args): + """Wrapper for import-srpm""" + # Call import-orig-rpm with added arg0 + return import_srpm(['arg0'] + args) + + class TestImportPacked(ComponentTestBase): """Test importing of src.rpm files""" def test_invalid_args(self): """See that import-srpm fails gracefully if called with invalid args""" - assert import_srpm(['arg0']) == 1 + eq_(mock_import([]), 1) with assert_raises(SystemExit): - import_srpm(['arg0', '--invalid-arg=123']) + mock_import(['--invalid-arg=123']) def test_basic_import(self): """Test importing of non-native src.rpm""" srpm = os.path.join(DATA_DIR, 'gbp-test-1.0-1.src.rpm') - assert import_srpm(['arg0', srpm]) == 0 + eq_(mock_import([srpm]), 0) # Check repository state repo = GitRepository('gbp-test') files = set(['Makefile', 'README', 'bar.tar.gz', 'dummy.sh', 'foo.txt', @@ -53,12 +59,12 @@ class TestImportPacked(ComponentTestBase): self._check_repo_state(repo, 'master', ['master', 'upstream'], files) # Four commits: upstream, packaging files, one patch and the removal # of imported patches - assert len(repo.get_commits()) == 4 + eq_(len(repo.get_commits()), 4) def test_basic_import2(self): """Import package with multiple spec files and full url patch""" srpm = os.path.join(DATA_DIR, 'gbp-test2-2.0-0.src.rpm') - assert import_srpm(['arg0', srpm]) == 0 + eq_(mock_import([srpm]), 0) # Check repository state repo = GitRepository('gbp-test2') files = set(['Makefile', 'README', 'bar.tar.gz', 'dummy.sh', 'foo.txt', @@ -68,7 +74,7 @@ class TestImportPacked(ComponentTestBase): # Four commits: upstream, packaging files, one patch and the removal # of imported patches - assert len(repo.get_commits()) == 4 + eq_(len(repo.get_commits()), 4) def test_basic_import_orphan(self): """ @@ -76,41 +82,41 @@ class TestImportPacked(ComponentTestBase): development branches """ srpm = os.path.join(DATA_DIR, 'gbp-test2-2.0-0.src.rpm') - assert import_srpm(['arg0', '--orphan-packaging', srpm]) == 0 + eq_(mock_import(['--orphan-packaging', srpm]), 0) # Check repository state repo = GitRepository('gbp-test2') files = set(['bar.tar.gz', 'foo.txt', 'gbp-test2.spec', 'gbp-test2-alt.spec', 'my.patch', 'my2.patch', 'my3.patch']) self._check_repo_state(repo, 'master', ['master', 'upstream'], files) # Only one commit: the packaging files - assert len(repo.get_commits()) == 1 + eq_(len(repo.get_commits()), 1) def test_basic_native_import(self): """Test importing of native src.rpm""" srpm = os.path.join(DATA_DIR, 'gbp-test-native-1.0-1.src.rpm') - assert import_srpm(['arg0', '--native', srpm]) == 0 + eq_(mock_import(['--native', srpm]), 0) # Check repository state files = set(['.gbp.conf', 'Makefile', 'README', 'dummy.sh', 'packaging/', 'packaging/gbp-test-native.spec']) repo = GitRepository('gbp-test-native') self._check_repo_state(repo, 'master', ['master'], files) # Only one commit: the imported source tarball - assert len(repo.get_commits()) == 1 + eq_(len(repo.get_commits()), 1) def test_import_no_orig_src(self): """Test importing of (native) srpm without orig tarball""" srpm = os.path.join(DATA_DIR, 'gbp-test-native2-2.0-0.src.rpm') - assert import_srpm(['arg0', srpm]) == 0 + eq_(mock_import([srpm]), 0) # Check repository state repo = GitRepository('gbp-test-native2') self._check_repo_state(repo, 'master', ['master']) # Only one commit: packaging files - assert len(repo.get_commits()) == 1 + eq_(len(repo.get_commits()), 1) def test_import_compressed_patches(self): """Test importing of non-native src.rpm with compressed patches""" srpm = os.path.join(DATA_DIR, 'gbp-test-1.1-2.src.rpm') - assert import_srpm(['arg0', srpm]) == 0 + eq_(mock_import([srpm]), 0) # Check repository state repo = GitRepository('gbp-test') files = set(['Makefile', 'README', 'AUTHORS', 'NEWS', 'bar.tar.gz', @@ -119,35 +125,35 @@ class TestImportPacked(ComponentTestBase): self._check_repo_state(repo, 'master', ['master', 'upstream'], files) # Four commits: upstream, packaging files, three patches and the removal # of imported patches - assert len(repo.get_commits()) == 6 + eq_(len(repo.get_commits()), 6) def test_multiple_versions(self): """Test importing of multiple versions""" srpms = [ os.path.join(DATA_DIR, 'gbp-test-1.0-1.src.rpm'), os.path.join(DATA_DIR, 'gbp-test-1.0-1.other.src.rpm'), os.path.join(DATA_DIR, 'gbp-test-1.1-1.src.rpm') ] - assert import_srpm(['arg0', srpms[0]]) == 0 + eq_(mock_import([srpms[0]]), 0) repo = GitRepository('gbp-test') self._check_repo_state(repo, 'master', ['master', 'upstream']) - assert len(repo.get_commits()) == 4 + eq_(len(repo.get_commits()), 4) # Try to import same version again - assert import_srpm(['arg0', srpms[1]]) == 0 - assert len(repo.get_commits()) == 4 - assert len(repo.get_commits(until='upstream')) == 1 - assert import_srpm(['arg0', '--allow-same-version', srpms[1]]) == 0 + eq_(mock_import([srpms[1]]), 0) + eq_(len(repo.get_commits()), 4) + eq_(len(repo.get_commits(until='upstream')), 1) + eq_(mock_import(['--allow-same-version', srpms[1]]), 0) # Added new versio packaging plus one patch - assert len(repo.get_commits()) == 7 - assert len(repo.get_commits(until='upstream')) == 1 + eq_(len(repo.get_commits()), 7) + eq_(len(repo.get_commits(until='upstream')), 1) # Import new version - assert import_srpm(['arg0', srpms[2]]) == 0 + eq_(mock_import([srpms[2]]), 0) files = set(['Makefile', 'README', 'bar.tar.gz', 'dummy.sh', 'foo.txt', 'gbp-test.spec', 'my.patch', 'mydir/', 'mydir/myfile.txt']) self._check_repo_state(repo, 'master', ['master', 'upstream'], files) - assert len(repo.get_commits()) == 11 - assert len(repo.get_commits(until='upstream')) == 2 + eq_(len(repo.get_commits()), 11) + eq_(len(repo.get_commits(until='upstream')), 2) # Check number of tags - assert len(repo.get_tags('upstream/*')) == 2 - assert len(repo.get_tags('vendor/*')) == 3 + eq_(len(repo.get_tags('upstream/*')), 2) + eq_(len(repo.get_tags('vendor/*')), 3) def test_import_to_existing(self): """Test importing to an existing repo""" @@ -162,31 +168,30 @@ class TestImportPacked(ComponentTestBase): # Test importing to non-clean repo shutil.copy2('.git/HEAD', 'foobaz') - assert import_srpm(['arg0', '--create-missing', srpm]) == 1 + eq_(mock_import(['--create-missing', srpm]), 1) self._check_log(0, 'gbp:error: Repository has uncommitted changes') self._clear_log() os.unlink('foobaz') # The first import should fail because upstream branch is missing - assert import_srpm(['arg0', srpm]) == 1 + eq_(mock_import([srpm]), 1) self._check_log(-1, 'Also check the --create-missing-branches') - assert import_srpm(['arg0', '--create-missing', srpm]) == 0 + eq_(mock_import(['--create-missing', srpm]), 0) self._check_repo_state(repo, 'master', ['master', 'upstream']) # Four commits: our initial, upstream, packaging files, one patch, # and the removal of imported patches - assert len(repo.get_commits()) == 5 + eq_(len(repo.get_commits()), 5) # The import should fail because missing packaging-branch srpm = os.path.join(DATA_DIR, 'gbp-test-1.1-1.src.rpm') - assert import_srpm(['arg0', '--packaging-branch=foo', srpm]) == 1 + eq_(mock_import(['--packaging-branch=foo', srpm]), 1) self._check_log(-1, 'Also check the --create-missing-branches') def test_filter(self): """Test filter option""" srpm = os.path.join(DATA_DIR, 'gbp-test-1.0-1.src.rpm') - assert import_srpm(['arg0', '--filter=README', '--filter=mydir', - srpm]) == 0 + eq_(mock_import(['--filter=README', '--filter=mydir', srpm]), 0) # Check repository state repo = GitRepository('gbp-test') files = set(['Makefile', 'dummy.sh', 'bar.tar.gz', 'foo.txt', @@ -197,8 +202,7 @@ class TestImportPacked(ComponentTestBase): """Test various options of git-import-srpm""" srpm = os.path.join(DATA_DIR, 'gbp-test2-2.0-0.src.rpm') - assert import_srpm([ - 'arg0', + eq_(mock_import([ '--no-patch-import', '--packaging-branch=pack', '--upstream-branch=orig', @@ -206,7 +210,7 @@ class TestImportPacked(ComponentTestBase): '--packaging-tag=ver_%(upstreamversion)s-rel_%(release)s', '--upstream-tag=orig/%(upstreamversion)s', '--author-is-committer', - srpm]) == 0 + srpm]), 0) # Check repository state repo = GitRepository('gbp-test2') files = set(['Makefile', 'README', 'dummy.sh', 'packaging/', @@ -215,18 +219,18 @@ class TestImportPacked(ComponentTestBase): 'packaging/my.patch', 'packaging/my2.patch', 'packaging/my3.patch']) self._check_repo_state(repo, 'pack', ['pack', 'orig'], files) - assert len(repo.get_commits()) == 2 + eq_(len(repo.get_commits()), 2) # Check packaging dir - assert len(repo.get_commits(paths='packaging')) == 1 + eq_(len(repo.get_commits(paths='packaging')), 1) # Check tags tags = repo.get_tags() - assert set(tags) == set(['orig/2.0', 'ver_2.0-rel_0']) + eq_(set(tags), set(['orig/2.0', 'ver_2.0-rel_0'])) # Check git committer/author info = repo.get_commit_info('pack') - assert info['author'].name == 'Markus Lehtonen' - assert info['author'].email == 'markus.lehtonen@linux.intel.com' - assert info['author'].name == info['committer'].name - assert info['author'].email == info['committer'].email + eq_(info['author'].name, 'Markus Lehtonen') + eq_(info['author'].email, 'markus.lehtonen@linux.intel.com') + eq_(info['author'].name, info['committer'].name) + eq_(info['author'].email, info['committer'].email) class TestImportUnPacked(ComponentTestBase): @@ -245,28 +249,28 @@ class TestImportUnPacked(ComponentTestBase): def test_import_dir(self): """Test importing of directories""" - assert import_srpm(['arg0', 'gbp-test-1.0-1-unpack']) == 0 + eq_(mock_import(['gbp-test-1.0-1-unpack']), 0) # Check repository state repo = GitRepository('gbp-test') self._check_repo_state(repo, 'master', ['master', 'upstream']) # Check that importing dir with multiple spec files fails - assert import_srpm(['arg0', 'multi-unpack']) == 1 + eq_(mock_import(['multi-unpack']), 1) self._check_log(-1, 'gbp:error: Failed determine spec file: ' 'Multiple spec files found') def test_import_spec(self): """Test importing of spec file""" specfile = 'gbp-test2-2.0-0-unpack/gbp-test2.spec' - assert import_srpm(['arg0', specfile]) == 0 + eq_(mock_import([specfile]), 0) # Check repository state - assert GitRepository('gbp-test2').is_clean() + ok_(GitRepository('gbp-test2').is_clean()) def test_missing_files(self): """Test importing of directory with missing packaging files""" specfile = 'gbp-test2-2.0-0-unpack/gbp-test2.spec' os.unlink('gbp-test2-2.0-0-unpack/my.patch') - assert import_srpm(['arg0', specfile]) == 1 + eq_(mock_import([specfile]), 1) self._check_log(-1, "gbp:error: File 'my.patch' listed in spec " "not found") @@ -283,7 +287,7 @@ class TestDownloadImport(ComponentTestBase): urllib2.urlopen = Mock() urllib2.urlopen.return_value = open(local_fn, 'r') - assert import_srpm(['arg0', '--download', srpm]) == 0 + eq_(mock_import(['--download', srpm]), 0) # Check repository state repo = GitRepository('gbp-test') self._check_repo_state(repo, 'master', ['master', 'upstream']) @@ -296,14 +300,14 @@ class TestDownloadImport(ComponentTestBase): urllib2.urlopen.side_effect = urllib2.HTTPError(srpm, 404, "Not found", None, None) - assert import_srpm(['arg0', '--download', srpm]) == 1 + eq_(mock_import(['--download', srpm]), 1) self._check_log(-1, "gbp:error: Download failed: HTTP Error 404") self._clear_log() def test_invalid_url(self): """Test graceful failure when trying download from invalid url""" srpm = 'foob://url.does.not.exist.com/foo.src.rpm' - assert import_srpm(['arg0', '--download', srpm]) == 1 + eq_(mock_import(['--download', srpm]), 1) self._check_log(-1, "gbp:error: Download failed: unknown url type:") self._clear_log() @@ -321,19 +325,19 @@ class TestPristineTar(ComponentTestBase): def test_basic_import_pristine_tar(self): """Test importing of non-native src.rpm, with pristine-tar""" srpm = os.path.join(DATA_DIR, 'gbp-test-1.0-1.src.rpm') - assert import_srpm(['arg0', '--pristine-tar', srpm]) == 0 + eq_(mock_import(['--pristine-tar', srpm]), 0) # Check repository state repo = GitRepository('gbp-test') self._check_repo_state(repo, 'master', ['master', 'upstream', 'pristine-tar']) # Four commits: upstream, packaging files, one patch and the removal # of imported patches - assert len(repo.get_commits()) == 4 + eq_(len(repo.get_commits()), 4) def test_unsupported_archive(self): """Test importing of src.rpm with a zip source archive""" srpm = os.path.join(DATA_DIR, 'gbp-test-native-1.0-1.src.rpm') - assert import_srpm(['arg0', '--pristine-tar', srpm]) == 0 + eq_(mock_import(['--pristine-tar', srpm]), 0) # Check repository state repo = GitRepository('gbp-test-native') self._check_repo_state(repo, 'master', ['master', 'upstream']) @@ -350,9 +354,9 @@ class TestBareRepo(ComponentTestBase): # Create new repo repo = GitRepository.create('myrepo', bare=True) os.chdir('myrepo') - assert import_srpm(['arg0', srpm]) == 0 + eq_(mock_import([srpm]), 0) self._check_repo_state(repo, 'master', ['master', 'upstream']) # Patch import to bare repos not supported -> only 2 commits - assert len(repo.get_commits(until='master')) == 2 + eq_(len(repo.get_commits(until='master')), 2) # vim:et:ts=4:sw=4:et:sts=4:ai:set list listchars=tab\:»·,trail\:·: -- cgit v1.2.3 From 04e6f7864e4a9a594238b1f6b16051869a103c6e Mon Sep 17 00:00:00 2001 From: Markus Lehtonen Date: Thu, 25 Oct 2012 09:35:46 +0300 Subject: packaging: Release, update changelogs Add rpm changelog. Start providing proper changelogs for Tizen Tools releases. Also, make it easier to track Tizen releases: - RPM: Add a 'Provides:' tag to the git-buildpackage-rpm subpackage in order to be able to track Tizen releases. - DEB: Change the package to non-native, by adding a corresponding release number to the version field in changelog of Debian packaging. Signed-off-by: Markus Lehtonen --- debian/changelog | 21 +++++++++++++++++++++ packaging/git-buildpackage.changes | 14 ++++++++++++++ packaging/git-buildpackage.spec | 1 + 3 files changed, 36 insertions(+) create mode 100644 packaging/git-buildpackage.changes diff --git a/debian/changelog b/debian/changelog index 93d533c1..0255e576 100644 --- a/debian/changelog +++ b/debian/changelog @@ -436,6 +436,27 @@ git-buildpackage (0.6.0) unstable; urgency=low -- Guido Günther Wed, 26 Jun 2013 16:36:41 +0200 +git-buildpackage (0.6.0git20130530-tizen20130822) unstable; urgency=low + + [ Markus Lehtonen ] + * GitRepository/add_files: consistently update all tracked files + * rpm: enhance spec parsing error messages + * rpm: simplify SpecFile._parse_filtered_spec() + * rpm: implement a wrapper module for rpm lib + * rpm: print a warning if importing gbp-specific librpm fails + * rpm: Improve logging in case of rpmlib error + + [ Lingchaox Xin ] + * GitRepository: Add force option to push method + * GitRepository: Add all option to pull method + * GitRepository: Add refspec option to fetch method + * Fix pylint warnings, follow Markus' sugesstion + * Add tags option in git push command + * Add all_remotes option in git fetch command + * Add clean method to GitRepository class + + -- Markus Lehtonen Thu, 22 Aug 2013 09:47:51 +0300 + git-buildpackage (0.6.0~git20130530) unstable; urgency=low [ Guido Günther ] diff --git a/packaging/git-buildpackage.changes b/packaging/git-buildpackage.changes new file mode 100644 index 00000000..bb201bfa --- /dev/null +++ b/packaging/git-buildpackage.changes @@ -0,0 +1,14 @@ +* Thu Aug 22 2013 Markus Lehtonen 0.6.0git20130530 +- rpm: Improve logging in case of rpmlib error +- Add clean method to GitRepository class +- Add all_remotes option in git fetch command +- Add tags option in git push command +- rpm: print a warning if importing gbp-specific librpm fails +- rpm: implement a wrapper module for rpm lib +- rpm: simplify SpecFile._parse_filtered_spec() +- Fix pylint warnings, follow Markus' sugesstion +- rpm: enhance spec parsing error messages +- GitRepository/add_files: consistently update all tracked files +- GitRepository: Add refspec option to fetch method +- GitRepository: Add all option to pull method +- GitRepository: Add force option to push method diff --git a/packaging/git-buildpackage.spec b/packaging/git-buildpackage.spec index 1b0fab79..374a6124 100644 --- a/packaging/git-buildpackage.spec +++ b/packaging/git-buildpackage.spec @@ -100,6 +100,7 @@ Group: Development/Tools/Building Requires: %{name}-common = %{version}-%{release} Requires: rpm Requires: %{rpm_python_pkg_name} +Provides: tizen-gbp-rpm = 20130822 %description rpm Set of tools from Debian that integrate the package build system with Git. -- cgit v1.2.3 From 044242ca50080afade5d067116a6d5ccf6bdcfa1 Mon Sep 17 00:00:00 2001 From: Markus Lehtonen Date: Mon, 2 Sep 2013 14:46:30 +0300 Subject: packaging: Update changelogs Signed-off-by: Markus Lehtonen --- debian/changelog | 37 +++++++++++++++++++++++++++++++++++++ packaging/git-buildpackage.changes | 31 +++++++++++++++++++++++++++++++ packaging/git-buildpackage.spec | 2 +- 3 files changed, 69 insertions(+), 1 deletion(-) diff --git a/debian/changelog b/debian/changelog index 0255e576..2eba00b3 100644 --- a/debian/changelog +++ b/debian/changelog @@ -300,6 +300,43 @@ git-buildpackage (0.6.4) unstable; urgency=low -- Guido Günther Sun, 06 Oct 2013 17:35:14 +0200 +git-buildpackage (0.6.3-tizen20130902) UNRELEASED; urgency=low + + [ Lingchaox Xin ] + * Fix `fatal: fetch --all does not take a repository argument` + + [ Markus Lehtonen ] + * UpstreamSource.guess_version: don't check for directories + * UpstreamSource: move version guessing logic to PkgPolicy + * rpm: UpstreamSource: move version guessing logic to PkgPolicy + * UpstreamSource: store the absolute path + * UpstreamSource: check that the sources exist + * UpstreamSource: implement prefix guessing + * rpm: UpstreamSource: implement prefix guessing + * UpstreamSource.pack: reuse unpacked dir if no filter is used + * UpstreamSource.unpack: return UpstreamSource instance + * import orig: import readline in the common module + * rpm: import orig: import readline in the common module + * buildpackage: fix handling of empty tarball prefix + * import-orig: new function for filtering/re-packing sources + * import-orig: rework sourcecode preparation and filtering + * tests.testutils: add ls_zip() helper + * rpm tests: test --filter option of git-import-srpm + * ComponentTestBase: more verbose output in case of branch mismatch + * import-orig-rpm: don't crash on invalid gbp.conf + * import-orig-rpm: remove unneeded try-except + * config: restore mangled env in doctests + * ComponentTestBase: fix env restore in teardown + * ComponentTestBase: keep tmpdir if GBP_TESTS_NOCLEAN is in env + * tests: add tests for git-import-orig-rpm + * ComponentTestBase: use eq_() ok_() from nose.tools + * rpm tests: slight modificatin of import-srpm tests + * Version bump, rebase on top of 0.6.3 + * docs: minor sgml syntax fix + * Disable cover-min-percentage setting of nose + + -- Markus Lehtonen Mon, 02 Sep 2013 14:44:00 +0300 + git-buildpackage (0.6.3) unstable; urgency=low * [60ffe95] --git-hooks doesn't take an argument diff --git a/packaging/git-buildpackage.changes b/packaging/git-buildpackage.changes index bb201bfa..35af7834 100644 --- a/packaging/git-buildpackage.changes +++ b/packaging/git-buildpackage.changes @@ -1,3 +1,34 @@ +* Tue Sep 03 2013 Markus Lehtonen 0.6.3 +- Version bump, rebase on top of 0.6.3 + * Disable cover-min-percentage setting of nose + * docs: minor sgml syntax fix +- rpm tests: slight modificatin of import-srpm tests +- ComponentTestBase: use eq_() ok_() from nose.tools +- tests: add tests for git-import-orig-rpm +- ComponentTestBase: keep tmpdir if GBP_TESTS_NOCLEAN is in env +- ComponentTestBase: fix env restore in teardown +- config: restore mangled env in doctests +- import-orig-rpm: remove unneeded try-except +- import-orig-rpm: don't crash on invalid gbp.conf +- ComponentTestBase: more verbose output in case of branch mismatch +- rpm tests: test --filter option of git-import-srpm +- tests.testutils: add ls_zip() helper +- import-orig: rework sourcecode preparation and filtering +- import-orig: new function for filtering/re-packing sources +- buildpackage: fix handling of empty tarball prefix +- rpm: import orig: import readline in the common module +- import orig: import readline in the common module +- UpstreamSource.unpack: return UpstreamSource instance +- UpstreamSource.pack: reuse unpacked dir if no filter is used +- rpm: UpstreamSource: implement prefix guessing +- UpstreamSource: implement prefix guessing +- UpstreamSource: check that the sources exist +- UpstreamSource: store the absolute path +- rpm: UpstreamSource: move version guessing logic to PkgPolicy +- UpstreamSource: move version guessing logic to PkgPolicy +- UpstreamSource.guess_version: don't check for directories +- Fix `fatal: fetch --all does not take a repository argument` + * Thu Aug 22 2013 Markus Lehtonen 0.6.0git20130530 - rpm: Improve logging in case of rpmlib error - Add clean method to GitRepository class diff --git a/packaging/git-buildpackage.spec b/packaging/git-buildpackage.spec index 374a6124..5883fcac 100644 --- a/packaging/git-buildpackage.spec +++ b/packaging/git-buildpackage.spec @@ -100,7 +100,7 @@ Group: Development/Tools/Building Requires: %{name}-common = %{version}-%{release} Requires: rpm Requires: %{rpm_python_pkg_name} -Provides: tizen-gbp-rpm = 20130822 +Provides: tizen-gbp-rpm = 20130902 %description rpm Set of tools from Debian that integrate the package build system with Git. -- cgit v1.2.3 From b1c4e6b136598dd08a06e3e8a6529577772f8ecf Mon Sep 17 00:00:00 2001 From: Markus Lehtonen Date: Mon, 2 Sep 2013 14:56:57 +0300 Subject: debian packaging: change to 1.0 source package format Changes package to be non-native (assuming debian/changelog has version in correct format). Signed-off-by: Markus Lehtonen --- debian/source/format | 2 +- debian/source/options | 2 ++ 2 files changed, 3 insertions(+), 1 deletion(-) create mode 100644 debian/source/options diff --git a/debian/source/format b/debian/source/format index 89ae9db8..d3827e75 100644 --- a/debian/source/format +++ b/debian/source/format @@ -1 +1 @@ -3.0 (native) +1.0 diff --git a/debian/source/options b/debian/source/options new file mode 100644 index 00000000..f2592903 --- /dev/null +++ b/debian/source/options @@ -0,0 +1,2 @@ +extend-diff-ignore = "^(tests/test_rpm_data/.*|tests/component/rpm/data/.*|tests/component/deb/data/.*)" +diff-ignore -- cgit v1.2.3 From 843d9a4df81624a4db619069587adb678535a48d Mon Sep 17 00:00:00 2001 From: Markus Lehtonen Date: Mon, 3 Dec 2012 10:21:43 +0200 Subject: GitRepository/get_remote_repos: return URLs, too In addition to the remote name, return remote URLs. Return value is now a dict with remote name as the key and a list of URLs as the value. The first value in the list is the effective fetch URL, the rest of the values are push URLs. NOTE! This patch is to be dropped, not going for upstream. Signed-off-by: Markus Lehtonen --- gbp/git/repository.py | 21 ++++++++++++++++++--- tests/test_GitRepository.py | 5 +++-- 2 files changed, 21 insertions(+), 5 deletions(-) diff --git a/gbp/git/repository.py b/gbp/git/repository.py index 04ba849a..cd779152 100644 --- a/gbp/git/repository.py +++ b/gbp/git/repository.py @@ -1187,10 +1187,25 @@ class GitRepository(object): @deprecated: Use get_remotes() instead @return: remote repositories - @rtype: C{list} of C{str} + @rtype: C{dict} of C{list} of C{str} """ - out = self._git_getoutput('remote')[0] - return [ remote.strip() for remote in out ] + stdout, stderr, ret = self._git_inout('remote', ['-v'], + capture_stderr=True) + if ret: + raise GitRepositoryError('Failed to get remotes: %s' % stderr) + + remotes = {} + for rem in stdout.splitlines(): + name, url_urltype = rem.split('\t', 1) + url, urltype = url_urltype.rsplit(' ', 1) + urltype = urltype.strip('()') + if not name in remotes: + remotes[name] = [''] + if urltype == 'fetch': + remotes[name][0] = url + else: + remotes[name].append(url) + return remotes def has_remote_repo(self, name): """ diff --git a/tests/test_GitRepository.py b/tests/test_GitRepository.py index b1a14326..e44b60b7 100644 --- a/tests/test_GitRepository.py +++ b/tests/test_GitRepository.py @@ -577,8 +577,9 @@ def test_clone(): >>> clone.get_merge_branch('bar') # None if no merge branch exists >>> clone.get_local_branches() ['bar', 'foo', 'master'] - >>> clone.get_remote_repos() - ['origin'] + >>> remotes = clone.get_remote_repos() + >>> {'origin': [repo_dir, repo_dir]} == remotes + True >>> clone.has_remote_repo('origin') True >>> clone.has_branch('origin/master', remote=True) -- cgit v1.2.3 From f55ceda38c9cb242a9c1079ff34976fa2104b927 Mon Sep 17 00:00:00 2001 From: Markus Lehtonen Date: Fri, 6 Sep 2013 16:43:23 +0300 Subject: rpm: change guess_spec() to return SpecFile object Signed-off-by: Markus Lehtonen --- gbp/rpm/__init__.py | 10 ++-------- gbp/scripts/buildpackage_rpm.py | 10 +++++----- gbp/scripts/import_orig_rpm.py | 14 +++++++------- gbp/scripts/import_srpm.py | 13 ++++++------- gbp/scripts/pq_rpm.py | 28 +++++++++++----------------- tests/test_rpm.py | 16 ++++------------ 6 files changed, 35 insertions(+), 56 deletions(-) diff --git a/gbp/rpm/__init__.py b/gbp/rpm/__init__.py index e62ae2d2..6815b0cd 100644 --- a/gbp/rpm/__init__.py +++ b/gbp/rpm/__init__.py @@ -755,13 +755,6 @@ def parse_srpm(srpmfile): return srcrpm -def parse_spec(specfile): - try: - return SpecFile(specfile) - except IOError, err: - raise GbpError, "Error reading spec file: %s" % err - - def guess_spec(topdir, recursive=True, preferred_name=None): """Guess a spec file""" specs = [] @@ -790,7 +783,8 @@ def guess_spec(topdir, recursive=True, preferred_name=None): filenames = [os.path.relpath(spec, abstop) for spec in specs] raise NoSpecError("Multiple spec files found (%s), don't know which " "to use." % ', '.join(filenames)) - return specs[0] + return SpecFile(specs[0]) + def guess_spec_repo(repo, branch, packaging_dir): """ diff --git a/gbp/scripts/buildpackage_rpm.py b/gbp/scripts/buildpackage_rpm.py index 56c6b893..b57c5285 100755 --- a/gbp/scripts/buildpackage_rpm.py +++ b/gbp/scripts/buildpackage_rpm.py @@ -514,12 +514,12 @@ def main(argv): options.packaging_dir = os.path.dirname(specfile) if not os.path.exists(specfile): raise rpm.NoSpecError("Failed to export specfile: %s" % options.spec_file) + spec = rpm.SpecFile(specfile) else: - specfile = rpm.guess_spec(os.path.join(dump_dir, options.packaging_dir), - True, - os.path.basename(repo.path) + '.spec') - spec = rpm.SpecFile(specfile) - gbp.log.debug("Using spec file '%s'" % specfile) + spec = rpm.guess_spec(os.path.join(dump_dir, options.packaging_dir), + True, + os.path.basename(repo.path) + '.spec') + gbp.log.debug("Using spec file '%s'" % spec.specfile) if not options.tag_only: # Setup builder opts diff --git a/gbp/scripts/import_orig_rpm.py b/gbp/scripts/import_orig_rpm.py index 62edd145..b208ad12 100755 --- a/gbp/scripts/import_orig_rpm.py +++ b/gbp/scripts/import_orig_rpm.py @@ -25,8 +25,8 @@ import gbp.tmpfile as tempfile import gbp.command_wrappers as gbpc import string from gbp.pkg import parse_archive_filename -from gbp.rpm import (RpmUpstreamSource, SpecFile, NoSpecError, parse_spec, - guess_spec, guess_spec_repo) +from gbp.rpm import (RpmUpstreamSource, SpecFile, NoSpecError, guess_spec, + guess_spec_repo) from gbp.rpm.policy import RpmPkgPolicy from gbp.rpm.git import (GitRepositoryError, RpmGitRepository) from gbp.config import GbpOptionParserRpm, GbpOptionGroup, no_upstream_branch_msg @@ -48,17 +48,17 @@ def detect_name_and_version(repo, source, options): # Try to find the source package name try: - spec = parse_spec(guess_spec(os.path.join(repo.path, options.packaging_dir), - True, - os.path.basename(repo.path) + '.spec')) + preferred_fn = os.path.basename(repo.path) + '.spec' + spec = guess_spec(os.path.join(repo.path, options.packaging_dir), True, + preferred_fn) sourcepackage = spec.name except NoSpecError: try: # Check the spec file from the repository, in case # we're not on the packaging-branch (but upstream, for # example). - specfile = guess_spec_repo(repo, options.packaging_branch, options.packaging_dir) - spec = SpecFile(specfile) + spec = guess_spec_repo(repo, options.packaging_branch, + options.packaging_dir) sourcepackage = spec.name except NoSpecError: if options.interactive: diff --git a/gbp/scripts/import_srpm.py b/gbp/scripts/import_srpm.py index bf661027..01c225cc 100755 --- a/gbp/scripts/import_srpm.py +++ b/gbp/scripts/import_srpm.py @@ -29,8 +29,8 @@ import urllib2 import gbp.tmpfile as tempfile import gbp.command_wrappers as gbpc -from gbp.rpm import (parse_srpm, guess_spec, NoSpecError, parse_spec, - RpmUpstreamSource) +from gbp.rpm import (parse_srpm, guess_spec, SpecFile, NoSpecError, + RpmUpstreamSource) from gbp.rpm.policy import RpmPkgPolicy from gbp.rpm.git import (RpmGitRepository, GitRepositoryError) from gbp.git.modifier import GitModifier @@ -290,12 +290,12 @@ def main(argv): if os.path.isdir(srpm): gbp.log.debug("Trying to import an unpacked srpm from '%s'" % srpm) dirs['src'] = os.path.abspath(srpm) - spec = parse_spec(guess_spec(srpm, True, preferred_spec)) + spec = guess_spec(srpm, True, preferred_spec) else: gbp.log.debug("Trying to import an srpm from '%s' with spec "\ "file '%s'" % (os.path.dirname(srpm), srpm)) dirs['src'] = os.path.abspath(os.path.dirname(srpm)) - spec = parse_spec(srpm) + spec = SpecFile(srpm) # Check the repository state try: @@ -489,9 +489,8 @@ def main(argv): # (only for non-native packages with non-orphan packaging) force_to_branch_head(repo, options.packaging_branch) if options.patch_import: - spec = parse_spec(os.path.join(repo.path, - options.packaging_dir, - spec.specfile)) + spec = SpecFile(os.path.join(repo.path, + options.packaging_dir, spec.specfile)) import_spec_patches(repo, spec, dirs) commit = options.packaging_branch diff --git a/gbp/scripts/pq_rpm.py b/gbp/scripts/pq_rpm.py index cf7b29ad..aba63537 100755 --- a/gbp/scripts/pq_rpm.py +++ b/gbp/scripts/pq_rpm.py @@ -185,13 +185,11 @@ def export_patches(repo, branch, options): # Find and parse .spec file try: if options.spec_file != 'auto': - specfilename = options.spec_file options.packaging_dir = os.path.dirname(specfilename) + spec = SpecFile(options.packaging_dir) else: - specfilename = guess_spec(options.packaging_dir, - True, - os.path.basename(repo.path) + '.spec') - spec = SpecFile(specfilename) + spec = guess_spec(options.packaging_dir, True, + os.path.basename(repo.path) + '.spec') except KeyError: raise GbpError, "Can't parse spec" @@ -293,13 +291,11 @@ def import_spec_patches(repo, branch, options): # Find and parse .spec file try: if options.spec_file != 'auto': - specfilename = options.spec_file - options.packaging_dir = os.path.dirname(specfilename) + options.packaging_dir = os.path.dirname(options.spec_file) + spec = SpecFile(options.spec_file) else: - specfilename = guess_spec(options.packaging_dir, - True, - os.path.basename(repo.path) + '.spec') - spec = SpecFile(specfilename) + spec = guess_spec(options.packaging_dir, True, + os.path.basename(repo.path) + '.spec') except KeyError: raise GbpError, "Can't parse spec" @@ -352,13 +348,11 @@ def rebase_pq(repo, branch, options): # Find and parse .spec file try: if options.spec_file != 'auto': - specfilename = options.spec_file - options.packaging_dir = os.path.dirname(specfilename) + options.packaging_dir = os.path.dirname(options.spec_file) + spec = SpecFile(options.spec_file) else: - specfilename = guess_spec(options.packaging_dir, - True, - os.path.basename(repo.path) + '.spec') - spec = SpecFile(specfilename) + spec = guess_spec(options.packaging_dir, True, + os.path.basename(repo.path) + '.spec') except KeyError: raise GbpError, "Can't parse spec" diff --git a/tests/test_rpm.py b/tests/test_rpm.py index ca1cc6a7..b37007b5 100644 --- a/tests/test_rpm.py +++ b/tests/test_rpm.py @@ -23,8 +23,7 @@ import tempfile from nose.tools import assert_raises from gbp.errors import GbpError -from gbp.rpm import (SrcRpmFile, SpecFile, parse_srpm, parse_spec, guess_spec, - NoSpecError) +from gbp.rpm import SrcRpmFile, SpecFile, parse_srpm, guess_spec, NoSpecError DATA_DIR = os.path.abspath(os.path.splitext(__file__)[0] + '_data') SRPM_DIR = os.path.join(DATA_DIR, 'srpms') @@ -306,14 +305,6 @@ class TestSpecFile(object): class TestUtilityFunctions(object): """Test utility functions of L{gbp.rpm}""" - def test_parse_spec(self): - """Test parse_spec() function""" - parse_spec(os.path.join(SPEC_DIR, 'gbp-test.spec')) - with assert_raises(NoSpecError): - parse_spec(os.path.join(DATA_DIR, 'notexists.spec')) - with assert_raises(GbpError): - parse_spec(os.path.join(SRPM_DIR, 'gbp-test-1.0-1.src.rpm')) - def test_parse_srpm(self): """Test parse_srpm() function""" parse_srpm(os.path.join(SRPM_DIR, 'gbp-test-1.0-1.src.rpm')) @@ -333,8 +324,9 @@ class TestUtilityFunctions(object): with assert_raises(NoSpecError): guess_spec(SPEC_DIR, recursive=False) # Spec found - spec_fn = guess_spec(SPEC_DIR, recursive=False, + spec = guess_spec(SPEC_DIR, recursive=False, preferred_name = 'gbp-test2.spec') - assert spec_fn == os.path.join(SPEC_DIR, 'gbp-test2.spec') + assert spec.specfile == 'gbp-test2.spec' + assert spec.specdir == SPEC_DIR # vim:et:ts=4:sw=4:et:sts=4:ai:set list listchars=tab\:»·,trail\:·: -- cgit v1.2.3 From 24c7e4e209cf1926e5ea2dff4a14c5fccecb5822 Mon Sep 17 00:00:00 2001 From: Markus Lehtonen Date: Fri, 6 Sep 2013 17:15:52 +0300 Subject: rpm.SpecFile: support parsing spec as raw text data Instead of reading from a file. Signed-off-by: Markus Lehtonen --- gbp/rpm/__init__.py | 33 +++++++++++++++++++++++---------- tests/test_rpm.py | 17 +++++++++++++++++ 2 files changed, 40 insertions(+), 10 deletions(-) diff --git a/gbp/rpm/__init__.py b/gbp/rpm/__init__.py index 6815b0cd..8bbab705 100644 --- a/gbp/rpm/__init__.py +++ b/gbp/rpm/__init__.py @@ -118,18 +118,31 @@ class SpecFile(object): 'files', 'changelog', 'triggerin', 'triggerpostin', 'triggerun', 'triggerpostun') - def __init__(self, specfile): + def __init__(self, filename=None, filedata=None): - # Load spec file into our special data structure - self.specfile = os.path.basename(specfile) - self.specdir = os.path.dirname(os.path.abspath(specfile)) self._content = LinkedList() - try: - with open(specfile) as spec_file: - for line in spec_file.readlines(): - self._content.append(line) - except IOError as err: - raise NoSpecError("Unable to read spec file: %s" % err) + + # Check args: only filename or filedata can be given, not both + if filename is None and filedata is None: + raise NoSpecError("No filename or raw data given for parsing!") + elif filename and filedata: + raise NoSpecError("Both filename and raw data given, don't know " + "which one to parse!") + elif filename: + # Load spec file into our special data structure + self.specfile = os.path.basename(filename) + self.specdir = os.path.dirname(os.path.abspath(filename)) + try: + with open(filename) as spec_file: + for line in spec_file.readlines(): + self._content.append(line) + except IOError as err: + raise NoSpecError("Unable to read spec file: %s" % err) + else: + self.specfile = None + self.specdir = None + for line in filedata.splitlines(): + self._content.append(line + '\n') # Use rpm-python to parse the spec file content self._filtertags = ("excludearch", "excludeos", "exclusivearch", diff --git a/tests/test_rpm.py b/tests/test_rpm.py index b37007b5..47aaf7f8 100644 --- a/tests/test_rpm.py +++ b/tests/test_rpm.py @@ -150,6 +150,23 @@ class TestSpecFile(object): assert spec.name == 'gbp-test-native2' assert spec.orig_src is None + def test_parse_raw(self): + """Test parsing of a valid spec file""" + with assert_raises(NoSpecError): + SpecFile(None, None) + with assert_raises(NoSpecError): + SpecFile('filename', 'filedata') + + spec_filepath = os.path.join(SPEC_DIR, 'gbp-test.spec') + with open(spec_filepath, 'r') as spec_fd: + spec_data = spec_fd.read() + spec = SpecFile(filedata=spec_data) + + # Test basic properties + assert spec.specfile == None + assert spec.specdir == None + assert spec.name == 'gbp-test' + def test_update_spec(self): """Test spec autoupdate functionality""" # Create temporary spec file -- cgit v1.2.3 From ba7623944bada45accb551ffe66901dfa756a0bc Mon Sep 17 00:00:00 2001 From: Markus Lehtonen Date: Fri, 6 Sep 2013 16:07:08 +0300 Subject: rpm: support guessing spec file from git treeish Signed-off-by: Markus Lehtonen --- gbp/rpm/__init__.py | 76 +++++++++++++++++++++++++++--------------- gbp/scripts/import_orig_rpm.py | 2 +- tests/test_rpm.py | 41 ++++++++++++++++++++++- 3 files changed, 90 insertions(+), 29 deletions(-) diff --git a/gbp/rpm/__init__.py b/gbp/rpm/__init__.py index 8bbab705..7aa7ba41 100644 --- a/gbp/rpm/__init__.py +++ b/gbp/rpm/__init__.py @@ -768,44 +768,66 @@ def parse_srpm(srpmfile): return srcrpm -def guess_spec(topdir, recursive=True, preferred_name=None): - """Guess a spec file""" +def guess_spec_fn(file_list, preferred_name=None): + """Guess spec file from a list of filenames""" specs = [] - abstop = os.path.abspath(topdir) - for (root, dirs, files) in os.walk(abstop): - for f in files: - # Stop at the first file matching the preferred name - if f == preferred_name: - gbp.log.debug("Found a preferred spec file: %s in %s" % (f, root)) - specs = [os.path.join(root,f)] - recursive = False - break - if f.endswith(".spec"): - gbp.log.debug("Found spec file: %s in %s" % (f, root)) - specs.append(os.path.join(root,f)) + for filepath in file_list: + filename = os.path.basename(filepath) + # Stop at the first file matching the preferred name + if filename == preferred_name: + gbp.log.debug("Found a preferred spec file %s" % filepath) + specs = [filepath] + break + if filename.endswith(".spec"): + gbp.log.debug("Found spec file %s" % filepath) + specs.append(filepath) + if len(specs) == 0: + raise NoSpecError("No spec file found.") + elif len(specs) > 1: + raise NoSpecError("Multiple spec files found (%s), don't know which " + "to use." % ', '.join(specs)) + return specs[0] + +def guess_spec(topdir, recursive=True, preferred_name=None): + """Guess a spec file""" + file_list = [] + if not topdir: + topdir = '.' + for root, dirs, files in os.walk(topdir): + file_list.extend([os.path.join(root, fname) for fname in files]) if not recursive: del dirs[:] # Skip .git dir in any case if '.git' in dirs: dirs.remove('.git') - - if len(specs) == 0: - raise NoSpecError("No spec file found.") - elif len(specs) > 1: - filenames = [os.path.relpath(spec, abstop) for spec in specs] - raise NoSpecError("Multiple spec files found (%s), don't know which " - "to use." % ', '.join(filenames)) - return SpecFile(specs[0]) + return SpecFile(os.path.abspath(guess_spec_fn(file_list, preferred_name))) -def guess_spec_repo(repo, branch, packaging_dir): +def guess_spec_repo(repo, treeish, topdir='', recursive=True, preferred_name=None): """ - @todo: implement this - Try to find/parse the spec file from given branch in the git - repository. + Try to find/parse the spec file from a given git treeish. """ - raise NoSpecError, "Searching spec from other branch not implemented yet" + topdir = topdir.rstrip('/') + ('/') if topdir else '' + try: + file_list = [nam for (mod, typ, sha, nam) in + repo.list_tree(treeish, recursive, topdir) if typ == 'blob'] + except GitRepositoryError as err: + raise NoSpecError("Cannot find spec file from treeish %s, Git error: %s" + % (treeish, err)) + spec_path = guess_spec_fn(file_list, preferred_name) + return spec_from_repo(repo, treeish, spec_path) + + +def spec_from_repo(repo, treeish, spec_path): + """Get and parse a spec file from a give Git treeish""" + try: + spec = SpecFile(filedata=repo.show('%s:%s' % (treeish, spec_path))) + spec.specdir = os.path.dirname(spec_path) + spec.specfile = os.path.basename(spec_path) + return spec + except GitRepositoryError as err: + raise NoSpecError("Git error: %s" % err) def string_to_int(val_str): diff --git a/gbp/scripts/import_orig_rpm.py b/gbp/scripts/import_orig_rpm.py index b208ad12..8eacfb2b 100755 --- a/gbp/scripts/import_orig_rpm.py +++ b/gbp/scripts/import_orig_rpm.py @@ -58,7 +58,7 @@ def detect_name_and_version(repo, source, options): # we're not on the packaging-branch (but upstream, for # example). spec = guess_spec_repo(repo, options.packaging_branch, - options.packaging_dir) + options.packaging_dir, True, preferred_fn) sourcepackage = spec.name except NoSpecError: if options.interactive: diff --git a/tests/test_rpm.py b/tests/test_rpm.py index 47aaf7f8..69ab85b6 100644 --- a/tests/test_rpm.py +++ b/tests/test_rpm.py @@ -23,7 +23,9 @@ import tempfile from nose.tools import assert_raises from gbp.errors import GbpError -from gbp.rpm import SrcRpmFile, SpecFile, parse_srpm, guess_spec, NoSpecError +from gbp.rpm import (SrcRpmFile, SpecFile, parse_srpm, NoSpecError, guess_spec, + guess_spec_repo, spec_from_repo) +from gbp.git.repository import GitRepository DATA_DIR = os.path.abspath(os.path.splitext(__file__)[0] + '_data') SRPM_DIR = os.path.join(DATA_DIR, 'srpms') @@ -321,6 +323,11 @@ class TestSpecFile(object): class TestUtilityFunctions(object): """Test utility functions of L{gbp.rpm}""" + def setup(self): + self.tmpdir = tempfile.mkdtemp(prefix='gbp_%s_' % __name__, dir='.') + + def teardown(self): + shutil.rmtree(self.tmpdir) def test_parse_srpm(self): """Test parse_srpm() function""" @@ -346,4 +353,36 @@ class TestUtilityFunctions(object): assert spec.specfile == 'gbp-test2.spec' assert spec.specdir == SPEC_DIR + def test_guess_spec_repo(self): + """Test guess_spec_repo() and spec_from_repo() functions""" + # Create dummy repository with some commits + repo = GitRepository.create(self.tmpdir) + with open(os.path.join(repo.path, 'foo.txt'), 'w') as fobj: + fobj.write('bar\n') + repo.add_files('foo.txt') + repo.commit_all('Add dummy file') + os.mkdir(os.path.join(repo.path, 'packaging')) + shutil.copy(os.path.join(SPEC_DIR, 'gbp-test.spec'), + os.path.join(repo.path, 'packaging')) + repo.add_files('packaging/gbp-test.spec') + repo.commit_all('Add spec file') + + # Spec not found + with assert_raises(NoSpecError): + guess_spec_repo(repo, 'HEAD~1', recursive=True) + with assert_raises(NoSpecError): + guess_spec_repo(repo, 'HEAD', recursive=False) + # Spec found + spec = guess_spec_repo(repo, 'HEAD', 'packaging', recursive=False) + spec = guess_spec_repo(repo, 'HEAD', recursive=True) + assert spec.specfile == 'gbp-test.spec' + assert spec.specdir == 'packaging' + assert spec.specpath == 'packaging/gbp-test.spec' + + # Test spec_from_repo() + with assert_raises(NoSpecError): + spec_from_repo(repo, 'HEAD~1', 'packaging/gbp-test.spec') + spec = spec_from_repo(repo, 'HEAD', 'packaging/gbp-test.spec') + assert spec.specfile == 'gbp-test.spec' + # vim:et:ts=4:sw=4:et:sts=4:ai:set list listchars=tab\:»·,trail\:·: -- cgit v1.2.3 From 2d3aba7cf791151760719f3eddecd3c2fa8c3639 Mon Sep 17 00:00:00 2001 From: Markus Lehtonen Date: Wed, 16 Oct 2013 11:07:10 +0300 Subject: packaging: Release, update changelogs Signed-off-by: Markus Lehtonen --- debian/changelog | 36 ++++++++++++++++++++++++++++++++++-- packaging/git-buildpackage.changes | 31 ++++++++++++++++++++++++++++++- packaging/git-buildpackage.spec | 2 +- 3 files changed, 65 insertions(+), 4 deletions(-) diff --git a/debian/changelog b/debian/changelog index 2eba00b3..d385bf94 100644 --- a/debian/changelog +++ b/debian/changelog @@ -300,7 +300,7 @@ git-buildpackage (0.6.4) unstable; urgency=low -- Guido Günther Sun, 06 Oct 2013 17:35:14 +0200 -git-buildpackage (0.6.3-tizen20130902) UNRELEASED; urgency=low +git-buildpackage (0.6.3-tizen20131017) unstable; urgency=low [ Lingchaox Xin ] * Fix `fatal: fetch --all does not take a repository argument` @@ -334,8 +334,40 @@ git-buildpackage (0.6.3-tizen20130902) UNRELEASED; urgency=low * Version bump, rebase on top of 0.6.3 * docs: minor sgml syntax fix * Disable cover-min-percentage setting of nose + * debian packaging: change to 1.0 source package format + * git: new class and method for remote repositories + * GitRepository.has_remote_repo: use get_remotes method + * GitRepository: deprecate the get_remote_repos method + * pq-rpm: drop unused 'tries' option + * common/pq: support more flexible pq-branch naming + * GitRepository.list_tree: add 'paths' option + * rpm: change guess_spec() to return SpecFile object + * rpm: minor docstring fixes + * rpm.SpecFile: support parsing spec as raw text data + * rpm: support guessing spec file from git treeish + * pq: don't overwrite patches in the same series + * pq-rpm: don't overwrite patches in the same series + * tests: use sanitize some submodule tests + * tests: use eq_ and ok_ from nose tools in submodule tests + * tests: add some docstrings to git submodule tests + * tests: upper case global variables in submodule tests + * tests: remove unused import in submodule tests + * buildpackage: refactor prefix handling + * common/pq: fix length of patch filenames + * pq: fix generation of series file + * pq.write_patch_file: drop unused argument + * pq: pass commit_info to format_patch() + * SpecFile.set_tag: change the default place for new tags + * buildpackage: support 'commit' variable for VCS tags - -- Markus Lehtonen Mon, 02 Sep 2013 14:44:00 +0300 + [ Zhang Qiang ] + * remove 'repo' param to adapt to changes of write_patch_file + + [ Guan Junchun ] + * Fix gbs clone failure if repo url is like host:repo.git + * Clone a repository to a specific directory + + -- Markus Lehtonen Thu, 17 Oct 2013 13:45:10 +0300 git-buildpackage (0.6.3) unstable; urgency=low diff --git a/packaging/git-buildpackage.changes b/packaging/git-buildpackage.changes index 35af7834..da3ffc20 100644 --- a/packaging/git-buildpackage.changes +++ b/packaging/git-buildpackage.changes @@ -1,4 +1,33 @@ -* Tue Sep 03 2013 Markus Lehtonen 0.6.3 +* Thu Oct 17 2013 Markus Lehtonen 0.6.3 +- buildpackage: support 'commit' variable for VCS tags +- Clone a repository to a specific directory +- Fix gbs clone failure if repo url is like host:repo.git +- SpecFile.set_tag: change the default place for new tags +- remove 'repo' param to adapt to changes of write_patch_file +- pq: pass commit_info to format_patch() +- pq: pass commit_info to format_patch() +- pq.write_patch_file: drop unused argument +- pq: fix generation of series file +- common/pq: fix length of patch filenames +- buildpackage: refactor prefix handling +- tests: remove unused import in submodule tests +- tests: upper case global variables in submodule tests +- tests: add some docstrings to git submodule tests +- tests: use eq_ and ok_ from nose tools in submodule tests +- tests: use sanitize some submodule tests +- pq-rpm: don't overwrite patches in the same series +- pq: don't overwrite patches in the same series +- rpm: support guessing spec file from git treeish +- rpm.SpecFile: support parsing spec as raw text data +- rpm: minor docstring fixes +- rpm: change guess_spec() to return SpecFile object +- GitRepository.list_tree: add 'paths' option +- common/pq: support more flexible pq-branch naming +- pq-rpm: drop unused 'tries' option +- GitRepository: deprecate the get_remote_repos method +- GitRepository.has_remote_repo: use get_remotes method +- git: new class and method for remote repositories +- debian packaging: change to 1.0 source package format - Version bump, rebase on top of 0.6.3 * Disable cover-min-percentage setting of nose * docs: minor sgml syntax fix diff --git a/packaging/git-buildpackage.spec b/packaging/git-buildpackage.spec index 5883fcac..242737ea 100644 --- a/packaging/git-buildpackage.spec +++ b/packaging/git-buildpackage.spec @@ -100,7 +100,7 @@ Group: Development/Tools/Building Requires: %{name}-common = %{version}-%{release} Requires: rpm Requires: %{rpm_python_pkg_name} -Provides: tizen-gbp-rpm = 20130902 +Provides: tizen-gbp-rpm = 20131017 %description rpm Set of tools from Debian that integrate the package build system with Git. -- cgit v1.2.3 From eecf64f0c5c45f04c8b333237652098f4ea3d006 Mon Sep 17 00:00:00 2001 From: Markus Lehtonen Date: Thu, 21 Nov 2013 17:25:37 +0200 Subject: pq-rpm: create diff up to the last merge commit Before, merge commits broke patch generation, or, (most probably) caused the generated patches to be unapplicable (similar to how git-format-patch behaves). Now, changes up to the last merge commit are squashed into one diff if merge commits are found in the revision list from which patches are to be generated. Individual patches (one per commit) are generated from the last merge commit up to the exported revision. Signed-off-by: Markus Lehtonen --- gbp/scripts/pq_rpm.py | 14 ++++++++++++++ 1 file changed, 14 insertions(+) diff --git a/gbp/scripts/pq_rpm.py b/gbp/scripts/pq_rpm.py index aba63537..6187d6c5 100755 --- a/gbp/scripts/pq_rpm.py +++ b/gbp/scripts/pq_rpm.py @@ -107,6 +107,20 @@ def generate_patches(repo, start, squash, end, outdir, options): if patch_fn: patches.append(patch_fn) start = squash_sha1 + # Check for merge commits, yet another squash if merges found + merges = repo.get_commits(start, end_commit, options=['--merges']) + if merges: + # Shorten SHA1s + start_sha1 = repo.rev_parse(start, short=7) + merge_sha1 = repo.rev_parse(merges[0], short=7) + patch_fn = format_diff(outdir, None, repo, start_sha1, merge_sha1, + options.patch_export_ignore_path) + if patch_fn: + gbp.log.info("Merge commits found! Diff between %s..%s written " + "into one monolithic diff" % (start_sha1, merge_sha1)) + patches.append(patch_fn) + start = merge_sha1 + print start # Generate patches for commit in reversed(repo.get_commits(start, end_commit)): -- cgit v1.2.3 From 550a5fe34bd0c5d063d28bcd6c4fd3bdb78d0137 Mon Sep 17 00:00:00 2001 From: Markus Lehtonen Date: Mon, 2 Dec 2013 13:01:13 +0200 Subject: packaging: Prepare for next Tizen tools release Signed-off-by: Markus Lehtonen --- debian/changelog | 19 +++++++++++++++++++ packaging/git-buildpackage.changes | 16 ++++++++++++++++ packaging/git-buildpackage.spec | 2 +- 3 files changed, 36 insertions(+), 1 deletion(-) diff --git a/debian/changelog b/debian/changelog index d385bf94..0bcc24db 100644 --- a/debian/changelog +++ b/debian/changelog @@ -164,6 +164,25 @@ git-buildpackage (0.6.7) unstable; urgency=low -- Guido Günther Fri, 29 Nov 2013 20:52:03 +0100 +git-buildpackage (0.6.6-tizen20131202) unstable; urgency=low + + * Rebase on top of upstream version 0.6.6 + * UpstreamSource: fix archive prefix guessing + * pq-rpm: create diff up to the last merge commit + Before, merge commits broke patch generation, or, (most probably) caused + the generated patches to be unapplicable (similar to how + git-format-patch behaves). + Now, changes up to the last merge commit are squashed into one diff if + merge commits are found in the revision list from which patches are to + be generated. Individual patches (one per commit) are generated from the + last merge commit up to the exported revision. + * pq-rpm: magic word HEAD for patch-squashing + When given as the squash-point, 'HEAD' translates to the end-commit. + This allows one to configure gbp to always squash all commits into one + monolithic diff. + + -- Markus Lehtonen Mon, 02 Dec 2013 12:55:14 +0200 + git-buildpackage (0.6.6) unstable; urgency=low [ Guan Junchun ] diff --git a/packaging/git-buildpackage.changes b/packaging/git-buildpackage.changes index da3ffc20..938808e2 100644 --- a/packaging/git-buildpackage.changes +++ b/packaging/git-buildpackage.changes @@ -1,3 +1,19 @@ +* Mon Dec 02 2013 Markus Lehtonen 0.6.6 +- Rebase on top of upstream version 0.6.6 +- UpstreamSource: fix archive prefix guessing +- pq-rpm: create diff up to the last merge commit + Before, merge commits broke patch generation, or, (most probably) caused + the generated patches to be unapplicable (similar to how + git-format-patch behaves). + Now, changes up to the last merge commit are squashed into one diff if + merge commits are found in the revision list from which patches are to + be generated. Individual patches (one per commit) are generated from the + last merge commit up to the exported revision. +- pq-rpm: magic word HEAD for patch-squashing + When given as the squash-point, 'HEAD' translates to the end-commit. + This allows one to configure gbp to always squash all commits into one + monolithic diff. + * Thu Oct 17 2013 Markus Lehtonen 0.6.3 - buildpackage: support 'commit' variable for VCS tags - Clone a repository to a specific directory diff --git a/packaging/git-buildpackage.spec b/packaging/git-buildpackage.spec index 242737ea..4fc97ad1 100644 --- a/packaging/git-buildpackage.spec +++ b/packaging/git-buildpackage.spec @@ -100,7 +100,7 @@ Group: Development/Tools/Building Requires: %{name}-common = %{version}-%{release} Requires: rpm Requires: %{rpm_python_pkg_name} -Provides: tizen-gbp-rpm = 20131017 +Provides: tizen-gbp-rpm = 20131202 %description rpm Set of tools from Debian that integrate the package build system with Git. -- cgit v1.2.3 From 54c9412b351fee5761040184d9758a45d7f5dc1a Mon Sep 17 00:00:00 2001 From: Markus Lehtonen Date: Thu, 19 Sep 2013 16:22:57 +0300 Subject: pq-rpm: bigger refactor of the code Support '%(upstreamversion)s' as a replacable string in the pq branch name. Eliminate some unneeded branch switches that were only needed for finding/parsing the spec file. Now, spec file is directly searched from the git repository (from the 'base' branch) if the command is run when on the pq branch - except for the 'export' subcommand which always switches to the base branch. Signed-off-by: Markus Lehtonen --- gbp/scripts/import_srpm.py | 2 +- gbp/scripts/pq_rpm.py | 424 ++++++++++++++++++++++++++------------------- 2 files changed, 242 insertions(+), 184 deletions(-) diff --git a/gbp/scripts/import_srpm.py b/gbp/scripts/import_srpm.py index 01c225cc..5a1d9d64 100755 --- a/gbp/scripts/import_srpm.py +++ b/gbp/scripts/import_srpm.py @@ -138,7 +138,7 @@ def import_spec_patches(repo, spec, dirs): packager = get_packager(spec) # Put patches in a safe place - queue = safe_patches(queue, tmpdir)[1] + queue = safe_patches(queue, tmpdir) for patch in queue: gbp.log.debug("Applying %s" % patch.path) try: diff --git a/gbp/scripts/pq_rpm.py b/gbp/scripts/pq_rpm.py index 6187d6c5..844062b7 100755 --- a/gbp/scripts/pq_rpm.py +++ b/gbp/scripts/pq_rpm.py @@ -27,23 +27,36 @@ import re import gzip import bz2 import subprocess + import gbp.tmpfile as tempfile -from gbp.config import (GbpOptionParserRpm, GbpOptionGroup) -from gbp.rpm.git import (GitRepositoryError, RpmGitRepository) -from gbp.git.modifier import GitModifier, GitTz -from gbp.command_wrappers import (Command, GitCommand, RunAtCommand, - CommandExecFailed) +from gbp.config import GbpOptionParserRpm +from gbp.rpm.git import GitRepositoryError, RpmGitRepository +from gbp.git.modifier import GitModifier +from gbp.command_wrappers import GitCommand, CommandExecFailed from gbp.errors import GbpError import gbp.log -from gbp.patch_series import (PatchSeries, Patch) +from gbp.patch_series import PatchSeries, Patch from gbp.pkg import parse_archive_filename -from gbp.rpm import (SpecFile, guess_spec, string_to_int) +from gbp.rpm import (SpecFile, NoSpecError, guess_spec, guess_spec_repo, + spec_from_repo, string_to_int) from gbp.scripts.common.pq import (is_pq_branch, pq_branch_name, pq_branch_base, parse_gbp_commands, format_patch, - format_diff, - switch_to_pq_branch, apply_single_patch, - apply_and_commit_patch, drop_pq) - + format_diff, apply_and_commit_patch, drop_pq) +from gbp.scripts.common.buildpackage import dump_tree + +USAGE_STRING = \ +"""%prog [options] action - maintain patches on a patch queue branch +tions: +export Export the patch queue / devel branch associated to the + current branch into a patch series in and update the spec file +import Create a patch queue / devel branch from spec file + and patches in current dir. +rebase Switch to patch queue / devel branch associated to the current + branch and rebase against upstream. +drop Drop (delete) the patch queue /devel branch associated to + the current branch. +apply Apply a patch +switch Switch to patch-queue branch and vice versa.""" def compress_patches(patches, compress_size=0): """ @@ -71,7 +84,7 @@ def generate_patches(repo, start, squash, end, outdir, options): commands = {} for treeish in [start, end]: if not repo.has_treeish(treeish): - raise GbpError('%s not a valid tree-ish' % treeish) + raise GbpError('Invalid treeish object %s' % treeish) start_sha1 = repo.rev_parse("%s^0" % start) try: @@ -84,7 +97,11 @@ def generate_patches(repo, start, squash, end, outdir, options): end_commit_sha1 = repo.rev_parse("%s^0" % end_commit) start_sha1 = repo.rev_parse("%s^0" % start) - if repo.get_merge_base(start_sha1, end_commit_sha1) != start_sha1: + try: + merge_base = repo.get_merge_base(start_sha1, end_commit_sha1) + except GitRepositoryError: + merge_base = None + if merge_base != start_sha1: raise GbpError("Start commit '%s' not an ancestor of end commit " "'%s'" % (start, end_commit)) # Squash commits, if requested @@ -186,36 +203,61 @@ def update_patch_series(repo, spec, start, end, options): spec.write_spec_file() -def export_patches(repo, branch, options): - """Export patches from the pq branch into a packaging branch""" - if is_pq_branch(branch, options): - base = pq_branch_base(branch, options) - gbp.log.info("On '%s', switching to '%s'" % (branch, base)) - branch = base - repo.set_branch(branch) - - pq_branch = pq_branch_name(branch, options) +def parse_spec(options, repo, treeish=None): + """ + Find and parse spec file. - # Find and parse .spec file + If treeish is given, try to find the spec file from that. Otherwise, search + for the spec file in the working copy. + """ try: if options.spec_file != 'auto': - options.packaging_dir = os.path.dirname(specfilename) - spec = SpecFile(options.packaging_dir) + options.packaging_dir = os.path.dirname(options.spec_file) + if not treeish: + spec = SpecFile(options.spec_file) + else: + spec = spec_from_repo(repo, treeish, options.spec_file) else: - spec = guess_spec(options.packaging_dir, True, - os.path.basename(repo.path) + '.spec') - except KeyError: - raise GbpError, "Can't parse spec" - - # Find upstream version - tag_str_fields = dict(upstreamversion=spec.upstreamversion, vendor="Upstream") - upstream_commit = repo.find_version(options.upstream_tag, tag_str_fields) + preferred_name = os.path.basename(repo.path) + '.spec' + if not treeish: + spec = guess_spec(options.packaging_dir, True, preferred_name) + else: + spec = guess_spec_repo(repo, treeish, options.packaging_dir, + True, preferred_name) + except NoSpecError as err: + raise GbpError("Can't parse spec: %s" % err) + relpath = spec.specpath if treeish else os.path.relpath(spec.specpath, + repo.path) + gbp.log.debug("Using '%s' from '%s'" % (relpath, treeish or 'working copy')) + return spec + + +def find_upstream_commit(repo, spec, upstream_tag): + """Find commit corresponding upstream version""" + tag_str_fields = {'upstreamversion': spec.upstreamversion, + 'vendor': 'Upstream'} + upstream_commit = repo.find_version(upstream_tag, tag_str_fields) if not upstream_commit: - raise GbpError, ("Couldn't find upstream version %s. Don't know on what base to import." % spec.upstreamversion) + raise GbpError("Couldn't find upstream version %s" % + spec.upstreamversion) + return upstream_commit + + +def export_patches(repo, options): + """Export patches from the pq branch into a packaging branch""" + current = repo.get_branch() + if is_pq_branch(current, options): + base = pq_branch_base(current, options) + gbp.log.info("On branch '%s', switching to '%s'" % (current, base)) + repo.set_branch(base) + spec = parse_spec(options, repo) + pq_branch = current + else: + spec = parse_spec(options, repo) + pq_branch = pq_branch_name(current, options, spec.version) + upstream_commit = find_upstream_commit(repo, spec, options.upstream_tag) export_treeish = options.export_rev if options.export_rev else pq_branch - if not repo.has_treeish(export_treeish): - raise GbpError('Invalid treeish object %s' % export_treeish) update_patch_series(repo, spec, upstream_commit, export_treeish, options) @@ -234,33 +276,34 @@ def safe_patches(queue, tmpdir_base): """ tmpdir = tempfile.mkdtemp(dir=tmpdir_base, prefix='patchimport_') - safequeue=PatchSeries() + safequeue = PatchSeries() if len(queue) > 0: - gbp.log.debug("Safeing patches '%s' in '%s'" % (os.path.dirname(queue[0].path), tmpdir)) - for p in queue: - (base, archive_fmt, comp) = parse_archive_filename(p.path) - uncompressors = {'gzip': gzip.open, 'bzip2': bz2.BZ2File} - if comp in uncompressors: - gbp.log.debug("Uncompressing '%s'" % os.path.basename(p.path)) - src = uncompressors[comp](p.path, 'r') - dst_name = os.path.join(tmpdir, os.path.basename(base)) - elif comp: - raise GbpError("Unsupported patch compression '%s', giving up" - % comp) - else: - src = open(p.path, 'r') - dst_name = os.path.join(tmpdir, os.path.basename(p.path)) + gbp.log.debug("Safeing patches '%s' in '%s'" % + (os.path.dirname(queue[0].path), tmpdir)) + for patch in queue: + base, _archive_fmt, comp = parse_archive_filename(patch.path) + uncompressors = {'gzip': gzip.open, 'bzip2': bz2.BZ2File} + if comp in uncompressors: + gbp.log.debug("Uncompressing '%s'" % os.path.basename(patch.path)) + src = uncompressors[comp](patch.path, 'r') + dst_name = os.path.join(tmpdir, os.path.basename(base)) + elif comp: + raise GbpError("Unsupported patch compression '%s', giving up" + % comp) + else: + src = open(patch.path, 'r') + dst_name = os.path.join(tmpdir, os.path.basename(patch.path)) - dst = open(dst_name, 'w') - dst.writelines(src) - src.close() - dst.close() + dst = open(dst_name, 'w') + dst.writelines(src) + src.close() + dst.close() - safequeue.append(p) - safequeue[-1].path = dst_name; + safequeue.append(patch) + safequeue[-1].path = dst_name - return (tmpdir, safequeue) + return safequeue def get_packager(spec): @@ -273,115 +316,93 @@ def get_packager(spec): return GitModifier() -def import_spec_patches(repo, branch, options): +def import_spec_patches(repo, options): """ apply a series of patches in a spec/packaging dir to branch the patch-queue branch for 'branch' @param repo: git repository to work on - @param branch: branch to base pqtch queue on @param options: command options """ - tmpdir = None - - if is_pq_branch(branch, options): + current = repo.get_branch() + # Get spec and related information + if is_pq_branch(current, options): + base = pq_branch_base(current, options) if options.force: - branch = pq_branch_base(branch, options) - pq_branch = pq_branch_name(branch, options) - repo.checkout(branch) + spec = parse_spec(options, repo, base) + spec_treeish = base else: - gbp.log.err("Already on a patch-queue branch '%s' - doing nothing." % branch) - raise GbpError + raise GbpError("Already on a patch-queue branch '%s' - doing " + "nothing." % current) else: - pq_branch = pq_branch_name(branch, options) - - if repo.has_branch(pq_branch): - if options.force: - drop_pq(repo, branch, options) - else: - raise GbpError, ("Patch queue branch '%s'. already exists. Try 'rebase' instead." - % pq_branch) + spec = parse_spec(options, repo) + spec_treeish = None + base = current + upstream_commit = find_upstream_commit(repo, spec, options.upstream_tag) + packager = get_packager(spec) + pq_branch = pq_branch_name(base, options, spec.version) - # Find and parse .spec file + # Create pq-branch + if repo.has_branch(pq_branch) and not options.force: + raise GbpError("Patch-queue branch '%s' already exists. " + "Try 'rebase' instead." % pq_branch) try: - if options.spec_file != 'auto': - options.packaging_dir = os.path.dirname(options.spec_file) - spec = SpecFile(options.spec_file) + if repo.get_branch() == pq_branch: + repo.force_head(upstream_commit, hard=True) else: - spec = guess_spec(options.packaging_dir, True, - os.path.basename(repo.path) + '.spec') - except KeyError: - raise GbpError, "Can't parse spec" - - # Find upstream version - tag_str_fields = dict(upstreamversion=spec.upstreamversion, vendor="Upstream") - commit = repo.find_version(options.upstream_tag, tag_str_fields) - if commit: - commits=[commit] - else: - raise GbpError, ("Couldn't find upstream version %s. Don't know on what base to import." % spec.upstreamversion) + repo.create_branch(pq_branch, upstream_commit, force=True) + except GitRepositoryError as err: + raise GbpError("Cannot create patch-queue branch '%s': %s" % + (pq_branch, err)) - queue = spec.patchseries() - packager = get_packager(spec) # Put patches in a safe place - tmpdir, queue = safe_patches(queue, options.tmp_dir) - for commit in commits: - try: - gbp.log.info("Trying to apply patches at '%s'" % commit) - repo.create_branch(pq_branch, commit) - except GitRepositoryError: - raise GbpError, ("Cannot create patch-queue branch '%s'." % pq_branch) - + if spec_treeish: + packaging_tmp = tempfile.mkdtemp(prefix='dump_', dir=options.tmp_dir) + packaging_tree = '%s:%s' % (spec_treeish, options.packaging_dir) + dump_tree(repo, packaging_tmp, packaging_tree, with_submodules=False, + recursive=False) + spec.specdir = packaging_tmp + in_queue = spec.patchseries() + queue = safe_patches(in_queue, options.tmp_dir) + # Do import + try: + gbp.log.info("Switching to branch '%s'" % pq_branch) repo.set_branch(pq_branch) + + if not queue: + return + gbp.log.info("Trying to apply patches from branch '%s' onto '%s'" % + (base, upstream_commit)) for patch in queue: gbp.log.debug("Applying %s" % patch.path) - try: - apply_and_commit_patch(repo, patch, packager) - except (GbpError, GitRepositoryError): - repo.set_branch(branch) - repo.delete_branch(pq_branch) - break - else: - # All patches applied successfully - break - else: - raise GbpError, "Couldn't apply patches" - - repo.set_branch(branch) - - return spec.specfile + apply_and_commit_patch(repo, patch, packager) + except (GbpError, GitRepositoryError) as err: + repo.set_branch(base) + repo.delete_branch(pq_branch) + raise GbpError('Import failed: %s' % err) + gbp.log.info("Patches listed in '%s' imported on '%s'" % (spec.specfile, + pq_branch)) -def rebase_pq(repo, branch, options): - if is_pq_branch(branch, options): - base = pq_branch_base(branch, options) - gbp.log.info("On '%s', switching to '%s'" % (branch, base)) - branch = base - repo.set_branch(branch) - # Find and parse .spec file - try: - if options.spec_file != 'auto': - options.packaging_dir = os.path.dirname(options.spec_file) - spec = SpecFile(options.spec_file) - else: - spec = guess_spec(options.packaging_dir, True, - os.path.basename(repo.path) + '.spec') - except KeyError: - raise GbpError, "Can't parse spec" - - # Find upstream version - tag_str_fields = dict(upstreamversion=spec.upstreamversion, vendor="Upstream") - upstream_commit = repo.find_version(options.upstream_tag, tag_str_fields) - if not upstream_commit: - raise GbpError, ("Couldn't find upstream version %s. Don't know on what base to import." % spec.upstreamversion) +def rebase_pq(repo, options): + """Rebase pq branch on the correct upstream version (from spec file).""" + current = repo.get_branch() + if is_pq_branch(current, options): + base = pq_branch_base(current, options) + spec = parse_spec(options, repo, base) + else: + base = current + spec = parse_spec(options, repo) + upstream_commit = find_upstream_commit(repo, spec, options.upstream_tag) - switch_to_pq_branch(repo, branch, options) + switch_to_pq_branch(repo, base, options) GitCommand("rebase")([upstream_commit]) -def switch_pq(repo, current, options): +def switch_pq(repo, options): """Switch to patch-queue branch if on base branch and vice versa""" + current = repo.get_branch() if is_pq_branch(current, options): base = pq_branch_base(current, options) gbp.log.info("Switching to branch '%s'" % base) @@ -390,51 +411,93 @@ def switch_pq(repo, current, options): switch_to_pq_branch(repo, current, options) +def drop_pq_rpm(repo, options): + """Remove pq branch""" + current = repo.get_branch() + if is_pq_branch(current, options): + base = pq_branch_base(current, options) + spec = parse_spec(options, repo, base) + else: + spec = parse_spec(options, repo) + drop_pq(repo, current, options, spec.version) + + +def switch_to_pq_branch(repo, branch, options): + """ + Switch to patch-queue branch if not already there, create it if it + doesn't exist yet + """ + if is_pq_branch(branch, options): + return + + spec = parse_spec(options, repo, branch) + pq_branch = pq_branch_name(branch, options, spec.version) + if not repo.has_branch(pq_branch): + upstream_commit = find_upstream_commit(repo, spec, options.upstream_tag) + try: + repo.create_branch(pq_branch, rev=upstream_commit) + except GitRepositoryError as err: + raise GbpError("Cannot create patch-queue branch: %s" % err) + + gbp.log.info("Switching to branch '%s'" % pq_branch) + repo.set_branch(pq_branch) + +def apply_single_patch(repo, patchfile, options): + """Apply a single patch onto the pq branch""" + current = repo.get_branch() + if not is_pq_branch(current, options): + switch_to_pq_branch(repo, current, options) + patch = Patch(patchfile) + apply_and_commit_patch(repo, patch, fallback_author=None) + + def main(argv): + """Main function for the gbp pq-rpm command""" retval = 0 try: - parser = GbpOptionParserRpm(command=os.path.basename(argv[0]), prefix='', - usage="%prog [options] action - maintain patches on a patch queue branch\n" - "Actions:\n" - " export Export the patch queue / devel branch associated to the\n" - " current branch into a patch series in and update the spec file\n" - " import Create a patch queue / devel branch from spec file\n" - " and patches in current dir.\n" - " rebase Switch to patch queue / devel branch associated to the current\n" - " branch and rebase against upstream.\n" - " drop Drop (delete) the patch queue /devel branch associated to\n" - " the current branch.\n" - " apply Apply a patch\n" - " switch Switch to patch-queue branch and vice versa") + parser = GbpOptionParserRpm(command=os.path.basename(argv[0]), + prefix='', usage=USAGE_STRING) except ConfigParser.ParsingError as err: gbp.log.err('Invalid config file: %s' % err) return 1 - parser.add_boolean_config_file_option(option_name="patch-numbers", dest="patch_numbers") - parser.add_option("-v", "--verbose", action="store_true", dest="verbose", default=False, - help="Verbose command execution") - parser.add_option("--force", dest="force", action="store_true", default=False, - help="In case of import even import if the branch already exists") - parser.add_config_file_option(option_name="vendor", action="store", dest="vendor") - parser.add_config_file_option(option_name="color", dest="color", type='tristate') + parser.add_boolean_config_file_option(option_name="patch-numbers", + dest="patch_numbers") + parser.add_option("-v", "--verbose", action="store_true", dest="verbose", + default=False, help="Verbose command execution") + parser.add_option("--force", dest="force", action="store_true", + default=False, + help="In case of import even import if the branch already exists") + parser.add_config_file_option(option_name="vendor", action="store", + dest="vendor") + parser.add_config_file_option(option_name="color", dest="color", + type='tristate') parser.add_config_file_option(option_name="color-scheme", - dest="color_scheme") + dest="color_scheme") parser.add_config_file_option(option_name="tmp-dir", dest="tmp_dir") - parser.add_config_file_option(option_name="upstream-tag", dest="upstream_tag") + parser.add_config_file_option(option_name="upstream-tag", + dest="upstream_tag") parser.add_config_file_option(option_name="spec-file", dest="spec_file") - parser.add_config_file_option(option_name="packaging-dir", dest="packaging_dir") + parser.add_config_file_option(option_name="packaging-dir", + dest="packaging_dir") parser.add_config_file_option(option_name="packaging-branch", - dest="packaging_branch", - help="Branch the packaging is being maintained on. Only relevant if a invariable/single pq-branch is defined, in which case this is used as the 'base' branch. Default is '%(packaging-branch)s'") + dest="packaging_branch", + help="Branch the packaging is being maintained on. Only relevant " + "if a invariable/single pq-branch is defined, in which case " + "this is used as the 'base' branch. Default is " + "'%(packaging-branch)s'") parser.add_config_file_option(option_name="pq-branch", dest="pq_branch") - parser.add_option("--export-rev", action="store", dest="export_rev", default="", - help="Export patches from treeish object TREEISH instead " - "of head of patch-queue branch", metavar="TREEISH") + parser.add_option("--export-rev", action="store", dest="export_rev", + default="", + help="Export patches from treeish object TREEISH instead of head " + "of patch-queue branch", metavar="TREEISH") parser.add_config_file_option("patch-export-compress", - dest="patch_export_compress") - parser.add_config_file_option("patch-export-squash-until", dest="patch_export_squash_until") - parser.add_config_file_option("patch-export-ignore-path", dest="patch_export_ignore_path") + dest="patch_export_compress") + parser.add_config_file_option("patch-export-squash-until", + dest="patch_export_squash_until") + parser.add_config_file_option("patch-export-ignore-path", + dest="patch_export_ignore_path") (options, args) = parser.parse_args(argv) gbp.log.setup(options.color, options.verbose, options.color_scheme) @@ -472,23 +535,18 @@ def main(argv): # Create base temporary directory for this run options.tmp_dir = tempfile.mkdtemp(dir=options.tmp_dir, prefix='gbp-pq-rpm_') - current = repo.get_branch() if action == "export": - export_patches(repo, current, options) + export_patches(repo, options) elif action == "import": - specfile=import_spec_patches(repo, current, options) - current = repo.get_branch() - gbp.log.info("Patches listed in '%s' imported on '%s'" % - (specfile, current)) + import_spec_patches(repo, options) elif action == "drop": - drop_pq(repo, current, options) + drop_pq_rpm(repo, options) elif action == "rebase": - rebase_pq(repo, current, options) + rebase_pq(repo, options) elif action == "apply": - patch = Patch(patchfile) - apply_single_patch(repo, current, patch, None, options) + apply_single_patch(repo, patchfile, options) elif action == "switch": - switch_pq(repo, current, options) + switch_pq(repo, options) except CommandExecFailed: retval = 1 except GitRepositoryError as err: -- cgit v1.2.3 From 534d37c1344cd1718a1ccce5084e795cf35aa677 Mon Sep 17 00:00:00 2001 From: Markus Lehtonen Date: Tue, 10 Dec 2013 15:25:32 +0200 Subject: pq-rpm: implement '--import-files' command line option For defining the packaging file(s) that will be imported into the development/patch-queue branch. By default, the local gbp conf files are imported in order to try to ensure that gbp sees the same settings on the development/pq branch as on the packaging branch. NOTE: This option does not affect the patch files that are imported. The files defined with this option will appear as new files in one monolithic commit in the development/patch-queue branch. Signed-off-by: Markus Lehtonen --- gbp/config.py | 7 +++++++ gbp/scripts/pq_rpm.py | 35 +++++++++++++++++++++++++++++++++++ 2 files changed, 42 insertions(+) diff --git a/gbp/config.py b/gbp/config.py index 77c36745..e6b3f612 100644 --- a/gbp/config.py +++ b/gbp/config.py @@ -585,6 +585,8 @@ class GbpOptionParserRpm(GbpOptionParser): 'packaging-tag' : '%(vendor)s/%(version)s', 'upstream-tag' : 'upstream/%(upstreamversion)s', 'pq-branch' : 'development/%(branch)s', + 'import-files' : ['.gbp.conf', + 'debian/gbp.conf'], 'spec-file' : 'auto', 'export-dir' : '../rpmbuild', 'ignore-untracked' : 'False', @@ -614,6 +616,11 @@ class GbpOptionParserRpm(GbpOptionParser): "format string for packaging tags, rpm counterpart of the 'debian-tag' option, default is '%(packaging-tag)s'", 'pq-branch': "format string for the patch-queue branch name, default is '%(pq-branch)s'", + 'import-files': + ("Comma-separated list of additional file(s) to import " + "from packaging branch. These will appear as one " + "monolithic patch in the pq/development branch. " + "Default is %(import-files)s"), 'spec-file': "Spec file to use, 'auto' makes gbp to guess, other values make the packaging-dir option to be ignored, default is '%(spec-file)s'", 'ignore-untracked': diff --git a/gbp/scripts/pq_rpm.py b/gbp/scripts/pq_rpm.py index 844062b7..64a4c7e4 100755 --- a/gbp/scripts/pq_rpm.py +++ b/gbp/scripts/pq_rpm.py @@ -315,6 +315,32 @@ def get_packager(spec): return GitModifier(match.group('name'), match.group('email')) return GitModifier() +def import_extra_files(repo, commitish, files): + """Import branch-specific gbp.conf files to current branch""" + found = {} + for fname in files: + if fname: + try: + found[fname] = repo.show('%s:%s' % (commitish, fname)) + except GitRepositoryError: + pass + if found: + gbp.log.info("Importing additional file(s) from branch '%s' into '%s'" % + (commitish, repo.get_branch())) + for fname, content in found.iteritems(): + dirname = os.path.dirname(fname) + if dirname and not os.path.exists(dirname): + os.makedirs(dirname) + with open(fname, 'w') as fobj: + fobj.write(content) + + files = found.keys() + gbp.log.debug('Adding/commiting %s' % files) + repo.add_files(files, force=True) + commit_msg = ('Auto-import packaging file(s) from branch %s:\n' + ' %s\n\nGbp: Ignore\nGbp-Rpm: Ignore' % (commitish, + ' '.join(files))) + repo.commit_files(files, msg=commit_msg) def import_spec_patches(repo, options): """ @@ -368,6 +394,7 @@ def import_spec_patches(repo, options): try: gbp.log.info("Switching to branch '%s'" % pq_branch) repo.set_branch(pq_branch) + import_extra_files(repo, base, options.import_files) if not queue: return @@ -451,6 +478,11 @@ def apply_single_patch(repo, patchfile, options): apply_and_commit_patch(repo, patch, fallback_author=None) +def opt_split_cb(option, opt_str, value, parser): + """Split option string into a list""" + setattr(parser.values, option.dest, value.split(',')) + + def main(argv): """Main function for the gbp pq-rpm command""" retval = 0 @@ -488,6 +520,9 @@ def main(argv): "this is used as the 'base' branch. Default is " "'%(packaging-branch)s'") parser.add_config_file_option(option_name="pq-branch", dest="pq_branch") + parser.add_config_file_option(option_name="import-files", + dest="import_files", type="string", action="callback", + callback=opt_split_cb) parser.add_option("--export-rev", action="store", dest="export_rev", default="", help="Export patches from treeish object TREEISH instead of head " -- cgit v1.2.3 From bea0e301f911932dc207ebd305c36f66108c33b0 Mon Sep 17 00:00:00 2001 From: Markus Lehtonen Date: Wed, 2 Oct 2013 12:35:22 +0300 Subject: rpm-tests: add RepoManifest class Signed-off-by: Markus Lehtonen --- tests/component/rpm/__init__.py | 38 ++++++++++++++++++++++++++++++++++++++ 1 file changed, 38 insertions(+) diff --git a/tests/component/rpm/__init__.py b/tests/component/rpm/__init__.py index e84fca94..913ceeec 100644 --- a/tests/component/rpm/__init__.py +++ b/tests/component/rpm/__init__.py @@ -17,12 +17,50 @@ """Test module for RPM command line tools of the git-buildpackage suite""" import os +from xml.dom import minidom from tests.component import ComponentTestGitRepository RPM_TEST_DATA_SUBMODULE = os.path.join('tests', 'component', 'rpm', 'data') RPM_TEST_DATA_DIR = os.path.abspath(RPM_TEST_DATA_SUBMODULE) +class RepoManifest(object): + """Class representing a test repo manifest file""" + def __init__(self, filename=None): + self._doc = minidom.Document() + if filename: + self._doc = minidom.parse(filename) + if self._doc.firstChild.nodeName != 'gbp-test-manifest': + raise Exception('%s is not a test repo manifest' % filename) + else: + self._doc.appendChild(self._doc.createElement("gbp-test-manifest")) + + def add_project(self, name, branches): + """Add new project to the manifest""" + prj_e = self._doc.createElement('project') + prj_e.setAttribute('name', name) + for branch, revision in branches.iteritems(): + br_e = self._doc.createElement('branch') + br_e.setAttribute('name', branch) + br_e.setAttribute('revision', revision) + prj_e.appendChild(br_e) + self._doc.firstChild.appendChild(prj_e) + + def projects_iter(self): + """Return an iterator over projects""" + for prj_e in self._doc.getElementsByTagName('project'): + branches = {} + for br_e in prj_e.getElementsByTagName('branch'): + rev = br_e.getAttribute('revision') + branches[br_e.getAttribute('name')] = rev + yield prj_e.getAttribute('name'), branches + + + def write(self, filename): + """Write to file""" + with open(filename, 'w') as fileobj: + fileobj.write(self._doc.toprettyxml()) + def setup(): """Test Module setup""" ComponentTestGitRepository.check_testdata(RPM_TEST_DATA_SUBMODULE) -- cgit v1.2.3 From 49a7452f7afa2c829772dfa958db33b4729f203a Mon Sep 17 00:00:00 2001 From: Markus Lehtonen Date: Fri, 27 Sep 2013 11:16:39 +0300 Subject: pq-rpm: add unit tests for the command line tool Signed-off-by: Markus Lehtonen --- tests/component/rpm/__init__.py | 51 +++- tests/component/rpm/data | 2 +- tests/component/rpm/test_pq_rpm.py | 505 +++++++++++++++++++++++++++++++++++++ 3 files changed, 556 insertions(+), 2 deletions(-) create mode 100644 tests/component/rpm/test_pq_rpm.py diff --git a/tests/component/rpm/__init__.py b/tests/component/rpm/__init__.py index 913ceeec..607aec49 100644 --- a/tests/component/rpm/__init__.py +++ b/tests/component/rpm/__init__.py @@ -16,10 +16,14 @@ # Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA """Test module for RPM command line tools of the git-buildpackage suite""" +from nose.tools import nottest import os +import shutil from xml.dom import minidom -from tests.component import ComponentTestGitRepository +from gbp.git import GitRepository, GitRepositoryError + +from tests.component import ComponentTestBase, ComponentTestGitRepository RPM_TEST_DATA_SUBMODULE = os.path.join('tests', 'component', 'rpm', 'data') RPM_TEST_DATA_DIR = os.path.abspath(RPM_TEST_DATA_SUBMODULE) @@ -65,4 +69,49 @@ def setup(): """Test Module setup""" ComponentTestGitRepository.check_testdata(RPM_TEST_DATA_SUBMODULE) + +class RpmRepoTestBase(ComponentTestBase): + """Baseclass for tests run in a Git repository with packaging data""" + + @classmethod + def setup_class(cls): + """Initializations only made once per test run""" + super(RpmRepoTestBase, cls).setup_class() + cls.manifest = RepoManifest(os.path.join(RPM_TEST_DATA_DIR, + 'test-repo-manifest.xml')) + cls.orig_repos = {} + for prj, brs in cls.manifest.projects_iter(): + repo = GitRepository.create(os.path.join(cls._tmproot, + '%s.repo' % prj)) + try: + repo.add_remote_repo('origin', RPM_TEST_DATA_DIR, fetch=True) + except GitRepositoryError: + # Workaround for older git working on submodules initialized + # with newer git + gitfile = os.path.join(RPM_TEST_DATA_DIR, '.git') + if os.path.isfile(gitfile): + with open(gitfile) as fobj: + link = fobj.readline().replace('gitdir:', '').strip() + link_dir = os.path.join(RPM_TEST_DATA_DIR, link) + repo.remove_remote_repo('origin') + repo.add_remote_repo('origin', link_dir, fetch=True) + else: + raise + # Fetch all remote refs of the orig repo, too + repo.fetch('origin', tags=True, + refspec='refs/remotes/*:refs/upstream/*') + for branch, rev in brs.iteritems(): + repo.create_branch(branch, rev) + repo.force_head('master', hard=True) + cls.orig_repos[prj] = repo + + @classmethod + @nottest + def init_test_repo(cls, pkg_name): + """Initialize git repository for testing""" + dirname = os.path.basename(cls.orig_repos[pkg_name].path) + shutil.copytree(cls.orig_repos[pkg_name].path, dirname) + os.chdir(dirname) + return GitRepository('.') + # vim:et:ts=4:sw=4:et:sts=4:ai:set list listchars=tab\:»·,trail\:·: diff --git a/tests/component/rpm/data b/tests/component/rpm/data index d32d64fe..b505e801 160000 --- a/tests/component/rpm/data +++ b/tests/component/rpm/data @@ -1 +1 @@ -Subproject commit d32d64fec32e36d911a9d9a4d6d583554cce8113 +Subproject commit b505e8016f5a5003fdfa12619600df91e1a8ae97 diff --git a/tests/component/rpm/test_pq_rpm.py b/tests/component/rpm/test_pq_rpm.py new file mode 100644 index 00000000..22025d6f --- /dev/null +++ b/tests/component/rpm/test_pq_rpm.py @@ -0,0 +1,505 @@ +# vim: set fileencoding=utf-8 : +# +# (C) 2013 Intel Corporation +# This program is free software; you can redistribute it and/or modify +# it under the terms of the GNU General Public License as published by +# the Free Software Foundation; either version 2 of the License, or +# (at your option) any later version. +# +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with this program; if not, write to the Free Software +# Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA +"""Tests for the gbp pq-rpm tool""" + +import os +import tempfile +from nose.tools import assert_raises, eq_, ok_ # pylint: disable=E0611 + +from gbp.scripts.pq_rpm import main as pq +from gbp.git import GitRepository +from gbp.command_wrappers import GitCommand + +from tests.component.rpm import RpmRepoTestBase + +# Disable "Method could be a function warning" +# pylint: disable=R0201 + + +def mock_pq(args): + """Wrapper for pq""" + # Call pq-rpm with added arg0 + return pq(['arg0'] + args) + +class TestPqRpm(RpmRepoTestBase): + """Basic tests for gbp-pq-rpm""" + + def test_invalid_args(self): + """See that pq-rpm fails gracefully when called with invalid args""" + GitRepository.create('.') + # Test empty args + eq_(mock_pq([]), 1) + self._check_log(0, 'gbp:error: No action given.') + self._clear_log() + + # Test invalid command + eq_(mock_pq(['mycommand']), 1) + self._check_log(0, "gbp:error: Unknown action 'mycommand'") + self._clear_log() + + # Test invalid cmdline options + with assert_raises(SystemExit): + mock_pq(['--invalid-arg=123']) + + def test_import_outside_repo(self): + """Run pq-rpm when not in a git repository""" + eq_(mock_pq(['export']), 1) + self._check_log(0, 'gbp:error: %s is not a git repository' % + os.path.abspath(os.getcwd())) + + def test_invalid_config_file(self): + """Test invalid config file""" + # Create dummy invalid config file and run pq-rpm + GitRepository.create('.') + with open('.gbp.conf', 'w') as conffd: + conffd.write('foobar\n') + eq_(mock_pq(['foo']), 1) + self._check_log(0, 'gbp:error: Invalid config file: File contains no ' + 'section headers.') + + def test_import_export(self): + """Basic test for patch import and export""" + repo = self.init_test_repo('gbp-test') + branches = repo.get_local_branches() + ['development/master'] + # Test import + eq_(mock_pq(['import']), 0) + files = ['AUTHORS', 'dummy.sh', 'Makefile', 'NEWS', 'README', 'mydir/', + 'mydir/myfile.txt', '.gbp.conf'] + branches.append('development/master') + self._check_repo_state(repo, 'development/master', branches, files) + eq_(repo.get_merge_base('upstream', 'development/master'), + repo.rev_parse('upstream')) + ok_(len(repo.get_commits('', 'upstream')) < + len(repo.get_commits('', 'development/master'))) + + # Test export + eq_(mock_pq(['export']), 0) + files = ['.gbp.conf', 'bar.tar.gz', 'foo.txt', 'gbp-test.spec', + '0001-my-gz.patch', '0002-my-bzip2.patch', '0003-my2.patch', + 'my.patch'] + self._check_repo_state(repo, 'master', branches, files) + eq_(repo.status()[' M'], ['gbp-test.spec']) + + # Another export after removing some patches + os.unlink('0001-my-gz.patch') + eq_(mock_pq(['export']), 0) + self._check_repo_state(repo, 'master', branches, files) + + def test_import_export2(self): + """Another test for import and export""" + repo = self.init_test_repo('gbp-test2') + branches = repo.get_local_branches() + ['development/master-orphan'] + repo.set_branch('master-orphan') + # Import + eq_(mock_pq(['import']), 0) + files = ['dummy.sh', 'Makefile', 'README', 'mydir/', + 'mydir/myfile.txt', '.gbp.conf'] + self._check_repo_state(repo, 'development/master-orphan', branches, + files) + + # Test export + eq_(mock_pq(['export']), 0) + self._check_repo_state(repo, 'master-orphan', branches) + eq_(repo.status()[' M'], ['packaging/gbp-test2.spec']) + + def test_import_in_subdir(self): + """Test running gbp-rpm-pq from a subdir in the git tree""" + repo = self.init_test_repo('gbp-test2') + repo.set_branch('master-orphan') + branches = repo.get_local_branches() + ['development/master-orphan'] + os.chdir('packaging') + + # Running from subdir should be ok + eq_(mock_pq(['import']), 0) + self._check_repo_state(repo, 'development/master-orphan', branches) + + + def test_rebase(self): + """Basic test for rebase action""" + repo = self.init_test_repo('gbp-test') + branches = repo.get_local_branches() + ['development/master'] + # Import and make development branch out-of-sync + eq_(mock_pq(['import']), 0) + GitCommand("rebase")(['--onto', 'upstream^', 'upstream']) + # Sanity check for our git rebase... + ok_(repo.get_merge_base('development/master', 'upstream') != + repo.rev_parse('upstream')) + + # Do rebase + eq_(mock_pq(['rebase']), 0) + self._check_repo_state(repo, 'development/master', branches) + ok_(repo.get_merge_base('development/master', 'upstream') == + repo.rev_parse('upstream')) + + # Get to out-of-sync, again, and try rebase from master branch + GitCommand("rebase")(['--onto', 'upstream^', 'upstream']) + eq_(mock_pq(['switch']), 0) + eq_(mock_pq(['rebase']), 0) + self._check_repo_state(repo, 'development/master', branches) + ok_(repo.get_merge_base('development/master', 'upstream') == + repo.rev_parse('upstream')) + + def test_switch(self): + """Basic test for switch action""" + repo = self.init_test_repo('gbp-test') + pkg_files = repo.list_files() + branches = repo.get_local_branches() + ['development/master'] + upstr_files = ['dummy.sh', 'Makefile', 'README'] + # Switch to pq branch + eq_(mock_pq(['switch']), 0) + self._check_repo_state(repo, 'development/master', branches, + upstr_files) + + # Switch back to packaging branch + eq_(mock_pq(['switch']), 0) + self._check_repo_state(repo, 'master', branches, pkg_files) + + def test_switch_drop(self): + """Basic test for drop action""" + repo = self.init_test_repo('gbp-test') + init_branches = repo.get_local_branches() + # Import + eq_(mock_pq(['import']), 0) + branches = init_branches + ['development/master'] + self._check_repo_state(repo, 'development/master', branches) + + # Drop pq should fail when on pq branch + eq_(mock_pq(['drop']), 1) + self._check_log(-1, "gbp:error: On a patch-queue branch, can't drop it") + self._check_repo_state(repo, 'development/master', branches) + + # Switch to master + eq_(mock_pq(['switch']), 0) + self._check_repo_state(repo, 'master', branches) + + # Drop should succeed when on master branch + eq_(mock_pq(['drop']), 0) + self._check_repo_state(repo, 'master', init_branches) + + def test_force_import(self): + """Test force import""" + repo = self.init_test_repo('gbp-test') + pkg_files = repo.list_files() + branches = repo.get_local_branches() + ['development/master'] + # Import + eq_(mock_pq(['import']), 0) + pq_files = ['AUTHORS', 'dummy.sh', 'Makefile', 'NEWS', 'README', + 'mydir/', 'mydir/myfile.txt', '.gbp.conf'] + branches.append('development/master') + self._check_repo_state(repo, 'development/master', branches, pq_files) + + # Re-import should fail + eq_(mock_pq(['import']), 1) + self._check_log(-1, "gbp:error: Already on a patch-queue branch") + self._check_repo_state(repo, 'development/master', branches, pq_files) + + # Mangle pq branch and try force import on top of that + repo.force_head('master', hard=True) + self._check_repo_state(repo, 'development/master', branches, pkg_files) + eq_(mock_pq(['import', '--force']), 0) + self._check_repo_state(repo, 'development/master', branches, pq_files) + + # Switch back to master + eq_(mock_pq(['switch']), 0) + self._check_repo_state(repo, 'master', branches, pkg_files) + + # Import should fail + eq_(mock_pq(['import']), 1) + self._check_log(-1, "gbp:error: Patch-queue branch .* already exists") + self._check_repo_state(repo, 'master', branches, pkg_files) + + # Force import should succeed + eq_(mock_pq(['import', '--force']), 0) + self._check_repo_state(repo, 'development/master', branches, pq_files) + + def test_apply(self): + """Basic test for apply action""" + repo = self.init_test_repo('gbp-test') + upstr_files = ['dummy.sh', 'Makefile', 'README'] + branches = repo.get_local_branches() + ['development/master'] + + # No patch given + eq_(mock_pq(['apply']), 1) + self._check_log(-1, "gbp:error: No patch name given.") + + # Apply patch + with tempfile.NamedTemporaryFile() as tmp_patch: + tmp_patch.write(repo.show('master:%s' % 'my.patch')) + tmp_patch.file.flush() + eq_(mock_pq(['apply', tmp_patch.name]), 0) + self._check_repo_state(repo, 'development/master', branches, + upstr_files) + + # Apply another patch, now when already on pq branch + with tempfile.NamedTemporaryFile() as tmp_patch: + tmp_patch.write(repo.show('master:%s' % 'my2.patch')) + tmp_patch.file.flush() + eq_(mock_pq(['apply', tmp_patch.name]), 0) + self._check_repo_state(repo, 'development/master', branches, + upstr_files + ['mydir/', 'mydir/myfile.txt']) + + def test_option_patch_numbers(self): + """Test the --patch-numbers cmdline option""" + repo = self.init_test_repo('gbp-test') + branches = repo.get_local_branches() + ['development/master'] + eq_(mock_pq(['import']), 0) + # Export + eq_(mock_pq(['export', '--no-patch-numbers']), 0) + files = ['.gbp.conf', 'bar.tar.gz', 'foo.txt', 'gbp-test.spec', + 'my-gz.patch', 'my-bzip2.patch', 'my2.patch', + 'my.patch'] + self._check_repo_state(repo, 'master', branches, files) + + def test_option_tmp_dir(self): + """Test the --tmp-dir cmdline option""" + self.init_test_repo('gbp-test') + eq_(mock_pq(['import', '--tmp-dir=foo/bar']), 0) + # Check that the tmp dir basedir was created + ok_(os.path.isdir('foo/bar')) + + def test_option_upstream_tag(self): + """Test the --upstream-tag cmdline option""" + repo = self.init_test_repo('gbp-test') + + # Non-existent upstream-tag -> failure + eq_(mock_pq(['import', '--upstream-tag=foobar/%(upstreamversion)s']), 1) + self._check_log(-1, "gbp:error: Couldn't find upstream version") + + # Create tag -> import should succeed + repo.create_tag('foobar/1.1', msg="test tag", commit='upstream') + eq_(mock_pq(['import', '--upstream-tag=foobar/%(upstreamversion)s']), 0) + + def test_option_spec_file(self): + """Test --spec-file commandline option""" + self.init_test_repo('gbp-test') + + # Non-existent spec file should lead to failure + eq_(mock_pq(['import', '--spec-file=foo.spec']), 1) + self._check_log(-1, "gbp:error: Can't parse spec: Unable to read spec") + # Correct spec file + eq_(mock_pq(['import', '--spec-file=gbp-test.spec']), 0) + + # Force import on top to test parsing spec from another branch + eq_(mock_pq(['import', '--spec-file=gbp-test.spec', '--force']), 0) + + # Test with export, too + eq_(mock_pq(['export', '--spec-file=foo.spec']), 1) + self._check_log(-1, "gbp:error: Can't parse spec: Unable to read spec") + eq_(mock_pq(['export', '--spec-file=gbp-test.spec']), 0) + + def test_option_packaging_dir(self): + """Test --packaging-dir command line option""" + self.init_test_repo('gbp-test') + + # Wrong packaging dir should lead to failure + eq_(mock_pq(['import', '--packaging-dir=foo']), 1) + self._check_log(-1, "gbp:error: Can't parse spec: No spec file found") + # Use correct packaging dir + eq_(mock_pq(['import', '--packaging-dir=.']), 0) + + # Test with export, --spec-file option should override packaging dir + eq_(mock_pq(['export', '--packaging-dir=foo', + '--spec-file=gbp-test.spec']), 0) + + def test_option_pq_branch(self): + """Test the --pq-branch and --packaging-branch options""" + repo = self.init_test_repo('gbp-test') + + # Invalid branch name + eq_(mock_pq(['import', '--pq-branch=foo:']), 1) + self._check_log(-1, "gbp:error: Cannot create patch-queue branch") + eq_(mock_pq(['switch', '--pq-branch=foo:']), 1) + self._check_log(-1, "gbp:error: Cannot create patch-queue branch") + + # Try all possible keys in pq-branch format string + eq_(mock_pq(['import', + '--pq-branch=dev/%(branch)s/%(upstreamversion)s']), 0) + branches = ['master', 'upstream', 'dev/master/1.1'] + self._check_repo_state(repo, 'dev/master/1.1', branches) + + # Switch to non-existent packaging branch should fail + eq_(mock_pq(['switch', '--pq-branch=dev/master/1.1', + '--packaging-branch=foobar']), 1) + self._check_log(-1, "gbp:error: Git command failed: Error running git") + self._check_repo_state(repo, 'dev/master/1.1', branches) + + # Export to existing packaging branch should be ok + eq_(mock_pq(['switch', '--pq-branch=dev/master/1.1', + '--packaging-branch=master']), 0) + self._check_repo_state(repo, 'master', branches) + + def test_option_export_rev(self): + """Test the --export-rev cmdline option""" + repo = self.init_test_repo('gbp-test') + eq_(mock_pq(['import']), 0) + + # Export directly from upstream -> no patches expected + eq_(mock_pq(['export', '--export-rev=upstream']), 0) + files = ['.gbp.conf', 'bar.tar.gz', 'foo.txt', 'gbp-test.spec', + 'my.patch'] + branches = ['master', 'upstream', 'development/master'] + self._check_repo_state(repo, 'master', branches, files) + + # Export another rev + eq_(mock_pq(['export', '--export-rev=development/master~2']), 0) + self._check_repo_state(repo, 'master', branches, + files + ['0001-my-gz.patch']) + + # Export from upstream..master should fail + eq_(mock_pq(['export', '--export-rev=master']), 1) + self._check_log(-1, "gbp:error: Start commit .* not an ancestor of end") + # Export invalid rev should fail + eq_(mock_pq(['export', '--export-rev=foobar']), 1) + self._check_log(-1, "gbp:error: Invalid treeish object foobar") + + # Export plain treeish. Doesn't work in pq (at least) - + # just for testing exception handling here + content = repo.list_tree('development/master') + tree = repo.make_tree(content) + eq_(mock_pq(['export', '--export-rev=%s' % tree]), 1) + self._check_log(-1, "gbp:error: Start commit .* not an ancestor of end") + + def test_option_patch_compress(self): + """Test the --patch-export-compress cmdline option""" + repo = self.init_test_repo('gbp-test') + eq_(mock_pq(['import']), 0) + + # Export, all generated patches should be compressed + eq_(mock_pq(['export', '--patch-export-compress=1']), 0) + files = ['.gbp.conf', 'bar.tar.gz', 'foo.txt', 'gbp-test.spec', + '0001-my-gz.patch.gz', '0002-my-bzip2.patch.gz', + '0003-my2.patch.gz', 'my.patch'] + branches = ['master', 'upstream', 'development/master'] + self._check_repo_state(repo, 'master', branches, files) + + def test_option_patch_export_squash(self): + """Test the --patch-export-squash-until cmdline option""" + repo = self.init_test_repo('gbp-test') + eq_(mock_pq(['import']), 0) + + # Non-existent squash point should fail + eq_(mock_pq(['export', '--patch-export-squash-until=foo']), 1) + self._check_log(-1, r"gbp:error: Git command failed: revision 'foo\^0'") + + # Invalid squash point should fail + eq_(mock_pq(['export', '--patch-export-squash-until=master']), 1) + self._check_log(-1, "gbp:error: Given squash point 'master' not in the " + "history of end commit 'development/master'") + + # Squashing up to the second latest patch -> 1 "normal" patch + squash = 'development/master~1' + eq_(mock_pq(['export', '--patch-export-squash-until=%s' % squash]), 0) + squash += ':squash' + eq_(mock_pq(['export', '--patch-export-squash-until=%s' % squash]), 0) + files = ['.gbp.conf', 'bar.tar.gz', 'foo.txt', 'gbp-test.spec', + 'my.patch', 'squash.diff', '0002-my2.patch'] + branches = ['master', 'upstream', 'development/master'] + self._check_repo_state(repo, 'master', branches, files) + + def test_option_patch_export_ignore(self): + """Test the --patch-export-ignore-path cmdline option""" + repo = self.init_test_repo('gbp-test') + + eq_(mock_pq(['import']), 0) + + # Export + eq_(mock_pq(['export', '--patch-export-ignore-path=mydir/.*']), 0) + files = ['.gbp.conf', 'bar.tar.gz', 'foo.txt', 'gbp-test.spec', + '0001-my-gz.patch', '0002-my-bzip2.patch', 'my.patch'] + branches = ['master', 'upstream', 'development/master'] + self._check_repo_state(repo, 'master', branches, files) + + def test_export_with_merges(self): + """Test exporting pq-branch with merge commits""" + repo = self.init_test_repo('gbp-test') + # Import + eq_(mock_pq(['import']), 0) + + # Create a merge commit in pq-branch + patches = repo.format_patches('HEAD^', 'HEAD', '.') + repo.force_head('HEAD^', hard=True) + repo.commit_dir('.', 'Merge with master', 'development/master', + ['master']) + merge_rev = repo.rev_parse('HEAD', short=7) + eq_(mock_pq(['apply', patches[0]]), 0) + upstr_rev = repo.rev_parse('upstream', short=7) + os.unlink(patches[0]) + + # Export should create diff up to the merge point and one "normal" patch + eq_(mock_pq(['export']), 0) + files = ['.gbp.conf', 'bar.tar.gz', 'foo.txt', 'gbp-test.spec', + 'my.patch', '%s-to-%s.diff' % (upstr_rev, merge_rev), + '0002-my2.patch'] + branches = ['master', 'upstream', 'development/master'] + self._check_repo_state(repo, 'master', branches, files) + + def test_option_import_files(self): + """Test the --import-files cmdline option""" + repo = self.init_test_repo('gbp-test') + # Add new conf file + os.mkdir('debian') + with open('debian/gbp.conf', 'w') as conf_file: + conf_file.write('[DEFAULT]\npq-branch = my-pq-branch\n') + repo.add_files(['debian/gbp.conf'], force=True) + repo.commit_files(['debian/gbp.conf'], msg="Add conf file") + + # Import with default settings (should import gbp conf files) + branches = repo.get_local_branches() + ['my-pq-branch'] + eq_(mock_pq(['import']), 0) + self._check_repo_state(repo, 'my-pq-branch', branches) + ok_('debian/gbp.conf' in repo.list_files()) + ok_('.gbp.conf' in repo.list_files()) + + # Re-import with user-defined files + eq_(mock_pq(['import', '--force', '--packaging-branch', 'master', + '--import-files', 'foo.txt,my.patch']), 0) + self._check_repo_state(repo, 'my-pq-branch', branches) + ok_('foo.txt' in repo.list_files()) + ok_('my.patch' in repo.list_files()) + + # Drop and re-import with no files + eq_(mock_pq(['switch', '--packaging-branch', 'master', '--pq-branch', + 'my-pq-branch']), 0) + eq_(mock_pq(['drop']), 0) + eq_(mock_pq(['import', '--packaging-branch', 'master', + '--pq-branch', 'my-pq-branch', '--import-files=']), 0) + self._check_repo_state(repo, 'my-pq-branch', branches) + ok_('debian/gbp.conf' not in repo.list_files()) + ok_('.gbp.conf' not in repo.list_files()) + + def test_import_unapplicable_patch(self): + """Test import when a patch does not apply""" + repo = self.init_test_repo('gbp-test') + branches = repo.get_local_branches() + # Mangle patch + with open('my2.patch', 'w') as patch_file: + patch_file.write('-this-does\n+not-apply\n') + eq_(mock_pq(['import']), 1) + self._check_log(-1, "(" + "Aborting|" + "Please, commit your changes or stash them|" + "gbp:error: Import failed.* You have local changes" + ")") + self._check_repo_state(repo, 'master', branches) + + # Now commit the changes to the patch and try again + repo.add_files(['my2.patch'], force=True) + repo.commit_files(['my2.patch'], msg="Mangle patch") + eq_(mock_pq(['import']), 1) + self._check_log(-1, "gbp:error: Import failed: Error running git apply") + self._check_repo_state(repo, 'master', branches) + -- cgit v1.2.3 From 1174d908ee88d8ef2c5b00167234ba256879102d Mon Sep 17 00:00:00 2001 From: Markus Lehtonen Date: Wed, 5 Feb 2014 12:12:38 +0200 Subject: rpm: support for getting/setting changelog in spec SpecFile objects now support reading and writing of the %changelog section. Signed-off-by: Markus Lehtonen --- gbp/rpm/__init__.py | 43 ++++++++++++++++++++++ tests/test_rpm.py | 38 +++++++++++++++++-- tests/test_rpm_data/rpmbuild/SPECS/gbp-test2.spec | 13 +++++++ tests/test_rpm_data/specs/gbp-test-reference2.spec | 3 ++ tests/test_rpm_data/specs/gbp-test2-reference.spec | 12 ++++++ .../test_rpm_data/specs/gbp-test2-reference2.spec | 13 +++++++ 6 files changed, 118 insertions(+), 4 deletions(-) diff --git a/gbp/rpm/__init__.py b/gbp/rpm/__init__.py index 7aa7ba41..0e04b4df 100644 --- a/gbp/rpm/__init__.py +++ b/gbp/rpm/__init__.py @@ -563,6 +563,49 @@ class SpecFile(object): self._special_directives[key].append(linerec) return ret + def _set_section(self, name, text): + """Update/create a complete section in spec file.""" + if name not in self.section_identifiers: + raise GbpError("Not a valid section directive: '%s'" % name) + # Delete section, if it exists + if name in self._special_directives: + if len(self._special_directives[name]) > 1: + raise GbpError("Multiple %%%s sections found, don't know " + "which to update" % name) + line = self._special_directives[name][0]['line'] + gbp.log.debug("Removing content of %s section" % name) + while line.next: + match = self.directive_re.match(str(line.next)) + if match and match.group('name') in self.section_identifiers: + break + self._content.delete(line.next) + else: + gbp.log.debug("Adding %s section to the end of spec file" % name) + line = self._content.append('%%%s\n' % name) + linerec = {'line': line, 'id': None, 'args': None} + self._special_directives[name] = [linerec] + # Add new lines + gbp.log.debug("Updating content of %s section" % name) + for linetext in text.splitlines(): + line = self._content.insert_after(line, linetext + '\n') + + def set_changelog(self, text): + """Update or create the %changelog section""" + self._set_section('changelog', text) + + def get_changelog(self): + """Get the %changelog section""" + text = '' + if 'changelog' in self._special_directives: + line = self._special_directives['changelog'][0]['line'] + while line.next: + line = line.next + match = self.directive_re.match(str(line)) + if match and match.group('name') in self.section_identifiers: + break + text += str(line) + return text + def update_patches(self, patches, commands): """Update spec with new patch tags and patch macros""" # Remove non-ignored patches diff --git a/tests/test_rpm.py b/tests/test_rpm.py index 69ab85b6..13799266 100644 --- a/tests/test_rpm.py +++ b/tests/test_rpm.py @@ -20,7 +20,7 @@ import filecmp import os import shutil import tempfile -from nose.tools import assert_raises +from nose.tools import assert_raises, eq_ from gbp.errors import GbpError from gbp.rpm import (SrcRpmFile, SpecFile, parse_srpm, NoSpecError, guess_spec, @@ -181,15 +181,16 @@ class TestSpecFile(object): spec.write_spec_file() assert filecmp.cmp(tmp_spec, reference_spec) is True - # Test adding the VCS tag + # Test adding the VCS tag and adding changelog reference_spec = os.path.join(SPEC_DIR, 'gbp-test-reference2.spec') spec.set_tag('VCS', None, 'myvcstag') + spec.set_changelog("* Wed Feb 05 2014 Name 1\n- New entry\n") spec.write_spec_file() assert filecmp.cmp(tmp_spec, reference_spec) is True def test_update_spec2(self): """Another test for spec autoupdate functionality""" - tmp_spec = os.path.join(self.tmpdir, 'gbp-test.spec') + tmp_spec = os.path.join(self.tmpdir, 'gbp-test2.spec') shutil.copy2(os.path.join(SPEC_DIR, 'gbp-test2.spec'), tmp_spec) reference_spec = os.path.join(SPEC_DIR, 'gbp-test2-reference2.spec') @@ -201,10 +202,12 @@ class TestSpecFile(object): spec.write_spec_file() assert filecmp.cmp(tmp_spec, reference_spec) is True - # Test updating patches again and removing the VCS tag + # Test updating patches again, removing the VCS tag and re-writing + # changelog reference_spec = os.path.join(SPEC_DIR, 'gbp-test2-reference.spec') spec.update_patches(['new.patch'], {'new.patch': {'if': '1'}}) spec.set_tag('VCS', None, '') + spec.set_changelog("* Wed Feb 05 2014 Name 2\n- New entry\n\n") spec.write_spec_file() assert filecmp.cmp(tmp_spec, reference_spec) is True @@ -247,6 +250,33 @@ class TestSpecFile(object): spec.write_spec_file() assert filecmp.cmp(tmp_spec, reference_spec) is True + def test_modifying_err(self): + """Test error conditions of modification methods""" + spec_filepath = os.path.join(SPEC_DIR, 'gbp-test2.spec') + spec = SpecFileTester(spec_filepath) + + # Unknown/invalid section name + with assert_raises(GbpError): + spec.protected('_set_section')('patch', 'new content\n') + + # Multiple sections with the same name + with assert_raises(GbpError): + spec.protected('_set_section')('files', '%{_sysconfdir}/foo\n') + + def test_changelog(self): + """Test changelog methods""" + spec_filepath = os.path.join(SPEC_DIR, 'gbp-test2.spec') + spec = SpecFile(spec_filepath) + + # Read changelog + eq_(spec.get_changelog(), + "* Tue Feb 04 2014 Name 1\n- My change\n\n\n") + + # Set changelog and check again + new_text = "* Wed Feb 05 2014 Name 2\n- New entry\n\n\n" + spec.set_changelog(new_text) + eq_(spec.get_changelog(), new_text) + def test_quirks(self): """Test spec that is broken/has anomalities""" spec_filepath = os.path.join(SPEC_DIR, 'gbp-test-quirks.spec') diff --git a/tests/test_rpm_data/rpmbuild/SPECS/gbp-test2.spec b/tests/test_rpm_data/rpmbuild/SPECS/gbp-test2.spec index dd9e2ec2..8a92725d 100644 --- a/tests/test_rpm_data/rpmbuild/SPECS/gbp-test2.spec +++ b/tests/test_rpm_data/rpmbuild/SPECS/gbp-test2.spec @@ -18,6 +18,12 @@ VCS: myoldvcstag %description Package for testing the RPM functionality of git-buildpackage. +%package empty +Summary: Empty subpackage + +%description empty +Empty subpackage for the %{name} test package. + %prep %setup -T -n %{name}-%{version} -c -a 10 @@ -40,8 +46,15 @@ cp -R * %{buildroot}/%{_datadir}/%{name} install %{SOURCE0} %{buildroot}/%{_datadir}/%{name} +%changelog +* Tue Feb 04 2014 Name 1 +- My change + %files %defattr(-,root,root,-) %dir %{_datadir}/%{name} %{_datadir}/%{name} + +%files empty +%defattr(-,root,root,-) diff --git a/tests/test_rpm_data/specs/gbp-test-reference2.spec b/tests/test_rpm_data/specs/gbp-test-reference2.spec index 1cd922b2..0fbe0260 100644 --- a/tests/test_rpm_data/specs/gbp-test-reference2.spec +++ b/tests/test_rpm_data/specs/gbp-test-reference2.spec @@ -42,3 +42,6 @@ install %{SOURCE0} %{buildroot}/%{_datadir}/%{name} %defattr(-,root,root,-) %dir %{_datadir}/%{name} %{_datadir}/%{name} +%changelog +* Wed Feb 05 2014 Name 1 +- New entry diff --git a/tests/test_rpm_data/specs/gbp-test2-reference.spec b/tests/test_rpm_data/specs/gbp-test2-reference.spec index dfd4b91f..1882131f 100644 --- a/tests/test_rpm_data/specs/gbp-test2-reference.spec +++ b/tests/test_rpm_data/specs/gbp-test2-reference.spec @@ -17,6 +17,12 @@ Packager: Markus Lehtonen %description Package for testing the RPM functionality of git-buildpackage. +%package empty +Summary: Empty subpackage + +%description empty +Empty subpackage for the %{name} test package. + %prep %setup -T -n %{name}-%{version} -c -a 10 @@ -42,8 +48,14 @@ cp -R * %{buildroot}/%{_datadir}/%{name} install %{SOURCE0} %{buildroot}/%{_datadir}/%{name} +%changelog +* Wed Feb 05 2014 Name 2 +- New entry %files %defattr(-,root,root,-) %dir %{_datadir}/%{name} %{_datadir}/%{name} + +%files empty +%defattr(-,root,root,-) diff --git a/tests/test_rpm_data/specs/gbp-test2-reference2.spec b/tests/test_rpm_data/specs/gbp-test2-reference2.spec index 0b93f0fa..d41f4503 100644 --- a/tests/test_rpm_data/specs/gbp-test2-reference2.spec +++ b/tests/test_rpm_data/specs/gbp-test2-reference2.spec @@ -19,6 +19,12 @@ VCS: myvcstag %description Package for testing the RPM functionality of git-buildpackage. +%package empty +Summary: Empty subpackage + +%description empty +Empty subpackage for the %{name} test package. + %prep %setup -T -n %{name}-%{version} -c -a 10 @@ -48,8 +54,15 @@ cp -R * %{buildroot}/%{_datadir}/%{name} install %{SOURCE0} %{buildroot}/%{_datadir}/%{name} +%changelog +* Tue Feb 04 2014 Name 1 +- My change + %files %defattr(-,root,root,-) %dir %{_datadir}/%{name} %{_datadir}/%{name} + +%files empty +%defattr(-,root,root,-) -- cgit v1.2.3 From 06e95f08ee08f96faaecf977a31d1d73f3e2135e Mon Sep 17 00:00:00 2001 From: Markus Lehtonen Date: Tue, 4 Feb 2014 17:49:28 +0200 Subject: rpm: add gbp.rpm.changelog module This new module contains basic containers and functionality for parsing and updating rpm changelogs. It is coupled with the rpm packaging policy class which now has definitions for rpm changelog formatting. Signed-off-by: Markus Lehtonen --- gbp/rpm/changelog.py | 246 ++++++++++++++++++++++++++++++++++++++++++++ gbp/rpm/policy.py | 15 +++ tests/test_rpm_changelog.py | 226 ++++++++++++++++++++++++++++++++++++++++ 3 files changed, 487 insertions(+) create mode 100644 gbp/rpm/changelog.py create mode 100644 tests/test_rpm_changelog.py diff --git a/gbp/rpm/changelog.py b/gbp/rpm/changelog.py new file mode 100644 index 00000000..8eb08db6 --- /dev/null +++ b/gbp/rpm/changelog.py @@ -0,0 +1,246 @@ +# vim: set fileencoding=utf-8 : +# +# (C) 2014 Intel Corporation +# This program is free software; you can redistribute it and/or modify +# it under the terms of the GNU General Public License as published by +# the Free Software Foundation; either version 2 of the License, or +# (at your option) any later version. +# +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with this program; if not, write to the Free Software +# Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA +"""An RPM Changelog""" + +import datetime +import re + +import gbp.log + + +class ChangelogError(Exception): + """Problem parsing changelog""" + pass + + +class _ChangelogHeader(object): + """The header part of one changelog section""" + + def __init__(self, pkgpolicy, time=None, **kwargs): + self._pkgpolicy = pkgpolicy + self._data = {'time': time} + self._data.update(kwargs) + + def __contains__(self, key): + return key in self._data + + def __getitem__(self, key): + if key in self._data: + return self._data[key] + return None + + def __str__(self): + keys = dict(self._data) + keys['time'] = self._data['time'].strftime( + self._pkgpolicy.Changelog.header_time_format) + try: + return self._pkgpolicy.Changelog.header_format % keys + '\n' + except KeyError as err: + raise ChangelogError("Unable to format changelog header, missing " + "property %s" % err) + + +class _ChangelogEntry(object): + """An entry (one 'change') in an RPM changelog""" + + def __init__(self, pkgpolicy, author, text): + """ + @param pkgpolicy: RPM packaging policy + @type pkgpolicy: L{RpmPkgPolicy} + @param author: author of the change + @type author: C{str} + @param text: message of the changelog entry + @type text: C{str} or C{list} of C{str} + """ + self._pkgpolicy = pkgpolicy + self.author = author + if isinstance(text, str): + self._text = text.splitlines() + else: + self._text = text + # Strip trailing empty lines + while text and not text[-1].strip(): + text.pop() + + def __str__(self): + # Currently no (re-)formatting, just raw text + string = "" + for line in self._text: + string += line + '\n' + return string + + +class _ChangelogSection(object): + """One section (set of changes) in an RPM changelog""" + + def __init__(self, pkgpolicy, *args, **kwargs): + self._pkgpolicy = pkgpolicy + self.header = _ChangelogHeader(pkgpolicy, *args, **kwargs) + self.entries = [] + self._trailer = '\n' + + + def __str__(self): + text = str(self.header) + for entry in self.entries: + text += str(entry) + # Add "section separator" + text += self._trailer + return text + + def set_header(self, *args, **kwargs): + """Change the section header""" + self.header = _ChangelogHeader(self._pkgpolicy, *args, **kwargs) + + def append_entry(self, entry): + """Add a new entry to the end of the list of entries""" + self.entries.append(entry) + return entry + + +class Changelog(object): + """An RPM changelog""" + + def __init__(self, pkgpolicy): + self._pkgpolicy = pkgpolicy + self.sections = [] + + def __str__(self): + string = "" + for section in self.sections: + string += str(section) + return string + + def create_entry(self, *args, **kwargs): + """Create and return new entry object""" + return _ChangelogEntry(self._pkgpolicy, *args, **kwargs) + + def add_section(self, *args, **kwargs): + """Add new empty section""" + section = _ChangelogSection(self._pkgpolicy, *args, **kwargs) + self.sections.insert(0, section) + return section + + +class ChangelogParser(object): + """Parser for RPM changelogs""" + + def __init__(self, pkgpolicy): + self._pkgpolicy = pkgpolicy + self.section_match_re = pkgpolicy.Changelog.section_match_re + self.section_split_re = pkgpolicy.Changelog.section_split_re + self.header_split_re = pkgpolicy.Changelog.header_split_re + self.header_name_split_re = pkgpolicy.Changelog.header_name_split_re + self.body_name_re = pkgpolicy.Changelog.body_name_re + + def raw_parse_string(self, string): + """Parse changelog - only splits out raw changelog sections.""" + changelog = Changelog(self._pkgpolicy) + ch_section = "" + for line in string.splitlines(): + if re.match(self.section_match_re, line, re.M | re.S): + if ch_section: + changelog.sections.append(ch_section) + ch_section = line + '\n' + elif ch_section: + ch_section += line + '\n' + else: + raise ChangelogError("First line in changelog is invalid") + if ch_section: + changelog.sections.append(ch_section) + return changelog + + def raw_parse_file(self, changelog): + """Parse changelog file - only splits out raw changelog sections.""" + try: + with open(changelog) as ch_file: + return self.raw_parse_string(ch_file.read()) + except IOError as err: + raise ChangelogError("Unable to read changelog file: %s" % err) + + def _parse_section_header(self, text): + """Parse one changelog section header""" + # Try to split out time stamp and "changelog name" + match = re.match(self.header_split_re, text, re.M) + if not match: + raise ChangelogError("Unable to parse changelog header: %s" % text) + try: + time = datetime.datetime.strptime(match.group('ch_time'), + "%a %b %d %Y") + except ValueError: + raise ChangelogError("Unable to parse changelog header: invalid " + "timestamp '%s'" % match.group('ch_time')) + # Parse "name" part which consists of name and/or email and an optional + # revision + name_text = match.group('ch_name') + match = re.match(self.header_name_split_re, name_text) + if not match: + raise ChangelogError("Unable to parse changelog header: invalid " + "name / revision '%s'" % name_text) + kwargs = match.groupdict() + return _ChangelogSection(self._pkgpolicy, time=time, **kwargs) + + def _create_entry(self, author, text): + """Create a new changelog entry""" + return _ChangelogEntry(self._pkgpolicy, author=author, text=text) + + def _parse_section_entries(self, text, default_author): + """Parse entries from a string and add them to a section""" + entries = [] + entry_text = [] + author = default_author + for line in text.splitlines(): + match = re.match(self.body_name_re, line) + if match: + if entry_text: + entries.append(self._create_entry(author, entry_text)) + author = match.group('name') + else: + if line.startswith("-"): + if entry_text: + entries.append(self._create_entry(author, entry_text)) + entry_text = [line] + else: + if not entry_text: + gbp.log.info("First changelog entry (%s) is garbled, " + "entries should start with a dash ('-')" % + line) + entry_text.append(line) + if entry_text: + entries.append(self._create_entry(author, entry_text)) + + return entries + + + def parse_section(self, text): + """Parse one section""" + # Check that the first line(s) look like a changelog header + match = re.match(self.section_split_re, text, re.M | re.S) + if not match: + raise ChangelogError("Doesn't look like changelog header: %s..." % + text.splitlines()[0]) + # Parse header + section = self._parse_section_header(match.group('ch_header')) + header = section.header + # Parse entries + default_author = header['name'] if 'name' in header else header['email'] + for entry in self._parse_section_entries(match.group('ch_body'), + default_author): + section.append_entry(entry) + + return section + diff --git a/gbp/rpm/policy.py b/gbp/rpm/policy.py index d5b096ba..62d98f92 100644 --- a/gbp/rpm/policy.py +++ b/gbp/rpm/policy.py @@ -143,3 +143,18 @@ class RpmPkgPolicy(PkgPolicy): return version return None + class Changelog(object): + """Container for changelog related policy settings""" + + # Regexps for splitting/parsing the changelog section (of + # Tizen / Fedora style changelogs) + section_match_re = r'^\*' + section_split_re = r'^\*\s*(?P\S.*?)$\n(?P.*)' + header_split_re = r'(?P\S.*\s[0-9]{4})\s+(?P\S.*$)' + header_name_split_re = r'(?P[^<]*)\s+<(?P[^>]+)>((\s*-)?\s+(?P\S+))?$' + body_name_re = r'\[(?P.*)\]' + + # Changelog header format (when writing out changelog) + header_format = "* %(time)s %(name)s <%(email)s> %(revision)s" + header_time_format = "%a %b %d %Y" + header_rev_format = "%(version)s" diff --git a/tests/test_rpm_changelog.py b/tests/test_rpm_changelog.py new file mode 100644 index 00000000..29732936 --- /dev/null +++ b/tests/test_rpm_changelog.py @@ -0,0 +1,226 @@ +# vim: set fileencoding=utf-8 : +# +# (C) 2014 Intel Corporation +# This program is free software; you can redistribute it and/or modify +# it under the terms of the GNU General Public License as published by +# the Free Software Foundation; either version 2 of the License, or +# (at your option) any later version. +# +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with this program; if not, write to the Free Software +# Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA +"""Test RPM changelog classes and parsing""" + +from datetime import datetime +from nose.tools import assert_raises, eq_, ok_ # pylint: disable=E0611 +from tempfile import NamedTemporaryFile + +from gbp.rpm.changelog import _ChangelogHeader, _ChangelogEntry +from gbp.rpm.changelog import _ChangelogSection, Changelog +from gbp.rpm.changelog import ChangelogParser, ChangelogError +from gbp.rpm.policy import RpmPkgPolicy + + +class TestChangelogHeader(object): + """Test the _ChangelogHeader class""" + + def test_str_format(self): + """Basic test for header""" + time = datetime(2014, 01, 29, 12, 13, 14) + header = _ChangelogHeader(RpmPkgPolicy, time, name="John Doe", + email="user@host.com", revision="1") + eq_(str(header), "* Wed Jan 29 2014 John Doe 1\n") + + def test_str_format_err(self): + """Test missing properties""" + time = datetime(2014, 01, 29, 12, 13, 14) + header = _ChangelogHeader(RpmPkgPolicy, time, name="John", revision="1") + with assert_raises(ChangelogError): + str(header) + + def test_container(self): + """Test the container methods of the class""" + header = _ChangelogHeader(RpmPkgPolicy, datetime(2014, 1, 1), name="N", + revision="1") + # Test __getitem__() + eq_(header['name'], "N") + eq_(header['email'], None) + # Test __contains__() + ok_('name' in header) + ok_('foo' not in header) + + +class TestChangelogEntry(object): + """Test the _ChangelogEntry class""" + + def test_str_format(self): + """Basic test""" + entry = _ChangelogEntry(RpmPkgPolicy, author="John Doe", + text="- foo\n bar") + eq_(str(entry), "- foo\n bar\n") + + +class TestChangelogSection(object): + """Test the _ChangelogSection class""" + + def setup(self): + """Initialize test""" + time = datetime(2014, 01, 29, 12, 13, 14) + self.default_sect = _ChangelogSection(RpmPkgPolicy, time, name="J. D.", + email="u@h", revision="1") + entry = _ChangelogEntry(RpmPkgPolicy, "J. D.", "- my change") + self.default_sect.entries = [entry] + + def test_str_format(self): + """Basic test""" + section = self.default_sect + eq_(str(section), "* Wed Jan 29 2014 J. D. 1\n- my change\n\n") + + def test_append_entry(self): + """Test add_entry() method""" + section = self.default_sect + entry = _ChangelogEntry(RpmPkgPolicy, author="", + text="- another\n change") + new_entry = section.append_entry(entry) + eq_(str(section), "* Wed Jan 29 2014 J. D. 1\n- my change\n" + "- another\n change\n\n") + eq_(new_entry, section.entries[-1]) + + + def test_set_header(self): + """Test set_header() method""" + section = self.default_sect + time = datetime(2014, 01, 30) + section.set_header(time=time, name="Jane", email="u@h", revision="1.1") + eq_(str(section), "* Thu Jan 30 2014 Jane 1.1\n- my change\n\n") + +class TestChangelogParser(object): + """Test the default changelog parser""" + + cl_default_style = """\ +* Wed Jan 29 2014 Markus Lehtonen 0.3-1 +- Version bump +- Drop foo.patch + +* Tue Jan 28 2014 Markus Lehtonen 0.2 +- Update to 0.2 + +* Mon Jan 27 2014 Markus Lehtonen 0.1 +- Initial version +""" + cl_with_authors = """\ +* Wed Jan 29 2014 Markus Lehtonen 0.3-1 +[Markus Lehtonen] +- Version bump +[John Doe] +- Bug fix +""" + # Invalid timestamp / name + cl_broken_header_1 = """\ +* Wed Jan 29 2014Markus Lehtonen 0.3-1 +- Version bump +""" + # Whitespace before the asterisk in the header + cl_broken_header_2 = """\ + * Wed Jan 29 2014 Markus Lehtonen 0.3-1 +- Version bump +""" + # Invalid timestamp + cl_broken_header_3 = """\ +* Wed Jan 32 2014 Markus Lehtonen 0.3-1 +- Version bump +""" + # Missing email + cl_broken_header_4 = """\ +* Wed Jan 29 2014 Markus Lehtonen 0.3-1 +- Version bump +""" + # Garbage before section header + cl_broken_header_5 = """\ +---garbage--- +* Wed Jan 29 2014 Markus Lehtonen 0.3-1 +- Version bump +""" + + parser = ChangelogParser(RpmPkgPolicy) + + def test_parse_changelog(self): + """Basic tests for successful parsing""" + # Raw parsing of changelog + changelog = self.parser.raw_parse_string(self.cl_default_style) + eq_(len(changelog.sections), 3) + + # Check that re-creating the changelog doesn't mangle it + eq_(str(changelog), self.cl_default_style) + + # Parse and check section + section = self.parser.parse_section(changelog.sections[0]) + + eq_(section.header['time'], datetime(2014, 1, 29)) + eq_(section.header['name'], "Markus Lehtonen") + eq_(section.header['email'], "markus.lehtonen@linux.intel.com") + eq_(section.header['revision'], "0.3-1") + + # Check that re-creating section doesn't mangle it + eq_(str(section), changelog.sections[0]) + + def test_parse_authors(self): + """Test parsing of authors from changelog entries""" + section = self.parser.parse_section(self.cl_with_authors) + eq_(section.entries[0].author, "Markus Lehtonen") + eq_(section.entries[1].author, "John Doe") + + def test_parse_changelog_file(self): + """Basic tests for parsing a file""" + # Create file and parse it + tmpfile = NamedTemporaryFile() + tmpfile.write(self.cl_default_style) + tmpfile.file.flush() + changelog = self.parser.raw_parse_file(tmpfile.name) + # Check parsing results + eq_(len(changelog.sections), 3) + eq_(str(changelog), self.cl_default_style) + # Cleanup + tmpfile.close() + + def test_parse_section_fail(self): + """Basic tests for failures of changelog section parsing""" + with assert_raises(ChangelogError): + self.parser.parse_section(self.cl_broken_header_1) + + with assert_raises(ChangelogError): + self.parser.parse_section(self.cl_broken_header_2) + + with assert_raises(ChangelogError): + self.parser.parse_section(self.cl_broken_header_3) + + with assert_raises(ChangelogError): + self.parser.parse_section(self.cl_broken_header_4) + + def test_parse_changelog_fail(self): + """Basic tests for changelog parsing failures""" + with assert_raises(ChangelogError): + self.parser.raw_parse_string(self.cl_broken_header_5) + + +class TestChangelog(object): + """Unit tests for the Changelog class""" + + def basic_test(self): + """Test basic initialization""" + changelog = Changelog(RpmPkgPolicy) + eq_(str(changelog), "") + + def test_add_section(self): + """Test the add_section() method""" + changelog = Changelog(RpmPkgPolicy) + time = datetime(2014, 01, 30) + new_section = changelog.add_section(time=time, name="Jane Doe", + email="j@doe.com", revision="1.2") + eq_(str(changelog), "* Thu Jan 30 2014 Jane Doe 1.2\n\n") + eq_(new_section, changelog.sections[0]) -- cgit v1.2.3 From 3bb47947eea49fdd8ece530d88ca287ac1b2b875 Mon Sep 17 00:00:00 2001 From: Markus Lehtonen Date: Tue, 4 Feb 2014 17:54:36 +0200 Subject: Introduce git-rpm-ch tool Initial version of the git-rpm-ch tool which is intended for maintaining RPM changelogs. Supports both spec files and separate "OBS style" changelog files. Signed-off-by: Markus Lehtonen --- bin/git-rpm-ch | 5 + gbp-rpm.conf | 9 ++ gbp/config.py | 16 ++ gbp/rpm/policy.py | 112 +++++++++++++ gbp/scripts/rpm_ch.py | 429 ++++++++++++++++++++++++++++++++++++++++++++++++++ setup.py | 3 +- 6 files changed, 573 insertions(+), 1 deletion(-) create mode 100755 bin/git-rpm-ch create mode 100755 gbp/scripts/rpm_ch.py diff --git a/bin/git-rpm-ch b/bin/git-rpm-ch new file mode 100755 index 00000000..ef1340e7 --- /dev/null +++ b/bin/git-rpm-ch @@ -0,0 +1,5 @@ +#! /usr/bin/python -u +import sys +from gbp.scripts.rpm_ch import main + +sys.exit(main(sys.argv)) diff --git a/gbp-rpm.conf b/gbp-rpm.conf index 27f80257..f9ebd9e6 100644 --- a/gbp-rpm.conf +++ b/gbp-rpm.conf @@ -132,3 +132,12 @@ [gbp-create-remote-repo] # Disable remote branch tracking #track = False + +# Options only affecting git-rpm-changelog +[git-rpm-changelog] +# Changelog filename, relative to the git topdir +#changelog-file = git-buildpackage.changelog +# Format string for the revision part of the changelog header +#changelog-revision = %(tagname)s +# Preferred editor +#editor-cmd = vim diff --git a/gbp/config.py b/gbp/config.py index e6b3f612..ff673cf6 100644 --- a/gbp/config.py +++ b/gbp/config.py @@ -604,6 +604,10 @@ class GbpOptionParserRpm(GbpOptionParser): 'orig-prefix' : 'auto', 'patch-import' : 'True', 'spec-vcs-tag' : '', + 'changelog-file' : 'auto', + 'changelog-revision' : '', + 'spawn-editor' : 'always', + 'editor-cmd' : 'vim', } ) help = dict(GbpOptionParser.help) @@ -647,6 +651,18 @@ class GbpOptionParserRpm(GbpOptionParser): ("Set/update the 'VCS:' tag in the spec file, empty " "value removes the tag entirely, default is " "'%(spec-vcs-tag)s'"), + 'changelog-file': + ("Changelog file to be used, default is " + "'%(changelog-file)s'"), + 'changelog-revision': + ("Format string for the revision field in the " + "changelog header. If empty or not defined the " + "default from packaging policy is used."), + 'editor-cmd': + "Editor command to use", + 'git-author': + ("Use name and email from git-config for the changelog " + "header, default is '%(git-author)s'"), } ) # vim:et:ts=4:sw=4:et:sts=4:ai:set list listchars=tab\:»·,trail\:·: diff --git a/gbp/rpm/policy.py b/gbp/rpm/policy.py index 62d98f92..216bd53e 100644 --- a/gbp/rpm/policy.py +++ b/gbp/rpm/policy.py @@ -17,7 +17,9 @@ """Default packaging policy for RPM""" import re + from gbp.pkg import PkgPolicy, parse_archive_filename +from gbp.scripts.common.pq import parse_gbp_commands class RpmPkgPolicy(PkgPolicy): """Packaging policy for RPM""" @@ -158,3 +160,113 @@ class RpmPkgPolicy(PkgPolicy): header_format = "* %(time)s %(name)s <%(email)s> %(revision)s" header_time_format = "%a %b %d %Y" header_rev_format = "%(version)s" + + + class ChangelogEntryFormatter(object): + """Helper class for generating changelog entries from git commits""" + + # Maximum length for a changelog entry line + max_entry_line_length = 76 + # Bug tracking system related meta tags recognized from git commit msg + bts_meta_tags = ("Close", "Closes", "Fixes", "Fix") + # Regexp for matching bug tracking system ids (e.g. "bgo#123") + bug_id_re = r'[A-Za-z0-9#_\-]+' + + @classmethod + def _parse_bts_tags(cls, lines, meta_tags): + """ + Parse and filter out bug tracking system related meta tags from + commit message. + + @param lines: commit message + @type lines: C{list} of C{str} + @param meta_tags: meta tags to look for + @type meta_tags: C{tuple} of C{str} + @return: bts-ids per meta tag and the non-mathced lines + @rtype: (C{dict}, C{list} of C{str}) + """ + tags = {} + other_lines = [] + bts_re = re.compile(r'^\s*(?P%s):\s*(?P.*)' % + ('|'.join(meta_tags)), re.I) + bug_id_re = re.compile(cls.bug_id_re) + for line in lines: + match = bts_re.match(line) + if match: + tag = match.group('tag') + ids_str = match.group('ids') + bug_ids = [bug_id.strip() for bug_id in + bug_id_re.findall(ids_str)] + if tag in tags: + tags[tag] += bug_ids + else: + tags[tag] = bug_ids + else: + other_lines.append(line) + return (tags, other_lines) + + @classmethod + def _extra_filter(cls, lines, ignore_re): + """ + Filter out specific lines from the commit message. + + @param lines: commit message + @type lines: C{list} of C{str} + @param ignore_re: regexp for matching ignored lines + @type ignore_re: C{str} + @return: filtered commit message + @rtype: C{list} of C{str} + """ + if ignore_re: + match = re.compile(ignore_re) + return [line for line in lines if not match.match(line)] + else: + return lines + + @classmethod + def compose(cls, commit_info, **kwargs): + """ + Generate a changelog entry from a git commit. + + @param commit_info: info about the commit + @type commit_info: C{commit_info} object from + L{gbp.git.repository.GitRepository.get_commit_info()}. + @param kwargs: additional arguments to the compose() method, + currently we recognize 'full', 'id_len' and 'ignore_re' + @type kwargs: C{dict} + @return: formatted changelog entry + @rtype: C{list} of C{str} + """ + # Parse and filter out gbp command meta-tags + cmds, body = parse_gbp_commands(commit_info, 'gbp-rpm-ch', + ('ignore', 'short', 'full'), ()) + if 'ignore' in cmds: + return None + + # Parse and filter out bts-related meta-tags + bts_tags, body = cls._parse_bts_tags(body, cls.bts_meta_tags) + + # Additional filtering + body = cls._extra_filter(body, kwargs['ignore_re']) + + # Generate changelog entry + subject = commit_info['subject'] + commitid = commit_info['id'] + if kwargs['id_len']: + text = ["- [%s] %s" % (commitid[0:kwargs['id_len']], subject)] + else: + text = ["- %s" % subject] + + # Add all non-filtered-out lines from commit message, unless 'short' + if (kwargs['full'] or 'full' in cmds) and not 'short' in cmds: + # Add all non-blank body lines. + text.extend([" " + line for line in body if line.strip()]) + + # Add bts tags and ids in the end + for tag, ids in bts_tags.iteritems(): + bts_msg = " (%s: %s)" % (tag, ', '.join(ids)) + if len(text[-1]) + len(bts_msg) >= cls.max_entry_line_length: + text.append(" ") + text[-1] += bts_msg + + return text diff --git a/gbp/scripts/rpm_ch.py b/gbp/scripts/rpm_ch.py new file mode 100755 index 00000000..7f66f624 --- /dev/null +++ b/gbp/scripts/rpm_ch.py @@ -0,0 +1,429 @@ +# vim: set fileencoding=utf-8 : +# +# (C) 2007, 2008, 2009, 2010, 2013 Guido Guenther +# (C) 2014 Intel Corporation +# This program is free software; you can redistribute it and/or modify +# it under the terms of the GNU General Public License as published by +# the Free Software Foundation; either version 2 of the License, or +# (at your option) any later version. +# +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with this program; if not, write to the Free Software +# Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA +# +"""Generate RPM changelog entries from git commit messages""" + +import ConfigParser +from datetime import datetime +import os.path +import pwd +import re +import sys +import socket + +import gbp.command_wrappers as gbpc +import gbp.log +from gbp.config import GbpOptionParserRpm, GbpOptionGroup +from gbp.errors import GbpError +from gbp.rpm import guess_spec, NoSpecError, SpecFile +from gbp.rpm.changelog import Changelog, ChangelogParser, ChangelogError +from gbp.rpm.git import GitRepositoryError, RpmGitRepository +from gbp.rpm.policy import RpmPkgPolicy + + +ChangelogEntryFormatter = RpmPkgPolicy.ChangelogEntryFormatter + + +class ChangelogFile(object): + """Container for changelog file, whether it be a standalone changelog + or a spec file""" + + def __init__(self, file_path): + parser = ChangelogParser(RpmPkgPolicy) + + if os.path.splitext(file_path)[1] == '.spec': + gbp.log.debug("Using spec file '%s' as changelog" % file_path) + self._file = SpecFile(file_path) + self.changelog = parser.raw_parse_string(self._file.get_changelog()) + else: + self._file = os.path.abspath(file_path) + if not os.path.exists(file_path): + gbp.log.info("Changelog '%s' not found, creating new " + "changelog file" % file_path) + self.changelog = Changelog(RpmPkgPolicy) + else: + gbp.log.debug("Using changelog file '%s'" % file_path) + self.changelog = parser.raw_parse_file(self._file) + + # Parse topmost section and try to determine the start commit + if self.changelog.sections: + self.changelog.sections[0] = parser.parse_section( + self.changelog.sections[0]) + + def write(self): + """Write changelog file to disk""" + if isinstance(self._file, SpecFile): + self._file.set_changelog(str(self.changelog)) + self._file.write_spec_file() + else: + with open(self._file, 'w') as fobj: + fobj.write(str(self.changelog)) + + @property + def path(self): + """File path""" + if isinstance(self._file, SpecFile): + return self._file.specpath + else: + return self._file + +def load_customizations(customization_file): + """Load user defined customizations file""" + # Load customization file + if not customization_file: + return + customizations = {} + try: + execfile(customization_file, customizations, customizations) + except Exception as err: + raise GbpError("Failed to load customization file: %s" % err) + + # Set customization classes / functions + global ChangelogEntryFormatter + if 'ChangelogEntryFormatter' in customizations: + ChangelogEntryFormatter = customizations.get('ChangelogEntryFormatter') + + +def determine_editor(options): + """Determine text editor""" + + # Check if we need to spawn an editor + states = ['always'] + if options.release: + states.append('release') + if options.spawn_editor not in states: + return None + + # Determine the correct editor + if options.editor_cmd: + return options.editor_cmd + elif 'EDITOR' in os.environ: + return os.environ['EDITOR'] + else: + return 'vi' + + +def check_branch(repo, options): + """Check the current git branch""" + branch = repo.get_branch() + if options.packaging_branch != branch and not options.ignore_branch: + gbp.log.err("You are not on branch '%s' but on '%s'" % + (options.packaging_branch, branch)) + raise GbpError("Use --ignore-branch to ignore or " + "--packaging-branch to set the branch name.") + + +def parse_spec_file(repo, options): + """Find and parse spec file""" + if options.spec_file != 'auto': + spec_path = os.path.join(repo.path, options.spec_file) + spec = SpecFile(spec_path) + else: + spec = guess_spec(os.path.join(repo.path, options.packaging_dir), + True, os.path.basename(repo.path) + '.spec') + options.packaging_dir = spec.specdir + return spec + + +def parse_changelog_file(repo, spec, options): + """Find and parse changelog file""" + changes_file_name = os.path.splitext(spec.specfile)[0] + '.changes' + changes_file_path = os.path.join(options.packaging_dir, changes_file_name) + + # Determine changelog file path + if options.changelog_file == "SPEC": + changelog_path = spec.specpath + elif options.changelog_file == "CHANGES": + changelog_path = changes_file_path + elif options.changelog_file == 'auto': + if os.path.exists(changes_file_path): + changelog_path = changes_file_path + else: + changelog_path = spec.specpath + else: + changelog_path = os.path.join(repo.path, options.changelog_file) + + return ChangelogFile(changelog_path) + + +def guess_commit(section, repo, options): + """Guess the last commit documented in a changelog header""" + + if not section: + return None + header = section.header + + # Try to parse the fields from the header revision + rev_re = '^%s$' % re.sub(r'%\((\S+?)\)s', r'(?P<\1>\S+)', + options.changelog_revision) + match = re.match(rev_re, header['revision'], re.I) + fields = match.groupdict() if match else {} + + # First, try to find tag-name, if present + if 'tagname' in fields: + gbp.log.debug("Trying to find tagname %s" % fields['tagname']) + try: + return repo.rev_parse("%s^0" % fields['tagname']) + except GitRepositoryError: + gbp.log.warn("Changelog points to tagname '%s' which is not found " + "in the git repository" % fields['tagname']) + + # Next, try to find packaging tag matching the version + tag_str_fields = {'vendor': options.vendor} + if 'version' in fields: + gbp.log.debug("Trying to find packaging tag for version '%s'" % + fields['version']) + full_version = fields['version'] + tag_str_fields.update(RpmPkgPolicy.split_full_version(full_version)) + elif 'upstreamversion' in fields: + gbp.log.debug("Trying to find packaging tag for version '%s'" % + fields['upstreamversion']) + tag_str_fields['upstreamversion'] = fields['upstreamversion'] + if 'release' in fields: + tag_str_fields['release'] = fields['release'] + commit = repo.find_version(options.packaging_tag, + tag_str_fields) + if commit: + return commit + else: + gbp.log.info("Couldn't find packaging tag for version %s" % + header['revision']) + + # As a last resort we look at the timestamp + timestamp = header['time'].isoformat() + last = repo.get_commits(num=1, options="--until='%s'" % timestamp) + if last: + gbp.log.info("Using commit (%s) before the last changelog timestamp " + "(%s)" % (last, timestamp)) + return last[0] + return None + + +def get_start_commit(changelog, repo, options): + """Get the start commit from which to generate new entries""" + if options.since: + since = options.since + else: + if changelog.sections: + since = guess_commit(changelog.sections[0], repo, options) + else: + since = None + if not since: + raise GbpError("Couldn't determine starting point from " + "changelog, please use the '--since' option") + gbp.log.info("Continuing from commit '%s'" % since) + return since + + +def get_author(repo, use_git_config): + """Get author and email from git configuration""" + author = email = None + + if use_git_config: + modifier = repo.get_author_info() + author = modifier.name + email = modifier.email + + passwd_data = pwd.getpwuid(os.getuid()) + if not author: + # On some distros (Ubuntu, at least) the gecos field has it's own + # internal structure of comma-separated fields + author = passwd_data.pw_gecos.split(',')[0].strip() + if not author: + author = passwd_data.pw_name + if not email: + if 'EMAIL' in os.environ: + email = os.environ['EMAIL'] + else: + email = "%s@%s" % (passwd_data.pw_name, socket.getfqdn()) + + return author, email + + +def entries_from_commits(changelog, repo, commits, options): + """Generate a list of formatted changelog entries from a list of commits""" + entries = [] + for commit in commits: + info = repo.get_commit_info(commit) + entry_text = ChangelogEntryFormatter.compose(info, full=options.full, + ignore_re=options.ignore_regex, id_len=options.idlen) + if entry_text: + entries.append(changelog.create_entry(author=info['author'].name, + text=entry_text)) + return entries + + +def update_changelog(changelog, entries, repo, spec, options): + """Update the changelog with a range of commits""" + # Get info for section header + now = datetime.now() + name, email = get_author(repo, options.git_author) + rev_str_fields = dict(spec.version, + version=RpmPkgPolicy.compose_full_version(spec.version), + vendor=options.vendor, + tagname=repo.describe('HEAD', longfmt=True, always=True)) + try: + revision = options.changelog_revision % rev_str_fields + except KeyError as err: + raise GbpError("Unable to construct revision field: unknown key " + "%s, only %s are accepted" % (err, rev_str_fields.keys())) + + # Add a new changelog section if new release or an empty changelog + if options.release or not changelog.sections: + top_section = changelog.add_section(time=now, name=name, + email=email, revision=revision) + else: + # Re-use already parsed top section + top_section = changelog.sections[0] + top_section.set_header(time=now, name=name, + email=email, revision=revision) + + # Add new entries to the topmost section + for entry in entries: + top_section.append_entry(entry) + + +def parse_args(argv): + """Parse command line and config file options""" + try: + parser = GbpOptionParserRpm(command=os.path.basename(argv[0]), + prefix='', usage='%prog [options] paths') + except ConfigParser.ParsingError as err: + gbp.log.error('invalid config file: %s' % err) + return None, None + + range_grp = GbpOptionGroup(parser, "commit range options", + "which commits to add to the changelog") + format_grp = GbpOptionGroup(parser, "changelog entry formatting", + "how to format the changelog entries") + naming_grp = GbpOptionGroup(parser, "naming", + "branch names, tag formats, directory and file naming") + parser.add_option_group(range_grp) + parser.add_option_group(format_grp) + parser.add_option_group(naming_grp) + + # Non-grouped options + parser.add_option("-v", "--verbose", action="store_true", dest="verbose", + help="verbose command execution") + parser.add_config_file_option(option_name="color", dest="color", + type='tristate') + parser.add_config_file_option(option_name="color-scheme", + dest="color_scheme") + parser.add_config_file_option(option_name="vendor", action="store", + dest="vendor") + parser.add_config_file_option(option_name="git-log", dest="git_log", + help="options to pass to git-log, default is '%(git-log)s'") + parser.add_boolean_config_file_option(option_name="ignore-branch", + dest="ignore_branch") + parser.add_config_file_option(option_name="customizations", + dest="customization_file", + help="Load Python code from CUSTOMIZATION_FILE. At the " + "moment, the only useful thing the code can do is define a " + "custom ChangelogEntryFormatter class.") + + # Naming group options + naming_grp.add_config_file_option(option_name="packaging-branch", + dest="packaging_branch") + naming_grp.add_config_file_option(option_name="packaging-tag", + dest="packaging_tag") + naming_grp.add_config_file_option(option_name="packaging-dir", + dest="packaging_dir") + naming_grp.add_config_file_option(option_name="changelog-file", + dest="changelog_file") + naming_grp.add_config_file_option(option_name="spec-file", dest="spec_file") + # Range group options + range_grp.add_option("-s", "--since", dest="since", + help="commit to start from (e.g. HEAD^^^, release/0.1.2)") + # Formatting group options + format_grp.add_option("--no-release", action="store_false", default=True, + dest="release", + help="no release, just update the last changelog section") + format_grp.add_boolean_config_file_option(option_name="git-author", + dest="git_author") + format_grp.add_boolean_config_file_option(option_name="full", dest="full") + format_grp.add_config_file_option(option_name="id-length", dest="idlen", + help="include N digits of the commit id in the changelog " + "entry, default is '%(id-length)s'", + type="int", metavar="N") + format_grp.add_config_file_option(option_name="ignore-regex", + dest="ignore_regex", + help="Ignore lines in commit message matching regex, " + "default is '%(ignore-regex)s'") + format_grp.add_config_file_option(option_name="changelog-revision", + dest="changelog_revision") + format_grp.add_config_file_option(option_name="spawn-editor", + dest="spawn_editor") + format_grp.add_config_file_option(option_name="editor-cmd", + dest="editor_cmd") + + options, args = parser.parse_args(argv[1:]) + if not options.changelog_revision: + options.changelog_revision = RpmPkgPolicy.Changelog.header_rev_format + + gbp.log.setup(options.color, options.verbose, options.color_scheme) + + return options, args + +def main(argv): + """Script main function""" + options, args = parse_args(argv) + if not options: + return 1 + + try: + load_customizations(options.customization_file) + editor_cmd = determine_editor(options) + + repo = RpmGitRepository('.') + check_branch(repo, options) + + # Find and parse spec file + spec = parse_spec_file(repo, options) + + # Find and parse changelog file + ch_file = parse_changelog_file(repo, spec, options) + since = get_start_commit(ch_file.changelog, repo, options) + + # Get range of commits from where to generate changes + if args: + gbp.log.info("Only looking for changes in '%s'" % ", ".join(args)) + commits = repo.get_commits(since=since, until='HEAD', paths=args, + options=options.git_log.split(" ")) + commits.reverse() + if not commits: + gbp.log.info("No changes detected from %s to %s." % (since, 'HEAD')) + + # Do the actual update + entries = entries_from_commits(ch_file.changelog, repo, commits, + options) + update_changelog(ch_file.changelog, entries, repo, spec, options) + + # Write to file + ch_file.write() + + if editor_cmd: + gbpc.Command(editor_cmd, [ch_file.path])() + + except (GbpError, GitRepositoryError, ChangelogError, NoSpecError) as err: + if len(err.__str__()): + gbp.log.err(err) + return 1 + return 0 + +if __name__ == "__main__": + sys.exit(main(sys.argv)) diff --git a/setup.py b/setup.py index 9506a5d1..e1159888 100644 --- a/setup.py +++ b/setup.py @@ -59,7 +59,8 @@ setup(name = "gbp", 'bin/git-import-srpm', 'bin/gbp-pq-rpm', 'bin/git-buildpackage-rpm', - 'bin/git-import-orig-rpm'], + 'bin/git-import-orig-rpm', + 'bin/git-rpm-ch'], packages = find_packages(exclude=['tests', 'tests.*']), data_files = [("/etc/git-buildpackage/", ["gbp.conf"]),], setup_requires=['nose>=0.11.1', 'coverage>=2.85'] if \ -- cgit v1.2.3 From df62c9b225fcadc62175391f1c50fe9bae5f1fb7 Mon Sep 17 00:00:00 2001 From: Markus Lehtonen Date: Thu, 6 Feb 2014 11:35:42 +0200 Subject: rpm-ch: make it possible to commit/tag the changes Implement '--tag' command line option (and other related options for signing) for creating and tagging a release. These correspond the tagging options in git-buildpackage-rpm. The git-buildpackage-rpm tool does not commit anything to git. However, in rpm-ch the '--tag' option causes the changelog modifications (and, all other staged changes) to be committed to git before creating the tag. This makes it possible to create a release and document the packaging/release tag name in the rpm changelog. Signed-off-by: Markus Lehtonen --- gbp/scripts/rpm_ch.py | 70 +++++++++++++++++++++++++++++++++++++++++++-------- 1 file changed, 60 insertions(+), 10 deletions(-) diff --git a/gbp/scripts/rpm_ch.py b/gbp/scripts/rpm_ch.py index 7f66f624..6206e884 100755 --- a/gbp/scripts/rpm_ch.py +++ b/gbp/scripts/rpm_ch.py @@ -30,10 +30,13 @@ import gbp.command_wrappers as gbpc import gbp.log from gbp.config import GbpOptionParserRpm, GbpOptionGroup from gbp.errors import GbpError +from gbp.git.modifier import GitModifier from gbp.rpm import guess_spec, NoSpecError, SpecFile from gbp.rpm.changelog import Changelog, ChangelogParser, ChangelogError from gbp.rpm.git import GitRepositoryError, RpmGitRepository from gbp.rpm.policy import RpmPkgPolicy +from gbp.scripts.buildpackage_rpm import packaging_tag_name +from gbp.scripts.buildpackage_rpm import create_packaging_tag ChangelogEntryFormatter = RpmPkgPolicy.ChangelogEntryFormatter @@ -118,14 +121,27 @@ def determine_editor(options): return 'vi' -def check_branch(repo, options): - """Check the current git branch""" +def check_repo_state(repo, options): + """Check that the repository is in good state""" + # Check branch branch = repo.get_branch() if options.packaging_branch != branch and not options.ignore_branch: gbp.log.err("You are not on branch '%s' but on '%s'" % (options.packaging_branch, branch)) raise GbpError("Use --ignore-branch to ignore or " "--packaging-branch to set the branch name.") + # Check unstaged changes + if options.tag: + unstaged = [] + status = repo.status() + for group, files in status.iteritems(): + if group != '??' and group[1] != ' ': + unstaged.extend(files) + if unstaged: + gbp.log.error("Unstaged changes in:\n %s" % + '\n '.join(unstaged)) + raise GbpError("Please commit or stage your changes before using " + "the --tag option") def parse_spec_file(repo, options): @@ -275,8 +291,17 @@ def update_changelog(changelog, entries, repo, spec, options): name, email = get_author(repo, options.git_author) rev_str_fields = dict(spec.version, version=RpmPkgPolicy.compose_full_version(spec.version), - vendor=options.vendor, - tagname=repo.describe('HEAD', longfmt=True, always=True)) + vendor=options.vendor) + if options.tag: + # Get fake information for the to-be-created git commit + commit_info = {'author': GitModifier(date=now), + 'committer': GitModifier(date=now)} + tag = packaging_tag_name(repo, spec, commit_info, options) + else: + commit_info = {'author': None, 'committer': None} + tag = repo.describe('HEAD', longfmt=True, always=True) + rev_str_fields['tagname'] = tag + try: revision = options.changelog_revision % rev_str_fields except KeyError as err: @@ -296,6 +321,13 @@ def update_changelog(changelog, entries, repo, spec, options): # Add new entries to the topmost section for entry in entries: top_section.append_entry(entry) + return (tag, commit_info['author'], commit_info['committer']) + +def commit_changelog(repo, changelog, author, committer, edit): + """Commit changelog and create a packaging/release tag""" + repo.add_files(changelog.path) + repo.commit_staged("Update changelog", author_info=author, + committer_info=committer, edit=edit) def parse_args(argv): @@ -313,9 +345,12 @@ def parse_args(argv): "how to format the changelog entries") naming_grp = GbpOptionGroup(parser, "naming", "branch names, tag formats, directory and file naming") + commit_grp = GbpOptionGroup(parser, "commit", + "automatic committing and tagging") parser.add_option_group(range_grp) parser.add_option_group(format_grp) parser.add_option_group(naming_grp) + parser.add_option_group(commit_grp) # Non-grouped options parser.add_option("-v", "--verbose", action="store_true", dest="verbose", @@ -333,9 +368,8 @@ def parse_args(argv): parser.add_config_file_option(option_name="customizations", dest="customization_file", help="Load Python code from CUSTOMIZATION_FILE. At the " - "moment, the only useful thing the code can do is define a " - "custom ChangelogEntryFormatter class.") - + "moment, the only useful thing the code can do is " + "define a custom ChangelogEntryFormatter class.") # Naming group options naming_grp.add_config_file_option(option_name="packaging-branch", dest="packaging_branch") @@ -370,6 +404,15 @@ def parse_args(argv): dest="spawn_editor") format_grp.add_config_file_option(option_name="editor-cmd", dest="editor_cmd") + # Commit/tag group options + commit_grp.add_option("--tag", action="store_true", + help="commit the changes and create a packaging/release" + "tag") + commit_grp.add_option("--retag", action="store_true", + help="Overwrite packaging tag if it already exists") + commit_grp.add_boolean_config_file_option(option_name="sign-tags", + dest="sign_tags") + commit_grp.add_config_file_option(option_name="keyid", dest="keyid") options, args = parser.parse_args(argv[1:]) if not options.changelog_revision: @@ -390,7 +433,7 @@ def main(argv): editor_cmd = determine_editor(options) repo = RpmGitRepository('.') - check_branch(repo, options) + check_repo_state(repo, options) # Find and parse spec file spec = parse_spec_file(repo, options) @@ -411,14 +454,21 @@ def main(argv): # Do the actual update entries = entries_from_commits(ch_file.changelog, repo, commits, options) - update_changelog(ch_file.changelog, entries, repo, spec, options) - + tag, author, committer = update_changelog(ch_file.changelog, entries, + repo, spec, options) # Write to file ch_file.write() if editor_cmd: gbpc.Command(editor_cmd, [ch_file.path])() + if options.tag: + if options.retag and repo.has_tag(tag): + repo.delete_tag(tag) + edit = True if editor_cmd else False + commit_changelog(repo, ch_file, author, committer, edit) + create_packaging_tag(repo, tag, 'HEAD', spec.version, options) + except (GbpError, GitRepositoryError, ChangelogError, NoSpecError) as err: if len(err.__str__()): gbp.log.err(err) -- cgit v1.2.3 From 95a55db9dc5fb4392c81f71a10c82944b98b9c0a Mon Sep 17 00:00:00 2001 From: Markus Lehtonen Date: Wed, 26 Mar 2014 09:01:28 +0200 Subject: rpm-ch: add --message cmdline option For giving the text for new changelog entry/entries, skipping git commit messages entirely. Signed-off-by: Markus Lehtonen --- gbp/scripts/rpm_ch.py | 49 +++++++++++++++++++++++++++++++++++++------------ 1 file changed, 37 insertions(+), 12 deletions(-) diff --git a/gbp/scripts/rpm_ch.py b/gbp/scripts/rpm_ch.py index 6206e884..14683f37 100755 --- a/gbp/scripts/rpm_ch.py +++ b/gbp/scripts/rpm_ch.py @@ -284,6 +284,37 @@ def entries_from_commits(changelog, repo, commits, options): return entries +def entries_from_text(changelog, text, author): + """Generate a list of changelog entries from a string""" + entries = [] + # Use current user as the author for all entries + for line in text.splitlines(): + if line.strip(): + entry_text = "- %s" % line.strip() + entries.append(changelog.create_entry(author=author, + text=entry_text)) + return entries + + +def generate_new_entries(changelog, repo, options, args): + """Generate new entries to be appended to changelog""" + if options.message: + author = get_author(repo, options.git_author)[0] + entries = entries_from_text(changelog, options.message, author) + else: + # Get range of commits from where to generate changes + since = get_start_commit(changelog, repo, options) + if args: + gbp.log.info("Only looking for changes in '%s'" % ", ".join(args)) + commits = repo.get_commits(since=since, until='HEAD', paths=args, + options=options.git_log.split(" ")) + commits.reverse() + if not commits: + gbp.log.info("No changes detected from %s to %s." % (since, 'HEAD')) + entries = entries_from_commits(changelog, repo, commits, options) + return entries + + def update_changelog(changelog, entries, repo, spec, options): """Update the changelog with a range of commits""" # Get info for section header @@ -404,6 +435,9 @@ def parse_args(argv): dest="spawn_editor") format_grp.add_config_file_option(option_name="editor-cmd", dest="editor_cmd") + format_grp.add_option("-m", '--message', + help="text to use as new changelog entries - git commit " + "messages and the --since are ignored in this case") # Commit/tag group options commit_grp.add_option("--tag", action="store_true", help="commit the changes and create a packaging/release" @@ -440,26 +474,17 @@ def main(argv): # Find and parse changelog file ch_file = parse_changelog_file(repo, spec, options) - since = get_start_commit(ch_file.changelog, repo, options) - # Get range of commits from where to generate changes - if args: - gbp.log.info("Only looking for changes in '%s'" % ", ".join(args)) - commits = repo.get_commits(since=since, until='HEAD', paths=args, - options=options.git_log.split(" ")) - commits.reverse() - if not commits: - gbp.log.info("No changes detected from %s to %s." % (since, 'HEAD')) + # Get new entries + entries = generate_new_entries(ch_file.changelog, repo, options, args) # Do the actual update - entries = entries_from_commits(ch_file.changelog, repo, commits, - options) tag, author, committer = update_changelog(ch_file.changelog, entries, repo, spec, options) # Write to file ch_file.write() - if editor_cmd: + if editor_cmd and not options.message: gbpc.Command(editor_cmd, [ch_file.path])() if options.tag: -- cgit v1.2.3 From 33b4aa7fa455225f0057d636645a9e6b2774b9c6 Mon Sep 17 00:00:00 2001 From: Markus Lehtonen Date: Fri, 16 May 2014 14:26:49 +0300 Subject: rpm-ch: implement '--all' option If defined, git-rpm-ch uses all commits in the Git history. Also, '--since' option is omitted. Signed-off-by: Markus Lehtonen --- gbp/scripts/rpm_ch.py | 9 +++++++-- 1 file changed, 7 insertions(+), 2 deletions(-) diff --git a/gbp/scripts/rpm_ch.py b/gbp/scripts/rpm_ch.py index 14683f37..09586d00 100755 --- a/gbp/scripts/rpm_ch.py +++ b/gbp/scripts/rpm_ch.py @@ -232,7 +232,9 @@ def guess_commit(section, repo, options): def get_start_commit(changelog, repo, options): """Get the start commit from which to generate new entries""" - if options.since: + if options.all: + since = None + elif options.since: since = options.since else: if changelog.sections: @@ -241,7 +243,7 @@ def get_start_commit(changelog, repo, options): since = None if not since: raise GbpError("Couldn't determine starting point from " - "changelog, please use the '--since' option") + "changelog, please use the '--since' or '--all'") gbp.log.info("Continuing from commit '%s'" % since) return since @@ -414,6 +416,9 @@ def parse_args(argv): # Range group options range_grp.add_option("-s", "--since", dest="since", help="commit to start from (e.g. HEAD^^^, release/0.1.2)") + range_grp.add_option("--all", action="store_true", + help="use all commits from the Git history, overrides " + "--since") # Formatting group options format_grp.add_option("--no-release", action="store_false", default=True, dest="release", -- cgit v1.2.3 From 6ea6a78b90e15c1261ec357ca296ae0d58b342e7 Mon Sep 17 00:00:00 2001 From: Markus Lehtonen Date: Tue, 25 Feb 2014 12:20:24 +0200 Subject: rpm-ch: add unit tests for the command line tool Signed-off-by: Markus Lehtonen --- tests/component/rpm/data | 2 +- tests/component/rpm/test_rpm_ch.py | 401 +++++++++++++++++++++++++++++++++++++ 2 files changed, 402 insertions(+), 1 deletion(-) create mode 100644 tests/component/rpm/test_rpm_ch.py diff --git a/tests/component/rpm/data b/tests/component/rpm/data index b505e801..e59a3efb 160000 --- a/tests/component/rpm/data +++ b/tests/component/rpm/data @@ -1 +1 @@ -Subproject commit b505e8016f5a5003fdfa12619600df91e1a8ae97 +Subproject commit e59a3efb43993c24c5d7c2e2f354806ec419ed90 diff --git a/tests/component/rpm/test_rpm_ch.py b/tests/component/rpm/test_rpm_ch.py new file mode 100644 index 00000000..968cfd4a --- /dev/null +++ b/tests/component/rpm/test_rpm_ch.py @@ -0,0 +1,401 @@ +# vim: set fileencoding=utf-8 : +# +# (C) 2013 Intel Corporation +# This program is free software; you can redistribute it and/or modify +# it under the terms of the GNU General Public License as published by +# the Free Software Foundation; either version 2 of the License, or +# (at your option) any later version. +# +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with this program; if not, write to the Free Software +# Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA +"""Tests for the git-rpm-ch tool""" + +import os +import re +from nose.tools import assert_raises, eq_, ok_ # pylint: disable=E0611 + +from gbp.scripts.rpm_ch import main as rpm_ch +from gbp.git import GitRepository + +from tests.component.rpm import RpmRepoTestBase + +# Disable "Method could be a function warning" +# pylint: disable=R0201 + + +def mock_ch(args): + """Wrapper for git-rpm-ch""" + + return rpm_ch(['arg0', '--packaging-branch=master', + '--spawn-editor=never'] + args) + +class TestRpmCh(RpmRepoTestBase): + """Basic tests for git-rpm-ch""" + + def setup(self): + """Test case setup""" + super(TestRpmCh, self).setup() + # Set environment so that commits succeed without git config + os.environ['GIT_AUTHOR_NAME'] = 'My Name' + os.environ['GIT_COMMITTER_NAME'] = 'My Name' + os.environ['EMAIL'] = 'me@example.com' + + @staticmethod + def read_file(filename): + """Read file to a list""" + with open(filename) as fobj: + return fobj.readlines() + + def test_invalid_args(self): + """See that git-rpm-ch fails gracefully when called with invalid args""" + GitRepository.create('.') + + with assert_raises(SystemExit): + mock_ch(['--invalid-opt']) + + def test_import_outside_repo(self): + """Run git-rpm-ch when not in a git repository""" + eq_(mock_ch([]), 1) + self._check_log(0, 'gbp:error: No Git repository at ') + + def test_invalid_config_file(self): + """Test invalid config file""" + # Create dummy invalid config file and run git-rpm-ch + GitRepository.create('.') + with open('.gbp.conf', 'w') as conffd: + conffd.write('foobar\n') + eq_(mock_ch([]), 1) + self._check_log(0, 'gbp:error: invalid config file: File contains no ' + 'section headers.') + + def test_update_spec_changelog(self): + """Test updating changelog in spec""" + repo = self.init_test_repo('gbp-test') + eq_(mock_ch([]), 0) + eq_(repo.status(), {' M': ['gbp-test.spec']}) + + def test_update_changes_file(self): + """Test updating a separate changes file""" + repo = self.init_test_repo('gbp-test-native') + eq_(mock_ch([]), 0) + eq_(repo.status(), {' M': ['packaging/gbp-test-native.changes']}) + + def test_create_spec_changelog(self): + """Test creating changelog in spec file""" + repo = self.init_test_repo('gbp-test2') + orig_content = self.read_file('packaging/gbp-test2.spec') + + # Fails if no starting point is given + eq_(mock_ch([]), 1) + self._check_log(-1, "gbp:error: Couldn't determine starting point") + + # Give starting point + eq_(mock_ch(['--since=HEAD^']), 0) + eq_(repo.status(), {' M': ['packaging/gbp-test2.spec']}) + content = self.read_file('packaging/gbp-test2.spec') + # Should contain 4 lines (%changelog, header, 1 entry and an empty line) + eq_(len(content), len(orig_content) + 4) + + def test_create_changes_file(self): + """Test creating a separate changes file""" + repo = self.init_test_repo('gbp-test2') + + # Fails if no starting point is given + eq_(mock_ch(['--changelog-file=CHANGES']), 1) + self._check_log(-1, "gbp:error: Couldn't determine starting point") + + # Give starting point + eq_(mock_ch(['--since=HEAD^', '--changelog-file=CHANGES']), 0) + eq_(repo.status(), {'??': ['packaging/gbp-test2.changes']}) + content = self.read_file('packaging/gbp-test2.changes') + # Should contain 3 lines (header, 1 entry and an empty line) + eq_(len(content), 3) + + def test_option_all(self): + """Test the --all cmdline option""" + repo = self.init_test_repo('gbp-test2') + + eq_(mock_ch(['--changelog-file=CHANGES', '--all']), 0) + content = self.read_file('packaging/gbp-test2.changes') + # Should contain N+2 lines (header, N commits and an empty line) + commit_cnt = len(repo.get_commits(since=None, until='master')) + eq_(len(content), commit_cnt + 2) + + def test_option_changelog_file(self): + """Test the --changelog-file cmdline option""" + repo = self.init_test_repo('gbp-test-native') + + # Guess changelog file + eq_(mock_ch(['--changelog-file=CHANGES']), 0) + eq_(repo.status(), {' M': ['packaging/gbp-test-native.changes']}) + + # Use spec file as changelog + eq_(mock_ch(['--changelog-file=SPEC', '--since=HEAD^']), 0) + eq_(repo.status(), {' M': ['packaging/gbp-test-native.changes', + 'packaging/gbp-test-native.spec']}) + + # Arbitrary name + eq_(mock_ch(['--changelog-file=foo.changes', '--since=HEAD^']), 0) + eq_(repo.status(), {' M': ['packaging/gbp-test-native.changes', + 'packaging/gbp-test-native.spec'], + '??': ['foo.changes']}) + + def test_option_spec_file(self): + """Test the --spec-file cmdline option""" + repo = self.init_test_repo('gbp-test2') + + eq_(mock_ch(['--spec-file=foo.spec']), 1) + self._check_log(-1, "gbp:error: Unable to read spec file") + + eq_(mock_ch(['--spec-file=auto']), 1) + self._check_log(-1, "gbp:error: Multiple spec files found") + + eq_(mock_ch(['--spec-file=packaging/gbp-test2.spec', '--since=HEAD^']), + 0) + eq_(repo.status(), {' M': ['packaging/gbp-test2.spec']}) + + def test_option_packaging_dir(self): + """Test the --packaging-dir cmdline option""" + repo = self.init_test_repo('gbp-test-native') + + eq_(mock_ch(['--packaging-dir=foo']), 1) + self._check_log(-1, "gbp:error: No spec file found") + + # Packaging dir should be taken from spec file if it is defined + eq_(mock_ch(['--packaging-dir', 'foo', '--spec-file', + 'packaging/gbp-test-native.spec']), 0) + eq_(repo.status(), {' M': ['packaging/gbp-test-native.changes']}) + + def test_branch_options(self): + """Test the --packaging-branch and --ignore-branch cmdline options""" + self.init_test_repo('gbp-test-native') + + eq_(mock_ch(['--packaging-branch=foo']), 1) + self._check_log(-2, "gbp:error: You are not on branch 'foo'") + + eq_(mock_ch(['--packaging-branch=foo', '--ignore-branch']), 0) + + def test_option_no_release(self): + """Test the --no-release cmdline option""" + self.init_test_repo('gbp-test-native') + orig_content = self.read_file('packaging/gbp-test-native.changes') + + eq_(mock_ch(['--no-release']), 0) + content = self.read_file('packaging/gbp-test-native.changes') + # Only one line (entry) added + eq_(len(content), len(orig_content) + 1) + + def test_author(self): + """Test determining the author name/email""" + repo = self.init_test_repo('gbp-test-native') + + # Test taking email address from env + os.environ['EMAIL'] = 'user@host.com' + eq_(mock_ch([]), 0) + header = self.read_file('packaging/gbp-test-native.changes')[0] + ok_(re.match(r'.+ .+', header)) + + # Missing git config setting should not cause a failure + del os.environ['EMAIL'] + del os.environ['GIT_AUTHOR_NAME'] + os.environ['GIT_CONFIG_NOSYSTEM'] = '1' + os.environ['HOME'] = os.path.abspath('.') + eq_(mock_ch(['--git-author', '--since=HEAD^1']), 0) + + # Test the --git-author option + with open(os.path.join(repo.git_dir, 'config'), 'a') as fobj: + fobj.write('[user]\n name=John Doe\n email=jd@host.com\n') + eq_(mock_ch(['--git-author', '--since=HEAD^']), 0) + header = self.read_file('packaging/gbp-test-native.changes')[0] + ok_(re.match(r'.+ John Doe .+', header), header) + + def test_option_full(self): + """Test the --full cmdline option""" + repo = self.init_test_repo('gbp-test-native') + orig_content = self.read_file('packaging/gbp-test-native.changes') + + eq_(mock_ch(['--full', '--since=HEAD^']), 0) + commit_msg_body = repo.get_commit_info('HEAD')['body'] + full_msg = [line for line in commit_msg_body.splitlines() if line] + content = self.read_file('packaging/gbp-test-native.changes') + # New lines: header, 1 entry "header", entry "body" from commit message + # and one empty line + eq_(len(content), len(orig_content) + 3 + len(full_msg)) + + def test_option_ignore_regex(self): + """Test the --ignore-regex cmdline option""" + repo = self.init_test_repo('gbp-test-native') + orig_content = self.read_file('packaging/gbp-test-native.changes') + + eq_(mock_ch(['--full', '--since', 'HEAD^', '--ignore-regex', + 'Signed-off-by:.*']), 0) + commit_msg_body = repo.get_commit_info('HEAD')['body'] + full_msg = [line for line in commit_msg_body.splitlines() if + (line and not line.startswith('Signed-off-by:'))] + content = self.read_file('packaging/gbp-test-native.changes') + # New lines: header, 1 entry "header", filtered entry "body" from + # commit message and one empty line + eq_(len(content), len(orig_content) + 3 + len(full_msg)) + + def test_option_id_len(self): + """Test the --id-len cmdline option""" + repo = self.init_test_repo('gbp-test-native') + + eq_(mock_ch(['--id-len=10']), 0) + commit_id = repo.rev_parse('HEAD', 10) + content = self.read_file('packaging/gbp-test-native.changes') + ok_(content[1].startswith('- [%s] ' % commit_id)) + + def test_option_changelog_revision(self): + """Test the --id-len cmdline option""" + self.init_test_repo('gbp-test-native') + + # Test invalid format (unknown field) + eq_(mock_ch(['--changelog-revision=%(unknown_field)s']), 1) + self._check_log(-1, 'gbp:error: Unable to construct revision field') + + # Test acceptable format + eq_(mock_ch(['--changelog-revision=foobar']), 0) + header = self.read_file('packaging/gbp-test-native.changes')[0] + ok_(re.match(r'.+ foobar$', header)) + + def test_tagging(self): + """Test commiting/tagging""" + repo = self.init_test_repo('gbp-test-native') + + # Update and commit+tag + eq_(mock_ch(['--tag', '--packaging-tag=new-tag', '--since=HEAD^']), 0) + ok_(repo.has_tag('new-tag')) + sha = repo.rev_parse('HEAD') + eq_(sha, repo.rev_parse('new-tag^0')) + + # Should fail if the tag already exists + eq_(mock_ch(['--tag', '--packaging-tag=new-tag', '--since=HEAD^']), 1) + + # Update and commit+tag + eq_(mock_ch(['--tag', '--packaging-tag=new-tag', '--since=HEAD^', + '--retag']), 0) + ok_(repo.has_tag('new-tag')) + sha2 = repo.rev_parse('HEAD') + ok_(sha2 != sha) + eq_(sha2, repo.rev_parse('new-tag^0')) + + def test_tagging2(self): + """Test commiting/tagging spec file""" + repo = self.init_test_repo('gbp-test2') + + # Check unclean repo + with open('untracked-file', 'w') as fobj: + fobj.write('this file is not tracked\n') + with open('README', 'a') as fobj: + fobj.write('some new content\n') + + # Unstaged file (README) -> failure + eq_(mock_ch(['--tag', '--packaging-tag=new-tag', '--since=HEAD^']), 1) + self._check_log(-1, 'gbp:error: Please commit or stage your changes') + + # Add file, update and commit+tag, untracked file should be ignored + repo.add_files('README') + eq_(mock_ch(['--tag', '--packaging-tag=new-tag', '--since=HEAD^']), 0) + ok_(repo.has_tag('new-tag')) + sha = repo.rev_parse('HEAD') + eq_(sha, repo.rev_parse('new-tag^0')) + + def test_option_editor_cmd(self): + """Test the --editor-cmd and --spawn-editor cmdline options""" + repo = self.init_test_repo('gbp-test-native') + eq_(mock_ch(['--spawn-editor=release', '--editor-cmd=rm']), 0) + eq_(repo.status(), {' D': ['packaging/gbp-test-native.changes']}) + + repo.force_head('HEAD', hard=True) + ok_(repo.is_clean()) + + os.environ['EDITOR'] = 'rm' + eq_(mock_ch(['--spawn-editor=always', '--editor-cmd=']), + 0) + + def test_option_message(self): + """Test the --message cmdline option""" + self.init_test_repo('gbp-test-native') + orig_content = self.read_file('packaging/gbp-test-native.changes') + + eq_(mock_ch(['--message', 'my entry\nanother entry']), 0) + content = self.read_file('packaging/gbp-test-native.changes') + # Added header, two entries and a blank line + eq_(len(content), len(orig_content) + 4) + eq_(content[2], '- another entry\n') + + def test_user_customizations(self): + """Test the user customizations""" + repo = self.init_test_repo('gbp-test-native') + + # Non-existent customization file + eq_(mock_ch(['--customizations=customizations.py']), 1) + + # Create user customizations file + with open('customizations.py', 'w') as fobj: + fobj.write("class ChangelogEntryFormatter(object):\n") + fobj.write(" @classmethod\n") + fobj.write(" def compose(cls, commit_info, **kwargs):\n") + fobj.write(" return ['- %s' % commit_info['id']]\n") + + eq_(mock_ch(['--customizations=customizations.py']), 0) + entry = self.read_file('packaging/gbp-test-native.changes')[1] + sha = repo.rev_parse('HEAD') + eq_(entry, '- %s\n' % sha) + + def test_paths(self): + """Test tracking of certain paths only""" + repo = self.init_test_repo('gbp-test-native') + orig_content = self.read_file('packaging/gbp-test-native.changes') + + # Add new commit with known content + with open('new-file.txt', 'w') as fobj: + fobj.write('this is new content\n') + repo.add_files('new-file.txt') + repo.commit_staged('Add new file') + + # Only track a non-existent file + eq_(mock_ch(['--since=HEAD^', 'non-existent-path']), 0) + content = self.read_file('packaging/gbp-test-native.changes') + # New lines: header and one empty line, no entries + eq_(len(content), len(orig_content) + 2) + + # Track existing file + repo.force_head('HEAD', hard=True) + eq_(mock_ch(['--since=HEAD^', 'new-file.txt']), 0) + content = self.read_file('packaging/gbp-test-native.changes') + # New lines: header, one entry line and one empty line + eq_(len(content), len(orig_content) + 3) + + def test_commit_guessing(self): + """Basic tests for guessing the starting point""" + repo = self.init_test_repo('gbp-test-native') + + # Check 'tagname' that is not found + eq_(mock_ch(['--changelog-revision=%(tagname)s']), 0) + self._check_log(0, 'gbp:warning: Changelog points to tagname') + + # Check 'upstreamversion' and 'release' fields + repo.force_head('HEAD', hard=True) + eq_(mock_ch(['--changelog-revision=%(upstreamversion)s-%(release)s']), + 0) + + def test_commit_guessing_fail(self): + """Test for failure of start commit guessing""" + repo = self.init_test_repo('gbp-test-native') + + # Add "very old" header to changelog + with open('packaging/gbp-test-native.changes', 'w') as ch_fp: + ch_fp.write('* Sat Jan 01 2000 User 123\n- foo\n') + # rpm-ch should fail by not being able to find any commits before the + # last changelog section + eq_(mock_ch([]), 1) + self._check_log(-1, "gbp:error: Couldn't determine starting point") + -- cgit v1.2.3 From 6c25ea094e734950a7b17d39cae70cc1999a1371 Mon Sep 17 00:00:00 2001 From: Markus Lehtonen Date: Wed, 12 Feb 2014 15:11:30 +0200 Subject: import-orig-rpm: implement --create-missing-branches option Create the upstream branch if it does not exist. Use the same option name that import-srpm has. Signed-off-by: Markus Lehtonen --- gbp/scripts/import_orig_rpm.py | 23 +++++++++++++++-------- tests/component/rpm/test_import_orig_rpm.py | 29 +++++++++++++++++++++++++---- 2 files changed, 40 insertions(+), 12 deletions(-) diff --git a/gbp/scripts/import_orig_rpm.py b/gbp/scripts/import_orig_rpm.py index 8eacfb2b..a8f874c6 100755 --- a/gbp/scripts/import_orig_rpm.py +++ b/gbp/scripts/import_orig_rpm.py @@ -159,6 +159,9 @@ def parse_args(argv): help="Upstream VCS tag add to the merge commit") branch_group.add_boolean_config_file_option(option_name="merge", dest="merge") branch_group.add_config_file_option(option_name="packaging-dir", dest="packaging_dir") + branch_group.add_boolean_config_file_option( + option_name="create-missing-branches", + dest="create_missing_branches") tag_group.add_boolean_config_file_option(option_name="sign-tags", dest="sign_tags") @@ -214,9 +217,14 @@ def main(argv): initial_branch = repo.get_branch() is_empty = False if initial_branch else True - if not repo.has_branch(options.upstream_branch) and not is_empty: - gbp.log.err(no_upstream_branch_msg % options.upstream_branch) - raise GbpError + if not repo.has_branch(options.upstream_branch): + if options.create_missing_branches: + gbp.log.info("Will create missing branch '%s'" % + options.upstream_branch) + elif is_empty: + options.create_missing_branches = True + else: + raise GbpError(no_upstream_branch_msg % options.upstream_branch) (sourcepackage, version) = detect_name_and_version(repo, source, options) @@ -262,11 +270,10 @@ def main(argv): parents = None commit = repo.commit_dir(unpacked_orig, - msg=msg, - branch=options.upstream_branch, - other_parents=parents, - create_missing_branch=True, - ) + msg=msg, + branch=options.upstream_branch, + other_parents=parents, + create_missing_branch=options.create_missing_branches) if options.pristine_tar and pristine_orig: gbp.log.info("Pristine-tar: commiting %s" % pristine_orig) repo.pristine_tar.commit(pristine_orig, options.upstream_branch) diff --git a/tests/component/rpm/test_import_orig_rpm.py b/tests/component/rpm/test_import_orig_rpm.py index e2de8b64..d26f5ebc 100644 --- a/tests/component/rpm/test_import_orig_rpm.py +++ b/tests/component/rpm/test_import_orig_rpm.py @@ -102,6 +102,15 @@ class ImportOrigTestBase(ComponentTestBase): class TestImportOrig(ImportOrigTestBase): """Basic tests for git-import-orig-rpm""" + @staticmethod + def _init_repo_with_dummy_packaging(): + """Create a dummy packaging branch with one commit""" + repo = GitRepository.create('.') + shutil.copy2('.git/HEAD', 'foobar') + repo.add_files('.') + repo.commit_all('First commit') + return repo + def test_invalid_args(self): """ See that import-orig-rpm fails gracefully when called with invalid args @@ -188,10 +197,7 @@ class TestImportOrig(ImportOrigTestBase): def test_import_to_existing(self): """Test importing of to an existing repo""" # Create new repo and add dummy files - repo = GitRepository.create('.') - shutil.copy2('.git/HEAD', 'foobar') - repo.add_files('.') - repo.commit_all('First commit') + repo = self._init_repo_with_dummy_packaging() sha1 = repo.rev_parse('HEAD^0') # Test missing upstream branch @@ -301,6 +307,21 @@ class TestImportOrig(ImportOrigTestBase): eq_(mock_import(['--no-interactive', orig_renamed], stdin_data=''), 1) self._check_log(-1, "gbp:error: Couldn't determine upstream version") + def test_option_create_missing(self): + """Test importing of to an existing repo""" + # Create new repo and add dummy files + repo = self._init_repo_with_dummy_packaging() + + # Test missing upstream branch + orig = os.path.join(DATA_DIR, 'gbp-test2-2.0.tar.gz') + eq_(mock_import([orig]), 1) + self._check_log(1, 'Repository does not have branch') + + # Try again, with --create-missing-branches + eq_(mock_import(['--create-missing-branches', orig]), 0) + self._check_repo_state(repo, 'master', ['master', 'upstream']) + eq_(len(repo.get_commits(until='upstream')), 1) + def test_misc_options(self): """Test various options of git-import-orig-rpm""" repo = GitRepository.create('.') -- cgit v1.2.3 From 8d24e7b7541816b8384b2ba0d8e33e36aed4d5b1 Mon Sep 17 00:00:00 2001 From: Markus Lehtonen Date: Thu, 13 Feb 2014 12:41:39 +0200 Subject: import-orig-rpm: implement automatic downloading Automatically try to download the archive if the archive filename points to a remote location. Signed-off-by: Markus Lehtonen --- gbp/scripts/import_orig_rpm.py | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/gbp/scripts/import_orig_rpm.py b/gbp/scripts/import_orig_rpm.py index a8f874c6..8a6df9e4 100755 --- a/gbp/scripts/import_orig_rpm.py +++ b/gbp/scripts/import_orig_rpm.py @@ -23,6 +23,7 @@ import os import sys import gbp.tmpfile as tempfile import gbp.command_wrappers as gbpc +import re import string from gbp.pkg import parse_archive_filename from gbp.rpm import (RpmUpstreamSource, SpecFile, NoSpecError, guess_spec, @@ -35,6 +36,7 @@ import gbp.log from gbp.scripts.common.import_orig import (cleanup_tmp_tree, ask_package_name, ask_package_version, prepare_sources) +from gbp.scripts.import_srpm import download_file def upstream_import_commit_msg(options, version): @@ -99,7 +101,10 @@ def find_source(options, args): elif len(args) == 0: raise GbpError, "No archive to import specified. Try --help." else: - return RpmUpstreamSource(args[0]) + path = args[0] + if re.match(r'[a-z]{1,5}://', path): + path = download_file('.', path) + return RpmUpstreamSource(path) def pristine_tarball_name(source, pkg_name, pkg_version, pristine_name): -- cgit v1.2.3 From 57bcf840587e524527374ee1f8863fe539c21a39 Mon Sep 17 00:00:00 2001 From: Markus Lehtonen Date: Thu, 13 Feb 2014 12:41:39 +0200 Subject: import-orig-rpm: get archive from spec file Try to get archive path/filename from spec file if no file name is given on the command line. This should make version bumps more straightforward: just update version number in the spec file and run 'git-import-orig-rpm'. Signed-off-by: Markus Lehtonen --- gbp/scripts/import_orig_rpm.py | 66 ++++++++++++++++++----------- tests/component/rpm/test_import_orig_rpm.py | 47 ++++++++++++++++++-- 2 files changed, 84 insertions(+), 29 deletions(-) diff --git a/gbp/scripts/import_orig_rpm.py b/gbp/scripts/import_orig_rpm.py index 8a6df9e4..1d3972a4 100755 --- a/gbp/scripts/import_orig_rpm.py +++ b/gbp/scripts/import_orig_rpm.py @@ -42,36 +42,41 @@ from gbp.scripts.import_srpm import download_file def upstream_import_commit_msg(options, version): return options.import_msg % dict(version=version) - -def detect_name_and_version(repo, source, options): - # Guess defaults for the package name and version from the - # original tarball. - (guessed_package, guessed_version) = source.guess_version() or ('', '') - - # Try to find the source package name +def find_spec(repo, options): + """Find spec in the working tree or repository""" try: preferred_fn = os.path.basename(repo.path) + '.spec' spec = guess_spec(os.path.join(repo.path, options.packaging_dir), True, preferred_fn) - sourcepackage = spec.name except NoSpecError: try: - # Check the spec file from the repository, in case - # we're not on the packaging-branch (but upstream, for - # example). + # Check the spec file from the repository, in case we're not on the + # packaging-branch (but upstream, for example). spec = guess_spec_repo(repo, options.packaging_branch, options.packaging_dir, True, preferred_fn) - sourcepackage = spec.name except NoSpecError: - if options.interactive: - sourcepackage = ask_package_name(guessed_package, - RpmPkgPolicy.is_valid_packagename, - RpmPkgPolicy.packagename_msg) + spec = None + return spec + +def detect_name_and_version(repo, source, spec, options): + """Determine name and version of the upstream project""" + # Guess defaults for the package name and version from the + # original tarball. + (guessed_package, guessed_version) = source.guess_version() or ('', '') + + # Try to find the source package name + if spec: + sourcepackage = spec.name + else: + if options.interactive: + sourcepackage = ask_package_name(guessed_package, + RpmPkgPolicy.is_valid_packagename, + RpmPkgPolicy.packagename_msg) + else: + if guessed_package: + sourcepackage = guessed_package else: - if guessed_package: - sourcepackage = guessed_package - else: - raise GbpError, "Couldn't determine upstream package name. Use --interactive." + raise GbpError, "Couldn't determine upstream package name. Use --interactive." # Try to find the version. if options.version: @@ -90,16 +95,24 @@ def detect_name_and_version(repo, source, options): return (sourcepackage, version) -def find_source(options, args): +def find_source(spec, options, args): """Find the tarball to import @return: upstream source filename or None if nothing to import @rtype: string @raise GbpError: raised on all detected errors """ if len(args) > 1: # source specified - raise GbpError, "More than one archive specified. Try --help." + raise GbpError("More than one archive specified. Try --help.") elif len(args) == 0: - raise GbpError, "No archive to import specified. Try --help." + if spec and spec.orig_src: + path = spec.orig_src['uri'] + gbp.log.info("Archive file path from spec is used ('%s')" % path) + elif spec: + raise GbpError("No archive to import specified and unable to " + "determine source from spec. Try --help.") + else: + raise GbpError("No archive to import specified and no spec file " + "found. Try --help.") else: path = args[0] if re.match(r'[a-z]{1,5}://', path): @@ -212,12 +225,14 @@ def main(argv): tmpdir = tempfile.mkdtemp(dir=options.tmp_dir, prefix='import-orig-rpm_') try: - source = find_source(options, args) try: repo = RpmGitRepository('.') except GitRepositoryError: raise GbpError, "%s is not a git repository" % (os.path.abspath('.')) + spec = find_spec(repo, options) + source = find_source(spec, options, args) + # an empty repo has now branches: initial_branch = repo.get_branch() is_empty = False if initial_branch else True @@ -231,7 +246,8 @@ def main(argv): else: raise GbpError(no_upstream_branch_msg % options.upstream_branch) - (sourcepackage, version) = detect_name_and_version(repo, source, options) + sourcepackage, version = detect_name_and_version(repo, source, spec, + options) (clean, out) = repo.is_clean() if not clean and not is_empty: diff --git a/tests/component/rpm/test_import_orig_rpm.py b/tests/component/rpm/test_import_orig_rpm.py index d26f5ebc..465c5fad 100644 --- a/tests/component/rpm/test_import_orig_rpm.py +++ b/tests/component/rpm/test_import_orig_rpm.py @@ -39,6 +39,18 @@ from tests.component.rpm import RPM_TEST_DATA_DIR DATA_DIR = os.path.join(RPM_TEST_DATA_DIR, 'orig') +DUMMY_SPEC = """ +Name: dummy +Version: 1.0 +Release: 0 +License: GPL-2.0 +Summary: Dummy package +Source: %(source)s + +%%description +Dummy package generated by unit tests +""" + def mock_import(args, stdin_data="\n\n", cwd=None): """Wrapper for import-orig-rpm for feeding mock stdin data to it""" old_cwd = os.path.abspath(os.path.curdir) @@ -111,6 +123,13 @@ class TestImportOrig(ImportOrigTestBase): repo.commit_all('First commit') return repo + @staticmethod + def _create_dummy_spec(path, **kwargs): + """Create a dummy spec file""" + with open(path, 'w') as fobj: + print kwargs + fobj.write(DUMMY_SPEC % kwargs) + def test_invalid_args(self): """ See that import-orig-rpm fails gracefully when called with invalid args @@ -118,10 +137,6 @@ class TestImportOrig(ImportOrigTestBase): repo = GitRepository.create('.') origs = [os.path.join(DATA_DIR, 'gbp-test-1.0.tar.bz2'), os.path.join(DATA_DIR, 'gbp-test-1.1.tar.bz2')] - # Test empty args - eq_(mock_import([]), 1) - self._clear_log() - # Test multiple archives eq_(mock_import([] + origs), 1) self._check_log(0, 'gbp:error: More than one archive specified') @@ -383,6 +398,30 @@ class TestImportOrig(ImportOrigTestBase): # Other parts of the import should've succeeded self._check_repo_state(repo, 'master', ['master', 'upstream']) + def test_archive_from_spec(self): + """Test taking archive file path from spec file""" + repo = GitRepository.create('.') + orig = os.path.join(DATA_DIR, 'gbp-test-1.0.tar.bz2') + + # Test non-existent spec file + eq_(mock_import([]), 1) + self._check_log(0, '.*No archive to import specified and no spec file') + + # Test non-existent archive + self._create_dummy_spec('dummy.spec', source='non-existent.tar.gz') + eq_(mock_import([]), 1) + self._check_log(-1, '.*unable to find \S+non-existent.tar.gz') + + # Test failing download + self._create_dummy_spec('dummy.spec', source='foo://bar.tar.gz') + eq_(mock_import([]), 1) + self._check_log(-1, '.*Download failed') + + # Test existing archive + self._create_dummy_spec('dummy.spec', source=orig) + eq_(mock_import([]), 0) + self._check_repo_state(repo, None, ['upstream'], ['dummy.spec']) + class TestPristineTar(ImportOrigTestBase): """ -- cgit v1.2.3 From 6a27d9944b0146aa8356a4f36f6b530732cba50c Mon Sep 17 00:00:00 2001 From: Markus Lehtonen Date: Thu, 6 Feb 2014 15:24:54 +0200 Subject: buildpackage-rpm: patch-export from development branch Adds git-buildpackage-rpm --patch-export support for the 'orphan packaging' development model (where packaging files and development sources are kept in separate branches). New functionality: 1. If patch-export is enabled and gbp detects that the current branch has a development/patch-queue branch it exports the patches from there, instead of the tip of the packaging branch. 2. If gbp detects that the current (or exported) branch is a development/patch-queue branch it automatically enables patch-export and exports packaging files from the base branch (instead of the development/patch-queue branch. Also, add a new '--git-patch-export-rev' command line option with which the user can explicitly set the treeish from which patches are generated (i.e. HEAD..) Signed-off-by: Markus Lehtonen --- gbp/scripts/buildpackage_rpm.py | 91 +++++++++++++++++++++++++++++------------ 1 file changed, 64 insertions(+), 27 deletions(-) diff --git a/gbp/scripts/buildpackage_rpm.py b/gbp/scripts/buildpackage_rpm.py index b57c5285..1ada6381 100755 --- a/gbp/scripts/buildpackage_rpm.py +++ b/gbp/scripts/buildpackage_rpm.py @@ -43,7 +43,8 @@ from gbp.scripts.common.buildpackage import (index_name, wc_names, git_archive_single, dump_tree, write_wc, drop_index) from gbp.pkg import (compressor_opts, compressor_aliases) -from gbp.scripts.pq_rpm import update_patch_series +from gbp.scripts.pq_rpm import update_patch_series, parse_spec +from gbp.scripts.common.pq import is_pq_branch, pq_branch_name, pq_branch_base class GbpAutoGenerateError(GbpError): @@ -193,6 +194,53 @@ def get_tree(repo, tree_name): return tree +def get_current_branch(repo): + """Get the currently checked-out branch""" + try: + branch = repo.get_branch() + except GitRepositoryError: + branch = None + return branch + + +def guess_export_params(repo, options): + """Get commit and tree from where to export packaging and patches""" + tree = None + branch = None + if options.export in wc_names.keys() + [index_name, 'HEAD']: + branch = get_current_branch(repo) + elif options.export in repo.get_local_branches(): + branch = options.export + if branch: + if is_pq_branch(branch, options): + packaging_branch = pq_branch_base(branch, options) + if repo.has_branch(packaging_branch): + gbp.log.info("It seems you're building a development/patch-" + "queue branch. Export target changed to '%s' and " + "patch-export enabled!" % packaging_branch) + options.patch_export = True + if not options.patch_export_rev: + options.patch_export_rev = options.export + options.export = packaging_branch + else: + gbp.log.warn("It seems you're building a development/patch-" + "queue branch. No corresponding packaging branch " + "found. Build may fail!") + elif options.patch_export and not options.patch_export_rev: + tree = get_tree(repo, options.export) + spec = parse_spec(options, repo, treeish=tree) + pq_branch = pq_branch_name(branch, options, spec.version) + if repo.has_branch(pq_branch): + gbp.log.info("Exporting patches from development/patch-queue " + "branch '%s'" % pq_branch) + options.patch_export_rev = pq_branch + if tree is None: + tree = get_tree(repo, options.export) + spec = parse_spec(options, repo, treeish=tree) + + # Return tree-ish object and relative spec path for for exporting packaging + return tree, spec.specpath + def git_archive_build_orig(repo, spec, output_dir, options): """ Build orig tarball using git-archive @@ -230,15 +278,6 @@ def export_patches(repo, spec, export_treeish, options): """ Generate patches and update spec file """ - # Fail if we have local patch files not marked for manual maintenance. - # Ignore patches listed in spec but not found in packaging dir - for patch in spec.patchseries(): - if os.path.exists(patch.path): - raise GbpAutoGenerateError( - 'Patches not marked for manual maintenance found, ' - 'refusing to overwrite! Fix by applying them to packaging ' - 'branch and removing the files.') - try: upstream_tree = get_upstream_tree(repo, spec, options) update_patch_series(repo, spec, upstream_tree, export_treeish, options) @@ -389,6 +428,7 @@ def parse_args(argv, prefix, git_treeish=None): orig_group.add_config_file_option(option_name="orig-prefix", dest="orig_prefix") branch_group.add_config_file_option(option_name="upstream-branch", dest="upstream_branch") branch_group.add_config_file_option(option_name="packaging-branch", dest="packaging_branch") + branch_group.add_config_file_option(option_name="pq-branch", dest="pq_branch") branch_group.add_boolean_config_file_option(option_name = "ignore-branch", dest="ignore_branch") branch_group.add_boolean_config_file_option(option_name = "submodules", dest="with_submodules") cmd_group.add_config_file_option(option_name="builder", dest="builder", @@ -426,6 +466,10 @@ def parse_args(argv, prefix, git_treeish=None): export_group.add_option("--git-export-only", action="store_true", dest="export_only", default=False, help="only export packaging files, don't build") export_group.add_boolean_config_file_option("patch-export", dest="patch_export") + export_group.add_option("--git-patch-export-rev", dest="patch_export_rev", + metavar="TREEISH", + help="[experimental] Export patches from treeish object " + "TREEISH") export_group.add_config_file_option("patch-export-ignore-path", dest="patch_export_ignore_path") export_group.add_config_file_option("patch-export-compress", dest="patch_export_compress") @@ -482,12 +526,11 @@ def main(argv): gbp.log.err(err) return 1 - try: - branch = repo.get_branch() - except GitRepositoryError: - branch = None + branch = get_current_branch(repo) try: + tree, relative_spec_path = guess_export_params(repo, options) + if not options.export_only: Command(options.cleaner, shell=True)() if not options.ignore_new: @@ -508,18 +551,8 @@ def main(argv): gbp.log.debug("Dumping tree '%s' to '%s'" % (options.export, dump_dir)) if not dump_tree(repo, dump_dir, tree, options.with_submodules): raise GbpError - # Find and parse spec from dump dir to get version etc. - if options.spec_file != 'auto': - specfile = os.path.join(dump_dir, options.spec_file) - options.packaging_dir = os.path.dirname(specfile) - if not os.path.exists(specfile): - raise rpm.NoSpecError("Failed to export specfile: %s" % options.spec_file) - spec = rpm.SpecFile(specfile) - else: - spec = rpm.guess_spec(os.path.join(dump_dir, options.packaging_dir), - True, - os.path.basename(repo.path) + '.spec') - gbp.log.debug("Using spec file '%s'" % spec.specfile) + # Parse spec from dump dir to get version etc. + spec = rpm.SpecFile(os.path.join(dump_dir, relative_spec_path)) if not options.tag_only: # Setup builder opts @@ -527,7 +560,11 @@ def main(argv): # Generate patches, if requested if options.patch_export and not is_native(repo, options): - export_patches(repo, spec, tree, options) + if options.patch_export_rev: + patch_tree = get_tree(repo, options.patch_export_rev) + else: + patch_tree = tree + export_patches(repo, spec, patch_tree, options) # Prepare final export dirs export_dir = prepare_export_dir(options.export_dir) -- cgit v1.2.3 From f2b0b748f5a09845714c7a44ded72ad3a968fd35 Mon Sep 17 00:00:00 2001 From: Markus Lehtonen Date: Mon, 10 Feb 2014 10:49:29 +0200 Subject: pq-rpm: implement 'convert' subcommand The new subcommand is intended to be a one-time-callable command for converting a package to use the "orphan-packaging" development model and git layout (where packaging files are maintained in a separate branch and code development in another branch). Signed-off-by: Markus Lehtonen --- gbp/scripts/pq_rpm.py | 99 +++++++++++++++++++++++++++++++++----- tests/component/rpm/test_pq_rpm.py | 39 +++++++++++++++ 2 files changed, 127 insertions(+), 11 deletions(-) diff --git a/gbp/scripts/pq_rpm.py b/gbp/scripts/pq_rpm.py index 64a4c7e4..6c07c725 100755 --- a/gbp/scripts/pq_rpm.py +++ b/gbp/scripts/pq_rpm.py @@ -56,7 +56,11 @@ rebase Switch to patch queue / devel branch associated to the current drop Drop (delete) the patch queue /devel branch associated to the current branch. apply Apply a patch -switch Switch to patch-queue branch and vice versa.""" +switch Switch to patch-queue branch and vice versa. +convert [experimental] Convert package from single-branch development + model (packaging and source code changes in the same branch) + into the orphan-packaging plus patch-queue / development branch + development model.""" def compress_patches(patches, compress_size=0): """ @@ -74,6 +78,15 @@ def compress_patches(patches, compress_size=0): ret_patches.append(os.path.basename(patch) + suffix) return ret_patches +def is_ancestor(repo, parent, child): + """Check if commit is ancestor of another""" + parent_sha1 = repo.rev_parse("%s^0" % parent) + child_sha1 = repo.rev_parse("%s^0" % child) + try: + merge_base = repo.get_merge_base(parent_sha1, child_sha1) + except GitRepositoryError: + merge_base = None + return merge_base == parent_sha1 def generate_patches(repo, start, squash, end, outdir, options): """ @@ -97,11 +110,8 @@ def generate_patches(repo, start, squash, end, outdir, options): end_commit_sha1 = repo.rev_parse("%s^0" % end_commit) start_sha1 = repo.rev_parse("%s^0" % start) - try: - merge_base = repo.get_merge_base(start_sha1, end_commit_sha1) - except GitRepositoryError: - merge_base = None - if merge_base != start_sha1: + + if not is_ancestor(repo, start_sha1, end_commit_sha1): raise GbpError("Start commit '%s' not an ancestor of end commit " "'%s'" % (start, end_commit)) # Squash commits, if requested @@ -201,6 +211,7 @@ def update_patch_series(repo, spec, start, end, options): spec.specdir, options) spec.update_patches(patches, commands) spec.write_spec_file() + return patches def parse_spec(options, repo, treeish=None): @@ -315,7 +326,7 @@ def get_packager(spec): return GitModifier(match.group('name'), match.group('email')) return GitModifier() -def import_extra_files(repo, commitish, files): +def import_extra_files(repo, commitish, files, patch_ignore=True): """Import branch-specific gbp.conf files to current branch""" found = {} for fname in files: @@ -337,10 +348,12 @@ def import_extra_files(repo, commitish, files): files = found.keys() gbp.log.debug('Adding/commiting %s' % files) repo.add_files(files, force=True) - commit_msg = ('Auto-import packaging file(s) from branch %s:\n' - ' %s\n\nGbp: Ignore\nGbp-Rpm: Ignore' % (commitish, - ' '.join(files))) + commit_msg = ("Auto-import file(s) from branch '%s':\n %s\n" % + (commitish, ' '.join(files))) + if patch_ignore: + commit_msg += "\nGbp: Ignore\nGbp-Rpm: Ignore" repo.commit_files(files, msg=commit_msg) + return found.keys() def import_spec_patches(repo, options): """ @@ -477,6 +490,68 @@ def apply_single_patch(repo, patchfile, options): patch = Patch(patchfile) apply_and_commit_patch(repo, patch, fallback_author=None) +def convert_package(repo, options): + """Convert package to orphan-packaging model""" + old_packaging = repo.get_branch() + # Check if we're on pq branch, already + err_msg_base = "Seems you're already using orphan-packaging model - " + if is_pq_branch(old_packaging, options): + raise GbpError(err_msg_base + "you're on patch-queue branch") + # Check if a pq branch already exists + spec = parse_spec(options, repo, treeish=old_packaging) + pq_branch = pq_branch_name(old_packaging, options, spec.version) + if repo.has_branch(pq_branch): + pq_branch = pq_branch_name(old_packaging, options, spec.version) + raise GbpError(err_msg_base + "pq branch %s already exists" % pq_branch) + # Check that the current branch is based on upstream + upstream_commit = find_upstream_commit(repo, spec, options.upstream_tag) + if not is_ancestor(repo, upstream_commit, old_packaging): + raise GbpError(err_msg_base + "%s is not based on upstream version %s" % + (old_packaging, spec.upstreamversion)) + # Check new branch + new_branch = old_packaging + "-orphan" + if repo.has_branch(new_branch): + if not options.force: + raise GbpError("Branch '%s' already exists!" % new_branch) + else: + gbp.log.info("Dropping branch '%s'" % new_branch) + repo.delete_branch(new_branch) + + # Dump and commit packaging files + gbp.log.info("Importing packaging files from branch '%s' to '%s'" % + (old_packaging, new_branch)) + packaging_tree = '%s:%s' % (old_packaging, options.packaging_dir) + packaging_tmp = tempfile.mkdtemp(prefix='pack_', dir=options.tmp_dir) + dump_tree(repo, packaging_tmp, packaging_tree, with_submodules=False, + recursive=False) + + msg = "Auto-import packaging files from branch '%s'" % old_packaging + repo.commit_dir(packaging_tmp, msg, new_branch, create_missing_branch=True) + repo.set_branch(new_branch) + + # Generate patches + spec = SpecFile(spec.specfile) + patches = update_patch_series(repo, spec, upstream_commit, old_packaging, + options) + + # Commit paches and spec + if patches: + gbp.log.info("Committing patches and modified spec file to git") + repo.add_files('.', untracked=False) + repo.add_files(patches) + msg = "Auto-generated patches from branch '%s'" % old_packaging + repo.commit_staged(msg=msg) + + # Copy extra files + import_extra_files(repo, old_packaging, options.import_files, + patch_ignore=False) + + gbp.log.info("Package successfully converted to orphan-packaging.") + gbp.log.info("You're now on the new '%s' packaging branch (the old " + "packaging branch '%s' was left intact)." % + (new_branch, old_packaging)) + gbp.log.info("Please check all files and test building the package!") + def opt_split_cb(option, opt_str, value, parser): """Split option string into a list""" @@ -544,7 +619,7 @@ def main(argv): else: action = args[1] - if args[1] in ["export", "import", "rebase", "drop", "switch"]: + if args[1] in ["export", "import", "rebase", "drop", "switch", "convert"]: pass elif args[1] in ["apply"]: if len(args) != 3: @@ -582,6 +657,8 @@ def main(argv): apply_single_patch(repo, patchfile, options) elif action == "switch": switch_pq(repo, options) + elif action == "convert": + convert_package(repo, options) except CommandExecFailed: retval = 1 except GitRepositoryError as err: diff --git a/tests/component/rpm/test_pq_rpm.py b/tests/component/rpm/test_pq_rpm.py index 22025d6f..8ef20a29 100644 --- a/tests/component/rpm/test_pq_rpm.py +++ b/tests/component/rpm/test_pq_rpm.py @@ -252,6 +252,45 @@ class TestPqRpm(RpmRepoTestBase): self._check_repo_state(repo, 'development/master', branches, upstr_files + ['mydir/', 'mydir/myfile.txt']) + def test_convert(self): + """Basic test for convert action""" + repo = self.init_test_repo('gbp-test2') + branches = repo.get_local_branches() + ['master-orphan'] + files = ['bar.tar.gz', 'foo.txt', 'gbp-test2.spec', + 'gbp-test2-alt.spec', 'my.patch', '0001-My-addition.patch'] + + # First should fail because 'master-orphan' branch already exists + eq_(mock_pq(['convert']), 1) + self._check_log(-1, "gbp:error: Branch 'master-orphan' already exists") + + # Re-try with force + eq_(mock_pq(['convert', '--import-files=', '--force']), 0) + self._check_repo_state(repo, 'master-orphan', branches, files) + + def test_convert_fail(self): + """Tests for convert action error cases""" + repo = self.init_test_repo('gbp-test') + branches = repo.get_local_branches() + + # Already on orphan packaging branch + eq_(mock_pq(['convert']), 1) + self._check_repo_state(repo, 'master', branches) + self._check_log(-1, ".*is not based on upstream version") + + # Create a pq branch and try from there + eq_(mock_pq(['import']), 0) + eq_(mock_pq(['convert']), 1) + self._check_repo_state(repo, 'development/master', + branches + ['development/master']) + self._check_log(-1, ".*you're on patch-queue branch") + + # Switch back to orphan packaging branch and try again + eq_(mock_pq(['switch']), 0) + eq_(mock_pq(['convert']), 1) + self._check_repo_state(repo, 'master', + branches + ['development/master']) + self._check_log(-1, r".*pq branch \S+ already exists") + def test_option_patch_numbers(self): """Test the --patch-numbers cmdline option""" repo = self.init_test_repo('gbp-test') -- cgit v1.2.3 From a4c9ea5d3f4475bf18dd60530c91e02e6d3f4520 Mon Sep 17 00:00:00 2001 From: Markus Lehtonen Date: Tue, 11 Feb 2014 10:18:47 +0200 Subject: pq-rpm: implement --new-packaging-dir cmdline option Used for setting the packaging directory to be used in the new orphan packaging branch. Defaults to --packaging-dir so that the gbp.conf files are more likely to work without modification. Signed-off-by: Markus Lehtonen --- gbp/scripts/pq_rpm.py | 12 ++++++++++-- tests/component/rpm/test_pq_rpm.py | 23 +++++++++++++++++++---- 2 files changed, 29 insertions(+), 6 deletions(-) diff --git a/gbp/scripts/pq_rpm.py b/gbp/scripts/pq_rpm.py index 6c07c725..7ee407dc 100755 --- a/gbp/scripts/pq_rpm.py +++ b/gbp/scripts/pq_rpm.py @@ -522,7 +522,8 @@ def convert_package(repo, options): (old_packaging, new_branch)) packaging_tree = '%s:%s' % (old_packaging, options.packaging_dir) packaging_tmp = tempfile.mkdtemp(prefix='pack_', dir=options.tmp_dir) - dump_tree(repo, packaging_tmp, packaging_tree, with_submodules=False, + dump_packaging_dir = os.path.join(packaging_tmp, options.new_packaging_dir) + dump_tree(repo, dump_packaging_dir, packaging_tree, with_submodules=False, recursive=False) msg = "Auto-import packaging files from branch '%s'" % old_packaging @@ -530,9 +531,10 @@ def convert_package(repo, options): repo.set_branch(new_branch) # Generate patches - spec = SpecFile(spec.specfile) + spec = SpecFile(os.path.join(options.new_packaging_dir, spec.specfile)) patches = update_patch_series(repo, spec, upstream_commit, old_packaging, options) + patches = [os.path.join(options.new_packaging_dir, pat) for pat in patches] # Commit paches and spec if patches: @@ -588,6 +590,10 @@ def main(argv): parser.add_config_file_option(option_name="spec-file", dest="spec_file") parser.add_config_file_option(option_name="packaging-dir", dest="packaging_dir") + parser.add_option("--new-packaging-dir", + help="Packaging directory in the new packaging branch. Only " + "relevant for the 'convert' action. If not defined, defaults " + "to '--packaging-dir'") parser.add_config_file_option(option_name="packaging-branch", dest="packaging_branch", help="Branch the packaging is being maintained on. Only relevant " @@ -612,6 +618,8 @@ def main(argv): (options, args) = parser.parse_args(argv) gbp.log.setup(options.color, options.verbose, options.color_scheme) options.patch_export_compress = string_to_int(options.patch_export_compress) + if options.new_packaging_dir is None: + options.new_packaging_dir = options.packaging_dir if len(args) < 2: gbp.log.err("No action given.") diff --git a/tests/component/rpm/test_pq_rpm.py b/tests/component/rpm/test_pq_rpm.py index 8ef20a29..968119e3 100644 --- a/tests/component/rpm/test_pq_rpm.py +++ b/tests/component/rpm/test_pq_rpm.py @@ -256,15 +256,16 @@ class TestPqRpm(RpmRepoTestBase): """Basic test for convert action""" repo = self.init_test_repo('gbp-test2') branches = repo.get_local_branches() + ['master-orphan'] - files = ['bar.tar.gz', 'foo.txt', 'gbp-test2.spec', - 'gbp-test2-alt.spec', 'my.patch', '0001-My-addition.patch'] - + files = ['packaging/', 'packaging/bar.tar.gz', 'packaging/foo.txt', + 'packaging/gbp-test2.spec', 'packaging/gbp-test2-alt.spec', + 'packaging/my.patch', 'packaging/0001-My-addition.patch', + '.gbp.conf'] # First should fail because 'master-orphan' branch already exists eq_(mock_pq(['convert']), 1) self._check_log(-1, "gbp:error: Branch 'master-orphan' already exists") # Re-try with force - eq_(mock_pq(['convert', '--import-files=', '--force']), 0) + eq_(mock_pq(['convert', '--force']), 0) self._check_repo_state(repo, 'master-orphan', branches, files) def test_convert_fail(self): @@ -520,6 +521,20 @@ class TestPqRpm(RpmRepoTestBase): ok_('debian/gbp.conf' not in repo.list_files()) ok_('.gbp.conf' not in repo.list_files()) + def test_option_new_packaging_dir(self): + """Test the --new-packaging-dir cmdline option""" + repo = self.init_test_repo('gbp-test2') + branches = repo.get_local_branches() + ['master-orphan'] + files = ['rpm/', 'rpm/bar.tar.gz', 'rpm/foo.txt', + 'rpm/gbp-test2.spec', 'rpm/gbp-test2-alt.spec', + 'rpm/my.patch', 'rpm/0001-My-addition.patch'] + # Drop already-existing master-orphan branch + repo.delete_branch('master-orphan') + # Try convert + eq_(mock_pq(['convert', '--import-files=', + '--new-packaging-dir=rpm']), 0) + self._check_repo_state(repo, 'master-orphan', branches, files) + def test_import_unapplicable_patch(self): """Test import when a patch does not apply""" repo = self.init_test_repo('gbp-test') -- cgit v1.2.3 From 33d2d4a9d07ffcef721f7cbae1c591613b59d3f0 Mon Sep 17 00:00:00 2001 From: Markus Lehtonen Date: Mon, 31 Mar 2014 15:18:34 +0300 Subject: pq-rpm: implement --retain-history option With this option defined gbp tries to preserve the history when converting. That is, for each commit in the old branch create one corresponding commit in the new orphan packaging branch. This works by dumping packaging files and updating patches for each commit. However, empty commits are not generated - these are caused e.g. by changes in files that are ignored by patch-generation. NOTE! Only valid for the 'convert' action. Signed-off-by: Markus Lehtonen --- gbp/scripts/pq_rpm.py | 99 ++++++++++++++++++++++++++++---------- tests/component/rpm/test_pq_rpm.py | 16 ++++++ 2 files changed, 90 insertions(+), 25 deletions(-) diff --git a/gbp/scripts/pq_rpm.py b/gbp/scripts/pq_rpm.py index 7ee407dc..d8fa88f8 100755 --- a/gbp/scripts/pq_rpm.py +++ b/gbp/scripts/pq_rpm.py @@ -517,33 +517,25 @@ def convert_package(repo, options): gbp.log.info("Dropping branch '%s'" % new_branch) repo.delete_branch(new_branch) - # Dump and commit packaging files + # Determine "history" + if options.retain_history: + # Find first commit that has the spec file and list commits from there + try: + repo.show('%s:%s' % (upstream_commit, spec.specpath)) + history = repo.get_commits(upstream_commit, old_packaging) + except GitRepositoryError: + history_start = repo.get_commits(upstream_commit, old_packaging, + spec.specpath)[-1] + history = repo.get_commits('%s^' % history_start, old_packaging) + else: + history = [repo.rev_parse(old_packaging)] + history.reverse() + + # Do import gbp.log.info("Importing packaging files from branch '%s' to '%s'" % (old_packaging, new_branch)) - packaging_tree = '%s:%s' % (old_packaging, options.packaging_dir) - packaging_tmp = tempfile.mkdtemp(prefix='pack_', dir=options.tmp_dir) - dump_packaging_dir = os.path.join(packaging_tmp, options.new_packaging_dir) - dump_tree(repo, dump_packaging_dir, packaging_tree, with_submodules=False, - recursive=False) - - msg = "Auto-import packaging files from branch '%s'" % old_packaging - repo.commit_dir(packaging_tmp, msg, new_branch, create_missing_branch=True) - repo.set_branch(new_branch) - - # Generate patches - spec = SpecFile(os.path.join(options.new_packaging_dir, spec.specfile)) - patches = update_patch_series(repo, spec, upstream_commit, old_packaging, - options) - patches = [os.path.join(options.new_packaging_dir, pat) for pat in patches] - - # Commit paches and spec - if patches: - gbp.log.info("Committing patches and modified spec file to git") - repo.add_files('.', untracked=False) - repo.add_files(patches) - msg = "Auto-generated patches from branch '%s'" % old_packaging - repo.commit_staged(msg=msg) - + convert_with_history(repo, upstream_commit, history, new_branch, + spec.specfile, options) # Copy extra files import_extra_files(repo, old_packaging, options.import_files, patch_ignore=False) @@ -555,6 +547,59 @@ def convert_package(repo, options): gbp.log.info("Please check all files and test building the package!") +def convert_with_history(repo, upstream, commits, new_branch, spec_fn, options): + """Auto-import packaging files and (auto-generated) patches""" + + # Dump and commit packaging files + packaging_tree = '%s:%s' % (commits[0], options.packaging_dir) + packaging_tmp = tempfile.mkdtemp(prefix='pack_', dir=options.tmp_dir) + dump_packaging_dir = os.path.join(packaging_tmp, options.new_packaging_dir) + dump_tree(repo, dump_packaging_dir, packaging_tree, with_submodules=False, + recursive=False) + + msg = "Auto-import packaging files\n\n" \ + "Imported initial packaging files from commit '%s'" % (commits[0]) + new_tree = repo.create_tree(packaging_tmp) + tip_commit = repo.commit_tree(new_tree, msg, []) + + # Generate initial patches + spec = SpecFile(os.path.join(dump_packaging_dir, spec_fn)) + update_patch_series(repo, spec, upstream, commits[0], options) + # Commit updated packaging files only if something was changed + new_tree = repo.create_tree(packaging_tmp) + if new_tree != repo.rev_parse(tip_commit + ':'): + msg = "Auto-generate patches\n\n" \ + "Generated patches from\n'%s..%s'\n\n" \ + "updating spec file and possibly removing old patches." \ + % (upstream, commits[0]) + tip_commit = repo.commit_tree(new_tree, msg, [tip_commit]) + + # Import rest of the commits + for commit in commits[1:]: + shutil.rmtree(dump_packaging_dir) + packaging_tree = '%s:%s' % (commit, options.packaging_dir) + dump_tree(repo, dump_packaging_dir, packaging_tree, + with_submodules=False, recursive=False) + try: + spec = SpecFile(os.path.join(dump_packaging_dir, spec_fn)) + update_patch_series(repo, spec, upstream, commit, options) + except (NoSpecError, GbpError): + gbp.log.warn("Failed to generate patches from '%s'" % commit) + + new_tree = repo.create_tree(packaging_tmp) + if new_tree == repo.rev_parse(tip_commit + ':'): + gbp.log.info("Skipping commit '%s' which generated no change" % + commit) + else: + info = repo.get_commit_info(commit) + msg = "%s\n\n%sAuto-imported by gbp from '%s'" % (info['subject'], + info['body'], commit) + tip_commit = repo.commit_tree(new_tree, msg, [tip_commit]) + + repo.create_branch(new_branch, tip_commit) + repo.set_branch(new_branch) + + def opt_split_cb(option, opt_str, value, parser): """Split option string into a list""" setattr(parser.values, option.dest, value.split(',')) @@ -604,6 +649,10 @@ def main(argv): parser.add_config_file_option(option_name="import-files", dest="import_files", type="string", action="callback", callback=opt_split_cb) + parser.add_option("--retain-history", action="store_true", + help="When doing convert, preserve as much of the git history as " + "possible, i.e. create one commit per commit. Only " + "relevant for the 'convert' action.") parser.add_option("--export-rev", action="store", dest="export_rev", default="", help="Export patches from treeish object TREEISH instead of head " diff --git a/tests/component/rpm/test_pq_rpm.py b/tests/component/rpm/test_pq_rpm.py index 968119e3..ba8648d2 100644 --- a/tests/component/rpm/test_pq_rpm.py +++ b/tests/component/rpm/test_pq_rpm.py @@ -535,6 +535,22 @@ class TestPqRpm(RpmRepoTestBase): '--new-packaging-dir=rpm']), 0) self._check_repo_state(repo, 'master-orphan', branches, files) + def test_option_retain_history(self): + """Test the --retain-history cmdline option""" + repo = self.init_test_repo('gbp-test2') + branches = repo.get_local_branches() + ['master-orphan'] + files = ['packaging/', 'packaging/bar.tar.gz', 'packaging/foo.txt', + 'packaging/gbp-test2.spec', 'packaging/gbp-test2-alt.spec', + 'packaging/my.patch', 'packaging/0001-My-addition.patch', + '.gbp.conf'] + # Drop pre-existing master-orphan branch + repo.delete_branch('master-orphan') + + # Convert with history + eq_(mock_pq(['convert', '--retain-history']), 0) + self._check_repo_state(repo, 'master-orphan', branches, files) + eq_(len(repo.get_commits('', 'master-orphan')), 7) + def test_import_unapplicable_patch(self): """Test import when a patch does not apply""" repo = self.init_test_repo('gbp-test') -- cgit v1.2.3 From 2190565be10524907f6431992751f0f6b2ea817f Mon Sep 17 00:00:00 2001 From: Markus Lehtonen Date: Thu, 7 Nov 2013 13:54:08 +0200 Subject: packaging: Prepare for next Tizen tools release Signed-off-by: Markus Lehtonen --- debian/changelog | 101 +++++++++++++++++++++++++++++++++++++ packaging/git-buildpackage.changes | 98 +++++++++++++++++++++++++++++++++++ packaging/git-buildpackage.spec | 4 +- 3 files changed, 201 insertions(+), 2 deletions(-) diff --git a/debian/changelog b/debian/changelog index 0bcc24db..5a874c07 100644 --- a/debian/changelog +++ b/debian/changelog @@ -138,6 +138,107 @@ git-buildpackage (0.6.9) unstable; urgency=medium -- Guido Günther Sat, 15 Feb 2014 11:45:00 +0100 +git-buildpackage (0.6.8-tizen20140306) unstable; urgency=low + + [ Markus Lehtonen ] + * Rebase on top of upstream version 0.6.8 + * Introduce git-rpm-ch tool. + Initial version of the git-rpm-ch tool which is intended for maintaining + RPM changelogs. Supports both spec files and separate "OBS style" + changelog files. + Implement '--tag' command line option (and other related options for + signing) for creating and tagging a release. These correspond the + tagging options in git-buildpackage-rpm. + The git-buildpackage-rpm tool does not commit anything to git. However, + in rpm-ch the '--tag' option causes the changelog modifications (and, + all other staged changes) to be committed to git before creating the + tag. This makes it possible to create a release and document the + packaging/release tag name in the rpm changelog. + * Changes to gbp-pq-rpm: + - implement 'convert' subcommand. + The new subcommand is intended to be a one-time-callable command for + converting a package to use the "orphan-packaging" development model and + git layout (where packaging files are maintained in a separate branch + and code development in another branch). + - implement '--import-files' command line option. + For defining the packaging file(s) that will be imported into the + development/patch-queue branch. + By default, the local gbp conf files are imported (so that gbp sees the + same settings on the development/pq branc as on the packaging branch). + Files defined with this option will appear as one monolithic commit in + the development/patch-queue branch. + - implement --new-packaging-dir cmdline option. + Used for setting the packaging directory to be used in the new orphan + packaging branch. Defaults to --packaging-dir so that the gbp.conf files + are more likely to work without modification. + - fail gracefully on invalid config files + - support '%(upstreamversion)s' as a replacable string in the pq branch + name. + * Changes to git-buildpackage-rpm + - patch-export from development branch. + Adds git-buildpackage-rpm --patch-export support for the 'orphan + packaging' development model (where packaging files and development sources are kept in separate + branches). + New functionality: + 1. If patch-export is enabled and gbp detects that the current branch + has a development/patch-queue branch it exports the patches from there, + instead of the tip of the packaging branch. + 2. If gbp detects that the current (or exported) branch is a + development/patch-queue branch it automatically enables patch-export + and exports packaging files from the base branch (instead of the + development/patch-queue branch. + Also, add a new '--git-patch-export-rev' command line option with which + the user can explicitly set the treeish from which patches are generated + (i.e. HEAD..) + - fix spec file vcs update when doing git-tag-only + - change default export directory. + So that the git working directory is not dirtied, by default. + * Changes ti git-import-orig-rpm: + - disable --merge by default. + Merging upstream to packaging does not usually make sense with rpm + packages. Merely, it can create confusion cause unapplicable patches to + be generated. + - implement --create-missing-branches option. + - implement automatic downloading. + Automatically try to download the archive if the archive filename points + to a remote location. + - get archive from spec file. + Try to get archive path/filename from spec file if no file name is given + on the command line. This should make version bumps more + straightforward: just update version number in the spec file and run + 'git-import-orig-rpm'. + * git-import-orig: implement --create-missing-branches option. + * Fixes and new features in GitRepository class + - GitRepository/get_commit_info: correctly handle file renames/copies. + - GitRepository.create_branch: add 'force' option + - GitRepository.archive: add 'paths' option + - GitRepository/git_command: strip stderr output in case of error. + - GitRepository/add_remote_repo: fix the 'tags' argument. + - GitRepository: allow interactive commands. + - GitRepository: fix the 'edit' mode in commit methods. + - GitRepository.commit_files: add committer_info and edit arguments. + - GitRepository.commit_all: add committer_info argument. + * Fixes and new features in internal rpm/spec support + - rpm.SpecFile: add 'specpath' attribute + - rpm: correctly handle 'NoSource' and 'NoPatch' tags in spec. + - rpm: Implement spec_from_repo() helper function + - rpm: track all "section" directives in spec file. + - rpm: add gbp.rpm.changelog module. + This new module contains basic containers and functionality for parsing + and updating rpm changelogs. It is coupled with the rpm packaging policy + class which now has definitions for rpm changelog formatting. + - rpm: support for getting/setting changelog in spec. + SpecFile objects now support reading and writing of the %changelog + section. + - rpm: store full path of spec file sources + + [ Łukasz Stelmach ] + * Fix detection of prefix directory in tarballs + gbs import failed to import tarball properly if paths in the archive + were prefixed with "./". + + -- Markus Lehtonen Thu, 27 Feb 2014 11:30:59 +0200 + git-buildpackage (0.6.8) unstable; urgency=medium * [f5718b8] No need to document --verbose. Properly document --help diff --git a/packaging/git-buildpackage.changes b/packaging/git-buildpackage.changes index 938808e2..d026530b 100644 --- a/packaging/git-buildpackage.changes +++ b/packaging/git-buildpackage.changes @@ -1,3 +1,101 @@ +* Thu Mar 06 2014 Markus Lehtonen tizen/0.6.8-20140306 +- Rebase on top of upstream version 0.6.8 +- Introduce git-rpm-ch tool. + Initial version of the git-rpm-ch tool which is intended for maintaining + RPM changelogs. Supports both spec files and separate "OBS style" + changelog files. + Implement '--tag' command line option (and other related options for + signing) for creating and tagging a release. These correspond the + tagging options in git-buildpackage-rpm. + The git-buildpackage-rpm tool does not commit anything to git. However, + in rpm-ch the '--tag' option causes the changelog modifications (and, + all other staged changes) to be committed to git before creating the + tag. This makes it possible to create a release and document the + packaging/release tag name in the rpm changelog. +- Changes to gbp-pq-rpm: + * implement 'convert' subcommand. + The new subcommand is intended to be a one-time-callable command for + converting a package to use the "orphan-packaging" development model and + git layout (where packaging files are maintained in a separate branch + and code development in another branch). + * implement '--import-files' command line option. + For defining the packaging file(s) that will be imported into the + development/patch-queue branch. + By default, the local gbp conf files are imported (so that gbp sees the + same settings on the development/pq branc as on the packaging branch). + Files defined with this option will appear as one monolithic commit in + the development/patch-queue branch. + * implement --new-packaging-dir cmdline option. + Used for setting the packaging directory to be used in the new orphan + packaging branch. Defaults to --packaging-dir so that the gbp.conf files + are more likely to work without modification. + * fail gracefully on invalid config files + * support '%(upstreamversion)s' as a replacable string in the pq branch + name. +- Changes to git-buildpackage-rpm + * patch-export from development branch. + Adds git-buildpackage-rpm --patch-export support for the 'orphan + packaging' development model (where packaging files and development sources are kept in separate + branches). + New functionality: + 1. If patch-export is enabled and gbp detects that the current branch + has a development/patch-queue branch it exports the patches from there, + instead of the tip of the packaging branch. + 2. If gbp detects that the current (or exported) branch is a + development/patch-queue branch it automatically enables patch-export + and exports packaging files from the base branch (instead of the + development/patch-queue branch. + Also, add a new '--git-patch-export-rev' command line option with which + the user can explicitly set the treeish from which patches are generated + (i.e. HEAD..) + * fix spec file vcs update when doing git-tag-only + * change default export directory. + So that the git working directory is not dirtied, by default. +- Changes ti git-import-orig-rpm: + * disable --merge by default. + Merging upstream to packaging does not usually make sense with rpm + packages. Merely, it can create confusion cause unapplicable patches to + be generated. + * implement --create-missing-branches option. + * implement automatic downloading. + Automatically try to download the archive if the archive filename points + to a remote location. + * get archive from spec file. + Try to get archive path/filename from spec file if no file name is given + on the command line. This should make version bumps more + straightforward: just update version number in the spec file and run + 'git-import-orig-rpm'. +- git-import-orig: implement --create-missing-branches option. +- Fixes and new features in GitRepository class + * GitRepository/get_commit_info: correctly handle file renames/copies. + * GitRepository.create_branch: add 'force' option + * GitRepository.archive: add 'paths' option + * GitRepository/git_command: strip stderr output in case of error. + * GitRepository/add_remote_repo: fix the 'tags' argument. + * GitRepository: allow interactive commands. + * GitRepository: fix the 'edit' mode in commit methods. + * GitRepository.commit_files: add committer_info and edit arguments. + * GitRepository.commit_all: add committer_info argument. +- Fixes and new features in internal rpm/spec support + * rpm.SpecFile: add 'specpath' attribute + * rpm: correctly handle 'NoSource' and 'NoPatch' tags in spec. + * rpm: Implement spec_from_repo() helper function + * rpm: track all "section" directives in spec file. + * rpm: add gbp.rpm.changelog module. + This new module contains basic containers and functionality for parsing + and updating rpm changelogs. It is coupled with the rpm packaging policy + class which now has definitions for rpm changelog formatting. + * rpm: support for getting/setting changelog in spec. + SpecFile objects now support reading and writing of the %changelog + section. + * rpm: store full path of spec file sources +- Fix detection of prefix directory in tarballs + gbs import failed to import tarball properly if paths in the archive + were prefixed with "./". + +* Tue Jan 07 2014 Markus Lehtonen 0.6.8 +- Rebase on top of upstream version 0.6.8 + * Mon Dec 02 2013 Markus Lehtonen 0.6.6 - Rebase on top of upstream version 0.6.6 - UpstreamSource: fix archive prefix guessing diff --git a/packaging/git-buildpackage.spec b/packaging/git-buildpackage.spec index 4fc97ad1..289e931a 100644 --- a/packaging/git-buildpackage.spec +++ b/packaging/git-buildpackage.spec @@ -3,7 +3,7 @@ Name: git-buildpackage Summary: Build packages from git -Version: 0.6.6 +Version: 0.6.8 Release: 0 Group: Development/Tools/Building License: GPLv2 @@ -100,7 +100,7 @@ Group: Development/Tools/Building Requires: %{name}-common = %{version}-%{release} Requires: rpm Requires: %{rpm_python_pkg_name} -Provides: tizen-gbp-rpm = 20131202 +Provides: tizen-gbp-rpm = 20140306 %description rpm Set of tools from Debian that integrate the package build system with Git. -- cgit v1.2.3 From 50c33fd0132beaf4583cadeb3bf24f1a776a3643 Mon Sep 17 00:00:00 2001 From: Markus Lehtonen Date: Wed, 9 Apr 2014 16:48:45 +0300 Subject: pq-rpm: don't create pq branch when switching Pq branch must be created with 'import'. Signed-off-by: Markus Lehtonen --- gbp/scripts/pq_rpm.py | 6 +----- tests/component/rpm/test_pq_rpm.py | 18 ++++++++++++------ 2 files changed, 13 insertions(+), 11 deletions(-) diff --git a/gbp/scripts/pq_rpm.py b/gbp/scripts/pq_rpm.py index d8fa88f8..6380ee22 100755 --- a/gbp/scripts/pq_rpm.py +++ b/gbp/scripts/pq_rpm.py @@ -473,11 +473,7 @@ def switch_to_pq_branch(repo, branch, options): spec = parse_spec(options, repo, branch) pq_branch = pq_branch_name(branch, options, spec.version) if not repo.has_branch(pq_branch): - upstream_commit = find_upstream_commit(repo, spec, options.upstream_tag) - try: - repo.create_branch(pq_branch, rev=upstream_commit) - except GitRepositoryError as err: - raise GbpError("Cannot create patch-queue branch: %s" % err) + raise GbpError("Branch '%s' does not exist" % pq_branch) gbp.log.info("Switching to branch '%s'" % pq_branch) repo.set_branch(pq_branch) diff --git a/tests/component/rpm/test_pq_rpm.py b/tests/component/rpm/test_pq_rpm.py index ba8648d2..8b6f4145 100644 --- a/tests/component/rpm/test_pq_rpm.py +++ b/tests/component/rpm/test_pq_rpm.py @@ -158,11 +158,16 @@ class TestPqRpm(RpmRepoTestBase): repo = self.init_test_repo('gbp-test') pkg_files = repo.list_files() branches = repo.get_local_branches() + ['development/master'] - upstr_files = ['dummy.sh', 'Makefile', 'README'] - # Switch to pq branch + # Switch to non-existent pq-branch should fail + eq_(mock_pq(['switch']), 1) + self._check_log(-1, ".*Branch 'development/master' does not exist") + + # Import and switch to base branch and back to pq + eq_(mock_pq(['import']), 0) eq_(mock_pq(['switch']), 0) - self._check_repo_state(repo, 'development/master', branches, - upstr_files) + self._check_repo_state(repo, 'master', branches) + eq_(mock_pq(['switch']), 0) + self._check_repo_state(repo, 'development/master', branches) # Switch back to packaging branch eq_(mock_pq(['switch']), 0) @@ -236,6 +241,9 @@ class TestPqRpm(RpmRepoTestBase): eq_(mock_pq(['apply']), 1) self._check_log(-1, "gbp:error: No patch name given.") + # Create a pristine pq-branch + repo.create_branch('development/master', 'upstream') + # Apply patch with tempfile.NamedTemporaryFile() as tmp_patch: tmp_patch.write(repo.show('master:%s' % 'my.patch')) @@ -362,8 +370,6 @@ class TestPqRpm(RpmRepoTestBase): # Invalid branch name eq_(mock_pq(['import', '--pq-branch=foo:']), 1) self._check_log(-1, "gbp:error: Cannot create patch-queue branch") - eq_(mock_pq(['switch', '--pq-branch=foo:']), 1) - self._check_log(-1, "gbp:error: Cannot create patch-queue branch") # Try all possible keys in pq-branch format string eq_(mock_pq(['import', -- cgit v1.2.3 From dbb401b6405b5ad199a09a4fc108716faf8e4eb3 Mon Sep 17 00:00:00 2001 From: Markus Lehtonen Date: Wed, 19 Mar 2014 15:31:19 +0200 Subject: Tizen release 0.6.12-20140521 Signed-off-by: Markus Lehtonen --- debian/changelog | 47 ++++++++++++++++++++++++++++++++++++++ packaging/git-buildpackage.changes | 41 +++++++++++++++++++++++++++++++++ packaging/git-buildpackage.spec | 4 ++-- 3 files changed, 90 insertions(+), 2 deletions(-) diff --git a/debian/changelog b/debian/changelog index 5a874c07..81fe0634 100644 --- a/debian/changelog +++ b/debian/changelog @@ -47,6 +47,53 @@ git-buildpackage (0.6.13) unstable; urgency=medium -- Guido Günther Thu, 03 Apr 2014 21:31:38 +0200 +git-buildpackage (0.6.12-tizen20140521) unstable; urgency=low + + [ Markus Lehtonen ] + * Rebase on top of upstream version 0.6.12 + * Changes in rpm-ch + - add --message cmdline option + For giving the text for new changelog entry/entries, skipping git commit + messages entirely. + - implement '--all' option + If defined, git-rpm-ch uses all commits in the Git history. Also, + '--since' option is omitted. + - implement --color-scheme option + - use name (string) as the entry author + - internal refactoring + - fix crash in guessing the start commit + * Changes in pq-rpm + - implement --retain-history option + With this option defined gbp tries to preserve the history when + converting. That is, for each commit in the old branch create one + corresponding commit in the new orphan packaging branch. This works by + dumping packaging files and updating patches for each commit. However, + empty commits are not generated - these are caused e.g. by changes in + files that are ignored by patch-generation. + NOTE! Only valid for the 'convert' action. + - convert: don't try to commit empty set of patches + - make sure we always get a sane author + - slight unification of log messages + - decrease (default) verbosity a bit + - don't create pq branch when switching + * Changes in buildpackage-rpm + - buildpackage-rpm: fix desktop notifications + - buildpackage-rpm: remove --purge option + - guess/parse spec as early as possible + * Documentation + - Include man pages in RPM packages + - Add -doc subpackage to RPM packaging + - Build deb and rpm html docs in one docbook + - A multitude of small cosmetic fixes + * Other misc. internal changes + - GitRepository: implement create_tree() method + - rpm: suppress some verbosity when updating patches in spec file + + [ Li Jinjing ] + * Fix missing return value in get_current_branch method + + -- Markus Lehtonen Wed, 21 May 2014 16:32:46 +0300 + git-buildpackage (0.6.12) unstable; urgency=medium * [89f3005] Use a much simpler version to fix the command name in --help diff --git a/packaging/git-buildpackage.changes b/packaging/git-buildpackage.changes index d026530b..448846de 100644 --- a/packaging/git-buildpackage.changes +++ b/packaging/git-buildpackage.changes @@ -1,3 +1,44 @@ +* Wed May 21 2014 Markus Lehtonen tizen/0.6.12-20140521 +- Rebase on top of upstream version 0.6.12 +- Changes in rpm-ch + * add --message cmdline option + For giving the text for new changelog entry/entries, skipping git commit + messages entirely. + * implement '--all' option + If defined, git-rpm-ch uses all commits in the Git history. Also, + '--since' option is omitted. + * implement --color-scheme option + * use name (string) as the entry author + * internal refactoring + * fix crash in guessing the start commit +- Changes in pq-rpm + * implement --retain-history option + With this option defined gbp tries to preserve the history when + converting. That is, for each commit in the old branch create one + corresponding commit in the new orphan packaging branch. This works by + dumping packaging files and updating patches for each commit. However, + empty commits are not generated - these are caused e.g. by changes in + files that are ignored by patch-generation. + NOTE! Only valid for the 'convert' action. + * convert: don't try to commit empty set of patches + * make sure we always get a sane author + * slight unification of log messages + * decrease (default) verbosity a bit + * don't create pq branch when switching +- Changes in buildpackage-rpm + * buildpackage-rpm: fix desktop notifications + * buildpackage-rpm: remove --purge option + * guess/parse spec as early as possible +- Documentation + * Include man pages in RPM packages + * Add -doc subpackage to RPM packaging + * Build deb and rpm html docs in one docbook + * A multitude of small cosmetic fixes +- Other misc. internal changes + * GitRepository: implement create_tree() method + * rpm: suppress some verbosity when updating patches in spec file + * [ Li Jinjing ] Fix missing return value in get_current_branch method + * Thu Mar 06 2014 Markus Lehtonen tizen/0.6.8-20140306 - Rebase on top of upstream version 0.6.8 - Introduce git-rpm-ch tool. diff --git a/packaging/git-buildpackage.spec b/packaging/git-buildpackage.spec index 289e931a..d70c870d 100644 --- a/packaging/git-buildpackage.spec +++ b/packaging/git-buildpackage.spec @@ -3,7 +3,7 @@ Name: git-buildpackage Summary: Build packages from git -Version: 0.6.8 +Version: 0.6.12 Release: 0 Group: Development/Tools/Building License: GPLv2 @@ -100,7 +100,7 @@ Group: Development/Tools/Building Requires: %{name}-common = %{version}-%{release} Requires: rpm Requires: %{rpm_python_pkg_name} -Provides: tizen-gbp-rpm = 20140306 +Provides: tizen-gbp-rpm = 20140521 %description rpm Set of tools from Debian that integrate the package build system with Git. -- cgit v1.2.3 From 3d54122699d97ea541420fc3e5370f31ee7633b2 Mon Sep 17 00:00:00 2001 From: Markus Lehtonen Date: Thu, 5 Jun 2014 13:56:16 +0300 Subject: packaging: rebase on top of upstream version 0.6.15 Signed-off-by: Markus Lehtonen --- debian/changelog | 6 ++++++ packaging/git-buildpackage.changes | 3 +++ packaging/git-buildpackage.spec | 4 ++-- 3 files changed, 11 insertions(+), 2 deletions(-) diff --git a/debian/changelog b/debian/changelog index 81fe0634..1c253ade 100644 --- a/debian/changelog +++ b/debian/changelog @@ -1,3 +1,9 @@ +git-buildpackage (0.6.15-tizen20140605) UNRELEASED; urgency=low + + * Rebase on top of upstream version 0.6.15 + + -- Markus Lehtonen Thu, 05 Jun 2014 13:54:54 +0300 + git-buildpackage (0.6.15) unstable; urgency=medium * [5cde49a] Revert "Determine build_dir upfront" diff --git a/packaging/git-buildpackage.changes b/packaging/git-buildpackage.changes index 448846de..7842c803 100644 --- a/packaging/git-buildpackage.changes +++ b/packaging/git-buildpackage.changes @@ -1,3 +1,6 @@ +* Thu Jun 05 2014 Markus Lehtonen debian/0.6.15-212-gdbb401b +- Rebase on top of upstream version 0.6.15 + * Wed May 21 2014 Markus Lehtonen tizen/0.6.12-20140521 - Rebase on top of upstream version 0.6.12 - Changes in rpm-ch diff --git a/packaging/git-buildpackage.spec b/packaging/git-buildpackage.spec index d70c870d..e15fc0f7 100644 --- a/packaging/git-buildpackage.spec +++ b/packaging/git-buildpackage.spec @@ -3,7 +3,7 @@ Name: git-buildpackage Summary: Build packages from git -Version: 0.6.12 +Version: 0.6.15 Release: 0 Group: Development/Tools/Building License: GPLv2 @@ -100,7 +100,7 @@ Group: Development/Tools/Building Requires: %{name}-common = %{version}-%{release} Requires: rpm Requires: %{rpm_python_pkg_name} -Provides: tizen-gbp-rpm = 20140521 +Provides: tizen-gbp-rpm = 20140605 %description rpm Set of tools from Debian that integrate the package build system with Git. -- cgit v1.2.3 From 2b7e580be069d30b86bb8633c57c653a0a328b81 Mon Sep 17 00:00:00 2001 From: Markus Lehtonen Date: Tue, 27 May 2014 10:09:36 +0300 Subject: docs: manpages for the rpm tools Signed-off-by: Markus Lehtonen --- docs/Makefile | 5 + docs/common.ent | 7 + docs/main.sgml | 2 + docs/man.gbp-buildpackage-rpm.sgml | 12 + docs/man.gbp-import-orig-rpm.sgml | 11 + docs/man.gbp-import-srpm.sgml | 11 + docs/man.gbp-pq-rpm.sgml | 11 + docs/man.gbp-rpm-ch.sgml | 11 + docs/manpages/gbp-buildpackage-rpm.sgml | 764 ++++++++++++++++++++++++++++++++ docs/manpages/gbp-import-orig-rpm.sgml | 324 ++++++++++++++ docs/manpages/gbp-import-srpm.sgml | 262 +++++++++++ docs/manpages/gbp-pq-rpm.sgml | 399 +++++++++++++++++ docs/manpages/gbp-rpm-ch.sgml | 406 +++++++++++++++++ docs/manpages/man.seealso-rpm.sgml | 12 + docs/manpages/manpages-rpm.ent | 10 + docs/manual-rpm.sgml | 8 + packaging/git-buildpackage.spec | 7 + 17 files changed, 2262 insertions(+) create mode 100644 docs/man.gbp-buildpackage-rpm.sgml create mode 100644 docs/man.gbp-import-orig-rpm.sgml create mode 100644 docs/man.gbp-import-srpm.sgml create mode 100644 docs/man.gbp-pq-rpm.sgml create mode 100644 docs/man.gbp-rpm-ch.sgml create mode 100644 docs/manpages/gbp-buildpackage-rpm.sgml create mode 100644 docs/manpages/gbp-import-orig-rpm.sgml create mode 100644 docs/manpages/gbp-import-srpm.sgml create mode 100644 docs/manpages/gbp-pq-rpm.sgml create mode 100644 docs/manpages/gbp-rpm-ch.sgml create mode 100644 docs/manpages/man.seealso-rpm.sgml create mode 100644 docs/manpages/manpages-rpm.ent diff --git a/docs/Makefile b/docs/Makefile index 5cd83a05..cd657017 100644 --- a/docs/Makefile +++ b/docs/Makefile @@ -3,6 +3,7 @@ MAN1S = \ gbp \ gbp-buildpackage \ + gbp-buildpackage-rpm \ gbp-clone \ gbp-config \ gbp-create-remote-repo \ @@ -10,8 +11,12 @@ MAN1S = \ gbp-import-dsc \ gbp-import-dscs \ gbp-import-orig \ + gbp-import-orig-rpm \ + gbp-import-srpm \ gbp-pq \ + gbp-pq-rpm \ gbp-pull \ + gbp-rpm-ch \ $(NULL) MAN5S = gbp.conf diff --git a/docs/common.ent b/docs/common.ent index 69a703f6..6fc532c4 100644 --- a/docs/common.ent +++ b/docs/common.ent @@ -24,11 +24,18 @@ debuild"> gbp.conf"> + Markus"> + Lehtonen"> + markus.lehtonen@linux.intel.com"> + + 1"> gbp buildpackage-rpm"> gbp import-orig-rpm"> gbp import-srpm"> gbp pq-rpm"> + gbp rpm-ch"> rpmbuild"> + wget"> Debian"> Git"> diff --git a/docs/main.sgml b/docs/main.sgml index bd1d97d7..7689bf7e 100644 --- a/docs/main.sgml +++ b/docs/main.sgml @@ -6,6 +6,8 @@ %VERSION; %MANPAGES; + + %MANPAGES.RPM; %CHAPTERS; diff --git a/docs/man.gbp-buildpackage-rpm.sgml b/docs/man.gbp-buildpackage-rpm.sgml new file mode 100644 index 00000000..8752d576 --- /dev/null +++ b/docs/man.gbp-buildpackage-rpm.sgml @@ -0,0 +1,12 @@ + + %COMMON; + + %MANPAGES; +]> + + +git-buildpackage-rpm Manual +&man.gbp.buildpackage.rpm; + diff --git a/docs/man.gbp-import-orig-rpm.sgml b/docs/man.gbp-import-orig-rpm.sgml new file mode 100644 index 00000000..621b11da --- /dev/null +++ b/docs/man.gbp-import-orig-rpm.sgml @@ -0,0 +1,11 @@ + + %COMMON; + + %MANPAGES; +]> + + +git-buildpackage-rpm Manual +&man.gbp.import.orig.rpm; + diff --git a/docs/man.gbp-import-srpm.sgml b/docs/man.gbp-import-srpm.sgml new file mode 100644 index 00000000..7efd8b10 --- /dev/null +++ b/docs/man.gbp-import-srpm.sgml @@ -0,0 +1,11 @@ + + %COMMON; + + %MANPAGES; +]> + + +git-buildpackage-rpm Manual +&man.gbp.import.srpm; + diff --git a/docs/man.gbp-pq-rpm.sgml b/docs/man.gbp-pq-rpm.sgml new file mode 100644 index 00000000..11615085 --- /dev/null +++ b/docs/man.gbp-pq-rpm.sgml @@ -0,0 +1,11 @@ + + %COMMON; + + %MANPAGES; +]> + + +git-buildpackage-rpm Manual +&man.gbp.pq.rpm; + diff --git a/docs/man.gbp-rpm-ch.sgml b/docs/man.gbp-rpm-ch.sgml new file mode 100644 index 00000000..63fed8d0 --- /dev/null +++ b/docs/man.gbp-rpm-ch.sgml @@ -0,0 +1,11 @@ + + %COMMON; + + %MANPAGES; +]> + + +git-buildpackage-rpm Manual +&man.gbp.rpm.ch; + diff --git a/docs/manpages/gbp-buildpackage-rpm.sgml b/docs/manpages/gbp-buildpackage-rpm.sgml new file mode 100644 index 00000000..b3c9e6c1 --- /dev/null +++ b/docs/manpages/gbp-buildpackage-rpm.sgml @@ -0,0 +1,764 @@ + + +
+ &rpm-email; +
+ + &rpm-firstname; + &rpm-surname; + +
+ gbp-buildpackage-rpm + &rpm-mansection; + + + git-buildpackage-rpm + gbp-buildpackage-rpm + Build RPM packages from a Git repository + + + + &gbp-buildpackage-rpm; + + + + + [auto|on|off] + COLOR_SCHEME + [auto|on|off] + =DIRECTORY + =VENDOR + TREEISH + BRANCH_NAME + BRANCH_NAME + + + BUILD_CMD + CLEAN_CMD + + GPG-KEYID + COMMAND + COMMAND + COMMAND + COMMAND + + + TAG-FORMAT + TAG-FORMAT + + + [TAG|BRANCH|TREEISH] + DIRECTORY + LEVEL + PREFIX + DIRECTORY + =DIRECTORY + =DIRECTORY + =DIRECTORY + =DIRECTORY + =DIRECTORY + =DIRECTORY + TREEISH + + DIRECTORY + FILEPATH + + + + + + TREEISH + THRESHOLD + REGEX + COMMITISH + + =TAG_FORMAT + + + + DESCRIPTION + + &gbp-buildpackage-rpm; is used to build RPM packages from a &git; + repository. It is an RPM counterpart for the &gbp-buildpackage; tool that + is designed for building Debian packages. + + + &gbp-buildpackage-rpm; will, in order: + + + + + Verify that it is being executed from the proper location. + + + + + Verify that the repository doesn't contain any uncommitted source + changes. + + + + + Verify that it is being executed from the correct branch. + + + + + Export packaging files to a separate build area. + + + + + Create an orig source tarball if it doesn't exist. + + + + + Call rpmbuild(1) (or the application + specified via ), passing along all + command line arguments that don't start with --git-. + + + + + (Optionally) tag the tree after a successful build. + + + + + (Optionally) call a post build hook - e.g. to run + rpmlint. + + + + + (Optionally) call a post tag hook - e.g. to push the results to a + remote repository after creating the tag. + + + + + + OPTIONS + + + + + + + Don't abort if there are uncommitted changes in the source tree or + the current branch doesn't match the + PACKAGING-BRANCH. + + + + + + + + + Don't abort if there are untracked files in the source tree. + + + + + + + + + Add a git tag after a successful build. + + + + + + + + + Use BUILD_CMD instead of + rpmbuild -ba. + + + + + + + + + Use CLEAN_CMD. + + + + + + + + + Verbose execution + + + + + [auto|on|off] + + + + Whether to use colored output. + + + + + COLOR_SCHEME + + + + Colors to use in output (when color is enabled). The format for + COLOR_SCHEME is + '<debug>:<info>:<warning>:<error>'. + Numerical values and color names are accepted, empty fields imply + the default color. For example --git-color-scheme='cyan:34::' would + show debug messages in cyan, info messages in blue and other messages + in default (i.e. warning and error messages in red). + + + + + [auto|on|off] + + + + Whether to send a desktop notification after the build. + + + + + =DIRECTORY + + + + Base directory under which temporary directories are created. + + + + + =VENDOR + + + + Distribution vendor name. + + + + + =BRANCH_NAME + + + + Branch to build the orig tarball from if + is set to + BRANCH. Default is + upstream. + + + + + =BRANCH_NAME + + + + If you're not on this branch when invoking &gbp-buildpackage-rpm; it + will fail. Default is master. This is done + to make sure you don't accidentally release from a topic branch. Not + being on this branch will be ignored when using + . + + + + + =BRANCH_NAME + + + + Name (format string) of the patch-queue/development branch. This + makes building easier when working with separate packaging and + development branches. + + + If is enabled and + &gbp-buildpackage-rpm; detects that the current branch has a + patch-queue/development branch it exports the patches from there + instead of the tip of the current branch (unless + is defined, of course). + Similarly, if the current branch is a patch-queue/development branch + &gbp-buildpackage-rpm; will automatically enable patch-export and + export packaging files from the packaging branch instead of the + current branch (unless ) is defined. + + + + + + + + + Don't check if the current branch matches + PACKAGING-BRANCH. + + + + + + + + + Include git submodules in the orig tarball. + + + + + + + + + GPG sign all created tags. + + + + + GPG-KEYID + + + + Use this keyid for gpg signing tags. + + + + + COMMAND + + + + Excecute COMMAND after tagging a new + version. + + + Exported environment variables are: GBP_TAG (the name + of the generated tag), GBP_BRANCH (the branch the + package was build from) and GBP_SHA1 (the sha1 of the + commit the tag was created at). + + + + + COMMAND + + + + Execute COMMAND after successful + build. + + + Exported environment variables are: GBP_CHANGES_FILE + (the name of the generated changes file), + GBP_BUILD_DIR (the build dir). + + + + + COMMAND + + + + Execute COMMAND after exporting the source + tree. + + + Exported environment variables are: GBP_GIT_DIR (the + repository the package is being built from), + GBP_TMP_DIR (the temporary directory where the sources + have been initially exported). + + + + + COMMAND + + + + Execute COMMAND from the build directory + before calling rpmbuild or the application + specified via . + + + Exported environment variables are: GBP_GIT_DIR (the + repository the package is being built from), + GBP_BUILD_DIR (the build dir). + + + + + + + + + Enable builder. Note: causes the + postbuild hook to be disabled, too. + + + + + + + + + Enable running all (cleaner, postexport, prebuild, postbuild, and + posttag) hooks. Note: the command is + not affected by this option. + + + + + TAG-FORMAT + + + + Use this tag format when tagging released versions of the package. + + + + + TAG-FORMAT + + + + Use this tag format when looking for tags of upstream versions, + default is upstream/%(version)s. + + + + + + + + + Force creation of an orig tarball (overwriting a pre-existing one if + present). + + + + + + + + + Don't try to create any orig tarball. + + + + + DIRECTORY + + + + Export the packaging files from the current branch head (or the + treeish object given via to + DIRECTORY before building. + + + + + =DIRECTORY + + =DIRECTORY + + =DIRECTORY + + =DIRECTORY + + =DIRECTORY + + =DIRECTORY + + + + Build subdirectory options for rpmbuild builder. Of these + and + also affects where + &gbp-buildpackage-rpm; exports the packaging files under the export + directory. + + + + + TREEISH + + + + Instead of exporting the current branch head, export the treeish + object TREEISH. The special name + INDEX exports the current index, + WC.TRACKED exports all files tracked by + Git in the current working copy as is, + WC.UNTRACKED exports all untracked files + too whereas WC (or + WC.IGNORED) exports all files in the + current working directory, even ignored files. + + + + + + + + + Only export packaging files without running builder. + + + + + DIRECTORY + + + + Subdirectory that contains the RPM packaging files. + + + + + FILEPATH + + + + Relative path to the spec file to use. Special value + auto causes &gbp-buildpackage-rpm; to + search and guess. Other values cause the + option to be ignored: the + directory of the spec file is used, instead. + + + + + [TAG|BRANCH|TREEISH] + + + + How to find the upstream sources used to generate the tarball. + TAG looks at a tag corresponding to the + version in the changelog. BRANCH looks at + the upstream branch given via the + option. Other values are + interpreted as treeishs. + + + This doesn't have any effect if + is being used. + + + + + DIRECTORY + + + + Search for original tarballs in DIRECTORY + instead of generating them. + + + + + LEVEL + + + + Specifies the upstream tarball compression level if an upstream + tarball needs to be built. + + + + + PREFIX + + + + Prefix (directory) to be used when generating tarballs. Special value + auto causes &gbp-buildpackage-rpm; to + guess the prefix. + + + + + + + + + Don't build, only tag and run post-tag hooks. + + + + + + + + + Don't fail tag operations if a tag with the same version already + exists, but, overwrite the existing tag, instead. + + + + + + + + + Use pristine-tar when generating the upstream tarball if it doesn't + exist. + + + + + + + + + Commit the pristine-tar delta to the pristine-tar branch if a new + tarball was generated and the pristine-tar data isn't already there. + + + + + + + + + Create patches from the commits between the upstream version and + export-treeish. That is, after exporting packaging files (from the + pacakging directory) &gbp-buildpackage-rpm; creates one patch per + commit (similar to git-format-patch) and updates the spec file in the + export dir. You use to + specify the tip commit of the patch series. + + + + + TREEISH + + + + Use TREEISH as the tip commit of the patch + series instead of the default - i.e. treeish from which the packaging + files are exported (which is defined with + . + + + + + THRESHOLD + + + + Compress (auto-generated) patches larger than given + THRESHOLD bytes. Special value 0 disabled + patch compression. + + + + + REGEX + + + + Exclude changes to path(s) matching REGEX + in patch generation. + + + + + COMMITISH + + + + Squash commits up to the given COMMITISH + into one monolitic diff. Could be used if one wants to squash commits + from an upstream release up to a stable update into a single diff + (commits on top of the stable would generate one patch per commit as + usual). The format is '<commit_ish>[:<filename_base>]', + i.e. commitish optionally followed by a colon and the desired + filename base for the diff (suffix '.diff' is automatically added by + &gbp-buildpackage-rpm;). Magic word 'HEAD' translates to the + patch-export-treeish when given as the squash-point. This allows one + to configure gbp to always squash all commits into one monolithic + diff. + + + + + + + + + Whether the patch files should start with a number or not. + + + + + =TAG_FORMAT + + + + &gbp-buildpackage-rpm; always automatically sets/updates the 'VCS:' + tag in the spec file after exporting. This option defines the format + string for the 'VCS:' tag. An empty value causes no 'VCS:' tag to be + inserted and possible old 'VCS:' tag to be removed. Otherwise, the + old 'VCS:' tag is updated or a new 'VCS:' tag is added if one does + not exist. In the format string '%(tagname)s' expands to the long tag + name (from git-describe) and '%(commit)s' expans to the sha1 of the + exported commit. + + + + + + + EXAMPLES + + Only build a source RPM with &rpmbuild; + + + &gbp-buildpackage-rpm; -bs + + + Build an RPM package with &rpmbuild; on a custom branch with the uncommitted + changes included. + + + &gbp-buildpackage-rpm; --git-ignore-branch --git-export=WC.UNTRACKED + + + + &man.gbp.config-files; + + All options in the config files are specified without the 'git-' prefix. + + + + SEE ALSO + + , + , + , + , + + rpmbuild + 8 + , + , + &man.seealso.common; + + + + AUTHOR + + &rpm-username; &rpm-email; + + +
diff --git a/docs/manpages/gbp-import-orig-rpm.sgml b/docs/manpages/gbp-import-orig-rpm.sgml new file mode 100644 index 00000000..8e2635be --- /dev/null +++ b/docs/manpages/gbp-import-orig-rpm.sgml @@ -0,0 +1,324 @@ + + +
+ &rpm-email; +
+ + &rpm-firstname; + &rpm-surname; + +
+ + gbp-import-orig-rpm + &rpm-mansection; + + + git-import-orig-rpm + gbp-import-orig-rpm + Import an upstream source into a git repository. + + + + &gbp-import-orig-rpm; + + &man.common.options.synopsis; + =VENDOR + VERSION + + BRANCH-NAME + BRANCH-NAME + DIRECTORY + + TAG-NAME + + GPG-KEYID + TAG-FORMAT + PATTERN + + + + + + + + UPSTREAM-SOURCE + + + + + DESCRIPTION + + &gbp-import-orig-rpm; is an basically identical to the &gbp-import-orig; + tool, with only some rpm-specific functionality added and some + Debian-specific functionality removed. + + + &gbp-import-orig-rpm; imports UPSTREAM-SOURCE + into the &git; repository. UPSTREAM-SOURCE can + either be a gzip, bzip2, lzma or xz compressed tar archive, a zip archive + or an already unpacked source tree. If it is already of the form + package-name-version.tar.gz, the version + information is read from the tarball's filename otherwise it can be given + on the command line via . If the source + package name or version can't be determined &gbp-import-orig-rpm; will + prompt for it unless is given. + + + &gbp-import-orig-rpm; tries to download the archive from a remote server if + a remote URL is given. In addition, if no + UPSTREAM-SOURCE is given &gbp-import-orig-rpm; + takes the archive URI from the spec file - this makes it possible to import + a new upstream version just by bumping the version number in the spec file + and running &gbp-import-orig-rpm; (assuming that the spec file contains + a full URL for the archive and its filename automatically follows the + package version e.g. by using the %{version} macro, of course). + + + The sources are placed on the upstream branch (default: + upstream) and tagged. + + + + OPTIONS + + &man.common.options.description; + + + =VENDOR + + + + Distribution vendor name. + + + + + =VERSION + VERSION + + + The upstream version number. + + + + + + + + Merge the upstream branch to the packaging branch after import. + + + + + =BRANCH-NAME + + + + The branch in the Git repository the upstream sources are put + onto. Default is upstream. + + + + + =BRANCH-NAME + + + + The branch in the Git repository the package is being developed on, + default is master. After importing the new + sources on the upstream branch, &gbp-import-orig-rpm; will try to + merge the new version onto this branch. + + + + + DIRECTORY + + + + Subdirectory that contains the RPM packaging files. + &gbp-import-orig-rpm; uses this to try to find a spec file which, in + turn, is used to get the upstream source archive URI if one is not + specified on the command line. + + + + + + + + + Create missing upstream branch if it does not exist. + + + + + =TAG-NAME + + + + Add TAG-NAME as additional parent to the + commit of the upstream tarball. Useful when upstream uses git and you + want to link to it's revision history. + + + + + + + + + GPG sign all created tags. + + + + + GPG-KEYID + + + + Use this keyid for gpg signing tags. + + + + + TAG-FORMAT + + + + Use this tag format when tagging upstream versions, + default is upstream/%(version)s. + + + + + MSG-FORMAT + + + + Use this format string for the commit message when importing upstream + versions, default is + Imported Upstream version %(version)s. + + + + + PATTERN + + + + Filter out files glob-matching pattern. Can be given multiple times. + + + + + + + + + Generate pristine-tar delta file. + + + + + + + + + If using a filter also filter the files out of the tarball + passed to pristine-tar. + + + + + FILENAME + + + + Filename to record to pristine-tar. This does not alter the tarball + content, just the filename with which the tarball can be checked out + with pristine-tar. + + + + + PREFIX + + + + Prefix (directory) to be used when importing sources into + pristine-tar. Only takes effect when + is used. Special value auto causes &gbp-import-orig-rpm; to guess + the prefix when importing unpacked sources, or, not to change the + prefix when importing source archives. + + + + Using this option will alter the source archive that is imported to + pristine-tar! That is, pristine-tar does not produce and identical + copy of the original tarball (but the mangled tarball, instead). + + + + + + + + + Run CMD after the import. + + + + + + + + Run command interactively, i.e. ask package name and version if + needed. + + + + + + + EXAMPLES + + Download and import a new upstream version using the informantion from the + spec file + + + &gbp-import-orig-rpm; + + + After manually downloading an upstream import it + + + &gbp-import-orig-rpm; ../upstream-tarball-0.1.tar.gz + + + Import unpacked sources + + + &gbp-import-orig-rpm; --orig-prefix=upstream-0.1 ../upstream/ + + + + &man.gbp.config-files; + + + SEE ALSO + + , + , + , + , + &man.seealso.common; + + + + AUTHOR + + &rpm-username; &rpm-email; + + +
diff --git a/docs/manpages/gbp-import-srpm.sgml b/docs/manpages/gbp-import-srpm.sgml new file mode 100644 index 00000000..91f6c0a5 --- /dev/null +++ b/docs/manpages/gbp-import-srpm.sgml @@ -0,0 +1,262 @@ + + +
+ &rpm-email; +
+ + &rpm-firstname; + &rpm-surname; + +
+ + gbp-import-srpm + &rpm-mansection; + + + git-import-srpm + gbp-import-srpm + Import source RPM packages into a Git repository + + + + &gbp-import-srpm; + &man.common.options.synopsis; + =VENDOR + + + BRANCH-NAME + TAG-FORMAT + + DIRECTORY + + PATTERN + GPG-KEYID + + + + BRANCH-NAME + TAG-FORMAT + + SRPM + + + &gbp-import-srpm; + + + + URL + SRC.RPM + DIRECTORY + + + + + DESCRIPTION + + &gbp-import-srpm; imports an RPM source package into a &git; repository, + notes the package version in the commit logs, and commits the change. All + information, including package name, version and upstream source is + automatically detected from the source package. The tool supports importing + both archived (src.rpm files) or unpacked (directory) source RPMs. + + + + OPTIONS + + &man.common.options.description; + + + =VENDOR + + + + Distribution vendor name. + + + + + =BRANCH-NAME + + + + The branch in the &git; repository the upstream sources are put + onto. Default is upstream. + + + + + =BRANCH-NAME + + + + The branch in the &git; repository the packaging files are put + onto. Default is master. + + + + + + + + + GPG sign all created tags. + + + + + GPG-KEYID + + + + Use this keyid for gpg signing tags. + + + + + TAG-FORMAT + + + + Use this tag format when tagging released versions, + default is %(vendor)s/%(version)s. + + + + + TAG-FORMAT + + + + Use this tag format when tagging upstream versions, + default is upstream/%(version)s. + + + + + DIRECTORY + + + + Subdirectory where to put the RPM packaging files. + + + + + + + + + Import patches to the packaging branch. That is, apply and commit all + patches (that are not marked for manual maintenance) into the + packaging branch after importing other packaging files. The patch + files are automatically removed from the packaging directory and the + spec file if all patches are successufully applied. This option is + ignored if is used. + + + + + PATTERN + + + + Filter out files glob-matching pattern. Can be given multiple times. + + + + + + + + + Generate pristine-tar delta file. + + + + + + + + + Download the source package instead of looking for it in the local + file system. The argument can either be a plain package name or an + URI. The former uses yumdownloader to download the + source while the later uses &wget;. + + + + + + + + + Allow to re-import a package with an already existing version. This + will not re-import the upstream sources - only packaging files will + be re-imported. + + + + + + + + + Use the author identity as the comitter when importing upstream + sources and packaging files. + + + + + + + + + Create missing upstream and/or packaging branch if missing. + + + + + + + + + Import packaging files into an orphan branch that will not be based + on the upstream branch. Useful if you want to maintain (non-native) + package using the 'orphan-packaging' model. This option have no + effect if is used. + + + + + + + + + Treat the package as native package. No separate upstream branch or + upstream tags will be created. + + + + + + + &man.gbp.config-files; + + + SEE ALSO + + + , + , + , + , + &man.seealso.common; + + + + AUTHOR + + &rpm-username; &rpm-email; + + +
diff --git a/docs/manpages/gbp-pq-rpm.sgml b/docs/manpages/gbp-pq-rpm.sgml new file mode 100644 index 00000000..30616635 --- /dev/null +++ b/docs/manpages/gbp-pq-rpm.sgml @@ -0,0 +1,399 @@ + + +
+ &rpm-email; +
+ + &rpm-firstname; + &rpm-surname; + +
+ + gbp-pq-rpm + &rpm-mansection; + + + gbp-pq-rpm + Manage patches and development branches in Git + + + + &gbp-pq-rpm; + &man.common.options.synopsis; + =VENDOR + BRANCH-NAME + BRANCH-NAME + DIRECTORY + FILEPATH + TAG-FORMAT + + FILES + TREEISH + THRESHOLD + REGEX + COMMITISH + + DIRECTORY + + + + + + + + + + + + + DESCRIPTION + + &gbp-pq-rpm; helps in managing patches and development branch(es) for + packages that are maintained with &gbp;. It designed to be used for + packages that are maintained using the "orphan-packaging" model. + &gbp-pq-rpm; has multiple subcommands, or actions, for working with the + branches and patches. + + + &gbp-pq-rpm; makes it easy to do source code development on a separate + development branch (patch-queue branch in Debian git-buildpackage terms). + For example, if the packaging files would be stored in + master the associated development branch would + be development/master. + + + + ACTIONS + + + + + + + Create a development (patch-queue) branch by applying all patches + from the packaging branch on top of the upstream version. The patches + must apply without fuzz. + + + + + + + + + Export patches from the development branch into the packaging branch. + It generates patches (one-per-commit) from the development branch and + updates the spec file accordingly. It doesn't automatically commit + the changes though - they need to verified and committed manually. + + + + + + + + + Switch to the development branch and rebase it against the current + upstream version (indicated in the spec file of the associated + packaging branch). + + + + + + + + + Drop (delete) the development branch associated to the current + branch. For example, you're on branch foo + this would drop branch development/foo. + + + + + + + + + Add a single patch to the development branch - similar to using + git-am. + + + + + + + + + Switch between the development branch and the associated packaging + branch. + + + + + + + + + Convert a package from the "joint-packaging" maintenance model and + git-layout to the "orphan-packaging" model. It takes the content of + the packaging directory, auto-generates patches and puts these into a + new orphan packaging branch. You can use the + to try to preserve as much of the + git history as possible. Converting is a one-time action - conversion + back to the "joint-packaging" model is not supported (yet). + + + + + + + OPTIONS + + &man.common.options.description; + + + =VENDOR + + + + Distribution vendor name. + + + + + =BRANCH-NAME + + + + Branch the packaging files are being maintained on. Only relevant if + a invariable/single development (pq-branch) is defined with + , in which case this is used as the + "base" branch. + + + + + =BRANCH_NAME + + + + Name (format string) of the development (patch-queue) branch. The + following string fields are accepted: "%(branch)s" (the base branch, + i.e. the packaging branch that the development branch is associated + to), "%(upstreamversion)s" (the upstream version), "%(release)s" (the + rpm patchlevel, i.e. Release), "%(version)s" (full rpm package + version). + + + + + DIRECTORY + + + + Subdirectory that contains the RPM packaging files. + + + + + FILEPATH + + + + Relative path to the spec file to use. Special value + auto causes &gbp; to search and guess. + Other values cause the option to be + ignored: the directory of the spec file is used, instead. + + + + + TAG-FORMAT + + + + Use this tag format when looking for tags of upstream versions, + default is upstream/%(version)s. + + + + + + + + Import even if the development (patch-queue) branch already exists. + Only valid for the import action. + + + + + FILES + + + + Comma-separated list of additional file(s) to import from packaging + branch. These will appear as one monolithic patch in the development + (patch-queue) branch. By default, the local gbp conf files are + imported in order to try to ensure that gbp sees the same settings on + the development (pq) branch as on the packaging branch. + + + + + TREEISH + + + + Export patches from TREEISH instead of the + default which is HEAD of the development (patch-queue) branch. + + + + + THRESHOLD + + + + Compress patches larger than given + THRESHOLD bytes. Special value 0 disabled + patch compression. + + + + + REGEX + + + + Exclude changes to path(s) matching REGEX + in patch generation. + + + + + COMMITISH + + + + Squash commits up to the given COMMITISH + into one monolitic diff. Could be used if one wants to squash commits + from an upstream release up to a stable update into a single diff + (commits on top of the stable would generate one patch per commit as + usual). The format is '<commit_ish>[:<filename_base>]', + i.e. commitish optionally followed by a colon and the desired + filename base for the diff (suffix '.diff' is automatically added by + &gbp;). Magic word 'HEAD' translates to the patch-export-treeish when + given as the squash-point. This allows one to configure gbp to + always squash all commits into one monolithic diff. + + + + + + + + + Whether the patch files should start with a number or not. + + + + + DIRECTORY + + + + Directory where packaging files are put in the new orphan packaging + branch after convert. If is not + defined, packaging-dir is used. + + + + + + + + + Try to preserve as much history as possible when converting. That is, + for each commit in the old branch create one corresponding commit in + the new orphan packaging branch. However, commits that will not + generate any changes are skipped (i.e. no empty commits are + generated) - these are caused e.g. by changes in files that are + ignored by patch-generation. + + + + + + + META TAGS + + When exporting patches from a patch-queue branch &gbp-pq-rpm; will look at + the commit message for special tags it recognizes. All tags need to start + at the first column and require at least one whitespace after the colon. + + + + + + + + Ignores the commit, no patch is generated out of it. + + + + + + + + + Conditional patch. Put patch inside "%if <expression>" in the + spec file. + + + + + + + + + Conditional patch. Put patch inside "%ifarch <expression>" in + the spec file. + + + + + + For example, the following commit message: + + + Fix around a problem in Fedora + + which is not applicable elsewhere. + + Gbp-Rpm: If 0%{?fedora} + + + Will result something like this in the spec file: + + + # 0001-Fix-around-a-problem-in-Fedora.patch + %if 0%{?fedora} + %patch0 -p1 + %endif + + + + SEE ALSO + + , + + + + + AUTHOR + + &rpm-username; &rpm-email; + + +
diff --git a/docs/manpages/gbp-rpm-ch.sgml b/docs/manpages/gbp-rpm-ch.sgml new file mode 100644 index 00000000..9f6ae999 --- /dev/null +++ b/docs/manpages/gbp-rpm-ch.sgml @@ -0,0 +1,406 @@ + + +
+ &rpm-email; +
+ + &rpm-firstname; + &rpm-surname; + +
+ + gbp-rpm-ch + &rpm-mansection; + + + git-rpm-ch; + gbp-rpm-ch; + Generate the RPM changelog from git commit messages + + + + &gbp-rpm-ch; + &man.common.options.synopsis; + =VENDOR + BRANCH-NAME + TAG-FORMAT + + DIRECTORY + FILEPATH + FILEPATH + + + MESSAGE + COMMITISH + + + + + NUMBER + REV-FORMAT + GIT-LOG-OPTIONS + + EDITOR + + + + GPG-KEYID + CUSTOMIZATION-FILE + [PATH1 PATH2] + + + + DESCRIPTION + + &gbp-rpm-ch; reads git commit messages up to the current tip of the current + branch and updates the RPM changelog from them. + + + By default, &gbp-rpm-ch; tries to guess the last &git; commit documented in + the changelog. Alternatively, can be used to + tell &gbp-rpm-ch; at which point it should start in the &git; history, or, + to use all commits from the &git; history. + + + The additional path arguments can be used to restrict the repository paths + &gbp-rpm-ch; looks at. For even more detailed control, you can use + to restrict the generated changelog entries + further. E.g. by using + "--author=Foo Bar". + + + + OPTIONS + + &man.common.options.description; + + + =VENDOR + + + + Distribution vendor name. + + + + + =BRANCH-NAME + + + + The branch in the Git repository the package is being developed on, + default is master. + + + + + + + + + Don't check if the current branch matches + PACKAGING-BRANCH. + + + + + TAG-FORMAT + + + + Tag format used, when tagging releases, + default is %(vendor)s/%(version)s + + + + + DIRECTORY + + + + Subdirectory that contains the RPM packaging files. + + + + + FILEPATH + + + + Relative path to the changelog file to use. Special value + auto causes &gbp; to guess, + SPEC uses the spec file, + CHANGES uses a separate changelog file + (name derived spec file name with .spec suffix replaced by .changes). + Guessing logic is simple: use separate changelog file if it is found, + otherwise use the spec file. + + + + + FILEPATH + + + + Relative path to the spec file to use. Special value + auto causes &gbp; to search and guess. + Other values cause the option to be + ignored: the directory of the spec file is used, instead. + + + + + + + + + Use all commits from the Git history, overrides + . + + + + + COMMITTISH + + + + Start reading commit messages at + COMMITTISH. + + + + + + + + + Do not create a new changelog section, just update the last + changelog section. + + + + + + + + + Include the full commit message in the changelog output. + + + + + GIT-LOG-OPTIONS + + + + Options passed on verbatim to git-log(1). + + + + + N + + + + Include N digits of the commit id in the + changelog entry. Default is to not include any commit ids at all. + + + + + REV-FORMAT + + + + Format string to use for revision field in the changelog header. The + following string fields are accepted: + %(upstreamversion)s the upstream version; + %(release)s the rpm patchlevel, i.e. + Release; %(version)s full rpm package + version; %(tagname)s tag/commit, i.e. + basically what git-describe would give. + If empty or not defined the default from packaging policy is used. + + + + + REGEX + + + + Ignore commit lines matching REGEX + when generating the changelog. + + + + + + + + + Use user.name and user.email from + git-config(1) for the changelog header. + + + + + + + + + Whether to spawn an editor: always, when doing a release or never. + + + + + + + + + The editor to use for editing the changelog. + + + + + + + + + Text to use for new changelog entries. Git history and the commit + messages, including and + options are ignored in this case. + + + + + + + + + Commit the changes and create a packaging (release) tag. All + changelog modifications (and importantly, all other staged changes) + are committed to git before creating the tag. This option makes it + possible to create a release and correctly document the the tag name + in the rpm changelog (by using %(tagname)s in the + string). + + + + + + + + + Don't fail tag operations if a tag with the same version already + exists, but, overwrite the existing tag, instead. + + + + + + + + + GPG sign all created tags. + + + + + GPG-KEYID + + + + Use this keyid for gpg signing tags. + + + + + CUSTOMIZATION-FILE + + + + Load Python code from CUSTOMIZATION-FILE. + At the moment, the only useful thing the code can do is define a + custom ChangelogEntryFormatter class. + + + + + + + META TAGS + + Additional to the above options the formatting of the new changelog entries + (one-per-commit) in the changelog can be modified by special tags (called + Meta Tags) given in the git commit message. The tags must start at the + first column of a commit message but can appear on any line. They are of + the form : VALUE. Valid + Meta Tags are: + + + + : ACTION + + + + Supported actions are: Ignore which will + ignore this commit when generating new changelog entries. + Short which will only use the description + (the first line) of the commit message when generating the changelog + entry (useful when is given) and + Full which will use the full commit + message when generating the changelog entry (useful when + is not given). + + + + + : BUGNUMBER + + + + Indicate in the changelog that the bug was addressed by this commit. + + + + + + The following git commit message: + + + Document meta tags + + so one doesn't have to consult the manual + + Git-Rpm-Ch: Short + Closes: #636088 + + + Results in this changelog entry: + + + - Document meta tags (Closes: #636088) + + + + &man.gbp.config-files; + + + SEE ALSO + + , + , + , + , + &man.seealso.common; + + Cl2vcs, + + + + AUTHOR + + &rpm-username; &rpm-email; + + +
diff --git a/docs/manpages/man.seealso-rpm.sgml b/docs/manpages/man.seealso-rpm.sgml new file mode 100644 index 00000000..a146875d --- /dev/null +++ b/docs/manpages/man.seealso-rpm.sgml @@ -0,0 +1,12 @@ + + rpmbuild + 1 + , + + git + 1 + , + + pristine-tar + 1 + , diff --git a/docs/manpages/manpages-rpm.ent b/docs/manpages/manpages-rpm.ent new file mode 100644 index 00000000..0839a3bf --- /dev/null +++ b/docs/manpages/manpages-rpm.ent @@ -0,0 +1,10 @@ + + + + + + + + + +%COMMON.OPTIONS; diff --git a/docs/manual-rpm.sgml b/docs/manual-rpm.sgml index 2e587306..1de37ffd 100644 --- a/docs/manual-rpm.sgml +++ b/docs/manual-rpm.sgml @@ -10,6 +10,14 @@ &ch.development-rpm; &ch.building-rpm; + + Command Reference + &man.gbp.buildpackage.rpm; + &man.gbp.import.orig.rpm; + &man.gbp.import.srpm; + &man.gbp.pq.rpm; + &man.gbp.rpm.ch; + Copyright &gbp.copyright; diff --git a/packaging/git-buildpackage.spec b/packaging/git-buildpackage.spec index e15fc0f7..40f4ab80 100644 --- a/packaging/git-buildpackage.spec +++ b/packaging/git-buildpackage.spec @@ -241,6 +241,13 @@ done %{_bindir}/*rpm* %{python_sitelib}/gbp/scripts/*rpm*.py* %{python_sitelib}/gbp/rpm/*py* +%if %{with docs} +%{_mandir}/man1/gbp-buildpackage-rpm.1* +%{_mandir}/man1/gbp-import-orig-rpm.1* +%{_mandir}/man1/gbp-import-srpm.1* +%{_mandir}/man1/gbp-pq-rpm.1* +%{_mandir}/man1/gbp-rpm-ch.1* +%endif %if %{with docs} -- cgit v1.2.3 From 9fa2dab904a0242c11e5f12069b923b1281b2264 Mon Sep 17 00:00:00 2001 From: Markus Lehtonen Date: Mon, 2 Jun 2014 10:14:52 +0300 Subject: tristate: implement __nonzero__() method Returns False if tristate is 'off', otherwise True ('on' or 'auto'). Change-Id: I6ade27fc85c6d05ed69dc694495b70725070d9c5 Signed-off-by: Markus Lehtonen --- gbp/tristate.py | 11 +++++++++++ 1 file changed, 11 insertions(+) diff --git a/gbp/tristate.py b/gbp/tristate.py index 93610605..0a800ecd 100644 --- a/gbp/tristate.py +++ b/gbp/tristate.py @@ -66,6 +66,17 @@ class Tristate(object): else: return 'off' + def __nonzero__(self): + """ + >>> Tristate('on').__nonzero__() + True + >>> Tristate('auto').__nonzero__() + True + >>> Tristate('off').__nonzero__() + False + """ + return self._state is not self.OFF + @property def state(self): """Get current state""" -- cgit v1.2.3 From d673c34ada960fbe47014d1795772378e3f6f2df Mon Sep 17 00:00:00 2001 From: Markus Lehtonen Date: Mon, 2 Jun 2014 11:57:34 +0300 Subject: buildpackage-rpm: new 'commitish' keyword for spec vcs tag Add a new keyword '%(commitish)s' that can be used in the --git-spec-vcs-tag option. This will be translated to the sha1 of the commitish (i.e. tag or commit). That is, if you export a tag you will get the sha1 of the tag object - not resolving to a commit object unlike '%(commit)s' does. Change-Id: Ia764e15ac0dc090dde9f8e709f31f66e62120abb Signed-off-by: Markus Lehtonen --- gbp/scripts/buildpackage_rpm.py | 34 ++++++++++++++++++++-------------- 1 file changed, 20 insertions(+), 14 deletions(-) diff --git a/gbp/scripts/buildpackage_rpm.py b/gbp/scripts/buildpackage_rpm.py index 1ada6381..b28ee8ca 100755 --- a/gbp/scripts/buildpackage_rpm.py +++ b/gbp/scripts/buildpackage_rpm.py @@ -203,6 +203,23 @@ def get_current_branch(repo): return branch +def get_vcs_info(repo, treeish): + """Get the info for spec vcs tag""" + info = {} + try: + info['tagname'] = repo.describe(treeish, longfmt=True, always=True, + abbrev=40) + info['commit'] = repo.rev_parse('%s^0' % treeish) + info['commitish'] = repo.rev_parse('%s' % treeish) + except GitRepositoryError: + # If tree is not commit-ish, expect it to be from current HEAD + info['tagname'] = repo.describe('HEAD', longfmt=True, always=True, + abbrev=40) + '-dirty' + info['commit'] = repo.rev_parse('HEAD') + '-dirty' + info['commitish'] = info['commit'] + return info + + def guess_export_params(repo, options): """Get commit and tree from where to export packaging and patches""" tree = None @@ -650,8 +667,7 @@ def main(argv): repo.delete_tag(tag) create_packaging_tag(repo, tag, commit=tree, version=spec.version, options=options) - tree_name = tag - commit_sha1 = repo.rev_parse('%s^0' % tag) + vcs_info = get_vcs_info(repo, tag) if options.posttag: sha = repo.rev_parse("%s^{}" % tag) Command(options.posttag, shell=True, @@ -659,19 +675,9 @@ def main(argv): 'GBP_BRANCH': branch, 'GBP_SHA1': sha})() else: - try: - tree_name = repo.describe(tree, longfmt=True, always=True, - abbrev=40) - commit_sha1 = repo.rev_parse('%s^0' % tree) - except GitRepositoryError: - # If tree is not commit-ish, expect it to be from current HEAD - tree_name = repo.describe('HEAD', longfmt=True, always=True, - abbrev=40) + '-dirty' - commit_sha1 = repo.rev_parse('HEAD') + '-dirty' + vcs_info = get_vcs_info(repo, tree) # Put 'VCS:' tag to .spec - spec.set_tag('VCS', None, - options.spec_vcs_tag % {'tagname': tree_name, - 'commit': commit_sha1}) + spec.set_tag('VCS', None, options.spec_vcs_tag % vcs_info) spec.write_spec_file() except CommandExecFailed: -- cgit v1.2.3 From dca47ece0d2f0de035dc1d2199ac9716ab9b559f Mon Sep 17 00:00:00 2001 From: Markus Lehtonen Date: Thu, 5 Jun 2014 16:37:25 +0300 Subject: rpm-ch: implement --commit option Change-Id: I89b05175d3c4f3def796b20b4e65c53af7d96d13 Signed-off-by: Markus Lehtonen --- docs/manpages/gbp-rpm-ch.sgml | 25 +++++++++++++++++++------ gbp/scripts/rpm_ch.py | 19 ++++++++++++------- tests/component/rpm/test_rpm_ch.py | 22 ++++++++++++++++++++++ 3 files changed, 53 insertions(+), 13 deletions(-) diff --git a/docs/manpages/gbp-rpm-ch.sgml b/docs/manpages/gbp-rpm-ch.sgml index 9f6ae999..37a42726 100644 --- a/docs/manpages/gbp-rpm-ch.sgml +++ b/docs/manpages/gbp-rpm-ch.sgml @@ -41,6 +41,7 @@ GIT-LOG-OPTIONS EDITOR + @@ -272,17 +273,29 @@ + + + + + + Commit changes to git after modifying changelog. Importantly, in + addition to the changelog modifications all other staged changes are + committed, too, making it possible to update other files in the same + commit. + + + - Commit the changes and create a packaging (release) tag. All - changelog modifications (and importantly, all other staged changes) - are committed to git before creating the tag. This option makes it - possible to create a release and correctly document the the tag name - in the rpm changelog (by using %(tagname)s in the - string). + Commit the changes and create a packaging (release) tag. Similarly to + , all staged changes are committed to git + before creating the tag. This option makes it possible to create a + release and correctly document the the tag name in the rpm changelog + (by using %(tagname)s in the + string). diff --git a/gbp/scripts/rpm_ch.py b/gbp/scripts/rpm_ch.py index 09586d00..b509bd39 100755 --- a/gbp/scripts/rpm_ch.py +++ b/gbp/scripts/rpm_ch.py @@ -131,7 +131,7 @@ def check_repo_state(repo, options): raise GbpError("Use --ignore-branch to ignore or " "--packaging-branch to set the branch name.") # Check unstaged changes - if options.tag: + if options.commit: unstaged = [] status = repo.status() for group, files in status.iteritems(): @@ -141,7 +141,7 @@ def check_repo_state(repo, options): gbp.log.error("Unstaged changes in:\n %s" % '\n '.join(unstaged)) raise GbpError("Please commit or stage your changes before using " - "the --tag option") + "the --commit or --tag option") def parse_spec_file(repo, options): @@ -325,7 +325,7 @@ def update_changelog(changelog, entries, repo, spec, options): rev_str_fields = dict(spec.version, version=RpmPkgPolicy.compose_full_version(spec.version), vendor=options.vendor) - if options.tag: + if options.commit: # Get fake information for the to-be-created git commit commit_info = {'author': GitModifier(date=now), 'committer': GitModifier(date=now)} @@ -444,6 +444,8 @@ def parse_args(argv): help="text to use as new changelog entries - git commit " "messages and the --since are ignored in this case") # Commit/tag group options + commit_grp.add_option("-c", "--commit", action="store_true", + help="commit changes") commit_grp.add_option("--tag", action="store_true", help="commit the changes and create a packaging/release" "tag") @@ -454,6 +456,8 @@ def parse_args(argv): commit_grp.add_config_file_option(option_name="keyid", dest="keyid") options, args = parser.parse_args(argv[1:]) + if options.tag: + options.commit = True if not options.changelog_revision: options.changelog_revision = RpmPkgPolicy.Changelog.header_rev_format @@ -492,12 +496,13 @@ def main(argv): if editor_cmd and not options.message: gbpc.Command(editor_cmd, [ch_file.path])() - if options.tag: - if options.retag and repo.has_tag(tag): - repo.delete_tag(tag) + if options.commit: edit = True if editor_cmd else False commit_changelog(repo, ch_file, author, committer, edit) - create_packaging_tag(repo, tag, 'HEAD', spec.version, options) + if options.tag: + if options.retag and repo.has_tag(tag): + repo.delete_tag(tag) + create_packaging_tag(repo, tag, 'HEAD', spec.version, options) except (GbpError, GitRepositoryError, ChangelogError, NoSpecError) as err: if len(err.__str__()): diff --git a/tests/component/rpm/test_rpm_ch.py b/tests/component/rpm/test_rpm_ch.py index 968cfd4a..b8c3bcaf 100644 --- a/tests/component/rpm/test_rpm_ch.py +++ b/tests/component/rpm/test_rpm_ch.py @@ -265,6 +265,28 @@ class TestRpmCh(RpmRepoTestBase): header = self.read_file('packaging/gbp-test-native.changes')[0] ok_(re.match(r'.+ foobar$', header)) + def test_option_commit(self): + """Test the --commit cmdline option""" + repo = self.init_test_repo('gbp-test') + + # Check unclean repo + with open('untracked-file', 'w') as fobj: + fobj.write('this file is not tracked\n') + with open('foo.txt', 'a') as fobj: + fobj.write('new stuff\n') + + # Unstaged file (foo.txt) -> failure + eq_(mock_ch(['--commit', '--since=HEAD^']), 1) + self._check_log(-1, 'gbp:error: Please commit or stage your changes') + + # Add file, update and commit, untracked file should be ignored + repo.add_files('foo.txt') + sha = repo.rev_parse('HEAD') + eq_(mock_ch(['--commit', '--since=HEAD^']), 0) + eq_(sha, repo.rev_parse('HEAD^')) + eq_(repo.get_commit_info('HEAD')['files'], + {'M': ['foo.txt', 'gbp-test.spec']}) + def test_tagging(self): """Test commiting/tagging""" repo = self.init_test_repo('gbp-test-native') -- cgit v1.2.3 From 0f1fc7f430e6f25ab5f8516ca5f8a79291f86c50 Mon Sep 17 00:00:00 2001 From: Markus Lehtonen Date: Thu, 5 Jun 2014 17:25:25 +0300 Subject: rpm-ch: implement --commit-msg option Change-Id: I10e2d4ad30dfd02c73fd0f318375715202ec36c2 Signed-off-by: Markus Lehtonen --- docs/manpages/gbp-rpm-ch.sgml | 10 ++++++++++ gbp/scripts/rpm_ch.py | 22 ++++++++++++++++++---- tests/component/rpm/test_rpm_ch.py | 11 +++++++++++ 3 files changed, 39 insertions(+), 4 deletions(-) diff --git a/docs/manpages/gbp-rpm-ch.sgml b/docs/manpages/gbp-rpm-ch.sgml index 37a42726..59adaa5a 100644 --- a/docs/manpages/gbp-rpm-ch.sgml +++ b/docs/manpages/gbp-rpm-ch.sgml @@ -285,6 +285,16 @@ + + MSG-FORMAT + + + + Format string for the commit message when committing changes + (when is given). + + + diff --git a/gbp/scripts/rpm_ch.py b/gbp/scripts/rpm_ch.py index b509bd39..3caaac2e 100755 --- a/gbp/scripts/rpm_ch.py +++ b/gbp/scripts/rpm_ch.py @@ -356,11 +356,22 @@ def update_changelog(changelog, entries, repo, spec, options): top_section.append_entry(entry) return (tag, commit_info['author'], commit_info['committer']) -def commit_changelog(repo, changelog, author, committer, edit): +def create_commit_message(spec, options): + """Generate commit message""" + fields = spec.version + fields['version'] = version=RpmPkgPolicy.compose_full_version(spec.version) + fields['vendor'] = options.vendor + try: + return options.commit_msg % fields + except KeyError as err: + raise GbpError("Unknown key %s in commit-msg string, " + "only %s are accepted" % (err, fields.keys())) + +def commit_changelog(repo, changelog, message, author, committer, edit): """Commit changelog and create a packaging/release tag""" repo.add_files(changelog.path) - repo.commit_staged("Update changelog", author_info=author, - committer_info=committer, edit=edit) + repo.commit_staged(message, author_info=author, committer_info=committer, + edit=edit) def parse_args(argv): @@ -446,6 +457,8 @@ def parse_args(argv): # Commit/tag group options commit_grp.add_option("-c", "--commit", action="store_true", help="commit changes") + commit_grp.add_config_file_option(option_name="commit-msg", + dest="commit_msg") commit_grp.add_option("--tag", action="store_true", help="commit the changes and create a packaging/release" "tag") @@ -498,7 +511,8 @@ def main(argv): if options.commit: edit = True if editor_cmd else False - commit_changelog(repo, ch_file, author, committer, edit) + msg = create_commit_message(spec, options) + commit_changelog(repo, ch_file, msg, author, committer, edit) if options.tag: if options.retag and repo.has_tag(tag): repo.delete_tag(tag) diff --git a/tests/component/rpm/test_rpm_ch.py b/tests/component/rpm/test_rpm_ch.py index b8c3bcaf..b69c517e 100644 --- a/tests/component/rpm/test_rpm_ch.py +++ b/tests/component/rpm/test_rpm_ch.py @@ -287,6 +287,17 @@ class TestRpmCh(RpmRepoTestBase): eq_(repo.get_commit_info('HEAD')['files'], {'M': ['foo.txt', 'gbp-test.spec']}) + def test_option_commit_msg(self): + """Test the --commit-msg cmdline option""" + repo = self.init_test_repo('gbp-test2') + + eq_(mock_ch(['--commit', '--since=HEAD^', '--commit-msg=Foo']), 0) + eq_(repo.get_commit_info('HEAD')['subject'], 'Foo') + + # Unknown key in format string causes failure + eq_(mock_ch(['--commit', '--since=HEAD^', '--commit-msg=%(foo)s']), 1) + self._check_log(-1, "gbp:error: Unknown key 'foo' in commit-msg string") + def test_tagging(self): """Test commiting/tagging""" repo = self.init_test_repo('gbp-test-native') -- cgit v1.2.3 From c54a7d81ddf924a9243d124dce1ee244967882ff Mon Sep 17 00:00:00 2001 From: Markus Lehtonen Date: Fri, 6 Jun 2014 12:39:15 +0300 Subject: rpm.policy: don't allow leading whitespace in bts meta tags Change-Id: Ib2d39739b4609c088b04b286adfb6aeb5e07f78a Signed-off-by: Markus Lehtonen --- gbp/rpm/policy.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/gbp/rpm/policy.py b/gbp/rpm/policy.py index 216bd53e..8f93d0fd 100644 --- a/gbp/rpm/policy.py +++ b/gbp/rpm/policy.py @@ -187,7 +187,7 @@ class RpmPkgPolicy(PkgPolicy): """ tags = {} other_lines = [] - bts_re = re.compile(r'^\s*(?P%s):\s*(?P.*)' % + bts_re = re.compile(r'^(?P%s):\s*(?P.*)' % ('|'.join(meta_tags)), re.I) bug_id_re = re.compile(cls.bug_id_re) for line in lines: -- cgit v1.2.3 From 818136d82ce121f9fc6f3fd98591cb1daee1bbc6 Mon Sep 17 00:00:00 2001 From: Markus Lehtonen Date: Fri, 6 Jun 2014 12:40:32 +0300 Subject: rpm-ch: implement --meta-bts option This gives the user the possibility to define what meta tags (in git commit message) git-rpm-ch recognizes as bug tracking system references. Or, makes it possible to disable bts meta tag tracking altogether. Change-Id: I7125ac951bf13816d43f1854868b15188bb92042 Signed-off-by: Markus Lehtonen --- docs/manpages/gbp-rpm-ch.sgml | 21 +++++++++++++++++++-- gbp/config.py | 4 ++++ gbp/rpm/policy.py | 15 ++++++++------- gbp/scripts/rpm_ch.py | 4 +++- tests/component/rpm/test_rpm_ch.py | 20 ++++++++++++++++++++ 5 files changed, 54 insertions(+), 10 deletions(-) diff --git a/docs/manpages/gbp-rpm-ch.sgml b/docs/manpages/gbp-rpm-ch.sgml index 59adaa5a..fbd28967 100644 --- a/docs/manpages/gbp-rpm-ch.sgml +++ b/docs/manpages/gbp-rpm-ch.sgml @@ -33,6 +33,7 @@ MESSAGE COMMITISH + META_TAGS @@ -170,6 +171,19 @@ + + META_TAGS + + + + Meta tags in the commit messages that are interpreted as bug tracking + system related references. The recognized bts references are added in + the generated changelog entries. See the META TAGS section below for + more information. The bts meta tag tracking feature can be disabled + by defining an empty string. + + + @@ -378,11 +392,14 @@ - : BUGNUMBER + : BUGNUMBER - Indicate in the changelog that the bug was addressed by this commit. + Indicate in the changelog entry that bug + BUGNUMBER was addressed in this commit. + The bts meta tags recognized by &gbp-rpm-ch; is actually defined by + the option. diff --git a/gbp/config.py b/gbp/config.py index ff673cf6..2d9c8fdd 100644 --- a/gbp/config.py +++ b/gbp/config.py @@ -608,6 +608,7 @@ class GbpOptionParserRpm(GbpOptionParser): 'changelog-revision' : '', 'spawn-editor' : 'always', 'editor-cmd' : 'vim', + 'meta-bts' : '(Close|Closes|Fixes|Fix)', } ) help = dict(GbpOptionParser.help) @@ -663,6 +664,9 @@ class GbpOptionParserRpm(GbpOptionParser): 'git-author': ("Use name and email from git-config for the changelog " "header, default is '%(git-author)s'"), + 'meta-bts': + ("Meta tags for the bts commands, default is " + "'%(meta-bts)s'"), } ) # vim:et:ts=4:sw=4:et:sts=4:ai:set list listchars=tab\:»·,trail\:·: diff --git a/gbp/rpm/policy.py b/gbp/rpm/policy.py index 8f93d0fd..93625545 100644 --- a/gbp/rpm/policy.py +++ b/gbp/rpm/policy.py @@ -167,8 +167,6 @@ class RpmPkgPolicy(PkgPolicy): # Maximum length for a changelog entry line max_entry_line_length = 76 - # Bug tracking system related meta tags recognized from git commit msg - bts_meta_tags = ("Close", "Closes", "Fixes", "Fix") # Regexp for matching bug tracking system ids (e.g. "bgo#123") bug_id_re = r'[A-Za-z0-9#_\-]+' @@ -180,15 +178,18 @@ class RpmPkgPolicy(PkgPolicy): @param lines: commit message @type lines: C{list} of C{str} - @param meta_tags: meta tags to look for - @type meta_tags: C{tuple} of C{str} + @param meta_tags: meta tags (regexp) to look for + @type meta_tags: C{str} @return: bts-ids per meta tag and the non-mathced lines @rtype: (C{dict}, C{list} of C{str}) """ + if not meta_tags: + return ({}, lines[:]) + tags = {} other_lines = [] - bts_re = re.compile(r'^(?P%s):\s*(?P.*)' % - ('|'.join(meta_tags)), re.I) + bts_re = re.compile(r'^(?P%s):\s*(?P.*)' % meta_tags, + re.I) bug_id_re = re.compile(cls.bug_id_re) for line in lines: match = bts_re.match(line) @@ -244,7 +245,7 @@ class RpmPkgPolicy(PkgPolicy): return None # Parse and filter out bts-related meta-tags - bts_tags, body = cls._parse_bts_tags(body, cls.bts_meta_tags) + bts_tags, body = cls._parse_bts_tags(body, kwargs['meta_bts']) # Additional filtering body = cls._extra_filter(body, kwargs['ignore_re']) diff --git a/gbp/scripts/rpm_ch.py b/gbp/scripts/rpm_ch.py index 3caaac2e..33058372 100755 --- a/gbp/scripts/rpm_ch.py +++ b/gbp/scripts/rpm_ch.py @@ -279,7 +279,8 @@ def entries_from_commits(changelog, repo, commits, options): for commit in commits: info = repo.get_commit_info(commit) entry_text = ChangelogEntryFormatter.compose(info, full=options.full, - ignore_re=options.ignore_regex, id_len=options.idlen) + ignore_re=options.ignore_regex, id_len=options.idlen, + meta_bts=options.meta_bts) if entry_text: entries.append(changelog.create_entry(author=info['author'].name, text=entry_text)) @@ -431,6 +432,7 @@ def parse_args(argv): help="use all commits from the Git history, overrides " "--since") # Formatting group options + format_grp.add_config_file_option(option_name="meta-bts", dest="meta_bts") format_grp.add_option("--no-release", action="store_false", default=True, dest="release", help="no release, just update the last changelog section") diff --git a/tests/component/rpm/test_rpm_ch.py b/tests/component/rpm/test_rpm_ch.py index b69c517e..db03c845 100644 --- a/tests/component/rpm/test_rpm_ch.py +++ b/tests/component/rpm/test_rpm_ch.py @@ -181,6 +181,26 @@ class TestRpmCh(RpmRepoTestBase): eq_(mock_ch(['--packaging-branch=foo', '--ignore-branch']), 0) + def test_option_meta_bts(self): + """Test parsing of the bts meta tags""" + repo = self.init_test_repo('gbp-test-native') + + # Create a dummy commit that references bts + with open('new-file', 'w') as fobj: + fobj.write('foobar\n') + repo.add_files('new-file') + repo.commit_all('Fix\n\nCloses: #123\nFixes: #456\n Fixes: #789') + + eq_(mock_ch(['--since=HEAD^']), 0) + content = self.read_file('packaging/gbp-test-native.changes') + # rpm-ch shouldn't have picked the ref with leading whitespace + eq_(content[1], '- Fix (Closes: #123) (Fixes: #456)\n') + + # Check the --meta-bts option + eq_(mock_ch(['--since=HEAD^', '--meta-bts=Fixes']), 0) + content = self.read_file('packaging/gbp-test-native.changes') + eq_(content[1], '- Fix (Fixes: #456)\n') + def test_option_no_release(self): """Test the --no-release cmdline option""" self.init_test_repo('gbp-test-native') -- cgit v1.2.3 From 46999caf5a9cfb4b91d9bc768bf7cea6de64612d Mon Sep 17 00:00:00 2001 From: Markus Lehtonen Date: Fri, 6 Jun 2014 10:22:31 +0300 Subject: gbp-dch: fix handling of the '--meta' option Make it effective again - previously it was totally ignored. Also, change it's default value to True to match the current behavior. Change-Id: I0fb1b5bb99aa8f622a7c52316e9320973333bad5 Signed-off-by: Markus Lehtonen --- gbp/config.py | 2 +- gbp/dch.py | 7 +++++-- 2 files changed, 6 insertions(+), 3 deletions(-) diff --git a/gbp/config.py b/gbp/config.py index 2d9c8fdd..a2c28def 100644 --- a/gbp/config.py +++ b/gbp/config.py @@ -123,7 +123,7 @@ class GbpOptionParser(OptionParser): 'tarball-dir' : '', 'ignore-new' : 'False', 'ignore-branch' : 'False', - 'meta' : 'False', + 'meta' : 'True', 'meta-closes' : 'Closes|LP', 'full' : 'False', 'id-length' : '0', diff --git a/gbp/dch.py b/gbp/dch.py index dc0149c3..f983234f 100644 --- a/gbp/dch.py +++ b/gbp/dch.py @@ -115,8 +115,11 @@ def format_changelog_entry(commit_info, options, last_commit=False): if options.idlen: entry[0] = '[%s] ' % commitid[0:options.idlen] + entry[0] - (bts_cmds, body) = extract_bts_cmds(body, options) - (thanks, body) = extract_thanks_info(body, options) + bts_cmds = {} + thanks = [] + if options.meta: + (bts_cmds, body) = extract_bts_cmds(body, options) + (thanks, body) = extract_thanks_info(body, options) body = filter_ignore_rx_matches(body, options) if 'full' in git_dch_cmds or (options.full and not 'short' in git_dch_cmds): -- cgit v1.2.3 From 0233ab89ba59925ffd627735f1b37ac0bc8cda86 Mon Sep 17 00:00:00 2001 From: Markus Lehtonen Date: Thu, 12 Jun 2014 12:04:09 +0300 Subject: notify: catch RuntimeError when importing pynotify Work around a problem in some distros (e.g. Fedora) where "import pynotify" crashes in RuntimeError in some cases, e.g. when DISPLAY env variable is not set. Signed-off-by: Markus Lehtonen --- gbp/notifications.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/gbp/notifications.py b/gbp/notifications.py index d60450e5..d628b269 100644 --- a/gbp/notifications.py +++ b/gbp/notifications.py @@ -28,7 +28,7 @@ def enable_notifications(): try: import pynotify notify_module = pynotify - except ImportError: + except (ImportError, RuntimeError): return False return notify_module.init("git-buildpackage") -- cgit v1.2.3 From b8ef37e4cb077abbc3e07da79c05608f9d7a702a Mon Sep 17 00:00:00 2001 From: Markus Lehtonen Date: Thu, 12 Jun 2014 15:42:21 +0300 Subject: buildpackage-rpm: fix exit code in case of GitRepositoryError Change-Id: I0afa3d5b744a912c63af66f2add9eb68bdc48f5b Signed-off-by: Markus Lehtonen --- gbp/scripts/buildpackage_rpm.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/gbp/scripts/buildpackage_rpm.py b/gbp/scripts/buildpackage_rpm.py index b28ee8ca..d288eec7 100755 --- a/gbp/scripts/buildpackage_rpm.py +++ b/gbp/scripts/buildpackage_rpm.py @@ -684,7 +684,7 @@ def main(argv): retval = 1 except GitRepositoryError as err: gbp.log.err("Git command failed: %s" % err) - ret = 1 + retval = 1 except GbpAutoGenerateError as err: if len(err.__str__()): gbp.log.err(err) -- cgit v1.2.3 From efc490c4a8da5ce7a0bd1bf4a20009c3a445bb47 Mon Sep 17 00:00:00 2001 From: Markus Lehtonen Date: Fri, 13 Jun 2014 13:31:48 +0300 Subject: buildpackage-rpm: always create tarball for native packages If the package is native, always (re-)create the source tarball, even if --git-no-create-orig is used. Not creating the tarball does not make much sense (and most probably just causes problems and confusion): for native packages there is no place for external tarball and no patches so we need to always have the correct sources (i.e. the exported revision) in the tarball. Change-Id: I3d4a46150a017de499d19ec4ae168e6f642325bd Signed-off-by: Markus Lehtonen --- gbp/scripts/buildpackage_rpm.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/gbp/scripts/buildpackage_rpm.py b/gbp/scripts/buildpackage_rpm.py index d288eec7..5a462966 100755 --- a/gbp/scripts/buildpackage_rpm.py +++ b/gbp/scripts/buildpackage_rpm.py @@ -617,7 +617,7 @@ def main(argv): # Get/build the orig tarball if is_native(repo, options): - if spec.orig_src and not options.no_create_orig: + if spec.orig_src: # Just build source archive from the exported tree gbp.log.info("Creating (native) source archive %s from '%s'" % (spec.orig_src['filename'], tree)) if spec.orig_src['compression']: -- cgit v1.2.3 From 4e28ad9e47a2c5e68bee9685ed6aa83ea37ec4fe Mon Sep 17 00:00:00 2001 From: Markus Lehtonen Date: Tue, 17 Jun 2014 11:08:38 +0300 Subject: import-orig-rpm: download tarball into parent directory Prevents dirtying of the current Git working directory. Change-Id: I6eca70b647130a380ba67d5b90fc23354b3974ea Signed-off-by: Markus Lehtonen --- gbp/scripts/import_orig_rpm.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/gbp/scripts/import_orig_rpm.py b/gbp/scripts/import_orig_rpm.py index 1d3972a4..b1247f1e 100755 --- a/gbp/scripts/import_orig_rpm.py +++ b/gbp/scripts/import_orig_rpm.py @@ -116,7 +116,7 @@ def find_source(spec, options, args): else: path = args[0] if re.match(r'[a-z]{1,5}://', path): - path = download_file('.', path) + path = download_file('..', path) return RpmUpstreamSource(path) -- cgit v1.2.3 From b04812b6f4e3f3859c4fd17b62ea9ed5d3bc035a Mon Sep 17 00:00:00 2001 From: Markus Lehtonen Date: Thu, 26 Jun 2014 10:01:18 +0300 Subject: ComponentTestBase: add check_files() method Change-Id: If23365cde15c2659aad039f19984a97968cd4545 Signed-off-by: Markus Lehtonen --- tests/component/__init__.py | 14 ++++++++++---- tests/component/rpm/test_import_orig_rpm.py | 8 -------- 2 files changed, 10 insertions(+), 12 deletions(-) diff --git a/tests/component/__init__.py b/tests/component/__init__.py index f029eb28..0c7e27f3 100644 --- a/tests/component/__init__.py +++ b/tests/component/__init__.py @@ -125,6 +125,15 @@ class ComponentTestBase(object): self._capture_log(False) + @staticmethod + def check_files(reference, filelist): + """Compare two file lists""" + extra = set(filelist) - set(reference) + missing = set(reference) - set(filelist) + assert_msg = "Unexpected files: %s, Missing files: %s" % \ + (list(extra), list(missing)) + assert not extra and not missing, assert_msg + @classmethod def _check_repo_state(cls, repo, current_branch, branches, files=None): """Check that repository is clean and given branches exist""" @@ -148,10 +157,7 @@ class ComponentTestBase(object): for dirname in dirnames: local.add(os.path.relpath(os.path.join(dirpath, dirname), repo.path) + '/') - extra = local - set(files) - ok_(not extra, "Unexpected files in repo: %s" % list(extra)) - missing = set(files) - local - ok_(not missing, "Files missing from repo: %s" % list(missing)) + cls.check_files(files, local) def _capture_log(self, capture=True): """ Capture log""" diff --git a/tests/component/rpm/test_import_orig_rpm.py b/tests/component/rpm/test_import_orig_rpm.py index 465c5fad..935e995f 100644 --- a/tests/component/rpm/test_import_orig_rpm.py +++ b/tests/component/rpm/test_import_orig_rpm.py @@ -96,14 +96,6 @@ class ImportOrigTestBase(ComponentTestBase): blobs = [obj[3] for obj in objs if obj[1] == 'blob'] return set(blobs) - @staticmethod - def check_files(reference, filelist): - """Compare two file lists""" - extra = set(filelist) - set(reference) - assert not extra, "Unexpected files: %s" % list(extra) - missing = set(reference) - set(filelist) - assert not missing, "Missing files: %s" % list(missing) - @classmethod def check_tree(cls, repo, treeish, filelist): """Check the contents (list of files) in a git treeish""" -- cgit v1.2.3 From aca165670f400c5d6b8556ff0849498f15546a60 Mon Sep 17 00:00:00 2001 From: Markus Lehtonen Date: Thu, 26 Jun 2014 10:05:01 +0300 Subject: ComponentTestBase: add ls_tree() method Change-Id: I53b06b41f613baad038117f55c27e7ebdaaadd7e Signed-off-by: Markus Lehtonen --- tests/component/__init__.py | 7 +++++++ tests/component/rpm/test_import_orig_rpm.py | 7 ------- 2 files changed, 7 insertions(+), 7 deletions(-) diff --git a/tests/component/__init__.py b/tests/component/__init__.py index 0c7e27f3..33caea70 100644 --- a/tests/component/__init__.py +++ b/tests/component/__init__.py @@ -134,6 +134,13 @@ class ComponentTestBase(object): (list(extra), list(missing)) assert not extra and not missing, assert_msg + @staticmethod + def ls_tree(repo, treeish): + """List contents (blobs) in a git treeish""" + objs = repo.list_tree(treeish, True) + blobs = [obj[3] for obj in objs if obj[1] == 'blob'] + return set(blobs) + @classmethod def _check_repo_state(cls, repo, current_branch, branches, files=None): """Check that repository is clean and given branches exist""" diff --git a/tests/component/rpm/test_import_orig_rpm.py b/tests/component/rpm/test_import_orig_rpm.py index 935e995f..27cfab45 100644 --- a/tests/component/rpm/test_import_orig_rpm.py +++ b/tests/component/rpm/test_import_orig_rpm.py @@ -89,13 +89,6 @@ class ImportOrigTestBase(ComponentTestBase): """Test case setup""" super(ImportOrigTestBase, self).setup() - @staticmethod - def ls_tree(repo, treeish): - """List contents (blobs) in a git treeish""" - objs = repo.list_tree(treeish, True) - blobs = [obj[3] for obj in objs if obj[1] == 'blob'] - return set(blobs) - @classmethod def check_tree(cls, repo, treeish, filelist): """Check the contents (list of files) in a git treeish""" -- cgit v1.2.3 From 64352000dd27733e961b2dce6fb511636a5b5073 Mon Sep 17 00:00:00 2001 From: Markus Lehtonen Date: Thu, 26 Jun 2014 13:35:19 +0300 Subject: ComponentTestBase: ignore system and user config User might have a system and/or user specific gbp config files. Disable these config files so that they don't affect the component tests. Change-Id: I04b83680016690ffa5a2433ad16e9968e54f6f4a Signed-off-by: Markus Lehtonen --- tests/component/__init__.py | 3 +++ 1 file changed, 3 insertions(+) diff --git a/tests/component/__init__.py b/tests/component/__init__.py index 33caea70..d8ad3e2d 100644 --- a/tests/component/__init__.py +++ b/tests/component/__init__.py @@ -88,6 +88,9 @@ class ComponentTestBase(object): # Create a top-level tmpdir for the test cls._tmproot = tempfile.mkdtemp(prefix='gbp_%s_' % cls.__name__, dir='.') + # Prevent local config files from messing up the tests + os.environ['GBP_CONF_FILES'] = '%(top_dir)s/.gbp.conf:' \ + '%(top_dir)s/debian/gbp.conf:%(git_dir)s/gbp.conf' @classmethod def teardown_class(cls): -- cgit v1.2.3 From 1ff2be668d6650103633566f86bd2e297d84c4fc Mon Sep 17 00:00:00 2001 From: Markus Lehtonen Date: Fri, 27 Jun 2014 08:36:29 +0300 Subject: GitRepository/has_submodules: add treeish argument For defining a Git treeish which to look into, instead of the current working copy. Change-Id: I27abd99f0416bd4300953d3c1bae2d99de3ab6c0 Signed-off-by: Markus Lehtonen --- gbp/git/repository.py | 13 +++++++++---- 1 file changed, 9 insertions(+), 4 deletions(-) diff --git a/gbp/git/repository.py b/gbp/git/repository.py index cd779152..6b21c252 100644 --- a/gbp/git/repository.py +++ b/gbp/git/repository.py @@ -1879,18 +1879,23 @@ class GitRepository(object): #{ Submodules - def has_submodules(self): + def has_submodules(self, treeish=None): """ Does the repo have any submodules? + @param treeish: look into treeish + @type treeish: C{str} @return: C{True} if the repository has any submodules, C{False} otherwise @rtype: C{bool} """ - if os.path.exists(os.path.join(self.path, '.gitmodules')): + if treeish: + try: + self.show('%s:.gitmodules' % treeish) + except GitRepositoryError: + return False return True - else: - return False + return os.path.exists(os.path.join(self.path, '.gitmodules')) def add_submodule(self, repo_path): -- cgit v1.2.3 From 8ada32322e53fb820b2ee3e18b7a2cc22e78322a Mon Sep 17 00:00:00 2001 From: Markus Lehtonen Date: Fri, 27 Jun 2014 08:42:33 +0300 Subject: buildpackage_rpm: check submodules from the exported treeish And not from the current working copy. Change-Id: I5320bd977073e7d69c02782a8a232b4a622553e1 Signed-off-by: Markus Lehtonen --- gbp/scripts/buildpackage_rpm.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/gbp/scripts/buildpackage_rpm.py b/gbp/scripts/buildpackage_rpm.py index 5a462966..6dc5b597 100755 --- a/gbp/scripts/buildpackage_rpm.py +++ b/gbp/scripts/buildpackage_rpm.py @@ -63,7 +63,7 @@ def git_archive(repo, spec, output_dir, tmpdir_base, treeish, prefix, # Remove extra slashes from prefix, will be added by git_archive_x funcs prefix = prefix.strip('/') try: - if repo.has_submodules() and with_submodules: + if repo.has_submodules(treeish) and with_submodules: repo.update_submodules() git_archive_submodules(repo, treeish, output, tmpdir_base, prefix, spec.orig_src['compression'], -- cgit v1.2.3 From 44ead55d0638ba3eebd730f249bbc7f209119848 Mon Sep 17 00:00:00 2001 From: Markus Lehtonen Date: Fri, 27 Jun 2014 08:39:15 +0300 Subject: tests/testutils: add directories arg to ls_* functions With this you can exclude directories from the listing returned by the ls_tar(), ls_zip() and ls_dir() functions. Change-Id: I8d586489a277c227a7fb61801e0b774f11e7a67e Signed-off-by: Markus Lehtonen --- tests/testutils.py | 15 ++++++++------- 1 file changed, 8 insertions(+), 7 deletions(-) diff --git a/tests/testutils.py b/tests/testutils.py index 587c273b..7cc7e361 100644 --- a/tests/testutils.py +++ b/tests/testutils.py @@ -119,34 +119,35 @@ def get_dch_default_urgency(): shutil.rmtree(tempdir) return urgency -def ls_dir(directory): +def ls_dir(directory, directories=True): """List the contents of directory, recurse to subdirectories""" contents = set() for root, dirs, files in os.walk(directory): prefix = '' if root != directory: prefix = os.path.relpath(root, directory) + '/' - contents.update(['%s%s' % (prefix, fname) for fname in files] + - ['%s%s' % (prefix, dname) for dname in dirs]) + contents.update(['%s%s' % (prefix, fname) for fname in files]) + if directories: + contents.update(['%s%s' % (prefix, dname) for dname in dirs]) return contents -def ls_tar(tarball): +def ls_tar(tarball, directories=True): """List the contents of tar archive""" tmpdir = tempfile.mkdtemp() try: tarobj = tarfile.open(tarball, 'r') tarobj.extractall(tmpdir) - return ls_dir(tmpdir) + return ls_dir(tmpdir, directories) finally: shutil.rmtree(tmpdir) -def ls_zip(archive): +def ls_zip(archive, directories=True): """List the contents of zip file""" tmpdir = tempfile.mkdtemp() try: zipobj = zipfile.ZipFile(archive, 'r') zipobj.extractall(tmpdir) - return ls_dir(tmpdir) + return ls_dir(tmpdir, directories) finally: shutil.rmtree(tmpdir) -- cgit v1.2.3 From c3c92011066dfbe9234d9de8e31d4b86463b20d4 Mon Sep 17 00:00:00 2001 From: Markus Lehtonen Date: Mon, 30 Jun 2014 17:12:48 +0300 Subject: buildpackage_rpm: fix crash when running prebuild hook GitRepository.git_dir is not callable. Change-Id: Ibc2040b8a36e60a9499b29ea675caa7a8fc8c968 Signed-off-by: Markus Lehtonen --- gbp/scripts/buildpackage_rpm.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/gbp/scripts/buildpackage_rpm.py b/gbp/scripts/buildpackage_rpm.py index 6dc5b597..20230abd 100755 --- a/gbp/scripts/buildpackage_rpm.py +++ b/gbp/scripts/buildpackage_rpm.py @@ -640,7 +640,7 @@ def main(argv): if not options.export_only and not options.tag_only: if options.prebuild: RunAtCommand(options.prebuild, shell=True, - extra_env={'GBP_GIT_DIR': repo.git_dir(), + extra_env={'GBP_GIT_DIR': repo.git_dir, 'GBP_BUILD_DIR': export_dir})(dir=export_dir) # Finally build the package: -- cgit v1.2.3 From 6b64f73538f8e516f7c5cbd608fe28d165b60b93 Mon Sep 17 00:00:00 2001 From: Markus Lehtonen Date: Mon, 30 Jun 2014 17:46:41 +0300 Subject: buildpackage_rpm: always run cleaner hook Change-Id: Ia13115e40a186e83c93cee3fe559005eb85858a3 Signed-off-by: Markus Lehtonen --- gbp/scripts/buildpackage_rpm.py | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/gbp/scripts/buildpackage_rpm.py b/gbp/scripts/buildpackage_rpm.py index 20230abd..5e24416e 100755 --- a/gbp/scripts/buildpackage_rpm.py +++ b/gbp/scripts/buildpackage_rpm.py @@ -548,8 +548,7 @@ def main(argv): try: tree, relative_spec_path = guess_export_params(repo, options) - if not options.export_only: - Command(options.cleaner, shell=True)() + Command(options.cleaner, shell=True)() if not options.ignore_new: (ret, out) = repo.is_clean(options.ignore_untracked) if not ret: -- cgit v1.2.3 From 12d8693963019a81ee737f33a2f7e95f46158935 Mon Sep 17 00:00:00 2001 From: Markus Lehtonen Date: Fri, 11 Jul 2014 15:23:19 +0300 Subject: buildpackage-rpm: add --git-no-build option Replaces and deprecates --git-export-only. The new option name is way better in line with the other option names. Change-Id: If54edf46eccaad4449ffe6b895b4958395e55c2e Signed-off-by: Markus Lehtonen --- gbp/scripts/buildpackage_rpm.py | 11 ++++++++++- 1 file changed, 10 insertions(+), 1 deletion(-) diff --git a/gbp/scripts/buildpackage_rpm.py b/gbp/scripts/buildpackage_rpm.py index 5e24416e..74a8aeb3 100755 --- a/gbp/scripts/buildpackage_rpm.py +++ b/gbp/scripts/buildpackage_rpm.py @@ -461,6 +461,9 @@ def parse_args(argv, prefix, git_treeish=None): cmd_group.add_config_file_option(option_name="posttag", dest="posttag", help="hook run after a successful tag operation, default is '%(posttag)s'") cmd_group.add_boolean_config_file_option(option_name="hooks", dest="hooks") + export_group.add_option("--git-no-build", action="store_true", + dest="no_build", + help="Don't run builder or the associated hooks") export_group.add_config_file_option(option_name="export-dir", dest="export_dir", type="path", help="Build topdir, also export the sources under EXPORT_DIR, default is '%(export-dir)s'") export_group.add_config_file_option(option_name="rpmbuild-builddir", dest="build_dir", type="path", @@ -504,6 +507,12 @@ def parse_args(argv, prefix, git_treeish=None): if not options.tag and not options.tag_only: gbp.log.err("'--%sretag' needs either '--%stag' or '--%stag-only'" % (prefix, prefix, prefix)) return None, None, None + # Use git_treeish as a way to print the warning only on the second parsing + # round + if options.export_only and git_treeish: + gbp.log.warn("Deprecated option '--git-export-only', please use " + "'--no-build' instead!") + options.no_build = True return options, args, builder_args @@ -636,7 +645,7 @@ def main(argv): extra_env={'GBP_GIT_DIR': repo.git_dir, 'GBP_TMP_DIR': export_dir})(dir=export_dir) # Do actual build - if not options.export_only and not options.tag_only: + if not options.no_build and not options.tag_only: if options.prebuild: RunAtCommand(options.prebuild, shell=True, extra_env={'GBP_GIT_DIR': repo.git_dir, -- cgit v1.2.3 From 9822e811bffa6b9484dec08e45184520c307d670 Mon Sep 17 00:00:00 2001 From: Markus Lehtonen Date: Fri, 11 Jul 2014 15:40:59 +0300 Subject: buildpackage-rpm: don't crash on invalid vcs format strings Change-Id: I307c82600b0e1336e54016c95cac6ea955adc337 Signed-off-by: Markus Lehtonen --- gbp/scripts/buildpackage_rpm.py | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/gbp/scripts/buildpackage_rpm.py b/gbp/scripts/buildpackage_rpm.py index 74a8aeb3..b458de60 100755 --- a/gbp/scripts/buildpackage_rpm.py +++ b/gbp/scripts/buildpackage_rpm.py @@ -685,7 +685,10 @@ def main(argv): else: vcs_info = get_vcs_info(repo, tree) # Put 'VCS:' tag to .spec - spec.set_tag('VCS', None, options.spec_vcs_tag % vcs_info) + try: + spec.set_tag('VCS', None, options.spec_vcs_tag % vcs_info) + except KeyError as err: + raise GbpError("Unknown key %s in vcs tag format string" % err) spec.write_spec_file() except CommandExecFailed: -- cgit v1.2.3 From 048d06cadf7f2fa22d076fcaa0453733b6e443e7 Mon Sep 17 00:00:00 2001 From: Markus Lehtonen Date: Fri, 11 Jul 2014 15:41:45 +0300 Subject: buildpackage-rpm: remove too general exception catching There should be no reason to catch general Exception here. Change-Id: I1857bf7010365cc6044ff2783eda55dda35e6507 Signed-off-by: Markus Lehtonen --- gbp/scripts/buildpackage_rpm.py | 3 --- 1 file changed, 3 deletions(-) diff --git a/gbp/scripts/buildpackage_rpm.py b/gbp/scripts/buildpackage_rpm.py index b458de60..ef784f42 100755 --- a/gbp/scripts/buildpackage_rpm.py +++ b/gbp/scripts/buildpackage_rpm.py @@ -82,9 +82,6 @@ def git_archive(repo, spec, output_dir, tmpdir_base, treeish, prefix, return False except GbpError: raise - except Exception as e: - gbp.log.err("Error creating %s: %s" % (output, e)) - return False return True -- cgit v1.2.3 From 5ee9fb39bf41ab8f7c074becc15dcf3a3cb15449 Mon Sep 17 00:00:00 2001 From: Markus Lehtonen Date: Thu, 10 Jul 2014 09:42:35 +0300 Subject: log: don't automatically setup gbp-specific logger This makes it nicer to use gbp.* modules (e.g. gbp.git) in other software projects which may have their own logging setup. Now, importing gbp.* modules won't force-setup logging. Change-Id: I3e9cfe27c67cdd74c32ceba5dad786cc694ad7b6 Signed-off-by: Markus Lehtonen --- gbp/log.py | 23 +++++++++++++++++------ tests/component/__init__.py | 2 ++ 2 files changed, 19 insertions(+), 6 deletions(-) diff --git a/gbp/log.py b/gbp/log.py index 1e177d41..e269d653 100644 --- a/gbp/log.py +++ b/gbp/log.py @@ -20,9 +20,11 @@ import os import sys import logging -from logging import (DEBUG, INFO, WARNING, ERROR, CRITICAL, getLogger) +from logging import DEBUG, INFO, WARNING, ERROR, CRITICAL import gbp.tristate +# Initialize default logger +LOGGER = logging.getLogger(__name__) COLORS = dict([('none', 0)] + zip(['black', 'red', 'green', 'yellow', 'blue', 'magenta', 'cyan', 'white'], range(30, 38))) @@ -162,8 +164,18 @@ def _parse_color_scheme(color_scheme=""): except KeyError: pass return scheme +def getLogger(*args, **kwargs): + """Gbp-specific function""" + if not issubclass(logging.getLoggerClass(), GbpLogger): + logging.setLoggerClass(GbpLogger) + return logging.getLogger(*args, **kwargs) + def setup(color, verbose, color_scheme=""): """Basic logger setup""" + # Initialize, if not done yet + if not isinstance(LOGGER, GbpLogger): + initialize() + LOGGER.set_color(color) LOGGER.set_color_scheme(_parse_color_scheme(color_scheme)) if verbose: @@ -171,9 +183,8 @@ def setup(color, verbose, color_scheme=""): else: LOGGER.setLevel(INFO) - -# Initialize the module -logging.setLoggerClass(GbpLogger) - -LOGGER = getLogger("gbp") +def initialize(): + """Initialize the logger module""" + global LOGGER + LOGGER = getLogger("gbp") diff --git a/tests/component/__init__.py b/tests/component/__init__.py index d8ad3e2d..57d86925 100644 --- a/tests/component/__init__.py +++ b/tests/component/__init__.py @@ -91,6 +91,8 @@ class ComponentTestBase(object): # Prevent local config files from messing up the tests os.environ['GBP_CONF_FILES'] = '%(top_dir)s/.gbp.conf:' \ '%(top_dir)s/debian/gbp.conf:%(git_dir)s/gbp.conf' + # Initialize gbp logging module + gbp.log.initialize() @classmethod def teardown_class(cls): -- cgit v1.2.3 From 2faed835d50d24630de2d756bd0325f9b9a9c480 Mon Sep 17 00:00:00 2001 From: Markus Lehtonen Date: Thu, 10 Jul 2014 11:26:19 +0300 Subject: log: fix auto colorizing for custom streams Check for existence of isatty() method in the stream object. Some custom streams (e.g. in nose) do not necessarily have this. Change-Id: I4c8386dfd6f016f926f2eb70b953b19095d585c2 Signed-off-by: Markus Lehtonen --- gbp/log.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/gbp/log.py b/gbp/log.py index e269d653..17cd680d 100644 --- a/gbp/log.py +++ b/gbp/log.py @@ -77,7 +77,7 @@ class GbpStreamHandler(logging.StreamHandler): """Check if to print in color or not""" if self._color.is_on(): return True - elif self._color.is_auto(): + elif self._color.is_auto() and hasattr(self.stream, 'isatty'): in_emacs = (os.getenv("EMACS") and os.getenv("INSIDE_EMACS", "").endswith(",comint")) return self.stream.isatty() and not in_emacs -- cgit v1.2.3 From 879c4d847473a25f24212f15062bbedbf9fd931e Mon Sep 17 00:00:00 2001 From: Markus Lehtonen Date: Fri, 18 Jul 2014 15:37:48 +0300 Subject: ComponentTestBase: add dirs argument to _check_repo_state() Change-Id: I01a421921c8783864d2a5c06d3299fc1ec5d13eb Signed-off-by: Markus Lehtonen --- tests/component/__init__.py | 21 +++++++++++++-------- tests/component/rpm/test_import_orig_rpm.py | 2 +- tests/component/rpm/test_import_srpm.py | 23 +++++++++++------------ tests/component/rpm/test_pq_rpm.py | 20 ++++++++++---------- 4 files changed, 35 insertions(+), 31 deletions(-) diff --git a/tests/component/__init__.py b/tests/component/__init__.py index 57d86925..31911e48 100644 --- a/tests/component/__init__.py +++ b/tests/component/__init__.py @@ -147,7 +147,8 @@ class ComponentTestBase(object): return set(blobs) @classmethod - def _check_repo_state(cls, repo, current_branch, branches, files=None): + def _check_repo_state(cls, repo, current_branch, branches, files=None, + dirs=None): """Check that repository is clean and given branches exist""" branch = repo.branch eq_(branch, current_branch) @@ -156,20 +157,24 @@ class ComponentTestBase(object): assert_msg = "Branches: expected %s, found %s" % (branches, local_branches) eq_(set(local_branches), set(branches), assert_msg) - if files is not None: + if files is not None or dirs is not None: # Get files of the working copy recursively - local = set() + local_f = set() + local_d = set() for dirpath, dirnames, filenames in os.walk(repo.path): # Skip git dir(s) if '.git' in dirnames: dirnames.remove('.git') for filename in filenames: - local.add(os.path.relpath(os.path.join(dirpath, filename), - repo.path)) + local_f.add(os.path.relpath(os.path.join(dirpath, filename), + repo.path)) for dirname in dirnames: - local.add(os.path.relpath(os.path.join(dirpath, dirname), - repo.path) + '/') - cls.check_files(files, local) + local_d.add(os.path.relpath(os.path.join(dirpath, dirname), + repo.path) + '/') + if files is not None: + cls.check_files(files, local_f) + if dirs is not None: + cls.check_files(dirs, local_d) def _capture_log(self, capture=True): """ Capture log""" diff --git a/tests/component/rpm/test_import_orig_rpm.py b/tests/component/rpm/test_import_orig_rpm.py index 27cfab45..a85366b1 100644 --- a/tests/component/rpm/test_import_orig_rpm.py +++ b/tests/component/rpm/test_import_orig_rpm.py @@ -298,7 +298,7 @@ class TestImportOrig(ImportOrigTestBase): # Guessing from the original archive should succeed eq_(mock_import(['--no-interactive', '--merge', orig], stdin_data=''), 0) - files = ['.gbp.conf', 'Makefile', 'README', 'dummy.sh', 'packaging/', + files = ['.gbp.conf', 'Makefile', 'README', 'dummy.sh', 'packaging/gbp-test-native.spec'] self._check_repo_state(repo, 'master', ['master', 'upstream'], files) eq_(len(repo.get_commits(until='master')), 1) diff --git a/tests/component/rpm/test_import_srpm.py b/tests/component/rpm/test_import_srpm.py index 69933912..4811794a 100644 --- a/tests/component/rpm/test_import_srpm.py +++ b/tests/component/rpm/test_import_srpm.py @@ -55,7 +55,7 @@ class TestImportPacked(ComponentTestBase): # Check repository state repo = GitRepository('gbp-test') files = set(['Makefile', 'README', 'bar.tar.gz', 'dummy.sh', 'foo.txt', - 'gbp-test.spec', 'my.patch', 'mydir/', 'mydir/myfile.txt']) + 'gbp-test.spec', 'my.patch', 'mydir/myfile.txt']) self._check_repo_state(repo, 'master', ['master', 'upstream'], files) # Four commits: upstream, packaging files, one patch and the removal # of imported patches @@ -68,8 +68,8 @@ class TestImportPacked(ComponentTestBase): # Check repository state repo = GitRepository('gbp-test2') files = set(['Makefile', 'README', 'bar.tar.gz', 'dummy.sh', 'foo.txt', - 'gbp-test2.spec', 'gbp-test2-alt.spec', 'my.patch', 'mydir/', - 'mydir/myfile.txt']) + 'gbp-test2.spec', 'gbp-test2-alt.spec', 'my.patch', + 'mydir/myfile.txt']) self._check_repo_state(repo, 'master', ['master', 'upstream'], files) # Four commits: upstream, packaging files, one patch and the removal @@ -97,7 +97,7 @@ class TestImportPacked(ComponentTestBase): eq_(mock_import(['--native', srpm]), 0) # Check repository state files = set(['.gbp.conf', 'Makefile', 'README', 'dummy.sh', - 'packaging/', 'packaging/gbp-test-native.spec']) + 'packaging/gbp-test-native.spec']) repo = GitRepository('gbp-test-native') self._check_repo_state(repo, 'master', ['master'], files) # Only one commit: the imported source tarball @@ -121,7 +121,7 @@ class TestImportPacked(ComponentTestBase): repo = GitRepository('gbp-test') files = set(['Makefile', 'README', 'AUTHORS', 'NEWS', 'bar.tar.gz', 'dummy.sh', 'foo.txt', 'gbp-test.spec', 'my.patch', - 'mydir/', 'mydir/myfile.txt']) + 'mydir/myfile.txt']) self._check_repo_state(repo, 'master', ['master', 'upstream'], files) # Four commits: upstream, packaging files, three patches and the removal # of imported patches @@ -147,7 +147,7 @@ class TestImportPacked(ComponentTestBase): # Import new version eq_(mock_import([srpms[2]]), 0) files = set(['Makefile', 'README', 'bar.tar.gz', 'dummy.sh', 'foo.txt', - 'gbp-test.spec', 'my.patch', 'mydir/', 'mydir/myfile.txt']) + 'gbp-test.spec', 'my.patch', 'mydir/myfile.txt']) self._check_repo_state(repo, 'master', ['master', 'upstream'], files) eq_(len(repo.get_commits()), 11) eq_(len(repo.get_commits(until='upstream')), 2) @@ -195,7 +195,7 @@ class TestImportPacked(ComponentTestBase): # Check repository state repo = GitRepository('gbp-test') files = set(['Makefile', 'dummy.sh', 'bar.tar.gz', 'foo.txt', - 'gbp-test.spec', 'my.patch', 'mydir/', 'mydir/myfile.txt']) + 'gbp-test.spec', 'my.patch', 'mydir/myfile.txt']) self._check_repo_state(repo, 'master', ['master', 'upstream'], files) def test_misc_options(self): @@ -213,11 +213,10 @@ class TestImportPacked(ComponentTestBase): srpm]), 0) # Check repository state repo = GitRepository('gbp-test2') - files = set(['Makefile', 'README', 'dummy.sh', 'packaging/', - 'packaging/bar.tar.gz', 'packaging/foo.txt', - 'packaging/gbp-test2.spec', 'packaging/gbp-test2-alt.spec', - 'packaging/my.patch', 'packaging/my2.patch', - 'packaging/my3.patch']) + files = set(['Makefile', 'README', 'dummy.sh', 'packaging/bar.tar.gz', + 'packaging/foo.txt', 'packaging/gbp-test2.spec', + 'packaging/gbp-test2-alt.spec', 'packaging/my.patch', + 'packaging/my2.patch', 'packaging/my3.patch']) self._check_repo_state(repo, 'pack', ['pack', 'orig'], files) eq_(len(repo.get_commits()), 2) # Check packaging dir diff --git a/tests/component/rpm/test_pq_rpm.py b/tests/component/rpm/test_pq_rpm.py index 8b6f4145..ba6229d2 100644 --- a/tests/component/rpm/test_pq_rpm.py +++ b/tests/component/rpm/test_pq_rpm.py @@ -77,7 +77,7 @@ class TestPqRpm(RpmRepoTestBase): branches = repo.get_local_branches() + ['development/master'] # Test import eq_(mock_pq(['import']), 0) - files = ['AUTHORS', 'dummy.sh', 'Makefile', 'NEWS', 'README', 'mydir/', + files = ['AUTHORS', 'dummy.sh', 'Makefile', 'NEWS', 'README', 'mydir/myfile.txt', '.gbp.conf'] branches.append('development/master') self._check_repo_state(repo, 'development/master', branches, files) @@ -106,8 +106,8 @@ class TestPqRpm(RpmRepoTestBase): repo.set_branch('master-orphan') # Import eq_(mock_pq(['import']), 0) - files = ['dummy.sh', 'Makefile', 'README', 'mydir/', - 'mydir/myfile.txt', '.gbp.conf'] + files = ['dummy.sh', 'Makefile', 'README', 'mydir/myfile.txt', + '.gbp.conf'] self._check_repo_state(repo, 'development/master-orphan', branches, files) @@ -203,7 +203,7 @@ class TestPqRpm(RpmRepoTestBase): # Import eq_(mock_pq(['import']), 0) pq_files = ['AUTHORS', 'dummy.sh', 'Makefile', 'NEWS', 'README', - 'mydir/', 'mydir/myfile.txt', '.gbp.conf'] + 'mydir/myfile.txt', '.gbp.conf'] branches.append('development/master') self._check_repo_state(repo, 'development/master', branches, pq_files) @@ -258,13 +258,13 @@ class TestPqRpm(RpmRepoTestBase): tmp_patch.file.flush() eq_(mock_pq(['apply', tmp_patch.name]), 0) self._check_repo_state(repo, 'development/master', branches, - upstr_files + ['mydir/', 'mydir/myfile.txt']) + upstr_files + ['mydir/myfile.txt']) def test_convert(self): """Basic test for convert action""" repo = self.init_test_repo('gbp-test2') branches = repo.get_local_branches() + ['master-orphan'] - files = ['packaging/', 'packaging/bar.tar.gz', 'packaging/foo.txt', + files = ['packaging/bar.tar.gz', 'packaging/foo.txt', 'packaging/gbp-test2.spec', 'packaging/gbp-test2-alt.spec', 'packaging/my.patch', 'packaging/0001-My-addition.patch', '.gbp.conf'] @@ -531,9 +531,9 @@ class TestPqRpm(RpmRepoTestBase): """Test the --new-packaging-dir cmdline option""" repo = self.init_test_repo('gbp-test2') branches = repo.get_local_branches() + ['master-orphan'] - files = ['rpm/', 'rpm/bar.tar.gz', 'rpm/foo.txt', - 'rpm/gbp-test2.spec', 'rpm/gbp-test2-alt.spec', - 'rpm/my.patch', 'rpm/0001-My-addition.patch'] + files = ['rpm/bar.tar.gz', 'rpm/foo.txt', 'rpm/gbp-test2.spec', + 'rpm/gbp-test2-alt.spec', 'rpm/my.patch', + 'rpm/0001-My-addition.patch'] # Drop already-existing master-orphan branch repo.delete_branch('master-orphan') # Try convert @@ -545,7 +545,7 @@ class TestPqRpm(RpmRepoTestBase): """Test the --retain-history cmdline option""" repo = self.init_test_repo('gbp-test2') branches = repo.get_local_branches() + ['master-orphan'] - files = ['packaging/', 'packaging/bar.tar.gz', 'packaging/foo.txt', + files = ['packaging/bar.tar.gz', 'packaging/foo.txt', 'packaging/gbp-test2.spec', 'packaging/gbp-test2-alt.spec', 'packaging/my.patch', 'packaging/0001-My-addition.patch', '.gbp.conf'] -- cgit v1.2.3 From 501b97f5ce846351f1968c5c019951094a884156 Mon Sep 17 00:00:00 2001 From: Markus Lehtonen Date: Tue, 10 Jun 2014 16:20:02 +0300 Subject: rpm tests: remove RepoManifest.add_project() This functionality is moved to the rpm testdata submodule. Change-Id: I0824dbabe84fa75e1053c2508cc86d894dc295e6 Signed-off-by: Markus Lehtonen --- tests/component/rpm/__init__.py | 11 ----------- 1 file changed, 11 deletions(-) diff --git a/tests/component/rpm/__init__.py b/tests/component/rpm/__init__.py index 607aec49..b5be3e7e 100644 --- a/tests/component/rpm/__init__.py +++ b/tests/component/rpm/__init__.py @@ -39,17 +39,6 @@ class RepoManifest(object): else: self._doc.appendChild(self._doc.createElement("gbp-test-manifest")) - def add_project(self, name, branches): - """Add new project to the manifest""" - prj_e = self._doc.createElement('project') - prj_e.setAttribute('name', name) - for branch, revision in branches.iteritems(): - br_e = self._doc.createElement('branch') - br_e.setAttribute('name', branch) - br_e.setAttribute('revision', revision) - prj_e.appendChild(br_e) - self._doc.firstChild.appendChild(prj_e) - def projects_iter(self): """Return an iterator over projects""" for prj_e in self._doc.getElementsByTagName('project'): -- cgit v1.2.3 From 01f4f24487f956ff34e86e11b1891c25fadad6b1 Mon Sep 17 00:00:00 2001 From: Markus Lehtonen Date: Fri, 18 Jul 2014 15:48:29 +0300 Subject: rpm tests: update component test data Adds pq/devel branch and .gitignore file to gbp-test package. Change-Id: Ia6dcbe875433bba00559bd65d9547a8b43e15e97 Signed-off-by: Markus Lehtonen --- tests/component/rpm/data | 2 +- tests/component/rpm/test_pq_rpm.py | 98 +++++++++++++++++++------------------- 2 files changed, 50 insertions(+), 50 deletions(-) diff --git a/tests/component/rpm/data b/tests/component/rpm/data index e59a3efb..bae44ddc 160000 --- a/tests/component/rpm/data +++ b/tests/component/rpm/data @@ -1 +1 @@ -Subproject commit e59a3efb43993c24c5d7c2e2f354806ec419ed90 +Subproject commit bae44ddc98ae0ed15ae078cb7c2fc597dee48da5 diff --git a/tests/component/rpm/test_pq_rpm.py b/tests/component/rpm/test_pq_rpm.py index ba6229d2..293244be 100644 --- a/tests/component/rpm/test_pq_rpm.py +++ b/tests/component/rpm/test_pq_rpm.py @@ -88,9 +88,9 @@ class TestPqRpm(RpmRepoTestBase): # Test export eq_(mock_pq(['export']), 0) - files = ['.gbp.conf', 'bar.tar.gz', 'foo.txt', 'gbp-test.spec', - '0001-my-gz.patch', '0002-my-bzip2.patch', '0003-my2.patch', - 'my.patch'] + files = ['.gbp.conf', '.gitignore', 'bar.tar.gz', 'foo.txt', + 'gbp-test.spec', '0001-my-gz.patch', '0002-my-bzip2.patch', + '0003-my2.patch', 'my.patch'] self._check_repo_state(repo, 'master', branches, files) eq_(repo.status()[' M'], ['gbp-test.spec']) @@ -131,9 +131,10 @@ class TestPqRpm(RpmRepoTestBase): def test_rebase(self): """Basic test for rebase action""" repo = self.init_test_repo('gbp-test') - branches = repo.get_local_branches() + ['development/master'] - # Import and make development branch out-of-sync - eq_(mock_pq(['import']), 0) + repo.rename_branch('pq/master', 'development/master') + repo.set_branch('development/master') + branches = repo.get_local_branches() + # Make development branch out-of-sync GitCommand("rebase")(['--onto', 'upstream^', 'upstream']) # Sanity check for our git rebase... ok_(repo.get_merge_base('development/master', 'upstream') != @@ -176,11 +177,9 @@ class TestPqRpm(RpmRepoTestBase): def test_switch_drop(self): """Basic test for drop action""" repo = self.init_test_repo('gbp-test') - init_branches = repo.get_local_branches() - # Import - eq_(mock_pq(['import']), 0) - branches = init_branches + ['development/master'] - self._check_repo_state(repo, 'development/master', branches) + repo.rename_branch('pq/master', 'development/master') + repo.set_branch('development/master') + branches = repo.get_local_branches() # Drop pq should fail when on pq branch eq_(mock_pq(['drop']), 1) @@ -193,23 +192,21 @@ class TestPqRpm(RpmRepoTestBase): # Drop should succeed when on master branch eq_(mock_pq(['drop']), 0) - self._check_repo_state(repo, 'master', init_branches) + branches.remove('development/master') + self._check_repo_state(repo, 'master', branches) def test_force_import(self): """Test force import""" repo = self.init_test_repo('gbp-test') pkg_files = repo.list_files() - branches = repo.get_local_branches() + ['development/master'] - # Import - eq_(mock_pq(['import']), 0) - pq_files = ['AUTHORS', 'dummy.sh', 'Makefile', 'NEWS', 'README', - 'mydir/myfile.txt', '.gbp.conf'] - branches.append('development/master') - self._check_repo_state(repo, 'development/master', branches, pq_files) + repo.rename_branch('pq/master', 'development/master') + repo.set_branch('development/master') + branches = repo.get_local_branches() + pq_files = repo.list_files() # Re-import should fail eq_(mock_pq(['import']), 1) - self._check_log(-1, "gbp:error: Already on a patch-queue branch") + self._check_log(0, "gbp:error: Already on a patch-queue branch") self._check_repo_state(repo, 'development/master', branches, pq_files) # Mangle pq branch and try force import on top of that @@ -303,12 +300,12 @@ class TestPqRpm(RpmRepoTestBase): def test_option_patch_numbers(self): """Test the --patch-numbers cmdline option""" repo = self.init_test_repo('gbp-test') - branches = repo.get_local_branches() + ['development/master'] - eq_(mock_pq(['import']), 0) + repo.rename_branch('pq/master', 'development/master') + branches = repo.get_local_branches() # Export eq_(mock_pq(['export', '--no-patch-numbers']), 0) - files = ['.gbp.conf', 'bar.tar.gz', 'foo.txt', 'gbp-test.spec', - 'my-gz.patch', 'my-bzip2.patch', 'my2.patch', + files = ['.gbp.conf', '.gitignore', 'bar.tar.gz', 'foo.txt', + 'gbp-test.spec', 'my-gz.patch', 'my-bzip2.patch', 'my2.patch', 'my.patch'] self._check_repo_state(repo, 'master', branches, files) @@ -366,6 +363,7 @@ class TestPqRpm(RpmRepoTestBase): def test_option_pq_branch(self): """Test the --pq-branch and --packaging-branch options""" repo = self.init_test_repo('gbp-test') + branches = repo.get_local_branches() # Invalid branch name eq_(mock_pq(['import', '--pq-branch=foo:']), 1) @@ -374,7 +372,7 @@ class TestPqRpm(RpmRepoTestBase): # Try all possible keys in pq-branch format string eq_(mock_pq(['import', '--pq-branch=dev/%(branch)s/%(upstreamversion)s']), 0) - branches = ['master', 'upstream', 'dev/master/1.1'] + branches.append('dev/master/1.1') self._check_repo_state(repo, 'dev/master/1.1', branches) # Switch to non-existent packaging branch should fail @@ -391,13 +389,14 @@ class TestPqRpm(RpmRepoTestBase): def test_option_export_rev(self): """Test the --export-rev cmdline option""" repo = self.init_test_repo('gbp-test') - eq_(mock_pq(['import']), 0) + repo.rename_branch('pq/master', 'development/master') + branches = repo.get_local_branches() + files = repo.list_files() # Export directly from upstream -> no patches expected eq_(mock_pq(['export', '--export-rev=upstream']), 0) - files = ['.gbp.conf', 'bar.tar.gz', 'foo.txt', 'gbp-test.spec', - 'my.patch'] - branches = ['master', 'upstream', 'development/master'] + files = ['.gbp.conf', '.gitignore', 'bar.tar.gz', 'foo.txt', + 'gbp-test.spec', 'my.patch'] self._check_repo_state(repo, 'master', branches, files) # Export another rev @@ -422,20 +421,22 @@ class TestPqRpm(RpmRepoTestBase): def test_option_patch_compress(self): """Test the --patch-export-compress cmdline option""" repo = self.init_test_repo('gbp-test') - eq_(mock_pq(['import']), 0) + repo.rename_branch('pq/master', 'development/master') + branches = repo.get_local_branches() # Export, all generated patches should be compressed eq_(mock_pq(['export', '--patch-export-compress=1']), 0) - files = ['.gbp.conf', 'bar.tar.gz', 'foo.txt', 'gbp-test.spec', - '0001-my-gz.patch.gz', '0002-my-bzip2.patch.gz', - '0003-my2.patch.gz', 'my.patch'] - branches = ['master', 'upstream', 'development/master'] + files = ['.gbp.conf', '.gitignore', 'bar.tar.gz', 'foo.txt', + 'gbp-test.spec', '0001-my-gz.patch.gz', + '0002-my-bzip2.patch.gz', '0003-my2.patch.gz', 'my.patch'] self._check_repo_state(repo, 'master', branches, files) def test_option_patch_export_squash(self): """Test the --patch-export-squash-until cmdline option""" repo = self.init_test_repo('gbp-test') - eq_(mock_pq(['import']), 0) + repo.rename_branch('pq/master', 'development/master') + repo.set_branch('development/master') + branches = repo.get_local_branches() # Non-existent squash point should fail eq_(mock_pq(['export', '--patch-export-squash-until=foo']), 1) @@ -451,29 +452,29 @@ class TestPqRpm(RpmRepoTestBase): eq_(mock_pq(['export', '--patch-export-squash-until=%s' % squash]), 0) squash += ':squash' eq_(mock_pq(['export', '--patch-export-squash-until=%s' % squash]), 0) - files = ['.gbp.conf', 'bar.tar.gz', 'foo.txt', 'gbp-test.spec', - 'my.patch', 'squash.diff', '0002-my2.patch'] - branches = ['master', 'upstream', 'development/master'] + files = ['.gbp.conf', '.gitignore', 'bar.tar.gz', 'foo.txt', + 'gbp-test.spec', 'my.patch', 'squash.diff', '0002-my2.patch'] self._check_repo_state(repo, 'master', branches, files) def test_option_patch_export_ignore(self): """Test the --patch-export-ignore-path cmdline option""" repo = self.init_test_repo('gbp-test') - - eq_(mock_pq(['import']), 0) + repo.rename_branch('pq/master', 'development/master') + branches = repo.get_local_branches() # Export eq_(mock_pq(['export', '--patch-export-ignore-path=mydir/.*']), 0) - files = ['.gbp.conf', 'bar.tar.gz', 'foo.txt', 'gbp-test.spec', - '0001-my-gz.patch', '0002-my-bzip2.patch', 'my.patch'] - branches = ['master', 'upstream', 'development/master'] + files = ['.gbp.conf', '.gitignore', 'bar.tar.gz', 'foo.txt', + 'gbp-test.spec', '0001-my-gz.patch', '0002-my-bzip2.patch', + 'my.patch'] self._check_repo_state(repo, 'master', branches, files) def test_export_with_merges(self): """Test exporting pq-branch with merge commits""" repo = self.init_test_repo('gbp-test') - # Import - eq_(mock_pq(['import']), 0) + repo.rename_branch('pq/master', 'development/master') + repo.set_branch('development/master') + branches = repo.get_local_branches() # Create a merge commit in pq-branch patches = repo.format_patches('HEAD^', 'HEAD', '.') @@ -487,10 +488,9 @@ class TestPqRpm(RpmRepoTestBase): # Export should create diff up to the merge point and one "normal" patch eq_(mock_pq(['export']), 0) - files = ['.gbp.conf', 'bar.tar.gz', 'foo.txt', 'gbp-test.spec', - 'my.patch', '%s-to-%s.diff' % (upstr_rev, merge_rev), - '0002-my2.patch'] - branches = ['master', 'upstream', 'development/master'] + files = ['.gbp.conf', '.gitignore', 'bar.tar.gz', 'foo.txt', + 'gbp-test.spec', 'my.patch', + '%s-to-%s.diff' % (upstr_rev, merge_rev), '0002-my2.patch'] self._check_repo_state(repo, 'master', branches, files) def test_option_import_files(self): -- cgit v1.2.3 From eb2e28fe963959365f4f2a68a50e7ad59a5612b9 Mon Sep 17 00:00:00 2001 From: Markus Lehtonen Date: Tue, 15 Jul 2014 08:46:41 +0300 Subject: rpm-packaging: recommend/require unzip Unzip is needed for handling zipped upstream sources. Change-Id: I21bb57ad96edece7041d209b1f8264e6ec8465de Signed-off-by: Markus Lehtonen --- packaging/git-buildpackage.spec | 2 ++ 1 file changed, 2 insertions(+) diff --git a/packaging/git-buildpackage.spec b/packaging/git-buildpackage.spec index 40f4ab80..59c4c502 100644 --- a/packaging/git-buildpackage.spec +++ b/packaging/git-buildpackage.spec @@ -86,8 +86,10 @@ Requires: %{man_pkg_name} Requires: %{python_pkg_name} %if 0%{?suse_version} || 0%{?tizen_version:1} Recommends: pristine-tar +Recommends: unzip %else Requires: pristine-tar +Requires: unzip %endif %description common -- cgit v1.2.3 From 78b5f54c98045f012a713e63342f3b92a37e0733 Mon Sep 17 00:00:00 2001 From: Markus Lehtonen Date: Tue, 15 Jul 2014 08:54:48 +0300 Subject: packaging: recommend/require zipmerge Needed by CatenateZipArchive(). Change-Id: I8f25d9da418414bbcc2eff7797b4f57ee5c69e1f Signed-off-by: Markus Lehtonen --- debian/control | 2 +- packaging/git-buildpackage.spec | 3 +++ 2 files changed, 4 insertions(+), 1 deletion(-) diff --git a/debian/control b/debian/control index 3b3cca0c..7eb2e227 100644 --- a/debian/control +++ b/debian/control @@ -34,7 +34,7 @@ Depends: ${python:Depends}, man-db, python-pkg-resources Recommends: pristine-tar (>= 0.5) -Suggests: python-notify, unzip +Suggests: python-notify, unzip, zipmerge Description: Suite to help with packaging in Git repositories This package contains the common API and scripts for Debian and rpm packaging diff --git a/packaging/git-buildpackage.spec b/packaging/git-buildpackage.spec index 59c4c502..86780bfe 100644 --- a/packaging/git-buildpackage.spec +++ b/packaging/git-buildpackage.spec @@ -66,6 +66,7 @@ BuildRequires: %{dpkg_pkg_name} BuildRequires: %{rpm_python_pkg_name} BuildRequires: pristine-tar BuildRequires: unzip +BuildRequires: libzip BuildRequires: gnupg # Missing dep of dpkg in openSUSE %if 0%{?suse_version} @@ -87,9 +88,11 @@ Requires: %{python_pkg_name} %if 0%{?suse_version} || 0%{?tizen_version:1} Recommends: pristine-tar Recommends: unzip +Recommends: libzip %else Requires: pristine-tar Requires: unzip +Requires: libzip %endif %description common -- cgit v1.2.3 From 5f70f08ebbcf6f381294741cc0978de97780728d Mon Sep 17 00:00:00 2001 From: Markus Lehtonen Date: Mon, 21 Jul 2014 12:29:36 +0000 Subject: buildpackage-rpm: remove unused imports Signed-off-by: Markus Lehtonen --- gbp/scripts/buildpackage_rpm.py | 7 ++----- 1 file changed, 2 insertions(+), 5 deletions(-) diff --git a/gbp/scripts/buildpackage_rpm.py b/gbp/scripts/buildpackage_rpm.py index ef784f42..07899ce8 100755 --- a/gbp/scripts/buildpackage_rpm.py +++ b/gbp/scripts/buildpackage_rpm.py @@ -25,14 +25,11 @@ import sys import shutil import re from datetime import datetime -import gzip import gbp.tmpfile as tempfile import gbp.rpm as rpm from gbp.rpm.policy import RpmPkgPolicy -from gbp.command_wrappers import (Command, - RunAtCommand, CommandExecFailed, - RemoveTree) +from gbp.command_wrappers import Command, RunAtCommand, CommandExecFailed from gbp.config import (GbpOptionParserRpm, GbpOptionGroup) from gbp.rpm.git import (GitRepositoryError, RpmGitRepository) from gbp.errors import GbpError @@ -42,7 +39,7 @@ from gbp.scripts.common.buildpackage import (index_name, wc_names, git_archive_submodules, git_archive_single, dump_tree, write_wc, drop_index) -from gbp.pkg import (compressor_opts, compressor_aliases) +from gbp.pkg import compressor_opts from gbp.scripts.pq_rpm import update_patch_series, parse_spec from gbp.scripts.common.pq import is_pq_branch, pq_branch_name, pq_branch_base -- cgit v1.2.3 From 5b9af1c1ca54182351eb2216a5954db46669bd9a Mon Sep 17 00:00:00 2001 From: Markus Lehtonen Date: Mon, 21 Jul 2014 12:39:12 +0000 Subject: buildpackage-rpm: add missing docstrings Signed-off-by: Markus Lehtonen --- gbp/scripts/buildpackage_rpm.py | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/gbp/scripts/buildpackage_rpm.py b/gbp/scripts/buildpackage_rpm.py index 07899ce8..fdf0cd3c 100755 --- a/gbp/scripts/buildpackage_rpm.py +++ b/gbp/scripts/buildpackage_rpm.py @@ -45,6 +45,7 @@ from gbp.scripts.common.pq import is_pq_branch, pq_branch_name, pq_branch_base class GbpAutoGenerateError(GbpError): + """Error for tarball and patch-generation failures""" pass @@ -111,6 +112,7 @@ def prepare_upstream_tarball(repo, spec, options, output_dir): def makedir(dir): + """Create directory""" output_dir = os.path.abspath(dir) try: @@ -297,6 +299,7 @@ def export_patches(repo, spec, export_treeish, options): def is_native(repo, options): + """Determine whether a package is native or non-native""" if repo.has_branch(options.upstream_branch): return False return True @@ -378,6 +381,7 @@ def disable_hooks(options): def parse_args(argv, prefix, git_treeish=None): + """Parse config and command line arguments""" args = [ arg for arg in argv[1:] if arg.find('--%s' % prefix) == 0 ] builder_args = [ arg for arg in argv[1:] if arg.find('--%s' % prefix) == -1 ] @@ -512,6 +516,7 @@ def parse_args(argv, prefix, git_treeish=None): def main(argv): + """Entry point for git-buildpackage-rpm""" retval = 0 prefix = "git-" spec = None -- cgit v1.2.3 From 2440f0609fc65f8329c6beb73e25fa2fe786c949 Mon Sep 17 00:00:00 2001 From: Markus Lehtonen Date: Mon, 21 Jul 2014 12:57:57 +0000 Subject: buildpackage-rpm: remove some unused variables Signed-off-by: Markus Lehtonen --- gbp/scripts/buildpackage_rpm.py | 6 +----- 1 file changed, 1 insertion(+), 5 deletions(-) diff --git a/gbp/scripts/buildpackage_rpm.py b/gbp/scripts/buildpackage_rpm.py index fdf0cd3c..d9abb800 100755 --- a/gbp/scripts/buildpackage_rpm.py +++ b/gbp/scripts/buildpackage_rpm.py @@ -113,8 +113,6 @@ def prepare_upstream_tarball(repo, spec, options, output_dir): def makedir(dir): """Create directory""" - output_dir = os.path.abspath(dir) - try: os.mkdir(dir) except OSError, (e, msg): @@ -329,7 +327,7 @@ def update_tag_str_fields(fields, tag_format_str, repo, commit_info): fields['authortime'] = datetime.fromtimestamp(int(commit_info['author'].date.split()[0])).strftime(RpmPkgPolicy.tag_timestamp_format) fields['committime'] = datetime.fromtimestamp(int(commit_info['committer'].date.split()[0])).strftime(RpmPkgPolicy.tag_timestamp_format) - fields['version'] = version=RpmPkgPolicy.compose_full_version(fields) + fields['version'] = RpmPkgPolicy.compose_full_version(fields) # Parse tags with incremental numbering re_fields = dict(fields, @@ -530,8 +528,6 @@ def main(argv): except GitRepositoryError: gbp.log.err("%s is not a git repository" % (os.path.abspath('.'))) return 1 - else: - repo_dir = os.path.abspath(os.path.curdir) # Determine tree-ish to be exported try: -- cgit v1.2.3 From 37bdee35b8fc66f33dc66c7bc7f048636ceefdd2 Mon Sep 17 00:00:00 2001 From: Markus Lehtonen Date: Mon, 14 Jul 2014 10:25:19 +0300 Subject: buildpackage: refactor tarball compression Introduce a new function for running the compressor commands. Unifies exception/error handling - GbpError will be returned if the compressor fails. Change-Id: I7d876f01d1855a7b6264f6298a16313045dc6873 Signed-off-by: Markus Lehtonen --- gbp/scripts/common/buildpackage.py | 48 ++++++++++++++++++++++++-------------- 1 file changed, 30 insertions(+), 18 deletions(-) diff --git a/gbp/scripts/common/buildpackage.py b/gbp/scripts/common/buildpackage.py index c49375d6..f95837c1 100644 --- a/gbp/scripts/common/buildpackage.py +++ b/gbp/scripts/common/buildpackage.py @@ -53,6 +53,26 @@ def sanitize_prefix(prefix): return '/' +def compress(cmd, options, output, input_data=None): + """ + Filter data through a compressor cmd. + + For better performance input_data should feed data in bigger chunks. + """ + stdin = subprocess.PIPE if input_data else None + try: + with open(output, 'w') as fobj: + popen = subprocess.Popen([cmd] + options, stdin=stdin, stdout=fobj) + if stdin: + for chunk in input_data: + popen.stdin.write(chunk) + popen.stdin.close() + if popen.wait(): + raise GbpError("Error creating %s: running '%s' failed" % + (output, ' '.join([cmd] + options))) + except (OSError, IOError) as err: + raise GbpError("Error creating %s: %s" % (output, err)) + def git_archive_submodules(repo, treeish, output, tmpdir_base, prefix, comp_type, comp_level, comp_opts, format='tar'): """ @@ -87,11 +107,8 @@ def git_archive_submodules(repo, treeish, output, tmpdir_base, prefix, # compress the output if comp_type: - ret = os.system("%s --stdout -%s %s %s > %s" % \ - (comp_type, comp_level, " ".join(comp_opts), - main_archive, output)) - if ret: - raise GbpError("Error creating %s: %d" % (output, ret)) + compress(comp_type, ['--stdout', '-%s' % comp_level] + comp_opts + + [main_archive], output) else: shutil.move(main_archive, output) finally: @@ -106,19 +123,14 @@ def git_archive_single(repo, treeish, output, prefix, comp_type, comp_level, Exception handling is left to the caller. """ prefix = sanitize_prefix(prefix) - with open(output, 'w') as archive_fd: - if comp_type: - cmd = [comp_type, '--stdout', '-%s' % comp_level] + comp_opts - else: - cmd = ['cat'] - - popen = subprocess.Popen(cmd, stdin=subprocess.PIPE, stdout=archive_fd) - for chunk in repo.archive(format, prefix, None, treeish): - popen.stdin.write(chunk) - popen.stdin.close() - if popen.wait(): - raise GbpError("Error creating %s: compressor cmd failed" % output) - + if comp_type: + cmd = comp_type + opts = ['--stdout', '-%s' % comp_level] + comp_opts + else: + cmd= 'cat' + opts = [] + input_data = repo.archive(format, prefix, None, treeish) + compress(cmd, opts, output, input_data) def untar_data(outdir, data): """Extract tar provided as an iterable""" -- cgit v1.2.3 From 1370bc3c58d07c23eed842ce122a668b1fcfe480 Mon Sep 17 00:00:00 2001 From: Markus Lehtonen Date: Tue, 15 Jul 2014 14:54:44 +0300 Subject: buildpackage-rpm: add '--git-native' option Can be used to explicitly configure a package as native or non-native. Default behavior is still to guess based on the existence of upstream branch. Change-Id: I09c3797fd3d88285ee1e920f4c40e3b22c06916a Signed-off-by: Markus Lehtonen --- gbp/config.py | 3 +++ gbp/scripts/buildpackage_rpm.py | 8 +++++--- 2 files changed, 8 insertions(+), 3 deletions(-) diff --git a/gbp/config.py b/gbp/config.py index a2c28def..90c5068d 100644 --- a/gbp/config.py +++ b/gbp/config.py @@ -578,6 +578,7 @@ class GbpOptionParserRpm(GbpOptionParser): defaults = dict(GbpOptionParser.defaults) defaults.update( { 'vendor' : 'vendor', + 'native' : 'auto', 'builder' : 'rpmbuild', 'cleaner' : '/bin/true', 'merge' : 'False', @@ -615,6 +616,8 @@ class GbpOptionParserRpm(GbpOptionParser): help.update( { 'vendor': "Distribution vendor name", + 'native': + "Treat this package as native, default is '%(native)s'", 'packaging-dir': "subdir where packaging files are stored, default is '%(packaging-dir)s'", 'packaging-tag': diff --git a/gbp/scripts/buildpackage_rpm.py b/gbp/scripts/buildpackage_rpm.py index d9abb800..fdde2db5 100755 --- a/gbp/scripts/buildpackage_rpm.py +++ b/gbp/scripts/buildpackage_rpm.py @@ -298,9 +298,9 @@ def export_patches(repo, spec, export_treeish, options): def is_native(repo, options): """Determine whether a package is native or non-native""" - if repo.has_branch(options.upstream_branch): - return False - return True + if options.native.is_auto(): + return not repo.has_branch(options.upstream_branch) + return options.native.is_on() def setup_builder(options, builder_args): @@ -416,6 +416,8 @@ def parse_args(argv, prefix, git_treeish=None): dest="color_scheme") parser.add_config_file_option(option_name="notify", dest="notify", type='tristate') parser.add_config_file_option(option_name="vendor", action="store", dest="vendor") + parser.add_config_file_option(option_name="native", dest="native", + type='tristate') tag_group.add_option("--git-tag", action="store_true", dest="tag", default=False, help="create a tag after a successful build") tag_group.add_option("--git-tag-only", action="store_true", dest="tag_only", default=False, -- cgit v1.2.3 From 34f28afe9b1b38229fee940119452fb6f3b25363 Mon Sep 17 00:00:00 2001 From: Markus Lehtonen Date: Mon, 14 Jul 2014 10:41:36 +0300 Subject: buildpackage-rpm: remove some outdated/unnecessary exception handling Change-Id: I01b75b3ff1ba7f483cb6c9b5648b11dde858ed80 Signed-off-by: Markus Lehtonen --- gbp/scripts/buildpackage_rpm.py | 5 ----- 1 file changed, 5 deletions(-) diff --git a/gbp/scripts/buildpackage_rpm.py b/gbp/scripts/buildpackage_rpm.py index fdde2db5..1af5b06b 100755 --- a/gbp/scripts/buildpackage_rpm.py +++ b/gbp/scripts/buildpackage_rpm.py @@ -75,11 +75,6 @@ def git_archive(repo, spec, output_dir, tmpdir_base, treeish, prefix, except (GitRepositoryError, CommandExecFailed): gbp.log.err("Error generating submodules' archives") return False - except OSError, err: - gbp.log.err("Error creating %s: %s" % (output, err[0])) - return False - except GbpError: - raise return True -- cgit v1.2.3 From 55b04a79d505f20f46c0137e737f723565cea38c Mon Sep 17 00:00:00 2001 From: Markus Lehtonen Date: Tue, 15 Jul 2014 13:45:06 +0300 Subject: buildpackage-rpm: get rid of prepare_export_dir() No need to mangle the export directory. Change-Id: I686cb9d23ea9e95206cdd1c55627b3ca14e83dad Signed-off-by: Markus Lehtonen --- gbp/scripts/buildpackage_rpm.py | 8 +------- 1 file changed, 1 insertion(+), 7 deletions(-) diff --git a/gbp/scripts/buildpackage_rpm.py b/gbp/scripts/buildpackage_rpm.py index 1af5b06b..c84b0a2e 100755 --- a/gbp/scripts/buildpackage_rpm.py +++ b/gbp/scripts/buildpackage_rpm.py @@ -116,12 +116,6 @@ def makedir(dir): return dir -def prepare_export_dir(dir): - if not dir: - dir = 'rpmbuild' - return makedir(dir) - - def pristine_tar_build_orig(repo, orig_file, output_dir, options): """ build orig using pristine-tar @@ -584,7 +578,7 @@ def main(argv): export_patches(repo, spec, patch_tree, options) # Prepare final export dirs - export_dir = prepare_export_dir(options.export_dir) + export_dir = makedir(options.export_dir) source_dir = makedir(os.path.join(export_dir, options.source_dir)) spec_dir = makedir(os.path.join(export_dir, options.spec_dir)) -- cgit v1.2.3 From fd1e8f6ac79624e8541968f926826eec597a9d1d Mon Sep 17 00:00:00 2001 From: Markus Lehtonen Date: Wed, 16 Jul 2014 17:15:03 +0300 Subject: buildpackage-rpm: minor refactor Change-Id: Ibe43e3e948cb8854dadfc03449854ef044370237 Signed-off-by: Markus Lehtonen --- gbp/scripts/buildpackage_rpm.py | 11 ++++------- 1 file changed, 4 insertions(+), 7 deletions(-) diff --git a/gbp/scripts/buildpackage_rpm.py b/gbp/scripts/buildpackage_rpm.py index c84b0a2e..be938aae 100755 --- a/gbp/scripts/buildpackage_rpm.py +++ b/gbp/scripts/buildpackage_rpm.py @@ -591,14 +591,11 @@ def main(argv): dst = os.path.join(spec_dir, f) else: dst = os.path.join(source_dir, f) - try: - if os.path.isdir(src): - # dir is not packaging files, skip it - continue - else: + if not os.path.isdir(src): + try: shutil.copy2(src, dst) - except IOError, err: - raise GbpError, "Error exporting files: %s" % err + except IOError as err: + raise GbpError, "Error exporting files: %s" % err spec.specdir = os.path.abspath(spec_dir) if options.orig_prefix != 'auto': -- cgit v1.2.3 From 81f4628b66b5c19fc71792932330d4a63d68a92d Mon Sep 17 00:00:00 2001 From: Markus Lehtonen Date: Wed, 16 Jul 2014 17:15:44 +0300 Subject: buildpackage-rpm: handle invalid keys in orig prefix Gracefully handle invalid keys in the --git-orig-prefix format string. Change-Id: I1948ed7b34cdd806a0154d8cf354c5095388988f Signed-off-by: Markus Lehtonen --- gbp/scripts/buildpackage_rpm.py | 11 +++++++---- 1 file changed, 7 insertions(+), 4 deletions(-) diff --git a/gbp/scripts/buildpackage_rpm.py b/gbp/scripts/buildpackage_rpm.py index be938aae..efc344d6 100755 --- a/gbp/scripts/buildpackage_rpm.py +++ b/gbp/scripts/buildpackage_rpm.py @@ -599,10 +599,13 @@ def main(argv): spec.specdir = os.path.abspath(spec_dir) if options.orig_prefix != 'auto': - options.orig_prefix = options.orig_prefix % dict(spec.version, - version=RpmPkgPolicy.compose_full_version(spec.version), - name=spec.name, - vendor=options.vendor) + try: + options.orig_prefix %= dict(spec.version, + version=RpmPkgPolicy.compose_full_version(spec.version), + name=spec.name, vendor=options.vendor) + except KeyError as err: + raise GbpError("Unknown key %s in orig prefix format " + "string" % err) elif spec.orig_src: options.orig_prefix = spec.orig_src['prefix'] -- cgit v1.2.3 From 33c372baf79097033423c8145df3fd5ed74595d3 Mon Sep 17 00:00:00 2001 From: Markus Lehtonen Date: Wed, 16 Jul 2014 17:16:48 +0300 Subject: buildpackage-rpm: drop unneeded exception We will never get here as parse_spec() always returns GbpError. Change-Id: I3ccf9826caeace00c9f1d136e51e64833a157f50 Signed-off-by: Markus Lehtonen --- gbp/scripts/buildpackage_rpm.py | 3 --- 1 file changed, 3 deletions(-) diff --git a/gbp/scripts/buildpackage_rpm.py b/gbp/scripts/buildpackage_rpm.py index efc344d6..c47e4d06 100755 --- a/gbp/scripts/buildpackage_rpm.py +++ b/gbp/scripts/buildpackage_rpm.py @@ -690,9 +690,6 @@ def main(argv): if len(err.__str__()): gbp.log.err(err) retval = 1 - except rpm.NoSpecError, err: - gbp.log.err(err) - retval = 1 finally: drop_index(repo) shutil.rmtree(options.tmp_dir) -- cgit v1.2.3 From f83192cef04241c35c71be66d04b55a5484a6e97 Mon Sep 17 00:00:00 2001 From: Markus Lehtonen Date: Wed, 16 Jul 2014 22:13:29 +0300 Subject: buildpackage-rpm: fix one error message Change-Id: I1985f1c4dc208e1b9c18d0b4dc570d1c73c4c0e0 Signed-off-by: Markus Lehtonen --- gbp/scripts/buildpackage_rpm.py | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/gbp/scripts/buildpackage_rpm.py b/gbp/scripts/buildpackage_rpm.py index c47e4d06..dcfa3ace 100755 --- a/gbp/scripts/buildpackage_rpm.py +++ b/gbp/scripts/buildpackage_rpm.py @@ -620,7 +620,8 @@ def main(argv): tree, options.orig_prefix, options.comp_level, options.with_submodules): - raise GbpError, "Cannot create source tarball at '%s'" % export_dir + raise GbpError("Cannot create source tarball at '%s'" % + source_dir) # Non-native packages: create orig tarball from upstream elif spec.orig_src: prepare_upstream_tarball(repo, spec, options, source_dir) -- cgit v1.2.3 From 3d8d732909016279e34768d13a588052e831962f Mon Sep 17 00:00:00 2001 From: Markus Lehtonen Date: Fri, 18 Jul 2014 17:27:03 +0300 Subject: packaging: depend/recommend rpmbuild Change-Id: Ifd5402f93a078eb97ff504eab1dbbf1e2d7c6ca1 Signed-off-by: Markus Lehtonen --- debian/control | 1 + packaging/git-buildpackage.spec | 5 +++++ 2 files changed, 6 insertions(+) diff --git a/debian/control b/debian/control index 7eb2e227..705fd7cd 100644 --- a/debian/control +++ b/debian/control @@ -66,6 +66,7 @@ Depends: ${python:Depends}, python-rpm, rpm2cpio, git-buildpackage-common (= ${binary:Version}) +Recommends: rpm Description: Suite to help with rpm packages in Git repositories This package contains the following tools: * git-import-srpm: import existing rpm source packages into a git diff --git a/packaging/git-buildpackage.spec b/packaging/git-buildpackage.spec index 86780bfe..b252de0c 100644 --- a/packaging/git-buildpackage.spec +++ b/packaging/git-buildpackage.spec @@ -105,6 +105,11 @@ Group: Development/Tools/Building Requires: %{name}-common = %{version}-%{release} Requires: rpm Requires: %{rpm_python_pkg_name} +%if 0%{?suse_version} || 0%{?tizen_version:1} +Recommends: rpm-build +%else +Requires: rpm-build +%endif Provides: tizen-gbp-rpm = 20140605 %description rpm -- cgit v1.2.3 From b7d4516e33bbbe8caddc1b399a7823b437363ca5 Mon Sep 17 00:00:00 2001 From: Markus Lehtonen Date: Mon, 21 Jul 2014 12:46:40 +0300 Subject: rpm tests: disable one anomalous pylint error Change-Id: Ic9b1d4fefaf1062b752c55e372b3644630747d36 Signed-off-by: Markus Lehtonen --- tests/component/rpm/__init__.py | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/tests/component/rpm/__init__.py b/tests/component/rpm/__init__.py index b5be3e7e..dea1c09f 100644 --- a/tests/component/rpm/__init__.py +++ b/tests/component/rpm/__init__.py @@ -25,6 +25,10 @@ from gbp.git import GitRepository, GitRepositoryError from tests.component import ComponentTestBase, ComponentTestGitRepository +# Disable "Instance of 'Document' has no 'firstChild' member" +# pylint: disable=E1103 + + RPM_TEST_DATA_SUBMODULE = os.path.join('tests', 'component', 'rpm', 'data') RPM_TEST_DATA_DIR = os.path.abspath(RPM_TEST_DATA_SUBMODULE) -- cgit v1.2.3 From e4cd3fec7a809d4f2d1572abfbc6cf1316883faa Mon Sep 17 00:00:00 2001 From: Markus Lehtonen Date: Fri, 18 Jul 2014 16:18:58 +0300 Subject: rpm tests: add unit tests for buildpackage-rpm Change-Id: If8a5cce2d43a8dffed6999059a84b3f6040eebdd Signed-off-by: Markus Lehtonen --- packaging/git-buildpackage.spec | 1 + tests/component/rpm/__init__.py | 21 +- tests/component/rpm/data | 2 +- tests/component/rpm/test_buildpackage_rpm.py | 742 +++++++++++++++++++++++++++ 4 files changed, 758 insertions(+), 8 deletions(-) create mode 100644 tests/component/rpm/test_buildpackage_rpm.py diff --git a/packaging/git-buildpackage.spec b/packaging/git-buildpackage.spec index b252de0c..12af022b 100644 --- a/packaging/git-buildpackage.spec +++ b/packaging/git-buildpackage.spec @@ -63,6 +63,7 @@ BuildRequires: python-nose BuildRequires: git-core BuildRequires: %{man_pkg_name} BuildRequires: %{dpkg_pkg_name} +BuildRequires: rpm-build BuildRequires: %{rpm_python_pkg_name} BuildRequires: pristine-tar BuildRequires: unzip diff --git a/tests/component/rpm/__init__.py b/tests/component/rpm/__init__.py index dea1c09f..26655756 100644 --- a/tests/component/rpm/__init__.py +++ b/tests/component/rpm/__init__.py @@ -46,10 +46,9 @@ class RepoManifest(object): def projects_iter(self): """Return an iterator over projects""" for prj_e in self._doc.getElementsByTagName('project'): - branches = {} + branches = [] for br_e in prj_e.getElementsByTagName('branch'): - rev = br_e.getAttribute('revision') - branches[br_e.getAttribute('name')] = rev + branches.append(dict(br_e.attributes.items())) yield prj_e.getAttribute('name'), branches @@ -67,7 +66,7 @@ class RpmRepoTestBase(ComponentTestBase): """Baseclass for tests run in a Git repository with packaging data""" @classmethod - def setup_class(cls): + def setup_class(cls, mangle_branch_names=True): """Initializations only made once per test run""" super(RpmRepoTestBase, cls).setup_class() cls.manifest = RepoManifest(os.path.join(RPM_TEST_DATA_DIR, @@ -93,9 +92,17 @@ class RpmRepoTestBase(ComponentTestBase): # Fetch all remote refs of the orig repo, too repo.fetch('origin', tags=True, refspec='refs/remotes/*:refs/upstream/*') - for branch, rev in brs.iteritems(): - repo.create_branch(branch, rev) - repo.force_head('master', hard=True) + master_branch = 'master' + for branch in brs: + if mangle_branch_names: + branch_name = branch['name'] + else: + branch_name = branch['orig_name'] + if branch['name'] == 'master': + master_branch = branch_name + repo.create_branch(branch_name, branch['revision']) + repo.set_branch(master_branch) + repo.force_head('HEAD', hard=True) cls.orig_repos[prj] = repo @classmethod diff --git a/tests/component/rpm/data b/tests/component/rpm/data index bae44ddc..ff090c1c 160000 --- a/tests/component/rpm/data +++ b/tests/component/rpm/data @@ -1 +1 @@ -Subproject commit bae44ddc98ae0ed15ae078cb7c2fc597dee48da5 +Subproject commit ff090c1cf946e3df67795ce3c1437ec6246dbf37 diff --git a/tests/component/rpm/test_buildpackage_rpm.py b/tests/component/rpm/test_buildpackage_rpm.py new file mode 100644 index 00000000..3060f84b --- /dev/null +++ b/tests/component/rpm/test_buildpackage_rpm.py @@ -0,0 +1,742 @@ +# vim: set fileencoding=utf-8 : +# +# (C) 2013 Intel Corporation +# This program is free software; you can redistribute it and/or modify +# it under the terms of the GNU General Public License as published by +# the Free Software Foundation; either version 2 of the License, or +# (at your option) any later version. +# +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with this program; if not, write to the Free Software +# Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA +"""Unit tests for the gbp-buildpackage-rpm tool""" + +import glob +import mock +import os +import re +import shutil +import stat +import subprocess +from nose.tools import assert_raises, eq_, ok_ # pylint: disable=E0611 + +from gbp.git import GitRepository +from gbp.scripts.buildpackage_rpm import main as gbp_rpm + +from tests.component.rpm import RpmRepoTestBase, RPM_TEST_DATA_DIR +from tests.testutils import ls_dir, ls_tar, ls_zip + +# Disable "Method could be a function warning" +# pylint: disable=R0201 +# Disable "Too many public methods" +# pylint: disable=R0904 + + +DATA_DIR = os.path.join(RPM_TEST_DATA_DIR, 'rpm') +ORIG_DATA_DIR = os.path.join(RPM_TEST_DATA_DIR, 'orig') + +MOCK_NOTIFICATIONS = [] + + +def mock_gbp(args): + """Wrapper for gbp-buildpackage-rpm""" + return gbp_rpm(['arg0', '--git-notify=off'] + args + + ['-ba', '--clean', '--target=noarch', '--nodeps']) + +def mock_notify(summary, message, notify_opt): + """Mock notification system""" + # Auto will succeed + if notify_opt.is_auto(): + MOCK_NOTIFICATIONS.append((summary, message)) + return True + # Otherwise fail + return False + + +class TestGbpRpm(RpmRepoTestBase): + """Basic tests for git-rpm-ch""" + + @staticmethod + def ls_rpm(rpm): + """List the contents of an rpm package""" + args = ['rpm', '-q', '--qf', + '[%{FILEDIGESTS %{FILEMODES} %{FILENAMES}\n]', '-p'] + popen = subprocess.Popen(args + [rpm], stdout=subprocess.PIPE, + stderr=subprocess.PIPE) + stdout, stderr = popen.communicate() + if popen.returncode: + raise Exception("Failed to get file metadata for %s: %s" % + (rpm, stderr)) + return sorted([(nam, mod, dig) for dig, mod, nam in + [lin.split(None, 2) for lin in stdout.splitlines()]]) + + @staticmethod + def check_rpms(directory): + """Check build results""" + # Only check files, at least for now + files = glob.glob(directory + '/*rpm') + assert files, "No rpms (%s)found in %s" % (files, directory) + for path in files: + ref_file = os.path.join(DATA_DIR, os.path.basename(path)) + eq_(TestGbpRpm.ls_rpm(path), TestGbpRpm.ls_rpm(ref_file)) + + @staticmethod + def check_and_rm_file(filepath, content): + """Check file content and remove it""" + with open(filepath) as fobj: + eq_(fobj.read(), content) + os.unlink(filepath) + + @classmethod + def setup_class(cls, **kwargs): + """Setup unit tests""" + # Don't mangle branch names so that we're able to build the packages + super(TestGbpRpm, cls).setup_class(mangle_branch_names=False, **kwargs) + + def test_invalid_args(self): + """Check graceful exit when called with invalid args""" + GitRepository.create('.') + with assert_raises(SystemExit): + mock_gbp(['--git-invalid-arg']) + + def test_outside_repo(self): + """Run outside a git repository""" + eq_(mock_gbp([]), 1) + self._check_log(0, 'gbp:error: %s is not a git repository' % + os.path.abspath('.')) + + def test_invalid_config_file(self): + """Test invalid config file""" + # Create and commit dummy invalid config file + repo = GitRepository.create('.') + with open('.gbp.conf', 'w') as conffd: + conffd.write('foobar\n') + repo.add_files('.gbp.conf') + repo.commit_all('Add conf') + eq_(mock_gbp([]), 1) + self._check_log(0, 'gbp:error: File contains no section headers.') + + def test_native_build(self): + """Basic test of native pkg""" + self.init_test_repo('gbp-test-native') + eq_(mock_gbp([]), 0) + self.check_rpms('../rpmbuild/RPMS/*') + shutil.rmtree('../rpmbuild') + + eq_(mock_gbp(['--git-native=off']), 2) + self._check_log(0, 'gbp:error: Invalid upstream treeish upstream/') + + def test_native_build2(self): + """Basic test of another native pkg""" + self.init_test_repo('gbp-test-native2') + eq_(mock_gbp([]), 0) + self.check_rpms('../rpmbuild/RPMS/*') + + def test_non_native_build(self): + """Basic test of non-native pkg""" + self.init_test_repo('gbp-test') + eq_(mock_gbp([]), 0) + self.check_rpms('../rpmbuild/RPMS/*') + + def test_option_native(self): + """Test the --git-native option""" + self.init_test_repo('gbp-test2') + eq_(mock_gbp([]), 0) + self.check_rpms('../rpmbuild/RPMS/*') + shutil.rmtree('../rpmbuild') + + # Building this pkg should succeed, but no patches generated, + # only one "manually maintained" patch + eq_(mock_gbp(['--git-native=on']), 0) + self.check_rpms('../rpmbuild/RPMS/*') + eq_(len(glob.glob('../rpmbuild/SOURCES/*patch')), 1) + + def test_options_ignore(self): + """Test the --git-ignore-[new|untracked] options""" + self.init_test_repo('gbp-test-native') + + # Create an untracked file + with open('untracked-file', 'w') as fobj: + fobj.write('this file is not tracked\n') + + eq_(mock_gbp([]), 1) + eq_(mock_gbp(['--git-ignore-untracked']), 0) + self.check_rpms('../rpmbuild/RPMS/*') + + # Modify tracked file + with open('README', 'a') as fobj: + fobj.write('new stuff\n') + + eq_(mock_gbp(['--git-ignore-untracked']), 1) + eq_(mock_gbp(['--git-ignore-new']), 0) + + @mock.patch('gbp.notifications.notify', mock_notify) + def test_option_notify(self): + """Test the --git-notify option""" + self.init_test_repo('gbp-test-native') + + eq_(mock_gbp(['--git-notify=auto']), 0) + summary, message = MOCK_NOTIFICATIONS.pop() + ok_(re.match(r'Gbp-rpm successful', summary), summary) + ok_(re.match(r'Build of \S+ \S+ succeeded', message), message) + + # Mock-notification will fail with "on" setting + eq_(mock_gbp(['--git-notify=on']), 1) + self._check_log(-1, "gbp:error: Failed to send notification") + + # No notification when "off" + eq_(mock_gbp(['--git-notify=off']), 0) + eq_(len(MOCK_NOTIFICATIONS), 0) + + def test_option_tmp_dir(self): + """Test the --git-tmp-dir option""" + self.init_test_repo('gbp-test-native') + + eq_(mock_gbp(['--git-tmp-dir=../gbptmp', '--git-no-build']), 0) + ok_(os.path.isdir('../gbptmp')) + + # Check tmpdir access/creation error + os.chmod('../gbptmp', 0) + try: + eq_(mock_gbp(['--git-tmp-dir=../gbptmp/foo', '--git-no-build']), 1) + finally: + os.chmod('../gbptmp', stat.S_IREAD | stat.S_IWRITE | stat.S_IEXEC) + + def test_tagging(self): + """Test tagging options""" + repo = self.init_test_repo('gbp-test-native') + + # Build and tag + eq_(mock_gbp(['--git-tag', '--git-packaging-tag=rel-tag']), 0) + self.check_rpms('../rpmbuild/RPMS/*') + ok_(repo.has_tag('rel-tag')) + sha = repo.rev_parse('HEAD') + eq_(sha, repo.rev_parse('rel-tag^0')) + self.check_rpms('../rpmbuild/RPMS/*') + + # Should fail if the tag already exists + eq_(mock_gbp(['--git-tag', '--git-packaging-tag=rel-tag']), 1) + + # Re-tag + eq_(mock_gbp(['--git-retag', '--git-packaging-tag=rel-tag']), 1) + self._check_log(-1, "gbp:error: '--git-retag' needs either '--git-tag'") + + eq_(mock_gbp(['--git-tag', '--git-packaging-tag=rel-tag', + '--git-retag', '--git-export=HEAD^']), 0) + ok_(repo.has_tag('rel-tag')) + sha2 = repo.rev_parse('HEAD^') + ok_(sha2 != sha) + eq_(sha2, repo.rev_parse('rel-tag^0')) + + # Tag-only + shutil.rmtree('../rpmbuild') + eq_(mock_gbp(['--git-tag-only', '--git-packaging-tag=rel-tag2']), 0) + ok_(not os.path.exists('../rpmbuild')) + ok_(repo.has_tag('rel-tag2')) + + # Valid tag format string keys + tag_keys = ['upstreamversion', 'release', 'version', 'vendor', + 'nowtime', 'authortime', 'committime', + 'nowtimenum', 'authortimenum', 'committimenum'] + # Should fail if the fag format has invalid keys (foo here) + tag_fmt = '_'.join(['%(' + key + ')s' for key in tag_keys + ['foo']]) + eq_(mock_gbp(['--git-tag', '--git-packaging-tag=%(foo)s']), 1) + # Remove 'foo' and should succeed + tag_fmt = '_'.join(['%(' + key + ')s' for key in tag_keys]) + eq_(mock_gbp(['--git-tag-only', '--git-packaging-tag=%s' % tag_fmt]), 0) + # New tag with same format should succeed when '*num' keys are present + eq_(mock_gbp(['--git-tag-only', '--git-packaging-tag=%s' % tag_fmt]), 0) + + def test_option_upstream_tree(self): + """Test the --git-upstream-tree option""" + repo = self.init_test_repo('gbp-test') + + # Dummy update to upstream branch + pkg_branch = repo.get_branch() + upstr_branch = 'srcdata/gbp-test/upstream' + orig_files = ['gbp-test/' + path for \ + path in self.ls_tree(repo, upstr_branch)] + ['gbp-test'] + repo.set_branch(upstr_branch) + with open('new-file', 'w') as fobj: + fobj.write('New file\n') + with open('new-file2', 'w') as fobj: + fobj.write('New file 2\n') + repo.add_files(['new-file', 'new-file2']) + repo.commit_files('new-file', 'New content') + repo.commit_files('new-file2', 'New content 2') + repo.set_branch(pkg_branch) + + # TAG (default) does not contain the new files + eq_(mock_gbp([]), 0) + tar_files = ls_tar('../rpmbuild/SOURCES/gbp-test-1.1.tar.bz2') + self.check_files(orig_files, tar_files) + shutil.rmtree('../rpmbuild') + + # Branch contains them both + eq_(mock_gbp(['--git-upstream-tree=BRANCH']), 0) + tar_files = ls_tar('../rpmbuild/SOURCES/gbp-test-1.1.tar.bz2') + self.check_files(orig_files + + ['gbp-test/new-file', 'gbp-test/new-file2'], tar_files) + shutil.rmtree('../rpmbuild') + + # The first "extra-commit" in upstream contains only one new file + eq_(mock_gbp(['--git-upstream-tree=%s^' % upstr_branch]), 0) + tar_files = ls_tar('../rpmbuild/SOURCES/gbp-test-1.1.tar.bz2') + self.check_files(orig_files + ['gbp-test/new-file'], tar_files) + shutil.rmtree('../rpmbuild') + + # Test invalid upstream treeish + eq_(mock_gbp(['--git-upstream-tree=TAG', + '--git-upstream-tag=invalid-tag']), 2) + self._check_log(-1, ".*Invalid upstream treeish invalid-tag") + eq_(mock_gbp(['--git-upstream-tree=BRANCH', '--git-native=no', + '--git-upstream-branch=invalid-branch']), 2) + self._check_log(-1, ".*invalid-branch is not a valid branch") + eq_(mock_gbp(['--git-upstream-tree=invalid-tree']), 2) + self._check_log(-1, ".*Invalid treeish object") + + def test_option_orig_prefix(self): + """Test the --git-orig-prefix option""" + repo = self.init_test_repo('gbp-test') + + # Building with invalid prefix should fail + eq_(mock_gbp(['--git-orig-prefix=foo']), 1) + upstr_branch = 'srcdata/gbp-test/upstream' + ref_files = ['foo/' + path for path in self.ls_tree(repo, upstr_branch)] + tar_files = ls_tar('../rpmbuild/SOURCES/gbp-test-1.1.tar.bz2', False) + self.check_files(tar_files, ref_files) + + # Test invalid keys + eq_(mock_gbp(['--git-orig-prefix=%(foo)s', '--git-no-build']), 1) + self._check_log(-1, ".*Unknown key 'foo' in orig prefix format") + + def test_pristine_tar(self): + """Test pristine-tar""" + repo = self.init_test_repo('gbp-test') + + # Pristine-tar checkout fails when no pristine-tar branch + eq_(mock_gbp(['--git-pristine-tar', + '--git-export=srcdata/gbp-test/release/1.1-2']), 1) + self._check_log(-1, ".*Couldn't checkout") + + # Create pristine-tar branch and try again + repo.create_branch('pristine-tar', 'srcdata/gbp-test/pristine_tar') + eq_(mock_gbp(['--git-pristine-tar', + '--git-export=srcdata/gbp-test/release/1.1-2']), 0) + self.check_rpms('../rpmbuild/RPMS/*') + + def test_pristine_tar_commit(self): + """Test committing upstream tarball to pristine-tar""" + repo = self.init_test_repo('gbp-test') + + eq_(repo.has_branch('pristine-tar'), False) + eq_(mock_gbp(['--git-pristine-tar-commit', + '--git-export=srcdata/gbp-test/release/1.0-1']), 0) + eq_(len(repo.get_commits(until='pristine-tar')), 1) + shutil.rmtree('../rpmbuild') + + # Using --git-pristine-tar and --git-pristine-tar-commit should be ok + eq_(mock_gbp(['--git-pristine-tar', '--git-pristine-tar-commit']), 0) + eq_(len(repo.get_commits(until='pristine-tar')), 2) + shutil.rmtree('../rpmbuild') + + # Second time no pristine-tar should not be commited + eq_(mock_gbp(['--git-pristine-tar-commit']), 0) + eq_(len(repo.get_commits(until='pristine-tar')), 2) + + def test_tarball_dir(self): + """Test a separate tarball cache""" + self.init_test_repo('gbp-test') + + # Create and populate tarball cache + tarball_dir = '../tarballs' + os.mkdir(tarball_dir) + shutil.copy2(os.path.join(ORIG_DATA_DIR, 'gbp-test-1.0.tar.bz2'), + tarball_dir) + + # Test build when tarball is found from cache + eq_(mock_gbp(['--git-export=srcdata/gbp-test/release/1.0-1', + '--git-tarball-dir=%s' % tarball_dir]), 0) + ok_(os.path.islink(os.path.join('..', 'rpmbuild', 'SOURCES', + 'gbp-test-1.0.tar.bz2'))) + + # Test build when tarball is not found from cache + eq_(mock_gbp(['--git-export=srcdata/gbp-test/release/1.1-2', + '--git-tarball-dir=%s' % tarball_dir]), 0) + ok_(os.path.isfile(os.path.join('..', 'rpmbuild', 'SOURCES', + 'gbp-test-1.1.tar.bz2'))) + + def test_packaging_branch_options(self): + """Test the --packaging-branch and --ignore-branch cmdline options""" + repo = self.init_test_repo('gbp-test-native') + + eq_(mock_gbp(['--git-packaging-branch=foo']), 1) + self._check_log(-2, "gbp:error: You are not on branch 'foo'") + + eq_(mock_gbp(['--git-packaging-branch=foo', '--git-ignore-branch']), 0) + + # Test building when not on any branch + repo.set_branch(repo.rev_parse('HEAD')) + eq_(mock_gbp(['--git-no-build']), 1) + eq_(mock_gbp(['--git-ignore-branch', '--git-no-build']), 0) + + def test_option_submodules(self): + """Test the --git-submodules option""" + repo = self.init_test_repo('gbp-test') + + # Create submodule to upstream branch + sub_repo = self.orig_repos['gbp-test-native'] + pkg_branch = repo.get_branch() + upstr_branch = 'srcdata/gbp-test/upstream' + repo.set_branch(upstr_branch) + repo.add_submodule(sub_repo.path) + repo.commit_all('Add submodule') + repo.set_branch(pkg_branch) + + sub_files = self.ls_tree(sub_repo, 'HEAD') + upstr_files = ['gbp-test/' + path for + path in self.ls_tree(repo, upstr_branch)] + + # Test the "no" option + eq_(mock_gbp(['--git-no-submodules', '--git-upstream-tree=%s' % + upstr_branch, '--git-ignore-untracked']), 0) + tar_files = ls_tar('../rpmbuild/SOURCES/gbp-test-1.1.tar.bz2', False) + self.check_files(upstr_files, tar_files) + shutil.rmtree('../rpmbuild') + + # Test the "yes" option + eq_(mock_gbp(['--git-submodules', '--git-upstream-tree=%s' % + upstr_branch, '--git-ignore-untracked']), 0) + tar_files = ls_tar('../rpmbuild/SOURCES/gbp-test-1.1.tar.bz2', False) + ref_files = upstr_files + ['gbp-test/gbp-test-native.repo/' + path for + path in sub_files] + self.check_files(ref_files, tar_files) + shutil.rmtree('../rpmbuild') + + # Test submodule failure + shutil.rmtree('gbp-test-native.repo') + repo.create('gbp-test-native.repo') + eq_(mock_gbp(['--git-submodules', '--git-upstream-tree=%s' % + upstr_branch, '--git-ignore-untracked']), 2) + + def test_option_submodules_native(self): + """Test the --git-submodules option for native packages""" + repo = self.init_test_repo('gbp-test-native') + + # Create submodule + sub_repo = self.orig_repos['gbp-test-native2'] + repo.add_submodule(sub_repo.path) + repo.commit_all('Add submodule') + + sub_files = self.ls_tree(sub_repo, 'HEAD') + master_files = ['gbp-test-native-1.0/' + path for + path in self.ls_tree(repo, 'HEAD')] + + # Test + eq_(mock_gbp(['--git-submodules']), 0) + zip_files = ls_zip('../rpmbuild/SOURCES/gbp-test-native-1.0.zip', False) + ref_files = master_files + \ + ['gbp-test-native-1.0/gbp-test-native2.repo/' + path for + path in sub_files] + self.check_files(ref_files, zip_files) + + # Test submodule failure + shutil.rmtree('gbp-test-native2.repo') + repo.create('gbp-test-native2.repo') + eq_(mock_gbp(['--git-submodules', '--git-ignore-untracked']), 1) + + def test_option_builder(self): + """Test --git-builder option and it's args""" + self.init_test_repo('gbp-test-native') + base_args = ['arg0', '--git-notify=off'] + + # Try rpmbuild with default args + eq_(gbp_rpm(base_args + ['--git-builder=rpmbuild', '--nodeps']), 0) + + # Build without builder args + builder_script = 'echo -n $* > builder_args.txt' + eq_(gbp_rpm(base_args + ['--git-builder=%s' % builder_script]), 0) + with open('../rpmbuild/builder_args.txt') as fobj: + args = fobj.read() + eq_(args, 'gbp-test-native.spec') + + # Build with builder args + eq_(gbp_rpm(base_args + ['--git-builder=%s' % builder_script, + '--arg1', '--arg2']), 0) + with open('../rpmbuild/builder_args.txt') as fobj: + args = fobj.read() + eq_(args, '--arg1 --arg2 gbp-test-native.spec') + + def test_option_builder_osc(self): + """Test --git-builder=osc""" + self.init_test_repo('gbp-test-native') + eq_(mock_gbp(['--git-builder=osc', '--git-no-build']), 0) + + eq_(set(os.listdir('../rpmbuild')), + set(os.listdir('./packaging') + ['gbp-test-native-1.0.zip'])) + + def test_option_cleaner(self): + """Test --git-cleaner option""" + self.init_test_repo('gbp-test-native') + + # Make repo dirty + with open('untracked-file', 'w') as fobj: + fobj.write('this file is not tracked\n') + + # Build on dirty repo should fail + eq_(mock_gbp([]), 1) + + # Build should succeed with cleaner + eq_(mock_gbp(['--git-cleaner=rm untracked-file']), 0) + + def test_hook_options(self): + """Test different hook options""" + self.init_test_repo('gbp-test-native') + + cleaner = 'echo -n cleaner >> ../hooks' + postexport = 'echo -n postexport >> $GBP_TMP_DIR/../hooks' + prebuild = 'echo -n prebuild >> $GBP_BUILD_DIR/../hooks' + postbuild = 'echo -n postbuild >> $GBP_BUILD_DIR/../hooks' + posttag = 'echo -n posttag >> ../hooks' + args = ['--git-cleaner=%s' % cleaner, + '--git-postexport=%s' % postexport, + '--git-prebuild=%s' % prebuild, + '--git-postbuild=%s' % postbuild, + '--git-posttag=%s' % posttag] + + # Only cleaner and posttag is run when tagging + eq_(mock_gbp(args + ['--git-tag-only', '--git-packaging-tag=tag1']), 0) + self.check_and_rm_file('../hooks', 'cleanerposttag') + + # Prebuild is not run when only exporting + eq_(mock_gbp(args + ['--git-no-build']), 0) + self.check_and_rm_file('../hooks', 'cleanerpostexport') + shutil.rmtree('../rpmbuild') + + # Export and build scripts are run when not tagging + eq_(mock_gbp(args), 0) + self.check_and_rm_file('../hooks', 'cleanerpostexportprebuildpostbuild') + shutil.rmtree('../rpmbuild') + + # All hooks are run when building + eq_(mock_gbp(args + ['--git-tag', '--git-packaging-tag=tag2']), 0) + self.check_and_rm_file('../hooks', + 'cleanerpostexportprebuildpostbuildposttag') + shutil.rmtree('../rpmbuild') + + # Run with hooks disabled + eq_(mock_gbp(args + ['--git-no-hooks']), 0) + ok_(not os.path.exists('../hooks')) + + def test_option_export_only(self): + """Test the (deprecated) --git-export-only option""" + self.init_test_repo('gbp-test-native') + eq_(mock_gbp(['--git-export-only']), 0) + self._check_log(-1, ".*Deprecated option '--git-export-only'") + + def test_builddir_options(self): + """Test the options related to different build directories""" + self.init_test_repo('gbp-test-native') + + eq_(mock_gbp(['--git-export-dir=../foo', + '--git-rpmbuild-builddir=build', + '--git-rpmbuild-buildrootdir=buildroot', + '--git-rpmbuild-rpmdir=rpm', + '--git-rpmbuild-sourcedir=source', + '--git-rpmbuild-specdir=spec', + '--git-rpmbuild-srpmdir=srpm']), 0) + + # Check all directories + eq_(set(os.listdir('../foo')), + set(['build', 'buildroot', 'rpm', 'source', 'spec', 'srpm'])) + + # Test export dir creation error (gbp will not create dir hierarchy) + eq_(mock_gbp(['--git-export-dir=../bar/foo']), 1) + self._check_log(-1, ".*gbp:error: Cannot create dir") + + def test_export_failure(self): + """Test export dir permission problems""" + self.init_test_repo('gbp-test-native') + s_rwx = stat.S_IREAD | stat.S_IWRITE | stat.S_IEXEC + + # Pre-create all files + eq_(mock_gbp(['--git-no-build']), 0) + + # Error in exporting packaging files + os.chmod('../rpmbuild/SOURCES', 0) + try: + eq_(mock_gbp(['--git-no-build']), 1) + finally: + os.chmod('../rpmbuild/SOURCES', s_rwx) + self._check_log(-1, ".*Error exporting files") + + # Error in creating archive + os.chmod('../rpmbuild/SOURCES/gbp-test-native-1.0.zip', 0) + try: + eq_(mock_gbp(['--git-no-build']), 1) + finally: + os.chmod('../rpmbuild/SOURCES/gbp-test-native-1.0.zip', s_rwx) + self._check_log(-1, ".*Error creating ../rpmbuild/SOURCES/.*.zip") + + def test_option_export(self): + """Test the --git-export-option""" + repo = self.init_test_repo('gbp-test') + + # Test exporting of some other commit than HEAD + eq_(mock_gbp(['--git-export=srcdata/gbp-test/release/1.0-1']), 0) + eq_(os.listdir('../rpmbuild/RPMS/noarch'), + ['gbp-test-1.0-1.noarch.rpm']) + self.check_rpms('../rpmbuild/RPMS/*') + + # Modify one tracked file, create one untracked and one ignored file + with open('foo.txt', 'a') as fobj: + fobj.write('staged') + fobj.flush() + repo.add_files('foo.txt') + fobj.write('unstaged') + with open('untracked', 'w') as fobj: + fobj.write('untracked') + with open('ignored.tmp', 'w') as fobj: + fobj.write('ignored') + + base_args = ['--git-ignore-new', '--git-no-build'] + # Test exporting of git index + foo_txt_index = repo.show('HEAD:foo.txt') + 'staged' + eq_(mock_gbp(base_args + ['--git-export=INDEX']), 0) + self.check_and_rm_file('../rpmbuild/SOURCES/foo.txt', foo_txt_index) + ok_(not os.path.exists('../rpmbuild/SOURCES/untracked')) + ok_(not os.path.exists('../rpmbuild/SOURCES/ignored.tmp')) + shutil.rmtree('../rpmbuild') + + # Test exporting of working copy (tracked files only) + eq_(mock_gbp(base_args + ['--git-export=WC.TRACKED']), 0) + foo_txt_wc = repo.show('HEAD:foo.txt') + 'staged' + 'unstaged' + self.check_and_rm_file('../rpmbuild/SOURCES/foo.txt', foo_txt_wc) + ok_(not os.path.exists('../rpmbuild/SOURCES/untracked')) + ok_(not os.path.exists('../rpmbuild/SOURCES/ignored.tmp')) + shutil.rmtree('../rpmbuild') + + # Test exporting of working copy (include untracked files) + eq_(mock_gbp(base_args + ['--git-export=WC.UNTRACKED']), 0) + self.check_and_rm_file('../rpmbuild/SOURCES/foo.txt', foo_txt_wc) + self.check_and_rm_file('../rpmbuild/SOURCES/untracked', 'untracked') + ok_(not os.path.exists('../rpmbuild/SOURCES/ignored.tmp')) + shutil.rmtree('../rpmbuild') + + # Test exporting of working copy (include all files) + eq_(mock_gbp(base_args + ['--git-export=WC']), 0) + self.check_and_rm_file('../rpmbuild/SOURCES/foo.txt', foo_txt_wc) + self.check_and_rm_file('../rpmbuild/SOURCES/untracked', 'untracked') + self.check_and_rm_file('../rpmbuild/SOURCES/ignored.tmp', 'ignored') + shutil.rmtree('../rpmbuild') + + # Test exporting an invalid treeish + eq_(mock_gbp(base_args + ['--git-export=invalid-treeish']), 1) + self._check_log(-1, "gbp:error: Failed to determine export treeish") + + def test_option_spec_file(self): + """Test the --git-spec-file cmdline option""" + repo = self.init_test_repo('gbp-test2') + + eq_(mock_gbp(['--git-spec-file=foo.spec']), 1) + self._check_log(-1, "gbp:error: Can't parse spec: Git error") + + eq_(mock_gbp(['--git-spec-file=auto']), 1) + self._check_log(-1, "gbp:error: Can't parse spec: Multiple spec files") + + eq_(mock_gbp(['--git-spec-file=packaging/gbp-test2.spec']), 0) + + # No spec file found error + repo.set_branch('srcdata/gbp-test2/upstream') + eq_(mock_gbp([]), 1) + self._check_log(-1, ".*Can't parse spec: No spec file found") + + def test_option_packaging_dir(self): + """Test the --git-packaging-dir cmdline option""" + self.init_test_repo('gbp-test-native') + + eq_(mock_gbp(['--git-packaging-dir=foo']), 1) + self._check_log(-1, "gbp:error: Can't parse spec: No spec file found") + + # Packaging dir should be taken from spec file if it is defined + eq_(mock_gbp(['--git-packaging-dir=foo', + '--git-spec-file=packaging/gbp-test-native.spec']), 0) + + def test_option_spec_vcs_tag(self): + """Test the --git-spec-vcs-tag cmdline option""" + repo = self.init_test_repo('gbp-test-native') + + eq_(mock_gbp(['--git-spec-vcs-tag=foobar-%(commit)s']), 0) + sha1 = repo.rev_parse('HEAD') + num_tags = 0 + with open('../rpmbuild/SPECS/gbp-test-native.spec') as fobj: + for line in fobj.readlines(): + if line.startswith('VCS: '): + ok_(re.match(r'VCS:\s+foobar-%s\n$' % sha1, line)) + num_tags += 1 + eq_(num_tags, 1) + + # Test invalid key + eq_(mock_gbp(['--git-spec-vcs-tag=%(invalid-key)s']), 1) + self._check_log(-1, ".*Unknown key 'invalid-key' in vcs tag format") + + def test_patch_export_options(self): + """Test patch export options""" + repo = self.init_test_repo('gbp-test2') + + # Test no-patch-export + base_args = ['--git-builder=osc', '--git-no-build'] + eq_(mock_gbp(base_args + ['--git-no-patch-export']), 0) + ref_files = self.ls_tree(repo, 'HEAD:packaging') + ref_files.add('gbp-test2-2.0.tar.gz') + eq_(ls_dir('../rpmbuild', False), ref_files) + shutil.rmtree('../rpmbuild') + + # No patches should be generated if patch-export-rev is upstream version + + # Test patch compression and numbering + eq_(mock_gbp(base_args + ['--git-no-patch-numbers', + '--git-patch-export-compress=1']), 0) + new_files = ls_dir('../rpmbuild', False) - ref_files + ok_(len(new_files) > 0) + for fname in new_files: + # Patches should start with an alphabet and be compressed with gz + ok_(re.match(r'^[a-zA-Z]\S*.patch.gz$', fname), fname) + + def test_devel_branch_support(self): + """Test patch-generation from q/development branch""" + repo = self.init_test_repo('gbp-test') + pq_br = 'srcdata/gbp-test/pq/master' + + # Patch export with no apparent pq branch should fail + eq_(mock_gbp(['--git-patch-export']), 2) + self._check_log(-1, r".*Start commit \S+ not an ancestor of end commit") + + # With valid pq branch patch export should succeeded + eq_(mock_gbp(['--git-patch-export', '--git-pq-branch=%s' % pq_br]), 0) + self.check_rpms('../rpmbuild/RPMS/*') + shutil.rmtree('../rpmbuild') + eq_(mock_gbp(['--git-patch-export', '--git-pq-branch=%s' % pq_br, + '--git-export=srcdata/gbp-test/master']), 0) + self.check_rpms('../rpmbuild/RPMS/*') + shutil.rmtree('../rpmbuild') + + # With pq branch but with wrong patch-export rev build should fail + eq_(mock_gbp(['--git-patch-export', '--git-pq-branch=%s' % pq_br, + '--git-patch-export-rev=HEAD']), 2) + self._check_log(-1, r".*Start commit \S+ not an ancestor of end commit") + + # Patch-export should be auto-enabled when on pq branch + repo.set_branch(pq_br) + eq_(mock_gbp(['--git-pq-branch=%s' % pq_br, '--git-ignore-branch']), 0) + self.check_rpms('../rpmbuild/RPMS/*') + shutil.rmtree('../rpmbuild') + + # Fail when (apparently) on pq branch but no packaging branch found + eq_(mock_gbp(['--git-pq-branch=%s' % pq_br, '--git-ignore-branch', + '--git-packaging-branch=foo']), 1) -- cgit v1.2.3 From ef52b32b782b5b5f2dac72b644ec5e9f1f34e5a8 Mon Sep 17 00:00:00 2001 From: Junchun Guan Date: Wed, 16 Jul 2014 11:28:29 +0800 Subject: Add PKGBUILD to support arch linux Three split packages: git-buildpackage-{common,rpm,doc} Signed-off-by: Junchun Guan --- packaging/PKGBUILD | 83 ++++++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 83 insertions(+) create mode 100644 packaging/PKGBUILD diff --git a/packaging/PKGBUILD b/packaging/PKGBUILD new file mode 100644 index 00000000..dbe4b00b --- /dev/null +++ b/packaging/PKGBUILD @@ -0,0 +1,83 @@ +pkgbase='git-buildpackage' +pkgname=('git-buildpackage-rpm' 'git-buildpackage-common' 'git-buildpackage-doc') +pkgver=0.6.15 +pkgrel=0 +pkgdesc="Tools from Debian to integrate the package build system with Git" +arch=(any) +url="https://honk.sigxcpu.org/piki/projects/git-buildpackage/" +license=('GPLv2') +conflicts=('git-buildpackage') +provides=('git-buildpackage') +makedepends=('python2-distribute' 'gtk-doc' 'docbook-sgml' 'docbook-utils') +source=(git-buildpackage_${pkgver}.tar.gz) +sha256sums=(SKIP) + +prepare() +{ + cd "$srcdir/$pkgbase-${pkgver}" + for patch_file in $(find ../../ -maxdepth 1 -name '*.patch' |sort) + do + patch -p1 -i $patch_file + done +} + +build() { + cd $srcdir/$pkgbase-$pkgver + WITHOUT_NOSETESTS=1 \ + python2 setup.py build + +# Prepare apidocs + epydoc -n git-buildpackage --no-sourcecode -o docs/apidocs/ \ + gbp*.py git*.py gbp/ + +# HTML docs + HAVE_SGML2X=0 make -C docs/ +} + +package_git-buildpackage-common() { + depends=('man-db' + 'python2' + 'git') + optdepends=('pristine-tar: regenerate pristine tarballs') + cd $srcdir/$pkgbase-$pkgver + WITHOUT_NOSETESTS=1 \ + python2 setup.py install \ + --root="$pkgdir" \ + --prefix=/usr \ + -O1 + rm $pkgdir/usr/lib/python*/site-packages/*info -rf + rm $pkgdir/usr/bin/*rpm* + rm $pkgdir/usr/lib/python*/site-packages/gbp/rpm -rf + rm $pkgdir/usr/lib/python*/site-packages/gbp/scripts/*rpm*.py* -rf +} + +package_git-buildpackage-rpm() { + depends=("git-buildpackage-common=$pkgver-$pkgrel" "rpm") + provides=("tizen-gbp-rpm=20140605") + cd $srcdir/$pkgbase-$pkgver + WITHOUT_NOSETESTS=1 \ + python2 setup.py install \ + --root="$pkgdir" \ + --prefix=/usr \ + -O1 + rm $pkgdir/usr/lib/python*/site-packages/*info -rf + rm -rf $pkgdir/etc + find $pkgdir/usr/bin -mindepth 1 -maxdepth 1 ! -name '*rpm*' -delete + find $pkgdir/usr/lib/python*/site-packages/gbp -mindepth 1 -maxdepth 1 -type f -o -type d ! -name rpm -a ! -name scripts |xargs rm -rf + find $pkgdir/usr/lib/python*/site-packages/gbp/scripts -mindepth 1 -maxdepth 1 ! -name '*rpm*.py*' |xargs rm -rf +} + +package_git-buildpackage-doc() { + cd $srcdir/$pkgbase-$pkgver +# Install man pages + mandir=/usr/share/man + install -d ${pkgdir}/${mandir}/man1 ${pkgdir}/${mandir}/man5 + install docs/*.1 ${pkgdir}/${mandir}/man1 + install docs/*.5 ${pkgdir}/${mandir}/man5 + +# Install html documentation + mkdir -p ${pkgdir}/${docdir}/${pkgbase} + cp -r docs/manual-html ${pkgdir}/${docdir}/${pkgbase} + cp -r docs/apidocs ${pkgdir}/${docdir}/${pkgbase} +} +# vim:set ts=2 sw=2 et: -- cgit v1.2.3 From 0ae97cbe473603ab03a666082ab26d1a34f96d41 Mon Sep 17 00:00:00 2001 From: Li Jinjing Date: Wed, 20 Aug 2014 14:25:02 +0800 Subject: rpm packaging: use macro for python binary For fedora distro, when building git-buildpackage rpm packages in the buildroot, /bin/python is called to do python setup.py actions during rpmbuild,which leads to /bin/python is taken as requirement of git-buildpackage-rpm-0.6.15-0.noarch.rpm automatically, resulting in: Install gbs with dnf command in fedora distro will raise error: nothing provides /bin/python needed by git-buildpackage-rpm-0.6.12-59.1.noarch Fixes: DEVT-197 Change-Id: I30169a506d7f92aed759124c40beb2803c196218 Signed-off-by: Li Jinjing Signed-off-by: Markus Lehtonen --- packaging/git-buildpackage.spec | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/packaging/git-buildpackage.spec b/packaging/git-buildpackage.spec index 12af022b..b808f119 100644 --- a/packaging/git-buildpackage.spec +++ b/packaging/git-buildpackage.spec @@ -135,7 +135,7 @@ Debian and the RPM tool set. %build -WITHOUT_NOSETESTS=1 python ./setup.py build +WITHOUT_NOSETESTS=1 %{__python} ./setup.py build %if %{with docs} # Prepare apidocs @@ -152,13 +152,13 @@ HAVE_SGML2X=0 make -C docs/ GIT_CEILING_DIRECTORIES=%{_builddir} \ GIT_AUTHOR_EMAIL=rpmbuild@example.com GIT_AUTHOR_NAME=rpmbuild \ GIT_COMMITTER_NAME=$GIT_AUTHOR_NAME GIT_COMMITTER_EMAIL=$GIT_AUTHOR_EMAIL \ - python setup.py nosetests + %{__python} setup.py nosetests %endif %install rm -rf %{buildroot} -WITHOUT_NOSETESTS=1 python ./setup.py install --root=%{buildroot} --prefix=/usr +WITHOUT_NOSETESTS=1 %{__python} ./setup.py install --root=%{buildroot} --prefix=/usr rm -rf %{buildroot}%{python_sitelib}/*info %if %{with docs} -- cgit v1.2.3 From e77373087b2aa750acd9ed495c5adbd91702c485 Mon Sep 17 00:00:00 2001 From: Markus Lehtonen Date: Thu, 28 Aug 2014 12:02:28 +0000 Subject: Tizen release 0.6.15-20140828 Change-Id: Ida5b65020a0e9f566aef3d86f5536c7581fdbd01 Signed-off-by: Markus Lehtonen --- debian/changelog | 49 ++++++++++++++++++++++++++++++++++++-- packaging/git-buildpackage.changes | 42 +++++++++++++++++++++++++++++++- packaging/git-buildpackage.spec | 2 +- 3 files changed, 89 insertions(+), 4 deletions(-) diff --git a/debian/changelog b/debian/changelog index 1c253ade..ef2921ef 100644 --- a/debian/changelog +++ b/debian/changelog @@ -1,8 +1,53 @@ -git-buildpackage (0.6.15-tizen20140605) UNRELEASED; urgency=low +git-buildpackage (0.6.15-tizen20140828) unstable; urgency=low + [ Markus Lehtonen ] * Rebase on top of upstream version 0.6.15 + * Changes in buildpackage-rpm + - new 'commitish' keyword for spec vcs tag + - notify: catch RuntimeError when importing pynotify + - fix exit code in case of GitRepositoryError + - always create tarball for native packages + - check submodules from the exported treeish + - fix crash when running prebuild hook + - always run cleaner hook + - add --git-no-build option + - don't crash on invalid vcs format strings + - add '--git-native' option + - remove some outdated/unnecessary exception handling + - get rid of prepare_export_dir() + - handle invalid keys in orig prefix + - internal refactoring and fixes + * Changes in rpm-ch + - implement --commit option + - implement --commit-msg option + - rpm-ch: implement --meta-bts option + - rpm.policy: don't allow leading whitespace in bts meta tags + * docs: manpages for the rpm tools + * Misc. fixes and features + - buildpackage: refactor tarball compression + - gbp-dch: fix handling of the '--meta' option + - import-orig-rpm: download tarball into parent directory + - GitRepository/has_submodules: add treeish argument + - tristate: implement __nonzero__() method + * Logging: + - don't automatically setup gbp-specific logger + - fix auto colorizing for custom streams + * Tests + - multiple fixes and additions in ComponentTestBase class + - testutils: add directories arg to ls_* functions + - add unit tests for buildpackage-rpm + * Packaging + - rpm-packaging: recommend/require unzip + - recommend/require zipmerge + - depend/recommend rpmbuild + + [ Junchun Guan ] + * Add PKGBUILD to support arch linux + + [ Li Jinjing ] + * rpm packaging: use macro for python binary - -- Markus Lehtonen Thu, 05 Jun 2014 13:54:54 +0300 + -- Markus Lehtonen Thu, 28 Aug 2014 11:40:05 +0300 git-buildpackage (0.6.15) unstable; urgency=medium diff --git a/packaging/git-buildpackage.changes b/packaging/git-buildpackage.changes index 7842c803..6a65a15a 100644 --- a/packaging/git-buildpackage.changes +++ b/packaging/git-buildpackage.changes @@ -1,5 +1,45 @@ -* Thu Jun 05 2014 Markus Lehtonen debian/0.6.15-212-gdbb401b +* Thu Aug 28 2014 Markus Lehtonen tizen/0.6.15-20140828 - Rebase on top of upstream version 0.6.15 +- Changes in buildpackage-rpm + * new 'commitish' keyword for spec vcs tag + * notify: catch RuntimeError when importing pynotify + * fix exit code in case of GitRepositoryError + * always create tarball for native packages + * check submodules from the exported treeish + * fix crash when running prebuild hook + * always run cleaner hook + * add --git-no-build option + * don't crash on invalid vcs format strings + * add '--git-native' option + * remove some outdated/unnecessary exception handling + * get rid of prepare_export_dir() + * handle invalid keys in orig prefix + * internal refactoring and fixes +- Changes in rpm-ch + * implement --commit option + * implement --commit-msg option + * rpm-ch: implement --meta-bts option + * rpm.policy: don't allow leading whitespace in bts meta tags +- docs: manpages for the rpm tools +- Misc. fixes and features + * buildpackage: refactor tarball compression + * gbp-dch: fix handling of the '--meta' option + * import-orig-rpm: download tarball into parent directory + * GitRepository/has_submodules: add treeish argument + * tristate: implement __nonzero__() method +- Logging: + * don't automatically setup gbp-specific logger + * fix auto colorizing for custom streams +- Tests + * multiple fixes and additions in ComponentTestBase class + * testutils: add directories arg to ls_* functions + * add unit tests for buildpackage-rpm +- Packaging + * rpm-packaging: recommend/require unzip + * recommend/require zipmerge + * depend/recommend rpmbuild + * [ Junchun Guan ] Add PKGBUILD to support arch linux + * [ Li Jinjing ] rpm packaging: use macro for python binary * Wed May 21 2014 Markus Lehtonen tizen/0.6.12-20140521 - Rebase on top of upstream version 0.6.12 diff --git a/packaging/git-buildpackage.spec b/packaging/git-buildpackage.spec index b808f119..3ff90288 100644 --- a/packaging/git-buildpackage.spec +++ b/packaging/git-buildpackage.spec @@ -111,7 +111,7 @@ Recommends: rpm-build %else Requires: rpm-build %endif -Provides: tizen-gbp-rpm = 20140605 +Provides: tizen-gbp-rpm = 20140828 %description rpm Set of tools from Debian that integrate the package build system with Git. -- cgit v1.2.3 From b7d2c5ec226f657196dae2262b42a21bc7730668 Mon Sep 17 00:00:00 2001 From: Markus Lehtonen Date: Tue, 3 Mar 2015 17:23:42 +0200 Subject: debian packaging: fix rpm build deps for Ubuntu 14.10 Dependencies of python-rpm got broken in Ubuntu 14.10 at the update to rpm v4.11.2-3ubuntu0.1. This change is a work around for that. Change-Id: I76a912e6e68b83e8e0d667fa881c6f35450c8b2c Signed-off-by: Markus Lehtonen --- debian/control | 2 ++ 1 file changed, 2 insertions(+) diff --git a/debian/control b/debian/control index 705fd7cd..856566a1 100644 --- a/debian/control +++ b/debian/control @@ -17,6 +17,7 @@ Build-Depends: python-setuptools, sgml2x, # For rpm (epydoc) + rpm-common, python-rpm Standards-Version: 3.9.4 Vcs-Git: git://honk.sigxcpu.org/git/git-buildpackage.git @@ -64,6 +65,7 @@ Depends: ${python:Depends}, ${shlibs:Depends}, ${misc:Depends}, python-rpm, + rpm-common, rpm2cpio, git-buildpackage-common (= ${binary:Version}) Recommends: rpm -- cgit v1.2.3 From 46ec85693a0fd6cfa5fa0559c3f7a2b9e4c1a1a1 Mon Sep 17 00:00:00 2001 From: Markus Lehtonen Date: Mon, 2 Mar 2015 17:38:44 +0200 Subject: Revert "buildpackage-rpm: always create tarball for native packages" Fixes: DEVT-215 This reverts commit efc490c4a8da5ce7a0bd1bf4a20009c3a445bb47. Change-Id: I2109f7ff48384a3b1190a73a3471bdc67f6d2427 Signed-off-by: Markus Lehtonen --- gbp/scripts/buildpackage_rpm.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/gbp/scripts/buildpackage_rpm.py b/gbp/scripts/buildpackage_rpm.py index dcfa3ace..b8c1e0d1 100755 --- a/gbp/scripts/buildpackage_rpm.py +++ b/gbp/scripts/buildpackage_rpm.py @@ -611,7 +611,7 @@ def main(argv): # Get/build the orig tarball if is_native(repo, options): - if spec.orig_src: + if spec.orig_src and not options.no_create_orig: # Just build source archive from the exported tree gbp.log.info("Creating (native) source archive %s from '%s'" % (spec.orig_src['filename'], tree)) if spec.orig_src['compression']: -- cgit v1.2.3 From f06bd614607c79790167c68909c7029bdf187af6 Mon Sep 17 00:00:00 2001 From: Markus Lehtonen Date: Tue, 3 Mar 2015 14:03:11 +0000 Subject: Tizen release 0.6.15-20150303 Change-Id: I631e30aff42fd5acd90b1b3d535a0e38f00aaa12 Signed-off-by: Markus Lehtonen --- debian/changelog | 10 ++++++++++ packaging/git-buildpackage.changes | 4 ++++ packaging/git-buildpackage.spec | 2 +- 3 files changed, 15 insertions(+), 1 deletion(-) diff --git a/debian/changelog b/debian/changelog index ef2921ef..9913aaca 100644 --- a/debian/changelog +++ b/debian/changelog @@ -1,3 +1,13 @@ +git-buildpackage (0.6.15-tizen20150303) unstable; urgency=low + + * Revert "buildpackage-rpm: always create tarball for native packages" + Fixes: DEVT-215 + * debian packaging: fix rpm build deps for Ubuntu 14.10. + Dependencies of python-rpm got broken in Ubuntu 14.10 at the update to + rpm v4.11.2-3ubuntu0.1. This change is a work around for that. + + -- Markus Lehtonen Tue, 03 Mar 2015 17:30:37 +0200 + git-buildpackage (0.6.15-tizen20140828) unstable; urgency=low [ Markus Lehtonen ] diff --git a/packaging/git-buildpackage.changes b/packaging/git-buildpackage.changes index 6a65a15a..20954e9e 100644 --- a/packaging/git-buildpackage.changes +++ b/packaging/git-buildpackage.changes @@ -1,3 +1,7 @@ +* Tue Mar 03 2015 Markus Lehtonen tizen/0.6.15-20150303 +- Revert "buildpackage-rpm: always create tarball for native packages" + (Fixes: DEVT-215) + * Thu Aug 28 2014 Markus Lehtonen tizen/0.6.15-20140828 - Rebase on top of upstream version 0.6.15 - Changes in buildpackage-rpm diff --git a/packaging/git-buildpackage.spec b/packaging/git-buildpackage.spec index 3ff90288..7e4e839a 100644 --- a/packaging/git-buildpackage.spec +++ b/packaging/git-buildpackage.spec @@ -111,7 +111,7 @@ Recommends: rpm-build %else Requires: rpm-build %endif -Provides: tizen-gbp-rpm = 20140828 +Provides: tizen-gbp-rpm = 0.6.15-20150303 %description rpm Set of tools from Debian that integrate the package build system with Git. -- cgit v1.2.3 From 82c3dd1838b9caa4bd992e51c74d860c9282f07c Mon Sep 17 00:00:00 2001 From: SoonKyu Park Date: Tue, 21 Jul 2015 15:04:59 +0900 Subject: Document changes and release 0.6.25 Change-Id: I03a3dc5bdb419ca3eaff6993989b260b5ef2e960 --- debian/changelog | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/debian/changelog b/debian/changelog index 9913aaca..9512d693 100644 --- a/debian/changelog +++ b/debian/changelog @@ -1,3 +1,9 @@ +git-buildpackage (0.6.25) unstable; urgency=medium + + * Upgrade version to 0.6.25 + + -- SoonKyu Park Tue, 21 Jul 2015 15:02:21 +0900 + git-buildpackage (0.6.15-tizen20150303) unstable; urgency=low * Revert "buildpackage-rpm: always create tarball for native packages" -- cgit v1.2.3 From 96398c46398eec541b59df3997e5b8b2a392ee56 Mon Sep 17 00:00:00 2001 From: SoonKyu Park Date: Tue, 21 Jul 2015 15:30:40 +0900 Subject: Upgrade version to 0.6.25-20150721 Change-Id: Ie60ce2da01b79fc584240f41dc8047ed79a3886d --- debian/changelog | 6 ++++++ packaging/PKGBUILD | 4 ++-- packaging/git-buildpackage.changes | 3 +++ packaging/git-buildpackage.spec | 4 ++-- 4 files changed, 13 insertions(+), 4 deletions(-) diff --git a/debian/changelog b/debian/changelog index 9512d693..545b7576 100644 --- a/debian/changelog +++ b/debian/changelog @@ -1,3 +1,9 @@ +git-buildpackage (0.6.25-tizen20150721) unstable; urgency=low + + * Upgrade version to 0.6.25-20150721 + + -- SoonKyu Park Tue, 21 Jul 2015 15:23:00 +0900 + git-buildpackage (0.6.25) unstable; urgency=medium * Upgrade version to 0.6.25 diff --git a/packaging/PKGBUILD b/packaging/PKGBUILD index dbe4b00b..09eeac15 100644 --- a/packaging/PKGBUILD +++ b/packaging/PKGBUILD @@ -1,6 +1,6 @@ pkgbase='git-buildpackage' pkgname=('git-buildpackage-rpm' 'git-buildpackage-common' 'git-buildpackage-doc') -pkgver=0.6.15 +pkgver=0.6.25 pkgrel=0 pkgdesc="Tools from Debian to integrate the package build system with Git" arch=(any) @@ -53,7 +53,7 @@ package_git-buildpackage-common() { package_git-buildpackage-rpm() { depends=("git-buildpackage-common=$pkgver-$pkgrel" "rpm") - provides=("tizen-gbp-rpm=20140605") + provides=("tizen-gbp-rpm=20150721") cd $srcdir/$pkgbase-$pkgver WITHOUT_NOSETESTS=1 \ python2 setup.py install \ diff --git a/packaging/git-buildpackage.changes b/packaging/git-buildpackage.changes index 20954e9e..ce8abfd3 100644 --- a/packaging/git-buildpackage.changes +++ b/packaging/git-buildpackage.changes @@ -1,3 +1,6 @@ +* Tue Jul 21 2015 SoonKyu Park tizen/0.6.25-20150721 +- Upgrade version to 0.6.25-20150721 + * Tue Mar 03 2015 Markus Lehtonen tizen/0.6.15-20150303 - Revert "buildpackage-rpm: always create tarball for native packages" (Fixes: DEVT-215) diff --git a/packaging/git-buildpackage.spec b/packaging/git-buildpackage.spec index 7e4e839a..a24f5c57 100644 --- a/packaging/git-buildpackage.spec +++ b/packaging/git-buildpackage.spec @@ -3,7 +3,7 @@ Name: git-buildpackage Summary: Build packages from git -Version: 0.6.15 +Version: 0.6.25 Release: 0 Group: Development/Tools/Building License: GPLv2 @@ -111,7 +111,7 @@ Recommends: rpm-build %else Requires: rpm-build %endif -Provides: tizen-gbp-rpm = 0.6.15-20150303 +Provides: tizen-gbp-rpm = 20150721 %description rpm Set of tools from Debian that integrate the package build system with Git. -- cgit v1.2.3 From f2f3a2346be7cbcc9f72cf2bf5329aa4aa837c6e Mon Sep 17 00:00:00 2001 From: Jun Wang Date: Fri, 29 Jan 2016 16:30:03 +0800 Subject: fix build problem on Debian_8 Change-Id: I145928ae1416f7847b4d8e6729c1daf07e2ab757 --- debian/control | 3 +++ 1 file changed, 3 insertions(+) diff --git a/debian/control b/debian/control index db7e05fb..58746a47 100644 --- a/debian/control +++ b/debian/control @@ -19,6 +19,9 @@ Build-Depends: python-setuptools, rpm, sgml2x, + librpm-tizen, +# For rpm (epydoc) + python-rpm Standards-Version: 3.9.4 Vcs-Git: git://honk.sigxcpu.org/git/git-buildpackage.git Vcs-Browser: https://honk.sigxcpu.org/gitweb/?p=git-buildpackage.git -- cgit v1.2.3 From af42c4afe972e7c2ac32284fa1afc2399726da1f Mon Sep 17 00:00:00 2001 From: Jun Wang Date: Tue, 2 Feb 2016 23:16:52 +0800 Subject: Update the version to 0.6.26 Change-Id: Ia8f0e526da0ecc9d765614fe5b3daf37c08e9171 --- packaging/git-buildpackage.spec | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/packaging/git-buildpackage.spec b/packaging/git-buildpackage.spec index db5ccc0c..55a1752c 100644 --- a/packaging/git-buildpackage.spec +++ b/packaging/git-buildpackage.spec @@ -3,7 +3,7 @@ Name: git-buildpackage Summary: Build packages from git -Version: 0.6.22 +Version: 0.6.26 Release: 0 Group: Development/Tools/Building License: GPLv2 -- cgit v1.2.3 From 91894415dc3a1e4f3056b680ffab9e737aed0f50 Mon Sep 17 00:00:00 2001 From: Jun Wang Date: Wed, 3 Feb 2016 23:40:55 +0800 Subject: fix gbp.log error in opensuse Change-Id: I1fc96948cbd8da9a6325b67ab511ae2c6a199c6e --- gbp/log.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/gbp/log.py b/gbp/log.py index 7b9a4aa8..5f8ae107 100644 --- a/gbp/log.py +++ b/gbp/log.py @@ -172,8 +172,8 @@ def _parse_color_scheme(color_scheme=""): def getLogger(*args, **kwargs): """Gbp-specific function""" - if not issubclass(logging.getLoggerClass(), GbpLogger): - logging.setLoggerClass(GbpLogger) +# if not issubclass(logging.getLoggerClass(), GbpLogger): + logging.setLoggerClass(GbpLogger) color = kwargs.pop('color') if 'color' in kwargs else 'auto' logger = logging.getLogger(*args, **kwargs) if hasattr(logger, 'default_handlers') and not logger.default_handlers: -- cgit v1.2.3 From c6438b3e4ca4ad5db0bac0f3cb76c0ada7cd0f84 Mon Sep 17 00:00:00 2001 From: Jun Wang Date: Thu, 4 Feb 2016 23:05:20 +0800 Subject: Fix errors logs when __import__ faild,like "No handlers could be found fo logger" Change-Id: I785e402e13879c6010780d3a453ea78956833fe1 --- gbp/log.py | 4 ++-- gbp/rpm/lib_rpm.py | 1 + 2 files changed, 3 insertions(+), 2 deletions(-) diff --git a/gbp/log.py b/gbp/log.py index 5f8ae107..7b9a4aa8 100644 --- a/gbp/log.py +++ b/gbp/log.py @@ -172,8 +172,8 @@ def _parse_color_scheme(color_scheme=""): def getLogger(*args, **kwargs): """Gbp-specific function""" -# if not issubclass(logging.getLoggerClass(), GbpLogger): - logging.setLoggerClass(GbpLogger) + if not issubclass(logging.getLoggerClass(), GbpLogger): + logging.setLoggerClass(GbpLogger) color = kwargs.pop('color') if 'color' in kwargs else 'auto' logger = logging.getLogger(*args, **kwargs) if hasattr(logger, 'default_handlers') and not logger.default_handlers: diff --git a/gbp/rpm/lib_rpm.py b/gbp/rpm/lib_rpm.py index 4bad44e7..da914207 100644 --- a/gbp/rpm/lib_rpm.py +++ b/gbp/rpm/lib_rpm.py @@ -25,6 +25,7 @@ try: # Try to load special RPM lib to be used for GBP (only) librpm = __import__(RpmPkgPolicy.python_rpmlib_module_name) except ImportError: + gbp.log.getLogger("gbp") gbp.log.warn("Failed to import '%s' as rpm python module, using host's " "default rpm library instead" % RpmPkgPolicy.python_rpmlib_module_name) -- cgit v1.2.3 From e0cdb584e34cdfed5366e18dc1b427978cd126c3 Mon Sep 17 00:00:00 2001 From: Jun Wang Date: Wed, 2 Mar 2016 16:47:08 +0800 Subject: change to local sources for tests files Change-Id: I8cf81926791323039b0b4150931aad3c658ed526 --- .gitmodules | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/.gitmodules b/.gitmodules index 3b52b91f..bce02724 100644 --- a/.gitmodules +++ b/.gitmodules @@ -1,6 +1,6 @@ [submodule "tests/component/deb/data"] path = tests/component/deb/data - url = git://honk.sigxcpu.org/git/gbp/deb-testdata + url = ssh://fushuai1985@review.tizen.org:29418/tizen.org-tools/git-buildpackage-deb-testdata [submodule "tests/component/rpm/data"] path = tests/component/rpm/data - url = git://github.com/marquiz/git-buildpackage-rpm-testdata.git + url = ssh://fushuai1985@review.tizen.org:29418/tizen.org-tools/git-buildpackage-rpm-testdata -- cgit v1.2.3 From 9e60e1646ee5de7ead3637b3aa1e7517c1e1d5cb Mon Sep 17 00:00:00 2001 From: Jun Wang Date: Wed, 2 Mar 2016 17:00:06 +0800 Subject: change to SRC-Nanjing Local server for tests resource Change-Id: If618a5f54843f094c4444e4b9505e0de843e29e6 --- .gitmodules | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/.gitmodules b/.gitmodules index bce02724..5d5970d0 100644 --- a/.gitmodules +++ b/.gitmodules @@ -1,6 +1,6 @@ [submodule "tests/component/deb/data"] path = tests/component/deb/data - url = ssh://fushuai1985@review.tizen.org:29418/tizen.org-tools/git-buildpackage-deb-testdata + url = ssh://shuai.fu@109.123.100.123:29418/tizen.org-tools/git-buildpackage-deb-testdata [submodule "tests/component/rpm/data"] path = tests/component/rpm/data - url = ssh://fushuai1985@review.tizen.org:29418/tizen.org-tools/git-buildpackage-rpm-testdata + url = ssh://shuai.fu@109.123.100.123:29418/tizen.org-tools/git-buildpackage-rpm-testdata -- cgit v1.2.3 From 49f9014acbebbe704d2196865d194796ce51d06c Mon Sep 17 00:00:00 2001 From: Jun Wang Date: Wed, 2 Mar 2016 17:31:13 +0800 Subject: change login user name to jenkins Change-Id: I99cb7dd3fb8242dc1542a392dd365a851011d481 --- .gitmodules | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/.gitmodules b/.gitmodules index 5d5970d0..68a6928c 100644 --- a/.gitmodules +++ b/.gitmodules @@ -1,6 +1,6 @@ [submodule "tests/component/deb/data"] path = tests/component/deb/data - url = ssh://shuai.fu@109.123.100.123:29418/tizen.org-tools/git-buildpackage-deb-testdata + url = ssh://jenkins@109.123.100.123:29418/tizen.org-tools/git-buildpackage-deb-testdata [submodule "tests/component/rpm/data"] path = tests/component/rpm/data - url = ssh://shuai.fu@109.123.100.123:29418/tizen.org-tools/git-buildpackage-rpm-testdata + url = ssh://jenkins@109.123.100.123:29418/tizen.org-tools/git-buildpackage-rpm-testdata -- cgit v1.2.3 From 75c58f7f034a997ec8377820431c7ebb70c7d34b Mon Sep 17 00:00:00 2001 From: Jun Wang Date: Wed, 2 Mar 2016 17:44:57 +0800 Subject: upgrade to 0.6.26 Change-Id: Id72b3231c078edd97ea5994b6ccd00ffb7d71162 --- debian/changelog | 7 +++++++ packaging/git-buildpackage.changes | 3 +++ 2 files changed, 10 insertions(+) diff --git a/debian/changelog b/debian/changelog index d490629d..94445748 100644 --- a/debian/changelog +++ b/debian/changelog @@ -1,3 +1,10 @@ +git-buildpackage (0.6.26) unstable; urgency=medium + + * Fix error logs when __import__ faild,like "No handlers could be found fo logger" + * Fix build problem on Debian 8 + + -- Jun Wang Wed, 02 Mar 2016 07:47:21 +0100 + git-buildpackage (0.6.22-tizen20150206) unstable; urgency=low * Rebase on top of upstream version 0.6.22 diff --git a/packaging/git-buildpackage.changes b/packaging/git-buildpackage.changes index c9dcafcb..50561bf0 100644 --- a/packaging/git-buildpackage.changes +++ b/packaging/git-buildpackage.changes @@ -1,3 +1,6 @@ +* Wed Mar 02 2016 Jun Wang tizen/0.6.26-20150206 +- Upgrade version to 0.6.26 + * Fri Feb 06 2015 Markus Lehtonen tizen/0.6.22-20150206 - Rebase on top of upstream version 0.6.22 - Experimental support for BitBake -- cgit v1.2.3 From 38470a55fe4b85fbb1aabc51ab1285ab4b817d7f Mon Sep 17 00:00:00 2001 From: Jun Wang Date: Wed, 2 Mar 2016 17:50:03 +0800 Subject: upgrade to 0.6.27 Change-Id: I4b29f41472de96278396ed0692e82e214fa9085a --- debian/changelog | 2 +- packaging/git-buildpackage.changes | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/debian/changelog b/debian/changelog index 94445748..ee6a5c4f 100644 --- a/debian/changelog +++ b/debian/changelog @@ -1,4 +1,4 @@ -git-buildpackage (0.6.26) unstable; urgency=medium +git-buildpackage (0.6.27) unstable; urgency=medium * Fix error logs when __import__ faild,like "No handlers could be found fo logger" * Fix build problem on Debian 8 diff --git a/packaging/git-buildpackage.changes b/packaging/git-buildpackage.changes index 50561bf0..735d6d74 100644 --- a/packaging/git-buildpackage.changes +++ b/packaging/git-buildpackage.changes @@ -1,5 +1,5 @@ * Wed Mar 02 2016 Jun Wang tizen/0.6.26-20150206 -- Upgrade version to 0.6.26 +- Upgrade version to 0.6.27 * Fri Feb 06 2015 Markus Lehtonen tizen/0.6.22-20150206 - Rebase on top of upstream version 0.6.22 -- cgit v1.2.3 From 5e389d45d9ad5606928cefbb79b11d428e2f0ad9 Mon Sep 17 00:00:00 2001 From: Jun Wang Date: Wed, 2 Mar 2016 18:33:22 +0800 Subject: change version files to match 0.6.27 Change-Id: I6dc3023b4bccffef4f0113229ae0eaf4ddcfc74f --- debian/changelog | 2 +- packaging/git-buildpackage.changes | 2 +- packaging/git-buildpackage.spec | 4 ++-- 3 files changed, 4 insertions(+), 4 deletions(-) diff --git a/debian/changelog b/debian/changelog index ee6a5c4f..bbd64edb 100644 --- a/debian/changelog +++ b/debian/changelog @@ -1,4 +1,4 @@ -git-buildpackage (0.6.27) unstable; urgency=medium +git-buildpackage (0.6.27-tizen20160302) unstable; urgency=medium * Fix error logs when __import__ faild,like "No handlers could be found fo logger" * Fix build problem on Debian 8 diff --git a/packaging/git-buildpackage.changes b/packaging/git-buildpackage.changes index 735d6d74..5f8ecf55 100644 --- a/packaging/git-buildpackage.changes +++ b/packaging/git-buildpackage.changes @@ -1,4 +1,4 @@ -* Wed Mar 02 2016 Jun Wang tizen/0.6.26-20150206 +* Wed Mar 02 2016 Jun Wang tizen/0.6.27-20160302 - Upgrade version to 0.6.27 * Fri Feb 06 2015 Markus Lehtonen tizen/0.6.22-20150206 diff --git a/packaging/git-buildpackage.spec b/packaging/git-buildpackage.spec index 55a1752c..c610606a 100644 --- a/packaging/git-buildpackage.spec +++ b/packaging/git-buildpackage.spec @@ -3,7 +3,7 @@ Name: git-buildpackage Summary: Build packages from git -Version: 0.6.26 +Version: 0.6.27 Release: 0 Group: Development/Tools/Building License: GPLv2 @@ -115,7 +115,7 @@ Recommends: rpm-build %else Requires: rpm-build %endif -Provides: tizen-gbp-rpm = 20150206 +Provides: tizen-gbp-rpm = 20160302 %description rpm Set of tools from Debian that integrate the package build system with Git. -- cgit v1.2.3 From 474a3c1b348bb9f69ea3e07f9f1da50d727c363d Mon Sep 17 00:00:00 2001 From: Jun Wang Date: Thu, 3 Mar 2016 03:52:52 +0800 Subject: Fix build errors in CentOS7 Change-Id: I4c690c005d23f4b184a0aa7ee3cf2306ad3cf3ad --- packaging/git-buildpackage.spec | 14 +++++--------- 1 file changed, 5 insertions(+), 9 deletions(-) diff --git a/packaging/git-buildpackage.spec b/packaging/git-buildpackage.spec index c610606a..8a9e3cad 100644 --- a/packaging/git-buildpackage.spec +++ b/packaging/git-buildpackage.spec @@ -12,15 +12,11 @@ URL: https://honk.sigxcpu.org/piki/projects/git-buildpackage/ Source0: %{name}_%{version}.tar.gz # Conditional package names for requirements -%if 0%{?fedora} || 0%{?centos_ver} > 7 -%define dpkg_pkg_name dpkg-dev -%else -%if 0%{?centos_version} +%if 0%{?fedora} || 0%{?centos_ver} %define dpkg_pkg_name dpkg-devel %else %define dpkg_pkg_name dpkg %endif -%endif %if 0%{?suse_version} && 0%{?suse_version} < 1230 %define devscripts_pkg_name devscripts-fixes @@ -34,7 +30,7 @@ Source0: %{name}_%{version}.tar.gz %define man_pkg_name man %endif -%if 0%{?fedora} || 0%{?centos_version} || 0%{?centos_ver} || 0%{?tizen_version:1} +%if 0%{?fedora} || 0%{?centos_ver} || 0%{?tizen_version:1} %define python_pkg_name python %else %define python_pkg_name python-base @@ -177,6 +173,7 @@ GIT_CEILING_DIRECTORIES=%{_builddir} \ %install rm -rf %{buildroot} WITHOUT_NOSETESTS=1 %{__python} ./setup.py install --root=%{buildroot} --prefix=/usr +rm -rf %{buildroot}%{python_sitelib}/*info %if %{with docs} # Install man pages @@ -222,8 +219,8 @@ cat >> files.list << EOF EOF %endif -# Disable the debian tools for old CentOS -%if 0%{?centos_version} && 0%{?centos_ver} < 7 +# Disable the debian tools for CentOS +%if 0%{?centos_version} for f in `cat files.list`; do rm -rfv %{buildroot}/$f done @@ -244,7 +241,6 @@ done %dir %{python_sitelib}/gbp/pkg %dir %{python_sitelib}/gbp/scripts %dir %{python_sitelib}/gbp/scripts/common -%{python_sitelib}/gbp-* %{python_sitelib}/gbp/*.py* %{python_sitelib}/gbp/scripts/__init__.py* %{python_sitelib}/gbp/scripts/clone.py* -- cgit v1.2.3 From 5bc292d8a471ad929a2d1c4d29de2006665b21de Mon Sep 17 00:00:00 2001 From: Jun Wang Date: Tue, 8 Mar 2016 18:00:33 +0800 Subject: Check devel branch codes to be good from latest release tizen/0.6.27-20160302 Change-Id: I87f32c6b28b8835c09004530d7e6e429143dc4bf --- bin/gbp-pq-rpm | 5 ++ bin/git-buildpackage-rpm | 5 ++ bin/git-import-orig-rpm | 5 ++ bin/git-import-srpm | 5 ++ bin/git-pbuilder | 3 +- bin/git-rpm-ch | 5 ++ debian/changelog | 105 +++++++++++++++--------------- debian/git-buildpackage-common.install | 29 +++------ debian/git-buildpackage-rpm.install | 5 +- debian/git-buildpackage.install | 17 +++-- gbp/pkg/__init__.py | 75 ++++----------------- gbp/rpm/__init__.py | 65 ------------------- gbp/rpm/git.py | 4 +- gbp/scripts/buildpackage_rpm.py | 15 +++-- gbp/scripts/common/buildpackage.py | 2 - gbp/scripts/common/import_orig.py | 115 ++++++++++++++++++--------------- gbp/scripts/pq_rpm.py | 24 ++++--- gbp/scripts/rpm_ch.py | 2 +- packaging/PKGBUILD | 4 +- setup.py | 7 +- 20 files changed, 206 insertions(+), 291 deletions(-) create mode 100644 bin/gbp-pq-rpm create mode 100644 bin/git-buildpackage-rpm create mode 100644 bin/git-import-orig-rpm create mode 100644 bin/git-import-srpm create mode 100644 bin/git-rpm-ch diff --git a/bin/gbp-pq-rpm b/bin/gbp-pq-rpm new file mode 100644 index 00000000..528020df --- /dev/null +++ b/bin/gbp-pq-rpm @@ -0,0 +1,5 @@ +#! /usr/bin/python -u +import sys +from gbp.scripts.pq_rpm import main + +sys.exit(main(sys.argv)) diff --git a/bin/git-buildpackage-rpm b/bin/git-buildpackage-rpm new file mode 100644 index 00000000..393f1ae1 --- /dev/null +++ b/bin/git-buildpackage-rpm @@ -0,0 +1,5 @@ +#! /usr/bin/python -u +import sys +from gbp.scripts.buildpackage_rpm import main + +sys.exit(main(sys.argv)) diff --git a/bin/git-import-orig-rpm b/bin/git-import-orig-rpm new file mode 100644 index 00000000..9e760c00 --- /dev/null +++ b/bin/git-import-orig-rpm @@ -0,0 +1,5 @@ +#! /usr/bin/python -u +import sys +from gbp.scripts.import_orig_rpm import main + +sys.exit(main(sys.argv)) diff --git a/bin/git-import-srpm b/bin/git-import-srpm new file mode 100644 index 00000000..721741b7 --- /dev/null +++ b/bin/git-import-srpm @@ -0,0 +1,5 @@ +#! /usr/bin/python -u +import sys +from gbp.scripts.import_srpm import main + +sys.exit(main(sys.argv)) diff --git a/bin/git-pbuilder b/bin/git-pbuilder index a9104d7a..a003b266 100644 --- a/bin/git-pbuilder +++ b/bin/git-pbuilder @@ -228,8 +228,7 @@ update|create|login) sudo "$BUILDER" --"$action" --distribution "$DIST" \ --othermirror "$OTHERMIRROR" "${OPTIONS[@]}" "$@" else - sudo "$BUILDER" --"$action" --distribution "$DIST" \ - "${OPTIONS[@]}" "$@" + sudo "$BUILDER" --"$action" --distribution "$DIST" "${OPTIONS[@]}" "$@" fi fi exit $? diff --git a/bin/git-rpm-ch b/bin/git-rpm-ch new file mode 100644 index 00000000..ef1340e7 --- /dev/null +++ b/bin/git-rpm-ch @@ -0,0 +1,5 @@ +#! /usr/bin/python -u +import sys +from gbp.scripts.rpm_ch import main + +sys.exit(main(sys.argv)) diff --git a/debian/changelog b/debian/changelog index bbd64edb..ee6ad668 100644 --- a/debian/changelog +++ b/debian/changelog @@ -62,6 +62,60 @@ git-buildpackage (0.6.22-tizen20150206) unstable; urgency=low -- Markus Lehtonen Fri, 06 Feb 2015 10:36:26 +0200 + * Upgrade version to 0.6.25 + + -- Rong Jinhui Thu, 04 Aug 2015 08:53:30 +0800 + +git-buildpackage (0.6.15-tizen20140828) unstable; urgency=low + + [ Markus Lehtonen ] + * Rebase on top of upstream version 0.6.15 + * Changes in buildpackage-rpm + - new 'commitish' keyword for spec vcs tag + - notify: catch RuntimeError when importing pynotify + - fix exit code in case of GitRepositoryError + - always create tarball for native packages + - check submodules from the exported treeish + - fix crash when running prebuild hook + - always run cleaner hook + - add --git-no-build option + - don't crash on invalid vcs format strings + - add '--git-native' option + - remove some outdated/unnecessary exception handling + - get rid of prepare_export_dir() + - handle invalid keys in orig prefix + - internal refactoring and fixes + * Changes in rpm-ch + - implement --commit option + - implement --commit-msg option + - rpm-ch: implement --meta-bts option + - rpm.policy: don't allow leading whitespace in bts meta tags + * docs: manpages for the rpm tools + * Misc. fixes and features + - buildpackage: refactor tarball compression + - gbp-dch: fix handling of the '--meta' option + - import-orig-rpm: download tarball into parent directory + - GitRepository/has_submodules: add treeish argument + - tristate: implement __nonzero__() method + * Logging: + - don't automatically setup gbp-specific logger + - fix auto colorizing for custom streams + * Tests + - multiple fixes and additions in ComponentTestBase class + - testutils: add directories arg to ls_* functions + - add unit tests for buildpackage-rpm + * Packaging + - rpm-packaging: recommend/require unzip + - recommend/require zipmerge + - depend/recommend rpmbuild + + [ Junchun Guan ] + * Add PKGBUILD to support arch linux + + [ Li Jinjing ] + * rpm packaging: use macro for python binary + + -- Markus Lehtonen Thu, 28 Aug 2014 11:40:05 +0300 git-buildpackage (0.6.22) unstable; urgency=medium * [3d8939d] git.vfs: fix close method. Preventing a infinite recursion @@ -147,57 +201,6 @@ git-buildpackage (0.6.16) experimental; urgency=medium -- Guido Günther Mon, 28 Jul 2014 15:57:49 +0200 -git-buildpackage (0.6.15-tizen20140828) unstable; urgency=low - - [ Markus Lehtonen ] - * Rebase on top of upstream version 0.6.15 - * Changes in buildpackage-rpm - - new 'commitish' keyword for spec vcs tag - - notify: catch RuntimeError when importing pynotify - - fix exit code in case of GitRepositoryError - - always create tarball for native packages - - check submodules from the exported treeish - - fix crash when running prebuild hook - - always run cleaner hook - - add --git-no-build option - - don't crash on invalid vcs format strings - - add '--git-native' option - - remove some outdated/unnecessary exception handling - - get rid of prepare_export_dir() - - handle invalid keys in orig prefix - - internal refactoring and fixes - * Changes in rpm-ch - - implement --commit option - - implement --commit-msg option - - rpm-ch: implement --meta-bts option - - rpm.policy: don't allow leading whitespace in bts meta tags - * docs: manpages for the rpm tools - * Misc. fixes and features - - buildpackage: refactor tarball compression - - gbp-dch: fix handling of the '--meta' option - - import-orig-rpm: download tarball into parent directory - - GitRepository/has_submodules: add treeish argument - - tristate: implement __nonzero__() method - * Logging: - - don't automatically setup gbp-specific logger - - fix auto colorizing for custom streams - * Tests - - multiple fixes and additions in ComponentTestBase class - - testutils: add directories arg to ls_* functions - - add unit tests for buildpackage-rpm - * Packaging - - rpm-packaging: recommend/require unzip - - recommend/require zipmerge - - depend/recommend rpmbuild - - [ Junchun Guan ] - * Add PKGBUILD to support arch linux - - [ Li Jinjing ] - * rpm packaging: use macro for python binary - - -- Markus Lehtonen Thu, 28 Aug 2014 11:40:05 +0300 - git-buildpackage (0.6.15) unstable; urgency=medium * [5cde49a] Revert "Determine build_dir upfront" diff --git a/debian/git-buildpackage-common.install b/debian/git-buildpackage-common.install index 722eab68..5283d546 100644 --- a/debian/git-buildpackage-common.install +++ b/debian/git-buildpackage-common.install @@ -1,24 +1,13 @@ usr/bin/gbp usr/bin/gbp-clone usr/bin/gbp-pull -usr/lib/python2.?/dist-packages/gbp-* -usr/lib/python2.?/dist-packages/gbp/command_wrappers.py -usr/lib/python2.?/dist-packages/gbp/config.py -usr/lib/python2.?/dist-packages/gbp/errors.py -usr/lib/python2.?/dist-packages/gbp/format.py -usr/lib/python2.?/dist-packages/gbp/git/ -usr/lib/python2.?/dist-packages/gbp/__init__.py -usr/lib/python2.?/dist-packages/gbp/log.py -usr/lib/python2.?/dist-packages/gbp/notifications.py -usr/lib/python2.?/dist-packages/gbp/patch_series.py -usr/lib/python2.?/dist-packages/gbp/pkg/ -usr/lib/python2.?/dist-packages/gbp/scripts/clone.py -usr/lib/python2.?/dist-packages/gbp/scripts/common/ -usr/lib/python2.?/dist-packages/gbp/scripts/config.py -usr/lib/python2.?/dist-packages/gbp/scripts/__init__.py -usr/lib/python2.?/dist-packages/gbp/scripts/pull.py -usr/lib/python2.?/dist-packages/gbp/scripts/supercommand.py -usr/lib/python2.?/dist-packages/gbp/tmpfile.py -usr/lib/python2.?/dist-packages/gbp/tristate.py -usr/lib/python2.?/dist-packages/gbp/version.py +usr/lib/python*/dist-packages/gbp/*.py* +usr/lib/python*/dist-packages/gbp/scripts/__init__.py* +usr/lib/python*/dist-packages/gbp/scripts/clone.py* +usr/lib/python*/dist-packages/gbp/scripts/config.py* +usr/lib/python*/dist-packages/gbp/scripts/pull.py* +usr/lib/python*/dist-packages/gbp/scripts/supercommand.py* +usr/lib/python*/dist-packages/gbp/scripts/common/*.py* +usr/lib/python*/dist-packages/gbp/git/*.py* +usr/lib/python*/dist-packages/gbp/pkg/*.py* etc/git-buildpackage/gbp.conf diff --git a/debian/git-buildpackage-rpm.install b/debian/git-buildpackage-rpm.install index f243ebb9..8c49491e 100644 --- a/debian/git-buildpackage-rpm.install +++ b/debian/git-buildpackage-rpm.install @@ -1,2 +1,3 @@ -usr/lib/python2.?/dist-packages/gbp/rpm/ -usr/lib/python2.?/dist-packages/gbp/scripts/*rpm*.py* +usr/bin/*rpm* +usr/lib/python*/dist-packages/gbp/rpm/*.py* +usr/lib/python*/dist-packages/gbp/scripts/*rpm*.py* diff --git a/debian/git-buildpackage.install b/debian/git-buildpackage.install index 291cb15a..7a276d7e 100644 --- a/debian/git-buildpackage.install +++ b/debian/git-buildpackage.install @@ -6,12 +6,11 @@ usr/bin/git-import-dscs usr/bin/git-import-orig usr/bin/git-pbuilder usr/bin/gbp-create-remote-repo -usr/lib/python2.?/dist-packages/gbp/dch.py -usr/lib/python2.?/dist-packages/gbp/deb/ -usr/lib/python2.?/dist-packages/gbp/scripts/buildpackage.py -usr/lib/python2.?/dist-packages/gbp/scripts/create_remote_repo.py -usr/lib/python2.?/dist-packages/gbp/scripts/dch.py -usr/lib/python2.?/dist-packages/gbp/scripts/import_dsc.py -usr/lib/python2.?/dist-packages/gbp/scripts/import_dscs.py -usr/lib/python2.?/dist-packages/gbp/scripts/import_orig.py -usr/lib/python2.?/dist-packages/gbp/scripts/pq.py +usr/lib/python*/dist-packages/gbp/deb/*.py* +usr/lib/python*/dist-packages/gbp/scripts/pq.py* +usr/lib/python*/dist-packages/gbp/scripts/buildpackage.py* +usr/lib/python*/dist-packages/gbp/scripts/dch.py* +usr/lib/python*/dist-packages/gbp/scripts/import_dsc.py* +usr/lib/python*/dist-packages/gbp/scripts/import_dscs.py* +usr/lib/python*/dist-packages/gbp/scripts/import_orig.py* +usr/lib/python*/dist-packages/gbp/scripts/create_remote_repo.py* diff --git a/gbp/pkg/__init__.py b/gbp/pkg/__init__.py index 4e99efe9..8162286b 100644 --- a/gbp/pkg/__init__.py +++ b/gbp/pkg/__init__.py @@ -142,67 +142,6 @@ class PkgPolicy(object): return True return False - @classmethod - def guess_upstream_src_version(cls, filename, extra_regex=r''): - """ - Guess the package name and version from the filename of an upstream - archive. - - @param filename: filename (archive or directory) from which to guess - @type filename: C{string} - @param extra_regex: additional regex to apply, needs a 'package' and a - 'version' group - @return: (package name, version) or ('', '') - @rtype: tuple - - >>> PkgPolicy.guess_upstream_src_version('foo-bar_0.2.orig.tar.gz') - ('foo-bar', '0.2') - >>> PkgPolicy.guess_upstream_src_version('foo-Bar_0.2.orig.tar.gz') - ('foo-Bar', '0.2.orig') - >>> PkgPolicy.guess_upstream_src_version('git-bar-0.2.tar.gz') - ('git-bar', '0.2') - >>> PkgPolicy.guess_upstream_src_version('git-bar-0.2-rc1.tar.gz') - ('git-bar', '0.2-rc1') - >>> PkgPolicy.guess_upstream_src_version('git-bar-0.2:~-rc1.tar.gz') - ('git-bar', '0.2:~-rc1') - >>> PkgPolicy.guess_upstream_src_version('git-Bar-0A2d:rc1.tar.bz2') - ('git-Bar', '0A2d:rc1') - >>> PkgPolicy.guess_upstream_src_version('git-1.tar.bz2') - ('git', '1') - >>> PkgPolicy.guess_upstream_src_version('kvm_87+dfsg.orig.tar.gz') - ('kvm', '87+dfsg') - >>> PkgPolicy.guess_upstream_src_version('foo-Bar-a.b.tar.gz') - ('', '') - >>> PkgPolicy.guess_upstream_src_version('foo-bar_0.2.orig.tar.xz') - ('foo-bar', '0.2') - >>> PkgPolicy.guess_upstream_src_version('foo-bar_0.2.tar.gz') - ('foo-bar', '0.2') - >>> PkgPolicy.guess_upstream_src_version('foo-bar_0.2.orig.tar.lzma') - ('foo-bar', '0.2') - >>> PkgPolicy.guess_upstream_src_version('foo-bar-0.2.zip') - ('foo-bar', '0.2') - >>> PkgPolicy.guess_upstream_src_version('foo-bar-0.2.tlz') - ('foo-bar', '0.2') - """ - version_chars = r'[a-zA-Z\d\.\~\-\:\+]' - basename = parse_archive_filename(os.path.basename(filename))[0] - - version_filters = map ( lambda x: x % version_chars, - ( # Debian upstream tarball: package_'.orig.tar.gz' - r'^(?P[a-z\d\.\+\-]+)_(?P%s+)\.orig', - # Upstream 'package-.tar.gz' - # or Debian native 'package_.tar.gz' - # or directory 'package-': - r'^(?P[a-zA-Z\d\.\+\-]+)(-|_)(?P[0-9]%s*)')) - if extra_regex: - version_filters = extra_regex + version_filters - - for filter in version_filters: - m = re.match(filter, basename) - if m: - return (m.group('package'), m.group('version')) - return ('', '') - @staticmethod def guess_upstream_src_version(filename, extra_regex=r''): """ @@ -441,11 +380,25 @@ class UpstreamSource(object): @property def archive_fmt(self): """Archive format of the sources, e.g. 'tar'""" + """ + >>> UpstreamSource('foo/bar.tar.gz').archive_fmt + 'tar' + >>> UpstreamSource('foo.bar.zip').archive_fmt + 'zip' + >>> UpstreamSource('foo.bar.baz').archive_fmt + """ return self._archive_fmt @property def compression(self): """Compression format of the sources, e.g. 'gzip'""" + """ + >>> UpstreamSource('foo/bar.tar.gz').compression + 'gzip' + >>> UpstreamSource('foo.bar.zip').compression + >>> UpstreamSource('foo.bz2').compression + 'bzip2' + """ return self._compression @property diff --git a/gbp/rpm/__init__.py b/gbp/rpm/__init__.py index 22983d2d..4c5c22bf 100644 --- a/gbp/rpm/__init__.py +++ b/gbp/rpm/__init__.py @@ -902,69 +902,4 @@ def string_to_int(val_str): return int(val_str) -def split_version_str(version): - """ - Parse full version string and split it into individual "version - components", i.e. upstreamversion, epoch and release - - @param version: full version of a package - @type version: C{str} - @return: individual version components - @rtype: C{dict} - - >>> split_version_str("1") - {'release': None, 'epoch': None, 'upstreamversion': '1'} - >>> split_version_str("1.2.3-5.3") - {'release': '5.3', 'epoch': None, 'upstreamversion': '1.2.3'} - >>> split_version_str("3:1.2.3") - {'release': None, 'epoch': '3', 'upstreamversion': '1.2.3'} - >>> split_version_str("3:1-0") - {'release': '0', 'epoch': '3', 'upstreamversion': '1'} - """ - ret = {'epoch': None, 'upstreamversion': None, 'release': None} - - e_vr = version.split(":", 1) - if len(e_vr) == 1: - v_r = e_vr[0].split("-", 1) - else: - ret['epoch'] = e_vr[0] - v_r = e_vr[1].split("-", 1) - ret['upstreamversion'] = v_r[0] - if len(v_r) > 1: - ret['release'] = v_r[1] - - return ret - -def compose_version_str(evr): - """ - Compose a full version string from individual "version components", - i.e. epoch, version and release - - @param evr: dict of version components - @type evr: C{dict} of C{str} - @return: full version - @rtype: C{str} - - >>> compose_version_str({'epoch': '', 'upstreamversion': '1.0'}) - '1.0' - >>> compose_version_str({'epoch': '2', 'upstreamversion': '1.0', 'release': None}) - '2:1.0' - >>> compose_version_str({'epoch': None, 'upstreamversion': '1', 'release': '0'}) - '1-0' - >>> compose_version_str({'epoch': '2', 'upstreamversion': '1.0', 'release': '2.3'}) - '2:1.0-2.3' - >>> compose_version_str({'epoch': '2', 'upstreamversion': '', 'release': '2.3'}) - """ - if 'upstreamversion' in evr and evr['upstreamversion']: - version = "" - if 'epoch' in evr and evr['epoch']: - version += "%s:" % evr['epoch'] - version += evr['upstreamversion'] - if 'release' in evr and evr['release']: - version += "-%s" % evr['release'] - if version: - return version - return None - - # vim:et:ts=4:sw=4:et:sts=4:ai:set list listchars=tab\:»·,trail\:·: diff --git a/gbp/rpm/git.py b/gbp/rpm/git.py index c7cc023b..92f8b2e0 100644 --- a/gbp/rpm/git.py +++ b/gbp/rpm/git.py @@ -19,7 +19,7 @@ import re from gbp.git import GitRepository, GitRepositoryError from gbp.pkg.pristinetar import PristineTar -from gbp.rpm import compose_version_str +from gbp.rpm.policy import RpmPkgPolicy class RpmGitRepository(GitRepository): """A git repository that holds the source of an RPM package""" @@ -66,7 +66,7 @@ class RpmGitRepository(GitRepository): 'myvendor/v1.0-2' """ version_tag = format % dict(str_fields, - version=compose_version_str(str_fields)) + version=RpmPkgPolicy.compose_full_version(str_fields)) return RpmGitRepository._sanitize_tag(version_tag) @staticmethod diff --git a/gbp/scripts/buildpackage_rpm.py b/gbp/scripts/buildpackage_rpm.py index 2b4f6386..56db5e13 100755 --- a/gbp/scripts/buildpackage_rpm.py +++ b/gbp/scripts/buildpackage_rpm.py @@ -137,10 +137,10 @@ def pristine_tar_build_orig(repo, orig_file, output_dir, options): raise return False -def get_upstream_tree(repo, version, options): +def get_upstream_tree(repo, spec, options): """Determine the upstream tree from the given options""" if options.upstream_tree.upper() == 'TAG': - tag_str_fields = {"upstreamversion": version, "vendor": "Upstream"} + tag_str_fields = dict(upstreamversion=spec.upstreamversion, vendor="Upstream") upstream_tree = repo.version_to_tag(options.upstream_tag, tag_str_fields) elif options.upstream_tree.upper() == 'BRANCH': if not repo.has_branch(options.upstream_branch): @@ -257,7 +257,7 @@ def git_archive_build_orig(repo, spec, output_dir, options): @rtype: C{str} """ try: - upstream_tree = get_upstream_tree(repo, spec.upstreamversion, options) + upstream_tree = get_upstream_tree(repo, spec, options) gbp.log.info("%s does not exist, creating from '%s'" % \ (spec.orig_src['filename'], upstream_tree)) if spec.orig_src['compression']: @@ -279,7 +279,7 @@ def export_patches(repo, spec, export_treeish, options): Generate patches and update spec file """ try: - upstream_tree = get_upstream_tree(repo, spec.upstreamversion, options) + upstream_tree = get_upstream_tree(repo, spec, options) update_patch_series(repo, spec, upstream_tree, export_treeish, options) except (GitRepositoryError, GbpError) as err: raise GbpAutoGenerateError(str(err)) @@ -353,9 +353,9 @@ def update_tag_str_fields(fields, tag_format_str, repo, commit_info): break -def packaging_tag_name(repo, version, commit_info, options): +def packaging_tag_name(repo, spec, commit_info, options): """Compose packaging tag as string""" - tag_str_fields = dict(version, vendor=options.vendor) + tag_str_fields = dict(spec.version, vendor=options.vendor) update_tag_str_fields(tag_str_fields, options.packaging_tag, repo, commit_info) return repo.version_to_tag(options.packaging_tag, tag_str_fields) @@ -667,7 +667,7 @@ def main(argv): if options.tag or options.tag_only: gbp.log.info("Tagging %s" % RpmPkgPolicy.compose_full_version(spec.version)) commit_info = repo.get_commit_info(tree) - tag = packaging_tag_name(repo, spec.version, commit_info, options) + tag = packaging_tag_name(repo, spec, commit_info, options) if options.retag and repo.has_tag(tag): repo.delete_tag(tag) create_packaging_tag(repo, tag, commit=tree, version=spec.version, @@ -708,6 +708,7 @@ def main(argv): if not options.tag_only: if spec and options.notify: summary = "Gbp-rpm %s" % ["failed", "successful"][not retval] + pkg_evr = {'upstreamversion': spec.version} message = ("Build of %s %s %s" % (spec.name, RpmPkgPolicy.compose_full_version(spec.version), ["failed", "succeeded"][not retval])) diff --git a/gbp/scripts/common/buildpackage.py b/gbp/scripts/common/buildpackage.py index 670f6823..d089df5a 100644 --- a/gbp/scripts/common/buildpackage.py +++ b/gbp/scripts/common/buildpackage.py @@ -73,7 +73,6 @@ def compress(cmd, options, output, input_data=None): except (OSError, IOError) as err: raise GbpError("Error creating %s: %s" % (output, err)) - def git_archive_submodules(repo, treeish, output, tmpdir_base, prefix, comp_type, comp_level, comp_opts, format='tar'): """ @@ -143,7 +142,6 @@ def untar_data(outdir, data): if popen.wait(): raise GbpError("Error extracting tar to %s" % outdir) - #{ Functions to handle export-dir def dump_tree(repo, export_dir, treeish, with_submodules, recursive=True): """Dump a git tree-ish to output_dir""" diff --git a/gbp/scripts/common/import_orig.py b/gbp/scripts/common/import_orig.py index adbfff5e..45e71c57 100644 --- a/gbp/scripts/common/import_orig.py +++ b/gbp/scripts/common/import_orig.py @@ -78,59 +78,6 @@ def ask_package_version(default, ver_validator_func, err_msg): # bit clearer. gbp.log.warn("\nNot a valid upstream version: '%s'.\n%s" % (version, err_msg)) - -def prepare_pristine_tar(source, pkg_name, pkg_version, pristine_commit_name, - filters=None, prefix=None, tmpdir=None): - """ - Prepare the upstream sources for pristine-tar import - - @param source: original upstream sources - @type source: C{UpstreamSource} - @param pkg_name: package name - @type pkg_name: C{str} - @param pkg_version: upstream version of the package - @type pkg_version: C{str} - @param pristine_commit_name: archive filename to commit to pristine-tar - @type pristine_commit_name: C{str} or C{None} - @param filters: filter to exclude files - @type filters: C{list} of C{str} or C{None} - @param prefix: prefix (i.e. leading directory of files) to use in - pristine-tar, set to C{None} to not mangle orig archive - @type prefix: C{str} or C{None} - @param tmpdir: temporary working dir (cleanup left to caller) - @type tmpdir: C{str} - @return: prepared source archive - @rtype: C{UpstreamSource} - """ - need_repack = False - if source.is_dir(): - if prefix is None: - prefix = '%s-%s' % (pkg_name, pkg_version) - gbp.log.info("Using guessed prefix '%s/' for pristine-tar" % prefix) - need_repack = True - else: - if prefix is not None and prefix == source.prefix: - prefix = None - comp = parse_archive_filename(pristine_commit_name)[2] - if filters or prefix is not None or source.compression != comp: - if not source.unpacked: - unpack_dir = tempfile.mkdtemp(prefix='pristine_unpack_', - dir=tmpdir) - source.unpack(unpack_dir) - need_repack = True - pristine_path = os.path.join(tmpdir, pristine_commit_name) - if need_repack: - gbp.log.debug("Packing '%s' from '%s' for pristine-tar" % - (pristine_path, source.unpacked)) - pristine = source.pack(pristine_path, filters, prefix) - else: - # Just create symlink for mangling the pristine tarball name - os.symlink(source.path, pristine_path) - pristine = source.__class__(pristine_path) - - return pristine - - def prepare_sources(source, pkg_name, pkg_version, pristine_commit_name, filters, filter_pristine, prefix, tmpdir): """ @@ -201,3 +148,65 @@ def prepare_sources(source, pkg_name, pkg_version, pristine_commit_name, pristine_path = pristine.path if pristine else '' return (filtered.unpacked, pristine_path) +def repack_source(source, new_name, unpack_dir, filters, new_prefix=None): + """Repack the source tree""" + repacked = source.pack(new_name, filters, new_prefix) + if source.is_tarball(): # the tarball was filtered on unpack + repacked.unpacked = source.unpacked + else: # otherwise unpack the generated tarball get a filtered tree + repacked.unpack(unpack_dir) + return repacked + + +def prepare_pristine_tar(source, pkg_name, pkg_version, pristine_commit_name, + filters=None, prefix=None, tmpdir=None): + """ + Prepare the upstream sources for pristine-tar import + + @param source: original upstream sources + @type source: C{UpstreamSource} + @param pkg_name: package name + @type pkg_name: C{str} + @param pkg_version: upstream version of the package + @type pkg_version: C{str} + @param pristine_commit_name: archive filename to commit to pristine-tar + @type pristine_commit_name: C{str} or C{None} + @param filters: filter to exclude files + @type filters: C{list} of C{str} or C{None} + @param prefix: prefix (i.e. leading directory of files) to use in + pristine-tar, set to C{None} to not mangle orig archive + @type prefix: C{str} or C{None} + @param tmpdir: temporary working dir (cleanup left to caller) + @type tmpdir: C{str} + @return: prepared source archive + @rtype: C{UpstreamSource} + """ + need_repack = False + if source.is_dir(): + if prefix is None: + prefix = '%s-%s' % (pkg_name, pkg_version) + gbp.log.info("Using guessed prefix '%s/' for pristine-tar" % prefix) + need_repack = True + else: + if prefix is not None and prefix == source.prefix: + prefix = None + comp = parse_archive_filename(pristine_commit_name)[2] + if filters or prefix is not None or source.compression != comp: + if not source.unpacked: + unpack_dir = tempfile.mkdtemp(prefix='pristine_unpack_', + dir=tmpdir) + source.unpack(unpack_dir) + need_repack = True + pristine_path = os.path.join(tmpdir, pristine_commit_name) + if need_repack: + gbp.log.debug("Packing '%s' from '%s' for pristine-tar" % + (pristine_path, source.unpacked)) + pristine = source.pack(pristine_path, filters, prefix) + else: + # Just create symlink for mangling the pristine tarball name + os.symlink(source.path, pristine_path) + pristine = source.__class__(pristine_path) + + return pristine + + diff --git a/gbp/scripts/pq_rpm.py b/gbp/scripts/pq_rpm.py index d8fcbf2f..e19218a9 100755 --- a/gbp/scripts/pq_rpm.py +++ b/gbp/scripts/pq_rpm.py @@ -27,11 +27,10 @@ import re import gzip import bz2 import subprocess - import gbp.tmpfile as tempfile from gbp.config import GbpOptionParserRpm from gbp.rpm.git import GitRepositoryError, RpmGitRepository -from gbp.git.modifier import GitModifier +from gbp.git.modifier import GitModifier, GitTz from gbp.command_wrappers import GitCommand, CommandExecFailed from gbp.errors import GbpError import gbp.log @@ -243,13 +242,14 @@ def parse_spec(options, repo, treeish=None): return spec -def find_upstream_commit(repo, upstreamversion, upstream_tag): +def find_upstream_commit(repo, spec, upstream_tag): """Find commit corresponding upstream version""" - tag_str_fields = {'upstreamversion': upstreamversion, + tag_str_fields = {'upstreamversion': spec.upstreamversion, 'vendor': 'Upstream'} upstream_commit = repo.find_version(upstream_tag, tag_str_fields) if not upstream_commit: - raise GbpError("Couldn't find upstream version %s" % upstreamversion) + raise GbpError("Couldn't find upstream version %s" % + spec.upstreamversion) return upstream_commit @@ -265,10 +265,11 @@ def export_patches(repo, options): else: spec = parse_spec(options, repo) pq_branch = pq_branch_name(current, options, spec.version) - upstream_commit = find_upstream_commit(repo, spec.upstreamversion, - options.upstream_tag) + upstream_commit = find_upstream_commit(repo, spec, options.upstream_tag) export_treeish = options.export_rev if options.export_rev else pq_branch + if not repo.has_treeish(export_treeish): + raise GbpError('Invalid treeish object %s' % export_treeish) update_patch_series(repo, spec, upstream_commit, export_treeish, options) @@ -377,8 +378,7 @@ def import_spec_patches(repo, options): spec = parse_spec(options, repo) spec_treeish = None base = current - upstream_commit = find_upstream_commit(repo, spec.upstreamversion, - options.upstream_tag) + upstream_commit = find_upstream_commit(repo, spec, options.upstream_tag) packager = get_packager(spec) pq_branch = pq_branch_name(base, options, spec.version) @@ -435,8 +435,7 @@ def rebase_pq(repo, options): else: base = current spec = parse_spec(options, repo) - upstream_commit = find_upstream_commit(repo, spec.upstreamversion, - options.upstream_tag) + upstream_commit = find_upstream_commit(repo, spec, options.upstream_tag) switch_to_pq_branch(repo, base, options) GitCommand("rebase")([upstream_commit]) @@ -502,8 +501,7 @@ def convert_package(repo, options): pq_branch = pq_branch_name(old_packaging, options, spec.version) raise GbpError(err_msg_base + "pq branch %s already exists" % pq_branch) # Check that the current branch is based on upstream - upstream_commit = find_upstream_commit(repo, spec.upstreamversion, - options.upstream_tag) + upstream_commit = find_upstream_commit(repo, spec, options.upstream_tag) if not is_ancestor(repo, upstream_commit, old_packaging): raise GbpError(err_msg_base + "%s is not based on upstream version %s" % (old_packaging, spec.upstreamversion)) diff --git a/gbp/scripts/rpm_ch.py b/gbp/scripts/rpm_ch.py index 5bbf6155..33058372 100755 --- a/gbp/scripts/rpm_ch.py +++ b/gbp/scripts/rpm_ch.py @@ -330,7 +330,7 @@ def update_changelog(changelog, entries, repo, spec, options): # Get fake information for the to-be-created git commit commit_info = {'author': GitModifier(date=now), 'committer': GitModifier(date=now)} - tag = packaging_tag_name(repo, spec.version, commit_info, options) + tag = packaging_tag_name(repo, spec, commit_info, options) else: commit_info = {'author': None, 'committer': None} tag = repo.describe('HEAD', longfmt=True, always=True) diff --git a/packaging/PKGBUILD b/packaging/PKGBUILD index dbe4b00b..60ffa9f6 100644 --- a/packaging/PKGBUILD +++ b/packaging/PKGBUILD @@ -1,6 +1,6 @@ pkgbase='git-buildpackage' pkgname=('git-buildpackage-rpm' 'git-buildpackage-common' 'git-buildpackage-doc') -pkgver=0.6.15 +pkgver=0.6.27 pkgrel=0 pkgdesc="Tools from Debian to integrate the package build system with Git" arch=(any) @@ -53,7 +53,7 @@ package_git-buildpackage-common() { package_git-buildpackage-rpm() { depends=("git-buildpackage-common=$pkgver-$pkgrel" "rpm") - provides=("tizen-gbp-rpm=20140605") + provides=("tizen-gbp-rpm=20160302") cd $srcdir/$pkgbase-$pkgver WITHOUT_NOSETESTS=1 \ python2 setup.py install \ diff --git a/setup.py b/setup.py index 8d4fc443..e733f9d7 100644 --- a/setup.py +++ b/setup.py @@ -70,7 +70,12 @@ setup(name = "gbp", 'bin/gbp-pull', 'bin/gbp-clone', 'bin/gbp-create-remote-repo', - 'bin/git-pbuilder'], + 'bin/git-pbuilder', + 'bin/git-import-srpm', + 'bin/gbp-pq-rpm', + 'bin/git-buildpackage-rpm', + 'bin/git-import-orig-rpm', + 'bin/git-rpm-ch'], packages = find_packages(exclude=['tests', 'tests.*']), data_files = [("/etc/git-buildpackage/", ["gbp.conf"]),], setup_requires=['nose>=0.11.1', 'coverage>=2.85'] if \ -- cgit v1.2.3 From 9a52da6cab99e92327416edce2c7daf75cad16c2 Mon Sep 17 00:00:00 2001 From: Jun Wang Date: Tue, 8 Mar 2016 18:18:58 +0800 Subject: Make new tag in devel Change-Id: Idc6a43b5a475733ad8568d041384319157db9a5c --- debian/changelog | 8 ++++++++ packaging/git-buildpackage.changes | 3 +++ 2 files changed, 11 insertions(+) diff --git a/debian/changelog b/debian/changelog index ee6ad668..4c36fbf8 100644 --- a/debian/changelog +++ b/debian/changelog @@ -1,3 +1,11 @@ +git-buildpackage (0.6.27-tizen20160308) unstable; urgency=medium + + * Check codes in devel branch + + -- Jun Wang TUE, 08 Mar 2016 10:20:21 +0800 + + + git-buildpackage (0.6.27-tizen20160302) unstable; urgency=medium * Fix error logs when __import__ faild,like "No handlers could be found fo logger" diff --git a/packaging/git-buildpackage.changes b/packaging/git-buildpackage.changes index 5f8ecf55..6eb0e922 100644 --- a/packaging/git-buildpackage.changes +++ b/packaging/git-buildpackage.changes @@ -1,3 +1,6 @@ +* Wed TUE 08 2016 Jun Wang tizen/0.6.27-20160308 +- Make new tag in devel + * Wed Mar 02 2016 Jun Wang tizen/0.6.27-20160302 - Upgrade version to 0.6.27 -- cgit v1.2.3 From c8f50821d3a1b2a27d2e9ba3d48176c513329ecd Mon Sep 17 00:00:00 2001 From: Jun Wang Date: Tue, 8 Mar 2016 18:50:48 +0800 Subject: fix .gitignore file Change-Id: I3ff293da5b50301425c327d044d8e7b3b4f81a80 --- .gitignore | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/.gitignore b/.gitignore index 80960ac9..afc87fff 100644 --- a/.gitignore +++ b/.gitignore @@ -18,10 +18,10 @@ docs/manpage.links docs/manpage.refs docs/version.ent -debian/git-buildpackage*.debhelper* +debian/git-buildpackage.*.debhelper +debian/git-buildpackage.debhelper.* debian/python-module-stampdir/ debian/files -debian/git-buildpackage*.substvars +debian/git-buildpackage.substvars debian/git-buildpackage/ -debian/git-buildpackage-rpm/ -debian/tmp/ + -- cgit v1.2.3 From 59467c0f9e6eff4e875cd679daeac27374d2070b Mon Sep 17 00:00:00 2001 From: Jun Wang Date: Tue, 8 Mar 2016 19:03:06 +0800 Subject: fix spec and control error Change-Id: Ia455b5475e56ff2344cba8ac3d5c47da9e306c29 --- debian/control | 13 ++++++------- packaging/git-buildpackage.spec | 1 + 2 files changed, 7 insertions(+), 7 deletions(-) diff --git a/debian/control b/debian/control index 58746a47..e5c828c9 100644 --- a/debian/control +++ b/debian/control @@ -12,12 +12,9 @@ Build-Depends: pychecker, python (>> 2.6.6-3~), python-epydoc, - python-mock, python-nose, python-pkg-resources, - python-rpm, python-setuptools, - rpm, sgml2x, librpm-tizen, # For rpm (epydoc) @@ -65,13 +62,15 @@ Description: Suite to help with Debian packages in Git repositories Package: git-buildpackage-rpm Architecture: all Depends: ${python:Depends}, + ${shlibs:Depends}, ${misc:Depends}, - git-buildpackage-common (= ${binary:Version}), python-rpm, - rpm, -Description: Suite to help with RPM packages in Git repositories + rpm2cpio, + git-buildpackage-common (= ${binary:Version}) +Recommends: rpm +Description: Suite to help with rpm packages in Git repositories This package contains the following tools: - * gbp import-srpm: import existing RPM source packages into a git + * git-import-srpm: import existing rpm source packages into a git repository * git-import-orig-rpm: import a new upstream version into the git repository * git-buildpackage-rpm: build a package out of a git repository, check for local diff --git a/packaging/git-buildpackage.spec b/packaging/git-buildpackage.spec index 8a9e3cad..d71f172d 100644 --- a/packaging/git-buildpackage.spec +++ b/packaging/git-buildpackage.spec @@ -263,6 +263,7 @@ done %files rpm %defattr(-,root,root,-) %dir %{python_sitelib}/gbp/rpm +%{_bindir}/*rpm* %{python_sitelib}/gbp/scripts/*rpm*.py* %{python_sitelib}/gbp/rpm/*py* %if %{with docs} -- cgit v1.2.3 From a4828d677b9523aa97bb594caedacb67c07875ab Mon Sep 17 00:00:00 2001 From: admin Date: Tue, 8 Mar 2016 20:01:17 +0800 Subject: add tag debian/0.6.27 Change-Id: I931ab6fa99ad1ee47fec90a8421e1185454da5ae Signed-off-by: admin --- TODO | 3 +++ 1 file changed, 3 insertions(+) diff --git a/TODO b/TODO index 295398a5..cf9c6809 100644 --- a/TODO +++ b/TODO @@ -1,5 +1,8 @@ See https://honk.sigxcpu.org/piki/projects/git-buildpackage/ + + + RPM-related things: - unit tests: - add unit tests for the rpm command line tools -- cgit v1.2.3 From b0b7977e8517e13f81b89787bfb18499fa722d6a Mon Sep 17 00:00:00 2001 From: Jun Wang Date: Wed, 9 Mar 2016 17:34:20 +0800 Subject: change version to 0.6.28 in devel branch Change-Id: I51379cbfa73533f9c7737ad9ff16107e83129d83 --- debian/changelog | 2 +- packaging/git-buildpackage.changes | 3 ++- packaging/git-buildpackage.spec | 2 +- 3 files changed, 4 insertions(+), 3 deletions(-) diff --git a/debian/changelog b/debian/changelog index 4c36fbf8..a6adc71f 100644 --- a/debian/changelog +++ b/debian/changelog @@ -1,4 +1,4 @@ -git-buildpackage (0.6.27-tizen20160308) unstable; urgency=medium +git-buildpackage (0.6.28-tizen20160308) unstable; urgency=medium * Check codes in devel branch diff --git a/packaging/git-buildpackage.changes b/packaging/git-buildpackage.changes index 6eb0e922..72b0548a 100644 --- a/packaging/git-buildpackage.changes +++ b/packaging/git-buildpackage.changes @@ -1,5 +1,6 @@ -* Wed TUE 08 2016 Jun Wang tizen/0.6.27-20160308 +* Wed TUE 08 2016 Jun Wang tizen/0.6.28-20160308 - Make new tag in devel +- Upgrade version to 0.6.28 * Wed Mar 02 2016 Jun Wang tizen/0.6.27-20160302 - Upgrade version to 0.6.27 diff --git a/packaging/git-buildpackage.spec b/packaging/git-buildpackage.spec index d71f172d..5532b3b3 100644 --- a/packaging/git-buildpackage.spec +++ b/packaging/git-buildpackage.spec @@ -3,7 +3,7 @@ Name: git-buildpackage Summary: Build packages from git -Version: 0.6.27 +Version: 0.6.28 Release: 0 Group: Development/Tools/Building License: GPLv2 -- cgit v1.2.3 From d20f0d6411c9bf719b2838445ed3f7b886acef15 Mon Sep 17 00:00:00 2001 From: Jun Wang Date: Wed, 9 Mar 2016 18:35:44 +0800 Subject: fix change log date error Change-Id: Icc99e018aac3b06bb2d16049ca2849e6eab5eeed --- packaging/git-buildpackage.changes | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/packaging/git-buildpackage.changes b/packaging/git-buildpackage.changes index 72b0548a..ef2c9eba 100644 --- a/packaging/git-buildpackage.changes +++ b/packaging/git-buildpackage.changes @@ -1,4 +1,4 @@ -* Wed TUE 08 2016 Jun Wang tizen/0.6.28-20160308 +* Wed Mar 08 2016 Jun Wang tizen/0.6.28-20160308 - Make new tag in devel - Upgrade version to 0.6.28 -- cgit v1.2.3 From b8b2060a6f941eb1124f313d306d3fff7269aa10 Mon Sep 17 00:00:00 2001 From: Jun Wang Date: Wed, 9 Mar 2016 18:44:48 +0800 Subject: add compose_version_str function Change-Id: Id1944627b2ec5cf450c978f77002c72d46206572 --- gbp/rpm/__init__.py | 31 ++++++++++++++++++++++++++++++- 1 file changed, 30 insertions(+), 1 deletion(-) diff --git a/gbp/rpm/__init__.py b/gbp/rpm/__init__.py index 4c5c22bf..d47fb302 100644 --- a/gbp/rpm/__init__.py +++ b/gbp/rpm/__init__.py @@ -901,5 +901,34 @@ def string_to_int(val_str): else: return int(val_str) - +def compose_version_str(evr): + """ + Compose a full version string from individual "version components", + i.e. epoch, version and release + + @param evr: dict of version components + @type evr: C{dict} of C{str} + @return: full version + @rtype: C{str} + + >>> compose_version_str({'epoch': '', 'upstreamversion': '1.0'}) + '1.0' + >>> compose_version_str({'epoch': '2', 'upstreamversion': '1.0', 'release': None}) + '2:1.0' + >>> compose_version_str({'epoch': None, 'upstreamversion': '1', 'release': '0'}) + '1-0' + >>> compose_version_str({'epoch': '2', 'upstreamversion': '1.0', 'release': '2.3'}) + '2:1.0-2.3' + >>> compose_version_str({'epoch': '2', 'upstreamversion': '', 'release': '2.3'}) + """ + if 'upstreamversion' in evr and evr['upstreamversion']: + version = "" + if 'epoch' in evr and evr['epoch']: + version += "%s:" % evr['epoch'] + version += evr['upstreamversion'] + if 'release' in evr and evr['release']: + version += "-%s" % evr['release'] + if version: + return version + return None # vim:et:ts=4:sw=4:et:sts=4:ai:set list listchars=tab\:»·,trail\:·: -- cgit v1.2.3 From 2f2269ffbf3c31f7df95ec2336d6c936c95a6e34 Mon Sep 17 00:00:00 2001 From: Jun Wang Date: Wed, 9 Mar 2016 22:43:29 +0800 Subject: Use vendor to publish in srpm unpack Change-Id: I02f5d8cc11a268c7dd075da6e0064d3fedf72721 --- gbp/config.py | 44 +++++++++--------- gbp/scripts/import_orig.py | 5 +- gbp/scripts/import_srpm.py | 112 ++++++++++++++++++++++++--------------------- 3 files changed, 84 insertions(+), 77 deletions(-) diff --git a/gbp/config.py b/gbp/config.py index 987be05d..267400ce 100644 --- a/gbp/config.py +++ b/gbp/config.py @@ -584,7 +584,6 @@ class GbpOptionParserDebian(GbpOptionParser): 'export-dir' : '', } ) - class GbpOptionParserRpm(GbpOptionParser): """ Handles commandline options and parsing of config files for rpm tools @@ -592,19 +591,21 @@ class GbpOptionParserRpm(GbpOptionParser): defaults = dict(GbpOptionParser.defaults) defaults.update({ 'tmp-dir' : '/var/tmp/gbp/', - 'vendor' : 'Downstream', - 'packaging-branch' : 'master', - 'packaging-dir' : '', - 'packaging-tag' : 'packaging/%(version)s', + 'vendor' : 'vendor', + 'native' : 'auto', + 'builder' : 'rpmbuild', + 'cleaner' : '/bin/true', + 'merge' : 'False', + 'packaging-dir' : '', + 'packaging-branch' : 'master', + 'packaging-tag' : '%(vendor)s/%(version)s', 'upstream-tag' : 'upstream/%(upstreamversion)s', 'pq-branch' : 'development/%(branch)s', 'import-files' : ['.gbp.conf', 'debian/gbp.conf'], 'spec-file' : 'auto', - 'builder' : 'rpmbuild', - 'cleaner' : '/bin/true', + 'export-dir' : '../rpmbuild', - 'native' : 'auto', 'ignore-untracked' : 'False', 'rpmbuild-builddir' : 'BUILD', 'rpmbuild-rpmdir' : 'RPMS', @@ -613,14 +614,15 @@ class GbpOptionParserRpm(GbpOptionParser): 'rpmbuild-srpmdir' : 'SRPMS', 'rpmbuild-buildrootdir' : 'BUILDROOT', 'patch-export' : 'False', + 'patch-export-ignore-path' : '', 'patch-export-compress' : '0', - 'patch-export-ignore-path' : '', 'patch-export-squash-until' : '', + 'pristine-tarball-name' : 'auto', + 'orig-prefix' : 'auto', 'patch-import' : 'True', 'spec-vcs-tag' : '', - 'merge' : 'False', - 'pristine-tarball-name' : 'auto', - 'orig-prefix' : 'auto', + + 'changelog-file' : 'auto', 'changelog-revision' : '', 'spawn-editor' : 'always', @@ -630,24 +632,22 @@ class GbpOptionParserRpm(GbpOptionParser): help = dict(GbpOptionParser.help) help.update({ - 'tmp-dir': - "Base directory under which temporary directories are " - "created, default is '%(tmp-dir)s'", + 'vendor': "Distribution vendor name, default is '%(vendor)s'", + 'native': + "Treat this package as native, default is '%(native)s'", 'packaging-branch': "Branch the packaging is being maintained on, rpm counterpart " "of the 'debian-branch' option, default is " "'%(packaging-branch)s'", 'packaging-dir': - "Subdir for RPM packaging files, default is " - "'%(packaging-dir)s'", + "Subdir for RPM packaging files, default is '%(packaging-dir)s'", 'packaging-tag': "Format string for packaging tags, RPM counterpart of the " "'debian-tag' option, default is '%(packaging-tag)s'", 'pq-branch': - "format string for the patch-queue branch name, default is " - "'%(pq-branch)s'", + "format string for the patch-queue branch name, default is '%(pq-branch)s'", 'import-files': "Comma-separated list of additional file(s) to import from " "packaging branch. These will appear as one monolithic patch " @@ -656,8 +656,7 @@ class GbpOptionParserRpm(GbpOptionParser): "Spec file to use, 'auto' makes gbp to guess, other values " "make the packaging-dir option to be ignored, default is " "'%(spec-file)s'", - 'native': - "Treat this package as native, default is '%(native)s'", + 'ignore-untracked': "build with untracked files in the source tree, default is " "'%(ignore-untracked)s'", @@ -700,6 +699,9 @@ class GbpOptionParserRpm(GbpOptionParser): "default is '%(git-author)s'", 'meta-bts': "Meta tags for the bts commands, default is '%(meta-bts)s'", + 'tmp-dir': + "Base directory under which temporary directories are " + "created, default is '%(tmp-dir)s'", }) class GbpOptionParserBB(GbpOptionParserRpm): diff --git a/gbp/scripts/import_orig.py b/gbp/scripts/import_orig.py index be857e35..56b1d9dc 100644 --- a/gbp/scripts/import_orig.py +++ b/gbp/scripts/import_orig.py @@ -33,9 +33,8 @@ from gbp.format import format_msg import gbp.log from gbp.pkg import compressor_opts from gbp.scripts.common.import_orig import (cleanup_tmp_tree, ask_package_name, - ask_package_version, - prepare_sources) - + ask_package_version, + prepare_sources) def upstream_import_commit_msg(options, version): return options.import_msg % dict(version=version) diff --git a/gbp/scripts/import_srpm.py b/gbp/scripts/import_srpm.py index ff946194..85f1225f 100755 --- a/gbp/scripts/import_srpm.py +++ b/gbp/scripts/import_srpm.py @@ -30,7 +30,8 @@ import urllib2 import gbp.tmpfile as tempfile import gbp.command_wrappers as gbpc from gbp.rpm import (parse_srpm, guess_spec, SpecFile, NoSpecError, - RpmUpstreamSource, compose_version_str) + RpmUpstreamSource) +from gbp.rpm.policy import RpmPkgPolicy from gbp.rpm.git import (RpmGitRepository, GitRepositoryError) from gbp.git.modifier import GitModifier from gbp.config import (GbpOptionParserRpm, GbpOptionGroup, @@ -42,8 +43,9 @@ from gbp.scripts.common.pq import apply_and_commit_patch from gbp.pkg import parse_archive_filename no_packaging_branch_msg = """ -Repository does not have branch '%s' for packaging/distribution sources. -You need to reate it or use --packaging-branch to specify it. +Repository does not have branch '%s' for packaging/distribution sources. If there is none see +file:///usr/share/doc/git-buildpackage/manual-html/gbp.import.html#GBP.IMPORT.CONVERT +on howto create it otherwise use --packaging-branch to specify it. """ PATCH_AUTODELETE_COMMIT_MSG = """ @@ -160,7 +162,6 @@ def import_spec_patches(repo, spec, dirs): def force_to_branch_head(repo, branch): - """Checkout branch and reset --hard""" if repo.get_branch() == branch: # Update HEAD if we modified the checked out branch repo.force_head(branch, hard=True) @@ -196,10 +197,10 @@ def parse_args(argv): parser.add_config_file_option(option_name="color-scheme", dest="color_scheme") parser.add_config_file_option(option_name="tmp-dir", dest="tmp_dir") - parser.add_config_file_option(option_name="vendor", action="store", - dest="vendor") parser.add_option("--download", action="store_true", dest="download", default=False, help="download source package") + parser.add_config_file_option(option_name="vendor", action="store", + dest="vendor") branch_group.add_config_file_option(option_name="packaging-branch", dest="packaging_branch") branch_group.add_config_file_option(option_name="upstream-branch", @@ -354,22 +355,22 @@ def main(argv): # Unpack orig source archive if spec.orig_src: orig_tarball = os.path.join(dirs['src'], spec.orig_src['filename']) - sources = RpmUpstreamSource(orig_tarball) - sources = sources.unpack(dirs['origsrc'], options.filters) + upstream = RpmUpstreamSource(orig_tarball) + upstream = upstream.unpack(dirs['origsrc'], options.filters) else: - sources = None + upstream = None - src_tag_format = options.packaging_tag if options.native \ - else options.upstream_tag - tag_str_fields = dict(spec.version, vendor=options.vendor.lower()) - src_tag = repo.version_to_tag(src_tag_format, tag_str_fields) - ver_str = compose_version_str(spec.version) + tag_format = [(options.upstream_tag, "Upstream"), + (options.packaging_tag, options.vendor)][options.native] + tag_str_fields = dict(spec.version, vendor=options.vendor) + tag = repo.version_to_tag(tag_format[0], tag_str_fields) if repo.find_version(options.packaging_tag, tag_str_fields): - gbp.log.warn("Version %s already imported." % ver_str) + gbp.log.warn("Version %s already imported." % + RpmPkgPolicy.compose_full_version(spec.version)) if options.allow_same_version: gbp.log.info("Moving tag of version '%s' since import forced" % - ver_str) + RpmPkgPolicy.compose_full_version(spec.version)) move_tag_stamp(repo, options.packaging_tag, tag_str_fields) else: raise SkipImport @@ -378,10 +379,10 @@ def main(argv): options.create_missing_branches = True # Determine author and committer info, currently same info is used - # for both sources and packaging files + # for both upstream sources and packaging files author = None if spec.packager: - match = re.match(r'(?P.*[^ ])\s*<(?P\S*)>', + match = re.match('(?P.*[^ ])\s*<(?P\S*)>', spec.packager.strip()) if match: author = GitModifier(match.group('name'), match.group('email')) @@ -390,11 +391,12 @@ def main(argv): gbp.log.debug("Couldn't determine packager info") committer = committer_from_author(author, options) - # Import sources - if sources: - src_commit = repo.find_version(src_tag_format, tag_str_fields) - if not src_commit: - gbp.log.info("Tag %s not found, importing sources" % src_tag) + # Import upstream sources + if upstream: + upstream_commit = repo.find_version(tag_format[0], tag_str_fields) + if not upstream_commit: + gbp.log.info("Tag %s not found, importing %s upstream sources" + % (tag, tag_format[1])) branch = [options.upstream_branch, options.packaging_branch][options.native] @@ -406,22 +408,22 @@ def main(argv): gbp.log.err(no_upstream_branch_msg % branch + "\n" "Also check the --create-missing-branches option.") raise GbpError - src_vendor = "Native" if options.native else "Upstream" - msg = "%s version %s" % (src_vendor, spec.upstreamversion) + + msg = "%s version %s" % (tag_format[1], spec.upstreamversion) if options.vcs_tag: parents = [repo.rev_parse("%s^{}" % options.vcs_tag)] else: parents = None - src_commit = repo.commit_dir(sources.unpacked, - "Imported %s" % msg, - branch, - other_parents=parents, - author=author, - committer=committer, - create_missing_branch=options.create_missing_branches) - repo.create_tag(name=src_tag, + upstream_commit = repo.commit_dir(upstream.unpacked, + "Imported %s" % msg, + branch, + other_parents=parents, + author=author, + committer=committer, + create_missing_branch=options.create_missing_branches) + repo.create_tag(name=tag, msg=msg, - commit=src_commit, + commit=upstream_commit, sign=options.sign_tags, keyid=options.keyid) @@ -440,7 +442,7 @@ def main(argv): # Import packaging files. For native packages we assume that also # packaging files are found in the source tarball - if not options.native or not sources: + if not options.native or not upstream: gbp.log.info("Importing packaging files") branch = options.packaging_branch if not repo.has_branch(branch): @@ -452,35 +454,37 @@ def main(argv): "option.") raise GbpError + tag_str_fields = dict(spec.version, vendor=options.vendor) tag = repo.version_to_tag(options.packaging_tag, tag_str_fields) - msg = "%s release %s" % (options.vendor, ver_str) + msg = "%s release %s" % (options.vendor, + RpmPkgPolicy.compose_full_version(spec.version)) - if options.orphan_packaging or not sources: + if options.orphan_packaging or not upstream: commit = repo.commit_dir(dirs['packaging_base'], - "Imported %s" % msg, - branch, - author=author, - committer=committer, - create_missing_branch=options.create_missing_branches) + "Imported %s" % msg, + branch, + author=author, + committer=committer, + create_missing_branch=options.create_missing_branches) else: # Copy packaging files to the unpacked sources dir try: - pkgsubdir = os.path.join(sources.unpacked, + pkgsubdir = os.path.join(upstream.unpacked, options.packaging_dir) os.mkdir(pkgsubdir) except OSError as err: if err.errno != errno.EEXIST: raise - for fname in os.listdir(dirs['packaging']): - shutil.copy2(os.path.join(dirs['packaging'], fname), + for fn in os.listdir(dirs['packaging']): + shutil.copy2(os.path.join(dirs['packaging'], fn), pkgsubdir) - commit = repo.commit_dir(sources.unpacked, - "Imported %s" % msg, - branch, - other_parents=[src_commit], - author=author, - committer=committer, - create_missing_branch=options.create_missing_branches) + commit = repo.commit_dir(upstream.unpacked, + "Imported %s" % msg, + branch, + other_parents=[upstream_commit], + author=author, + committer=committer, + create_missing_branch=options.create_missing_branches) # Import patches on top of the source tree # (only for non-native packages with non-orphan packaging) force_to_branch_head(repo, options.packaging_branch) @@ -524,7 +528,9 @@ def main(argv): gbpc.RemoveTree(dirs['tmp_base'])() if not ret and not skipped: - gbp.log.info("Version '%s' imported under '%s'" % (ver_str, spec.name)) + gbp.log.info("Version '%s' imported under '%s'" % + (RpmPkgPolicy.compose_full_version(spec.version), + spec.name)) return ret if __name__ == '__main__': -- cgit v1.2.3 From 7c4962c9ce5cdab6d191f11297ea1b14dc464c14 Mon Sep 17 00:00:00 2001 From: Jun Wang Date: Fri, 18 Mar 2016 21:49:38 +0800 Subject: Modify unit test cases which called 'assert_raises' function to fix pre-review test bugs on CentOS_6. Change-Id: Ibb930eb107c18526876fc58428db359f9d31e716 --- tests/20_test_rpm.py | 56 ++++++++++++++++++++++++++++ tests/component/rpm/test_buildpackage_rpm.py | 4 ++ tests/component/rpm/test_import_orig_rpm.py | 4 ++ tests/component/rpm/test_import_srpm.py | 4 ++ tests/component/rpm/test_pq_rpm.py | 4 ++ tests/component/rpm/test_rpm_ch.py | 4 ++ tests/test_rpm_changelog.py | 20 ++++++++++ 7 files changed, 96 insertions(+) diff --git a/tests/20_test_rpm.py b/tests/20_test_rpm.py index 98ffbc9b..adf205f5 100644 --- a/tests/20_test_rpm.py +++ b/tests/20_test_rpm.py @@ -158,10 +158,15 @@ class TestSpecFile(RpmTestBase): def test_parse_raw(self): """Test parsing of a valid spec file""" + assert_raises(NoSpecError, SpecFile, None, None) + assert_raises(NoSpecError, SpecFile, 'filename', 'filedata') + + """ with assert_raises(NoSpecError): SpecFile(None, None) with assert_raises(NoSpecError): SpecFile('filename', 'filedata') + """ spec_filepath = os.path.join(SPEC_DIR, 'gbp-test.spec') with open(spec_filepath, 'r') as spec_fd: @@ -233,22 +238,36 @@ class TestSpecFile(RpmTestBase): eq_(spec.protected('_patches')(), {}) prev = spec.protected('_delete_tag')('invalidtag', None) + assert_raises(GbpError, spec.protected('_set_tag'), + 'Version', None, '', prev) + assert_raises(GbpError, spec.set_tag, + 'invalidtag', None, 'value') + + """ with assert_raises(GbpError): # Check that setting empty value fails spec.protected('_set_tag')('Version', None, '', prev) with assert_raises(GbpError): # Check that setting invalid tag with public method fails spec.set_tag('invalidtag', None, 'value') + """ # Mangle macros prev = spec.protected('_delete_special_macro')('patch', -1) spec.protected('_delete_special_macro')('patch', 123) spec.protected('_set_special_macro')('patch', 0, 'my new args', prev) + assert_raises(GbpError, spec.protected('_delete_special_macro'), + 'invalidmacro', 0) + assert_raises(GbpError, spec.protected('_set_special_macro'), + 'invalidmacro', 0, 'args', prev) + + """ with assert_raises(GbpError): spec.protected('_delete_special_macro')('invalidmacro', 0) with assert_raises(GbpError): spec.protected('_set_special_macro')('invalidmacro', 0, 'args', prev) + """ # Check resulting spec file spec.write_spec_file() @@ -260,12 +279,21 @@ class TestSpecFile(RpmTestBase): spec = SpecFileTester(spec_filepath) # Unknown/invalid section name + assert_raises(GbpError, spec.protected('_set_section'), + 'patch', 'new content\n') + """ with assert_raises(GbpError): spec.protected('_set_section')('patch', 'new content\n') + """ # Multiple sections with the same name + assert_raises(GbpError, spec.protected('_set_section'), + 'files', '%{_sysconfdir}/foo\n') + + """ with assert_raises(GbpError): spec.protected('_set_section')('files', '%{_sysconfdir}/foo\n') + """ def test_changelog(self): """Test changelog methods""" @@ -360,13 +388,27 @@ class TestUtilityFunctions(RpmTestBase): def test_guess_spec(self): """Test guess_spec() function""" # Spec not found + assert_raises(NoSpecError, guess_spec, + DATA_DIR, recursive=False) + + """ with assert_raises(NoSpecError): guess_spec(DATA_DIR, recursive=False) + """ + # Multiple spec files + assert_raises(NoSpecError, guess_spec, + DATA_DIR, recursive=True) + assert_raises(NoSpecError, guess_spec, + SPEC_DIR, recursive=False) + + """ with assert_raises(NoSpecError): guess_spec(DATA_DIR, recursive=True) with assert_raises(NoSpecError): guess_spec(SPEC_DIR, recursive=False) + """ + # Spec found spec = guess_spec(SPEC_DIR, recursive=False, preferred_name = 'gbp-test2.spec') @@ -388,10 +430,18 @@ class TestUtilityFunctions(RpmTestBase): repo.commit_all('Add spec file') # Spec not found + assert_raises(NoSpecError, guess_spec_repo, + repo, 'HEAD~1', recursive=True) + assert_raises(NoSpecError, guess_spec_repo, + repo, 'HEAD', recursive=False) + + """ with assert_raises(NoSpecError): guess_spec_repo(repo, 'HEAD~1', recursive=True) with assert_raises(NoSpecError): guess_spec_repo(repo, 'HEAD', recursive=False) + """ + # Spec found spec = guess_spec_repo(repo, 'HEAD', 'packaging', recursive=False) spec = guess_spec_repo(repo, 'HEAD', recursive=True) @@ -400,8 +450,14 @@ class TestUtilityFunctions(RpmTestBase): eq_(spec.specpath, 'packaging/gbp-test.spec') # Test spec_from_repo() + assert_raises(NoSpecError, spec_from_repo, + repo, 'HEAD~1', 'packaging/gbp-test.spec') + + """ with assert_raises(NoSpecError): spec_from_repo(repo, 'HEAD~1', 'packaging/gbp-test.spec') + """ + spec = spec_from_repo(repo, 'HEAD', 'packaging/gbp-test.spec') eq_(spec.specfile, 'gbp-test.spec') diff --git a/tests/component/rpm/test_buildpackage_rpm.py b/tests/component/rpm/test_buildpackage_rpm.py index 88a66fc0..652b1528 100644 --- a/tests/component/rpm/test_buildpackage_rpm.py +++ b/tests/component/rpm/test_buildpackage_rpm.py @@ -101,8 +101,12 @@ class TestGbpRpm(RpmRepoTestBase): def test_invalid_args(self): """Check graceful exit when called with invalid args""" GitRepository.create('.') + assert_raises(SystemExit, mock_gbp, ['--git-invalid-arg']) + + """ with assert_raises(SystemExit): mock_gbp(['--git-invalid-arg']) + """ def test_outside_repo(self): """Run outside a git repository""" diff --git a/tests/component/rpm/test_import_orig_rpm.py b/tests/component/rpm/test_import_orig_rpm.py index a85366b1..ebf592a0 100644 --- a/tests/component/rpm/test_import_orig_rpm.py +++ b/tests/component/rpm/test_import_orig_rpm.py @@ -142,8 +142,12 @@ class TestImportOrig(ImportOrigTestBase): self._check_repo_state(repo, None, []) # Test invalid cmdline options + assert_raises(SystemExit, mock_import, ['--invalid-arg=123']) + + """ with assert_raises(SystemExit): mock_import(['--invalid-arg=123']) + """ def test_import_outside_repo(self): """Test importing when not in a git repository""" diff --git a/tests/component/rpm/test_import_srpm.py b/tests/component/rpm/test_import_srpm.py index 54898f7f..de28259a 100644 --- a/tests/component/rpm/test_import_srpm.py +++ b/tests/component/rpm/test_import_srpm.py @@ -45,8 +45,12 @@ class TestImportPacked(ComponentTestBase): def test_invalid_args(self): """See that import-srpm fails gracefully if called with invalid args""" eq_(mock_import([]), 1) + assert_raises(SystemExit, mock_import, ['--invalid-arg=123']) + + """ with assert_raises(SystemExit): mock_import(['--invalid-arg=123']) + """ def test_basic_import(self): """Test importing of non-native src.rpm""" diff --git a/tests/component/rpm/test_pq_rpm.py b/tests/component/rpm/test_pq_rpm.py index 293244be..c14ea681 100644 --- a/tests/component/rpm/test_pq_rpm.py +++ b/tests/component/rpm/test_pq_rpm.py @@ -52,8 +52,12 @@ class TestPqRpm(RpmRepoTestBase): self._clear_log() # Test invalid cmdline options + assert_raises(SystemExit, mock_pq, ['--invalid-arg=123']) + + """ with assert_raises(SystemExit): mock_pq(['--invalid-arg=123']) + """ def test_import_outside_repo(self): """Run pq-rpm when not in a git repository""" diff --git a/tests/component/rpm/test_rpm_ch.py b/tests/component/rpm/test_rpm_ch.py index db03c845..4b3354b7 100644 --- a/tests/component/rpm/test_rpm_ch.py +++ b/tests/component/rpm/test_rpm_ch.py @@ -56,8 +56,12 @@ class TestRpmCh(RpmRepoTestBase): """See that git-rpm-ch fails gracefully when called with invalid args""" GitRepository.create('.') + assert_raises(SystemExit, mock_ch, ['--invalid-opt']) + + """ with assert_raises(SystemExit): mock_ch(['--invalid-opt']) + """ def test_import_outside_repo(self): """Run git-rpm-ch when not in a git repository""" diff --git a/tests/test_rpm_changelog.py b/tests/test_rpm_changelog.py index 29732936..22739f0e 100644 --- a/tests/test_rpm_changelog.py +++ b/tests/test_rpm_changelog.py @@ -40,8 +40,12 @@ class TestChangelogHeader(object): """Test missing properties""" time = datetime(2014, 01, 29, 12, 13, 14) header = _ChangelogHeader(RpmPkgPolicy, time, name="John", revision="1") + assert_raises(ChangelogError, str, header) + + """ with assert_raises(ChangelogError): str(header) + """ def test_container(self): """Test the container methods of the class""" @@ -190,6 +194,16 @@ class TestChangelogParser(object): def test_parse_section_fail(self): """Basic tests for failures of changelog section parsing""" + assert_raises(ChangelogError, self.parser.parse_section, + self.cl_broken_header_1) + assert_raises(ChangelogError, self.parser.parse_section, + self.cl_broken_header_2) + assert_raises(ChangelogError, self.parser.parse_section, + self.cl_broken_header_3) + assert_raises(ChangelogError, self.parser.parse_section, + self.cl_broken_header_4) + + """ with assert_raises(ChangelogError): self.parser.parse_section(self.cl_broken_header_1) @@ -201,11 +215,17 @@ class TestChangelogParser(object): with assert_raises(ChangelogError): self.parser.parse_section(self.cl_broken_header_4) + """ def test_parse_changelog_fail(self): """Basic tests for changelog parsing failures""" + assert_raises(ChangelogError, self.parser.raw_parse_string, + self.cl_broken_header_5) + + """ with assert_raises(ChangelogError): self.parser.raw_parse_string(self.cl_broken_header_5) + """ class TestChangelog(object): -- cgit v1.2.3 From 98ebae2eb4504a80000aa21a4ddc6266e25c17cb Mon Sep 17 00:00:00 2001 From: Jun Wang Date: Mon, 21 Mar 2016 19:34:15 +0800 Subject: Fix 20_test_rpm.py to suit different edition of python. Change-Id: Ibe03d1614fafb5ceb01af634da90eda8d1426fbd --- tests/20_test_rpm.py | 199 +++++++++++++++++++++++++++------------------------ 1 file changed, 107 insertions(+), 92 deletions(-) diff --git a/tests/20_test_rpm.py b/tests/20_test_rpm.py index adf205f5..f76b129f 100644 --- a/tests/20_test_rpm.py +++ b/tests/20_test_rpm.py @@ -20,23 +20,17 @@ import filecmp import os import shutil import tempfile -from nose.tools import assert_raises, eq_, ok_ # pylint: disable=E0611 +from nose.tools import assert_raises, eq_ from gbp.errors import GbpError from gbp.rpm import (SrcRpmFile, SpecFile, parse_srpm, NoSpecError, guess_spec, guess_spec_repo, spec_from_repo) from gbp.git.repository import GitRepository -# Disable "Method could be a function" -# pylint: disable=R0201 - - -DATA_DIR = os.path.join(os.path.dirname(os.path.abspath(__file__)), 'data', - 'rpm') +DATA_DIR = os.path.abspath(os.path.splitext(__file__)[0] + '_data') SRPM_DIR = os.path.join(DATA_DIR, 'srpms') SPEC_DIR = os.path.join(DATA_DIR, 'specs') - class SpecFileTester(SpecFile): """Helper class for testing""" @@ -45,36 +39,30 @@ class SpecFileTester(SpecFile): return super(SpecFileTester, self).__getattribute__(name) -class RpmTestBase(object): - """Test base class""" - def __init__(self): - self.tmpdir = None +class TestSrcRpmFile(object): + """Test L{gbp.rpm.SrcRpmFile}""" def setup(self): - """Test case setup""" self.tmpdir = tempfile.mkdtemp(prefix='gbp_%s_' % __name__, dir='.') def teardown(self): - """Test case teardown""" shutil.rmtree(self.tmpdir) -class TestSrcRpmFile(RpmTestBase): - """Test L{gbp.rpm.SrcRpmFile}""" - def test_srpm(self): """Test parsing of a source rpm""" srpm = SrcRpmFile(os.path.join(SRPM_DIR, 'gbp-test-1.0-1.src.rpm')) - eq_(srpm.version, {'release': '1', 'upstreamversion': '1.0'}) - eq_(srpm.name, 'gbp-test') - eq_(srpm.upstreamversion, '1.0') - eq_(srpm.packager, None) + assert srpm.version == {'release': '1', 'upstreamversion': '1.0'} + assert srpm.name == 'gbp-test' + assert srpm.upstreamversion == '1.0' + assert srpm.packager is None def test_srpm_2(self): """Test parsing of another source rpm""" srpm = SrcRpmFile(os.path.join(SRPM_DIR, 'gbp-test2-3.0-0.src.rpm')) - eq_(srpm.version, {'release': '0', 'upstreamversion': '3.0', - 'epoch': '2'}) - eq_(srpm.packager, 'Markus Lehtonen ') + assert srpm.version == {'release': '0', 'upstreamversion': '3.0', + 'epoch': '2'} + assert srpm.packager == 'Markus Lehtonen '\ + '' def test_unpack_srpm(self): """Test unpacking of a source rpm""" @@ -82,37 +70,44 @@ class TestSrcRpmFile(RpmTestBase): srpm.unpack(self.tmpdir) for fn in ['gbp-test-1.0.tar.bz2', 'foo.txt', 'bar.tar.gz', 'my.patch', 'my2.patch', 'my3.patch']: - ok_(os.path.exists(os.path.join(self.tmpdir, fn)), - "%s not found" % fn) + assert os.path.exists(os.path.join(self.tmpdir, fn)), \ + "%s not found" % fn -class TestSpecFile(RpmTestBase): + +class TestSpecFile(object): """Test L{gbp.rpm.SpecFile}""" + def setup(self): + self.tmpdir = tempfile.mkdtemp(prefix='gbp_%s_' % __name__, dir='.') + + def teardown(self): + shutil.rmtree(self.tmpdir) + def test_spec(self): """Test parsing of a valid spec file""" spec_filepath = os.path.join(SPEC_DIR, 'gbp-test.spec') spec = SpecFileTester(spec_filepath) # Test basic properties - eq_(spec.specfile, os.path.basename(spec_filepath)) - eq_(spec.specdir, os.path.dirname(spec_filepath)) - eq_(spec.specpath, spec_filepath) + assert spec.specfile == os.path.basename(spec_filepath) + assert spec.specdir == os.path.dirname(spec_filepath) + assert spec.specpath == spec_filepath - eq_(spec.name, 'gbp-test') - eq_(spec.packager, None) + assert spec.name == 'gbp-test' + assert spec.packager is None - eq_(spec.upstreamversion, '1.0') - eq_(spec.release, '1') - eq_(spec.epoch, None) - eq_(spec.version, {'release': '1', 'upstreamversion': '1.0'}) + assert spec.upstreamversion == '1.0' + assert spec.release == '1' + assert spec.epoch is None + assert spec.version == {'release': '1', 'upstreamversion': '1.0'} orig = spec.orig_src - eq_(orig['filename'], 'gbp-test-1.0.tar.bz2') - eq_(orig['uri'], 'gbp-test-1.0.tar.bz2') - eq_(orig['filename_base'], 'gbp-test-1.0') - eq_(orig['archive_fmt'], 'tar') - eq_(orig['compression'], 'bzip2') - eq_(orig['prefix'], 'gbp-test/') + assert orig['filename'] == 'gbp-test-1.0.tar.bz2' + assert orig['uri'] == 'gbp-test-1.0.tar.bz2' + assert orig['filename_base'] == 'gbp-test-1.0' + assert orig['archive_fmt'] == 'tar' + assert orig['compression'] == 'bzip2' + assert orig['prefix'] == 'gbp-test/' def test_spec_2(self): """Test parsing of another valid spec file""" @@ -120,19 +115,20 @@ class TestSpecFile(RpmTestBase): spec = SpecFile(spec_filepath) # Test basic properties - eq_(spec.name, 'gbp-test2') - eq_(spec.packager, 'Markus Lehtonen ') + assert spec.name == 'gbp-test2' + assert spec.packager == 'Markus Lehtonen ' \ + '' - eq_(spec.epoch, '2') - eq_(spec.version, {'release': '0', 'upstreamversion': '3.0', - 'epoch': '2'}) + assert spec.epoch == '2' + assert spec.version == {'release': '0', 'upstreamversion': '3.0', + 'epoch': '2'} orig = spec.orig_src - eq_(orig['filename'], 'gbp-test2-3.0.tar.gz') - eq_(orig['uri'], 'ftp://ftp.host.com/gbp-test2-3.0.tar.gz') - eq_(orig['archive_fmt'], 'tar') - eq_(orig['compression'], 'gzip') - eq_(orig['prefix'], '') + assert orig['filename'] == 'gbp-test2-3.0.tar.gz' + assert orig['uri'] == 'ftp://ftp.host.com/gbp-test2-3.0.tar.gz' + assert orig['archive_fmt'] == 'tar' + assert orig['compression'] == 'gzip' + assert orig['prefix'] == '' def test_spec_3(self): """Test parsing of yet another valid spec file""" @@ -140,12 +136,12 @@ class TestSpecFile(RpmTestBase): spec = SpecFile(spec_filepath) # Test basic properties - eq_(spec.name, 'gbp-test-native') + assert spec.name == 'gbp-test-native' orig = spec.orig_src - eq_(orig['filename'], 'gbp-test-native-1.0.zip') - eq_(orig['archive_fmt'], 'zip') - eq_(orig['compression'], None) - eq_(orig['prefix'], 'gbp-test-native-1.0/') + assert orig['filename'] == 'gbp-test-native-1.0.zip' + assert orig['archive_fmt'] == 'zip' + assert orig['compression'] == None + assert orig['prefix'] == 'gbp-test-native-1.0/' def test_spec_4(self): """Test parsing of spec without orig tarball""" @@ -153,8 +149,8 @@ class TestSpecFile(RpmTestBase): spec = SpecFile(spec_filepath) # Test basic properties - eq_(spec.name, 'gbp-test-native2') - eq_(spec.orig_src, None) + assert spec.name == 'gbp-test-native2' + assert spec.orig_src is None def test_parse_raw(self): """Test parsing of a valid spec file""" @@ -174,9 +170,9 @@ class TestSpecFile(RpmTestBase): spec = SpecFile(filedata=spec_data) # Test basic properties - eq_(spec.specfile, None) - eq_(spec.specdir, None) - eq_(spec.name, 'gbp-test') + assert spec.specfile == None + assert spec.specdir == None + assert spec.name == 'gbp-test' def test_update_spec(self): """Test spec autoupdate functionality""" @@ -188,14 +184,14 @@ class TestSpecFile(RpmTestBase): spec = SpecFile(tmp_spec) spec.update_patches(['new.patch'], {}) spec.write_spec_file() - eq_(filecmp.cmp(tmp_spec, reference_spec), True) + assert filecmp.cmp(tmp_spec, reference_spec) is True # Test adding the VCS tag and adding changelog reference_spec = os.path.join(SPEC_DIR, 'gbp-test-reference2.spec') spec.set_tag('VCS', None, 'myvcstag') spec.set_changelog("* Wed Feb 05 2014 Name 1\n- New entry\n") spec.write_spec_file() - eq_(filecmp.cmp(tmp_spec, reference_spec), True) + assert filecmp.cmp(tmp_spec, reference_spec) is True def test_update_spec2(self): """Another test for spec autoupdate functionality""" @@ -209,7 +205,7 @@ class TestSpecFile(RpmTestBase): '2.patch': {'ifarch': '%ix86'}}) spec.set_tag('VCS', None, 'myvcstag') spec.write_spec_file() - eq_(filecmp.cmp(tmp_spec, reference_spec), True) + assert filecmp.cmp(tmp_spec, reference_spec) is True # Test updating patches again, removing the VCS tag and re-writing # changelog @@ -218,7 +214,7 @@ class TestSpecFile(RpmTestBase): spec.set_tag('VCS', None, '') spec.set_changelog("* Wed Feb 05 2014 Name 2\n- New entry\n\n") spec.write_spec_file() - eq_(filecmp.cmp(tmp_spec, reference_spec), True) + assert filecmp.cmp(tmp_spec, reference_spec) is True def test_modifying(self): """Test updating/deleting of tags and macros""" @@ -232,10 +228,10 @@ class TestSpecFile(RpmTestBase): prev = spec.protected('_delete_tag')('Vendor', None) spec.protected('_set_tag')('License', None, 'new license', prev) spec.protected('_delete_tag')('source', 0) - eq_(spec.sources(), {}) + assert spec.sources() == {} spec.protected('_delete_tag')('patch', 0) spec.protected('_delete_tag')('patch', -1) - eq_(spec.protected('_patches')(), {}) + assert spec.protected('_patches')() == {} prev = spec.protected('_delete_tag')('invalidtag', None) assert_raises(GbpError, spec.protected('_set_tag'), @@ -271,7 +267,7 @@ class TestSpecFile(RpmTestBase): # Check resulting spec file spec.write_spec_file() - eq_(filecmp.cmp(tmp_spec, reference_spec), True) + assert filecmp.cmp(tmp_spec, reference_spec) is True def test_modifying_err(self): """Test error conditions of modification methods""" @@ -315,7 +311,7 @@ class TestSpecFile(RpmTestBase): spec = SpecFile(spec_filepath) # Check that we quess orig source and prefix correctly - eq_(spec.orig_src['prefix'], 'foobar/') + assert spec.orig_src['prefix'] == 'foobar/' def test_tags(self): """Test parsing of all the different tags of spec file""" @@ -332,33 +328,33 @@ class TestSpecFile(RpmTestBase): elif name not in spec.protected('_listtags'): rval = 'my_%s' % name if rval: - eq_(val['value'], rval, ("'%s:' is '%s', expecting '%s'" % - (name, val['value'], rval))) - eq_(spec.ignorepatches, []) + assert val['value'] == rval, ("'%s:' is '%s', expecting '%s'" % + (name, val['value'], rval)) + assert spec.ignorepatches == [] # Check patch numbers and patch filenames patches = {} for patch in spec.protected('_tags')['patch']['lines']: patches[patch['num']] = patch['linevalue'] - eq_(patches, {0: 'my_patch0', -1: 'my_patch'}) + assert patches == {0: 'my_patch0', -1: 'my_patch'} def test_patch_series(self): """Test the getting the patches as a patchseries""" spec_filepath = os.path.join(SPEC_DIR, 'gbp-test-native.spec') spec = SpecFileTester(spec_filepath) - eq_(len(spec.patchseries()), 0) + assert len(spec.patchseries()) == 0 spec.update_patches(['1.patch', '2.patch', '3.patch'], {}) - eq_(len(spec.patchseries()), 3) + assert len(spec.patchseries()) == 3 spec.protected('_gbp_tags')['ignore-patches'].append({'args': "0"}) spec.update_patches(['4.patch'], {}) - eq_(len(spec.patchseries()), 1) - eq_(len(spec.patchseries(ignored=True)), 2) + assert len(spec.patchseries()) == 1 + assert len(spec.patchseries(ignored=True)) == 2 spec.protected('_delete_special_macro')('patch', 0) - eq_(len(spec.patchseries(ignored=True)), 1) + assert len(spec.patchseries(ignored=True)) == 1 series = spec.patchseries(unapplied=True, ignored=True) - eq_(len(series), 2) - eq_(os.path.basename(series[-1].path), '1.patch') + assert len(series) == 2 + assert os.path.basename(series[-1].path) == '1.patch' def test_patch_series_quirks(self): """Patches are applied in order different from the patch numbering""" @@ -367,23 +363,42 @@ class TestSpecFile(RpmTestBase): # Check series is returned in the order the patches are applied files = [os.path.basename(patch.path) for patch in spec.patchseries()] - eq_(files, ['05.patch', '01.patch']) + assert files == ['05.patch', '01.patch'] # Also ignored patches are returned in the correct order files = [os.path.basename(patch.path) for patch in spec.patchseries(ignored=True)] - eq_(files, ['05.patch', '02.patch', '01.patch']) + assert files == ['05.patch', '02.patch', '01.patch'] # Unapplied patches are added to the end of the series files = [os.path.basename(patch.path) for patch in spec.patchseries(unapplied=True)] - eq_(files, ['05.patch', '01.patch', '03.patch']) + assert files == ['05.patch', '01.patch', '03.patch'] # Return all patches (for which tag is found) files = [os.path.basename(patch.path) for patch in spec.patchseries(unapplied=True, ignored=True)] - eq_(files, ['05.patch', '02.patch', '01.patch', '03.patch', '04.patch']) + assert files == ['05.patch', '02.patch', '01.patch', '03.patch', + '04.patch'] -class TestUtilityFunctions(RpmTestBase): +class TestUtilityFunctions(object): """Test utility functions of L{gbp.rpm}""" + def setup(self): + self.tmpdir = tempfile.mkdtemp(prefix='gbp_%s_' % __name__, dir='.') + + def teardown(self): + shutil.rmtree(self.tmpdir) + + def test_parse_srpm(self): + """Test parse_srpm() function""" + parse_srpm(os.path.join(SRPM_DIR, 'gbp-test-1.0-1.src.rpm')) + assert_raises(GbpError, parse_srpm, + os.path.join(DATA_DIR, 'notexists.src.rpm')) + + """ + with assert_raises(GbpError): + parse_srpm(os.path.join(DATA_DIR, 'notexists.src.rpm')) + with assert_raises(GbpError): + parse_srpm(os.path.join(SPEC_DIR, 'gbp-test.spec')) + """ def test_guess_spec(self): """Test guess_spec() function""" @@ -412,8 +427,8 @@ class TestUtilityFunctions(RpmTestBase): # Spec found spec = guess_spec(SPEC_DIR, recursive=False, preferred_name = 'gbp-test2.spec') - eq_(spec.specfile, 'gbp-test2.spec') - eq_(spec.specdir, SPEC_DIR) + assert spec.specfile == 'gbp-test2.spec' + assert spec.specdir == SPEC_DIR def test_guess_spec_repo(self): """Test guess_spec_repo() and spec_from_repo() functions""" @@ -445,9 +460,9 @@ class TestUtilityFunctions(RpmTestBase): # Spec found spec = guess_spec_repo(repo, 'HEAD', 'packaging', recursive=False) spec = guess_spec_repo(repo, 'HEAD', recursive=True) - eq_(spec.specfile, 'gbp-test.spec') - eq_(spec.specdir, 'packaging') - eq_(spec.specpath, 'packaging/gbp-test.spec') + assert spec.specfile == 'gbp-test.spec' + assert spec.specdir == 'packaging' + assert spec.specpath == 'packaging/gbp-test.spec' # Test spec_from_repo() assert_raises(NoSpecError, spec_from_repo, @@ -459,6 +474,6 @@ class TestUtilityFunctions(RpmTestBase): """ spec = spec_from_repo(repo, 'HEAD', 'packaging/gbp-test.spec') - eq_(spec.specfile, 'gbp-test.spec') + assert spec.specfile == 'gbp-test.spec' # vim:et:ts=4:sw=4:et:sts=4:ai:set list listchars=tab\:»·,trail\:·: -- cgit v1.2.3 From 212d7cb7cf1afc9ad03e995e71b9fb54372f7f10 Mon Sep 17 00:00:00 2001 From: Jun Wang Date: Tue, 22 Mar 2016 00:23:09 +0800 Subject: 1.Change to way to get test data dirctory 2.Fix the error of indent in tests/20_test_rpm.py 3.Change to vendor tag Change-Id: Ia9520a6c441fa9d34eff76c96a41764f3fb0ba76 --- tests/20_test_rpm.py | 4 ++-- tests/component/rpm/test_import_srpm.py | 2 +- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/tests/20_test_rpm.py b/tests/20_test_rpm.py index f76b129f..52a14ff1 100644 --- a/tests/20_test_rpm.py +++ b/tests/20_test_rpm.py @@ -27,7 +27,7 @@ from gbp.rpm import (SrcRpmFile, SpecFile, parse_srpm, NoSpecError, guess_spec, guess_spec_repo, spec_from_repo) from gbp.git.repository import GitRepository -DATA_DIR = os.path.abspath(os.path.splitext(__file__)[0] + '_data') +DATA_DIR = os.path.join(os.path.dirname(os.path.abspath(__file__)), 'data','rpm') SRPM_DIR = os.path.join(DATA_DIR, 'srpms') SPEC_DIR = os.path.join(DATA_DIR, 'specs') @@ -390,7 +390,7 @@ class TestUtilityFunctions(object): def test_parse_srpm(self): """Test parse_srpm() function""" parse_srpm(os.path.join(SRPM_DIR, 'gbp-test-1.0-1.src.rpm')) - assert_raises(GbpError, parse_srpm, + assert_raises(GbpError, parse_srpm, os.path.join(DATA_DIR, 'notexists.src.rpm')) """ diff --git a/tests/component/rpm/test_import_srpm.py b/tests/component/rpm/test_import_srpm.py index de28259a..b35a5bd6 100644 --- a/tests/component/rpm/test_import_srpm.py +++ b/tests/component/rpm/test_import_srpm.py @@ -158,7 +158,7 @@ class TestImportPacked(ComponentTestBase): eq_(len(repo.get_commits(until='upstream')), 2) # Check number of tags eq_(len(repo.get_tags('upstream/*')), 2) - eq_(len(repo.get_tags('packaging/*')), 3) + eq_(len(repo.get_tags('vendor/*')), 3) def test_import_to_existing(self): """Test importing to an existing repo""" -- cgit v1.2.3 From 8456b886b0fcd8ce465c3e3c44b47beeaf436afb Mon Sep 17 00:00:00 2001 From: SoonKyu Park Date: Fri, 8 Apr 2016 14:19:55 +0900 Subject: change testdata's gerrit server IP to review.tizen.org Change-Id: Ie4a8ad352400f8196cb8bd544a506e5b8ae484b7 --- .gitmodules | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/.gitmodules b/.gitmodules index cb63fcb6..19d19953 100644 --- a/.gitmodules +++ b/.gitmodules @@ -1,6 +1,6 @@ [submodule "tests/component/deb/data"] path = tests/component/deb/data - url = ssh://jenkins@10.113.136.109:29418/tools/git-buildpackage-deb-testdata + url = git://honk.sigxcpu.org/git/gbp/deb-testdata [submodule "tests/component/rpm/data"] path = tests/component/rpm/data - url = ssh://jenkins@10.113.136.109:29418/tools/git-buildpackage-rpm-testdata + url = git://github.com/marquiz/git-buildpackage-rpm-testdata.git -- cgit v1.2.3 From f8507197185efce41747a49bd029a8185b2e9292 Mon Sep 17 00:00:00 2001 From: "shuai.fu" Date: Tue, 10 May 2016 13:51:00 +0800 Subject: Add tests/component/rpm/data and tests/component/deb/data Signed-off-by: shuai.fu Change-Id: I850ffbab50fa949be56a3e35665e80bc51d06adf --- .gitmodules | 8 ++++---- tests/component/rpm/data | 2 +- 2 files changed, 5 insertions(+), 5 deletions(-) diff --git a/.gitmodules b/.gitmodules index 68a6928c..7f8a520a 100644 --- a/.gitmodules +++ b/.gitmodules @@ -1,6 +1,6 @@ -[submodule "tests/component/deb/data"] - path = tests/component/deb/data - url = ssh://jenkins@109.123.100.123:29418/tizen.org-tools/git-buildpackage-deb-testdata [submodule "tests/component/rpm/data"] path = tests/component/rpm/data - url = ssh://jenkins@109.123.100.123:29418/tizen.org-tools/git-buildpackage-rpm-testdata + url = ssh://jenkins@109.123.100.123:29418/tizen.org-tools/git-buildpackage-rpm-testdata +[submodule "tests/component/deb/data"] + path = tests/component/deb/data + url = ssh://jenkins@109.123.100.123:29418/tizen.org-tools/git-buildpackage-deb-testdata diff --git a/tests/component/rpm/data b/tests/component/rpm/data index ff090c1c..03eefbe8 160000 --- a/tests/component/rpm/data +++ b/tests/component/rpm/data @@ -1 +1 @@ -Subproject commit ff090c1cf946e3df67795ce3c1437ec6246dbf37 +Subproject commit 03eefbe8e09d0bf0bafd817f896c7998048b55ec -- cgit v1.2.3 From f709f11844fea7cec177ee01e2536d0d97edeee0 Mon Sep 17 00:00:00 2001 From: Jun Wang Date: Tue, 10 May 2016 14:03:50 +0800 Subject: Remove unused functions Change-Id: I7cfa375f77ccc068fb5107d334e6b5fe1511cda5 --- gbp/rpm/__init__.py | 30 ------------------------------ 1 file changed, 30 deletions(-) diff --git a/gbp/rpm/__init__.py b/gbp/rpm/__init__.py index d47fb302..d5fa1ee8 100644 --- a/gbp/rpm/__init__.py +++ b/gbp/rpm/__init__.py @@ -901,34 +901,4 @@ def string_to_int(val_str): else: return int(val_str) -def compose_version_str(evr): - """ - Compose a full version string from individual "version components", - i.e. epoch, version and release - - @param evr: dict of version components - @type evr: C{dict} of C{str} - @return: full version - @rtype: C{str} - - >>> compose_version_str({'epoch': '', 'upstreamversion': '1.0'}) - '1.0' - >>> compose_version_str({'epoch': '2', 'upstreamversion': '1.0', 'release': None}) - '2:1.0' - >>> compose_version_str({'epoch': None, 'upstreamversion': '1', 'release': '0'}) - '1-0' - >>> compose_version_str({'epoch': '2', 'upstreamversion': '1.0', 'release': '2.3'}) - '2:1.0-2.3' - >>> compose_version_str({'epoch': '2', 'upstreamversion': '', 'release': '2.3'}) - """ - if 'upstreamversion' in evr and evr['upstreamversion']: - version = "" - if 'epoch' in evr and evr['epoch']: - version += "%s:" % evr['epoch'] - version += evr['upstreamversion'] - if 'release' in evr and evr['release']: - version += "-%s" % evr['release'] - if version: - return version - return None # vim:et:ts=4:sw=4:et:sts=4:ai:set list listchars=tab\:»·,trail\:·: -- cgit v1.2.3 From cd4c5addd10e00af3c480b941fb52057573b7c67 Mon Sep 17 00:00:00 2001 From: Jun Wang Date: Tue, 10 May 2016 15:03:01 +0800 Subject: 1. Reset to 0.27 2. Keep same code with latest release Change-Id: I30588773b0a039c9f5002bf65b5c768a16fb7935 --- .gitmodules | 6 +- README | 6 +- TODO | 3 - debian/changelog | 8 - debian/source/options | 2 +- gbp/scripts/common/import_orig.py | 10 - packaging/git-buildpackage.changes | 4 - packaging/git-buildpackage.spec | 2 +- tests/20_test_rpm.py | 479 --------------------- tests/component/rpm/test_import_srpm.py | 21 +- tests/data/rpm/rpmbuild/SOURCES/bar.tar.gz | Bin 177 -> 0 bytes tests/data/rpm/rpmbuild/SOURCES/foo.txt | 3 - .../data/rpm/rpmbuild/SOURCES/gbp-test-1.0.tar.bz2 | Bin 383 -> 0 bytes .../rpm/rpmbuild/SOURCES/gbp-test-native-1.0.zip | Bin 656 -> 0 bytes .../data/rpm/rpmbuild/SOURCES/gbp-test2-3.0.tar.gz | Bin 328 -> 0 bytes tests/data/rpm/rpmbuild/SOURCES/my.patch | 9 - tests/data/rpm/rpmbuild/SOURCES/my2.patch | 7 - tests/data/rpm/rpmbuild/SOURCES/my3.patch | 7 - tests/data/rpm/rpmbuild/SPECS/gbp-test-native.spec | 34 -- .../data/rpm/rpmbuild/SPECS/gbp-test-native2.spec | 35 -- tests/data/rpm/rpmbuild/SPECS/gbp-test.spec | 42 -- tests/data/rpm/rpmbuild/SPECS/gbp-test2.spec | 60 --- tests/data/rpm/specs/gbp-test-native.spec | 1 - tests/data/rpm/specs/gbp-test-native2.spec | 1 - tests/data/rpm/specs/gbp-test-quirks.spec | 30 -- tests/data/rpm/specs/gbp-test-reference.spec | 43 -- tests/data/rpm/specs/gbp-test-reference2.spec | 47 -- tests/data/rpm/specs/gbp-test-tags.spec | 74 ---- .../data/rpm/specs/gbp-test-updates-reference.spec | 44 -- tests/data/rpm/specs/gbp-test-updates.spec | 49 --- tests/data/rpm/specs/gbp-test.spec | 1 - tests/data/rpm/specs/gbp-test2-reference.spec | 61 --- tests/data/rpm/specs/gbp-test2-reference2.spec | 68 --- tests/data/rpm/specs/gbp-test2.spec | 1 - tests/data/rpm/srpms/gbp-test-1.0-1.src.rpm | Bin 3427 -> 0 bytes tests/data/rpm/srpms/gbp-test-native-1.0-1.src.rpm | Bin 2187 -> 0 bytes .../data/rpm/srpms/gbp-test-native2-2.0-0.src.rpm | Bin 2008 -> 0 bytes tests/data/rpm/srpms/gbp-test2-3.0-0.src.rpm | Bin 3507 -> 0 bytes tests/test_rpm.py | 479 +++++++++++++++++++++ tests/test_rpm_data/rpmbuild/SOURCES/bar.tar.gz | Bin 0 -> 177 bytes tests/test_rpm_data/rpmbuild/SOURCES/foo.txt | 3 + .../rpmbuild/SOURCES/gbp-test-1.0.tar.bz2 | Bin 0 -> 383 bytes .../rpmbuild/SOURCES/gbp-test-native-1.0.zip | Bin 0 -> 656 bytes .../rpmbuild/SOURCES/gbp-test2-3.0.tar.gz | Bin 0 -> 328 bytes tests/test_rpm_data/rpmbuild/SOURCES/my.patch | 9 + tests/test_rpm_data/rpmbuild/SOURCES/my2.patch | 7 + tests/test_rpm_data/rpmbuild/SOURCES/my3.patch | 7 + .../rpmbuild/SPECS/gbp-test-native.spec | 34 ++ .../rpmbuild/SPECS/gbp-test-native2.spec | 35 ++ tests/test_rpm_data/rpmbuild/SPECS/gbp-test.spec | 42 ++ tests/test_rpm_data/rpmbuild/SPECS/gbp-test2.spec | 60 +++ .../rpmbuild/SPECS/gbp-test2.spec.orig | 46 ++ tests/test_rpm_data/specs/gbp-test-native.spec | 1 + tests/test_rpm_data/specs/gbp-test-native2.spec | 1 + tests/test_rpm_data/specs/gbp-test-quirks.spec | 30 ++ tests/test_rpm_data/specs/gbp-test-reference.spec | 43 ++ tests/test_rpm_data/specs/gbp-test-reference2.spec | 47 ++ tests/test_rpm_data/specs/gbp-test-tags.spec | 74 ++++ .../specs/gbp-test-updates-reference.spec | 44 ++ tests/test_rpm_data/specs/gbp-test-updates.spec | 49 +++ tests/test_rpm_data/specs/gbp-test.spec | 1 + tests/test_rpm_data/specs/gbp-test2-reference.spec | 61 +++ .../test_rpm_data/specs/gbp-test2-reference2.spec | 68 +++ tests/test_rpm_data/specs/gbp-test2.spec | 1 + tests/test_rpm_data/srpms/gbp-test-1.0-1.src.rpm | Bin 0 -> 3427 bytes .../srpms/gbp-test-native-1.0-1.src.rpm | Bin 0 -> 2187 bytes .../srpms/gbp-test-native2-2.0-0.src.rpm | Bin 0 -> 2008 bytes tests/test_rpm_data/srpms/gbp-test2-3.0-0.src.rpm | Bin 0 -> 3507 bytes 68 files changed, 1162 insertions(+), 1138 deletions(-) delete mode 100644 tests/20_test_rpm.py delete mode 100644 tests/data/rpm/rpmbuild/SOURCES/bar.tar.gz delete mode 100644 tests/data/rpm/rpmbuild/SOURCES/foo.txt delete mode 100644 tests/data/rpm/rpmbuild/SOURCES/gbp-test-1.0.tar.bz2 delete mode 100644 tests/data/rpm/rpmbuild/SOURCES/gbp-test-native-1.0.zip delete mode 100644 tests/data/rpm/rpmbuild/SOURCES/gbp-test2-3.0.tar.gz delete mode 100644 tests/data/rpm/rpmbuild/SOURCES/my.patch delete mode 100644 tests/data/rpm/rpmbuild/SOURCES/my2.patch delete mode 100644 tests/data/rpm/rpmbuild/SOURCES/my3.patch delete mode 100644 tests/data/rpm/rpmbuild/SPECS/gbp-test-native.spec delete mode 100644 tests/data/rpm/rpmbuild/SPECS/gbp-test-native2.spec delete mode 100644 tests/data/rpm/rpmbuild/SPECS/gbp-test.spec delete mode 100644 tests/data/rpm/rpmbuild/SPECS/gbp-test2.spec delete mode 120000 tests/data/rpm/specs/gbp-test-native.spec delete mode 120000 tests/data/rpm/specs/gbp-test-native2.spec delete mode 100644 tests/data/rpm/specs/gbp-test-quirks.spec delete mode 100644 tests/data/rpm/specs/gbp-test-reference.spec delete mode 100644 tests/data/rpm/specs/gbp-test-reference2.spec delete mode 100644 tests/data/rpm/specs/gbp-test-tags.spec delete mode 100644 tests/data/rpm/specs/gbp-test-updates-reference.spec delete mode 100644 tests/data/rpm/specs/gbp-test-updates.spec delete mode 120000 tests/data/rpm/specs/gbp-test.spec delete mode 100644 tests/data/rpm/specs/gbp-test2-reference.spec delete mode 100644 tests/data/rpm/specs/gbp-test2-reference2.spec delete mode 120000 tests/data/rpm/specs/gbp-test2.spec delete mode 100644 tests/data/rpm/srpms/gbp-test-1.0-1.src.rpm delete mode 100644 tests/data/rpm/srpms/gbp-test-native-1.0-1.src.rpm delete mode 100644 tests/data/rpm/srpms/gbp-test-native2-2.0-0.src.rpm delete mode 100644 tests/data/rpm/srpms/gbp-test2-3.0-0.src.rpm create mode 100644 tests/test_rpm.py create mode 100644 tests/test_rpm_data/rpmbuild/SOURCES/bar.tar.gz create mode 100644 tests/test_rpm_data/rpmbuild/SOURCES/foo.txt create mode 100644 tests/test_rpm_data/rpmbuild/SOURCES/gbp-test-1.0.tar.bz2 create mode 100644 tests/test_rpm_data/rpmbuild/SOURCES/gbp-test-native-1.0.zip create mode 100644 tests/test_rpm_data/rpmbuild/SOURCES/gbp-test2-3.0.tar.gz create mode 100644 tests/test_rpm_data/rpmbuild/SOURCES/my.patch create mode 100644 tests/test_rpm_data/rpmbuild/SOURCES/my2.patch create mode 100644 tests/test_rpm_data/rpmbuild/SOURCES/my3.patch create mode 100644 tests/test_rpm_data/rpmbuild/SPECS/gbp-test-native.spec create mode 100644 tests/test_rpm_data/rpmbuild/SPECS/gbp-test-native2.spec create mode 100644 tests/test_rpm_data/rpmbuild/SPECS/gbp-test.spec create mode 100644 tests/test_rpm_data/rpmbuild/SPECS/gbp-test2.spec create mode 100644 tests/test_rpm_data/rpmbuild/SPECS/gbp-test2.spec.orig create mode 120000 tests/test_rpm_data/specs/gbp-test-native.spec create mode 120000 tests/test_rpm_data/specs/gbp-test-native2.spec create mode 100644 tests/test_rpm_data/specs/gbp-test-quirks.spec create mode 100644 tests/test_rpm_data/specs/gbp-test-reference.spec create mode 100644 tests/test_rpm_data/specs/gbp-test-reference2.spec create mode 100644 tests/test_rpm_data/specs/gbp-test-tags.spec create mode 100644 tests/test_rpm_data/specs/gbp-test-updates-reference.spec create mode 100644 tests/test_rpm_data/specs/gbp-test-updates.spec create mode 120000 tests/test_rpm_data/specs/gbp-test.spec create mode 100644 tests/test_rpm_data/specs/gbp-test2-reference.spec create mode 100644 tests/test_rpm_data/specs/gbp-test2-reference2.spec create mode 120000 tests/test_rpm_data/specs/gbp-test2.spec create mode 100644 tests/test_rpm_data/srpms/gbp-test-1.0-1.src.rpm create mode 100644 tests/test_rpm_data/srpms/gbp-test-native-1.0-1.src.rpm create mode 100644 tests/test_rpm_data/srpms/gbp-test-native2-2.0-0.src.rpm create mode 100644 tests/test_rpm_data/srpms/gbp-test2-3.0-0.src.rpm diff --git a/.gitmodules b/.gitmodules index 7f8a520a..02d21b87 100644 --- a/.gitmodules +++ b/.gitmodules @@ -1,6 +1,6 @@ -[submodule "tests/component/rpm/data"] - path = tests/component/rpm/data - url = ssh://jenkins@109.123.100.123:29418/tizen.org-tools/git-buildpackage-rpm-testdata [submodule "tests/component/deb/data"] path = tests/component/deb/data url = ssh://jenkins@109.123.100.123:29418/tizen.org-tools/git-buildpackage-deb-testdata +[submodule "tests/component/rpm/data"] + path = tests/component/rpm/data + url = ssh://jenkins@109.123.100.123:29418/tizen.org-tools/git-buildpackage-rpm-testdata diff --git a/README b/README index 4acc68bc..26a155aa 100644 --- a/README +++ b/README @@ -14,6 +14,10 @@ The API documentation of the gbp module can be found at: http://honk.sigxcpu.org/projects/git-buildpackage/apidocs/ -The documentation available for the RPM support can be found at +The limited documentation available for the RPM support can be found at http://marquiz.github.com/git-buildpackage-rpm/ + +Unfortunately, the manpages for RPM tools are still missing. Refer to +--help option of the commands, for the most detailed description of different +options. diff --git a/TODO b/TODO index cf9c6809..295398a5 100644 --- a/TODO +++ b/TODO @@ -1,8 +1,5 @@ See https://honk.sigxcpu.org/piki/projects/git-buildpackage/ - - - RPM-related things: - unit tests: - add unit tests for the rpm command line tools diff --git a/debian/changelog b/debian/changelog index a6adc71f..ee6ad668 100644 --- a/debian/changelog +++ b/debian/changelog @@ -1,11 +1,3 @@ -git-buildpackage (0.6.28-tizen20160308) unstable; urgency=medium - - * Check codes in devel branch - - -- Jun Wang TUE, 08 Mar 2016 10:20:21 +0800 - - - git-buildpackage (0.6.27-tizen20160302) unstable; urgency=medium * Fix error logs when __import__ faild,like "No handlers could be found fo logger" diff --git a/debian/source/options b/debian/source/options index 6862544b..f2592903 100644 --- a/debian/source/options +++ b/debian/source/options @@ -1,2 +1,2 @@ -extend-diff-ignore = "^(tests/data/rpm/.*|tests/component/rpm/data/.*|tests/component/deb/data/.*)" +extend-diff-ignore = "^(tests/test_rpm_data/.*|tests/component/rpm/data/.*|tests/component/deb/data/.*)" diff-ignore diff --git a/gbp/scripts/common/import_orig.py b/gbp/scripts/common/import_orig.py index 45e71c57..16244423 100644 --- a/gbp/scripts/common/import_orig.py +++ b/gbp/scripts/common/import_orig.py @@ -148,16 +148,6 @@ def prepare_sources(source, pkg_name, pkg_version, pristine_commit_name, pristine_path = pristine.path if pristine else '' return (filtered.unpacked, pristine_path) -def repack_source(source, new_name, unpack_dir, filters, new_prefix=None): - """Repack the source tree""" - repacked = source.pack(new_name, filters, new_prefix) - if source.is_tarball(): # the tarball was filtered on unpack - repacked.unpacked = source.unpacked - else: # otherwise unpack the generated tarball get a filtered tree - repacked.unpack(unpack_dir) - return repacked - - def prepare_pristine_tar(source, pkg_name, pkg_version, pristine_commit_name, filters=None, prefix=None, tmpdir=None): """ diff --git a/packaging/git-buildpackage.changes b/packaging/git-buildpackage.changes index ef2c9eba..5f8ecf55 100644 --- a/packaging/git-buildpackage.changes +++ b/packaging/git-buildpackage.changes @@ -1,7 +1,3 @@ -* Wed Mar 08 2016 Jun Wang tizen/0.6.28-20160308 -- Make new tag in devel -- Upgrade version to 0.6.28 - * Wed Mar 02 2016 Jun Wang tizen/0.6.27-20160302 - Upgrade version to 0.6.27 diff --git a/packaging/git-buildpackage.spec b/packaging/git-buildpackage.spec index 5532b3b3..d71f172d 100644 --- a/packaging/git-buildpackage.spec +++ b/packaging/git-buildpackage.spec @@ -3,7 +3,7 @@ Name: git-buildpackage Summary: Build packages from git -Version: 0.6.28 +Version: 0.6.27 Release: 0 Group: Development/Tools/Building License: GPLv2 diff --git a/tests/20_test_rpm.py b/tests/20_test_rpm.py deleted file mode 100644 index 52a14ff1..00000000 --- a/tests/20_test_rpm.py +++ /dev/null @@ -1,479 +0,0 @@ -# vim: set fileencoding=utf-8 : -# -# (C) 2012 Intel Corporation -# This program is free software; you can redistribute it and/or modify -# it under the terms of the GNU General Public License as published by -# the Free Software Foundation; either version 2 of the License, or -# (at your option) any later version. -# -# This program is distributed in the hope that it will be useful, -# but WITHOUT ANY WARRANTY; without even the implied warranty of -# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -# GNU General Public License for more details. -# -# You should have received a copy of the GNU General Public License -# along with this program; if not, write to the Free Software -# Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA -"""Test the classes under L{gbp.rpm}""" - -import filecmp -import os -import shutil -import tempfile -from nose.tools import assert_raises, eq_ - -from gbp.errors import GbpError -from gbp.rpm import (SrcRpmFile, SpecFile, parse_srpm, NoSpecError, guess_spec, - guess_spec_repo, spec_from_repo) -from gbp.git.repository import GitRepository - -DATA_DIR = os.path.join(os.path.dirname(os.path.abspath(__file__)), 'data','rpm') -SRPM_DIR = os.path.join(DATA_DIR, 'srpms') -SPEC_DIR = os.path.join(DATA_DIR, 'specs') - -class SpecFileTester(SpecFile): - """Helper class for testing""" - - def protected(self, name): - """Get a protected member""" - return super(SpecFileTester, self).__getattribute__(name) - - -class TestSrcRpmFile(object): - """Test L{gbp.rpm.SrcRpmFile}""" - - def setup(self): - self.tmpdir = tempfile.mkdtemp(prefix='gbp_%s_' % __name__, dir='.') - - def teardown(self): - shutil.rmtree(self.tmpdir) - - def test_srpm(self): - """Test parsing of a source rpm""" - srpm = SrcRpmFile(os.path.join(SRPM_DIR, 'gbp-test-1.0-1.src.rpm')) - assert srpm.version == {'release': '1', 'upstreamversion': '1.0'} - assert srpm.name == 'gbp-test' - assert srpm.upstreamversion == '1.0' - assert srpm.packager is None - - def test_srpm_2(self): - """Test parsing of another source rpm""" - srpm = SrcRpmFile(os.path.join(SRPM_DIR, 'gbp-test2-3.0-0.src.rpm')) - assert srpm.version == {'release': '0', 'upstreamversion': '3.0', - 'epoch': '2'} - assert srpm.packager == 'Markus Lehtonen '\ - '' - - def test_unpack_srpm(self): - """Test unpacking of a source rpm""" - srpm = SrcRpmFile(os.path.join(SRPM_DIR, 'gbp-test-1.0-1.src.rpm')) - srpm.unpack(self.tmpdir) - for fn in ['gbp-test-1.0.tar.bz2', 'foo.txt', 'bar.tar.gz', 'my.patch', - 'my2.patch', 'my3.patch']: - assert os.path.exists(os.path.join(self.tmpdir, fn)), \ - "%s not found" % fn - - -class TestSpecFile(object): - """Test L{gbp.rpm.SpecFile}""" - - def setup(self): - self.tmpdir = tempfile.mkdtemp(prefix='gbp_%s_' % __name__, dir='.') - - def teardown(self): - shutil.rmtree(self.tmpdir) - - def test_spec(self): - """Test parsing of a valid spec file""" - spec_filepath = os.path.join(SPEC_DIR, 'gbp-test.spec') - spec = SpecFileTester(spec_filepath) - - # Test basic properties - assert spec.specfile == os.path.basename(spec_filepath) - assert spec.specdir == os.path.dirname(spec_filepath) - assert spec.specpath == spec_filepath - - assert spec.name == 'gbp-test' - assert spec.packager is None - - assert spec.upstreamversion == '1.0' - assert spec.release == '1' - assert spec.epoch is None - assert spec.version == {'release': '1', 'upstreamversion': '1.0'} - - orig = spec.orig_src - assert orig['filename'] == 'gbp-test-1.0.tar.bz2' - assert orig['uri'] == 'gbp-test-1.0.tar.bz2' - assert orig['filename_base'] == 'gbp-test-1.0' - assert orig['archive_fmt'] == 'tar' - assert orig['compression'] == 'bzip2' - assert orig['prefix'] == 'gbp-test/' - - def test_spec_2(self): - """Test parsing of another valid spec file""" - spec_filepath = os.path.join(SPEC_DIR, 'gbp-test2.spec') - spec = SpecFile(spec_filepath) - - # Test basic properties - assert spec.name == 'gbp-test2' - assert spec.packager == 'Markus Lehtonen ' \ - '' - - assert spec.epoch == '2' - assert spec.version == {'release': '0', 'upstreamversion': '3.0', - 'epoch': '2'} - - orig = spec.orig_src - assert orig['filename'] == 'gbp-test2-3.0.tar.gz' - assert orig['uri'] == 'ftp://ftp.host.com/gbp-test2-3.0.tar.gz' - assert orig['archive_fmt'] == 'tar' - assert orig['compression'] == 'gzip' - assert orig['prefix'] == '' - - def test_spec_3(self): - """Test parsing of yet another valid spec file""" - spec_filepath = os.path.join(SPEC_DIR, 'gbp-test-native.spec') - spec = SpecFile(spec_filepath) - - # Test basic properties - assert spec.name == 'gbp-test-native' - orig = spec.orig_src - assert orig['filename'] == 'gbp-test-native-1.0.zip' - assert orig['archive_fmt'] == 'zip' - assert orig['compression'] == None - assert orig['prefix'] == 'gbp-test-native-1.0/' - - def test_spec_4(self): - """Test parsing of spec without orig tarball""" - spec_filepath = os.path.join(SPEC_DIR, 'gbp-test-native2.spec') - spec = SpecFile(spec_filepath) - - # Test basic properties - assert spec.name == 'gbp-test-native2' - assert spec.orig_src is None - - def test_parse_raw(self): - """Test parsing of a valid spec file""" - assert_raises(NoSpecError, SpecFile, None, None) - assert_raises(NoSpecError, SpecFile, 'filename', 'filedata') - - """ - with assert_raises(NoSpecError): - SpecFile(None, None) - with assert_raises(NoSpecError): - SpecFile('filename', 'filedata') - """ - - spec_filepath = os.path.join(SPEC_DIR, 'gbp-test.spec') - with open(spec_filepath, 'r') as spec_fd: - spec_data = spec_fd.read() - spec = SpecFile(filedata=spec_data) - - # Test basic properties - assert spec.specfile == None - assert spec.specdir == None - assert spec.name == 'gbp-test' - - def test_update_spec(self): - """Test spec autoupdate functionality""" - # Create temporary spec file - tmp_spec = os.path.join(self.tmpdir, 'gbp-test.spec') - shutil.copy2(os.path.join(SPEC_DIR, 'gbp-test.spec'), tmp_spec) - - reference_spec = os.path.join(SPEC_DIR, 'gbp-test-reference.spec') - spec = SpecFile(tmp_spec) - spec.update_patches(['new.patch'], {}) - spec.write_spec_file() - assert filecmp.cmp(tmp_spec, reference_spec) is True - - # Test adding the VCS tag and adding changelog - reference_spec = os.path.join(SPEC_DIR, 'gbp-test-reference2.spec') - spec.set_tag('VCS', None, 'myvcstag') - spec.set_changelog("* Wed Feb 05 2014 Name 1\n- New entry\n") - spec.write_spec_file() - assert filecmp.cmp(tmp_spec, reference_spec) is True - - def test_update_spec2(self): - """Another test for spec autoupdate functionality""" - tmp_spec = os.path.join(self.tmpdir, 'gbp-test2.spec') - shutil.copy2(os.path.join(SPEC_DIR, 'gbp-test2.spec'), tmp_spec) - - reference_spec = os.path.join(SPEC_DIR, 'gbp-test2-reference2.spec') - spec = SpecFile(tmp_spec) - spec.update_patches(['1.patch', '2.patch'], - {'1.patch': {'if': 'true'}, - '2.patch': {'ifarch': '%ix86'}}) - spec.set_tag('VCS', None, 'myvcstag') - spec.write_spec_file() - assert filecmp.cmp(tmp_spec, reference_spec) is True - - # Test updating patches again, removing the VCS tag and re-writing - # changelog - reference_spec = os.path.join(SPEC_DIR, 'gbp-test2-reference.spec') - spec.update_patches(['new.patch'], {'new.patch': {'if': '1'}}) - spec.set_tag('VCS', None, '') - spec.set_changelog("* Wed Feb 05 2014 Name 2\n- New entry\n\n") - spec.write_spec_file() - assert filecmp.cmp(tmp_spec, reference_spec) is True - - def test_modifying(self): - """Test updating/deleting of tags and macros""" - tmp_spec = os.path.join(self.tmpdir, 'gbp-test.spec') - shutil.copy2(os.path.join(SPEC_DIR, 'gbp-test-updates.spec'), tmp_spec) - reference_spec = os.path.join(SPEC_DIR, - 'gbp-test-updates-reference.spec') - spec = SpecFileTester(tmp_spec) - - # Mangle tags - prev = spec.protected('_delete_tag')('Vendor', None) - spec.protected('_set_tag')('License', None, 'new license', prev) - spec.protected('_delete_tag')('source', 0) - assert spec.sources() == {} - spec.protected('_delete_tag')('patch', 0) - spec.protected('_delete_tag')('patch', -1) - assert spec.protected('_patches')() == {} - prev = spec.protected('_delete_tag')('invalidtag', None) - - assert_raises(GbpError, spec.protected('_set_tag'), - 'Version', None, '', prev) - assert_raises(GbpError, spec.set_tag, - 'invalidtag', None, 'value') - - """ - with assert_raises(GbpError): - # Check that setting empty value fails - spec.protected('_set_tag')('Version', None, '', prev) - with assert_raises(GbpError): - # Check that setting invalid tag with public method fails - spec.set_tag('invalidtag', None, 'value') - """ - - # Mangle macros - prev = spec.protected('_delete_special_macro')('patch', -1) - spec.protected('_delete_special_macro')('patch', 123) - spec.protected('_set_special_macro')('patch', 0, 'my new args', prev) - assert_raises(GbpError, spec.protected('_delete_special_macro'), - 'invalidmacro', 0) - assert_raises(GbpError, spec.protected('_set_special_macro'), - 'invalidmacro', 0, 'args', prev) - - """ - with assert_raises(GbpError): - spec.protected('_delete_special_macro')('invalidmacro', 0) - with assert_raises(GbpError): - spec.protected('_set_special_macro')('invalidmacro', 0, 'args', - prev) - """ - - # Check resulting spec file - spec.write_spec_file() - assert filecmp.cmp(tmp_spec, reference_spec) is True - - def test_modifying_err(self): - """Test error conditions of modification methods""" - spec_filepath = os.path.join(SPEC_DIR, 'gbp-test2.spec') - spec = SpecFileTester(spec_filepath) - - # Unknown/invalid section name - assert_raises(GbpError, spec.protected('_set_section'), - 'patch', 'new content\n') - """ - with assert_raises(GbpError): - spec.protected('_set_section')('patch', 'new content\n') - """ - - # Multiple sections with the same name - assert_raises(GbpError, spec.protected('_set_section'), - 'files', '%{_sysconfdir}/foo\n') - - """ - with assert_raises(GbpError): - spec.protected('_set_section')('files', '%{_sysconfdir}/foo\n') - """ - - def test_changelog(self): - """Test changelog methods""" - spec_filepath = os.path.join(SPEC_DIR, 'gbp-test2.spec') - spec = SpecFile(spec_filepath) - - # Read changelog - eq_(spec.get_changelog(), - "* Tue Feb 04 2014 Name 1\n- My change\n\n\n") - - # Set changelog and check again - new_text = "* Wed Feb 05 2014 Name 2\n- New entry\n\n\n" - spec.set_changelog(new_text) - eq_(spec.get_changelog(), new_text) - - def test_quirks(self): - """Test spec that is broken/has anomalities""" - spec_filepath = os.path.join(SPEC_DIR, 'gbp-test-quirks.spec') - spec = SpecFile(spec_filepath) - - # Check that we quess orig source and prefix correctly - assert spec.orig_src['prefix'] == 'foobar/' - - def test_tags(self): - """Test parsing of all the different tags of spec file""" - spec_filepath = os.path.join(SPEC_DIR, 'gbp-test-tags.spec') - spec = SpecFileTester(spec_filepath) - - # Check all the tags - for name, val in spec.protected('_tags').iteritems(): - rval = None - if name in ('version', 'release', 'epoch'): - rval = '0' - elif name in ('autoreq', 'autoprov', 'autoreqprov'): - rval = 'No' - elif name not in spec.protected('_listtags'): - rval = 'my_%s' % name - if rval: - assert val['value'] == rval, ("'%s:' is '%s', expecting '%s'" % - (name, val['value'], rval)) - assert spec.ignorepatches == [] - # Check patch numbers and patch filenames - patches = {} - for patch in spec.protected('_tags')['patch']['lines']: - patches[patch['num']] = patch['linevalue'] - - assert patches == {0: 'my_patch0', -1: 'my_patch'} - - def test_patch_series(self): - """Test the getting the patches as a patchseries""" - spec_filepath = os.path.join(SPEC_DIR, 'gbp-test-native.spec') - spec = SpecFileTester(spec_filepath) - - assert len(spec.patchseries()) == 0 - spec.update_patches(['1.patch', '2.patch', '3.patch'], {}) - assert len(spec.patchseries()) == 3 - spec.protected('_gbp_tags')['ignore-patches'].append({'args': "0"}) - spec.update_patches(['4.patch'], {}) - assert len(spec.patchseries()) == 1 - assert len(spec.patchseries(ignored=True)) == 2 - spec.protected('_delete_special_macro')('patch', 0) - assert len(spec.patchseries(ignored=True)) == 1 - series = spec.patchseries(unapplied=True, ignored=True) - assert len(series) == 2 - assert os.path.basename(series[-1].path) == '1.patch' - - def test_patch_series_quirks(self): - """Patches are applied in order different from the patch numbering""" - spec_filepath = os.path.join(SPEC_DIR, 'gbp-test-quirks.spec') - spec = SpecFileTester(spec_filepath) - - # Check series is returned in the order the patches are applied - files = [os.path.basename(patch.path) for patch in spec.patchseries()] - assert files == ['05.patch', '01.patch'] - # Also ignored patches are returned in the correct order - files = [os.path.basename(patch.path) for patch in - spec.patchseries(ignored=True)] - assert files == ['05.patch', '02.patch', '01.patch'] - # Unapplied patches are added to the end of the series - files = [os.path.basename(patch.path) for patch in - spec.patchseries(unapplied=True)] - assert files == ['05.patch', '01.patch', '03.patch'] - # Return all patches (for which tag is found) - files = [os.path.basename(patch.path) for patch in - spec.patchseries(unapplied=True, ignored=True)] - assert files == ['05.patch', '02.patch', '01.patch', '03.patch', - '04.patch'] - - -class TestUtilityFunctions(object): - """Test utility functions of L{gbp.rpm}""" - def setup(self): - self.tmpdir = tempfile.mkdtemp(prefix='gbp_%s_' % __name__, dir='.') - - def teardown(self): - shutil.rmtree(self.tmpdir) - - def test_parse_srpm(self): - """Test parse_srpm() function""" - parse_srpm(os.path.join(SRPM_DIR, 'gbp-test-1.0-1.src.rpm')) - assert_raises(GbpError, parse_srpm, - os.path.join(DATA_DIR, 'notexists.src.rpm')) - - """ - with assert_raises(GbpError): - parse_srpm(os.path.join(DATA_DIR, 'notexists.src.rpm')) - with assert_raises(GbpError): - parse_srpm(os.path.join(SPEC_DIR, 'gbp-test.spec')) - """ - - def test_guess_spec(self): - """Test guess_spec() function""" - # Spec not found - assert_raises(NoSpecError, guess_spec, - DATA_DIR, recursive=False) - - """ - with assert_raises(NoSpecError): - guess_spec(DATA_DIR, recursive=False) - """ - - # Multiple spec files - assert_raises(NoSpecError, guess_spec, - DATA_DIR, recursive=True) - assert_raises(NoSpecError, guess_spec, - SPEC_DIR, recursive=False) - - """ - with assert_raises(NoSpecError): - guess_spec(DATA_DIR, recursive=True) - with assert_raises(NoSpecError): - guess_spec(SPEC_DIR, recursive=False) - """ - - # Spec found - spec = guess_spec(SPEC_DIR, recursive=False, - preferred_name = 'gbp-test2.spec') - assert spec.specfile == 'gbp-test2.spec' - assert spec.specdir == SPEC_DIR - - def test_guess_spec_repo(self): - """Test guess_spec_repo() and spec_from_repo() functions""" - # Create dummy repository with some commits - repo = GitRepository.create(self.tmpdir) - with open(os.path.join(repo.path, 'foo.txt'), 'w') as fobj: - fobj.write('bar\n') - repo.add_files('foo.txt') - repo.commit_all('Add dummy file') - os.mkdir(os.path.join(repo.path, 'packaging')) - shutil.copy(os.path.join(SPEC_DIR, 'gbp-test.spec'), - os.path.join(repo.path, 'packaging')) - repo.add_files('packaging/gbp-test.spec') - repo.commit_all('Add spec file') - - # Spec not found - assert_raises(NoSpecError, guess_spec_repo, - repo, 'HEAD~1', recursive=True) - assert_raises(NoSpecError, guess_spec_repo, - repo, 'HEAD', recursive=False) - - """ - with assert_raises(NoSpecError): - guess_spec_repo(repo, 'HEAD~1', recursive=True) - with assert_raises(NoSpecError): - guess_spec_repo(repo, 'HEAD', recursive=False) - """ - - # Spec found - spec = guess_spec_repo(repo, 'HEAD', 'packaging', recursive=False) - spec = guess_spec_repo(repo, 'HEAD', recursive=True) - assert spec.specfile == 'gbp-test.spec' - assert spec.specdir == 'packaging' - assert spec.specpath == 'packaging/gbp-test.spec' - - # Test spec_from_repo() - assert_raises(NoSpecError, spec_from_repo, - repo, 'HEAD~1', 'packaging/gbp-test.spec') - - """ - with assert_raises(NoSpecError): - spec_from_repo(repo, 'HEAD~1', 'packaging/gbp-test.spec') - """ - - spec = spec_from_repo(repo, 'HEAD', 'packaging/gbp-test.spec') - assert spec.specfile == 'gbp-test.spec' - -# vim:et:ts=4:sw=4:et:sts=4:ai:set list listchars=tab\:»·,trail\:·: diff --git a/tests/component/rpm/test_import_srpm.py b/tests/component/rpm/test_import_srpm.py index b35a5bd6..6635400b 100644 --- a/tests/component/rpm/test_import_srpm.py +++ b/tests/component/rpm/test_import_srpm.py @@ -72,8 +72,8 @@ class TestImportPacked(ComponentTestBase): # Check repository state repo = GitRepository('gbp-test2') files = set(['Makefile', 'README', 'bar.tar.gz', 'dummy.sh', 'foo.txt', - 'gbp-test2.spec', 'gbp-test2-alt.spec', 'my.patch', - 'mydir/myfile.txt']) + 'gbp-test2.spec', 'gbp-test2-alt.spec', 'my.patch', + 'mydir/myfile.txt']) self._check_repo_state(repo, 'master', ['master', 'upstream'], files) # Four commits: upstream, packaging files, one patch and the removal @@ -101,7 +101,7 @@ class TestImportPacked(ComponentTestBase): eq_(mock_import(['--native', srpm]), 0) # Check repository state files = set(['.gbp.conf', 'Makefile', 'README', 'dummy.sh', - 'packaging/gbp-test-native.spec']) + 'packaging/gbp-test-native.spec']) repo = GitRepository('gbp-test-native') self._check_repo_state(repo, 'master', ['master'], files) # Only one commit: the imported source tarball @@ -120,7 +120,7 @@ class TestImportPacked(ComponentTestBase): def test_import_compressed_patches(self): """Test importing of non-native src.rpm with compressed patches""" srpm = os.path.join(DATA_DIR, 'gbp-test-1.1-2.src.rpm') - eq_(import_srpm(['arg0', srpm]), 0) + eq_(mock_import([srpm]), 0) # Check repository state repo = GitRepository('gbp-test') files = set(['Makefile', 'README', 'AUTHORS', 'NEWS', 'bar.tar.gz', @@ -144,13 +144,12 @@ class TestImportPacked(ComponentTestBase): eq_(mock_import([srpms[1]]), 0) eq_(len(repo.get_commits()), 4) eq_(len(repo.get_commits(until='upstream')), 1) - eq_(mock_import(['--no-pristine-tar', '--allow-same-version', - srpms[1]]), 0) + eq_(mock_import(['--allow-same-version', srpms[1]]), 0) # Added new versio packaging plus one patch eq_(len(repo.get_commits()), 7) eq_(len(repo.get_commits(until='upstream')), 1) # Import new version - eq_(mock_import(['--no-pristine-tar', srpms[2]]), 0) + eq_(mock_import([srpms[2]]), 0) files = set(['Makefile', 'README', 'bar.tar.gz', 'dummy.sh', 'foo.txt', 'gbp-test.spec', 'my.patch', 'mydir/myfile.txt']) self._check_repo_state(repo, 'master', ['master', 'upstream'], files) @@ -207,7 +206,7 @@ class TestImportPacked(ComponentTestBase): """Test various options of git-import-srpm""" srpm = os.path.join(DATA_DIR, 'gbp-test2-2.0-0.src.rpm') - eq_(mock_import(['--no-pristine-tar', + eq_(mock_import([ '--no-patch-import', '--packaging-branch=pack', '--upstream-branch=orig', @@ -219,9 +218,9 @@ class TestImportPacked(ComponentTestBase): # Check repository state repo = GitRepository('gbp-test2') files = set(['Makefile', 'README', 'dummy.sh', 'packaging/bar.tar.gz', - 'packaging/foo.txt', 'packaging/gbp-test2.spec', - 'packaging/gbp-test2-alt.spec', 'packaging/my.patch', - 'packaging/my2.patch', 'packaging/my3.patch']) + 'packaging/foo.txt', 'packaging/gbp-test2.spec', + 'packaging/gbp-test2-alt.spec', 'packaging/my.patch', + 'packaging/my2.patch', 'packaging/my3.patch']) self._check_repo_state(repo, 'pack', ['pack', 'orig'], files) eq_(len(repo.get_commits()), 2) # Check packaging dir diff --git a/tests/data/rpm/rpmbuild/SOURCES/bar.tar.gz b/tests/data/rpm/rpmbuild/SOURCES/bar.tar.gz deleted file mode 100644 index f5dae803..00000000 Binary files a/tests/data/rpm/rpmbuild/SOURCES/bar.tar.gz and /dev/null differ diff --git a/tests/data/rpm/rpmbuild/SOURCES/foo.txt b/tests/data/rpm/rpmbuild/SOURCES/foo.txt deleted file mode 100644 index 25ed442f..00000000 --- a/tests/data/rpm/rpmbuild/SOURCES/foo.txt +++ /dev/null @@ -1,3 +0,0 @@ -FOO: - -file for testing rpm support of git-buildpackage. diff --git a/tests/data/rpm/rpmbuild/SOURCES/gbp-test-1.0.tar.bz2 b/tests/data/rpm/rpmbuild/SOURCES/gbp-test-1.0.tar.bz2 deleted file mode 100644 index 7d0759fe..00000000 Binary files a/tests/data/rpm/rpmbuild/SOURCES/gbp-test-1.0.tar.bz2 and /dev/null differ diff --git a/tests/data/rpm/rpmbuild/SOURCES/gbp-test-native-1.0.zip b/tests/data/rpm/rpmbuild/SOURCES/gbp-test-native-1.0.zip deleted file mode 100644 index 22a273d1..00000000 Binary files a/tests/data/rpm/rpmbuild/SOURCES/gbp-test-native-1.0.zip and /dev/null differ diff --git a/tests/data/rpm/rpmbuild/SOURCES/gbp-test2-3.0.tar.gz b/tests/data/rpm/rpmbuild/SOURCES/gbp-test2-3.0.tar.gz deleted file mode 100644 index 7b3eaf3c..00000000 Binary files a/tests/data/rpm/rpmbuild/SOURCES/gbp-test2-3.0.tar.gz and /dev/null differ diff --git a/tests/data/rpm/rpmbuild/SOURCES/my.patch b/tests/data/rpm/rpmbuild/SOURCES/my.patch deleted file mode 100644 index 50870df2..00000000 --- a/tests/data/rpm/rpmbuild/SOURCES/my.patch +++ /dev/null @@ -1,9 +0,0 @@ -diff --git a/dummy.sh b/dummy.sh -index 8c33db6..6f04268 100755 ---- dummy.sh -+++ dummy.sh -@@ -1,3 +1,3 @@ - #!/bin/sh - --echo "Hello world" -+echo "Hello GBP" diff --git a/tests/data/rpm/rpmbuild/SOURCES/my2.patch b/tests/data/rpm/rpmbuild/SOURCES/my2.patch deleted file mode 100644 index ad5ca2d2..00000000 --- a/tests/data/rpm/rpmbuild/SOURCES/my2.patch +++ /dev/null @@ -1,7 +0,0 @@ -diff --git a/mydir/myfile.txt b/mydir/myfile.txt -new file mode 100644 -index 0000000..2cdad29 ---- /dev/null -+++ b/mydir/myfile.txt -@@ -0,0 +1 @@ -+Dummy diff --git a/tests/data/rpm/rpmbuild/SOURCES/my3.patch b/tests/data/rpm/rpmbuild/SOURCES/my3.patch deleted file mode 100644 index 9fee859d..00000000 --- a/tests/data/rpm/rpmbuild/SOURCES/my3.patch +++ /dev/null @@ -1,7 +0,0 @@ -diff --git a/README b/README -index a1311cb..a59f1b9 100644 ---- a/README -+++ b/README -@@ -1 +1 @@ --Just for testing git-buildpackage. -+Just for testing GBP. diff --git a/tests/data/rpm/rpmbuild/SPECS/gbp-test-native.spec b/tests/data/rpm/rpmbuild/SPECS/gbp-test-native.spec deleted file mode 100644 index 38b07e48..00000000 --- a/tests/data/rpm/rpmbuild/SPECS/gbp-test-native.spec +++ /dev/null @@ -1,34 +0,0 @@ -Name: gbp-test-native -Summary: Test package for git-buildpackage -Version: 1.0 -Release: 1 -Group: Development/Libraries -License: GPLv2 -Source1: %{name}-%{version}.zip -BuildRequires: unzip - -%description -Package for testing the RPM functionality of git-buildpackage. -Mimics a "native" package - - -%prep -unzip %{SOURCE1} -%setup -T -D - - -%build -make - - -%install -rm -rf %{buildroot} -mkdir -p %{buildroot}/%{_datadir}/%{name} -cp -R * %{buildroot}/%{_datadir}/%{name} - - - -%files -%defattr(-,root,root,-) -%dir %{_datadir}/%{name} -%{_datadir}/%{name} diff --git a/tests/data/rpm/rpmbuild/SPECS/gbp-test-native2.spec b/tests/data/rpm/rpmbuild/SPECS/gbp-test-native2.spec deleted file mode 100644 index 34fd33dc..00000000 --- a/tests/data/rpm/rpmbuild/SPECS/gbp-test-native2.spec +++ /dev/null @@ -1,35 +0,0 @@ -Name: gbp-test-native2 -Summary: Test package for git-buildpackage -Version: 2.0 -Release: 0 -Group: Development/Libraries -License: GPLv2 -Source: foo.txt -BuildRequires: unzip - -%description -Package for testing the RPM functionality of git-buildpackage. -Mimics a "native" package that doesn't have any source tarball. - - -%prep -# Just create build dir -%setup -T -c -cp %{SOURCE0} . - - -%build -# Nothing to do - - -%install -rm -rf %{buildroot} -mkdir -p %{buildroot}/%{_datadir}/%{name} -cp -R * %{buildroot}/%{_datadir}/%{name} - - - -%files -%defattr(-,root,root,-) -%dir %{_datadir}/%{name} -%{_datadir}/%{name} diff --git a/tests/data/rpm/rpmbuild/SPECS/gbp-test.spec b/tests/data/rpm/rpmbuild/SPECS/gbp-test.spec deleted file mode 100644 index c46a734e..00000000 --- a/tests/data/rpm/rpmbuild/SPECS/gbp-test.spec +++ /dev/null @@ -1,42 +0,0 @@ -Name: gbp-test -Summary: Test package for git-buildpackage -Version: 1.0 -Release: 1 -Group: Development/Libraries -License: GPLv2 -Source: %{name}-%{version}.tar.bz2 -Source1: foo.txt -Source20: bar.tar.gz -# Gbp-Ignore-Patches: 0 -Patch0: my.patch -Patch10: my2.patch -Patch20: my3.patch - - -%description -Package for testing the RPM functionality of git-buildpackage. - - -%prep -%setup -n %{name} -a 20 - -%patch0 -%patch10 -p1 - - -%build -make - - -%install -rm -rf %{buildroot} -mkdir -p %{buildroot}/%{_datadir}/%{name} -cp -R * %{buildroot}/%{_datadir}/%{name} -install %{SOURCE0} %{buildroot}/%{_datadir}/%{name} - - - -%files -%defattr(-,root,root,-) -%dir %{_datadir}/%{name} -%{_datadir}/%{name} diff --git a/tests/data/rpm/rpmbuild/SPECS/gbp-test2.spec b/tests/data/rpm/rpmbuild/SPECS/gbp-test2.spec deleted file mode 100644 index 8a92725d..00000000 --- a/tests/data/rpm/rpmbuild/SPECS/gbp-test2.spec +++ /dev/null @@ -1,60 +0,0 @@ -Name: gbp-test2 -Summary: Test package 2 for git-buildpackage -Epoch: 2 -Version: 3.0 -Release: 0 -Group: Development/Libraries -License: GPLv2 -Source10: ftp://ftp.host.com/%{name}-%{version}.tar.gz -Source: foo.txt -Source20: bar.tar.gz -# Gbp-Ignore-Patches: -1 -Patch: my.patch -Patch10: my2.patch -Patch20: my3.patch -Packager: Markus Lehtonen -VCS: myoldvcstag - -%description -Package for testing the RPM functionality of git-buildpackage. - -%package empty -Summary: Empty subpackage - -%description empty -Empty subpackage for the %{name} test package. - - -%prep -%setup -T -n %{name}-%{version} -c -a 10 - -%patch -%patch -P 10 -p1 - -echo "Do things" - -# Gbp-Patch-Macros - -%build -make - - -%install -rm -rf %{buildroot} -mkdir -p %{buildroot}/%{_datadir}/%{name} -cp -R * %{buildroot}/%{_datadir}/%{name} -install %{SOURCE0} %{buildroot}/%{_datadir}/%{name} - - -%changelog -* Tue Feb 04 2014 Name 1 -- My change - - -%files -%defattr(-,root,root,-) -%dir %{_datadir}/%{name} -%{_datadir}/%{name} - -%files empty -%defattr(-,root,root,-) diff --git a/tests/data/rpm/specs/gbp-test-native.spec b/tests/data/rpm/specs/gbp-test-native.spec deleted file mode 120000 index 60de36f2..00000000 --- a/tests/data/rpm/specs/gbp-test-native.spec +++ /dev/null @@ -1 +0,0 @@ -../rpmbuild/SPECS/gbp-test-native.spec \ No newline at end of file diff --git a/tests/data/rpm/specs/gbp-test-native2.spec b/tests/data/rpm/specs/gbp-test-native2.spec deleted file mode 120000 index ad13ad6a..00000000 --- a/tests/data/rpm/specs/gbp-test-native2.spec +++ /dev/null @@ -1 +0,0 @@ -../rpmbuild/SPECS/gbp-test-native2.spec \ No newline at end of file diff --git a/tests/data/rpm/specs/gbp-test-quirks.spec b/tests/data/rpm/specs/gbp-test-quirks.spec deleted file mode 100644 index bb56b008..00000000 --- a/tests/data/rpm/specs/gbp-test-quirks.spec +++ /dev/null @@ -1,30 +0,0 @@ -# -# Spec for testing some quirks of spec parsing -# - -Name: pkg_name -Summary: Spec for testing some quirks of spec parsing -Version: 0.1 -Release: 1.2 -License: GPLv2 -Source1: foobar.tar.gz -# Gbp-Ignore-Patches: 2 4 888 -Patch1: 01.patch -Patch2: 02.patch -Patch3: 03.patch -Patch4: 04.patch -Patch5: 05.patch - -%description -Spec for testing some quirks of spec parsing. No intended for building an RPM. - -%prep -# We don't have Source0 so rpmbuild would fail, but gbp shouldn't crash -%setup -q - -# Patches are applied out-of-order wrt. numbering -%patch5 -%patch2 -%patch1 -# Patch 999 does not exist, rpmbuild would fail but GBP should not -%patch999 diff --git a/tests/data/rpm/specs/gbp-test-reference.spec b/tests/data/rpm/specs/gbp-test-reference.spec deleted file mode 100644 index 050d1398..00000000 --- a/tests/data/rpm/specs/gbp-test-reference.spec +++ /dev/null @@ -1,43 +0,0 @@ -Name: gbp-test -Summary: Test package for git-buildpackage -Version: 1.0 -Release: 1 -Group: Development/Libraries -License: GPLv2 -Source: %{name}-%{version}.tar.bz2 -Source1: foo.txt -Source20: bar.tar.gz -# Gbp-Ignore-Patches: 0 -Patch0: my.patch -# Patches auto-generated by git-buildpackage: -Patch1: new.patch - - -%description -Package for testing the RPM functionality of git-buildpackage. - - -%prep -%setup -n %{name} -a 20 - -%patch0 -# new.patch -%patch1 -p1 - - -%build -make - - -%install -rm -rf %{buildroot} -mkdir -p %{buildroot}/%{_datadir}/%{name} -cp -R * %{buildroot}/%{_datadir}/%{name} -install %{SOURCE0} %{buildroot}/%{_datadir}/%{name} - - - -%files -%defattr(-,root,root,-) -%dir %{_datadir}/%{name} -%{_datadir}/%{name} diff --git a/tests/data/rpm/specs/gbp-test-reference2.spec b/tests/data/rpm/specs/gbp-test-reference2.spec deleted file mode 100644 index 0fbe0260..00000000 --- a/tests/data/rpm/specs/gbp-test-reference2.spec +++ /dev/null @@ -1,47 +0,0 @@ -Name: gbp-test -VCS: myvcstag -Summary: Test package for git-buildpackage -Version: 1.0 -Release: 1 -Group: Development/Libraries -License: GPLv2 -Source: %{name}-%{version}.tar.bz2 -Source1: foo.txt -Source20: bar.tar.gz -# Gbp-Ignore-Patches: 0 -Patch0: my.patch -# Patches auto-generated by git-buildpackage: -Patch1: new.patch - - -%description -Package for testing the RPM functionality of git-buildpackage. - - -%prep -%setup -n %{name} -a 20 - -%patch0 -# new.patch -%patch1 -p1 - - -%build -make - - -%install -rm -rf %{buildroot} -mkdir -p %{buildroot}/%{_datadir}/%{name} -cp -R * %{buildroot}/%{_datadir}/%{name} -install %{SOURCE0} %{buildroot}/%{_datadir}/%{name} - - - -%files -%defattr(-,root,root,-) -%dir %{_datadir}/%{name} -%{_datadir}/%{name} -%changelog -* Wed Feb 05 2014 Name 1 -- New entry diff --git a/tests/data/rpm/specs/gbp-test-tags.spec b/tests/data/rpm/specs/gbp-test-tags.spec deleted file mode 100644 index ee4c2b94..00000000 --- a/tests/data/rpm/specs/gbp-test-tags.spec +++ /dev/null @@ -1,74 +0,0 @@ -# -# Spec file for testing all RPM tags (that we know of -# - -%define suse_release %(test -e /etc/SuSE-release && head -n1 /etc/SuSE-release | cut -d ' ' -f2 | cut --output-delimiter=0 -d. -f1,2 || echo 0) -%if "%{suse_release}" >= "1201" -%define test_weak_dep_tags 1 -%endif - -%define test_arch_os_tags %(test -n "$GBP_SKIP_ARCH_OS_TAGS" && echo 0 || echo 1) - -%define source_fn_base source -%define patch_fn_base patch - -# Gbp-Undefined-Tag: foobar - -# Test that we accept different cases -NAME: my_name -version: 0 -ReLeasE: 0 - -# Rest of the tags -Epoch: 0 -Summary: my_summary -License: my_license -Distribution: my_distribution -Vendor: my_vendor -Group: my_group -Packager: my_packager -Url: my_url -Vcs: my_vcs -Source: my_source -Patch: my_%patch_fn_base -Patch0: my_%{patch_fn_base}0 -Nosource: 0 -Nopatch: 0 -#Icon: my_icon -BuildRoot: my_buildroot -Provides: my_provides -Requires: my_requires -Conflicts: my_conflicts -Obsoletes: my_obsoletes -BuildConflicts: my_buildconflicts -BuildRequires: my_buildrequires -AutoReqProv: No -AutoReq: No -AutoProv: No -DistTag: my_disttag -BugUrl: my_bugurl -Collections: my_collections - -%if 0%{?test_weak_dep_tags} -Recommends: my_recommends -Suggests: my_suggests -Supplements: my_supplements -Enhances: my_enhances -BuildRecommends:my_buildrecommends -BuildSuggests: my_buildsuggests -BuildSupplements:my_buildsupplements -BuildEnhances: my_buildenhances -%endif - -# These should be filtered out by GBP -%if "%{test_arch_os_tags}" != "0" -BuildArch: my_buildarch -ExcludeArch: my_excludearch -ExclusiveArch: my_exclusivearch -ExcludeOs: my_excludeos -ExclusiveOs: my_exclusiveos -%endif - -%description -Package for testing GBP. - diff --git a/tests/data/rpm/specs/gbp-test-updates-reference.spec b/tests/data/rpm/specs/gbp-test-updates-reference.spec deleted file mode 100644 index ff56f589..00000000 --- a/tests/data/rpm/specs/gbp-test-updates-reference.spec +++ /dev/null @@ -1,44 +0,0 @@ -# -# Spec file for testing deleting/adding/updating tags and macros -# - -# Gbp-Undefined-Tag: foobar - -# Test that we accept different cases -Name: my_name -Version: 0 -Release: 1 -Summary: my_summary -License: new license -Distribution: my_distribution -Group: my_group -Packager: my_packager -Url: my_url -Vcs: my_vcs -Nosource: 0 -Nopatch: 0 -BuildRoot: my_buildroot -Provides: my_provides -Requires: my_requires -Conflicts: my_conflicts -Obsoletes: my_obsoletes -BuildConflicts: my_buildconflicts -BuildRequires: my_buildrequires -AutoReqProv: No -AutoReq: No -AutoProv: No -DistTag: my_disttag -BugUrl: my_bugurl -Collections: my_collections - -%description -Package for testing GBP. - -%prep -%setup -n my_prefix - -%patch0 my new args - -%build - -%install diff --git a/tests/data/rpm/specs/gbp-test-updates.spec b/tests/data/rpm/specs/gbp-test-updates.spec deleted file mode 100644 index dc8ffbf9..00000000 --- a/tests/data/rpm/specs/gbp-test-updates.spec +++ /dev/null @@ -1,49 +0,0 @@ -# -# Spec file for testing deleting/adding/updating tags and macros -# - -# Gbp-Undefined-Tag: foobar - -# Test that we accept different cases -Name: my_name -Version: 0 -Release: 1 -Summary: my_summary -License: my_license -Distribution: my_distribution -Vendor: my_vendor -Group: my_group -Packager: my_packager -Url: my_url -Vcs: my_vcs -Source: my_source -Patch: my_%patch_fn_base -Patch0: my_%{patch_fn_base}0 -Nosource: 0 -Nopatch: 0 -BuildRoot: my_buildroot -Provides: my_provides -Requires: my_requires -Conflicts: my_conflicts -Obsoletes: my_obsoletes -BuildConflicts: my_buildconflicts -BuildRequires: my_buildrequires -AutoReqProv: No -AutoReq: No -AutoProv: No -DistTag: my_disttag -BugUrl: my_bugurl -Collections: my_collections - -%description -Package for testing GBP. - -%prep -%setup -n my_prefix - -%patch -b my_patch -%patch -P0 -b my_patch0 - -%build - -%install diff --git a/tests/data/rpm/specs/gbp-test.spec b/tests/data/rpm/specs/gbp-test.spec deleted file mode 120000 index 30ae2845..00000000 --- a/tests/data/rpm/specs/gbp-test.spec +++ /dev/null @@ -1 +0,0 @@ -../rpmbuild/SPECS/gbp-test.spec \ No newline at end of file diff --git a/tests/data/rpm/specs/gbp-test2-reference.spec b/tests/data/rpm/specs/gbp-test2-reference.spec deleted file mode 100644 index 1882131f..00000000 --- a/tests/data/rpm/specs/gbp-test2-reference.spec +++ /dev/null @@ -1,61 +0,0 @@ -Name: gbp-test2 -Summary: Test package 2 for git-buildpackage -Epoch: 2 -Version: 3.0 -Release: 0 -Group: Development/Libraries -License: GPLv2 -Source10: ftp://ftp.host.com/%{name}-%{version}.tar.gz -Source: foo.txt -Source20: bar.tar.gz -# Gbp-Ignore-Patches: -1 -Patch: my.patch -# Patches auto-generated by git-buildpackage: -Patch0: new.patch -Packager: Markus Lehtonen - -%description -Package for testing the RPM functionality of git-buildpackage. - -%package empty -Summary: Empty subpackage - -%description empty -Empty subpackage for the %{name} test package. - - -%prep -%setup -T -n %{name}-%{version} -c -a 10 - -%patch - -echo "Do things" - -# Gbp-Patch-Macros -# new.patch -%if 1 -%patch0 -p1 -%endif - -%build -make - - -%install -rm -rf %{buildroot} -mkdir -p %{buildroot}/%{_datadir}/%{name} -cp -R * %{buildroot}/%{_datadir}/%{name} -install %{SOURCE0} %{buildroot}/%{_datadir}/%{name} - - -%changelog -* Wed Feb 05 2014 Name 2 -- New entry - -%files -%defattr(-,root,root,-) -%dir %{_datadir}/%{name} -%{_datadir}/%{name} - -%files empty -%defattr(-,root,root,-) diff --git a/tests/data/rpm/specs/gbp-test2-reference2.spec b/tests/data/rpm/specs/gbp-test2-reference2.spec deleted file mode 100644 index d41f4503..00000000 --- a/tests/data/rpm/specs/gbp-test2-reference2.spec +++ /dev/null @@ -1,68 +0,0 @@ -Name: gbp-test2 -Summary: Test package 2 for git-buildpackage -Epoch: 2 -Version: 3.0 -Release: 0 -Group: Development/Libraries -License: GPLv2 -Source10: ftp://ftp.host.com/%{name}-%{version}.tar.gz -Source: foo.txt -Source20: bar.tar.gz -# Gbp-Ignore-Patches: -1 -Patch: my.patch -# Patches auto-generated by git-buildpackage: -Patch0: 1.patch -Patch1: 2.patch -Packager: Markus Lehtonen -VCS: myvcstag - -%description -Package for testing the RPM functionality of git-buildpackage. - -%package empty -Summary: Empty subpackage - -%description empty -Empty subpackage for the %{name} test package. - - -%prep -%setup -T -n %{name}-%{version} -c -a 10 - -%patch - -echo "Do things" - -# Gbp-Patch-Macros -# 1.patch -%if true -%patch0 -p1 -%endif -# 2.patch -%ifarch %ix86 -%patch1 -p1 -%endif - -%build -make - - -%install -rm -rf %{buildroot} -mkdir -p %{buildroot}/%{_datadir}/%{name} -cp -R * %{buildroot}/%{_datadir}/%{name} -install %{SOURCE0} %{buildroot}/%{_datadir}/%{name} - - -%changelog -* Tue Feb 04 2014 Name 1 -- My change - - -%files -%defattr(-,root,root,-) -%dir %{_datadir}/%{name} -%{_datadir}/%{name} - -%files empty -%defattr(-,root,root,-) diff --git a/tests/data/rpm/specs/gbp-test2.spec b/tests/data/rpm/specs/gbp-test2.spec deleted file mode 120000 index af4080cb..00000000 --- a/tests/data/rpm/specs/gbp-test2.spec +++ /dev/null @@ -1 +0,0 @@ -../rpmbuild/SPECS/gbp-test2.spec \ No newline at end of file diff --git a/tests/data/rpm/srpms/gbp-test-1.0-1.src.rpm b/tests/data/rpm/srpms/gbp-test-1.0-1.src.rpm deleted file mode 100644 index 74afbd6c..00000000 Binary files a/tests/data/rpm/srpms/gbp-test-1.0-1.src.rpm and /dev/null differ diff --git a/tests/data/rpm/srpms/gbp-test-native-1.0-1.src.rpm b/tests/data/rpm/srpms/gbp-test-native-1.0-1.src.rpm deleted file mode 100644 index 1002aaea..00000000 Binary files a/tests/data/rpm/srpms/gbp-test-native-1.0-1.src.rpm and /dev/null differ diff --git a/tests/data/rpm/srpms/gbp-test-native2-2.0-0.src.rpm b/tests/data/rpm/srpms/gbp-test-native2-2.0-0.src.rpm deleted file mode 100644 index 880b3100..00000000 Binary files a/tests/data/rpm/srpms/gbp-test-native2-2.0-0.src.rpm and /dev/null differ diff --git a/tests/data/rpm/srpms/gbp-test2-3.0-0.src.rpm b/tests/data/rpm/srpms/gbp-test2-3.0-0.src.rpm deleted file mode 100644 index 1cf12c7a..00000000 Binary files a/tests/data/rpm/srpms/gbp-test2-3.0-0.src.rpm and /dev/null differ diff --git a/tests/test_rpm.py b/tests/test_rpm.py new file mode 100644 index 00000000..97390465 --- /dev/null +++ b/tests/test_rpm.py @@ -0,0 +1,479 @@ +# vim: set fileencoding=utf-8 : +# +# (C) 2012 Intel Corporation +# This program is free software; you can redistribute it and/or modify +# it under the terms of the GNU General Public License as published by +# the Free Software Foundation; either version 2 of the License, or +# (at your option) any later version. +# +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with this program; if not, write to the Free Software +# Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA +"""Test the classes under L{gbp.rpm}""" + +import filecmp +import os +import shutil +import tempfile +from nose.tools import assert_raises, eq_ + +from gbp.errors import GbpError +from gbp.rpm import (SrcRpmFile, SpecFile, parse_srpm, NoSpecError, guess_spec, + guess_spec_repo, spec_from_repo) +from gbp.git.repository import GitRepository + +DATA_DIR = os.path.abspath(os.path.splitext(__file__)[0] + '_data') +SRPM_DIR = os.path.join(DATA_DIR, 'srpms') +SPEC_DIR = os.path.join(DATA_DIR, 'specs') + +class SpecFileTester(SpecFile): + """Helper class for testing""" + + def protected(self, name): + """Get a protected member""" + return super(SpecFileTester, self).__getattribute__(name) + + +class TestSrcRpmFile(object): + """Test L{gbp.rpm.SrcRpmFile}""" + + def setup(self): + self.tmpdir = tempfile.mkdtemp(prefix='gbp_%s_' % __name__, dir='.') + + def teardown(self): + shutil.rmtree(self.tmpdir) + + def test_srpm(self): + """Test parsing of a source rpm""" + srpm = SrcRpmFile(os.path.join(SRPM_DIR, 'gbp-test-1.0-1.src.rpm')) + assert srpm.version == {'release': '1', 'upstreamversion': '1.0'} + assert srpm.name == 'gbp-test' + assert srpm.upstreamversion == '1.0' + assert srpm.packager is None + + def test_srpm_2(self): + """Test parsing of another source rpm""" + srpm = SrcRpmFile(os.path.join(SRPM_DIR, 'gbp-test2-3.0-0.src.rpm')) + assert srpm.version == {'release': '0', 'upstreamversion': '3.0', + 'epoch': '2'} + assert srpm.packager == 'Markus Lehtonen '\ + '' + + def test_unpack_srpm(self): + """Test unpacking of a source rpm""" + srpm = SrcRpmFile(os.path.join(SRPM_DIR, 'gbp-test-1.0-1.src.rpm')) + srpm.unpack(self.tmpdir) + for fn in ['gbp-test-1.0.tar.bz2', 'foo.txt', 'bar.tar.gz', 'my.patch', + 'my2.patch', 'my3.patch']: + assert os.path.exists(os.path.join(self.tmpdir, fn)), \ + "%s not found" % fn + + +class TestSpecFile(object): + """Test L{gbp.rpm.SpecFile}""" + + def setup(self): + self.tmpdir = tempfile.mkdtemp(prefix='gbp_%s_' % __name__, dir='.') + + def teardown(self): + shutil.rmtree(self.tmpdir) + + def test_spec(self): + """Test parsing of a valid spec file""" + spec_filepath = os.path.join(SPEC_DIR, 'gbp-test.spec') + spec = SpecFileTester(spec_filepath) + + # Test basic properties + assert spec.specfile == os.path.basename(spec_filepath) + assert spec.specdir == os.path.dirname(spec_filepath) + assert spec.specpath == spec_filepath + + assert spec.name == 'gbp-test' + assert spec.packager is None + + assert spec.upstreamversion == '1.0' + assert spec.release == '1' + assert spec.epoch is None + assert spec.version == {'release': '1', 'upstreamversion': '1.0'} + + orig = spec.orig_src + assert orig['filename'] == 'gbp-test-1.0.tar.bz2' + assert orig['uri'] == 'gbp-test-1.0.tar.bz2' + assert orig['filename_base'] == 'gbp-test-1.0' + assert orig['archive_fmt'] == 'tar' + assert orig['compression'] == 'bzip2' + assert orig['prefix'] == 'gbp-test/' + + def test_spec_2(self): + """Test parsing of another valid spec file""" + spec_filepath = os.path.join(SPEC_DIR, 'gbp-test2.spec') + spec = SpecFile(spec_filepath) + + # Test basic properties + assert spec.name == 'gbp-test2' + assert spec.packager == 'Markus Lehtonen ' \ + '' + + assert spec.epoch == '2' + assert spec.version == {'release': '0', 'upstreamversion': '3.0', + 'epoch': '2'} + + orig = spec.orig_src + assert orig['filename'] == 'gbp-test2-3.0.tar.gz' + assert orig['uri'] == 'ftp://ftp.host.com/gbp-test2-3.0.tar.gz' + assert orig['archive_fmt'] == 'tar' + assert orig['compression'] == 'gzip' + assert orig['prefix'] == '' + + def test_spec_3(self): + """Test parsing of yet another valid spec file""" + spec_filepath = os.path.join(SPEC_DIR, 'gbp-test-native.spec') + spec = SpecFile(spec_filepath) + + # Test basic properties + assert spec.name == 'gbp-test-native' + orig = spec.orig_src + assert orig['filename'] == 'gbp-test-native-1.0.zip' + assert orig['archive_fmt'] == 'zip' + assert orig['compression'] == None + assert orig['prefix'] == 'gbp-test-native-1.0/' + + def test_spec_4(self): + """Test parsing of spec without orig tarball""" + spec_filepath = os.path.join(SPEC_DIR, 'gbp-test-native2.spec') + spec = SpecFile(spec_filepath) + + # Test basic properties + assert spec.name == 'gbp-test-native2' + assert spec.orig_src is None + + def test_parse_raw(self): + """Test parsing of a valid spec file""" + assert_raises(NoSpecError, SpecFile, None, None) + assert_raises(NoSpecError, SpecFile, 'filename', 'filedata') + + """ + with assert_raises(NoSpecError): + SpecFile(None, None) + with assert_raises(NoSpecError): + SpecFile('filename', 'filedata') + """ + + spec_filepath = os.path.join(SPEC_DIR, 'gbp-test.spec') + with open(spec_filepath, 'r') as spec_fd: + spec_data = spec_fd.read() + spec = SpecFile(filedata=spec_data) + + # Test basic properties + assert spec.specfile == None + assert spec.specdir == None + assert spec.name == 'gbp-test' + + def test_update_spec(self): + """Test spec autoupdate functionality""" + # Create temporary spec file + tmp_spec = os.path.join(self.tmpdir, 'gbp-test.spec') + shutil.copy2(os.path.join(SPEC_DIR, 'gbp-test.spec'), tmp_spec) + + reference_spec = os.path.join(SPEC_DIR, 'gbp-test-reference.spec') + spec = SpecFile(tmp_spec) + spec.update_patches(['new.patch'], {}) + spec.write_spec_file() + assert filecmp.cmp(tmp_spec, reference_spec) is True + + # Test adding the VCS tag and adding changelog + reference_spec = os.path.join(SPEC_DIR, 'gbp-test-reference2.spec') + spec.set_tag('VCS', None, 'myvcstag') + spec.set_changelog("* Wed Feb 05 2014 Name 1\n- New entry\n") + spec.write_spec_file() + assert filecmp.cmp(tmp_spec, reference_spec) is True + + def test_update_spec2(self): + """Another test for spec autoupdate functionality""" + tmp_spec = os.path.join(self.tmpdir, 'gbp-test2.spec') + shutil.copy2(os.path.join(SPEC_DIR, 'gbp-test2.spec'), tmp_spec) + + reference_spec = os.path.join(SPEC_DIR, 'gbp-test2-reference2.spec') + spec = SpecFile(tmp_spec) + spec.update_patches(['1.patch', '2.patch'], + {'1.patch': {'if': 'true'}, + '2.patch': {'ifarch': '%ix86'}}) + spec.set_tag('VCS', None, 'myvcstag') + spec.write_spec_file() + assert filecmp.cmp(tmp_spec, reference_spec) is True + + # Test updating patches again, removing the VCS tag and re-writing + # changelog + reference_spec = os.path.join(SPEC_DIR, 'gbp-test2-reference.spec') + spec.update_patches(['new.patch'], {'new.patch': {'if': '1'}}) + spec.set_tag('VCS', None, '') + spec.set_changelog("* Wed Feb 05 2014 Name 2\n- New entry\n\n") + spec.write_spec_file() + assert filecmp.cmp(tmp_spec, reference_spec) is True + + def test_modifying(self): + """Test updating/deleting of tags and macros""" + tmp_spec = os.path.join(self.tmpdir, 'gbp-test.spec') + shutil.copy2(os.path.join(SPEC_DIR, 'gbp-test-updates.spec'), tmp_spec) + reference_spec = os.path.join(SPEC_DIR, + 'gbp-test-updates-reference.spec') + spec = SpecFileTester(tmp_spec) + + # Mangle tags + prev = spec.protected('_delete_tag')('Vendor', None) + spec.protected('_set_tag')('License', None, 'new license', prev) + spec.protected('_delete_tag')('source', 0) + assert spec.sources() == {} + spec.protected('_delete_tag')('patch', 0) + spec.protected('_delete_tag')('patch', -1) + assert spec.protected('_patches')() == {} + prev = spec.protected('_delete_tag')('invalidtag', None) + + assert_raises(GbpError, spec.protected('_set_tag'), + 'Version', None, '', prev) + assert_raises(GbpError, spec.set_tag, + 'invalidtag', None, 'value') + + """ + with assert_raises(GbpError): + # Check that setting empty value fails + spec.protected('_set_tag')('Version', None, '', prev) + with assert_raises(GbpError): + # Check that setting invalid tag with public method fails + spec.set_tag('invalidtag', None, 'value') + """ + + # Mangle macros + prev = spec.protected('_delete_special_macro')('patch', -1) + spec.protected('_delete_special_macro')('patch', 123) + spec.protected('_set_special_macro')('patch', 0, 'my new args', prev) + assert_raises(GbpError, spec.protected('_delete_special_macro'), + 'invalidmacro', 0) + assert_raises(GbpError, spec.protected('_set_special_macro'), + 'invalidmacro', 0, 'args', prev) + + """ + with assert_raises(GbpError): + spec.protected('_delete_special_macro')('invalidmacro', 0) + with assert_raises(GbpError): + spec.protected('_set_special_macro')('invalidmacro', 0, 'args', + prev) + """ + + # Check resulting spec file + spec.write_spec_file() + assert filecmp.cmp(tmp_spec, reference_spec) is True + + def test_modifying_err(self): + """Test error conditions of modification methods""" + spec_filepath = os.path.join(SPEC_DIR, 'gbp-test2.spec') + spec = SpecFileTester(spec_filepath) + + # Unknown/invalid section name + assert_raises(GbpError, spec.protected('_set_section'), + 'patch', 'new content\n') + """ + with assert_raises(GbpError): + spec.protected('_set_section')('patch', 'new content\n') + """ + + # Multiple sections with the same name + assert_raises(GbpError, spec.protected('_set_section'), + 'files', '%{_sysconfdir}/foo\n') + + """ + with assert_raises(GbpError): + spec.protected('_set_section')('files', '%{_sysconfdir}/foo\n') + """ + + def test_changelog(self): + """Test changelog methods""" + spec_filepath = os.path.join(SPEC_DIR, 'gbp-test2.spec') + spec = SpecFile(spec_filepath) + + # Read changelog + eq_(spec.get_changelog(), + "* Tue Feb 04 2014 Name 1\n- My change\n\n\n") + + # Set changelog and check again + new_text = "* Wed Feb 05 2014 Name 2\n- New entry\n\n\n" + spec.set_changelog(new_text) + eq_(spec.get_changelog(), new_text) + + def test_quirks(self): + """Test spec that is broken/has anomalities""" + spec_filepath = os.path.join(SPEC_DIR, 'gbp-test-quirks.spec') + spec = SpecFile(spec_filepath) + + # Check that we quess orig source and prefix correctly + assert spec.orig_src['prefix'] == 'foobar/' + + def test_tags(self): + """Test parsing of all the different tags of spec file""" + spec_filepath = os.path.join(SPEC_DIR, 'gbp-test-tags.spec') + spec = SpecFileTester(spec_filepath) + + # Check all the tags + for name, val in spec.protected('_tags').iteritems(): + rval = None + if name in ('version', 'release', 'epoch'): + rval = '0' + elif name in ('autoreq', 'autoprov', 'autoreqprov'): + rval = 'No' + elif name not in spec.protected('_listtags'): + rval = 'my_%s' % name + if rval: + assert val['value'] == rval, ("'%s:' is '%s', expecting '%s'" % + (name, val['value'], rval)) + assert spec.ignorepatches == [] + # Check patch numbers and patch filenames + patches = {} + for patch in spec.protected('_tags')['patch']['lines']: + patches[patch['num']] = patch['linevalue'] + + assert patches == {0: 'my_patch0', -1: 'my_patch'} + + def test_patch_series(self): + """Test the getting the patches as a patchseries""" + spec_filepath = os.path.join(SPEC_DIR, 'gbp-test-native.spec') + spec = SpecFileTester(spec_filepath) + + assert len(spec.patchseries()) == 0 + spec.update_patches(['1.patch', '2.patch', '3.patch'], {}) + assert len(spec.patchseries()) == 3 + spec.protected('_gbp_tags')['ignore-patches'].append({'args': "0"}) + spec.update_patches(['4.patch'], {}) + assert len(spec.patchseries()) == 1 + assert len(spec.patchseries(ignored=True)) == 2 + spec.protected('_delete_special_macro')('patch', 0) + assert len(spec.patchseries(ignored=True)) == 1 + series = spec.patchseries(unapplied=True, ignored=True) + assert len(series) == 2 + assert os.path.basename(series[-1].path) == '1.patch' + + def test_patch_series_quirks(self): + """Patches are applied in order different from the patch numbering""" + spec_filepath = os.path.join(SPEC_DIR, 'gbp-test-quirks.spec') + spec = SpecFileTester(spec_filepath) + + # Check series is returned in the order the patches are applied + files = [os.path.basename(patch.path) for patch in spec.patchseries()] + assert files == ['05.patch', '01.patch'] + # Also ignored patches are returned in the correct order + files = [os.path.basename(patch.path) for patch in + spec.patchseries(ignored=True)] + assert files == ['05.patch', '02.patch', '01.patch'] + # Unapplied patches are added to the end of the series + files = [os.path.basename(patch.path) for patch in + spec.patchseries(unapplied=True)] + assert files == ['05.patch', '01.patch', '03.patch'] + # Return all patches (for which tag is found) + files = [os.path.basename(patch.path) for patch in + spec.patchseries(unapplied=True, ignored=True)] + assert files == ['05.patch', '02.patch', '01.patch', '03.patch', + '04.patch'] + + +class TestUtilityFunctions(object): + """Test utility functions of L{gbp.rpm}""" + def setup(self): + self.tmpdir = tempfile.mkdtemp(prefix='gbp_%s_' % __name__, dir='.') + + def teardown(self): + shutil.rmtree(self.tmpdir) + + def test_parse_srpm(self): + """Test parse_srpm() function""" + parse_srpm(os.path.join(SRPM_DIR, 'gbp-test-1.0-1.src.rpm')) + assert_raises(GbpError, parse_srpm, + os.path.join(DATA_DIR, 'notexists.src.rpm')) + + """ + with assert_raises(GbpError): + parse_srpm(os.path.join(DATA_DIR, 'notexists.src.rpm')) + with assert_raises(GbpError): + parse_srpm(os.path.join(SPEC_DIR, 'gbp-test.spec')) + """ + + def test_guess_spec(self): + """Test guess_spec() function""" + # Spec not found + assert_raises(NoSpecError, guess_spec, + DATA_DIR, recursive=False) + + """ + with assert_raises(NoSpecError): + guess_spec(DATA_DIR, recursive=False) + """ + + # Multiple spec files + assert_raises(NoSpecError, guess_spec, + DATA_DIR, recursive=True) + assert_raises(NoSpecError, guess_spec, + SPEC_DIR, recursive=False) + + """ + with assert_raises(NoSpecError): + guess_spec(DATA_DIR, recursive=True) + with assert_raises(NoSpecError): + guess_spec(SPEC_DIR, recursive=False) + """ + + # Spec found + spec = guess_spec(SPEC_DIR, recursive=False, + preferred_name = 'gbp-test2.spec') + assert spec.specfile == 'gbp-test2.spec' + assert spec.specdir == SPEC_DIR + + def test_guess_spec_repo(self): + """Test guess_spec_repo() and spec_from_repo() functions""" + # Create dummy repository with some commits + repo = GitRepository.create(self.tmpdir) + with open(os.path.join(repo.path, 'foo.txt'), 'w') as fobj: + fobj.write('bar\n') + repo.add_files('foo.txt') + repo.commit_all('Add dummy file') + os.mkdir(os.path.join(repo.path, 'packaging')) + shutil.copy(os.path.join(SPEC_DIR, 'gbp-test.spec'), + os.path.join(repo.path, 'packaging')) + repo.add_files('packaging/gbp-test.spec') + repo.commit_all('Add spec file') + + # Spec not found + assert_raises(NoSpecError, guess_spec_repo, + repo, 'HEAD~1', recursive=True) + assert_raises(NoSpecError, guess_spec_repo, + repo, 'HEAD', recursive=False) + + """ + with assert_raises(NoSpecError): + guess_spec_repo(repo, 'HEAD~1', recursive=True) + with assert_raises(NoSpecError): + guess_spec_repo(repo, 'HEAD', recursive=False) + """ + + # Spec found + spec = guess_spec_repo(repo, 'HEAD', 'packaging', recursive=False) + spec = guess_spec_repo(repo, 'HEAD', recursive=True) + assert spec.specfile == 'gbp-test.spec' + assert spec.specdir == 'packaging' + assert spec.specpath == 'packaging/gbp-test.spec' + + # Test spec_from_repo() + assert_raises(NoSpecError, spec_from_repo, + repo, 'HEAD~1', 'packaging/gbp-test.spec') + + """ + with assert_raises(NoSpecError): + spec_from_repo(repo, 'HEAD~1', 'packaging/gbp-test.spec') + """ + + spec = spec_from_repo(repo, 'HEAD', 'packaging/gbp-test.spec') + assert spec.specfile == 'gbp-test.spec' + +# vim:et:ts=4:sw=4:et:sts=4:ai:set list listchars=tab\:»·,trail\:·: diff --git a/tests/test_rpm_data/rpmbuild/SOURCES/bar.tar.gz b/tests/test_rpm_data/rpmbuild/SOURCES/bar.tar.gz new file mode 100644 index 00000000..f5dae803 Binary files /dev/null and b/tests/test_rpm_data/rpmbuild/SOURCES/bar.tar.gz differ diff --git a/tests/test_rpm_data/rpmbuild/SOURCES/foo.txt b/tests/test_rpm_data/rpmbuild/SOURCES/foo.txt new file mode 100644 index 00000000..25ed442f --- /dev/null +++ b/tests/test_rpm_data/rpmbuild/SOURCES/foo.txt @@ -0,0 +1,3 @@ +FOO: + +file for testing rpm support of git-buildpackage. diff --git a/tests/test_rpm_data/rpmbuild/SOURCES/gbp-test-1.0.tar.bz2 b/tests/test_rpm_data/rpmbuild/SOURCES/gbp-test-1.0.tar.bz2 new file mode 100644 index 00000000..7d0759fe Binary files /dev/null and b/tests/test_rpm_data/rpmbuild/SOURCES/gbp-test-1.0.tar.bz2 differ diff --git a/tests/test_rpm_data/rpmbuild/SOURCES/gbp-test-native-1.0.zip b/tests/test_rpm_data/rpmbuild/SOURCES/gbp-test-native-1.0.zip new file mode 100644 index 00000000..22a273d1 Binary files /dev/null and b/tests/test_rpm_data/rpmbuild/SOURCES/gbp-test-native-1.0.zip differ diff --git a/tests/test_rpm_data/rpmbuild/SOURCES/gbp-test2-3.0.tar.gz b/tests/test_rpm_data/rpmbuild/SOURCES/gbp-test2-3.0.tar.gz new file mode 100644 index 00000000..7b3eaf3c Binary files /dev/null and b/tests/test_rpm_data/rpmbuild/SOURCES/gbp-test2-3.0.tar.gz differ diff --git a/tests/test_rpm_data/rpmbuild/SOURCES/my.patch b/tests/test_rpm_data/rpmbuild/SOURCES/my.patch new file mode 100644 index 00000000..50870df2 --- /dev/null +++ b/tests/test_rpm_data/rpmbuild/SOURCES/my.patch @@ -0,0 +1,9 @@ +diff --git a/dummy.sh b/dummy.sh +index 8c33db6..6f04268 100755 +--- dummy.sh ++++ dummy.sh +@@ -1,3 +1,3 @@ + #!/bin/sh + +-echo "Hello world" ++echo "Hello GBP" diff --git a/tests/test_rpm_data/rpmbuild/SOURCES/my2.patch b/tests/test_rpm_data/rpmbuild/SOURCES/my2.patch new file mode 100644 index 00000000..ad5ca2d2 --- /dev/null +++ b/tests/test_rpm_data/rpmbuild/SOURCES/my2.patch @@ -0,0 +1,7 @@ +diff --git a/mydir/myfile.txt b/mydir/myfile.txt +new file mode 100644 +index 0000000..2cdad29 +--- /dev/null ++++ b/mydir/myfile.txt +@@ -0,0 +1 @@ ++Dummy diff --git a/tests/test_rpm_data/rpmbuild/SOURCES/my3.patch b/tests/test_rpm_data/rpmbuild/SOURCES/my3.patch new file mode 100644 index 00000000..9fee859d --- /dev/null +++ b/tests/test_rpm_data/rpmbuild/SOURCES/my3.patch @@ -0,0 +1,7 @@ +diff --git a/README b/README +index a1311cb..a59f1b9 100644 +--- a/README ++++ b/README +@@ -1 +1 @@ +-Just for testing git-buildpackage. ++Just for testing GBP. diff --git a/tests/test_rpm_data/rpmbuild/SPECS/gbp-test-native.spec b/tests/test_rpm_data/rpmbuild/SPECS/gbp-test-native.spec new file mode 100644 index 00000000..38b07e48 --- /dev/null +++ b/tests/test_rpm_data/rpmbuild/SPECS/gbp-test-native.spec @@ -0,0 +1,34 @@ +Name: gbp-test-native +Summary: Test package for git-buildpackage +Version: 1.0 +Release: 1 +Group: Development/Libraries +License: GPLv2 +Source1: %{name}-%{version}.zip +BuildRequires: unzip + +%description +Package for testing the RPM functionality of git-buildpackage. +Mimics a "native" package + + +%prep +unzip %{SOURCE1} +%setup -T -D + + +%build +make + + +%install +rm -rf %{buildroot} +mkdir -p %{buildroot}/%{_datadir}/%{name} +cp -R * %{buildroot}/%{_datadir}/%{name} + + + +%files +%defattr(-,root,root,-) +%dir %{_datadir}/%{name} +%{_datadir}/%{name} diff --git a/tests/test_rpm_data/rpmbuild/SPECS/gbp-test-native2.spec b/tests/test_rpm_data/rpmbuild/SPECS/gbp-test-native2.spec new file mode 100644 index 00000000..34fd33dc --- /dev/null +++ b/tests/test_rpm_data/rpmbuild/SPECS/gbp-test-native2.spec @@ -0,0 +1,35 @@ +Name: gbp-test-native2 +Summary: Test package for git-buildpackage +Version: 2.0 +Release: 0 +Group: Development/Libraries +License: GPLv2 +Source: foo.txt +BuildRequires: unzip + +%description +Package for testing the RPM functionality of git-buildpackage. +Mimics a "native" package that doesn't have any source tarball. + + +%prep +# Just create build dir +%setup -T -c +cp %{SOURCE0} . + + +%build +# Nothing to do + + +%install +rm -rf %{buildroot} +mkdir -p %{buildroot}/%{_datadir}/%{name} +cp -R * %{buildroot}/%{_datadir}/%{name} + + + +%files +%defattr(-,root,root,-) +%dir %{_datadir}/%{name} +%{_datadir}/%{name} diff --git a/tests/test_rpm_data/rpmbuild/SPECS/gbp-test.spec b/tests/test_rpm_data/rpmbuild/SPECS/gbp-test.spec new file mode 100644 index 00000000..c46a734e --- /dev/null +++ b/tests/test_rpm_data/rpmbuild/SPECS/gbp-test.spec @@ -0,0 +1,42 @@ +Name: gbp-test +Summary: Test package for git-buildpackage +Version: 1.0 +Release: 1 +Group: Development/Libraries +License: GPLv2 +Source: %{name}-%{version}.tar.bz2 +Source1: foo.txt +Source20: bar.tar.gz +# Gbp-Ignore-Patches: 0 +Patch0: my.patch +Patch10: my2.patch +Patch20: my3.patch + + +%description +Package for testing the RPM functionality of git-buildpackage. + + +%prep +%setup -n %{name} -a 20 + +%patch0 +%patch10 -p1 + + +%build +make + + +%install +rm -rf %{buildroot} +mkdir -p %{buildroot}/%{_datadir}/%{name} +cp -R * %{buildroot}/%{_datadir}/%{name} +install %{SOURCE0} %{buildroot}/%{_datadir}/%{name} + + + +%files +%defattr(-,root,root,-) +%dir %{_datadir}/%{name} +%{_datadir}/%{name} diff --git a/tests/test_rpm_data/rpmbuild/SPECS/gbp-test2.spec b/tests/test_rpm_data/rpmbuild/SPECS/gbp-test2.spec new file mode 100644 index 00000000..8a92725d --- /dev/null +++ b/tests/test_rpm_data/rpmbuild/SPECS/gbp-test2.spec @@ -0,0 +1,60 @@ +Name: gbp-test2 +Summary: Test package 2 for git-buildpackage +Epoch: 2 +Version: 3.0 +Release: 0 +Group: Development/Libraries +License: GPLv2 +Source10: ftp://ftp.host.com/%{name}-%{version}.tar.gz +Source: foo.txt +Source20: bar.tar.gz +# Gbp-Ignore-Patches: -1 +Patch: my.patch +Patch10: my2.patch +Patch20: my3.patch +Packager: Markus Lehtonen +VCS: myoldvcstag + +%description +Package for testing the RPM functionality of git-buildpackage. + +%package empty +Summary: Empty subpackage + +%description empty +Empty subpackage for the %{name} test package. + + +%prep +%setup -T -n %{name}-%{version} -c -a 10 + +%patch +%patch -P 10 -p1 + +echo "Do things" + +# Gbp-Patch-Macros + +%build +make + + +%install +rm -rf %{buildroot} +mkdir -p %{buildroot}/%{_datadir}/%{name} +cp -R * %{buildroot}/%{_datadir}/%{name} +install %{SOURCE0} %{buildroot}/%{_datadir}/%{name} + + +%changelog +* Tue Feb 04 2014 Name 1 +- My change + + +%files +%defattr(-,root,root,-) +%dir %{_datadir}/%{name} +%{_datadir}/%{name} + +%files empty +%defattr(-,root,root,-) diff --git a/tests/test_rpm_data/rpmbuild/SPECS/gbp-test2.spec.orig b/tests/test_rpm_data/rpmbuild/SPECS/gbp-test2.spec.orig new file mode 100644 index 00000000..ffae7e99 --- /dev/null +++ b/tests/test_rpm_data/rpmbuild/SPECS/gbp-test2.spec.orig @@ -0,0 +1,46 @@ +Name: gbp-test2 +Summary: Test package 2 for git-buildpackage +Epoch: 2 +Version: 3.0 +Release: 0 +Group: Development/Libraries +License: GPLv2 +Source10: ftp://ftp.host.com/%{name}-%{version}.tar.gz +Source: foo.txt +Source20: bar.tar.gz +# Gbp-Ignore-Patches: 0 +Patch: my.patch +Patch10: my2.patch +Patch20: my3.patch +Packager: Markus Lehtonen + +%description +Package for testing the RPM functionality of git-buildpackage. + + +%prep +%setup -T -n %{name}-%{version} -c -a 10 + +%patch +%patch -P 10 -p1 + +echo "Do things" + +# Gbp-Patch-Macros + +%build +make + + +%install +rm -rf %{buildroot} +mkdir -p %{buildroot}/%{_datadir}/%{name} +cp -R * %{buildroot}/%{_datadir}/%{name} +install %{SOURCE0} %{buildroot}/%{_datadir}/%{name} + + + +%files +%defattr(-,root,root,-) +%dir %{_datadir}/%{name} +%{_datadir}/%{name} diff --git a/tests/test_rpm_data/specs/gbp-test-native.spec b/tests/test_rpm_data/specs/gbp-test-native.spec new file mode 120000 index 00000000..60de36f2 --- /dev/null +++ b/tests/test_rpm_data/specs/gbp-test-native.spec @@ -0,0 +1 @@ +../rpmbuild/SPECS/gbp-test-native.spec \ No newline at end of file diff --git a/tests/test_rpm_data/specs/gbp-test-native2.spec b/tests/test_rpm_data/specs/gbp-test-native2.spec new file mode 120000 index 00000000..ad13ad6a --- /dev/null +++ b/tests/test_rpm_data/specs/gbp-test-native2.spec @@ -0,0 +1 @@ +../rpmbuild/SPECS/gbp-test-native2.spec \ No newline at end of file diff --git a/tests/test_rpm_data/specs/gbp-test-quirks.spec b/tests/test_rpm_data/specs/gbp-test-quirks.spec new file mode 100644 index 00000000..bb56b008 --- /dev/null +++ b/tests/test_rpm_data/specs/gbp-test-quirks.spec @@ -0,0 +1,30 @@ +# +# Spec for testing some quirks of spec parsing +# + +Name: pkg_name +Summary: Spec for testing some quirks of spec parsing +Version: 0.1 +Release: 1.2 +License: GPLv2 +Source1: foobar.tar.gz +# Gbp-Ignore-Patches: 2 4 888 +Patch1: 01.patch +Patch2: 02.patch +Patch3: 03.patch +Patch4: 04.patch +Patch5: 05.patch + +%description +Spec for testing some quirks of spec parsing. No intended for building an RPM. + +%prep +# We don't have Source0 so rpmbuild would fail, but gbp shouldn't crash +%setup -q + +# Patches are applied out-of-order wrt. numbering +%patch5 +%patch2 +%patch1 +# Patch 999 does not exist, rpmbuild would fail but GBP should not +%patch999 diff --git a/tests/test_rpm_data/specs/gbp-test-reference.spec b/tests/test_rpm_data/specs/gbp-test-reference.spec new file mode 100644 index 00000000..050d1398 --- /dev/null +++ b/tests/test_rpm_data/specs/gbp-test-reference.spec @@ -0,0 +1,43 @@ +Name: gbp-test +Summary: Test package for git-buildpackage +Version: 1.0 +Release: 1 +Group: Development/Libraries +License: GPLv2 +Source: %{name}-%{version}.tar.bz2 +Source1: foo.txt +Source20: bar.tar.gz +# Gbp-Ignore-Patches: 0 +Patch0: my.patch +# Patches auto-generated by git-buildpackage: +Patch1: new.patch + + +%description +Package for testing the RPM functionality of git-buildpackage. + + +%prep +%setup -n %{name} -a 20 + +%patch0 +# new.patch +%patch1 -p1 + + +%build +make + + +%install +rm -rf %{buildroot} +mkdir -p %{buildroot}/%{_datadir}/%{name} +cp -R * %{buildroot}/%{_datadir}/%{name} +install %{SOURCE0} %{buildroot}/%{_datadir}/%{name} + + + +%files +%defattr(-,root,root,-) +%dir %{_datadir}/%{name} +%{_datadir}/%{name} diff --git a/tests/test_rpm_data/specs/gbp-test-reference2.spec b/tests/test_rpm_data/specs/gbp-test-reference2.spec new file mode 100644 index 00000000..0fbe0260 --- /dev/null +++ b/tests/test_rpm_data/specs/gbp-test-reference2.spec @@ -0,0 +1,47 @@ +Name: gbp-test +VCS: myvcstag +Summary: Test package for git-buildpackage +Version: 1.0 +Release: 1 +Group: Development/Libraries +License: GPLv2 +Source: %{name}-%{version}.tar.bz2 +Source1: foo.txt +Source20: bar.tar.gz +# Gbp-Ignore-Patches: 0 +Patch0: my.patch +# Patches auto-generated by git-buildpackage: +Patch1: new.patch + + +%description +Package for testing the RPM functionality of git-buildpackage. + + +%prep +%setup -n %{name} -a 20 + +%patch0 +# new.patch +%patch1 -p1 + + +%build +make + + +%install +rm -rf %{buildroot} +mkdir -p %{buildroot}/%{_datadir}/%{name} +cp -R * %{buildroot}/%{_datadir}/%{name} +install %{SOURCE0} %{buildroot}/%{_datadir}/%{name} + + + +%files +%defattr(-,root,root,-) +%dir %{_datadir}/%{name} +%{_datadir}/%{name} +%changelog +* Wed Feb 05 2014 Name 1 +- New entry diff --git a/tests/test_rpm_data/specs/gbp-test-tags.spec b/tests/test_rpm_data/specs/gbp-test-tags.spec new file mode 100644 index 00000000..ee4c2b94 --- /dev/null +++ b/tests/test_rpm_data/specs/gbp-test-tags.spec @@ -0,0 +1,74 @@ +# +# Spec file for testing all RPM tags (that we know of +# + +%define suse_release %(test -e /etc/SuSE-release && head -n1 /etc/SuSE-release | cut -d ' ' -f2 | cut --output-delimiter=0 -d. -f1,2 || echo 0) +%if "%{suse_release}" >= "1201" +%define test_weak_dep_tags 1 +%endif + +%define test_arch_os_tags %(test -n "$GBP_SKIP_ARCH_OS_TAGS" && echo 0 || echo 1) + +%define source_fn_base source +%define patch_fn_base patch + +# Gbp-Undefined-Tag: foobar + +# Test that we accept different cases +NAME: my_name +version: 0 +ReLeasE: 0 + +# Rest of the tags +Epoch: 0 +Summary: my_summary +License: my_license +Distribution: my_distribution +Vendor: my_vendor +Group: my_group +Packager: my_packager +Url: my_url +Vcs: my_vcs +Source: my_source +Patch: my_%patch_fn_base +Patch0: my_%{patch_fn_base}0 +Nosource: 0 +Nopatch: 0 +#Icon: my_icon +BuildRoot: my_buildroot +Provides: my_provides +Requires: my_requires +Conflicts: my_conflicts +Obsoletes: my_obsoletes +BuildConflicts: my_buildconflicts +BuildRequires: my_buildrequires +AutoReqProv: No +AutoReq: No +AutoProv: No +DistTag: my_disttag +BugUrl: my_bugurl +Collections: my_collections + +%if 0%{?test_weak_dep_tags} +Recommends: my_recommends +Suggests: my_suggests +Supplements: my_supplements +Enhances: my_enhances +BuildRecommends:my_buildrecommends +BuildSuggests: my_buildsuggests +BuildSupplements:my_buildsupplements +BuildEnhances: my_buildenhances +%endif + +# These should be filtered out by GBP +%if "%{test_arch_os_tags}" != "0" +BuildArch: my_buildarch +ExcludeArch: my_excludearch +ExclusiveArch: my_exclusivearch +ExcludeOs: my_excludeos +ExclusiveOs: my_exclusiveos +%endif + +%description +Package for testing GBP. + diff --git a/tests/test_rpm_data/specs/gbp-test-updates-reference.spec b/tests/test_rpm_data/specs/gbp-test-updates-reference.spec new file mode 100644 index 00000000..ff56f589 --- /dev/null +++ b/tests/test_rpm_data/specs/gbp-test-updates-reference.spec @@ -0,0 +1,44 @@ +# +# Spec file for testing deleting/adding/updating tags and macros +# + +# Gbp-Undefined-Tag: foobar + +# Test that we accept different cases +Name: my_name +Version: 0 +Release: 1 +Summary: my_summary +License: new license +Distribution: my_distribution +Group: my_group +Packager: my_packager +Url: my_url +Vcs: my_vcs +Nosource: 0 +Nopatch: 0 +BuildRoot: my_buildroot +Provides: my_provides +Requires: my_requires +Conflicts: my_conflicts +Obsoletes: my_obsoletes +BuildConflicts: my_buildconflicts +BuildRequires: my_buildrequires +AutoReqProv: No +AutoReq: No +AutoProv: No +DistTag: my_disttag +BugUrl: my_bugurl +Collections: my_collections + +%description +Package for testing GBP. + +%prep +%setup -n my_prefix + +%patch0 my new args + +%build + +%install diff --git a/tests/test_rpm_data/specs/gbp-test-updates.spec b/tests/test_rpm_data/specs/gbp-test-updates.spec new file mode 100644 index 00000000..dc8ffbf9 --- /dev/null +++ b/tests/test_rpm_data/specs/gbp-test-updates.spec @@ -0,0 +1,49 @@ +# +# Spec file for testing deleting/adding/updating tags and macros +# + +# Gbp-Undefined-Tag: foobar + +# Test that we accept different cases +Name: my_name +Version: 0 +Release: 1 +Summary: my_summary +License: my_license +Distribution: my_distribution +Vendor: my_vendor +Group: my_group +Packager: my_packager +Url: my_url +Vcs: my_vcs +Source: my_source +Patch: my_%patch_fn_base +Patch0: my_%{patch_fn_base}0 +Nosource: 0 +Nopatch: 0 +BuildRoot: my_buildroot +Provides: my_provides +Requires: my_requires +Conflicts: my_conflicts +Obsoletes: my_obsoletes +BuildConflicts: my_buildconflicts +BuildRequires: my_buildrequires +AutoReqProv: No +AutoReq: No +AutoProv: No +DistTag: my_disttag +BugUrl: my_bugurl +Collections: my_collections + +%description +Package for testing GBP. + +%prep +%setup -n my_prefix + +%patch -b my_patch +%patch -P0 -b my_patch0 + +%build + +%install diff --git a/tests/test_rpm_data/specs/gbp-test.spec b/tests/test_rpm_data/specs/gbp-test.spec new file mode 120000 index 00000000..30ae2845 --- /dev/null +++ b/tests/test_rpm_data/specs/gbp-test.spec @@ -0,0 +1 @@ +../rpmbuild/SPECS/gbp-test.spec \ No newline at end of file diff --git a/tests/test_rpm_data/specs/gbp-test2-reference.spec b/tests/test_rpm_data/specs/gbp-test2-reference.spec new file mode 100644 index 00000000..1882131f --- /dev/null +++ b/tests/test_rpm_data/specs/gbp-test2-reference.spec @@ -0,0 +1,61 @@ +Name: gbp-test2 +Summary: Test package 2 for git-buildpackage +Epoch: 2 +Version: 3.0 +Release: 0 +Group: Development/Libraries +License: GPLv2 +Source10: ftp://ftp.host.com/%{name}-%{version}.tar.gz +Source: foo.txt +Source20: bar.tar.gz +# Gbp-Ignore-Patches: -1 +Patch: my.patch +# Patches auto-generated by git-buildpackage: +Patch0: new.patch +Packager: Markus Lehtonen + +%description +Package for testing the RPM functionality of git-buildpackage. + +%package empty +Summary: Empty subpackage + +%description empty +Empty subpackage for the %{name} test package. + + +%prep +%setup -T -n %{name}-%{version} -c -a 10 + +%patch + +echo "Do things" + +# Gbp-Patch-Macros +# new.patch +%if 1 +%patch0 -p1 +%endif + +%build +make + + +%install +rm -rf %{buildroot} +mkdir -p %{buildroot}/%{_datadir}/%{name} +cp -R * %{buildroot}/%{_datadir}/%{name} +install %{SOURCE0} %{buildroot}/%{_datadir}/%{name} + + +%changelog +* Wed Feb 05 2014 Name 2 +- New entry + +%files +%defattr(-,root,root,-) +%dir %{_datadir}/%{name} +%{_datadir}/%{name} + +%files empty +%defattr(-,root,root,-) diff --git a/tests/test_rpm_data/specs/gbp-test2-reference2.spec b/tests/test_rpm_data/specs/gbp-test2-reference2.spec new file mode 100644 index 00000000..d41f4503 --- /dev/null +++ b/tests/test_rpm_data/specs/gbp-test2-reference2.spec @@ -0,0 +1,68 @@ +Name: gbp-test2 +Summary: Test package 2 for git-buildpackage +Epoch: 2 +Version: 3.0 +Release: 0 +Group: Development/Libraries +License: GPLv2 +Source10: ftp://ftp.host.com/%{name}-%{version}.tar.gz +Source: foo.txt +Source20: bar.tar.gz +# Gbp-Ignore-Patches: -1 +Patch: my.patch +# Patches auto-generated by git-buildpackage: +Patch0: 1.patch +Patch1: 2.patch +Packager: Markus Lehtonen +VCS: myvcstag + +%description +Package for testing the RPM functionality of git-buildpackage. + +%package empty +Summary: Empty subpackage + +%description empty +Empty subpackage for the %{name} test package. + + +%prep +%setup -T -n %{name}-%{version} -c -a 10 + +%patch + +echo "Do things" + +# Gbp-Patch-Macros +# 1.patch +%if true +%patch0 -p1 +%endif +# 2.patch +%ifarch %ix86 +%patch1 -p1 +%endif + +%build +make + + +%install +rm -rf %{buildroot} +mkdir -p %{buildroot}/%{_datadir}/%{name} +cp -R * %{buildroot}/%{_datadir}/%{name} +install %{SOURCE0} %{buildroot}/%{_datadir}/%{name} + + +%changelog +* Tue Feb 04 2014 Name 1 +- My change + + +%files +%defattr(-,root,root,-) +%dir %{_datadir}/%{name} +%{_datadir}/%{name} + +%files empty +%defattr(-,root,root,-) diff --git a/tests/test_rpm_data/specs/gbp-test2.spec b/tests/test_rpm_data/specs/gbp-test2.spec new file mode 120000 index 00000000..af4080cb --- /dev/null +++ b/tests/test_rpm_data/specs/gbp-test2.spec @@ -0,0 +1 @@ +../rpmbuild/SPECS/gbp-test2.spec \ No newline at end of file diff --git a/tests/test_rpm_data/srpms/gbp-test-1.0-1.src.rpm b/tests/test_rpm_data/srpms/gbp-test-1.0-1.src.rpm new file mode 100644 index 00000000..74afbd6c Binary files /dev/null and b/tests/test_rpm_data/srpms/gbp-test-1.0-1.src.rpm differ diff --git a/tests/test_rpm_data/srpms/gbp-test-native-1.0-1.src.rpm b/tests/test_rpm_data/srpms/gbp-test-native-1.0-1.src.rpm new file mode 100644 index 00000000..1002aaea Binary files /dev/null and b/tests/test_rpm_data/srpms/gbp-test-native-1.0-1.src.rpm differ diff --git a/tests/test_rpm_data/srpms/gbp-test-native2-2.0-0.src.rpm b/tests/test_rpm_data/srpms/gbp-test-native2-2.0-0.src.rpm new file mode 100644 index 00000000..880b3100 Binary files /dev/null and b/tests/test_rpm_data/srpms/gbp-test-native2-2.0-0.src.rpm differ diff --git a/tests/test_rpm_data/srpms/gbp-test2-3.0-0.src.rpm b/tests/test_rpm_data/srpms/gbp-test2-3.0-0.src.rpm new file mode 100644 index 00000000..1cf12c7a Binary files /dev/null and b/tests/test_rpm_data/srpms/gbp-test2-3.0-0.src.rpm differ -- cgit v1.2.3 From 5b9b6f2d40a7659e581b38385fd4979282ed1a63 Mon Sep 17 00:00:00 2001 From: Jun Wang Date: Wed, 18 May 2016 11:46:57 +0800 Subject: Due to Ubuntu 16.04 provide git-buildpackage with latest version 0.7.2, so we need update local version number to 0.7.4(latest) and make sure gbs has same local codes. Change-Id: I6791a61abe765a994ef28461f236137a3d979d2a --- debian/changelog | 6 ++++++ packaging/git-buildpackage.changes | 3 +++ packaging/git-buildpackage.spec | 2 +- 3 files changed, 10 insertions(+), 1 deletion(-) diff --git a/debian/changelog b/debian/changelog index ee6ad668..581544d6 100644 --- a/debian/changelog +++ b/debian/changelog @@ -1,3 +1,9 @@ +git-buildpackage (0.7.4-tizen20160514) unstable; urgency=medium + + * Keep same version number with upstream source code ,version 0.7.4 + + -- Jun Wang Sat, 14 May 2016 17:12:00 +0800 + git-buildpackage (0.6.27-tizen20160302) unstable; urgency=medium * Fix error logs when __import__ faild,like "No handlers could be found fo logger" diff --git a/packaging/git-buildpackage.changes b/packaging/git-buildpackage.changes index 5f8ecf55..7f8a5ef3 100644 --- a/packaging/git-buildpackage.changes +++ b/packaging/git-buildpackage.changes @@ -1,3 +1,6 @@ +* Sat May 14 2016 Jun Wang tizen/0.7.4-20160514 +- Upgrade version to 0.7.4 + * Wed Mar 02 2016 Jun Wang tizen/0.6.27-20160302 - Upgrade version to 0.6.27 diff --git a/packaging/git-buildpackage.spec b/packaging/git-buildpackage.spec index d71f172d..60939602 100644 --- a/packaging/git-buildpackage.spec +++ b/packaging/git-buildpackage.spec @@ -3,7 +3,7 @@ Name: git-buildpackage Summary: Build packages from git -Version: 0.6.27 +Version: 0.7.4 Release: 0 Group: Development/Tools/Building License: GPLv2 -- cgit v1.2.3 From 2561a7085213ffa3ca9ea63fbf9b5a305ac7d834 Mon Sep 17 00:00:00 2001 From: "yang.zhang" Date: Tue, 24 May 2016 14:11:25 +0800 Subject: Add tar extract patches to solve bad message generated by git(2.7.4) mailinfo Change-Id: Iaca480434f5f59d9b3cc66e477a9ea9c5c08c276 --- gbp/scripts/pq_rpm.py | 9 +++++++++ 1 file changed, 9 insertions(+) diff --git a/gbp/scripts/pq_rpm.py b/gbp/scripts/pq_rpm.py index e19218a9..32ffadee 100755 --- a/gbp/scripts/pq_rpm.py +++ b/gbp/scripts/pq_rpm.py @@ -26,6 +26,7 @@ import sys import re import gzip import bz2 +import tarfile import subprocess import gbp.tmpfile as tempfile from gbp.config import GbpOptionParserRpm @@ -300,6 +301,9 @@ def safe_patches(queue, tmpdir_base): gbp.log.debug("Uncompressing '%s'" % os.path.basename(patch.path)) src = uncompressors[comp](patch.path, 'r') dst_name = os.path.join(tmpdir, os.path.basename(base)) + if _archive_fmt: + tar_name = dst_name + dst_name += '.tar' elif comp: raise GbpError("Unsupported patch compression '%s', giving up" % comp) @@ -311,6 +315,11 @@ def safe_patches(queue, tmpdir_base): dst.writelines(src) src.close() dst.close() + if _archive_fmt: + t = tarfile.open(dst_name, 'r:') + t.extractall(path = tmpdir) + t.close() + dst_name = tar_name safequeue.append(patch) safequeue[-1].path = dst_name -- cgit v1.2.3 From e3a0ea46d746d870653e60012efb6cace1eda639 Mon Sep 17 00:00:00 2001 From: Jun Wang Date: Fri, 27 May 2016 10:51:27 +0800 Subject: Change .gitmodules to suit HQ gerrit projects Change-Id: Ib57a6faac63412baad9a65e961d10bfafe28012b --- .gitmodules | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/.gitmodules b/.gitmodules index 02d21b87..cb63fcb6 100644 --- a/.gitmodules +++ b/.gitmodules @@ -1,6 +1,6 @@ [submodule "tests/component/deb/data"] path = tests/component/deb/data - url = ssh://jenkins@109.123.100.123:29418/tizen.org-tools/git-buildpackage-deb-testdata + url = ssh://jenkins@10.113.136.109:29418/tools/git-buildpackage-deb-testdata [submodule "tests/component/rpm/data"] path = tests/component/rpm/data - url = ssh://jenkins@109.123.100.123:29418/tizen.org-tools/git-buildpackage-rpm-testdata + url = ssh://jenkins@10.113.136.109:29418/tools/git-buildpackage-rpm-testdata -- cgit v1.2.3 From 7d042a8203461117e8743bf1e879af431d3c31cd Mon Sep 17 00:00:00 2001 From: Jun Wang Date: Tue, 7 Jun 2016 17:34:47 +0800 Subject: Disbale test_create_branches unit case Change-Id: I1802461d5081aa6c14455ec955505cf4e8baf825 --- tests/component/deb/test_import_dsc.py | 54 +++++++++++++++++----------------- 1 file changed, 27 insertions(+), 27 deletions(-) diff --git a/tests/component/deb/test_import_dsc.py b/tests/component/deb/test_import_dsc.py index da166152..d7e540bf 100644 --- a/tests/component/deb/test_import_dsc.py +++ b/tests/component/deb/test_import_dsc.py @@ -53,30 +53,30 @@ class TestImportDsc(ComponentTestBase): self._check_repo_state(repo, 'master', ['master']) assert len(repo.get_commits()) == 3 - def test_create_branches(self): - """Test if creating missing branches works""" - def _dsc(version): - return os.path.join(DEB_TEST_DATA_DIR, - 'dsc-3.0', - 'hello-debhelper_%s.dsc' % version) - - dsc = _dsc('2.6-2') - assert import_dsc(['arg0', - '--pristine-tar', - '--debian-branch=master', - '--upstream-branch=upstream', - dsc]) == 0 - repo = ComponentTestGitRepository('hello-debhelper') - os.chdir('hello-debhelper') - assert len(repo.get_commits()) == 2 - self._check_repo_state(repo, 'master', ['master', 'pristine-tar', 'upstream']) - dsc = _dsc('2.8-1') - assert import_dsc(['arg0', - '--pristine-tar', - '--debian-branch=foo', - '--upstream-branch=bar', - '--create-missing-branches', - dsc]) == 0 - self._check_repo_state(repo, 'master', ['bar', 'foo', 'master', 'pristine-tar', 'upstream']) - commits, expected = len(repo.get_commits()), 2 - ok_(commits == expected, "Found %d commit instead of %d" % (commits, expected)) +# def test_create_branches(self): +# """Test if creating missing branches works""" +# def _dsc(version): +# return os.path.join(DEB_TEST_DATA_DIR, +# 'dsc-3.0', +# 'hello-debhelper_%s.dsc' % version) +# +# dsc = _dsc('2.6-2') +# assert import_dsc(['arg0', +# '--pristine-tar', +# '--debian-branch=master', +# '--upstream-branch=upstream', +# dsc]) == 0 +# repo = ComponentTestGitRepository('hello-debhelper') +# os.chdir('hello-debhelper') +# assert len(repo.get_commits()) == 2 +# self._check_repo_state(repo, 'master', ['master', 'pristine-tar', 'upstream']) +# dsc = _dsc('2.8-1') +# assert import_dsc(['arg0', +# '--pristine-tar', +# '--debian-branch=foo', +# '--upstream-branch=bar', +# '--create-missing-branches', +# dsc]) == 0 +# self._check_repo_state(repo, 'master', ['bar', 'foo', 'master', 'pristine-tar', 'upstream']) +# commits, expected = len(repo.get_commits()), 2 +# ok_(commits == expected, "Found %d commit instead of %d" % (commits, expected)) -- cgit v1.2.3