#! /bin/bash
#                               -*- Mode: Sh -*- 
# deb-cvs --- 
# Author           : Manoj Srivastava ( srivasta@tiamat.datasync.com ) 
# Created On       : Mon May 26 14:23:17 1997
# Created On Node  : tiamat.datasync.com
# Last Modified By : Manoj Srivastava
# Last Modified On : Sun May 16 22:43:24 1999
# Last Machine Used: glaurung.green-gryphon.com
# Update Count     : 127
# Status           : Unknown, Use with caution!
# HISTORY          : 
# Description      : 
# $Id: cvs-buildpackage,v 1.31 2000/01/25 22:11:45 srivasta Exp $
# 

# Make sure we abort on error
set -e

progname="`basename \"$0\"`"
pversion='$Revision: 1.31 $'

setq() {
    # Variable Value Doc string
    if [ "x$2" = "x" ]; then
	echo >&2 "$progname: Unable to determine $3"
	exit 1;
    else
	if [ ! "x$Verbose" = "x" ]; then
	    echo "$progname: $3 is $2";
	fi
	eval "$1=\"\$2\"";
    fi
}

withecho () {
        echo " $@" >&2
        "$@"
}

usageversion () {
        cat >&2 <<END
Debian GNU/Linux $progname $pversion.
           Copyright (C) 1997 Manoj Srivastava.
This is free software; see the Artistic Licence for copying
conditions.  There is NO warranty.  

Usage: $progname  [options]
Options: 
  -M<module>   CVS module name.     }
  -P<package>  Package name.        } Allow operation out of the
  -V<version>  Package Version      } checked out source tree
  -T<tag>      CVS Tag to use
  -R<root dir> Root directory.
  -W<work dir> Working directory.
  -F           Force a cvs tag -F before exporting (Only valid in a
               CVS working dir)
  -d           Turn on Debugging
  -n           "Dry-run" mode - No action taken, only print commands.
  -tC          Clean all non-upload files in workdir after a successful build.
  -ctp         Include <package>_ at start of CVS tag.
  -x<prefix>   CVS default module prefix.
 The rest are passed to dpkg-buildpackage, though we do pay attention
 to the -r option. For reference, the following were the options for
 dpkg-buildpackage at the time $progname was written, however, we make
 no attempt to check any option (passing them straight through, and
 the options for dpkg-buildpackage may actually be different now. 
    -r<gain-root-command>
    -p<pgp-command>
    -us           unsigned source
    -uc           unsigned changes
    -a<arch>      architecture field of the changes _file_name_
    -b            binary-only, do not build source } also passed to
    -B            binary-only, no arch-indep files } dpkg-genchanges
    -v<version>   changes since version <version>      }
    -m<maint>     maintainer for release is <maint>    } only passed
    -C<descfile>  changes are described in <descfile>  }  to dpkg-
    -si (default) src includes orig for rev. 0 or 1    } genchanges
    -sa           uploaded src always includes orig    }
    -sd           uploaded src is diff and .dsc only   }
    -tc           clean source tree when finished
    -h            print this message
END
}

#
# Long term variables, which may be set in the config file or the
# environment: 
# DEBUG rootdir workdir (if all original sources are kept in one dir)
#
# 

action='withecho'
DEBUG=0

TEMPDIR=/tmp/$$
mkdir $TEMPDIR || exit 1
TEMPFILE=$TEMPDIR/cl-tmp

cleansource=0
TAGOPT=

# Command line
while [ $# != 0 ]; do
    value="`echo x\"$1\" | sed -e 's/^x-.//'`"
    case "$1" in
        -h)  usageversion; exit 0   ;;
	-M*)  opt_cvsmodule="$value" ;;
	-P*)  opt_package="$value"   ;;
	-R*)  opt_rootdir="$value"   ;;
	-T*)  opt_tag="$value"       ;;
	-V*)  opt_version="$value"   ;;
	-W*)  opt_workdir="$value"   ;;
	-F)   opt_forcetag=1         ;;
	-d)   opt_DEBUG=1            ;;
	-ctp) opt_packageintag=1     ;;
	-n)   action='echo'          ;;
        -r*)  opt_rootcommand="$value";;
	-tC*) cleansource=1 ;;
	-x*)  opt_prefix="$value" ;;
        -*)   dpkg_options=("${dpkg_options[@]}" "$1") ;;
	*)    opt_package="$1" ;;
    esac
    shift
