#! /bin/sh

# default variable values

PPAURL="http://ppa.launchpad.net/ubuntu-mobile/ubuntu/pool/main"
USERNAME=`whoami`
OUTDIR=`pwd`

print_usage() {
    echo ""
    echo "Usage: ppaprepare [-d outdir] [-u user] project tag"
    echo "Required Arguments:"
    echo "   project: repo name (as full URL or just a project name)"
    echo "   tag: git tag identifying source you want to release"
    echo "Options:"
    echo "   -d: outdir is the directory to place the source tree"
    echo "   -u: user is the login id for the git repo"
    echo ""
    echo "This program creates a new upstream release of a given project."
    echo "It downloads the current PPA version from ppa.launchpad.net, then"
    echo "rolls in the latest changes from a specific tag in its parent"
    echo "git repo. The output is a source tree representing the latest"
    echo "and greatest source for the project"
    echo ""
    echo "After running this command, the user should verify that the"
    echo "contents of this new tree are correct, then run this command:"
    echo "debuild -S -sa -k<gpgkey>"
    echo "Where the gpg key is found via \"gpg --list-keys\":"
    echo "  pub   1024D/<gpgkey> 2008-01-01"
    echo "  uid                  Full Name (My PPA Key) <my.email@mydomain.com>"
    echo "  sub   2048g/58CF328B 2008-01-01"
    echo ""
    exit 0
}

# argument and option processing

while getopts ":d:u:hf" opt; do
    case $opt in
    d) OUTDIR=$OPTARG;;
    u) USERNAME=$OPTARG;;
    h) print_usage;;
    \?) print_usage;;
    esac
