chore: catch lint failures before push (misspell + scoped golangci-lint) - #2994
chore: catch lint failures before push (misspell + scoped golangci-lint)#2994momosh-ssv wants to merge 6 commits into
Conversation
Greptile SummaryThe PR adds an opt-in pre-push misspell check, a Make target to install repository hooks, and a pinned Go tool declaration for the standalone linter.
Confidence Score: 4/5The PR appears safe to merge, with non-blocking hook reliability and diagnostic issues worth addressing. The hook can silently omit linting in some remote layouts, mislabel tool failures as spelling findings, and mishandle unusual filenames, but these concerns affect the optional local check rather than production behavior. Files Needing Attention: scripts/git-hooks/pre-push
|
| Filename | Overview |
|---|---|
| scripts/git-hooks/pre-push | Adds the committed-blob misspell hook, with non-blocking robustness issues around base discovery, tool-error classification, and pathname handling. |
| Makefile | Adds a straightforward opt-in target that configures the repository-relative hooks path. |
| tool.mod | Promotes the already-pinned golangci misspell command to a Go tool without changing dependency versions. |
Flowchart
%%{init: {'theme': 'neutral'}}%%
flowchart TD
Push[git push] --> Ref{Existing remote ref?}
Ref -->|Yes| Remote[Use remote SHA as base]
Ref -->|No| Merge[Find merge-base with origin/stage or origin/main]
Merge -->|Neither available| Skip[Silently skip ref]
Remote --> Diff[Collect changed Go and Markdown paths]
Merge --> Diff
Diff --> Blob[Read each blob at local SHA]
Blob --> Tool[Run misspell through go tool]
Tool -->|Any output| Block[Label as misspell issue and block]
Tool -->|No output| Allow[Allow push]
Reviews (1): Last reviewed commit: "chore: add versioned pre-push hook runni..." | Re-trigger Greptile
| base=$(git merge-base "$local_sha" origin/stage 2>/dev/null) || | ||
| base=$(git merge-base "$local_sha" origin/main 2>/dev/null) || continue |
There was a problem hiding this comment.
| out=$(git show "$local_sha:$f" 2>/dev/null | | ||
| GOWORK=off "$GO" tool -modfile="$root/tool.mod" misspell -locale US -error 2>&1) | ||
| if [ -n "$out" ]; then | ||
| echo "pre-push: misspell found issues in $f:" >&2 | ||
| echo "$out" | sed "s|^stdin| $f|" >&2 | ||
| status=1 | ||
| fi |
|
|
||
| # Check the blobs at local_sha, not the working tree, so uncommitted edits | ||
| # don't mask (or fake) findings in what's actually being pushed. | ||
| for f in $files; do |
There was a problem hiding this comment.
Codecov Report✅ All modified and coverable lines are covered by tests. ☔ View full report in Codecov by Harness. 🚀 New features to boost your workflow:
|
Why
Most PRs lately have hit a red
lintcheck that only surfaces in CI, since nothing in the repo installs a local check. Two flavors so far:misspellfindings (.golangci.yaml,locale: US) — usually British spellings in comments (cancelled,behaviour, ...).QF1008(embedded-field selector) in a test helper.What
scripts/git-hooks/pre-pushruns two stages against what a push actually introduces or modifies (diffed against the remote ref, or the merge-base withstage/mainfor new branches):.go/.mdblobs at the pushed commit with the standalonemisspellbinary, and blocks the push with the samefile:line:coloutput CI would produce. It scans the blobs, not the working tree, so uncommitted edits can't mask findings. Plain text scanning — near-instant.golangci-lint(same configmake lintuses in CI, staticcheck included) on just the packages containing changed.gofiles. Type-checking linters need full packages on disk, so this stage lints the checkout and only runs when the pushed ref is the checked-out HEAD; nested modules (ssvsigner/,scripts/differ/) are skipped since CI's root-module run doesn't cover them either. ~1.5s warm on a one-package change, vs CI's ~7-minute full-repo run.Also:
make install-hooks— opt-in, pointscore.hooksPathatscripts/git-hooks(relative, so it resolves per-worktree).tool.mod— promotesgithub.com/golangci/misspell/cmd/misspellto atooldirective, pinned at the v0.7.0 already in the graph via golangci-lint (one-line diff, no version changes;tool.sumuntouched). Using golangci's fork keeps the hook's word list identical to CI's. golangci-lint itself was already atooldirective.git push --no-verifybypasses the whole hook for a one-off.Verified
S1002bool-comparison + unused func fails both stages with CI-identical output (~6s cold-cache, ~1.5s warm); a clean comment-only probe on the same package passes in ~1.5s.make install-hookssets and resolves the hooks path correctly across worktrees.