Merge lp:~rogpeppe/gnuflag/001-merge-go-updates into lp:gnuflag

Proposed by Roger Peppe
Status: Merged
Merged at revision: 14
Proposed branch: lp:~rogpeppe/gnuflag/001-merge-go-updates
Merge into: lp:gnuflag
Diff against target: 621 lines (+192/-58)
3 files modified
export_test.go (+1/-6)
flag.go (+92/-47)
flag_test.go (+99/-5)
To merge this branch: bzr merge lp:~rogpeppe/gnuflag/001-merge-go-updates
Reviewer Review Type Date Requested Status
gnuflag maintainers Pending
Review via email: mp+247632@code.launchpad.net

Description of the change

merge updates from Go tree

The flag package in the Go source tree has had
a bunch of updates. This change brings gnuflag
up to date with that.

https://codereview.appspot.com/199070043/

To post a comment you must log in.
Revision history for this message
Roger Peppe (rogpeppe) wrote :

Please take a look.

Revision history for this message
Roger Peppe (rogpeppe) wrote :

Reviewers: mp+247632_code.launchpad.net,

Message:
Please take a look.

Description:
merge updates from Go tree

The flag package in the Go source tree has had
a bunch of updates. This change brings gnuflag
up to date with that.

https://code.launchpad.net/~rogpeppe/gnuflag/001-merge-go-updates/+merge/247632

(do not edit description out of merge proposal)

Please review this at https://codereview.appspot.com/199070043/

Affected files (+194, -58 lines):
   A [revision details]
   M export_test.go
   M flag.go
   M flag_test.go

Revision history for this message
Martin Hilton (martin-hilton) wrote :
Revision history for this message
Jay R. Wren (evarlast) wrote :
Revision history for this message
Roger Peppe (rogpeppe) wrote :

*** Submitted:

merge updates from Go tree

The flag package in the Go source tree has had
a bunch of updates. This change brings gnuflag
up to date with that.

R=martin.hilton, jay.wren
CC=
https://codereview.appspot.com/199070043

https://codereview.appspot.com/199070043/

Preview Diff

