Skip to content

Commit 1c62fb2

Browse files
authored
Merge pull request #431 from LeGEC/430-fix-usage-message-for-func-flags
fix usage message for func flags, fix arguments order
2 parents 8a6c85f + 1a4b5b2 commit 1c62fb2

File tree

5 files changed

+73
-11
lines changed

5 files changed

+73
-11
lines changed

bool_func.go

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,7 @@ type boolfuncValue func(string) error
55

66
func (f boolfuncValue) Set(s string) error { return f(s) }
77

8-
func (f boolfuncValue) Type() string { return "func" }
8+
func (f boolfuncValue) Type() string { return "boolfunc" }
99

1010
func (f boolfuncValue) String() string { return "" } // same behavior as stdlib 'flag' package
1111

@@ -35,6 +35,6 @@ func BoolFunc(name string, usage string, fn func(string) error) {
3535
}
3636

3737
// BoolFuncP is like BoolFunc, but accepts a shorthand letter that can be used after a single dash.
38-
func BoolFuncP(name, shorthand string, fn func(string) error, usage string) {
38+
func BoolFuncP(name, shorthand string, usage string, fn func(string) error) {
3939
CommandLine.BoolFuncP(name, shorthand, usage, fn)
4040
}

bool_func_test.go

Lines changed: 32 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -75,7 +75,7 @@ func TestBoolFuncCompat(t *testing.T) {
7575
args := []string{"--bflag", "--bflag=false", "--bflag=1", "--bflag=bar", "--bflag="}
7676

7777
// It turns out that, even though the function is called "BoolFunc",
78-
// the stanard flag package does not try to parse the value assigned to
78+
// the standard flag package does not try to parse the value assigned to
7979
// that cli flag as a boolean. The string provided on the command line is
8080
// passed as is to the callback.
8181
// e.g: with "--bflag=not_a_bool" on the command line, the FlagSet does not
@@ -106,7 +106,7 @@ func TestBoolFuncCompat(t *testing.T) {
106106
flagName := "bflag"
107107
args := []string{"--bflag", "--bflag=err", "--bflag=after"}
108108

109-
// test behavior of standard flag.Fset with an error triggere by the callback:
109+
// test behavior of standard flag.Fset with an error triggered by the callback:
110110
// (note: as can be seen in 'runCase()', if the callback sees "err" as a value
111111
// for the bool flag, it will return an error)
112112
stdFSet := flag.NewFlagSet("std test", flag.ContinueOnError)
@@ -145,3 +145,33 @@ func TestBoolFuncCompat(t *testing.T) {
145145
}
146146
})
147147
}
148+
149+
func TestBoolFuncUsage(t *testing.T) {
150+
t.Run("regular func flag", func(t *testing.T) {
151+
// regular boolfunc flag:
152+
// expect to see '--flag1' followed by the usageMessage, and no mention of a default value
153+
fset := NewFlagSet("unittest", ContinueOnError)
154+
fset.BoolFunc("flag1", "usage message", func(s string) error { return nil })
155+
usage := fset.FlagUsagesWrapped(80)
156+
157+
usage = strings.TrimSpace(usage)
158+
expected := "--flag1 usage message"
159+
if usage != expected {
160+
t.Fatalf("unexpected generated usage message\n expected: %s\n got: %s", expected, usage)
161+
}
162+
})
163+
164+
t.Run("func flag with placeholder name", func(t *testing.T) {
165+
// func flag, with a placeholder name:
166+
// if usageMesage contains a placeholder, expect '--flag2 {placeholder}'; still expect no mention of a default value
167+
fset := NewFlagSet("unittest", ContinueOnError)
168+
fset.BoolFunc("flag2", "usage message with `name` placeholder", func(s string) error { return nil })
169+
usage := fset.FlagUsagesWrapped(80)
170+
171+
usage = strings.TrimSpace(usage)
172+
expected := "--flag2 name usage message with name placeholder"
173+
if usage != expected {
174+
t.Fatalf("unexpected generated usage message\n expected: %s\n got: %s", expected, usage)
175+
}
176+
})
177+
}

flag.go

