From 4f495a16ec1f418648f3659e3b782815a92d3ca3 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Thu, 24 Jun 2021 13:09:07 -0400 Subject: [PATCH] Bump github.com/kisielk/errcheck from 1.4.0 to 1.6.0 (#119) Bumps [github.com/kisielk/errcheck](https://github.com/kisielk/errcheck) from 1.4.0 to 1.6.0. - [Release notes](https://github.com/kisielk/errcheck/releases) - [Commits](https://github.com/kisielk/errcheck/compare/v1.4.0...v1.6.0) --- updated-dependencies: - dependency-name: github.com/kisielk/errcheck dependency-type: direct:production update-type: version-update:semver-minor ... Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- go.mod | 2 +- go.sum | 4 +- .../github.com/kisielk/errcheck/.travis.yml | 38 -- vendor/github.com/kisielk/errcheck/README.md | 19 +- .../errcheck/embedded_walker.go | 0 .../{internal => }/errcheck/errcheck.go | 426 +++++++++--------- .../kisielk/errcheck/errcheck/tags.go | 12 + .../kisielk/errcheck/errcheck/tags_compat.go | 13 + vendor/github.com/kisielk/errcheck/main.go | 139 ++++-- vendor/modules.txt | 4 +- 10 files changed, 355 insertions(+), 302 deletions(-) delete mode 100644 vendor/github.com/kisielk/errcheck/.travis.yml rename vendor/github.com/kisielk/errcheck/{internal => }/errcheck/embedded_walker.go (100%) rename vendor/github.com/kisielk/errcheck/{internal => }/errcheck/errcheck.go (66%) create mode 100644 vendor/github.com/kisielk/errcheck/errcheck/tags.go create mode 100644 vendor/github.com/kisielk/errcheck/errcheck/tags_compat.go diff --git a/go.mod b/go.mod index c0f1c571..a04f6e04 100644 --- a/go.mod +++ b/go.mod @@ -8,7 +8,7 @@ require ( github.com/google/go-containerregistry v0.4.0 github.com/hashicorp/go-version v1.3.0 github.com/k14s/imgpkg v0.3.0 - github.com/kisielk/errcheck v1.4.0 + github.com/kisielk/errcheck v1.6.0 github.com/spf13/cobra v1.0.0 github.com/vmware-tanzu/carvel-vendir v0.17.0 golang.org/x/sync v0.0.0-20201207232520-09787c993a3a diff --git a/go.sum b/go.sum index ad316829..280ffb25 100644 --- a/go.sum +++ b/go.sum @@ -266,8 +266,8 @@ github.com/k14s/imgpkg v0.3.0 h1:WR0U9ZbTf2W68k0hoA6u28cDKvCiSE9UEKv7PxZy1zA= github.com/k14s/imgpkg v0.3.0/go.mod h1:UawhPTP5NySKEa+LW224ZlDccGb4qbSaiCyadSxgMSE= github.com/kisielk/errcheck v1.1.0/go.mod h1:EZBBE59ingxPouuu3KfxchcWSUPOHkagtvWXihfKN4Q= github.com/kisielk/errcheck v1.2.0/go.mod h1:/BMXB+zMLi60iA8Vv6Ksmxu/1UDYcXs4uQLJ+jE2L00= -github.com/kisielk/errcheck v1.4.0 h1:ueN6QYA+c7eDQo7ebpNdYR8mUJZThiGz9PEoJEMGPzA= -github.com/kisielk/errcheck v1.4.0/go.mod h1:pFxgyoBC7bSaBwPgfKdkLd5X25qrDl4LWUI2bnpBCr8= +github.com/kisielk/errcheck v1.6.0 h1:YTDO4pNy7AUN/021p+JGHycQyYNIyMoenM1YDVK6RlY= +github.com/kisielk/errcheck v1.6.0/go.mod h1:pFxgyoBC7bSaBwPgfKdkLd5X25qrDl4LWUI2bnpBCr8= github.com/kisielk/gotool v1.0.0/go.mod h1:XhKaO+MFFWcvkIS/tQcRk01m1F5IRFswLeQ+oQHNcck= github.com/konsorten/go-windows-terminal-sequences v1.0.1/go.mod h1:T0+1ngSBFLxvqU3pZ+m/2kptfBszLMUkC4ZK/EgS/cQ= github.com/konsorten/go-windows-terminal-sequences v1.0.3/go.mod h1:T0+1ngSBFLxvqU3pZ+m/2kptfBszLMUkC4ZK/EgS/cQ= diff --git a/vendor/github.com/kisielk/errcheck/.travis.yml b/vendor/github.com/kisielk/errcheck/.travis.yml deleted file mode 100644 index 6e13d3a0..00000000 --- a/vendor/github.com/kisielk/errcheck/.travis.yml +++ /dev/null @@ -1,38 +0,0 @@ -language: go -sudo: false - -matrix: - include: - - go: "1.11.x" - env: {GO111MODULE: "off"} - - go: "1.11.x" - env: {GO111MODULE: "on"} - - go: "1.12.x" - env: {GO111MODULE: "off"} - - go: "1.12.x" - env: {GO111MODULE: "on"} - - go: "1.13.x" - env: {GO111MODULE: "off"} - - go: "1.13.x" - env: {GO111MODULE: "on"} - - go: "1.14.x" - env: {GO111MODULE: "off"} - - go: "1.14.x" - env: {GO111MODULE: "on"} - - go: "tip" - env: {GO111MODULE: "off"} - - go: "tip" - env: {GO111MODULE: "on"} - -install: | - if test -z "$(go env GOMOD)"; then - go get -d -t ./... && - ver=$(sed -n '/^require/s/.*[ -]//p' go.mod) && - ( - cd "$(go env GOPATH)/src/golang.org/x/tools" && - git checkout "$ver" - ) - fi - -script: - - go test -race ./... diff --git a/vendor/github.com/kisielk/errcheck/README.md b/vendor/github.com/kisielk/errcheck/README.md index f763ee17..484556b9 100644 --- a/vendor/github.com/kisielk/errcheck/README.md +++ b/vendor/github.com/kisielk/errcheck/README.md @@ -2,13 +2,13 @@ errcheck is a program for checking for unchecked errors in go programs. -[![Build Status](https://travis-ci.org/kisielk/errcheck.svg?branch=master)](https://travis-ci.org/kisielk/errcheck) +![errcheck](https://github.com/kisielk/errcheck/workflows/errcheck/badge.svg) ## Install go get -u github.com/kisielk/errcheck -errcheck requires Go 1.11 or newer, and depends on the package go/packages from the golang.org/x/tools repository. +errcheck requires Go 1.12 or newer, and depends on the package go/packages from the golang.org/x/tools repository. ## Use @@ -59,8 +59,11 @@ An example of an exclude file is: // Sometimes we don't care if a HTTP request fails. (*net/http.Client).Do -The exclude list is combined with an internal list for functions in the Go standard library that -have an error return type but are documented to never return an error. +By default, the exclude list is combined with an internal list for functions in +the Go standard library that have an error return type but are documented to never +return an error. To disable the built-in exclude list, pass the `-excludeonly` flag. + +Run errcheck in `-verbose` mode to see the resulting list of added excludes. When using vendored dependencies, specify the full import path. For example: * Your project's import path is `example.com/yourpkg` @@ -109,14 +112,6 @@ specified for it. To disable this, specify a regex that matches nothing: The `-ignoretests` flag disables checking of `_test.go` files. It takes no arguments. -## Cgo - -Currently errcheck is unable to check packages that import "C" due to limitations in the importer when used with versions earlier than Go 1.11. - -However, you can use errcheck on packages that depend on those which use cgo. In order for this to work you need to go install the cgo dependencies before running errcheck on the dependent packages. - -See https://github.com/kisielk/errcheck/issues/16 for more details. - ## Exit Codes errcheck returns 1 if any problems were found in the checked files. diff --git a/vendor/github.com/kisielk/errcheck/internal/errcheck/embedded_walker.go b/vendor/github.com/kisielk/errcheck/errcheck/embedded_walker.go similarity index 100% rename from vendor/github.com/kisielk/errcheck/internal/errcheck/embedded_walker.go rename to vendor/github.com/kisielk/errcheck/errcheck/embedded_walker.go diff --git a/vendor/github.com/kisielk/errcheck/internal/errcheck/errcheck.go b/vendor/github.com/kisielk/errcheck/errcheck/errcheck.go similarity index 66% rename from vendor/github.com/kisielk/errcheck/internal/errcheck/errcheck.go rename to vendor/github.com/kisielk/errcheck/errcheck/errcheck.go index e1548bac..724e3e88 100644 --- a/vendor/github.com/kisielk/errcheck/internal/errcheck/errcheck.go +++ b/vendor/github.com/kisielk/errcheck/errcheck/errcheck.go @@ -1,6 +1,4 @@ // Package errcheck is the library used to implement the errcheck command-line tool. -// -// Note: The API of this package has not been finalized and may change at any point. package errcheck import ( @@ -11,12 +9,9 @@ import ( "go/token" "go/types" "os" - "os/exec" "regexp" - "runtime" "sort" "strings" - "sync" "golang.org/x/tools/go/packages" ) @@ -25,107 +20,16 @@ var errorType *types.Interface func init() { errorType = types.Universe.Lookup("error").Type().Underlying().(*types.Interface) - } var ( // ErrNoGoFiles is returned when CheckPackage is run on a package with no Go source files ErrNoGoFiles = errors.New("package contains no go source files") -) - -// UncheckedError indicates the position of an unchecked error return. -type UncheckedError struct { - Pos token.Position - Line string - FuncName string -} - -// UncheckedErrors is returned from the CheckPackage function if the package contains -// any unchecked errors. -// Errors should be appended using the Append method, which is safe to use concurrently. -type UncheckedErrors struct { - mu sync.Mutex - - // Errors is a list of all the unchecked errors in the package. - // Printing an error reports its position within the file and the contents of the line. - Errors []UncheckedError -} - -func (e *UncheckedErrors) Append(errors ...UncheckedError) { - e.mu.Lock() - defer e.mu.Unlock() - e.Errors = append(e.Errors, errors...) -} - -func (e *UncheckedErrors) Error() string { - return fmt.Sprintf("%d unchecked errors", len(e.Errors)) -} - -// Len is the number of elements in the collection. -func (e *UncheckedErrors) Len() int { return len(e.Errors) } - -// Swap swaps the elements with indexes i and j. -func (e *UncheckedErrors) Swap(i, j int) { e.Errors[i], e.Errors[j] = e.Errors[j], e.Errors[i] } - -type byName struct{ *UncheckedErrors } - -// Less reports whether the element with index i should sort before the element with index j. -func (e byName) Less(i, j int) bool { - ei, ej := e.Errors[i], e.Errors[j] - - pi, pj := ei.Pos, ej.Pos - - if pi.Filename != pj.Filename { - return pi.Filename < pj.Filename - } - if pi.Line != pj.Line { - return pi.Line < pj.Line - } - if pi.Column != pj.Column { - return pi.Column < pj.Column - } - return ei.Line < ej.Line -} - -type Checker struct { - // ignore is a map of package names to regular expressions. Identifiers from a package are - // checked against its regular expressions and if any of the expressions match the call - // is not checked. - Ignore map[string]*regexp.Regexp - - // If blank is true then assignments to the blank identifier are also considered to be - // ignored errors. - Blank bool - - // If asserts is true then ignored type assertion results are also checked - Asserts bool - - // build tags - Tags []string - - Verbose bool - - // If true, checking of _test.go files is disabled - WithoutTests bool - - // If true, checking of files with generated code is disabled - WithoutGeneratedCode bool - - exclude map[string]bool -} - -func NewChecker() *Checker { - c := Checker{} - c.SetExclude(map[string]bool{}) - return &c -} - -func (c *Checker) SetExclude(l map[string]bool) { - c.exclude = map[string]bool{} - - // Default exclude for stdlib functions - for _, exc := range []string{ + // DefaultExcludedSymbols is a list of symbol names that are usually excluded from checks by default. + // + // Note, that they still need to be explicitly copied to Checker.Exclusions.Symbols + DefaultExcludedSymbols = []string{ // bytes "(*bytes.Buffer).Write", "(*bytes.Buffer).WriteByte", @@ -159,19 +63,134 @@ func (c *Checker) SetExclude(l map[string]bool) { // hash "(hash.Hash).Write", - } { - c.exclude[exc] = true } +) + +// UncheckedError indicates the position of an unchecked error return. +type UncheckedError struct { + Pos token.Position + Line string + FuncName string + SelectorName string +} + +// Result is returned from the CheckPackage function, and holds all the errors +// that were found to be unchecked in a package. +// +// Aggregation can be done using the Append method for users that want to +// combine results from multiple packages. +type Result struct { + // UncheckedErrors is a list of all the unchecked errors in the package. + // Printing an error reports its position within the file and the contents of the line. + UncheckedErrors []UncheckedError +} + +type byName []UncheckedError + +// Less reports whether the element with index i should sort before the element with index j. +func (b byName) Less(i, j int) bool { + ei, ej := b[i], b[j] + + pi, pj := ei.Pos, ej.Pos - for k := range l { - c.exclude[k] = true + if pi.Filename != pj.Filename { + return pi.Filename < pj.Filename + } + if pi.Line != pj.Line { + return pi.Line < pj.Line + } + if pi.Column != pj.Column { + return pi.Column < pj.Column } + + return ei.Line < ej.Line +} + +func (b byName) Swap(i, j int) { + b[i], b[j] = b[j], b[i] +} + +func (b byName) Len() int { + return len(b) +} + +// Append appends errors to e. Append does not do any duplicate checking. +func (r *Result) Append(other Result) { + r.UncheckedErrors = append(r.UncheckedErrors, other.UncheckedErrors...) } -func (c *Checker) logf(msg string, args ...interface{}) { - if c.Verbose { - fmt.Fprintf(os.Stderr, msg+"\n", args...) +// Returns the unique errors that have been accumulated. Duplicates may occur +// when a file containing an unchecked error belongs to > 1 package. +// +// The method receiver remains unmodified after the call to Unique. +func (r Result) Unique() Result { + result := make([]UncheckedError, len(r.UncheckedErrors)) + copy(result, r.UncheckedErrors) + sort.Sort((byName)(result)) + uniq := result[:0] // compact in-place + for i, err := range result { + if i == 0 || err != result[i-1] { + uniq = append(uniq, err) + } } + return Result{UncheckedErrors: uniq} +} + +// Exclusions define symbols and language elements that will be not checked +type Exclusions struct { + + // Packages lists paths of excluded packages. + Packages []string + + // SymbolRegexpsByPackage maps individual package paths to regular + // expressions that match symbols to be excluded. + // + // Packages whose paths appear both here and in Packages list will + // be excluded entirely. + // + // This is a legacy input that will be deprecated in errcheck version 2 and + // should not be used. + SymbolRegexpsByPackage map[string]*regexp.Regexp + + // Symbols lists patterns that exclude individual package symbols. + // + // For example: + // + // "fmt.Errorf" // function + // "fmt.Fprintf(os.Stderr)" // function with set argument value + // "(hash.Hash).Write" // method + // + Symbols []string + + // TestFiles excludes _test.go files. + TestFiles bool + + // GeneratedFiles excludes generated source files. + // + // Source file is assumed to be generated if its contents + // match the following regular expression: + // + // ^// Code generated .* DO NOT EDIT\\.$ + // + GeneratedFiles bool + + // BlankAssignments ignores assignments to blank identifier. + BlankAssignments bool + + // TypeAssertions ignores unchecked type assertions. + TypeAssertions bool +} + +// Checker checks that you checked errors. +type Checker struct { + // Exclusions defines code packages, symbols, and other elements that will not be checked. + Exclusions Exclusions + + // Tags are a list of build tags to use. + Tags []string + + // The mod flag for go build. + Mod string } // loadPackages is used for testing. @@ -179,19 +198,26 @@ var loadPackages = func(cfg *packages.Config, paths ...string) ([]*packages.Pack return packages.Load(cfg, paths...) } -func (c *Checker) load(paths ...string) ([]*packages.Package, error) { +// LoadPackages loads all the packages in all the paths provided. It uses the +// exclusions and build tags provided to by the user when loading the packages. +func (c *Checker) LoadPackages(paths ...string) ([]*packages.Package, error) { + buildFlags := []string{fmtTags(c.Tags)} + if c.Mod != "" { + buildFlags = append(buildFlags, fmt.Sprintf("-mod=%s", c.Mod)) + } cfg := &packages.Config{ Mode: packages.LoadAllSyntax, - Tests: !c.WithoutTests, - BuildFlags: []string{fmt.Sprintf("-tags=%s", strings.Join(c.Tags, " "))}, + Tests: !c.Exclusions.TestFiles, + BuildFlags: buildFlags, } return loadPackages(cfg, paths...) } var generatedCodeRegexp = regexp.MustCompile("^// Code generated .* DO NOT EDIT\\.$") +var dotStar = regexp.MustCompile(".*") func (c *Checker) shouldSkipFile(file *ast.File) bool { - if !c.WithoutGeneratedCode { + if !c.Exclusions.GeneratedFiles { return false } @@ -206,94 +232,57 @@ func (c *Checker) shouldSkipFile(file *ast.File) bool { return false } -// CheckPackages checks packages for errors. -func (c *Checker) CheckPackages(paths ...string) error { - pkgs, err := c.load(paths...) - if err != nil { - return err - } - // Check for errors in the initial packages. - work := make(chan *packages.Package, len(pkgs)) - for _, pkg := range pkgs { - if len(pkg.Errors) > 0 { - return fmt.Errorf("errors while loading package %s: %v", pkg.ID, pkg.Errors) - } - work <- pkg - } - close(work) - - gomod, err := exec.Command("go", "env", "GOMOD").Output() - go111module := (err == nil) && strings.TrimSpace(string(gomod)) != "" - ignore := c.Ignore - if go111module { - ignore = make(map[string]*regexp.Regexp) - for pkg, re := range c.Ignore { - if nonVendoredPkg, ok := nonVendoredPkgPath(pkg); ok { - ignore[nonVendoredPkg] = re - } else { - ignore[pkg] = re - } +// CheckPackage checks packages for errors that have not been checked. +// +// It will exclude specific errors from analysis if the user has configured +// exclusions. +func (c *Checker) CheckPackage(pkg *packages.Package) Result { + excludedSymbols := map[string]bool{} + for _, sym := range c.Exclusions.Symbols { + excludedSymbols[sym] = true + } + + ignore := map[string]*regexp.Regexp{} + // Apply SymbolRegexpsByPackage first so that if the same path appears in + // Packages, a more narrow regexp will be superceded by dotStar below. + if regexps := c.Exclusions.SymbolRegexpsByPackage; regexps != nil { + for pkg, re := range regexps { + // TODO warn if previous entry overwritten? + ignore[nonVendoredPkgPath(pkg)] = re } } + for _, pkg := range c.Exclusions.Packages { + // TODO warn if previous entry overwritten? + ignore[nonVendoredPkgPath(pkg)] = dotStar + } - var wg sync.WaitGroup - u := &UncheckedErrors{} - for i := 0; i < runtime.NumCPU(); i++ { - wg.Add(1) - - go func() { - defer wg.Done() - for pkg := range work { - c.logf("Checking %s", pkg.Types.Path()) - - v := &visitor{ - pkg: pkg, - ignore: ignore, - blank: c.Blank, - asserts: c.Asserts, - lines: make(map[string][]string), - exclude: c.exclude, - go111module: go111module, - errors: []UncheckedError{}, - } + v := &visitor{ + pkg: pkg, + ignore: ignore, + blank: !c.Exclusions.BlankAssignments, + asserts: !c.Exclusions.TypeAssertions, + lines: make(map[string][]string), + exclude: excludedSymbols, + errors: []UncheckedError{}, + } - for _, astFile := range v.pkg.Syntax { - if c.shouldSkipFile(astFile) { - continue - } - ast.Walk(v, astFile) - } - u.Append(v.errors...) - } - }() - } - - wg.Wait() - if u.Len() > 0 { - // Sort unchecked errors and remove duplicates. Duplicates may occur when a file - // containing an unchecked error belongs to > 1 package. - sort.Sort(byName{u}) - uniq := u.Errors[:0] // compact in-place - for i, err := range u.Errors { - if i == 0 || err != u.Errors[i-1] { - uniq = append(uniq, err) - } + for _, astFile := range v.pkg.Syntax { + if c.shouldSkipFile(astFile) { + continue } - u.Errors = uniq - return u + ast.Walk(v, astFile) } - return nil + return Result{UncheckedErrors: v.errors} } // visitor implements the errcheck algorithm type visitor struct { - pkg *packages.Package - ignore map[string]*regexp.Regexp - blank bool - asserts bool - lines map[string][]string - exclude map[string]bool - go111module bool + pkg *packages.Package + ignore map[string]*regexp.Regexp + blank bool + asserts bool + lines map[string][]string + exclude map[string]bool errors []UncheckedError } @@ -347,6 +336,37 @@ func (v *visitor) fullName(call *ast.CallExpr) string { return fn.FullName() } +func getSelectorName(sel *ast.SelectorExpr) string { + if ident, ok := sel.X.(*ast.Ident); ok { + return fmt.Sprintf("%s.%s", ident.Name, sel.Sel.Name) + } + if s, ok := sel.X.(*ast.SelectorExpr); ok { + return fmt.Sprintf("%s.%s", getSelectorName(s), sel.Sel.Name) + } + + return "" +} + +// selectorName will return a name for a called function +// if the function is the result of a selector. Otherwise it will return +// the empty string. +// +// The name is fully qualified by the import path, possible type, +// function/method name and pointer receiver. +// +// For example, +// - for "fmt.Printf(...)" it will return "fmt.Printf" +// - for "base64.StdEncoding.Decode(...)" it will return "base64.StdEncoding.Decode" +// - for "myFunc()" it will return "" +func (v *visitor) selectorName(call *ast.CallExpr) string { + sel, _, ok := v.selectorAndFunc(call) + if !ok { + return "" + } + + return getSelectorName(sel) +} + // namesForExcludeCheck will return a list of fully-qualified function names // from a function call that can be used to check against the exclusion list. // @@ -456,34 +476,24 @@ func (v *visitor) ignoreCall(call *ast.CallExpr) bool { if obj := v.pkg.TypesInfo.Uses[id]; obj != nil { if pkg := obj.Pkg(); pkg != nil { - if re, ok := v.ignore[pkg.Path()]; ok { + if re, ok := v.ignore[nonVendoredPkgPath(pkg.Path())]; ok { return re.MatchString(id.Name) } - - // if current package being considered is vendored, check to see if it should be ignored based - // on the unvendored path. - if !v.go111module { - if nonVendoredPkg, ok := nonVendoredPkgPath(pkg.Path()); ok { - if re, ok := v.ignore[nonVendoredPkg]; ok { - return re.MatchString(id.Name) - } - } - } } } return false } -// nonVendoredPkgPath returns the unvendored version of the provided package path (or returns the provided path if it -// does not represent a vendored path). The second return value is true if the provided package was vendored, false -// otherwise. -func nonVendoredPkgPath(pkgPath string) (string, bool) { +// nonVendoredPkgPath returns the unvendored version of the provided package +// path (or returns the provided path if it does not represent a vendored +// path). +func nonVendoredPkgPath(pkgPath string) string { lastVendorIndex := strings.LastIndex(pkgPath, "/vendor/") if lastVendorIndex == -1 { - return pkgPath, false + return pkgPath } - return pkgPath[lastVendorIndex+len("/vendor/"):], true + return pkgPath[lastVendorIndex+len("/vendor/"):] } // errorsByArg returns a slice s such that @@ -553,11 +563,13 @@ func (v *visitor) addErrorAtPosition(position token.Pos, call *ast.CallExpr) { } var name string + var sel string if call != nil { name = v.fullName(call) + sel = v.selectorName(call) } - v.errors = append(v.errors, UncheckedError{pos, line, name}) + v.errors = append(v.errors, UncheckedError{pos, line, name, sel}) } func readfile(filename string) []string { diff --git a/vendor/github.com/kisielk/errcheck/errcheck/tags.go b/vendor/github.com/kisielk/errcheck/errcheck/tags.go new file mode 100644 index 00000000..7b423ca6 --- /dev/null +++ b/vendor/github.com/kisielk/errcheck/errcheck/tags.go @@ -0,0 +1,12 @@ +// +build go1.13 + +package errcheck + +import ( + "fmt" + "strings" +) + +func fmtTags(tags []string) string { + return fmt.Sprintf("-tags=%s", strings.Join(tags, ",")) +} diff --git a/vendor/github.com/kisielk/errcheck/errcheck/tags_compat.go b/vendor/github.com/kisielk/errcheck/errcheck/tags_compat.go new file mode 100644 index 00000000..2f534f40 --- /dev/null +++ b/vendor/github.com/kisielk/errcheck/errcheck/tags_compat.go @@ -0,0 +1,13 @@ +// +build go1.11 +// +build !go1.13 + +package errcheck + +import ( + "fmt" + "strings" +) + +func fmtTags(tags []string) string { + return fmt.Sprintf("-tags=%s", strings.Join(tags, " ")) +} diff --git a/vendor/github.com/kisielk/errcheck/main.go b/vendor/github.com/kisielk/errcheck/main.go index da37140e..641aa548 100644 --- a/vendor/github.com/kisielk/errcheck/main.go +++ b/vendor/github.com/kisielk/errcheck/main.go @@ -11,8 +11,10 @@ import ( "regexp" "runtime" "strings" + "sync" - "github.com/kisielk/errcheck/internal/errcheck" + "github.com/kisielk/errcheck/errcheck" + "golang.org/x/tools/go/packages" ) const ( @@ -21,10 +23,14 @@ const ( exitFatalError ) -var abspath bool - type ignoreFlag map[string]*regexp.Regexp +// global flags +var ( + abspath bool + verbose bool +) + func (f ignoreFlag) String() string { pairs := make([]string, 0, len(f)) for pkg, re := range f { @@ -63,17 +69,16 @@ func (f ignoreFlag) Set(s string) error { type tagsFlag []string func (f *tagsFlag) String() string { - return fmt.Sprintf("%q", strings.Join(*f, " ")) + return fmt.Sprintf("%q", strings.Join(*f, ",")) } func (f *tagsFlag) Set(s string) error { if s == "" { return nil } - tags := strings.Split(s, " ") - if tags == nil { - return nil - } + tags := strings.FieldsFunc(s, func(c rune) bool { + return c == ' ' || c == ',' + }) for _, tag := range tags { if tag != "" { *f = append(*f, tag) @@ -82,14 +87,12 @@ func (f *tagsFlag) Set(s string) error { return nil } -var dotStar = regexp.MustCompile(".*") - -func reportUncheckedErrors(e *errcheck.UncheckedErrors, verbose bool) { +func reportResult(e errcheck.Result) { wd, err := os.Getwd() if err != nil { wd = "" } - for _, uncheckedError := range e.Errors { + for _, uncheckedError := range e.UncheckedErrors { pos := uncheckedError.Pos.String() if !abspath { newPos, err := filepath.Rel(wd, pos) @@ -106,41 +109,87 @@ func reportUncheckedErrors(e *errcheck.UncheckedErrors, verbose bool) { } } -func mainCmd(args []string) int { - runtime.GOMAXPROCS(runtime.NumCPU()) +func logf(msg string, args ...interface{}) { + if verbose { + fmt.Fprintf(os.Stderr, msg+"\n", args...) + } +} - checker := errcheck.NewChecker() - paths, err := parseFlags(checker, args) - if err != exitCodeOk { - return err +func mainCmd(args []string) int { + var checker errcheck.Checker + paths, rc := parseFlags(&checker, args) + if rc != exitCodeOk { + return rc } - if err := checker.CheckPackages(paths...); err != nil { - if e, ok := err.(*errcheck.UncheckedErrors); ok { - reportUncheckedErrors(e, checker.Verbose) - return exitUncheckedError - } else if err == errcheck.ErrNoGoFiles { + result, err := checkPaths(&checker, paths...) + if err != nil { + if err == errcheck.ErrNoGoFiles { fmt.Fprintln(os.Stderr, err) return exitCodeOk } fmt.Fprintf(os.Stderr, "error: failed to check packages: %s\n", err) return exitFatalError } + if len(result.UncheckedErrors) > 0 { + reportResult(result) + return exitUncheckedError + } return exitCodeOk } +func checkPaths(c *errcheck.Checker, paths ...string) (errcheck.Result, error) { + pkgs, err := c.LoadPackages(paths...) + if err != nil { + return errcheck.Result{}, err + } + // Check for errors in the initial packages. + work := make(chan *packages.Package, len(pkgs)) + for _, pkg := range pkgs { + if len(pkg.Errors) > 0 { + return errcheck.Result{}, fmt.Errorf("errors while loading package %s: %v", pkg.ID, pkg.Errors) + } + work <- pkg + } + close(work) + + var wg sync.WaitGroup + result := &errcheck.Result{} + mu := &sync.Mutex{} + for i := 0; i < runtime.NumCPU(); i++ { + wg.Add(1) + + go func() { + defer wg.Done() + for pkg := range work { + logf("checking %s", pkg.Types.Path()) + r := c.CheckPackage(pkg) + mu.Lock() + result.Append(r) + mu.Unlock() + } + }() + } + + wg.Wait() + return result.Unique(), nil +} + func parseFlags(checker *errcheck.Checker, args []string) ([]string, int) { flags := flag.NewFlagSet(args[0], flag.ContinueOnError) - flags.BoolVar(&checker.Blank, "blank", false, "if true, check for errors assigned to blank identifier") - flags.BoolVar(&checker.Asserts, "asserts", false, "if true, check for ignored type assertion results") - flags.BoolVar(&checker.WithoutTests, "ignoretests", false, "if true, checking of _test.go files is disabled") - flags.BoolVar(&checker.WithoutGeneratedCode, "ignoregenerated", false, "if true, checking of files with generated code is disabled") - flags.BoolVar(&checker.Verbose, "verbose", false, "produce more verbose logging") + + var checkAsserts, checkBlanks bool + + flags.BoolVar(&checkBlanks, "blank", false, "if true, check for errors assigned to blank identifier") + flags.BoolVar(&checkAsserts, "asserts", false, "if true, check for ignored type assertion results") + flags.BoolVar(&checker.Exclusions.TestFiles, "ignoretests", false, "if true, checking of _test.go files is disabled") + flags.BoolVar(&checker.Exclusions.GeneratedFiles, "ignoregenerated", false, "if true, checking of files with generated code is disabled") + flags.BoolVar(&verbose, "verbose", false, "produce more verbose logging") flags.BoolVar(&abspath, "abspath", false, "print absolute paths to files") tags := tagsFlag{} - flags.Var(&tags, "tags", "space-separated list of build tags to include") + flags.Var(&tags, "tags", "comma or space-separated list of build tags to include") ignorePkg := flags.String("ignorepkg", "", "comma-separated list of package paths to ignore") ignore := ignoreFlag(map[string]*regexp.Regexp{}) flags.Var(ignore, "ignore", "[deprecated] comma-separated list of pairs of the form pkg:regex\n"+ @@ -149,43 +198,52 @@ func parseFlags(checker *errcheck.Checker, args []string) ([]string, int) { var excludeFile string flags.StringVar(&excludeFile, "exclude", "", "Path to a file containing a list of functions to exclude from checking") + var excludeOnly bool + flags.BoolVar(&excludeOnly, "excludeonly", false, "Use only excludes from -exclude file") + + flags.StringVar(&checker.Mod, "mod", "", "module download mode to use: readonly or vendor. See 'go help modules' for more.") + if err := flags.Parse(args[1:]); err != nil { return nil, exitFatalError } + checker.Exclusions.BlankAssignments = !checkBlanks + checker.Exclusions.TypeAssertions = !checkAsserts + + if !excludeOnly { + checker.Exclusions.Symbols = append(checker.Exclusions.Symbols, errcheck.DefaultExcludedSymbols...) + } + if excludeFile != "" { excludes, err := readExcludes(excludeFile) if err != nil { fmt.Fprintf(os.Stderr, "Could not read exclude file: %v\n", err) return nil, exitFatalError } - if checker.Verbose { - for _, exclude := range excludes { - fmt.Printf("Excluding %v\n", exclude) - } - } - checker.SetExclude(excludes) + checker.Exclusions.Symbols = append(checker.Exclusions.Symbols, excludes...) } checker.Tags = tags for _, pkg := range strings.Split(*ignorePkg, ",") { if pkg != "" { - ignore[pkg] = dotStar + checker.Exclusions.Packages = append(checker.Exclusions.Packages, pkg) } } - checker.Ignore = ignore + + checker.Exclusions.SymbolRegexpsByPackage = ignore paths := flags.Args() if len(paths) == 0 { paths = []string{"."} } + return paths, exitCodeOk } // readExcludes reads an excludes file, a newline delimited file that lists // patterns for which to allow unchecked errors. -func readExcludes(path string) (map[string]bool, error) { - excludes := map[string]bool{} +func readExcludes(path string) ([]string, error) { + var excludes []string buf, err := ioutil.ReadFile(path) if err != nil { @@ -193,13 +251,14 @@ func readExcludes(path string) (map[string]bool, error) { } scanner := bufio.NewScanner(bytes.NewReader(buf)) + for scanner.Scan() { name := scanner.Text() // Skip comments and empty lines. if strings.HasPrefix(name, "//") || name == "" { continue } - excludes[name] = true + excludes = append(excludes, name) } if err := scanner.Err(); err != nil { return nil, err diff --git a/vendor/modules.txt b/vendor/modules.txt index 5abda6fb..e869d5bc 100644 --- a/vendor/modules.txt +++ b/vendor/modules.txt @@ -56,10 +56,10 @@ github.com/json-iterator/go # github.com/k14s/imgpkg v0.3.0 ## explicit github.com/k14s/imgpkg/pkg/imgpkg/lockconfig -# github.com/kisielk/errcheck v1.4.0 +# github.com/kisielk/errcheck v1.6.0 ## explicit github.com/kisielk/errcheck -github.com/kisielk/errcheck/internal/errcheck +github.com/kisielk/errcheck/errcheck # github.com/mattn/go-colorable v0.0.9 github.com/mattn/go-colorable # github.com/mattn/go-isatty v0.0.4