Skip to content

CheckPackage function #188

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 1 commit into from
Aug 31, 2020
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
105 changes: 62 additions & 43 deletions errcheck/errcheck.go
Original file line number Diff line number Diff line change
Expand Up @@ -205,8 +205,59 @@ func (c *Checker) shouldSkipFile(file *ast.File) bool {
return false
}

// CheckPackages checks packages for errors.
func (c *Checker) CheckPackages(paths ...string) error {
var (
goModStatus bool
goModOnce sync.Once
)

func isGoMod() bool {
goModOnce.Do(func() {
gomod, err := exec.Command("go", "env", "GOMOD").Output()
goModStatus = (err == nil) && strings.TrimSpace(string(gomod)) != ""
})
return goModStatus
}

// CheckPaths checks packages for errors.
func (c *Checker) CheckPackage(pkg *packages.Package) []UncheckedError {
c.logf("Checking %s", pkg.Types.Path())

v := &visitor{
pkg: pkg,
ignore: c.Ignore,
blank: c.Blank,
asserts: c.Asserts,
lines: make(map[string][]string),
exclude: c.exclude,
errors: []UncheckedError{},
}

for _, astFile := range v.pkg.Syntax {
if c.shouldSkipFile(astFile) {
continue
}
ast.Walk(v, astFile)
}
return v.errors
}

// UpdateNonVendoredIgnore updates the Ignores to use non vendored paths
func (c *Checker) UpdateNonVendoredIgnore() {
if isGoMod() {
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
}
}
c.Ignore = ignore
}
}

// CheckPaths checks packages for errors.
func (c *Checker) CheckPaths(paths ...string) error {
pkgs, err := c.load(paths...)
if err != nil {
return err
Expand All @@ -221,19 +272,7 @@ func (c *Checker) CheckPackages(paths ...string) error {
}
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
}
}
}
c.UpdateNonVendoredIgnore()

var wg sync.WaitGroup
u := &UncheckedErrors{}
Expand All @@ -243,26 +282,7 @@ func (c *Checker) CheckPackages(paths ...string) error {
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{},
}

for _, astFile := range v.pkg.Syntax {
if c.shouldSkipFile(astFile) {
continue
}
ast.Walk(v, astFile)
}
u.Append(v.errors...)
u.Append(c.CheckPackage(pkg)...)
}
}()
}
Expand All @@ -286,13 +306,12 @@ func (c *Checker) CheckPackages(paths ...string) error {

// 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
}
Expand Down Expand Up @@ -461,7 +480,7 @@ func (v *visitor) ignoreCall(call *ast.CallExpr) bool {

// if current package being considered is vendored, check to see if it should be ignored based
// on the unvendored path.
if !v.go111module {
if !isGoMod() {
if nonVendoredPkg, ok := nonVendoredPkgPath(pkg.Path()); ok {
if re, ok := v.ignore[nonVendoredPkg]; ok {
return re.MatchString(id.Name)
Expand Down
8 changes: 4 additions & 4 deletions errcheck/errcheck_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -176,7 +176,7 @@ package custom
pkgs, err := packages.Load(cfg, paths...)
return pkgs, err
}
err := checker.CheckPackages("github.com/testbuildtags")
err := checker.CheckPaths("github.com/testbuildtags")

if currCase.numExpectedErrs == 0 {
if err != nil {
Expand Down Expand Up @@ -282,7 +282,7 @@ require github.com/testlog v0.0.0
pkgs, err := packages.Load(cfg, paths...)
return pkgs, err
}
err := checker.CheckPackages("github.com/testvendor")
err := checker.CheckPaths("github.com/testvendor")

if currCase.numExpectedErrs == 0 {
if err != nil {
Expand Down Expand Up @@ -378,7 +378,7 @@ require github.com/testlog v0.0.0
pkgs, err := packages.Load(cfg, paths...)
return pkgs, err
}
err := checker.CheckPackages(path.Join("github.com/testvendor"))
err := checker.CheckPaths(path.Join("github.com/testvendor"))

if currCase.numExpectedErrs == 0 {
if err != nil {
Expand Down Expand Up @@ -411,7 +411,7 @@ func test(t *testing.T, f flags) {
checker.AddExcludes([]string{
fmt.Sprintf("(%s.ErrorMakerInterface).MakeNilError", testPackage),
})
err := checker.CheckPackages(testPackage)
err := checker.CheckPaths(testPackage)
uerr, ok := err.(*UncheckedErrors)
if !ok {
t.Fatalf("wrong error type returned: %v", err)
Expand Down
2 changes: 1 addition & 1 deletion main.go
Original file line number Diff line number Diff line change
Expand Up @@ -111,7 +111,7 @@ func mainCmd(args []string) int {
return err
}

if err := checker.CheckPackages(paths...); err != nil {
if err := checker.CheckPaths(paths...); err != nil {
if e, ok := err.(*errcheck.UncheckedErrors); ok {
reportUncheckedErrors(e, checker.Verbose)
return exitUncheckedError
Expand Down