bin/mdw-sbuild-server: Unbreak local package support.
[profile] / bin / mdw-sbuild-server
index 1ac507f..e4c919f 100755 (executable)
@@ -33,7 +33,6 @@ do
 done
 : ${buildroot=$HOME/build}
 : ${default_targets="wheezy-amd64 wheezy-i386"}
-: ${parallel=-j3}
 : ${DEB_BUILD_OPTIONS=parallel=4}; export DEB_BUILD_OPTIONS
 
 ###--------------------------------------------------------------------------
@@ -42,7 +41,7 @@ done
 prog=${0##*/}
 
 fail () { echo >&2 "$prog: $*"; exit 1; }
-usage () { echo "usage: $prog [-ain] [-t TARGET] COMMAND [ARGUMENTS ...]"; }
+usage () { echo "usage: $prog [-aiknT] [-t TARGET] [-A DBPARGS] COMMAND [ARGUMENTS ...]"; }
 fail_usage () { usage >&2; exit 1; }
 
 want_1 () {
@@ -57,13 +56,27 @@ want_1 () {
   echo "$1"
 }
 
+run () {
+  case $notreally in
+    t) echo "+ $*" ;;
+    nil) nice "$@" ;;
+  esac
+}
+
+decor () {
+  tag=$1 marker=$2
+  while IFS= read -r line; do
+    printf "%-21s %c %s\n" "$tag" "$marker" "$line"
+  done
+}
+
 ###--------------------------------------------------------------------------
 ### Parse options.
 
-bogusp=nil archp=nil indepp=nil makeopts=""
-unset targets
+bogusp=nil archp=nil indepp=nil keepon=nil notreally=nil
+unset targets dbpargs
 
-while getopts "haint:" opt; do
+while getopts "haint:A:T" opt; do
   case $opt in
     h)
       usage
@@ -73,8 +86,11 @@ Options:
        -h              Show this help text.
        -a              Build only architecture-dependent packages.
        -i              Build only architecture-neutral packages.
+       -k              Keep going even if one fails.
        -n              Don't actually do the build.
        -t TARGET       Build in TARGET build environment.
+       -A ARGS         Pass ARGS to \`dpkg-buildpackage'.
+       -T              Don't run the tests.
 
 Commands available:
 
@@ -91,8 +107,16 @@ EOF
       ;;
     a) archp=t ;;
     i) indepp=t ;;
-    n) makeopts="${makeopts+$makeopts }-n" ;;
+    k) keepon=t ;;
+    n) notreally=t ;;
     t) targets="${targets+$targets }$OPTARG" ;;
+    A) dbpargs="${dbpargs+$dbpargs }$OPTARG" ;;
+    T)
+      case " $DEB_BUILD_OPTIONS " in
+       *" nocheck "*) ;;
+       *) DEB_BUILD_OPTIONS=${DEB_BUILD_OPTIONS+"$DEB_BUILD_OPTIONS "} nocheck ;;
+      esac
+      ;;
     *) bogusp=nil ;;
   esac
 done
@@ -137,6 +161,7 @@ case "$#,$1" in
       ## racing with another process, but that's why we're trying in a loop.
       if mkdir "$ver#$nn" >/dev/null 2>&1; then
        winp=t
+       cd "$ver#$nn"
        break
       fi
 
@@ -149,6 +174,9 @@ case "$#,$1" in
     ## Make sure we actually succeeded.
     case $winp in t) ;; *) fail "failed to create build directory" ;; esac
 
+    ## Make an empty directory for dependency packages.
+    mkdir -p pkgs/
+
     ## Done.
     echo "$buildroot/$dist#$nn"
     ;;
@@ -210,7 +238,7 @@ case "$#,$1" in
          *)
            ## There's at least one architecture-specific package.
 
-           ## If we don't want to build architecture-specific package then
+           ## If we don't want to build architecture-specific packages then
            ## there's nothing to do.
            case $archp in nil) continue ;; esac
 
@@ -242,48 +270,51 @@ case "$#,$1" in
     esac
     case $archp in
       t) ;;
-      nil) firstopt="$firstopt --debbuildopt=-A" ;;
+      nil) firstopt="$firstopt --no-arch-any" ;;
     esac
 
-    ## Build a cheesy makefile to run these in parallel.
-    cat >build.mk <<EOF
-### -*-makefile-*-
-DSC = $dsc
-FIRST = $first
-REST = $rest
-sbuild-wrap = \\
-       t=\$@; \\
-       host=\$\${t\#\#*/} full=\$\${t%/*}; \\
-       suite=\$\${full%%-*} target=\$\${full\#*-}; \\
-       { echo started >build-status.\$\$full; \\
-         sbuild \\
-               --dist=\$\$suite --build=\$\$host --host=\$\$target \\
-               --chroot=\$\$suite-\$\$host --verbose \$1 \$(DSC); \\
-         rc=\$\$?; case \$\$rc in \\
-           0) echo ok >build-status.\$\$full ;; \\
-           *) echo failed rc=\$\$rc >build-status.\$\$full ;; \\
-         esac; } | \\
-       while IFS= read -r line; do \\
-         printf "%s: %s\n" "\$\$full" "\$\$line"; \\
-       done; \\
-       read st _ <build-status.\$\$full && \\
-       case \$\$st in ok) exit 0 ;; *) exit 1 ;; esac
-all: \$(FIRST) \$(REST)
-\$(FIRST):; \$(call sbuild-wrap,$firstopt)
-\$(REST):; \$(call sbuild-wrap,--no-arch-all)
-EOF
+    ## Sort out the additional packages.  This is rather annoying, because
+    ## sbuild(1) does this in a really stupid way.
+    rm -rf pkgs.*
+    for a in $buildarchs; do
+      mkdir pkgs.$a
+      for f in $(dpkg-scanpackages -a$a pkgs/ |
+                   sed -n '/^Filename: /s///p')
+      do
+       ln $f pkgs.$a/
+      done
+    done
 
-    ## Make some marker files to say things are in progress.
-    for i in $first $rest; do echo "starting" >build-status.${i%/*}; done
-
-    ## And we're ready to go.
-    mkfifo pipeout
-    cat pipeout& catpid=$!
-    set +e; make -fbuild.mk $parallel $makeopts -k all >pipeout
-    rc=$?; set -e
-    wait $!
-    rm build.mk pipeout build-status.*
-    find . -maxdepth 1 -type l -exec rm {} \;
+    ## Build the builds sequentially.  Tests can conflict with each other,
+    ## e.g., over port numbers.
+    rc=0 buildopt=$firstopt
+    for t in $first $rest; do
+      host=${t##*/} full=${t%/*}
+      suite=${full%%-*} target=${full#*-}
+
+      ## And we're ready to go.
+      exec 3>&1
+      thisrc=$(
+       { { { { set +e
+               run sbuild --extra-package=pkgs.$target \
+                   --dist=$suite --build=$host --host=$target \
+                   --chroot=$suite-$host --verbose $buildopt $dsc \
+                   ${dbpargs+--debbuildopts="$dbpargs"} \
+                   3>&- 4>&- 5>&-
+               echo $? >&5
+             } |
+               decor "$full" "|" >&4; } 2>&1 |
+             decor "$full" "*" >&4; } 4>&1 |
+           cat -u >&3; } 5>&1 </dev/null)
+      exec 3>&-
+      case $thisrc in 0) ;;
+       *)
+         echo failed rc=$thisrc >$stat; rc=$thisrc
+         case $keepon in nil) break ;; esac
+         ;;
+      esac
+      buildopt=--no-arch-all
+    done
     exit $rc
     ;;
   build,*)