Merge lp:~rogpeppe/gnuflag/001-merge-go-updates into lp:gnuflag
- 001-merge-go-updates
- Merge into trunk
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 |
Related bugs: |
Reviewer | Review Type | Date Requested | Status |
---|---|---|---|
gnuflag maintainers | Pending | ||
Review via email: mp+247632@code.launchpad.net |
Commit message
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.
Roger Peppe (rogpeppe) wrote : | # |
Roger Peppe (rogpeppe) wrote : | # |
Reviewers: mp+247632_
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:/
(do not edit description out of merge proposal)
Please review this at https:/
Affected files (+194, -58 lines):
A [revision details]
M export_test.go
M flag.go
M flag_test.go
Martin Hilton (martin-hilton) wrote : | # |
Jay R. Wren (evarlast) wrote : | # |
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:/
Preview Diff
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) |
Please take a look.