Skip to content

Commit de0957d

Browse files
committed
cmd/go: relax version's error on unexpected flags
In https://golang.org/cl/221397 we made commands like "go version -v" error, since both of the command's flags only make sense when arguments follow them. Without arguments, the command only reports Go's own version, and the flags are most likely a mistake. However, the script below is entirely reasonable: export GOFLAGS=-v # make all Go commands verbose go version go build After the previous CL, "go version" would error. Instead, only error if the flag was passed explicitly, and not via GOFLAGS. The patch does mean that we won't error on "GOFLAGS=-v go version -v", but that very unlikely false negative is okay. The error is only meant to help the user not misuse the flags, anyway - it's not a critical error of any sort. To reuse inGOFLAGS, we move it to the base package and export it there, since it's where the rest of the GOFLAGS funcs are. Fixes #41264. Change-Id: I74003dd25d94bacf9ac507b5cad778fd65233321 Reviewed-on: https://go-review.googlesource.com/c/go/+/254157 Trust: Daniel Martí <[email protected]> Run-TryBot: Daniel Martí <[email protected]> TryBot-Result: Go Bot <[email protected]> Reviewed-by: Bryan C. Mills <[email protected]>
1 parent f1c400a commit de0957d

File tree

4 files changed

+34
-20
lines changed

4 files changed

+34
-20
lines changed

src/cmd/go/internal/base/goflags.go

Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -130,3 +130,20 @@ func SetFromGOFLAGS(flags *flag.FlagSet) {
130130
}
131131
}
132132
}
133+
134+
// InGOFLAGS returns whether GOFLAGS contains the given flag, such as "-mod".
135+
func InGOFLAGS(flag string) bool {
136+
for _, goflag := range GOFLAGS() {
137+
name := goflag
138+
if strings.HasPrefix(name, "--") {
139+
name = name[1:]
140+
}
141+
if i := strings.Index(name, "="); i >= 0 {
142+
name = name[:i]
143+
}
144+
if name == flag {
145+
return true
146+
}
147+
}
148+
return false
149+
}

src/cmd/go/internal/version/version.go

Lines changed: 8 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -54,7 +54,14 @@ var (
5454

5555
func runVersion(ctx context.Context, cmd *base.Command, args []string) {
5656
if len(args) == 0 {
57-
if *versionM || *versionV {
57+
// If any of this command's flags were passed explicitly, error
58+
// out, because they only make sense with arguments.
59+
//
60+
// Don't error if the flags came from GOFLAGS, since that can be
61+
// a reasonable use case. For example, imagine GOFLAGS=-v to
62+
// turn "verbose mode" on for all Go commands, which should not
63+
// break "go version".
64+
if (!base.InGOFLAGS("-m") && *versionM) || (!base.InGOFLAGS("-v") && *versionV) {
5865
fmt.Fprintf(os.Stderr, "go version: flags can only be used with arguments\n")
5966
base.SetExitStatus(2)
6067
return

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

Lines changed: 3 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -254,34 +254,18 @@ func buildModeInit() {
254254
case "":
255255
// Behavior will be determined automatically, as if no flag were passed.
256256
case "readonly", "vendor", "mod":
257-
if !cfg.ModulesEnabled && !inGOFLAGS("-mod") {
257+
if !cfg.ModulesEnabled && !base.InGOFLAGS("-mod") {
258258
base.Fatalf("build flag -mod=%s only valid when using modules", cfg.BuildMod)
259259
}
260260
default:
261261
base.Fatalf("-mod=%s not supported (can be '', 'mod', 'readonly', or 'vendor')", cfg.BuildMod)
262262
}
263263
if !cfg.ModulesEnabled {
264-
if cfg.ModCacheRW && !inGOFLAGS("-modcacherw") {
264+
if cfg.ModCacheRW && !base.InGOFLAGS("-modcacherw") {
265265
base.Fatalf("build flag -modcacherw only valid when using modules")
266266
}
267-
if cfg.ModFile != "" && !inGOFLAGS("-mod") {
267+
if cfg.ModFile != "" && !base.InGOFLAGS("-mod") {
268268
base.Fatalf("build flag -modfile only valid when using modules")
269269
}
270270
}
271271
}
272-
273-
func inGOFLAGS(flag string) bool {
274-
for _, goflag := range base.GOFLAGS() {
275-
name := goflag
276-
if strings.HasPrefix(name, "--") {
277-
name = name[1:]
278-
}
279-
if i := strings.Index(name, "="); i >= 0 {
280-
name = name[:i]
281-
}
282-
if name == flag {
283-
return true
284-
}
285-
}
286-
return false
287-
}

src/cmd/go/testdata/script/version.txt

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,12 @@ stderr 'with arguments'
99
! go version -v
1010
stderr 'with arguments'
1111

12+
# Neither of the two flags above should be an issue via GOFLAGS.
13+
env GOFLAGS='-m -v'
14+
go version
15+
stdout '^go version'
16+
env GOFLAGS=
17+
1218
env GO111MODULE=on
1319
# Skip the builds below if we are running in short mode.
1420
[short] skip

0 commit comments

Comments
 (0)