GoPLS Viewer

Home|gopls/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
9package packages
10
11import (
12    "bytes"
13    "encoding/json"
14    "fmt"
15    exec "golang.org/x/sys/execabs"
16    "os"
17    "strings"
18)
19
20// The Driver Protocol
21//
22// The driver, given the inputs to a call to Load, returns metadata about the packages specified.
23// This allows for different build systems to support go/packages by telling go/packages how the
24// packages' source is organized.
25// The driver is a binary, either specified by the GOPACKAGESDRIVER environment variable or in
26// the path as gopackagesdriver. It's given the inputs to load in its argv. See the package
27// documentation in doc.go for the full description of the patterns that need to be supported.
28// A driver receives as a JSON-serialized driverRequest struct in standard input and will
29// produce a JSON-serialized driverResponse (see definition in packages.go) in its standard output.
30
31// driverRequest is used to provide the portion of Load's Config that is needed by a driver.
32type driverRequest struct {
33    Mode LoadMode `json:"mode"`
34    // Env specifies the environment the underlying build system should be run in.
35    Env []string `json:"env"`
36    // BuildFlags are flags that should be passed to the underlying build system.
37    BuildFlags []string `json:"build_flags"`
38    // Tests specifies whether the patterns should also return test packages.
39    Tests bool `json:"tests"`
40    // Overlay maps file paths (relative to the driver's working directory) to the byte contents
41    // of overlay files.
42    Overlay map[string][]byte `json:"overlay"`
43}
44
45// findExternalDriver returns the file path of a tool that supplies
46// the build system package structure, or "" if not found."
47// If GOPACKAGESDRIVER is set in the environment findExternalTool returns its
48// value, otherwise it searches for a binary named gopackagesdriver on the PATH.
49func findExternalDriver(cfg *Configdriver {
50    const toolPrefix = "GOPACKAGESDRIVER="
51    tool := ""
52    for _env := range cfg.Env {
53        if val := strings.TrimPrefix(envtoolPrefix); val != env {
54            tool = val
55        }
56    }
57    if tool != "" && tool == "off" {
58        return nil
59    }
60    if tool == "" {
61        var err error
62        toolerr = exec.LookPath("gopackagesdriver")
63        if err != nil {
64            return nil
65        }
66    }
67    return func(cfg *Configwords ...string) (*driverResponseerror) {
68        reqerr := json.Marshal(driverRequest{
69            Mode:       cfg.Mode,
70            Env:        cfg.Env,
71            BuildFlagscfg.BuildFlags,
72            Tests:      cfg.Tests,
73            Overlay:    cfg.Overlay,
74        })
75        if err != nil {
76            return nilfmt.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.Contexttoolwords...)
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 nilfmt.Errorf("%v: %v: %s"toolerrcmd.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 nilerr
98        }
99        return &responsenil
100    }
101}
102
MembersX
findExternalDriver
findExternalDriver.RangeStmt_2194.env
findExternalDriver.BlockStmt.err
driverRequest.BuildFlags
findExternalDriver.toolPrefix
findExternalDriver.BlockStmt.stderr
driverRequest.Tests
exec
driverRequest
driverRequest.Mode
findExternalDriver.cfg
findExternalDriver.RangeStmt_2194.BlockStmt.val
findExternalDriver.BlockStmt.req
findExternalDriver.BlockStmt.cmd
bytes
strings
driverRequest.Env
driverRequest.Overlay
findExternalDriver.tool
findExternalDriver.BlockStmt.buf
findExternalDriver.BlockStmt.response
json
Members
X