Skip to content

Commit a18c645

Browse files
committed
feat: allow the analysis of generated files
1 parent 0cb1418 commit a18c645

File tree

8 files changed

+61
-39
lines changed

8 files changed

+61
-39
lines changed

.golangci.next.reference.yml

+9-9
Original file line numberDiff line numberDiff line change
@@ -2871,17 +2871,17 @@ issues:
28712871
- ".*\\.my\\.go$"
28722872
- lib/bad.go
28732873

2874-
# To follow strictly the Go generated file convention.
2874+
# Mode of the generated files analysis.
28752875
#
2876-
# If set to true, source files that have lines matching only the following regular expression will be excluded:
2877-
# `^// Code generated .* DO NOT EDIT\.$`
2878-
# This line must appear before the first non-comment, non-blank text in the file.
2879-
# https://go.dev/s/generatedcode
2876+
# - `strict`: sources are excluded by following strictly the Go generated file convention.
2877+
# Source files that have lines matching only the following regular expression will be excluded: `^// Code generated .* DO NOT EDIT\.$`
2878+
# This line must appear before the first non-comment, non-blank text in the file.
2879+
# https://go.dev/s/generatedcode
2880+
# - `lax`: sources are excluded if they contain lines `autogenerated file`, `code generated`, `do not edit`, etc.
2881+
# - `disable`: xxx
28802882
#
2881-
# By default, a lax pattern is applied:
2882-
# sources are excluded if they contain lines `autogenerated file`, `code generated`, `do not edit`, etc.
2883-
# Default: false
2884-
exclude-generated-strict: true
2883+
# Default: lax
2884+
exclude-generated: strict
28852885

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

jsonschema/golangci.next.jsonschema.json

