Hi, Please find another patch attached (incremental to the previous one) which workaround the limitation I explained in the report.
The patch might seem longer, but it changes the level of indentation of a large chunk; it's actually a bit more readable than with the previous one only. I didn't test it extensively on Provides and "|" in build-deps, but I hope I was careful enough not to break that part. Bye, -- Loïc Minier <[EMAIL PROTECTED]>
diff -urN pbuilder-0.160/debian/changelog pbuilder-0.161/debian/changelog --- pbuilder-0.160/debian/changelog 2006-10-03 15:20:25.000000000 +0200 +++ pbuilder-0.161/debian/changelog 2006-10-03 19:04:42.000000000 +0200 @@ -1,3 +1,12 @@ +pbuilder (0.161) unstable; urgency=low + + * Non-maintainer upload. + * Recover from APT errors caused by unsufficient dependencies (libfoo-dev + Depends: bar but baz is to be installed); this permits simply listing + build-deps when uploading to experimental. + + -- Loic Minier <[EMAIL PROTECTED]> Tue, 3 Oct 2006 16:37:57 +0200 + pbuilder (0.160) unstable; urgency=low * Non-maintainer upload. diff -urN pbuilder-0.160/pbuilder-satisfydepends pbuilder-0.161/pbuilder-satisfydepends --- pbuilder-0.160/pbuilder-satisfydepends 2006-10-03 15:19:43.000000000 +0200 +++ pbuilder-0.161/pbuilder-satisfydepends 2006-10-03 20:36:14.000000000 +0200 @@ -93,6 +93,43 @@ PROVIDED=$($CHROOTEXEC /usr/bin/apt-cache showpkg $PACKAGENAME | awk '{p=0}/^Reverse Provides:/,/^$/{p=1}{if(p && ($0 !~ "Reverse Provides:")){PACKAGE=$1}} END{print PACKAGE}') } +# returns either "package=version", to append to an apt-get install line, or +# package +function versioneddep_to_aptcmd () { + local INSTALLPKG="$1" + + local PACKAGE + local PACKAGE_WITHVERSION + local PACKAGEVERSIONS + local CANDIDATE_VERSION + local COMPARESTRING + local DEPSVERSION + + PACKAGE="$(echo "$INSTALLPKG" | sed -e 's/^[/]*//' -e 's/[[/(].*//')" + PACKAGE_WITHVERSION="$PACKAGE" + + # if not versionned, we skip directly to outputting $PACKAGE + if echo "$INSTALLPKG" | grep '[(]' > /dev/null; then + # package versions returned by APT, in reversed order + PACKAGEVERSIONS="$( package_versions "$PACKAGE" | tac | xargs )" + CANDIDATE_VERSION="$( candidate_version "$PACKAGE" )" + + # try the candidate version, then all available versions (asc) + for VERSION in $CANDIDATE_VERSION $PACKAGEVERSIONS; do + COMPARESTRING=$(echo "$INSTALLPKG" | tr "/" " " | sed 's/^.*([ ]*\(<<\|<=\|>=\|=\|<\|>>\|>\)[ ]*\(.*\)).*$/\1/') + DEPSVERSION="$(echo "$INSTALLPKG" | tr "/" " " | sed 's/^.*([ ]*\(<<\|<=\|>=\|=\|<\|>>\|>\)[ ]*\(.*\)).*$/\2/')" + if dpkg --compare-versions "$VERSION" "$COMPARESTRING" "$DEPSVERSION"; then + if [ $VERSION != $CANDIDATE_VERSION ]; then + PACKAGE_WITHVERSION="$PACKAGE=$VERSION" + fi + break; + fi + done + fi + + echo "$PACKAGE_WITHVERSION" +} + function checkbuilddep_internal () { # Use this function to fulfill the dependency (almost) @@ -129,56 +166,54 @@ fi fi - # the default is to try to install without any version constraint - CURRENTREALPKGNAME_WITHVERSION="$CURRENTREALPKGNAME" + CURRENT_APT_COMMAND="$(versioneddep_to_aptcmd "$INSTALLPKG")" - if echo "$INSTALLPKG" | grep '[(]' > /dev/null; then - # package versions returned by APT, in reversed order - PACKAGEVERSIONS="$( package_versions "$CURRENTREALPKGNAME" | tac | xargs )" - CANDIDATE_VERSION="$( candidate_version "$CURRENTREALPKGNAME" )" - - # try the candidate version, then all available versions (asc) - for VERSION in $CANDIDATE_VERSION $PACKAGEVERSIONS; do - if [ $VERSION = $CANDIDATE_VERSION ]; then - echo " -> Looking at APT's $CURRENTREALPKGNAME" - else - echo " -> Looking at APT's $CURRENTREALPKGNAME $VERSION" - fi - COMPARESTRING=$(echo "$INSTALLPKG" | tr "/" " " | sed 's/^.*([ ]*\(<<\|<=\|>=\|=\|<\|>>\|>\)[ ]*\(.*\)).*$/\1/') - DEPSVERSION="$(echo "$INSTALLPKG" | tr "/" " " | sed 's/^.*([ ]*\(<<\|<=\|>=\|=\|<\|>>\|>\)[ ]*\(.*\)).*$/\2/')" - if dpkg --compare-versions "$VERSION" "$COMPARESTRING" "$DEPSVERSION"; then - if [ $VERSION != $CANDIDATE_VERSION ]; then - CURRENTREALPKGNAME_WITHVERSION="$CURRENTREALPKGNAME_WITHVERSION=$VERSION" - fi - break; - fi - done + while [ "$SATISFIED" = "no" ]; do + echo " -> Trying to add ${CURRENT_APT_COMMAND}" + set +e + APT_OUTPUT="$( exec 2>&1; LC_ALL=C $CHROOTEXEC /usr/bin/apt-get -s install ${INSTALLPKGLIST} ${CURRENT_APT_COMMAND} )" + error="$?" + set -e + # success, we're done + if [ "$error" -eq 0 ]; then + SATISFIED="yes" + INSTALLPKGLIST="${INSTALLPKGLIST} ${CURRENT_APT_COMMAND}" + break + fi + # try to parse APT's output to recognize lines such as: + # libfoo-dev: Depends: bar (>= xyz) but www is to be installed + DEP_INSTALLPKG="$(echo "$APT_OUTPUT" | sed -n "s/^ *.*: *Depends: *\(.*\) but.*is to be installed\$/\\1/p" | tr " " "/")" + APT_ADD_COMMAND="$(versioneddep_to_aptcmd "$DEP_INSTALLPKG")" + if echo "$CURRENT_APT_COMMAND" | grep -q "$APT_ADD_COMMAND"; then + # loop detected, give up with real packages + echo " -> Loop detected, last APT error was:" + echo "$APT_OUTPUT" + break + fi + CURRENT_APT_COMMAND="$CURRENT_APT_COMMAND $APT_ADD_COMMAND" + done + if [ "$SATISFIED" = "yes" ]; then + break; fi - echo " -> Trying ${CURRENTREALPKGNAME_WITHVERSION}" - if $CHROOTEXEC /usr/bin/apt-get -s install ${INSTALLPKGLIST} ${CURRENTREALPKGNAME_WITHVERSION} >& /dev/null; then - SATISFIED="yes" - INSTALLPKGLIST="${INSTALLPKGLIST} ${CURRENTREALPKGNAME_WITHVERSION}" - else - echo " -> Cannot install ${CURRENTREALPKGNAME_WITHVERSION}; apt errors follow:" - if $CHROOTEXEC /usr/bin/apt-get -s install ${INSTALLPKGLIST} "${CURRENTREALPKGNAME_WITHVERSION}"; then - : - fi - # package could not be found. -- looking for alternative. - PROVIDED="" - checkbuilddep_provides "${CURRENTREALPKGNAME}" - if [ -n "$PROVIDED" ]; then - # something provides this package - echo " -> Considering $PROVIDED to satisfy the dependency " - if $CHROOTEXEC /usr/bin/apt-get -s install ${INSTALLPKGLIST} ${PROVIDED} >& /dev/null; then - SATISFIED="yes"; - INSTALLPKGLIST="${INSTALLPKGLIST} ${PROVIDED}" - else - # show the error for diagnostic purposes - echo " -> Cannot install $PROVIDED; apt errors follow:" - if $CHROOTEXEC /usr/bin/apt-get -s install ${INSTALLPKGLIST} ${PROVIDED}; then - : - fi + echo " -> Cannot install ${CURRENT_APT_COMMAND}; apt errors follow:" + if $CHROOTEXEC /usr/bin/apt-get -s install ${INSTALLPKGLIST} "${CURRENT_APT_COMMAND}"; then + : + fi + # package could not be found. -- looking for alternative. + PROVIDED="" + checkbuilddep_provides "${CURRENTREALPKGNAME}" + if [ -n "$PROVIDED" ]; then + # something provides this package + echo " -> Considering $PROVIDED to satisfy the dependency " + if $CHROOTEXEC /usr/bin/apt-get -s install ${INSTALLPKGLIST} ${PROVIDED} >& /dev/null; then + SATISFIED="yes"; + INSTALLPKGLIST="${INSTALLPKGLIST} ${PROVIDED}" + else + # show the error for diagnostic purposes + echo " -> Cannot install $PROVIDED; apt errors follow:" + if $CHROOTEXEC /usr/bin/apt-get -s install ${INSTALLPKGLIST} ${PROVIDED}; then + : fi fi fi