vulndb/govulncheck: add file-system caching

Change-Id: I19d0a456e69df8bbc776f7c25596f7f869aa5542
Reviewed-on: https://go-review.googlesource.com/c/exp/+/344869
Run-TryBot: Zvonimir Pavlinovic <zpavlinovic@google.com>
TryBot-Result: Go Bot <gobot@golang.org>
Reviewed-by: Tim King <taking@google.com>
Trust: Zvonimir Pavlinovic <zpavlinovic@google.com>
diff --git a/vulndb/govulncheck/main.go b/vulndb/govulncheck/main.go
index ba555f2..a3faacc 100644
--- a/vulndb/govulncheck/main.go
+++ b/vulndb/govulncheck/main.go
@@ -83,12 +83,14 @@
 	if GOVULNDB := os.Getenv("GOVULNDB"); GOVULNDB != "" {
 		dbs = strings.Split(GOVULNDB, ",")
 	}
-
-	cfg := &packages.Config{
-		Mode: packages.LoadAllSyntax | packages.NeedModule,
+	dbClient, err := client.NewClient(dbs, client.Options{HTTPCache: client.NewFsCache()})
+	if err != nil {
+		fmt.Fprintf(os.Stderr, "govulncheck: %s\n", err)
+		os.Exit(1)
 	}
 
-	r, err := run(cfg, flag.Args(), *importsFlag, dbs)
+	cfg := &packages.Config{Mode: packages.LoadAllSyntax | packages.NeedModule}
+	r, err := run(cfg, flag.Args(), *importsFlag, dbClient)
 	if err != nil {
 		fmt.Fprintf(os.Stderr, "govulncheck: %s\n", err)
 		os.Exit(1)
@@ -176,18 +178,13 @@
 	return !s.IsDir()
 }
 
-func run(cfg *packages.Config, patterns []string, importsOnly bool, dbs []string) (*audit.Results, error) {
+func run(cfg *packages.Config, patterns []string, importsOnly bool, dbClient *client.Client) (*audit.Results, error) {
 	if len(patterns) == 1 && isFile(patterns[0]) {
 		modules, symbols, err := binscan.ExtractPackagesAndSymbols(patterns[0])
 		if err != nil {
 			return nil, err
 		}
 
-		dbClient, err := client.NewClient(dbs, client.Options{})
-		if err != nil {
-			return nil, fmt.Errorf("failed to create database client: %s", err)
-		}
-
 		vulns, err := audit.FetchVulnerabilities(dbClient, modules)
 		if err != nil {
 			return nil, fmt.Errorf("failed to load vulnerability dbs: %v", err)
@@ -217,10 +214,6 @@
 	if *verboseFlag {
 		log.Println("loading database...")
 	}
-	dbClient, err := client.NewClient(dbs, client.Options{})
-	if err != nil {
-		return nil, fmt.Errorf("failed to create database client: %s", err)
-	}
 
 	modVulns, err := audit.FetchVulnerabilities(dbClient, extractModules(pkgs))
 	if err != nil {
diff --git a/vulndb/govulncheck/main_test.go b/vulndb/govulncheck/main_test.go
index 00c069a..6cb3987 100644
--- a/vulndb/govulncheck/main_test.go
+++ b/vulndb/govulncheck/main_test.go
@@ -22,6 +22,7 @@
 	"golang.org/x/exp/vulndb/internal/audit"
 	"golang.org/x/tools/go/packages"
 	"golang.org/x/tools/go/packages/packagestest"
+	"golang.org/x/vulndb/client"
 )
 
 // TODO(zpavlinovic): improve integration tests.
@@ -223,7 +224,13 @@
 			}
 		}
 
-		r, err := run(cfg, []string{hashiVaultOkta}, false, []string{test.source})
+		// TODO: add caching
+		dbClient, err := client.NewClient([]string{test.source}, client.Options{})
+		if err != nil {
+			t.Error(err)
+		}
+
+		r, err := run(cfg, []string{hashiVaultOkta}, false, dbClient)
 		if err != nil {
 			t.Fatal(err)
 		}
@@ -374,7 +381,13 @@
 			}
 		}
 
-		r, err := run(cfg, []string{"./..."}, false, []string{test.source})
+		// TODO: add caching
+		dbClient, err := client.NewClient([]string{test.source}, client.Options{})
+		if err != nil {
+			t.Error(err)
+		}
+
+		r, err := run(cfg, []string{"./..."}, false, dbClient)
 		if err != nil {
 			t.Fatal(err)
 		}