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