go/packages: change driver communication mechanism

Pass in parameters to the driver in stdin rather than through argv.
This allows us to more easily route parameters to the driver and add
more parameters without breaking users. The driver doesn't need to
have the same interface as go list, because it's unlikely the driver interface
will converge with the go list interface.

We still pass in the query "words" to the driver in the argv, because
that's as good a place as any, but there's no "list" command.

Question: should we add a "command" option to the driverRequest struct?

Change-Id: Ifdbb3f84b6bfd04259f5ab63e756341d7f69de9b
Reviewed-on: https://go-review.googlesource.com/c/150337
Reviewed-by: Ian Cottrell <iancottrell@google.com>
This commit is contained in:
Michael Matloob 2018-11-19 17:59:29 -05:00
parent b5f2cae84d
commit ff0519d4cf
1 changed files with 25 additions and 13 deletions

View File

@ -16,6 +16,17 @@ import (
"strings"
)
// Driver
type driverRequest struct {
// TODO(matloob): Add a "command" option, so the "list" argument
// to the command is instead supplied in the driverRequest?
Mode LoadMode `json:"mode"`
Env []string `json:"env"`
BuildFlags []string `json:"build_flags"`
Tests bool `json:"tests"`
Overlay map[string][]byte `json:"overlay"`
}
// findExternalTool returns the file path of a tool that supplies
// the build system package structure, or "" if not found."
// If GOPACKAGESDRIVER is set in the environment findExternalTool returns its
@ -39,21 +50,22 @@ func findExternalDriver(cfg *Config) driver {
}
}
return func(cfg *Config, words ...string) (*driverResponse, error) {
req, err := json.Marshal(driverRequest{
Mode: cfg.Mode,
Env: cfg.Env,
BuildFlags: cfg.BuildFlags,
Tests: cfg.Tests,
Overlay: cfg.Overlay,
})
if err != nil {
return nil, fmt.Errorf("failed to encode message to driver tool: %v", err)
}
buf := new(bytes.Buffer)
fullargs := []string{
"list",
fmt.Sprintf("-test=%t", cfg.Tests),
fmt.Sprintf("-export=%t", usesExportData(cfg)),
fmt.Sprintf("-deps=%t", cfg.Mode >= LoadImports),
}
for _, f := range cfg.BuildFlags {
fullargs = append(fullargs, fmt.Sprintf("-buildflag=%v", f))
}
fullargs = append(fullargs, "--")
fullargs = append(fullargs, words...)
cmd := exec.CommandContext(cfg.Context, tool, fullargs...)
cmd.Env = cfg.Env
cmd := exec.CommandContext(cfg.Context, tool, words...)
cmd.Dir = cfg.Dir
cmd.Env = cfg.Env
cmd.Stdin = bytes.NewReader(req)
cmd.Stdout = buf
cmd.Stderr = new(bytes.Buffer)
if err := cmd.Run(); err != nil {