Skip to content

Commit

Permalink
linters/errcheck: add support for ignore/exclude flags
Browse files Browse the repository at this point in the history
Add support for the exclude and ignore flags of errcheck.
Note that, this commit depends on golangci/errcheck#1. We need
to merge it first, update vendors and only then merge this one.
  • Loading branch information
a8m authored and jirfag committed Oct 10, 2018
1 parent 59c3d20 commit b81346f
Show file tree
Hide file tree
Showing 9 changed files with 530 additions and 14 deletions.
6 changes: 3 additions & 3 deletions Gopkg.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

4 changes: 4 additions & 0 deletions Gopkg.toml
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,10 @@
name = "github.com/spf13/viper"
version = "1.0.2"

[[constraint]]
branch = "master"
name = "github.com/spf13/pflag"

[[constraint]]
branch = "master"
name = "github.com/mitchellh/go-ps"
Expand Down
8 changes: 6 additions & 2 deletions pkg/commands/run.go
Original file line number Diff line number Diff line change
Expand Up @@ -75,16 +75,20 @@ func initFlagSet(fs *pflag.FlagSet, cfg *config.Config, m *lintersdb.Manager) {
lsc := &cfg.LintersSettings

// Hide all linters settings flags: they were initially visible,
// but when number of linters started to grow it became ovious that
// but when number of linters started to grow it became obvious that
// we can't fill 90% of flags by linters settings: common flags became hard to find.
// New linters settings should be done only through config file.
fs.BoolVar(&lsc.Errcheck.CheckTypeAssertions, "errcheck.check-type-assertions",
false, "Errcheck: check for ignored type assertion results")
hideFlag("errcheck.check-type-assertions")

fs.BoolVar(&lsc.Errcheck.CheckAssignToBlank, "errcheck.check-blank", false,
"Errcheck: check for errors assigned to blank identifier: _ = errFunc()")
hideFlag("errcheck.check-blank")
fs.StringVar(&lsc.Errcheck.Exclude, "errcheck.exclude", "", "errcheck.exclude")
hideFlag("errcheck.exclude")
lsc.Errcheck.Ignore = config.IgnoreFlag{}
fs.Var(&lsc.Errcheck.Ignore, "errcheck.ignore", "errcheck.ignore")
hideFlag("errcheck.ignore")

fs.BoolVar(&lsc.Govet.CheckShadowing, "govet.check-shadowing", false,
"Govet: check for shadowed variables")
Expand Down
59 changes: 55 additions & 4 deletions pkg/config/config.go
Original file line number Diff line number Diff line change
@@ -1,6 +1,9 @@
package config

import (
"fmt"
"regexp"
"strings"
"time"
)

Expand Down Expand Up @@ -115,10 +118,6 @@ type Run struct {
}

type LintersSettings struct {
Errcheck struct {
CheckTypeAssertions bool `mapstructure:"check-type-assertions"`
CheckAssignToBlank bool `mapstructure:"check-blank"`
}
Govet struct {
CheckShadowing bool `mapstructure:"check-shadowing"`
UseInstalledPackages bool `mapstructure:"use-installed-packages"`
Expand Down Expand Up @@ -164,6 +163,14 @@ type LintersSettings struct {
Unparam UnparamSettings
Nakedret NakedretSettings
Prealloc PreallocSettings
Errcheck ErrcheckSettings
}

type ErrcheckSettings struct {
CheckTypeAssertions bool `mapstructure:"check-type-assertions"`
CheckAssignToBlank bool `mapstructure:"check-blank"`
Ignore IgnoreFlag `mapstructure:"ignore"`
Exclude string `mapstructure:"exclude"`
}

type LllSettings struct {
Expand Down Expand Up @@ -248,3 +255,47 @@ func NewDefault() *Config {
LintersSettings: defaultLintersSettings,
}
}

// IgnoreFlags was taken from errcheck in order to keep the API identical.
// https://github.com/kisielk/errcheck/blob/1787c4bee836470bf45018cfbc783650db3c6501/main.go#L25-L60
type IgnoreFlag map[string]*regexp.Regexp

func (f IgnoreFlag) String() string {
pairs := make([]string, 0, len(f))
for pkg, re := range f {
prefix := ""
if pkg != "" {
prefix = pkg + ":"
}
pairs = append(pairs, prefix+re.String())
}
return fmt.Sprintf("%q", strings.Join(pairs, ","))
}

func (f IgnoreFlag) Set(s string) error {
if s == "" {
return nil
}
for _, pair := range strings.Split(s, ",") {
colonIndex := strings.Index(pair, ":")
var pkg, re string
if colonIndex == -1 {
pkg = ""
re = pair
} else {
pkg = pair[:colonIndex]
re = pair[colonIndex+1:]
}
regex, err := regexp.Compile(re)
if err != nil {
return err
}
f[pkg] = regex
}
return nil
}

// Type returns the type of the flag follow the pflag format.
func (IgnoreFlag) Type() string {
return "stringToRegexp"
}
44 changes: 42 additions & 2 deletions pkg/golinters/errcheck.go
Original file line number Diff line number Diff line change
@@ -1,12 +1,16 @@
package golinters

import (
"bufio"
"context"
"fmt"
"os"

errcheckAPI "github.com/golangci/errcheck/golangci"
"github.com/golangci/golangci-lint/pkg/config"
"github.com/golangci/golangci-lint/pkg/lint/linter"
"github.com/golangci/golangci-lint/pkg/result"
"github.com/pkg/errors"
)

type Errcheck struct{}
Expand All @@ -21,8 +25,11 @@ func (Errcheck) Desc() string {
}

func (e Errcheck) Run(ctx context.Context, lintCtx *linter.Context) ([]result.Issue, error) {
errCfg := &lintCtx.Settings().Errcheck
issues, err := errcheckAPI.Run(lintCtx.Program, errCfg.CheckAssignToBlank, errCfg.CheckTypeAssertions)
errCfg, err := genConfig(&lintCtx.Settings().Errcheck)
if err != nil {
return nil, err
}
issues, err := errcheckAPI.RunWithConfig(lintCtx.Program, errCfg)
if err != nil {
return nil, err
}
Expand All @@ -48,3 +55,36 @@ func (e Errcheck) Run(ctx context.Context, lintCtx *linter.Context) ([]result.Is

return res, nil
}

func genConfig(errCfg *config.ErrcheckSettings) (*errcheckAPI.Config, error) {
c := &errcheckAPI.Config{
Ignore: errCfg.Ignore,
Blank: errCfg.CheckAssignToBlank,
Asserts: errCfg.CheckTypeAssertions,
}
if errCfg.Exclude != "" {
exclude, err := readExcludeFile(errCfg.Exclude)
if err != nil {
return nil, err
}
c.Exclude = exclude
}
return c, nil
}

func readExcludeFile(name string) (map[string]bool, error) {
exclude := make(map[string]bool)
fh, err := os.Open(name)
if err != nil {
return nil, errors.Wrapf(err, "failed reading exclude file: %s", name)
}
scanner := bufio.NewScanner(fh)
for scanner.Scan() {
name := scanner.Text()
exclude[name] = true
}
if err := scanner.Err(); err != nil {
return nil, errors.Wrapf(err, "failed scanning file: %s", name)
}
return exclude, nil
}
104 changes: 104 additions & 0 deletions vendor/github.com/spf13/pflag/bytes.go

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

10 changes: 7 additions & 3 deletions vendor/github.com/spf13/pflag/flag.go

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

Loading

0 comments on commit b81346f

Please sign in to comment.