# /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