internal/scan: improve error message for govulncheck - Previously, an error was not returned if the govulncheck function was called without any patterns. - Now if patterns are not included, then an explicit error is returned indicating to users that they should specify patterns or simply use `govulncheck ./...`. Fixes golang/go#77167 Change-Id: I539246a6f18b50937068ce9c984d0d3e4973c534 Reviewed-on: https://go-review.googlesource.com/c/vuln/+/736180 Reviewed-by: Roland Shoemaker <roland@golang.org> Auto-Submit: Ethan Lee <ethanalee@google.com> LUCI-TryBot-Result: Go LUCI <golang-scoped@luci-project-accounts.iam.gserviceaccount.com>
diff --git a/internal/scan/errors.go b/internal/scan/errors.go index c28e3c5..905e1e6 100644 --- a/internal/scan/errors.go +++ b/internal/scan/errors.go
@@ -11,7 +11,7 @@ //lint:file-ignore ST1005 Ignore staticcheck message about error formatting var ( - // ErrVulnerabilitiesFound indicates that vulnerabilities were detected + // errVulnerabilitiesFound indicates that vulnerabilities were detected // when running govulncheck. This returns exit status 3 when running // without the -json flag. errVulnerabilitiesFound = &exitCodeError{message: "vulnerabilities found", code: 3} @@ -25,6 +25,18 @@ // govulncheck and exit with status 2. errUsage = &exitCodeError{message: "invalid usage", code: 2} + // errNoPatterns indicates that no package patterns were provided if the scan level is WantPackages. + errNoPatterns = &exitCodeError{ + message: "no package patterns provided\n\nTo scan the current module, run: govulncheck ./...", + code: 2, + } + + // errNoPackagesMatched indicates that the provided patterns matched no packages if scan level is WantPackages. + errNoPackagesMatched = &exitCodeError{ + message: "no packages matched the provided patterns", + code: 2, + } + // errGoVersionMismatch is used to indicate that there is a mismatch between // the Go version used to build govulncheck and the one currently on PATH. errGoVersionMismatch = errors.New(`Loading packages failed, possibly due to a mismatch between the Go version
diff --git a/internal/scan/run_test.go b/internal/scan/run_test.go index 736804c..deb83a0 100644 --- a/internal/scan/run_test.go +++ b/internal/scan/run_test.go
@@ -5,7 +5,10 @@ package scan import ( + "bytes" + "context" "runtime/debug" + "strings" "testing" ) @@ -24,3 +27,32 @@ t.Errorf("got %s; want %s", got.ScannerVersion, want) } } + +func TestRunGovulncheck_NoPatternsError(t *testing.T) { + ctx := context.Background() + stdout := &bytes.Buffer{} + stderr := &bytes.Buffer{} + + err := RunGovulncheck(ctx, nil, nil, stdout, stderr, []string{}) + if err == nil { + t.Fatal("expected RunGovulncheck to return an error for missing patterns, got nil") + } + + wantMsg := "no package patterns provided" + if !strings.Contains(err.Error(), wantMsg) { + t.Errorf("got error: %v; want error containing %q", err, wantMsg) + } +} + +func TestRunGovulncheck_ModuleModeNoPatterns(t *testing.T) { + ctx := context.Background() + stdout := &bytes.Buffer{} + stderr := &bytes.Buffer{} + + // ScanLevelModule does not require packages, so it should not error out on empty patterns. + err := RunGovulncheck(ctx, nil, nil, stdout, stderr, []string{"-scan", "module"}) + + if err != nil && strings.Contains(err.Error(), "no package patterns provided") { + t.Errorf("unexpected 'no package patterns' error in module mode: %v", err) + } +}
diff --git a/internal/scan/source.go b/internal/scan/source.go index e923211..b34e443 100644 --- a/internal/scan/source.go +++ b/internal/scan/source.go
@@ -24,7 +24,7 @@ defer derrors.Wrap(&err, "govulncheck") if cfg.ScanLevel.WantPackages() && len(cfg.patterns) == 0 { - return nil // don't throw an error here + return errNoPatterns } if !gomodExists(dir) { return errNoGoMod @@ -43,7 +43,7 @@ } if cfg.ScanLevel.WantPackages() && len(graph.TopPkgs()) == 0 { - return nil // early exit + return errNoPackagesMatched } return vulncheck.Source(ctx, handler, &cfg.Config, client, graph) }