Skip to content

Commit fa77e54

Browse files
committed
chore: consolidate git hooks into lefthook, perfect the repo
Dual hook systems (.githooks/ + lefthook.yml) consolidated into single canonical lefthook setup: - Remove .githooks/ — functionality merged into lefthook.yml - lefthook.yml pre-commit: add ast-grep scan (moved from .githooks) - lefthook.yml commit-msg: add Co-authored-by stripping (moved from .githooks) - lefthook.yml: soft-skip gofumpt/goimports when missing (was hard-exit) - lefthook.yml: bump pre-push test timeout 60s -> 120s to match 'make test' - Makefile setup: auto-install lefthook and run 'lefthook install' - Makefile hooks target: use 'lefthook install' (was 'git config core.hooksPath') - CONTRIBUTING.md: update co-author guidance to use 'make hooks'
1 parent 3bb7366 commit fa77e54

5 files changed

Lines changed: 35 additions & 20 deletions

File tree

.githooks/pre-commit

Lines changed: 0 additions & 8 deletions
This file was deleted.

.githooks/prepare-commit-msg

Lines changed: 0 additions & 3 deletions
This file was deleted.

CONTRIBUTING.md

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -74,10 +74,11 @@ refactor!: rename ClientV1 to Client (BREAKING CHANGE)
7474
```
7575

7676
**Co-authors:** do not add `Co-authored-by:` trailers. Commits should list
77-
only the human author. Enable the repo hook with:
77+
only the human author. Hooks are auto-installed by `make setup` via
78+
[lefthook](https://github.com/evilmartians/lefthook). To re-install manually:
7879

7980
```bash
80-
git config core.hooksPath .githooks
81+
make hooks
8182
```
8283

8384
## Pull request checklist

Makefile

Lines changed: 7 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -175,8 +175,12 @@ setup: ## Set up local development environment (go.work + external repos).
175175
@command -v $(GOIMPORTS) >/dev/null 2>&1 || go install golang.org/x/tools/cmd/goimports@latest
176176
@command -v $(GOLANGCI) >/dev/null 2>&1 || go install github.com/golangci/golangci-lint/v2/cmd/golangci-lint@latest
177177
@command -v $(GOVULNCHECK) >/dev/null 2>&1 || go install golang.org/x/vuln/cmd/govulncheck@latest
178+
@command -v lefthook >/dev/null 2>&1 || go install github.com/evilmartians/lefthook@latest
178179
@echo "✓ All tools installed"
179180
@echo ""
181+
@echo "=== Installing git hooks ==="
182+
@lefthook install || echo " ⚠ lefthook install failed (run 'make hooks' manually)"
183+
@echo ""
180184
@echo "=== Setup complete! ==="
181185
@echo "Run 'make ci' to verify everything works."
182186

@@ -197,8 +201,9 @@ compat-check: ## Strict validation — non-zero exit if any component lacks a ve
197201
@go run ./cmd/compat-test -matrix=next -strict -file=testdata/compatibility-matrix.json
198202

199203
.PHONY: hooks
200-
hooks:
201-
git config core.hooksPath .githooks
204+
hooks: ## Install git hooks via lefthook (formatting, linting, conventional commits).
205+
@command -v lefthook >/dev/null 2>&1 || (echo "install: go install github.com/evilmartians/lefthook@latest" && exit 1)
206+
lefthook install
202207
# === Cross-platform binary targets (add after existing 'build' target) ===
203208

204209
.PHONY: build-all build-static size-check

lefthook.yml

Lines changed: 25 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,7 @@
66
# go install github.com/evilmartians/lefthook@latest
77
# npm install -g lefthook (cross-platform)
88
#
9-
# Activate hooks in this repo (one time):
9+
# Activate hooks in this repo (one time, done automatically by `make setup`):
1010
# lefthook install
1111
#
1212
# Skip hooks for a single commit (use sparingly):
@@ -23,7 +23,8 @@ pre-commit:
2323
glob: "*.go"
2424
run: |
2525
if ! command -v gofumpt >/dev/null 2>&1; then
26-
echo "lefthook: gofumpt not installed (go install mvdan.cc/gofumpt@latest)"; exit 1
26+
echo "lefthook: gofumpt not installed (go install mvdan.cc/gofumpt@latest) — skipping"
27+
exit 0
2728
fi
2829
gofumpt -w {staged_files}
2930
stage_fixed: true
@@ -32,7 +33,8 @@ pre-commit:
3233
glob: "*.go"
3334
run: |
3435
if ! command -v goimports >/dev/null 2>&1; then
35-
echo "lefthook: goimports not installed (go install golang.org/x/tools/cmd/goimports@latest)"; exit 1
36+
echo "lefthook: goimports not installed (go install golang.org/x/tools/cmd/goimports@latest) — skipping"
37+
exit 0
3638
fi
3739
goimports -w {staged_files}
3840
stage_fixed: true
@@ -47,6 +49,18 @@ pre-commit:
4749
golangci-lint run --new-from-rev=HEAD~1 --fix {staged_files}
4850
stage_fixed: true
4951

52+
ast-grep:
53+
glob: "*.go"
54+
run: |
55+
# Run ast-grep structural code search on staged Go files.
56+
# Falls back gracefully if `sg` (ast-grep) is not installed.
57+
STAGED=$(git diff --cached --name-only --diff-filter=ACMR | grep '\.go$' || true)
58+
if [ -n "$STAGED" ]; then
59+
if command -v sg >/dev/null 2>&1; then
60+
echo "$STAGED" | xargs sg scan 2>&1 | head -20
61+
fi
62+
fi
63+
5064
yaml-lint:
5165
glob: "*.{yml,yaml}"
5266
run: |
@@ -76,7 +90,7 @@ pre-push:
7690
commands:
7791

7892
test:
79-
run: go test ./... -count=1 -timeout=60s
93+
run: go test ./... -count=1 -timeout=120s
8094

8195
vet:
8296
run: go vet ./...
@@ -90,7 +104,7 @@ pre-push:
90104
govulncheck ./...
91105
92106
# ---------------------------------------------------------------------------
93-
# commit-msg — validate Conventional Commits (release-please depends on it).
107+
# commit-msg — validate Conventional Commits and strip AI co-author trailers.
94108
# ---------------------------------------------------------------------------
95109
commit-msg:
96110
commands:
@@ -110,3 +124,9 @@ commit-msg:
110124
echo " full guide: https://www.conventionalcommits.org/"
111125
exit 1
112126
fi
127+
128+
strip-co-authored-by:
129+
run: |
130+
# Strip Co-authored-by: trailers that AI tools (Claude, Cursor, etc.) add.
131+
# This enforces the rule that commits list only the human author.
132+
sed '/^[Cc]o-[Aa]uthored-[Bb]y:/d' "{1}" > "{1}.tmp" && mv "{1}.tmp" "{1}"

0 commit comments

Comments
 (0)