#!/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