You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
Daily Go-dependency deep-dive. This module is the foundation of gh-aw's custom linter framework under pkg/linters/ β and is currently the most-recently-pushed direct dependency in go.mod (pushed_at 2026-05-19T17:00:38Z, version v0.45.0). The review surfaces a few small inconsistencies in the analyzer suite, a brand-new published modernize package that could clean up the codebase in one pass, and several opportunities to emit SuggestedFixes so gopls and go vet -fix can apply fixes automatically.
Then run grabs pass.ResultOf[inspect.Analyzer].(*inspector.Inspector) and uses insp.Preorder(nodeFilter, ...). Test files use analysistest.Run(t, analysistest.TestData(), Analyzer, "a") against testdata packages.
Analyzer roster
Analyzer
What it flags
ctxbackground
context.Background() inside funcs that already receive a ctx context.Context
go/analysis/passes/modernize β a brand-new published suite of 25+ analyzers (commit cd58e99, 2026-05-05) that mechanically modernize older Go code with safe, auto-appliable SuggestedFixes: slices.Concat, slices.Clone, min/max, for i := range N, typed atomic.Int32, strings.Cut/CutPrefix, omitzero, errors.As type-param form, and more. Distributed as a CLI: go run golang.org/x/tools/go/analysis/passes/modernize/cmd/modernize@latest -fix ./....
inspector.Cursor API (2025-12 β 2026-01) β Cursor.Valid, Cursor.ParentEdge{Kind,Index}, FindByPos improvements. Lets analyzers cheaply ask "what AST edge connects me to my parent?" without manually maintaining a stack.
Best practices observed in the maintainers' own analyzers
One shared inspector.Inspector per driver via inspect.Analyzer β already followed everywhere except ssljson.
Filter at the []ast.Node level β already followed.
Emit SuggestedFixes whenever the fix is mechanical β not followed by any gh-aw analyzer.
Use pass.ReportRangef(node, ...) for range diagnostics β not followed; everyone uses Reportf(node.Pos(), ...).
URL: field pointing to rule docs β followed (idiomatic).
Improvement Opportunities
π Quick Wins
Fix ctxbackground body walk (pkg/linters/ctxbackground/ctxbackground.go:43) β it requires inspect.Analyzer but then uses raw ast.Inspect(fn.Body, ...). Use insp.WithStack([]ast.Node{(*ast.CallExpr)(nil)}, ...) and check the enclosing *ast.FuncDecl from the stack β one traversal instead of two.
Add _test.go filtering to ctxbackground β every other analyzer skips test files; ctxbackground does not. Likely an oversight: test helpers commonly accept ctx context.Context and also legitimately call context.Background() for goroutines that outlive the test.
Lift the duplicated _test.go check into pkg/linters/internal/ β strings.HasSuffix(filename, "_test.go") appears in 5 different analyzers. One helper, one consistent rule.
Swap pass.Reportf(node.Pos(), ...) for pass.ReportRangef(node, ...) in largefunc, excessivefuncparams, errormessage, errstringmatch, ctxbackground, osexitinlibrary, rawloginlib β editors and gopls get a precise underlined range instead of a single-character marker.
β¨ Feature Opportunities
Emit SuggestedFix from ctxbackground β the fix is mechanical: replace context.Background() with the in-scope ctx parameter name. gopls can then auto-apply it.
Emit SuggestedFix from errstringmatch for common sentinels β strings.Contains(err.Error(), "context canceled") β errors.Is(err, context.Canceled). Same shape for context.DeadlineExceeded, io.EOF, os.ErrNotExist, fs.ErrNotExist.
Run modernize once β go run golang.org/x/tools/go/analysis/passes/modernize/cmd/modernize@latest -fix ./.... One-shot cleanup, not a CI gate.
Adopt the inspector.Cursor API in errormessage for cheap ancestor lookups ("am I inside a return statement?").
π Best Practice Alignment
Reconsider the ssljson "anchor package" trick (pkg/linters/ssljson/ssljson.go:207) β it's a workaround for multichecker running each analyzer once per package. ssljson is fundamentally a file-system validator, not a Go-source analyzer, so a separate cmd/ssljson binary using singlechecker.Main (or a stand-alone go test) is a cleaner long-term shape. At minimum, document the anchor-package trick in the Doc: field.
Cache the error interface lookup in internal/nolint.ImplementsError (pkg/linters/internal/nolint/nolint.go:60) β types.Universe.Lookup("error") runs on every call. sync.Once-initialized package var is trivially correct.
π§ General Improvements
Add direct unit tests for pkg/linters/internal/nolint β currently only exercised indirectly via the analyzer end-to-end tests.
Add a CI smoke test that runs the linters binary in vet-mode β confirms the multichecker.Main binding builds and at least one analyzer fires.
Recommendations (prioritized)
ctxbackground fix-ups β body-walk consolidation + _test.go skip + SuggestedFix. Single PR, small diff, immediate correctness/UX improvement.
Run modernize -fix once β separate PR, mechanical, easy to review.
errstringmatch sentinel SuggestedFixes β meaningful gopls UX upgrade, scoped to the well-known sentinels.
Lift _test.go and pkg/ skip helpers into internal/ β DRY cleanup; pairs naturally with rejig docsΒ #1.
Swap to ReportRangef β drive-by polish, can ride any of the above PRs.
Reshape ssljson (longer-term) β orthogonal to go/analysis; tackle when the SSL rules grow.
πΉ Go Fan Report:
golang.org/x/toolsDaily Go-dependency deep-dive. This module is the foundation of gh-aw's custom linter framework under
pkg/linters/β and is currently the most-recently-pushed direct dependency ingo.mod(pushed_at2026-05-19T17:00:38Z, versionv0.45.0). The review surfaces a few small inconsistencies in the analyzer suite, a brand-new publishedmodernizepackage that could clean up the codebase in one pass, and several opportunities to emitSuggestedFixes sogoplsandgo vet -fixcan apply fixes automatically.Summary
go/analysis,go/analysis/analysistest,go/analysis/multichecker,go/analysis/passes/inspect,go/ast/inspectorcmd/linters/main.go: 8Current Usage in gh-aw
Every custom linter in
pkg/linters/is built ongolang.org/x/tools/go/analysis. The shape is consistent across 7 of 8 analyzers:Then
rungrabspass.ResultOf[inspect.Analyzer].(*inspector.Inspector)and usesinsp.Preorder(nodeFilter, ...). Test files useanalysistest.Run(t, analysistest.TestData(), Analyzer, "a")against testdata packages.Analyzer roster
ctxbackgroundcontext.Background()inside funcs that already receive actx context.Contexterrormessageerrstringmatchstrings.Contains(err.Error(), "...")substring matchingexcessivefuncparamslargefuncosexitinlibraryos.Exitinsidepkg/rawloginliblog.*insidepkg/ssljson.github/skills/*/ssl.jsonResearch Findings
Recent upstream activity
go/analysis/passes/modernizeβ a brand-new published suite of 25+ analyzers (commitcd58e99, 2026-05-05) that mechanically modernize older Go code with safe, auto-appliableSuggestedFixes:slices.Concat,slices.Clone,min/max,for i := range N, typedatomic.Int32,strings.Cut/CutPrefix,omitzero,errors.Astype-param form, and more. Distributed as a CLI:go run golang.org/x/tools/go/analysis/passes/modernize/cmd/modernize@latest -fix ./....inspector.CursorAPI (2025-12 β 2026-01) βCursor.Valid,Cursor.ParentEdge{Kind,Index},FindByPosimprovements. Lets analyzers cheaply ask "what AST edge connects me to my parent?" without manually maintaining a stack.Best practices observed in the maintainers' own analyzers
inspector.Inspectorper driver viainspect.Analyzerβ already followed everywhere exceptssljson.[]ast.Nodelevel β already followed.SuggestedFixes whenever the fix is mechanical β not followed by any gh-aw analyzer.pass.ReportRangef(node, ...)for range diagnostics β not followed; everyone usesReportf(node.Pos(), ...).URL:field pointing to rule docs β followed (idiomatic).Improvement Opportunities
π Quick Wins
ctxbackgroundbody walk (pkg/linters/ctxbackground/ctxbackground.go:43) β it requiresinspect.Analyzerbut then uses rawast.Inspect(fn.Body, ...). Useinsp.WithStack([]ast.Node{(*ast.CallExpr)(nil)}, ...)and check the enclosing*ast.FuncDeclfrom the stack β one traversal instead of two._test.gofiltering toctxbackgroundβ every other analyzer skips test files;ctxbackgrounddoes not. Likely an oversight: test helpers commonly acceptctx context.Contextand also legitimately callcontext.Background()for goroutines that outlive the test._test.gocheck intopkg/linters/internal/βstrings.HasSuffix(filename, "_test.go")appears in 5 different analyzers. One helper, one consistent rule.pass.Reportf(node.Pos(), ...)forpass.ReportRangef(node, ...)inlargefunc,excessivefuncparams,errormessage,errstringmatch,ctxbackground,osexitinlibrary,rawloginlibβ editors andgoplsget a precise underlined range instead of a single-character marker.β¨ Feature Opportunities
SuggestedFixfromctxbackgroundβ the fix is mechanical: replacecontext.Background()with the in-scopectxparameter name.goplscan then auto-apply it.SuggestedFixfromerrstringmatchfor common sentinels βstrings.Contains(err.Error(), "context canceled")βerrors.Is(err, context.Canceled). Same shape forcontext.DeadlineExceeded,io.EOF,os.ErrNotExist,fs.ErrNotExist.modernizeonce βgo run golang.org/x/tools/go/analysis/passes/modernize/cmd/modernize@latest -fix ./.... One-shot cleanup, not a CI gate.inspector.CursorAPI inerrormessagefor cheap ancestor lookups ("am I inside a return statement?").π Best Practice Alignment
ssljson"anchor package" trick (pkg/linters/ssljson/ssljson.go:207) β it's a workaround formulticheckerrunning each analyzer once per package.ssljsonis fundamentally a file-system validator, not a Go-source analyzer, so a separatecmd/ssljsonbinary usingsinglechecker.Main(or a stand-alonego test) is a cleaner long-term shape. At minimum, document the anchor-package trick in theDoc:field.errorinterface lookup ininternal/nolint.ImplementsError(pkg/linters/internal/nolint/nolint.go:60) βtypes.Universe.Lookup("error")runs on every call.sync.Once-initialized package var is trivially correct.π§ General Improvements
pkg/linters/internal/nolintβ currently only exercised indirectly via the analyzer end-to-end tests.lintersbinary invet-mode β confirms themultichecker.Mainbinding builds and at least one analyzer fires.Recommendations (prioritized)
ctxbackgroundfix-ups β body-walk consolidation +_test.goskip +SuggestedFix. Single PR, small diff, immediate correctness/UX improvement.modernize -fixonce β separate PR, mechanical, easy to review.errstringmatchsentinelSuggestedFixes β meaningful gopls UX upgrade, scoped to the well-known sentinels._test.goandpkg/skip helpers intointernal/β DRY cleanup; pairs naturally with rejig docsΒ #1.ReportRangefβ drive-by polish, can ride any of the above PRs.ssljson(longer-term) β orthogonal togo/analysis; tackle when the SSL rules grow.Next Steps
scratchpad/mods/golang-x-tools.mdwith the full analysis.References:
Generated by Go Fan πΉ
Module summary:
scratchpad/mods/golang-x-tools.md