# gitpkg hook script to build packages locally after export
#
# To enable this hook, use:
# git config gitpkg.exit-hook /usr/share/gitpkg/hooks/dpkg-buildpackage-exit-hook

# We're out of the repo tree, but want to check git-config
. /usr/share/gitpkg/hooks/repo-config-helper

# We need bash 4.4 or later for the ${var@Q} parameter transformation, so check
# and bail out here with a friendly warning instead of crashing obscurely later.
require_bash_version 4.4

# The --sign-source-changes option is a bit special, some of its values effect
# both what we do here, and the options that we pass to other tools.
get_option_value 'DPKG_BP_SSC' 'sign-source-changes' \
			       'gitpkg-dpkg-buildpackage-exit-hook.source-changes'
SOURCE_CHANGES=
EXTRA_DPKG_BP_OPTS=()
case ${DPKG_BP_SSC-unset} in
    "")			EXTRA_DPKG_BP_OPTS+=( '-uc' '-us' )	;&
    true|yes|signed)	SOURCE_CHANGES=${DPKG_BP_SSC:-signed}	;;
    unset|false|no)						;;
    *)
	echo "Unknown option value for --sign-source-changes '$DPKG_BP_SSC'.  Stopping."
	exit 1
	;;
esac

# --dpkg-bp command line options override the git config .options settings.
# Any dpkg-buildpackage(1) option can be passed via --dpkg-bp or .options.
# The more specialised config options exist so that it is easy to override
# (and make overridable) just a subset them, without requiring the user to
# manually re-enter all of the otherwise unchanged default configuration.
#
# Multi-value options:
get_option_values 'DPKG_BP_OPTS' 'dpkg-bp' 'gitpkg-dpkg-buildpackage-exit-hook.options'

# Single-value options:
get_option_value 'DPKG_BP_SIGN'     'sign'      'gitpkg-dpkg-buildpackage-exit-hook.sign-key'
get_bool_value   'DPKG_BP_BUILDLOG' 'build-log' 'gitpkg-dpkg-buildpackage-exit-hook.build-log'

# Remove empty elements so that --dpkg-bp= can be used to override config
# default settings to pass no options without passing "" as an option word.
trim_array 'DPKG_BP_OPTS'

DPKG_BP_OPTS+=( "${DPKG_BP_SIGN[@]/#/-k}"
		"${EXTRA_DPKG_BP_OPTS[@]}"
)


# The option of a veto is a handy safety catch for running an unexpected hook,
# but if the user has explicitly passed a dpkg-bp-specific command line option
# then we'll take that as an implicit assent, and expressed intent, to proceed.
ASK_YES_OPTS=( 'dpkg-bp' )

if [ "$(repo_config --get --bool gitpkg-dpkg-buildpackage-exit-hook.ask-first)" = 'true' ] &&
   ! have_any_of_these_commandline_options "${ASK_YES_OPTS[@]}"
    then
	printf "Build binary packages from $DEB_DSC now (Y/n)? "
	read -e yesno
	case $yesno in
	    N* | n*)
		echo "Ok, you're the boss.  If you change your mind, just run:"
		echo "cd $DEB_DIR/$DEB_SOURCE/$DEB_PACKAGE &&" \
		     "dpkg-buildpackage" "${DPKG_BP_OPTS[@]@Q}"
		echo
		exit 0
		;;
	    "") echo "Yes" # read doesn't echo a line feed if the user just hit <enter>
		;;
	    *)	;;
	esac
fi


