#!/bin/bash

#    makearch - Small script to handle building of source tarballs.
#    Copyright (C) 2003, 2004, 2011  Roy Keene
#
#    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
#
#    Keene Enterprises <makearch@rkeene.org>

CMD="$1"
SNAPSHOT='0'
COPY_TO_ARCHIVE='1'
BASIS=''
case "${CMD}" in
	snapshot)
		OVERRIDE_VERS=`date +%Y%m%d%H%M`
		SNAPSHOT=1
		COPY_TO_ARCHIVE='0'
		;;
	test)
		COPY_TO_ARCHIVE='0'
		;;
	version=*)
		COPY_TO_ARCHIVE='0'
		OVERRIDE_VERS="$(echo "$1" | cut -f 2 -d '=')"
		BASIS="${OVERRIDE_VERS}"
		;;
esac

if [ -f "_FOSSIL_" -o -f ".fos" -o -f ".fslckout" ]; then
	VC="fossil"
elif [ -d '.svn' ]; then
	VC="svn"
elif svn info makearch.info >/dev/null 2>/dev/null || svn info build/makearch.info >/dev/null 2>/dev/null; then
	VC="svn"
else
	VC="unknown"
fi

CO_TMPDIR=''

function cleanup_co_tmpdir() {
	if [ -n "${CO_TMPDIR}" ]; then
		rm -rf "${CO_TMPDIR}"
	fi
}

function cleanup() {
	cleanup_co_tmpdir
}

trap cleanup EXIT

if [ "${SNAPSHOT}" != "1" ]; then
	CHECK=''
	case "${VC}" in
		fossil)
			if [ -z "${BASIS}" ]; then
				fossil_co="$(fossil info | grep '^checkout:' | awk '{ print $2 }' | head -1)"
			else
				fossil_co="${BASIS}"
			fi
			echo "Creating archive based on Fossil checkout ${fossil_co}"

			CO_TMPDIR="../makearch-${fossil_co}"
			rm -rf "${CO_TMPDIR}"
			mkdir "${CO_TMPDIR}"

			VC_G_VERS="$(fossil info "${fossil_co}" | grep '^tags:' | sed 's@^tags:@@;s@ @@g' | tr ',' "\n" | egrep '^[0-9][0-9]*(\.[0-9][0-9]*)*$')"
			fossil tarball "${fossil_co}" "${CO_TMPDIR}/x.tar.gz" || exit 1

			cd "${CO_TMPDIR}" || exit 1
			CO_TMPDIR="$(pwd)"

			tar --strip-components=1 -xf x.tar.gz || exit 1
			rm -f x.tar.gz
			;;
		svn)
			VC_G_VERS=''
			CHECK="$(svn stat | egrep '^(A|M|R|D|[ _]M)')"
			;;
	esac

	if [ -n "${CHECK}" ]; then
		echo 'Uncommited files in directory, aborting.' >&2

		exit 1
	fi
fi

G_VERS=`grep '^AC_INIT(.*,.*)' configure.{in,ac} 2>/dev/null | sed 's@^.*AC_INIT(\([^,]*\), *\(.*\)).*$@\2@g;s@ *,.*$@@;s@^\[@@;s@\]$@@'`
if [ -z "${G_VERS}" ]; then
	G_VERS="`grep '^# *define *.*VERSION ' version.h src/version.h *.h src/*.h *.c src/*.c 2>/dev/null | grep -v '^config.*\.h:' | head -1 | sed -e s/'^.* '//g -e s/'"'//g`"
fi

if [ -z "${G_VERS}" -a -n "${VC_G_VERS}" ]; then
	G_VERS="${VC_G_VERS}"
fi

if [ -f makearch.info ]; then
	source makearch.info
elif [ -f build/makearch.info ]; then
	source build/makearch.info
else
	echo "Error: No \"makearch.info\" file found." >&2
	exit 1
fi
DATE_VAL="`date`"

if [ -z "${VERS}" ]; then
	VERS="${G_VERS}"
fi
if [ ! -z "${OVERRIDE_VERS}" ]; then
	VERS="${OVERRIDE_VERS}"
