#!/bin/sh

set -u
set -e
# set -x

if [ -f ~/.devscripts ] 
then
  . ~/.devscripts
fi

PACKAGE=frobinator
UPSTREAM=sourceforge.net

UNARCHIVE=do_unzip
WRAPDIR=true

LOG=README.Debian-source

VERBOSE=${VERBOSE:-1}
CLEANUP=${CLEANUP:-0}

SCRIPTDIR=$(dirname $(readlink -f $0))

NAME=$(basename $0)
RCFILE=$SCRIPTDIR/repackagerc

EXCLUDE_LIST=""
# Originally '197001010000.00' but tar complains about an 
# "implausibly old time stamp"
TOUCHTIME=199001010000.00

# Set a consistent umask for repackaging so that the tarball is reproducible
# (overridable in the rc file)
umask 002

usage() {
  cat <<EOT 1>&2
Usage: $NAME --upstream-version x.y.z filename.zip 
          [src_package_revision] [target_dir]

Where the the version x.y.z is the version number of the new version and
filename.zip (or .tar.gz or whatever) is the new source filename for the
package $PACKAGE.

If filename.zip starts with http:// or ftp:// then wget is used to download
the archive first.

The file $RCFILE must exist and set the following environment variables
(and these are their current versions):

  PACKAGE=$PACKAGE
  UPSTREAM=$UPSTREAM

  UNARCHIVE=$UNARCHIVE
  EXCLUDE_LIST=$EXCLUDE_LIST

(EXCLUDE_LIST is a list of exclusions for tar, one per line. Note that
spaces in path names are problematic)

It is expected that this utility is run by uscan or and is run in the
base directory of the source package.

The optional argument 'src_package_revision' can be specified to 
indicate additional cycles of source package revision that may have
been undertaken in addition to the regular packaging activities.
If not specified, the debian/changelog is parsed to try to work out what
the source revision should be.

The optional argument 'target_dir' may be used to specify where the repackaged
source should be left.

EOT
}

progress() {
  if [ "$VERBOSE" != 0 -a -n $VERBOSE ]
  then
    echo "$@"
  fi
}

logmsg() {
  echo "$@" >> $LOGFILE
}

logcmd() {
  logcmdpieces "$@"
  "$@" >> $LOGFILE
}

# This is a truly appalling hack, but the only sensible way to 
# maintain proper quoting in the log, it seems, unless each command is
# double quoted to begin with... which is also an ugly, bug-attracting
# hack.
logcmdpieces() {
  printf "\n$ " >> $LOGFILE
  echo "$@" >> $LOGFILE
}

carp() {
  echo "E: ($NAME) $*"
  exit 1
}

do_unzip() {
  logcmd unzip -qq -d "$1" "$2"
}

do_untargz() {
  logcmd tar -C "$1" -zxf "$2"
}

do_untarbz2() {
  logcmd tar -C "$1" -jxf "$2"
}

testarchive() {
  case "$1" in
    do_unzip)
         ALLDIRS=$(zipinfo -1 "$2" | cut -f1 -d/ | sort -u)
         if [ $(echo "$ALLDIRS" | wc -l) -gt 1 ]
         then
           testarchiveerror
         fi
         echo "$ALLDIRS"
      ;;
    do_untargz)
         ALLDIRS=$(tar ztf "$2" | cut -f1 -d/ | sort -u)
         if [ $(echo "$ALLDIRS" | wc -l) -gt 1 ]
         then
           testarchiveerror
         fi
         echo "$ALLDIRS"
      ;;
    do_untarbz2)
         ALLDIRS=$(tar jtf "$2" | cut -f1 -d/ | sort -u)
         if [ $(echo "$ALLDIRS" | wc -l) -gt 1 ]
         then
           testarchiveerror
         fi
         echo "$ALLDIRS"
      ;;
  esac
}

testarchiveerror() {
  echo "E: More than one directory was found in the unwrapped archive."
  echo "E: Set WRAPDIR to wrap the contents of the tarball in a directory."
  exit 1
}

make_exclude_list() {
  echo "$EXCLUDE_LIST" | grep -v -e ^$ | sed 's/^\(.*\)/--exclude=\1/'
}

next_source_version() {
  LAST_SRC=$(dpkg-parsechangelog | \
                sed -n 's/Version: \(.*\)+[0-9\-]*/\1/p')
  #echo "LS=$LAST_SRC"
  if [ $LAST_SRC = $VERSION ]
  then
    SRCVERSION=$(dpkg-parsechangelog | \
                sed -n 's/Version: [^+]*+\(.*\)-.*/\1/p')
    SRCVERSION=$(($SRCVERSION+1))
  else
    SRCVERSION=1
  fi
  echo $SRCVERSION
}

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

