blob: 9beeda8ecca93e377b2fad71d2ef275e1bd039bd [file] [log] [blame]
Kent Hagermane566c2e2019-06-03 17:56:42 -04001// Copyright 2009 The Go Authors. All rights reserved.
2// Use of this source code is governed by a BSD-style
3// license that can be found in the LICENSE file.
4
5/*
6Package pflag is a drop-in replacement for Go's flag package, implementing
7POSIX/GNU-style --flags.
8
9pflag is compatible with the GNU extensions to the POSIX recommendations
10for command-line options. See
11http://www.gnu.org/software/libc/manual/html_node/Argument-Syntax.html
12
13Usage:
14
15pflag is a drop-in replacement of Go's native flag package. If you import
16pflag under the name "flag" then all code should continue to function
17with no changes.
18
19 import flag "github.com/spf13/pflag"
20
21There is one exception to this: if you directly instantiate the Flag struct
22there is one more field "Shorthand" that you will need to set.
23Most code never instantiates this struct directly, and instead uses
24functions such as String(), BoolVar(), and Var(), and is therefore
25unaffected.
26
27Define flags using flag.String(), Bool(), Int(), etc.
28
29This declares an integer flag, -flagname, stored in the pointer ip, with type *int.
30 var ip = flag.Int("flagname", 1234, "help message for flagname")
31If you like, you can bind the flag to a variable using the Var() functions.
32 var flagvar int
33 func init() {
34 flag.IntVar(&flagvar, "flagname", 1234, "help message for flagname")
35 }
36Or you can create custom flags that satisfy the Value interface (with
37pointer receivers) and couple them to flag parsing by
38 flag.Var(&flagVal, "name", "help message for flagname")
39For such flags, the default value is just the initial value of the variable.
40
41After all flags are defined, call
42 flag.Parse()
43to parse the command line into the defined flags.
44
45Flags may then be used directly. If you're using the flags themselves,
46they are all pointers; if you bind to variables, they're values.
47 fmt.Println("ip has value ", *ip)
48 fmt.Println("flagvar has value ", flagvar)
49
50After parsing, the arguments after the flag are available as the
51slice flag.Args() or individually as flag.Arg(i).
52The arguments are indexed from 0 through flag.NArg()-1.
53
54The pflag package also defines some new functions that are not in flag,
55that give one-letter shorthands for flags. You can use these by appending
56'P' to the name of any function that defines a flag.
57 var ip = flag.IntP("flagname", "f", 1234, "help message")
58 var flagvar bool
59 func init() {
60 flag.BoolVarP("boolname", "b", true, "help message")
61 }
62 flag.VarP(&flagVar, "varname", "v", 1234, "help message")
63Shorthand letters can be used with single dashes on the command line.
64Boolean shorthand flags can be combined with other shorthand flags.
65
66Command line flag syntax:
67 --flag // boolean flags only
68 --flag=x
69
70Unlike the flag package, a single dash before an option means something
71different than a double dash. Single dashes signify a series of shorthand
72letters for flags. All but the last shorthand letter must be boolean flags.
73 // boolean flags
74 -f
75 -abc
76 // non-boolean flags
77 -n 1234
78 -Ifile
79 // mixed
80 -abcs "hello"
81 -abcn1234
82
83Flag parsing stops after the terminator "--". Unlike the flag package,
84flags can be interspersed with arguments anywhere on the command line
85before this terminator.
86
87Integer flags accept 1234, 0664, 0x1234 and may be negative.
88Boolean flags (in their long form) accept 1, 0, t, f, true, false,
89TRUE, FALSE, True, False.
90Duration flags accept any input valid for time.ParseDuration.
91
92The default set of command-line flags is controlled by
93top-level functions. The FlagSet type allows one to define
94independent sets of flags, such as to implement subcommands
95in a command-line interface. The methods of FlagSet are
96analogous to the top-level functions for the command-line
97flag set.
98*/
99package pflag
100
101import (
102 "bytes"
103 "errors"
104 goflag "flag"
105 "fmt"
106 "io"
107 "os"
108 "sort"
109 "strings"
110)
111
112// ErrHelp is the error returned if the flag -help is invoked but no such flag is defined.
113var ErrHelp = errors.New("pflag: help requested")
114
115// ErrorHandling defines how to handle flag parsing errors.
116type ErrorHandling int
117
118const (
119 // ContinueOnError will return an err from Parse() if an error is found
120 ContinueOnError ErrorHandling = iota
121 // ExitOnError will call os.Exit(2) if an error is found when parsing
122 ExitOnError
123 // PanicOnError will panic() if an error is found when parsing flags
124 PanicOnError
125)
126
127// ParseErrorsWhitelist defines the parsing errors that can be ignored
128type ParseErrorsWhitelist struct {
129 // UnknownFlags will ignore unknown flags errors and continue parsing rest of the flags
130 UnknownFlags bool
131}
132
133// NormalizedName is a flag name that has been normalized according to rules
134// for the FlagSet (e.g. making '-' and '_' equivalent).
135type NormalizedName string
136
137// A FlagSet represents a set of defined flags.
138type FlagSet struct {
139 // Usage is the function called when an error occurs while parsing flags.
140 // The field is a function (not a method) that may be changed to point to
141 // a custom error handler.
142 Usage func()
143
144 // SortFlags is used to indicate, if user wants to have sorted flags in
145 // help/usage messages.
146 SortFlags bool
147
148 // ParseErrorsWhitelist is used to configure a whitelist of errors
149 ParseErrorsWhitelist ParseErrorsWhitelist
150
151 name string
152 parsed bool
153 actual map[NormalizedName]*Flag
154 orderedActual []*Flag
155 sortedActual []*Flag
156 formal map[NormalizedName]*Flag
157 orderedFormal []*Flag
158 sortedFormal []*Flag
159 shorthands map[byte]*Flag
160 args []string // arguments after flags
161 argsLenAtDash int // len(args) when a '--' was located when parsing, or -1 if no --
162 errorHandling ErrorHandling
163 output io.Writer // nil means stderr; use out() accessor
164 interspersed bool // allow interspersed option/non-option args
165 normalizeNameFunc func(f *FlagSet, name string) NormalizedName
166
167 addedGoFlagSets []*goflag.FlagSet
168}
169
170// A Flag represents the state of a flag.
171type Flag struct {
172 Name string // name as it appears on command line
173 Shorthand string // one-letter abbreviated flag
174 Usage string // help message
175 Value Value // value as set
176 DefValue string // default value (as text); for usage message
177 Changed bool // If the user set the value (or if left to default)
178 NoOptDefVal string // default value (as text); if the flag is on the command line without any options
179 Deprecated string // If this flag is deprecated, this string is the new or now thing to use
180 Hidden bool // used by cobra.Command to allow flags to be hidden from help/usage text
181 ShorthandDeprecated string // If the shorthand of this flag is deprecated, this string is the new or now thing to use
182 Annotations map[string][]string // used by cobra.Command bash autocomple code
183}
184
185// Value is the interface to the dynamic value stored in a flag.
186// (The default value is represented as a string.)
187type Value interface {
188 String() string
189 Set(string) error
190 Type() string
191}
192
193// sortFlags returns the flags as a slice in lexicographical sorted order.
194func sortFlags(flags map[NormalizedName]*Flag) []*Flag {
195 list := make(sort.StringSlice, len(flags))
196 i := 0
197 for k := range flags {
198 list[i] = string(k)
199 i++
200 }
201 list.Sort()
202 result := make([]*Flag, len(list))
203 for i, name := range list {
204 result[i] = flags[NormalizedName(name)]
205 }
206 return result
207}
208
209// SetNormalizeFunc allows you to add a function which can translate flag names.
210// Flags added to the FlagSet will be translated and then when anything tries to
211// look up the flag that will also be translated. So it would be possible to create
212// a flag named "getURL" and have it translated to "geturl". A user could then pass
213// "--getUrl" which may also be translated to "geturl" and everything will work.
214func (f *FlagSet) SetNormalizeFunc(n func(f *FlagSet, name string) NormalizedName) {
215 f.normalizeNameFunc = n
216 f.sortedFormal = f.sortedFormal[:0]
217 for fname, flag := range f.formal {
218 nname := f.normalizeFlagName(flag.Name)
219 if fname == nname {
220 continue
221 }
222 flag.Name = string(nname)
223 delete(f.formal, fname)
224 f.formal[nname] = flag
225 if _, set := f.actual[fname]; set {
226 delete(f.actual, fname)
227 f.actual[nname] = flag
228 }
229 }
230}
231
232// GetNormalizeFunc returns the previously set NormalizeFunc of a function which
233// does no translation, if not set previously.
234func (f *FlagSet) GetNormalizeFunc() func(f *FlagSet, name string) NormalizedName {
235 if f.normalizeNameFunc != nil {
236 return f.normalizeNameFunc
237 }
238 return func(f *FlagSet, name string) NormalizedName { return NormalizedName(name) }
239}
240
241func (f *FlagSet) normalizeFlagName(name string) NormalizedName {
242 n := f.GetNormalizeFunc()
243 return n(f, name)
244}
245
246func (f *FlagSet) out() io.Writer {
247 if f.output == nil {
248 return os.Stderr
249 }
250 return f.output
251}
252
253// SetOutput sets the destination for usage and error messages.
254// If output is nil, os.Stderr is used.
255func (f *FlagSet) SetOutput(output io.Writer) {
256 f.output = output
257}
258
259// VisitAll visits the flags in lexicographical order or
260// in primordial order if f.SortFlags is false, calling fn for each.
261// It visits all flags, even those not set.
262func (f *FlagSet) VisitAll(fn func(*Flag)) {
263 if len(f.formal) == 0 {
264 return
265 }
266
267 var flags []*Flag
268 if f.SortFlags {
269 if len(f.formal) != len(f.sortedFormal) {
270 f.sortedFormal = sortFlags(f.formal)
271 }
272 flags = f.sortedFormal
273 } else {
274 flags = f.orderedFormal
275 }
276
277 for _, flag := range flags {
278 fn(flag)
279 }
280}
281
282// HasFlags returns a bool to indicate if the FlagSet has any flags defined.
283func (f *FlagSet) HasFlags() bool {
284 return len(f.formal) > 0
285}
286
287// HasAvailableFlags returns a bool to indicate if the FlagSet has any flags
288// that are not hidden.
289func (f *FlagSet) HasAvailableFlags() bool {
290 for _, flag := range f.formal {
291 if !flag.Hidden {
292 return true
293 }
294 }
295 return false
296}
297
298// VisitAll visits the command-line flags in lexicographical order or
299// in primordial order if f.SortFlags is false, calling fn for each.
300// It visits all flags, even those not set.
301func VisitAll(fn func(*Flag)) {
302 CommandLine.VisitAll(fn)
303}
304
305// Visit visits the flags in lexicographical order or
306// in primordial order if f.SortFlags is false, calling fn for each.
307// It visits only those flags that have been set.
308func (f *FlagSet) Visit(fn func(*Flag)) {
309 if len(f.actual) == 0 {
310 return
311 }
312
313 var flags []*Flag
314 if f.SortFlags {
315 if len(f.actual) != len(f.sortedActual) {
316 f.sortedActual = sortFlags(f.actual)
317 }
318 flags = f.sortedActual
319 } else {
320 flags = f.orderedActual
321 }
322
323 for _, flag := range flags {
324 fn(flag)
325 }
326}
327
328// Visit visits the command-line flags in lexicographical order or
329// in primordial order if f.SortFlags is false, calling fn for each.
330// It visits only those flags that have been set.
331func Visit(fn func(*Flag)) {
332 CommandLine.Visit(fn)
333}
334
335// Lookup returns the Flag structure of the named flag, returning nil if none exists.
336func (f *FlagSet) Lookup(name string) *Flag {
337 return f.lookup(f.normalizeFlagName(name))
338}
339
340// ShorthandLookup returns the Flag structure of the short handed flag,
341// returning nil if none exists.
342// It panics, if len(name) > 1.
343func (f *FlagSet) ShorthandLookup(name string) *Flag {
344 if name == "" {
345 return nil
346 }
347 if len(name) > 1 {
348 msg := fmt.Sprintf("can not look up shorthand which is more than one ASCII character: %q", name)
349 fmt.Fprintf(f.out(), msg)
350 panic(msg)
351 }
352 c := name[0]
353 return f.shorthands[c]
354}
355
356// lookup returns the Flag structure of the named flag, returning nil if none exists.
357func (f *FlagSet) lookup(name NormalizedName) *Flag {
358 return f.formal[name]
359}
360
361// func to return a given type for a given flag name
362func (f *FlagSet) getFlagType(name string, ftype string, convFunc func(sval string) (interface{}, error)) (interface{}, error) {
363 flag := f.Lookup(name)
364 if flag == nil {
365 err := fmt.Errorf("flag accessed but not defined: %s", name)
366 return nil, err
367 }
368
369 if flag.Value.Type() != ftype {
370 err := fmt.Errorf("trying to get %s value of flag of type %s", ftype, flag.Value.Type())
371 return nil, err
372 }
373
374 sval := flag.Value.String()
375 result, err := convFunc(sval)
376 if err != nil {
377 return nil, err
378 }
379 return result, nil
380}
381
382// ArgsLenAtDash will return the length of f.Args at the moment when a -- was
383// found during arg parsing. This allows your program to know which args were
384// before the -- and which came after.
385func (f *FlagSet) ArgsLenAtDash() int {
386 return f.argsLenAtDash
387}
388
389// MarkDeprecated indicated that a flag is deprecated in your program. It will
390// continue to function but will not show up in help or usage messages. Using
391// this flag will also print the given usageMessage.
392func (f *FlagSet) MarkDeprecated(name string, usageMessage string) error {
393 flag := f.Lookup(name)
394 if flag == nil {
395 return fmt.Errorf("flag %q does not exist", name)
396 }
397 if usageMessage == "" {
398 return fmt.Errorf("deprecated message for flag %q must be set", name)
399 }
400 flag.Deprecated = usageMessage
401 flag.Hidden = true
402 return nil
403}
404
405// MarkShorthandDeprecated will mark the shorthand of a flag deprecated in your
406// program. It will continue to function but will not show up in help or usage
407// messages. Using this flag will also print the given usageMessage.
408func (f *FlagSet) MarkShorthandDeprecated(name string, usageMessage string) error {
409 flag := f.Lookup(name)
410 if flag == nil {
411 return fmt.Errorf("flag %q does not exist", name)
412 }
413 if usageMessage == "" {
414 return fmt.Errorf("deprecated message for flag %q must be set", name)
415 }
416 flag.ShorthandDeprecated = usageMessage
417 return nil
418}
419
420// MarkHidden sets a flag to 'hidden' in your program. It will continue to
421// function but will not show up in help or usage messages.
422func (f *FlagSet) MarkHidden(name string) error {
423 flag := f.Lookup(name)
424 if flag == nil {
425 return fmt.Errorf("flag %q does not exist", name)
426 }
427 flag.Hidden = true
428 return nil
429}
430
431// Lookup returns the Flag structure of the named command-line flag,
432// returning nil if none exists.
433func Lookup(name string) *Flag {
434 return CommandLine.Lookup(name)
435}
436
437// ShorthandLookup returns the Flag structure of the short handed flag,
438// returning nil if none exists.
439func ShorthandLookup(name string) *Flag {
440 return CommandLine.ShorthandLookup(name)
441}
442
443// Set sets the value of the named flag.
444func (f *FlagSet) Set(name, value string) error {
445 normalName := f.normalizeFlagName(name)
446 flag, ok := f.formal[normalName]
447 if !ok {
448 return fmt.Errorf("no such flag -%v", name)
449 }
450
451 err := flag.Value.Set(value)
452 if err != nil {
453 var flagName string
454 if flag.Shorthand != "" && flag.ShorthandDeprecated == "" {
455 flagName = fmt.Sprintf("-%s, --%s", flag.Shorthand, flag.Name)
456 } else {
457 flagName = fmt.Sprintf("--%s", flag.Name)
458 }
459 return fmt.Errorf("invalid argument %q for %q flag: %v", value, flagName, err)
460 }
461
462 if !flag.Changed {
463 if f.actual == nil {
464 f.actual = make(map[NormalizedName]*Flag)
465 }
466 f.actual[normalName] = flag
467 f.orderedActual = append(f.orderedActual, flag)
468
469 flag.Changed = true
470 }
471
472 if flag.Deprecated != "" {
473 fmt.Fprintf(f.out(), "Flag --%s has been deprecated, %s\n", flag.Name, flag.Deprecated)
474 }
475 return nil
476}
477
478// SetAnnotation allows one to set arbitrary annotations on a flag in the FlagSet.
479// This is sometimes used by spf13/cobra programs which want to generate additional
480// bash completion information.
481func (f *FlagSet) SetAnnotation(name, key string, values []string) error {
482 normalName := f.normalizeFlagName(name)
483 flag, ok := f.formal[normalName]
484 if !ok {
485 return fmt.Errorf("no such flag -%v", name)
486 }
487 if flag.Annotations == nil {
488 flag.Annotations = map[string][]string{}
489 }
490 flag.Annotations[key] = values
491 return nil
492}
493
494// Changed returns true if the flag was explicitly set during Parse() and false
495// otherwise
496func (f *FlagSet) Changed(name string) bool {
497 flag := f.Lookup(name)
498 // If a flag doesn't exist, it wasn't changed....
499 if flag == nil {
500 return false
501 }
502 return flag.Changed
503}
504
505// Set sets the value of the named command-line flag.
506func Set(name, value string) error {
507 return CommandLine.Set(name, value)
508}
509
510// PrintDefaults prints, to standard error unless configured
511// otherwise, the default values of all defined flags in the set.
512func (f *FlagSet) PrintDefaults() {
513 usages := f.FlagUsages()
514 fmt.Fprint(f.out(), usages)
515}
516
517// defaultIsZeroValue returns true if the default value for this flag represents
518// a zero value.
519func (f *Flag) defaultIsZeroValue() bool {
520 switch f.Value.(type) {
521 case boolFlag:
522 return f.DefValue == "false"
523 case *durationValue:
524 // Beginning in Go 1.7, duration zero values are "0s"
525 return f.DefValue == "0" || f.DefValue == "0s"
526 case *intValue, *int8Value, *int32Value, *int64Value, *uintValue, *uint8Value, *uint16Value, *uint32Value, *uint64Value, *countValue, *float32Value, *float64Value:
527 return f.DefValue == "0"
528 case *stringValue:
529 return f.DefValue == ""
530 case *ipValue, *ipMaskValue, *ipNetValue:
531 return f.DefValue == "<nil>"
532 case *intSliceValue, *stringSliceValue, *stringArrayValue:
533 return f.DefValue == "[]"
534 default:
535 switch f.Value.String() {
536 case "false":
537 return true
538 case "<nil>":
539 return true
540 case "":
541 return true
542 case "0":
543 return true
544 }
545 return false
546 }
547}
548
549// UnquoteUsage extracts a back-quoted name from the usage
550// string for a flag and returns it and the un-quoted usage.
551// Given "a `name` to show" it returns ("name", "a name to show").
552// If there are no back quotes, the name is an educated guess of the
553// type of the flag's value, or the empty string if the flag is boolean.
554func UnquoteUsage(flag *Flag) (name string, usage string) {
555 // Look for a back-quoted name, but avoid the strings package.
556 usage = flag.Usage
557 for i := 0; i < len(usage); i++ {
558 if usage[i] == '`' {
559 for j := i + 1; j < len(usage); j++ {
560 if usage[j] == '`' {
561 name = usage[i+1 : j]
562 usage = usage[:i] + name + usage[j+1:]
563 return name, usage
564 }
565 }
566 break // Only one back quote; use type name.
567 }
568 }
569
570 name = flag.Value.Type()
571 switch name {
572 case "bool":
573 name = ""
574 case "float64":
575 name = "float"
576 case "int64":
577 name = "int"
578 case "uint64":
579 name = "uint"
580 case "stringSlice":
581 name = "strings"
582 case "intSlice":
583 name = "ints"
584 case "uintSlice":
585 name = "uints"
586 case "boolSlice":
587 name = "bools"
588 }
589
590 return
591}
592
593// Splits the string `s` on whitespace into an initial substring up to
594// `i` runes in length and the remainder. Will go `slop` over `i` if
595// that encompasses the entire string (which allows the caller to
596// avoid short orphan words on the final line).
597func wrapN(i, slop int, s string) (string, string) {
598 if i+slop > len(s) {
599 return s, ""
600 }
601
602 w := strings.LastIndexAny(s[:i], " \t\n")
603 if w <= 0 {
604 return s, ""
605 }
606 nlPos := strings.LastIndex(s[:i], "\n")
607 if nlPos > 0 && nlPos < w {
608 return s[:nlPos], s[nlPos+1:]
609 }
610 return s[:w], s[w+1:]
611}
612
613// Wraps the string `s` to a maximum width `w` with leading indent
614// `i`. The first line is not indented (this is assumed to be done by
615// caller). Pass `w` == 0 to do no wrapping
616func wrap(i, w int, s string) string {
617 if w == 0 {
618 return strings.Replace(s, "\n", "\n"+strings.Repeat(" ", i), -1)
619 }
620
621 // space between indent i and end of line width w into which
622 // we should wrap the text.
623 wrap := w - i
624
625 var r, l string
626
627 // Not enough space for sensible wrapping. Wrap as a block on
628 // the next line instead.
629 if wrap < 24 {
630 i = 16
631 wrap = w - i
632 r += "\n" + strings.Repeat(" ", i)
633 }
634 // If still not enough space then don't even try to wrap.
635 if wrap < 24 {
636 return strings.Replace(s, "\n", r, -1)
637 }
638
639 // Try to avoid short orphan words on the final line, by
640 // allowing wrapN to go a bit over if that would fit in the
641 // remainder of the line.
642 slop := 5
643 wrap = wrap - slop
644
645 // Handle first line, which is indented by the caller (or the
646 // special case above)
647 l, s = wrapN(wrap, slop, s)
648 r = r + strings.Replace(l, "\n", "\n"+strings.Repeat(" ", i), -1)
649
650 // Now wrap the rest
651 for s != "" {
652 var t string
653
654 t, s = wrapN(wrap, slop, s)
655 r = r + "\n" + strings.Repeat(" ", i) + strings.Replace(t, "\n", "\n"+strings.Repeat(" ", i), -1)
656 }
657
658 return r
659
660}
661
662// FlagUsagesWrapped returns a string containing the usage information
663// for all flags in the FlagSet. Wrapped to `cols` columns (0 for no
664// wrapping)
665func (f *FlagSet) FlagUsagesWrapped(cols int) string {
666 buf := new(bytes.Buffer)
667
668 lines := make([]string, 0, len(f.formal))
669
670 maxlen := 0
671 f.VisitAll(func(flag *Flag) {
672 if flag.Hidden {
673 return
674 }
675
676 line := ""
677 if flag.Shorthand != "" && flag.ShorthandDeprecated == "" {
678 line = fmt.Sprintf(" -%s, --%s", flag.Shorthand, flag.Name)
679 } else {
680 line = fmt.Sprintf(" --%s", flag.Name)
681 }
682
683 varname, usage := UnquoteUsage(flag)
684 if varname != "" {
685 line += " " + varname
686 }
687 if flag.NoOptDefVal != "" {
688 switch flag.Value.Type() {
689 case "string":
690 line += fmt.Sprintf("[=\"%s\"]", flag.NoOptDefVal)
691 case "bool":
692 if flag.NoOptDefVal != "true" {
693 line += fmt.Sprintf("[=%s]", flag.NoOptDefVal)
694 }
695 case "count":
696 if flag.NoOptDefVal != "+1" {
697 line += fmt.Sprintf("[=%s]", flag.NoOptDefVal)
698 }
699 default:
700 line += fmt.Sprintf("[=%s]", flag.NoOptDefVal)
701 }
702 }
703
704 // This special character will be replaced with spacing once the
705 // correct alignment is calculated
706 line += "\x00"
707 if len(line) > maxlen {
708 maxlen = len(line)
709 }
710
711 line += usage
712 if !flag.defaultIsZeroValue() {
713 if flag.Value.Type() == "string" {
714 line += fmt.Sprintf(" (default %q)", flag.DefValue)
715 } else {
716 line += fmt.Sprintf(" (default %s)", flag.DefValue)
717 }
718 }
719 if len(flag.Deprecated) != 0 {
720 line += fmt.Sprintf(" (DEPRECATED: %s)", flag.Deprecated)
721 }
722
723 lines = append(lines, line)
724 })
725
726 for _, line := range lines {
727 sidx := strings.Index(line, "\x00")
728 spacing := strings.Repeat(" ", maxlen-sidx)
729 // maxlen + 2 comes from + 1 for the \x00 and + 1 for the (deliberate) off-by-one in maxlen-sidx
730 fmt.Fprintln(buf, line[:sidx], spacing, wrap(maxlen+2, cols, line[sidx+1:]))
731 }
732
733 return buf.String()
734}
735
736// FlagUsages returns a string containing the usage information for all flags in
737// the FlagSet
738func (f *FlagSet) FlagUsages() string {
739 return f.FlagUsagesWrapped(0)
740}
741
742// PrintDefaults prints to standard error the default values of all defined command-line flags.
743func PrintDefaults() {
744 CommandLine.PrintDefaults()
745}
746
747// defaultUsage is the default function to print a usage message.
748func defaultUsage(f *FlagSet) {
749 fmt.Fprintf(f.out(), "Usage of %s:\n", f.name)
750 f.PrintDefaults()
751}
752
753// NOTE: Usage is not just defaultUsage(CommandLine)
754// because it serves (via godoc flag Usage) as the example
755// for how to write your own usage function.
756
757// Usage prints to standard error a usage message documenting all defined command-line flags.
758// The function is a variable that may be changed to point to a custom function.
759// By default it prints a simple header and calls PrintDefaults; for details about the
760// format of the output and how to control it, see the documentation for PrintDefaults.
761var Usage = func() {
762 fmt.Fprintf(os.Stderr, "Usage of %s:\n", os.Args[0])
763 PrintDefaults()
764}
765
766// NFlag returns the number of flags that have been set.
767func (f *FlagSet) NFlag() int { return len(f.actual) }
768
769// NFlag returns the number of command-line flags that have been set.
770func NFlag() int { return len(CommandLine.actual) }
771
772// Arg returns the i'th argument. Arg(0) is the first remaining argument
773// after flags have been processed.
774func (f *FlagSet) Arg(i int) string {
775 if i < 0 || i >= len(f.args) {
776 return ""
777 }
778 return f.args[i]
779}
780
781// Arg returns the i'th command-line argument. Arg(0) is the first remaining argument
782// after flags have been processed.
783func Arg(i int) string {
784 return CommandLine.Arg(i)
785}
786
787// NArg is the number of arguments remaining after flags have been processed.
788func (f *FlagSet) NArg() int { return len(f.args) }
789
790// NArg is the number of arguments remaining after flags have been processed.
791func NArg() int { return len(CommandLine.args) }
792
793// Args returns the non-flag arguments.
794func (f *FlagSet) Args() []string { return f.args }
795
796// Args returns the non-flag command-line arguments.
797func Args() []string { return CommandLine.args }
798
799// Var defines a flag with the specified name and usage string. The type and
800// value of the flag are represented by the first argument, of type Value, which
801// typically holds a user-defined implementation of Value. For instance, the
802// caller could create a flag that turns a comma-separated string into a slice
803// of strings by giving the slice the methods of Value; in particular, Set would
804// decompose the comma-separated string into the slice.
805func (f *FlagSet) Var(value Value, name string, usage string) {
806 f.VarP(value, name, "", usage)
807}
808
809// VarPF is like VarP, but returns the flag created
810func (f *FlagSet) VarPF(value Value, name, shorthand, usage string) *Flag {
811 // Remember the default value as a string; it won't change.
812 flag := &Flag{
813 Name: name,
814 Shorthand: shorthand,
815 Usage: usage,
816 Value: value,
817 DefValue: value.String(),
818 }
819 f.AddFlag(flag)
820 return flag
821}
822
823// VarP is like Var, but accepts a shorthand letter that can be used after a single dash.
824func (f *FlagSet) VarP(value Value, name, shorthand, usage string) {
825 f.VarPF(value, name, shorthand, usage)
826}
827
828// AddFlag will add the flag to the FlagSet
829func (f *FlagSet) AddFlag(flag *Flag) {
830 normalizedFlagName := f.normalizeFlagName(flag.Name)
831
832 _, alreadyThere := f.formal[normalizedFlagName]
833 if alreadyThere {
834 msg := fmt.Sprintf("%s flag redefined: %s", f.name, flag.Name)
835 fmt.Fprintln(f.out(), msg)
836 panic(msg) // Happens only if flags are declared with identical names
837 }
838 if f.formal == nil {
839 f.formal = make(map[NormalizedName]*Flag)
840 }
841
842 flag.Name = string(normalizedFlagName)
843 f.formal[normalizedFlagName] = flag
844 f.orderedFormal = append(f.orderedFormal, flag)
845
846 if flag.Shorthand == "" {
847 return
848 }
849 if len(flag.Shorthand) > 1 {
850 msg := fmt.Sprintf("%q shorthand is more than one ASCII character", flag.Shorthand)
851 fmt.Fprintf(f.out(), msg)
852 panic(msg)
853 }
854 if f.shorthands == nil {
855 f.shorthands = make(map[byte]*Flag)
856 }
857 c := flag.Shorthand[0]
858 used, alreadyThere := f.shorthands[c]
859 if alreadyThere {
860 msg := fmt.Sprintf("unable to redefine %q shorthand in %q flagset: it's already used for %q flag", c, f.name, used.Name)
861 fmt.Fprintf(f.out(), msg)
862 panic(msg)
863 }
864 f.shorthands[c] = flag
865}
866
867// AddFlagSet adds one FlagSet to another. If a flag is already present in f
868// the flag from newSet will be ignored.
869func (f *FlagSet) AddFlagSet(newSet *FlagSet) {
870 if newSet == nil {
871 return
872 }
873 newSet.VisitAll(func(flag *Flag) {
874 if f.Lookup(flag.Name) == nil {
875 f.AddFlag(flag)
876 }
877 })
878}
879
880// Var defines a flag with the specified name and usage string. The type and
881// value of the flag are represented by the first argument, of type Value, which
882// typically holds a user-defined implementation of Value. For instance, the
883// caller could create a flag that turns a comma-separated string into a slice
884// of strings by giving the slice the methods of Value; in particular, Set would
885// decompose the comma-separated string into the slice.
886func Var(value Value, name string, usage string) {
887 CommandLine.VarP(value, name, "", usage)
888}
889
890// VarP is like Var, but accepts a shorthand letter that can be used after a single dash.
891func VarP(value Value, name, shorthand, usage string) {
892 CommandLine.VarP(value, name, shorthand, usage)
893}
894
895// failf prints to standard error a formatted error and usage message and
896// returns the error.
897func (f *FlagSet) failf(format string, a ...interface{}) error {
898 err := fmt.Errorf(format, a...)
899 if f.errorHandling != ContinueOnError {
900 fmt.Fprintln(f.out(), err)
901 f.usage()
902 }
903 return err
904}
905
906// usage calls the Usage method for the flag set, or the usage function if
907// the flag set is CommandLine.
908func (f *FlagSet) usage() {
909 if f == CommandLine {
910 Usage()
911 } else if f.Usage == nil {
912 defaultUsage(f)
913 } else {
914 f.Usage()
915 }
916}
917
918//--unknown (args will be empty)
919//--unknown --next-flag ... (args will be --next-flag ...)
920//--unknown arg ... (args will be arg ...)
921func stripUnknownFlagValue(args []string) []string {
922 if len(args) == 0 {
923 //--unknown
924 return args
925 }
926
927 first := args[0]
928 if len(first) > 0 && first[0] == '-' {
929 //--unknown --next-flag ...
930 return args
931 }
932
933 //--unknown arg ... (args will be arg ...)
934 if len(args) > 1 {
935 return args[1:]
936 }
937 return nil
938}
939
940func (f *FlagSet) parseLongArg(s string, args []string, fn parseFunc) (a []string, err error) {
941 a = args
942 name := s[2:]
943 if len(name) == 0 || name[0] == '-' || name[0] == '=' {
944 err = f.failf("bad flag syntax: %s", s)
945 return
946 }
947
948 split := strings.SplitN(name, "=", 2)
949 name = split[0]
950 flag, exists := f.formal[f.normalizeFlagName(name)]
951
952 if !exists {
953 switch {
954 case name == "help":
955 f.usage()
956 return a, ErrHelp
957 case f.ParseErrorsWhitelist.UnknownFlags:
958 // --unknown=unknownval arg ...
959 // we do not want to lose arg in this case
960 if len(split) >= 2 {
961 return a, nil
962 }
963
964 return stripUnknownFlagValue(a), nil
965 default:
966 err = f.failf("unknown flag: --%s", name)
967 return
968 }
969 }
970
971 var value string
972 if len(split) == 2 {
973 // '--flag=arg'
974 value = split[1]
975 } else if flag.NoOptDefVal != "" {
976 // '--flag' (arg was optional)
977 value = flag.NoOptDefVal
978 } else if len(a) > 0 {
979 // '--flag arg'
980 value = a[0]
981 a = a[1:]
982 } else {
983 // '--flag' (arg was required)
984 err = f.failf("flag needs an argument: %s", s)
985 return
986 }
987
988 err = fn(flag, value)
989 if err != nil {
990 f.failf(err.Error())
991 }
992 return
993}
994
995func (f *FlagSet) parseSingleShortArg(shorthands string, args []string, fn parseFunc) (outShorts string, outArgs []string, err error) {
996 outArgs = args
997
998 if strings.HasPrefix(shorthands, "test.") {
999 return
1000 }
1001
1002 outShorts = shorthands[1:]
1003 c := shorthands[0]
1004
1005 flag, exists := f.shorthands[c]
1006 if !exists {
1007 switch {
1008 case c == 'h':
1009 f.usage()
1010 err = ErrHelp
1011 return
1012 case f.ParseErrorsWhitelist.UnknownFlags:
1013 // '-f=arg arg ...'
1014 // we do not want to lose arg in this case
1015 if len(shorthands) > 2 && shorthands[1] == '=' {
1016 outShorts = ""
1017 return
1018 }
1019
1020 outArgs = stripUnknownFlagValue(outArgs)
1021 return
1022 default:
1023 err = f.failf("unknown shorthand flag: %q in -%s", c, shorthands)
1024 return
1025 }
1026 }
1027
1028 var value string
1029 if len(shorthands) > 2 && shorthands[1] == '=' {
1030 // '-f=arg'
1031 value = shorthands[2:]
1032 outShorts = ""
1033 } else if flag.NoOptDefVal != "" {
1034 // '-f' (arg was optional)
1035 value = flag.NoOptDefVal
1036 } else if len(shorthands) > 1 {
1037 // '-farg'
1038 value = shorthands[1:]
1039 outShorts = ""
1040 } else if len(args) > 0 {
1041 // '-f arg'
1042 value = args[0]
1043 outArgs = args[1:]
1044 } else {
1045 // '-f' (arg was required)
1046 err = f.failf("flag needs an argument: %q in -%s", c, shorthands)
1047 return
1048 }
1049
1050 if flag.ShorthandDeprecated != "" {
1051 fmt.Fprintf(f.out(), "Flag shorthand -%s has been deprecated, %s\n", flag.Shorthand, flag.ShorthandDeprecated)
1052 }
1053
1054 err = fn(flag, value)
1055 if err != nil {
1056 f.failf(err.Error())
1057 }
1058 return
1059}
1060
1061func (f *FlagSet) parseShortArg(s string, args []string, fn parseFunc) (a []string, err error) {
1062 a = args
1063 shorthands := s[1:]
1064
1065 // "shorthands" can be a series of shorthand letters of flags (e.g. "-vvv").
1066 for len(shorthands) > 0 {
1067 shorthands, a, err = f.parseSingleShortArg(shorthands, args, fn)
1068 if err != nil {
1069 return
1070 }
1071 }
1072
1073 return
1074}
1075
1076func (f *FlagSet) parseArgs(args []string, fn parseFunc) (err error) {
1077 for len(args) > 0 {
1078 s := args[0]
1079 args = args[1:]
1080 if len(s) == 0 || s[0] != '-' || len(s) == 1 {
1081 if !f.interspersed {
1082 f.args = append(f.args, s)
1083 f.args = append(f.args, args...)
1084 return nil
1085 }
1086 f.args = append(f.args, s)
1087 continue
1088 }
1089
1090 if s[1] == '-' {
1091 if len(s) == 2 { // "--" terminates the flags
1092 f.argsLenAtDash = len(f.args)
1093 f.args = append(f.args, args...)
1094 break
1095 }
1096 args, err = f.parseLongArg(s, args, fn)
1097 } else {
1098 args, err = f.parseShortArg(s, args, fn)
1099 }
1100 if err != nil {
1101 return
1102 }
1103 }
1104 return
1105}
1106
1107// Parse parses flag definitions from the argument list, which should not
1108// include the command name. Must be called after all flags in the FlagSet
1109// are defined and before flags are accessed by the program.
1110// The return value will be ErrHelp if -help was set but not defined.
1111func (f *FlagSet) Parse(arguments []string) error {
1112 if f.addedGoFlagSets != nil {
1113 for _, goFlagSet := range f.addedGoFlagSets {
1114 goFlagSet.Parse(nil)
1115 }
1116 }
1117 f.parsed = true
1118
1119 if len(arguments) < 0 {
1120 return nil
1121 }
1122
1123 f.args = make([]string, 0, len(arguments))
1124
1125 set := func(flag *Flag, value string) error {
1126 return f.Set(flag.Name, value)
1127 }
1128
1129 err := f.parseArgs(arguments, set)
1130 if err != nil {
1131 switch f.errorHandling {
1132 case ContinueOnError:
1133 return err
1134 case ExitOnError:
1135 fmt.Println(err)
1136 os.Exit(2)
1137 case PanicOnError:
1138 panic(err)
1139 }
1140 }
1141 return nil
1142}
1143
1144type parseFunc func(flag *Flag, value string) error
1145
1146// ParseAll parses flag definitions from the argument list, which should not
1147// include the command name. The arguments for fn are flag and value. Must be
1148// called after all flags in the FlagSet are defined and before flags are
1149// accessed by the program. The return value will be ErrHelp if -help was set
1150// but not defined.
1151func (f *FlagSet) ParseAll(arguments []string, fn func(flag *Flag, value string) error) error {
1152 f.parsed = true
1153 f.args = make([]string, 0, len(arguments))
1154
1155 err := f.parseArgs(arguments, fn)
1156 if err != nil {
1157 switch f.errorHandling {
1158 case ContinueOnError:
1159 return err
1160 case ExitOnError:
1161 os.Exit(2)
1162 case PanicOnError:
1163 panic(err)
1164 }
1165 }
1166 return nil
1167}
1168
1169// Parsed reports whether f.Parse has been called.
1170func (f *FlagSet) Parsed() bool {
1171 return f.parsed
1172}
1173
1174// Parse parses the command-line flags from os.Args[1:]. Must be called
1175// after all flags are defined and before flags are accessed by the program.
1176func Parse() {
1177 // Ignore errors; CommandLine is set for ExitOnError.
1178 CommandLine.Parse(os.Args[1:])
1179}
1180
1181// ParseAll parses the command-line flags from os.Args[1:] and called fn for each.
1182// The arguments for fn are flag and value. Must be called after all flags are
1183// defined and before flags are accessed by the program.
1184func ParseAll(fn func(flag *Flag, value string) error) {
1185 // Ignore errors; CommandLine is set for ExitOnError.
1186 CommandLine.ParseAll(os.Args[1:], fn)
1187}
1188
1189// SetInterspersed sets whether to support interspersed option/non-option arguments.
1190func SetInterspersed(interspersed bool) {
1191 CommandLine.SetInterspersed(interspersed)
1192}
1193
1194// Parsed returns true if the command-line flags have been parsed.
1195func Parsed() bool {
1196 return CommandLine.Parsed()
1197}
1198
1199// CommandLine is the default set of command-line flags, parsed from os.Args.
1200var CommandLine = NewFlagSet(os.Args[0], ExitOnError)
1201
1202// NewFlagSet returns a new, empty flag set with the specified name,
1203// error handling property and SortFlags set to true.
1204func NewFlagSet(name string, errorHandling ErrorHandling) *FlagSet {
1205 f := &FlagSet{
1206 name: name,
1207 errorHandling: errorHandling,
1208 argsLenAtDash: -1,
1209 interspersed: true,
1210 SortFlags: true,
1211 }
1212 return f
1213}
1214
1215// SetInterspersed sets whether to support interspersed option/non-option arguments.
1216func (f *FlagSet) SetInterspersed(interspersed bool) {
1217 f.interspersed = interspersed
1218}
1219
1220// Init sets the name and error handling property for a flag set.
1221// By default, the zero FlagSet uses an empty name and the
1222// ContinueOnError error handling policy.
1223func (f *FlagSet) Init(name string, errorHandling ErrorHandling) {
1224 f.name = name
1225 f.errorHandling = errorHandling
1226 f.argsLenAtDash = -1
1227}