done

if [ "x$opt_cvsmodule" = "x" -a "x$opt_package" = "x" -a \
      ! -e 'debian/changelog' ] ; then
    echo >&2 "$progname should be run in the top working directory of"
    echo >&2 "a Debian Package, or an explicit package (or CVS module) name"
    echo >&2 "should be given." 
    exit 1
fi

if [ "x$opt_tag" != "x" ]; then
    TAGOPT=-r$opt_tag
fi

# Command line, env variable, config file, or default
# This anomalous position is in case we need to check out the changelog
# below (anaomalous since we ahve not loaded the config file yet)
if [ ! "x$opt_prefix" = "x" ]; then
    prefix="$opt_prefix"
elif [ ! "x$CVSDEB_PREFIX" = "x" ]; then
    prefix="$CVSDEB_PREFIX"
elif [ ! "x$conf_prefix" = "x" ]; then
    prefix="$conf_prefix"
else
    prefix=""
fi



# put a slash at the end of the prefix
if [ "X$prefix" != "X" ]; then
    prefix="$prefix/";
    prefix=`echo $prefix | sed 's://:/:g'`;
fi

if [ "x$opt_package" = "x" ]; then
    # Get the official package name and version.
    if [ -f debian/changelog ]; then
	# Ok, changelog exists
	 setq "package" \
	    "`dpkg-parsechangelog | sed -n 's/^Source: //p'`" \
		"source package"
	setq "version" \
	    "`dpkg-parsechangelog | sed -n 's/^Version: //p'`" \
		"source version"
    elif [ "x$opt_cvsmodule" != "x" ]; then
	# Hmm. Well, see if we can checkout the changelog file
	rm -f $TEMPFILE
	cvs -q co -p $TAGOPT $opt_cvsmodule/debian/changelog > $TEMPFILE
        setq "package" \
	    "`dpkg-parsechangelog -l$TEMPFILE | sed -n 's/^Source: //p'`" \
          "source package"
        setq "version" \
          "`dpkg-parsechangelog -l$TEMPFILE | sed -n 's/^Version: //p'`" \
          "source version"
        rm -f $TEMPFILE
    else
	# Well. We don't know what this package is.
	echo >&2 " This does not appear be a Debian source tree, since"
	echo >&2 " theres is no debian/changelog, and there was no"
	echo >&2 " package name or cvs module given on the comand line"
	echo >&2 " it is hard to figure out what the package name "
	echo >&2 " should be. I give up."
	exit 1
    fi
else
    # The user knows best; package name is provided
    setq "package" "$opt_package" "source package"

    # Now, the version number
    if [ "x$opt_version" != "x" ]; then
	# All hail the user provided value
	setq "version" "$opt_version" "source package"
    elif [ -f debian/changelog ]; then
	# Fine, see what the changelog says
	setq "version" \
	    "`dpkg-parsechangelog | sed -n 's/^Version: //p'`" \
		"source version"
    elif [ "x$opt_cvsmodule" != "x" ]; then
	# Hmm. The CVS module name is known, so lets us try exporting changelog
	rm -f $TEMPFILE
	cvs -q co -p $TAGOPT $opt_cvsmodule/debian/changelog > $TEMPFILE
        setq "version" \
          "`dpkg-parsechangelog -l$TEMPFILE | sed -n 's/^Version: //p'`" \
          "source version"
        rm -f $TEMPFILE
    else
	# Ok, try exporting the package name
	rm -f $TEMPFILE
	cvsmodule="${prefix}$package"
	cvs -q co -p $TAGOPT $cvsmodule/debian/changelog > $TEMPFILE
        setq "version" \
          "`dpkg-parsechangelog -l$TEMPFILE | sed -n 's/^Version: //p'`" \
          "source version"
        rm -f $TEMPFILE
    fi
fi

rm -f $TEMPFILE
rmdir $TEMPDIR


