Bug#390888: [Pbuilder-maint] Bug#390888: Full support for experimental

Loïc Minier lool at dooz.org
Fri Oct 13 20:13:38 UTC 2006


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

 Here is an updated version which handles a third type of APT error when
 you mix experimental and unstable sources.  I attach the updated
 combined patch, and a samble build log.

-- 
Loïc Minier <lool at dooz.org>
-------------- next part --------------
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-13 22:08:28.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", or simply
+    "libfoo-dev Depends: bar"); 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 <lool at dooz.org>  Fri, 13 Oct 2006 22:07:30 +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-13 22:05:39.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,63 @@
 		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" \
+		    -e "s/^ *.*: *Depends: *\(.*\)\$/\\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
-------------- next part --------------
 -> Considering build-dep libgtk-directfb-2.0-dev (>= 2.10.1-1)
   -> Trying to add libgtk-directfb-2.0-dev=2.10.6-2
   -> Trying to add  libgtk-directfb-2.0-dev=2.10.6-2
   -> Loop detected, last APT error was: ======
Reading package lists...
Building dependency tree...
Some packages could not be installed. This may mean that you have
requested an impossible situation or if you are using the unstable
distribution that some required packages have not yet been created
or been moved out of Incoming.
The following information may help to resolve the situation:

The following packages have unmet dependencies:
  libgtk-directfb-2.0-dev: Depends: libgtk-directfb-2.0-0 (= 2.10.6-2)
E: Broken packages
   -> =========================================
   -> (not adding  to  libgtk-directfb-2.0-dev=2.10.6-2)


More information about the Pbuilder-maint mailing list