1 // 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.
6 Package pflag is a drop-in replacement for Go's flag package, implementing
7 POSIX/GNU-style --flags.
9 pflag is compatible with the GNU extensions to the POSIX recommendations
10 for command-line options. See
11 http://www.gnu.org/software/libc/manual/html_node/Argument-Syntax.html
15 pflag is a drop-in replacement of Go's native flag package. If you import
16 pflag under the name "flag" then all code should continue to function
19 import flag "github.com/spf13/pflag"
21 There is one exception to this: if you directly instantiate the Flag struct
22 there is one more field "Shorthand" that you will need to set.
23 Most code never instantiates this struct directly, and instead uses
24 functions such as String(), BoolVar(), and Var(), and is therefore
27 Define flags using flag.String(), Bool(), Int(), etc.
29 This declares an integer flag, -flagname, stored in the pointer ip, with type *int.
30 var ip = flag.Int("flagname", 1234, "help message for flagname")
31 If you like, you can bind the flag to a variable using the Var() functions.
34 flag.IntVar(&flagvar, "flagname", 1234, "help message for flagname")
36 Or you can create custom flags that satisfy the Value interface (with
37 pointer receivers) and couple them to flag parsing by
38 flag.Var(&flagVal, "name", "help message for flagname")
39 For such flags, the default value is just the initial value of the variable.
41 After all flags are defined, call
43 to parse the command line into the defined flags.
45 Flags may then be used directly. If you're using the flags themselves,
46 they 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)
50 After parsing, the arguments after the flag are available as the
51 slice flag.Args() or individually as flag.Arg(i).
52 The arguments are indexed from 0 through flag.NArg()-1.
54 The pflag package also defines some new functions that are not in flag,
55 that 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")
60 flag.BoolVarP("boolname", "b", true, "help message")
62 flag.VarP(&flagVar, "varname", "v", 1234, "help message")
63 Shorthand letters can be used with single dashes on the command line.
64 Boolean shorthand flags can be combined with other shorthand flags.
66 Command line flag syntax:
67 --flag // boolean flags only
70 Unlike the flag package, a single dash before an option means something
71 different than a double dash. Single dashes signify a series of shorthand
72 letters for flags. All but the last shorthand letter must be boolean flags.
83 Flag parsing stops after the terminator "--". Unlike the flag package,
84 flags can be interspersed with arguments anywhere on the command line
85 before this terminator.
87 Integer flags accept 1234, 0664, 0x1234 and may be negative.
88 Boolean flags (in their long form) accept 1, 0, t, f, true, false,
89 TRUE, FALSE, True, False.
90 Duration flags accept any input valid for time.ParseDuration.
92 The default set of command-line flags is controlled by
93 top-level functions. The FlagSet type allows one to define
94 independent sets of flags, such as to implement subcommands
95 in a command-line interface. The methods of FlagSet are
96 analogous to the top-level functions for the command-line
111 // ErrHelp is the error returned if the flag -help is invoked but no such flag is defined.
112 var ErrHelp = errors.New("pflag: help requested")
114 // ErrorHandling defines how to handle flag parsing errors.
115 type ErrorHandling int
118 // ContinueOnError will return an err from Parse() if an error is found
119 ContinueOnError ErrorHandling = iota
120 // ExitOnError will call os.Exit(2) if an error is found when parsing
122 // PanicOnError will panic() if an error is found when parsing flags
126 // NormalizedName is a flag name that has been normalized according to rules
127 // for the FlagSet (e.g. making '-' and '_' equivalent).
128 type NormalizedName string
130 // A FlagSet represents a set of defined flags.
131 type FlagSet struct {
132 // Usage is the function called when an error occurs while parsing flags.
133 // The field is a function (not a method) that may be changed to point to
134 // a custom error handler.
137 // SortFlags is used to indicate, if user wants to have sorted flags in
138 // help/usage messages.
143 actual map[NormalizedName]*Flag
144 orderedActual []*Flag
146 formal map[NormalizedName]*Flag
147 orderedFormal []*Flag
149 shorthands map[byte]*Flag
150 args []string // arguments after flags
151 argsLenAtDash int // len(args) when a '--' was located when parsing, or -1 if no --
152 errorHandling ErrorHandling
153 output io.Writer // nil means stderr; use out() accessor
154 interspersed bool // allow interspersed option/non-option args
155 normalizeNameFunc func(f *FlagSet, name string) NormalizedName
158 // A Flag represents the state of a flag.
160 Name string // name as it appears on command line
161 Shorthand string // one-letter abbreviated flag
162 Usage string // help message
163 Value Value // value as set
164 DefValue string // default value (as text); for usage message
165 Changed bool // If the user set the value (or if left to default)
166 NoOptDefVal string // default value (as text); if the flag is on the command line without any options
167 Deprecated string // If this flag is deprecated, this string is the new or now thing to use
168 Hidden bool // used by cobra.Command to allow flags to be hidden from help/usage text
169 ShorthandDeprecated string // If the shorthand of this flag is deprecated, this string is the new or now thing to use
170 Annotations map[string][]string // used by cobra.Command bash autocomple code
173 // Value is the interface to the dynamic value stored in a flag.
174 // (The default value is represented as a string.)
175 type Value interface {
181 // sortFlags returns the flags as a slice in lexicographical sorted order.
182 func sortFlags(flags map[NormalizedName]*Flag) []*Flag {
183 list := make(sort.StringSlice, len(flags))
185 for k := range flags {
190 result := make([]*Flag, len(list))
191 for i, name := range list {
192 result[i] = flags[NormalizedName(name)]
197 // SetNormalizeFunc allows you to add a function which can translate flag names.
198 // Flags added to the FlagSet will be translated and then when anything tries to
199 // look up the flag that will also be translated. So it would be possible to create
200 // a flag named "getURL" and have it translated to "geturl". A user could then pass
201 // "--getUrl" which may also be translated to "geturl" and everything will work.
202 func (f *FlagSet) SetNormalizeFunc(n func(f *FlagSet, name string) NormalizedName) {
203 f.normalizeNameFunc = n
204 f.sortedFormal = f.sortedFormal[:0]
205 for fname, flag := range f.formal {
206 nname := f.normalizeFlagName(flag.Name)
210 flag.Name = string(nname)
211 delete(f.formal, fname)
212 f.formal[nname] = flag
213 if _, set := f.actual[fname]; set {
214 delete(f.actual, fname)
215 f.actual[nname] = flag
220 // GetNormalizeFunc returns the previously set NormalizeFunc of a function which
221 // does no translation, if not set previously.
222 func (f *FlagSet) GetNormalizeFunc() func(f *FlagSet, name string) NormalizedName {
223 if f.normalizeNameFunc != nil {
224 return f.normalizeNameFunc
226 return func(f *FlagSet, name string) NormalizedName { return NormalizedName(name) }
229 func (f *FlagSet) normalizeFlagName(name string) NormalizedName {
230 n := f.GetNormalizeFunc()
234 func (f *FlagSet) out() io.Writer {
241 // SetOutput sets the destination for usage and error messages.
242 // If output is nil, os.Stderr is used.
243 func (f *FlagSet) SetOutput(output io.Writer) {
247 // VisitAll visits the flags in lexicographical order or
248 // in primordial order if f.SortFlags is false, calling fn for each.
249 // It visits all flags, even those not set.
250 func (f *FlagSet) VisitAll(fn func(*Flag)) {
251 if len(f.formal) == 0 {
257 if len(f.formal) != len(f.sortedFormal) {
258 f.sortedFormal = sortFlags(f.formal)
260 flags = f.sortedFormal
262 flags = f.orderedFormal
265 for _, flag := range flags {
270 // HasFlags returns a bool to indicate if the FlagSet has any flags definied.
271 func (f *FlagSet) HasFlags() bool {
272 return len(f.formal) > 0
275 // HasAvailableFlags returns a bool to indicate if the FlagSet has any flags
276 // definied that are not hidden or deprecated.
277 func (f *FlagSet) HasAvailableFlags() bool {
278 for _, flag := range f.formal {
279 if !flag.Hidden && len(flag.Deprecated) == 0 {
286 // VisitAll visits the command-line flags in lexicographical order or
287 // in primordial order if f.SortFlags is false, calling fn for each.
288 // It visits all flags, even those not set.
289 func VisitAll(fn func(*Flag)) {
290 CommandLine.VisitAll(fn)
293 // Visit visits the flags in lexicographical order or
294 // in primordial order if f.SortFlags is false, calling fn for each.
295 // It visits only those flags that have been set.
296 func (f *FlagSet) Visit(fn func(*Flag)) {
297 if len(f.actual) == 0 {
303 if len(f.actual) != len(f.sortedActual) {
304 f.sortedActual = sortFlags(f.actual)
306 flags = f.sortedActual
308 flags = f.orderedActual
311 for _, flag := range flags {
316 // Visit visits the command-line flags in lexicographical order or
317 // in primordial order if f.SortFlags is false, calling fn for each.
318 // It visits only those flags that have been set.
319 func Visit(fn func(*Flag)) {
320 CommandLine.Visit(fn)
323 // Lookup returns the Flag structure of the named flag, returning nil if none exists.
324 func (f *FlagSet) Lookup(name string) *Flag {
325 return f.lookup(f.normalizeFlagName(name))
328 // ShorthandLookup returns the Flag structure of the short handed flag,
329 // returning nil if none exists.
330 // It panics, if len(name) > 1.
331 func (f *FlagSet) ShorthandLookup(name string) *Flag {
336 msg := fmt.Sprintf("can not look up shorthand which is more than one ASCII character: %q", name)
337 fmt.Fprintf(f.out(), msg)
341 return f.shorthands[c]
344 // lookup returns the Flag structure of the named flag, returning nil if none exists.
345 func (f *FlagSet) lookup(name NormalizedName) *Flag {
346 return f.formal[name]
349 // func to return a given type for a given flag name
350 func (f *FlagSet) getFlagType(name string, ftype string, convFunc func(sval string) (interface{}, error)) (interface{}, error) {
351 flag := f.Lookup(name)
353 err := fmt.Errorf("flag accessed but not defined: %s", name)
357 if flag.Value.Type() != ftype {
358 err := fmt.Errorf("trying to get %s value of flag of type %s", ftype, flag.Value.Type())
362 sval := flag.Value.String()
363 result, err := convFunc(sval)
370 // ArgsLenAtDash will return the length of f.Args at the moment when a -- was
371 // found during arg parsing. This allows your program to know which args were
372 // before the -- and which came after.
373 func (f *FlagSet) ArgsLenAtDash() int {
374 return f.argsLenAtDash
377 // MarkDeprecated indicated that a flag is deprecated in your program. It will
378 // continue to function but will not show up in help or usage messages. Using
379 // this flag will also print the given usageMessage.
380 func (f *FlagSet) MarkDeprecated(name string, usageMessage string) error {
381 flag := f.Lookup(name)
383 return fmt.Errorf("flag %q does not exist", name)
385 if usageMessage == "" {
386 return fmt.Errorf("deprecated message for flag %q must be set", name)
388 flag.Deprecated = usageMessage
392 // MarkShorthandDeprecated will mark the shorthand of a flag deprecated in your
393 // program. It will continue to function but will not show up in help or usage
394 // messages. Using this flag will also print the given usageMessage.
395 func (f *FlagSet) MarkShorthandDeprecated(name string, usageMessage string) error {
396 flag := f.Lookup(name)
398 return fmt.Errorf("flag %q does not exist", name)
400 if usageMessage == "" {
401 return fmt.Errorf("deprecated message for flag %q must be set", name)
403 flag.ShorthandDeprecated = usageMessage
407 // MarkHidden sets a flag to 'hidden' in your program. It will continue to
408 // function but will not show up in help or usage messages.
409 func (f *FlagSet) MarkHidden(name string) error {
410 flag := f.Lookup(name)
412 return fmt.Errorf("flag %q does not exist", name)
418 // Lookup returns the Flag structure of the named command-line flag,
419 // returning nil if none exists.
420 func Lookup(name string) *Flag {
421 return CommandLine.Lookup(name)
424 // ShorthandLookup returns the Flag structure of the short handed flag,
425 // returning nil if none exists.
426 func ShorthandLookup(name string) *Flag {
427 return CommandLine.ShorthandLookup(name)
430 // Set sets the value of the named flag.
431 func (f *FlagSet) Set(name, value string) error {
432 normalName := f.normalizeFlagName(name)
433 flag, ok := f.formal[normalName]
435 return fmt.Errorf("no such flag -%v", name)
438 err := flag.Value.Set(value)
441 if flag.Shorthand != "" && flag.ShorthandDeprecated == "" {
442 flagName = fmt.Sprintf("-%s, --%s", flag.Shorthand, flag.Name)
444 flagName = fmt.Sprintf("--%s", flag.Name)
446 return fmt.Errorf("invalid argument %q for %q flag: %v", value, flagName, err)
451 f.actual = make(map[NormalizedName]*Flag)
453 f.actual[normalName] = flag
454 f.orderedActual = append(f.orderedActual, flag)
459 if flag.Deprecated != "" {
460 fmt.Fprintf(f.out(), "Flag --%s has been deprecated, %s\n", flag.Name, flag.Deprecated)
465 // SetAnnotation allows one to set arbitrary annotations on a flag in the FlagSet.
466 // This is sometimes used by spf13/cobra programs which want to generate additional
467 // bash completion information.
468 func (f *FlagSet) SetAnnotation(name, key string, values []string) error {
469 normalName := f.normalizeFlagName(name)
470 flag, ok := f.formal[normalName]
472 return fmt.Errorf("no such flag -%v", name)
474 if flag.Annotations == nil {
475 flag.Annotations = map[string][]string{}
477 flag.Annotations[key] = values
481 // Changed returns true if the flag was explicitly set during Parse() and false
483 func (f *FlagSet) Changed(name string) bool {
484 flag := f.Lookup(name)
485 // If a flag doesn't exist, it wasn't changed....
492 // Set sets the value of the named command-line flag.
493 func Set(name, value string) error {
494 return CommandLine.Set(name, value)
497 // PrintDefaults prints, to standard error unless configured
498 // otherwise, the default values of all defined flags in the set.
499 func (f *FlagSet) PrintDefaults() {
500 usages := f.FlagUsages()
501 fmt.Fprint(f.out(), usages)
504 // defaultIsZeroValue returns true if the default value for this flag represents
506 func (f *Flag) defaultIsZeroValue() bool {
507 switch f.Value.(type) {
509 return f.DefValue == "false"
511 // Beginning in Go 1.7, duration zero values are "0s"
512 return f.DefValue == "0" || f.DefValue == "0s"
513 case *intValue, *int8Value, *int32Value, *int64Value, *uintValue, *uint8Value, *uint16Value, *uint32Value, *uint64Value, *countValue, *float32Value, *float64Value:
514 return f.DefValue == "0"
516 return f.DefValue == ""
517 case *ipValue, *ipMaskValue, *ipNetValue:
518 return f.DefValue == "<nil>"
519 case *intSliceValue, *stringSliceValue, *stringArrayValue:
520 return f.DefValue == "[]"
522 switch f.Value.String() {
536 // UnquoteUsage extracts a back-quoted name from the usage
537 // string for a flag and returns it and the un-quoted usage.
538 // Given "a `name` to show" it returns ("name", "a name to show").
539 // If there are no back quotes, the name is an educated guess of the
540 // type of the flag's value, or the empty string if the flag is boolean.
541 func UnquoteUsage(flag *Flag) (name string, usage string) {
542 // Look for a back-quoted name, but avoid the strings package.
544 for i := 0; i < len(usage); i++ {
546 for j := i + 1; j < len(usage); j++ {
548 name = usage[i+1 : j]
549 usage = usage[:i] + name + usage[j+1:]
553 break // Only one back quote; use type name.
557 name = flag.Value.Type()
576 // Splits the string `s` on whitespace into an initial substring up to
577 // `i` runes in length and the remainder. Will go `slop` over `i` if
578 // that encompasses the entire string (which allows the caller to
579 // avoid short orphan words on the final line).
580 func wrapN(i, slop int, s string) (string, string) {
585 w := strings.LastIndexAny(s[:i], " \t")
590 return s[:w], s[w+1:]
593 // Wraps the string `s` to a maximum width `w` with leading indent
594 // `i`. The first line is not indented (this is assumed to be done by
595 // caller). Pass `w` == 0 to do no wrapping
596 func wrap(i, w int, s string) string {
601 // space between indent i and end of line width w into which
602 // we should wrap the text.
607 // Not enough space for sensible wrapping. Wrap as a block on
608 // the next line instead.
612 r += "\n" + strings.Repeat(" ", i)
614 // If still not enough space then don't even try to wrap.
619 // Try to avoid short orphan words on the final line, by
620 // allowing wrapN to go a bit over if that would fit in the
621 // remainder of the line.
625 // Handle first line, which is indented by the caller (or the
626 // special case above)
627 l, s = wrapN(wrap, slop, s)
634 t, s = wrapN(wrap, slop, s)
635 r = r + "\n" + strings.Repeat(" ", i) + t
642 // FlagUsagesWrapped returns a string containing the usage information
643 // for all flags in the FlagSet. Wrapped to `cols` columns (0 for no
645 func (f *FlagSet) FlagUsagesWrapped(cols int) string {
646 buf := new(bytes.Buffer)
648 lines := make([]string, 0, len(f.formal))
651 f.VisitAll(func(flag *Flag) {
652 if flag.Deprecated != "" || flag.Hidden {
657 if flag.Shorthand != "" && flag.ShorthandDeprecated == "" {
658 line = fmt.Sprintf(" -%s, --%s", flag.Shorthand, flag.Name)
660 line = fmt.Sprintf(" --%s", flag.Name)
663 varname, usage := UnquoteUsage(flag)
665 line += " " + varname
667 if flag.NoOptDefVal != "" {
668 switch flag.Value.Type() {
670 line += fmt.Sprintf("[=\"%s\"]", flag.NoOptDefVal)
672 if flag.NoOptDefVal != "true" {
673 line += fmt.Sprintf("[=%s]", flag.NoOptDefVal)
676 if flag.NoOptDefVal != "+1" {
677 line += fmt.Sprintf("[=%s]", flag.NoOptDefVal)
680 line += fmt.Sprintf("[=%s]", flag.NoOptDefVal)
684 // This special character will be replaced with spacing once the
685 // correct alignment is calculated
687 if len(line) > maxlen {
692 if !flag.defaultIsZeroValue() {
693 if flag.Value.Type() == "string" {
694 line += fmt.Sprintf(" (default %q)", flag.DefValue)
696 line += fmt.Sprintf(" (default %s)", flag.DefValue)
700 lines = append(lines, line)
703 for _, line := range lines {
704 sidx := strings.Index(line, "\x00")
705 spacing := strings.Repeat(" ", maxlen-sidx)
706 // maxlen + 2 comes from + 1 for the \x00 and + 1 for the (deliberate) off-by-one in maxlen-sidx
707 fmt.Fprintln(buf, line[:sidx], spacing, wrap(maxlen+2, cols, line[sidx+1:]))
713 // FlagUsages returns a string containing the usage information for all flags in
715 func (f *FlagSet) FlagUsages() string {
716 return f.FlagUsagesWrapped(0)
719 // PrintDefaults prints to standard error the default values of all defined command-line flags.
720 func PrintDefaults() {
721 CommandLine.PrintDefaults()
724 // defaultUsage is the default function to print a usage message.
725 func defaultUsage(f *FlagSet) {
726 fmt.Fprintf(f.out(), "Usage of %s:\n", f.name)
730 // NOTE: Usage is not just defaultUsage(CommandLine)
731 // because it serves (via godoc flag Usage) as the example
732 // for how to write your own usage function.
734 // Usage prints to standard error a usage message documenting all defined command-line flags.
735 // The function is a variable that may be changed to point to a custom function.
736 // By default it prints a simple header and calls PrintDefaults; for details about the
737 // format of the output and how to control it, see the documentation for PrintDefaults.
739 fmt.Fprintf(os.Stderr, "Usage of %s:\n", os.Args[0])
743 // NFlag returns the number of flags that have been set.
744 func (f *FlagSet) NFlag() int { return len(f.actual) }
746 // NFlag returns the number of command-line flags that have been set.
747 func NFlag() int { return len(CommandLine.actual) }
749 // Arg returns the i'th argument. Arg(0) is the first remaining argument
750 // after flags have been processed.
751 func (f *FlagSet) Arg(i int) string {
752 if i < 0 || i >= len(f.args) {
758 // Arg returns the i'th command-line argument. Arg(0) is the first remaining argument
759 // after flags have been processed.
760 func Arg(i int) string {
761 return CommandLine.Arg(i)
764 // NArg is the number of arguments remaining after flags have been processed.
765 func (f *FlagSet) NArg() int { return len(f.args) }
767 // NArg is the number of arguments remaining after flags have been processed.
768 func NArg() int { return len(CommandLine.args) }
770 // Args returns the non-flag arguments.
771 func (f *FlagSet) Args() []string { return f.args }
773 // Args returns the non-flag command-line arguments.
774 func Args() []string { return CommandLine.args }
776 // Var defines a flag with the specified name and usage string. The type and
777 // value of the flag are represented by the first argument, of type Value, which
778 // typically holds a user-defined implementation of Value. For instance, the
779 // caller could create a flag that turns a comma-separated string into a slice
780 // of strings by giving the slice the methods of Value; in particular, Set would
781 // decompose the comma-separated string into the slice.
782 func (f *FlagSet) Var(value Value, name string, usage string) {
783 f.VarP(value, name, "", usage)
786 // VarPF is like VarP, but returns the flag created
787 func (f *FlagSet) VarPF(value Value, name, shorthand, usage string) *Flag {
788 // Remember the default value as a string; it won't change.
791 Shorthand: shorthand,
794 DefValue: value.String(),
800 // VarP is like Var, but accepts a shorthand letter that can be used after a single dash.
801 func (f *FlagSet) VarP(value Value, name, shorthand, usage string) {
802 f.VarPF(value, name, shorthand, usage)
805 // AddFlag will add the flag to the FlagSet
806 func (f *FlagSet) AddFlag(flag *Flag) {
807 normalizedFlagName := f.normalizeFlagName(flag.Name)
809 _, alreadyThere := f.formal[normalizedFlagName]
811 msg := fmt.Sprintf("%s flag redefined: %s", f.name, flag.Name)
812 fmt.Fprintln(f.out(), msg)
813 panic(msg) // Happens only if flags are declared with identical names
816 f.formal = make(map[NormalizedName]*Flag)
819 flag.Name = string(normalizedFlagName)
820 f.formal[normalizedFlagName] = flag
821 f.orderedFormal = append(f.orderedFormal, flag)
823 if flag.Shorthand == "" {
826 if len(flag.Shorthand) > 1 {
827 msg := fmt.Sprintf("%q shorthand is more than one ASCII character", flag.Shorthand)
828 fmt.Fprintf(f.out(), msg)
831 if f.shorthands == nil {
832 f.shorthands = make(map[byte]*Flag)
834 c := flag.Shorthand[0]
835 used, alreadyThere := f.shorthands[c]
837 msg := fmt.Sprintf("unable to redefine %q shorthand in %q flagset: it's already used for %q flag", c, f.name, used.Name)
838 fmt.Fprintf(f.out(), msg)
841 f.shorthands[c] = flag
844 // AddFlagSet adds one FlagSet to another. If a flag is already present in f
845 // the flag from newSet will be ignored.
846 func (f *FlagSet) AddFlagSet(newSet *FlagSet) {
850 newSet.VisitAll(func(flag *Flag) {
851 if f.Lookup(flag.Name) == nil {
857 // Var defines a flag with the specified name and usage string. The type and
858 // value of the flag are represented by the first argument, of type Value, which
859 // typically holds a user-defined implementation of Value. For instance, the
860 // caller could create a flag that turns a comma-separated string into a slice
861 // of strings by giving the slice the methods of Value; in particular, Set would
862 // decompose the comma-separated string into the slice.
863 func Var(value Value, name string, usage string) {
864 CommandLine.VarP(value, name, "", usage)
867 // VarP is like Var, but accepts a shorthand letter that can be used after a single dash.
868 func VarP(value Value, name, shorthand, usage string) {
869 CommandLine.VarP(value, name, shorthand, usage)
872 // failf prints to standard error a formatted error and usage message and
873 // returns the error.
874 func (f *FlagSet) failf(format string, a ...interface{}) error {
875 err := fmt.Errorf(format, a...)
876 if f.errorHandling != ContinueOnError {
877 fmt.Fprintln(f.out(), err)
883 // usage calls the Usage method for the flag set, or the usage function if
884 // the flag set is CommandLine.
885 func (f *FlagSet) usage() {
886 if f == CommandLine {
888 } else if f.Usage == nil {
895 func (f *FlagSet) parseLongArg(s string, args []string, fn parseFunc) (a []string, err error) {
898 if len(name) == 0 || name[0] == '-' || name[0] == '=' {
899 err = f.failf("bad flag syntax: %s", s)
903 split := strings.SplitN(name, "=", 2)
905 flag, exists := f.formal[f.normalizeFlagName(name)]
907 if name == "help" { // special case for nice help message.
911 err = f.failf("unknown flag: --%s", name)
919 } else if flag.NoOptDefVal != "" {
920 // '--flag' (arg was optional)
921 value = flag.NoOptDefVal
922 } else if len(a) > 0 {
927 // '--flag' (arg was required)
928 err = f.failf("flag needs an argument: %s", s)
932 err = fn(flag, value)
939 func (f *FlagSet) parseSingleShortArg(shorthands string, args []string, fn parseFunc) (outShorts string, outArgs []string, err error) {
940 if strings.HasPrefix(shorthands, "test.") {
945 outShorts = shorthands[1:]
948 flag, exists := f.shorthands[c]
950 if c == 'h' { // special case for nice help message.
955 err = f.failf("unknown shorthand flag: %q in -%s", c, shorthands)
960 if len(shorthands) > 2 && shorthands[1] == '=' {
962 value = shorthands[2:]
964 } else if flag.NoOptDefVal != "" {
965 // '-f' (arg was optional)
966 value = flag.NoOptDefVal
967 } else if len(shorthands) > 1 {
969 value = shorthands[1:]
971 } else if len(args) > 0 {
976 // '-f' (arg was required)
977 err = f.failf("flag needs an argument: %q in -%s", c, shorthands)
981 if flag.ShorthandDeprecated != "" {
982 fmt.Fprintf(f.out(), "Flag shorthand -%s has been deprecated, %s\n", flag.Shorthand, flag.ShorthandDeprecated)
985 err = fn(flag, value)
992 func (f *FlagSet) parseShortArg(s string, args []string, fn parseFunc) (a []string, err error) {
996 // "shorthands" can be a series of shorthand letters of flags (e.g. "-vvv").
997 for len(shorthands) > 0 {
998 shorthands, a, err = f.parseSingleShortArg(shorthands, args, fn)
1007 func (f *FlagSet) parseArgs(args []string, fn parseFunc) (err error) {
1011 if len(s) == 0 || s[0] != '-' || len(s) == 1 {
1012 if !f.interspersed {
1013 f.args = append(f.args, s)
1014 f.args = append(f.args, args...)
1017 f.args = append(f.args, s)
1022 if len(s) == 2 { // "--" terminates the flags
1023 f.argsLenAtDash = len(f.args)
1024 f.args = append(f.args, args...)
1027 args, err = f.parseLongArg(s, args, fn)
1029 args, err = f.parseShortArg(s, args, fn)
1038 // Parse parses flag definitions from the argument list, which should not
1039 // include the command name. Must be called after all flags in the FlagSet
1040 // are defined and before flags are accessed by the program.
1041 // The return value will be ErrHelp if -help was set but not defined.
1042 func (f *FlagSet) Parse(arguments []string) error {
1045 if len(arguments) < 0 {
1049 f.args = make([]string, 0, len(arguments))
1051 set := func(flag *Flag, value string) error {
1052 return f.Set(flag.Name, value)
1055 err := f.parseArgs(arguments, set)
1057 switch f.errorHandling {
1058 case ContinueOnError:
1070 type parseFunc func(flag *Flag, value string) error
1072 // ParseAll parses flag definitions from the argument list, which should not
1073 // include the command name. The arguments for fn are flag and value. Must be
1074 // called after all flags in the FlagSet are defined and before flags are
1075 // accessed by the program. The return value will be ErrHelp if -help was set
1077 func (f *FlagSet) ParseAll(arguments []string, fn func(flag *Flag, value string) error) error {
1079 f.args = make([]string, 0, len(arguments))
1081 err := f.parseArgs(arguments, fn)
1083 switch f.errorHandling {
1084 case ContinueOnError:
1095 // Parsed reports whether f.Parse has been called.
1096 func (f *FlagSet) Parsed() bool {
1100 // Parse parses the command-line flags from os.Args[1:]. Must be called
1101 // after all flags are defined and before flags are accessed by the program.
1103 // Ignore errors; CommandLine is set for ExitOnError.
1104 CommandLine.Parse(os.Args[1:])
1107 // ParseAll parses the command-line flags from os.Args[1:] and called fn for each.
1108 // The arguments for fn are flag and value. Must be called after all flags are
1109 // defined and before flags are accessed by the program.
1110 func ParseAll(fn func(flag *Flag, value string) error) {
1111 // Ignore errors; CommandLine is set for ExitOnError.
1112 CommandLine.ParseAll(os.Args[1:], fn)
1115 // SetInterspersed sets whether to support interspersed option/non-option arguments.
1116 func SetInterspersed(interspersed bool) {
1117 CommandLine.SetInterspersed(interspersed)
1120 // Parsed returns true if the command-line flags have been parsed.
1121 func Parsed() bool {
1122 return CommandLine.Parsed()
1125 // CommandLine is the default set of command-line flags, parsed from os.Args.
1126 var CommandLine = NewFlagSet(os.Args[0], ExitOnError)
1128 // NewFlagSet returns a new, empty flag set with the specified name,
1129 // error handling property and SortFlags set to true.
1130 func NewFlagSet(name string, errorHandling ErrorHandling) *FlagSet {
1133 errorHandling: errorHandling,
1141 // SetInterspersed sets whether to support interspersed option/non-option arguments.
1142 func (f *FlagSet) SetInterspersed(interspersed bool) {
1143 f.interspersed = interspersed
1146 // Init sets the name and error handling property for a flag set.
1147 // By default, the zero FlagSet uses an empty name and the
1148 // ContinueOnError error handling policy.
1149 func (f *FlagSet) Init(name string, errorHandling ErrorHandling) {
1151 f.errorHandling = errorHandling
1152 f.argsLenAtDash = -1