68 lines
1.9 KiB
Go
68 lines
1.9 KiB
Go
// Copyright 2018 The Go Authors. All rights reserved.
|
|
// Use of this source code is governed by a BSD-style
|
|
// license that can be found in the LICENSE file.
|
|
|
|
// This file enables an external tool to intercept package requests.
|
|
// If the tool is present then its results are used in preference to
|
|
// the go list command.
|
|
|
|
package packages
|
|
|
|
import (
|
|
"bytes"
|
|
"encoding/json"
|
|
"fmt"
|
|
"os/exec"
|
|
"strings"
|
|
)
|
|
|
|
// 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
|
|
// value, otherwise it searches for a binary named gopackagesdriver on the PATH.
|
|
func findExternalDriver(cfg *Config) driver {
|
|
const toolPrefix = "GOPACKAGESDRIVER="
|
|
tool := ""
|
|
for _, env := range cfg.Env {
|
|
if val := strings.TrimPrefix(env, toolPrefix); val != env {
|
|
tool = val
|
|
}
|
|
}
|
|
if tool != "" && tool == "off" {
|
|
return nil
|
|
}
|
|
if tool == "" {
|
|
var err error
|
|
tool, err = exec.LookPath("gopackagesdriver")
|
|
if err != nil {
|
|
return nil
|
|
}
|
|
}
|
|
return func(cfg *Config, words ...string) (*driverResponse, error) {
|
|
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.Dir = cfg.Dir
|
|
cmd.Stdout = buf
|
|
cmd.Stderr = new(bytes.Buffer)
|
|
if err := cmd.Run(); err != nil {
|
|
return nil, fmt.Errorf("%v: %v: %s", tool, err, cmd.Stderr)
|
|
}
|
|
var response driverResponse
|
|
if err := json.Unmarshal(buf.Bytes(), &response); err != nil {
|
|
return nil, err
|
|
}
|
|
return &response, nil
|
|
}
|
|
}
|