Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
5 changes: 5 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,11 @@ constable ./...

constable skips files that carry the standard generated-code comment, `// Code generated ... DO NOT EDIT.`.
A diagnostic in such a file is not actionable because the next run of the generator overwrites the file.
Set `-include-generated` to report in them anyway,

```sh
constable -include-generated ./...
```

## Example

Expand Down
38 changes: 38 additions & 0 deletions cmd/constable/main_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -400,6 +400,44 @@ func TestCLIEmbeddedAnalyzersSkipGeneratedFiles(t *testing.T) {
assert.Empty(t, output)
}

func TestCLIIncludeGenerated(t *testing.T) {
binary := buildBinary(t)
moduleDir := writeModule(t, module{
GoMod: []string{
"module example.com/generated",
"",
"go 1.26",
},
Files: map[string][]string{"gen.go": {
"// Code generated by hand. DO NOT EDIT.",
"",
"package generated",
"",
"import \"os\"",
"",
"func F() {",
"\tos.Remove(\"x\")",
"}",
"",
"//constable:nonmutating",
"func G(p *int) {",
"\t*p = 1",
"}",
}},
})

output, err := runConstable(t, binary, moduleDir)
require.NoError(t, err, output)
assert.Empty(t, output)

// One flag turns the skip off for the analyzers that constable owns and for
// the analyzers that it embeds.
output, err = runConstable(t, binary, moduleDir, "-include-generated")
require.Error(t, err, output)
assert.Contains(t, output, "unchecked error")
assert.Contains(t, output, "//constable:nonmutating function mutates pointer parameter p")
}

func buildBinary(t *testing.T) string {
t.Helper()

Expand Down
5 changes: 5 additions & 0 deletions internal/driver/driver.go
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,8 @@ import (
"golang.org/x/tools/go/analysis/checker"
"golang.org/x/tools/go/analysis/unitchecker"
"golang.org/x/tools/go/packages"

"github.com/nnutter/constable/internal/generated"
)

// Options controls driver output.
Expand Down Expand Up @@ -152,9 +154,12 @@ func Main(version string, hooks Hooks, analyzers ...*analysis.Analyzer) {
flag.BoolVar(&opts.Fix, "fix", false, "apply all suggested fixes")
flag.BoolVar(&opts.Diff, "diff", false, "with -fix, don't update the files, but print a unified diff")
flag.BoolVar(&opts.IncludeTests, "test", true, "indicates whether test files should be analyzed, too")
includeGenerated := flag.Bool("include-generated", false, "report in generated files, which constable skips by default")

flag.Parse()

generated.Include(*includeGenerated)

if *printFlags {
writeFlagsJSON()
return
Expand Down
16 changes: 14 additions & 2 deletions internal/generated/generated.go
Original file line number Diff line number Diff line change
Expand Up @@ -4,12 +4,24 @@ package generated

import "go/ast"

// include reports whether analyzers report in generated files.
var include bool

// Include makes analyzers report in generated files when enabled is true.
//
// The driver sets it from -include-generated, so every analyzer follows one
// answer without carrying a flag of its own.
func Include(enabled bool) {
include = enabled
}

// Skipped reports whether analyzers omit the diagnostics of file.
//
// A diagnostic in a generated file is not actionable because the next run of
// the generating tool overwrites the file. The mark is the Go convention,
// "// Code generated <tool> DO NOT EDIT.", so an author controls it with the
// comment alone.
// comment alone. Include overrides the rule for a run that wants every
// diagnostic.
func Skipped(file *ast.File) bool {
return ast.IsGenerated(file)
return !include && ast.IsGenerated(file)
}
7 changes: 7 additions & 0 deletions internal/generated/skip_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -32,3 +32,10 @@ var reportFuncs = &analysis.Analyzer{
func TestSkip(t *testing.T) {
analysistest.Run(t, analysistest.TestData(), generated.Skip(reportFuncs), "g")
}

func TestSkipWithInclude(t *testing.T) {
generated.Include(true)
t.Cleanup(func() { generated.Include(false) })

analysistest.Run(t, analysistest.TestData(), generated.Skip(reportFuncs), "h")
}
3 changes: 3 additions & 0 deletions internal/generated/testdata/src/h/h.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
package h

func Gen() {} // want `func Gen`
5 changes: 5 additions & 0 deletions internal/generated/testdata/src/h/zz_generated.go

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

Loading