mirror of
https://github.com/tw93/Mole.git
synced 2026-03-22 20:15:07 +00:00
chore: add pre-commit hook and update review skill to mirror GitHub CI
.githooks/pre-commit runs bash syntax check, shfmt format check, shellcheck, and go vet against staged files on every commit. Catches the same issues as check.yml before they reach GitHub. Also update CONTRIBUTING.md setup instructions to include `git config core.hooksPath .githooks`.
This commit is contained in:
96
.githooks/pre-commit
Executable file
96
.githooks/pre-commit
Executable file
@@ -0,0 +1,96 @@
|
||||
#!/usr/bin/env bash
|
||||
# Pre-commit hook: mirrors GitHub CI checks locally.
|
||||
# Installed via: git config core.hooksPath .githooks
|
||||
#
|
||||
# Runs on every `git commit`. Catches format/lint/test failures before push.
|
||||
|
||||
set -euo pipefail
|
||||
|
||||
REPO_ROOT="$(git rev-parse --show-toplevel)"
|
||||
cd "$REPO_ROOT"
|
||||
|
||||
RED='\033[0;31m'
|
||||
GREEN='\033[0;32m'
|
||||
YELLOW='\033[1;33m'
|
||||
NC='\033[0m'
|
||||
|
||||
_ok() { echo -e "${GREEN}✓${NC} $1"; }
|
||||
_fail() { echo -e "${RED}✗${NC} $1"; }
|
||||
_info() { echo -e "${YELLOW}→${NC} $1"; }
|
||||
|
||||
echo ""
|
||||
_info "Running pre-commit checks (mirrors GitHub CI)..."
|
||||
echo ""
|
||||
|
||||
# Only check staged shell/Go files to keep commits fast.
|
||||
STAGED=$(git diff --cached --name-only --diff-filter=ACM)
|
||||
HAS_SHELL=$(echo "$STAGED" | grep -E '\.sh$|^mole$|^bin/' || true)
|
||||
HAS_GO=$(echo "$STAGED" | grep -E '\.go$' || true)
|
||||
|
||||
FAILED=0
|
||||
|
||||
# --- 1. Shell syntax check (fast, no tool required) ---
|
||||
if [[ -n "$HAS_SHELL" ]]; then
|
||||
_info "Shell syntax check..."
|
||||
while IFS= read -r f; do
|
||||
[[ -f "$f" ]] || continue
|
||||
if ! bash -n "$f" 2>&1; then
|
||||
_fail "Syntax error: $f"
|
||||
FAILED=1
|
||||
fi
|
||||
done <<< "$HAS_SHELL"
|
||||
[[ $FAILED -eq 0 ]] && _ok "Shell syntax clean"
|
||||
fi
|
||||
|
||||
# --- 2. shfmt format check (if installed) ---
|
||||
if [[ -n "$HAS_SHELL" ]] && command -v shfmt > /dev/null 2>&1; then
|
||||
_info "shfmt format check..."
|
||||
UNFORMATTED=""
|
||||
while IFS= read -r f; do
|
||||
[[ -f "$f" ]] || continue
|
||||
if ! shfmt -i 4 -ci -sr -d "$f" > /dev/null 2>&1; then
|
||||
UNFORMATTED="$UNFORMATTED $f"
|
||||
fi
|
||||
done <<< "$HAS_SHELL"
|
||||
if [[ -n "$UNFORMATTED" ]]; then
|
||||
_fail "shfmt: unformatted files:$UNFORMATTED"
|
||||
_info "Fix with: ./scripts/check.sh --format"
|
||||
FAILED=1
|
||||
else
|
||||
_ok "shfmt format clean"
|
||||
fi
|
||||
fi
|
||||
|
||||
# --- 3. shellcheck (if installed) ---
|
||||
if [[ -n "$HAS_SHELL" ]] && command -v shellcheck > /dev/null 2>&1; then
|
||||
_info "shellcheck..."
|
||||
while IFS= read -r f; do
|
||||
[[ -f "$f" ]] || continue
|
||||
if ! shellcheck "$f" 2>&1; then
|
||||
FAILED=1
|
||||
fi
|
||||
done <<< "$HAS_SHELL"
|
||||
[[ $FAILED -eq 0 ]] && _ok "shellcheck clean"
|
||||
fi
|
||||
|
||||
# --- 4. Go vet (if staged Go files) ---
|
||||
if [[ -n "$HAS_GO" ]] && command -v go > /dev/null 2>&1; then
|
||||
_info "go vet..."
|
||||
if go vet ./cmd/... 2>&1; then
|
||||
_ok "go vet clean"
|
||||
else
|
||||
_fail "go vet failed"
|
||||
FAILED=1
|
||||
fi
|
||||
fi
|
||||
|
||||
echo ""
|
||||
if [[ $FAILED -ne 0 ]]; then
|
||||
_fail "Pre-commit checks failed. Fix the issues above before committing."
|
||||
_info "Run './scripts/check.sh --format' to auto-fix formatting."
|
||||
echo ""
|
||||
exit 1
|
||||
fi
|
||||
|
||||
_ok "All pre-commit checks passed."
|
||||
echo ""
|
||||
Reference in New Issue
Block a user