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