Skip to content

Commit 30a84b3

Browse files
committed
cmd/go: replace -getmode with -mod, $GOPROXY
The old -getmode flag had two settings: -getmode=local meant don't download from the network. -getmode=vendor meant only use the vendor directory. The new -mod flag has two settings: -mod=readonly means refuse to automatically update go.mod (mainly for CI testing). -mod=vendor means only use the vendor directory. The old GOPROXY variable had two settings: a proxy URL or else the empty string (direct connect). The new GOPROXY variable has three settings: a proxy URL, the string "off" (no network use allowed), or else the empty string or the explicit string "direct" (direct connection). We anticipate allow a comma-separated sequence in a future release, so commas are disallowed entirely right now. Fixes #24666. Fixes #26586. Fixes #26370. Fixes #26361. Change-Id: If2601a16b09f04800f666938c071fc053b4c3f9c Reviewed-on: https://go-review.googlesource.com/126696 Run-TryBot: Russ Cox <[email protected]> TryBot-Result: Gobot Gobot <[email protected]> Reviewed-by: Bryan C. Mills <[email protected]>
1 parent c1a4fc3 commit 30a84b3

File tree

16 files changed

+178
-91
lines changed

16 files changed

+178
-91
lines changed

src/cmd/go/internal/cfg/cfg.go

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -21,7 +21,7 @@ var (
2121
BuildA bool // -a flag
2222
BuildBuildmode string // -buildmode flag
2323
BuildContext = defaultContext()
24-
BuildGetmode string // -getmode flag
24+
BuildMod string // -mod flag
2525
BuildI bool // -i flag
2626
BuildLinkshared bool // -linkshared flag
2727
BuildMSan bool // -msan flag

src/cmd/go/internal/modfetch/proxy.go

Lines changed: 8 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -25,11 +25,14 @@ var HelpGoproxy = &base.Command{
2525
Short: "module proxy protocol",
2626
Long: `
2727
The go command by default downloads modules from version control systems
28-
directly, just as 'go get' always has. If the GOPROXY environment variable
29-
is set to the URL of a module proxy, the go command will instead fetch
30-
all modules from that proxy. No matter the source of the modules, downloaded
31-
modules must match existing entries in go.sum (see 'go help modules' for
32-
discussion of verification).
28+
directly, just as 'go get' always has. The GOPROXY environment variable allows
29+
further control over the download source. If GOPROXY is unset, is the empty string,
30+
or is the string "direct", downloads use the default direct connection to version
31+
control systems. Setting GOPROXY to "off" disallows downloading modules from
32+
any source. Otherwise, GOPROXY is expected to be the URL of a module proxy,
33+
in which case the go command will fetch all modules from that proxy.
34+
No matter the source of the modules, downloaded modules must match existing
35+
entries in go.sum (see 'go help modules' for discussion of verification).
3336
3437
A Go module proxy is any web server that can respond to GET requests for
3538
URLs of a specified form. The requests have no query parameters, so even

src/cmd/go/internal/modfetch/repo.go

Lines changed: 8 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -203,10 +203,13 @@ func Lookup(path string) (Repo, error) {
203203

204204
// lookup returns the module with the given module path.
205205
func lookup(path string) (r Repo, err error) {
206-
if cfg.BuildGetmode != "" {
207-
return nil, fmt.Errorf("module lookup disabled by -getmode=%s", cfg.BuildGetmode)
206+
if cfg.BuildMod == "vendor" {
207+
return nil, fmt.Errorf("module lookup disabled by -mod=%s", cfg.BuildMod)
208208
}
209-
if proxyURL != "" {
209+
if proxyURL == "off" {
210+
return nil, fmt.Errorf("module lookup disabled by GOPROXY=%s", proxyURL)
211+
}
212+
if proxyURL != "" && proxyURL != "direct" {
210213
return lookupProxy(path)
211214
}
212215

@@ -241,8 +244,8 @@ func lookupCodeRepo(rr *get.RepoRoot) (codehost.Repo, error) {
241244
// the original "go get" would have used, at the specific repository revision
242245
// (typically a commit hash, but possibly also a source control tag).
243246
func ImportRepoRev(path, rev string) (Repo, *RevInfo, error) {
244-
if cfg.BuildGetmode != "" {
245-
return nil, nil, fmt.Errorf("repo version lookup disabled by -getmode=%s", cfg.BuildGetmode)
247+
if cfg.BuildMod == "vendor" || cfg.BuildMod == "readonly" {
248+
return nil, nil, fmt.Errorf("repo version lookup disabled by -mod=%s", cfg.BuildMod)
246249
}
247250

248251
// Note: Because we are converting a code reference from a legacy

src/cmd/go/internal/modget/get.go

Lines changed: 8 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -35,7 +35,7 @@ var CmdGet = &base.Command{
3535
Get resolves and adds dependencies to the current development module
3636
and then builds and installs them.
3737
38-
The first step is to resolve which dependencies to add.
38+
The first step is to resolve which dependencies to add.
3939
4040
For each named package or package pattern, get must decide which version of
4141
the corresponding module to use. By default, get chooses the latest tagged
@@ -189,6 +189,11 @@ type task struct {
189189
}
190190

191191
func runGet(cmd *base.Command, args []string) {
192+
// -mod=readonly has no effect on "go get".
193+
if cfg.BuildMod == "readonly" {
194+
cfg.BuildMod = ""
195+
}
196+
192197
switch getU {
193198
case "", "patch", "true":
194199
// ok
@@ -205,8 +210,8 @@ func runGet(cmd *base.Command, args []string) {
205210
fmt.Fprintf(os.Stderr, "go get: -t flag is a no-op when using modules\n")
206211
}
207212

208-
if cfg.BuildGetmode == "vendor" {
209-
base.Fatalf("go get: disabled by -getmode=vendor")
213+
if cfg.BuildMod == "vendor" {
214+
base.Fatalf("go get: disabled by -mod=%s", cfg.BuildMod)
210215
}
211216

212217
modload.LoadBuildList()

src/cmd/go/internal/modload/build.go

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -108,7 +108,7 @@ func moduleInfo(m module.Version, fromBuildList bool) *modinfo.ModulePublic {
108108
info.GoVersion = loaded.goVersion[m.Path]
109109
}
110110

111-
if cfg.BuildGetmode == "vendor" {
111+
if cfg.BuildMod == "vendor" {
112112
info.Dir = filepath.Join(ModRoot, "vendor", m.Path)
113113
return info
114114
}
@@ -137,7 +137,7 @@ func moduleInfo(m module.Version, fromBuildList bool) *modinfo.ModulePublic {
137137
}
138138
}
139139
}
140-
if cfg.BuildGetmode == "vendor" {
140+
if cfg.BuildMod == "vendor" {
141141
m.Dir = filepath.Join(ModRoot, "vendor", m.Path)
142142
}
143143
}

src/cmd/go/internal/modload/help.go

Lines changed: 17 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -20,12 +20,12 @@ including recording and resolving dependencies on other modules.
2020
Modules replace the old GOPATH-based approach to specifying
2121
which source files are used in a given build.
2222
23-
Experimental module support
23+
Preliminary module support
2424
25-
Go 1.11 includes experimental support for Go modules,
25+
Go 1.11 includes preliminary support for Go modules,
2626
including a new module-aware 'go get' command.
2727
We intend to keep revising this support, while preserving compatibility,
28-
until it can be declared official (no longer experimental),
28+
until it can be declared official (no longer preliminary),
2929
and then at a later point we may remove support for work
3030
in GOPATH and the old 'go get' command.
3131
@@ -173,6 +173,19 @@ automatically make any implied upgrades and update go.mod to reflect them.
173173
The 'go mod' command provides other functionality for use in maintaining
174174
and understanding modules and go.mod files. See 'go help mod'.
175175
176+
The -mod build flag provides additional control over updating and use of go.mod.
177+
178+
If invoked with -mod=readonly, the go command is disallowed from the implicit
179+
automatic updating of go.mod described above. Instead, it fails when any changes
180+
to go.mod are needed. This setting is most useful to check that go.mod does
181+
not need updates, such as in a continuous integration and testing system.
182+
The "go get" command remains permitted to update go.mod even with -mod=readonly,
183+
and the "go mod" commands do not take the -mod flag (or any other build flags).
184+
185+
If invoked with -mod=vendor, the go command assumes that the vendor
186+
directory holds the correct copies of dependencies and ignores
187+
the dependency descriptions in go.mod.
188+
176189
Pseudo-versions
177190
178191
The go.mod file and the go command more generally use semantic versions as
@@ -363,7 +376,7 @@ tests of packages in the main module.
363376
364377
To build using the main module's top-level vendor directory to satisfy
365378
dependencies (disabling use of the usual network sources and local
366-
caches), use 'go build -getmode=vendor'. Note that only the main module's
379+
caches), use 'go build -mod=vendor'. Note that only the main module's
367380
top-level vendor directory is used; vendor directories in other locations
368381
are still ignored.
369382
`,

src/cmd/go/internal/modload/import.go

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -66,9 +66,9 @@ func Import(path string) (m module.Version, dir string, err error) {
6666
}
6767
}
6868

69-
// -getmode=vendor is special.
69+
// -mod=vendor is special.
7070
// Everything must be in the main module or the main module's vendor directory.
71-
if cfg.BuildGetmode == "vendor" {
71+
if cfg.BuildMod == "vendor" {
7272
mainDir, mainOK := dirInModule(path, Target.Path, ModRoot, true)
7373
vendorDir, vendorOK := dirInModule(path, "", filepath.Join(ModRoot, "vendor"), false)
7474
if mainOK && vendorOK {
@@ -146,8 +146,8 @@ func Import(path string) (m module.Version, dir string, err error) {
146146

147147
// Look up module containing the package, for addition to the build list.
148148
// Goal is to determine the module, download it to dir, and return m, dir, ErrMissing.
149-
if cfg.BuildGetmode == "local" {
150-
return module.Version{}, "", fmt.Errorf("import lookup disabled by -getmode=local")
149+
if cfg.BuildMod == "readonly" {
150+
return module.Version{}, "", fmt.Errorf("import lookup disabled by -mod=%s", cfg.BuildMod)
151151
}
152152

153153
for p := path; p != "."; p = pathpkg.Dir(p) {

src/cmd/go/internal/modload/init.go

Lines changed: 8 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -525,8 +525,6 @@ func WriteGoMod() {
525525
return
526526
}
527527

528-
modfetch.WriteGoSum()
529-
530528
if loaded != nil {
531529
reqs := MinReqs()
532530
min, err := reqs.Required(Target)
@@ -550,12 +548,15 @@ func WriteGoMod() {
550548
if err != nil {
551549
base.Fatalf("go: %v", err)
552550
}
553-
if bytes.Equal(old, new) {
554-
return
555-
}
556-
if err := ioutil.WriteFile(file, new, 0666); err != nil {
557-
base.Fatalf("go: %v", err)
551+
if !bytes.Equal(old, new) {
552+
if cfg.BuildMod == "readonly" {
553+
base.Fatalf("go: updates to go.mod needed, disabled by -mod=readonly")
554+
}
555+
if err := ioutil.WriteFile(file, new, 0666); err != nil {
556+
base.Fatalf("go: %v", err)
557+
}
558558
}
559+
modfetch.WriteGoSum()
559560
}
560561

561562
func fixVersion(path, vers string) (string, error) {

src/cmd/go/internal/modload/load.go

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -651,6 +651,7 @@ func Replacement(mod module.Version) module.Version {
651651
// Happens during testing.
652652
return module.Version{}
653653
}
654+
654655
var found *modfile.Replace
655656
for _, r := range modFile.Replace {
656657
if r.Old.Path == mod.Path && (r.Old.Version == "" || r.Old.Version == mod.Version) {
@@ -761,7 +762,7 @@ func (r *mvsReqs) required(mod module.Version) ([]module.Version, error) {
761762
return append(list, r.buildList[1:]...), nil
762763
}
763764

764-
if cfg.BuildGetmode == "vendor" {
765+
if cfg.BuildMod == "vendor" {
765766
// For every module other than the target,
766767
// return the full list of modules from modules.txt.
767768
readVendorList()

src/cmd/go/internal/vet/vetflag.go

Lines changed: 38 additions & 30 deletions
Original file line numberDiff line numberDiff line change
@@ -27,33 +27,33 @@ var vetFlagDefn = []*cmdflag.Defn{
2727
// to vet. We handle them in vetFlags.
2828

2929
// local.
30-
{Name: "all", BoolVar: new(bool)},
31-
{Name: "asmdecl", BoolVar: new(bool)},
32-
{Name: "assign", BoolVar: new(bool)},
33-
{Name: "atomic", BoolVar: new(bool)},
34-
{Name: "bool", BoolVar: new(bool)},
35-
{Name: "buildtags", BoolVar: new(bool)},
36-
{Name: "cgocall", BoolVar: new(bool)},
37-
{Name: "composites", BoolVar: new(bool)},
38-
{Name: "copylocks", BoolVar: new(bool)},
39-
{Name: "httpresponse", BoolVar: new(bool)},
40-
{Name: "lostcancel", BoolVar: new(bool)},
41-
{Name: "methods", BoolVar: new(bool)},
42-
{Name: "nilfunc", BoolVar: new(bool)},
43-
{Name: "printf", BoolVar: new(bool)},
44-
{Name: "printfuncs"},
45-
{Name: "rangeloops", BoolVar: new(bool)},
46-
{Name: "shadow", BoolVar: new(bool)},
47-
{Name: "shadowstrict", BoolVar: new(bool)},
48-
{Name: "shift", BoolVar: new(bool)},
49-
{Name: "source", BoolVar: new(bool)},
50-
{Name: "structtags", BoolVar: new(bool)},
51-
{Name: "tests", BoolVar: new(bool)},
52-
{Name: "unreachable", BoolVar: new(bool)},
53-
{Name: "unsafeptr", BoolVar: new(bool)},
54-
{Name: "unusedfuncs"},
55-
{Name: "unusedresult", BoolVar: new(bool)},
56-
{Name: "unusedstringmethods"},
30+
{Name: "all", BoolVar: new(bool), PassToTest: true},
31+
{Name: "asmdecl", BoolVar: new(bool), PassToTest: true},
32+
{Name: "assign", BoolVar: new(bool), PassToTest: true},
33+
{Name: "atomic", BoolVar: new(bool), PassToTest: true},
34+
{Name: "bool", BoolVar: new(bool), PassToTest: true},
35+
{Name: "buildtags", BoolVar: new(bool), PassToTest: true},
36+
{Name: "cgocall", BoolVar: new(bool), PassToTest: true},
37+
{Name: "composites", BoolVar: new(bool), PassToTest: true},
38+
{Name: "copylocks", BoolVar: new(bool), PassToTest: true},
39+
{Name: "httpresponse", BoolVar: new(bool), PassToTest: true},
40+
{Name: "lostcancel", BoolVar: new(bool), PassToTest: true},
41+
{Name: "methods", BoolVar: new(bool), PassToTest: true},
42+
{Name: "nilfunc", BoolVar: new(bool), PassToTest: true},
43+
{Name: "printf", BoolVar: new(bool), PassToTest: true},
44+
{Name: "printfuncs", PassToTest: true},
45+
{Name: "rangeloops", BoolVar: new(bool), PassToTest: true},
46+
{Name: "shadow", BoolVar: new(bool), PassToTest: true},
47+
{Name: "shadowstrict", BoolVar: new(bool), PassToTest: true},
48+
{Name: "shift", BoolVar: new(bool), PassToTest: true},
49+
{Name: "source", BoolVar: new(bool), PassToTest: true},
50+
{Name: "structtags", BoolVar: new(bool), PassToTest: true},
51+
{Name: "tests", BoolVar: new(bool), PassToTest: true},
52+
{Name: "unreachable", BoolVar: new(bool), PassToTest: true},
53+
{Name: "unsafeptr", BoolVar: new(bool), PassToTest: true},
54+
{Name: "unusedfuncs", PassToTest: true},
55+
{Name: "unusedresult", BoolVar: new(bool), PassToTest: true},
56+
{Name: "unusedstringmethods", PassToTest: true},
5757
}
5858

5959
var vetTool string
@@ -91,9 +91,17 @@ func vetFlags(args []string) (passToVet, packageNames []string) {
9191
if err := f.Value.Set(value); err != nil {
9292
base.Fatalf("invalid flag argument for -%s: %v", f.Name, err)
9393
}
94-
switch f.Name {
95-
// Flags known to the build but not to vet, so must be dropped.
96-
case "a", "x", "n", "vettool", "compiler":
94+
keep := f.PassToTest
95+
if !keep {
96+
// A build flag, probably one we don't want to pass to vet.
97+
// Can whitelist.
98+
switch f.Name {
99+
case "tags", "v":
100+
keep = true
101+
}
102+
}
103+
if !keep {
104+
// Flags known to the build but not to vet, so must be dropped.
97105
if extraWord {
98106
args = append(args[:i], args[i+2:]...)
99107
extraWord = false

src/cmd/go/internal/work/build.go

Lines changed: 4 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -86,8 +86,6 @@ and test commands:
8686
arguments to pass on each gccgo compiler/linker invocation.
8787
-gcflags '[pattern=]arg list'
8888
arguments to pass on each go tool compile invocation.
89-
-getmode mode
90-
module download mode to use. See 'go help modules' for more.
9189
-installsuffix suffix
9290
a suffix to use in the name of the package installation directory,
9391
in order to keep output separate from default builds.
@@ -100,6 +98,9 @@ and test commands:
10098
-linkshared
10199
link against shared libraries previously created with
102100
-buildmode=shared.
101+
-mod mode
102+
module download mode to use: readonly, release, or vendor.
103+
See 'go help modules' for more.
103104
-pkgdir dir
104105
install and load all packages from dir instead of the usual locations.
105106
For example, when building with a non-standard configuration,
@@ -220,7 +221,7 @@ func AddBuildFlags(cmd *base.Command) {
220221
cmd.Flag.StringVar(&cfg.BuildBuildmode, "buildmode", "default", "")
221222
cmd.Flag.Var(&load.BuildGcflags, "gcflags", "")
222223
cmd.Flag.Var(&load.BuildGccgoflags, "gccgoflags", "")
223-
cmd.Flag.StringVar(&cfg.BuildGetmode, "getmode", "", "")
224+
cmd.Flag.StringVar(&cfg.BuildMod, "mod", "", "")
224225
cmd.Flag.StringVar(&cfg.BuildContext.InstallSuffix, "installsuffix", "", "")
225226
cmd.Flag.Var(&load.BuildLdflags, "ldflags", "")
226227
cmd.Flag.BoolVar(&cfg.BuildLinkshared, "linkshared", false, "")

src/cmd/go/internal/work/init.go

Lines changed: 22 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -14,6 +14,7 @@ import (
1414
"fmt"
1515
"os"
1616
"path/filepath"
17+
"strings"
1718
)
1819

1920
func BuildInit() {
@@ -227,15 +228,30 @@ func buildModeInit() {
227228
}
228229
}
229230

230-
switch cfg.BuildGetmode {
231+
switch cfg.BuildMod {
231232
case "":
232233
// ok
233-
case "local", "vendor":
234-
// ok but check for modules
235-
if load.ModLookup == nil {
236-
base.Fatalf("build flag -getmode=%s only valid when using modules", cfg.BuildGetmode)
234+
case "readonly", "vendor":
235+
if load.ModLookup == nil && !inGOFLAGS("-mod") {
236+
base.Fatalf("build flag -mod=%s only valid when using modules", cfg.BuildMod)
237237
}
238238
default:
239-
base.Fatalf("-getmode=%s not supported (can be '', 'local', or 'vendor')", cfg.BuildGetmode)
239+
base.Fatalf("-mod=%s not supported (can be '', 'readonly', or 'vendor')", cfg.BuildMod)
240240
}
241241
}
242+
243+
func inGOFLAGS(flag string) bool {
244+
for _, goflag := range base.GOFLAGS() {
245+
name := goflag
246+
if strings.HasPrefix(name, "--") {
247+
name = name[1:]
248+
}
249+
if i := strings.Index(name, "="); i >= 0 {
250+
name = name[:i]
251+
}
252+
if name == flag {
253+
return true
254+
}
255+
}
256+
return false
257+
}

0 commit comments

Comments
 (0)