+4-4
Original file line numberDiff line numberDiff line change
@@ -3517,10 +3517,10 @@
35173517
"type": "boolean",
35183518
"default": false
35193519
},
3520-
"exclude-generated-strict": {
3521-
"description": "To follow strict Go generated file convention",
3522-
"type": "boolean",
3523-
"default": false
3520+
"exclude-generated": {
3521+
"description": "Mode of the generated files analysis.",
3522+
"enum": ["lax", "strict", "disable"],
3523+
"default": "lax"
35243524
},
35253525
"exclude-dirs": {
35263526
"description": "Which directories to exclude: issues from them won't be reported.",

pkg/commands/flagsets.go

+3
Original file line numberDiff line numberDiff line change
@@ -103,6 +103,9 @@ func setupIssuesFlagSet(v *viper.Viper, fs *pflag.FlagSet) {
103103
internal.AddFlagAndBind(v, fs, fs.Bool, "exclude-dirs-use-default", "issues.exclude-dirs-use-default", true,
104104
getDefaultDirectoryExcludeHelp())
105105

106+
internal.AddFlagAndBind(v, fs, fs.String, "exclude-generated", "issues.exclude-generated", processors.AutogeneratedModeLax,
107+
color.GreenString("Mode of the generated files analysis"))
108+
106109
const newDesc = "Show only new issues: if there are unstaged changes or untracked files, only those changes " +
107110
"are analyzed, else only changes in HEAD~ are analyzed.\nIt's a super-useful option for integration " +
108111
"of golangci-lint into existing large codebase.\nIt's not practical to fix all existing issues at " +

pkg/config/issues.go

+8-4
Original file line numberDiff line numberDiff line change
@@ -108,12 +108,14 @@ type Issues struct {
108108
ExcludeCaseSensitive bool `mapstructure:"exclude-case-sensitive"`
109109
ExcludePatterns []string `mapstructure:"exclude"`
110110
ExcludeRules []ExcludeRule `mapstructure:"exclude-rules"`
111-
ExcludeGeneratedStrict bool `mapstructure:"exclude-generated-strict"`
112111
UseDefaultExcludes bool `mapstructure:"exclude-use-default"`
113112

114-
ExcludeFiles []string `mapstructure:"exclude-files"`
115-
ExcludeDirs []string `mapstructure:"exclude-dirs"`
116-
UseDefaultExcludeDirs bool `mapstructure:"exclude-dirs-use-default"`
113+
ExcludeGenerated string `mapstructure:"exclude-generated"`
114+
115+
ExcludeFiles []string `mapstructure:"exclude-files"`
116+
ExcludeDirs []string `mapstructure:"exclude-dirs"`
117+
118+
UseDefaultExcludeDirs bool `mapstructure:"exclude-dirs-use-default"`
117119

118120
MaxIssuesPerLinter int `mapstructure:"max-issues-per-linter"`
119121
MaxSameIssues int `mapstructure:"max-same-issues"`
@@ -124,6 +126,8 @@ type Issues struct {
124126
Diff bool `mapstructure:"new"`
125127

126128
NeedFix bool `mapstructure:"fix"`
129+
130+
ExcludeGeneratedStrict bool `mapstructure:"exclude-generated-strict"` // Deprecated: use ExcludeGenerated instead.
127131
}
128132

129133
func (i *Issues) Validate() error {

pkg/config/loader.go

+5
Original file line numberDiff line numberDiff line change
@@ -357,6 +357,11 @@ func (l *Loader) handleDeprecation() error {
357357
}
358358
}
359359

360+
// Deprecated since v1.59.0
361+
if l.cfg.Issues.ExcludeGeneratedStrict {
362+
l.log.Warnf("The configuration option `issues.exclude-generated-strict` is deprecated, please use `issues.exclude-generated`")
363+
}
364+
360365
l.handleLinterOptionDeprecations()
361366

362367
return nil

pkg/lint/runner.go

+1-1
Original file line numberDiff line numberDiff line change
@@ -75,7 +75,7 @@ func NewRunner(log logutils.Log, cfg *config.Config, args []string, goenv *gouti
7575
skipFilesProcessor,
7676
skipDirsProcessor, // must be after path prettifier
7777

78-
processors.NewAutogeneratedExclude(cfg.Issues.ExcludeGeneratedStrict),
78+
processors.NewAutogeneratedExclude(cfg.Issues.ExcludeGenerated),
7979

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

pkg/result/processors/autogenerated_exclude.go

+14-4
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,12 @@ import (
1212
"github.com/golangci/golangci-lint/pkg/result"
1313
)
1414

15+
const (
16+
AutogeneratedModeLax = "lax"
17+
AutogeneratedModeStrict = "strict"
18+
AutogeneratedModeDisable = "disable"
19+
)
20+
1521
const (
1622
genCodeGenerated = "code generated"
1723
genDoNotEdit = "do not edit"
@@ -27,16 +33,16 @@ type fileSummary struct {
2733
type AutogeneratedExclude struct {
2834
debugf logutils.DebugFunc
2935

30-
strict bool
36+
mode string
3137
strictPattern *regexp.Regexp
3238

3339
fileSummaryCache map[string]*fileSummary
3440
}
3541

36-
func NewAutogeneratedExclude(strict bool) *AutogeneratedExclude {
42+
func NewAutogeneratedExclude(mode string) *AutogeneratedExclude {
3743
return &AutogeneratedExclude{
3844
debugf: logutils.Debug(logutils.DebugKeyAutogenExclude),
39-
strict: strict,
45+
mode: mode,
4046
strictPattern: regexp.MustCompile(`^// Code generated .* DO NOT EDIT\.$`),
4147
fileSummaryCache: map[string]*fileSummary{},
4248
}
@@ -47,6 +53,10 @@ func (*AutogeneratedExclude) Name() string {
4753
}
4854

4955
func (p *AutogeneratedExclude) Process(issues []result.Issue) ([]result.Issue, error) {
56+
if p.mode == AutogeneratedModeDisable {
57+
return issues, nil
58+
}
59+
5060
return filterIssuesErr(issues, p.shouldPassIssue)
5161
}
5262

@@ -71,7 +81,7 @@ func (p *AutogeneratedExclude) shouldPassIssue(issue *result.Issue) (bool, error
7181
fs = &fileSummary{}
7282
p.fileSummaryCache[issue.FilePath()] = fs
7383

74-
if p.strict {
84+
if p.mode == AutogeneratedModeStrict {
7585
var err error
7686
fs.generated, err = p.isGeneratedFileStrict(issue.FilePath())
7787
if err != nil {

pkg/result/processors/autogenerated_exclude_test.go

+17-17
Original file line numberDiff line numberDiff line change
@@ -14,7 +14,7 @@ import (
1414
)
1515

1616
func TestAutogeneratedExclude_isGeneratedFileLax_generated(t *testing.T) {
17-
p := NewAutogeneratedExclude(false)
17+
p := NewAutogeneratedExclude(AutogeneratedModeLax)
1818

1919
comments := []string{
2020
` // generated by stringer -type Pill pill.go; DO NOT EDIT`,
@@ -56,7 +56,7 @@ func TestAutogeneratedExclude_isGeneratedFileLax_generated(t *testing.T) {
5656
}
5757

5858
func TestAutogeneratedExclude_isGeneratedFileLax_nonGenerated(t *testing.T) {
59-
p := NewAutogeneratedExclude(false)
59+
p := NewAutogeneratedExclude(AutogeneratedModeLax)
6060

6161
comments := []string{
6262
"code not generated by",
@@ -75,7 +75,7 @@ func TestAutogeneratedExclude_isGeneratedFileLax_nonGenerated(t *testing.T) {
7575
}
7676

7777
func TestAutogeneratedExclude_isGeneratedFileStrict(t *testing.T) {
78-
p := NewAutogeneratedExclude(true)
78+
p := NewAutogeneratedExclude(AutogeneratedModeStrict)
7979

8080
testCases := []struct {
8181
desc string
@@ -154,21 +154,21 @@ func Test_getComments_fileWithLongLine(t *testing.T) {
154154
func Test_shouldPassIssue(t *testing.T) {
155155
testCases := []struct {
156156
desc string
157-
strict bool
157+
mode string
158158
issue *result.Issue
159159
assert assert.BoolAssertionFunc
160160
}{
161161
{
162-
desc: "typecheck issue",
163-
strict: false,
162+
desc: "typecheck issue",
163+
mode: AutogeneratedModeLax,
164164
issue: &result.Issue{
165165
FromLinter: "typecheck",
166166
},
167167
assert: assert.True,
168168
},
169169
{
170-
desc: "lax ",
171-
strict: false,
170+
desc: "lax ",
171+
mode: AutogeneratedModeLax,
172172
issue: &result.Issue{
173173
FromLinter: "example",
174174
Pos: token.Position{
@@ -178,8 +178,8 @@ func Test_shouldPassIssue(t *testing.T) {
178178
assert: assert.False,
179179
},
180180
{
181-
desc: "strict ",
182-
strict: true,
181+
desc: "strict ",
182+
mode: AutogeneratedModeStrict,
183183
issue: &result.Issue{
184184
FromLinter: "example",
185185
Pos: token.Position{
@@ -195,7 +195,7 @@ func Test_shouldPassIssue(t *testing.T) {
195195
t.Run(test.desc, func(t *testing.T) {
196196
t.Parallel()
197197

198-
p := NewAutogeneratedExclude(test.strict)
198+
p := NewAutogeneratedExclude(test.mode)
199199

200200
pass, err := p.shouldPassIssue(test.issue)
201201
require.NoError(t, err)
@@ -213,13 +213,13 @@ func Test_shouldPassIssue_error(t *testing.T) {
213213

214214
testCases := []struct {
215215
desc string
216-
strict bool
216+
mode string
217217
issue *result.Issue
218218
expected string
219219
}{
220220
{
221-
desc: "non-existing file (lax)",
222-
strict: false,
221+
desc: "non-existing file (lax)",
222+
mode: AutogeneratedModeLax,
223223
issue: &result.Issue{
224224
FromLinter: "example",
225225
Pos: token.Position{
@@ -230,8 +230,8 @@ func Test_shouldPassIssue_error(t *testing.T) {
230230
filepath.FromSlash("no-existing.go"), notFoundMsg),
231231
},
232232
{
233-
desc: "non-existing file (strict)",
234-
strict: true,
233+
desc: "non-existing file (strict)",
234+
mode: AutogeneratedModeStrict,
235235
issue: &result.Issue{
236236
FromLinter: "example",
237237
Pos: token.Position{
@@ -248,7 +248,7 @@ func Test_shouldPassIssue_error(t *testing.T) {
248248
t.Run(test.desc, func(t *testing.T) {
249249
t.Parallel()
250250

251-
p := NewAutogeneratedExclude(test.strict)
251+
p := NewAutogeneratedExclude(test.mode)
252252

253253
pass, err := p.shouldPassIssue(test.issue)
254254

0 commit comments

Comments
 (0)