#!/bin/bash
# Copyright (c) 2000-2006 Matthias S. Benkmann <article AT winterdrache DOT de>
# You may do everything with this code except misrepresent its origin.
# PROVIDED `AS IS' WITH ABSOLUTELY NO WARRANTY OF ANY KIND!

# This script will build a package based on the commands in $HOME/build.conf
# It can be called with the following parameters that
# will cause it to execute the respective *_commands() functions. If it is
# called with no parameter, that is equivalent to
# build unpack patch configure make check install clean
#
# It will create 8 log files in the $HOME directory:
#   configure.log: All messages output during configure
#   configure.err: Just the errors output during configure
#   check.log: All messages output during checking
#   check.err: Just the errors output during checking
#   make.log: All messages output during make
#   make.err: Just the errors output during make
#   install.log: All messages output during make install
#   install.err: Just the errors output during make install
#
# After running the script you should check the *.err files to see
# if any problems have occurred. If that is the case, use the corresponding
# *.log files to see the error messages in context.

build_script="$(readlink -f "$0")"

cd  # go HOME

source "$HOME"/build.conf

if [ "_$(whoami)" != _root ]; then
  export PACKAGE_OWNER="$(whoami)"
fi


 # This function auto-extracts tarballs based on PATTERNS (see build.conf) inside
 # the directory $HOME/xxxbuild and
 # cds into the fist directory created by the first tarball. This is also
 # stored in the variable $srcdir.
unpack_commands()
{ :
  export srcdir=""
  rm -rf "$HOME/xxxbuild"
  mkdir -p "$HOME/xxxbuild" 
  cd "$HOME/xxxbuild" || return 1
  
  for p in $PATTERNS ; do
    for archive in "$HOME"/*"$p"* ; do
      dir=""
      if [ -f "$archive" ]; then
        case z"$archive" in
          z*.tar.bz2) dir=$(tar tjf "$archive" | grep / | head -n 1) ; tar xjf "$archive"  ;;
          z*.tar.gz)  dir=$(tar tzf "$archive" | grep / | head -n 1) ; tar xzf "$archive"  ;;
        esac
      fi
      dir=${dir##./}
      test -z "$dir" && echo 1>&2 "Error extracting $archive"
      test -z "$srcdir" && srcdir=${dir%%/*}
    done
  done
  
  test -z "$srcdir" && { echo 1>&2 "Source directory not found" ; return 1 ; }
  ln -s "$srcdir" yyysrc
}

clean_commands()
{
  rm -rf "$HOME/xxxbuild"
}

test_pipe()
{
  for i in "${PIPESTATUS[@]}" 
  do
    test $i != 0 && { echo FAILED! ; exit 1 ; }
  done
  echo successful!
  return 0
}

if [ $# -eq 0 ]; then
  set -- unpack patch configure make check root_pre_install install root_post_install clean
fi

while [ -n "$1" ]; do
  case "_$1" in
    _all)
        shift 1
        set -- dummy unpack patch configure make check root_pre_install install root_post_install clean "$@"
        ;;
        
    _unpack)
        echo -n Unpacking...

        unpack_commands # no logging for unpack necessary 
        test_pipe
        ;;
   
    _patch)
        cd "$HOME/xxxbuild/yyysrc" && srcdir="$(pwd)" || exit 1
        patch_commands # no logging for patch necessary 
        #test_pipe
        ;;

    _configure)
        cd "$HOME/xxxbuild/yyysrc" && srcdir="$(pwd)" || exit 1
        echo -n Configuring...

        { configure_commands 3>&1 1>&2 2>&3 | tee "$HOME/configure.err" ;} &>"$HOME/configure.log"
        test_pipe
        # NOTE: Simply using && instead of test_pipe would not work, because &&
        # only tests the exit status of the last command in the pipe, which is tee.
        ;;

    _make)
        cd "$HOME/xxxbuild/yyysrc" && srcdir="$(pwd)" || exit 1
        echo -n Building...

        { make_commands 3>&1 1>&2 2>&3 | tee "$HOME/make.err" ;} &>"$HOME/make.log"
        test_pipe
        ;;

    _check)
        cd "$HOME/xxxbuild/yyysrc" && srcdir="$(pwd)" || exit 1
        echo -n Checking...

        { check_commands 3>&1 1>&2 2>&3 | tee "$HOME/check.err" ;} &>"$HOME/check.log"
        test_pipe
        ;;
    
    _root_pre_install)
        if type root_pre_install_commands &>/dev/null ; then
          if [ _$(whoami) != _root ]; then
            su --preserve-environment root -c "HOME='$HOME' '$build_script' root_pre_install" || exit 1
          else  
            echo -n "Preparing for install(root)..."
  
            { root_pre_install_commands 3>&1 1>&2 2>&3 | tee "$HOME/preinstall.err" ;} &>"$HOME/preinstall.log"
            test_pipe
          fi  
        fi
        ;;
        
    _install)
        cd "$HOME/xxxbuild/yyysrc" && srcdir="$(pwd)" || exit 1
        echo -n Installing...

        { install_commands 3>&1 1>&2 2>&3 | tee "$HOME/install.err" ;} &>"$HOME/install.log"
        test_pipe
        ;;
    
    _root_post_install)
        if type root_post_install_commands &>/dev/null ; then
          if [ _$(whoami) != _root ]; then
            su --preserve-environment root -c "HOME='$HOME' '$build_script' root_post_install" || exit 1
          else  
            echo -n "Finishing install(root)..."
  
            { root_post_install_commands 3>&1 1>&2 2>&3 | tee "$HOME/postinstall.err" ;} &>"$HOME/postinstall.log"
            test_pipe
          fi  
        fi  
        ;;
        
    _clean)
        cd "$HOME"
        echo -n Cleaning...
        clean_commands
        echo done!
        ;;
    *)
        echo 1>&2 "Unknown command '$1'"
        exit 1
        ;;
  esac       
  shift 1
done
