#!/bin/sh
#
# Script to build a single package.  Based on pbulk's pkg-build.
#
# This script receives the ScanIndex entries for the package in question on
# stdin.
#

set -e

# Required core variables.
: ${bob_bulklog:?}
: ${bob_make:?}
: ${bob_packages:?}
: ${bob_pkgtools:?}
: ${bob_pkgsrc:?}
: ${bob_prefix:?}
: ${bob_status_fd:?}
: ${bob_tar:?}

cleanup() {
	if [ -n "${KEEP_WRKDIR}" ]; then
		${bob_make} pbulk-save-wrkdir \
		    INTO="${pkglogdir}/wrkdir.tar.gz" \
		    TAR="${bob_tar}" 2>&1 || true
	fi
	if [ -n "${KEEP_PREFIX}" ] && [ -f "${pkglogdir}/install.log" ]; then
		${bob_tar} -czf "${pkglogdir}/prefix.tar.gz" \
		    ${bob_prefix} 2>&1 || true
	fi
	#
	# Don't run make clean if SKIP_CLEAN is set, this is so bob can handle
	# save_wrkdir_patterns first before cleaning up itself.
	#
	if [ -z "${SKIP_CLEAN}" ]; then
		${bob_make} clean > /dev/null 2>&1 || true
	fi
	exit 1
}

run_direct() { "$@"; }
run_su() { su "${bob_build_user}" -c '"$@"' make "$@"; }

run_make() {
	local run_cmd
	run_cmd=$1
	shift
	${run_cmd} ${bob_make} "$@" \
		BATCH=1 \
		DEPENDS_TARGET=/nonexistent \
		${MAKE_FLAGS} \
		WRKLOG="${pkglogdir}/work.log"
}

run_usergroup() {
	case "${usergroup_phase}" in
	*configure)
		[ "$1" != "configure" ] || ${bob_make} create-usergroup clean
		;;
	*build)
		[ "$1" != "build" ] || ${bob_make} create-usergroup
		;;
	pre-install)
		[ "$1" != "install" ] || ${bob_make} create-usergroup
		;;
	esac
}

# Write current stage to .stage file and status fd for reporting
set_stage() {
	echo "$1" > "${pkglogdir}/.stage"
	echo "stage:$1" >&${bob_status_fd}
}

# Send a status message to the master process
send_status() {
	echo "$1" >&${bob_status_fd}
}

#
# Script starts here.  Parse ScanIndex from stdin.
#
while read scan_input; do
	case "${scan_input}" in
	PKGNAME=*)
		pkgname=${scan_input#PKGNAME=}
		;;
	PKG_LOCATION=*)
		pkgdir=${scan_input#PKG_LOCATION=}
		;;
	DEPENDS=*)
		dependencies=${scan_input#DEPENDS=}
		;;
	MULTI_VERSION=*)
		MAKE_FLAGS=${scan_input#MULTI_VERSION=}
		;;
	BOOTSTRAP_PKG=*)
		is_bootstrap=${scan_input#BOOTSTRAP_PKG=}
		;;
	USERGROUP_PHASE=*)
		usergroup_phase=${scan_input#USERGROUP_PHASE=}
	esac
done

pkglogdir="${bob_bulklog}/${pkgname}"

if [ -z "${bob_build_user}" ]; then
	run_checksum=run_direct
	run_build=run_direct
	run_install=run_direct
else
	run_checksum=run_direct
	run_build=run_su
	run_install=run_su
fi

if [ -n "${PKG_UP_TO_DATE}" ] && [ -x "${PKG_UP_TO_DATE}" ]; then
    mkdir -p "${pkglogdir}"
    if "${PKG_UP_TO_DATE}" "${pkgname}" ${dependencies} > "${pkglogdir}/up-to-date.log" 2>&1; then
        rm -rf "${pkglogdir}"
        send_status "skipped"
        exit 0
    fi
fi

cd ${bob_pkgsrc}/${pkgdir}

mkdir -p "${pkglogdir}"
rm -f "${pkglogdir}"/.stage

exec >${pkglogdir}/pkg-build.log 2>&1
set -x

# Create work.log and make it writable by the unprivileged user
touch "${pkglogdir}/work.log"
if [ -n "${bob_build_user}" ]; then
	chown "${bob_build_user}" "${pkglogdir}/work.log"
fi

trap cleanup INT TERM

set_stage "pre-clean"
${bob_make} clean > "${pkglogdir}/pre-clean.log" 2>&1

# Install dependencies
if [ -n "${dependencies}" ]; then
	set_stage "depends"
	PKG_PATH="${bob_packages}/All" ${bob_pkgtools}/pkg_add \
	    ${dependencies} > "${pkglogdir}/depends.log" 2>&1 || cleanup
fi

set_stage "checksum"
run_make ${run_checksum} checksum > "${pkglogdir}/checksum.log" 2>&1 || cleanup

set_stage "configure"
run_usergroup configure > ${pkglogdir}/configure.log 2>&1 || cleanup
run_make ${run_build} configure >> ${pkglogdir}/configure.log 2>&1 || cleanup

set_stage "build"
run_usergroup build > ${pkglogdir}/build.log 2>&1 || cleanup
run_make ${run_build} all >> ${pkglogdir}/build.log 2>&1 || cleanup

set_stage "install"
run_usergroup install > ${pkglogdir}/install.log 2>&1 || cleanup
run_make ${run_install} stage-install >> ${pkglogdir}/install.log 2>&1 || cleanup

set_stage "package"
run_make run_direct stage-package-create > ${pkglogdir}/package.log 2>&1 || cleanup

pkgfile=$(run_make run_direct show-var VARNAME=STAGE_PKGFILE)

# Test package install unless this is a bootstrap package as it will likely
# already be installed.
if [ -z "${is_bootstrap}" ]; then
	${bob_pkgtools}/pkg_add ${pkgfile} >> "${pkglogdir}/package.log" 2>&1 || cleanup
fi

# Test package uninstall unless bootstrap package (will have preserve flag set).
if [ -z "${is_bootstrap}" ]; then
	set_stage "deinstall"
	${bob_pkgtools}/pkg_delete ${pkgname} > "${pkglogdir}/deinstall.log" 2>&1 || cleanup
fi

# Save package.
mkdir -p "${bob_packages}/All"
cp "${pkgfile}" "${bob_packages}/All/"

set_stage "clean"
${bob_make} clean > "${pkglogdir}/clean.log" 2>&1 || true

# Remove package bulklog directory on success
rm -rf "${pkglogdir}"

exit 0
