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.
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(&flagvar, "boolname", "b", true, "help message")
61 }
62 flag.VarP(&flagval, "varname", "v", "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 Output() 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// SliceValue is a secondary interface to all flags which hold a list
194// of values. This allows full control over the value of list flags,
195// and avoids complicated marshalling and unmarshalling to csv.
196type SliceValue interface {
197 // Append adds the specified value to the end of the flag value list.
198 Append(string) error
199 // Replace will fully overwrite any data currently in the flag value list.
200 Replace([]string) error
201 // GetSlice returns the flag value list as an array of strings.
202 GetSlice() []string
203}
204
205// sortFlags returns the flags as a slice in lexicographical sorted order.
206func sortFlags(flags map[NormalizedName]*Flag) []*Flag {
207 list := make(sort.StringSlice, len(flags))
208 i := 0
209 for k := range flags {
210 list[i] = string(k)
211 i++
212 }
213 list.Sort()
214 result := make([]*Flag, len(list))
215 for i, name := range list {
216 result[i] = flags[NormalizedName(name)]
217 }
218 return result
219}
220
221// SetNormalizeFunc allows you to add a function which can translate flag names.
222// Flags added to the FlagSet will be translated and then when anything tries to
223// look up the flag that will also be translated. So it would be possible to create
224// a flag named "getURL" and have it translated to "geturl". A user could then pass
225// "--getUrl" which may also be translated to "geturl" and everything will work.
226func (f *FlagSet) SetNormalizeFunc(n func(f *FlagSet, name string) NormalizedName) {
227 f.normalizeNameFunc = n
228 f.sortedFormal = f.sortedFormal[:0]
229 for fname, flag := range f.formal {
230 nname := f.normalizeFlagName(flag.Name)
231 if fname == nname {
232 continue
233 }
234 flag.Name = string(nname)
235 delete(f.formal, fname)
236 f.formal[nname] = flag
237 if _, set := f.actual[fname]; set {
238 delete(f.actual, fname)
239 f.actual[nname] = flag
240 }
241 }
242}
243
244// GetNormalizeFunc returns the previously set NormalizeFunc of a function which
245// does no translation, if not set previously.
246func (f *FlagSet) GetNormalizeFunc() func(f *FlagSet, name string) NormalizedName {
247 if f.normalizeNameFunc != nil {
248 return f.normalizeNameFunc
249 }
250 return func(f *FlagSet, name string) NormalizedName { return NormalizedName(name) }
251}
252
253func (f *FlagSet) normalizeFlagName(name string) NormalizedName {
254 n := f.GetNormalizeFunc()
255 return n(f, name)
256}
257
258// Output returns the destination for usage and error messages. os.Stderr is returned if
259// output was not set or was set to nil.
260func (f *FlagSet) Output() io.Writer {
261 if f.output == nil {
262 return os.Stderr
263 }
264 return f.output
265}
266
267// Name returns the name of the flag set.
268func (f *FlagSet) Name() string {
269 return f.name
270}
271
272// SetOutput sets the destination for usage and error messages.
273// If output is nil, os.Stderr is used.
274func (f *FlagSet) SetOutput(output io.Writer) {
275 f.output = output
276}
277
278// VisitAll visits the flags in lexicographical order or
279// in primordial order if f.SortFlags is false, calling fn for each.
280// It visits all flags, even those not set.
281func (f *FlagSet) VisitAll(fn func(*Flag)) {
282 if len(f.formal) == 0 {
283 return
284 }
285
286 var flags []*Flag
287 if f.SortFlags {
288 if len(f.formal) != len(f.sortedFormal) {
289 f.sortedFormal = sortFlags(f.formal)
290 }
291 flags = f.sortedFormal
292 } else {
293 flags = f.orderedFormal
294 }
295
296 for _, flag := range flags {
297 fn(flag)
298 }
299}
300
301// HasFlags returns a bool to indicate if the FlagSet has any flags defined.
302func (f *FlagSet) HasFlags() bool {
303 return len(f.formal) > 0
304}
305
306// HasAvailableFlags returns a bool to indicate if the FlagSet has any flags
307// that are not hidden.
308func (f *FlagSet) HasAvailableFlags() bool {
309 for _, flag := range f.formal {
310 if !flag.Hidden {
311 return true
312 }
313 }
314 return false
315}
316
317// VisitAll visits the command-line flags in lexicographical order or
318// in primordial order if f.SortFlags is false, calling fn for each.
319// It visits all flags, even those not set.
320func VisitAll(fn func(*Flag)) {
321 CommandLine.VisitAll(fn)
322}
323
324// Visit visits the flags in lexicographical order or
325// in primordial order if f.SortFlags is false, calling fn for each.
326// It visits only those flags that have been set.
327func (f *FlagSet) Visit(fn func(*Flag)) {
328 if len(f.actual) == 0 {
329 return
330 }
331
332 var flags []*Flag
333 if f.SortFlags {
334 if len(f.actual) != len(f.sortedActual) {
335 f.sortedActual = sortFlags(f.actual)
336 }
337 flags = f.sortedActual
338 } else {
339 flags = f.orderedActual
340 }
341
342 for _, flag := range flags {
343 fn(flag)
344 }
345}
346
347// Visit visits the command-line flags in lexicographical order or
348// in primordial order if f.SortFlags is false, calling fn for each.
349// It visits only those flags that have been set.
350func Visit(fn func(*Flag)) {
351 CommandLine.Visit(fn)
352}
353
354// Lookup returns the Flag structure of the named flag, returning nil if none exists.
355func (f *FlagSet) Lookup(name string) *Flag {
356 return f.lookup(f.normalizeFlagName(name))
357}
358
359// ShorthandLookup returns the Flag structure of the short handed flag,
360// returning nil if none exists.
361// It panics, if len(name) > 1.
362func (f *FlagSet) ShorthandLookup(name string) *Flag {
363 if name == "" {
364 return nil
365 }
366 if len(name) > 1 {
367 msg := fmt.Sprintf("can not look up shorthand which is more than one ASCII character: %q", name)
368 fmt.Fprintf(f.Output(), msg)
369 panic(msg)
370 }
371 c := name[0]
372 return f.shorthands[c]
373}
374
375// lookup returns the Flag structure of the named flag, returning nil if none exists.
376func (f *FlagSet) lookup(name NormalizedName) *Flag {
377 return f.formal[name]
378}
379
380// func to return a given type for a given flag name
381func (f *FlagSet) getFlagType(name string, ftype string, convFunc func(sval string) (interface{}, error)) (interface{}, error) {
382 flag := f.Lookup(name)
383 if flag == nil {
384 err := fmt.Errorf("flag accessed but not defined: %s", name)
385 return nil, err
386 }
387
388 if flag.Value.Type() != ftype {
389 err := fmt.Errorf("trying to get %s value of flag of type %s", ftype, flag.Value.Type())
390 return nil, err
391 }
392
393 sval := flag.Value.String()
394 result, err := convFunc(sval)
395 if err != nil {
396 return nil, err
397 }
398 return result, nil
399}
400
401// ArgsLenAtDash will return the length of f.Args at the moment when a -- was
402// found during arg parsing. This allows your program to know which args were
403// before the -- and which came after.
404func (f *FlagSet) ArgsLenAtDash() int {
405 return f.argsLenAtDash
406}
407
408// MarkDeprecated indicated that a flag is deprecated in your program. It will
409// continue to function but will not show up in help or usage messages. Using
410// this flag will also print the given usageMessage.
411func (f *FlagSet) MarkDeprecated(name string, usageMessage string) error {
412 flag := f.Lookup(name)
413 if flag == nil {
414 return fmt.Errorf("flag %q does not exist", name)
415 }
416 if usageMessage == "" {
417 return fmt.Errorf("deprecated message for flag %q must be set", name)
418 }
419 flag.Deprecated = usageMessage
420 flag.Hidden = true
421 return nil
422}
423
424// MarkShorthandDeprecated will mark the shorthand of a flag deprecated in your
425// program. It will continue to function but will not show up in help or usage
426// messages. Using this flag will also print the given usageMessage.
427func (f *FlagSet) MarkShorthandDeprecated(name string, usageMessage string) error {
428 flag := f.Lookup(name)
429 if flag == nil {
430 return fmt.Errorf("flag %q does not exist", name)
431 }
432 if usageMessage == "" {
433 return fmt.Errorf("deprecated message for flag %q must be set", name)
434 }
435 flag.ShorthandDeprecated = usageMessage
436 return nil
437}
438
439// MarkHidden sets a flag to 'hidden' in your program. It will continue to
440// function but will not show up in help or usage messages.
441func (f *FlagSet) MarkHidden(name string) error {
442 flag := f.Lookup(name)
443 if flag == nil {
444 return fmt.Errorf("flag %q does not exist", name)
445 }
446 flag.Hidden = true
447 return nil
448}
449
450// Lookup returns the Flag structure of the named command-line flag,
451// returning nil if none exists.
452func Lookup(name string) *Flag {
453 return CommandLine.Lookup(name)
454}
455
456// ShorthandLookup returns the Flag structure of the short handed flag,
457// returning nil if none exists.
458func ShorthandLookup(name string) *Flag {
459 return CommandLine.ShorthandLookup(name)
460}
461
462// Set sets the value of the named flag.
463func (f *FlagSet) Set(name, value string) error {
464 normalName := f.normalizeFlagName(name)
465 flag, ok := f.formal[normalName]
466 if !ok {
467 return fmt.Errorf("no such flag -%v", name)
468 }
469
470 err := flag.Value.Set(value)
471 if err != nil {
472 var flagName string
473 if flag.Shorthand != "" && flag.ShorthandDeprecated == "" {
474 flagName = fmt.Sprintf("-%s, --%s", flag.Shorthand, flag.Name)
475 } else {
476 flagName = fmt.Sprintf("--%s", flag.Name)
477 }
478 return fmt.Errorf("invalid argument %q for %q flag: %v", value, flagName, err)
479 }
480
481 if !flag.Changed {
482 if f.actual == nil {
483 f.actual = make(map[NormalizedName]*Flag)
484 }
485 f.actual[normalName] = flag
486 f.orderedActual = append(f.orderedActual, flag)
487
488 flag.Changed = true
489 }
490
491 if flag.Deprecated != "" {
492 fmt.Fprintf(f.Output(), "Flag --%s has been deprecated, %s\n", flag.Name, flag.Deprecated)
493 }
494 return nil
495}
496
497// SetAnnotation allows one to set arbitrary annotations on a flag in the FlagSet.
498// This is sometimes used by spf13/cobra programs which want to generate additional
499// bash completion information.
500func (f *FlagSet) SetAnnotation(name, key string, values []string) error {
501 normalName := f.normalizeFlagName(name)
502 flag, ok := f.formal[normalName]
503 if !ok {
504 return fmt.Errorf("no such flag -%v", name)
505 }
506 if flag.Annotations == nil {
507 flag.Annotations = map[string][]string{}
508 }
509 flag.Annotations[key] = values
510 return nil
511}
512
513// Changed returns true if the flag was explicitly set during Parse() and false
514// otherwise
515func (f *FlagSet) Changed(name string) bool {
516 flag := f.Lookup(name)
517 // If a flag doesn't exist, it wasn't changed....
518 if flag == nil {
519 return false
520 }
521 return flag.Changed
522}
523
524// Set sets the value of the named command-line flag.
525func Set(name, value string) error {
526 return CommandLine.Set(name, value)
527}
528
529// PrintDefaults prints, to standard error unless configured
530// otherwise, the default values of all defined flags in the set.
531func (f *FlagSet) PrintDefaults() {
532 usages := f.FlagUsages()
533 fmt.Fprint(f.Output(), usages)
534}
535
536// defaultIsZeroValue returns true if the default value for this flag represents
537// a zero value.
538func (f *Flag) defaultIsZeroValue() bool {
539 switch f.Value.(type) {
540 case boolFlag:
541 return f.DefValue == "false"
542 case *durationValue:
543 // Beginning in Go 1.7, duration zero values are "0s"
544 return f.DefValue == "0" || f.DefValue == "0s"
545 case *intValue, *int8Value, *int32Value, *int64Value, *uintValue, *uint8Value, *uint16Value, *uint32Value, *uint64Value, *countValue, *float32Value, *float64Value:
546 return f.DefValue == "0"
547 case *stringValue:
548 return f.DefValue == ""
549 case *ipValue, *ipMaskValue, *ipNetValue:
550 return f.DefValue == "<nil>"
551 case *intSliceValue, *stringSliceValue, *stringArrayValue:
552 return f.DefValue == "[]"
553 default:
554 switch f.Value.String() {
555 case "false":
556 return true
557 case "<nil>":
558 return true
559 case "":
560 return true
561 case "0":
562 return true
563 }
564 return false
565 }
566}
567
568// UnquoteUsage extracts a back-quoted name from the usage
569// string for a flag and returns it and the un-quoted usage.
570// Given "a `name` to show" it returns ("name", "a name to show").
571// If there are no back quotes, the name is an educated guess of the
572// type of the flag's value, or the empty string if the flag is boolean.
573func UnquoteUsage(flag *Flag) (name string, usage string) {
574 // Look for a back-quoted name, but avoid the strings package.
575 usage = flag.Usage
576 for i := 0; i < len(usage); i++ {
577 if usage[i] == '`' {
578 for j := i + 1; j < len(usage); j++ {
579 if usage[j] == '`' {
580 name = usage[i+1 : j]
581 usage = usage[:i] + name + usage[j+1:]
582 return name, usage
583 }
584 }
585 break // Only one back quote; use type name.
586 }
587 }
588
589 name = flag.Value.Type()
590 switch name {
591 case "bool":
592 name = ""
593 case "float64":
594 name = "float"
595 case "int64":
596 name = "int"
597 case "uint64":
598 name = "uint"
599 case "stringSlice":
600 name = "strings"
601 case "intSlice":
602 name = "ints"
603 case "uintSlice":
604 name = "uints"
605 case "boolSlice":
606 name = "bools"
607 }
608
609 return
610}
611
612// Splits the string `s` on whitespace into an initial substring up to
613// `i` runes in length and the remainder. Will go `slop` over `i` if
614// that encompasses the entire string (which allows the caller to
615// avoid short orphan words on the final line).
616func wrapN(i, slop int, s string) (string, string) {
617 if i+slop > len(s) {
618 return s, ""
619 }
620
621 w := strings.LastIndexAny(s[:i], " \t\n")
622 if w <= 0 {
623 return s, ""
624 }
625 nlPos := strings.LastIndex(s[:i], "\n")
626 if nlPos > 0 && nlPos < w {
627 return s[:nlPos], s[nlPos+1:]
628 }
629 return s[:w], s[w+1:]
630}
631
632// Wraps the string `s` to a maximum width `w` with leading indent
633// `i`. The first line is not indented (this is assumed to be done by
634// caller). Pass `w` == 0 to do no wrapping
635func wrap(i, w int, s string) string {
636 if w == 0 {
637 return strings.Replace(s, "\n", "\n"+strings.Repeat(" ", i), -1)
638 }
639
640 // space between indent i and end of line width w into which
641 // we should wrap the text.
642 wrap := w - i
643
644 var r, l string
645
646 // Not enough space for sensible wrapping. Wrap as a block on
647 // the next line instead.
648 if wrap < 24 {
649 i = 16
650 wrap = w - i
651 r += "\n" + strings.Repeat(" ", i)
652 }
653 // If still not enough space then don't even try to wrap.
654 if wrap < 24 {
655 return strings.Replace(s, "\n", r, -1)
656 }
657
658 // Try to avoid short orphan words on the final line, by
659 // allowing wrapN to go a bit over if that would fit in the
660 // remainder of the line.
661 slop := 5
662 wrap = wrap - slop
663
664 // Handle first line, which is indented by the caller (or the
665 // special case above)
666 l, s = wrapN(wrap, slop, s)
667 r = r + strings.Replace(l, "\n", "\n"+strings.Repeat(" ", i), -1)
668
669 // Now wrap the rest
670 for s != "" {
671 var t string
672
673 t, s = wrapN(wrap, slop, s)
674 r = r + "\n" + strings.Repeat(" ", i) + strings.Replace(t, "\n", "\n"+strings.Repeat(" ", i), -1)
675 }
676
677 return r
678
679}
680
681// FlagUsagesWrapped returns a string containing the usage information
682// for all flags in the FlagSet. Wrapped to `cols` columns (0 for no
683// wrapping)
684func (f *FlagSet) FlagUsagesWrapped(cols int) string {
685 buf := new(bytes.Buffer)
686
687 lines := make([]string, 0, len(f.formal))
688
689 maxlen := 0
690 f.VisitAll(func(flag *Flag) {
691 if flag.Hidden {
692 return
693 }
694
695 line := ""
696 if flag.Shorthand != "" && flag.ShorthandDeprecated == "" {
697 line = fmt.Sprintf(" -%s, --%s", flag.Shorthand, flag.Name)
698 } else {
699 line = fmt.Sprintf(" --%s", flag.Name)
700 }
701
702 varname, usage := UnquoteUsage(flag)
703 if varname != "" {
704 line += " " + varname
705 }
706 if flag.NoOptDefVal != "" {
707 switch flag.Value.Type() {
708 case "string":
709 line += fmt.Sprintf("[=\"%s\"]", flag.NoOptDefVal)
710 case "bool":
711 if flag.NoOptDefVal != "true" {
712 line += fmt.Sprintf("[=%s]", flag.NoOptDefVal)
713 }
714 case "count":
715 if flag.NoOptDefVal != "+1" {
716 line += fmt.Sprintf("[=%s]", flag.NoOptDefVal)
717 }
718 default:
719 line += fmt.Sprintf("[=%s]", flag.NoOptDefVal)
720 }
721 }
722
723 // This special character will be replaced with spacing once the
724 // correct alignment is calculated
725 line += "\x00"
726 if len(line) > maxlen {
727 maxlen = len(line)
728 }
729
730 line += usage
731 if !flag.defaultIsZeroValue() {
732 if flag.Value.Type() == "string" {
733 line += fmt.Sprintf(" (default %q)", flag.DefValue)
734 } else {
735 line += fmt.Sprintf(" (default %s)", flag.DefValue)
736 }
737 }
738 if len(flag.Deprecated) != 0 {
739 line += fmt.Sprintf(" (DEPRECATED: %s)", flag.Deprecated)
740 }
741
742 lines = append(lines, line)
743 })
744
745 for _, line := range lines {
746 sidx := strings.Index(line, "\x00")
747 spacing := strings.Repeat(" ", maxlen-sidx)
748 // maxlen + 2 comes from + 1 for the \x00 and + 1 for the (deliberate) off-by-one in maxlen-sidx
749 fmt.Fprintln(buf, line[:sidx], spacing, wrap(maxlen+2, cols, line[sidx+1:]))
750 }
751
752 return buf.String()
753}
754
755// FlagUsages returns a string containing the usage information for all flags in
756// the FlagSet
757func (f *FlagSet) FlagUsages() string {
758 return f.FlagUsagesWrapped(0)
759}
760
761// PrintDefaults prints to standard error the default values of all defined command-line flags.
762func PrintDefaults() {
763 CommandLine.PrintDefaults()
764}
765
766// defaultUsage is the default function to print a usage message.
767func defaultUsage(f *FlagSet) {
768 fmt.Fprintf(f.Output(), "Usage of %s:\n", f.name)
769 f.PrintDefaults()
770}
771
772// NOTE: Usage is not just defaultUsage(CommandLine)
773// because it serves (via godoc flag Usage) as the example
774// for how to write your own usage function.
775
776// Usage prints to standard error a usage message documenting all defined command-line flags.
777// The function is a variable that may be changed to point to a custom function.
778// By default it prints a simple header and calls PrintDefaults; for details about the
779// format of the output and how to control it, see the documentation for PrintDefaults.
780var Usage = func() {
781 fmt.Fprintf(os.Stderr, "Usage of %s:\n", os.Args[0])
782 PrintDefaults()
783}
784
785// NFlag returns the number of flags that have been set.
786func (f *FlagSet) NFlag() int { return len(f.actual) }
787
788// NFlag returns the number of command-line flags that have been set.
789func NFlag() int { return len(CommandLine.actual) }
790
791// Arg returns the i'th argument. Arg(0) is the first remaining argument
792// after flags have been processed.
793func (f *FlagSet) Arg(i int) string {
794 if i < 0 || i >= len(f.args) {
795 return ""
796 }
797 return f.args[i]
798}
799
800// Arg returns the i'th command-line argument. Arg(0) is the first remaining argument
801// after flags have been processed.
802func Arg(i int) string {
803 return CommandLine.Arg(i)
804}
805
806// NArg is the number of arguments remaining after flags have been processed.
807func (f *FlagSet) NArg() int { return len(f.args) }
808
809// NArg is the number of arguments remaining after flags have been processed.
810func NArg() int { return len(CommandLine.args) }
811
812// Args returns the non-flag arguments.
813func (f *FlagSet) Args() []string { return f.args }
814
815// Args returns the non-flag command-line arguments.
816func Args() []string { return CommandLine.args }
817
818// Var defines a flag with the specified name and usage string. The type and
819// value of the flag are represented by the first argument, of type Value, which
820// typically holds a user-defined implementation of Value. For instance, the
821// caller could create a flag that turns a comma-separated string into a slice
822// of strings by giving the slice the methods of Value; in particular, Set would
823// decompose the comma-separated string into the slice.
824func (f *FlagSet) Var(value Value, name string, usage string) {
825 f.VarP(value, name, "", usage)
826}
827
828// VarPF is like VarP, but returns the flag created
829func (f *FlagSet) VarPF(value Value, name, shorthand, usage string) *Flag {
830 // Remember the default value as a string; it won't change.
831 flag := &Flag{
832 Name: name,
833 Shorthand: shorthand,
834 Usage: usage,
835 Value: value,
836 DefValue: value.String(),
837 }
838 f.AddFlag(flag)
839 return flag
840}
841
842// VarP is like Var, but accepts a shorthand letter that can be used after a single dash.
843func (f *FlagSet) VarP(value Value, name, shorthand, usage string) {
844 f.VarPF(value, name, shorthand, usage)
845}
846
847// AddFlag will add the flag to the FlagSet
848func (f *FlagSet) AddFlag(flag *Flag) {
849 normalizedFlagName := f.normalizeFlagName(flag.Name)
850
851 _, alreadyThere := f.formal[normalizedFlagName]
852 if alreadyThere {
853 msg := fmt.Sprintf("%s flag redefined: %s", f.name, flag.Name)
854 fmt.Fprintln(f.Output(), msg)
855 panic(msg) // Happens only if flags are declared with identical names
856 }
857 if f.formal == nil {
858 f.formal = make(map[NormalizedName]*Flag)
859 }
860
861 flag.Name = string(normalizedFlagName)
862 f.formal[normalizedFlagName] = flag
863 f.orderedFormal = append(f.orderedFormal, flag)
864
865 if flag.Shorthand == "" {
866 return
867 }
868 if len(flag.Shorthand) > 1 {
869 msg := fmt.Sprintf("%q shorthand is more than one ASCII character", flag.Shorthand)
870 fmt.Fprintf(f.Output(), msg)
871 panic(msg)
872 }
873 if f.shorthands == nil {
874 f.shorthands = make(map[byte]*Flag)
875 }
876 c := flag.Shorthand[0]
877 used, alreadyThere := f.shorthands[c]
878 if alreadyThere {
879 msg := fmt.Sprintf("unable to redefine %q shorthand in %q flagset: it's already used for %q flag", c, f.name, used.Name)
880 fmt.Fprintf(f.Output(), msg)
881 panic(msg)
882 }
883 f.shorthands[c] = flag
884}
885
886// AddFlagSet adds one FlagSet to another. If a flag is already present in f
887// the flag from newSet will be ignored.
888func (f *FlagSet) AddFlagSet(newSet *FlagSet) {
889 if newSet == nil {
890 return
891 }
892 newSet.VisitAll(func(flag *Flag) {
893 if f.Lookup(flag.Name) == nil {
894 f.AddFlag(flag)
895 }
896 })
897}
898
899// Var defines a flag with the specified name and usage string. The type and
900// value of the flag are represented by the first argument, of type Value, which
901// typically holds a user-defined implementation of Value. For instance, the
902// caller could create a flag that turns a comma-separated string into a slice
903// of strings by giving the slice the methods of Value; in particular, Set would
904// decompose the comma-separated string into the slice.
905func Var(value Value, name string, usage string) {
906 CommandLine.VarP(value, name, "", usage)
907}
908
909// VarP is like Var, but accepts a shorthand letter that can be used after a single dash.
910func VarP(value Value, name, shorthand, usage string) {
911 CommandLine.VarP(value, name, shorthand, usage)
912}
913
914// failf prints to standard error a formatted error and usage message and
915// returns the error.
916func (f *FlagSet) failf(format string, a ...interface{}) error {
917 err := fmt.Errorf(format, a...)
918 if f.errorHandling != ContinueOnError {
919 fmt.Fprintln(f.Output(), err)
920 f.usage()
921 }
922 return err
923}
924
925// usage calls the Usage method for the flag set, or the usage function if
926// the flag set is CommandLine.
927func (f *FlagSet) usage() {
928 if f == CommandLine {
929 Usage()
930 } else if f.Usage == nil {
931 defaultUsage(f)
932 } else {
933 f.Usage()
934 }
935}
936
937//--unknown (args will be empty)
938//--unknown --next-flag ... (args will be --next-flag ...)
939//--unknown arg ... (args will be arg ...)
940func stripUnknownFlagValue(args []string) []string {
941 if len(args) == 0 {
942 //--unknown
943 return args
944 }
945
946 first := args[0]
947 if len(first) > 0 && first[0] == '-' {
948 //--unknown --next-flag ...
949 return args
950 }
951
952 //--unknown arg ... (args will be arg ...)
953 if len(args) > 1 {
954 return args[1:]
955 }
956 return nil
957}
958
959func (f *FlagSet) parseLongArg(s string, args []string, fn parseFunc) (a []string, err error) {
960 a = args
961 name := s[2:]
962 if len(name) == 0 || name[0] == '-' || name[0] == '=' {
963 err = f.failf("bad flag syntax: %s", s)
964 return
965 }
966
967 split := strings.SplitN(name, "=", 2)
968 name = split[0]
969 flag, exists := f.formal[f.normalizeFlagName(name)]
970
971 if !exists {
972 switch {
973 case name == "help":
974 f.usage()
975 return a, ErrHelp
976 case f.ParseErrorsWhitelist.UnknownFlags:
977 // --unknown=unknownval arg ...
978 // we do not want to lose arg in this case
979 if len(split) >= 2 {
980 return a, nil
981 }
982
983 return stripUnknownFlagValue(a), nil
984 default:
985 err = f.failf("unknown flag: --%s", name)
986 return
987 }
988 }
989
990 var value string
991 if len(split) == 2 {
992 // '--flag=arg'
993 value = split[1]
994 } else if flag.NoOptDefVal != "" {
995 // '--flag' (arg was optional)
996 value = flag.NoOptDefVal
997 } else if len(a) > 0 {
998 // '--flag arg'
999 value = a[0]
1000 a = a[1:]
1001 } else {
1002 // '--flag' (arg was required)
1003 err = f.failf("flag needs an argument: %s", s)
1004 return
1005 }
1006
1007 err = fn(flag, value)
1008 if err != nil {
1009 f.failf(err.Error())
1010 }
1011 return
1012}
1013
1014func (f *FlagSet) parseSingleShortArg(shorthands string, args []string, fn parseFunc) (outShorts string, outArgs []string, err error) {
1015 outArgs = args
1016
1017 if strings.HasPrefix(shorthands, "test.") {
1018 return
1019 }
1020
1021 outShorts = shorthands[1:]
1022 c := shorthands[0]
1023
1024 flag, exists := f.shorthands[c]
1025 if !exists {
1026 switch {
1027 case c == 'h':
1028 f.usage()
1029 err = ErrHelp
1030 return
1031 case f.ParseErrorsWhitelist.UnknownFlags:
1032 // '-f=arg arg ...'
1033 // we do not want to lose arg in this case
1034 if len(shorthands) > 2 && shorthands[1] == '=' {
1035 outShorts = ""
1036 return
1037 }
1038
1039 outArgs = stripUnknownFlagValue(outArgs)
1040 return
1041 default:
1042 err = f.failf("unknown shorthand flag: %q in -%s", c, shorthands)
1043 return
1044 }
1045 }
1046
1047 var value string
1048 if len(shorthands) > 2 && shorthands[1] == '=' {
1049 // '-f=arg'
1050 value = shorthands[2:]
1051 outShorts = ""
1052 } else if flag.NoOptDefVal != "" {
1053 // '-f' (arg was optional)
1054 value = flag.NoOptDefVal
1055 } else if len(shorthands) > 1 {
1056 // '-farg'
1057 value = shorthands[1:]
1058 outShorts = ""
1059 } else if len(args) > 0 {
1060 // '-f arg'
1061 value = args[0]
1062 outArgs = args[1:]
1063 } else {
1064 // '-f' (arg was required)
1065 err = f.failf("flag needs an argument: %q in -%s", c, shorthands)
1066 return
1067 }
1068
1069 if flag.ShorthandDeprecated != "" {
1070 fmt.Fprintf(f.Output(), "Flag shorthand -%s has been deprecated, %s\n", flag.Shorthand, flag.ShorthandDeprecated)
1071 }
1072
1073 err = fn(flag, value)
1074 if err != nil {
1075 f.failf(err.Error())
1076 }
1077 return
1078}
1079
1080func (f *FlagSet) parseShortArg(s string, args []string, fn parseFunc) (a []string, err error) {
1081 a = args
1082 shorthands := s[1:]
1083
1084 // "shorthands" can be a series of shorthand letters of flags (e.g. "-vvv").
1085 for len(shorthands) > 0 {
1086 shorthands, a, err = f.parseSingleShortArg(shorthands, args, fn)
1087 if err != nil {
1088 return
1089 }
1090 }
1091
1092 return
1093}
1094
1095func (f *FlagSet) parseArgs(args []string, fn parseFunc) (err error) {
1096 for len(args) > 0 {
1097 s := args[0]
1098 args = args[1:]
1099 if len(s) == 0 || s[0] != '-' || len(s) == 1 {
1100 if !f.interspersed {
1101 f.args = append(f.args, s)
1102 f.args = append(f.args, args...)
1103 return nil
1104 }
1105 f.args = append(f.args, s)
1106 continue
1107 }
1108
1109 if s[1] == '-' {
1110 if len(s) == 2 { // "--" terminates the flags
1111 f.argsLenAtDash = len(f.args)
1112 f.args = append(f.args, args...)
1113 break
1114 }
1115 args, err = f.parseLongArg(s, args, fn)
1116 } else {
1117 args, err = f.parseShortArg(s, args, fn)
1118 }
1119 if err != nil {
1120 return
1121 }
1122 }
1123 return
1124}
1125
1126// Parse parses flag definitions from the argument list, which should not
1127// include the command name. Must be called after all flags in the FlagSet
1128// are defined and before flags are accessed by the program.
1129// The return value will be ErrHelp if -help was set but not defined.
1130func (f *FlagSet) Parse(arguments []string) error {
1131 if f.addedGoFlagSets != nil {
1132 for _, goFlagSet := range f.addedGoFlagSets {
1133 goFlagSet.Parse(nil)
1134 }
1135 }
1136 f.parsed = true
1137
1138 if len(arguments) < 0 {
1139 return nil
1140 }
1141
1142 f.args = make([]string, 0, len(arguments))
1143
1144 set := func(flag *Flag, value string) error {
1145 return f.Set(flag.Name, value)
1146 }
1147
1148 err := f.parseArgs(arguments, set)
1149 if err != nil {
1150 switch f.errorHandling {
1151 case ContinueOnError:
1152 return err
1153 case ExitOnError:
1154 fmt.Println(err)
1155 os.Exit(2)
1156 case PanicOnError:
1157 panic(err)
1158 }
1159 }
1160 return nil
1161}
1162
1163type parseFunc func(flag *Flag, value string) error
1164
1165// ParseAll parses flag definitions from the argument list, which should not
1166// include the command name. The arguments for fn are flag and value. Must be
1167// called after all flags in the FlagSet are defined and before flags are
1168// accessed by the program. The return value will be ErrHelp if -help was set
1169// but not defined.
1170func (f *FlagSet) ParseAll(arguments []string, fn func(flag *Flag, value string) error) error {
1171 f.parsed = true
1172 f.args = make([]string, 0, len(arguments))
1173
1174 err := f.parseArgs(arguments, fn)
1175 if err != nil {
1176 switch f.errorHandling {
1177 case ContinueOnError:
1178 return err
1179 case ExitOnError:
1180 os.Exit(2)
1181 case PanicOnError:
1182 panic(err)
1183 }
1184 }
1185 return nil
1186}
1187
1188// Parsed reports whether f.Parse has been called.
1189func (f *FlagSet) Parsed() bool {
1190 return f.parsed
1191}
1192
1193// Parse parses the command-line flags from os.Args[1:]. Must be called
1194// after all flags are defined and before flags are accessed by the program.
1195func Parse() {
1196 // Ignore errors; CommandLine is set for ExitOnError.
1197 CommandLine.Parse(os.Args[1:])
1198}
1199
1200// ParseAll parses the command-line flags from os.Args[1:] and called fn for each.
1201// The arguments for fn are flag and value. Must be called after all flags are
1202// defined and before flags are accessed by the program.
1203func ParseAll(fn func(flag *Flag, value string) error) {
1204 // Ignore errors; CommandLine is set for ExitOnError.
1205 CommandLine.ParseAll(os.Args[1:], fn)
1206}
1207
1208// SetInterspersed sets whether to support interspersed option/non-option arguments.
1209func SetInterspersed(interspersed bool) {
1210 CommandLine.SetInterspersed(interspersed)
1211}
1212
1213// Parsed returns true if the command-line flags have been parsed.
1214func Parsed() bool {
1215 return CommandLine.Parsed()
1216}
1217
1218// CommandLine is the default set of command-line flags, parsed from os.Args.
1219var CommandLine = NewFlagSet(os.Args[0], ExitOnError)
1220
1221// NewFlagSet returns a new, empty flag set with the specified name,
1222// error handling property and SortFlags set to true.
1223func NewFlagSet(name string, errorHandling ErrorHandling) *FlagSet {
1224 f := &FlagSet{
1225 name: name,
1226 errorHandling: errorHandling,
1227 argsLenAtDash: -1,
1228 interspersed: true,
1229 SortFlags: true,
1230 }
1231 return f
1232}
1233
1234// SetInterspersed sets whether to support interspersed option/non-option arguments.
1235func (f *FlagSet) SetInterspersed(interspersed bool) {
1236 f.interspersed = interspersed
1237}
1238
1239// Init sets the name and error handling property for a flag set.
1240// By default, the zero FlagSet uses an empty name and the
1241// ContinueOnError error handling policy.
1242func (f *FlagSet) Init(name string, errorHandling ErrorHandling) {
1243 f.name = name
1244 f.errorHandling = errorHandling
1245 f.argsLenAtDash = -1
1246}