internal/lsp/cmd: add -config option to gopls vulncheck

If -config=true, gopls vulncheck reads the package load
configuration JSON (build flags, env, tests, and later
maybe overlay info) from stdin.

And, add some logging to gopls/internal/vulncheck/command.go
that helps measuring the package loading overhead.

Update golang/go#50577

Change-Id: I5c1ce145b07f2bed03911613f42c09a3d6be6c28
Reviewed-on: https://go-review.googlesource.com/c/tools/+/404575
Reviewed-by: Robert Findley <rfindley@google.com>
This commit is contained in:
Hana 2022-05-06 09:44:57 -04:00 committed by Hyang-Ah Hana Kim
parent 62d837c1f3
commit ad497c6c68
3 changed files with 39 additions and 6 deletions

View File

@ -10,6 +10,7 @@ package vulncheck
import (
"context"
"fmt"
"log"
"os"
"strings"
@ -83,10 +84,15 @@ func (c *cmd) run(ctx context.Context, packagesCfg *packages.Config, patterns []
packages.NeedCompiledGoFiles | packages.NeedImports | packages.NeedTypes |
packages.NeedTypesSizes | packages.NeedSyntax | packages.NeedTypesInfo | packages.NeedDeps
log.Println("loading packages...")
loadedPkgs, err := packages.Load(packagesCfg, patterns...)
if err != nil {
log.Printf("package load failed: %v", err)
return nil, err
}
log.Printf("loaded %d packages\n", len(loadedPkgs))
pkgs := vulncheck.Convert(loadedPkgs)
res, err := vulncheck.Source(ctx, pkgs, &vulncheck.Config{
Client: c.Client,

View File

@ -8,6 +8,8 @@ Usage:
By default, the command outputs a JSON-encoded
golang.org/x/tools/internal/lsp/command.VulncheckResult
message.
Example:
$ gopls vulncheck <packages>
-config
If true, the command reads a JSON-encoded package load configuration from stdin

View File

@ -20,9 +20,25 @@ import (
// vulncheck implements the vulncheck command.
type vulncheck struct {
app *Application
Config bool `flag:"config" help:"If true, the command reads a JSON-encoded package load configuration from stdin"`
app *Application
}
type pkgLoadConfig struct {
// BuildFlags is a list of command-line flags to be passed through to
// the build system's query tool.
BuildFlags []string
// Env is the environment to use when invoking the build system's query tool.
// If Env is nil, the current environment is used.
Env []string
// If Tests is set, the loader includes related test packages.
Tests bool
}
// TODO(hyangah): document pkgLoadConfig
func (v *vulncheck) Name() string { return "vulncheck" }
func (v *vulncheck) Parent() string { return v.app.Name() }
func (v *vulncheck) Usage() string { return "" }
@ -36,9 +52,9 @@ func (v *vulncheck) DetailedHelp(f *flag.FlagSet) {
By default, the command outputs a JSON-encoded
golang.org/x/tools/internal/lsp/command.VulncheckResult
message.
Example:
$ gopls vulncheck <packages>
`)
printFlagDefaults(f)
}
@ -56,6 +72,12 @@ func (v *vulncheck) Run(ctx context.Context, args ...string) error {
if err != nil {
return tool.CommandLineErrorf("failed to get current directory: %v", err)
}
var cfg pkgLoadConfig
if v.Config {
if err := json.NewDecoder(os.Stdin).Decode(&cfg); err != nil {
return tool.CommandLineErrorf("failed to parse cfg: %v", err)
}
}
opts := source.DefaultOptions().Clone()
v.app.options(opts) // register hook
@ -64,7 +86,10 @@ func (v *vulncheck) Run(ctx context.Context, args ...string) error {
}
loadCfg := &packages.Config{
Context: ctx,
Context: ctx,
Tests: cfg.Tests,
BuildFlags: cfg.BuildFlags,
Env: cfg.Env,
}
res, err := opts.Hooks.Govulncheck(ctx, loadCfg, command.VulncheckArgs{
@ -72,11 +97,11 @@ func (v *vulncheck) Run(ctx context.Context, args ...string) error {
Pattern: pattern,
})
if err != nil {
return err
return tool.CommandLineErrorf("govulncheck failed: %v", err)
}
data, err := json.MarshalIndent(res, " ", " ")
if err != nil {
return fmt.Errorf("failed to decode results: %v", err)
return tool.CommandLineErrorf("failed to decode results: %v", err)
}
fmt.Printf("%s", data)
return nil