diff options
49 files changed, 787 insertions, 184 deletions
diff --git a/.gitmodules b/.gitmodules index 3b52b91f..19d19953 100644 --- a/.gitmodules +++ b/.gitmodules @@ -1,6 +1,6 @@ [submodule "tests/component/deb/data"] path = tests/component/deb/data - url = git://honk.sigxcpu.org/git/gbp/deb-testdata + url = 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 + url = git://github.com/marquiz/git-buildpackage-rpm-testdata.git @@ -1,10 +1,17 @@ +Git-buildpackage +---------------- This is a bunch of scripts to ease the development of Debian packages with git. -For more documentation see the manual. On Debian systems this can be found in +For more documentation on howto use these tools see the manual +online at: + + http://honk.sigxcpu.org/projects/git-buildpackage/manual-html/gbp.html + +On Debian systems this can be found in /usr/share/doc/git-buildpackage/manual-html. -It can be found online at +The API documentation of the gbp module can be found at: - http://honk.sigxcpu.org/projects/git-buildpackage/manual-html/gbp.html + http://honk.sigxcpu.org/projects/git-buildpackage/apidocs/ The limited documentation available for the RPM support can be found at diff --git a/bin/git-pbuilder b/bin/git-pbuilder index 4024d124..a003b266 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 <eagle@eyrie.org> # Based on the example in the git-buildpackage documentation +# Copyright 2014 Russ Allbery <eagle@eyrie.org> # Copyright 2008, 2009, 2010, 2011, 2012, 2013 # The Board of Trustees of the Leland Stanford Junior University # @@ -264,7 +265,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 + if [ x'-S' = x"$arg" ] ; then + source_only=true + fi DEBBUILDOPTS+=" $(shell_quote "$arg")" done @@ -278,7 +283,7 @@ else --debbuildopts "$DEBBUILDOPTS" -- "${OPTIONS[@]}" fi status="$?" -if [ -n "`ls ../*_source.changes`" ] ; then +if [ -n "`ls ../*_source.changes`" ] && [ true != "$source_only" ] ; then rm ../*_source.changes fi exit "$status" diff --git a/debian/changelog b/debian/changelog index 545b7576..ee6ad668 100644 --- a/debian/changelog +++ b/debian/changelog @@ -1,24 +1,70 @@ -git-buildpackage (0.6.25-tizen20150721) unstable; urgency=low - - * Upgrade version to 0.6.25-20150721 - - -- SoonKyu Park <sk7.park@samsung.com> Tue, 21 Jul 2015 15:23:00 +0900 - -git-buildpackage (0.6.25) unstable; urgency=medium +git-buildpackage (0.6.27-tizen20160302) unstable; urgency=medium + + * Fix error logs when __import__ faild,like "No handlers could be found fo logger" + * Fix build problem on Debian 8 + + -- Jun Wang <junbill.wangx@samsung.com> Wed, 02 Mar 2016 07:47:21 +0100 + +git-buildpackage (0.6.22-tizen20150206) unstable; urgency=low + + * Rebase on top of upstream version 0.6.22 + * Experimental support for BitBake + - Introduce import-bb tool. + This is the first tool in an effort of enabling gbp in the BitBake build + environment. Gbp-import-bb is a tool for importing packages from a + BitBake-based "combined" distro repository into individual per-package + Git repositories. + - Introduce pq-bb tool. + This is a tool for managing patch-queues for packages maintained in the + BitBake packaging format (.bb recipes). + - Introduce buildpackage-bb tool. + Initial version of the tool for building BitBake packages from Git. + NOTE: The buildpackage-bb tool itself is able to operate even without an + initialized BitBake build environment although the build likely fails in + this case. However, this makes it possible to export the packaging meta + data, for example. + - Introcude clone-bb tool. + This is a new tool for helping to clone remote per-package Git + repositories when working in BitBake-based "full distro" build + environment. This is useful in the case that individual packages are + actually maintained in per-package Git repositories (like Tizen). That + is, the full distro repository that the developer operates in is + composed of the packaging meta data from the individual per-package + repositories. When willing to contribute to a package the developer + would use clone-bb to clone the correct per-package repository and make + his changes there. + NOTE: clone-bb uses GBP_PACKAGING_REPO variable to determine the remote + repository URI. This variable should be defined in the package recipes + in order to make clone-bb usable. + - Introduce submit-bb tool. + This is a Tizen-specific tool for creating and pushing special submit + tags. + * pq-rpm: better error message + * buildpackage-rpm: look for remote upstream branches. + Consider remote branches, too, while looking for the upstream branch + when trying to guess if a package is native or not. + * rpm packaging changes + - enable CentOS 7. + - include python egg-info in -common. + * rpm: suppress stderr when unpacking src.rpm + * UpstreamSource: suppress stderr from tar in _determine_prefix() + * patchseries: strip numbering when guessing subject from filename + * Changes in logging + - don't propagate to ancestor loggers + - don't initialize handlers in GbpLogger init. + Better compatibility with 3rd party modules that have their own logging + initializations. + * Features/fixes in GitRepository + - GitRepository/__git_inout: correctly handle input error + - GitRepository.create_tag: add 'annotate' argument. + For forcing the creation of annotated tags. Causes the an editor to be + spawned if no message is given. + + -- Markus Lehtonen <markus.lehtonen@linux.intel.com> Fri, 06 Feb 2015 10:36:26 +0200 * Upgrade version to 0.6.25 - -- SoonKyu Park <sk7.park@samsung.com> Tue, 21 Jul 2015 15:02:21 +0900 - -git-buildpackage (0.6.15-tizen20150303) unstable; urgency=low - - * Revert "buildpackage-rpm: always create tarball for native packages" - Fixes: DEVT-215 - * debian packaging: fix rpm build deps for Ubuntu 14.10. - Dependencies of python-rpm got broken in Ubuntu 14.10 at the update to - rpm v4.11.2-3ubuntu0.1. This change is a work around for that. - - -- Markus Lehtonen <markus.lehtonen@linux.intel.com> Tue, 03 Mar 2015 17:30:37 +0200 + -- Rong Jinhui <jinhui.rong@samsung.com> Thu, 04 Aug 2015 08:53:30 +0800 git-buildpackage (0.6.15-tizen20140828) unstable; urgency=low @@ -70,6 +116,90 @@ git-buildpackage (0.6.15-tizen20140828) unstable; urgency=low * rpm packaging: use macro for python binary -- Markus Lehtonen <markus.lehtonen@linux.intel.com> Thu, 28 Aug 2014 11:40:05 +0300 +git-buildpackage (0.6.22) unstable; urgency=medium + + * [3d8939d] git.vfs: fix close method. Preventing a infinite recursion + which can be triggered by gbp pq export --commit. + + -- Guido Günther <agx@sigxcpu.org> 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 + 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 <agx@sigxcpu.org> 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) + * [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 <agx@sigxcpu.org> Sun, 12 Oct 2014 11:42:27 +0200 + +git-buildpackage (0.6.19) unstable; urgency=medium + + * [5d4cb92] Update to git-pbuilder 1.33 + + -- Guido Günther <agx@sigxcpu.org> Sun, 07 Sep 2014 09:25:48 +0200 + +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 <agx@sigxcpu.org> Sat, 06 Sep 2014 13:41:05 +0200 + +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 <agx@sigxcpu.org> Sun, 24 Aug 2014 11:31:28 +0200 + +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 <agx@sigxcpu.org> Mon, 28 Jul 2014 15:57:49 +0200 git-buildpackage (0.6.15) unstable; urgency=medium diff --git a/debian/control b/debian/control index 856566a1..f8d1a808 100644 --- a/debian/control +++ b/debian/control @@ -16,6 +16,7 @@ Build-Depends: python-pkg-resources, python-setuptools, sgml2x, + librpm-tizen, # For rpm (epydoc) rpm-common, python-rpm 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") @@ -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: @@ -105,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] diff --git a/gbp/config.py b/gbp/config.py index 90c5068d..9fd31b73 100644 --- a/gbp/config.py +++ b/gbp/config.py @@ -112,6 +112,7 @@ class GbpOptionParser(OptionParser): 'build' : 'True', 'hooks' : 'True', 'debian-tag' : 'debian/%(version)s', + 'debian-tag-msg' : '%(pkg)s Debian release %(version)s', 'upstream-tag' : 'upstream/%(version)s', 'import-msg' : 'Imported Upstream version %(version)s', 'commit-msg' : 'Update changelog for %(version)s release', @@ -159,6 +160,8 @@ class GbpOptionParser(OptionParser): 'allow-unauthenticated': 'False', 'symlink-orig': 'True', 'purge': 'True', + 'drop': 'False', + 'commit': 'False', 'tmp-dir' : '/var/tmp/gbp/', } help = { @@ -177,6 +180,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'"), @@ -206,6 +212,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': @@ -302,7 +310,12 @@ class GbpOptionParser(OptionParser): "'%(symlink-orig)s'"), 'purge': "Purge exported package build directory. Default is '%(purge)s'", - 'tmp-dir': + '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'", + 'tmp-dir': ("Base directory under which temporary directories are " "created, default is '%(tmp-dir)s'"), } @@ -672,4 +685,5 @@ class GbpOptionParserRpm(GbpOptionParser): "'%(meta-bts)s'"), } ) + # vim:et:ts=4:sw=4:et:sts=4:ai:set list listchars=tab\:»·,trail\:·: diff --git a/gbp/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 <agx@sigxcpu.org> +# 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/git/repository.py b/gbp/git/repository.py index 6b21c252..20251a00 100644 --- a/gbp/git/repository.py +++ b/gbp/git/repository.py @@ -252,7 +252,12 @@ class GitRepository(object): ready = select.select(out_fds, in_fds, []) # Write in chunks of 512 bytes if ready[1]: - popen.stdin.write(stdin[w_ind:w_ind+512]) + try: + popen.stdin.write(stdin[w_ind:w_ind+512]) + except IOError: + # Ignore, we want to read buffers to e.g. get error message + # Git should give an error code so that we catch an error + pass w_ind += 512 if w_ind > len(stdin): rm_polled_fd(popen.stdin, in_fds) @@ -695,7 +700,8 @@ class GitRepository(object): #{ Tags - def create_tag(self, name, msg=None, commit=None, sign=False, keyid=None): + def create_tag(self, name, msg=None, commit=None, sign=False, keyid=None, + annotate=False): """ Create a new tag. @@ -710,15 +716,18 @@ class GitRepository(object): @type sign: C{bool} @param keyid: the GPG keyid used to sign the tag @type keyid: C{str} + @param annotate: Create an annotated tag + @type annotate: C{bool} """ - args = [] - args += [ '-m', msg ] if msg else [] + args = GitArgs() + args.add_true(msg, ['-m', msg]) if sign: - args += [ '-s' ] - args += [ '-u', keyid ] if keyid else [] - args += [ name ] - args += [ commit ] if commit else [] - self._git_command("tag", args) + args.add('-s') + args.add_true(keyid, ['-u', keyid]) + args.add_true(annotate, '-a') + args.add(name) + args.add_true(commit, commit) + self._git_command("tag", args.args, interactive=True) def delete_tag(self, tag): """ 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): """ @@ -96,29 +96,35 @@ class GbpStreamHandler(logging.StreamHandler): class GbpLogger(logging.Logger): """Logger class for git-buildpackage""" - def __init__(self, name, color='auto', *args, **kwargs): + def __init__(self, name, *args, **kwargs): logging.Logger.__init__(self, name, *args, **kwargs) - self._default_handlers = [GbpStreamHandler(sys.stdout, color), - GbpStreamHandler(sys.stderr, color)] - self._default_handlers[0].addFilter(GbpFilter([DEBUG, INFO])) - self._default_handlers[1].addFilter(GbpFilter([WARNING, ERROR, - CRITICAL])) - for hdlr in self._default_handlers: + self.default_handlers = [] + + def init_default_handlers(self, color='auto'): + """Initialize and set default handlers to logger""" + self.default_handlers = [GbpStreamHandler(sys.stdout, color), + GbpStreamHandler(sys.stderr, color)] + self.default_handlers[0].addFilter(GbpFilter([DEBUG, INFO])) + self.default_handlers[1].addFilter(GbpFilter([WARNING, ERROR, + CRITICAL])) + for hdlr in self.default_handlers: self.addHandler(hdlr) + # We don't want to propagate as we add our own handlers + self.propagate = False def set_color(self, color): """Set/unset colorized output of the default handlers""" - for hdlr in self._default_handlers: + for hdlr in self.default_handlers: hdlr.set_color(color) def set_color_scheme(self, color_scheme={}): """Set the color scheme of the default handlers""" - for hdlr in self._default_handlers: + for hdlr in self.default_handlers: hdlr.set_color_scheme(color_scheme) def set_format(self, fmt): """Set the format of the default handlers""" - for hdlr in self._default_handlers: + for hdlr in self.default_handlers: hdlr.set_format(fmt) @@ -168,7 +174,11 @@ def getLogger(*args, **kwargs): """Gbp-specific function""" if not issubclass(logging.getLoggerClass(), GbpLogger): logging.setLoggerClass(GbpLogger) - return logging.getLogger(*args, **kwargs) + color = kwargs.pop('color') if 'color' in kwargs else 'auto' + logger = logging.getLogger(*args, **kwargs) + if hasattr(logger, 'default_handlers') and not logger.default_handlers: + logger.init_default_handlers(color) + return logger def setup(color, verbose, color_scheme=""): """Basic logger setup""" diff --git a/gbp/patch_series.py b/gbp/patch_series.py index 10fccfc6..327997f5 100644 --- a/gbp/patch_series.py +++ b/gbp/patch_series.py @@ -95,6 +95,12 @@ class Patch(object): >>> p = Patch('debian/patches/foo') >>> p._get_subject_from_filename() 'foo' + >>> Patch('0123-foo.patch')._get_subject_from_filename() + 'foo' + >>> Patch('0123.patch')._get_subject_from_filename() + '0123' + >>> Patch('0123-foo-0123.patch')._get_subject_from_filename() + 'foo-0123' @return: the patch's subject @rtype: C{str} @@ -107,7 +113,7 @@ class Patch(object): subject = base except ValueError: pass # No ext so keep subject as is - return subject + return subject.lstrip('0123456789-') or subject def _get_info_field(self, key, get_val=None): """ diff --git a/gbp/pkg/__init__.py b/gbp/pkg/__init__.py index f02caf01..8162286b 100644 --- a/gbp/pkg/__init__.py +++ b/gbp/pkg/__init__.py @@ -38,9 +38,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'), @@ -82,7 +82,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: @@ -90,7 +90,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] @@ -142,8 +142,8 @@ class PkgPolicy(object): return True return 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. @@ -158,7 +158,7 @@ class PkgPolicy(object): >>> PkgPolicy.guess_upstream_src_version('foo-bar_0.2.orig.tar.gz') ('foo-bar', '0.2') >>> PkgPolicy.guess_upstream_src_version('foo-Bar_0.2.orig.tar.gz') - ('foo-Bar', '0.2.orig') + ('', '') >>> PkgPolicy.guess_upstream_src_version('git-bar-0.2.tar.gz') ('git-bar', '0.2') >>> PkgPolicy.guess_upstream_src_version('git-bar-0.2-rc1.tar.gz') @@ -175,14 +175,14 @@ class PkgPolicy(object): ('', '') >>> PkgPolicy.guess_upstream_src_version('foo-bar_0.2.orig.tar.xz') ('foo-bar', '0.2') - >>> PkgPolicy.guess_upstream_src_version('foo-bar_0.2.tar.gz') - ('foo-bar', '0.2') >>> PkgPolicy.guess_upstream_src_version('foo-bar_0.2.orig.tar.lzma') ('foo-bar', '0.2') >>> PkgPolicy.guess_upstream_src_version('foo-bar-0.2.zip') ('foo-bar', '0.2') >>> PkgPolicy.guess_upstream_src_version('foo-bar-0.2.tlz') ('foo-bar', '0.2') + >>> PkgPolicy.guess_upstream_src_version('foo-bar_0.2.tar.gz') + ('foo-bar', '0.2') """ version_chars = r'[a-zA-Z\d\.\~\-\:\+]' basename = parse_archive_filename(os.path.basename(filename))[0] @@ -190,10 +190,11 @@ class PkgPolicy(object): version_filters = map ( lambda x: x % version_chars, ( # Debian upstream tarball: package_'<version>.orig.tar.gz' r'^(?P<package>[a-z\d\.\+\-]+)_(?P<version>%s+)\.orig', + # Debian native: 'package_<version>.tar.gz' + r'^(?P<package>[a-z\d\.\+\-]+)_(?P<version>%s+)', # Upstream 'package-<version>.tar.gz' - # or Debian native 'package_<version>.tar.gz' # or directory 'package-<version>': - r'^(?P<package>[a-zA-Z\d\.\+\-]+)(-|_)(?P<version>[0-9]%s*)')) + r'^(?P<package>[a-zA-Z\d\.\+\-]+)(-)(?P<version>[0-9]%s*)')) if extra_regex: version_filters = extra_regex + version_filters @@ -358,7 +359,7 @@ class UpstreamSource(object): files.append((typ, info.filename)) elif self._archive_fmt == 'tar': popen = subprocess.Popen(['tar', '-t', '-v', '-f', self.path], - stdout=subprocess.PIPE) + stdout=subprocess.PIPE, stderr=subprocess.PIPE) out, _err = popen.communicate() if popen.returncode: raise GbpError("Listing tar archive content failed") @@ -379,11 +380,25 @@ class UpstreamSource(object): @property def archive_fmt(self): """Archive format of the sources, e.g. 'tar'""" + """ + >>> UpstreamSource('foo/bar.tar.gz').archive_fmt + 'tar' + >>> UpstreamSource('foo.bar.zip').archive_fmt + 'zip' + >>> UpstreamSource('foo.bar.baz').archive_fmt + """ return self._archive_fmt @property def compression(self): """Compression format of the sources, e.g. 'gzip'""" + """ + >>> UpstreamSource('foo/bar.tar.gz').compression + 'gzip' + >>> UpstreamSource('foo.bar.zip').compression + >>> UpstreamSource('foo.bz2').compression + 'bzip2' + """ return self._compression @property diff --git a/gbp/rpm/__init__.py b/gbp/rpm/__init__.py index 0e04b4df..4c5c22bf 100644 --- a/gbp/rpm/__init__.py +++ b/gbp/rpm/__init__.py @@ -100,7 +100,7 @@ class SrcRpmFile(object): """ gbpc.RunAtCommand('rpm2cpio', [self.srpmfile, '|', 'cpio', '-id'], - shell=True)(dir=dest_dir) + shell=True, capture_stderr=True)(dir=dest_dir) class SpecFile(object): diff --git a/gbp/rpm/lib_rpm.py b/gbp/rpm/lib_rpm.py index 4bad44e7..da914207 100644 --- a/gbp/rpm/lib_rpm.py +++ b/gbp/rpm/lib_rpm.py @@ -25,6 +25,7 @@ try: # Try to load special RPM lib to be used for GBP (only) librpm = __import__(RpmPkgPolicy.python_rpmlib_module_name) except ImportError: + gbp.log.getLogger("gbp") gbp.log.warn("Failed to import '%s' as rpm python module, using host's " "default rpm library instead" % RpmPkgPolicy.python_rpmlib_module_name) 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 diff --git a/gbp/scripts/buildpackage.py b/gbp/scripts/buildpackage.py index a92e7ca8..cef0584f 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 @@ -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 @@ -415,6 +416,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="packaging_tag") + tag_group.add_config_file_option(option_name="debian-tag-msg", dest="debian_tag_msg") tag_group.add_config_file_option(option_name="upstream-tag", dest="upstream_tag") orig_group.add_config_file_option(option_name="upstream-tree", dest="upstream_tree") orig_group.add_boolean_config_file_option(option_name="pristine-tar", dest="pristine_tar") @@ -615,13 +617,15 @@ 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.packaging_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) + tag_msg = format_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) diff --git a/gbp/scripts/buildpackage_rpm.py b/gbp/scripts/buildpackage_rpm.py index b8c1e0d1..8fb0b2a4 100755 --- a/gbp/scripts/buildpackage_rpm.py +++ b/gbp/scripts/buildpackage_rpm.py @@ -288,7 +288,17 @@ def export_patches(repo, spec, export_treeish, options): def is_native(repo, options): """Determine whether a package is native or non-native""" if options.native.is_auto(): - return not repo.has_branch(options.upstream_branch) + if repo.has_branch(options.upstream_branch): + return False + # Check remotes, too + for remote_branch in repo.get_remote_branches(): + remote, branch = remote_branch.split('/', 1) + if branch == options.upstream_branch: + gbp.log.debug("Found upstream branch '%s' from remote '%s'" % + (remote, branch)) + return False + return True + return options.native.is_on() @@ -698,6 +708,7 @@ def main(argv): if not options.tag_only: if spec and options.notify: summary = "Gbp-rpm %s" % ["failed", "successful"][not retval] + pkg_evr = {'upstreamversion': spec.version} message = ("Build of %s %s %s" % (spec.name, RpmPkgPolicy.compose_full_version(spec.version), ["failed", "succeeded"][not retval])) diff --git a/gbp/scripts/clone.py b/gbp/scripts/clone.py index 9dd0ae9c..2810a310 100755 --- a/gbp/scripts/clone.py +++ b/gbp/scripts/clone.py @@ -17,7 +17,7 @@ # # inspired by dom-git-checkout # -"""clone a repo and set it up for gbp""" +"""Clone a GIT repository and set it up for gbp""" import ConfigParser import sys diff --git a/gbp/scripts/common/buildpackage.py b/gbp/scripts/common/buildpackage.py index f95837c1..d089df5a 100644 --- a/gbp/scripts/common/buildpackage.py +++ b/gbp/scripts/common/buildpackage.py @@ -142,7 +142,6 @@ def untar_data(outdir, data): if popen.wait(): raise GbpError("Error extracting tar to %s" % outdir) - #{ Functions to handle export-dir def dump_tree(repo, export_dir, treeish, with_submodules, recursive=True): """Dump a git tree-ish to output_dir""" diff --git a/gbp/scripts/common/import_orig.py b/gbp/scripts/common/import_orig.py index adbfff5e..16244423 100644 --- a/gbp/scripts/common/import_orig.py +++ b/gbp/scripts/common/import_orig.py @@ -78,59 +78,6 @@ def ask_package_version(default, ver_validator_func, err_msg): # bit clearer. gbp.log.warn("\nNot a valid upstream version: '%s'.\n%s" % (version, err_msg)) - -def prepare_pristine_tar(source, pkg_name, pkg_version, pristine_commit_name, - filters=None, prefix=None, tmpdir=None): - """ - Prepare the upstream sources for pristine-tar import - - @param source: original upstream sources - @type source: C{UpstreamSource} - @param pkg_name: package name - @type pkg_name: C{str} - @param pkg_version: upstream version of the package - @type pkg_version: C{str} - @param pristine_commit_name: archive filename to commit to pristine-tar - @type pristine_commit_name: C{str} or C{None} - @param filters: filter to exclude files - @type filters: C{list} of C{str} or C{None} - @param prefix: prefix (i.e. leading directory of files) to use in - pristine-tar, set to C{None} to not mangle orig archive - @type prefix: C{str} or C{None} - @param tmpdir: temporary working dir (cleanup left to caller) - @type tmpdir: C{str} - @return: prepared source archive - @rtype: C{UpstreamSource} - """ - need_repack = False - if source.is_dir(): - if prefix is None: - prefix = '%s-%s' % (pkg_name, pkg_version) - gbp.log.info("Using guessed prefix '%s/' for pristine-tar" % prefix) - need_repack = True - else: - if prefix is not None and prefix == source.prefix: - prefix = None - comp = parse_archive_filename(pristine_commit_name)[2] - if filters or prefix is not None or source.compression != comp: - if not source.unpacked: - unpack_dir = tempfile.mkdtemp(prefix='pristine_unpack_', - dir=tmpdir) - source.unpack(unpack_dir) - need_repack = True - pristine_path = os.path.join(tmpdir, pristine_commit_name) - if need_repack: - gbp.log.debug("Packing '%s' from '%s' for pristine-tar" % - (pristine_path, source.unpacked)) - pristine = source.pack(pristine_path, filters, prefix) - else: - # Just create symlink for mangling the pristine tarball name - os.symlink(source.path, pristine_path) - pristine = source.__class__(pristine_path) - - return pristine - - def prepare_sources(source, pkg_name, pkg_version, pristine_commit_name, filters, filter_pristine, prefix, tmpdir): """ @@ -201,3 +148,55 @@ def prepare_sources(source, pkg_name, pkg_version, pristine_commit_name, pristine_path = pristine.path if pristine else '' return (filtered.unpacked, pristine_path) +def prepare_pristine_tar(source, pkg_name, pkg_version, pristine_commit_name, + filters=None, prefix=None, tmpdir=None): + """ + Prepare the upstream sources for pristine-tar import + + @param source: original upstream sources + @type source: C{UpstreamSource} + @param pkg_name: package name + @type pkg_name: C{str} + @param pkg_version: upstream version of the package + @type pkg_version: C{str} + @param pristine_commit_name: archive filename to commit to pristine-tar + @type pristine_commit_name: C{str} or C{None} + @param filters: filter to exclude files + @type filters: C{list} of C{str} or C{None} + @param prefix: prefix (i.e. leading directory of files) to use in + pristine-tar, set to C{None} to not mangle orig archive + @type prefix: C{str} or C{None} + @param tmpdir: temporary working dir (cleanup left to caller) + @type tmpdir: C{str} + @return: prepared source archive + @rtype: C{UpstreamSource} + """ + need_repack = False + if source.is_dir(): + if prefix is None: + prefix = '%s-%s' % (pkg_name, pkg_version) + gbp.log.info("Using guessed prefix '%s/' for pristine-tar" % prefix) + need_repack = True + else: + if prefix is not None and prefix == source.prefix: + prefix = None + comp = parse_archive_filename(pristine_commit_name)[2] + if filters or prefix is not None or source.compression != comp: + if not source.unpacked: + unpack_dir = tempfile.mkdtemp(prefix='pristine_unpack_', + dir=tmpdir) + source.unpack(unpack_dir) + need_repack = True + pristine_path = os.path.join(tmpdir, pristine_commit_name) + if need_repack: + gbp.log.debug("Packing '%s' from '%s' for pristine-tar" % + (pristine_path, source.unpacked)) + pristine = source.pack(pristine_path, filters, prefix) + else: + # Just create symlink for mangling the pristine tarball name + os.symlink(source.path, pristine_path) + pristine = source.__class__(pristine_path) + + return pristine + + diff --git a/gbp/scripts/create_remote_repo.py b/gbp/scripts/create_remote_repo.py index 0d2345cd..a9832a1d 100755 --- a/gbp/scripts/create_remote_repo.py +++ b/gbp/scripts/create_remote_repo.py @@ -16,7 +16,7 @@ # Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA # # Based on the aa-create-git-repo and dom-new-git-repo shell scripts -"""Create a remote repo based on the current one""" +"""Create a remote GIT repository based on the current one""" import ConfigParser import sys diff --git a/gbp/scripts/dch.py b/gbp/scripts/dch.py index 0cf2e452..b8a86a77 100755 --- a/gbp/scripts/dch.py +++ b/gbp/scripts/dch.py @@ -15,7 +15,7 @@ # along with this program; if not, write to the Free Software # Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA # -"""Generate Debian changelog entries from git commit messages""" +"""Generate Debian changelog entries from GIT commit messages""" import ConfigParser import os.path @@ -64,17 +64,19 @@ 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 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) + author, email = get_author_email(repo, use_git_author) used_options = ['distribution', 'urgency'] - header_opts = [] + opts = [] + mainttrailer_opts = [ '--nomainttrailer', '--mainttrailer', '-t' ] # This must not be done for snapshots or snapshots changelog entries # will not be concatenated @@ -83,11 +85,17 @@ 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) + 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) def snapshot_version(version): @@ -153,9 +161,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 @@ -343,10 +351,9 @@ 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'") + 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'", @@ -507,11 +514,11 @@ def main(argv): version=version_change, dch_options=dch_options) - fixup_section(repo, git_author=options.git_author, options=options, + fixup_section(repo, use_git_author=options.use_git_author, options=options, dch_options=dch_options) if options.release: - do_release(changelog, repo, cp, git_author=options.git_author, + do_release(changelog, repo, cp, use_git_author=options.use_git_author, dch_options=dch_options) elif options.snapshot: (snap, version) = do_snapshot(changelog, repo, options.snapshot_number) diff --git a/gbp/scripts/import_dsc.py b/gbp/scripts/import_dsc.py index e6f72105..b19d95fc 100755 --- a/gbp/scripts/import_dsc.py +++ b/gbp/scripts/import_dsc.py @@ -14,7 +14,7 @@ # You should have received a copy of the GNU General Public License # along with this program; if not, write to the Free Software # Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA -"""Import a Debian source package into a git repository""" +"""Import a Debian source package into a GIT repository""" import ConfigParser import sys diff --git a/gbp/scripts/import_dscs.py b/gbp/scripts/import_dscs.py index f480fea4..5409ca11 100644 --- a/gbp/scripts/import_dscs.py +++ b/gbp/scripts/import_dscs.py @@ -14,7 +14,7 @@ # You should have received a copy of the GNU General Public License # along with this program; if not, write to the Free Software # Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA -"""Import multiple dsc files in one go""" +"""Import multiple dsc files into GIT in one go""" import glob import os diff --git a/gbp/scripts/import_orig.py b/gbp/scripts/import_orig.py index 78bbf476..9d183b6d 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 @@ -29,12 +29,12 @@ from gbp.deb.changelog import ChangeLog, NoChangeLogError from gbp.deb.git import (GitRepositoryError, DebianGitRepository) from gbp.config import GbpOptionParserDebian, GbpOptionGroup, no_upstream_branch_msg from gbp.errors import GbpError +from gbp.format import format_msg import gbp.log from gbp.pkg import compressor_opts from gbp.scripts.common.import_orig import (cleanup_tmp_tree, ask_package_name, - ask_package_version, - prepare_sources) - + ask_package_version, + prepare_sources) def upstream_import_commit_msg(options, version): return options.import_msg % dict(version=version) @@ -270,6 +270,12 @@ def main(argv): source, pkg_name, version, prepare_pristine, options.filters, options.filter_pristine_tar, None, tmpdir) + # Prepare sources for importing + pristine_name = pristine_tarball_name(source, pkg_name, version) + prepare_pristine = pristine_name if options.pristine_tar else None + unpacked_orig, pristine_orig = prepare_sources( + source, pkg_name, version, prepare_pristine, options.filters, + options.filter_pristine_tar, None, tmpdir) # Don't mess up our repo with git metadata from an upstream tarball try: if os.path.isdir(os.path.join(unpacked_orig, '.git/')): @@ -331,7 +337,7 @@ def main(argv): epoch = '%s:' % cp.epoch info = { 'version': "%s%s-1" % (epoch, version) } env = { 'GBP_BRANCH': options.packaging_branch } - gbpc.Command(options.postimport % info, extra_env=env, shell=True)() + gbpc.Command(format_msg(options.postimport, info), extra_env=env, shell=True)() # Update working copy and index if we've possibly updated the # checked out branch current_branch = repo.get_branch() diff --git a/gbp/scripts/import_srpm.py b/gbp/scripts/import_srpm.py index 5a1d9d64..85f1225f 100755 --- a/gbp/scripts/import_srpm.py +++ b/gbp/scripts/import_srpm.py @@ -15,7 +15,7 @@ # You should have received a copy of the GNU General Public License # along with this program; if not, write to the Free Software # Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA -"""Import an RPM source package into a git repository""" +"""Import an RPM source package into a GIT repository""" import ConfigParser import sys diff --git a/gbp/scripts/pq.py b/gbp/scripts/pq.py index 75348501..7053d0af 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 <agx@sigxcpu.org> +# (C) 2011,2014 Guido Günther <agx@sigxcpu.org> # 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 @@ -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 @@ -35,6 +35,7 @@ from gbp.scripts.common.pq import (is_pq_branch, pq_branch_name, pq_branch_base, switch_to_pq_branch, apply_single_patch, apply_and_commit_patch, drop_pq, get_maintainer_from_control) +from gbp.dch import extract_bts_cmds PATCH_DIR = "debian/patches/" SERIES_FILE = os.path.join(PATCH_DIR,"series") @@ -90,6 +91,71 @@ 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: <REASON>\\nDropped b: <REASON>\\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: <REASON>\n' % p + for p in removed: + msg += 'Dropped %s: <REASON>\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) + 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 + added, removed = compare_series(oldpatches, newpatches) + msg = format_series_diff(added, removed, options) + repo.add_files(PATCH_DIR) + repo.commit_staged(msg=msg) + return added, removed + + def export_patches(repo, branch, options): """Export patches from the pq branch into a patch series""" if is_pq_branch(branch, options): @@ -113,10 +179,22 @@ 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: + what = 'patches' if len(added) > 1 else 'patch' + gbp.log.info("Added %s %s to patch series" % (what, ', '.join(added))) + if 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: gbp.log.info("No patches on '%s' - nothing to do." % pq_branch) + if options.drop: + drop_pq(repo, branch, options) + def safe_patches(series, tmpdir_base): """ @@ -257,11 +335,14 @@ 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_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") parser.add_config_file_option(option_name="tmp-dir", dest="tmp_dir") return parser diff --git a/gbp/scripts/pq_rpm.py b/gbp/scripts/pq_rpm.py index 6380ee22..e19218a9 100755 --- a/gbp/scripts/pq_rpm.py +++ b/gbp/scripts/pq_rpm.py @@ -27,11 +27,10 @@ import re import gzip import bz2 import subprocess - import gbp.tmpfile as tempfile from gbp.config import GbpOptionParserRpm from gbp.rpm.git import GitRepositoryError, RpmGitRepository -from gbp.git.modifier import GitModifier +from gbp.git.modifier import GitModifier, GitTz from gbp.command_wrappers import GitCommand, CommandExecFailed from gbp.errors import GbpError import gbp.log @@ -269,6 +268,8 @@ def export_patches(repo, options): upstream_commit = find_upstream_commit(repo, spec, options.upstream_tag) export_treeish = options.export_rev if options.export_rev else pq_branch + if not repo.has_treeish(export_treeish): + raise GbpError('Invalid treeish object %s' % export_treeish) update_patch_series(repo, spec, upstream_commit, export_treeish, options) @@ -384,7 +385,7 @@ def import_spec_patches(repo, options): # Create pq-branch if repo.has_branch(pq_branch) and not options.force: raise GbpError("Patch-queue branch '%s' already exists. " - "Try 'rebase' instead." % pq_branch) + "Try 'switch' instead." % pq_branch) try: if repo.get_branch() == pq_branch: repo.force_head(upstream_commit, hard=True) diff --git a/gbp/scripts/pull.py b/gbp/scripts/pull.py index 12da8c5f..166955a9 100755 --- a/gbp/scripts/pull.py +++ b/gbp/scripts/pull.py @@ -17,7 +17,7 @@ # # heavily inspired by dom-safe-pull which is © 2009 Stéphane Glondu <steph@glondu.net> # -"""fast forward debian, upstream and pristine-tar branch""" +"""Pull remote changes and fast forward debian, upstream and pristine-tar branch""" import ConfigParser import sys diff --git a/gbp/scripts/supercommand.py b/gbp/scripts/supercommand.py index 2eb64de2..83c8446b 100644 --- a/gbp/scripts/supercommand.py +++ b/gbp/scripts/supercommand.py @@ -17,6 +17,8 @@ # 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 @@ -42,8 +44,18 @@ 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): + 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 @@ -56,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 @@ -63,12 +109,18 @@ def supercommand(argv=None): usage() return 1 - cmd = argv[1] + 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) @@ -81,4 +133,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\:·: diff --git a/packaging/PKGBUILD b/packaging/PKGBUILD index 09eeac15..60ffa9f6 100644 --- a/packaging/PKGBUILD +++ b/packaging/PKGBUILD @@ -1,6 +1,6 @@ pkgbase='git-buildpackage' pkgname=('git-buildpackage-rpm' 'git-buildpackage-common' 'git-buildpackage-doc') -pkgver=0.6.25 +pkgver=0.6.27 pkgrel=0 pkgdesc="Tools from Debian to integrate the package build system with Git" arch=(any) @@ -53,7 +53,7 @@ package_git-buildpackage-common() { package_git-buildpackage-rpm() { depends=("git-buildpackage-common=$pkgver-$pkgrel" "rpm") - provides=("tizen-gbp-rpm=20150721") + provides=("tizen-gbp-rpm=20160302") cd $srcdir/$pkgbase-$pkgver WITHOUT_NOSETESTS=1 \ python2 setup.py install \ diff --git a/packaging/git-buildpackage.changes b/packaging/git-buildpackage.changes index ce8abfd3..5f8ecf55 100644 --- a/packaging/git-buildpackage.changes +++ b/packaging/git-buildpackage.changes @@ -1,9 +1,59 @@ -* Tue Jul 21 2015 SoonKyu Park <sk7.park@samsung.com> tizen/0.6.25-20150721 -- Upgrade version to 0.6.25-20150721 +* Wed Mar 02 2016 Jun Wang <junbill.wang@samsung.com> tizen/0.6.27-20160302 +- Upgrade version to 0.6.27 -* Tue Mar 03 2015 Markus Lehtonen <markus.lehtonen@linux.intel.com> tizen/0.6.15-20150303 -- Revert "buildpackage-rpm: always create tarball for native packages" - (Fixes: DEVT-215) +* Fri Feb 06 2015 Markus Lehtonen <markus.lehtonen@linux.intel.com> tizen/0.6.22-20150206 +- Rebase on top of upstream version 0.6.22 +- Experimental support for BitBake + * Introduce import-bb tool. + This is the first tool in an effort of enabling gbp in the BitBake build + environment. Gbp-import-bb is a tool for importing packages from a + BitBake-based "combined" distro repository into individual per-package + Git repositories. + * Introduce pq-bb tool. + This is a tool for managing patch-queues for packages maintained in the + BitBake packaging format (.bb recipes). + * Introduce buildpackage-bb tool. + Initial version of the tool for building BitBake packages from Git. + NOTE: The buildpackage-bb tool itself is able to operate even without an + initialized BitBake build environment although the build likely fails in + this case. However, this makes it possible to export the packaging meta + data, for example. + * Introcude clone-bb tool. + This is a new tool for helping to clone remote per-package Git + repositories when working in BitBake-based "full distro" build + environment. This is useful in the case that individual packages are + actually maintained in per-package Git repositories (like Tizen). That + is, the full distro repository that the developer operates in is + composed of the packaging meta data from the individual per-package + repositories. When willing to contribute to a package the developer + would use clone-bb to clone the correct per-package repository and make + his changes there. + NOTE: clone-bb uses GBP_PACKAGING_REPO variable to determine the remote + repository URI. This variable should be defined in the package recipes + in order to make clone-bb usable. + * Introduce submit-bb tool. + This is a Tizen-specific tool for creating and pushing special submit + tags. +- pq-rpm: better error message +- buildpackage-rpm: look for remote upstream branches. + Consider remote branches, too, while looking for the upstream branch + when trying to guess if a package is native or not. +- rpm packaging changes + * enable CentOS 7. + * include python egg-info in -common. +- rpm: suppress stderr when unpacking src.rpm +- UpstreamSource: suppress stderr from tar in _determine_prefix() +- patchseries: strip numbering when guessing subject from filename +- Changes in logging + * don't propagate to ancestor loggers + * don't initialize handlers in GbpLogger init. + Better compatibility with 3rd party modules that have their own logging + initializations. +- Features/fixes in GitRepository + * GitRepository/__git_inout: correctly handle input error + * GitRepository.create_tag: add 'annotate' argument. + For forcing the creation of annotated tags. Causes the an editor to be + spawned if no message is given. * Thu Aug 28 2014 Markus Lehtonen <markus.lehtonen@linux.intel.com> tizen/0.6.15-20140828 - Rebase on top of upstream version 0.6.15 diff --git a/packaging/git-buildpackage.spec b/packaging/git-buildpackage.spec index a24f5c57..1a2f49b8 100644 --- a/packaging/git-buildpackage.spec +++ b/packaging/git-buildpackage.spec @@ -3,7 +3,7 @@ Name: git-buildpackage Summary: Build packages from git -Version: 0.6.25 +Version: 0.6.27 Release: 0 Group: Development/Tools/Building License: GPLv2 @@ -111,7 +111,7 @@ Recommends: rpm-build %else Requires: rpm-build %endif -Provides: tizen-gbp-rpm = 20150721 +Provides: tizen-gbp-rpm = 20160302 %description rpm Set of tools from Debian that integrate the package build system with Git. @@ -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', diff --git a/tests/13_test_gbp_pq.py b/tests/13_test_gbp_pq.py index 0b400c21..f71c5420 100644 --- a/tests/13_test_gbp_pq.py +++ b/tests/13_test_gbp_pq.py @@ -25,7 +25,7 @@ try: except ImportError: import unittest -from gbp.scripts.pq import generate_patches +from gbp.scripts.pq import generate_patches, switch_pq, export_patches import gbp.scripts.common.pq as pq import gbp.patch_series import tests.testutils as testutils @@ -137,5 +137,26 @@ class TestWritePatch(testutils.DebianGitTestRepo): # Branches must be identical afterwards self.assertEqual('', diff) +class TestExport(testutils.DebianGitTestRepo): + class Options(object): + drop = True + patch_numbers = False + + def setUp(self): + testutils.DebianGitTestRepo.setUp(self) + self.add_file('bar', 'bar') + + def test_drop(self): + """Test if we drop the patch-queue branch with --drop""" + repo = self.repo + start = repo.get_branch() + pq = os.path.join('patch-queue', start) + switch_pq(repo, start, TestExport.Options) + 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) diff --git a/tests/component/__init__.py b/tests/component/__init__.py index 31911e48..baabbbd3 100644 --- a/tests/component/__init__.py +++ b/tests/component/__init__.py @@ -183,6 +183,8 @@ class ComponentTestBase(object): self._loghandler = gbp.log.GbpStreamHandler(self._log, False) self._loghandler.addFilter(gbp.log.GbpFilter([gbp.log.WARNING, gbp.log.ERROR])) + for hdl in gbp.log.LOGGER.handlers: + gbp.log.LOGGER.removeHandler(hdl) gbp.log.LOGGER.addHandler(self._loghandler) elif self._log is not None: gbp.log.LOGGER.removeHandler(self._loghandler) diff --git a/tests/component/rpm/data b/tests/component/rpm/data deleted file mode 160000 -Subproject ff090c1cf946e3df67795ce3c1437ec6246dbf3 diff --git a/tests/component/rpm/data/.keep b/tests/component/rpm/data/.keep new file mode 100644 index 00000000..e69de29b --- /dev/null +++ b/tests/component/rpm/data/.keep diff --git a/tests/component/rpm/test_buildpackage_rpm.py b/tests/component/rpm/test_buildpackage_rpm.py index 3060f84b..652b1528 100644 --- a/tests/component/rpm/test_buildpackage_rpm.py +++ b/tests/component/rpm/test_buildpackage_rpm.py @@ -101,8 +101,12 @@ class TestGbpRpm(RpmRepoTestBase): def test_invalid_args(self): """Check graceful exit when called with invalid args""" GitRepository.create('.') + assert_raises(SystemExit, mock_gbp, ['--git-invalid-arg']) + + """ with assert_raises(SystemExit): mock_gbp(['--git-invalid-arg']) + """ def test_outside_repo(self): """Run outside a git repository""" @@ -139,10 +143,16 @@ class TestGbpRpm(RpmRepoTestBase): def test_non_native_build(self): """Basic test of non-native pkg""" - self.init_test_repo('gbp-test') + repo = self.init_test_repo('gbp-test') eq_(mock_gbp([]), 0) self.check_rpms('../rpmbuild/RPMS/*') + # Test nativity guessing from remote branches by creating a dummy + # remote branch + repo.update_ref('refs/remotes/fooremote/foobranch', + 'srcdata/gbp-test/upstream') + eq_(mock_gbp(['--git-upstream-branch=foobranch']), 0) + def test_option_native(self): """Test the --git-native option""" self.init_test_repo('gbp-test2') diff --git a/tests/component/rpm/test_import_orig_rpm.py b/tests/component/rpm/test_import_orig_rpm.py index a85366b1..ebf592a0 100644 --- a/tests/component/rpm/test_import_orig_rpm.py +++ b/tests/component/rpm/test_import_orig_rpm.py @@ -142,8 +142,12 @@ class TestImportOrig(ImportOrigTestBase): self._check_repo_state(repo, None, []) # Test invalid cmdline options + assert_raises(SystemExit, mock_import, ['--invalid-arg=123']) + + """ with assert_raises(SystemExit): mock_import(['--invalid-arg=123']) + """ def test_import_outside_repo(self): """Test importing when not in a git repository""" diff --git a/tests/component/rpm/test_import_srpm.py b/tests/component/rpm/test_import_srpm.py index 4811794a..6635400b 100644 --- a/tests/component/rpm/test_import_srpm.py +++ b/tests/component/rpm/test_import_srpm.py @@ -45,13 +45,17 @@ class TestImportPacked(ComponentTestBase): def test_invalid_args(self): """See that import-srpm fails gracefully if called with invalid args""" eq_(mock_import([]), 1) + assert_raises(SystemExit, mock_import, ['--invalid-arg=123']) + + """ with assert_raises(SystemExit): mock_import(['--invalid-arg=123']) + """ def test_basic_import(self): """Test importing of non-native src.rpm""" srpm = os.path.join(DATA_DIR, 'gbp-test-1.0-1.src.rpm') - eq_(mock_import([srpm]), 0) + eq_(mock_import(['--no-pristine-tar', srpm]), 0) # Check repository state repo = GitRepository('gbp-test') files = set(['Makefile', 'README', 'bar.tar.gz', 'dummy.sh', 'foo.txt', @@ -64,7 +68,7 @@ class TestImportPacked(ComponentTestBase): def test_basic_import2(self): """Import package with multiple spec files and full url patch""" srpm = os.path.join(DATA_DIR, 'gbp-test2-2.0-0.src.rpm') - eq_(mock_import([srpm]), 0) + eq_(mock_import(['--no-pristine-tar', srpm]), 0) # Check repository state repo = GitRepository('gbp-test2') files = set(['Makefile', 'README', 'bar.tar.gz', 'dummy.sh', 'foo.txt', @@ -82,7 +86,7 @@ class TestImportPacked(ComponentTestBase): development branches """ srpm = os.path.join(DATA_DIR, 'gbp-test2-2.0-0.src.rpm') - eq_(mock_import(['--orphan-packaging', srpm]), 0) + eq_(mock_import(['--no-pristine-tar', '--orphan-packaging', srpm]), 0) # Check repository state repo = GitRepository('gbp-test2') files = set(['bar.tar.gz', 'foo.txt', 'gbp-test2.spec', @@ -132,7 +136,7 @@ class TestImportPacked(ComponentTestBase): srpms = [ os.path.join(DATA_DIR, 'gbp-test-1.0-1.src.rpm'), os.path.join(DATA_DIR, 'gbp-test-1.0-1.other.src.rpm'), os.path.join(DATA_DIR, 'gbp-test-1.1-1.src.rpm') ] - eq_(mock_import([srpms[0]]), 0) + eq_(mock_import(['--no-pristine-tar', srpms[0]]), 0) repo = GitRepository('gbp-test') self._check_repo_state(repo, 'master', ['master', 'upstream']) eq_(len(repo.get_commits()), 4) @@ -176,7 +180,7 @@ class TestImportPacked(ComponentTestBase): # The first import should fail because upstream branch is missing eq_(mock_import([srpm]), 1) self._check_log(-1, 'Also check the --create-missing-branches') - eq_(mock_import(['--create-missing', srpm]), 0) + eq_(mock_import(['--no-pristine-tar', '--create-missing', srpm]), 0) self._check_repo_state(repo, 'master', ['master', 'upstream']) # Four commits: our initial, upstream, packaging files, one patch, # and the removal of imported patches @@ -191,7 +195,7 @@ class TestImportPacked(ComponentTestBase): def test_filter(self): """Test filter option""" srpm = os.path.join(DATA_DIR, 'gbp-test-1.0-1.src.rpm') - eq_(mock_import(['--filter=README', '--filter=mydir', srpm]), 0) + eq_(mock_import(['--no-pristine-tar', '--filter=README', '--filter=mydir', srpm]), 0) # Check repository state repo = GitRepository('gbp-test') files = set(['Makefile', 'dummy.sh', 'bar.tar.gz', 'foo.txt', @@ -248,7 +252,7 @@ class TestImportUnPacked(ComponentTestBase): def test_import_dir(self): """Test importing of directories""" - eq_(mock_import(['gbp-test-1.0-1-unpack']), 0) + eq_(mock_import(['--no-pristine-tar', 'gbp-test-1.0-1-unpack']), 0) # Check repository state repo = GitRepository('gbp-test') self._check_repo_state(repo, 'master', ['master', 'upstream']) @@ -286,7 +290,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']) diff --git a/tests/component/rpm/test_pq_rpm.py b/tests/component/rpm/test_pq_rpm.py index 293244be..c14ea681 100644 --- a/tests/component/rpm/test_pq_rpm.py +++ b/tests/component/rpm/test_pq_rpm.py @@ -52,8 +52,12 @@ class TestPqRpm(RpmRepoTestBase): self._clear_log() # Test invalid cmdline options + assert_raises(SystemExit, mock_pq, ['--invalid-arg=123']) + + """ with assert_raises(SystemExit): mock_pq(['--invalid-arg=123']) + """ def test_import_outside_repo(self): """Run pq-rpm when not in a git repository""" diff --git a/tests/component/rpm/test_rpm_ch.py b/tests/component/rpm/test_rpm_ch.py index db03c845..4b3354b7 100644 --- a/tests/component/rpm/test_rpm_ch.py +++ b/tests/component/rpm/test_rpm_ch.py @@ -56,8 +56,12 @@ class TestRpmCh(RpmRepoTestBase): """See that git-rpm-ch fails gracefully when called with invalid args""" GitRepository.create('.') + assert_raises(SystemExit, mock_ch, ['--invalid-opt']) + + """ with assert_raises(SystemExit): mock_ch(['--invalid-opt']) + """ def test_import_outside_repo(self): """Run git-rpm-ch when not in a git repository""" diff --git a/tests/test_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') diff --git a/tests/test_rpm.py b/tests/test_rpm.py index 13799266..97390465 100644 --- a/tests/test_rpm.py +++ b/tests/test_rpm.py @@ -154,10 +154,15 @@ class TestSpecFile(object): def test_parse_raw(self): """Test parsing of a valid spec file""" + assert_raises(NoSpecError, SpecFile, None, None) + assert_raises(NoSpecError, SpecFile, 'filename', 'filedata') + + """ with assert_raises(NoSpecError): SpecFile(None, None) with assert_raises(NoSpecError): SpecFile('filename', 'filedata') + """ spec_filepath = os.path.join(SPEC_DIR, 'gbp-test.spec') with open(spec_filepath, 'r') as spec_fd: @@ -229,22 +234,36 @@ class TestSpecFile(object): assert spec.protected('_patches')() == {} prev = spec.protected('_delete_tag')('invalidtag', None) + assert_raises(GbpError, spec.protected('_set_tag'), + 'Version', None, '', prev) + assert_raises(GbpError, spec.set_tag, + 'invalidtag', None, 'value') + + """ with assert_raises(GbpError): # Check that setting empty value fails spec.protected('_set_tag')('Version', None, '', prev) with assert_raises(GbpError): # Check that setting invalid tag with public method fails spec.set_tag('invalidtag', None, 'value') + """ # Mangle macros prev = spec.protected('_delete_special_macro')('patch', -1) spec.protected('_delete_special_macro')('patch', 123) spec.protected('_set_special_macro')('patch', 0, 'my new args', prev) + assert_raises(GbpError, spec.protected('_delete_special_macro'), + 'invalidmacro', 0) + assert_raises(GbpError, spec.protected('_set_special_macro'), + 'invalidmacro', 0, 'args', prev) + + """ with assert_raises(GbpError): spec.protected('_delete_special_macro')('invalidmacro', 0) with assert_raises(GbpError): spec.protected('_set_special_macro')('invalidmacro', 0, 'args', prev) + """ # Check resulting spec file spec.write_spec_file() @@ -256,12 +275,21 @@ class TestSpecFile(object): spec = SpecFileTester(spec_filepath) # Unknown/invalid section name + assert_raises(GbpError, spec.protected('_set_section'), + 'patch', 'new content\n') + """ with assert_raises(GbpError): spec.protected('_set_section')('patch', 'new content\n') + """ # Multiple sections with the same name + assert_raises(GbpError, spec.protected('_set_section'), + 'files', '%{_sysconfdir}/foo\n') + + """ with assert_raises(GbpError): spec.protected('_set_section')('files', '%{_sysconfdir}/foo\n') + """ def test_changelog(self): """Test changelog methods""" @@ -362,21 +390,40 @@ class TestUtilityFunctions(object): def test_parse_srpm(self): """Test parse_srpm() function""" parse_srpm(os.path.join(SRPM_DIR, 'gbp-test-1.0-1.src.rpm')) + assert_raises(GbpError, parse_srpm, + os.path.join(DATA_DIR, 'notexists.src.rpm')) + + """ with assert_raises(GbpError): parse_srpm(os.path.join(DATA_DIR, 'notexists.src.rpm')) with assert_raises(GbpError): parse_srpm(os.path.join(SPEC_DIR, 'gbp-test.spec')) + """ def test_guess_spec(self): """Test guess_spec() function""" # Spec not found + assert_raises(NoSpecError, guess_spec, + DATA_DIR, recursive=False) + + """ with assert_raises(NoSpecError): guess_spec(DATA_DIR, recursive=False) + """ + # Multiple spec files + assert_raises(NoSpecError, guess_spec, + DATA_DIR, recursive=True) + assert_raises(NoSpecError, guess_spec, + SPEC_DIR, recursive=False) + + """ with assert_raises(NoSpecError): guess_spec(DATA_DIR, recursive=True) with assert_raises(NoSpecError): guess_spec(SPEC_DIR, recursive=False) + """ + # Spec found spec = guess_spec(SPEC_DIR, recursive=False, preferred_name = 'gbp-test2.spec') @@ -398,10 +445,18 @@ class TestUtilityFunctions(object): repo.commit_all('Add spec file') # Spec not found + assert_raises(NoSpecError, guess_spec_repo, + repo, 'HEAD~1', recursive=True) + assert_raises(NoSpecError, guess_spec_repo, + repo, 'HEAD', recursive=False) + + """ with assert_raises(NoSpecError): guess_spec_repo(repo, 'HEAD~1', recursive=True) with assert_raises(NoSpecError): guess_spec_repo(repo, 'HEAD', recursive=False) + """ + # Spec found spec = guess_spec_repo(repo, 'HEAD', 'packaging', recursive=False) spec = guess_spec_repo(repo, 'HEAD', recursive=True) @@ -410,8 +465,14 @@ class TestUtilityFunctions(object): assert spec.specpath == 'packaging/gbp-test.spec' # Test spec_from_repo() + assert_raises(NoSpecError, spec_from_repo, + repo, 'HEAD~1', 'packaging/gbp-test.spec') + + """ with assert_raises(NoSpecError): spec_from_repo(repo, 'HEAD~1', 'packaging/gbp-test.spec') + """ + spec = spec_from_repo(repo, 'HEAD', 'packaging/gbp-test.spec') assert spec.specfile == 'gbp-test.spec' diff --git a/tests/test_rpm_changelog.py b/tests/test_rpm_changelog.py index 29732936..22739f0e 100644 --- a/tests/test_rpm_changelog.py +++ b/tests/test_rpm_changelog.py @@ -40,8 +40,12 @@ class TestChangelogHeader(object): """Test missing properties""" time = datetime(2014, 01, 29, 12, 13, 14) header = _ChangelogHeader(RpmPkgPolicy, time, name="John", revision="1") + assert_raises(ChangelogError, str, header) + + """ with assert_raises(ChangelogError): str(header) + """ def test_container(self): """Test the container methods of the class""" @@ -190,6 +194,16 @@ class TestChangelogParser(object): def test_parse_section_fail(self): """Basic tests for failures of changelog section parsing""" + assert_raises(ChangelogError, self.parser.parse_section, + self.cl_broken_header_1) + assert_raises(ChangelogError, self.parser.parse_section, + self.cl_broken_header_2) + assert_raises(ChangelogError, self.parser.parse_section, + self.cl_broken_header_3) + assert_raises(ChangelogError, self.parser.parse_section, + self.cl_broken_header_4) + + """ with assert_raises(ChangelogError): self.parser.parse_section(self.cl_broken_header_1) @@ -201,11 +215,17 @@ class TestChangelogParser(object): with assert_raises(ChangelogError): self.parser.parse_section(self.cl_broken_header_4) + """ def test_parse_changelog_fail(self): """Basic tests for changelog parsing failures""" + assert_raises(ChangelogError, self.parser.raw_parse_string, + self.cl_broken_header_5) + + """ with assert_raises(ChangelogError): self.parser.raw_parse_string(self.cl_broken_header_5) + """ class TestChangelog(object): |