fi
if [ -z "${UTIL}" ]; then
	echo "Error: Unable to determine utility name, aborting." >&2
	exit 1
fi
if [ "${VERS}" = "auto" ]; then
	VERS=`cat .version 2>/dev/null`
	if [ -z "${VERS}" ]; then
		VERS="0.0.1"
	fi
	NEWVERSLAST=$[`echo ${VERS} | sed s/'^.*\.'/''/`+1]
	NEWVERSFIRST=`echo ${VERS} | sed s/'[^\.]*$'/''/`
	NEWVERS="${NEWVERSFIRST}${NEWVERSLAST}"
	mv .version .version_prev 2>/dev/null
	echo "${NEWVERS}" > .version
	unset NEWVERSLAST NEWVERSFIRST NEWVERS
fi
if echo "${VERS}" | grep '@@SVNLCR@@' >/dev/null; then
	SVNLCR=''
	case "${VC}" in
		fossil)
			SVNLCR="$(fossil timeline -W 0 -n 0 -t ci trunk | grep -v '^[=+][=+][=+] ' | wc -l)"
			;;
		svn)
			SVNLCR=$(svn info -R 2>/dev/null | grep '^Last Changed Rev: ' | sed 's@^Last Changed Rev: @@' | sort -n | tail -n 1)
			;;
	esac
	if [ -z "${SVNLCR}" ]; then
		SVNLCR="0"
	fi
	VERS="$(echo "${VERS}" | sed "s/@@SVNLCR@@/${SVNLCR}/g")"
fi
if [ -z "${VERS}" ]; then
	echo "Error: Unable to determine version number, aborting." >&2
	exit 1
fi
if echo ${UTIL} | egrep '/'  2>/dev/null >/dev/null; then
	echo "Error: Utility name has a slash (/) in it." >&2
	exit 1
fi

export VERS UTIL SNAPSHOT

TMPDIR="../${UTIL}-${VERS}"
if mkdir "${TMPDIR}"; then
	true
else
	TMPDIR="/tmp/${UTIL}-${VERS}"
	mkdir "${TMPDIR}" || exit 1
fi

cp -rp * "${TMPDIR}" 2>/dev/null >/dev/null
cd "${TMPDIR}" || exit 1

if [ -n "${CO_TMPDIR}" ]; then
	rm -rf "${CO_TMPDIR}"
fi

function cleanup_co_tmpdir() {
	true
}

if [ ! -z "${BEFORE}" -a -x "${BEFORE}" ]; then
	if "${BEFORE}" 2>/dev/null >/dev/null; then
		rm -f "${BEFORE}" 2>/dev/null >/dev/null
	else
		echo "Error: BEFORE script failed." >&2
		exit 1
	fi
fi

rm -f makearch.info .* 2>/dev/null >/dev/null
find . \( -name 'CVS' -o -name '.svn' \) -type d -exec rm -rf {} \; >/dev/null 2>/dev/null
find . -name '.*.sw?' -type f -exec rm -rf {} \; >/dev/null 2>/dev/null

for file in ${DOC_HDR} ${DOCS} ${UPDATE_VARS}; do
	if [ "${file}" = "ChangeLog" -a ! -f ChangeLog ]; then
		build_changelog "${UTIL}" > ChangeLog 2>/dev/null
		if [ ! -s ChangeLog ]; then
			rm -f ChangeLog
		fi
	fi
	if [ ! -f "${file}" -o -z "${file}" ]; then continue; fi

	TMPFILE="/tmp/sed$$`date +%H%M%S`${RANDOM}"
	rm -f ${TMPFILE} 2>/dev/null >/dev/null
	sed -e s/'@@VERS@@'/"${VERS}"/g -e s/'@@UTIL@@'/"${UTIL}"/g -e s/'@@DATE@@'/"${DATE_VAL}"/g ${file} > ${TMPFILE}
	if echo " ${DOCS} " | grep " ${file} " >/dev/null; then
		cat ${DOC_HDR} > ${file}
	else
		echo -n > ${file}
	fi
	cat ${TMPFILE} >> ${file}
	rm -f ${TMPFILE} 2>/dev/null >/dev/null
