#!/bin/bash
# Generate changelogs for any GIT project repositories:
# git log v0.5...v0.6 --pretty=format:'%s'
# Note: this script requires the use of the cdtools functions.
# -------------------------------------------------------------------------------------------

function doHelp
{
    echo ""
    echo "Generate a Changelog for a collection of repositories."
    echo ""
    echo "$0 [-d | -t <msg> ] -r <repofile> -s <version> -e <version>"
    echo "where"
    echo "-r <repofile>    File containing cdtools projects for which Changelogs should be generated"
    echo "-s <version>     Start tag, such as v0.5."
    echo "-e <version>     End tag, such as v0.6."
    echo "-t <msg>         Apply end tag (with specified message) before generating Changelog"
    echo "-d               Dry run (print but don't perform)"
}

# Test a return code.  Write code to RCFILE if not 0.
function rcCheck
{
    rc=$1
    shift
    msg=$@
    if [ $rc -ne 0 ]
    then 
        echo "$msg"
        echo $rc>${RCFILE}
    fi
    return $rc
}

# Enable debug output (aka "dry run")
function debug
{
    if [ $doDebug -eq 1 ]
    then
        echo $*
    fi
}

#--------------------------------------------------------------
# Read command line arguments
#--------------------------------------------------------------
CWD=`pwd`
ECHO=
RCFILE=${CWD}/clrc.$$
ERRFILE=${CWD}/clerr.$$
REPOS=
START=
END=
MSG=
doTag=0
doDebug=0
while getopts ":de:r:s:t:" Option
do
    case $Option in
    d) doDebug=1;;
    r) REPOS=$OPTARG;;
    e) END=$OPTARG;;
    s) START=$OPTARG;;
    t) doTag=1; MSG=$OPTARG;;
    *) doHelp; exit 0;;
    esac
done

#--------------------------------------------------------------
# Validate configuration
#--------------------------------------------------------------
if [ "$REPOS" = "" ]
then
    doHelp
    exit 0
fi

if [ ! -f $REPOS ]
then
    echo "No such file: $REPOS"
    doHelp
    exit 0
fi

if [ "$START" = "" ] || [ "$END" = "" ]
then
    doHelp
    exit 0
fi

if [ $doTag -eq 1 ] && [ "$MSG" = "" ]
then
    doHelp
    exit 0
fi

if [ $doDebug -eq 1 ]
then
    ECHO=echo
fi

#--------------------------------------------------------------
# Build command strings
#--------------------------------------------------------------
TAGCMD="git tag -a ${END} -m\"${MSG}\" >${ERRFILE} 2>&1"
PUSHCMD="git push origin --tags >${ERRFILE} 2>&1"
CLCMD="git log ${START}...${END} --pretty=format:'%s'"

# Setup
rm -rf logs
mkdir logs
cd logs
LOGDIR=`pwd`
cd $CWD

#--------------------------------------------------------------
# Process repo list
# Format:
# repoFile repo [repo ...]
#--------------------------------------------------------------
cat ${REPOS} | while read line
do
    # skip comments and blank lines
    if [ "`echo $line|cut -c1`" = "#" ] || [ "$line" = "" ]
    then
        continue;
    fi

    echo "------------------------------------"

    # Parse line for repoFile and repo command
    # "name" is used as suffix for Changelog
    repoFile=`echo ${line}|cut -f1 -d" "`
    repo=`echo ${line}|sed 's%'${repoFile}'%%'|sed 's% %%'`
    name=`echo ${repo}|cut -f1 -d" "`

    # Validate this line
    if [ "$repoFile" = "" ] || [ ! -f `expr $repoFile` ]
    then
        debug "No such file, skipping: $repoFile"
        continue
    fi
    if [ "$repo" = "" ] 
    then
        debug "Missing repo, skipping: $repoFile"
        continue
    fi

    # Change to repo location and generate log file
    # Then save log file and cleanup
    echo "Generating changelog for: $repo"
    . $repoFile
    $repo
    cd $GM_SRC
    debug "PWD=`pwd`"
    if [ $doTag -eq 1 ]
    then
        ${ECHO} eval $TAGCMD
        rcCheck $? "Failed: Tag $repo" || break
        ${ECHO} eval $PUSHCMD
        rcCheck $? "Failed: Push tags for $repo" || break
    fi
    ${ECHO} eval $CLCMD > ${LOGDIR}/Changelog.${name} 2>${ERRFILE}
    rcCheck $? "Failed: Changelog gen for $repo" || break
done

if [ -f ${RCFILE} ]
then
    rc=`cat ${RCFILE}`
    err=`cat ${ERRFILE}`
    if [ "$err" != "" ]
    then
        echo "Error: $err"
    fi
    rm -f ${RCFILE} ${ERRFILE}
    exit $rc
fi
rm -f ${RCFILE} ${ERRFILE}

# Don't do the rest if we're just doing a dry run
if [ $doDebug -eq 1 ]
then
    exit 0
fi

#--------------------------------------------------------------
# Consilidate changelogs
#--------------------------------------------------------------
cd $LOGDIR
for file in `ls -1`
do
    if [ -s $file ]
    then
        repo=`echo $file | cut -f2 -d"."`
        hdr="Repository: $repo"

        echo "-----------------------------------------------------" >> Changelog
        echo "$hdr" >> Changelog
        echo "-----------------------------------------------------" >> Changelog

        # cat $file | sort >> Changelog
        cat $file >> Changelog
        echo "" >> Changelog
    fi
done

echo "Changelog generated: "
ls -1 $LOGDIR/Changelog