non_epoch_version=`echo "$version" | perl -pe 's/^\d+://'`
upstream_version=`echo "$non_epoch_version" | sed  -e 's/-[^-]*$//'`
debian_version=`echo $non_epoch_version |  perl -nle 'm/-([^-]*)$/ && print $1'`

# The default
rootdir='/usr/local/src/Packages'
workdir="$rootdir/$package"
sversion=$non_epoch_version
uversion=$upstream_version
tversion=$debian_version

# Load site defaults and over rides.
if [ -f /etc/cvsdeb.conf ]; then
    . /etc/cvsdeb.conf
fi

# Load user defaults and over rides.
if [ -f ~/.cvsdeb.conf ]; then
    . ~/.cvsdeb.conf
fi

# Handle module prefixes
if [ ! "x$opt_prefix" = "x" ]; then
    prefix="$opt_prefix"
elif [ ! "x$CVSDEB_PREFIX" = "x" ]; then
    prefix="$CVSDEB_PREFIX"
elif [ ! "x$conf_prefix" = "x" ]; then
    prefix="$conf_prefix"
else
    prefix=""
fi



# put a slash at the end of the prefix
if [ "X$prefix" != "X" ]; then
    prefix="$prefix/";
    prefix=`echo $prefix | sed 's://:/:g'`;
fi


# Command line, env variable, config file, or default
if [ ! "x$opt_packageintag" = "x" ]; then
    packageintag="$opt_packageintag"
elif [ ! "x$CVSDEB_PACKAGEINTAG" = "x" ]; then
    packageintag="$CVSDEB_PACKAGEINTAG"
elif [ ! "x$conf_packageintag" = "x" ]; then
    packageintag="$conf_packageintag"
else
    packageintag=""
fi


if [ "x$opt_tag" != "x" ]; then
    cvstag="$opt_tag"
else
    cvstag=`echo "debian_version_$non_epoch_version" | tr . _ `
fi
cvs_upstream_tag=`echo "upstream_version_$upstream_version" | tr . _ `
if [ "x$packageintag" != x ]; then
    cvstag="${package}_$cvstag"
    cvs_upstream_tag="${package}_$cvs_upstream_tag"
fi

if [ "x$opt_cvsmodule" != "x" ]; then
  cvsmodule="$opt_cvsmodule"
else
  cvsmodule="${prefix}$package" 
fi

# conf_dpkg_options is where one may stash -us -uc or whatever
if [ -n "${conf_dpkg_options[*]}" ]; then
    dpkg_options=("${dpkg_options[@]}" "${conf_dpkg_options[@]}");
elif [ "x$conf_dpkg_options" != "x" ] ; then
    echo "conf_dpkg_options is now supposed to be an array variable"
    echo "However, you seem to have it set to a simple variable, which"
    echo "was the old way of doing things. Please set it to an array"
    echo "variable, with a form similar to"
    echo 'dpkg_options=("${dpkg_options[@]}" "value")';
    exit 1;
fi

# If asked to debug on command line, that's what we get
if [ ! "x$opt_DEBUG" = "x" ]; then
    DEBUG="$opt_DEBUG"
fi

# Command line, env variable, config file, or default
if [ ! "x$opt_rootdir" = "x" ]; then
    rootdir="$opt_rootdir"
elif [ ! "x$CVSDEB_ROOTDIR" = "x" ]; then
    rootdir="$CVSDEB_ROOTDIR"
elif [ ! "x$conf_rootdir" = "x" ]; then
    rootdir="$conf_rootdir"
fi

# Command line, env variable, config file, or default
if [ ! "x$opt_workdir" = "x" ]; then
    workdir="$opt_workdir"
elif [ ! "x$CVSDEB_WORKDIR" = "x" ]; then
    workdir="$CVSDEB_WORKDIR"
elif [ ! "x$conf_workdir" = "x" ]; then
    workdir="$conf_workdir"
else
    workdir="$rootdir/$package"
fi

# Command line, env variable, config file, or default
if [ ! "x$opt_forcetag" = "x" ]; then
    forcetag="$opt_forcetag"
elif [ ! "x$CVSDEB_FORCETAG" = "x" ]; then
    forcetag="$CVSDEB_FORCETAG"
elif [ ! "x$conf_forcetag" = "x" ]; then
    forcetag="$conf_forcetag"