if [ ! -f $RCFILE ]
then
  cat <<EOT 1>&2
$0 Error: No configuration parameters found in file $RCFILE.
Exiting.
EOT
  usage
  exit 1
fi

# Read in the user/package settings
. $RCFILE

if [ $# -lt 3 -o $# -gt 5 ] 
then
  usage
  exit 1
fi

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

DATE=$(date -R)

VERSION=$2
SRCPATH=$3

SRCVERSION=""
TARGETDIR=$(pwd)
if [ $# -eq 5 ]
then
  SRCVERSION="$4"
  TARGETDIR="$5"
elif [ $# -eq 4 ]
then
  if [ -d $4 ]
  then
    TARGETDIR="$4"
    SRCVERSION=$(next_source_version)
  else
    SRCVERSION="$4"
  fi
else
  SRCVERSION=$(next_source_version)
fi
VERSION="$VERSION+$SRCVERSION"

if [ ! -d "$TARGETDIR" ]
then
  carp "Target directory '$TARGETDIR' doesn't exist!"
fi

progress "I: Making orig tarball for $VERSION"

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

LOGFILE=$TARGETDIR/$LOG

if [ -f "$LOGFILE" ]
then
  progress "W: Deleting existing log file"
  rm "$LOGFILE"
fi

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

DIR=${PACKAGE}-$VERSION.orig

ARCHIVEFILE=${PACKAGE}_${VERSION}.orig.tar
ARCHIVELOCATION="$TARGETDIR"

TEMPDIR=$(mktemp -t -d $NAME.XXXXXXXXXX) || carp "Couldn't make temp dir"

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

progress "I: Locating source $SRCPATH"

SRCARCHIVE=$(basename "$SRCPATH")
if [ $(expr substr "$SRCPATH" 1 7) = "http://" -o \
     $(expr substr "$SRCPATH" 1 6) = "ftp://" ]
then
  UPSTREAMURL="$SRCPATH"
  wget "$UPSTREAMURL" -O "$TEMPDIR/$SRCARCHIVE"
else
  cp "$SRCPATH" "$TEMPDIR"
fi

cd $TEMPDIR || carp "Couldn't cd to temp dir $TEMPDIR"

###########################################################################
MD5="md5sum --binary"

logmsg "
Repackaging of original source for $PACKAGE
---------------------------------------------------------------------

$PACKAGE version $VERSION.

Downloaded file:  $SRCARCHIVE
From:             $UPSTREAM
Path:             $SRCPATH"

logcmd $MD5 $SRCARCHIVE

progress "I: Directory:    $DIR
I: Package name: $PACKAGE
I: Version:      $VERSION"

logmsg "
The following commands were used to repackage the original source (the
'touch' commands ensure that the md5sum of the archives stays the same):"

# get the source
progress "I: Uncompressing source"
if $WRAPDIR 
then
  logcmd mkdir $DIR
  $UNARCHIVE $DIR $SRCARCHIVE
else
  INNERDIR=$(testarchive $UNARCHIVE $SRCARCHIVE)
  $UNARCHIVE . $SRCARCHIVE
  logcmd mv $INNERDIR $DIR
fi
# set a consistent time for the top directory
logcmd touch -t $TOUCHTIME $DIR
# repackage the archive
progress "I: Creating 'orig' tar archive"

#echo "$(make_exclude_list)"

logcmd tar cf $ARCHIVEFILE --owner 0 --group 0 --numeric-owner \
        $(make_exclude_list)  \
        $DIR

# Also set a consistent time on the tar archive
logcmd touch -t $TOUCHTIME $ARCHIVEFILE
#logcmd md5sum $ARCHIVEFILE
progress "I: Compressing archive"
logcmd gzip -9 $ARCHIVEFILE
logcmd md5sum --binary $ARCHIVEFILE.gz

logmsg "
  -- $DEBFULLNAME <$DEBEMAIL> $DATE
---------------------------------------------------------------------
"

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

progress "I: Moving archive $ARCHIVEFILE.gz"
#mv $ARCHIVEFILE $ARCHIVELOCATION
touch $ARCHIVEFILE.gz
mv $ARCHIVEFILE.gz $ARCHIVELOCATION

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

if [ $CLEANUP != 0 ]
then
  progress "I: Cleaning up $TEMPDIR"
  rm -rf $TEMPDIR
else
  progress "I: Files left in $TEMPDIR for your inspection"
fi

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