A pedagogical Go-idiom linter. Rules beyond gopls and golangci-lint, aimed at the layer of feedback you want when learning Go: "this compiles, but it isn't how Go is usually written." Part of the CivNode Training semantic engine.
Apache-2.0 licensed. No runtime dependencies outside golang.org/x/tools/go/analysis.
Library:
go get github.com/CivNode/go-idiomatic@latest
Standalone linter:
go install github.com/CivNode/go-idiomatic/cmd/go-idiomatic@latest
go-idiomatic ./...
import goidiomatic "github.com/CivNode/go-idiomatic"
score, findings, err := goidiomatic.Score(src, goidiomatic.DefaultRules())Score returns an integer on [0, 100] plus every finding. The score starts at 100 and deducts per severity: 15 for Error, 7 for Warn, 2 for Info, floored at 0.
| ID | Severity | What it catches |
|---|---|---|
prefer-range-int |
info | for i := 0; i < len(xs); i++ where for i := range xs would do |
errors-is-as |
warn | err.Error() == "..." or err == someErr; use errors.Is / errors.As |
any-over-empty-interface |
info | interface{} on a Go 1.18+ target; suggests any |
context-first-arg |
warn | functions where context.Context is not the first argument |
no-sleep-for-coordination |
error | time.Sleep inside a function that also uses channels or context.Context |
Each rule ships with golden fixtures under rules/testdata/src/<fixture>/.
- Drop a new file in
rules/, implementing theRuleinterface. - Add it to
rules.All. - Add
testdata/src/<name>_ok/ok.goandtestdata/src/<name>_bad/bad.gofixtures, using// want ...comments on lines that must flag. - Write a test with
analysistest.Runplus a few in-memoryrules.Rununit tests for the edge cases. make lint testmust stay clean.
v0.1.0 ships the five rules above with >= 85% coverage on the rules package. Future tiers extend the ruleset and add fixers.