#!/bin/sh
#
########################################################################
#
# Variable and function definitions
#
AUTHOR='S.Bardeau, J.Pety <name@iram.fr>'
VERSION=`echo '$Revision: 1.38 $' | cut -d' ' -f2`
PROJECT='GILDAS <http://www.iram.fr/IRAMFR/GILDAS>'
PROGNAME=`basename $0`
#
# Changelog program name and options
CVS2CL="cvs2cl.pl"
CVS2CLFLAGS="--show-dead --no-common-dir --separate-header --stdout --stdin --window 600 --branches"
#
# Administration
WORKDIR=$HOME/gildas
LOGDIR=$WORKDIR/logs                  # Where changelog are saved
gagadmdir=$WORKDIR/gildas-admin       # Where to find executable scripts
PROJFILE=log-gildas-changes.projects  # File providing each project variables
#
SLINE="***************************************************************************"
HLINE="---------------------------------------------------------------------------"
#
########################################################################
#
# Program general functions
#
function usage() {
    cat <<EOF 1>&2

Make incremental change logs whose structure is adapted to GILDAS, and send
them as email. Versions and people mailed to are read from the file
./log-gildas-changes.projects

usage: $PROGNAME [options]

options:
  -d <date> Compute changelog between <date> 00:00:00 UTC and today
            00:00:00 UTC. <date> must be of the form "2008-08-12". Blanks
            are NOT (yet) allowed, e.g. like in "last friday".
  -l        Load correct shell environment for use in a cronjob
  -h        Show this help page
  -v        Show version information

EOF
}
#
function showversion() {
    echo "$PROGNAME version $VERSION, by $AUTHOR"
    echo "Project: $PROJECT"
}
#
function message() {
    echo "$PROGNAME: $1"
}
#
function error_exit() {
    echo 1>&2
    echo "$PROGNAME error: $1" 1>&2
    echo 1>&2
    cleanup
    exit 1
}
#
function report() {
    #
    # Send the changelog to recipients. 6 global variables must be
    # defined elsewhere:
    #   $REFDAY: used in mail subject
    #   $CLFILE: changelog file to be emailed
    #   $KEYWORD: used in mail subject
    #   $BODY: optional line to be added to the body of the mail
    #   $RECIPIENTS1: people who will also receive "No change" reports
    #   $RECIPIENTS2: people who will NOT receive "No change" reports
    #   (one or both RECIPIENTS might be empty)
    #
    echo "Sending $KEYWORD report"
    DATE=`date --date="$REFDAY" +"%d-%b-%y 00:00:00 UTC"`
    if [ -s $CLFILE ]; then
	if [ -n "$BODY" ]; then
	    echo -e "1\ni\n$BODY\n.\nw\nq\n" | \ed $CLFILE  # Add body text at beginning
	fi
	echo "$SLINE" >> $CLFILE
	SUBJECT="[$KEYWORD-changelog] All changes since $DATE"
	RECIPIENTS="$RECIPIENTS1 $RECIPIENTS2"
    else
	touch $CLFILE
	SUBJECT="[$KEYWORD-changelog] No change since $DATE"
	RECIPIENTS="$RECIPIENTS1"
    fi
    #
    echo "    File:       $CLFILE"
    echo "    Subject:    $SUBJECT"
    if [ -n "$RECIPIENTS" ]; then
	cat $CLFILE | $gagadmdir/sendmail.pl -s "$SUBJECT" $RECIPIENTS
	echo "    Recipients: $RECIPIENTS"
    else
	echo "    Recipients: <none>"
    fi
    #
}
#
########################################################################
#
# Changelog functions
#
function changelog_subsection() {
    rm -f $CLFILE1 $CLFILE2
    for DIR
	do
	if [ -d "$SRCDIR/$DIR" ]; then
	    echo "Entering $SRCDIR/$DIR"
	    cd $SRCDIR/$DIR
	    cvs log -d"$REFDATE<today 00:00:00 UTC" $CVSLOGFLAGS | $gagadmdir/$CVS2CL $CVS2CLFLAGS > $CLFILE1 || \
		error_exit "cvs2cl problem in $DIR"
	    if [ -s $CLFILE1 ]; then
		echo "$HLINE" >> $CLFILE2
		echo $DIR     >> $CLFILE2
		echo          >> $CLFILE2
		cat $CLFILE1  >> $CLFILE2
	    fi
	fi
    done
}
#
function changelog_section() {
    if [ -s $CLFILE2 ]; then
	echo "$SLINE" >> $CLFILE
	echo $1       >> $CLFILE
	echo          >> $CLFILE
	cat $CLFILE2  >> $CLFILE
    fi
}
#
function changelog_all() {
    #
    ALL_DONE="True"
    ALL_REFDAY=$REFDAY
    ALL_BODY="$ALL_BODY$KEYWORD ($PERIODICITY)\\n"
    echo $SUBJECT >> $ALL_CLFILE
    echo          >> $ALL_CLFILE
    if [ -s $CLFILE ]; then
	ALL_CHANGED="True"
	cat $CLFILE   >> $ALL_CLFILE
	echo          >> $ALL_CLFILE
    fi
    echo >> $ALL_CLFILE
    echo >> $ALL_CLFILE
    #
}
#
function cleanup() {
    rm -f $CLFILE1 $CLFILE2
    if [ -n "$TEMPDIR" -a -d "$TEMPDIR" ]; then
	rm -rf $TEMPDIR
    fi
}
#
###########################################################################
#
# Start work by tracking time
#
date
#
###########################################################################
#
# Option parsing
#
temp=`getopt "d:lhv" "$@"`
if [ $? -ne 0 ]; then usage; exit 1; fi
eval set -- "$temp"
unset temp
while [ $1 != -- ]; do
    case $1 in
    -d) INREFDAY=$2; shift ;;
    -l) loadenv=1 ;;
    -v) showversion; exit 0 ;;
    -h) usage; exit 0 ;;
    esac
    shift # Next flag
