Code refactoring for bpa operator
[icn.git] / cmd / bpa-operator / vendor / golang.org / x / tools / go / packages / external.go
1 // Copyright 2018 The Go Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style
3 // license that can be found in the LICENSE file.
4
5 // This file enables an external tool to intercept package requests.
6 // If the tool is present then its results are used in preference to
7 // the go list command.
8
9 package packages
10
11 import (
12         "bytes"
13         "encoding/json"
14         "fmt"
15         "os/exec"
16         "strings"
17 )
18
19 // Driver
20 type driverRequest struct {
21         Command    string            `json:"command"`
22         Mode       LoadMode          `json:"mode"`
23         Env        []string          `json:"env"`
24         BuildFlags []string          `json:"build_flags"`
25         Tests      bool              `json:"tests"`
26         Overlay    map[string][]byte `json:"overlay"`
27 }
28
29 // findExternalDriver returns the file path of a tool that supplies
30 // the build system package structure, or "" if not found."
31 // If GOPACKAGESDRIVER is set in the environment findExternalTool returns its
32 // value, otherwise it searches for a binary named gopackagesdriver on the PATH.
33 func findExternalDriver(cfg *Config) driver {
34         const toolPrefix = "GOPACKAGESDRIVER="
35         tool := ""
36         for _, env := range cfg.Env {
37                 if val := strings.TrimPrefix(env, toolPrefix); val != env {
38                         tool = val
39                 }
40         }
41         if tool != "" && tool == "off" {
42                 return nil
43         }
44         if tool == "" {
45                 var err error
46                 tool, err = exec.LookPath("gopackagesdriver")
47                 if err != nil {
48                         return nil
49                 }
50         }
51         return func(cfg *Config, words ...string) (*driverResponse, error) {
52                 req, err := json.Marshal(driverRequest{
53                         Mode:       cfg.Mode,
54                         Env:        cfg.Env,
55                         BuildFlags: cfg.BuildFlags,
56                         Tests:      cfg.Tests,
57                         Overlay:    cfg.Overlay,
58                 })
59                 if err != nil {
60                         return nil, fmt.Errorf("failed to encode message to driver tool: %v", err)
61                 }
62
63                 buf := new(bytes.Buffer)
64                 cmd := exec.CommandContext(cfg.Context, tool, words...)
65                 cmd.Dir = cfg.Dir
66                 cmd.Env = cfg.Env
67                 cmd.Stdin = bytes.NewReader(req)
68                 cmd.Stdout = buf
69                 cmd.Stderr = new(bytes.Buffer)
70                 if err := cmd.Run(); err != nil {
71                         return nil, fmt.Errorf("%v: %v: %s", tool, err, cmd.Stderr)
72                 }
73                 var response driverResponse
74                 if err := json.Unmarshal(buf.Bytes(), &response); err != nil {
75                         return nil, err
76                 }
77                 return &response, nil
78         }
79 }