env/utils/scripts/zone-serial-number-hook.sh

86 lines
1.8 KiB
Bash

#!/bin/sh
# zone-serial-number-hook - Check for missing serial bumps
#
# Written in 2020 by Lucas
#
# To the extent possible under law, the author(s) have dedicated all
# copyright and related and neighboring rights to this software to the
# public domain worldwide. This software is distributed without any
# warranty.
#
# You should have received a copy of the CC0 Public Domain Dedication
# along with this software. If not, see
# <http://creativecommons.org/publicdomain/zero/1.0/>.
# Requires:
# - POSIX sh
# - bc
# - git
# - ldns-utils
# Install instructions:
#
# cp zone-serial-number-hook "$myrepo/.git/hooks/pre-commit"
# chmod +x "$myrepo/.git/hooks/pre-commit"
bc_cmp()
{
_X=$1
_OP=$2
_Y=$3
_rc=$(bc <<EOF
define t(x, y){
if (x $_OP y) {
return(0)
}
return(1)
}
t($_X, $_Y)
EOF
)
return $_rc
}
get_serial()
{
git show "$1" 2>/dev/null | ldns-read-zone -E SOA | {
read -r _name _ttl _class _rrtype _rname _mname _serial _rest
printf "%s\n" "${_serial:-0}"
}
}
if git rev-parse --verify HEAD >/dev/null 2>&1; then
against=HEAD
else
# Initial commit: diff against an empty tree object
against=$(git hash-object -t tree /dev/null)
fi
# Zonefiles names are matched against hooks.zonefile_regex option.
# Defaults to `\.zone$`.
zonefile_regex=$(git config --default '\.zone$' hooks.zonefileregex)
needs_serial_bump=$(git diff-index --name-only --cached "$against" |
grep -E -- "$zonefile_regex" | {
rc=0
while IFS= read -r filename; do
old=$(get_serial "$against:$filename")
new=$(get_serial ":$filename")
if bc_cmp "$new" "<=" "$old"; then
printf "%s\n" "$filename"
rc=1
fi
done
return $rc
})
rc=$?
if [ $rc -ne 0 ]; then
# send all output to standard error
exec >&2
printf "The following zonefiles require a serial bump:\n"
printf "- %s\n" $needs_serial_bump
fi
exit $rc