done
shift $(($OPTIND - 1))
if [ $# -lt 2 ]; then
    print_usage
fi

PROJECTURL=""
CHECK1=`echo $1 | sed -n -e "/ssh:\/\/.*\.git/p"`
CHECK2=`echo $1 | sed -n -e "/.*\.git/p" -e "/[\/:]/p"`
if [ -n "$CHECK1" ]; then
    PROJECTURL=$1
    PROJECT=`echo $1 | sed 's/\.git//;s/.*\///'`
elif [ -z "$CHECK2" ]; then
    PROJECT=$1
else
    echo "Malformed project argument, needs to either be a full Git URL or just a project name"
    exit
fi
TAG=$2

# need a separate directory for the PPA source since
# its tree will have the same name as the git one

PPADIR="${OUTDIR}/ppa-${PROJECT}"
if [ -d $PPADIR ]; then
    rm -rf $PPADIR
fi
mkdir -p $PPADIR

# we want a fresh copy, delete all remnants of previous
# calls to this script

CHECK=`ls -1d ${OUTDIR}/${PROJECT}* 2>/dev/null`
for i in $CHECK; do
    if [ -d $i ]; then
	rm -rf $i
    else
	rm -f $i
    fi
done

# clone the git repo

cd $OUTDIR
if [ -z "$PROJECTURL" ]; then
    PROJECTURL=ssh://${USERNAME}@moblin.org/home/repos/projects/${PROJECT}.git
fi
echo ""
echo "Cloning GIT source tree from:"
echo "  $PROJECTURL"
echo ""
git-clone $PROJECTURL $PROJECT
if [ ! -d ${PROJECT} ]; then
    echo "[ERROR] Failed to clone the repo at ${PROJECT}"
    exit
fi

# switch to the tag the user specified

cd $PROJECT
git-checkout $TAG > /dev/null 2>&1
if [ $? -ne 0 ]; then 
    echo "Failed to checkout ${TAG}, check if the tag is correct";
    exit;
fi

# determine the git version from the ChangeLog

if [ ! -e ChangeLog ]; then
    echo "[ERROR] No ChangeLog present in ${PROJECT}"
    exit;
fi
GVERMAJOR=`grep -a -o "(.*)" ChangeLog | sed 's/(//;s/)//;2,$d'` 
if [ -z "$GVERMAJOR" ]; then
    echo "Couldn't read the version from the ChangeLog"
    exit
fi

# set the git source directory's name to include the version

cd ..
mv -f $OUTDIR/$PROJECT $OUTDIR/$PROJECT-$GVERMAJOR
GITSRC="${OUTDIR}/${PROJECT}-${GVERMAJOR}"
if [ -d $GITSRC/debian ]; then mv -f $GITSRC/debian $PPADIR/debian-git; fi
if [ -d $GITSRC/.git ]; then mv -f $GITSRC/.git $PPADIR; fi

# create a git source tarball minus the debian and .git folders

tar -cvzf $PROJECT-$GVERMAJOR.tar.gz $PROJECT-$GVERMAJOR > /dev/null 2>&1
md5sum $PROJECT-$GVERMAJOR.tar.gz > $PROJECT-$GVERMAJOR.tar.gz.md5sum
if [ -d $PPADIR/debian-git ]; then mv -f $PPADIR/debian-git $GITSRC/debian; fi
if [ -d $PPADIR/.git ]; then mv -f $PPADIR/.git $GITSRC; fi

# find the dsc filename of the current PPA release

TMPFILE=`tempfile`
DSCURL="${PPAURL}/${PROJECT%${PROJECT#?}}/${PROJECT}/"
wget $DSCURL -q -O $TMPFILE
DSCFILE=`grep -a -o "href.*dsc.*</a>" $TMPFILE | sed 's/<.*//;s/.*>//' | sort -rn | head -1`

# extract the PPA version from the dsc filename

PVERSION=`echo $DSCFILE | sed 's/\.dsc//;s/.*_//'`
PVERMAJOR=`echo $PVERSION | sed 's/\(.*\)-.*/\1/'`
rm -f $TMPFILE

if [ "$GVERMAJOR" = "$PVERMAJOR" ]; then
    echo "[ERROR] The GIT version, ${GVERMAJOR}, must be greater than the PPA version, ${PVERMAJOR}"
    echo "Update your ChangeLog with a new version, push the changes, and reapply the tag"
    exit
fi

# download and create the current ppa source repo

echo ""
echo "Getting PPA source tree from:"
echo "  $DSCURL/$DSCFILE"
echo ""

cd $PPADIR
dget -x $DSCURL/$DSCFILE
PPASRCOLD=$PPADIR/$PROJECT-$PVERMAJOR

# use uupdate to create the new ppa source repo

cd $PPASRCOLD
uupdate ${OUTDIR}/${PROJECT}-${GVERMAJOR}.tar.gz > /dev/null
PPASRCNEW=$PPADIR/$PROJECT-$GVERMAJOR
if [ ! -d $PPASRCNEW ]; then
    echo "[ERROR] uupdate failed to create ${PPASRCNEW}"
    exit
fi
if [ ! -h ${PPADIR}/${PROJECT}_${GVERMAJOR}.orig.tar.gz ]; then
    echo "[ERROR] uupdate failed to create ${PPADIR}/${PROJECT}_${GVERMAJOR}.orig.tar.gz"
    exit
fi
cd $PPADIR

# if the git repo has its own debian/changelog, use it instead
# of the default one uupdate makes. The new entry it adds usually gets
# the version and platform wrong and puts in one useless comment:
# "New upstream release". This has to be changed anyway, so if your
# git tree already did this, we will use it

GITCLOG=$GITSRC/debian/changelog
PPACLOGOLD=$PPASRCOLD/debian/changelog
PPACLOGNEW=$PPASRCNEW/debian/changelog
DEBDIFF=""

if [ -e $GITCLOG -a -e $PPACLOGOLD -a -e $PPACLOGNEW ]; then
    USEDEB=1

    # get the versions of the current ppa release and your git tree
    PPAVDEB=`grep -a -o "(.*)" $PPACLOGOLD | sed 's/(//;s/)//;2,$d'`
    GITVDEB=`grep -a -o "(.*)" $GITCLOG | sed 's/(//;s/)//;2,$d'`

    # check to make sure the git changelog actually has an entry
    # for the current ppa release. If it doesn't, this script
    # doesn't know why the developer still has it in his tree and
    # rolls its eyes in disgust
    CHECK=`sed -n -e "/$PACKAGE[[:space:]]*($PPAVDEB/p" $GITCLOG`
    if [ -n "$CHECK" ]; then
	TMPFILE=`tempfile`
	# extract all the changelog data between the git's
	# latest version and the current ppa version and 
	# append it to PPACLOGOLD to create PPACLOGNEW
	sed -n -e "/$PACKAGE[[:space:]]*($GITVDEB/,/$PACKAGE[[:space:]]*($PPAVDEB/p" \
	    $GITCLOG | head --lines=-1 > $TMPFILE
	cat $PPACLOGOLD >> $TMPFILE
	mv -f $TMPFILE $PPACLOGNEW
    fi

    # This script doesn't actually patch in any debian
    # folder changes (beyond changelog), it's up to the 
    # developer to do that. For convenience though we 
    # provide a diff as a list of changes that may require attention
    DEBDIFF=$PPADIR/$PROJECT-ppa$GVERMAJOR-git$GVERMAJOR-debian.diff
    diff -uNr $PPASRCNEW/debian $GITSRC/debian > $DEBDIFF
fi

# run diff for the two source trees

SDIFF=$PPADIR/$PROJECT-ppa$PVERMAJOR-ppa$GVERMAJOR.diff
mv -f $PPASRCOLD/debian $PPADIR/debian-ppa-old
mv -f $PPASRCNEW/debian $PPADIR/debian-ppa-new
diff -uNr $PPASRCOLD $PPASRCNEW > $SDIFF
mv -f $PPADIR/debian-ppa-old $PPASRCOLD/debian
mv -f $PPADIR/debian-ppa-new $PPASRCNEW/debian

echo ""
echo "New source tree creation complete!"
echo ""
echo "GIT source tree: ${GITSRC}"
echo "PPA source tree: ${PPASRCOLD}"
echo "NEW source tree: ${PPASRCNEW}"
echo "Source changes from ${PVERMAJOR}(PPA) to ${GVERMAJOR}(NEW):"
echo "  $SDIFF"
if [ -n "$DEBDIFF" ]; then
    echo "Differences between (GIT${GVERMAJOR})/debian and (NEW${GVERMAJOR})/debian:"
    echo "  ${DEBDIFF}"
fi
echo ""
