#!/bin/bash
#
# pre-push hook that checks that all commits that are about to be pushed have
# the bugzilla ID specified and the bug reports have all the necessary acks.
#

exec 1>&2

if ! type parallel 2>&1 > /dev/null; then
    echo "parallel must be installed"
    exit 99
fi

# git gives us these on STDIN
read more_args
local_ref=$(echo ${more_args}|cut -d' ' -f1)

echo "*** Checking commits that are about to be pushed" >&2

## initialization ##
remote="${1}"
ACK_FATAL=0
branch_name=$(echo "${local_ref}" | cut -d'/' -f3)
branch_pattern="^rhel([[:digit:]])-(.*)"
if [[ ! "$branch_name" =~ $branch_pattern ]]; then
   exit 0
fi
release=${BASH_REMATCH[1]}

# Is this a local branch, or the primary branch?
if [ "${BASH_REMATCH[2]}" == "branch" ]; then
    # Make a missing ack block the commit
    ACK_FATAL=0
else
    # Missing acks are just warnings
    ACK_FATAL=1
fi

if [ -f "${HOME}/.rhbzauth" ]; then
    . "${HOME}/.rhbzauth"
fi

bzcmd="bugzilla"
if [ ! -z "${RHBZ_USER}" ]; then
   if [ ! -z "${RHBZ_PASSWORD}" ]; then
       bzcmd_login="${bzcmd} --user=${RHBZ_USER} --password=${RHBZ_PASSWORD} login"
   else
       bzcmd_login="${bzcmd} --user=${RHBZ_USER} login"
   fi
else
    bzcmd_login="${bzcmd} login"
fi

commits=$(git log --pretty='%H' ${remote}/${branch_name}..${branch_name})
if [ $? != 0 ]; then
    if [ -n ${NEW_BRANCH} ]; then
        exit 0
    else
        echo "*** Cannot find the remote branch ***"
        echo 'Set the $NEW_BRANCH variable to an nonempty string to allow this push'
        exit 1
    fi
fi

${bzcmd} >/dev/null 2>&1
if [ $? -eq 127 ]; then
    echo "*** 'dnf install python-bugzilla' to validate bug references."

    msg="$(mktemp $(pwd)/commit.msg.XXXXXXXXXX)"
    cp "${1}" "${msg}"
    echo
    echo "Aborted commit message written to: $(basename ${msg})"
    exit 1
else
    ${bzcmd_login} >/dev/null
fi

## main ##
# fork separate process for every commit, querying bugzilla takes time
echo -n ${commits}|parallel --no-notice -d' ' --gnu -j0 .git/hooks/check_commit_msg.sh ${release} {}
ret=$?
if [ ${ACK_FATAL} == "0" ]; then
    test ${ret} -eq 0
    exit $?
else
    exit 0
fi
