On Wed, Oct 11, 2006, Junichi Uekawa wrote:
> Hearing that I feel positive about merging this patch.
> 1. could you re-send the patch in a non-incremental form so that it's
>    easier to apply?

 Sure.  I also kept the patch split because I found the second change
 more intrusive and because it was an optional extension to the first.
 I thought you would commit those separately.  I think it's easier to
 merge the two patches separately.

 I attach a combined diff.

> 2. It might not be suitable for etch release if it's happening in two
>    months time.

 There's time to rollback the change if necessary.  The second change is
 sufficiently separate that its behavior can be made configurable.

-- 
Loïc Minier <[EMAIL PROTECTED]>
diff -urN pbuilder-0.159/debian/changelog pbuilder-0.161/debian/changelog
--- pbuilder-0.159/debian/changelog     2006-09-26 00:49:04.000000000 +0200
+++ pbuilder-0.161/debian/changelog     2006-10-11 08:14:05.000000000 +0200
@@ -1,3 +1,24 @@
+pbuilder (0.160) unstable; urgency=low
+
+  * Non-maintainer upload.
+  * Drop an useless awk invocation in pbuilder-satisfydepends.
+  * Add and use new package_versions() and candidate_version() helpers; the
+    former returns all versions of a package available via APT, the later
+    APT's candidate version.
+  * For versionned build-deps, when building the "apt-get install" command,
+    try APT's candidate version or all available versions available from APT
+    in ascending order (the reverse order of apt-cache's output);
+    checkbuilddep_versiondeps() isn't used for this part of the process
+    anymore, but it is still used to honor build-conflicts.
+  * Recover from APT errors caused by unsufficient dependencies ("libfoo-dev
+    Depends: bar but baz is to be installed") and missing dependencies
+    ("libfoo-dev Depends: bar but it is not going to be installed"); this
+    permits simply listing build-deps when uploading to experimental; achieved
+    by moving the version matching logic in the new versioneddep_to_aptcmd()
+    helper.
+
+ -- Loic Minier <[EMAIL PROTECTED]>  Tue,  3 Oct 2006 14:32:58 +0200
+
 pbuilder (0.159) unstable; urgency=low
 
   [Junichi Uekawa]
diff -urN pbuilder-0.159/pbuilder-satisfydepends 
pbuilder-0.161/pbuilder-satisfydepends
--- pbuilder-0.159/pbuilder-satisfydepends      2006-05-31 01:45:45.000000000 
+0200
+++ pbuilder-0.161/pbuilder-satisfydepends      2006-10-04 09:47:02.000000000 
+0200
@@ -21,11 +21,21 @@
 
 set -e
 
+function package_versions() {
+       local PACKAGE="$1"
+       ( $CHROOTEXEC /usr/bin/apt-cache show "$PACKAGE" ) | sed -n 
's/^Version: \(.*\)$/\1/p'
+}
+
+function candidate_version() {
+       local PACKAGE="$1"
+       LC_ALL=C $CHROOTEXEC apt-cache policy "$PACKAGE" | sed -n 's/ 
*Candidate: *\(.*\)/\1/p'
+}
+
 function checkbuilddep_versiondeps () {
     local PACKAGE="$1"
     local COMPARESTRING="$2"
     local DEPSVERSION="$3"
-    local PACKAGEVERSIONS=$( ( $CHROOTEXEC /usr/bin/apt-cache show "$PACKAGE" 
) | sed -n  's/^Version: \(.*\)$/\1/p' | xargs)
+    local PACKAGEVERSIONS=$( package_versions "$PACKAGE" | xargs)
     # no versioned provides.
     if [ "${FORCEVERSION}" = "yes" ]; then
        return 0;
@@ -83,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)
 
@@ -92,6 +139,8 @@
     local INSTALLPKGMULTI
     local CURRENTREALPKGNAME
     local SATISFIED
+    local PACKAGEVERSIONS
+    local CANDIDATE_VERSION
     echo " -> Attempting to parse the build-deps $Id: 
pbuilder-satisfydepends,v 1.28 2006/05/30 23:45:45 dancer Exp $"
     for INSTALLPKGMULTI in $(cat ${DEBIAN_CONTROL} | \
        awk '
@@ -104,7 +153,7 @@
        sed 's/^[^: ]*://' | \
        tr " " "/" | \
        awk 'BEGIN{RS=","} {print}'); do
-      echo " -> Considering $(echo "$INSTALLPKGMULTI" | tr "/" " " | awk 
'{print $0}' )"
+      echo " -> Considering build-dep$(echo "$INSTALLPKGMULTI" | tr "/" " " )"
       SATISFIED="no"
       for INSTALLPKG in $(echo "$INSTALLPKGMULTI" | \
          awk 'BEGIN{RS="|"} {print}'); do
@@ -116,40 +165,62 @@
                continue;
            fi
        fi
-       if echo "$INSTALLPKG" | grep '[(]' > /dev/null; then
-           #echo "Debug: $INSTALLPKG"
-           if ! checkbuilddep_versiondeps ${CURRENTREALPKGNAME} \
-               $(echo "$INSTALLPKG" | tr "/" " " | sed 's/^.*([ 
]*\(<<\|<=\|>=\|=\|<\|>>\|>\)[ ]*\(.*\)).*$/\1/') \
-               $(echo "$INSTALLPKG" | tr "/" " " | sed 's/^.*([ 
]*\(<<\|<=\|>=\|=\|<\|>>\|>\)[ ]*\(.*\)).*$/\2/') ; then
-             echo "   -> Does not satisfy version, not trying"
-             continue;
+
+       CURRENT_APT_COMMAND="$(versioneddep_to_aptcmd "$INSTALLPKG")"
+
+       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 \
+                   -e "s/^ *.*: *Depends: *\(.*\) but.*is to be 
installed\$/\\1/p" \
+                   -e "s/^ *.*: *Depends: *\(.*\) but it is not going to be 
installed\$/\\1/p" | \
+               head -1 | \
+               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"
+               echo "   -> ========================================="
+               echo "   -> (not adding $APT_ADD_COMMAND to 
$CURRENT_APT_COMMAND)"
+               break
+           fi
+           CURRENT_APT_COMMAND="$CURRENT_APT_COMMAND $APT_ADD_COMMAND"
+       done
+       if [ "$SATISFIED" = "yes" ]; then
+           break;
        fi
-       echo "   -> Trying ${CURRENTREALPKGNAME}"
 
-       if $CHROOTEXEC /usr/bin/apt-get -s install ${INSTALLPKGLIST} 
${CURRENTREALPKGNAME} >& /dev/null; then
-           SATISFIED="yes"
-           INSTALLPKGLIST="${INSTALLPKGLIST} ${CURRENTREALPKGNAME}"
-       else
-           echo "       -> Cannot install ${CURRENTREALPKGNAME}; apt errors 
follow:"
-           if $CHROOTEXEC /usr/bin/apt-get -s install ${INSTALLPKGLIST} 
"${CURRENTREALPKGNAME}"; 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

Reply via email to