#! /bin/bash
#
# Prepare a release of libpqxx.  This is tailored to my machine and my current
# postgres installation.  It's not supposed to work on anything else.
#
# Usage: preprelease [sourcedir]
#
# where sourcedir is the main directory of the libpqxx source tree; defaults
# to "."
# 
# The script builds libpqxx and runs a regression test from the tarball
# generated by 'make dist'.  This ensures that no important files are left out
# of the distribution archive, and that there are no regression failures in the
# released version.
#
# If successful, the script leaves a distribution tarball in /tmp.
#
# Set CONFIG_ARGS to any argument list you wish to pass to configure for
# compilation.  Defaults to "--enable-shared".  Don't set the compiler here;
# use COMPILERS instead (see below).
#
# Set CONFIGDIST_ARGS to any argument list you wish to pass to configure when
# preparing to make a distribution archive.  Defaults to
# "--enable-maintainer-mode" so that the HTML documentation is built and
# included in the archive.
#
# The distribution is tested for several compilers by default; override the list
# by setting COMPILERS to a space-separated list of compilers.
#
# Set CONCURRENCY_LEVEL to the number of parallel jobs you want "make" to run.
# This can be useful on SMP or SMT systems, or in conjunction with distcc.

LOGFILE=/tmp/libpqxx-preprelease.log
ERRLOG=/tmp/libpqxx-preprelease.err

SOURCEDIR=$1

DEFAULTCOMPILERS="g++-2.95 g++-3.0 g++-3.3 g++-3.4 g++-4.0"


if test -z "$CONCURRENCY_LEVEL" ; then
	CONCURRENCY_LEVEL=1
fi

if test -z "$COMPILERS" ; then
	COMPILERS="$DEFAULTCOMPILERS"
fi

if test -z "$CONFIG_ARGS" ; then
	CONFIG_ARGS="--enable-shared"
fi

if test -z "$CONFIGDIST_ARGS" ; then
	CONFIGDIST_ARGS="--enable-maintainer-mode"
fi


print () {
	echo "$1" >>$LOGFILE
	echo "$1" >>$ERRLOG
}

log () {
	print
	print "`date`: $1"
	print
}

command () {
	print "$ $1"
	$2 $1 >>$LOGFILE 2>>$ERRLOG
}


# In current directory, configure, build, and run regression test using the
# compiler given as an argument.  If no argument is given, the default compiler
# is used.
run_test () {
	if ! test -z "$1" ; then
		COMPILEROPT="CXX=$1"
	fi

	if test -z "$1" || which "$1" ; then
		log "********* Testing with $1 *********"
		log "Configuring"
		command "./configure $CONFIG_ARGS $COMPILEROPT" nice

		log "Building"
		command "make -j $CONCURRENCY_LEVEL" nice

		log "Running regression test"
		command "make -j $CONCURRENCY_LEVEL check" nice
		grep '^FAIL:' $LOGFILE 2>>$ERRLOG || true
		grep '^All [0-9]* tests passed' $LOGFILE
	else
		log "********* Skipping $1 *********"
	fi
}


LC_ALL=C

rm -f $LOGFILE $ERRLOG

PQXXVERSION=`grep '\<PQXXVERSION\>' VERSION | sed -e 's/^[[:space:]A-Z_]*//' | sed -e 's/[[:space:]]*#.*$//'`

# See if debian/changelog needs updating
log "Seeing if debian/changelog is up to date..."
if ! head -n 1 debian/changelog | grep "($PQXXVERSION-" >/dev/null
then
	echo "Please update debian/changelog to mention version $PQXXVERSION!"
	exit 1
fi

# See if NEWS describes the new release
log "Seeing if NEWS is up to date..."
if ! head -n 1 NEWS | grep "^$PQXXVERSION[[:space:]]*$"
then
	echo "Please update NEWS to describe $PQXXVERSION release!"
	exit 1
fi


log "Preparing libpqxx release $PQXXVERSION."
log "Log file is $LOGFILE, errors go to $ERRLOG"

tail -f --pid=$$ $ERRLOG &


log "Ensuring PostgreSQL is running..."
command startpostgres nice

if test -z "$PGHOST"; then 
	log "Looking for local PostgreSQL socket..."
	SOCKET=".s.PGSQL.5432"
	for d in /var/run /tmp /var/run/postgresql ; do
		if test -S "$d/$SOCKET" ; then
			log "Found socket in $d."
			export PGHOST="$d"
		fi
	done
	if test -z "$PGHOST" ; then
		log "WARNING: No local PostgreSQL found.  Tests may not run."
	fi
fi

if test -z "$PGHOST" ; then
	log "Using default PostgreSQL location."
else
	log "Accessing PostgreSQL in $PGHOST"
fi

set -e

if test -z "$SOURCEDIR"; then SOURCEDIR="."; fi
command "cd $SOURCEDIR"
SOURCEDIR=`pwd`

log "Building from \"$SOURCEDIR\" (`pwd`)"

DISTNAME=libpqxx-$PQXXVERSION
TARBALL=$DISTNAME.tar.gz

log "Generating autoconf/automake files"
command "env NOCONFIGURE=1 ./autogen.sh" nice

log "Configuring for make dist"
command "./configure $CONFIGDIST_ARGS" nice

log "Creating $TARBALL"
command "make dist" nice

command "rm -f /tmp/$TARBALL"
command "mv $TARBALL /tmp"

command "cd /tmp"
command "rm -rf $DISTNAME"

log "Extracting $TARBALL in /tmp"
command "tar xzf $TARBALL"
command "rm $TARBALL"
command "cd $DISTNAME"

for compiler in $COMPILERS ; do
	run_test "$compiler"
done


log "Generating symbol table"
mkdir -p "$SOURCEDIR/lib"
nm --demangle src/.libs/libpqxx.a | cut -d' ' -f 3-  | grep -v '^_' | grep -v '^$' | grep -i '^pqxx' | sort -u -o "$SOURCEDIR/lib/SYMBOLS.$PQXXVERSION"

log "Creating release version of $TARBALL"
command "make dist" nice
command "mv $TARBALL .."
command "cd .."
command "rm -r $DISTNAME"

set +e
nice vacuumdb >/dev/null 2>&1 &

log "Finished.  Release tarball is /tmp/$TARBALL"

# Give output time to catch up with command prompt
sleep 2