[H/L] Next/Prev Comment, [J/K] Next/Prev File, [N/P] Next/Prev Hunk
1=== modified file 'export_test.go'
2--- export_test.go 2012-02-01 11:10:44 +0000
3+++ export_test.go 2015-01-26 18:18:29 +0000
4@@ -14,11 +14,6 @@
5 // After calling ResetForTesting, parse errors in flag handling will not
6 // exit the program.
7 func ResetForTesting(usage func()) {
8- commandLine = NewFlagSet(os.Args[0], ContinueOnError)
9+ CommandLine = NewFlagSet(os.Args[0], ContinueOnError)
10 Usage = usage
11 }
12-
13-// CommandLine returns the default FlagSet.
14-func CommandLine() *FlagSet {
15- return commandLine
16-}
17
18=== modified file 'flag.go'
19--- flag.go 2012-10-02 13:48:04 +0000
20+++ flag.go 2015-01-26 18:18:29 +0000
21@@ -23,7 +23,7 @@
22
23 Flag parsing stops after the terminator "--", or just before the first
24 non-flag argument ("-" is a non-flag argument) if the interspersed
25- argument to Parse is false.
26+ argument to Parse is false.
27 */
28 package gnuflag
29
30@@ -40,7 +40,8 @@
31 "unicode/utf8"
32 )
33
34-// ErrHelp is the error returned if the flag -help is invoked but no such flag is defined.
35+// ErrHelp is the error returned if the -help or -h flag is invoked
36+// but no such flag is defined.
37 var ErrHelp = errors.New("flag: help requested")
38
39 // -- bool Value
40@@ -57,8 +58,19 @@
41 return err
42 }
43
44+func (b *boolValue) Get() interface{} { return bool(*b) }
45+
46 func (b *boolValue) String() string { return fmt.Sprintf("%v", *b) }
47
48+func (b *boolValue) IsBoolFlag() bool { return true }
49+
50+// optional interface to indicate boolean flags that can be
51+// supplied without "=value" text
52+type boolFlag interface {
53+ Value
54+ IsBoolFlag() bool
55+}
56+
57 // -- int Value
58 type intValue int
59
60@@ -73,6 +85,8 @@
61 return err
62 }
63
64+func (i *intValue) Get() interface{} { return int(*i) }
65+
66 func (i *intValue) String() string { return fmt.Sprintf("%v", *i) }
67
68 // -- int64 Value
69@@ -89,6 +103,8 @@
70 return err
71 }
72
73+func (i *int64Value) Get() interface{} { return int64(*i) }
74+
75 func (i *int64Value) String() string { return fmt.Sprintf("%v", *i) }
76
77 // -- uint Value
78@@ -105,6 +121,8 @@
79 return err
80 }
81
82+func (i *uintValue) Get() interface{} { return uint(*i) }
83+
84 func (i *uintValue) String() string { return fmt.Sprintf("%v", *i) }
85
86 // -- uint64 Value
87@@ -121,6 +139,8 @@
88 return err
89 }
90
91+func (i *uint64Value) Get() interface{} { return uint64(*i) }
92+
93 func (i *uint64Value) String() string { return fmt.Sprintf("%v", *i) }
94
95 // -- string Value
96@@ -136,6 +156,8 @@
97 return nil
98 }
99
100+func (s *stringValue) Get() interface{} { return string(*s) }
101+
102 func (s *stringValue) String() string { return fmt.Sprintf("%s", *s) }
103
104 // -- float64 Value
105@@ -152,6 +174,8 @@
106 return err
107 }
108
109+func (f *float64Value) Get() interface{} { return float64(*f) }
110+
111 func (f *float64Value) String() string { return fmt.Sprintf("%v", *f) }
112
113 // -- time.Duration Value
114@@ -168,6 +192,8 @@
115 return err
116 }
117
118+func (d *durationValue) Get() interface{} { return time.Duration(*d) }
119+
120 func (d *durationValue) String() string { return (*time.Duration)(d).String() }
121
122 // Value is the interface to the dynamic value stored in a flag.
123@@ -177,6 +203,15 @@
124 Set(string) error
125 }
126
127+// Getter is an interface that allows the contents of a Value to be retrieved.
128+// It wraps the Value interface, rather than being part of it, because it
129+// appeared after Go 1 and its compatibility rules. All Value types provided
130+// by this package satisfy the Getter interface.
131+type Getter interface {
132+ Value
133+ Get() interface{}
134+}
135+
136 // ErrorHandling defines how to handle flag parsing errors.
137 type ErrorHandling int
138
139@@ -254,7 +289,7 @@
140 // VisitAll visits the command-line flags in lexicographical order, calling
141 // fn for each. It visits all flags, even those not set.
142 func VisitAll(fn func(*Flag)) {
143- commandLine.VisitAll(fn)
144+ CommandLine.VisitAll(fn)
145 }
146
147 // Visit visits the flags in lexicographical order, calling fn for each.
148@@ -268,7 +303,7 @@
149 // Visit visits the command-line flags in lexicographical order, calling fn
150 // for each. It visits only those flags that have been set.
151 func Visit(fn func(*Flag)) {
152- commandLine.Visit(fn)
153+ CommandLine.Visit(fn)
154 }
155
156 // Lookup returns the Flag structure of the named flag, returning nil if none exists.
157@@ -279,7 +314,7 @@
158 // Lookup returns the Flag structure of the named command-line flag,
159 // returning nil if none exists.
160 func Lookup(name string) *Flag {
161- return commandLine.formal[name]
162+ return CommandLine.formal[name]
163 }
164
165 // Set sets the value of the named flag.
166@@ -301,7 +336,7 @@
167
168 // Set sets the value of the named command-line flag.
169 func Set(name, value string) error {
170- return commandLine.Set(name, value)
171+ return CommandLine.Set(name, value)
172 }
173
174 // flagsByLength is a slice of flags implementing sort.Interface,
175@@ -377,16 +412,20 @@
176
177 // PrintDefaults prints to standard error the default values of all defined command-line flags.
178 func PrintDefaults() {
179- commandLine.PrintDefaults()
180+ CommandLine.PrintDefaults()
181 }
182
183 // defaultUsage is the default function to print a usage message.
184 func defaultUsage(f *FlagSet) {
185- fmt.Fprintf(f.out(), "Usage of %s:\n", f.name)
186+ if f.name == "" {
187+ fmt.Fprintf(f.out(), "Usage:\n")
188+ } else {
189+ fmt.Fprintf(f.out(), "Usage of %s:\n", f.name)
190+ }
191 f.PrintDefaults()
192 }
193
194-// NOTE: Usage is not just defaultUsage(commandLine)
195+// NOTE: Usage is not just defaultUsage(CommandLine)
196 // because it serves (via godoc flag Usage) as the example
197 // for how to write your own usage function.
198
199@@ -401,7 +440,7 @@
200 func (f *FlagSet) NFlag() int { return len(f.actual) }
201
202 // NFlag returns the number of command-line flags that have been set.
203-func NFlag() int { return len(commandLine.actual) }
204+func NFlag() int { return len(CommandLine.actual) }
205
206 // Arg returns the i'th argument. Arg(0) is the first remaining argument
207 // after flags have been processed.
208@@ -415,20 +454,20 @@
209 // Arg returns the i'th command-line argument. Arg(0) is the first remaining argument
210 // after flags have been processed.
211 func Arg(i int) string {
212- return commandLine.Arg(i)
213+ return CommandLine.Arg(i)
214 }
215
216 // NArg is the number of arguments remaining after flags have been processed.
217 func (f *FlagSet) NArg() int { return len(f.args) }
218
219 // NArg is the number of arguments remaining after flags have been processed.
220-func NArg() int { return len(commandLine.args) }
221+func NArg() int { return len(CommandLine.args) }
222
223 // Args returns the non-flag arguments.
224 func (f *FlagSet) Args() []string { return f.args }
225
226 // Args returns the non-flag command-line arguments.
227-func Args() []string { return commandLine.args }
228+func Args() []string { return CommandLine.args }
229
230 // BoolVar defines a bool flag with specified name, default value, and usage string.
231 // The argument p points to a bool variable in which to store the value of the flag.
232@@ -439,7 +478,7 @@
233 // BoolVar defines a bool flag with specified name, default value, and usage string.
234 // The argument p points to a bool variable in which to store the value of the flag.
235 func BoolVar(p *bool, name string, value bool, usage string) {
236- commandLine.Var(newBoolValue(value, p), name, usage)
237+ CommandLine.Var(newBoolValue(value, p), name, usage)
238 }
239
240 // Bool defines a bool flag with specified name, default value, and usage string.
241@@ -453,7 +492,7 @@
242 // Bool defines a bool flag with specified name, default value, and usage string.
243 // The return value is the address of a bool variable that stores the value of the flag.
244 func Bool(name string, value bool, usage string) *bool {
245- return commandLine.Bool(name, value, usage)
246+ return CommandLine.Bool(name, value, usage)
247 }
248
249 // IntVar defines an int flag with specified name, default value, and usage string.
250@@ -465,7 +504,7 @@
251 // IntVar defines an int flag with specified name, default value, and usage string.
252 // The argument p points to an int variable in which to store the value of the flag.
253 func IntVar(p *int, name string, value int, usage string) {
254- commandLine.Var(newIntValue(value, p), name, usage)
255+ CommandLine.Var(newIntValue(value, p), name, usage)
256 }
257
258 // Int defines an int flag with specified name, default value, and usage string.
259@@ -479,7 +518,7 @@
260 // Int defines an int flag with specified name, default value, and usage string.
261 // The return value is the address of an int variable that stores the value of the flag.
262 func Int(name string, value int, usage string) *int {
263- return commandLine.Int(name, value, usage)
264+ return CommandLine.Int(name, value, usage)
265 }
266
267 // Int64Var defines an int64 flag with specified name, default value, and usage string.
268@@ -491,7 +530,7 @@
269 // Int64Var defines an int64 flag with specified name, default value, and usage string.
270 // The argument p points to an int64 variable in which to store the value of the flag.
271 func Int64Var(p *int64, name string, value int64, usage string) {
272- commandLine.Var(newInt64Value(value, p), name, usage)
273+ CommandLine.Var(newInt64Value(value, p), name, usage)
274 }
275
276 // Int64 defines an int64 flag with specified name, default value, and usage string.
277@@ -505,7 +544,7 @@
278 // Int64 defines an int64 flag with specified name, default value, and usage string.
279 // The return value is the address of an int64 variable that stores the value of the flag.
280 func Int64(name string, value int64, usage string) *int64 {
281- return commandLine.Int64(name, value, usage)
282+ return CommandLine.Int64(name, value, usage)
283 }
284
285 // UintVar defines a uint flag with specified name, default value, and usage string.
286@@ -517,7 +556,7 @@
287 // UintVar defines a uint flag with specified name, default value, and usage string.
288 // The argument p points to a uint variable in which to store the value of the flag.
289 func UintVar(p *uint, name string, value uint, usage string) {
290- commandLine.Var(newUintValue(value, p), name, usage)
291+ CommandLine.Var(newUintValue(value, p), name, usage)
292 }
293
294 // Uint defines a uint flag with specified name, default value, and usage string.
295@@ -531,7 +570,7 @@
296 // Uint defines a uint flag with specified name, default value, and usage string.
297 // The return value is the address of a uint variable that stores the value of the flag.
298 func Uint(name string, value uint, usage string) *uint {
299- return commandLine.Uint(name, value, usage)
300+ return CommandLine.Uint(name, value, usage)
301 }
302
303 // Uint64Var defines a uint64 flag with specified name, default value, and usage string.
304@@ -543,7 +582,7 @@
305 // Uint64Var defines a uint64 flag with specified name, default value, and usage string.
306 // The argument p points to a uint64 variable in which to store the value of the flag.
307 func Uint64Var(p *uint64, name string, value uint64, usage string) {
308- commandLine.Var(newUint64Value(value, p), name, usage)
309+ CommandLine.Var(newUint64Value(value, p), name, usage)
310 }
311
312 // Uint64 defines a uint64 flag with specified name, default value, and usage string.
313@@ -557,7 +596,7 @@
314 // Uint64 defines a uint64 flag with specified name, default value, and usage string.
315 // The return value is the address of a uint64 variable that stores the value of the flag.
316 func Uint64(name string, value uint64, usage string) *uint64 {
317- return commandLine.Uint64(name, value, usage)
318+ return CommandLine.Uint64(name, value, usage)
319 }
320
321 // StringVar defines a string flag with specified name, default value, and usage string.
322@@ -569,7 +608,7 @@
323 // StringVar defines a string flag with specified name, default value, and usage string.
324 // The argument p points to a string variable in which to store the value of the flag.
325 func StringVar(p *string, name string, value string, usage string) {
326- commandLine.Var(newStringValue(value, p), name, usage)
327+ CommandLine.Var(newStringValue(value, p), name, usage)
328 }
329
330 // String defines a string flag with specified name, default value, and usage string.
331@@ -583,7 +622,7 @@
332 // String defines a string flag with specified name, default value, and usage string.
333 // The return value is the address of a string variable that stores the value of the flag.
334 func String(name string, value string, usage string) *string {
335- return commandLine.String(name, value, usage)
336+ return CommandLine.String(name, value, usage)
337 }
338
339 // Float64Var defines a float64 flag with specified name, default value, and usage string.
340@@ -595,7 +634,7 @@
341 // Float64Var defines a float64 flag with specified name, default value, and usage string.
342 // The argument p points to a float64 variable in which to store the value of the flag.
343 func Float64Var(p *float64, name string, value float64, usage string) {
344- commandLine.Var(newFloat64Value(value, p), name, usage)
345+ CommandLine.Var(newFloat64Value(value, p), name, usage)
346 }
347
348 // Float64 defines a float64 flag with specified name, default value, and usage string.
349@@ -609,7 +648,7 @@
350 // Float64 defines a float64 flag with specified name, default value, and usage string.
351 // The return value is the address of a float64 variable that stores the value of the flag.
352 func Float64(name string, value float64, usage string) *float64 {
353- return commandLine.Float64(name, value, usage)
354+ return CommandLine.Float64(name, value, usage)
355 }
356
357 // DurationVar defines a time.Duration flag with specified name, default value, and usage string.
358@@ -621,7 +660,7 @@
359 // DurationVar defines a time.Duration flag with specified name, default value, and usage string.
360 // The argument p points to a time.Duration variable in which to store the value of the flag.
361 func DurationVar(p *time.Duration, name string, value time.Duration, usage string) {
362- commandLine.Var(newDurationValue(value, p), name, usage)
363+ CommandLine.Var(newDurationValue(value, p), name, usage)
364 }
365
366 // Duration defines a time.Duration flag with specified name, default value, and usage string.
367@@ -635,7 +674,7 @@
368 // Duration defines a time.Duration flag with specified name, default value, and usage string.
369 // The return value is the address of a time.Duration variable that stores the value of the flag.
370 func Duration(name string, value time.Duration, usage string) *time.Duration {
371- return commandLine.Duration(name, value, usage)
372+ return CommandLine.Duration(name, value, usage)
373 }
374
375 // Var defines a flag with the specified name and usage string. The type and
376@@ -665,7 +704,7 @@
377 // of strings by giving the slice the methods of Value; in particular, Set would
378 // decompose the comma-separated string into the slice.
379 func Var(value Value, name string, usage string) {
380- commandLine.Var(value, name, usage)
381+ CommandLine.Var(value, name, usage)
382 }
383
384 // failf prints to standard error a formatted error and usage message and
385@@ -678,18 +717,20 @@
386 }
387
388 // usage calls the Usage method for the flag set, or the usage function if
389-// the flag set is commandLine.
390+// the flag set is CommandLine.
391 func (f *FlagSet) usage() {
392- if f == commandLine {
393- Usage()
394- } else if f.Usage == nil {
395- defaultUsage(f)
396+ if f.Usage == nil {
397+ if f == CommandLine {
398+ Usage()
399+ } else {
400+ defaultUsage(f)
401+ }
402 } else {
403 f.Usage()
404 }
405 }
406
407-func (f *FlagSet) parseOneGnu() (flagName string, long, finished bool, err error) {
408+func (f *FlagSet) parseOne() (flagName string, long, finished bool, err error) {
409 if len(f.procArgs) == 0 {
410 finished = true
411 return
412@@ -761,7 +802,7 @@
413 return "-" + name
414 }
415
416-func (f *FlagSet) parseGnuFlagArg(name string, long bool) (finished bool, err error) {
417+func (f *FlagSet) parseFlagArg(name string, long bool) (finished bool, err error) {
418 m := f.formal
419 flag, alreadythere := m[name] // BUG
420 if !alreadythere {
421@@ -772,10 +813,12 @@
422 // TODO print --xxx when flag is more than one rune.
423 return false, f.failf("flag provided but not defined: %s", flagWithMinus(name))
424 }
425- if fv, ok := flag.Value.(*boolValue); ok && !strings.HasPrefix(f.procFlag, "=") {
426+ if fv, ok := flag.Value.(boolFlag); ok && fv.IsBoolFlag() && !strings.HasPrefix(f.procFlag, "=") {
427 // special case: doesn't need an arg, and an arg hasn't
428 // been provided explicitly.
429- fv.Set("true")
430+ if err := fv.Set("true"); err != nil {
431+ return false, f.failf("invalid boolean flag %s: %v", name, err)
432+ }
433 } else {
434 // It must have a value, which might be the next argument.
435 var hasValue bool
436@@ -814,7 +857,7 @@
437 // Parse parses flag definitions from the argument list, which should not
438 // include the command name. Must be called after all flags in the FlagSet
439 // are defined and before flags are accessed by the program.
440-// The return value will be ErrHelp if --help was set but not defined.
441+// The return value will be ErrHelp if --help or -h was set but not defined.
442 // If allowIntersperse is set, arguments and flags can be interspersed, that
443 // is flags can follow positional arguments.
444 func (f *FlagSet) Parse(allowIntersperse bool, arguments []string) error {
445@@ -824,10 +867,10 @@
446 f.args = nil
447 f.allowIntersperse = allowIntersperse
448 for {
449- name, long, finished, err := f.parseOneGnu()
450+ name, long, finished, err := f.parseOne()
451 if !finished {
452 if name != "" {
453- finished, err = f.parseGnuFlagArg(name, long)
454+ finished, err = f.parseFlagArg(name, long)
455 }
456 }
457 if err != nil {
458@@ -860,17 +903,19 @@
459 // If allowIntersperse is set, arguments and flags can be interspersed, that
460 // is flags can follow positional arguments.
461 func Parse(allowIntersperse bool) {
462- // Ignore errors; commandLine is set for ExitOnError.
463- commandLine.Parse(allowIntersperse, os.Args[1:])
464+ // Ignore errors; CommandLine is set for ExitOnError.
465+ CommandLine.Parse(allowIntersperse, os.Args[1:])
466 }
467
468 // Parsed returns true if the command-line flags have been parsed.
469 func Parsed() bool {
470- return commandLine.Parsed()
471+ return CommandLine.Parsed()
472 }
473
474-// The default set of command-line flags, parsed from os.Args.
475-var commandLine = NewFlagSet(os.Args[0], ExitOnError)
476+// CommandLine is the default set of command-line flags, parsed from os.Args.
477+// The top-level functions such as BoolVar, Arg, and so on are wrappers for the
478+// methods of CommandLine.
479+var CommandLine = NewFlagSet(os.Args[0], ExitOnError)
480
481 // NewFlagSet returns a new, empty flag set with the specified name and
482 // error handling property.
483
484=== modified file 'flag_test.go'
485--- flag_test.go 2012-10-02 13:48:04 +0000
486+++ flag_test.go 2015-01-26 18:18:29 +0000
487@@ -94,10 +94,54 @@
488 }
489 }
490
491+func TestGet(t *testing.T) {
492+ ResetForTesting(nil)
493+ Bool("test_bool", true, "bool value")
494+ Int("test_int", 1, "int value")
495+ Int64("test_int64", 2, "int64 value")
496+ Uint("test_uint", 3, "uint value")
497+ Uint64("test_uint64", 4, "uint64 value")
498+ String("test_string", "5", "string value")
499+ Float64("test_float64", 6, "float64 value")
500+ Duration("test_duration", 7, "time.Duration value")
501+
502+ visitor := func(f *Flag) {
503+ if len(f.Name) > 5 && f.Name[0:5] == "test_" {
504+ g, ok := f.Value.(Getter)
505+ if !ok {
506+ t.Errorf("Visit: value does not satisfy Getter: %T", f.Value)
507+ return
508+ }
509+ switch f.Name {
510+ case "test_bool":
511+ ok = g.Get() == true
512+ case "test_int":
513+ ok = g.Get() == int(1)
514+ case "test_int64":
515+ ok = g.Get() == int64(2)
516+ case "test_uint":
517+ ok = g.Get() == uint(3)
518+ case "test_uint64":
519+ ok = g.Get() == uint64(4)
520+ case "test_string":
521+ ok = g.Get() == "5"
522+ case "test_float64":
523+ ok = g.Get() == float64(6)
524+ case "test_duration":
525+ ok = g.Get() == time.Duration(7)
526+ }
527+ if !ok {
528+ t.Errorf("Visit: bad value %T(%v) for %s", g.Get(), g.Get(), f.Name)
529+ }
530+ }
531+ }
532+ VisitAll(visitor)
533+}
534+
535 func TestUsage(t *testing.T) {
536 called := false
537 ResetForTesting(func() { called = true })
538- f := CommandLine()
539+ f := CommandLine
540 f.SetOutput(nullWriter{})
541 if f.Parse(true, []string{"-x"}) == nil {
542 t.Error("parse did not fail for unknown flag")
543@@ -383,9 +427,8 @@
544 func TestParse(t *testing.T) {
545 testParse(func() *FlagSet {
546 ResetForTesting(func() {})
547- f := CommandLine()
548- f.SetOutput(nullWriter{})
549- return f
550+ CommandLine.SetOutput(nullWriter{})
551+ return CommandLine
552 }, t)
553 }
554
555@@ -426,6 +469,57 @@
556 }
557 }
558
559+func TestUserDefinedForCommandLine(t *testing.T) {
560+ const help = "HELP"
561+ var result string
562+ ResetForTesting(func() { result = help })
563+ Usage()
564+ if result != help {
565+ t.Fatalf("got %q; expected %q", result, help)
566+ }
567+}
568+
569+// Declare a user-defined boolean flag type.
570+type boolFlagVar struct {
571+ count int
572+}
573+
574+func (b *boolFlagVar) String() string {
575+ return fmt.Sprintf("%d", b.count)
576+}
577+
578+func (b *boolFlagVar) Set(value string) error {
579+ if value == "true" {
580+ b.count++
581+ }
582+ return nil
583+}
584+
585+func (b *boolFlagVar) IsBoolFlag() bool {
586+ return b.count < 4
587+}
588+
589+func TestUserDefinedBool(t *testing.T) {
590+ var flags FlagSet
591+ flags.Init("test", ContinueOnError)
592+ var b boolFlagVar
593+ var err error
594+ flags.Var(&b, "b", "usage")
595+ if err = flags.Parse(true, []string{"-b", "-b", "-b", "-b=true", "-b=false", "-b", "barg", "-b"}); err != nil {
596+ if b.count < 4 {
597+ t.Error(err)
598+ }
599+ }
600+
601+ if b.count != 4 {
602+ t.Errorf("want: %d; got: %d", 4, b.count)
603+ }
604+
605+ if err == nil {
606+ t.Error("expected error; got none")
607+ }
608+}
609+
610 func TestSetOutput(t *testing.T) {
611 var flags FlagSet
612 var buf bytes.Buffer
613@@ -445,7 +539,7 @@
614 defer func() { os.Args = oldArgs }()
615 os.Args = []string{"cmd", "--before", "subcmd", "--after", "args"}
616 before := Bool("before", false, "")
617- if err := CommandLine().Parse(false, os.Args[1:]); err != nil {
618+ if err := CommandLine.Parse(false, os.Args[1:]); err != nil {
619 t.Fatal(err)
620 }
621 cmd := Arg(0)

Subscribers

People subscribed via source and target branches