#! /bin/sh
#
# Upgrade an existing package
# Christoph Lameter, December 24, 1996
# Many modifications by Julian Gilbey <jdg@debian.org> January 1999 onwards

# Copyright 1999, Julian Gilbey
#
# This program is free software; you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
# the Free Software Foundation; either version 2 of the License, or
# (at your option) any later version.
#
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
# GNU General Public License for more details.
#
# You should have received a copy of the GNU General Public License
# along with this program; if not, write to the Free Software
# Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA


# Command line syntax is one of:
# For a new archive:
#  uupdate [-v <Version>] [-r <gain-root-command>] [-u] <new upstream archive>
# or
#  uupdate [-r <gain-root-command>] [-u] <new upstream archive> <Version>
# For a patch file:
#  uupdate [-v <Version>] [-r <gain-root-command>] -p <patch>.gz
#
# In the first case, the new version number may be specified explicitly,
# either with the -v option before the archive name, or with a version
# number after the archive file name.  If both are given, the latter
# takes precedence.
#
# The -u option requests that the new .orig.tar.gz archive be the
# pristine source, although this only makes sense when the original
# archive itself is a tar.gz or tgz archive.
#
# Has to be called from within the source archive

TEXTDOMAIN=devscripts
PROGNAME=`basename $0`
PKG_VERSION=2.5.8.2

usage () {
    echo \
$"Usage for a new archive:
  uupdate [options] <new upstream archive> [<version>]
For a patch file:
  uupdate [options] --patch|-p <patch>.gz
Options are:
   --upstream-version <version>, -v <version>
                      specify version number of upstream package
   --rootcmd <gain-root-command>, -r <gain-root-command>
                      which command to be used to become root
                      for package-building
   --pristine, -u     Source is pristine upstream source and should be
                      copied to <pkg>_<version>.orig.tar.gz; not valid
                      for patches
$PROGNAME [--help|--version]
  show this message or give version information."
}

version () {
    echo \
$"This is $PROGNAME, from the Debian devscripts package, version $PKG_VERSION
This code is copyright 1999 by Julian Gilbey, all rights reserved.
Original code by Christoph Lameter.
This program comes with ABSOLUTELY NO WARRANTY.
You are free to redistribute this code under the terms of the
GNU General Public License, version 2 or later."
}

mustsetvar () {
    if [ "x$2" = x ]
    then
	echo >&2 $"$0: unable to determine $3"
	exit 1
    else
	# echo $"$0: $3 is $2"
	eval "$1=\"\$2\""
    fi
}

# Match Pattern to extract a new version number from a given filename.
# I already had to fiddle with this a couple of times so I better put it up
# at front.  It is now written as a Perl regexp to make it nicer:
MPATTERN='^[-\w+]+(\d+\.[\d.]*\d+)$'

STATUS=0
ROOT_COMMAND=''
PRISTINE='FALSE'

# Process Parameters
while [ "$1" ]; do
    case $1 in
    --upstream-version|-v)
	shift; NEW_VERSION="$1" ;;
    --upstream-version=*)
	NEW_VERSION=`expr "$1" : '--upstream-version=\(.*\)'` ;;
    --patch|-p)
	shift; PATCH="$1" ;;
    --rootcmd|-r)
	shift; ROOT_COMMAND="$1" ;;
    --rootcmd=*)
	NEW_VERSION=`expr "$1" : '--rootcmd=\(.*\)'` ;;
    --pristine|-u)
	PRISTINE='TRUE' ;;
    --help) usage; exit 0 ;;
    --version) version; exit 0 ;;
    -*) echo $"Unrecognised option: $1; try uupdate --help for more info" >&2
	exit 1 ;;
    *)	ARCHIVE=$1
	[ "x$2" != x ] && NEW_VERSION="$2"
	break   # So that we only look at the first non-option argument
	;;
    esac
    shift
done

# Get Parameters from current source archive