done
shift # Skip double dash
set abc; shift # This line to avoid remanence effect in a portable way
#
###########################################################################
#
# Run common code
#
# Load shell environment when asked
if [ "$loadenv" ]; then
    . $HOME/.bash_profile
fi
#
# Create working directories
TEMPDIR=/tmp/$PROGNAME-$$
mkdir $TEMPDIR   || error_exit "couldn't create TEMPDIR=$TEMPDIR"
mkdir -p $LOGDIR || error_exit "couldn't create LOGDIR=$LOGDIR"
#
# General changelog with all changes
ALL_KEYWORD=all
ALL_CLFILE=$LOGDIR/$ALL_KEYWORD-changelog
rm -f $ALL_CLFILE
ALL_DONE=      # Non-empty if any ChangeLog is produced (but may be empty)
ALL_CHANGED=   # Non-empty if any ChangeLog is not empty
#
export CVSROOT=:pserver:anonymous@cvs.iram.fr:/CVS/GILDAS
#
###########################################################################
#
# Loop over all projects in $PROJFILE
#
# Read from file $PROJFILE
PROJFILE="$gagadmdir/$PROJFILE"
#
if [ ! -e "$PROJFILE" ]; then
    error_exit "$PROJFILE not found in $gagadmdir."
fi
#
while read line; do
    #
    eval $line
    #
    if [ -n "`echo $line | grep '^PERIODICITY='`" ]; then
	#
	# Check if we have to compute this changelog today
	if [ "$PERIODICITY" = "daily" ]; then
	    GAG_TAG=`date '+%d%b' | tr '[:upper:]' '[:lower:]'`
	    if [ -n "$INREFDAY" ]; then
		REFDAY=$INREFDAY
	    else
		TODAY=`date +"%a"`
		case $TODAY in
		    "Mon")  REFDAY="last friday" ;;
		    "Sat")  REFDAY=              ;;
		    "Sun")  REFDAY=              ;;
		    *)      REFDAY="yesterday"   ;;
		esac
	    fi
	#
	elif [ "$PERIODICITY" = "weekly" ]; then
	    GAG_TAG=`date '+w%W-%y' | tr '[:upper:]' '[:lower:]'`
	    TODAY=`date +"%a"`
	    case $TODAY in
		"Mon")  REFDAY="last monday" ;;
		*)      REFDAY=              ;;
	    esac
	#
	elif [ "$PERIODICITY" = "monthly" ]; then
	    GAG_TAG=`date '+%b%y' | tr '[:upper:]' '[:lower:]'`
	    TODAY=`date +"%d"`
	    case $TODAY in
		"01")  REFDAY="1 month ago" ;;
		*)     REFDAY=              ;;
	    esac
	#
	else
	    REFDAY=
	fi
	#
    fi
    #
    if [ -z "$REFDAY" ]; then
	continue  # Cycle loop
    fi
    #
    if [ -n "`echo $line | grep '^KEYWORD='`" ]; then
	#
	# Found a new module
	if [ -z "$BRANCH" ]; then
	    BRANCH="HEAD"
	fi
	#
	echo
	echo "Changelog'ing $MODULE -r $BRANCH"
	#
	# Check-out module
	if [ -z "$SRCDIR" ]; then
	    cd $TEMPDIR
	    cvs co -r $BRANCH -d $KEYWORD $MODULE > /dev/null || \
		error_exit "couldn't check-out $MODULE -r $BRANCH"
	    #
	    SRCDIR=$TEMPDIR/$KEYWORD
	    cd $SRCDIR
	else
	    cd $SRCDIR || error_exit "couldn't cd to $SRCDIR"
	    cvs up -r $BRANCH > /dev/null || \
		error_exit "couldn't cvs up -r $BRANCH in $SRCDIR"
	fi
	#
	REFDATE=`date --date="$REFDAY" +"%Y-%m-%d 00:00:00 UTC"`
	#
	# Tune the cvs log command:
	if [ "$BRANCH" = "HEAD" ]; then
	    # -b stands for the main default (main) branch,
	    # while -rHEAD would log only the latest commit
	    CVSLOGFLAGS="-b"
	else
	    CVSLOGFLAGS="-r$BRANCH"
	fi
	#
	# Define the changelog files
	if [ ! -d "$LOGDIR/$GAG_TAG" ]; then
	    mkdir $LOGDIR/$GAG_TAG || error_exit "couldn't create LOGDIR=$LOGDIR/$GAG_TAG"
	fi
	CLFILE=$LOGDIR/$GAG_TAG/$KEYWORD-changelog
	CLFILE1=/tmp/$PROGNAME-$$-1
	CLFILE2=/tmp/$PROGNAME-$$-2
	rm -f $CLFILE
	#
    fi
    #
    if [ -n "`echo $line | grep '^SECTION_DIRS='`" ]; then
	#
	# Found a new section, compute its changelog
	changelog_subsection $SECTION_DIRS
	changelog_section    $SECTION_NAME
	#
    fi
    #
    if [ -n "`echo $line | grep '^BODY='`" ]; then
	#
	# Found the 2 recipients list and the body, now send report
	report
	#
	# Increment general changelog
	changelog_all
	#
    fi
    #
done < $PROJFILE
#
###########################################################################
#
# "all" changelog
#
if [ -n "$ALL_DONE" ]; then
    echo
    echo "General changelog"
    #
    if [ -z "$ALL_CHANGED" ]; then
	# Actually nothing changed, and $ALL_CLFILE contains only
	# lines with "[gildas-foo-changelog] No change since..."
	rm -f $ALL_CLFILE
    fi
    #
    MODULE=
    KEYWORD=$ALL_KEYWORD
    RECIPIENTS1=$ALL_RECIPIENTS1
    RECIPIENTS2=$ALL_RECIPIENTS2
    BODY=$ALL_BODY
    CLFILE=$ALL_CLFILE
    REFDAY=$ALL_REFDAY
    #
    report
    #
fi
#
###########################################################################
#
# End work
#
cleanup
#
echo
date
#
###########################################################################
