#!/bin/sh
#
# $Id: bkexport.sh,v 1.36 2003/07/09 12:52:00 dwmw2 Exp $ 

BKDIR="$1"
PATCHDIR="$2"
CACHEDIR="$3"
MLIST="$4"
STAGINGDIR="$5"

STAGINGLOCK=$CACHEDIR/staginglock
SCRIPTLOCK=$CACHEDIR/scriptlock

if [ "$BKDIR" = "" -o "$PATCHDIR" = "" -o "$CACHEDIR" = "" ] ; then
    echo "Usage: $0 <bkdir> <patchdir> <cachedir> [<mlist>] [<stagingdir>]"
    exit 1
fi

if [ "$STAGINGDIR" = "" ] ; then
    STAGINGDIR="$PATCHDIR"
fi

cd $STAGINGDIR || exit 1

cd $PATCHDIR || exit 1

cd $CACHEDIR || exit 1

cd $BKDIR || exit 1

if [ -r $SCRIPTLOCK ] ; then
    exec 200< $SCRIPTLOCK
    flock -x -n 200 || exit 0
fi

bk pull -q


############################

# List mailing....

if [ ! -z $MLIST ]; then

    CSETSTOMAIL=`bk set -d -rMailDone -r+`

    for CSET in $CSETSTOMAIL ; do
	/home/dwmw2/working/bkexport/mailcset.sh $CSET $MLIST | /usr/lib/sendmail $MLIST
    done

    bk tag -q MailDone

fi

############################

# Patch export to web....

TAGCSET=`bk changes -t -d':I: :TAG:\n' | sed s/MailDone//g | grep " v2." | head -1 | cut -f1 -d\ `

# Get the list of differences between the current and the last tag.  The
# output from "bk set" is passed to "bk changes" to prune empty changesets
# and to turn the cset list into a list of "KEY CSET" pairs.  It is also
# passed to sort so that 'join' can be used.
bk set -d -r$TAGCSET -r+ -k | bk changes -d':KEY: :I:\n' - \
    | sort > $CACHEDIR/csetkeys.$$

# Get list of the keys that already have patches available.
ls -1 $PATCHDIR | sed -n '/^cset-.*\.txt$/ { s/^cset-\(.*\).txt$/\1/ ; p }' \
    > $CACHEDIR/curkeys.$$

# Get list of new csets that need patches made.
join $CACHEDIR/csetkeys.$$ $CACHEDIR/curkeys.$$ -1 1 -v1 > $CACHEDIR/newkeys.$$

# Get list of stale patches that will need to be removed.
join $CACHEDIR/csetkeys.$$ $CACHEDIR/curkeys.$$ -1 1 -v2> $CACHEDIR/stalekeys.$$

# Check if any new work needs to be done.
if [ ! -s $CACHEDIR/newkeys.$$ -a ! -s $CACHEDIR/stalekeys.$$ ]; then
    rm -f $CACHEDIR/csetkeys.$$ $CACHEDIR/curkeys.$$ \
        $CACHEDIR/newkeys.$$ $CACHEDIR/stalekeys.$$
    exit 0
fi

# Create compressed mega-patch.
BIGPATCH=cset-`date -u '+%Y%m%d_%H%M'`.txt.gz
bk export -tpatch -r$TAGCSET, | gzip > $STAGINGDIR/$BIGPATCH

# Create the new patches that are needed.
cat $CACHEDIR/newkeys.$$ | while read BKKEY CSET ; do
    #echo "Building patch for $BKKEY"
    bk export -tpatch -r"$CSET" > $STAGINGDIR/cset-"$BKKEY".txt
done

# Create the web page index data.  The 'lastindex' file (located in the
# CACHEDIR directory) stores the cumulative output from the previous "bk
# changes" commands; it is basically the web page without the header and
# trailer information.  This file helps ensure recent changes are always at
# the top of the web page (so users that click "refresh" in their web
# browser do not need to search the whole page for recent additions).  To
# maintain the desired ordering this script will generate index data only
# for new csets and then prepend this info to the 'lastindex' file.
if [ ! -s $CACHEDIR/lastindex ] ; then
    echo -n "" > $CACHEDIR/lastindex
    INDEXLIST=$CACHEDIR/csetkeys.$$