Lines changed: 5 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -549,7 +549,7 @@ func (f *FlagSet) PrintDefaults() {
549549
func (f *Flag) defaultIsZeroValue() bool {
550550
switch f.Value.(type) {
551551
case boolFlag:
552-
return f.DefValue == "false"
552+
return f.DefValue == "false" || f.DefValue == ""
553553
case *durationValue:
554554
// Beginning in Go 1.7, duration zero values are "0s"
555555
return f.DefValue == "0" || f.DefValue == "0s"
@@ -599,8 +599,10 @@ func UnquoteUsage(flag *Flag) (name string, usage string) {
599599

600600
name = flag.Value.Type()
601601
switch name {
602-
case "bool":
602+
case "bool", "boolfunc":
603603
name = ""
604+
case "func":
605+
name = "value"
604606
case "float64":
605607
name = "float"
606608
case "int64":
@@ -718,7 +720,7 @@ func (f *FlagSet) FlagUsagesWrapped(cols int) string {
718720
switch flag.Value.Type() {
719721
case "string":
720722
line += fmt.Sprintf("[=\"%s\"]", flag.NoOptDefVal)
721-
case "bool":
723+
case "bool", "boolfunc":
722724
if flag.NoOptDefVal != "true" {
723725
line += fmt.Sprintf("[=%s]", flag.NoOptDefVal)
724726
}

func.go

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -27,11 +27,11 @@ func (f *FlagSet) FuncP(name string, shorthand string, usage string, fn func(str
2727
//
2828
// The callback function will be called every time "--{name}={value}" (or equivalent) is
2929
// parsed on the command line, with "{value}" as an argument.
30-
func Func(name string, fn func(string) error, usage string) {
30+
func Func(name string, usage string, fn func(string) error) {
3131
CommandLine.FuncP(name, "", usage, fn)
3232
}
3333

3434
// FuncP is like Func, but accepts a shorthand letter that can be used after a single dash.
35-
func FuncP(name, shorthand string, fn func(string) error, usage string) {
35+
func FuncP(name, shorthand string, usage string, fn func(string) error) {
3636
CommandLine.FuncP(name, shorthand, usage, fn)
3737
}

func_test.go

Lines changed: 32 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -112,9 +112,9 @@ func TestFuncCompat(t *testing.T) {
112112
flagName := "fnflag"
113113
args := []string{"--fnflag", "before", "--fnflag", "err", "--fnflag", "after"}
114114

115-
// test behavior of standard flag.Fset with an error triggere by the callback:
115+
// test behavior of standard flag.Fset with an error triggered by the callback:
116116
// (note: as can be seen in 'runCase()', if the callback sees "err" as a value
117-
// for the bool flag, it will return an error)
117+
// for the flag, it will return an error)
118118
stdFSet := flag.NewFlagSet("std test", flag.ContinueOnError)
119119
stdFSet.SetOutput(io.Discard) // suppress output
120120

@@ -151,3 +151,33 @@ func TestFuncCompat(t *testing.T) {
151151
}
152152
})
153153
}
154+
155+
func TestFuncUsage(t *testing.T) {
156+
t.Run("regular func flag", func(t *testing.T) {
157+
// regular func flag:
158+
// expect to see '--flag1 value' followed by the usageMessage, and no mention of a default value
159+
fset := NewFlagSet("unittest", ContinueOnError)
160+
fset.Func("flag1", "usage message", func(s string) error { return nil })
161+
usage := fset.FlagUsagesWrapped(80)
162+
163+
usage = strings.TrimSpace(usage)
164+
expected := "--flag1 value usage message"
165+
if usage != expected {
166+
t.Fatalf("unexpected generated usage message\n expected: %s\n got: %s", expected, usage)
167+
}
168+
})
169+
170+
t.Run("func flag with placeholder name", func(t *testing.T) {
171+
// func flag, with a placeholder name:
172+
// if usageMesage contains a placeholder, expect that name; still expect no mention of a default value
173+
fset := NewFlagSet("unittest", ContinueOnError)
174+
fset.Func("flag2", "usage message with `name` placeholder", func(s string) error { return nil })
175+
usage := fset.FlagUsagesWrapped(80)
176+
177+
usage = strings.TrimSpace(usage)
178+
expected := "--flag2 name usage message with name placeholder"
179+
if usage != expected {
180+
t.Fatalf("unexpected generated usage message\n expected: %s\n got: %s", expected, usage)
181+
}
182+
})
183+
}

0 commit comments

Comments
 (0)
pFad - Phonifier reborn

Pfad - The Proxy pFad of © 2024 Garber Painting. All rights reserved.

Note: This service is not intended for secure transactions such as banking, social media, email, or purchasing. Use at your own risk. We assume no liability whatsoever for broken pages.


Alternative Proxies:

Alternative Proxy

pFad Proxy

pFad v3 Proxy

pFad v4 Proxy