diff options
author | Guido Günther <agx@sigxcpu.org> | 2015-03-17 09:16:03 +0100 |
---|---|---|
committer | Guido Günther <agx@sigxcpu.org> | 2015-03-17 09:16:03 +0100 |
commit | 6f51faef5a021488a159c62473c5f17d4bead1ee (patch) | |
tree | 02dd28ff140ae846ba7b5cb6abe3d96ef2728b14 | |
parent | 2271202a44b461a9c61ccd1815822483b64bc4d3 (diff) | |
parent | 4c9d692d52fd3fdf72733b07a5c4d5da3a128ca8 (diff) |
Merge tag 'debian/0.6.22' into bpo/wheezy
git-buildpackage Debian release 0.6.22
87 files changed, 5000 insertions, 995 deletions
@@ -18,10 +18,10 @@ docs/manpage.links docs/manpage.refs docs/version.ent -debian/git-buildpackage.*.debhelper -debian/git-buildpackage.debhelper.* +debian/git-buildpackage*.debhelper* debian/python-module-stampdir/ debian/files -debian/git-buildpackage.substvars +debian/git-buildpackage*.substvars debian/git-buildpackage/ - +debian/git-buildpackage-rpm/ +debian/tmp/ diff --git a/.gitmodules b/.gitmodules index 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 @@ -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/ diff --git a/bin/git-pbuilder b/bin/git-pbuilder index 4024d124..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 <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 # @@ -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,7 +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 + if [ x'-S' = x"$arg" ] ; then + source_only=true + fi DEBBUILDOPTS+=" $(shell_quote "$arg")" done @@ -278,7 +284,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 638c09ae..e6eaf494 100644 --- a/debian/changelog +++ b/debian/changelog @@ -1,3 +1,114 @@ +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 + + * [5cde49a] Revert "Determine build_dir upfront" + This reverts commit b2549fac19f2d666552291a4fcf2020ca0570834. + Closes: #749104 + + -- Guido Günther <agx@sigxcpu.org> Sat, 24 May 2014 18:40:44 +0200 + +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 <agx@sigxcpu.org> Thu, 22 May 2014 22:47:37 +0200 + git-buildpackage (0.6.13~bpo70+1) wheezy-backports; urgency=medium * Rebuild for wheezy-backports. diff --git a/debian/control b/debian/control index 712dcd41..7858f233 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.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") diff --git a/debian/git-buildpackage.install b/debian/git-buildpackage.install new file mode 100644 index 00000000..1a25e1dc --- /dev/null +++ b/debian/git-buildpackage.install @@ -0,0 +1,31 @@ +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/format.py +usr/lib/python2.?/dist-packages/gbp/git/ +usr/lib/python2.?/dist-packages/gbp/__init__.py +usr/lib/python2.?/dist-packages/gbp/log.py +usr/lib/python2.?/dist-packages/gbp/notifications.py +usr/lib/python2.?/dist-packages/gbp/patch_series.py +usr/lib/python2.?/dist-packages/gbp/pkg/ +usr/lib/python2.?/dist-packages/gbp/scripts/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 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) diff --git a/docs/manpages/gbp-buildpackage.sgml b/docs/manpages/gbp-buildpackage.sgml index 37d2c313..0e5561ef 100644 --- a/docs/manpages/gbp-buildpackage.sgml +++ b/docs/manpages/gbp-buildpackage.sgml @@ -8,8 +8,7 @@ &dhsurname; </author> </refentryinfo> - <refmeta> - <refentrytitle>gbp-buildpackage</refentrytitle> + <refmeta><refentrytitle>gbp-buildpackage</refentrytitle> &dhsection; </refmeta> <refnamediv> @@ -24,10 +23,12 @@ <arg><option>--git-tag</option></arg> <arg><option>--git-verbose</option></arg> <arg><option>--git-color=</option><replaceable>[auto|on|off]</replaceable></arg> + <arg><option>--git-color-scheme</option>=<replaceable>COLOR_SCHEME</replaceable></arg> <arg><option>--git-notify=</option><replaceable>[auto|on|off]</replaceable></arg> - <arg><option>--git-upstream-branch=</option><replaceable>treeish</replaceable></arg> - <arg><option>--git-debian-branch=</option><replaceable>branch_name</replaceable></arg> + <arg><option>--git-upstream-branch=</option><replaceable>TREEISH</replaceable></arg> + <arg><option>--git-debian-branch=</option><replaceable>BRANCH_NAME</replaceable></arg> <arg><option>--git-ignore-branch</option></arg> + <arg><option>--git-[no-]submodules</option></arg> <arg><option>--git-builder=</option><replaceable>BUILD_CMD</replaceable></arg> <arg><option>--git-cleaner=</option><replaceable>CLEAN_CMD</replaceable></arg> <arg><option>--git-[no-]pbuilder</option></arg> @@ -35,24 +36,25 @@ <arg><option>--git-dist=</option><replaceable>DIST</replaceable></arg> <arg><option>--git-arch=</option><replaceable>ARCH</replaceable></arg> <arg><option>--git-[no-]pbuilder-autoconf</option></arg> - <arg><option>--git-pbuilder-options</option></arg> + <arg><option>--git-pbuilder-options</option>=<replaceable>PBUILDER_OPTIONS</replaceable></arg> <arg><option>--git-[no-]sign-tags</option></arg> - <arg><option>--git-keyid=</option><replaceable>gpg-keyid</replaceable></arg> - <arg><option>--git-posttag=</option><replaceable>command</replaceable></arg> - <arg><option>--git-postbuild=</option><replaceable>command</replaceable></arg> - <arg><option>--git-postexport=</option><replaceable>command</replaceable></arg> - <arg><option>--git-prebuild=</option><replaceable>command</replaceable></arg> + <arg><option>--git-keyid=</option><replaceable>GPG-KEYID</replaceable></arg> + <arg><option>--git-posttag=</option><replaceable>COMMAND</replaceable></arg> + <arg><option>--git-postbuild=</option><replaceable>COMMAND</replaceable></arg> + <arg><option>--git-postexport=</option><replaceable>COMMAND</replaceable></arg> + <arg><option>--git-prebuild=</option><replaceable>COMMAND</replaceable></arg> <arg><option>--git-[no-]hooks</option></arg> <arg><option>--git-debian-tag=</option><replaceable>tag-format</replaceable></arg> <arg><option>--git-upstream-tag=</option><replaceable>tag-format</replaceable></arg> + <arg><option>--git-debian-tag-msg=</option><replaceable>tag-msg-format</replaceable></arg> <arg><option>--git-force-create</option></arg> <arg><option>--git-no-create-orig</option></arg> - <arg><option>--git-upstream-tree=</option><replaceable>[TAG|BRANCH|treeish]</replaceable></arg> - <arg><option>--git-tarball-dir=</option><replaceable>directory</replaceable></arg> - <arg><option>--git-compression=</option><replaceable>type</replaceable></arg> - <arg><option>--git-compression-level=</option><replaceable>level</replaceable></arg> - <arg><option>--git-export-dir=</option><replaceable>directory</replaceable></arg> - <arg><option>--git-export=</option><replaceable>treeish</replaceable></arg> + <arg><option>--git-upstream-tree=</option><replaceable>[TAG|BRANCH|TREEISH]</replaceable></arg> + <arg><option>--git-tarball-dir=</option><replaceable>DIRECTORY</replaceable></arg> + <arg><option>--git-compression=</option><replaceable>TYPE</replaceable></arg> + <arg><option>--git-compression-level=</option><replaceable>LEVEL</replaceable></arg> + <arg><option>--git-export-dir=</option><replaceable>DIRECTORY</replaceable></arg> + <arg><option>--git-export=</option><replaceable>TREEISH</replaceable></arg> <arg><option>--git-[no-]pristine-tar</option></arg> <arg><option>--git-[no-]pristine-tar-commit</option></arg> <arg><option>--git-[no-]-purge</option></arg> @@ -64,397 +66,557 @@ <refsect1> <title>DESCRIPTION</title> <para> - &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. </para> <para> - &gbp-buildpackage; will, in order: - </para> + &gbp-buildpackage; will, in order: + </para> <itemizedlist> - <listitem><para>Verify that it is being executed from the - proper location.</para> - </listitem> - <listitem><para>Verify that the repository doesn't contain any - uncommitted source changes.</para> - </listitem> - <listitem><para>Verify that it is being executed from the - correct branch.</para> - </listitem> - <listitem><para> - (Optionally) export the source tree to a separate build area - </para></listitem> - <listitem><para>Build an orig tarball if it doesn't exist.</para> - </listitem> - <listitem><para>Call <application>debuild</application>(1) - (or the application specified via <option>--git-builder</option>) - 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-. - </para> - </listitem> - <listitem><para> - (Optionally) tag the tree after a successful build - </para></listitem> - <listitem><para> - (Optionally) call a post build hook - e.g. to run &lintian; - </para></listitem> - <listitem><para> - (Optionally) call a post tag hook - e.g. to push the results to a remote - repository after creating the tag - </para></listitem> + <listitem> + <para> + Verify that it is being executed from the proper location. + </para> + </listitem> + <listitem> + <para> + Verify that the repository doesn't contain any uncommitted source + changes. + </para> + </listitem> + <listitem> + <para> + Verify that it is being executed from the correct branch. + </para> + </listitem> + <listitem> + <para> + (Optionally) export the source tree to a separate build area + </para> + </listitem> + <listitem> + <para> + Build an orig tarball if it doesn't exist. + </para> + </listitem> + <listitem> + <para> + Call <application>debuild</application>(1) (or the application + specified via <option>--git-builder</option>) 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-. + </para> + </listitem> + <listitem> + <para> + (Optionally) tag the tree after a successful build + </para> + </listitem> + <listitem> + <para> + (Optionally) call a post build hook - e.g. to run &lintian; + </para> + </listitem> + <listitem> + <para> + (Optionally) call a post tag hook - e.g. to push the results to a + remote repository after creating the tag + </para> + </listitem> </itemizedlist> </refsect1> <refsect1> <title>OPTIONS</title> - <variablelist> <varlistentry> <term><option>--git-[no-]ignore-new</option> </term> <listitem> - <para>Don't abort if there are uncommitted changes in the source tree - or the current branch doesn't match the - <replaceable>debian-branch</replaceable>.</para> + <para> + Don't abort if there are uncommitted changes in the source tree or + the current branch doesn't match the + <replaceable>DEBIAN-BRANCH</replaceable>. + </para> </listitem> </varlistentry> <varlistentry> <term><option>--git-tag</option> </term> <listitem> - <para>Add a git tag after a successful build.</para> + <para> + Add a git tag after a successful build. + </para> </listitem> </varlistentry> <varlistentry> - <term><option>--git-builder=<replaceable>BUILD_CMD</replaceable></option></term> + <term><option>--git-builder=<replaceable>BUILD_CMD</replaceable></option> + </term> <listitem> - <para>Use <replaceable>BUILD_CMD</replaceable> instead of <command>debuild -i -I</command></para> + <para> + Use <replaceable>BUILD_CMD</replaceable> instead of + <command>debuild -i -I</command> + </para> </listitem> </varlistentry> <varlistentry> - <term><option>--git-cleaner=<replaceable>CLEAN_CMD</replaceable></option></term> + <term><option>--git-cleaner=<replaceable>CLEAN_CMD</replaceable></option> + </term> <listitem> - <para>Use <replaceable>CLEAN_CMD</replaceable> instead of <command>debuild clean</command></para> + <para> + Use <replaceable>CLEAN_CMD</replaceable> instead of + <command>debuild clean</command> + </para> </listitem> </varlistentry> <varlistentry> - <term><option>--git-pbuilder</option></term> + <term><option>--git-pbuilder</option> + </term> <listitem> - <para>Build package using <command>git-pbuilder</command>. Note that - this overwrites any <option>--git-builder</option> and - <option>--git-cleaner</option> options.</para> + <para> + Build package using <command>git-pbuilder</command>. Note that this + overwrites any <option>--git-builder</option> and + <option>--git-cleaner</option> options. + </para> </listitem> </varlistentry> <varlistentry> - <term><option>--git-qemubuilder</option></term> + <term><option>--git-qemubuilder</option> + </term> <listitem> - <para>Build package using <command>git-pbuilder</command> with - <command>qemubuilder</command>. Note that this overwrites any - <option>--git-builder</option> and <option>--git-cleaner</option> - options.</para> + <para> + Build package using <command>git-pbuilder</command> with + <command>qemubuilder</command>. Note that this overwrites any + <option>--git-builder</option> and <option>--git-cleaner</option> + options. + </para> </listitem> </varlistentry> <varlistentry> - <term><option>--git-dist=<replaceable>DIST</replaceable></option></term> + <term><option>--git-dist=<replaceable>DIST</replaceable></option> + </term> <listitem> - <para>Build for distribution <replaceable>DIST</replaceable> when - using <command>--git-pbuilder</command>. If unset build for the - unstable distribution.</para> + <para> + Build for distribution <replaceable>DIST</replaceable> when using + <command>--git-pbuilder</command>. If unset build for the unstable + distribution. + </para> </listitem> </varlistentry> <varlistentry> - <term><option>--git-arch=<replaceable>ARCH</replaceable></option></term> + <term><option>--git-arch=<replaceable>ARCH</replaceable></option> + </term> <listitem> - <para>Build for architecture <replaceable>ARCH</replaceable> when - using <command>--git-pbuilder</command>. If unset no architecture is - passed to <command>git-pbuilder</command>.</para> + <para> + Build for architecture <replaceable>ARCH</replaceable> when using + <command>--git-pbuilder</command>. If unset no architecture is passed + to <command>git-pbuilder</command>. + </para> </listitem> </varlistentry> <varlistentry> - <term><option>--git-pbuilder-autoconf</option></term> + <term><option>--git-pbuilder-autoconf</option> + </term> <listitem> - <para>Whether to try to autoconfigure - <command>git-pbuilder</command> or to rely on the settings in - .pbuilderrc. See the <command>git-pbuilder</command> - manpage for details.</para></listitem> + <para> + Whether to try to autoconfigure <command>git-pbuilder</command> or to + rely on the settings in .pbuilderrc. See the + <command>git-pbuilder</command> manpage for details. + </para> + </listitem> </varlistentry> <varlistentry> - <term><option>--git-pbuilder-options</option></term> + <term><option>--git-pbuilder-options</option> + </term> <listitem> - <para>Options to pass to pbuilder</para> + <para> + Options to pass to pbuilder + </para> </listitem> </varlistentry> <varlistentry> <term><option>--git-verbose</option> </term> <listitem> - <para>verbose execution</para> + <para> + verbose execution + </para> </listitem> </varlistentry> <varlistentry> <term><option>--git-color=</option><replaceable>[auto|on|off]</replaceable> </term> <listitem> - <para>Whether to use colored output.</para> + <para> + Whether to use colored output. + </para> </listitem> </varlistentry> <varlistentry> <term><option>--git-notify=</option><replaceable>[auto|on|off]</replaceable> </term> <listitem> - <para>Whether to send a desktop notification after the build.</para> + <para> + Whether to send a desktop notification after the build. + </para> </listitem> </varlistentry> <varlistentry> - <term><option>--git-upstream-branch</option>=<replaceable>branch_name</replaceable> + <term><option>--git-color-scheme</option>=<replaceable>COLOR_SCHEME</replaceable> </term> <listitem> - <para>Branch to build the orig tarball from if <option>--git-upstream-tree</option> - is set to <replaceable>BRANCH</replaceable>. Default is - <replaceable>upstream</replaceable>.</para> + <para> + 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). + </para> </listitem> </varlistentry> <varlistentry> - <term><option>--git-debian-branch</option>=<replaceable>branch_name</replaceable> + <term><option>--git-upstream-branch</option>=<replaceable>BRANCH_NAME</replaceable> </term> <listitem> - <para>If you're not on this branch when invoking &gbp-buildpackage; - it will fail. Default is <replaceable>master</replaceable>. 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 - <option>--git-ignore-new</option>. - </para> + <para> + Branch to build the orig tarball from if + <option>--git-upstream-tree</option> is set to + <replaceable>BRANCH</replaceable>. Default is + <replaceable>upstream</replaceable>. + </para> + </listitem> + </varlistentry> + <varlistentry> + <term><option>--git-debian-branch</option>=<replaceable>BRANCH_NAME</replaceable> + </term> + <listitem> + <para> + If you're not on this branch when invoking &gbp-buildpackage; it will + fail. Default is <replaceable>master</replaceable>. 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 + <option>--git-ignore-new</option>. + </para> </listitem> </varlistentry> <varlistentry> <term><option>--git-ignore-branch</option> </term> <listitem> - <para>Don't check if the current branch matches - <replaceable>debian-branch</replaceable>.</para> + <para> + Don't check if the current branch matches + <replaceable>DEBIAN-BRANCH</replaceable>. + </para> </listitem> </varlistentry> <varlistentry> <term><option>--git-[no-]sign-tags</option> </term> <listitem> - <para>GPG sign all created tags</para> + <para> + GPG sign all created tags + </para> + </listitem> + </varlistentry> + <varlistentry> + <term><option>--git-[no-]submodules</option> + </term> + <listitem> + <para> + Include git submodules in the orig tarball. + </para> + </listitem> + </varlistentry> + <varlistentry> + <term><option>--git-keyid=</option><replaceable>GPG-KEYID</replaceable> + </term> + <listitem> + <para> + use this keyid for gpg signing tags + </para> </listitem> </varlistentry> <varlistentry> - <term><option>--git-keyid=</option><replaceable>gpg-keyid</replaceable> + <term><option>--git-posttag=</option><replaceable>COMMAND</replaceable> </term> <listitem> - <para>use this keyid for gpg signing tags</para> + <para> + excecute <replaceable>COMMAND</replaceable> after tagging a new + version. + </para> + <para> + Exported environment variables are: <envar>GBP_TAG</envar> (the name + of the generated tag), <envar>GBP_BRANCH</envar> (the branch the + package was build from) and <envar>GBP_SHA1</envar> (the sha1 of the + commit the tag was created at). + </para> </listitem> </varlistentry> <varlistentry> - <term><option>--git-posttag=</option><replaceable>command</replaceable> + <term><option>--git-postbuild=</option><replaceable>COMMAND</replaceable> </term> <listitem> - <para>excecute <replaceable>command</replaceable> after tagging a new - version.</para><para>Exported environment variables are: - <envar>GBP_TAG</envar> (the name of the generated tag), - <envar>GBP_BRANCH</envar> (the branch the package was build from) and - <envar>GBP_SHA1</envar> (the sha1 of the commit the tag was created - at).</para> + <para> + execute <replaceable>COMMAND</replaceable> after successful + build. + </para> + <para> + Exported environment variables are: <envar>GBP_CHANGES_FILE</envar> + (the name of the generated changes file), + <envar>GBP_BUILD_DIR</envar> (the build dir). + </para> </listitem> </varlistentry> <varlistentry> - <term><option>--git-postbuild=</option><replaceable>command</replaceable> + <term><option>--git-postexport=</option><replaceable>COMMAND</replaceable> </term> <listitem> - <para>execute <replaceable>command</replaceable> after successful - build.</para><para> Exported environment variables are: - <envar>GBP_CHANGES_FILE</envar> (the name of the generated changes - file), <envar>GBP_BUILD_DIR</envar> (the build dir).</para> + <para> + execute <replaceable>COMMAND</replaceable> after exporting the source + tree - valid only if --git-export-dir has been specified. + </para> + <para> + Exported environment variables are: <envar>GBP_GIT_DIR</envar> (the + repository the package is being built from), + <envar>GBP_TMP_DIR</envar> (the temporary directory where the sources + have been initially exported). + </para> </listitem> </varlistentry> <varlistentry> - <term><option>--git-postexport=</option><replaceable>command</replaceable> + <term><option>--git-prebuild=</option><replaceable>COMMAND</replaceable> </term> <listitem> - <para>execute <replaceable>command</replaceable> after exporting the source - tree - valid only if --git-export-dir has been specified.</para> - <para> Exported environment variables are: - <envar>GBP_GIT_DIR</envar> (the repository the package is being built - from), <envar>GBP_TMP_DIR</envar> (the temporary directory where the - sources have been initially exported).</para> + <para> + execute <replaceable>COMMAND</replaceable> from the build directory + before calling <application>debuild</application> or the application + specified via <option>--git-builder</option>. + </para> + <para> + Exported environment variables are: <envar>GBP_GIT_DIR</envar> (the + repository the package is being built from), + <envar>GBP_BUILD_DIR</envar> (the build dir). + </para> </listitem> </varlistentry> <varlistentry> - <term><option>--git-prebuild=</option><replaceable>command</replaceable> + <term><option>--git-[no-]hooks</option> </term> <listitem> - <para>execute <replaceable>command</replaceable> from the build - directory before calling <application>debuild</application> - or the application specified via <option>--git-builder</option>.</para> - <para>Exported environment variables are: - <envar>GBP_GIT_DIR</envar> (the repository the package is being built from), - <envar>GBP_BUILD_DIR</envar> (the build dir).</para> + <para> + Enable running all (cleaner, postexport, prebuild, postbuild, and + posttag) hooks. Note: the <option>--git-builder</option> command is + not affected by this option. + </para> </listitem> </varlistentry> <varlistentry> - <term><option>--git-[no-]hooks</option></term> + <term><option>--git-debian-tag=</option><replaceable>TAG-FORMAT</replaceable> + </term> <listitem> - <para>Enable running all (cleaner, postexport, prebuild, postbuild, - and posttag) hooks. Note: the <option>--git-builder</option> command is - not affected by this option.</para> + <para> + use this tag format when tagging Debian versions, default is + <replaceable>debian/%(version)s</replaceable> + </para> </listitem> </varlistentry> <varlistentry> - <term><option>--git-debian-tag=</option><replaceable>tag-format</replaceable> + <term><option>--git-upstream-tag=</option><replaceable>TAG-FORMAT</replaceable> </term> <listitem> - <para>use this tag format when tagging Debian versions, - default is <replaceable>debian/%(version)s</replaceable></para> + <para> + use this tag format when looking for tags of upstream versions, + default is <replaceable>upstream/%(version)s</replaceable>. + </para> </listitem> </varlistentry> <varlistentry> - <term><option>--git-upstream-tag=</option><replaceable>tag-format</replaceable> + <term><option>--git-debian-tag-msg=</option><replaceable>tag-msg-format</replaceable> </term> <listitem> - <para>use this tag format when looking for tags of upstream versions, - default is <replaceable>upstream/%(version)s</replaceable>.</para> + <para>use this tag message format when signing Debian versions, + default is <replaceable>%(pkg)s Debian release %(version)s</replaceable></para> </listitem> </varlistentry> <varlistentry> <term><option>--git-force-create</option> </term> <listitem> - <para>Force creation of an orig tarball (overwriting a pre-existing one if present)</para> + <para> + Force creation of an orig tarball (overwriting a pre-existing one if + present) + </para> </listitem> </varlistentry> <varlistentry> <term><option>--git-no-create-orig</option> </term> <listitem> - <para>Don't try to create any orig tarball</para> + <para> + Don't try to create any orig tarball + </para> </listitem> </varlistentry> <varlistentry> <term><option>--git-overlay</option> </term> <listitem> - <para>Extract orig tarball when using export-dir option (analog to mergeWithUpstream in svn-bp)</para> + <para> + Extract orig tarball when using export-dir option (analog to + mergeWithUpstream in svn-bp) + </para> </listitem> </varlistentry> <varlistentry> - <term><option>--git-export-dir=</option><replaceable>directory</replaceable> + <term><option>--git-export-dir=</option><replaceable>DIRECTORY</replaceable> </term> <listitem> - <para>Export the current branch head (or the treeish object given via - <option>--git-export</option> to <replaceable>directory</replaceable> - before building.</para> + <para> + Export the current branch head (or the treeish object given via + <option>--git-export</option> to <replaceable>DIRECTORY</replaceable> + before building. + </para> </listitem> </varlistentry> <varlistentry> - <term><option>--git-export=</option><replaceable>treeish</replaceable> + <term><option>--git-export=</option><replaceable>TREEISH</replaceable> </term> - <listitem> - <para>Instead of exporting the current branch head, export the - treeish object <replaceable>treeish</replaceable>. The special name - <replaceable>INDEX</replaceable> exports the current index whereas - the special name <replaceable>WC</replaceable> exports the current working - copy as is.</para> + <listitem> + <para> + Instead of exporting the current branch head, export the treeish + object <replaceable>TREEISH</replaceable>. The special name + <replaceable>INDEX</replaceable> exports the current index whereas + the special name <replaceable>WC</replaceable> exports the current + working copy as is. + </para> </listitem> </varlistentry> <varlistentry> - <term><option>--git-upstream-tree=</option><replaceable>[tag|branch]</replaceable> + <term><option>--git-upstream-tree=</option><replaceable>[TAG|BRANCH|TREEISH]</replaceable> </term> <listitem> - <para>How to find the upstream sources used to generate the tarball. - <replaceable>TAG</replaceable> looks at a tag corresponding to the - version in the changelog. <replaceable>BRANCH</replaceable> looks at - the upstream branch given via the <option>--git-upstream-branch</option> - option. Other values are interpreted as treeishs. - </para><para> - This doesn't have any effect if <option>--git-pristine-tar</option> - is being used. - </para> + <para> + How to find the upstream sources used to generate the tarball. + <replaceable>TAG</replaceable> looks at a tag corresponding to the + version in the changelog. <replaceable>BRANCH</replaceable> looks at + the upstream branch given via the + <option>--git-upstream-branch</option> option. Other values are + interpreted as treeishs. + </para> + <para> + This doesn't have any effect if <option>--git-pristine-tar</option> + is being used. + </para> </listitem> </varlistentry> <varlistentry> - <term><option>--git-tarball-dir=</option><replaceable>directory</replaceable> + <term><option>--git-tarball-dir=</option><replaceable>DIRECTORY</replaceable> </term> <listitem> - <para>Search for original tarballs in <replaceable>directory</replaceable> instead of generating them</para> + <para> + Search for original tarballs in <replaceable>DIRECTORY</replaceable> + instead of generating them + </para> </listitem> </varlistentry> <varlistentry> - <term><option>--git-compression=</option><replaceable>type</replaceable> + <term><option>--git-compression=</option><replaceable>TYPE</replaceable> </term> <listitem> - <para>Specifies the upstream tarball compression type. This will be - used to locate and build the upstream tarball if necessary. The - default is <replaceable>auto</replaceable> which derives the - compression type from the pristine-tar branch if available and falls - back to gzip otherwise. Other options are - <replaceable>gzip</replaceable>, <replaceable>bzip2</replaceable>, - <replaceable>lzma</replaceable> and <replaceable>xz</replaceable>. - </para> + <para> + Specifies the upstream tarball compression type. This will be used to + locate and build the upstream tarball if necessary. The default is + <replaceable>auto</replaceable> which derives the compression type + from the pristine-tar branch if available and falls back to gzip + otherwise. Other options are <replaceable>gzip</replaceable>, + <replaceable>bzip2</replaceable>, <replaceable>lzma</replaceable> and + <replaceable>xz</replaceable>. + </para> </listitem> </varlistentry> <varlistentry> - <term><option>--git-compression-level=</option><replaceable>level</replaceable> + <term><option>--git-compression-level=</option><replaceable>LEVEL</replaceable> </term> <listitem> - <para>Specifies the upstream tarball compression level if an upstream tarball needs to be built.</para> + <para> + Specifies the upstream tarball compression level if an upstream + tarball needs to be built. + </para> </listitem> </varlistentry> <varlistentry> <term><option>--git[-no]-purge</option> </term> <listitem> - <para>Purge (remove) temporary build directory after build</para> + <para> + Purge (remove) temporary build directory after build + </para> </listitem> </varlistentry> <varlistentry> <term><option>--git-dont-purge</option> </term> <listitem> - <para>Deprecated, use --git-no-purge instead.</para> + <para> + Deprecated, use --git-no-purge instead. + </para> </listitem> </varlistentry> <varlistentry> <term><option>--git-tag-only</option> </term> <listitem> - <para>don't build, only tag and run post-tag hooks</para> + <para> + don't build, only tag and run post-tag hooks + </para> </listitem> </varlistentry> <varlistentry> <term><option>--git-retag</option> </term> <listitem> - <para>don't fail tag operations if a tag with the same version - already exists</para> + <para> + don't fail tag operations if a tag with the same version already + exists + </para> </listitem> </varlistentry> <varlistentry> <term><option>--git-pristine-tar</option> </term> <listitem> - <para>Use pristine-tar when generating the upstream tarball if it doesn't exist.</para> + <para> + Use pristine-tar when generating the upstream tarball if it doesn't + exist. + </para> </listitem> </varlistentry> <varlistentry> <term><option>--git-pristine-tar-commit</option> </term> <listitem> - <para>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.</para> + <para> + 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. + </para> </listitem> </varlistentry> </variablelist> </refsect1> <refsect1> <title>EXAMPLES</title> - <para>Build a Debian package using &git-pbuilder; which in turn invokes &cowbuildercmd;. - Instruct cowbuilder to build within a Wheezy chroot for i386.</para> + <para> + Build a Debian package using &git-pbuilder; which in turn invokes + &cowbuildercmd;. Instruct cowbuilder to build within a Wheezy chroot for + i386. + </para> <screen> &gbp-buildpackage; --git-pbuilder --git-arch=i386 --git-dist=wheezy </screen> <para> - 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: </para> <screen> DIST=wheezy ARCH=i386 &git-pbuilder; create @@ -462,46 +624,33 @@ </refsect1> <refsect1> &man.gbp.config-files; - <para>All options in the config files are specified without the 'git-' prefix.</para> + <para> + All options in the config files are specified without the 'git-' prefix. + </para> </refsect1> <refsect1> <title>SEE ALSO</title> <para> - <citerefentry> - <refentrytitle>gbp-import-dsc</refentrytitle> - <manvolnum>1</manvolnum> - </citerefentry>, - <citerefentry> - <refentrytitle>gbp-import-dscs</refentrytitle> - <manvolnum>1</manvolnum> - </citerefentry>, - <citerefentry> - <refentrytitle>gbp-import-orig</refentrytitle> - <manvolnum>1</manvolnum> - </citerefentry>, - <citerefentry> - <refentrytitle>gbp-dch</refentrytitle> - <manvolnum>1</manvolnum> - </citerefentry>, - <citerefentry> - <refentrytitle>git-pbuilder</refentrytitle> - <manvolnum>1</manvolnum> - </citerefentry>, - <citerefentry> - <refentrytitle>cowbuilder</refentrytitle> - <manvolnum>8</manvolnum> - </citerefentry>, - <citerefentry> - <refentrytitle>gbp.conf</refentrytitle> - &dhconfsection; - </citerefentry> - &man.seealso.common; + <xref linkend="man.gbp.import.dsc">, + <xref linkend="man.gbp.import.dscs">, + <xref linkend="man.gbp.import.orig">, + <xref linkend="man.gbp.dch">, + <citerefentry> + <refentrytitle>git-pbuilder</refentrytitle> + <manvolnum>1</manvolnum> + </citerefentry>, + <citerefentry> + <refentrytitle>cowbuilder</refentrytitle> + <manvolnum>8</manvolnum> + </citerefentry>, + <xref linkend="man.gbp.conf">, + &man.seealso.common; </para> </refsect1> <refsect1> <title>AUTHOR</title> - - <para>&dhusername; &dhemail;</para> - + <para> + &dhusername; &dhemail; + </para> </refsect1> </refentry> diff --git a/docs/manpages/gbp-clone.sgml b/docs/manpages/gbp-clone.sgml index c63db2f5..20e61472 100644 --- a/docs/manpages/gbp-clone.sgml +++ b/docs/manpages/gbp-clone.sgml @@ -21,7 +21,7 @@ <cmdsynopsis> &gbp-clone; - <arg><option>--verbose</option></arg> + &man.common.options.synopsis; <arg><option>--all</option></arg> <arg><option>--[no-]pristine-tar</option></arg> <arg><option>--debian-branch=</option><replaceable>branch_name</replaceable></arg> @@ -43,6 +43,8 @@ <title>OPTIONS</title> <variablelist> + &man.common.options.description; + <varlistentry> <term><option>--all</option> </term> @@ -75,13 +77,6 @@ </listitem> </varlistentry> <varlistentry> - <term><option>--verbose</option></term> - <term><option>-v</option></term> - <listitem> - <para>verbose execution</para> - </listitem> - </varlistentry> - <varlistentry> <term><option>--pristine-tar</option> </term> <listitem> @@ -96,18 +91,9 @@ <refsect1> <title>SEE ALSO</title> <para> - <citerefentry> - <refentrytitle>gbp-buildpackage</refentrytitle> - <manvolnum>1</manvolnum> - </citerefentry>, - <citerefentry> - <refentrytitle>gbp-pull</refentrytitle> - <manvolnum>1</manvolnum> - </citerefentry>, - <citerefentry> - <refentrytitle>gbp.conf</refentrytitle> - &dhconfsection; - </citerefentry> + <xref linkend="man.gbp.buildpackage">, + <xref linkend="man.gbp.pull">, + <xref linkend="man.gbp.conf"> </para> </refsect1> <refsect1> diff --git a/docs/manpages/gbp-config.sgml b/docs/manpages/gbp-config.sgml index d68ac643..9b3d7edd 100644 --- a/docs/manpages/gbp-config.sgml +++ b/docs/manpages/gbp-config.sgml @@ -21,8 +21,7 @@ <cmdsynopsis> &gbp-config; - <arg><option>--verbose</option></arg> - <arg><option>--color=</option><replaceable>[auto|on|off]</replaceable></arg> + &man.common.options.synopsis; <group choice='req'> <arg choice="plain"><replaceable>command.option</replaceable></arg> <arg choice="plain"><replaceable>command</replaceable></arg> @@ -40,26 +39,13 @@ <refsect1> <title>OPTIONS</title> <variablelist> - <varlistentry> - <term><option>--verbose</option></term> - <term><option>-v</option></term> - <listitem> - <para>verbose execution</para> - </listitem> - </varlistentry> - <varlistentry> - <term><option>--color=</option><replaceable>[auto|on|off]</replaceable> - </term> - <listitem> - <para>Whether to use colored output.</para> - </listitem> - </varlistentry> + &man.common.options.description; </variablelist> </refsect1> <refsect1> <title>EXIT CODES</title> <para> - 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: </para> <variablelist> <varlistentry> @@ -104,10 +90,7 @@ <refsect1> <title>SEE ALSO</title> <para> - <citerefentry> - <refentrytitle>gbp.conf</refentrytitle> - &dhconfsection; - </citerefentry> + <xref linkend="man.gbp.conf"> </para> </refsect1> <refsect1> diff --git a/docs/manpages/gbp-create-remote-repo.sgml b/docs/manpages/gbp-create-remote-repo.sgml index 08c621a5..e8f6a092 100644 --- a/docs/manpages/gbp-create-remote-repo.sgml +++ b/docs/manpages/gbp-create-remote-repo.sgml @@ -20,8 +20,7 @@ <refsynopsisdiv> <cmdsynopsis> &gbp-create-remote-repo; - <arg><option>--verbose</option></arg> - <arg><option>--color=</option><replaceable>[auto|on|off]</replaceable></arg> + &man.common.options.synopsis; <arg><option>--remote-url-pattern=</option><replaceable>url-pattern</replaceable></arg> <arg><option>--remote-name=</option><replaceable>name</replaceable></arg> <arg><option>--template-dir=</option><replaceable>directory</replaceable></arg> @@ -52,6 +51,8 @@ <refsect1> <title>OPTIONS</title> <variablelist> + &man.common.options.description; + <varlistentry> <term><option>--remote-url-pattern</option>=<replaceable>pattern</replaceable> </term> @@ -112,20 +113,6 @@ </listitem> </varlistentry> <varlistentry> - <term><option>--verbose</option></term> - <term><option>-v</option></term> - <listitem> - <para>verbose execution</para> - </listitem> - </varlistentry> - <varlistentry> - <term><option>--color=</option><replaceable>[auto|on|off]</replaceable> - </term> - <listitem> - <para>Whether to use colored output.</para> - </listitem> - </varlistentry> - <varlistentry> <term><option>--[no-]track</option> </term> <listitem> @@ -141,18 +128,9 @@ <refsect1> <title>SEE ALSO</title> <para> - <citerefentry> - <refentrytitle>gbp-buildpackage</refentrytitle> - <manvolnum>1</manvolnum> - </citerefentry>, - <citerefentry> - <refentrytitle>gbp-pull</refentrytitle> - <manvolnum>1</manvolnum> - </citerefentry>, - <citerefentry> - <refentrytitle>gbp.conf</refentrytitle> - &dhconfsection; - </citerefentry> + <xref linkend="man.gbp.buildpackage">, + <xref linkend="man.gbp.pull">, + <xref linkend="man.gbp.conf"> </para> </refsect1> <refsect1> diff --git a/docs/manpages/gbp-dch.sgml b/docs/manpages/gbp-dch.sgml index 177f45dd..8ffdc4f6 100644 --- a/docs/manpages/gbp-dch.sgml +++ b/docs/manpages/gbp-dch.sgml @@ -9,7 +9,7 @@ </author> </refentryinfo> <refmeta> - <refentrytitle>gbp-dch</refentrytitle> + <refentrytitle>gbp-dch</refentrytitle> &dhsection; </refmeta> <refnamediv> @@ -20,26 +20,25 @@ <refsynopsisdiv> <cmdsynopsis> &gbp-dch; - - <arg><option>--verbose</option></arg> + &man.common.options.synopsis; <arg><option>--debian-branch=</option><replaceable>branch_name</replaceable></arg> <arg><option>--debian-tag=</option><replaceable>tag-format</replaceable></arg> <arg><option>--upstream-tag=</option><replaceable>tag-format</replaceable></arg> <arg><option>--ignore-branch</option></arg> <group> <arg><option>--snapshot</option></arg> - <arg><option>--release</option></arg> + <arg><option>--release</option></arg> </group> <group> - <arg><option>--auto</option></arg> - <arg><option>--since=</option><replaceable>commitish</replaceable></arg> + <arg><option>--auto</option></arg> + <arg><option>--since=</option><replaceable>commitish</replaceable></arg> </group> <arg><option>--new-version=</option><replaceable>version</replaceable></arg> <group> - <arg><option>--bpo</option></arg> - <arg><option>--nmu</option></arg> - <arg><option>--qa</option></arg> - <arg><option>--team</option></arg> + <arg><option>--bpo</option></arg> + <arg><option>--nmu</option></arg> + <arg><option>--qa</option></arg> + <arg><option>--team</option></arg> </group> <arg><option>--distribution=</option><replaceable>name</replaceable></arg> <arg><option>--force-distribution</option></arg> @@ -56,7 +55,7 @@ <arg><option>--spawn-editor=[always|snapshot|release]</option></arg> <arg><option>--commit-msg=</option><replaceable>msg-format</replaceable></arg> <arg><option>--commit</option></arg> - <arg><option>--customization=</option><replaceable>customization-file</replaceable></arg> + <arg><option>--customizations=</option><replaceable>customization-file</replaceable></arg> <arg choice="plain"><replaceable>[path1 path2]</replaceable></arg> </cmdsynopsis> </refsynopsisdiv> @@ -69,11 +68,14 @@ distribution of the topmost section in <filename>debian/changelog</filename> is <emphasis>UNRELEASED</emphasis> the changelog entries will be inserted into this section. Otherwise a new - section will be created.</para> - <para>If <option>--auto</option> is given &gbp-dch; tries to guess the + section will be created. + </para> + <para> + If <option>--auto</option> is given &gbp-dch; tries to guess the last &git; commit documented in the changelog - this only works in snapshot mode. Otherwise <option>--since</option> can be used to tell &gbp-dch; - at which point it should start in the &git; history.</para> + at which point it should start in the &git; history. + </para> <para> The additional path arguments can be used to restrict the repository paths &gbp-dch; looks at. Setting <replaceable>path</replaceable> to @@ -81,106 +83,124 @@ all Debian packaging changes are restricted to the <replaceable>debian/</replaceable> subdir. In more sophisticated cases (like backports) you can use <option>--git-log</option> to restrict the - generated changelog entries further. E.g. by using - <option>--git-log=</option><replaceable>"--author=Foo Bar"</replaceable>.</para> + generated changelog entries further. E.g. by using + <option>--git-log=</option><replaceable>"--author=Foo Bar"</replaceable>. + </para> </refsect1> <refsect1> <title>OPTIONS</title> - <variablelist> + &man.common.options.description; + <varlistentry> <term><option>--debian-branch</option>=<replaceable>branch_name</replaceable> </term> <listitem> - <para>The branch in the Git repository the Debian package is being - developed on, default is <replaceable>master</replaceable>.</para> + <para> + The branch in the Git repository the Debian package is being + developed on, default is <replaceable>master</replaceable>. + </para> </listitem> </varlistentry> <varlistentry> <term><option>--ignore-branch</option> </term> <listitem> - <para>Don't check if the current branch matches - <replaceable>debian-branch</replaceable>.</para> - </listitem> - </varlistentry> - <varlistentry> - <term><option>--verbose</option></term> - <term><option>-v</option></term> - <listitem> - <para>verbose execution</para> + <para> + Don't check if the current branch matches + <replaceable>debian-branch</replaceable>. + </para> </listitem> </varlistentry> <varlistentry> <term><option>--debian-tag=</option><replaceable>tag-format</replaceable> </term> <listitem> - <para>tag format used, when tagging debian versions, - default is <replaceable>debian/%(version)s</replaceable></para> + <para> + tag format used, when tagging debian versions, + default is <replaceable>debian/%(version)s</replaceable> + </para> </listitem> </varlistentry> <varlistentry> <term><option>--since=</option><replaceable>committish</replaceable> </term> <listitem> - <para>Start reading commit messages at <replaceable>committish</replaceable>.</para> + <para> + Start reading commit messages at + <replaceable>committish</replaceable>. + </para> </listitem> </varlistentry> <varlistentry> <term><option>--auto</option>, - <option>-a</option></term> + <option>-a</option></term> <listitem> - <para>Guess the last commit documented in the changelog from the - snapshot banner (or from the last tag if no snapshot banner exists). - </para> + <para> + Guess the last commit documented in the changelog from the + snapshot banner (or from the last tag if no snapshot banner exists). + </para> </listitem> </varlistentry> <varlistentry> <term><option>--[no-]meta</option></term> <listitem> - <para>Parse meta tags like <option>Closes:</option>, - <option>Thanks:</option> and <option>Git-Dch:</option>. See META TAGS below.</para> + <para> + Parse meta tags like <option>Closes:</option>, + <option>Thanks:</option> and <option>Git-Dch:</option>. See META TAGS + below. + </para> </listitem> </varlistentry> <varlistentry> <term><option>--meta-closes=</option><replaceable>bug-close-tags</replaceable> </term> <listitem> - <para>What meta tags to look for to generate bug-closing changelog - entries. The default is 'Closes|LP' to support Debian and - Launchpad.</para> + <para> + What meta tags to look for to generate bug-closing changelog entries. + The default is 'Closes|LP' to support Debian and Launchpad. + </para> </listitem> </varlistentry> <varlistentry> - <term><option>--[no-]full</option></term> + <term><option>--[no-]full</option> + </term> <listitem> - <para>Include the full commit message in the changelog output.</para> + <para> + Include the full commit message in the changelog output. + </para> </listitem> </varlistentry> <varlistentry> <term><option>--snapshot</option>, <option>-S</option></term> <listitem> - <para>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.</para> + <para> + 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. + </para> </listitem> </varlistentry> <varlistentry> <term><option>--snapshot-number=</option><replaceable>expression</replaceable> </term> <listitem> - <para>Python expression that gets eval()ed to the new snapshot number.</para> + <para> + Python expression that gets eval()ed to the new snapshot number. + </para> </listitem> </varlistentry> <varlistentry> <term><option>--release</option>, <option>-R</option></term> <listitem> - <para>Remove any snapshot release banners and version suffixes, set - the current distribution to <replaceable>unstable</replaceable> and - open the changelog for final tweaking.</para> + <para> + Remove any snapshot release banners and version suffixes, set + the current distribution to <replaceable>unstable</replaceable> and + open the changelog for final tweaking. + </para> </listitem> </varlistentry> <varlistentry> @@ -188,155 +208,196 @@ <option>-N</option> <replaceable>version</replaceable> </term> <listitem> - <para>Add a new changelog section with version - <replaceable>newversion</replaceable>. Together with - <option>--snapshot</option> the snapshot number will be appended to - <replaceable>newversion</replaceable>.</para> + <para> + Add a new changelog section with version + <replaceable>newversion</replaceable>. Together with + <option>--snapshot</option> the snapshot number will be appended to + <replaceable>newversion</replaceable>. + </para> </listitem> </varlistentry> <varlistentry> - <term><option>--team</option></term> + <term><option>--team</option> + </term> <listitem> - <para>Create a Team upload changelog entry.</para> + <para> + Create a Team upload changelog entry. + </para> </listitem> </varlistentry> <varlistentry> <term><option>--bpo</option> </term> <listitem> - <para>Increment the Debian release number for an upload to - backports, and add a backport upload changelog comment.</para> + <para> + Increment the Debian release number for an upload to backports, and + add a backport upload changelog comment. + </para> </listitem> </varlistentry> <varlistentry> <term><option>--nmu</option> </term> <listitem> - <para>Increment the Debian release number for a non-maintainer upload.</para> + <para> + Increment the Debian release number for a non-maintainer upload. + </para> </listitem> </varlistentry> <varlistentry> <term><option>--qa</option> </term> <listitem> - <para>Increment the Debian release number for a Debian QA Team - upload, and add a QA upload changelog comment.</para> + <para> + Increment the Debian release number for a Debian QA Team upload, and + add a QA upload changelog comment. + </para> </listitem> </varlistentry> <varlistentry> - <term><option>--distribution=</option><replaceable>name</replaceable> - </term> - <listitem> - <para>Set the distribution field - to <replaceable>name</replaceable>.</para> - </listitem> + <term><option>--distribution=</option><replaceable>name</replaceable> + </term> + <listitem> + <para> + Set the distribution field to <replaceable>name</replaceable>. + </para> + </listitem> </varlistentry> <varlistentry> - <term><option>--force-distribution</option> - </term> - <listitem> - <para>Force the distribution specified - with <option>--distribution</option> to be used, even if it - doesn't match the list of known distributions.</para> - </listitem> + <term><option>--force-distribution</option> + </term> + <listitem> + <para> + Force the distribution specified with <option>--distribution</option> + to be used, even if it doesn't match the list of known distributions. + </para> + </listitem> </varlistentry> <varlistentry> - <term><option>--urgency=</option><replaceable>level</replaceable> - </term> - <listitem> - <para>Set the urgency field - to <replaceable>level</replaceable>.</para> - </listitem> + <term><option>--urgency=</option><replaceable>level</replaceable> + </term> + <listitem> + <para> + Set the urgency field to <replaceable>level</replaceable>. + </para> + </listitem> </varlistentry> <varlistentry> <term><option>--git-log=</option><replaceable>git-log-options</replaceable> </term> <listitem> - <para>Options passed on verbatim to git-log(1).</para> + <para> + Options passed on verbatim to git-log(1). + </para> </listitem> </varlistentry> <varlistentry> <term><option>--id-length=</option><replaceable>N</replaceable> </term> <listitem> - <para>Include <replaceable>N</replaceable> digits of the commit id in - the changelog entry. Default is to not include any commit ids at - all.</para> + <para> + Include <replaceable>N</replaceable> digits of the commit id in the + changelog entry. Default is to not include any commit ids at all. + </para> </listitem> </varlistentry> <varlistentry> <term><option>--ignore-regex=</option><replaceable>regex</replaceable> </term> <listitem> - <para>Ignore commit lines matching <replaceable>regex</replaceable> - when generating the changelog. - </para> + <para> + Ignore commit lines matching <replaceable>regex</replaceable> + when generating the changelog. + </para> </listitem> </varlistentry> <varlistentry> <term><option>--git-author</option> </term> <listitem> - <para>Use user.name and user.email from <application>git-config</application>(1) for changelog trailer.</para> + <para> + Use user.name and user.email from + <application>git-config</application>(1) for changelog trailer. + </para> </listitem> </varlistentry> <varlistentry> <term><option>--[no-]multimaint-merge</option> </term> <listitem> - <para>Merge commits by maintainer.</para> + <para> + Merge commits by maintainer. + </para> </listitem> </varlistentry> <varlistentry> <term><option>--spawn-editor=<replaceable>[always|snapshot|release]</replaceable></option> </term> <listitem> - <para>Whether to spawn an editor: always, when doing snapshots or - when doing a release.</para> + <para> + Whether to spawn an editor: always, when doing snapshots or when + doing a release. + </para> </listitem> </varlistentry> <varlistentry> <term><option>--commit-msg=</option><replaceable>msg-format</replaceable> </term> <listitem> - <para>use this format string for the commit message when - committing the generated changelog file (when - <option>--commit</option> is given). Default is - <replaceable>Update changelog for %(version)s - release</replaceable></para> + <para> + use this format string for the commit message when committing the + generated changelog file (when <option>--commit</option> is given). + Default is + <replaceable>Update changelog for %(version)s release</replaceable> + </para> </listitem> </varlistentry> <varlistentry> <term><option>--commit</option> </term> <listitem> - <para>Commit the generated changelog.</para> + <para> + Commit the generated changelog. + </para> + </listitem> + </varlistentry> + <varlistentry> + <term><option>--customizations=</option><replaceable>customization-file</replaceable> + </term> + <listitem> + <para> + Load Python code from <replaceable>customization-file</replaceable>. + At the moment, the only useful thing the code can do is define a + custom format_changelog_entry() function. + </para> </listitem> </varlistentry> </variablelist> </refsect1> <refsect1> - <title>Snapshot mode</title> - <para> - Snapshot mode can be used for quick test and install cycles without - having to worry about version numbers or changelog entries. - </para><para> - When using <option>--snapshot</option> or <option>-S</option> &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 - <replaceable>~<snaspshotnumber>.gbp<commitid></replaceable>. - It automatically increments the snapshot number on subsequent invocations - of &gbp-dch; <option>-S</option> so that later snapshots automatically - have a higher version number. To leave snapshot mode invoke &gbp-dch; - with the <option>--release</option> option. This removes the pseudo - header and unmangles the version number so the released version has a - higher version number than the snapshots. - </para> + <title>Snapshot mode</title> + <para> + Snapshot mode can be used for quick test and install cycles without + having to worry about version numbers or changelog entries. + </para> + <para> + When using <option>--snapshot</option> or <option>-S</option> &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 + <replaceable>~<snaspshotnumber>.gbp<commitid></replaceable>. + It automatically increments the snapshot number on subsequent invocations + of &gbp-dch; <option>-S</option> so that later snapshots automatically + have a higher version number. To leave snapshot mode invoke &gbp-dch; + with the <option>--release</option> option. This removes the pseudo + header and unmangles the version number so the released version has a + higher version number than the snapshots. + </para> </refsect1> <refsect1> <title>META TAGS</title> - <para>Additional to the above options the formatting of the commit message + <para> + Additional to the above options the formatting of the commit message in <filename>debian/changelog</filename> can be modified by special tags (called Meta Tags) given in the git commit message. Meta Tag processing can be activated via @@ -349,40 +410,44 @@ <varlistentry> <term><option>Git-Dch</option>: <replaceable>action</replaceable> </term> - <listitem><para> - Supported actions are: <replaceable>Ignore</replaceable> which will ignore - this commit when generating <filename>debian/changelog</filename>, - <replaceable>Short</replaceable> which will only use the - description (the first line) of the commit message when - generating the changelog entry (useful when - <option>--full</option> is given) and - <replaceable>Full</replaceable> which will use the full commit - message when generating the changelog entry (useful when - <option>--full</option> is not given). - </para></listitem> + <listitem> + <para> + Supported actions are: <replaceable>Ignore</replaceable> which will + ignore this commit when generating + <filename>debian/changelog</filename>, + <replaceable>Short</replaceable> which will only use the description + (the first line) of the commit message when generating the changelog + entry (useful when <option>--full</option> is given) and + <replaceable>Full</replaceable> which will use the full commit + message when generating the changelog entry (useful when + <option>--full</option> is not given). + </para> + </listitem> </varlistentry> <varlistentry> - <term><option>Thanks</option>: <replaceable>msg</replaceable> - </term> - <listitem> - <para> - Add a thanks message after the commit message. - </para> - </listitem> + <term><option>Thanks</option>: <replaceable>msg</replaceable> + </term> + <listitem> + <para> + Add a thanks message after the commit message. + </para> + </listitem> </varlistentry> <varlistentry> - <term><option>Closes</option>: <replaceable>bugnumber</replaceable> - </term> - <listitem> - <para> - Indicate in the <filename>debian/changelog</filename> that the bug was - closed by this commit. See the <option>--meta-closes</option> - on how to extend this for other bugtrackers. - </para> - </listitem> + <term><option>Closes</option>: <replaceable>bugnumber</replaceable> + </term> + <listitem> + <para> + Indicate in the <filename>debian/changelog</filename> that the bug + was closed by this commit. See the <option>--meta-closes</option> on + how to extend this for other bugtrackers. + </para> + </listitem> </varlistentry> </variablelist> - <para>The following git commit message:</para> + <para> + The following git commit message: + </para> <screen> Document meta tags @@ -393,7 +458,7 @@ Thanks: Raphaël Hertzog for the suggestion </screen> <para> - Results in this <filename>debian/changelog</filename> entry: + Results in this <filename>debian/changelog</filename> entry: </para> <screen> * Document meta tags. @@ -401,32 +466,16 @@ </screen> </refsect1> <refsect1> - &man.gbp.config-files; + &man.gbp.config-files; </refsect1> <refsect1> <title>SEE ALSO</title> - <para> - <citerefentry> - <refentrytitle>gbp-buildpackage</refentrytitle> - <manvolnum>1</manvolnum> - </citerefentry>, - <citerefentry> - <refentrytitle>gbp-import-dsc</refentrytitle> - <manvolnum>1</manvolnum> - </citerefentry>, - <citerefentry> - <refentrytitle>gbp-import-dscs</refentrytitle> - <manvolnum>1</manvolnum> - </citerefentry>, - <citerefentry> - <refentrytitle>gbp-import-orig</refentrytitle> - <manvolnum>1</manvolnum> - </citerefentry>, - <citerefentry> - <refentrytitle>gbp.conf</refentrytitle> - &dhconfsection; - </citerefentry>, + <xref linkend="man.gbp.buildpackage">, + <xref linkend="man.gbp.import.dsc">, + <xref linkend="man.gbp.import.dscs">, + <xref linkend="man.gbp.import.orig">, + <xref linkend="man.gbp.conf">, &man.seealso.common; <ulink url="https://honk.sigxcpu.org/cl2vcs"> <citetitle>Cl2vcs</citetitle></ulink>, @@ -434,8 +483,8 @@ </refsect1> <refsect1> <title>AUTHOR</title> - - <para>&dhusername; &dhemail;</para> - + <para> + &dhusername; &dhemail; + </para> </refsect1> </refentry> diff --git a/docs/manpages/gbp-import-dsc.sgml b/docs/manpages/gbp-import-dsc.sgml index 98f70e72..e635a3d9 100644 --- a/docs/manpages/gbp-import-dsc.sgml +++ b/docs/manpages/gbp-import-dsc.sgml @@ -20,7 +20,7 @@ <refsynopsisdiv> <cmdsynopsis> &gbp-import-dsc; - + &man.common.options.synopsis; <arg><option>--allow-same-versions</option></arg> <arg><option>--author-date-is-committer-date</option></arg> <arg><option>--author-is-committer</option></arg> @@ -35,18 +35,16 @@ <arg><option>--skip-debian-tag=</option></arg> <arg><option>--upstream-branch=</option><replaceable>branch_name</replaceable></arg> <arg><option>--upstream-tag=</option><replaceable>tag-format</replaceable></arg> - <arg><option>--verbose</option></arg> <arg choice="plain"><replaceable>debian-source.dsc</replaceable></arg> </cmdsynopsis> <cmdsynopsis> &gbp-import-dsc; - <arg><option>options</option></arg> <arg choice="req"><option>--download</option></arg> <arg><option>--[no-]allow-unauthenticated</option></arg> <group choice="plain"> - <arg><replaceable>URL</replaceable></arg> - <arg><replaceable>source-package</replaceable></arg> + <arg><replaceable>URL</replaceable></arg> + <arg><replaceable>source-package</replaceable></arg> </group> </cmdsynopsis> </refsynopsisdiv> @@ -61,135 +59,163 @@ </refsect1> <refsect1> <title>OPTIONS</title> - <variablelist> + &man.common.options.description; + <varlistentry> <term><option>--upstream-branch</option>=<replaceable>branch_name</replaceable> </term> <listitem> - <para>The branch in the &git; repository the upstream sources are put - onto. Default is <replaceable>upstream</replaceable>.</para> + <para> + The branch in the &git; repository the upstream sources are put + onto. Default is <replaceable>upstream</replaceable>. + </para> </listitem> </varlistentry> <varlistentry> <term><option>--debian-branch</option>=<replaceable>branch_name</replaceable> </term> <listitem> - <para>The branch in the &git; repository the debian sources are put - onto. Default is <replaceable>master</replaceable>.</para> - </listitem> - </varlistentry> - <varlistentry> - <term><option>--verbose</option></term> - <term><option>-v</option></term> - <listitem> - <para>verbose execution</para> + <para> + The branch in the &git; repository the debian sources are put + onto. Default is <replaceable>master</replaceable>. + </para> </listitem> </varlistentry> <varlistentry> <term><option>--[no-]sign-tags</option> </term> <listitem> - <para>GPG sign all created tags</para> + <para> + GPG sign all created tags + </para> </listitem> </varlistentry> <varlistentry> <term><option>--keyid=</option><replaceable>gpg-keyid</replaceable> </term> <listitem> - <para>use this keyid for gpg signing tags</para> + <para> + use this keyid for gpg signing tags + </para> </listitem> </varlistentry> <varlistentry> <term><option>--debian-tag=</option><replaceable>tag-format</replaceable> </term> <listitem> - <para>use this tag format when tagging Debian versions, - default is <replaceable>debian/%(version)s</replaceable></para> + <para> + use this tag format when tagging Debian versions, + default is <replaceable>debian/%(version)s</replaceable> + </para> </listitem> </varlistentry> <varlistentry> <term><option>--upstream-tag=</option><replaceable>tag-format</replaceable> </term> <listitem> - <para>use this tag format when tagging upstream versions, - default is <replaceable>upstream/%(version)s</replaceable></para> + <para> + use this tag format when tagging upstream versions, + default is <replaceable>upstream/%(version)s</replaceable> + </para> </listitem> </varlistentry> <varlistentry> - <term><option>--skip-debian-tag</option></term> + <term><option>--skip-debian-tag</option> + </term> <listitem> - <para>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.</para> + <para> + 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. + </para> </listitem> </varlistentry> <varlistentry> <term><option>--filter=</option><replaceable>pattern</replaceable> </term> <listitem> - <para>filter out files glob-matching pattern. Can be given multiple times.</para> + <para> + filter out files glob-matching pattern. Can be given multiple times. + </para> </listitem> </varlistentry> <varlistentry> <term><option>--pristine-tar</option> </term> <listitem> - <para>generate pristine-tar delta file</para> + <para> + generate pristine-tar delta file + </para> </listitem> </varlistentry> <varlistentry> <term><option>--download</option> </term> <listitem> - <para>Download the source package instead of looking for it in the local - file system. The argument can either be a - <replaceable>source-package</replaceable> name or an - <replaceable>URL</replaceable>. The former uses &apt-get; to download - the source while the later uses &dget;. - </para> + <para> + Download the source package instead of looking for it in the local + file system. The argument can either be a + <replaceable>source-package</replaceable> name or an + <replaceable>URL</replaceable>. The former uses &apt-get; to download + the source while the later uses &dget;. + </para> </listitem> </varlistentry> <varlistentry> <term><option>--allow-unauthenticated</option> </term> <listitem> - <para>Whether to skip signature verification on downloads.</para> + <para> + Whether to skip signature verification on downloads. + </para> </listitem> </varlistentry> <varlistentry> <term><option>--allow-same-version</option> </term> <listitem> - <para>Allow to import a package with the same debian version.</para> + <para> + Allow to import a package with the same debian version. + </para> </listitem> </varlistentry> <varlistentry> <term><option>--author-is-committer</option> </term> <listitem> - <para>When importing the Debian patch, use the author identity as - comitter identity.</para> + <para> + When importing the Debian patch, use the author identity as + committer identity. + </para> </listitem> </varlistentry> <varlistentry> <term><option>--author-date-is-committer-date</option> </term> <listitem> - <para>When importing the Debian patch, use the author date as - comitter date. <warning><para>Git will subtly misbehave if the - committer date of a commit is not later than or equal to all - its parents.</para></warning></para> + <para> + When importing the Debian patch, use the author date as + committer date. + <warning> + <para> + Git will subtly misbehave if the committer date of a commit is not + later than or equal to all its parents. + </para> + </warning> + </para> </listitem> </varlistentry> <varlistentry> <term><option>--[no-]create-missing-branches</option> </term> <listitem> - <para>Create missing upstream and debian branch if missing.</para> + <para> + Create missing upstream and debian branch if missing. + </para> </listitem> </varlistentry> - </variablelist> + </variablelist> </refsect1> <refsect1> &man.gbp.config-files; @@ -198,22 +224,10 @@ <title>SEE ALSO</title> <para> - <citerefentry> - <refentrytitle>gbp-import-dscs</refentrytitle> - <manvolnum>1</manvolnum> - </citerefentry>, - <citerefentry> - <refentrytitle>gbp-buildpackage</refentrytitle> - <manvolnum>1</manvolnum> - </citerefentry>, - <citerefentry> - <refentrytitle>gbp-import-orig</refentrytitle> - <manvolnum>1</manvolnum> - </citerefentry>, - <citerefentry> - <refentrytitle>gbp-dch</refentrytitle> - <manvolnum>1</manvolnum> - </citerefentry>, + <xref linkend="man.gbp.import.dscs">, + <xref linkend="man.gbp.buildpackage">, + <xref linkend="man.gbp.import.orig">, + <xref linkend="man.gbp.dch">, <citerefentry> <refentrytitle>apt-get</refentrytitle> <manvolnum>1</manvolnum> @@ -222,17 +236,14 @@ <refentrytitle>dget</refentrytitle> <manvolnum>1</manvolnum> </citerefentry>, - <citerefentry> - <refentrytitle>gbp.conf</refentrytitle> - &dhconfsection; - </citerefentry>, + <xref linkend="man.gbp.conf">, &man.seealso.common; </para> </refsect1> <refsect1> <title>AUTHOR</title> - - <para>&dhusername; &dhemail;</para> - + <para> + &dhusername; &dhemail; + </para> </refsect1> </refentry> 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.</para> <title>SEE ALSO</title> <para> - <citerefentry> - <refentrytitle>gbp-import-dsc</refentrytitle> - <manvolnum>1</manvolnum> - </citerefentry>, - <citerefentry> - <refentrytitle>gbp-buildpackage</refentrytitle> - <manvolnum>1</manvolnum> - </citerefentry>, - <citerefentry> - <refentrytitle>gbp-import-orig</refentrytitle> - <manvolnum>1</manvolnum> - </citerefentry>, - <citerefentry> - <refentrytitle>gbp-dch</refentrytitle> - <manvolnum>1</manvolnum> - </citerefentry>, - <citerefentry> - <refentrytitle>gbp.conf</refentrytitle> - &dhconfsection; - </citerefentry>, + <xref linkend="man.gbp.import.dsc">, + <xref linkend="man.gbp.buildpackage">, + <xref linkend="man.gbp.import.orig">, + <xref linkend="man.gbp.dch">, + <xref linkend="man.gbp.conf">, &man.seealso.common; </para> </refsect1> diff --git a/docs/manpages/gbp-import-orig.sgml b/docs/manpages/gbp-import-orig.sgml index f6df6659..31f433b4 100644 --- a/docs/manpages/gbp-import-orig.sgml +++ b/docs/manpages/gbp-import-orig.sgml @@ -9,7 +9,7 @@ </author> </refentryinfo> <refmeta> - <refentrytitle>gbp-import-orig</refentrytitle> + <refentrytitle>gbp-import-orig</refentrytitle> &dhsection; </refmeta> <refnamediv> @@ -21,7 +21,7 @@ <cmdsynopsis> &gbp-import-orig; - <arg><option>--verbose</option></arg> + &man.common.options.synopsis; <arg><option>--upstream-version=</option><replaceable>version</replaceable></arg> <arg><option>--[no-]merge</option></arg> <arg><option>--upstream-branch=</option><replaceable>branch_name</replaceable></arg> @@ -37,8 +37,8 @@ <arg><option>--postimport=cmd</option></arg> <arg><option>--[no-]interactive</option></arg> <group choice="plain"> - <arg choice="plain"><replaceable>upstream-source</replaceable></arg> - <arg><option>--uscan</option></arg> + <arg choice="plain"><replaceable>upstream-source</replaceable></arg> + <arg><option>--uscan</option></arg> </group> </cmdsynopsis> </refsynopsisdiv> @@ -50,201 +50,215 @@ 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 <replaceable>package-name_version.orig.tar.gz</replaceable>, the version - information is read from the tarball's filename otherwise it can be - given on the command line via <option>--upstream-version</option>. - If the source package name or version can't be determined - &gbp-import-orig; will prompt for it unless <option>--no-interactive</option> - is given.</para> - - <para>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 <option>--upstream-version</option>. If the source + package name or version can't be determined &gbp-import-orig; will prompt + for it unless <option>--no-interactive</option> is given. + </para> + <para> + The sources are placed on the upstream branch (default: <replaceable>upstream</replaceable>), tagged and merged onto the debian branch (default: <replaceable>master</replaceable>). </para> </refsect1> <refsect1> <title>OPTIONS</title> - <variablelist> + &man.common.options.description; + <varlistentry> <term><option>--upstream-version</option>=<replaceable>version</replaceable></term> <term><option>-u</option><replaceable>version</replaceable></term> <listitem> - <para>The upstream version number</para> + <para> + The upstream version number + </para> </listitem> </varlistentry> <varlistentry> - <term><option>--merge</option></term> + <term><option>--[no-]merge</option></term> <listitem> - <para>Merge the upstream branch to the debian branch after import</para> + <para> + Merge the upstream branch to the debian branch after import + </para> </listitem> </varlistentry> - <varlistentry> <term><option>--upstream-branch</option>=<replaceable>branch_name</replaceable> </term> <listitem> - <para>The branch in the Git repository the upstream sources are put - onto. Default is <replaceable>upstream</replaceable>.</para> + <para> + The branch in the Git repository the upstream sources are put + onto. Default is <replaceable>upstream</replaceable>. + </para> </listitem> </varlistentry> <varlistentry> <term><option>--debian-branch</option>=<replaceable>branch_name</replaceable> </term> <listitem> - <para>The branch in the Git repository the Debian package is being - developed on, default is <replaceable>master</replaceable>. After - importing the new sources on the upstream branch, &gbp-import-orig; - will try to merge the new version onto this branch.</para> + <para> + The branch in the Git repository the Debian package is being + developed on, default is <replaceable>master</replaceable>. After + importing the new sources on the upstream branch, &gbp-import-orig; + will try to merge the new version onto this branch. + </para> </listitem> </varlistentry> <varlistentry> <term><option>--upstream-vcs-tag</option>=<replaceable>tag_name</replaceable> </term> <listitem> - <para> - Add <replaceable>tag_name</replaceable> 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. - </para> - </listitem> - </varlistentry> - <varlistentry> - <term><option>--verbose</option></term> - <term><option>-v</option></term> - <listitem> - <para>verbose execution</para> + <para> + Add <replaceable>tag_name</replaceable> 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. + </para> </listitem> </varlistentry> <varlistentry> <term><option>--[no-]sign-tags</option> </term> <listitem> - <para>GPG sign all created tags</para> + <para> + GPG sign all created tags + </para> </listitem> </varlistentry> <varlistentry> <term><option>--keyid=</option><replaceable>gpg-keyid</replaceable> </term> <listitem> - <para>use this keyid for gpg signing tags</para> + <para> + use this keyid for gpg signing tags + </para> </listitem> </varlistentry> <varlistentry> <term><option>--upstream-tag=</option><replaceable>tag-format</replaceable> </term> <listitem> - <para>use this tag format when tagging upstream versions, - default is <replaceable>upstream/%(version)s</replaceable></para> + <para> + use this tag format when tagging upstream versions, + default is <replaceable>upstream/%(version)s</replaceable> + </para> </listitem> </varlistentry> <varlistentry> <term><option>--import-msg=</option><replaceable>msg-format</replaceable> </term> <listitem> - <para>use this format string for the commit message when - importing upstream versions, default is <replaceable>Imported - Upstream version %(version)s</replaceable></para> + <para> + use this format string for the commit message when importing upstream + versions, default is + <replaceable>Imported Upstream version %(version)s</replaceable> + </para> </listitem> </varlistentry> <varlistentry> <term><option>--filter=</option><replaceable>pattern</replaceable> </term> <listitem> - <para>filter out files glob-matching pattern. Can be given multiple times.</para> + <para> + filter out files glob-matching pattern. Can be given multiple times. + </para> </listitem> </varlistentry> <varlistentry> <term><option>--[no-]pristine-tar</option> </term> <listitem> - <para>generate <command>pristine-tar</command> delta file</para> + <para> + generate <command>pristine-tar</command> delta file + </para> </listitem> </varlistentry> <varlistentry> <term><option>--[no-]filter-pristine-tar</option> </term> <listitem> - <para>if using a filter also filter the files out of the tarball - passed to <command>pristine-tar</command></para> + <para> + if using a filter also filter the files out of the tarball + passed to <command>pristine-tar</command> + </para> </listitem> </varlistentry> <varlistentry> <term><option>--[no-]symlink-orig</option></term> <listitem> - <para> - Whether to create and keep a symlink from the upstream tarball - to a Debian policy conformant upstream tarball name located in - <filename class='directory'>../</filename>. - </para> - <para> - This is a good idea if not using <command>pristine-tar</command> - since it avoids creating a new tarball with a different md5sum. - </para> + <para> + Whether to create and keep a symlink from the upstream tarball + to a Debian policy conformant upstream tarball name located in + <filename class="directory">../</filename>. + </para> + <para> + This is a good idea if not using <command>pristine-tar</command> + since it avoids creating a new tarball with a different md5sum. + </para> </listitem> </varlistentry> <varlistentry> <term><option>--postimport=<replaceable>cmd</replaceable></option></term> <listitem> - <para>run <replaceable>cmd</replaceable> after the import.</para> + <para> + run <replaceable>cmd</replaceable> after the import. + </para> </listitem> </varlistentry> <varlistentry> <term><option>--uscan</option></term> <listitem> - <para>Use uscan to fetch new upstream version.</para> + <para> + Use uscan to fetch new upstream version. + </para> + </listitem> + </varlistentry> + <varlistentry> + <term><option>--[no-]interactive</option></term> + <listitem> + <para> + Run command interactively, i.e. ask package name and version if + needed. + </para> </listitem> </varlistentry> </variablelist> </refsect1> <refsect1> <title>EXAMPLES</title> - <para>Download and import a new upstream version using the informantion from <filename>debian/watch</filename></para> + <para> + Download and import a new upstream version using the informantion from <filename>debian/watch</filename> + </para> <screen> &gbp-import-orig; --uscan </screen> - <para>After downloading an upstream tarball by hand import it</para> + <para> + After downloading an upstream tarball by hand import it + </para> <screen> &gbp-import-orig; ../upstream-tarball-0.1.tar.gz </screen> </refsect1> <refsect1> - &man.gbp.config-files; + &man.gbp.config-files; </refsect1> <refsect1> <title>SEE ALSO</title> - <para> - <citerefentry> - <refentrytitle>gbp-buildpackage</refentrytitle> - <manvolnum>1</manvolnum> - </citerefentry>, - <citerefentry> - <refentrytitle>gbp-import-dsc</refentrytitle> - <manvolnum>1</manvolnum> - </citerefentry>, - <citerefentry> - <refentrytitle>gbp-import-dscs</refentrytitle> - <manvolnum>1</manvolnum> - </citerefentry>, - <citerefentry> - <refentrytitle>gbp-dch</refentrytitle> - <manvolnum>1</manvolnum> - </citerefentry>, - <citerefentry> - <refentrytitle>gbp.conf</refentrytitle> - &dhconfsection; - </citerefentry>, + <xref linkend="man.gbp.buildpackage">, + <xref linkend="man.gbp.import.dsc">, + <xref linkend="man.gbp.import.dscs">, + <xref linkend="man.gbp.dch">, + <xref linkend="man.gbp.conf">, &man.seealso.common; </para> - </refsect1> <refsect1> <title>AUTHOR</title> - - <para>&dhusername; &dhemail;</para> - + <para> + &dhusername; &dhemail; + </para> </refsect1> </refentry> - <!-- LocalWords: xz lzma bzip gzip tarball --> diff --git a/docs/manpages/gbp-pq.sgml b/docs/manpages/gbp-pq.sgml index 83f64123..f1afb04d 100644 --- a/docs/manpages/gbp-pq.sgml +++ b/docs/manpages/gbp-pq.sgml @@ -14,39 +14,40 @@ </refmeta> <refnamediv> <refname>gbp-pq</refname> - <refpurpose>Manage quilt patches on patch queue branches in git</refpurpose> </refnamediv> <refsynopsisdiv> <cmdsynopsis> &gbp-pq; - <arg><option>--verbose</option></arg> - <arg><option>--color=</option><replaceable>[auto|on|off]</replaceable></arg> + &man.common.options.synopsis; <arg><option>--[no-]patch-numbers</option></arg> <arg><option>--topic=</option><replaceable>topic</replaceable></arg> <arg><option>--time-machine=</option><replaceable>num</replaceable></arg> + <arg><option>--[no-]drop</option></arg> + <arg><option>--force</option></arg> <group choice="plain"> - <arg><option>drop</option></arg> - <arg><option>export</option></arg> - <arg><option>import</option></arg> - <arg><option>rebase</option></arg> - <arg><option>switch</option></arg> + <arg><option>drop</option></arg> + <arg><option>export</option></arg> + <arg><option>import</option></arg> + <arg><option>rebase</option></arg> + <arg><option>switch</option></arg> </group> </cmdsynopsis> </refsynopsisdiv> <refsect1> <title>DESCRIPTION</title> <para> - &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 <replaceable>master</replaceable> - the associated patch-queue branch will be called - <replaceable>patch-queue/master</replaceable>. + &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 + <replaceable>master</replaceable> the associated patch-queue branch will be + called <replaceable>patch-queue/master</replaceable>. </para> <para> - See <ulink url="https://honk.sigxcpu.org/piki/development/debian_packages_in_git/"></ulink> for example workflows. + See <ulink url="https://honk.sigxcpu.org/piki/development/debian_packages_in_git/"></ulink> + for example workflows. </para> </refsect1> <refsect1> @@ -56,64 +57,66 @@ <term><option>import</option> </term> <listitem> - <para> - Create a patch queue branch from quilt patches in debian/patches/ that - are listed in debian/patches/series. - </para> + <para> + Create a patch queue branch from quilt patches in debian/patches/ + that are listed in debian/patches/series. The patches must apply + without fuzz. + </para> </listitem> </varlistentry> <varlistentry> <term><option>export</option> </term> <listitem> - <para> - 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. - </para> + <para> + 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. + </para> </listitem> </varlistentry> <varlistentry> <term><option>rebase</option> </term> <listitem> - <para> - Switch to the patch-queue branch associated to the current branch and - rebase it against the current branch. - </para> + <para> + Switch to the patch-queue branch associated to the current branch and + rebase it against the current branch. + </para> </listitem> </varlistentry> <varlistentry> <term><option>drop</option> </term> <listitem> - <para> - Drop (delete) the patch queue associated to the current branch. So if - you're on branch <replaceable>foo</replaceable> this would drop branch - <replaceable>patch-queue/foo</replaceable>. - </para> + <para> + Drop (delete) the patch queue associated to the current branch. So if + you're on branch <replaceable>foo</replaceable> this would drop + branch <replaceable>patch-queue/foo</replaceable>. + </para> </listitem> </varlistentry> <varlistentry> <term><option>apply</option> </term> <listitem> - <para> - Add a single patch to the patch-queue similar to using - <command>git-am</command>. Use <option>--topic</option> if you want - the patch to appear in a separate subdir when exporting the patch queue - using <option>export</option>. This can be used to separate upstream - pathes from debian specific patches.</para> + <para> + Add a single patch to the patch-queue similar to using + <command>git-am</command>. Use <option>--topic</option> if you want + the patch to appear in a separate subdir when exporting the patch queue + using <option>export</option>. This can be used to separate upstream + pathes from debian specific patches. + </para> </listitem> </varlistentry> <varlistentry> <term><option>switch</option> </term> <listitem> - <para> - Switch to the patch-queue branch if on the base branch and switch - to base branch if on patch-queue branch. - </para> + <para> + Switch to the patch-queue branch if on the base branch and switch + to base branch if on patch-queue branch. + </para> </listitem> </varlistentry> </variablelist> @@ -121,44 +124,51 @@ <refsect1> <title>OPTIONS</title> <variablelist> + &man.common.options.description; + <varlistentry> - <term><option>--verbose</option></term> - <term><option>-v</option></term> + <term><option>--[no-]patch-numbers</option> + </term> <listitem> - <para>verbose execution</para> + <para> + Whether the patch files should start with a number or not. + </para> </listitem> </varlistentry> <varlistentry> - <term><option>--color=</option><replaceable>[auto|on|off]</replaceable> + <term><option>--topic=</option><replaceable>topic</replaceable> </term> <listitem> - <para>Whether to use colored output.</para> + <para> + Topic to use when importing a single patch + </para> </listitem> </varlistentry> <varlistentry> - <term><option>--[no-]patch-numbers</option> + <term><option>--time-machine=</option><replaceable>NUM</replaceable> </term> <listitem> - <para>Whether the patch files should start with a number or not.</para> + <para> + 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 <replaceable>NUM</replaceable> 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. + </para> </listitem> </varlistentry> <varlistentry> - <term><option>--topic=</option><replaceable>topic</replaceable> - </term> + <term><option>--[no-]drop</option></term> <listitem> - <para>Topic to use when importing a single patch</para> + <para>Whether to drop (delete) the patch queue branch after + a succesful export</para> </listitem> </varlistentry> <varlistentry> - <term><option>--time-machine=</option><replaceable>NUM</replaceable> - </term> + <term><option>--force</option></term> <listitem> - <para>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 <replaceable>NUM</replaceable> 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. - </para> + <para>In case of import even import if the branch already + exists</para> </listitem> </varlistentry> </variablelist> @@ -172,28 +182,33 @@ </para> <variablelist> <varlistentry> - <term><option>Gbp[-Pq]: Ignore</option></term> + <term><option>Gbp[-Pq]: Ignore</option> + </term> <listitem> - <para>Ignores the commit, no patch is generated out of it.</para> + <para> + Ignores the commit, no patch is generated out of it. + </para> </listitem> </varlistentry> <varlistentry> - <term><option>Gbp[-Pq]: Topic</option> <replaceable>topic</replaceable></term> + <term><option>Gbp[-Pq]: Topic</option> <replaceable>topic</replaceable> + </term> <listitem> - <para>Moves the patch into a subdir called - <replaceable>topic</replaceable> when running - <screen>&gbp-pq; export</screen> - This allows for some structure below - <filename>debian/patches</filename>. - </para> + <para> + Moves the patch into a subdir called <replaceable>topic</replaceable> + when running <screen>&gbp-pq; export</screen> This allows for some + structure below <filename>debian/patches</filename>. + </para> </listitem> </varlistentry> <varlistentry> - <term><option>Gbp-Pq-Topic:</option> <replaceable>topic</replaceable></term> + <term><option>Gbp-Pq-Topic:</option> <replaceable>topic</replaceable> + </term> <listitem> - <para>Deprecated: use <option>Gbp[-Pq]: Topic</option> - <replaceable>topic</replaceable> instead. - </para> + <para> + Deprecated: use <option>Gbp[-Pq]: Topic</option> + <replaceable>topic</replaceable> instead. + </para> </listitem> </varlistentry> </variablelist> @@ -201,10 +216,7 @@ <refsect1> <title>SEE ALSO</title> <para> - <citerefentry> - <refentrytitle>gbp-buildpackage</refentrytitle> - <manvolnum>1</manvolnum> - </citerefentry>, + <xref linkend="man.gbp.buildpackage">, <citerefentry> <refentrytitle>dpkg-source</refentrytitle> <manvolnum>1</manvolnum> @@ -213,16 +225,13 @@ <refentrytitle>quilt</refentrytitle> <manvolnum>1</manvolnum> </citerefentry>, - <citerefentry> - <refentrytitle>gbp.conf</refentrytitle> - &dhconfsection; - </citerefentry> + <xref linkend="man.gbp.conf"> </para> </refsect1> <refsect1> <title>AUTHOR</title> - - <para>&dhusername; &dhemail;</para> - + <para> + &dhusername; &dhemail; + </para> </refsect1> </refentry> diff --git a/docs/manpages/gbp-pull.sgml b/docs/manpages/gbp-pull.sgml index d223228e..fd658c8d 100644 --- a/docs/manpages/gbp-pull.sgml +++ b/docs/manpages/gbp-pull.sgml @@ -21,7 +21,7 @@ <cmdsynopsis> &gbp-pull; - <arg><option>--verbose</option></arg> + &man.common.options.synopsis; <arg><option>--force</option></arg> <arg><option>--redo-pq</option></arg> <arg><option>--[no-]pristine-tar</option></arg> @@ -44,6 +44,8 @@ <title>OPTIONS</title> <variablelist> + &man.common.options.description; + <varlistentry> <term><option>--force</option></term> <listitem> @@ -90,13 +92,6 @@ </listitem> </varlistentry> <varlistentry> - <term><option>--verbose</option></term> - <term><option>-v</option></term> - <listitem> - <para>verbose execution</para> - </listitem> - </varlistentry> - <varlistentry> <term><option>--pristine-tar</option> </term> <listitem> @@ -108,7 +103,7 @@ <refsect1> <title>EXIT CODES</title> <para> - 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: </para> <variablelist> <varlistentry> @@ -137,22 +132,10 @@ <refsect1> <title>SEE ALSO</title> <para> - <citerefentry> - <refentrytitle>gbp-buildpackage</refentrytitle> - <manvolnum>1</manvolnum> - </citerefentry>, - <citerefentry> - <refentrytitle>gbp-clone</refentrytitle> - <manvolnum>1</manvolnum> - </citerefentry>, - <citerefentry> - <refentrytitle>gbp-pq</refentrytitle> - <manvolnum>1</manvolnum> - </citerefentry>, - <citerefentry> - <refentrytitle>gbp.conf</refentrytitle> - &dhconfsection; - </citerefentry> + <xref linkend="man.gbp.buildpackage">, + <xref linkend="man.gbp.clone">, + <xref linkend="man.gbp.pq">, + <xref linkend="man.gbp.conf"> </para> </refsect1> <refsect1> diff --git a/docs/manpages/gbp.conf.sgml b/docs/manpages/gbp.conf.sgml index a580220a..a0228759 100644 --- a/docs/manpages/gbp.conf.sgml +++ b/docs/manpages/gbp.conf.sgml @@ -215,38 +215,14 @@ the above list of configuration files.</para></listitem> <refsect1> <title>SEE ALSO</title> <para> - <citerefentry> - <refentrytitle>gbp-clone</refentrytitle> - <manvolnum>1</manvolnum> - </citerefentry>, - <citerefentry> - <refentrytitle>gbp-create-remote-repo</refentrytitle> - <manvolnum>1</manvolnum> - </citerefentry>, - <citerefentry> - <refentrytitle>gbp-pq</refentrytitle> - <manvolnum>1</manvolnum> - </citerefentry> - <citerefentry> - <refentrytitle>gbp-pull</refentrytitle> - <manvolnum>1</manvolnum> - </citerefentry>, - <citerefentry> - <refentrytitle>gbp-dch</refentrytitle> - <manvolnum>1</manvolnum> - </citerefentry>, - <citerefentry> - <refentrytitle>gbp-import-dsc</refentrytitle> - <manvolnum>1</manvolnum> - </citerefentry>, - <citerefentry> - <refentrytitle>gbp-import-orig</refentrytitle> - <manvolnum>1</manvolnum> - </citerefentry>, - <citerefentry> - <refentrytitle>gbp-buildpackage</refentrytitle> - <manvolnum>1</manvolnum> - </citerefentry>, + <xref linkend="man.gbp.clone">, + <xref linkend="man.gbp.create.remote.repo">, + <xref linkend="man.gbp.pq">, + <xref linkend="man.gbp.pull">, + <xref linkend="man.gbp.dch">, + <xref linkend="man.gbp.import.dsc">, + <xref linkend="man.gbp.import.orig">, + <xref linkend="man.gbp.buildpackage">, <ulink url="file:///usr/share/doc/git-buildpackage/manual-html/index.html"> <citetitle>The Git-Buildpackage Manual</citetitle></ulink> </para> diff --git a/docs/manpages/gbp.sgml b/docs/manpages/gbp.sgml index 2b570d4d..c0fdddc7 100644 --- a/docs/manpages/gbp.sgml +++ b/docs/manpages/gbp.sgml @@ -21,6 +21,8 @@ &gbp; <group choice='req'> <arg><option>--help</option></arg> + <arg><option>--version</option></arg> + <arg><option>--list-cmds</option></arg> <arg><option>command</option><arg choice='opt' rep='repeat'><option>args</option></arg></arg> </group> </cmdsynopsis> @@ -41,6 +43,20 @@ <para>Print help</para> </listitem> </varlistentry> + <varlistentry> + <term><option>--version</option> + </term> + <listitem> + <para>Print the programs version</para> + </listitem> + </varlistentry> + <varlistentry> + <term><option>--list-cmds</option> + </term> + <listitem> + <para>List all available commands</para> + </listitem> + </varlistentry> </variablelist> </refsect1> <refsect1> @@ -138,42 +154,20 @@ <refsect1> <title>SEE ALSO</title> <para> - <citerefentry> - <refentrytitle>gbp-import-dsc</refentrytitle> - <manvolnum>1</manvolnum> - </citerefentry>, - <citerefentry> - <refentrytitle>gbp-import-dscs</refentrytitle> - <manvolnum>1</manvolnum> - </citerefentry>, - <citerefentry> - <refentrytitle>gbp-import-orig</refentrytitle> - <manvolnum>1</manvolnum> - </citerefentry>, - <citerefentry> - <refentrytitle>gbp-dch</refentrytitle> - <manvolnum>1</manvolnum> - </citerefentry>, - <citerefentry> - <refentrytitle>gbp-create-remote-repo</refentrytitle> - <manvolnum>1</manvolnum> - </citerefentry>, - <citerefentry> - <refentrytitle>gbp-pull</refentrytitle> - <manvolnum>1</manvolnum> - </citerefentry>, - <citerefentry> - <refentrytitle>gbp-clone</refentrytitle> - <manvolnum>1</manvolnum> - </citerefentry>, + <xref linkend="man.gbp.buildpackage">, + <xref linkend="man.gbp.import.dsc">, + <xref linkend="man.gbp.import.dscs">, + <xref linkend="man.gbp.import.orig">, + <xref linkend="man.gbp.dch">, + <xref linkend="man.gbp.pq">, + <xref linkend="man.gbp.create.remote.repo">, + <xref linkend="man.gbp.pull">, + <xref linkend="man.gbp.clone">, <citerefentry> <refentrytitle>git-pbuilder</refentrytitle> <manvolnum>1</manvolnum> </citerefentry>, - <citerefentry> - <refentrytitle>gbp.conf</refentrytitle> - &dhconfsection; - </citerefentry> + <xref linkend="man.gbp.conf">, &man.seealso.common; </para> </refsect1> 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 @@ +<!ENTITY man.common.options.synopsis +" + <arg><option>--version</option></arg> + <arg><option>--help</option></arg> + <arg><option>--verbose</option></arg> + <arg><option>--color=</option><replaceable>[auto|on|off]</replaceable></arg> + <arg><option>--color-scheme=</option><replaceable>COLOR_SCHEME</replaceable></arg> +" +> +<!ENTITY man.common.options.description +" + <varlistentry> + <term><option>--version</option></term> + <listitem> + <para> + Print version of the program, i.e. version of the git-buildpackage + suite + </para> + </listitem> + </varlistentry> + <varlistentry> + <term><option>-v</option></term> + <term><option>--verbose</option></term> + <listitem> + <para> + Verbose execution + </para> + </listitem> + </varlistentry> + <varlistentry> + <term><option>-h</option></term> + <term><option>--help</option></term> + <listitem> + <para> + Print help and exit + </para> + </listitem> + </varlistentry> + <varlistentry> + <term><option>--color=</option><replaceable>[auto|on|off]</replaceable> + </term> + <listitem> + <para> + Whether to use colored output. + </para> + </listitem> + </varlistentry> + <varlistentry> + <term><option>--color-scheme=</option><replaceable>COLOR_SCHEME</replaceable> + </term> + <listitem> + <para> + 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). + </para> + </listitem> + </varlistentry> +" +> + 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 @@ <!ENTITY man.gbp.conf SYSTEM "gbp.conf.sgml"> <!ENTITY man.gbp.config-files SYSTEM "man.conffiles.sgml"> <!ENTITY man.seealso.common SYSTEM "man.seealso.sgml"> +<!ENTITY % COMMON.OPTIONS SYSTEM "man.common-options.ent"> +%COMMON.OPTIONS; @@ -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/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)) diff --git a/gbp/config.py b/gbp/config.py index fc31076e..174eba42 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', @@ -154,6 +155,8 @@ class GbpOptionParser(OptionParser): 'allow-unauthenticated': 'False', 'symlink-orig': 'True', 'purge': 'True', + 'drop': 'False', + 'commit': 'False', } help = { 'debian-branch': @@ -167,6 +170,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'"), @@ -196,6 +202,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': @@ -249,10 +257,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, " @@ -290,6 +298,11 @@ 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'"), + 'commit': + "commit changes after export, Default is '%(commit)s'", } def_config_files = [ '/etc/git-buildpackage/gbp.conf', @@ -516,4 +529,37 @@ 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/', + 'vendor' : 'Downstream', + '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'", + '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 " + "'%(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/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<pkg>.+)\s*') version_re = re.compile(r'Version:\s((?P<epoch>\d+)\:)?' '(?P<version>[%s]+)\s*$' diff --git a/gbp/deb/git.py b/gbp/deb/git.py index 7a328bed..2a848d4f 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 <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 @@ -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/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 <markus.lehtonen@linux.intel.com> +# 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/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/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/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/gbp/pkg/__init__.py b/gbp/pkg/__init__.py index e68fc61a..34f81cda 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 +archive_formats = [ 'tar', 'zip' ] + +# Map combined file extensions to archive 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 archive_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 archive_formats: + base_name = ".".join(split[:-2]) + archive_fmt = split[-2] + + return (base_name, archive_fmt, compression) + + class PkgPolicy(object): """ Common helpers for packaging policy. @@ -72,25 +132,63 @@ class PkgPolicy(object): return True if cls.upstreamversion_re.match(version) else False @staticmethod - def get_compression(orig_file): + def guess_upstream_src_version(filename, extra_regex=r''): """ - 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") + 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') """ - 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 + 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_'<version>.orig.tar.gz' + r'^(?P<package>[a-z\d\.\+\-]+)_(?P<version>%s+)\.orig', + # 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*)')) + 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): @@ -140,8 +238,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 @@ -278,63 +377,12 @@ class UpstreamSource(object): except gbpc.CommandExecFailed: # repackArchive already printed an error raise GbpError - return UpstreamSource(newarchive) + return type(self)(newarchive) @staticmethod def known_compressions(): 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: extra regular expression to check - @type extra_regex: raw C{string} - - >>> 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') - - @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(): - extensions = '' - else: - extensions = r'\.tar\.(%s)' % "|".join(self.known_compressions()) - - version_filters = map ( lambda x: x % (version_chars, extensions), - ( # Debian upstream tarball: package_'<version>.orig.tar.gz' - r'^(?P<package>[a-z\d\.\+\-]+)_(?P<version>%s+)\.orig%s', - # Upstream 'package-<version>.tar.gz' - # or directory 'package-<version>': - r'^(?P<package>[a-zA-Z\d\.\+\-]+)-(?P<version>[0-9]%s*)%s')) - if extra_regex: - version_filters = extra_regex + version_filters - - for filter in version_filters: - m = re.match(filter, os.path.basename(self.path)) - 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/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 <agx@sigxcpu.org> +# (C) 2012 Intel Corporation <markus.lehtonen@linux.intel.com> +# 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<name>[a-z]+)(?P<num>[0-9]+)?\s*:\s*' + '(?P<value>\S(.*\S)?)\s*$', flags=re.I) + directive_re = re.compile(r'^%(?P<name>[a-z]+)(?P<num>[0-9]+)?' + '(\s+(?P<args>.*))?$', flags=re.I) + gbptag_re = re.compile(r'^\s*#\s*gbp-(?P<name>[a-z-]+)' + '(\s*:\s*(?P<args>\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<macro_name>[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 <agx@sigxcpu.org> +# (C) 2012 Intel Corporation <markus.lehtonen@linux.intel.com> +# 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 <markus.lehtonen@linux.intel.com> +# 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..74d897bc --- /dev/null +++ b/gbp/rpm/linkedlist.py @@ -0,0 +1,214 @@ +# vim: set fileencoding=utf-8 : +# +# (C) 2012 Intel Corporation <markus.lehtonen@linux.intel.com> +# 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.debug("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.debug("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 + <BLANKLINE> + >>> 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 <markus.lehtonen@linux.intel.com> +# 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/gbp/scripts/buildpackage.py b/gbp/scripts/buildpackage.py index c077b9e6..e96e8e77 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 <agx@sigxcpu.org> +# (C) 2006-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 # -"""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,7 +29,9 @@ 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 import gbp.log import gbp.notifications @@ -37,7 +39,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) +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" @@ -171,7 +173,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: @@ -241,6 +243,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': @@ -316,7 +320,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' @@ -399,6 +403,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") @@ -482,6 +487,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-" @@ -547,9 +559,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) @@ -569,9 +581,9 @@ def main(argv): build_dir = repo_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: @@ -584,24 +596,26 @@ 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) + 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) - 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: 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/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/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 f36f2877..ce19c9a6 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 @@ -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 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 - 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'", @@ -505,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) diff --git a/gbp/scripts/import_dsc.py b/gbp/scripts/import_dsc.py index 600b394d..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 @@ -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_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 542896ef..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 @@ -23,13 +23,15 @@ 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 +from gbp.format import format_msg 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) @@ -80,7 +82,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: @@ -167,7 +169,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 +302,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) @@ -372,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() diff --git a/gbp/scripts/import_srpm.py b/gbp/scripts/import_srpm.py new file mode 100755 index 00000000..958f5ff7 --- /dev/null +++ b/gbp/scripts/import_srpm.py @@ -0,0 +1,462 @@ +# vim: set fileencoding=utf-8 : +# +# (C) 2006,2007,2011 Guido Guenther <agx@sigxcpu.org> +# (C) 2012 Intel Corporation <markus.lehtonen@linux.intel.com> +# 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_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", + 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 = dict(spec.version, vendor=options.vendor.lower()) + src_tag = repo.version_to_tag(src_tag_format, tag_str_fields) + ver_str = compose_version_str(spec.version) + + if repo.find_version(options.packaging_tag, tag_str_fields): + gbp.log.warn("Version %s already imported." % ver_str) + if options.allow_same_version: + gbp.log.info("Moving tag of version '%s' since import forced" % + ver_str) + 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<name>.*[^ ])\s*<(?P<email>\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) + msg = "%s release %s" % (options.vendor, ver_str) + + if options.orphan_packaging or not sources: + commit = repo.commit_dir(dirs['packaging_base'], + "Imported %s" % msg, + branch, + author=author, + committer=committer, + create_missing_branch=options.create_missing_branches) + else: + # Copy packaging files to the unpacked sources dir + try: + pkgsubdir = os.path.join(sources.unpacked, + 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/gbp/scripts/pq.py b/gbp/scripts/pq.py index fc205bf2..194145e8 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") @@ -67,6 +68,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): @@ -90,10 +156,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) + def safe_patches(series): """ @@ -174,8 +252,9 @@ 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.force_head('HEAD', hard=True) repo.set_branch(branch) repo.delete_branch(pq_branch) break @@ -233,11 +312,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") return parser 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 <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/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 <markus.lehtonen@linux.intel.com> +# 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\:·: + @@ -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/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/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) 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 <markus.lehtonen@linux.intel.com> +# 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 ' \ + '<markus.lehtonen@linux.intel.com>' + + 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 <email> 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 <email> 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 <email> 1\n- My change\n\n\n") + + # Set changelog and check again + new_text = "* Wed Feb 05 2014 Name <email> 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/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) 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 <markus.lehtonen@linux.intel.com> +# 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 +Subproject 90bf36d7981fdd1677cf7e734d9e1056a5fced1 diff --git a/tests/component/rpm/test_import_srpm.py b/tests/component/rpm/test_import_srpm.py new file mode 100644 index 00000000..d0e71701 --- /dev/null +++ b/tests/component/rpm/test_import_srpm.py @@ -0,0 +1,343 @@ +# vim: set fileencoding=utf-8 : +# +# (C) 2012 Intel Corporation <markus.lehtonen@linux.intel.com> +# 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(['--no-pristine-tar', 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(['--no-pristine-tar', 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(['--no-pristine-tar', '--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(['--no-pristine-tar', 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(['--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(['--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) + 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(['--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) + + # 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(['--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', + '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(['--no-pristine-tar', + '--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(['--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']) + + # 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(['--no-pristine-tar', '--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\:·: diff --git a/tests/data/rpm/rpmbuild/SOURCES/bar.tar.gz b/tests/data/rpm/rpmbuild/SOURCES/bar.tar.gz Binary files differnew file mode 100644 index 00000000..f5dae803 --- /dev/null +++ b/tests/data/rpm/rpmbuild/SOURCES/bar.tar.gz 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 Binary files differnew file mode 100644 index 00000000..7d0759fe --- /dev/null +++ b/tests/data/rpm/rpmbuild/SOURCES/gbp-test-1.0.tar.bz2 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 Binary files differnew file mode 100644 index 00000000..22a273d1 --- /dev/null +++ b/tests/data/rpm/rpmbuild/SOURCES/gbp-test-native-1.0.zip 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 Binary files differnew file mode 100644 index 00000000..7b3eaf3c --- /dev/null +++ b/tests/data/rpm/rpmbuild/SOURCES/gbp-test2-3.0.tar.gz 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 <markus.lehtonen@linux.intel.com> +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 <email> 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 <email> 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 <markus.lehtonen@linux.intel.com> + +%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 <email> 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 <markus.lehtonen@linux.intel.com> +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 <email> 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 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'] 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') |