#!/bin/bash
# Simple shell script for creating Debian source releases from a git repository
#
# Copyright(C) 2007, Ron <ron@debian.org>
# This script is distributed according to the terms of the GNU GPL.

set -e

BUILD_ROOTCMD="fakeroot"
DEB_DIR="../deb-packages/"
HOOK_FILE=".gitpkg_hook"

for f in /etc/gitpkg.conf ~/.gitpkg .git/gitpkg.conf; do [ -r $f ] && . $f; done


usage()
{
    cat 1>&2 <<EOF

gitpkg branch [origbranch]

  If gitpkg is run in a git repo with a single branch specified, then it will
  do a git-archive export of that branch to the $DEB_DIR directory.  If
  the package is Debian native it will simply create a source package from it.
  If the package has a Debian version, then an orig.tar.gz will be created
  containing everything except the debian/ directory.

  If gitpkg is invoked with two branches specified, then the first branch will
  be checked out as the unpacked complete source, while the second branch will
  be checked out as the orig.tar.gz.  This allows all local changes to the
  source to be recorded in the resulting diff.gz if a pristine upstream branch
  exists in the repository.

  'branch' should always have a debian/ dir and may be any tree-ish object that
  is accepted by git-archive.  'origbranch', if supplied, should usually not
  have a debian/ dir.

EOF

    exit $1
}

[ $# -gt 0 ] && [ $# -lt 3 ] || usage 1

if [ $# -eq 1 ]; then

    echo "git archive --format=tar $1"
    git archive --format=tar --prefix="gitpkg-${1}/" $1 |
    (
	mkdir -p $DEB_DIR
	cd $DEB_DIR
	tar xf -

	DEB_SOURCE="$(cd gitpkg-${1} && dpkg-parsechangelog | awk '/Source:/ {print $2}')"
	DEB_VERSION="$(cd gitpkg-${1} && dpkg-parsechangelog | sed -rne 's/^Version: ([^:]+:)?//p')"
	DEB_PACKAGE="${DEB_SOURCE}-${DEB_VERSION%-*}"

	if [ -z "$DEB_SOURCE" ] || [ -z "$DEB_VERSION" ];  then
	    rm -rf "gitpkg-${1}"
	    echo "ERROR: Failed to parse debian/changelog"
	    exit 1
	fi

	[ -e "$DEB_SOURCE/$DEB_PACKAGE" ] && rm -rf "$DEB_SOURCE/$DEB_PACKAGE"
	mkdir -p $DEB_SOURCE
	mv "gitpkg-${1}" "$DEB_SOURCE/$DEB_PACKAGE"
	cd $DEB_SOURCE

	(
	    cd "$DEB_PACKAGE"
	    for f in $(find -name ".gitignore"); do rm $f; done

	    ( [ -r "$HOOK_FILE" ] && . "$HOOK_FILE" )

	    # We run this now because the clean target may have one-shot rules
	    # that build autoconf files and the like, and we want to do that
	    # prior to creating the orig.gz/diff.gz.  They should never be
	    # regenerated for a normal package build, but they shouldn't really
	    # be in the repo either.
	    $BUILD_ROOTCMD debian/rules clean
	)

	#(( syntax hack
	case $DEB_VERSION in
	    *-*)
		# Re-use an existing orig.tar.gz if we have one ...
		if [ -e "${DEB_SOURCE}_${DEB_VERSION%-*}.orig.tar.gz" ]
		then
		    echo "dpkg-source -b -sp $DEB_PACKAGE"
		    dpkg-source -b -sp "$DEB_PACKAGE"
		else
		    echo "dpkg-source -b -sR $DEB_PACKAGE"
		    cp -al "$DEB_PACKAGE" "$DEB_PACKAGE.orig"
		    rm -rf "$DEB_PACKAGE.orig/debian"
		    dpkg-source -b -sR "$DEB_PACKAGE"
		fi
		;;
	    *)
		echo "dpkg-source -b -sn $DEB_PACKAGE"
		dpkg-source -b -sn "$DEB_PACKAGE"
		;;
	esac
    )
fi

if [ $# -eq 2 ]; then

    echo "git archive --format=tar $1"
    git archive --format=tar --prefix="gitpkg-${1}/" $1 |
    (
	mkdir -p $DEB_DIR
	cd $DEB_DIR
	tar xf -
    )

    DEB_SOURCE="$(cd $DEB_DIR/gitpkg-${1} && dpkg-parsechangelog | awk '/Source:/ {print $2}')"
    DEB_VERSION="$(cd $DEB_DIR/gitpkg-${1} && dpkg-parsechangelog | sed -rne 's/^Version: ([^:]+:)?//p')"
    DEB_PACKAGE="${DEB_SOURCE}-${DEB_VERSION%-*}"

    if [ -z "$DEB_SOURCE" ] || [ -z "$DEB_VERSION" ];  then
	rm -rf "$DEB_DIR/gitpkg-${1}"
	echo "ERROR: Failed to parse debian/changelog"
	exit 1
    fi

    (
	cd $DEB_DIR

	[ -e "$DEB_SOURCE/$DEB_PACKAGE" ] && rm -rf "$DEB_SOURCE/$DEB_PACKAGE"
	mkdir -p $DEB_SOURCE
	mv "gitpkg-${1}" "$DEB_SOURCE/$DEB_PACKAGE"

	cd "$DEB_SOURCE/$DEB_PACKAGE"
	for f in $(find -name ".gitignore"); do rm $f; done

	( [ -r "$HOOK_FILE" ] && . "$HOOK_FILE" )

	# We run this now because the clean target may have one-shot rules
	# that build autoconf files and the like, and we want to do that
	# prior to creating the orig.gz/diff.gz.  They should never be
	# regenerated for a normal package build, but they shouldn't really
	# be in the repo either.
	$BUILD_ROOTCMD debian/rules clean
    )

    # Re-use an existing orig.tar.gz if we have one ...
    if [ -e "$DEB_DIR/$DEB_SOURCE/${DEB_SOURCE}_${DEB_VERSION%-*}.orig.tar.gz" ]
    then
	(
	    cd $DEB_DIR/$DEB_SOURCE
	    echo "dpkg-source -b -sp $DEB_PACKAGE"
	    dpkg-source -b -sp "$DEB_PACKAGE"
	)
	#All done!
	exit 0
    fi

    # else check out the pristine upstream branch also
    echo "git archive --format=tar --prefix=$DEB_PACKAGE.orig/ $2"
    git archive --format=tar --prefix="$DEB_PACKAGE.orig/" $2 |
    (
	cd $DEB_DIR/$DEB_SOURCE
	tar xf -
	(
	    cd "$DEB_PACKAGE.orig"
	    for f in $(find -name ".gitignore"); do rm $f; done

	    ( [ -r "$HOOK_FILE" ] && . "$HOOK_FILE" )
	)
	echo "dpkg-source -b -sR $DEB_PACKAGE"
	dpkg-source -b -sR "$DEB_PACKAGE"
    )
fi