done

if [ -f "version.h.in" ]; then
	sed s/@@VERS@@/"${VERS}"/g version.h.in > version.h
	rm -f version.h.in
fi

if [ ! -z "${UPDATED}" -a -x "${UPDATED}" ]; then
	if "${UPDATED}" 2>/dev/null >/dev/null; then
		rm -f "${UPDATED}" 2>/dev/null >/dev/null
	else
		echo "Error: UPDATED script failed." >&2
		exit 1
	fi
fi

${MAKE:-make} clean 2>/dev/null >/dev/null
${MAKE:-make} distclean 2>/dev/null >/dev/null
./configure 2>/dev/null >/dev/null
${MAKE:-make} 2>/dev/null >/dev/null
${MAKE:-make} test 2>/dev/null >/dev/null
for file in ${BINS}; do
	if [ ! -x ${file} ]; then
		echo "Sanity check: building \"${file}\" failed." >&2
		exit=true
	fi
done
for file in ${REQS}; do
	if [ ! -f ${file} ]; then
		echo "Sanity check: required file \"${file}\" failed." >&2
		exit=true
	fi
done
for file in ${TMPS}; do
	if echo ${file} | grep '/' 2>/dev/null >/dev/null; then
		echo "Error: TMPS list contains a slash (/)" >&2
		exit=true
		break
	fi
	if [ -d "${file}" ]; then
		rm -rf "${file}" 2>/dev/null >/dev/null
	else
		rm -f ${file} 2>/dev/null >/dev/null
	fi
done
if [ ! -z "${exit}" ]; then
	cd ../
	exit 1
fi

${MAKE:-make} clean 2>/dev/null >/dev/null
${MAKE:-make} depend 2>/dev/null >/dev/null
${MAKE:-make} Makefile.dep 2>/dev/null >/dev/null
${MAKE:-make} distclean 2>/dev/null >/dev/null
rm -f MD5SUMS SHA256SUMS 2>/dev/null >/dev/null

# Perform after script
if [ ! -z "${AFTER}" -a -x "${AFTER}" ]; then
	if "${AFTER}" 2>/dev/null >/dev/null; then
		rm -f "${AFTER}" 2>/dev/null >/dev/null
	else
		echo "Error: AFTER script failed." >&2
		exit=true
	fi
fi

find . -type f ! -print 2>/dev/null | egrep -v '^\./(MD5SUMS|SHA256SUMS)$' | sort -u | sed s/'^\.\/'/''/ | xargs openssl md5 | sed 's@MD5(\(.*\))= \([0-9a-f]*\)@\2  \1@' > MD5SUMS 2>/dev/null
find . -type f ! -print 2>/dev/null | egrep -v '^\./(SHA256SUMS)$' | sort -u | sed s/'^\.\/'/''/ | xargs openssl sha1 -sha256 | sed 's@SHA256(\(.*\))= \([0-9a-f]*\)@\2  \1@' > SHA256SUMS 2>/dev/null

cd ../
echo "Creating ${UTIL}-${VERS}.tar.gz..."
tar -cvf - ${UTIL}-${VERS} | gzip -9c > ${UTIL}-${VERS}.tar.gz || exit 1
rm -rf ${UTIL}-${VERS}/ 2>/dev/null >/dev/null

if [ -d archive -a "${COPY_TO_ARCHIVE}" = '1' ]; then
	mkdir -p archive/${UTIL}/ 2>/dev/null
	mv ${UTIL}-${VERS}.tar.gz archive/${UTIL}/ 2>/dev/null >/dev/null
	for file in archive/${UTIL}-*.tar.gz; do
		if [ -L "${file}" ]; then rm -f ${file} 2>/dev/null; fi
	done
	ln -s ${UTIL}/${UTIL}-${VERS}.tar.gz archive/${UTIL}-${VERS}.tar.gz 2>/dev/null >/dev/null

	case "${VC}" in
		fossil)
			if [ -n "${fossil_co}" ]; then
				echo "# Recommended action to tag this release:"
				echo "fossil tag add ${VERS} ${fossil_co}"
			fi
			;;
	esac
fi
