From ecbf8409f9c4ea2db6f92008a2545f7742d41ad0 Mon Sep 17 00:00:00 2001 From: Marty Oehme Date: Fri, 7 Feb 2020 22:31:41 +0100 Subject: [PATCH] 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. --- .githooks/.stow-local-ignore | 1 + .githooks/prepare-commit-msg | 58 +++++++++++++++++++++++++++++++++++ _bootstrap/.stow-local-ignore | 2 +- install.sh | 16 ++++++++++ 4 files changed, 76 insertions(+), 1 deletion(-) create mode 100644 .githooks/.stow-local-ignore create mode 100755 .githooks/prepare-commit-msg diff --git a/.githooks/.stow-local-ignore b/.githooks/.stow-local-ignore new file mode 100644 index 0000000..96787ae --- /dev/null +++ b/.githooks/.stow-local-ignore @@ -0,0 +1 @@ +^/.* # everything diff --git a/.githooks/prepare-commit-msg b/.githooks/prepare-commit-msg new file mode 100755 index 0000000..cacaa1e --- /dev/null +++ b/.githooks/prepare-commit-msg @@ -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 diff --git a/_bootstrap/.stow-local-ignore b/_bootstrap/.stow-local-ignore index 1bf0cf2..1b5258a 100644 --- a/_bootstrap/.stow-local-ignore +++ b/_bootstrap/.stow-local-ignore @@ -1,4 +1,4 @@ # TODO find a more generic way to express 'ignore any non-folder files' ^/install_packages.sh -^/packages.csv +^/packages.*.txt diff --git a/install.sh b/install.sh index c67c377..7ce8596 100755 --- a/install.sh +++ b/install.sh @@ -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 }