mirror of
https://github.com/tw93/Mole.git
synced 2026-03-22 15:00:07 +00:00
.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`.
97 lines
2.6 KiB
Bash
Executable File
97 lines
2.6 KiB
Bash
Executable File
#!/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 ""
|