#!/usr/bin/sh
#
# build 3.3
#
# This script builds new (?), added (A), modified (M), and updated (U) files.
#
# USAGE: build [-f "filelist" | -l logfile] [log message]
#        (the default CVS log message is "new/updated files")
#
# History:
#
# 3.3 - now appends Hub files to log with line breaks
# 3.2 - only build newer Hub files
#     - fixed premature exit on repeated Ctrl-C
# 3.1 - added jsi/glossary to filelist
#     - don't build Hub files after clearing build queue
# 3.0 - removed stylesheets and jsi from filelist
#     - suppress build queue if only Hub files found
# 2.9 - 2nd revision to Hub registration file integration
# 2.8 - revised Hub registration file integration
#     - added double quotes around variables in comparisons
# 2.7 - now builds Hub registration files
# 2.6 - now builds updated files
#     - added stylesheets to filelist
# 2.5 - upload tarball as 'username' for portability
#     - derive $project from $SITE for portability
#     - fixed basedir bug
# 2.4 - now displays queue before adding files to CVS
#     - now exits if any command fails (set -e)
#     - rewrote -f code
#     - replaced epp2link with epp_generic2.gif detection
#     - added queue generation animation
#     - added directory creation notifications
# 2.3 - now sets global vars if not already set
# 2.2 - changed "-f" option to "-l" for log
#     - added "-f" option to build files/directories
#     - fixed CVS error when nothing to build
# 2.1 - revised space detection code
#     - streamlined main conditional logic
#     - added exit code when nothing to build
# 2.0 - integrated cvsadd functionality (recursive add)
#     - changed "f" option to "-f"
# 1.9 - added call to cvsadd script
# 1.8 - now exits on CVS commit error
# 1.7 - added call to epp2link script
# 1.6 - added ability to build from file with "f" argument
# 1.5 - now exits on empty queue
# 1.4 - added check for invalid characters in filenames
# 1.3 - updated build confirmation to allow selective build
# 1.2 - added tarball upload stage
# 1.1 - added build confirmation
# 1.0 - initial release

### Precautionary measures

unset IFS
PATH=/usr/bin:/usr/local/bin
: ${SITE:=~/htdocs/site}
: ${LOGS:=~/logs}

### Set variables

cd $SITE/..

project=`echo $SITE | sed "s|^.*/||"`
filelist="$project/3d-files $project/data_sheet $project/html $project/images $project/jsi/glossary $project/pdf $project/xml"
newdirs=""
devdrop=~/dev_drop
logfile=$LOGS/release
stamp=`date +%Y-%m%d-%H%M`
tarball=$project-$stamp.tar
upload=username@site:upload
hubfiles=`find hub/*.xml -newer hub/lasttime`

### Main logic

if [ ! -d "$LOGS" ]; then
  mkdir $LOGS
  echo "Created $LOGS directory."
fi
if [ ! -d "$devdrop" ]; then
  mkdir $devdrop
  echo "Created $devdrop directory."
fi

addFiles() {
  if [ -f "$1/CVS/Root" ]; then
    for i in `cvs -nq update $1 | sed -n "s/^[?AMU] //p"`; do
      cvs -Q update $i
      if [ -f "$i" ]; then
        echo $i >> $logfile
      else
        addFiles $i
      fi
    done
  else
    newdirs=$newdirs" "`find $1 -type d`
    find $1 -type f >> $logfile
  fi
}

if [ "$1" = "-l" ]; then
  if [ -f "$LOGS/$2" ]; then
    logfile=$LOGS/$2
    shift 2
  else
    echo "No such log to build from."
    exit 1
  fi
else
  trap 'kill $!; trap 2; exit 1' 2
  echo "Generating build queue ..\c"
  { while :; do echo ".\c"; sleep 2; done; } &

  if [ "$1" = "-f" ]; then
    basedir=`echo $OLDPWD | sed "s|^$SITE|$project|"`
    basedir=`echo $basedir | sed "s|^/home/username/htdocs/||"`
    filelist=""
    for i in $2; do
      i=`echo $i | sed 's|/$||'`
      if ! echo $i | egrep -q '^/'; then
        filelist=$filelist" "$basedir/$i
      else
        i=`echo $i | sed "s|^$SITE|$project|"`
        filelist=$filelist" "$i
      fi
    done
    shift 2
  fi

  cat /dev/null > $logfile
  for i in $filelist; do
    if [ -d "$i" ]; then
      addFiles $i
    elif [ -f "$i" ]; then
      echo $i >> $logfile
    else
      kill $!
      echo "\n\nNo such file or directory: $i\n"
      exit 1
    fi
  done

  kill $!
  trap 2
  echo "\n"
fi

if [ ! -s "$logfile" ] && [ -z "$hubfiles" ]; then
  echo "Nothing to build!\n"
  exit 1
elif egrep ' [^/]+( |$)' $logfile; then
  echo "\nERROR: A space was detected in the filename(s) above."
  echo "       Please rename the file(s) and build again.\n"
  exit 1
elif files=`egrep epp_generic2.gif $logfile` && [ `find $files -size +43c` ]; then
  rm $files
  cvs -Q update $files
  echo $files
  echo "\nERROR: The placeholder image above was overwritten by an EPP"
  echo "       image that replaced its symlink. Please delete the"
  echo "       image's symlink before uploading the image.\n"
  exit 1
fi

if [ -s "$logfile" ]; then
  echo "The current build queue will be loaded in vi. Delete all files you do NOT"
  echo "want to build from the list, then save and exit vi to build only the"
  echo "remaining files.\n\nPress Enter to continue or Ctrl-C to cancel..."
  read
  vi $logfile
  if [ ! -s "$logfile" ]; then
    echo "Queue is empty. Exiting..."
    exit 1
  fi
elif [ -n "$hubfiles" ]; then
  echo "Only Hub registration files were found."
  echo "Press Enter to build these files or Ctrl-C to cancel..."
  read
fi

files=`cat $logfile`
logmsg=$*

if [ -n "$files" ]; then
  echo "Adding files to CVS ...\n"
  cvs add $newdirs $files
  echo "=====\nChecking files into the repository ...\n"
  set -e
  cvs commit -m "${logmsg:-new/updated files}" $files
fi
if [ -n "$hubfiles" ]; then
  echo $hubfiles | tr " " "\n" >> $logfile
  touch -m hub/lasttime
fi
echo "=====\nSaving log of released files to ${logfile}_$stamp ...\n"
cp $logfile ${logfile}_$stamp
echo "=====\nArchiving released files to $devdrop/$tarball ...\n"
tar cvf $devdrop/$tarball $files $hubfiles
echo "=====\nUploading $tarball to $upload ...\n"
scp -d $devdrop/$tarball $upload
echo "=====\nDONE!\n"