From ff0519d4cf5e7411f0ac96c0571c3d8589d8458c Mon Sep 17 00:00:00 2001 From: Michael Matloob Date: Mon, 19 Nov 2018 17:59:29 -0500 Subject: [PATCH] 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 --- go/packages/external.go | 38 +++++++++++++++++++++++++------------- 1 file changed, 25 insertions(+), 13 deletions(-) diff --git a/go/packages/external.go b/go/packages/external.go index 53cc080d..9d369a30 100644 --- a/go/packages/external.go +++ b/go/packages/external.go @@ -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 {