Skip to content

Commit 39617e4

Browse files
authored
feat: rename exclude-autogenerated-strict to exclude-generated-strict (#4514)
1 parent d239c9b commit 39617e4

File tree

6 files changed

+182
-27
lines changed

6 files changed

+182
-27
lines changed

.golangci.next.reference.yml

+9-3
Original file line numberDiff line numberDiff line change
@@ -2814,11 +2814,17 @@ issues:
28142814
# Default: false
28152815
exclude-case-sensitive: false
28162816

2817-
# To follow strict Go autogenerated file convention.
2817+
# To follow strictly the Go generated file convention.
2818+
#
2819+
# If set to true, source files that have lines matching only the following regular expression will be excluded:
2820+
# `^// Code generated .* DO NOT EDIT\.$`
2821+
# This line must appear before the first non-comment, non-blank text in the file.
28182822
# https://go.dev/s/generatedcode
2819-
# By default a lax pattern is applied.
2823+
#
2824+
# By default, a lax pattern is applied:
2825+
# sources are excluded if they contain lines `autogenerated file`, `code generated`, `do not edit`, etc.
28202826
# Default: false
2821-
exclude-autogenerated-strict: true
2827+
exclude-generated-strict: true
28222828

28232829
# The list of ids of default excludes to include or disable.
28242830
# https://golangci-lint.run/usage/false-positives/#default-exclusions

jsonschema/golangci.next.jsonschema.json

+2-2
Original file line numberDiff line numberDiff line change
@@ -3342,8 +3342,8 @@
33423342
"type": "boolean",
33433343
"default": false
33443344
},
3345-
"exclude-autogenerated-strict": {
3346-
"description": "To follow strict Go autogenerated file convention",
3345+
"exclude-generated-strict": {
3346+
"description": "To follow strict Go generated file convention",
33473347
"type": "boolean",
33483348
"default": false
33493349
},

pkg/config/issues.go

+6-6
Original file line numberDiff line numberDiff line change
@@ -105,12 +105,12 @@ var DefaultExcludePatterns = []ExcludePattern{
105105
}
106106

107107
type Issues struct {
108-
IncludeDefaultExcludes []string `mapstructure:"include"`
109-
ExcludeCaseSensitive bool `mapstructure:"exclude-case-sensitive"`
110-
ExcludePatterns []string `mapstructure:"exclude"`
111-
ExcludeRules []ExcludeRule `mapstructure:"exclude-rules"`
112-
ExcludeAutogeneratedStrict bool `mapstructure:"exclude-autogenerated-strict"`
113-
UseDefaultExcludes bool `mapstructure:"exclude-use-default"`
108+
IncludeDefaultExcludes []string `mapstructure:"include"`
109+
ExcludeCaseSensitive bool `mapstructure:"exclude-case-sensitive"`
110+
ExcludePatterns []string `mapstructure:"exclude"`
111+
ExcludeRules []ExcludeRule `mapstructure:"exclude-rules"`
112+
ExcludeGeneratedStrict bool `mapstructure:"exclude-generated-strict"`
113+
UseDefaultExcludes bool `mapstructure:"exclude-use-default"`
114114

115115
MaxIssuesPerLinter int `mapstructure:"max-issues-per-linter"`
116116
MaxSameIssues int `mapstructure:"max-same-issues"`

pkg/lint/runner.go

+1-1
Original file line numberDiff line numberDiff line change
@@ -72,7 +72,7 @@ func NewRunner(log logutils.Log, cfg *config.Config, goenv *goutil.Env,
7272
skipFilesProcessor,
7373
skipDirsProcessor, // must be after path prettifier
7474

75-
processors.NewAutogeneratedExclude(cfg.Issues.ExcludeAutogeneratedStrict),
75+
processors.NewAutogeneratedExclude(cfg.Issues.ExcludeGeneratedStrict),
7676

7777
// Must be before exclude because users see already marked output and configure excluding by it.
7878
processors.NewIdentifierMarker(),

pkg/result/processors/autogenerated_exclude.go

+13-9
Original file line numberDiff line numberDiff line change
@@ -63,6 +63,10 @@ func (p *AutogeneratedExclude) shouldPassIssue(issue *result.Issue) (bool, error
6363
return true, nil
6464
}
6565

66+
if issue.FilePath() == "" {
67+
return false, errors.New("no file path for issue")
68+
}
69+
6670
if !isGoFile(issue.FilePath()) {
6771
return false, nil
6872
}
@@ -76,20 +80,16 @@ func (p *AutogeneratedExclude) shouldPassIssue(issue *result.Issue) (bool, error
7680
fs = &fileSummary{}
7781
p.fileSummaryCache[issue.FilePath()] = fs
7882

79-
if issue.FilePath() == "" {
80-
return false, errors.New("no file path for issue")
81-
}
82-
8383
if p.strict {
8484
var err error
8585
fs.generated, err = p.isGeneratedFileStrict(issue.FilePath())
8686
if err != nil {
87-
return false, fmt.Errorf("failed to get doc of file %s: %w", issue.FilePath(), err)
87+
return false, fmt.Errorf("failed to get doc (strict) of file %s: %w", issue.FilePath(), err)
8888
}
8989
} else {
9090
doc, err := getComments(issue.FilePath())
9191
if err != nil {
92-
return false, fmt.Errorf("failed to get doc of file %s: %w", issue.FilePath(), err)
92+
return false, fmt.Errorf("failed to get doc (lax) of file %s: %w", issue.FilePath(), err)
9393
}
9494

9595
fs.generated = p.isGeneratedFileLax(doc)
@@ -102,7 +102,7 @@ func (p *AutogeneratedExclude) shouldPassIssue(issue *result.Issue) (bool, error
102102
}
103103

104104
// isGeneratedFileLax reports whether the source file is generated code.
105-
// Using a bit laxer rules than https://go.dev/s/generatedcode to match more generated code.
105+
// The function uses a bit laxer rules than isGeneratedFileStrict to match more generated code.
106106
// See https://github.com/golangci/golangci-lint/issues/48 and https://github.com/golangci/golangci-lint/issues/72.
107107
func (p *AutogeneratedExclude) isGeneratedFileLax(doc string) bool {
108108
markers := []string{genCodeGenerated, genDoNotEdit, genAutoFile}
@@ -122,8 +122,12 @@ func (p *AutogeneratedExclude) isGeneratedFileLax(doc string) bool {
122122
return false
123123
}
124124

125-
// Based on https://go.dev/s/generatedcode
126-
// > This line must appear before the first non-comment, non-blank text in the file.
125+
// isGeneratedFileStrict returns true if the source file has a line that matches the regular expression:
126+
//
127+
// ^// Code generated .* DO NOT EDIT\.$
128+
//
129+
// This line must appear before the first non-comment, non-blank text in the file.
130+
// Based on https://go.dev/s/generatedcode.
127131
func (p *AutogeneratedExclude) isGeneratedFileStrict(filePath string) (bool, error) {
128132
file, err := parser.ParseFile(token.NewFileSet(), filePath, nil, parser.PackageClauseOnly|parser.ParseComments)
129133
if err != nil {

pkg/result/processors/autogenerated_exclude_test.go

+151-6
Original file line numberDiff line numberDiff line change
@@ -1,11 +1,16 @@
11
package processors
22

33
import (
4+
"fmt"
5+
"go/token"
46
"path/filepath"
7+
"runtime"
58
"testing"
69

710
"github.com/stretchr/testify/assert"
811
"github.com/stretchr/testify/require"
12+
13+
"github.com/golangci/golangci-lint/pkg/result"
914
)
1015

1116
func TestAutogeneratedExclude_isGeneratedFileLax_generated(t *testing.T) {
@@ -79,12 +84,12 @@ func TestAutogeneratedExclude_isGeneratedFileStrict(t *testing.T) {
7984
}{
8085
{
8186
desc: "",
82-
filepath: filepath.FromSlash("./testdata/autogen_go_strict.go"),
87+
filepath: filepath.FromSlash("testdata/autogen_go_strict.go"),
8388
assert: assert.True,
8489
},
8590
{
8691
desc: "",
87-
filepath: filepath.FromSlash("./testdata/autogen_go_strict_invalid.go"),
92+
filepath: filepath.FromSlash("testdata/autogen_go_strict_invalid.go"),
8893
assert: assert.False,
8994
},
9095
}
@@ -108,19 +113,19 @@ func Test_getComments(t *testing.T) {
108113
doc string
109114
}{
110115
{
111-
fpath: filepath.Join("testdata", "autogen_exclude.go"),
116+
fpath: filepath.FromSlash("testdata/autogen_exclude.go"),
112117
doc: `first line
113118
second line
114119
third line
115120
this text also
116121
and this text also`,
117122
},
118123
{
119-
fpath: filepath.Join("testdata", "autogen_exclude_doc.go"),
124+
fpath: filepath.FromSlash("testdata/autogen_exclude_doc.go"),
120125
doc: `DO NOT EDIT`,
121126
},
122127
{
123-
fpath: filepath.Join("testdata", "autogen_exclude_block_comment.go"),
128+
fpath: filepath.FromSlash("testdata/autogen_exclude_block_comment.go"),
124129
doc: `* first line
125130
*
126131
* second line
@@ -141,7 +146,147 @@ this one line comment also`,
141146
// Issue 954: Some lines can be very long, e.g. auto-generated
142147
// embedded resources. Reported on file of 86.2KB.
143148
func Test_getComments_fileWithLongLine(t *testing.T) {
144-
fpath := filepath.Join("testdata", "autogen_exclude_long_line.go")
149+
fpath := filepath.FromSlash("testdata/autogen_exclude_long_line.go")
145150
_, err := getComments(fpath)
146151
assert.NoError(t, err)
147152
}
153+
154+
func Test_shouldPassIssue(t *testing.T) {
155+
testCases := []struct {
156+
desc string
157+
strict bool
158+
issue *result.Issue
159+
assert assert.BoolAssertionFunc
160+
}{
161+
{
162+
desc: "typecheck issue",
163+
strict: false,
164+
issue: &result.Issue{
165+
FromLinter: "typecheck",
166+
},
167+
assert: assert.True,
168+
},
169+
{
170+
desc: "go.mod",
171+
strict: false,
172+
issue: &result.Issue{
173+
FromLinter: "example",
174+
Pos: token.Position{
175+
Filename: filepath.FromSlash("/a/b/c/go.mod"),
176+
},
177+
},
178+
assert: assert.True,
179+
},
180+
{
181+
desc: "non Go file",
182+
strict: false,
183+
issue: &result.Issue{
184+
FromLinter: "example",
185+
Pos: token.Position{
186+
Filename: filepath.FromSlash("/a/b/c/test.txt"),
187+
},
188+
},
189+
assert: assert.False,
190+
},
191+
{
192+
desc: "lax ",
193+
strict: false,
194+
issue: &result.Issue{
195+
FromLinter: "example",
196+
Pos: token.Position{
197+
Filename: filepath.FromSlash("testdata/autogen_go_strict_invalid.go"),
198+
},
199+
},
200+
assert: assert.False,
201+
},
202+
{
203+
desc: "strict ",
204+
strict: true,
205+
issue: &result.Issue{
206+
FromLinter: "example",
207+
Pos: token.Position{
208+
Filename: filepath.FromSlash("testdata/autogen_go_strict_invalid.go"),
209+
},
210+
},
211+
assert: assert.True,
212+
},
213+
}
214+
215+
for _, test := range testCases {
216+
test := test
217+
t.Run(test.desc, func(t *testing.T) {
218+
t.Parallel()
219+
220+
p := NewAutogeneratedExclude(test.strict)
221+
222+
pass, err := p.shouldPassIssue(test.issue)
223+
require.NoError(t, err)
224+
225+
test.assert(t, pass)
226+
})
227+
}
228+
}
229+
230+
func Test_shouldPassIssue_error(t *testing.T) {
231+
notFoundMsg := "no such file or directory"
232+
if runtime.GOOS == "windows" {
233+
notFoundMsg = "The system cannot find the file specified."
234+
}
235+
236+
testCases := []struct {
237+
desc string
238+
strict bool
239+
issue *result.Issue
240+
expected string
241+
}{
242+
{
243+
desc: "missing Filename",
244+
strict: false,
245+
issue: &result.Issue{
246+
FromLinter: "example",
247+
Pos: token.Position{
248+
Filename: "",
249+
},
250+
},
251+
expected: "no file path for issue",
252+
},
253+
{
254+
desc: "non-existing file (lax)",
255+
strict: false,
256+
issue: &result.Issue{
257+
FromLinter: "example",
258+
Pos: token.Position{
259+
Filename: filepath.FromSlash("no-existing.go"),
260+
},
261+
},
262+
expected: fmt.Sprintf("failed to get doc (lax) of file %[1]s: failed to parse file: open %[1]s: %[2]s",
263+
filepath.FromSlash("no-existing.go"), notFoundMsg),
264+
},
265+
{
266+
desc: "non-existing file (strict)",
267+
strict: true,
268+
issue: &result.Issue{
269+
FromLinter: "example",
270+
Pos: token.Position{
271+
Filename: filepath.FromSlash("no-existing.go"),
272+
},
273+
},
274+
expected: fmt.Sprintf("failed to get doc (strict) of file %[1]s: failed to parse file: open %[1]s: %[2]s",
275+
filepath.FromSlash("no-existing.go"), notFoundMsg),
276+
},
277+
}
278+
279+
for _, test := range testCases {
280+
test := test
281+
t.Run(test.desc, func(t *testing.T) {
282+
t.Parallel()
283+
284+
p := NewAutogeneratedExclude(test.strict)
285+
286+
pass, err := p.shouldPassIssue(test.issue)
287+
288+
assert.EqualError(t, err, test.expected)
289+
assert.False(t, pass)
290+
})
291+
}
292+
}

0 commit comments

Comments
 (0)