bin/mdw-build: Force use of `bash' to allow file descriptors >= 10.
[profile] / bin / mdw-build
index 2af71e3..0f3f7a4 100755 (executable)
@@ -77,12 +77,14 @@ default_depends () {
 }
 : ${checkout=yes} ${checkoutrev=HEAD}
 : ${build=test}
-: ${setup=yes} ${setupcmd=mdw-setup}
+: ${setup=yes} ${setupcmd=!guess}
 : ${distcheck=yes}
 : ${debian=yes}
 : ${clean=yes}
 : ${vpath=yes}
 : ${native=yes}
+: ${make=make}
+: ${test=yes}
 default_depends sbuild sbuildsrv
 default_depends sign signkey
 default_depends upload uploadpath
@@ -111,7 +113,9 @@ Build options:
   [no]vpath
   [no]sbuild[=SERVER]
   [no]sign[=KEYID]
+  [no]test
   [no]native
+  make=MAKE
 EOF
 }
 
@@ -141,7 +145,7 @@ for opt; do
     checkout=*) checkout=yes checkoutrev=${opt#*=} ;;
     release)   build=release ;;
     norelease) build=test ;;
-    setup)     setup=yes setupcmd=mdw-setup ;;
+    setup)     setup=yes setupcmd=!guess ;;
     setup=*)   setup=yes setupcmd=${opt#*=} ;;
     upload)    maybe_set upload uploadpath ;;
     upload=*)  upload=yes uploadpath=${opt#*=} ;;
@@ -151,12 +155,14 @@ for opt; do
     sbuild=*)  sbuild=yes sbuildsrv=${opt#*=} ;;
     dput)      maybe_set dput dputtarget ;;
     dput=*)    dput=yes dputtarget=${opt#*=} ;;
+    make=*)    make=${opt#*=} ;;
 
-    distcheck | debian | clean | vpath | native)
+    distcheck | debian | clean | vpath | native | test)
       eval "$opt=yes"
       ;;
     nocheckout | nosetup | nodistcheck | nodebian | \
-    noupload | nodput | noclean | novpath | nonative | nosbuild | nosign)
+      noupload | nodput | noclean | novpath | nonative | notest | \
+      nosbuild | nosign )
       eval "${opt#no}=no"
       ;;
     *)
@@ -172,6 +178,7 @@ set -- $DEB_BUILD_OPTIONS
 for opt; do
   case "$opt" in
     parallel=*) jobs=${opt#*=} ;;
+    nocheck) test=no ;;
   esac
 done
 
@@ -181,12 +188,19 @@ case $jobs in 1) ;; *) makeopts="$makeopts -j$jobs" ;; esac
 ###--------------------------------------------------------------------------
 ### Utility functions.
 
-exec 3>&2 4>/dev/null 5>&2
+## File descriptor assignments:
+##
+##    0 -- original stdin (never touched)
+## 1, 2 -- stdout, stderr, redirected to 3 while running comamnds
+##  log -- logfile and original stderr (verbose), or logfile only (quiet);
+##             captures command output
+## diag -- logfile; primary diagnostic output
+## term -- orginal stderr; secondary diagnostic output (with colours)
 
 notify () {
   colour=$1 message=$2
-  echo $message >&4
-  echo "$(tput bold; tput setaf $colour)$message$(tput sgr0; tput op)" >&5
+  echo $message >&$diag
+  echo "$(tput bold; tput setaf $colour)$message$(tput sgr0; tput op)" >&$term
 }
 
 fail () {
@@ -212,18 +226,18 @@ assign () {
 
 runx () {
   notify 2 "+++ $*"
-  "$@" 2>&3 || fail "$1: exit $?"
+  nice "$@" 2>&$log {log}>&- {diag}>&- {term}>&- || fail "$1: exit $?"
 }
 
-run () { runx "$@" >&3; }
+run () { runx "$@" >&$log; }
 
 yesno () {
-  echo -n "(test $*)" >&4
-  if "$@" >&4 2>&4; then
-    echo "(yes)" >&4
+  echo -n "(test $*)" >&$diag
+  if "$@" >&$diag 2>&$diag {log}>&- {diag}>&- {term}>&-; then
+    echo "(yes)" >&$diag
     echo yes
   else
-    echo "(no)" >&4
+    echo "(no)" >&$diag
     echo no
   fi
 }
@@ -231,6 +245,17 @@ yesno () {
 ###--------------------------------------------------------------------------
 ### Do the building.
 
+## Some preflight checks.
+case $test,$build in
+  no,release) fail "refusing to make release build without testing" ;;
+esac
+case $test,$distcheck in
+  no,yes)
+    info "forcing \`distcheck' off because tsting disabled"
+    distcheck=no
+    ;;
+esac
+
 ## Find the top-level package directory.
 while [ ! -f configure.ac -a ! -f configure.in -a \
        ! -f .links -a ! -d .git ]; do
@@ -241,8 +266,7 @@ while [ ! -f configure.ac -a ! -f configure.in -a \
   esac
   cd ..
 done
-assign toppath $(pwd)
-assign srcpath $toppath
+toppath=$(pwd)
 
 ## Build any necessary qualifiers.
 qual= sep=.
@@ -252,19 +276,25 @@ case ${SBOX_SESSION_DIR+t},${DEB_BUILD_ARCH+t} in
 esac
 
 ## Construct the output directory.
-assign releasepath $srcpath/dist-$build$qual
+releasepath=$toppath/dist-$build$qual
 chmod -R +w $releasepath 2>/dev/null || :
 rm -rf $releasepath 2>/dev/null || :
 mkdir $releasepath
+logfile=$releasepath/mdw-build.log
+exec {term}>&2
+exec {diag}>>$logfile || fail "Failed to create log."
 case $verbose in
-  no)
-    exec 4>$releasepath/mdw-build.log 3>&4 ||
-      fail "Failed to create log."
-    ;;
+  no) exec {log}>&$diag ;;
+  yes) exec {log}> >(tee -a $logfile >&$term {term}>&- {diag}>&-) ;;
 esac
 
+## Repeat the earlier assignments for tbe benefit of the logfile.
+assign toppath $toppath
+assign releasepath $releasepath
+assign logfile $logfile
+
 ## Do we have a Git repository?
-case "$checkout,$setup,$(yesno [ -d $srcpath/.git ])" in
+case "$checkout,$setup,$(yesno [ -d $toppath/.git ])" in
   yes,no,*)
     fail "Inconsistent options: can't check out without setup."
     ;;
@@ -273,14 +303,14 @@ case "$checkout,$setup,$(yesno [ -d $srcpath/.git ])" in
     checkout=no gitver=none
     ;;
   yes,yes,yes)
-    cd $srcpath
+    cd $toppath
     [ "$(git ls-files -m)" = "" ] ||
       warn "working tree has uncommitted changes"
     ;;
 esac
 
 ## Is there Debian build equipment?
-case "$debian,$(yesno [ -d $srcpath/debian ])" in
+case "$debian,$(yesno [ -d $toppath/debian ])" in
   yes,no)
     info "No debian directory found."
     debian=no debver=none
@@ -299,12 +329,18 @@ esac
 case "$checkout" in
   yes)
     cd $releasepath
-    run git clone -sn $srcpath/.git _source
+    run git clone -sn $toppath/.git _source
     assign srcpath $releasepath/_source
     cd $srcpath
-    run git checkout -b mdw-build $checkoutrev
+    run git update-ref refs/heads/mdw-build $checkoutrev ""
+    run git symbolic-ref HEAD refs/heads/mdw-build
+    run git read-tree --reset refs/heads/mdw-build
+    run git checkout-index -afu
     assign gitversion "$(git describe --abbrev=4)"
     ;;
+  no)
+    assign srcpath $toppath
+    ;;
 esac
 
 ## Check the version number.
@@ -330,6 +366,16 @@ esac
 ## Maybe refresh the build machinery.
 case "$setup" in
   yes)
+    case $setupcmd in
+      !guess)
+       if [ -f .links ]; then setupcmd=mdw-setup
+       elif [ -x autogen.sh ]; then setupcmd=./autogen.sh
+       elif [ -x setup ]; then setupcmd=./setup
+       elif [ -f configure.ac ]; then setupcmd="autoreconf -is"
+       else setupcmd=mdw-setup
+       fi
+       ;;
+    esac
     run $setupcmd
     ;;
 esac
@@ -360,18 +406,18 @@ esac
 cat >find-distdir.mk <<'EOF'
 include Makefile
 print-distdir:
-       @echo >&3 $(distdir)
+       @bash -c 'echo >&$(fd) $(distdir)'
 EOF
 assign distdir \
-       $({ make -f find-distdir.mk print-distdir >/dev/null 2>&1; } 3>&1)
+  $({ $make -f find-distdir.mk print-distdir fd=$t >/dev/null 2>&1; } {t}>&1)
 
 ## Get a tarball distribution.
 case "$distcheck" in
   yes)
-    run make $makeopts distcheck
+    run $make $makeopts distcheck
     ;;
   no)
-    run make $makeopts dist
+    run $make $makeopts dist
     ;;
 esac
 
@@ -422,6 +468,13 @@ EOF
        fi
        ;;
     esac
+    case "$sbuild,$test, $DEB_BUILD_OPTIONS " in
+      yes,no,*) sbuildargs="-T $sbuildargs" ;;
+      *" nocheck "*) ;;
+      no,no,*)
+       DEB_BUILD_OPTIONS=${DEB_BUILD_OPTIONS+"$DEB_BUILD_OPTIONS nocheck"}
+       ;;
+    esac
     case $sbuild,$build,$sign in
       yes,*) run mdw-sbuild $sbuildargs ;;
       no,release,yes) run dpkg-buildpackage -k$signkey ;;