Home | History | Annotate | Download | only in bin
      1 # /bin/sh
      2 # $Id$
      3 # vim:et:ft=sh:sts=2:sw=2
      4 #
      5 # Copyright 2010 Kate Ward. All Rights Reserved.
      6 # Author: kate.ward (at] forestent.com (Kate Ward)
      7 #
      8 # Continuous build script for shell library testing.
      9 #
     10 # Sample usages:
     11 # $ blah
     12 
     13 # treat unset variables as an error
     14 set -u
     15 
     16 # global constants
     17 ARGV0=`basename "$0"`
     18 ARGV0_DIR=`dirname "$0"`
     19 SHLIB_DIR="${ARGV0_DIR}/../lib"
     20 
     21 # load libraries
     22 . ${SHFLAGS_LIB:-${SHLIB_DIR}/shflags} \
     23     || (echo 'unable to load shflags library' >&2; exit 1)
     24 . ${VERSIONS_LIB:-${SHLIB_DIR}/versions} \
     25     || (echo 'unable to load versions library' >&2; exit 1)
     26 
     27 OUTPUT_FILE="${VERSIONS_OS_NAME}_${VERSIONS_OS_RELEASE}"
     28 
     29 # define flags
     30 DEFINE_string 'command' '' 'the command to start a build' 'c'
     31 DEFINE_string 'watch' '' 'file to watch for changes' 'w'
     32 DEFINE_string 'watch_from' '' 'file containing filenames to watch' 'W'
     33 DEFINE_string 'output' "${OUTPUT_FILE}" 'output file to write to' 'o'
     34 DEFINE_string 'output_dir' '.' 'directory to write output file' 'O'
     35 DEFINE_integer 'pause' 60 'pause between successive runs (sec)' 'p'
     36 
     37 FLAGS_HELP="USAGE: ${ARGV0} [flags]"
     38 
     39 #------------------------------------------------------------------------------
     40 # functions
     41 #
     42 
     43 # This function exits the script, optionally printing a message
     44 #
     45 # Args:
     46 #   message: string: an error message to be output (optional)
     47 # Output:
     48 #   string: usable flags
     49 die() {
     50   [ $# -ne 0 ] && echo "$@" >&2
     51   flags_help
     52   exit 1
     53 }
     54 
     55 # Function to give the current date in ISO format
     56 #
     57 # Args:
     58 #   none
     59 # Output:
     60 #   string: isodate
     61 isodate() {
     62   date -u '+%Y%m%dT%H%M%SZ'
     63 }
     64 
     65 age() {
     66   awkScript=''
     67   case ${VERSIONS_OS_NAME} in
     68     FreeBSD|Solaris) awkScript='{print $6,$7,$8}' ;;
     69     Linux) awkScript='{print $6,$7}' ;;
     70     *) echo "unrecognized OS name (${VERSIONS_OS_NAME})" >&2 ;;
     71   esac
     72   ls -l "$1" |awk "${awkScript}"
     73 }
     74 
     75 #------------------------------------------------------------------------------
     76 # main
     77 #
     78 
     79 main()
     80 {
     81   # checks
     82   [ -n "${FLAGS_command}" ] || die 'command required'
     83   [ -z "${FLAGS_watch}" -a -z "${FLAGS_watch_from}" ] \
     84     && die 'one of watch or watch_from required'
     85   [ -n "${FLAGS_watch}" -a -n "${FLAGS_watch_from}" ] \
     86     && die 'only one of watch or watch_from can be specified'
     87   [ -r "${FLAGS_watch}" ] || die 'unable to read watch file'
     88   [ -w "${FLAGS_output_dir}" ] || die 'unable to write to output directory'
     89 
     90   watchAge=`age "${FLAGS_watch}"`
     91   watchAgePrev=${watchAge}
     92 
     93   # build
     94   while true; do
     95     if [ ! "${watchAge}" == "${watchAgePrev}" ]; then
     96       date=`isodate`
     97       echo "building ${VERSIONS_OS_NAME}-${VERSIONS_OS_RELEASE} @ ${date}"
     98       outputFileDated="${FLAGS_output}-${date}"
     99       ${FLAGS_command} >"${FLAGS_output_dir}/${outputFileDated}" 2>&1
    100 
    101       ( cd "${FLAGS_output_dir}";
    102         rm -f "${FLAGS_output}";
    103         ln -s "${outputFileDated}" "${FLAGS_output}";
    104         grep FAIL "${FLAGS_output}"; )
    105 
    106       watchAgePrev=${watchAge}
    107     fi
    108 
    109     watchAge=`age "${FLAGS_watch}"`
    110     if [ "${watchAge}" == "${watchAgePrev}" ]; then
    111       echo 'sleeping...'
    112       while [ "${watchAge}" == "${watchAgePrev}" ]; do
    113         sleep ${FLAGS_pause}
    114         watchAge=`age "${FLAGS_watch}"`
    115       done
    116     fi
    117   done
    118 }
    119 
    120 # execute main() if this is run in standalone mode (i.e. not in a unit test)
    121 argv0=`echo "${ARGV0}" |sed 's/_test$//;s/_test\.sh$//'`
    122 if [ "${ARGV0}" = "${argv0}" ]; then
    123   FLAGS "$@" || exit $?
    124   eval set -- "${FLAGS_ARGV}"
    125   if [ $# -gt 0 ]; then main "$@"; else main; fi
    126 fi
    127