Skip to content

Commit 2d74194

Browse files
committed
flag: test IsBoolFlag when creating the usage message
Although I can't think of any reason to do this, it is possible for a user-defined flag to implement IsBoolFlag but return "false". This is nuts because checking the interface is satisfied should obviously be sufficient, but the documentation kinda implies it's not. And if you try this, you'll discover that the usage message ignores the return value even though the rest of the package plays nice. Bother. So we fix it, as the fix is trivial: call the method when creating the usage message. Fixes #53473 Change-Id: I1ac80a876ad5626eebfc5ef6cb972cd3007afaad Reviewed-on: https://go-review.googlesource.com/c/go/+/431102 Reviewed-by: Cherry Mui <[email protected]> Run-TryBot: Ian Lance Taylor <[email protected]> TryBot-Result: Gopher Robot <[email protected]> Reviewed-by: Ian Lance Taylor <[email protected]>
1 parent d31f850 commit 2d74194

File tree

2 files changed

+30
-2
lines changed

2 files changed

+30
-2
lines changed

src/flag/flag.go

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -550,9 +550,11 @@ func UnquoteUsage(flag *Flag) (name string, usage string) {
550550
}
551551
// No explicit name, so use type if we can find one.
552552
name = "value"
553-
switch flag.Value.(type) {
553+
switch fv := flag.Value.(type) {
554554
case boolFlag:
555-
name = ""
555+
if fv.IsBoolFlag() {
556+
name = ""
557+
}
556558
case *durationValue:
557559
name = "duration"
558560
case *float64Value:

src/flag/flag_test.go

Lines changed: 26 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,7 @@
55
package flag_test
66

77
import (
8+
"bytes"
89
. "flag"
910
"fmt"
1011
"internal/testenv"
@@ -355,6 +356,31 @@ func TestUserDefinedBool(t *testing.T) {
355356
}
356357
}
357358

359+
func TestUserDefinedBoolUsage(t *testing.T) {
360+
var flags FlagSet
361+
flags.Init("test", ContinueOnError)
362+
var buf bytes.Buffer
363+
flags.SetOutput(&buf)
364+
var b boolFlagVar
365+
flags.Var(&b, "b", "X")
366+
b.count = 0
367+
// b.IsBoolFlag() will return true and usage will look boolean.
368+
flags.PrintDefaults()
369+
got := buf.String()
370+
want := " -b\tX\n"
371+
if got != want {
372+
t.Errorf("false: want %q; got %q", want, got)
373+
}
374+
b.count = 4
375+
// b.IsBoolFlag() will return false and usage will look non-boolean.
376+
flags.PrintDefaults()
377+
got = buf.String()
378+
want = " -b\tX\n -b value\n \tX\n"
379+
if got != want {
380+
t.Errorf("false: want %q; got %q", want, got)
381+
}
382+
}
383+
358384
func TestSetOutput(t *testing.T) {
359385
var flags FlagSet
360386
var buf strings.Builder

0 commit comments

Comments
 (0)