Skip to content

Commit 4b7a55a

Browse files
authored
feat: replace run.skip-xxx options by issues.exclude-xxx options (#4509)
1 parent 1466b36 commit 4b7a55a

18 files changed

+234
-159
lines changed

.golangci.next.reference.yml

+26-26
Original file line numberDiff line numberDiff line change
@@ -28,31 +28,6 @@ run:
2828
build-tags:
2929
- mytag
3030

31-
# Which dirs to skip: issues from them won't be reported.
32-
# Can use regexp here: `generated.*`, regexp is applied on full path,
33-
# including the path prefix if one is set.
34-
# Default dirs are skipped independently of this option's value (see skip-dirs-use-default).
35-
# "/" will be replaced by current OS file path separator to properly work on Windows.
36-
# Default: []
37-
skip-dirs:
38-
- src/external_libs
39-
- autogenerated_by_my_lib
40-
41-
# Enables skipping of directories:
42-
# - vendor$, third_party$, testdata$, examples$, Godeps$, builtin$
43-
# Default: true
44-
skip-dirs-use-default: false
45-
46-
# Which files to skip: they will be analyzed, but issues from them won't be reported.
47-
# There is no need to include all autogenerated files,
48-
# we confidently recognize autogenerated files.
49-
# If it's not, please let us know.
50-
# "/" will be replaced by current OS file path separator to properly work on Windows.
51-
# Default: []
52-
skip-files:
53-
- ".*\\.my\\.go$"
54-
- lib/bad.go
55-
5631
# If set, we pass it to "go list -mod={option}". From "go help modules":
5732
# If invoked with -mod=readonly, the go command is disallowed from the implicit
5833
# automatic updating of go.mod described above. Instead, it fails when any changes
@@ -2810,10 +2785,35 @@ issues:
28102785
# Default: true
28112786
exclude-use-default: false
28122787

2813-
# If set to true exclude and exclude-rules regular expressions become case-sensitive.
2788+
# If set to true, `exclude` and `exclude-rules` regular expressions become case-sensitive.
28142789
# Default: false
28152790
exclude-case-sensitive: false
28162791

2792+
# Which dirs to exclude: issues from them won't be reported.
2793+
# Can use regexp here: `generated.*`, regexp is applied on full path,
2794+
# including the path prefix if one is set.
2795+
# Default dirs are skipped independently of this option's value (see exclude-dirs-use-default).
2796+
# "/" will be replaced by current OS file path separator to properly work on Windows.
2797+
# Default: []
2798+
exclude-dirs:
2799+
- src/external_libs
2800+
- autogenerated_by_my_lib
2801+
2802+
# Enables exclude of directories:
2803+
# - vendor$, third_party$, testdata$, examples$, Godeps$, builtin$
2804+
# Default: true
2805+
exclude-dirs-use-default: false
2806+
2807+
# Which files to exclude: they will be analyzed, but issues from them won't be reported.
2808+
# There is no need to include all autogenerated files,
2809+
# we confidently recognize autogenerated files.
2810+
# If it's not, please let us know.
2811+
# "/" will be replaced by current OS file path separator to properly work on Windows.
2812+
# Default: []
2813+
exclude-files:
2814+
- ".*\\.my\\.go$"
2815+
- lib/bad.go
2816+
28172817
# To follow strictly the Go generated file convention.
28182818
#
28192819
# If set to true, source files that have lines matching only the following regular expression will be excluded:

.golangci.yml

+1-1
Original file line numberDiff line numberDiff line change
@@ -175,7 +175,7 @@ issues:
175175

176176
run:
177177
timeout: 5m
178-
skip-dirs:
178+
skip-dirs: # TODO(ldez): should be replaced by `issues.exclude-dirs` after the next release.
179179
- test/testdata_etc # test files
180180
- internal/cache # extracted from Go code
181181
- internal/renameio # extracted from Go code

docs/src/docs/usage/false-positives.mdx

+7-7
Original file line numberDiff line numberDiff line change
@@ -74,7 +74,7 @@ issues:
7474

7575
### Exclude Issues by Path
7676

77-
Exclude issues in path by `run.skip-dirs`, `run.skip-files` or `issues.exclude-rules` config options.
77+
Exclude issues in path by `issues.exclude-dirs`, `issues.exclude-files` or `issues.exclude-rules` config options.
7878

7979
Beware that the paths that get matched here are relative to the current working directory.
8080
When the configuration contains path patterns that check for specific directories,
@@ -103,19 +103,19 @@ issues:
103103
- goconst
104104
```
105105
106-
In the following example, all the reports related to the files (`skip-files`) are excluded:
106+
In the following example, all the reports related to the files (`exclude-files`) are excluded:
107107

108108
```yml
109-
run:
110-
skip-files:
109+
issues:
110+
exclude-files:
111111
- path/to/a/file.go
112112
```
113113

114-
In the following example, all the reports related to the directories (`skip-dirs`) are excluded:
114+
In the following example, all the reports related to the directories (`exclude-dirs`) are excluded:
115115

116116
```yml
117-
run:
118-
skip-dirs:
117+
issues:
118+
exclude-dirs:
119119
- path/to/a/dir/
120120
```
121121

jsonschema/golangci.next.jsonschema.json

+27-27
Original file line numberDiff line numberDiff line change
@@ -422,33 +422,6 @@
422422
"default": [],
423423
"examples": [["mytag"]]
424424
},
425-
"skip-dirs": {
426-
"description": "Which directories to skip: issues from them won't be reported.",
427-
"type": "array",
428-
"items": {
429-
"description": "You can use regexp here. The regexp is applied on the full path.\n\"/\" will be replaced by current OS file path separator to properly work on Windows.",
430-
"type": "string",
431-
"examples": ["generated.*"]
432-
},
433-
"default": [],
434-
"examples": [["src/external_libs", "autogenerated_by_my_lib"]]
435-
},
436-
"skip-dirs-use-default": {
437-
"description": "Enable skipping of directories \"vendor\", \"third_party\", \"testdata\", \"examples\", \"Godeps\", and \"builtin\".",
438-
"type": "boolean",
439-
"default": true
440-
},
441-
"skip-files": {
442-
"description": "Which files to skip: they will be analyzed, but issues from them will not be reported.",
443-
"type": "array",
444-
"items": {
445-
"description": "You can use regexp here. There is no need to include all autogenerated files, we confidently recognize them. If that is not the case, please let us know.\n\"/\" will be replaced by current OS file path separator to properly work on Windows.",
446-
"type": "string",
447-
"examples": [".*\\.my\\.go$"]
448-
},
449-
"default": [],
450-
"examples": [[".*\\.my\\.go$", "lib/bad.go"]]
451-
},
452425
"modules-download-mode": {
453426
"description": "Option to pass to \"go list -mod={option}\".\nSee \"go help modules\" for more information.",
454427
"enum": ["mod", "readonly", "vendor"]
@@ -3347,6 +3320,33 @@
33473320
"type": "boolean",
33483321
"default": false
33493322
},
3323+
"exclude-dirs": {
3324+
"description": "Which directories to exclude: issues from them won't be reported.",
3325+
"type": "array",
3326+
"items": {
3327+
"description": "You can use regexp here. The regexp is applied on the full path.\n\"/\" will be replaced by current OS file path separator to properly work on Windows.",
3328+
"type": "string",
3329+
"examples": ["generated.*"]
3330+
},
3331+
"default": [],
3332+
"examples": [["src/external_libs", "autogenerated_by_my_lib"]]
3333+
},
3334+
"exclude-dirs-use-default": {
3335+
"description": "Enable exclusion of directories \"vendor\", \"third_party\", \"testdata\", \"examples\", \"Godeps\", and \"builtin\".",
3336+
"type": "boolean",
3337+
"default": true
3338+
},
3339+
"exclude-files": {
3340+
"description": "Which files to exclude: they will be analyzed, but issues from them will not be reported.",
3341+
"type": "array",
3342+
"items": {
3343+
"description": "You can use regexp here. There is no need to include all autogenerated files, we confidently recognize them. If that is not the case, please let us know.\n\"/\" will be replaced by current OS file path separator to properly work on Windows.",
3344+
"type": "string",
3345+
"examples": [".*\\.my\\.go$"]
3346+
},
3347+
"default": [],
3348+
"examples": [[".*\\.my\\.go$", "lib/bad.go"]]
3349+
},
33503350
"include": {
33513351
"description": "The list of ids of default excludes to include or disable.",
33523352
"type": "array",

pkg/commands/flagsets.go

+39-11
Original file line numberDiff line numberDiff line change
@@ -12,22 +12,22 @@ import (
1212
"github.com/golangci/golangci-lint/pkg/config"
1313
"github.com/golangci/golangci-lint/pkg/exitcodes"
1414
"github.com/golangci/golangci-lint/pkg/lint/lintersdb"
15+
"github.com/golangci/golangci-lint/pkg/packages"
1516
)
1617

1718
func setupLintersFlagSet(v *viper.Viper, fs *pflag.FlagSet) {
18-
fs.StringSliceP("disable", "D", nil, color.GreenString("Disable specific linter")) // Hack see Loader.applyStringSliceHack
19+
internal.AddHackedStringSliceP(fs, "disable", "D", color.GreenString("Disable specific linter"))
1920
internal.AddFlagAndBind(v, fs, fs.Bool, "disable-all", "linters.disable-all", false, color.GreenString("Disable all linters"))
2021

21-
fs.StringSliceP("enable", "E", nil, color.GreenString("Enable specific linter")) // Hack see Loader.applyStringSliceHack
22+
internal.AddHackedStringSliceP(fs, "enable", "E", color.GreenString("Enable specific linter"))
2223
internal.AddFlagAndBind(v, fs, fs.Bool, "enable-all", "linters.enable-all", false, color.GreenString("Enable all linters"))
2324

2425
internal.AddFlagAndBind(v, fs, fs.Bool, "fast", "linters.fast", false,
2526
color.GreenString("Enable only fast linters from enabled linters set (first run won't be fast)"))
2627

27-
// Hack see Loader.applyStringSliceHack
28-
fs.StringSliceP("presets", "p", nil,
29-
color.GreenString(fmt.Sprintf("Enable presets (%s) of linters. Run 'golangci-lint help linters' to see "+
30-
"them. This option implies option --disable-all", strings.Join(lintersdb.AllPresets(), "|"))))
28+
internal.AddHackedStringSliceP(fs, "presets", "p",
29+
color.GreenString(fmt.Sprintf("Enable presets (%s) of linters. Run 'golangci-lint help linters' to see them. "+
30+
"This option implies option --disable-all", strings.Join(lintersdb.AllPresets(), "|"))))
3131

3232
fs.StringSlice("enable-only", nil,
3333
color.GreenString("Override linters configuration section to only run the specific linter(s)")) // Flags only.
@@ -42,14 +42,16 @@ func setupRunFlagSet(v *viper.Viper, fs *pflag.FlagSet) {
4242
internal.AddFlagAndBind(v, fs, fs.Int, "issues-exit-code", "run.issues-exit-code", exitcodes.IssuesFound,
4343
color.GreenString("Exit code when issues were found"))
4444
internal.AddFlagAndBind(v, fs, fs.String, "go", "run.go", "", color.GreenString("Targeted Go version"))
45-
fs.StringSlice("build-tags", nil, color.GreenString("Build tags")) // Hack see Loader.applyStringSliceHack
45+
internal.AddHackedStringSlice(fs, "build-tags", color.GreenString("Build tags"))
4646

4747
internal.AddFlagAndBind(v, fs, fs.Duration, "timeout", "run.timeout", defaultTimeout, color.GreenString("Timeout for total work"))
4848

4949
internal.AddFlagAndBind(v, fs, fs.Bool, "tests", "run.tests", true, color.GreenString("Analyze tests (*_test.go)"))
50-
fs.StringSlice("skip-dirs", nil, color.GreenString("Regexps of directories to skip")) // Hack see Loader.applyStringSliceHack
51-
internal.AddFlagAndBind(v, fs, fs.Bool, "skip-dirs-use-default", "run.skip-dirs-use-default", true, getDefaultDirectoryExcludeHelp())
52-
fs.StringSlice("skip-files", nil, color.GreenString("Regexps of files to skip")) // Hack see Loader.applyStringSliceHack
50+
51+
internal.AddDeprecatedHackedStringSlice(fs, "skip-files", color.GreenString("Regexps of files to skip"))
52+
internal.AddDeprecatedHackedStringSlice(fs, "skip-dirs", color.GreenString("Regexps of directories to skip"))
53+
internal.AddDeprecatedFlagAndBind(v, fs, fs.Bool, "skip-dirs-use-default", "run.skip-dirs-use-default", true,
54+
getDefaultDirectoryExcludeHelp())
5355

5456
const allowParallelDesc = "Allow multiple parallel golangci-lint instances running. " +
5557
"If false (default) - golangci-lint acquires file lock on start."
@@ -80,7 +82,7 @@ func setupOutputFlagSet(v *viper.Viper, fs *pflag.FlagSet) {
8082

8183
//nolint:gomnd
8284
func setupIssuesFlagSet(v *viper.Viper, fs *pflag.FlagSet) {
83-
fs.StringSliceP("exclude", "e", nil, color.GreenString("Exclude issue by regexp")) // Hack see Loader.applyStringSliceHack
85+
internal.AddHackedStringSliceP(fs, "exclude", "e", color.GreenString("Exclude issue by regexp"))
8486
internal.AddFlagAndBind(v, fs, fs.Bool, "exclude-use-default", "issues.exclude-use-default", true,
8587
getDefaultIssueExcludeHelp())
8688
internal.AddFlagAndBind(v, fs, fs.Bool, "exclude-case-sensitive", "issues.exclude-case-sensitive", false,
@@ -91,6 +93,11 @@ func setupIssuesFlagSet(v *viper.Viper, fs *pflag.FlagSet) {
9193
internal.AddFlagAndBind(v, fs, fs.Int, "max-same-issues", "issues.max-same-issues", 3,
9294
color.GreenString("Maximum count of issues with the same text. Set to 0 to disable"))
9395

96+
internal.AddHackedStringSlice(fs, "exclude-files", color.GreenString("Regexps of files to exclude"))
97+
internal.AddHackedStringSlice(fs, "exclude-dirs", color.GreenString("Regexps of directories to exclude"))
98+
internal.AddFlagAndBind(v, fs, fs.Bool, "exclude-dirs-use-default", "issues.exclude-dirs-use-default", true,
99+
getDefaultDirectoryExcludeHelp())
100+
94101
const newDesc = "Show only new issues: if there are unstaged changes or untracked files, only those changes " +
95102
"are analyzed, else only changes in HEAD~ are analyzed.\nIt's a super-useful option for integration " +
96103
"of golangci-lint into existing large codebase.\nIt's not practical to fix all existing issues at " +
@@ -107,3 +114,24 @@ func setupIssuesFlagSet(v *viper.Viper, fs *pflag.FlagSet) {
107114
internal.AddFlagAndBind(v, fs, fs.Bool, "fix", "issues.fix", false,
108115
color.GreenString("Fix found issues (if it's supported by the linter)"))
109116
}
117+
118+
func getDefaultIssueExcludeHelp() string {
119+
parts := []string{color.GreenString("Use or not use default excludes:")}
120+
for _, ep := range config.DefaultExcludePatterns {
121+
parts = append(parts,
122+
fmt.Sprintf(" # %s %s: %s", ep.ID, ep.Linter, ep.Why),
123+
fmt.Sprintf(" - %s", color.YellowString(ep.Pattern)),
124+
"",
125+
)
126+
}
127+
return strings.Join(parts, "\n")
128+
}
129+
130+
func getDefaultDirectoryExcludeHelp() string {
131+
parts := []string{color.GreenString("Use or not use default excluded directories:")}
132+
for _, dir := range packages.StdExcludeDirRegexps {
133+
parts = append(parts, fmt.Sprintf(" - %s", color.YellowString(dir)))
134+
}
135+
parts = append(parts, "")
136+
return strings.Join(parts, "\n")
137+
}

pkg/commands/internal/vibra.go

+27
Original file line numberDiff line numberDiff line change
@@ -30,3 +30,30 @@ func AddFlagAndBindP[T any](v *viper.Viper, fs *pflag.FlagSet, pfn FlagPFunc[T],
3030
panic(fmt.Sprintf("failed to bind flag %s: %v", name, err))
3131
}
3232
}
33+
34+
// AddDeprecatedFlagAndBind similar to AddFlagAndBind but deprecate the flag.
35+
func AddDeprecatedFlagAndBind[T any](v *viper.Viper, fs *pflag.FlagSet, pfn FlagFunc[T], name, bind string, value T, usage string) {
36+
AddFlagAndBind(v, fs, pfn, name, bind, value, usage)
37+
deprecateFlag(fs, name)
38+
}
39+
40+
// AddHackedStringSliceP Hack for slice, see Loader.applyStringSliceHack.
41+
func AddHackedStringSliceP(fs *pflag.FlagSet, name, shorthand, usage string) {
42+
fs.StringSliceP(name, shorthand, nil, usage)
43+
}
44+
45+
// AddHackedStringSlice Hack for slice, see Loader.applyStringSliceHack.
46+
func AddHackedStringSlice(fs *pflag.FlagSet, name, usage string) {
47+
AddHackedStringSliceP(fs, name, "", usage)
48+
}
49+
50+
// AddDeprecatedHackedStringSlice similar to AddHackedStringSlice but deprecate the flag.
51+
func AddDeprecatedHackedStringSlice(fs *pflag.FlagSet, name, usage string) {
52+
AddHackedStringSlice(fs, name, usage)
53+
deprecateFlag(fs, name)
54+
}
55+
56+
func deprecateFlag(fs *pflag.FlagSet, name string) {
57+
_ = fs.MarkHidden(name)
58+
_ = fs.MarkDeprecated(name, "check the documentation for more information.")
59+
}

pkg/commands/run.go

+2-28
Original file line numberDiff line numberDiff line change
@@ -38,7 +38,6 @@ import (
3838
"github.com/golangci/golangci-lint/pkg/lint/linter"
3939
"github.com/golangci/golangci-lint/pkg/lint/lintersdb"
4040
"github.com/golangci/golangci-lint/pkg/logutils"
41-
"github.com/golangci/golangci-lint/pkg/packages"
4241
"github.com/golangci/golangci-lint/pkg/printers"
4342
"github.com/golangci/golangci-lint/pkg/report"
4443
"github.com/golangci/golangci-lint/pkg/result"
@@ -426,11 +425,7 @@ func (c *runCommand) printDeprecatedLinterMessages(enabledLinters map[string]*li
426425
}
427426

428427
func (c *runCommand) printStats(issues []result.Issue) {
429-
if c.cfg.Run.ShowStats {
430-
c.log.Warnf("The configuration option `run.show-stats` is deprecated, please use `output.show-stats`")
431-
}
432-
433-
if !c.cfg.Run.ShowStats && !c.cfg.Output.ShowStats {
428+
if !c.cfg.Output.ShowStats {
434429
return
435430
}
436431

@@ -465,7 +460,7 @@ func (c *runCommand) setupExitCode(ctx context.Context) {
465460
return
466461
}
467462

468-
needFailOnWarnings := os.Getenv(lintersdb.EnvTestRun) == "1" || os.Getenv(envFailOnWarnings) == "1"
463+
needFailOnWarnings := os.Getenv(logutils.EnvTestRun) == "1" || os.Getenv(envFailOnWarnings) == "1"
469464
if needFailOnWarnings && len(c.reportData.Warnings) != 0 {
470465
c.exitCode = exitcodes.WarningInTest
471466
return
@@ -578,27 +573,6 @@ func setupConfigFileFlagSet(fs *pflag.FlagSet, cfg *config.LoaderOptions) {
578573
fs.BoolVar(&cfg.NoConfig, "no-config", false, color.GreenString("Don't read config file"))
579574
}
580575

581-
func getDefaultIssueExcludeHelp() string {
582-
parts := []string{color.GreenString("Use or not use default excludes:")}
583-
for _, ep := range config.DefaultExcludePatterns {
584-
parts = append(parts,
585-
fmt.Sprintf(" # %s %s: %s", ep.ID, ep.Linter, ep.Why),
586-
fmt.Sprintf(" - %s", color.YellowString(ep.Pattern)),
587-
"",
588-
)
589-
}
590-
return strings.Join(parts, "\n")
591-
}
592-
593-
func getDefaultDirectoryExcludeHelp() string {
594-
parts := []string{color.GreenString("Use or not use default excluded directories:")}
595-
for _, dir := range packages.StdExcludeDirRegexps {
596-
parts = append(parts, fmt.Sprintf(" - %s", color.YellowString(dir)))
597-
}
598-
parts = append(parts, "")
599-
return strings.Join(parts, "\n")
600-
}
601-
602576
func setupRunPersistentFlags(fs *pflag.FlagSet, opts *runOptions) {
603577
fs.BoolVar(&opts.PrintResourcesUsage, "print-resources-usage", false,
604578
color.GreenString("Print avg and max memory usage of golangci-lint and total time"))

pkg/config/issues.go

+4
Original file line numberDiff line numberDiff line change
@@ -112,6 +112,10 @@ type Issues struct {
112112
ExcludeGeneratedStrict bool `mapstructure:"exclude-generated-strict"`
113113
UseDefaultExcludes bool `mapstructure:"exclude-use-default"`
114114

115+
ExcludeFiles []string `mapstructure:"exclude-files"`
116+
ExcludeDirs []string `mapstructure:"exclude-dirs"`
117+
UseDefaultExcludeDirs bool `mapstructure:"exclude-dirs-use-default"`
118+
115119
MaxIssuesPerLinter int `mapstructure:"max-issues-per-linter"`
116120
MaxSameIssues int `mapstructure:"max-same-issues"`
117121

0 commit comments

Comments
 (0)