Update gometalinter config (#331)

* Update gometalinter config

gometalinter now uses `maligned` instead of `aligncheck`
(https://github.com/alecthomas/gometalinter/pull/367), so we need to update our
config accordingly.

* Update gometalinter

* Disable gotype linter

gotype does not seem to play nicely with the gb vendor directory. In
particular, it wants each of our dependencies to be built and installed (see
https://github.com/golang/go/issues/10969), but (empirically) it will not
accept them being installed in `pkg` but insists on them being in `vendor/pkg`.

This presents a problem because `gb build` builds the packages into `pkg`
(which doesn't seem entirely unreasonable since `.` comes before `vendor` in
`$GOPATH`). `go install github.com/x/y` does install in `vendor/pkg` but
requires us to know the name of each package.

The general conclusion of https://github.com/alecthomas/gometalinter/issues/91
seems to have been that the easiest thing to do is to disable `gotype` for now.

* Fix `unparam` lint

* Fix goshadow lint
This commit is contained in:
Richard van der Hoff 2017-11-15 10:25:48 +00:00 committed by Erik Johnston
parent dc782ec399
commit 8fff0e887c
95 changed files with 8927 additions and 1176 deletions

View file

@ -1,6 +1,7 @@
package main
import (
"fmt"
"go/ast"
"go/parser"
"go/token"
@ -14,6 +15,7 @@ type ignoredRange struct {
col int
start, end int
linters []string
matched bool
}
func (i *ignoredRange) matches(issue *Issue) bool {
@ -35,6 +37,14 @@ func (i *ignoredRange) near(col, start int) bool {
return col == i.col && i.end == start-1
}
func (i *ignoredRange) String() string {
linters := strings.Join(i.linters, ",")
if len(i.linters) == 0 {
linters = "all"
}
return fmt.Sprintf("%s:%d-%d", linters, i.start, i.end)
}
type ignoredRanges []*ignoredRange
func (ir ignoredRanges) Len() int { return len(ir) }
@ -66,12 +76,43 @@ func (d *directiveParser) IsIgnored(issue *Issue) bool {
d.lock.Unlock()
for _, r := range ranges {
if r.matches(issue) {
debug("nolint: matched %s to issue %s", r, issue)
r.matched = true
return true
}
}
return false
}
// Unmatched returns all the ranges which were never used to ignore an issue
func (d *directiveParser) Unmatched() map[string]ignoredRanges {
unmatched := map[string]ignoredRanges{}
for path, ranges := range d.files {
for _, ignore := range ranges {
if !ignore.matched {
unmatched[path] = append(unmatched[path], ignore)
}
}
}
return unmatched
}
// LoadFiles from a list of directories
func (d *directiveParser) LoadFiles(paths []string) error {
d.lock.Lock()
defer d.lock.Unlock()
filenames, err := pathsToFileGlobs(paths)
if err != nil {
return err
}
for _, filename := range filenames {
ranges := d.parseFile(filename)
sort.Sort(ranges)
d.files[filename] = ranges
}
return nil
}
// Takes a set of ignoredRanges, determines if they immediately precede a statement
// construct, and expands the range to include that construct. Why? So you can
// precede a function or struct with //nolint
@ -150,7 +191,28 @@ func filterIssuesViaDirectives(directives *directiveParser, issues chan *Issue)
out <- issue
}
}
if config.WarnUnmatchedDirective {
for _, issue := range warnOnUnusedDirective(directives) {
out <- issue
}
}
close(out)
}()
return out
}
func warnOnUnusedDirective(directives *directiveParser) []*Issue {
out := []*Issue{}
for path, ranges := range directives.Unmatched() {
for _, ignore := range ranges {
issue, _ := NewIssue("nolint", config.formatTemplate)
issue.Path = path
issue.Line = ignore.start
issue.Col = ignore.col
issue.Message = "nolint directive did not match any issue"
out = append(out, issue)
}
}
return out
}