PostToolUse hook auto-formats files after Edit/Write/MultiEdit with git-blob checkpoints for safe revert. Pre-commit hook for staged files. Canonical formatter scripts for py, sh, ts, sql, json (+ symlinks for js, yaml, md). Install and setup scripts for project opt-in. Includes best-practices/linting.md, HOOKS.md docs, README.md, and session log. Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
55 lines
1.4 KiB
Bash
Executable File
55 lines
1.4 KiB
Bash
Executable File
#!/usr/bin/env bash
|
|
# Git pre-commit hook: format and lint staged files using project formatters.
|
|
# Reuses the same formatter scripts from formatters/.
|
|
# Exits non-zero if lint errors remain after auto-fix (blocks commit).
|
|
|
|
# Find formatters/ directory relative to repo root
|
|
REPO_ROOT="$(git rev-parse --show-toplevel 2>/dev/null)"
|
|
[ -z "$REPO_ROOT" ] && exit 0
|
|
|
|
FORMATTERS_DIR="$REPO_ROOT/formatters"
|
|
[ -d "$FORMATTERS_DIR" ] || exit 0
|
|
|
|
HAD_ERRORS=0
|
|
ERROR_OUTPUT=""
|
|
|
|
# Iterate staged files (only Added/Modified, not Deleted)
|
|
while IFS= read -r FILE; do
|
|
[ -z "$FILE" ] && continue
|
|
|
|
ABS_FILE="$REPO_ROOT/$FILE"
|
|
[ -f "$ABS_FILE" ] || continue
|
|
|
|
# Extract extension (normalise yml → yaml)
|
|
EXT="${FILE##*.}"
|
|
case "$EXT" in
|
|
yml) EXT="yaml" ;;
|
|
esac
|
|
[ -z "$EXT" ] || [ "$EXT" = "$FILE" ] && continue
|
|
|
|
# Check for formatter
|
|
FORMATTER="$FORMATTERS_DIR/$EXT"
|
|
[ -x "$FORMATTER" ] || continue
|
|
|
|
# Run formatter
|
|
ERRORS=$("$FORMATTER" "$ABS_FILE" 2>&1)
|
|
EXIT_CODE=$?
|
|
|
|
# Re-stage the file (formatter may have modified it)
|
|
git add "$ABS_FILE"
|
|
|
|
if [ $EXIT_CODE -ne 0 ]; then
|
|
HAD_ERRORS=1
|
|
ERROR_OUTPUT="${ERROR_OUTPUT}${FILE}:\n${ERRORS}\n\n"
|
|
fi
|
|
done < <(git diff --cached --name-only --diff-filter=AM)
|
|
|
|
if [ $HAD_ERRORS -ne 0 ]; then
|
|
echo "Pre-commit lint errors — commit blocked:" >&2
|
|
echo -e "$ERROR_OUTPUT" >&2
|
|
echo "Fix the errors above and try again." >&2
|
|
exit 1
|
|
fi
|
|
|
|
exit 0
|