#!/usr/bin/bash
#
# The Qubes OS Project, http://www.qubes-os.org
#
# Copyright (C) 2015 Jason Mehring <nrgaway@gmail.com>
# Copyright (C) 2015 Marek Marczykowski-Górecki <marmarek@invisiblethingslab.com>
# Copyright (C) 2022 Frédéric Pierret (fepitre) <frederic@invisiblethingslab.com>
#
# 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, see <https://www.gnu.org/licenses/>.
#
# SPDX-License-Identifier: GPL-3.0-or-later

# =============================================================================
# This script is run before the Debian package is built and possibly updates
# the debian/changelog to indicate a devel or release version
#
# There are 2 modes:
# 1. Development mode.  Will append devel# and increment it by one on each
#    build.  The changelogs will be saved in package/debain directory as
#    changlelog.$(DIST) and are copied into place at time of build for each
#    specific distribution
# 2. Release mode.  If the version number (minus epoc and release info) in
#    package root directory differs from what is reported in changelog a
#    release is created, updating the changelog with commits since previous
#    version and bumping the changelog version
#
# Addtionally, if the script is called with --verify option, it will only check
# if the debian/changelog entry matches version/rel file and set appropriate
# exit code.
# -----------------------------------------------------------------------------
# NOTES:
#
# Examples used within this script are using the following package for
# reference:
#   core-agent-linux; release2 branch; tagged as v2.1.5.5
#   building in a wheezy chroot environment
# =============================================================================

if ! [ -r version ]; then
    echo "This package does not have version file, changelog will not be generated" >&2
    exit 0
fi

debian_parser=$(dirname "${0}")/debian-parser

changelog=debian/changelog

deb_version=$($debian_parser changelog --package-version $changelog)
deb_revision=$($debian_parser changelog --package-revision $changelog)
deb_epoc=$($debian_parser changelog --package-version-epoc $changelog)

# drop dist-specific suffix for version comparison
deb_revision=${deb_revision%+deb*}

version="$(sed 's/-rc/~rc/' version)"
# only two components supports non-default revisions: linux-kernel and vmm-xen
revision="$(cat rel 2>/dev/null)"
previous_tag="v${deb_version/\~/-}-${deb_revision}"
if [ -z "$revision" ]; then
    revision="1"
    previous_tag="v${deb_version/\~/-}"
fi
if [ -z "$deb_revision" ]; then
    revision=""
fi

if [ "$1" = "--verify" ]; then
    if [ "${deb_version}-${deb_revision}" = "${version}-${revision}" ]; then
        exit 0
    else
        echo "Version mismatch: ${deb_version}-${deb_revision} in debian/changelog but ${version}-${revision} in version+rel" >&2
        exit 1
    fi
fi

# =============================================================================
#                            R E L E A S E   M O D E
# =============================================================================
# Release version: Update changelog with commit history
# -----------------------------------------------------------------------------
#           --newversion:  Specifies the new version number
#          --no-auto-nmu:  Disable automatic non-maintainer upload detection
#   --nomultimaint-merge:  Do not merge all changes made by same author into
#                          same changelog section
#           --multimaint:  Indicate parts of a changelog entry have been made
#                          by different maintainers
if [ "${deb_version}-${deb_revision}" != "${version}-${revision}" ]; then
    # -----------------------------------------------------------------------------
    # Create new version number adding epoc and revision info for quilt packages
    # if they exist
    # -----------------------------------------------------------------------------
    if [ "X${deb_revision}" == "X" ]; then
        new_version="${version}"
    else
        new_version="${version}-${revision}"
        if [ "X${deb_epoc}" != "X" ]; then
            new_version="${deb_epoc}:${new_version}"
        fi
    fi

    # -----------------------------------------------------------------------------
    # Add new version number and git commit history to changelog
    # -----------------------------------------------------------------------------
    IFS=%
    # shellcheck disable=SC2034
    (
        git log --no-merges --topo-order --reverse --pretty=format:%an%%%ae%%%ad%%%s "${previous_tag}"..HEAD
        echo
    ) |
        while read -r a_name a_email date sum; do
            DEBFULLNAME="${a_name}" DEBEMAIL="${a_email}" \
                         debchange --newversion="${new_version}" --no-auto-nmu --nomultimaint-merge --multimaint -- "${sum}"
        done

    # -----------------------------------------------------------------------------
    # Release - changelog name, email and distribution updated
    # -----------------------------------------------------------------------------
    if [ -z "$DEBFULLNAME" ]; then
        DEBFULLNAME="$(git config user.name)"
    fi
    if [ -z "$DEBEMAIL" ]; then
        DEBEMAIL="$(git config user.email)"
    fi
    export DEBFULLNAME
    export DEBEMAIL
    debchange --force-distribution --distribution "${DIST}" --release -- ''
fi

# =============================================================================
#                            D E V E L O P   M O D E
# =============================================================================
# Devel version: Update changelog
# -----------------------------------------------------------------------------
# Check to see if the debain changelog contains ?devel in the version number
# - If it does; update the changelog, then exit with...
#            DEBFULLNAME:  Add users git name to changelog entry
#                DEBNAME:  Add users git email address to changelog entry
#   --nomultimaint-merge:  Do not merge all changes made by same author into
#                          same changelog section
#           --multimaint:  Indicate parts of a changelog entry have been made
#                          by different maintainers
#               -l~devel:  add a local suffix to the debian version of
#                          '~devel'
#         --distribution:  Used in --release to change the DISTRIBUTION value
#                          in changelog to value provided ($DIST == wheezy)
#              --release:  Finalize the changelog for a release which updates
#                          timestamp, If DISTRIBUTION in changelog is set to
#                          UNRELEASED change it to the distribution $DIST
#                          (wheezy)

if [ "0${INCREMENT_DEVEL_VERSIONS}" -eq 1 ] && [ "0${DEVEL_VERSION}" -gt 0 ]; then
    if [ -z "$DEBFULLNAME" ]; then
        DEBFULLNAME="$(git config user.name)"
    fi
    if [ -z "$DEBEMAIL" ]; then
        DEBEMAIL="$(git config user.email)"
    fi
    export DEBFULLNAME
    export DEBEMAIL
    debchange --nomultimaint-merge --multimaint -l"+${DIST_TAG}1+devel" -- 'Test build'
    sed -i "s/+${DIST_TAG}1+devel1/+${DIST_TAG}1+devel${DEVEL_VERSION}/g" debian/changelog
    debchange --force-distribution --distribution "${DIST}" --release -- ''
fi
