cmd/govulncheck: move package loading to internal/govulncheck
Move the code to load packages into internal/govulncheck so it
can be shared with gopls.
Change-Id: I3a3e6e055b3640639a5978cfd36791ea1884c9ad
Reviewed-on: https://go-review.googlesource.com/c/vuln/+/406581
TryBot-Result: Gopher Robot <gobot@golang.org>
Run-TryBot: Jonathan Amsterdam <jba@google.com>
Reviewed-by: Zvonimir Pavlinovic <zpavlinovic@google.com>
Reviewed-by: Hyang-Ah Hana Kim <hyangah@gmail.com>
diff --git a/cmd/govulncheck/internal/govulncheck/source.go b/cmd/govulncheck/internal/govulncheck/source.go
new file mode 100644
index 0000000..155ddf1
--- /dev/null
+++ b/cmd/govulncheck/internal/govulncheck/source.go
@@ -0,0 +1,52 @@
+// Copyright 2022 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+package govulncheck
+
+import (
+ "fmt"
+ "strings"
+
+ "golang.org/x/tools/go/packages"
+ "golang.org/x/vuln/vulncheck"
+)
+
+// A PackageError contains errors from loading a set of packages.
+type PackageError struct {
+ Errors []packages.Error
+}
+
+func (e *PackageError) Error() string {
+ var b strings.Builder
+ fmt.Fprintln(&b, "Packages contain errors:")
+ for _, e := range e.Errors {
+ fmt.Println(&b, e)
+ }
+ return b.String()
+}
+
+// LoadPackages loads the packages matching patterns using cfg, after setting
+// the cfg mode flags that vulncheck needs for analysis.
+// If the packages contain errors, a PackageError is returned containing a list of the errors,
+// along with the packages themselves.
+func LoadPackages(cfg *packages.Config, patterns ...string) ([]*vulncheck.Package, error) {
+ cfg.Mode |= packages.NeedName | packages.NeedFiles | packages.NeedCompiledGoFiles |
+ packages.NeedImports | packages.NeedTypes | packages.NeedTypesSizes |
+ packages.NeedSyntax | packages.NeedTypesInfo | packages.NeedDeps |
+ packages.NeedModule
+
+ pkgs, err := packages.Load(cfg, patterns...)
+ vpkgs := vulncheck.Convert(pkgs)
+ if err != nil {
+ return nil, err
+ }
+ var perrs []packages.Error
+ packages.Visit(pkgs, nil, func(p *packages.Package) {
+ perrs = append(perrs, p.Errors...)
+ })
+ if len(perrs) > 0 {
+ err = &PackageError{perrs}
+ }
+ return vpkgs, err
+}
diff --git a/cmd/govulncheck/main.go b/cmd/govulncheck/main.go
index 66ec2d7..a37dd23 100644
--- a/cmd/govulncheck/main.go
+++ b/cmd/govulncheck/main.go
@@ -99,7 +99,7 @@
patterns := flag.Args()
var (
r *vulncheck.Result
- pkgs []*packages.Package
+ pkgs []*vulncheck.Package
vulns []*vulncheck.Vuln
)
if len(patterns) == 1 && isFile(patterns[0]) {
@@ -115,7 +115,6 @@
vulns = r.Vulns
} else {
cfg := &packages.Config{
- Mode: packages.NeedName | packages.NeedFiles | packages.NeedCompiledGoFiles | packages.NeedImports | packages.NeedTypes | packages.NeedTypesSizes | packages.NeedSyntax | packages.NeedTypesInfo | packages.NeedDeps | packages.NeedModule,
Tests: *testsFlag,
BuildFlags: []string{fmt.Sprintf("-tags=%s", strings.Join(build.Default.BuildTags, ","))},
}
@@ -123,7 +122,7 @@
if err != nil {
die("govulncheck: %v", err)
}
- r, err = vulncheck.Source(ctx, vulncheck.Convert(pkgs), vcfg)
+ r, err = vulncheck.Source(ctx, pkgs, vcfg)
if err != nil {
die("govulncheck: %v", err)
}
@@ -262,17 +261,14 @@
return !s.IsDir()
}
-func loadPackages(cfg *packages.Config, patterns []string) ([]*packages.Package, error) {
+func loadPackages(cfg *packages.Config, patterns []string) ([]*vulncheck.Package, error) {
if *verboseFlag {
log.Println("loading packages...")
}
- pkgs, err := packages.Load(cfg, patterns...)
+ pkgs, err := govulncheck.LoadPackages(cfg, patterns...)
if err != nil {
return nil, err
}
- if packages.PrintErrors(pkgs) > 0 {
- return nil, fmt.Errorf("packages contain errors")
- }
if *verboseFlag {
log.Printf("\t%d loaded packages\n", len(pkgs))
}