#!/bin/bash

# Copyright (C) @johnraff

set -o nounset # do not accept unset variables

HELP="Script to build a Debian package from the directory tree,
in a clean chroot using pbuilder.

SUMMARY:    pbuild [options]

Architecture is amd64 by default, can be changed by option.

Distribution is determined from package changelog,
or set manually via option. (supported: stretch|buster)

Package is signed by default, disabled by option.

OPTIONS:
            -a, --arch <arch>
Where <arch> is amd64 or i386
            -d, --dist <dist>
Where <dist> is stretch or buster
            -u, --unsigned
Do not sign the package.
            -h, --help
Output this message.

---
You might consider creating ~/.pbuilderrc for some customization.
Example:

MIRRORSITE=https://deb.debian.org/debian
COMPONENTS='main contrib non-free'
HOOKDIR='/var/cache/pbuilder/hooks'
export EDITOR='nano'
export DH_VERBOSE=1

"

# fallbacks
dist=buster
arch=amd64

# pbuilder base file
# -${dist}-${arch}.tgz will be appended
# Make sure such files exist!
# e.g. sudo pbuilder create --distribution stretch --architecture amd64 --basetgz /var/cache/pbuilder/base-stretch-amd64.tgz --debootstrapopts --variant=buildd
base_stem='/var/cache/pbuilder/base'

# where to put built files
# See lines 161~166 to set other dir based on package name, architecture, etc.
# Set logfile there too.
results_dir=..

########################################################################
required_commands='pdebuild'

error_exit() {
    echo "$0 ERROR: $1" >&2
    [[ -n "$logfile" ]] && echo "ERROR: $1" >> "$logfile"
    exit 1
}
warning() {
    echo "$0 WARNING: $1"$'\n' >&2
    [[ -n "$logfile" ]] && echo "WARNING: $1" >> "$logfile"
}

log() {
    echo "$1"
    [[ -n "$logfile" ]] && echo "$1" >> "$logfile"
}

confirm() {
    echo "$*"
    echo '(Enter to agree, any other key to decline.)'
    read -srn1
    [[ -n $REPLY ]] && {
        [[ -n "$logfile" ]] && echo "$*"$'\nUser declined.' >> "$logfile"
        return 1
    }
    [[ -n "$logfile" ]] && echo "$*"$'\nUser agreed.' >> "$logfile"
    return 0
}

missing_commands=
for i in $required_commands
do
    hash "$i" || missing_commands+=" $i"
done
[[ $missing_commands ]] && error_exit "This script requires the following commands: $missing_commands
Please install the packages containing the missing commands
and rerun the script."

dist_warning=false
pkg_dist=$(dpkg-parsechangelog --show-field Distribution)
case $pkg_dist in
helium|stretch)
    dist=stretch
    ;;
lithium|buster)
    dist=buster
    ;;
*)
    dist_warning=true
    # but dist might be declared in command line option
    ;;
esac

sign_pkg=true

while [[ -n ${1-} ]]
do
    case ${1-} in
    --dist|-d)
        dist=$2
        shift 2
        ;;
    --arch|-a)
        arch=$2
        shift 2
        ;;
    ---unsigned|-u)
        sign_pkg=false
        shift
        ;;
    --help|-h)
        echo "$HELP"
        exit
        ;;
    *)
        error_exit "${1}: no such option"$'\n'"$HELP"
        ;;
    esac
done

case $dist in
stretch|buster)
    :;;
*)
    error_exit "Distribution $dist not supported"
    ;;
esac

case $arch in
amd64|i386)
    :;;
*)
    error_exit "Architecture $arch not supported"
    ;;
esac

[[ -f "${base_stem}-${dist}-${arch}.tgz" ]] || error_exit "basefile ${base_stem}-${dist}-${arch}.tgz not found"

# in Debian source directory?
[[ -f debian/changelog ]] || error_exit 'No file debian/changelog (wrong directory?)'

pkg_name=$(dpkg-parsechangelog --show-field Source)
[[ "${PWD##*/}" = ${pkg_name}* ]] || error_exit "The parent directory (${PWD##*/})
is not named after the package (${pkg_name}).
Most Debian packaging tools expect this."

pkg_ver=$(dpkg-parsechangelog --show-field Version)

# SET RESULTS DIR
# alternative destination
#results_dir=../"result-${arch}"
mkdir -p "$results_dir"

logfile="$results_dir/${pkg_name}_${pkg_ver}_${arch}.build"

[[ $dist_warning = true ]] && warning "Package declares unsupported distribution: $pkg_dist"

make_orig=true
log "creating orig.tar.gz..."$'\n'
origname="${pkg_name}_${pkg_ver%-*}.orig.tar.gz"
if [[ -f ../$origname ]]
then
    confirm "../$origname exists. Overwrite?" || make_orig=false
fi
[[ $make_orig = true ]] && tar -caf ../"${origname}" --exclude=debian --exclude-vcs --exclude-vcs-ignores .

sign_arg='--auto-debsign'
log "Building ${pkg_name} ${pkg_ver} on ${dist} for architecture ${arch}."
if [[ $sign_pkg != true ]]
then
    sign_arg=
    warning 'Package will not be signed.'
fi
log "
Using pdebuild with ${base_stem}-${dist}-${arch}.tgz...
"

echo "Press Enter to continue, any other key to exit:"

read -srn1
[[ -n $REPLY ]] && exit

pdebuild $sign_arg --architecture "${arch}" --buildresult "$results_dir" --logfile "${logfile}.pbuild" --debbuildopts -b -- --basetgz "${base_stem}-${dist}-${arch}.tgz" || error_exit "pdebuild failed"

cat "${logfile}.pbuild" >> "${logfile}" || error_exit "failed to merge ${logfile}.pbuild with ${logfile}"
rm "${logfile}.pbuild"

#log 'running debc'
#debc | tee -a "$logfile"

log '
running Lintian...'
lintian --pedantic --info "$results_dir/${pkg_name}_${pkg_ver}_${arch}.changes" | tee -a "$logfile"