...

Source file src/github.com/spf13/pflag/flag.go

Documentation: github.com/spf13/pflag

     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  /*
     6  Package pflag is a drop-in replacement for Go's flag package, implementing
     7  POSIX/GNU-style --flags.
     8  
     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
    12  
    13  Usage:
    14  
    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
    17  with no changes.
    18  
    19  	import flag "github.com/spf13/pflag"
    20  
    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
    25  unaffected.
    26  
    27  Define flags using flag.String(), Bool(), Int(), etc.
    28  
    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.
    32  	var flagvar int
    33  	func init() {
    34  		flag.IntVar(&flagvar, "flagname", 1234, "help message for flagname")
    35  	}
    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.
    40  
    41  After all flags are defined, call
    42  	flag.Parse()
    43  to parse the command line into the defined flags.
    44  
    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)
    49  
    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.
    53  
    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")
    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")
    63  Shorthand letters can be used with single dashes on the command line.
    64  Boolean shorthand flags can be combined with other shorthand flags.
    65  
    66  Command line flag syntax:
    67  	--flag    // boolean flags only
    68  	--flag=x
    69  
    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.
    73  	// boolean flags
    74  	-f
    75  	-abc
    76  	// non-boolean flags
    77  	-n 1234
    78  	-Ifile
    79  	// mixed
    80  	-abcs "hello"
    81  	-abcn1234
    82  
    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.
    86  
    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.
    91  
    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
    97  flag set.
    98  */
    99  package pflag
   100  
   101  import (
   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.
   113  var ErrHelp = errors.New("pflag: help requested")
   114  
   115  // ErrorHandling defines how to handle flag parsing errors.
   116  type ErrorHandling int
   117  
   118  const (
   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
   128  type 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).
   135  type NormalizedName string
   136  
   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.
   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.
   171  type 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.)
   187  type 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.
   196  type 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.
   206  func 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.
   226  func (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.
   246  func (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  
   253  func (f *FlagSet) normalizeFlagName(name string) NormalizedName {
   254  	n := f.GetNormalizeFunc()
   255  	return n(f, name)
   256  }
   257  
   258  func (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.
   267  func (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.
   274  func (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.
   295  func (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.
   301  func (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.
   313  func 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.
   320  func (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.
   343  func 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.
   348  func (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.
   355  func (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.
   369  func (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
   374  func (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.
   397  func (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.
   404  func (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.
   420  func (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.
   434  func (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.
   445  func 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.
   451  func ShorthandLookup(name string) *Flag {
   452  	return CommandLine.ShorthandLookup(name)
   453  }
   454  
   455  // Set sets the value of the named flag.
   456  func (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.
   493  func (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
   508  func (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.
   518  func 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.
   524  func (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.
   531  func (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.
   566  func 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).
   609  func 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
   628  func 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)
   677  func (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
   750  func (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.
   755  func PrintDefaults() {
   756  	CommandLine.PrintDefaults()
   757  }
   758  
   759  // defaultUsage is the default function to print a usage message.
   760  func 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.
   773  var 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.
   779  func (f *FlagSet) NFlag() int { return len(f.actual) }
   780  
   781  // NFlag returns the number of command-line flags that have been set.
   782  func 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.
   786  func (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.
   795  func Arg(i int) string {
   796  	return CommandLine.Arg(i)
   797  }
   798  
   799  // NArg is the number of arguments remaining after flags have been processed.
   800  func (f *FlagSet) NArg() int { return len(f.args) }
   801  
   802  // NArg is the number of arguments remaining after flags have been processed.
   803  func NArg() int { return len(CommandLine.args) }
   804  
   805  // Args returns the non-flag arguments.
   806  func (f *FlagSet) Args() []string { return f.args }
   807  
   808  // Args returns the non-flag command-line arguments.
   809  func 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.
   817  func (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
   822  func (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.
   836  func (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
   841  func (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.
   881  func (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.
   898  func 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.
   903  func 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.
   909  func (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.
   920  func (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 ...)
   933  func 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  
   952  func (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  
  1007  func (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  
  1073  func (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  
  1088  func (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.
  1123  func (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  
  1156  type 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.
  1163  func (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.
  1182  func (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.
  1188  func 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.
  1196  func 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.
  1202  func SetInterspersed(interspersed bool) {
  1203  	CommandLine.SetInterspersed(interspersed)
  1204  }
  1205  
  1206  // Parsed returns true if the command-line flags have been parsed.
  1207  func Parsed() bool {
  1208  	return CommandLine.Parsed()
  1209  }
  1210  
  1211  // CommandLine is the default set of command-line flags, parsed from os.Args.
  1212  var 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.
  1216  func 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.
  1228  func (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.
  1235  func (f *FlagSet) Init(name string, errorHandling ErrorHandling) {
  1236  	f.name = name
  1237  	f.errorHandling = errorHandling
  1238  	f.argsLenAtDash = -1
  1239  }
  1240  

View as plain text