# Look for debian/changelog; save pwd before we goes walkabout
OPWD=`pwd`
until [ -f debian/changelog ]; do
    cd ..
    if [ `pwd` = "/" ]; then
	echo $"Cannot find debian/changelog anywhere." >&2
	exit 1
    fi
done

# Figure out package info we need
mustsetvar PACKAGE "`dpkg-parsechangelog | sed -n 's/^Source: //p'`" \
    $"source package"
mustsetvar VERSION "`dpkg-parsechangelog | sed -n 's/^Version: //p'`" \
    $"source version"

# Strip epoch number
SVERSION=`echo "$VERSION" | perl -pe 's/^\d+://'`

UVERSION=`expr "$SVERSION" : '\(.*\)-[0-9a-z.+]*$'` ||
{
    echo $"A native Debian package cannot take upstream updates" >&2
    exit 1
}

# Strip epoch number
UVERSION=`echo "$UVERSION" | perl -pe 's/^\d+://'`

if [ "$PATCH" ]; then
    if [ "$ARCHIVE" ]; then
	echo $"You can only specify a patch or a source code archive, not both!" >&2
	exit 1
    fi
    # do the patching
    X="${PATCH##*/}"
    case "$PATCH" in
	/*)
	    if [ ! -r "$PATCH" ]; then
		echo $"Cannot read patch file $PATCH!  Aborting." >&2
		exit 1
	    fi
	    case "$PATCH" in
		*.gz) CATPATCH="zcat $PATCH"; X=${X%.gz};;
		*)    CATPATCH="cat $PATCH";;
	    esac
	    ;;
	*)
	    if [ ! -r "$OPWD/$PATCH" ] && [ ! -r "../$PATCH" ]; then
		echo $"Cannot read patch file $PATCH!  Aborting." >&2
		exit 1
	    fi
	    case "$PATCH" in
		*.gz)
		    if [ -r "$OPWD/$PATCH" ]; then
			CATPATCH="zcat $OPWD/$PATCH"
		    else
			CATPATCH="zcat ../$PATCH"
		    fi
		    X=${X%.gz}
		    ;;
		*)    if [ -r "$OPWD/$PATCH" ]; then
			CATPATCH="cat $OPWD/$PATCH"
		    else
			CATPATCH="cat ../$PATCH"
		    fi
		    ;;
	    esac
	    ;;
    esac
    if [ "$NEW_VERSION" = "" ]; then
	# Figure out the new version; we may have to remove a trailing ".diff"
	NEW_VERSION=`echo "$X" |
		perl -ne 's/\.diff$//; /'"$MPATTERN"'/ && print $1'`
	if [ -z "$NEW_VERSION" ]; then
	    echo $"New version number not recognized from given filename" >&2
	    echo $"Please run uupdate with the -v option" >&2
	    exit 1
	fi

	echo $"New Release will be $NEW_VERSION-1."
    fi
    # Strip epoch number
    SNEW_VERSION=`echo "$NEW_VERSION" | perl -pe 's/^\d+://'`

    if [ -e "../$PACKAGE-$SNEW_VERSION" ]; then
	echo $"$PACKAGE-$SNEW_VERSION already exists in the parent directory!" >&2
	echo $"Aborting...." >&2
	exit 1
    fi
    if [ -e "../$PACKAGE-$SNEW_VERSION.orig" ]; then
	echo $"$PACKAGE-$SNEW_VERSION.orig already exists in the parent directory!" >&2
	echo $"Aborting...." >&2
	exit 1
    fi
    if [ ! -r "../${PACKAGE}_$UVERSION.orig.tar.gz" ]; then
	echo $"Can't find/read ${PACKAGE}_$UVERSION.orig.tar.gz in the parent directory!" >&2
	echo $"Aborting...." >&2
	exit 1
    fi

    # Clean package
    if [ -n "$ROOT_COMMAND" ]; then
	debuild -r"$ROOT_COMMAND" clean || {
	    echo $"Couldn't run debuild -r$ROOT_COMMAND clean successfully.  Why not?" >&2
	    echo $"Aborting...." >&2
	    exit 1
	}
    else debuild clean || {
	    echo $"Couldn't run debuild -r$ROOT_COMMAND clean successfully.  Why not?" >&2
	    echo $"Aborting...." >&2
	    exit 1
	}
    fi

    cd ..
    rm -rf $PACKAGE-$UVERSION.orig
    tar zxf ${PACKAGE}_$UVERSION.orig.tar.gz
    cd $PACKAGE-$UVERSION.orig
    if $CATPATCH | patch -sp1; then
	cd ..
	mv $PACKAGE-$UVERSION.orig $PACKAGE-$SNEW_VERSION.orig
	echo $"-- Originals could be successfully patched"
	cp -a $PACKAGE-$UVERSION $PACKAGE-$SNEW_VERSION
	cd $PACKAGE-$SNEW_VERSION
	if $CATPATCH | patch -sp1; then
	    echo $"Success. The supplied diffs worked fine on the Debian sources."
	else
	    echo $"The diffs from did not apply cleanly!" >&2
	    X="`find . -name "*.rej"`"
	    echo $"Rejected diffs are in $X" >&2
	    if [ -t 0 ] && [ -t 2 ]; then
		echo -n $"Press <RETURN> to continue..." >&2
		read JUNK
	    fi
	    STATUS=1
	fi
	chmod a+x debian/rules
	debchange -v "$NEW_VERSION-1" "New upstream release"
	echo $"Remember: Your current directory is the OLD sourcearchive!"
	echo $"Do a \"cd ../$PACKAGE-$SNEW_VERSION\" to see the new package"
	exit
    else
	echo $"Patch failed to apply to original sources $UVERSION" >&2
	cd ..
	rm -rf $PACKAGE-$UVERSION.orig
	exit 1
    fi
else
# This is an orginal sourcearchive
    if [ "$ARCHIVE" = "" ]; then
	echo $"Upstream source archive not specified" >&2
	exit 1
    fi
    case "$ARCHIVE" in
	/*)
	    if [ ! -r "$ARCHIVE" ]; then
		echo $"Cannot read archive file $ARCHIVE!  Aborting." >&2
		exit 1
	    fi
	    ;;
	*)
	    if [ ! -r "$OPWD/$ARCHIVE" ] && [ ! -r "../$ARCHIVE" ]; then
		echo $"Cannot read archive file $ARCHIVE!  Aborting." >&2
		exit 1
	    fi
	    ;;
    esac
    echo $"Old Release $PACKAGE $VERSION."
    # Figure out the type of archive
    X="${ARCHIVE##*/}"
    case "$X" in
	*.tar.gz) X="${X%.tar.gz}"; UNPACK="tar zxf" ;;
	*.tar.Z)  X="${X%.tar.Z}";  UNPACK="tar zxf" ;;
	*.tgz)    X="${X%.tgz}";    UNPACK="tar zxf" ;;
	*.tar)    X="${X%.tar}";    UNPACK="tar xf"  ;;
	*.zip)    X="${X%.zip}";    UNPACK="unzip"   ;;
	*)
	    echo $"Sorry: Unknown archive type" >&2
	    exit 1
    esac
    if [ "$NEW_VERSION" = "" ]; then
	# Figure out the new version
	NEW_VERSION=`echo "$X" | perl -ne "/$MPATTERN/"' && print $1'`
	if [ -z "$NEW_VERSION" ]; then
	    echo $"New version number not recognized from given filename" >&2
	    echo $"Please run uupdate with the -v option" >&2
	    exit 1
	fi
    fi
    echo $"New Release will be $NEW_VERSION-1."
    # Strip epoch number
    SNEW_VERSION=`echo "$NEW_VERSION" | perl -pe 's/^\d+://'`
    if [ -e "../$PACKAGE-$SNEW_VERSION.orig" ]; then
	echo $"Original source tree already exists as $PACKAGE-$SNEW_VERSION.orig!" >&2
	echo $"Aborting...." >&2
	exit 1
    fi
    if [ -e "../$PACKAGE-$SNEW_VERSION" ]; then
	echo $"Source tree for new version already exists as $PACKAGE-$SNEW_VERSION!" >&2
	echo $"Aborting...." >&2
	exit 1
    fi
    if [ -e "../${PACKAGE}_$SNEW_VERSION.orig.tar.gz" ] &&
	    [ "${ARCHIVE##*/}" != "${PACKAGE}_$SNEW_VERSION.orig.tar.gz" ]
    then
	echo $"${PACKAGE}_$SNEW_VERSION.orig.tar.gz already exists in the parent dir;" >&2
	echo $"  please check on the situation before trying uupdate again." >&2
	exit 1
    fi

    if [ "$PRISTINE" = "TRUE" ]; then
	echo $"Copying pristine source to ${PACKAGE}_$SNEW_VERSION.orig.tar.gz..."
	case $ARCHIVE in
	    /*.tar.gz|/*.tgz)
		cp "$ARCHIVE" "../${PACKAGE}_$SNEW_VERSION.orig.tar.gz" ;;
	    *.tar.gz|*.tgz)
		if [ -r "$OPWD/$ARCHIVE" ]; then
		    cp "$OPWD/$ARCHIVE" "../${PACKAGE}_$SNEW_VERSION.orig.tar.gz"
		else
		    cp "../$ARCHIVE" "../${PACKAGE}_$SNEW_VERSION.orig.tar.gz"
		fi
		;;
	    *) echo $"Can't preserve pristine sources from non .tar.gz upstream archive!" >&2
		echo $"Continuing anyway..." >&2
		;;
	esac
    fi

    cd ..
    mkdir tmp
    cd tmp
    echo $"-- Untarring the new sourcecode archive $ARCHIVE"
    case "$ARCHIVE" in
	/*) $UNPACK "$ARCHIVE" ;;
	*)    if [ -r "$OPWD/$ARCHIVE" ]; then $UNPACK "$OPWD/$ARCHIVE"
	    else $UNPACK "../$ARCHIVE"; fi
	    ;;
    esac
    cd ..
    if [ `ls tmp | wc -l` -eq 1 ]; then
	# The files are stored in the archive under a top directory, we presume
	mv tmp/* $PACKAGE-$SNEW_VERSION
    else
	# Otherwise, we put them into a new directory
	mkdir $PACKAGE-$SNEW_VERSION
	mv tmp/* $PACKAGE-$SNEW_VERSION
    fi
    rm -rf tmp
    cp -a $PACKAGE-$SNEW_VERSION $PACKAGE-$SNEW_VERSION.orig
    cd $PACKAGE-$SNEW_VERSION
    if [ -r "../${PACKAGE}_$SVERSION.diff.gz" ] &&
	    zcat ../${PACKAGE}_$SVERSION.diff.gz | patch -sNp1 ; then
	echo $"Success!  The diffs from version $VERSION worked fine."
    elif [ ! -r "../${PACKAGE}_$SVERSION.diff.gz" ]; then
	echo $"Could not find diffs from version $VERSION to apply!" >&2
	exit 1
    else
	echo $"The diffs from version $VERSION did not apply cleanly!" >&2
	X="`find . -name "*.rej"`"
	echo $"Rejected diffs are in $X" >&2
	if [ -t 0 ] && [ -t 2 ]; then
	    echo -n $"Press <RETURN> to continue..." >&2
	    read JUNK
	fi
	STATUS=1
    fi
    chmod a+x debian/rules
    debchange -v "$NEW_VERSION-1" New upstream release
    echo $"Remember: Your current directory is the OLD sourcearchive!"
    echo $"Do a \"cd ../$PACKAGE-$SNEW_VERSION\" to see the new package"
fi

exit $STATUS
