Package: git-buildpackage Version: 0.6.0~git20120822 Severity: normal Good day-
I've found that I occasionally need to pass arguments with spaces in them to pbuilder through git-pbuilder. For example, say I needed to create a new cowdancer build environment using the distribution components "main" and "contrib" both (so, I would want to pass '--components "main contrib"' to pbuilder). The way to pass extra arguments to pbuilder through git-pbuilder (without using a .pbuilderrc) is with $GIT_PBUILDER_OPTIONS, so I would try that: GIT_PBUILDER_OPTIONS='--components "main contrib"' \ DIST=sid \ BUILDER=cowbuilder \ git-pbuilder create Unfortunately, this fails with the error: E: too many parameters for create Running the same command under bash -x sheds some extra light on the problem: + set -e + BACKPORTS=http://backports.debian.org/debian-backports + default_BUILDER=pbuilder + default_DIST=pbuilder + default_BUILDER=pbuilder + case $default_BUILDER in + default_BUILDER=cowbuilder + case $default_BUILDER in + case $default_DIST in + default_DIST= + : cowbuilder + : cowbuilder + : sid + : + expr sid : '.*-backports$' + EXT= + '[' '!' -x /usr/sbin/cowbuilder ']' + OPTIONS='--components "main contrib"' + OUTPUT_DIR=../ + '[' no '!=' '' ']' + case $BUILDER in + : /var/cache/pbuilder + : sid + '[' -n '' ']' + '[' sid = sid ']' + '[' -d /var/cache/pbuilder/base-sid.cow ']' + BASE=/var/cache/pbuilder/base.cow + OPTIONS='--components "main contrib" --basepath /var/cache/pbuilder/base.cow' + '[' '!' -d /var/cache/pbuilder/base.cow ']' + '[' create '!=' create ']' + '[' sid = etch ']' + '[' sid = ebo ']' + case $1 in + action=create + shift + '[' -f /home/paul/.pbuilderrc ']' + '[' no = '' ']' + '[' '' = -backports ']' + sudo cowbuilder --create --dist sid --components '"main' 'contrib"' --basepath /var/cache/pbuilder/base.cow E: too many parameters for create As you can see, the quoting I used in GIT_PBUILDER_OPTIONS is not respected, despite the language on the man page which seems to imply that the contents of the variable will undergo additional shell expansion inside git-pbuilder. This is a difficult problem to fix within the confines of POSIX sh, but if we switch to bash, we can make use of the fairly-decent array functionality in order to keep better track of argument lists. I'm attaching a patch which does this. With the patch applied, the command shown above works correctly, and the chroot environment is created as expected with the noted components. I also have the given changes available in a git repo at https://github.com/thepaul/git-buildpackage.git To browse the specific changes: https://github.com/thepaul/git-buildpackage/commit/cecf2ba5 Thank you for your consideration. Hope this helps- p -- System Information: Debian Release: wheezy/sid APT prefers testing APT policy: (900, 'testing'), (50, 'unstable') Architecture: amd64 (x86_64) Kernel: Linux 3.2.0-4-amd64 (SMP w/1 CPU core) Locale: LANG=en_US.UTF-8, LC_CTYPE=en_US.UTF-8 (charmap=UTF-8) Shell: /bin/sh linked to /bin/dash Versions of packages git-buildpackage depends on: ii devscripts 2.12.4 ii git 1:1.8.0-1 ii python 2.7.3~rc2-1 ii python-dateutil 1.5+dfsg-0.1 Versions of packages git-buildpackage recommends: ii cowbuilder 0.70 ii pristine-tar 1.25 Versions of packages git-buildpackage suggests: pn python-notify <none> ii unzip 6.0-7 -- no debconf information
commit cecf2ba5359b9c3f251dd186c54634e8b04a3edd Author: paul cannon <p...@spacemonkey.com> Date: Thu Nov 8 22:47:55 2012 -0700 git-pbuilder: use arrays to handle lists of args ..so that arguments intended for pbuilder or debbuild can have spaces or other special characters in them. There was previously no way to accomplish this, since git-pbuilder only knows how to split the pbuilder-options environment variable on $IFS, without any sort of lexing (in its defense, sh/bash makes it a pain). Change-Id: I869fc00b3ef5c46ee32b6bbd008a0a2c49c8f5ea diff --git a/bin/git-pbuilder b/bin/git-pbuilder index fc0f48c..7f0d80f 100644 --- a/bin/git-pbuilder +++ b/bin/git-pbuilder @@ -1,4 +1,4 @@ -#!/bin/sh +#!/bin/bash # $Id: git-pbuilder,v 1.27 2012/01/13 04:12:35 eagle Exp $ # # git-pbuilder -- Wrapper around pbuilder for git-buildpackage @@ -75,7 +75,8 @@ if [ ! -x /usr/sbin/"$BUILDER" ]; then fi # Default options come from the environment. -OPTIONS="$GIT_PBUILDER_OPTIONS" +# eval GIT_PBUILDER_OPTIONS into an array, as some arguments may have quoting +eval "OPTIONS=( $GIT_PBUILDER_OPTIONS )" OUTPUT_DIR="${GIT_PBUILDER_OUTPUT_DIR:-../}" # How we handle options depends on what type of builder we're using. Ignore @@ -94,7 +95,7 @@ if [ no != "$GIT_PBUILDER_AUTOCONF" ] ; then : ${DIST:=sid} if [ -n "$ARCH" ] ; then BASE="$PBUILDER_BASE/base-$DIST$EXT-$ARCH.tgz" - OPTIONS="$OPTIONS --architecture $ARCH" + OPTIONS+=( --architecture "$ARCH" ) elif [ "$DIST" = 'sid' ] ; then if [ -f "$PBUILDER_BASE/base-sid.tgz" ] ; then BASE="$PBUILDER_BASE/base-sid.tgz" @@ -104,7 +105,7 @@ if [ no != "$GIT_PBUILDER_AUTOCONF" ] ; then else BASE="$PBUILDER_BASE/base-$DIST$EXT.tgz" fi - OPTIONS="$OPTIONS --basetgz $BASE" + OPTIONS+=( --basetgz "$BASE" ) # Make sure the base tarball exists. if [ ! -f "$BASE" ] && [ "$1" != "create" ]; then @@ -115,7 +116,7 @@ if [ no != "$GIT_PBUILDER_AUTOCONF" ] ; then # Set --debian-etch-workaround if DIST is etch. Assume that # everything else is new enough that it will be fine. if [ "$DIST" = 'etch' ] || [ "$DIST" = 'ebo' ] ; then - OPTIONS="$OPTIONS --debian-etch-workaround" + OPTIONS+=( --debian-etch-workaround ) fi ;; @@ -131,7 +132,7 @@ if [ no != "$GIT_PBUILDER_AUTOCONF" ] ; then : ${DIST:=sid} if [ -n "$ARCH" ] ; then BASE="$COWBUILDER_BASE/base-$DIST$EXT-$ARCH.cow" - OPTIONS="$OPTIONS --architecture $ARCH" + OPTIONS+=( --architecture "$ARCH" ) elif [ "$DIST" = 'sid' ] ; then if [ -d "$COWBUILDER_BASE/base-sid.cow" ] ; then BASE="$COWBUILDER_BASE/base-sid.cow" @@ -141,7 +142,7 @@ if [ no != "$GIT_PBUILDER_AUTOCONF" ] ; then else BASE="$COWBUILDER_BASE/base-$DIST$EXT.cow" fi - OPTIONS="$OPTIONS --basepath $BASE" + OPTIONS+=( --basepath "$BASE" ) # Make sure the base directory exists. if [ ! -d "$BASE" ] && [ "$1" != "create" ]; then @@ -152,7 +153,7 @@ if [ no != "$GIT_PBUILDER_AUTOCONF" ] ; then # Set --debian-etch-workaround if DIST is etch. Assume that # everything else is new enough that it will be fine. if [ "$DIST" = 'etch' ] || [ "$DIST" = 'ebo' ] ; then - OPTIONS="$OPTIONS --debian-etch-workaround" + OPTIONS+=( --debian-etch-workaround ) fi ;; @@ -171,7 +172,7 @@ if [ no != "$GIT_PBUILDER_AUTOCONF" ] ; then echo "Cannot read configuration file $QEMUCONFIG" >&2 exit 1 fi - OPTIONS="$OPTIONS --config $QEMUCONFIG" + OPTIONS+=( --config "$QEMUCONFIG" ) ;; *) @@ -194,19 +195,19 @@ update|create|login) # it. Instead, check if the user has a .pbuilderrc and, if so, explicitly # add it as a configuration file. if [ -f "$HOME/.pbuilderrc" ] ; then - OPTIONS="$OPTIONS --configfile $HOME/.pbuilderrc" + OPTIONS+=( --configfile "$HOME/.pbuilderrc" ) fi # Run the builder. if [ no = "$GIT_PBUILDER_AUTOCONF" ] ; then - sudo "$BUILDER" --"$action" $OPTIONS "$@" + sudo "$BUILDER" --"$action" "${OPTIONS[@]}" "$@" else if [ "$EXT" = '-backports' ] ; then OTHERMIRROR="deb $BACKPORTS $DIST$EXT main" sudo "$BUILDER" --"$action" --dist "$DIST" \ - --othermirror "$OTHERMIRROR" $OPTIONS "$@" + --othermirror "$OTHERMIRROR" "${OPTIONS[@]}" "$@" else - sudo "$BUILDER" --"$action" --dist "$DIST" $OPTIONS "$@" + sudo "$BUILDER" --"$action" --dist "$DIST" "${OPTIONS[@]}" "$@" fi fi exit $? @@ -235,18 +236,27 @@ fi # or -I flags unless we're using source format 1.0. if [ ! -f debian/source/format ] || grep -qs '^1.0' debian/source/format ; then echo 'Source format 1.0 detected, adding exclude flags' - DEBBUILDOPTS="-i'(?:^|/)\\.git(attributes)?(?:\$|/.*\$)' -I.git $*" + DEBBUILDOPTS="-i'(?:^|/)\\.git(attributes)?(?:\$|/.*\$)' -I.git" else - DEBBUILDOPTS="$*" + DEBBUILDOPTS="" fi +shell_quote () { + echo "$1" | sed -e "s/'/'\"'\"'/g" -e "1 s/^/'/" -e "\$ s/\$/'/" +} + +for arg in "$@"; do + DEBBUILDOPTS+=" $(shell_quote "$arg")" +done + # Now we can finally run pdebuild. The quoting here is tricky, but this # seems to pass everything through properly. if [ no = "$GIT_PBUILDER_AUTOCONF" ] ; then - pdebuild --pbuilder "$BUILDER" --debbuildopts "$DEBBUILDOPTS" -- $OPTIONS + pdebuild --pbuilder "$BUILDER" --debbuildopts "$DEBBUILDOPTS" -- \ + "${OPTIONS[@]}" else pdebuild --buildresult $OUTPUT_DIR --pbuilder "$BUILDER" \ - --debbuildopts "$DEBBUILDOPTS" -- $OPTIONS + --debbuildopts "$DEBBUILDOPTS" -- "${OPTIONS[@]}" fi status="$?" if [ -n "`ls ../*_source.changes`" ] ; then