elif [ -s $CACHEDIR/stalekeys.$$ ] ; then
    if cmp -s $CACHEDIR/curkeys.$$ $CACHEDIR/stalekeys.$$ ; then
        # All current patches are invalid.  Restart index from scratch.
        echo -n "" > $CACHEDIR/lastindex
        INDEXLIST=$CACHEDIR/csetkeys.$$
    else
        # Prune out stale patches from index.
        sed 's/\(.*\)/<A HREF="cset-\1.txt">/' < $CACHEDIR/stalekeys.$$ \
            | fgrep -vf - $CACHEDIR/lastindex > $CACHEDIR/newindex.$$
        mv $CACHEDIR/newindex.$$ $CACHEDIR/lastindex
        INDEXLIST=$CACHEDIR/newkeys.$$
    fi
else
    # New changes will be prepended to the lastindex file.
    INDEXLIST=$CACHEDIR/newkeys.$$
fi
cut -f1 -d\ < $INDEXLIST \
    | bk changes -e -d'<H3><A HREF="cset-:KEY:.txt">:G: :D: :T::TZ:, :USER: @ :HOST:</A> <A HREF="http://www.kernel.org/diff/diffview.cgi?file='$PATCHDIR'/cset-:KEY:.txt">[diffview]</A></H3> <P>:HTML_C:</P>\n' - \
    | cat - $CACHEDIR/lastindex >> $CACHEDIR/newindex.$$
mv $CACHEDIR/newindex.$$ $CACHEDIR/lastindex

# Create web page.
TAG=`bk changes -r$TAGCSET -d:TAG: | sed "s/[ ]*MailDone[ ]*//"`
NUMCSETS=`wc -l < $CACHEDIR/csetkeys.$$`
cat > $CACHEDIR/newindex.$$.html <<EOF
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
<html>
  <head>
    <title>BitKeeper patches for `hostname`:$BKDIR</title>
  </head>

  <body>
 <H1>BitKeeper patches since $TAG: $NUMCSETS Changesets</H1>

 <H2><A HREF="$BIGPATCH">Gzipped full patch from $TAG</A></H2>

EOF

if [ "$NUMCSETS" -eq 0 ] ; then
    echo "<H3>No changes since last tag</h3>" >> $CACHEDIR/newindex.$$.html
else
    cat $CACHEDIR/lastindex >> $CACHEDIR/newindex.$$.html
fi

cat >> $CACHEDIR/newindex.$$.html <<EOF
  <hr>
  Index generated at `date -u`
  </body>
</HTML>
EOF
mv $CACHEDIR/newindex.$$.html $STAGINGDIR/index.html


# If staging, lock and move new files into place.

if [ -r $STAGINGLOCK ]; then 
    exec 201<$STAGINGLOCK
    flock -s 201
fi

if [ "$STAGINGDIR" != "$PATCHDIR" ] ; then 
    # Can't get xargs to do this nicely...
    cd $STAGINGDIR
    for a in *; do
	mv "$a" $PATCHDIR
    done
fi

# Clean up old files from patch directory

cd $PATCHDIR

for FILE in *.txt.gz *.txt.bz2; do
    case $FILE in
    $BIGPATCH|${BIGPATCH//%.gz/.bz2})
	continue
	;;
    *)
	rm -f $FILE $FILE.sign
	;;
    esac
done

# Prune extra patch files.
sed 's/\(.*\)/cset-\1.txt cset-\1.txt.sign/' < $CACHEDIR/stalekeys.$$ \
    | xargs rm -f

# Remove temporary files.
rm -f $CACHEDIR/csetkeys.$$ $CACHEDIR/curkeys.$$ \
    $CACHEDIR/newkeys.$$ $CACHEDIR/stalekeys.$$
