From 949ce84c9af869d3cf151eadac8e69d720ff2774 Mon Sep 17 00:00:00 2001 From: Guido Günther Date: Fri, 4 Apr 2014 12:57:30 +0200 Subject: Slightly improve usage output --- gbp/scripts/config.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/gbp/scripts/config.py b/gbp/scripts/config.py index 0ebca130..07c731c0 100755 --- a/gbp/scripts/config.py +++ b/gbp/scripts/config.py @@ -29,7 +29,7 @@ import gbp.log def build_parser(name): try: parser = GbpOptionParser(command=os.path.basename(name), prefix='', - usage='%prog [options] - display configuration settings') + usage='%prog [options] command[.optionname] - display configuration settings') except ConfigParser.ParsingError as err: gbp.log.err(err) return None @@ -112,7 +112,7 @@ def main(argv): gbp.log.error("No command given") return 2 elif len(args) != 2: - gbp.log.error("Can only take a single argument") + gbp.log.error("Can only take a command or command.optionname, check --help") return 2 else: query = args[1] -- cgit v1.2.3 From 045e60755306716af245b0fc5fd9d7156d0faec3 Mon Sep 17 00:00:00 2001 From: Guido Günther Date: Fri, 2 May 2014 17:10:48 +0200 Subject: gbp pq: document --force --- docs/manpages/gbp-pq.sgml | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/docs/manpages/gbp-pq.sgml b/docs/manpages/gbp-pq.sgml index 83f64123..e7a2bdd2 100644 --- a/docs/manpages/gbp-pq.sgml +++ b/docs/manpages/gbp-pq.sgml @@ -25,6 +25,7 @@ topic num + @@ -161,6 +162,13 @@ + + + + In case of import even import if the branch already + exists + + -- cgit v1.2.3 From 817976e1117228641e93b76e4aee350f51316caf Mon Sep 17 00:00:00 2001 From: Guido Günther Date: Wed, 7 May 2014 20:35:48 +0200 Subject: Handle version format errors more gracefully So far if a package claimed to be non native but the version number didn't contain a '-' we failed like: Traceback (most recent call last): File "/usr/bin/gbp", line 9, in load_entry_point('gbp==0.6.13', 'console_scripts', 'gbp')() File "/usr/lib/python2.7/dist-packages/gbp/scripts/supercommand.py", line 82, in supercommand return module.main(args) File "/usr/lib/python2.7/dist-packages/gbp/scripts/buildpackage.py", line 541, in main output_dir) File "/usr/lib/python2.7/dist-packages/gbp/scripts/buildpackage.py", line 96, in prepare_upstream_tarball upstream_tree = git_archive_build_orig(repo, cp, output_dir, options) File "/usr/lib/python2.7/dist-packages/gbp/scripts/buildpackage.py", line 270, in git_archive_build_orig upstream_tree = get_upstream_tree(repo, cp, options) File "/usr/lib/python2.7/dist-packages/gbp/scripts/buildpackage.py", line 245, in get_upstream_tree cp['Upstream-Version']) File "/usr/lib/python2.7/dist-packages/gbp/deb/git.py", line 107, in version_to_tag return format % dict(version=DebianGitRepository._sanitize_version(version)) File "/usr/lib/python2.7/dist-packages/gbp/deb/git.py", line 122, in _sanitize_version return version.replace('~', '_').replace(':', '%') It shouldn't be like that. --- gbp/scripts/buildpackage.py | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/gbp/scripts/buildpackage.py b/gbp/scripts/buildpackage.py index c077b9e6..77a5b969 100755 --- a/gbp/scripts/buildpackage.py +++ b/gbp/scripts/buildpackage.py @@ -1,6 +1,6 @@ # vim: set fileencoding=utf-8 : # -# (C) 2006-2013 Guido Günther +# (C) 2006-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 @@ -241,6 +241,8 @@ def pristine_tar_build_orig(repo, cp, output_dir, options): def get_upstream_tree(repo, cp, options): """Determine the upstream tree from the given options""" if options.upstream_tree.upper() == 'TAG': + if cp['Upstream-Version'] is None: + raise GitRepositoryError("Can't determine upstream version from changelog") upstream_tree = repo.version_to_tag(options.upstream_tag, cp['Upstream-Version']) elif options.upstream_tree.upper() == 'BRANCH': -- cgit v1.2.3 From b0390d15c9d77303a607e4b760771c71f6b7d971 Mon Sep 17 00:00:00 2001 From: Guido Günther Date: Fri, 16 May 2014 19:51:26 +0200 Subject: Fix comitter vs committer typos Thanks: Sandro Tosi Closes: #748339 --- docs/manpages/gbp-import-dsc.sgml | 4 ++-- gbp/config.py | 4 ++-- gbp/deb/git.py | 2 +- gbp/git/modifier.py | 8 ++++---- gbp/git/repository.py | 2 +- gbp/scripts/dch.py | 2 +- tests/test_GitModifier.py | 2 +- 7 files changed, 12 insertions(+), 12 deletions(-) diff --git a/docs/manpages/gbp-import-dsc.sgml b/docs/manpages/gbp-import-dsc.sgml index 98f70e72..2d186ed8 100644 --- a/docs/manpages/gbp-import-dsc.sgml +++ b/docs/manpages/gbp-import-dsc.sgml @@ -169,7 +169,7 @@ When importing the Debian patch, use the author identity as - comitter identity. + committer identity. @@ -177,7 +177,7 @@ When importing the Debian patch, use the author date as - comitter date. Git will subtly misbehave if the + committer date. Git will subtly misbehave if the committer date of a commit is not later than or equal to all its parents. diff --git a/gbp/config.py b/gbp/config.py index fc31076e..3fa59186 100644 --- a/gbp/config.py +++ b/gbp/config.py @@ -249,10 +249,10 @@ class GbpOptionParser(OptionParser): ("Set up tracking for remote branches, " "default is '%(track)s'"), 'author-is-committer': - ("Use the authors's name also as the comitter's name, " + ("Use the authors's name also as the committer's name, " "default is '%(author-is-committer)s'"), 'author-date-is-committer-date': - ("Use the authors's date as the comitter's date, " + ("Use the authors's date as the committer's date, " "default is '%(author-date-is-committer-date)s'"), 'create-missing-branches': ("Create missing branches automatically, " diff --git a/gbp/deb/git.py b/gbp/deb/git.py index 7a328bed..6105fe7d 100644 --- a/gbp/deb/git.py +++ b/gbp/deb/git.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 diff --git a/gbp/git/modifier.py b/gbp/git/modifier.py index bc986491..2452e0b5 100644 --- a/gbp/git/modifier.py +++ b/gbp/git/modifier.py @@ -41,7 +41,7 @@ class GitTz(datetime.tzinfo): return datetime.timedelta(0) class GitModifier(object): - """Stores authorship/comitter information""" + """Stores authorship/committer information""" def __init__(self, name=None, email=None, date=None): """ @param name: the modifier's name @@ -77,10 +77,10 @@ class GitModifier(object): "datetime object or git raw date" % date) def _get_env(self, who): - """Get author or comitter information as env var dictionary""" + """Get author or committer information as env var dictionary""" who = who.upper() if who not in ['AUTHOR', 'COMMITTER']: - raise GitModifierError("Neither comitter nor author") + raise GitModifierError("Neither committer nor author") extra_env = {} if self.name: @@ -130,7 +130,7 @@ class GitModifier(object): def get_committer_env(self): """ - Get env vars for comitter information + Get env vars for committer information >>> g = GitModifier("foo", "bar") >>> g.get_committer_env() diff --git a/gbp/git/repository.py b/gbp/git/repository.py index 10b90308..23f9482a 100644 --- a/gbp/git/repository.py +++ b/gbp/git/repository.py @@ -1408,7 +1408,7 @@ class GitRepository(object): @param parents: parents of this commit @param author: authorship information @type author: C{dict} with keys 'name' and 'email' or L{GitModifier} - @param committer: comitter information + @param committer: committer information @type committer: C{dict} with keys 'name' and 'email' """ extra_env = {} diff --git a/gbp/scripts/dch.py b/gbp/scripts/dch.py index f36f2877..c0344805 100644 --- a/gbp/scripts/dch.py +++ b/gbp/scripts/dch.py @@ -66,7 +66,7 @@ def get_author_email(repo, use_git_config): def fixup_section(repo, git_author, options, dch_options): """ - Fixup the changelog header and trailer's comitter and email address + Fixup the changelog header and trailer's committer and email address It might otherwise point to the last git committer instead of the person creating the changelog diff --git a/tests/test_GitModifier.py b/tests/test_GitModifier.py index 1a28c0a8..0a05d4b8 100644 --- a/tests/test_GitModifier.py +++ b/tests/test_GitModifier.py @@ -26,7 +26,7 @@ def test_author(): >>> modifier._get_env('foo') Traceback (most recent call last): ... - GitModifierError: Neither comitter nor author + GitModifierError: Neither committer nor author >>> modifier['name'] 'foo' >>> modifier['email'] -- cgit v1.2.3 From dc231f2e75fe8733df35433be6455aeefcc47a44 Mon Sep 17 00:00:00 2001 From: Guido Günther Date: Mon, 19 May 2014 11:34:01 +0200 Subject: Documnt that the patches must apply without fuzz --- docs/manpages/gbp-pq.sgml | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/docs/manpages/gbp-pq.sgml b/docs/manpages/gbp-pq.sgml index e7a2bdd2..fa86ff2b 100644 --- a/docs/manpages/gbp-pq.sgml +++ b/docs/manpages/gbp-pq.sgml @@ -58,8 +58,9 @@ - Create a patch queue branch from quilt patches in debian/patches/ that - are listed in debian/patches/series. + Create a patch queue branch from quilt patches in + debian/patches/ that are listed in debian/patches/series. The + patches must apply without fuzz. -- cgit v1.2.3 From de77df731cd752a9d26c8bef7cf9933f30bfb50a Mon Sep 17 00:00:00 2001 From: Guido Günther Date: Mon, 19 May 2014 12:06:08 +0200 Subject: pq: Print proper error message if we fail to apply the tree e.g. instead of gbp:error: Failed to apply 'debian/patches/poison+remember_trash' we now have gbp:error: Failed to apply 'debian/patches/poison+remember_trash': Failed to commit tree: fatal: invalid date format: 1998/03/21 --- gbp/scripts/pq.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/gbp/scripts/pq.py b/gbp/scripts/pq.py index fc205bf2..05e5660c 100755 --- a/gbp/scripts/pq.py +++ b/gbp/scripts/pq.py @@ -174,8 +174,8 @@ def import_quilt_patches(repo, branch, series, tries, force): gbp.log.debug("Applying %s" % patch.path) try: apply_and_commit_patch(repo, patch, maintainer, patch.topic) - except (GbpError, GitRepositoryError): - gbp.log.err("Failed to apply '%s'" % patch.path) + except (GbpError, GitRepositoryError) as e: + gbp.log.err("Failed to apply '%s': %s" % (patch.path, e)) repo.set_branch(branch) repo.delete_branch(pq_branch) break -- cgit v1.2.3 From 54e454209a7573b4c321fc19a39f6991a6bd1ac0 Mon Sep 17 00:00:00 2001 From: Guido Günther Date: Mon, 19 May 2014 12:06:39 +0200 Subject: pq: Try harder to cleanup after a failed patch If we fail to apply the patch the tree is left in a dirty state so reset to the last head. This avoids irritating errors like: gbp:error: Failed to apply 'debian/patches/poison+remember_trash': Failed to commit tree: fatal: invalid date format: 1998/03/21 following files would be overwritten by checkout: doc/hosts.nntp.5 innd/art.c innd/innd.h innd/rc.c Please, commit your changes or stash them before you can switch branches. Aborting Thanks: Marco d'Itri for the repo to debug this --- gbp/scripts/pq.py | 1 + 1 file changed, 1 insertion(+) diff --git a/gbp/scripts/pq.py b/gbp/scripts/pq.py index 05e5660c..ea33c26c 100755 --- a/gbp/scripts/pq.py +++ b/gbp/scripts/pq.py @@ -176,6 +176,7 @@ def import_quilt_patches(repo, branch, series, tries, force): apply_and_commit_patch(repo, patch, maintainer, patch.topic) except (GbpError, GitRepositoryError) as e: gbp.log.err("Failed to apply '%s': %s" % (patch.path, e)) + repo.force_head('HEAD', hard=True) repo.set_branch(branch) repo.delete_branch(pq_branch) break -- cgit v1.2.3 From b2549fac19f2d666552291a4fcf2020ca0570834 Mon Sep 17 00:00:00 2001 From: Guido Günther Date: Thu, 22 May 2014 14:53:47 +0200 Subject: Determine build_dir upfront so it's available to all hooks --- gbp/scripts/buildpackage.py | 6 +----- 1 file changed, 1 insertion(+), 5 deletions(-) diff --git a/gbp/scripts/buildpackage.py b/gbp/scripts/buildpackage.py index 77a5b969..24a759e9 100755 --- a/gbp/scripts/buildpackage.py +++ b/gbp/scripts/buildpackage.py @@ -526,6 +526,7 @@ def main(argv): tree = write_tree(repo, options) source = source_vfs(repo, options, tree) + build_dir = export_dir if options.export_dir else repo_dir if not options.tag_only: output_dir = prepare_output_dir(options.export_dir) tarball_dir = options.tarball_dir or output_dir @@ -565,11 +566,6 @@ def main(argv): prepare_upstream_tarball(repo, source.changelog, options, tarball_dir, output_dir) - if options.export_dir: - build_dir = export_dir - else: - build_dir = repo_dir - if options.prebuild: RunAtCommand(options.prebuild, shell=True, extra_env={'GBP_GIT_DIR': repo.git_dir, -- cgit v1.2.3 From a050942804729e4e96352a5bdd34e6d27fb4f24b Mon Sep 17 00:00:00 2001 From: Guido Günther Date: Thu, 22 May 2014 13:00:15 +0200 Subject: Improve error reporting on failed commands Make it more clear if the command exited with non zero exit status. Also don't report the command line twice. Closes: #748248 --- gbp/command_wrappers.py | 10 ++++------ 1 file changed, 4 insertions(+), 6 deletions(-) diff --git a/gbp/command_wrappers.py b/gbp/command_wrappers.py index 8a131e11..b8bd21f7 100644 --- a/gbp/command_wrappers.py +++ b/gbp/command_wrappers.py @@ -40,8 +40,7 @@ class Command(object): capture_stderr=False): self.cmd = cmd self.args = args - self.run_error = "Couldn't run '%s'" % (" ".join([self.cmd] + - self.args)) + self.run_error = "'%s' failed" % (" ".join([self.cmd] + self.args)) self.shell = shell self.retcode = 1 self.stderr = '' @@ -91,12 +90,11 @@ class Command(object): try: retcode = self.__call(args) if retcode < 0: - err_detail = "%s was terminated by signal %d" % (self.cmd, - -retcode) + err_detail = "it was terminated by signal %d" % -retcode elif retcode > 0: - err_detail = "%s returned %d" % (self.cmd, retcode) + err_detail = "it exited with %d" % retcode except OSError as err: - err_detail = "Execution failed: %s" % err + err_detail = "execution failed: %s" % err retcode = 1 if retcode and not quiet: log.err("%s: %s" % (self.run_error, err_detail)) -- cgit v1.2.3 From 030ff96b12d851b51f4f390d222a264c26dcc49d Mon Sep 17 00:00:00 2001 From: Guido Günther Date: Thu, 22 May 2014 13:20:11 +0200 Subject: Improve error reporting on hooks Make it obvious that a hook failed and not a gbp internal function --- gbp/scripts/buildpackage.py | 33 ++++++++++++++++++++------------- 1 file changed, 20 insertions(+), 13 deletions(-) diff --git a/gbp/scripts/buildpackage.py b/gbp/scripts/buildpackage.py index 24a759e9..af3cd152 100755 --- a/gbp/scripts/buildpackage.py +++ b/gbp/scripts/buildpackage.py @@ -484,6 +484,13 @@ def parse_args(argv, prefix): return options, args, dpkg_args +class Hook(RunAtCommand): + "A hook run during the build" + def __init__(self, name, *args, **kwargs): + RunAtCommand.__init__(self, *args, **kwargs) + self.run_error = '%s-hook %s' % (name, self.run_error) + + def main(argv): retval = 0 prefix = "git-" @@ -550,9 +557,9 @@ def main(argv): # Run postexport hook if options.postexport: - RunAtCommand(options.postexport, shell=True, - extra_env={'GBP_GIT_DIR': repo.git_dir, - 'GBP_TMP_DIR': tmp_dir})(dir=tmp_dir) + Hook('Postexport', options.postexport, shell=True, + extra_env={'GBP_GIT_DIR': repo.git_dir, + 'GBP_TMP_DIR': tmp_dir})(dir=tmp_dir) major = (source.changelog.debian_version if source.is_native() else source.changelog.upstream_version) @@ -567,9 +574,9 @@ def main(argv): output_dir) if options.prebuild: - RunAtCommand(options.prebuild, shell=True, - extra_env={'GBP_GIT_DIR': repo.git_dir, - 'GBP_BUILD_DIR': build_dir})(dir=build_dir) + Hook('Prebuild', options.prebuild, shell=True, + extra_env={'GBP_GIT_DIR': repo.git_dir, + 'GBP_BUILD_DIR': build_dir})(dir=build_dir) setup_pbuilder(options) # Finally build the package: @@ -582,9 +589,9 @@ def main(argv): source.changelog.noepoch, changes_file_suffix(dpkg_args))) gbp.log.debug("Looking for changes file %s" % changes) - Command(options.postbuild, shell=True, - extra_env={'GBP_CHANGES_FILE': changes, - 'GBP_BUILD_DIR': build_dir})() + Hook('Postbuild', options.postbuild, shell=True, + extra_env={'GBP_CHANGES_FILE': changes, + '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) @@ -596,10 +603,10 @@ def main(argv): sign=options.sign_tags, keyid=options.keyid) if options.posttag: sha = repo.rev_parse("%s^{}" % tag) - Command(options.posttag, shell=True, - extra_env={'GBP_TAG': tag, - 'GBP_BRANCH': branch or '(no branch)', - 'GBP_SHA1': sha})() + Hook('Posttag', options.posttag, shell=True, + extra_env={'GBP_TAG': tag, + 'GBP_BRANCH': branch or '(no branch)', + 'GBP_SHA1': sha})() except CommandExecFailed: retval = 1 except (GbpError, GitRepositoryError) as err: -- cgit v1.2.3 From 7543b8e9598e3d67bf33c811c4fc9d5a99553eb7 Mon Sep 17 00:00:00 2001 From: Guido Günther Date: Thu, 22 May 2014 22:49:01 +0200 Subject: Document changes and release 0.6.14 --- debian/changelog | 18 ++++++++++++++++++ 1 file changed, 18 insertions(+) diff --git a/debian/changelog b/debian/changelog index aef756c3..fb592ee9 100644 --- a/debian/changelog +++ b/debian/changelog @@ -1,3 +1,21 @@ +git-buildpackage (0.6.14) unstable; urgency=medium + + * [949ce84] Slightly improve usage output + * [045e607] gbp pq: document --force + * [817976e] Handle version format errors more gracefully. + * [b0390d1] Fix comitter vs committer typos. + Thanks to Sandro Tosi (Closes: #748339) + * [dc231f2] Document that the patches must apply without fuzz + * [de77df7] pq: Print proper error message if we fail to apply the tree + * [54e4542] pq: Try harder to cleanup after a failed patch. + Thanks to Marco d'Itri for the repo to debug this + * [b2549fa] Determine build_dir upfront + * [a050942] Improve error reporting on failed commands. + (Closes: #748248) + * [030ff96] Improve error reporting on hooks. + + -- Guido Günther Thu, 22 May 2014 22:47:37 +0200 + git-buildpackage (0.6.13) unstable; urgency=medium [ Guido Günther ] -- cgit v1.2.3 From 5cde49a3cc2fac3d1f93fbdebbaa81ea9e4e2b4c Mon Sep 17 00:00:00 2001 From: Guido Günther Date: Sat, 24 May 2014 18:40:35 +0200 Subject: Revert "Determine build_dir upfront" This reverts commit b2549fac19f2d666552291a4fcf2020ca0570834. --- gbp/scripts/buildpackage.py | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/gbp/scripts/buildpackage.py b/gbp/scripts/buildpackage.py index af3cd152..54e66bd2 100755 --- a/gbp/scripts/buildpackage.py +++ b/gbp/scripts/buildpackage.py @@ -533,7 +533,6 @@ def main(argv): tree = write_tree(repo, options) source = source_vfs(repo, options, tree) - build_dir = export_dir if options.export_dir else repo_dir if not options.tag_only: output_dir = prepare_output_dir(options.export_dir) tarball_dir = options.tarball_dir or output_dir @@ -573,6 +572,11 @@ def main(argv): prepare_upstream_tarball(repo, source.changelog, options, tarball_dir, output_dir) + if options.export_dir: + build_dir = export_dir + else: + build_dir = repo_dir + if options.prebuild: Hook('Prebuild', options.prebuild, shell=True, extra_env={'GBP_GIT_DIR': repo.git_dir, -- cgit v1.2.3 From 65af043024a7323e28784b865d8bcba4d67540f2 Mon Sep 17 00:00:00 2001 From: Guido Günther Date: Sat, 24 May 2014 18:41:05 +0200 Subject: Document changes and release 0.6.15 --- debian/changelog | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/debian/changelog b/debian/changelog index fb592ee9..93d533c1 100644 --- a/debian/changelog +++ b/debian/changelog @@ -1,3 +1,11 @@ +git-buildpackage (0.6.15) unstable; urgency=medium + + * [5cde49a] Revert "Determine build_dir upfront" + This reverts commit b2549fac19f2d666552291a4fcf2020ca0570834. + Closes: #749104 + + -- Guido Günther Sat, 24 May 2014 18:40:44 +0200 + git-buildpackage (0.6.14) unstable; urgency=medium * [949ce84] Slightly improve usage output -- cgit v1.2.3 From c7f0f39cf2f9cba18763df32d581519f5325b8c9 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 ad8f726f376e3865a58e35d606bce4c8bab44afa 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 575c0e72492254a73e4cc1602515f28207c465e3 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 5b5b68a1be03f86d6cddbf638c5f2e60acdc8acb 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 67666b7dedeb02044664bac4d8a9422a3fb7d417 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 093d03594c6665e98e9d91ac4d8cc58a4481b36f 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 70f008d8e881bcaad6d95577d0b8c87b334962c0 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 07637abe3540c65a6352aba667ebdecfcb4bfe85 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 655a6f0528afcebe1b4493abe865ee568c505bbf 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 0b1fc0d602d75da30748bbc979fed48aab805503 Mon Sep 17 00:00:00 2001 From: Guido Günther Date: Sat, 14 Jun 2014 11:55:17 +0200 Subject: buildpackage: Also print tag name when tagging the Debian release Based on a patch by Kamal Mostafa --- 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 54e66bd2..0ef6e9c7 100755 --- a/gbp/scripts/buildpackage.py +++ b/gbp/scripts/buildpackage.py @@ -597,8 +597,8 @@ def main(argv): extra_env={'GBP_CHANGES_FILE': changes, '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) + gbp.log.info("Tagging %s as %s" % (source.changelog.version, tag)) if options.retag and repo.has_tag(tag): repo.delete_tag(tag) repo.create_tag(name=tag, -- cgit v1.2.3 From ab7d8d5a3c1cf3357c5b1302a571d416d148bbac 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 f2ae5f96cf6c490ab52860e1dda8591001d0f3b4 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 57999ca2c716dd628f3018b5f16dcf7d4013fcdc 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 eb537963fe167ac0b8f61a4e8641b54b9161a68d 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 4be93211fe146a884bdbe517e8b2afacb99da4dd 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 4290a94fcdc34f405184b9fff3d81ee5e090dbb5 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 36c8e5cd00fd600be63160b0ef9427a70ab45870 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 7f6b72e039efa5e2c3517b9336f9b29b4cb65c71 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 e68fc61a..66638380 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 0ef6e9c7..8d79e8be 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 fb45b7ec0e6eb24899f7a77a82642c9665ac93b1 Mon Sep 17 00:00:00 2001 From: Guido Günther Date: Thu, 24 Jul 2014 19:43:25 +0200 Subject: Fix typos --- gbp/pkg/__init__.py | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/gbp/pkg/__init__.py b/gbp/pkg/__init__.py index 66638380..52d34691 100644 --- a/gbp/pkg/__init__.py +++ b/gbp/pkg/__init__.py @@ -35,9 +35,9 @@ compressor_aliases = { 'bz2' : 'bzip2', 'gz' : 'gzip', } # Supported archive formats -arhive_formats = [ 'tar', 'zip' ] +archive_formats = [ 'tar', 'zip' ] -# Map combined file extensions to arhive and compression format +# Map combined file extensions to archive and compression format archive_ext_aliases = { 'tgz' : ('tar', 'gzip'), 'tbz2' : ('tar', 'bzip2'), 'tlz' : ('tar', 'lzma'), @@ -79,7 +79,7 @@ def parse_archive_filename(filename): 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: + elif split[-1] in archive_formats: base_name = ".".join(split[:-1]) (archive_fmt, compression) = (split[-1], None) else: @@ -87,7 +87,7 @@ def parse_archive_filename(filename): if o[1] == split[-1]: base_name = ".".join(split[:-1]) compression = c - if len(split) > 2 and split[-2] in arhive_formats: + if len(split) > 2 and split[-2] in archive_formats: base_name = ".".join(split[:-2]) archive_fmt = split[-2] -- cgit v1.2.3 From d76a1a55abecf66b37594fa0e7984273ef5059e7 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 52d34691..18ca8125 100644 --- a/gbp/pkg/__init__.py +++ b/gbp/pkg/__init__.py @@ -352,6 +352,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 @@ -360,20 +364,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 e374ee5a2381ba30056c1fa33bdb515d99ec704e 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 18ca8125..1fd17418 100644 --- a/gbp/pkg/__init__.py +++ b/gbp/pkg/__init__.py @@ -328,8 +328,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') @@ -356,17 +358,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 dbfc6276c4aa50b79f1cf27cfc24badc0b18da8f 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 1fd17418..2e24648a 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 @@ -317,7 +318,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 8d79e8be..457673c9 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 c2c53a64..8e18e978 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 542896ef..f81d2493 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 @@ -300,7 +301,7 @@ def main(argv): source.unpack(tmpdir, 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)) (source, tmpdir) = repack_source(source, sourcepackage, version, tmpdir, options.filters) -- cgit v1.2.3 From 86e1ba6bf098433f08c46585b6103e7efa2f0e48 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 Conflicts: gbp/pkg/__init__.py --- gbp/pkg/__init__.py | 112 ++++++++++++++++++++++++--------------------- gbp/scripts/import_orig.py | 2 +- 2 files changed, 62 insertions(+), 52 deletions(-) diff --git a/gbp/pkg/__init__.py b/gbp/pkg/__init__.py index 2e24648a..05f1f2cd 100644 --- a/gbp/pkg/__init__.py +++ b/gbp/pkg/__init__.py @@ -131,6 +131,65 @@ class PkgPolicy(object): raise NotImplementedError("Class needs to provide upstreamversion_re") return True if cls.upstreamversion_re.match(version) else 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') + ('', '') + >>> 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.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" @@ -325,54 +384,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() - >>> 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_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.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 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 f81d2493..8eed96b5 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: -- cgit v1.2.3 From 1a8e6d12cc94d2b40324fe8f99de012cf2cf5913 Mon Sep 17 00:00:00 2001 From: Guido Günther Date: Thu, 24 Jul 2014 23:13:03 +0200 Subject: Make pychecker happy We don't use the class variable anywhere --- gbp/pkg/__init__.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/gbp/pkg/__init__.py b/gbp/pkg/__init__.py index 05f1f2cd..34f81cda 100644 --- a/gbp/pkg/__init__.py +++ b/gbp/pkg/__init__.py @@ -131,8 +131,8 @@ class PkgPolicy(object): raise NotImplementedError("Class needs to provide upstreamversion_re") return True if cls.upstreamversion_re.match(version) else False - @classmethod - def guess_upstream_src_version(cls, filename, extra_regex=r''): + @staticmethod + def guess_upstream_src_version(filename, extra_regex=r''): """ Guess the package name and version from the filename of an upstream archive. -- cgit v1.2.3 From e7251f84bc17d585e260091b9efe2dade073982c Mon Sep 17 00:00:00 2001 From: Markus Lehtonen Date: Thu, 12 Jan 2012 15:29:03 +0200 Subject: Introduce rpm helpers Implements a new gbp.rpm module that contains functionality for e.g. parsing and editing spec files, reading src.rpm files rpm-specific packaging policy etc. Signed-off-by: Markus Lehtonen Signed-off-by: Ed Bartosh Signed-off-by: Zhang Qiang Signed-off-by: Huang Hao --- gbp/rpm/__init__.py | 962 +++++++++++++++++++++ gbp/rpm/git.py | 105 +++ gbp/rpm/lib_rpm.py | 47 + gbp/rpm/linkedlist.py | 214 +++++ gbp/rpm/policy.py | 72 ++ tests/20_test_rpm.py | 383 ++++++++ tests/data/rpm/rpmbuild/SOURCES/bar.tar.gz | Bin 0 -> 177 bytes tests/data/rpm/rpmbuild/SOURCES/foo.txt | 3 + .../data/rpm/rpmbuild/SOURCES/gbp-test-1.0.tar.bz2 | Bin 0 -> 383 bytes .../rpm/rpmbuild/SOURCES/gbp-test-native-1.0.zip | Bin 0 -> 656 bytes .../data/rpm/rpmbuild/SOURCES/gbp-test2-3.0.tar.gz | Bin 0 -> 328 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 + 30 files changed, 2400 insertions(+) create mode 100644 gbp/rpm/__init__.py create mode 100644 gbp/rpm/git.py create mode 100644 gbp/rpm/lib_rpm.py create mode 100644 gbp/rpm/linkedlist.py create mode 100644 gbp/rpm/policy.py create mode 100644 tests/20_test_rpm.py create mode 100644 tests/data/rpm/rpmbuild/SOURCES/bar.tar.gz create mode 100644 tests/data/rpm/rpmbuild/SOURCES/foo.txt create mode 100644 tests/data/rpm/rpmbuild/SOURCES/gbp-test-1.0.tar.bz2 create mode 100644 tests/data/rpm/rpmbuild/SOURCES/gbp-test-native-1.0.zip create mode 100644 tests/data/rpm/rpmbuild/SOURCES/gbp-test2-3.0.tar.gz create mode 100644 tests/data/rpm/rpmbuild/SOURCES/my.patch create mode 100644 tests/data/rpm/rpmbuild/SOURCES/my2.patch create mode 100644 tests/data/rpm/rpmbuild/SOURCES/my3.patch create mode 100644 tests/data/rpm/rpmbuild/SPECS/gbp-test-native.spec create mode 100644 tests/data/rpm/rpmbuild/SPECS/gbp-test-native2.spec create mode 100644 tests/data/rpm/rpmbuild/SPECS/gbp-test.spec create mode 100644 tests/data/rpm/rpmbuild/SPECS/gbp-test2.spec create mode 120000 tests/data/rpm/specs/gbp-test-native.spec create mode 120000 tests/data/rpm/specs/gbp-test-native2.spec create mode 100644 tests/data/rpm/specs/gbp-test-quirks.spec create mode 100644 tests/data/rpm/specs/gbp-test-reference.spec create mode 100644 tests/data/rpm/specs/gbp-test-reference2.spec create mode 100644 tests/data/rpm/specs/gbp-test-tags.spec create mode 100644 tests/data/rpm/specs/gbp-test-updates-reference.spec create mode 100644 tests/data/rpm/specs/gbp-test-updates.spec create mode 120000 tests/data/rpm/specs/gbp-test.spec create mode 100644 tests/data/rpm/specs/gbp-test2-reference.spec create mode 100644 tests/data/rpm/specs/gbp-test2-reference2.spec create mode 120000 tests/data/rpm/specs/gbp-test2.spec diff --git a/gbp/rpm/__init__.py b/gbp/rpm/__init__.py new file mode 100644 index 00000000..87f82ffa --- /dev/null +++ b/gbp/rpm/__init__.py @@ -0,0 +1,962 @@ +# 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 glob +import shutil as shutil +from optparse import OptionParser +from collections import defaultdict + +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 +from gbp.rpm.linkedlist import LinkedList +from gbp.rpm.lib_rpm import librpm, get_librpm_log + + +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""" + 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 = (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 = 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[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[librpm.RPMTAG_NAME] + + @property + def upstreamversion(self): + """Get the upstream version of the RPM package""" + return self.rpmhdr[librpm.RPMTAG_VERSION] + + @property + def packager(self): + """Get the packager of the RPM package""" + return self.rpmhdr[librpm.RPMTAG_PACKAGER] + + def unpack(self, dest_dir): + """ + 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) + + +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) + 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, filename=None, filedata=None): + + self._content = LinkedList() + + # 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", + "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 + source_header = self._specinfo.packages[0].header + 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[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) + + # Parse extra info from spec file + self._parse_content() + + # Find 'Packager' tag. Needed to circumvent a bug in python-rpm where + # spec.sourceHeader[librpm.RPMTAG_PACKAGER] is not reset when a new spec + # file is parsed + if 'packager' not in self._tags: + self.packager = None + + self.orig_src = 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 + librpm.spec(filtered.name) + return librpm.spec(filtered.name) + except ValueError as 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): + """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""" + return os.path.join(self.specdir, self.specfile) + + @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 _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 _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, + '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 + """ + with open(os.path.join(self.specdir, self.specfile), 'w') as spec_file: + 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 + # 'Patch:' tags + elif tagname == 'patch': + tagnum = -1 if tagnum is None else tagnum + + # Record all tag locations + try: + header = self._specinfo.packages[0].header + tagvalue = header[getattr(librpm, 'RPMTAG_%s' % tagname.upper())] + except AttributeError: + tagvalue = None + # We don't support "multivalue" tags like "Provides:" or "SourceX:" + # 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 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, + '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]} + + return tagname + + @staticmethod + def _patch_macro_opts(args): + """Parse arguments of the '%patch' macro""" + + 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] + + @staticmethod + def _setup_macro_opts(args): + """Parse arguments of the '%setup' macro""" + + 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") + 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) + if not matchobj: + return None + + directivename = matchobj.group('name') + # '%patch' macros + directiveid = None + if directivename == 'patch': + 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 + + # 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 + + 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) + + # Update sources info (basically possible macros expanded by rpm) + # And, double-check that we parsed spec content correctly + patches = self._patches() + sources = self._sources() + for name, num, typ in self._specinfo.sources: + # workaround rpm parsing bug + if typ == 1 or typ == 9: + if num in sources: + sources[num]['linevalue'] = name + else: + 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): + num = -1 + if num in patches: + patches[num]['linevalue'] = name + else: + gbp.log.err("BUG: failed to parse all 'Patch' tags!") + + 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(librpm, '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() + 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: + self._set_tag(tag, num, value, after_line) + elif key in self._tags: + self._delete_tag(tag, num) + 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 _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 + tag_prev = None + macro_prev = None + ignored = self.ignorepatches + # Remove 'Patch:̈́' tags + 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 + if re.match("^\s*#.*patch.*auto-generated", + 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: + 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 + 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(patches) == 0: + return + + # Determine where to add Patch tag lines + if tag_prev: + gbp.log.debug("Adding 'Patch' tags in place of the removed tags") + tag_line = tag_prev + elif 'patch' in self._tags: + gbp.log.debug("Adding new 'Patch' tags after the last 'Patch' tag") + 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.") + 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.") + 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") + macro_line = self._gbp_tags['patch-macros'][-1]['line'] + elif macro_prev: + gbp.log.debug("Adding '%patch' macros in place of the removed " + "macros") + macro_line = macro_prev + elif self._special_directives['patch']: + gbp.log.debug("Adding new '%patch' macros after the last existing" + "'%patch' macro") + 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") + 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") + macro_line = self._special_directives['prep'][-1]['line'] + else: + raise GbpError("Couldn't determine where to add '%patch' macros") + + 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, patch in enumerate(patches): + cmds = commands[patch] if patch in commands else {} + patchnum = startnum + ind + tag_line = self._set_tag("Patch", patchnum, patch, tag_line) + # Add '%patch' macro and a preceding comment line + 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""" + series = PatchSeries() + if 'patch' in self._tags: + tags = self._patches() + applied = [] + for macro in self._special_directives['patch']: + 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 + 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): + """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 + 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: + 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) + prefix = orig['filename_base'] + '/' + else: + # RPM default + 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): + """parse srpm by creating a SrcRpmFile object""" + try: + srcrpm = SrcRpmFile(srpmfile) + except IOError, err: + raise GbpError, "Error reading src.rpm file: %s" % err + except librpm.error, err: + raise GbpError, "RPM error while reading src.rpm: %s" % err + + return srcrpm + + +def guess_spec_fn(file_list, preferred_name=None): + """Guess spec file from a list of filenames""" + specs = [] + 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') + return SpecFile(os.path.abspath(guess_spec_fn(file_list, preferred_name))) + + +def guess_spec_repo(repo, treeish, topdir='', recursive=True, preferred_name=None): + """ + Try to find/parse the spec file from a given git treeish. + """ + 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): + """ + 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) + + +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 new file mode 100644 index 00000000..c7cc023b --- /dev/null +++ b/gbp/rpm/git.py @@ -0,0 +1,105 @@ +# 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 +from gbp.rpm import compose_version_str + +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, 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 + commit object it points to. + + @param format: tag pattern + @type format: 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 + """ + 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, str_fields): + """ + Generate a tag from a given format and a version + + @param format: tag pattern + @type format: 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', vendor="myvendor")) + 'myvendor/v1.0-2' + """ + version_tag = format % dict(str_fields, + version=compose_version_str(str_fields)) + return RpmGitRepository._sanitize_tag(version_tag) + + @staticmethod + def _sanitize_tag(tag): + """sanitize a version so git accepts it as a tag + + >>> RpmGitRepository._sanitize_tag("0.0.0") + '0.0.0' + >>> RpmGitRepository._sanitize_tag("0.0~0") + '0.0_0' + >>> RpmGitRepository._sanitize_tag("0:0.0") + '0%0.0' + >>> RpmGitRepository._sanitize_tag("0%0~0") + '0%0_0' + """ + return tag.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/lib_rpm.py b/gbp/rpm/lib_rpm.py new file mode 100644 index 00000000..4bad44e7 --- /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.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 +_rpmlog = tempfile.NamedTemporaryFile(prefix='gbp_rpmlog') +_rpmlogfd = _rpmlog.file +librpm.setVerbosity(librpm.RPMLOG_INFO) +librpm.setLogFile(_rpmlogfd) + + +def get_librpm_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 + diff --git a/gbp/rpm/linkedlist.py b/gbp/rpm/linkedlist.py new file mode 100644 index 00000000..ca000453 --- /dev/null +++ b/gbp/rpm/linkedlist.py @@ -0,0 +1,214 @@ +# 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'] + >>> str(list.delete(node3)) + 'foo' + >>> [str(data) for data in list] + ['foo', 'bar'] + >>> print "%s" % node3 + + >>> 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: + 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\:·: diff --git a/gbp/rpm/policy.py b/gbp/rpm/policy.py new file mode 100644 index 00000000..f8cb8630 --- /dev/null +++ b/gbp/rpm/policy.py @@ -0,0 +1,72 @@ +# 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""" + + # Special rpmlib python module for GBP (only) + python_rpmlib_module_name = "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 + diff --git a/tests/20_test_rpm.py b/tests/20_test_rpm.py new file mode 100644 index 00000000..227a1c68 --- /dev/null +++ b/tests/20_test_rpm.py @@ -0,0 +1,383 @@ +# 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_ # pylint: disable=E0611 + +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') +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 RpmTestBase(object): + """Test base class""" + def __init__(self): + self.tmpdir = None + + 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 TestSpecFile(RpmTestBase): + """Test L{gbp.rpm.SpecFile}""" + + 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""" + 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) + + 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) + 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 + 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') + 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(RpmTestBase): + """Test utility functions of L{gbp.rpm}""" + + 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 = 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 + 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\:·: diff --git a/tests/data/rpm/rpmbuild/SOURCES/bar.tar.gz b/tests/data/rpm/rpmbuild/SOURCES/bar.tar.gz new file mode 100644 index 00000000..f5dae803 Binary files /dev/null and b/tests/data/rpm/rpmbuild/SOURCES/bar.tar.gz differ diff --git a/tests/data/rpm/rpmbuild/SOURCES/foo.txt b/tests/data/rpm/rpmbuild/SOURCES/foo.txt new file mode 100644 index 00000000..25ed442f --- /dev/null +++ b/tests/data/rpm/rpmbuild/SOURCES/foo.txt @@ -0,0 +1,3 @@ +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 new file mode 100644 index 00000000..7d0759fe Binary files /dev/null and b/tests/data/rpm/rpmbuild/SOURCES/gbp-test-1.0.tar.bz2 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 new file mode 100644 index 00000000..22a273d1 Binary files /dev/null and b/tests/data/rpm/rpmbuild/SOURCES/gbp-test-native-1.0.zip 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 new file mode 100644 index 00000000..7b3eaf3c Binary files /dev/null and b/tests/data/rpm/rpmbuild/SOURCES/gbp-test2-3.0.tar.gz differ diff --git a/tests/data/rpm/rpmbuild/SOURCES/my.patch b/tests/data/rpm/rpmbuild/SOURCES/my.patch new file mode 100644 index 00000000..50870df2 --- /dev/null +++ b/tests/data/rpm/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/data/rpm/rpmbuild/SOURCES/my2.patch b/tests/data/rpm/rpmbuild/SOURCES/my2.patch new file mode 100644 index 00000000..ad5ca2d2 --- /dev/null +++ b/tests/data/rpm/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/data/rpm/rpmbuild/SOURCES/my3.patch b/tests/data/rpm/rpmbuild/SOURCES/my3.patch new file mode 100644 index 00000000..9fee859d --- /dev/null +++ b/tests/data/rpm/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/data/rpm/rpmbuild/SPECS/gbp-test-native.spec b/tests/data/rpm/rpmbuild/SPECS/gbp-test-native.spec new file mode 100644 index 00000000..38b07e48 --- /dev/null +++ b/tests/data/rpm/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/data/rpm/rpmbuild/SPECS/gbp-test-native2.spec b/tests/data/rpm/rpmbuild/SPECS/gbp-test-native2.spec new file mode 100644 index 00000000..34fd33dc --- /dev/null +++ b/tests/data/rpm/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/data/rpm/rpmbuild/SPECS/gbp-test.spec b/tests/data/rpm/rpmbuild/SPECS/gbp-test.spec new file mode 100644 index 00000000..c46a734e --- /dev/null +++ b/tests/data/rpm/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/data/rpm/rpmbuild/SPECS/gbp-test2.spec b/tests/data/rpm/rpmbuild/SPECS/gbp-test2.spec new file mode 100644 index 00000000..8a92725d --- /dev/null +++ b/tests/data/rpm/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/data/rpm/specs/gbp-test-native.spec b/tests/data/rpm/specs/gbp-test-native.spec new file mode 120000 index 00000000..60de36f2 --- /dev/null +++ b/tests/data/rpm/specs/gbp-test-native.spec @@ -0,0 +1 @@ +../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 new file mode 120000 index 00000000..ad13ad6a --- /dev/null +++ b/tests/data/rpm/specs/gbp-test-native2.spec @@ -0,0 +1 @@ +../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 new file mode 100644 index 00000000..bb56b008 --- /dev/null +++ b/tests/data/rpm/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/data/rpm/specs/gbp-test-reference.spec b/tests/data/rpm/specs/gbp-test-reference.spec new file mode 100644 index 00000000..050d1398 --- /dev/null +++ b/tests/data/rpm/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/data/rpm/specs/gbp-test-reference2.spec b/tests/data/rpm/specs/gbp-test-reference2.spec new file mode 100644 index 00000000..0fbe0260 --- /dev/null +++ b/tests/data/rpm/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/data/rpm/specs/gbp-test-tags.spec b/tests/data/rpm/specs/gbp-test-tags.spec new file mode 100644 index 00000000..ee4c2b94 --- /dev/null +++ b/tests/data/rpm/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/data/rpm/specs/gbp-test-updates-reference.spec b/tests/data/rpm/specs/gbp-test-updates-reference.spec new file mode 100644 index 00000000..ff56f589 --- /dev/null +++ b/tests/data/rpm/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/data/rpm/specs/gbp-test-updates.spec b/tests/data/rpm/specs/gbp-test-updates.spec new file mode 100644 index 00000000..dc8ffbf9 --- /dev/null +++ b/tests/data/rpm/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/data/rpm/specs/gbp-test.spec b/tests/data/rpm/specs/gbp-test.spec new file mode 120000 index 00000000..30ae2845 --- /dev/null +++ b/tests/data/rpm/specs/gbp-test.spec @@ -0,0 +1 @@ +../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 new file mode 100644 index 00000000..1882131f --- /dev/null +++ b/tests/data/rpm/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/data/rpm/specs/gbp-test2-reference2.spec b/tests/data/rpm/specs/gbp-test2-reference2.spec new file mode 100644 index 00000000..d41f4503 --- /dev/null +++ b/tests/data/rpm/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/data/rpm/specs/gbp-test2.spec b/tests/data/rpm/specs/gbp-test2.spec new file mode 120000 index 00000000..af4080cb --- /dev/null +++ b/tests/data/rpm/specs/gbp-test2.spec @@ -0,0 +1 @@ +../rpmbuild/SPECS/gbp-test2.spec \ No newline at end of file -- cgit v1.2.3 From 00db052c6e2e1865a7981f5fbe48841a6185f9e2 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 736b9d889b5ff5d3a5abd6ec18564ff81696d8c4 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 --- .gitmodules | 3 + gbp/config.py | 30 +++ gbp/scripts/import_srpm.py | 461 ++++++++++++++++++++++++++++++++ tests/01_test_help.py | 9 + tests/component/rpm/__init__.py | 30 +++ tests/component/rpm/data | 1 + tests/component/rpm/test_import_srpm.py | 343 ++++++++++++++++++++++++ 7 files changed, 877 insertions(+) create mode 100755 gbp/scripts/import_srpm.py 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/gbp/config.py b/gbp/config.py index 3fa59186..02a6f06f 100644 --- a/gbp/config.py +++ b/gbp/config.py @@ -516,4 +516,34 @@ 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({ + 'tmp-dir' : '/var/tmp/gbp/', + 'packaging-branch' : 'master', + 'packaging-dir' : '', + 'packaging-tag' : 'packaging/%(version)s', + }) + + help = dict(GbpOptionParser.help) + help.update({ + 'tmp-dir': + "Base directory under which temporary directories are " + "created, default is '%(tmp-dir)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'", + '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\:·: diff --git a/gbp/scripts/import_srpm.py b/gbp/scripts/import_srpm.py new file mode 100755 index 00000000..7fd5a4e7 --- /dev/null +++ b/gbp/scripts/import_srpm.py @@ -0,0 +1,461 @@ +# 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 glob +import time +import shutil +import errno +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) +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 +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. +""" + +class SkipImport(Exception): + """Nothing imported""" + 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): + """Download package from a remote location""" + if re.match(r'[a-z]{1,5}://', pkg): + mode = 'python urllib2' + else: + mode = 'yumdownloader' + + 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=tmpdir) + else: + download_file(tmpdir, pkg) + srpm = glob.glob(os.path.join(tmpdir, '*.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, tag_format, tag_str_fields): + "Move tag out of the way appending the current timestamp" + 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) + + +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 = False + + +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) + # Checkout packaging branch + repo.set_branch(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') + 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_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="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, options.color_scheme) + return options, args + + +def main(argv): + """Main function of the git-import-srpm script""" + dirs = dict(top=os.path.abspath(os.curdir)) + + ret = 0 + skipped = False + + 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'] = tempfile.mkdtemp(dir=options.tmp_dir, + prefix='import-srpm') + except GbpError as err: + gbp.log.err(err) + return 1 + try: + srpm = args[0] + if options.download: + 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']) + 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 = 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 = SpecFile(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(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']) + except OSError as err: + if err.errno != errno.EEXIST: + raise + + 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)) + # 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): + shutil.copy2(fpath, dirs['packaging']) + else: + 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']) + 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) + 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 sources and packaging files + author = None + if spec.packager: + match = re.match(r'(?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 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) + + 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 + "\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) + 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, + sign=options.sign_tags, + keyid=options.keyid) + + if not options.native: + if options.pristine_tar: + 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") + + # 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: + 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 + "\n" + "Also check the --create-missing-branches " + "option.") + raise GbpError + + 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, + 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), + 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) + + # Create packaging tag + repo.create_tag(name=tag, + msg=msg, + commit=commit, + sign=options.sign_tags, + keyid=options.keyid) + + force_to_branch_head(repo, options.packaging_branch) + + except KeyboardInterrupt: + ret = 1 + gbp.log.err("Interrupted. Aborting.") + except gbpc.CommandExecFailed: + ret = 1 + except GitRepositoryError as err: + gbp.log.err("Git command failed: %s" % err) + ret = 1 + except GbpError as err: + if len(err.__str__()): + gbp.log.err(err) + ret = 1 + except NoSpecError as err: + gbp.log.err("Failed determine spec file: %s" % err) + ret = 1 + except SkipImport: + skipped = True + finally: + os.chdir(dirs['top']) + gbpc.RemoveTree(dirs['tmp_base'])() + + if not ret and not skipped: + gbp.log.info("Version '%s' imported under '%s'" % (ver_str, spec.name)) + 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/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\:·: 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..90bf36d7 --- /dev/null +++ b/tests/component/rpm/data @@ -0,0 +1 @@ +Subproject commit 90bf36d7981fdd1677cf7e734d9e1056a5fced1c diff --git a/tests/component/rpm/test_import_srpm.py b/tests/component/rpm/test_import_srpm.py new file mode 100644 index 00000000..8c3f69e2 --- /dev/null +++ b/tests/component/rpm/test_import_srpm.py @@ -0,0 +1,343 @@ +# 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, eq_, ok_ # 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 + +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""" + eq_(mock_import([]), 1) + with assert_raises(SystemExit): + 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') + eq_(mock_import([srpm]), 0) + # Check repository state + repo = GitRepository('gbp-test') + files = {'Makefile', 'README', 'bar.tar.gz', 'dummy.sh', 'foo.txt', + 'gbp-test.spec', 'my.patch', 'my2.patch', 'my3.patch'} + self._check_repo_state(repo, 'master', ['master', 'upstream'], files) + # Two commits: upstream and packaging files + eq_(len(repo.get_commits()), 2) + + 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) + # Check repository state + repo = GitRepository('gbp-test2') + files = {'Makefile', 'README', 'bar.tar.gz', 'dummy.sh', 'foo.txt', + 'gbp-test2.spec', 'gbp-test2-alt.spec', 'my.patch', + 'my2.patch', 'my3.patch'} + self._check_repo_state(repo, 'master', ['master', 'upstream'], files) + + # Two commits: upstream and packaging files + eq_(len(repo.get_commits()), 2) + + 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') + eq_(mock_import(['--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'} + self._check_repo_state(repo, 'master', ['master', 'upstream'], files) + # Only one commit: the packaging files + 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') + eq_(mock_import(['--native', srpm]), 0) + # Check repository state + 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 + 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') + 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 + eq_(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') ] + eq_(mock_import([srpms[0]]), 0) + repo = GitRepository('gbp-test') + self._check_repo_state(repo, 'master', ['master', 'upstream']) + eq_(len(repo.get_commits()), 2) + # Try to import same version again + eq_(mock_import([srpms[1]]), 0) + eq_(len(repo.get_commits()), 2) + eq_(len(repo.get_commits(until='upstream')), 1) + eq_(mock_import(['--allow-same-version', srpms[1]]), 0) + # Added new version of packaging + eq_(len(repo.get_commits()), 3) + eq_(len(repo.get_commits(until='upstream')), 1) + # Import new version + eq_(mock_import([srpms[2]]), 0) + files = {'Makefile', 'README', 'bar.tar.gz', 'dummy.sh', 'foo.txt', + 'gbp-test.spec', 'my.patch', 'my2.patch', 'my3.patch'} + self._check_repo_state(repo, 'master', ['master', 'upstream'], files) + eq_(len(repo.get_commits()), 5) + 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) + + 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') + 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 + eq_(mock_import([srpm]), 1) + self._check_log(-1, 'Also check the --create-missing-branches') + eq_(mock_import(['--create-missing', srpm]), 0) + self._check_repo_state(repo, 'master', ['master', 'upstream']) + # Four commits: our initial, upstream and packaging files + eq_(len(repo.get_commits()), 3) + + # The import should fail because missing packaging-branch + srpm = os.path.join(DATA_DIR, 'gbp-test-1.1-1.src.rpm') + 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') + 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', + 'gbp-test.spec', 'my.patch', 'my2.patch', 'my3.patch']) + 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') + + eq_(mock_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') + 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) + eq_(len(repo.get_commits()), 2) + # Check packaging dir + eq_(len(repo.get_commits(paths='packaging')), 1) + # Check tags + tags = repo.get_tags() + eq_(set(tags), set(['orig/2.0', 'ver_2.0-rel_0'])) + # Check git committer/author + info = repo.get_commit_info('pack') + 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): + """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""" + 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 + 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' + eq_(mock_import([specfile]), 0) + # Check repository state + 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') + eq_(mock_import([specfile]), 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') + + eq_(mock_import(['--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) + + 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' + eq_(mock_import(['--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') + eq_(mock_import(['--pristine-tar', srpm]), 0) + # Check repository state + repo = GitRepository('gbp-test') + self._check_repo_state(repo, 'master', ['master', 'upstream', + 'pristine-tar']) + # Two commits: upstream and packaging files + eq_(len(repo.get_commits()), 2) + + 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') + eq_(mock_import(['--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""" + + 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') + eq_(mock_import([srpm]), 0) + self._check_repo_state(repo, 'master', ['master', 'upstream']) + # Patch import to bare repos not supported -> only 2 commits + 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 2bf944f14ceef34cd50afd7786b6627c6bd7df72 Mon Sep 17 00:00:00 2001 From: Guido Günther 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 --- tests/component/rpm/test_import_srpm.py | 22 +++++++++++----------- 1 file changed, 11 insertions(+), 11 deletions(-) diff --git a/tests/component/rpm/test_import_srpm.py b/tests/component/rpm/test_import_srpm.py index 8c3f69e2..d0e71701 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 = {'Makefile', 'README', 'bar.tar.gz', 'dummy.sh', 'foo.txt', @@ -63,7 +63,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 = {'Makefile', 'README', 'bar.tar.gz', 'dummy.sh', 'foo.txt', @@ -80,7 +80,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 = {'bar.tar.gz', 'foo.txt', 'gbp-test2.spec', @@ -116,7 +116,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()), 2) @@ -124,12 +124,12 @@ class TestImportPacked(ComponentTestBase): eq_(mock_import([srpms[1]]), 0) eq_(len(repo.get_commits()), 2) eq_(len(repo.get_commits(until='upstream')), 1) - eq_(mock_import(['--allow-same-version', srpms[1]]), 0) + eq_(mock_import(['--no-pristine-tar', '--allow-same-version', srpms[1]]), 0) # Added new version of packaging eq_(len(repo.get_commits()), 3) eq_(len(repo.get_commits(until='upstream')), 1) # Import new version - eq_(mock_import([srpms[2]]), 0) + eq_(mock_import(['--no-pristine-tar', srpms[2]]), 0) files = {'Makefile', 'README', 'bar.tar.gz', 'dummy.sh', 'foo.txt', 'gbp-test.spec', 'my.patch', 'my2.patch', 'my3.patch'} self._check_repo_state(repo, 'master', ['master', 'upstream'], files) @@ -160,7 +160,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 and packaging files eq_(len(repo.get_commits()), 3) @@ -174,7 +174,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', @@ -185,7 +185,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([ + eq_(mock_import(['--no-pristine-tar', '--packaging-branch=pack', '--upstream-branch=orig', '--packaging-dir=packaging', @@ -231,7 +231,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']) @@ -269,7 +269,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 ed228a25059d4600a0e3155151febb8c8e1f66fb 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 --- gbp/config.py | 3 +++ gbp/scripts/import_srpm.py | 7 ++++--- 2 files changed, 7 insertions(+), 3 deletions(-) diff --git a/gbp/config.py b/gbp/config.py index 02a6f06f..af21fb8a 100644 --- a/gbp/config.py +++ b/gbp/config.py @@ -524,6 +524,7 @@ 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', @@ -534,6 +535,8 @@ class GbpOptionParserRpm(GbpOptionParser): 'tmp-dir': "Base directory under which temporary directories are " "created, default is '%(tmp-dir)s'", + 'vendor': + "Distribution vendor name, default is '%(vendor)s'", 'packaging-branch': "Branch the packaging is being maintained on, rpm counterpart " "of the 'debian-branch' option, default is " diff --git a/gbp/scripts/import_srpm.py b/gbp/scripts/import_srpm.py index 7fd5a4e7..193b9245 100755 --- a/gbp/scripts/import_srpm.py +++ b/gbp/scripts/import_srpm.py @@ -143,6 +143,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") branch_group.add_config_file_option(option_name="packaging-branch", @@ -301,7 +303,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) @@ -388,8 +390,7 @@ def main(argv): raise GbpError 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 23090c9c4e2f2654064269e66da8efba103f0515 Mon Sep 17 00:00:00 2001 From: Guido Günther Date: Thu, 24 Jul 2014 23:12:30 +0200 Subject: Introduce git-buildpackage-rpm Currently only including "gbp import-srpm" --- .gitignore | 8 ++++---- debian/control | 17 +++++++++++++++++ debian/git-buildpackage-rpm.install | 2 ++ debian/git-buildpackage.install | 30 ++++++++++++++++++++++++++++++ 4 files changed, 53 insertions(+), 4 deletions(-) create mode 100644 debian/git-buildpackage-rpm.install create mode 100644 debian/git-buildpackage.install 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 a5dad37b..58d9a35a 100644 --- a/debian/control +++ b/debian/control @@ -14,10 +14,13 @@ Build-Depends: python-coverage, python-dateutil, python-epydoc, + python-mock, python-nose, python-nosexcover, python-pkg-resources, + python-rpm, python-setuptools, + rpm, sgml2x, # For the testsuite bzip2, @@ -54,3 +57,17 @@ 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}, + ${misc:Depends}, + git-buildpackage (= ${binary:Version}), + python-rpm, + rpm, +Recommends: pristine-tar (>= 0.5) +Suggests: python-notify, unzip +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 + repository diff --git a/debian/git-buildpackage-rpm.install b/debian/git-buildpackage-rpm.install new file mode 100644 index 00000000..67c03097 --- /dev/null +++ b/debian/git-buildpackage-rpm.install @@ -0,0 +1,2 @@ +usr/lib/python2.?/dist-packages/gbp/rpm/ +usr/lib/python2.7/dist-packages/gbp/scripts/import_srpm.py diff --git a/debian/git-buildpackage.install b/debian/git-buildpackage.install new file mode 100644 index 00000000..9d46900f --- /dev/null +++ b/debian/git-buildpackage.install @@ -0,0 +1,30 @@ +usr/bin/ +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/dch.py +usr/lib/python2.?/dist-packages/gbp/deb/ +usr/lib/python2.?/dist-packages/gbp/errors.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/buildpackage.py +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/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/__init__.py +usr/lib/python2.?/dist-packages/gbp/scripts/pq.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 +etc/git-buildpackage/gbp.conf -- cgit v1.2.3 From 3f43e4ee68d2a169a3e604a6bd0b60f99b71d812 Mon Sep 17 00:00:00 2001 From: Guido Günther 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 243b6fca2739d03f6e1086d23473d178f42df530 Mon Sep 17 00:00:00 2001 From: Guido Günther 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 4ef22563..7abb16d1 100644 --- a/tests/component/__init__.py +++ b/tests/component/__init__.py @@ -153,6 +153,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 b305116a285ae4028e6028297e2c1c9c6c60dded Mon Sep 17 00:00:00 2001 From: Guido Günther Date: Mon, 28 Jul 2014 16:00:12 +0200 Subject: Document changes and release 0.6.16 --- debian/changelog | 20 ++++++++++++++++++++ 1 file changed, 20 insertions(+) diff --git a/debian/changelog b/debian/changelog index 93d533c1..055ceb2c 100644 --- a/debian/changelog +++ b/debian/changelog @@ -1,3 +1,23 @@ +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 * [5cde49a] Revert "Determine build_dir upfront" -- cgit v1.2.3 From 692e5da2efa8f691a75200cf16df06112ffad435 Mon Sep 17 00:00:00 2001 From: Guido Günther 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 c0344805..20a7b1b5 100644 --- 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 688c7c3db3d5e1e04c9dfde01394d5e7fcb20dec 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 20a7b1b5..c6172698 100644 --- 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 7cc96699f234303bc86908172fabcd6177b18571 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 c6172698..49333882 100644 --- 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'") @@ -512,11 +512,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 c3258c19c6cfa291c8bebac1dae230f6e3ccca36 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 49333882..126f3b77 100644 --- 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 6823e519deaf2a37a3d6225cd0392954c423b569 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 --- docs/manpages/gbp-buildpackage.sgml | 13 +++++++++++-- gbp.conf | 1 + gbp/config.py | 4 ++++ gbp/scripts/buildpackage.py | 7 +++++-- 4 files changed, 21 insertions(+), 4 deletions(-) diff --git a/docs/manpages/gbp-buildpackage.sgml b/docs/manpages/gbp-buildpackage.sgml index d0d68bc6..42e6fc78 100644 --- a/docs/manpages/gbp-buildpackage.sgml +++ b/docs/manpages/gbp-buildpackage.sgml @@ -44,8 +44,9 @@ COMMAND COMMAND - TAG-FORMAT - TAG-FORMAT + tag-format + tag-format + tag-msg-format [TAG|BRANCH|TREEISH] @@ -430,6 +431,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 af21fb8a..e0cd779a 100644 --- a/gbp/config.py +++ b/gbp/config.py @@ -106,6 +106,7 @@ class GbpOptionParser(OptionParser): 'postimport' : '', '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', @@ -167,6 +168,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 457673c9..86cf2703 100755 --- a/gbp/scripts/buildpackage.py +++ b/gbp/scripts/buildpackage.py @@ -402,6 +402,7 @@ def build_parser(name, prefix=None): 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-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") @@ -602,9 +603,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 ae5805e4db74e844f78777c2fd91f409e0fcd7a8 Mon Sep 17 00:00:00 2001 From: Guido Günther 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. --- debian/git-buildpackage.install | 1 + gbp/deb/git.py | 3 ++- gbp/format.py | 44 +++++++++++++++++++++++++++++++++++++++++ gbp/scripts/buildpackage.py | 7 ++++--- gbp/scripts/import_orig.py | 3 ++- 5 files changed, 53 insertions(+), 5 deletions(-) create mode 100644 gbp/format.py diff --git a/debian/git-buildpackage.install b/debian/git-buildpackage.install index 9d46900f..1a25e1dc 100644 --- a/debian/git-buildpackage.install +++ b/debian/git-buildpackage.install @@ -5,6 +5,7 @@ usr/lib/python2.?/dist-packages/gbp/config.py usr/lib/python2.?/dist-packages/gbp/dch.py usr/lib/python2.?/dist-packages/gbp/deb/ 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 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 86cf2703..ef058aed 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 @@ -603,9 +604,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 8eed96b5..a08c1c32 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.scripts.common.import_orig import (orig_needs_repack, cleanup_tmp_tree, ask_package_name, ask_package_version, @@ -373,7 +374,7 @@ def main(argv): epoch = '%s:' % cp.epoch info = { 'version': "%s%s-1" % (epoch, version) } env = { 'GBP_BRANCH': options.debian_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 5f82f445abbab55a6b2ad8d82b8ddf21eff69628 Mon Sep 17 00:00:00 2001 From: Guido Günther 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 04aa92f1d283e5995998d70580de0c8c21c40133 Mon Sep 17 00:00:00 2001 From: Guido Günther 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 68c053ff469eb48efbbc4f6d20cd6f9cdec9ff3d Mon Sep 17 00:00:00 2001 From: Guido Günther 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 ef058aed..e96e8e77 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 62d0dcc2..8078854b 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 f0e680b4..b8923cd1 100644 --- 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 126f3b77..0faa1b45 100644 --- 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 ce97fcb0..c0bf6504 100644 --- 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 28413faf..2a71560e 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 a08c1c32..6256431c 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 193b9245..958f5ff7 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 ea33c26c..3186de5b 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 fb0d8271..65e3e492 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 6d510cedb99249198963d1bc38e56c8c39f14c1f Mon Sep 17 00:00:00 2001 From: Guido Günther 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 f6e3104958708a5fda10a154eec8e7e22c9a5e0c Mon Sep 17 00:00:00 2001 From: Guido Günther Date: Sun, 24 Aug 2014 11:31:57 +0200 Subject: Document changes and release 0.6.17 --- debian/changelog | 22 ++++++++++++++++++++++ 1 file changed, 22 insertions(+) diff --git a/debian/changelog b/debian/changelog index 055ceb2c..a33f0432 100644 --- a/debian/changelog +++ b/debian/changelog @@ -1,3 +1,25 @@ +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 6edd8363eab02832f8bb58f3405609503b6458af Mon Sep 17 00:00:00 2001 From: Guido Günther 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 a37832e418f3b96acf1c14838a495e2bc08fa574 Mon Sep 17 00:00:00 2001 From: Guido Günther 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 b744752a..31f433b4 100644 --- a/docs/manpages/gbp-import-orig.sgml +++ b/docs/manpages/gbp-import-orig.sgml @@ -76,7 +76,7 @@ - + Merge the upstream branch to the debian branch after import -- cgit v1.2.3 From d9dd13d37159fb6997498f665c6f7a95301d50ee Mon Sep 17 00:00:00 2001 From: Guido Günther Date: Sat, 6 Sep 2014 13:41:27 +0200 Subject: Document changes and release 0.6.18 --- debian/changelog | 9 +++++++++ 1 file changed, 9 insertions(+) diff --git a/debian/changelog b/debian/changelog index a33f0432..ae1eeb4e 100644 --- a/debian/changelog +++ b/debian/changelog @@ -1,3 +1,12 @@ +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 5d4cb9208f72e20cfd4d457b5d885a44859c40ef Mon Sep 17 00:00:00 2001 From: Guido Günther 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 e3ea8907d7ef653fe03f0e870a4955deb6a9d9cc Mon Sep 17 00:00:00 2001 From: Guido Günther Date: Sun, 7 Sep 2014 09:25:53 +0200 Subject: Document changes and release 0.6.19 --- debian/changelog | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/debian/changelog b/debian/changelog index ae1eeb4e..50b1bea5 100644 --- a/debian/changelog +++ b/debian/changelog @@ -1,3 +1,9 @@ +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 ee4447920b41cad774f1494c0e2b2312ca3a5a9a Mon Sep 17 00:00:00 2001 From: Guido Günther Date: Fri, 12 Sep 2014 13:05:47 +0200 Subject: Allow to always drop pq branch after export Closes: #761160 --- 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 e0cd779a..0580cc51 100644 --- a/gbp/config.py +++ b/gbp/config.py @@ -155,6 +155,7 @@ class GbpOptionParser(OptionParser): 'allow-unauthenticated': 'False', 'symlink-orig': 'True', 'purge': 'True', + 'drop': 'False', } help = { 'debian-branch': @@ -294,6 +295,9 @@ class GbpOptionParser(OptionParser): "'%(symlink-orig)s'"), 'purge': "Purge exported package build directory. Default is '%(purge)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 3186de5b..80520d49 100755 --- a/gbp/scripts/pq.py +++ b/gbp/scripts/pq.py @@ -94,6 +94,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): """ @@ -234,6 +237,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 753143d3..910ce206 100644 --- a/tests/13_test_gbp_pq.py +++ b/tests/13_test_gbp_pq.py @@ -21,7 +21,7 @@ import os import logging 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 @@ -132,5 +132,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 51ac0a5a7026301704b92d8fd6affd098a1442b5 Mon Sep 17 00:00:00 2001 From: Guido Günther 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 e0942083..f1afb04d 100644 --- a/docs/manpages/gbp-pq.sgml +++ b/docs/manpages/gbp-pq.sgml @@ -23,6 +23,7 @@ topic num + @@ -156,6 +157,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 90b283fefe8345eb7fd0f219bb64710cf535703a Mon Sep 17 00:00:00 2001 From: Guido Günther 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 0580cc51..93506141 100644 --- a/gbp/config.py +++ b/gbp/config.py @@ -201,6 +201,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 0faa1b45..ce19c9a6 100644 --- 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 0afcd3d359f078013474a2fec43eaaed823d67d2 Mon Sep 17 00:00:00 2001 From: Guido Günther 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. --- 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 93506141..174eba42 100644 --- a/gbp/config.py +++ b/gbp/config.py @@ -156,6 +156,7 @@ class GbpOptionParser(OptionParser): 'symlink-orig': 'True', 'purge': 'True', 'drop': 'False', + 'commit': 'False', } help = { 'debian-branch': @@ -300,6 +301,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 80520d49..d9f49d4f 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") @@ -67,6 +68,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): @@ -90,7 +151,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) @@ -238,11 +306,13 @@ 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="meta-closes", dest="meta_closes") return parser -- cgit v1.2.3 From 8ff800d817989c3d32ef7af829b9a6d962f29ef6 Mon Sep 17 00:00:00 2001 From: Guido Günther Date: Sun, 12 Oct 2014 11:42:52 +0200 Subject: Document changes and release 0.6.20 --- debian/changelog | 11 +++++++++++ 1 file changed, 11 insertions(+) diff --git a/debian/changelog b/debian/changelog index 50b1bea5..ce6c0654 100644 --- a/debian/changelog +++ b/debian/changelog @@ -1,3 +1,14 @@ +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 81dab4be2a8941767b524af79ca22991c0dce109 Mon Sep 17 00:00:00 2001 From: Guido Günther 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 d9f49d4f..e78f92cc 100755 --- a/gbp/scripts/pq.py +++ b/gbp/scripts/pq.py @@ -116,8 +116,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 740e431fc4113be86df6bf87bb8a0a7167f583f3 Mon Sep 17 00:00:00 2001 From: Guido Günther 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 42e6fc78..0e5561ef 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 22a698736486f1097e034ae9c5c432f39fdaa239 Mon Sep 17 00:00:00 2001 From: Guido Günther 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 e78f92cc..194145e8 100755 --- a/gbp/scripts/pq.py +++ b/gbp/scripts/pq.py @@ -159,9 +159,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 e08d64d9d01aff2e398906788150b9fd3029e571 Mon Sep 17 00:00:00 2001 From: Guido Günther 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 fb6f6245..3337c21a 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 773496389a41f077db3806050230c0327a146c7b Mon Sep 17 00:00:00 2001 From: Guido Günther Date: Fri, 17 Oct 2014 18:29:15 +0200 Subject: Update README a bit Git-Dch: Ignore --- README | 13 ++++++++++--- 1 file changed, 10 insertions(+), 3 deletions(-) diff --git a/README b/README index 3301ae61..7a827fb1 100644 --- a/README +++ b/README @@ -1,7 +1,14 @@ +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/ -- cgit v1.2.3 From e94709baab527ca7a11182cc024a84cff05c8704 Mon Sep 17 00:00:00 2001 From: Guido Günther Date: Fri, 17 Oct 2014 18:41:21 +0200 Subject: Document changes and release 0.6.21 --- debian/changelog | 10 ++++++++++ 1 file changed, 10 insertions(+) diff --git a/debian/changelog b/debian/changelog index ce6c0654..6efb4382 100644 --- a/debian/changelog +++ b/debian/changelog @@ -1,3 +1,13 @@ +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 3d8939d4514484fd65bf6a84fd7304604924e8f3 Mon Sep 17 00:00:00 2001 From: Guido Günther 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 4c9d692d52fd3fdf72733b07a5c4d5da3a128ca8 Mon Sep 17 00:00:00 2001 From: Guido Günther Date: Wed, 29 Oct 2014 07:47:29 +0100 Subject: Document changes and release 0.6.22 --- debian/changelog | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/debian/changelog b/debian/changelog index 6efb4382..f26464ce 100644 --- a/debian/changelog +++ b/debian/changelog @@ -1,3 +1,10 @@ +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