Add git hook for package comparison

When moving to commit, this hook will automatically fire and check the
current system's installed packages against those explicitly committed
to the repository. If they mismatch it will inform the user.

It will not prevent the commit, but simply add a comment at the top of
the commit messages to remind the user that something is unbalanced
between both. It would be recommended to either check the additional
package into source control, remove it from the current system, or
explicitly add it to ignored packages.
This commit is contained in:
Marty Oehme 2020-02-07 22:31:41 +01:00
parent c7ed986c0e
commit ecbf8409f9
No known key found for this signature in database
GPG key ID: 0CCB0526EFB9611A
4 changed files with 76 additions and 1 deletions

View file

@ -0,0 +1 @@
^/.* # everything

58
.githooks/prepare-commit-msg Executable file
View file

@ -0,0 +1,58 @@
#!/usr/bin/env sh
COMMIT_MSG_FILE="$1"
COMMIT_SOURCE="$2"
pkgfileloc="$(git rev-parse --show-toplevel)/_bootstrap/packages.txt"
pkgignoreloc="$(git rev-parse --show-toplevel)/_bootstrap/packages_ignore.txt"
listgen="yay"
err() {
printf "\x1b[33mCAUTION:\x1b[0m %s\n" "$*"
exit 1
}
if [ ! -f "$pkgfileloc" ]; then
err "File not found - $pkgfileloc, can not determine package differences!"
fi
if ! type "$listgen" >/dev/null 2>&1; then
err "Yay not installed on machine, can not reliably determine package differences!"
fi
# get commited packages, remove empty lines
# and lines beginning with # to allow comments
pkgcommited=$(mktemp)
sed -e '/^[#$]/d' <"$pkgfileloc" | sort >"$pkgcommited"
# get packages on this machine
# q removes extraneous info
# e only lists explicitly installed
# tt removes those that are depended on, but NOT those optionally depended on
pkgcurrent=$(yay -Qqett | sort)
# remove those listed in package_ignore.txt
if [ -f "$pkgignoreloc" ]; then
pkgcurrent=$(echo "$pkgcurrent" | comm -23 - "$pkgignoreloc")
fi
# compare the lists, list differences
result=$(echo "$pkgcurrent" | comm -3 - "$pkgcommited")
# get files only in repo (field1), and only on machine (field2)
added=$(echo "$result" | cut -f1 | sed -e '/^$/d')
removed=$(echo "$result" | cut -s -f2)
# if we have no changes, do nothing
if [ -n "$added" ] || [ -n "$removed" ]; then
text=$(printf "\-- PACKAGE DIFFERENCES TO COMMITED LIST FOUND --\nPackages NOT YET in repo:\n%s\n\nPackages ONLY in repo:%s\n" "$added" "$removed" | sed 's/^/# /gm')
else
exit 0
fi
# prepend package changes to message
case $COMMIT_SOURCE in
"" | message, | template,)
msg=$(echo "$text" | cat - "$COMMIT_MSG_FILE")
printf "%s" "$msg" >"$COMMIT_MSG_FILE"
;;
esac

View file

@ -1,4 +1,4 @@
# TODO find a more generic way to express 'ignore any non-folder files'
^/install_packages.sh
^/packages.csv
^/packages.*.txt

View file

@ -44,6 +44,19 @@ check_consent() {
fi
}
enable_git_hooks() {
if [ "$1" == "false" ]; then
echo "Should we enable git hooks for this repository, so that installed packages are automatically compared when committing? [Y/n]"
read -r no
if [[ "$no" == n* ]]; then
echo "Not changing repository settings."
return
fi
fi
git config --local core.hooksPath .githooks/
echo "Changed repository settings."
}
install() {
unattended=$1
if ! "$unattended"; then
@ -68,6 +81,9 @@ install() {
# -- for some reason stow only works with unqoted var expansion
stow -R ${targets} 2> >(grep -v 'Absolute/relative mismatch between Stow dir' 1>&2)
echo "================== ENABLING GIT REPOSITORY HOOKS =========================="
enable_git_hooks "$unattended"
echo "====================== INSTALLATION FINISHED =============================="
exit 0
}