• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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@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
14set -u
15
16# global constants
17ARGV0=`basename "$0"`
18ARGV0_DIR=`dirname "$0"`
19SHLIB_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
27OUTPUT_FILE="${VERSIONS_OS_NAME}_${VERSIONS_OS_RELEASE}"
28
29# define flags
30DEFINE_string 'command' '' 'the command to start a build' 'c'
31DEFINE_string 'watch' '' 'file to watch for changes' 'w'
32DEFINE_string 'watch_from' '' 'file containing filenames to watch' 'W'
33DEFINE_string 'output' "${OUTPUT_FILE}" 'output file to write to' 'o'
34DEFINE_string 'output_dir' '.' 'directory to write output file' 'O'
35DEFINE_integer 'pause' 60 'pause between successive runs (sec)' 'p'
36
37FLAGS_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
49die() {
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
61isodate() {
62  date -u '+%Y%m%dT%H%M%SZ'
63}
64
65age() {
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
79main()
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)
121argv0=`echo "${ARGV0}" |sed 's/_test$//;s/_test\.sh$//'`
122if [ "${ARGV0}" = "${argv0}" ]; then
123  FLAGS "$@" || exit $?
124  eval set -- "${FLAGS_ARGV}"
125  if [ $# -gt 0 ]; then main "$@"; else main; fi
126fi
127