Skip to content

Commit 9822de2

Browse files
committed
include generated
1 parent 8c4cfb6 commit 9822de2

File tree

5 files changed

+141
-28
lines changed

5 files changed

+141
-28
lines changed

.golangci.reference.yml

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2845,6 +2845,11 @@ issues:
28452845
- ".*\\.my\\.go$"
28462846
- lib/bad.go
28472847

2848+
# Which files do not excluded as a generated they will be analyzed and issues will be reported.
2849+
# Default: []
2850+
exclude-generated-skip-files:
2851+
- ".*pb.go$"
2852+
28482853
# To follow strictly the Go generated file convention.
28492854
#
28502855
# If set to true, source files that have lines matching only the following regular expression will be excluded:

pkg/config/issues.go

Lines changed: 7 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -104,12 +104,13 @@ var DefaultExcludePatterns = []ExcludePattern{
104104
}
105105

106106
type Issues struct {
107-
IncludeDefaultExcludes []string `mapstructure:"include"`
108-
ExcludeCaseSensitive bool `mapstructure:"exclude-case-sensitive"`
109-
ExcludePatterns []string `mapstructure:"exclude"`
110-
ExcludeRules []ExcludeRule `mapstructure:"exclude-rules"`
111-
ExcludeGeneratedStrict bool `mapstructure:"exclude-generated-strict"`
112-
UseDefaultExcludes bool `mapstructure:"exclude-use-default"`
107+
IncludeDefaultExcludes []string `mapstructure:"include"`
108+
ExcludeCaseSensitive bool `mapstructure:"exclude-case-sensitive"`
109+
ExcludePatterns []string `mapstructure:"exclude"`
110+
ExcludeRules []ExcludeRule `mapstructure:"exclude-rules"`
111+
ExcludeGeneratedSkipFiles []string `mapstructure:"exclude-generated-skip-files"`
112+
ExcludeGeneratedStrict bool `mapstructure:"exclude-generated-strict"`
113+
UseDefaultExcludes bool `mapstructure:"exclude-use-default"`
113114

114115
ExcludeFiles []string `mapstructure:"exclude-files"`
115116
ExcludeDirs []string `mapstructure:"exclude-dirs"`

pkg/lint/runner.go

Lines changed: 7 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -60,6 +60,12 @@ func NewRunner(log logutils.Log, cfg *config.Config, args []string, goenv *gouti
6060
return nil, fmt.Errorf("failed to get enabled linters: %w", err)
6161
}
6262

63+
autogeneratedExclude, err := processors.NewAutogeneratedExclude(
64+
cfg.Issues.ExcludeGeneratedStrict, cfg.Issues.ExcludeGeneratedSkipFiles)
65+
if err != nil {
66+
return nil, fmt.Errorf("failed to construct autogenerated exclude: %w", err)
67+
}
68+
6369
return &Runner{
6470
Processors: []processors.Processor{
6571
processors.NewCgo(goenv),
@@ -75,7 +81,7 @@ func NewRunner(log logutils.Log, cfg *config.Config, args []string, goenv *gouti
7581
skipFilesProcessor,
7682
skipDirsProcessor, // must be after path prettifier
7783

78-
processors.NewAutogeneratedExclude(cfg.Issues.ExcludeGeneratedStrict),
84+
autogeneratedExclude,
7985

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

pkg/result/processors/autogenerated_exclude.go

Lines changed: 24 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,7 @@ import (
88
"regexp"
99
"strings"
1010

11+
"github.com/golangci/golangci-lint/pkg/fsutils"
1112
"github.com/golangci/golangci-lint/pkg/logutils"
1213
"github.com/golangci/golangci-lint/pkg/result"
1314
)
@@ -27,19 +28,34 @@ type fileSummary struct {
2728
type AutogeneratedExclude struct {
2829
debugf logutils.DebugFunc
2930

31+
skipFilesRe []*regexp.Regexp
32+
3033
strict bool
3134
strictPattern *regexp.Regexp
3235

3336
fileSummaryCache map[string]*fileSummary
3437
}
3538

36-
func NewAutogeneratedExclude(strict bool) *AutogeneratedExclude {
39+
func NewAutogeneratedExclude(strict bool, skipFilesPattern []string) (*AutogeneratedExclude, error) {
40+
var patternsRe []*regexp.Regexp
41+
for _, p := range skipFilesPattern {
42+
p = fsutils.NormalizePathInRegex(p)
43+
44+
patternRe, err := regexp.Compile(p)
45+
if err != nil {
46+
return nil, fmt.Errorf("can't compile regexp %q: %w", p, err)
47+
}
48+
49+
patternsRe = append(patternsRe, patternRe)
50+
}
51+
3752
return &AutogeneratedExclude{
3853
debugf: logutils.Debug(logutils.DebugKeyAutogenExclude),
54+
skipFilesRe: patternsRe,
3955
strict: strict,
4056
strictPattern: regexp.MustCompile(`^// Code generated .* DO NOT EDIT\.$`),
4157
fileSummaryCache: map[string]*fileSummary{},
42-
}
58+
}, nil
4359
}
4460

4561
func (*AutogeneratedExclude) Name() string {
@@ -53,6 +69,12 @@ func (p *AutogeneratedExclude) Process(issues []result.Issue) ([]result.Issue, e
5369
func (*AutogeneratedExclude) Finish() {}
5470

5571
func (p *AutogeneratedExclude) shouldPassIssue(issue *result.Issue) (bool, error) {
72+
for _, pattern := range p.skipFilesRe {
73+
if pattern.MatchString(issue.FilePath()) {
74+
return true, nil
75+
}
76+
}
77+
5678
if issue.FromLinter == typeCheckName {
5779
// don't hide typechecking errors in generated files: users expect to see why the project isn't compiling
5880
return true, nil

pkg/result/processors/autogenerated_exclude_test.go

Lines changed: 98 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -14,7 +14,8 @@ import (
1414
)
1515

1616
func TestAutogeneratedExclude_isGeneratedFileLax_generated(t *testing.T) {
17-
p := NewAutogeneratedExclude(false)
17+
p, err := NewAutogeneratedExclude(false, nil)
18+
require.NoError(t, err)
1819

1920
comments := []string{
2021
` // generated by stringer -type Pill pill.go; DO NOT EDIT`,
@@ -56,7 +57,8 @@ func TestAutogeneratedExclude_isGeneratedFileLax_generated(t *testing.T) {
5657
}
5758

5859
func TestAutogeneratedExclude_isGeneratedFileLax_nonGenerated(t *testing.T) {
59-
p := NewAutogeneratedExclude(false)
60+
p, err := NewAutogeneratedExclude(false, nil)
61+
require.NoError(t, err)
6062

6163
comments := []string{
6264
"code not generated by",
@@ -75,7 +77,8 @@ func TestAutogeneratedExclude_isGeneratedFileLax_nonGenerated(t *testing.T) {
7577
}
7678

7779
func TestAutogeneratedExclude_isGeneratedFileStrict(t *testing.T) {
78-
p := NewAutogeneratedExclude(true)
80+
p, err := NewAutogeneratedExclude(true, nil)
81+
require.NoError(t, err)
7982

8083
testCases := []struct {
8184
desc string
@@ -153,22 +156,25 @@ func Test_getComments_fileWithLongLine(t *testing.T) {
153156

154157
func Test_shouldPassIssue(t *testing.T) {
155158
testCases := []struct {
156-
desc string
157-
strict bool
158-
issue *result.Issue
159-
assert assert.BoolAssertionFunc
159+
desc string
160+
include []string
161+
strict bool
162+
issue *result.Issue
163+
assert assert.BoolAssertionFunc
160164
}{
161165
{
162-
desc: "typecheck issue",
163-
strict: false,
166+
desc: "typecheck issue",
167+
include: nil,
168+
strict: false,
164169
issue: &result.Issue{
165170
FromLinter: "typecheck",
166171
},
167172
assert: assert.True,
168173
},
169174
{
170-
desc: "lax ",
171-
strict: false,
175+
desc: "lax ",
176+
include: nil,
177+
strict: false,
172178
issue: &result.Issue{
173179
FromLinter: "example",
174180
Pos: token.Position{
@@ -178,8 +184,9 @@ func Test_shouldPassIssue(t *testing.T) {
178184
assert: assert.False,
179185
},
180186
{
181-
desc: "strict ",
182-
strict: true,
187+
desc: "strict ",
188+
include: nil,
189+
strict: true,
183190
issue: &result.Issue{
184191
FromLinter: "example",
185192
Pos: token.Position{
@@ -188,14 +195,39 @@ func Test_shouldPassIssue(t *testing.T) {
188195
},
189196
assert: assert.True,
190197
},
198+
{
199+
desc: "include ",
200+
include: []string{"(.*)?invalid.go"},
201+
strict: false,
202+
issue: &result.Issue{
203+
FromLinter: "example",
204+
Pos: token.Position{
205+
Filename: filepath.FromSlash("testdata/autogen_go_strict_invalid.go"),
206+
},
207+
},
208+
assert: assert.True,
209+
},
210+
{
211+
desc: "include other pattern",
212+
include: []string{"(.*)?.pb.go"},
213+
strict: false,
214+
issue: &result.Issue{
215+
FromLinter: "example",
216+
Pos: token.Position{
217+
Filename: filepath.FromSlash("testdata/autogen_go_strict_invalid.go"),
218+
},
219+
},
220+
assert: assert.False,
221+
},
191222
}
192223

193224
for _, test := range testCases {
194225
test := test
195226
t.Run(test.desc, func(t *testing.T) {
196227
t.Parallel()
197228

198-
p := NewAutogeneratedExclude(test.strict)
229+
p, err := NewAutogeneratedExclude(test.strict, test.include)
230+
require.NoError(t, err)
199231

200232
pass, err := p.shouldPassIssue(test.issue)
201233
require.NoError(t, err)
@@ -213,13 +245,15 @@ func Test_shouldPassIssue_error(t *testing.T) {
213245

214246
testCases := []struct {
215247
desc string
248+
include []string
216249
strict bool
217250
issue *result.Issue
218251
expected string
219252
}{
220253
{
221-
desc: "non-existing file (lax)",
222-
strict: false,
254+
desc: "non-existing file (lax)",
255+
include: nil,
256+
strict: false,
223257
issue: &result.Issue{
224258
FromLinter: "example",
225259
Pos: token.Position{
@@ -230,8 +264,9 @@ func Test_shouldPassIssue_error(t *testing.T) {
230264
filepath.FromSlash("no-existing.go"), notFoundMsg),
231265
},
232266
{
233-
desc: "non-existing file (strict)",
234-
strict: true,
267+
desc: "non-existing file (strict)",
268+
include: nil,
269+
strict: true,
235270
issue: &result.Issue{
236271
FromLinter: "example",
237272
Pos: token.Position{
@@ -248,7 +283,8 @@ func Test_shouldPassIssue_error(t *testing.T) {
248283
t.Run(test.desc, func(t *testing.T) {
249284
t.Parallel()
250285

251-
p := NewAutogeneratedExclude(test.strict)
286+
p, err := NewAutogeneratedExclude(test.strict, test.include)
287+
require.NoError(t, err)
252288

253289
pass, err := p.shouldPassIssue(test.issue)
254290

@@ -258,3 +294,46 @@ func Test_shouldPassIssue_error(t *testing.T) {
258294
})
259295
}
260296
}
297+
298+
func Test_NewAutogeneratedExclude(t *testing.T) {
299+
testCases := []struct {
300+
desc string
301+
include []string
302+
strict bool
303+
assert assert.ValueAssertionFunc
304+
expectedError string
305+
}{
306+
{
307+
desc: "success ",
308+
include: []string{".pb.go"},
309+
strict: false,
310+
311+
assert: assert.NotNil,
312+
expectedError: "",
313+
},
314+
{
315+
desc: "regexp compilation error ",
316+
include: []string{"*bad_regexp*"},
317+
strict: false,
318+
319+
assert: assert.Nil,
320+
expectedError: "can't compile regexp \"*bad_regexp*\": error parsing regexp: missing argument to repetition operator: `*`",
321+
},
322+
}
323+
324+
for _, test := range testCases {
325+
test := test
326+
t.Run(test.desc, func(t *testing.T) {
327+
t.Parallel()
328+
329+
p, err := NewAutogeneratedExclude(test.strict, test.include)
330+
test.assert(t, p)
331+
332+
if test.expectedError == "" {
333+
assert.NoError(t, err)
334+
} else {
335+
assert.EqualError(t, err, test.expectedError)
336+
}
337+
})
338+
}
339+
}

0 commit comments

Comments
 (0)