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