else
    forcetag=""
fi

# Command line, env variable, config file, or default
if [ ! "x$opt_rootcommand" = "x" ]; then
    rootcommand="$opt_rootcommand"
elif [ ! "x$CVSDEB_ROOTCOMMAND" = "x" ]; then
    rootcommand="$CVSDEB_ROOTCOMMAND"
elif [ ! "x$conf_rootcommand" = "x" ]; then
    rootcommand="$conf_rootcommand"
else
    rootcommand=""
fi

if [ "X$rootcommand" != "X" ]; then
     dpkg_options=("${dpkg_options[@]}" "-r$rootcommand") ;
fi


# Command line, env variable, config file, or default
if [ ! "x$opt_strict_check" = "x" ]; then
    strict_check="$opt_strict_check"
elif [ ! "x$CVSDEB_STRICT_CHECK" = "x" ]; then
    strict_check="$CVSDEB_STRICT_CHECK"
elif [ ! "x$conf_strict_check" = "x" ]; then
    strict_check="$conf_strict_check"
else
    strict_check=""
fi

# No user defined changes here
pkgdir="$workdir/$package-$upstream_version"
oversion="$workdir/${package}_${upstream_version}.orig.tar.gz"

if [ $DEBUG -gt 0 ]; then
    echo >&2 ""
    echo >&2 "============================================================"
    echo >&2 ""
    echo >&2 "Non Epoch Version = $non_epoch_version "
    echo >&2 "Upstream Version  = $upstream_version "
    echo >&2 "Debian Version    = $debian_version"
    echo >&2 ""
    echo >&2 "cvs tag           = $cvstag"
    echo >&2 "cvs upstream tag  = $cvs_upstream_tag"
    echo >&2 ""
    echo >&2 "Working Directory = $workdir"
    echo >&2 "Package Directory = $pkgdir"
    echo >&2 ""
    echo >&2 "Original="
    echo >&2 "   $oversion"
    echo >&2 ""
    echo >&2 "============================================================"
    echo >&2 ""
fi

if [  -f debian/changelog  ]; then
    # Checking for uncommitted changes
    if [ "X$strict_check" != "X" ]; then
	unknown_regexp='^(M|A) ';
    else
	unknown_regexp='^(M|A|\?) ';
    fi
    set +e
    uncommitted=$(cvs -n update 2>/dev/null | egrep $unknown_regexp);
    set -e
    if [ "X$uncommitted" != "X" ]; then
	echo "There are uncommitted files."
	echo "$uncommitted"
	echo -n "Are you sure you wish to proceed?[y/N]: "
	read answer
	case $answer in
	    [Yy]*) nop= ;;
		*) exit 1
		;;
	esac
    fi
fi
if [ ! -d $workdir ]; then
    $action mkdir -p "$workdir"
fi

$action $rootcommand /bin/rm -rf "$pkgdir" "$pkgdir.orig"

if [ -f debian/changelog -a "X$forcetag" != "X" ]; then
    $action cvs tag -F "$cvstag"
fi

if [ "X$WORKINGCVS" = "X" ]; then
    cd $(dirname $pkgdir)
    $action cvs -q export -d $(basename $pkgdir) -r "$cvstag" "$cvsmodule"
    # See if we can reproduce the original sources from CVS
    if [ "x$debian_version" != "x" -a ! -e $oversion ]; then
      $action cvs -q export -d "$(basename $pkgdir).orig" -r "$cvs_upstream_tag" "$cvsmodule"
    fi
else
    $action cd "$workdir"
    $action cvs -q export -d $package-$upstream_version -r "$cvstag" "$cvsmodule"
 
    # See if we can reproduce the original sources from CVS
    if [ "x$debian_version" != "x" -a ! -e $oversion ]; then
      $action cvs -q export -d "$package-$upstream_version.orig" -r "$cvs_upstream_tag" "$cvsmodule"
    fi
fi

$action cd "$pkgdir"
$action dpkg-buildpackage "${dpkg_options[@]}"

# Clean up if asked to do so
if [ $cleansource -eq 1 ]; then
    $action cd "$workdir"
    $action $rootcommand /bin/rm -rf "$pkgdir" "$pkgdir.orig" 
fi

exit 0




