Skip to content

Commit 8841790

Browse files
mvdandmitshur
authored andcommitted
[release-branch.go1.15] 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 #41464. 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]> (cherry picked from commit de0957d) Reviewed-on: https://go-review.googlesource.com/c/go/+/255498 Trust: Bryan C. Mills <[email protected]> Run-TryBot: Bryan C. Mills <[email protected]>
1 parent bf79f91 commit 8841790

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
@@ -153,3 +153,20 @@ func SetFromGOFLAGS(flags *flag.FlagSet) {
153153
}
154154
}
155155
}
156+
157+
// InGOFLAGS returns whether GOFLAGS contains the given flag, such as "-mod".
158+
func InGOFLAGS(flag string) bool {
159+
for _, goflag := range GOFLAGS() {
160+
name := goflag
161+
if strings.HasPrefix(name, "--") {
162+
name = name[1:]
163+
}
164+
if i := strings.Index(name, "="); i >= 0 {
165+
name = name[:i]
166+
}
167+
if name == flag {
168+
return true
169+
}
170+
}
171+
return false
172+
}

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

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

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