podman

Форк
0
140 строк · 4.6 Кб
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
package packages
6

7
// This file defines the protocol that enables an external "driver"
8
// tool to supply package metadata in place of 'go list'.
9

10
import (
11
	"bytes"
12
	"encoding/json"
13
	"fmt"
14
	"os"
15
	"os/exec"
16
	"strings"
17
)
18

19
// DriverRequest defines the schema of a request for package metadata
20
// from an external driver program. The JSON-encoded DriverRequest
21
// message is provided to the driver program's standard input. The
22
// query patterns are provided as command-line arguments.
23
//
24
// See the package documentation for an overview.
25
type DriverRequest struct {
26
	Mode LoadMode `json:"mode"`
27

28
	// Env specifies the environment the underlying build system should be run in.
29
	Env []string `json:"env"`
30

31
	// BuildFlags are flags that should be passed to the underlying build system.
32
	BuildFlags []string `json:"build_flags"`
33

34
	// Tests specifies whether the patterns should also return test packages.
35
	Tests bool `json:"tests"`
36

37
	// Overlay maps file paths (relative to the driver's working directory) to the byte contents
38
	// of overlay files.
39
	Overlay map[string][]byte `json:"overlay"`
40
}
41

42
// DriverResponse defines the schema of a response from an external
43
// driver program, providing the results of a query for package
44
// metadata. The driver program must write a JSON-encoded
45
// DriverResponse message to its standard output.
46
//
47
// See the package documentation for an overview.
48
type DriverResponse struct {
49
	// NotHandled is returned if the request can't be handled by the current
50
	// driver. If an external driver returns a response with NotHandled, the
51
	// rest of the DriverResponse is ignored, and go/packages will fallback
52
	// to the next driver. If go/packages is extended in the future to support
53
	// lists of multiple drivers, go/packages will fall back to the next driver.
54
	NotHandled bool
55

56
	// Compiler and Arch are the arguments pass of types.SizesFor
57
	// to get a types.Sizes to use when type checking.
58
	Compiler string
59
	Arch     string
60

61
	// Roots is the set of package IDs that make up the root packages.
62
	// We have to encode this separately because when we encode a single package
63
	// we cannot know if it is one of the roots as that requires knowledge of the
64
	// graph it is part of.
65
	Roots []string `json:",omitempty"`
66

67
	// Packages is the full set of packages in the graph.
68
	// The packages are not connected into a graph.
69
	// The Imports if populated will be stubs that only have their ID set.
70
	// Imports will be connected and then type and syntax information added in a
71
	// later pass (see refine).
72
	Packages []*Package
73

74
	// GoVersion is the minor version number used by the driver
75
	// (e.g. the go command on the PATH) when selecting .go files.
76
	// Zero means unknown.
77
	GoVersion int
78
}
79

80
// driver is the type for functions that query the build system for the
81
// packages named by the patterns.
82
type driver func(cfg *Config, patterns ...string) (*DriverResponse, error)
83

84
// findExternalDriver returns the file path of a tool that supplies
85
// the build system package structure, or "" if not found."
86
// If GOPACKAGESDRIVER is set in the environment findExternalTool returns its
87
// value, otherwise it searches for a binary named gopackagesdriver on the PATH.
88
func findExternalDriver(cfg *Config) driver {
89
	const toolPrefix = "GOPACKAGESDRIVER="
90
	tool := ""
91
	for _, env := range cfg.Env {
92
		if val := strings.TrimPrefix(env, toolPrefix); val != env {
93
			tool = val
94
		}
95
	}
96
	if tool != "" && tool == "off" {
97
		return nil
98
	}
99
	if tool == "" {
100
		var err error
101
		tool, err = exec.LookPath("gopackagesdriver")
102
		if err != nil {
103
			return nil
104
		}
105
	}
106
	return func(cfg *Config, words ...string) (*DriverResponse, error) {
107
		req, err := json.Marshal(DriverRequest{
108
			Mode:       cfg.Mode,
109
			Env:        cfg.Env,
110
			BuildFlags: cfg.BuildFlags,
111
			Tests:      cfg.Tests,
112
			Overlay:    cfg.Overlay,
113
		})
114
		if err != nil {
115
			return nil, fmt.Errorf("failed to encode message to driver tool: %v", err)
116
		}
117

118
		buf := new(bytes.Buffer)
119
		stderr := new(bytes.Buffer)
120
		cmd := exec.CommandContext(cfg.Context, tool, words...)
121
		cmd.Dir = cfg.Dir
122
		cmd.Env = cfg.Env
123
		cmd.Stdin = bytes.NewReader(req)
124
		cmd.Stdout = buf
125
		cmd.Stderr = stderr
126

127
		if err := cmd.Run(); err != nil {
128
			return nil, fmt.Errorf("%v: %v: %s", tool, err, cmd.Stderr)
129
		}
130
		if len(stderr.Bytes()) != 0 && os.Getenv("GOPACKAGESPRINTDRIVERERRORS") != "" {
131
			fmt.Fprintf(os.Stderr, "%s stderr: <<%s>>\n", cmdDebugStr(cmd), stderr)
132
		}
133

134
		var response DriverResponse
135
		if err := json.Unmarshal(buf.Bytes(), &response); err != nil {
136
			return nil, err
137
		}
138
		return &response, nil
139
	}
140
}
141

Использование cookies

Мы используем файлы cookie в соответствии с Политикой конфиденциальности и Политикой использования cookies.

Нажимая кнопку «Принимаю», Вы даете АО «СберТех» согласие на обработку Ваших персональных данных в целях совершенствования нашего веб-сайта и Сервиса GitVerse, а также повышения удобства их использования.

Запретить использование cookies Вы можете самостоятельно в настройках Вашего браузера.