# /bin/sh # $Id$ # vim:et:ft=sh:sts=2:sw=2 # # Copyright 2010 Kate Ward. All Rights Reserved. # Author: kate.ward@forestent.com (Kate Ward) # # Continuous build script for shell library testing. # # Sample usages: # $ blah # treat unset variables as an error set -u # global constants ARGV0=`basename "$0"` ARGV0_DIR=`dirname "$0"` SHLIB_DIR="${ARGV0_DIR}/../lib" # load libraries . ${SHFLAGS_LIB:-${SHLIB_DIR}/shflags} \ || (echo 'unable to load shflags library' >&2; exit 1) . ${VERSIONS_LIB:-${SHLIB_DIR}/versions} \ || (echo 'unable to load versions library' >&2; exit 1) OUTPUT_FILE="${VERSIONS_OS_NAME}_${VERSIONS_OS_RELEASE}" # define flags DEFINE_string 'command' '' 'the command to start a build' 'c' DEFINE_string 'watch' '' 'file to watch for changes' 'w' DEFINE_string 'watch_from' '' 'file containing filenames to watch' 'W' DEFINE_string 'output' "${OUTPUT_FILE}" 'output file to write to' 'o' DEFINE_string 'output_dir' '.' 'directory to write output file' 'O' DEFINE_integer 'pause' 60 'pause between successive runs (sec)' 'p' FLAGS_HELP="USAGE: ${ARGV0} [flags]" #------------------------------------------------------------------------------ # functions # # This function exits the script, optionally printing a message # # Args: # message: string: an error message to be output (optional) # Output: # string: usable flags die() { [ $# -ne 0 ] && echo "$@" >&2 flags_help exit 1 } # Function to give the current date in ISO format # # Args: # none # Output: # string: isodate isodate() { date -u '+%Y%m%dT%H%M%SZ' } age() { awkScript='' case ${VERSIONS_OS_NAME} in FreeBSD|Solaris) awkScript='{print $6,$7,$8}' ;; Linux) awkScript='{print $6,$7}' ;; *) echo "unrecognized OS name (${VERSIONS_OS_NAME})" >&2 ;; esac ls -l "$1" |awk "${awkScript}" } #------------------------------------------------------------------------------ # main # main() { # checks [ -n "${FLAGS_command}" ] || die 'command required' [ -z "${FLAGS_watch}" -a -z "${FLAGS_watch_from}" ] \ && die 'one of watch or watch_from required' [ -n "${FLAGS_watch}" -a -n "${FLAGS_watch_from}" ] \ && die 'only one of watch or watch_from can be specified' [ -r "${FLAGS_watch}" ] || die 'unable to read watch file' [ -w "${FLAGS_output_dir}" ] || die 'unable to write to output directory' watchAge=`age "${FLAGS_watch}"` watchAgePrev=${watchAge} # build while true; do if [ ! "${watchAge}" == "${watchAgePrev}" ]; then date=`isodate` echo "building ${VERSIONS_OS_NAME}-${VERSIONS_OS_RELEASE} @ ${date}" outputFileDated="${FLAGS_output}-${date}" ${FLAGS_command} >"${FLAGS_output_dir}/${outputFileDated}" 2>&1 ( cd "${FLAGS_output_dir}"; rm -f "${FLAGS_output}"; ln -s "${outputFileDated}" "${FLAGS_output}"; grep FAIL "${FLAGS_output}"; ) watchAgePrev=${watchAge} fi watchAge=`age "${FLAGS_watch}"` if [ "${watchAge}" == "${watchAgePrev}" ]; then echo 'sleeping...' while [ "${watchAge}" == "${watchAgePrev}" ]; do sleep ${FLAGS_pause} watchAge=`age "${FLAGS_watch}"` done fi done } # execute main() if this is run in standalone mode (i.e. not in a unit test) argv0=`echo "${ARGV0}" |sed 's/_test$//;s/_test\.sh$//'` if [ "${ARGV0}" = "${argv0}" ]; then FLAGS "$@" || exit $? eval set -- "${FLAGS_ARGV}" if [ $# -gt 0 ]; then main "$@"; else main; fi fi