Skip to content

Commit

Permalink
dev: cleanup config package (#1929)
Browse files Browse the repository at this point in the history
* split config section into files.
* extract anonymous types.
* sort linters alphabetically.
  • Loading branch information
ldez committed Apr 24, 2021
1 parent 12e3251 commit db80e16
Show file tree
Hide file tree
Showing 10 changed files with 725 additions and 680 deletions.
685 changes: 5 additions & 680 deletions pkg/config/config.go

Large diffs are not rendered by default.

180 changes: 180 additions & 0 deletions pkg/config/issues.go
@@ -0,0 +1,180 @@
package config

import (
"fmt"
"regexp"
)

const excludeRuleMinConditionsCount = 2

var DefaultExcludePatterns = []ExcludePattern{
{
ID: "EXC0001",
Pattern: "Error return value of .((os\\.)?std(out|err)\\..*|.*Close" +
"|.*Flush|os\\.Remove(All)?|.*print(f|ln)?|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|G307)",
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)'",
},
{
ID: "EXC0011",
Pattern: "(comment on exported (method|function|type|const)|" +
"should have( a package)? comment|comment should be of the form)",
Linter: "stylecheck",
Why: "Annoying issue about not having a comment. The rare codebase has such comments",
},
}

type Issues struct {
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"`

DiffFromRevision string `mapstructure:"new-from-rev"`
DiffPatchFilePath string `mapstructure:"new-from-patch"`
Diff bool `mapstructure:"new"`

NeedFix bool `mapstructure:"fix"`
}

type ExcludeRule struct {
BaseRule `mapstructure:",squash"`
}

func (e ExcludeRule) Validate() error {
return e.BaseRule.Validate(excludeRuleMinConditionsCount)
}

type BaseRule struct {
Linters []string
Path string
Text string
Source string
}

func (b BaseRule) Validate(minConditionsCount int) error {
if err := validateOptionalRegex(b.Path); err != nil {
return fmt.Errorf("invalid path regex: %v", err)
}
if err := validateOptionalRegex(b.Text); err != nil {
return fmt.Errorf("invalid text regex: %v", err)
}
if err := validateOptionalRegex(b.Source); err != nil {
return fmt.Errorf("invalid source regex: %v", err)
}
nonBlank := 0
if len(b.Linters) > 0 {
nonBlank++
}
if b.Path != "" {
nonBlank++
}
if b.Text != "" {
nonBlank++
}
if b.Source != "" {
nonBlank++
}
if nonBlank < minConditionsCount {
return fmt.Errorf("at least %d of (text, source, path, linters) should be set", minConditionsCount)
}
return nil
}

func validateOptionalRegex(value string) error {
if value == "" {
return nil
}
_, err := regexp.Compile(value)
return err
}

type ExcludePattern struct {
ID string
Pattern string
Linter string
Why string
}

func GetDefaultExcludePatternsStrings() []string {
ret := make([]string, len(DefaultExcludePatterns))
for i, p := range DefaultExcludePatterns {
ret[i] = p.Pattern
}
return ret
}

func GetExcludePatterns(include []string) []ExcludePattern {
includeMap := make(map[string]bool, len(include))
for _, inc := range include {
includeMap[inc] = true
}

var ret []ExcludePattern
for _, p := range DefaultExcludePatterns {
if !includeMap[p.ID] {
ret = append(ret, p)
}
}

return ret
}
File renamed without changes.
11 changes: 11 additions & 0 deletions pkg/config/linters.go
@@ -0,0 +1,11 @@
package config

type Linters struct {
Enable []string
Disable []string
EnableAll bool `mapstructure:"enable-all"`
DisableAll bool `mapstructure:"disable-all"`
Fast bool

Presets []string
}

0 comments on commit db80e16

Please sign in to comment.