GoPLS Viewer

Home|gopls/internal/gocommand/vendor.go
1// Copyright 2020 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
5package gocommand
6
7import (
8    "bytes"
9    "context"
10    "fmt"
11    "os"
12    "path/filepath"
13    "regexp"
14    "strings"
15    "time"
16
17    "golang.org/x/mod/semver"
18)
19
20// ModuleJSON holds information about a module.
21type ModuleJSON struct {
22    Path      string      // module path
23    Version   string      // module version
24    Versions  []string    // available module versions (with -versions)
25    Replace   *ModuleJSON // replaced by this module
26    Time      *time.Time  // time version was created
27    Update    *ModuleJSON // available update, if any (with -u)
28    Main      bool        // is this the main module?
29    Indirect  bool        // is this module only an indirect dependency of main module?
30    Dir       string      // directory holding files for this module, if any
31    GoMod     string      // path to go.mod file used when loading this module, if any
32    GoVersion string      // go version used in module
33}
34
35var modFlagRegexp = regexp.MustCompile(`-mod[ =](\w+)`)
36
37// VendorEnabled reports whether vendoring is enabled. It takes a *Runner to execute Go commands
38// with the supplied context.Context and Invocation. The Invocation can contain pre-defined fields,
39// of which only Verb and Args are modified to run the appropriate Go command.
40// Inspired by setDefaultBuildMod in modload/init.go
41func VendorEnabled(ctx context.Contextinv Invocationr *Runner) (bool, *ModuleJSONerror) {
42    mainModgo114err := getMainModuleAnd114(ctxinvr)
43    if err != nil {
44        return falsenilerr
45    }
46
47    // We check the GOFLAGS to see if there is anything overridden or not.
48    inv.Verb = "env"
49    inv.Args = []string{"GOFLAGS"}
50    stdouterr := r.Run(ctxinv)
51    if err != nil {
52        return falsenilerr
53    }
54    goflags := string(bytes.TrimSpace(stdout.Bytes()))
55    matches := modFlagRegexp.FindStringSubmatch(goflags)
56    var modFlag string
57    if len(matches) != 0 {
58        modFlag = matches[1]
59    }
60    // Don't override an explicit '-mod=' argument.
61    if modFlag == "vendor" {
62        return truemainModnil
63    } else if modFlag != "" {
64        return falsenilnil
65    }
66    if mainMod == nil || !go114 {
67        return falsenilnil
68    }
69    // Check 1.14's automatic vendor mode.
70    if fierr := os.Stat(filepath.Join(mainMod.Dir"vendor")); err == nil && fi.IsDir() {
71        if mainMod.GoVersion != "" && semver.Compare("v"+mainMod.GoVersion"v1.14") >= 0 {
72            // The Go version is at least 1.14, and a vendor directory exists.
73            // Set -mod=vendor by default.
74            return truemainModnil
75        }
76    }
77    return falsenilnil
78}
79
80// getMainModuleAnd114 gets one of the main modules' information and whether the
81// go command in use is 1.14+. This is the information needed to figure out
82// if vendoring should be enabled.
83func getMainModuleAnd114(ctx context.Contextinv Invocationr *Runner) (*ModuleJSONboolerror) {
84    const format = `{{.Path}}
85{{.Dir}}
86{{.GoMod}}
87{{.GoVersion}}
88{{range context.ReleaseTags}}{{if eq . "go1.14"}}{{.}}{{end}}{{end}}
89`
90    inv.Verb = "list"
91    inv.Args = []string{"-m""-f"format}
92    stdouterr := r.Run(ctxinv)
93    if err != nil {
94        return nilfalseerr
95    }
96
97    lines := strings.Split(stdout.String(), "\n")
98    if len(lines) < 5 {
99        return nilfalsefmt.Errorf("unexpected stdout: %q"stdout.String())
100    }
101    mod := &ModuleJSON{
102        Path:      lines[0],
103        Dir:       lines[1],
104        GoMod:     lines[2],
105        GoVersionlines[3],
106        Main:      true,
107    }
108    return modlines[4] == "go1.14"nil
109}
110
MembersX
ModuleJSON.Dir
VendorEnabled.matches
getMainModuleAnd114.r
getMainModuleAnd114.err
getMainModuleAnd114.format
getMainModuleAnd114.lines
semver
ModuleJSON.Path
VendorEnabled
VendorEnabled.r
VendorEnabled.mainMod
VendorEnabled.goflags
getMainModuleAnd114.mod
getMainModuleAnd114.stdout
ModuleJSON.Version
ModuleJSON.Time
VendorEnabled.inv
VendorEnabled.err
VendorEnabled.fi
getMainModuleAnd114.ctx
filepath
ModuleJSON
ModuleJSON.Replace
VendorEnabled.go114
VendorEnabled.modFlag
getMainModuleAnd114.inv
ModuleJSON.GoMod
VendorEnabled.ctx
VendorEnabled.stdout
ModuleJSON.Update
ModuleJSON.GoVersion
ModuleJSON.Versions
ModuleJSON.Main
ModuleJSON.Indirect
getMainModuleAnd114
Members
X