#!/bin/bash -e
usage='
  kentBuild [options] [kentDir] [outRoot]

Build kent/src tree and run tests.  

Designed for running under a cron job, this saves the stdout/err in *.log
files in kentDir. It then parses the output file to find errors reported by
make an copies the regions of the output log containing the errors to stderr.
This way, both the error message and the context can be seen without needing
to read through the entire log. If there are no errors, there is no output.

This requires a checked out tree, a cvs update can optionally be done 
after a make clean, so that deleted directories can be removed.

Options:
   -update - do a cvs update after the make clean
   -noClean - do not execute the make clean step
   -noCompile - do not execute the compile step
   -noTest - do not execute the make test step
Arguments:
   o kentDir - top of kent tree; this should be the "kent" directory,
     NOT kent/src.  Defaults  to ~/kent.
   o outRoot - if specified, bin and cgi-bin output is placed under this
     directory instead of clobbering the standard locations.
'

# make a path absolute
absPath() {
    case "$1" in
        /*) echo "$1";;
        *) echo "`pwd`/$1";;
    esac
}

# print a message about a failure in a make, output filtered log file
# and exit.
makeErr() {
    local desc="$1"
    local logFile="$2"
    echo "Error: kent/src $desc failed"  >&2
    echo "full log file is on `hostname`: $kentDir/$logFile" >&2
    echo "Error summary:" >&2
    ./build/makeErrFilter $logFile
    exit 2
}

# begin here
doUpdate="no"
doClean="yes"
doCompile="yes"
doTest="yes"
while [[ "$1" == -* ]] ; do
    case $1 in
        -update) doUpdate="yes" ;;
        -noClean) doClean="no" ;;
        -noCompile) doCompile="no" ;;
        -noTest) doTest="no" ;;
        *) echo "Error: invalid option: $1" >&2
            exit 1;;
    esac
    shift
done

if [ $# -gt 2 ]  ; then
    echo "Error: wrong number of arguments" >&2
    echo "$usage" >&2
    exit 1
fi

# some setup
export MACHTYPE=`uname -m`
if [ "$MACHTYPE" == "i686" ] ; then
    export MACHTYPE=i386
fi
# might need to change HOME
USERHOME=$HOME

# parse command line
if [ $# -gt 0 ] ; then
    kentDir=`absPath "$1"`
    shift
else
    kentDir=$USERHOME/kent
fi

# don't want test to pickup other binaries
export PATH=".:/usr/local/bin:/bin:/usr/bin"

if [ $# -gt 0 ] ; then
    outRoot=`absPath "$1"`
    shift
    # reconfigure enviromment for different output directory
    export SCRIPTS=$outRoot/bin/scripts
    export CGI_BIN=$outRoot/cgi-bin
    export HOME=$outRoot
    export HGDB_CONF=$USERHOME/.hg.conf
    machBinDir=$outRoot/bin/${MACHTYPE}
    export PATH="${machBinDir}:${SCRIPTS}:${PATH}"
    mkdir -p ${machBinDir}
    mkdir -p ${SCRIPTS}
    mkdir -p ${CGI_BIN}-${USER}
else
    export PATH="${HOME}/bin/${MACHTYPE}:${HOME}/bin/scripts:${PATH}"
fi

# find mysql libraries
if [ "$MACHTYPE" == "x86_64" ] ; then
    export MYSQLINC="/usr/include/mysql"
    export MYSQLLIBS="/usr/lib64/mysql/libmysqlclient.a -lz"
elif [ -e /usr/lib/mysql/libmysqlclient.a ] ; then 
    export MYSQLINC="/usr/include/mysql"
    export MYSQLLIBS="/usr/lib/mysql/libmysqlclient.a -lz"
else
    export MYSQLINC="/usr/local/mysql/include/mysql"
    export MYSQLLIBS="/usr/local/mysql/lib/mysql/libmysqlclient.a -lz"
fi

cd $kentDir

if [ $doClean = "yes" ] ; then
    ((cd src && make -k clean) > clean.log 2>&1) || {
        makeErr "clean" clean.log
    }
fi

if [ $doUpdate = "yes" ] ; then
    (cvs update -d -P > update.log 2>&1) || {
        echo "Error: kent/src cvs update failed" >&2
        echo "full log file is on `hostname`: $kentDir/update.log" >&2
        exit 2
    }
fi

if [ $doCompile = "yes" ] ; then
    ((cd src && make -k) > compile.log 2>&1) || {
        makeErr "compile" compile.log
    }
fi


((cd src && make tags etags) > tags.log 2>&1) || {
    makeErr "tags" tags.log
}

if [ $doTest = "yes" ] ; then
    ((cd src && make -k test) > test.log 2>&1) || {
        makeErr "tests" test.log
    }
fi
