From 179a080867d6343f140ec64809ef0143e977d5b6 Mon Sep 17 00:00:00 2001 From: Adrian Duke Date: Thu, 16 Apr 2026 14:30:20 +0100 Subject: [PATCH] just: Introduce commit-msg hook for typos Add a `commit-msg` hook to continuously run `typos` against the COMMIT_MSG. --- justfile | 12 +++++++++--- scripts/git-hook-template.sh | 11 ++++++++--- scripts/just/commit-msg.sh | 16 ++++++++++++++++ 3 files changed, 33 insertions(+), 6 deletions(-) create mode 100755 scripts/just/commit-msg.sh diff --git a/justfile b/justfile index 35441d45..e89421ac 100644 --- a/justfile +++ b/justfile @@ -1,4 +1,4 @@ -hooks := "pre-commit pre-push post-checkout" +hooks := "pre-commit pre-push post-checkout commit-msg" hook-script := "scripts/git-hook-template.sh" WARN := "⚠️ " + YELLOW + BOLD @@ -14,6 +14,12 @@ default: check-hooks [group('hooks')] post-checkout: +# Run commit-msg checks +[group('hooks')] +commit-msg file: (verify-tool "typos" "typos-cli") + @echo "{{CHECK}}Checking commit message for typos...{{NORMAL}}" + @NORMAL="{{NORMAL}}" WARN="{{WARN}}" scripts/just/commit-msg.sh "{{file}}" + # Run pre-commit checks [group('hooks')] pre-commit: format-rust check-rust check-docs check-typos check-spelling check-scripts check-keywords format-nix @@ -66,8 +72,8 @@ check-spelling: (verify-tool "codespell") @echo "{{CHECK}}Checking for code typos...{{NORMAL}}" @git ls-files -z | xargs -0 codespell --write-changes --check-filenames -# just runs with `/bin/sh` which has no doublestar glob -# expansion, furthermore, `time ls **/*.sh` takes ~5s +# just runs with `/bin/sh` which has no doublestar glob +# expansion, furthermore, `time ls **/*.sh` takes ~5s # locally. The `find` solution below is fastest ~900ms. # # Run shellcheck on all shell scripts diff --git a/scripts/git-hook-template.sh b/scripts/git-hook-template.sh index 189b6674..e6fc71bd 100644 --- a/scripts/git-hook-template.sh +++ b/scripts/git-hook-template.sh @@ -3,7 +3,7 @@ set -euo pipefail readonly HOOK="${HOOK:-$(basename "$0")}" -if ! [[ "$HOOK" =~ ^(pre-(commit|push)|post-checkout)$ ]] +if ! [[ "$HOOK" =~ ^(pre-(commit|push)|post-checkout|commit-msg)$ ]] then echo "Unknown hook '${HOOK}'." exit 1 @@ -41,5 +41,10 @@ then esac fi -just "$HOOK" - +# Execute the appropriate just recipe based on the hook name. +if [ "$HOOK" = "commit-msg" ] +then + just "$HOOK" "$1" +else + just "$HOOK" +fi diff --git a/scripts/just/commit-msg.sh b/scripts/just/commit-msg.sh new file mode 100755 index 00000000..004e459c --- /dev/null +++ b/scripts/just/commit-msg.sh @@ -0,0 +1,16 @@ +#! /usr/bin/env bash +set -euo pipefail + +FILE=$1 + +while ! typos "$FILE"; do \ + exec < /dev/tty; \ + echo ""; \ + printf "%sTypos found.%s (e)dit, (c)ontinue, or (a)bort? [E/c/a] " "${WARN}" "${NORMAL}"; \ + read -r response; \ + case "$response" in \ + [cC]*) exit 0 ;; \ + [aA]*) exit 1 ;; \ + *) ${EDITOR:-nano} "$FILE" ;; \ + esac; \ +done