#!/bin/sh
# $NetBSD: pkg-build,v 1.31 2016/12/18 09:36:38 joerg Exp $
#
# Copyright (c) 2007, 2008 Joerg Sonnenberger <joerg@NetBSD.org>.
# All rights reserved.
#
# This code was developed as part of Google's Summer of Code 2007 program.
#
# Redistribution and use in source and binary forms, with or without
# modification, are permitted provided that the following conditions
# are met:
#
# 1. Redistributions of source code must retain the above copyright
#    notice, this list of conditions and the following disclaimer.
# 2. Redistributions in binary form must reproduce the above copyright
#    notice, this list of conditions and the following disclaimer in
#    the documentation and/or other materials provided with the
#    distribution.
#
# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
# ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
# LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
# FOR A PARTICULAR PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE
# COPYRIGHT HOLDERS OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
# INCIDENTAL, SPECIAL, EXEMPLARY OR CONSEQUENTIAL DAMAGES (INCLUDING,
# BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
# LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
# AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
# OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
# OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
# SUCH DAMAGE.

. /usr/pkg/etc/pbulk.conf

if [ "${config_version}" != "0.68" ]; then
	echo "Your configuration has version ${config_version}."
	echo "This version of pbulk expects version 0.68."
	exit 1
fi

default_sync_package() {
	mkdir -p ${packages}/All
	cp "$1" "${packages}/All/${pkgname}${pkg_sufx}"
}

cleanup() {
	if [ "$keep_wrkdir" = yes ]; then
		${make} pbulk-save-wrkdir INTO=${bulklog}/${pkgname}/wrkdir.tar.gz TAR="${tar}"
	fi
	if [ "$keep_prefix" = yes ] && [ -f ${bulklog}/${pkgname}/install.log ]; then
		if [ "$cross_compile" != "no" ]; then
			cur_destdir=${target_destdir}
		else
			cur_destdir=
		fi
		${tar} -czf ${bulklog}/${pkgname}/prefix.tar.gz ${cur_destdir}${prefix}
	fi
	${make} clean > /dev/null 2>&1 || true
	${sync_buildlog} ${bulklog} ${pkgname}
	exit 1
}

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

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

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

while read build_info_line; do
	case "${build_info_line}" in
	PKGNAME=*)
		pkgname=${build_info_line#PKGNAME=}
		;;
	PKG_LOCATION=*)
		pkgdir=${build_info_line#PKG_LOCATION=}
		;;
	DEPENDS=*)
		dependencies=${build_info_line#DEPENDS=}
		;;
	CATEGORIES=*)
		categories=${build_info_line#CATEGORIES=}
		;;
	MULTI_VERSION=*)
		MAKE_FLAGS=${build_info_line#MULTI_VERSION=}
		;;
	USE_DESTDIR=*)
		use_destdir=${build_info_line#USE_DESTDIR=}
		;;
	BOOTSTRAP_PKG=*)
		is_bootstrap=${build_info_line#BOOTSTRAP_PKG=}
		;;
	USERGROUP_PHASE=*)
		usergroup_phase=${build_info_line#USERGROUP_PHASE=}
	esac
done

if [ "$use_unprivileged_checksum" != "no" ]; then
	run_checksum=run_su
else
	run_checksum=run_direct
fi
if [ "$use_destdir" = user-destdir ]; then
	run_build=run_su
	run_install=run_su
else
	run_build=run_su
	run_install=run_direct
fi

if [ `/usr/bin/id -u` -ne 0 ]; then
	run_checksum=run_direct
	run_build=run_direct
	run_install=run_direct
fi

${pkg_up_to_date_script} ${pkgname} ${dependencies} && exit 0

set -e

/usr/pkg/libexec/pbulk/client-clean

# Create the output directory and clean it up
mkdir -p ${bulklog}/${pkgname}
rm -f ${bulklog}/${pkgname}/*

touch ${bulklog}/${pkgname}/work.log
/usr/sbin/chown ${unprivileged_user} ${bulklog}/${pkgname}/work.log

pkg_add_normal() {
	PKG_PATH=${packages}/All ${pkg_add} -K ${cur_pkgdb} "$@"
}

pkg_add_cross() {
	PKG_PATH=${packages}/All ${pkg_add} -K ${cur_pkgdb} \
	    -m ${target_arch} -I -p ${target_destdir}${prefix} "$@"
	echo "Fixing recorded cwd..."
	${pkg_info} -K ${target_destdir}${pkgdb} | while read pkg junk; do
		${sed} -e 's|@cwd '"${target_destdir}"'|@cwd |' \
		    ${cur_pkgdb}/"${pkg}"/+CONTENTS > \
		    ${cur_pkgdb}/"${pkg}"/+CONTENTS.tmp
		mv ${cur_pkgdb}/"${pkg}"/+CONTENTS.tmp \
		    ${cur_pkgdb}/"${pkg}"/+CONTENTS
	done
}

if [ "$cross_compile" != "no" ]; then
	pkg_add_cmd=pkg_add_cross
	cur_pkgdb="${target_destdir}${pkgdb}"
else
	pkg_add_cmd=pkg_add_normal
	cur_pkgdb="${pkgdb}"
fi

# Go to target directory
cd ${pkgsrc}/${pkgdir}
# Clean build area, just in case
${make} clean > ${bulklog}/${pkgname}/pre-clean.log 2>&1
# Install all dependencies the package said it would need
if [ ! -z "$dependencies" ]; then
	${pkg_add_cmd} $dependencies > ${bulklog}/${pkgname}/depends.log 2>&1 || cleanup
fi
# Build package, create a separate log file for each major phase
run_make ${run_checksum} checksum  > ${bulklog}/${pkgname}/checksum.log 2>&1 || cleanup
run_usergroup configure > ${bulklog}/${pkgname}/configure.log 2>&1 || cleanup
run_make ${run_build} configure >> ${bulklog}/${pkgname}/configure.log 2>&1 || cleanup
run_usergroup build> ${bulklog}/${pkgname}/build.log 2>&1 || cleanup
run_make ${run_build} all >> ${bulklog}/${pkgname}/build.log 2>&1 || cleanup
run_usergroup install > ${bulklog}/${pkgname}/install.log 2>&1 || cleanup
run_make ${run_install} stage-install >> ${bulklog}/${pkgname}/install.log 2>&1 || cleanup
run_make run_direct stage-package-create > ${bulklog}/${pkgname}/package.log 2>&1 || cleanup

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

# Add the package once to test install rules.  This is not done for
# potential bootstrap packages as they might already be installed.
if [ -z "${is_bootstrap}" ]; then
	if ! ${pkg_add_cmd} ${pkgfile} \
	    >> ${bulklog}/${pkgname}/package.log 2>&1; then
		cleanup
	fi
fi

# Test uninstall rules. This is not for cross-compiling as the install script
# is not run in that case anyway. This is also not done for packages marked as
# part of the bootstrap, those have the preserve flag set.
if [ "$cross_compile" = "no" ] && \
   [ -z "${is_bootstrap}" ]; then
	${pkg_delete} -K ${cur_pkgdb} ${pkgname} > ${bulklog}/${pkgname}/deinstall.log 2>&1 || cleanup
fi

# Comment the following out if you want to test all deinstall scripts.
# This is quite expensive and mostly redundant, so it is disabled by default.
#${pkg_delete} -r \* > /dev/null 2>&1 || cleanup

${sync_package} ${pkgfile} ${pkgname} "${categories}" || cleanup

# Clean build area
${make} clean > ${bulklog}/${pkgname}/clean.log 2>&1 || true

# Cleanup build logs on success
rm -R ${bulklog}/${pkgname}
