...
1
2
3
4
5
6
7
8
9 package packages
10
11 import (
12 "bytes"
13 "encoding/json"
14 "fmt"
15 exec "golang.org/x/sys/execabs"
16 "os"
17 "strings"
18 )
19
20
21
22
23
24
25
26
27
28
29
30
31
32 type driverRequest struct {
33 Mode LoadMode `json:"mode"`
34
35 Env []string `json:"env"`
36
37 BuildFlags []string `json:"build_flags"`
38
39 Tests bool `json:"tests"`
40
41
42 Overlay map[string][]byte `json:"overlay"`
43 }
44
45
46
47
48
49 func findExternalDriver(cfg *Config) driver {
50 const toolPrefix = "GOPACKAGESDRIVER="
51 tool := ""
52 for _, env := range cfg.Env {
53 if val := strings.TrimPrefix(env, toolPrefix); val != env {
54 tool = val
55 }
56 }
57 if tool != "" && tool == "off" {
58 return nil
59 }
60 if tool == "" {
61 var err error
62 tool, err = exec.LookPath("gopackagesdriver")
63 if err != nil {
64 return nil
65 }
66 }
67 return func(cfg *Config, words ...string) (*driverResponse, error) {
68 req, err := json.Marshal(driverRequest{
69 Mode: cfg.Mode,
70 Env: cfg.Env,
71 BuildFlags: cfg.BuildFlags,
72 Tests: cfg.Tests,
73 Overlay: cfg.Overlay,
74 })
75 if err != nil {
76 return nil, fmt.Errorf("failed to encode message to driver tool: %v", err)
77 }
78
79 buf := new(bytes.Buffer)
80 stderr := new(bytes.Buffer)
81 cmd := exec.CommandContext(cfg.Context, tool, words...)
82 cmd.Dir = cfg.Dir
83 cmd.Env = cfg.Env
84 cmd.Stdin = bytes.NewReader(req)
85 cmd.Stdout = buf
86 cmd.Stderr = stderr
87
88 if err := cmd.Run(); err != nil {
89 return nil, fmt.Errorf("%v: %v: %s", tool, err, cmd.Stderr)
90 }
91 if len(stderr.Bytes()) != 0 && os.Getenv("GOPACKAGESPRINTDRIVERERRORS") != "" {
92 fmt.Fprintf(os.Stderr, "%s stderr: <<%s>>\n", cmdDebugStr(cmd), stderr)
93 }
94
95 var response driverResponse
96 if err := json.Unmarshal(buf.Bytes(), &response); err != nil {
97 return nil, err
98 }
99 return &response, nil
100 }
101 }
102
View as plain text