do_build()
{
    echo "cd $DEB_PACKAGE && dpkg-buildpackage" "${DPKG_BP_OPTS[@]@Q}"
    ( cd "$DEB_PACKAGE" && dpkg-buildpackage "${DPKG_BP_OPTS[@]}" ) || exit 1


    # If source-changes = true, we respect -uc if passed and generate a
    # <package>_source.changes file but do not sign it.
    #
    # If source-changes = signed, we consider -uc (if passed) to only apply
    # to the <package>_<arch>.changes, and sign the source-only changes file.
    # The -us option is ignored in this case, as debsign will also sign all
    # .dsc and .buildinfo files referenced by the .changes it is signing.
    case $SOURCE_CHANGES in
	true|yes)
	    SIGN_SOURCE_CHANGES=
	    ;;
	signed)
	    SIGN_SOURCE_CHANGES="yes"
	    ;;
	*)
	    return 0
	    ;;
    esac

    # Keep using the dpkg-buildpackage options which apply to dpkg-genchanges
    # and debsign when creating a _source.changes for the package.
    DPKG_GENCHANGES_OPTS=( "-S" )
    DEBSIGN_OPTS=()

    # We use DEB_SIGN_KEYID from the environment, if set, as dpkg-buildpackage
    # does.  But ignore DEBSIGN_KEYID here which is specific to debsign and is
    # not an environment variable.  It can only be set in devscripts.conf and
    # will still be used by debsign (overriding -m or -e) if we do not choose
    # a key explicitly with -k.
    SIGNING_KEY=$DEB_SIGN_KEYID

    for opt in "${DPKG_BP_OPTS[@]}"; do
	case $opt in
	    -s[iad]|-v*|-C*)
		DPKG_GENCHANGES_OPTS+=( "$opt" )
		;;
	    --changes-option=*)
		DPKG_GENCHANGES_OPTS+=( "${opt#--changes-option=}" )
		;;

	    # dpkg-buildpackage added long forms of these options, but didn't
	    # add those to any of the tools it passes them through to, so we
	    # need to fuck around here fixing that up.
	    -m*|-e*)
		DPKG_GENCHANGES_OPTS+=( "$opt" )
		DEBSIGN_OPTS+=( "$opt" )
		;;
	    --release-by=*)
		DPKG_GENCHANGES_OPTS+=( "-m${opt#--release-by=}" )
		DEBSIGN_OPTS+=( "-m${opt#--release-by=}" )
		;;
	    --build-by=*)
		DPKG_GENCHANGES_OPTS+=( "-e${opt#--build-by=}" )
		DEBSIGN_OPTS+=( "-e${opt#--build-by=}" )
		;;
	    -k*)
		SIGNING_KEY=${opt#-k}
		;;
	    --sign-key=*)
		SIGNING_KEY=${opt#--sign-key=}
		;;

	    -uc|--unsigned-changes|--no-sign)
		SIGN_SOURCE_CHANGES=${SIGN_SOURCE_CHANGES:-"no"}
		;;
	esac
    done

    # debsign will fall back to DEBSIGN_KEYID from devscripts.conf if it is set
    # and no -k override is passed, regardless of -m or -e - which is different
    # to the key dpkg-buildpackage would select
    [ -z "$SIGNING_KEY" ] || DEBSIGN_OPTS+=( "-k$SIGNING_KEY" )

    SOURCE_CHANGES_FILE="${DEB_SOURCE}_${UPSTREAM_VERSION}_source.changes"


    echo "cd $DEB_PACKAGE && dpkg-genchanges" "${DPKG_GENCHANGES_OPTS[@]@Q}"	\
					    "> ../$SOURCE_CHANGES_FILE"
    ( cd "$DEB_PACKAGE" && dpkg-genchanges "${DPKG_GENCHANGES_OPTS[@]}"		\
					    > "../$SOURCE_CHANGES_FILE"
    ) || exit 1


    [ "$SIGN_SOURCE_CHANGES" != 'no' ] || return 0

    echo "debsign" "${DEBSIGN_OPTS[@]@Q}" "$SOURCE_CHANGES_FILE"
    debsign "${DEBSIGN_OPTS[@]}" "$SOURCE_CHANGES_FILE"
}


if [ "$DPKG_BP_BUILDLOG" = 'false' ]
then
    do_build
else
    DATE="$(date +%Y%m%d+%H.%M 2>/dev/null)"
    BUILD_LOGFILE="build-${DEB_SOURCE}_${DEB_VERSION}_${DATE}.log"

    echo "Recording build log in $BUILD_LOGFILE"
    do_build 2>&1 | tee "$BUILD_LOGFILE"
fi

# vi:sts=4:sw=4:noet:foldmethod=marker
