diff --git a/pkg/commands/run.go b/pkg/commands/run.go index 17f0f3fb..434b85d5 100644 --- a/pkg/commands/run.go +++ b/pkg/commands/run.go @@ -30,7 +30,7 @@ func getDefaultIssueExcludeHelp() string { parts := []string{"Use or not use default excludes:"} for _, ep := range config.DefaultExcludePatterns { parts = append(parts, - fmt.Sprintf(" # %s: %s", ep.Linter, ep.Why), + fmt.Sprintf(" # %s %s: %s", ep.ID, ep.Linter, ep.Why), fmt.Sprintf(" - %s", color.YellowString(ep.Pattern)), "", ) diff --git a/pkg/config/config.go b/pkg/config/config.go index 2b3048cb..f5cf3b4c 100644 --- a/pkg/config/config.go +++ b/pkg/config/config.go @@ -30,6 +30,7 @@ var OutFormats = []string{ } type ExcludePattern struct { + ID string Pattern string Linter string Why string @@ -37,63 +38,80 @@ type ExcludePattern struct { var DefaultExcludePatterns = []ExcludePattern{ { + ID: "EXC0001", Pattern: "Error return value of .((os\\.)?std(out|err)\\..*|.*Close" + "|.*Flush|os\\.Remove(All)?|.*printf?|os\\.(Un)?Setenv). is not checked", Linter: "errcheck", Why: "Almost all programs ignore errors on these functions and in most cases it's ok", }, { + ID: "EXC0002", Pattern: "(comment on exported (method|function|type|const)|" + "should have( a package)? comment|comment should be of the form)", Linter: "golint", Why: "Annoying issue about not having a comment. The rare codebase has such comments", }, { + ID: "EXC0003", Pattern: "func name will be used as test\\.Test.* by other packages, and that stutters; consider calling this", Linter: "golint", Why: "False positive when tests are defined in package 'test'", }, { + ID: "EXC0004", Pattern: "(possible misuse of unsafe.Pointer|should have signature)", Linter: "govet", Why: "Common false positives", }, { + ID: "EXC0005", Pattern: "ineffective break statement. Did you mean to break out of the outer loop", Linter: "staticcheck", Why: "Developers tend to write in C-style with an explicit 'break' in a 'switch', so it's ok to ignore", }, { + ID: "EXC0006", Pattern: "Use of unsafe calls should be audited", Linter: "gosec", Why: "Too many false-positives on 'unsafe' usage", }, { + ID: "EXC0007", Pattern: "Subprocess launch(ed with variable|ing should be audited)", Linter: "gosec", Why: "Too many false-positives for parametrized shell calls", }, { + ID: "EXC0008", Pattern: "G104", Linter: "gosec", Why: "Duplicated errcheck checks", }, { + ID: "EXC0009", Pattern: "(Expect directory permissions to be 0750 or less|Expect file permissions to be 0600 or less)", Linter: "gosec", Why: "Too many issues in popular repos", }, { + ID: "EXC0010", Pattern: "Potential file inclusion via variable", Linter: "gosec", Why: "False positive is triggered by 'src, err := ioutil.ReadFile(filename)'", }, } -func GetDefaultExcludePatternsStrings() []string { +func GetDefaultExcludePatternsStrings(include []string) []string { + includeMap := make(map[string]bool, len(include)) + for _, inc := range include { + includeMap[inc] = true + } + var ret []string for _, p := range DefaultExcludePatterns { - ret = append(ret, p.Pattern) + if !includeMap[p.ID] { + ret = append(ret, p.Pattern) + } } return ret @@ -411,10 +429,11 @@ func (e ExcludeRule) Validate() error { } type Issues struct { - ExcludeCaseSensitive bool `mapstructure:"exclude-case-sensitive"` - ExcludePatterns []string `mapstructure:"exclude"` - ExcludeRules []ExcludeRule `mapstructure:"exclude-rules"` - UseDefaultExcludes bool `mapstructure:"exclude-use-default"` + IncludeDefaultExcludes []string `mapstructure:"include"` + ExcludeCaseSensitive bool `mapstructure:"exclude-case-sensitive"` + ExcludePatterns []string `mapstructure:"exclude"` + ExcludeRules []ExcludeRule `mapstructure:"exclude-rules"` + UseDefaultExcludes bool `mapstructure:"exclude-use-default"` MaxIssuesPerLinter int `mapstructure:"max-issues-per-linter"` MaxSameIssues int `mapstructure:"max-same-issues"` diff --git a/pkg/lint/runner.go b/pkg/lint/runner.go index dd9e6946..3be2700a 100644 --- a/pkg/lint/runner.go +++ b/pkg/lint/runner.go @@ -32,7 +32,7 @@ func NewRunner(cfg *config.Config, log logutils.Log, goenv *goutil.Env, icfg := cfg.Issues excludePatterns := icfg.ExcludePatterns if icfg.UseDefaultExcludes { - excludePatterns = append(excludePatterns, config.GetDefaultExcludePatternsStrings()...) + excludePatterns = append(excludePatterns, config.GetDefaultExcludePatternsStrings(icfg.IncludeDefaultExcludes)...) } var excludeTotalPattern string diff --git a/test/bench/bench_test.go b/test/bench/bench_test.go index 42caffd7..5084ee96 100644 --- a/test/bench/bench_test.go +++ b/test/bench/bench_test.go @@ -77,7 +77,7 @@ func getGometalinterCommonArgs() []string { "--vendor", "--cyclo-over=30", "--dupl-threshold=150", - "--exclude", fmt.Sprintf("(%s)", strings.Join(config.GetDefaultExcludePatternsStrings(), "|")), + "--exclude", fmt.Sprintf("(%s)", strings.Join(config.GetDefaultExcludePatternsStrings(nil), "|")), "--disable-all", "--enable=vet", "--enable=vetshadow",