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
112 // ErrHelp is the error returned if the flag -help is invoked but no such flag is defined.
113 var ErrHelp = errors.New("pflag: help requested")
115 // ErrorHandling defines how to handle flag parsing errors.
116 type ErrorHandling int
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
123 // PanicOnError will panic() if an error is found when parsing flags
127 // ParseErrorsWhitelist defines the parsing errors that can be ignored
128 type ParseErrorsWhitelist struct {
129 // UnknownFlags will ignore unknown flags errors and continue parsing rest of the flags
133 // NormalizedName is a flag name that has been normalized according to rules
134 // for the FlagSet (e.g. making '-' and '_' equivalent).
135 type NormalizedName string
137 // A FlagSet represents a set of defined flags.
138 type 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.
144 // SortFlags is used to indicate, if user wants to have sorted flags in
145 // help/usage messages.
148 // ParseErrorsWhitelist is used to configure a whitelist of errors
149 ParseErrorsWhitelist ParseErrorsWhitelist
153 actual map[NormalizedName]*Flag
154 orderedActual []*Flag
156 formal map[NormalizedName]*Flag
157 orderedFormal []*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
167 addedGoFlagSets []*goflag.FlagSet
170 // A Flag represents the state of a flag.
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
185 // Value is the interface to the dynamic value stored in a flag.
186 // (The default value is represented as a string.)
187 type Value interface {
193 // sortFlags returns the flags as a slice in lexicographical sorted order.
194 func sortFlags(flags map[NormalizedName]*Flag) []*Flag {
195 list := make(sort.StringSlice, len(flags))
197 for k := range flags {
202 result := make([]*Flag, len(list))
203 for i, name := range list {
204 result[i] = flags[NormalizedName(name)]
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.
214 func (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)
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
232 // GetNormalizeFunc returns the previously set NormalizeFunc of a function which
233 // does no translation, if not set previously.
234 func (f *FlagSet) GetNormalizeFunc() func(f *FlagSet, name string) NormalizedName {
235 if f.normalizeNameFunc != nil {
236 return f.normalizeNameFunc
238 return func(f *FlagSet, name string) NormalizedName { return NormalizedName(name) }
241 func (f *FlagSet) normalizeFlagName(name string) NormalizedName {
242 n := f.GetNormalizeFunc()
246 func (f *FlagSet) out() io.Writer {
253 // SetOutput sets the destination for usage and error messages.
254 // If output is nil, os.Stderr is used.
255 func (f *FlagSet) SetOutput(output io.Writer) {
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.
262 func (f *FlagSet) VisitAll(fn func(*Flag)) {
263 if len(f.formal) == 0 {
269 if len(f.formal) != len(f.sortedFormal) {
270 f.sortedFormal = sortFlags(f.formal)
272 flags = f.sortedFormal
274 flags = f.orderedFormal
277 for _, flag := range flags {
282 // HasFlags returns a bool to indicate if the FlagSet has any flags defined.
283 func (f *FlagSet) HasFlags() bool {
284 return len(f.formal) > 0
287 // HasAvailableFlags returns a bool to indicate if the FlagSet has any flags
288 // that are not hidden.
289 func (f *FlagSet) HasAvailableFlags() bool {
290 for _, flag := range f.formal {
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.
301 func VisitAll(fn func(*Flag)) {
302 CommandLine.VisitAll(fn)
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.
308 func (f *FlagSet) Visit(fn func(*Flag)) {
309 if len(f.actual) == 0 {
315 if len(f.actual) != len(f.sortedActual) {
316 f.sortedActual = sortFlags(f.actual)
318 flags = f.sortedActual
320 flags = f.orderedActual
323 for _, flag := range flags {
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.
331 func Visit(fn func(*Flag)) {
332 CommandLine.Visit(fn)
335 // Lookup returns the Flag structure of the named flag, returning nil if none exists.
336 func (f *FlagSet) Lookup(name string) *Flag {
337 return f.lookup(f.normalizeFlagName(name))
340 // ShorthandLookup returns the Flag structure of the short handed flag,
341 // returning nil if none exists.
342 // It panics, if len(name) > 1.
343 func (f *FlagSet) ShorthandLookup(name string) *Flag {
348 msg := fmt.Sprintf("can not look up shorthand which is more than one ASCII character: %q", name)
349 fmt.Fprintf(f.out(), msg)
353 return f.shorthands[c]
356 // lookup returns the Flag structure of the named flag, returning nil if none exists.
357 func (f *FlagSet) lookup(name NormalizedName) *Flag {
358 return f.formal[name]
361 // func to return a given type for a given flag name
362 func (f *FlagSet) getFlagType(name string, ftype string, convFunc func(sval string) (interface{}, error)) (interface{}, error) {
363 flag := f.Lookup(name)
365 err := fmt.Errorf("flag accessed but not defined: %s", name)
369 if flag.Value.Type() != ftype {
370 err := fmt.Errorf("trying to get %s value of flag of type %s", ftype, flag.Value.Type())
374 sval := flag.Value.String()
375 result, err := convFunc(sval)
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.
385 func (f *FlagSet) ArgsLenAtDash() int {
386 return f.argsLenAtDash
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.
392 func (f *FlagSet) MarkDeprecated(name string, usageMessage string) error {
393 flag := f.Lookup(name)
395 return fmt.Errorf("flag %q does not exist", name)
397 if usageMessage == "" {
398 return fmt.Errorf("deprecated message for flag %q must be set", name)
400 flag.Deprecated = usageMessage
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.
408 func (f *FlagSet) MarkShorthandDeprecated(name string, usageMessage string) error {
409 flag := f.Lookup(name)
411 return fmt.Errorf("flag %q does not exist", name)
413 if usageMessage == "" {
414 return fmt.Errorf("deprecated message for flag %q must be set", name)
416 flag.ShorthandDeprecated = usageMessage
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.
422 func (f *FlagSet) MarkHidden(name string) error {
423 flag := f.Lookup(name)
425 return fmt.Errorf("flag %q does not exist", name)
431 // Lookup returns the Flag structure of the named command-line flag,
432 // returning nil if none exists.
433 func Lookup(name string) *Flag {
434 return CommandLine.Lookup(name)
437 // ShorthandLookup returns the Flag structure of the short handed flag,
438 // returning nil if none exists.
439 func ShorthandLookup(name string) *Flag {
440 return CommandLine.ShorthandLookup(name)
443 // Set sets the value of the named flag.
444 func (f *FlagSet) Set(name, value string) error {
445 normalName := f.normalizeFlagName(name)
446 flag, ok := f.formal[normalName]
448 return fmt.Errorf("no such flag -%v", name)
451 err := flag.Value.Set(value)
454 if flag.Shorthand != "" && flag.ShorthandDeprecated == "" {
455 flagName = fmt.Sprintf("-%s, --%s", flag.Shorthand, flag.Name)
457 flagName = fmt.Sprintf("--%s", flag.Name)
459 return fmt.Errorf("invalid argument %q for %q flag: %v", value, flagName, err)
464 f.actual = make(map[NormalizedName]*Flag)
466 f.actual[normalName] = flag
467 f.orderedActual = append(f.orderedActual, flag)
472 if flag.Deprecated != "" {
473 fmt.Fprintf(f.out(), "Flag --%s has been deprecated, %s\n", flag.Name, flag.Deprecated)
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.
481 func (f *FlagSet) SetAnnotation(name, key string, values []string) error {
482 normalName := f.normalizeFlagName(name)
483 flag, ok := f.formal[normalName]
485 return fmt.Errorf("no such flag -%v", name)
487 if flag.Annotations == nil {
488 flag.Annotations = map[string][]string{}
490 flag.Annotations[key] = values
494 // Changed returns true if the flag was explicitly set during Parse() and false
496 func (f *FlagSet) Changed(name string) bool {
497 flag := f.Lookup(name)
498 // If a flag doesn't exist, it wasn't changed....
505 // Set sets the value of the named command-line flag.
506 func Set(name, value string) error {
507 return CommandLine.Set(name, value)
510 // PrintDefaults prints, to standard error unless configured
511 // otherwise, the default values of all defined flags in the set.
512 func (f *FlagSet) PrintDefaults() {
513 usages := f.FlagUsages()
514 fmt.Fprint(f.out(), usages)
517 // defaultIsZeroValue returns true if the default value for this flag represents
519 func (f *Flag) defaultIsZeroValue() bool {
520 switch f.Value.(type) {
522 return f.DefValue == "false"
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"
529 return f.DefValue == ""
530 case *ipValue, *ipMaskValue, *ipNetValue:
531 return f.DefValue == "<nil>"
532 case *intSliceValue, *stringSliceValue, *stringArrayValue:
533 return f.DefValue == "[]"
535 switch f.Value.String() {
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.
554 func UnquoteUsage(flag *Flag) (name string, usage string) {
555 // Look for a back-quoted name, but avoid the strings package.
557 for i := 0; i < len(usage); i++ {
559 for j := i + 1; j < len(usage); j++ {
561 name = usage[i+1 : j]
562 usage = usage[:i] + name + usage[j+1:]
566 break // Only one back quote; use type name.
570 name = flag.Value.Type()
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).
597 func wrapN(i, slop int, s string) (string, string) {
602 w := strings.LastIndexAny(s[:i], " \t\n")
606 nlPos := strings.LastIndex(s[:i], "\n")
607 if nlPos > 0 && nlPos < w {
608 return s[:nlPos], s[nlPos+1:]
610 return s[:w], s[w+1:]
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
616 func wrap(i, w int, s string) string {
618 return strings.Replace(s, "\n", "\n"+strings.Repeat(" ", i), -1)
621 // space between indent i and end of line width w into which
622 // we should wrap the text.
627 // Not enough space for sensible wrapping. Wrap as a block on
628 // the next line instead.
632 r += "\n" + strings.Repeat(" ", i)
634 // If still not enough space then don't even try to wrap.
636 return strings.Replace(s, "\n", r, -1)
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.
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)
654 t, s = wrapN(wrap, slop, s)
655 r = r + "\n" + strings.Repeat(" ", i) + strings.Replace(t, "\n", "\n"+strings.Repeat(" ", i), -1)
662 // FlagUsagesWrapped returns a string containing the usage information
663 // for all flags in the FlagSet. Wrapped to `cols` columns (0 for no
665 func (f *FlagSet) FlagUsagesWrapped(cols int) string {
666 buf := new(bytes.Buffer)
668 lines := make([]string, 0, len(f.formal))
671 f.VisitAll(func(flag *Flag) {
677 if flag.Shorthand != "" && flag.ShorthandDeprecated == "" {
678 line = fmt.Sprintf(" -%s, --%s", flag.Shorthand, flag.Name)
680 line = fmt.Sprintf(" --%s", flag.Name)
683 varname, usage := UnquoteUsage(flag)
685 line += " " + varname
687 if flag.NoOptDefVal != "" {
688 switch flag.Value.Type() {
690 line += fmt.Sprintf("[=\"%s\"]", flag.NoOptDefVal)
692 if flag.NoOptDefVal != "true" {
693 line += fmt.Sprintf("[=%s]", flag.NoOptDefVal)
696 if flag.NoOptDefVal != "+1" {
697 line += fmt.Sprintf("[=%s]", flag.NoOptDefVal)
700 line += fmt.Sprintf("[=%s]", flag.NoOptDefVal)
704 // This special character will be replaced with spacing once the
705 // correct alignment is calculated
707 if len(line) > maxlen {
712 if !flag.defaultIsZeroValue() {
713 if flag.Value.Type() == "string" {
714 line += fmt.Sprintf(" (default %q)", flag.DefValue)
716 line += fmt.Sprintf(" (default %s)", flag.DefValue)
719 if len(flag.Deprecated) != 0 {
720 line += fmt.Sprintf(" (DEPRECATED: %s)", flag.Deprecated)
723 lines = append(lines, line)
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:]))
736 // FlagUsages returns a string containing the usage information for all flags in
738 func (f *FlagSet) FlagUsages() string {
739 return f.FlagUsagesWrapped(0)
742 // PrintDefaults prints to standard error the default values of all defined command-line flags.
743 func PrintDefaults() {
744 CommandLine.PrintDefaults()
747 // defaultUsage is the default function to print a usage message.
748 func defaultUsage(f *FlagSet) {
749 fmt.Fprintf(f.out(), "Usage of %s:\n", f.name)
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.
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.
762 fmt.Fprintf(os.Stderr, "Usage of %s:\n", os.Args[0])
766 // NFlag returns the number of flags that have been set.
767 func (f *FlagSet) NFlag() int { return len(f.actual) }
769 // NFlag returns the number of command-line flags that have been set.
770 func NFlag() int { return len(CommandLine.actual) }
772 // Arg returns the i'th argument. Arg(0) is the first remaining argument
773 // after flags have been processed.
774 func (f *FlagSet) Arg(i int) string {
775 if i < 0 || i >= len(f.args) {
781 // Arg returns the i'th command-line argument. Arg(0) is the first remaining argument
782 // after flags have been processed.
783 func Arg(i int) string {
784 return CommandLine.Arg(i)
787 // NArg is the number of arguments remaining after flags have been processed.
788 func (f *FlagSet) NArg() int { return len(f.args) }
790 // NArg is the number of arguments remaining after flags have been processed.
791 func NArg() int { return len(CommandLine.args) }
793 // Args returns the non-flag arguments.
794 func (f *FlagSet) Args() []string { return f.args }
796 // Args returns the non-flag command-line arguments.
797 func Args() []string { return CommandLine.args }
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.
805 func (f *FlagSet) Var(value Value, name string, usage string) {
806 f.VarP(value, name, "", usage)
809 // VarPF is like VarP, but returns the flag created
810 func (f *FlagSet) VarPF(value Value, name, shorthand, usage string) *Flag {
811 // Remember the default value as a string; it won't change.
814 Shorthand: shorthand,
817 DefValue: value.String(),
823 // VarP is like Var, but accepts a shorthand letter that can be used after a single dash.
824 func (f *FlagSet) VarP(value Value, name, shorthand, usage string) {
825 f.VarPF(value, name, shorthand, usage)
828 // AddFlag will add the flag to the FlagSet
829 func (f *FlagSet) AddFlag(flag *Flag) {
830 normalizedFlagName := f.normalizeFlagName(flag.Name)
832 _, alreadyThere := f.formal[normalizedFlagName]
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
839 f.formal = make(map[NormalizedName]*Flag)
842 flag.Name = string(normalizedFlagName)
843 f.formal[normalizedFlagName] = flag
844 f.orderedFormal = append(f.orderedFormal, flag)
846 if flag.Shorthand == "" {
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)
854 if f.shorthands == nil {
855 f.shorthands = make(map[byte]*Flag)
857 c := flag.Shorthand[0]
858 used, alreadyThere := f.shorthands[c]
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)
864 f.shorthands[c] = flag
867 // AddFlagSet adds one FlagSet to another. If a flag is already present in f
868 // the flag from newSet will be ignored.
869 func (f *FlagSet) AddFlagSet(newSet *FlagSet) {
873 newSet.VisitAll(func(flag *Flag) {
874 if f.Lookup(flag.Name) == nil {
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.
886 func Var(value Value, name string, usage string) {
887 CommandLine.VarP(value, name, "", usage)
890 // VarP is like Var, but accepts a shorthand letter that can be used after a single dash.
891 func VarP(value Value, name, shorthand, usage string) {
892 CommandLine.VarP(value, name, shorthand, usage)
895 // failf prints to standard error a formatted error and usage message and
896 // returns the error.
897 func (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)
906 // usage calls the Usage method for the flag set, or the usage function if
907 // the flag set is CommandLine.
908 func (f *FlagSet) usage() {
909 if f == CommandLine {
911 } else if f.Usage == nil {
918 //--unknown (args will be empty)
919 //--unknown --next-flag ... (args will be --next-flag ...)
920 //--unknown arg ... (args will be arg ...)
921 func stripUnknownFlagValue(args []string) []string {
928 if len(first) > 0 && first[0] == '-' {
929 //--unknown --next-flag ...
933 //--unknown arg ... (args will be arg ...)
940 func (f *FlagSet) parseLongArg(s string, args []string, fn parseFunc) (a []string, err error) {
943 if len(name) == 0 || name[0] == '-' || name[0] == '=' {
944 err = f.failf("bad flag syntax: %s", s)
948 split := strings.SplitN(name, "=", 2)
950 flag, exists := f.formal[f.normalizeFlagName(name)]
957 case f.ParseErrorsWhitelist.UnknownFlags:
958 // --unknown=unknownval arg ...
959 // we do not want to lose arg in this case
964 return stripUnknownFlagValue(a), nil
966 err = f.failf("unknown flag: --%s", name)
975 } else if flag.NoOptDefVal != "" {
976 // '--flag' (arg was optional)
977 value = flag.NoOptDefVal
978 } else if len(a) > 0 {
983 // '--flag' (arg was required)
984 err = f.failf("flag needs an argument: %s", s)
988 err = fn(flag, value)
995 func (f *FlagSet) parseSingleShortArg(shorthands string, args []string, fn parseFunc) (outShorts string, outArgs []string, err error) {
998 if strings.HasPrefix(shorthands, "test.") {
1002 outShorts = shorthands[1:]
1005 flag, exists := f.shorthands[c]
1012 case f.ParseErrorsWhitelist.UnknownFlags:
1014 // we do not want to lose arg in this case
1015 if len(shorthands) > 2 && shorthands[1] == '=' {
1020 outArgs = stripUnknownFlagValue(outArgs)
1023 err = f.failf("unknown shorthand flag: %q in -%s", c, shorthands)
1029 if len(shorthands) > 2 && shorthands[1] == '=' {
1031 value = shorthands[2:]
1033 } else if flag.NoOptDefVal != "" {
1034 // '-f' (arg was optional)
1035 value = flag.NoOptDefVal
1036 } else if len(shorthands) > 1 {
1038 value = shorthands[1:]
1040 } else if len(args) > 0 {
1045 // '-f' (arg was required)
1046 err = f.failf("flag needs an argument: %q in -%s", c, shorthands)
1050 if flag.ShorthandDeprecated != "" {
1051 fmt.Fprintf(f.out(), "Flag shorthand -%s has been deprecated, %s\n", flag.Shorthand, flag.ShorthandDeprecated)
1054 err = fn(flag, value)
1056 f.failf(err.Error())
1061 func (f *FlagSet) parseShortArg(s string, args []string, fn parseFunc) (a []string, err error) {
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)
1076 func (f *FlagSet) parseArgs(args []string, fn parseFunc) (err error) {
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...)
1086 f.args = append(f.args, s)
1091 if len(s) == 2 { // "--" terminates the flags
1092 f.argsLenAtDash = len(f.args)
1093 f.args = append(f.args, args...)
1096 args, err = f.parseLongArg(s, args, fn)
1098 args, err = f.parseShortArg(s, args, fn)
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.
1111 func (f *FlagSet) Parse(arguments []string) error {
1112 if f.addedGoFlagSets != nil {
1113 for _, goFlagSet := range f.addedGoFlagSets {
1114 goFlagSet.Parse(nil)
1119 if len(arguments) < 0 {
1123 f.args = make([]string, 0, len(arguments))
1125 set := func(flag *Flag, value string) error {
1126 return f.Set(flag.Name, value)
1129 err := f.parseArgs(arguments, set)
1131 switch f.errorHandling {
1132 case ContinueOnError:
1144 type parseFunc func(flag *Flag, value string) error
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
1151 func (f *FlagSet) ParseAll(arguments []string, fn func(flag *Flag, value string) error) error {
1153 f.args = make([]string, 0, len(arguments))
1155 err := f.parseArgs(arguments, fn)
1157 switch f.errorHandling {
1158 case ContinueOnError:
1169 // Parsed reports whether f.Parse has been called.
1170 func (f *FlagSet) Parsed() bool {
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.
1177 // Ignore errors; CommandLine is set for ExitOnError.
1178 CommandLine.Parse(os.Args[1:])
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.
1184 func ParseAll(fn func(flag *Flag, value string) error) {
1185 // Ignore errors; CommandLine is set for ExitOnError.
1186 CommandLine.ParseAll(os.Args[1:], fn)
1189 // SetInterspersed sets whether to support interspersed option/non-option arguments.
1190 func SetInterspersed(interspersed bool) {
1191 CommandLine.SetInterspersed(interspersed)
1194 // Parsed returns true if the command-line flags have been parsed.
1195 func Parsed() bool {
1196 return CommandLine.Parsed()
1199 // CommandLine is the default set of command-line flags, parsed from os.Args.
1200 var CommandLine = NewFlagSet(os.Args[0], ExitOnError)
1202 // NewFlagSet returns a new, empty flag set with the specified name,
1203 // error handling property and SortFlags set to true.
1204 func NewFlagSet(name string, errorHandling ErrorHandling) *FlagSet {
1207 errorHandling: errorHandling,
1215 // SetInterspersed sets whether to support interspersed option/non-option arguments.
1216 func (f *FlagSet) SetInterspersed(interspersed bool) {
1217 f.interspersed = interspersed
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.
1223 func (f *FlagSet) Init(name string, errorHandling ErrorHandling) {
1225 f.errorHandling = errorHandling
1226 f.argsLenAtDash = -1