← back to Dw Pitch Followup
.githooks/pre-commit
26 lines
#!/bin/sh
# pre-commit: lint every staged launchd/*.plist so a malformed plist (bad
# schedule, mismatched tags) can never ship silently again. Born 2026-08-06
# after a broken dw-pitch-rebuild.plist (opened <array>, closed </dict>) failed
# to parse, never installed, and froze the pitch board for a week.
#
# Lints the STAGED blob (via git show :file), not the working tree, so a fixed
# working copy can't mask a broken thing you're actually committing.
fail=0
for f in $(git diff --cached --name-only --diff-filter=ACM -- launchd/); do
case "$f" in *.plist) ;; *) continue ;; esac
tmp=$(mktemp)
git show ":$f" > "$tmp" 2>/dev/null
if ! plutil -lint "$tmp" >/dev/null 2>&1; then
echo "pre-commit ✗ invalid plist: $f"
plutil -lint "$tmp" 2>&1 | sed "s|$tmp|$f|"
fail=1
fi
rm -f "$tmp"
done
if [ "$fail" -ne 0 ]; then
echo "commit blocked — fix the malformed plist(s) above (macOS: plutil -lint <file>)."
exit 1
fi
exit 0