aboutsummaryrefslogtreecommitdiff
path: root/vendor/github.com/spf13/pflag/flag.go
diff options
context:
space:
mode:
Diffstat (limited to 'vendor/github.com/spf13/pflag/flag.go')
-rw-r--r--vendor/github.com/spf13/pflag/flag.go230
1 files changed, 144 insertions, 86 deletions
diff --git a/vendor/github.com/spf13/pflag/flag.go b/vendor/github.com/spf13/pflag/flag.go
index 3a2e255..187e4c9 100644
--- a/vendor/github.com/spf13/pflag/flag.go
+++ b/vendor/github.com/spf13/pflag/flag.go
@@ -16,9 +16,9 @@ pflag is a drop-in replacement of Go's native flag package. If you import
pflag under the name "flag" then all code should continue to function
with no changes.
- import flag "github.com/ogier/pflag"
+ import flag "github.com/spf13/pflag"
- There is one exception to this: if you directly instantiate the Flag struct
+There is one exception to this: if you directly instantiate the Flag struct
there is one more field "Shorthand" that you will need to set.
Most code never instantiates this struct directly, and instead uses
functions such as String(), BoolVar(), and Var(), and is therefore
@@ -142,12 +142,13 @@ type FlagSet struct {
parsed bool
actual map[NormalizedName]*Flag
orderedActual []*Flag
+ sortedActual []*Flag
formal map[NormalizedName]*Flag
orderedFormal []*Flag
+ sortedFormal []*Flag
shorthands map[byte]*Flag
args []string // arguments after flags
argsLenAtDash int // len(args) when a '--' was located when parsing, or -1 if no --
- exitOnError bool // does the program exit if there's an error?
errorHandling ErrorHandling
output io.Writer // nil means stderr; use out() accessor
interspersed bool // allow interspersed option/non-option args
@@ -200,12 +201,19 @@ func sortFlags(flags map[NormalizedName]*Flag) []*Flag {
// "--getUrl" which may also be translated to "geturl" and everything will work.
func (f *FlagSet) SetNormalizeFunc(n func(f *FlagSet, name string) NormalizedName) {
f.normalizeNameFunc = n
- for k, v := range f.orderedFormal {
- delete(f.formal, NormalizedName(v.Name))
- nname := f.normalizeFlagName(v.Name)
- v.Name = string(nname)
- f.formal[nname] = v
- f.orderedFormal[k] = v
+ f.sortedFormal = f.sortedFormal[:0]
+ for fname, flag := range f.formal {
+ nname := f.normalizeFlagName(flag.Name)
+ if fname == nname {
+ continue
+ }
+ flag.Name = string(nname)
+ delete(f.formal, fname)
+ f.formal[nname] = flag
+ if _, set := f.actual[fname]; set {
+ delete(f.actual, fname)
+ f.actual[nname] = flag
+ }
}
}
@@ -240,9 +248,16 @@ func (f *FlagSet) SetOutput(output io.Writer) {
// in primordial order if f.SortFlags is false, calling fn for each.
// It visits all flags, even those not set.
func (f *FlagSet) VisitAll(fn func(*Flag)) {
+ if len(f.formal) == 0 {
+ return
+ }
+
var flags []*Flag
if f.SortFlags {
- flags = sortFlags(f.formal)
+ if len(f.formal) != len(f.sortedFormal) {
+ f.sortedFormal = sortFlags(f.formal)
+ }
+ flags = f.sortedFormal
} else {
flags = f.orderedFormal
}
@@ -279,9 +294,16 @@ func VisitAll(fn func(*Flag)) {
// in primordial order if f.SortFlags is false, calling fn for each.
// It visits only those flags that have been set.
func (f *FlagSet) Visit(fn func(*Flag)) {
+ if len(f.actual) == 0 {
+ return
+ }
+
var flags []*Flag
if f.SortFlags {
- flags = sortFlags(f.actual)
+ if len(f.actual) != len(f.sortedActual) {
+ f.sortedActual = sortFlags(f.actual)
+ }
+ flags = f.sortedActual
} else {
flags = f.orderedActual
}
@@ -303,6 +325,22 @@ func (f *FlagSet) Lookup(name string) *Flag {
return f.lookup(f.normalizeFlagName(name))
}
+// ShorthandLookup returns the Flag structure of the short handed flag,
+// returning nil if none exists.
+// It panics, if len(name) > 1.
+func (f *FlagSet) ShorthandLookup(name string) *Flag {
+ if name == "" {
+ return nil
+ }
+ if len(name) > 1 {
+ msg := fmt.Sprintf("can not look up shorthand which is more than one ASCII character: %q", name)
+ fmt.Fprintf(f.out(), msg)
+ panic(msg)
+ }
+ c := name[0]
+ return f.shorthands[c]
+}
+
// lookup returns the Flag structure of the named flag, returning nil if none exists.
func (f *FlagSet) lookup(name NormalizedName) *Flag {
return f.formal[name]
@@ -344,7 +382,7 @@ func (f *FlagSet) MarkDeprecated(name string, usageMessage string) error {
if flag == nil {
return fmt.Errorf("flag %q does not exist", name)
}
- if len(usageMessage) == 0 {
+ if usageMessage == "" {
return fmt.Errorf("deprecated message for flag %q must be set", name)
}
flag.Deprecated = usageMessage
@@ -359,7 +397,7 @@ func (f *FlagSet) MarkShorthandDeprecated(name string, usageMessage string) erro
if flag == nil {
return fmt.Errorf("flag %q does not exist", name)
}
- if len(usageMessage) == 0 {
+ if usageMessage == "" {
return fmt.Errorf("deprecated message for flag %q must be set", name)
}
flag.ShorthandDeprecated = usageMessage
@@ -383,6 +421,12 @@ func Lookup(name string) *Flag {
return CommandLine.Lookup(name)
}
+// ShorthandLookup returns the Flag structure of the short handed flag,
+// returning nil if none exists.
+func ShorthandLookup(name string) *Flag {
+ return CommandLine.ShorthandLookup(name)
+}
+
// Set sets the value of the named flag.
func (f *FlagSet) Set(name, value string) error {
normalName := f.normalizeFlagName(name)
@@ -390,18 +434,30 @@ func (f *FlagSet) Set(name, value string) error {
if !ok {
return fmt.Errorf("no such flag -%v", name)
}
+
err := flag.Value.Set(value)
if err != nil {
- return err
+ var flagName string
+ if flag.Shorthand != "" && flag.ShorthandDeprecated == "" {
+ flagName = fmt.Sprintf("-%s, --%s", flag.Shorthand, flag.Name)
+ } else {
+ flagName = fmt.Sprintf("--%s", flag.Name)
+ }
+ return fmt.Errorf("invalid argument %q for %q flag: %v", value, flagName, err)
}
- if f.actual == nil {
- f.actual = make(map[NormalizedName]*Flag)
+
+ if !flag.Changed {
+ if f.actual == nil {
+ f.actual = make(map[NormalizedName]*Flag)
+ }
+ f.actual[normalName] = flag
+ f.orderedActual = append(f.orderedActual, flag)
+
+ flag.Changed = true
}
- f.actual[normalName] = flag
- f.orderedActual = append(f.orderedActual, flag)
- flag.Changed = true
- if len(flag.Deprecated) > 0 {
- fmt.Fprintf(os.Stderr, "Flag --%s has been deprecated, %s\n", flag.Name, flag.Deprecated)
+
+ if flag.Deprecated != "" {
+ fmt.Fprintf(f.out(), "Flag --%s has been deprecated, %s\n", flag.Name, flag.Deprecated)
}
return nil
}
@@ -508,6 +564,10 @@ func UnquoteUsage(flag *Flag) (name string, usage string) {
name = "int"
case "uint64":
name = "uint"
+ case "stringSlice":
+ name = "strings"
+ case "intSlice":
+ name = "ints"
}
return
@@ -583,28 +643,28 @@ func wrap(i, w int, s string) string {
// for all flags in the FlagSet. Wrapped to `cols` columns (0 for no
// wrapping)
func (f *FlagSet) FlagUsagesWrapped(cols int) string {
- x := new(bytes.Buffer)
+ buf := new(bytes.Buffer)
lines := make([]string, 0, len(f.formal))
maxlen := 0
f.VisitAll(func(flag *Flag) {
- if len(flag.Deprecated) > 0 || flag.Hidden {
+ if flag.Deprecated != "" || flag.Hidden {
return
}
line := ""
- if len(flag.Shorthand) > 0 && len(flag.ShorthandDeprecated) == 0 {
+ if flag.Shorthand != "" && flag.ShorthandDeprecated == "" {
line = fmt.Sprintf(" -%s, --%s", flag.Shorthand, flag.Name)
} else {
line = fmt.Sprintf(" --%s", flag.Name)
}
varname, usage := UnquoteUsage(flag)
- if len(varname) > 0 {
+ if varname != "" {
line += " " + varname
}
- if len(flag.NoOptDefVal) > 0 {
+ if flag.NoOptDefVal != "" {
switch flag.Value.Type() {
case "string":
line += fmt.Sprintf("[=\"%s\"]", flag.NoOptDefVal)
@@ -612,6 +672,10 @@ func (f *FlagSet) FlagUsagesWrapped(cols int) string {
if flag.NoOptDefVal != "true" {
line += fmt.Sprintf("[=%s]", flag.NoOptDefVal)
}
+ case "count":
+ if flag.NoOptDefVal != "+1" {
+ line += fmt.Sprintf("[=%s]", flag.NoOptDefVal)
+ }
default:
line += fmt.Sprintf("[=%s]", flag.NoOptDefVal)
}
@@ -640,10 +704,10 @@ func (f *FlagSet) FlagUsagesWrapped(cols int) string {
sidx := strings.Index(line, "\x00")
spacing := strings.Repeat(" ", maxlen-sidx)
// maxlen + 2 comes from + 1 for the \x00 and + 1 for the (deliberate) off-by-one in maxlen-sidx
- fmt.Fprintln(x, line[:sidx], spacing, wrap(maxlen+2, cols, line[sidx+1:]))
+ fmt.Fprintln(buf, line[:sidx], spacing, wrap(maxlen+2, cols, line[sidx+1:]))
}
- return x.String()
+ return buf.String()
}
// FlagUsages returns a string containing the usage information for all flags in
@@ -740,11 +804,10 @@ func (f *FlagSet) VarP(value Value, name, shorthand, usage string) {
// AddFlag will add the flag to the FlagSet
func (f *FlagSet) AddFlag(flag *Flag) {
- // Call normalizeFlagName function only once
normalizedFlagName := f.normalizeFlagName(flag.Name)
- _, alreadythere := f.formal[normalizedFlagName]
- if alreadythere {
+ _, alreadyThere := f.formal[normalizedFlagName]
+ if alreadyThere {
msg := fmt.Sprintf("%s flag redefined: %s", f.name, flag.Name)
fmt.Fprintln(f.out(), msg)
panic(msg) // Happens only if flags are declared with identical names
@@ -757,27 +820,29 @@ func (f *FlagSet) AddFlag(flag *Flag) {
f.formal[normalizedFlagName] = flag
f.orderedFormal = append(f.orderedFormal, flag)
- if len(flag.Shorthand) == 0 {
+ if flag.Shorthand == "" {
return
}
if len(flag.Shorthand) > 1 {
- fmt.Fprintf(f.out(), "%s shorthand more than ASCII character: %s\n", f.name, flag.Shorthand)
- panic("shorthand is more than one character")
+ msg := fmt.Sprintf("%q shorthand is more than one ASCII character", flag.Shorthand)
+ fmt.Fprintf(f.out(), msg)
+ panic(msg)
}
if f.shorthands == nil {
f.shorthands = make(map[byte]*Flag)
}
c := flag.Shorthand[0]
- old, alreadythere := f.shorthands[c]
- if alreadythere {
- fmt.Fprintf(f.out(), "%s shorthand reused: %q for %s already used for %s\n", f.name, c, flag.Name, old.Name)
- panic("shorthand redefinition")
+ used, alreadyThere := f.shorthands[c]
+ if alreadyThere {
+ msg := fmt.Sprintf("unable to redefine %q shorthand in %q flagset: it's already used for %q flag", c, f.name, used.Name)
+ fmt.Fprintf(f.out(), msg)
+ panic(msg)
}
f.shorthands[c] = flag
}
// AddFlagSet adds one FlagSet to another. If a flag is already present in f
-// the flag from newSet will be ignored
+// the flag from newSet will be ignored.
func (f *FlagSet) AddFlagSet(newSet *FlagSet) {
if newSet == nil {
return
@@ -825,35 +890,6 @@ func (f *FlagSet) usage() {
}
}
-func (f *FlagSet) setFlag(flag *Flag, value string, origArg string) error {
- if err := flag.Value.Set(value); err != nil {
- return f.failf("invalid argument %q for %s: %v", value, origArg, err)
- }
- // mark as visited for Visit()
- if f.actual == nil {
- f.actual = make(map[NormalizedName]*Flag)
- }
- f.actual[f.normalizeFlagName(flag.Name)] = flag
- f.orderedActual = append(f.orderedActual, flag)
- flag.Changed = true
- if len(flag.Deprecated) > 0 {
- fmt.Fprintf(os.Stderr, "Flag --%s has been deprecated, %s\n", flag.Name, flag.Deprecated)
- }
- if len(flag.ShorthandDeprecated) > 0 && containsShorthand(origArg, flag.Shorthand) {
- fmt.Fprintf(os.Stderr, "Flag shorthand -%s has been deprecated, %s\n", flag.Shorthand, flag.ShorthandDeprecated)
- }
- return nil
-}
-
-func containsShorthand(arg, shorthand string) bool {
- // filter out flags --<flag_name>
- if strings.HasPrefix(arg, "-") {
- return false
- }
- arg = strings.SplitN(arg, "=", 2)[0]
- return strings.Contains(arg, shorthand)
-}
-
func (f *FlagSet) parseLongArg(s string, args []string, fn parseFunc) (a []string, err error) {
a = args
name := s[2:]
@@ -861,10 +897,11 @@ func (f *FlagSet) parseLongArg(s string, args []string, fn parseFunc) (a []strin
err = f.failf("bad flag syntax: %s", s)
return
}
+
split := strings.SplitN(name, "=", 2)
name = split[0]
- flag, alreadythere := f.formal[f.normalizeFlagName(name)]
- if !alreadythere {
+ flag, exists := f.formal[f.normalizeFlagName(name)]
+ if !exists {
if name == "help" { // special case for nice help message.
f.usage()
return a, ErrHelp
@@ -872,11 +909,12 @@ func (f *FlagSet) parseLongArg(s string, args []string, fn parseFunc) (a []strin
err = f.failf("unknown flag: --%s", name)
return
}
+
var value string
if len(split) == 2 {
// '--flag=arg'
value = split[1]
- } else if len(flag.NoOptDefVal) > 0 {
+ } else if flag.NoOptDefVal != "" {
// '--flag' (arg was optional)
value = flag.NoOptDefVal
} else if len(a) > 0 {
@@ -888,7 +926,11 @@ func (f *FlagSet) parseLongArg(s string, args []string, fn parseFunc) (a []strin
err = f.failf("flag needs an argument: %s", s)
return
}
- err = fn(flag, value, s)
+
+ err = fn(flag, value)
+ if err != nil {
+ f.failf(err.Error())
+ }
return
}
@@ -896,38 +938,52 @@ func (f *FlagSet) parseSingleShortArg(shorthands string, args []string, fn parse
if strings.HasPrefix(shorthands, "test.") {
return
}
+
outArgs = args
outShorts = shorthands[1:]
c := shorthands[0]
- flag, alreadythere := f.shorthands[c]
- if !alreadythere {
+ flag, exists := f.shorthands[c]
+ if !exists {
if c == 'h' { // special case for nice help message.
f.usage()
err = ErrHelp
return
}
- //TODO continue on error
err = f.failf("unknown shorthand flag: %q in -%s", c, shorthands)
return
}
+
var value string
if len(shorthands) > 2 && shorthands[1] == '=' {
+ // '-f=arg'
value = shorthands[2:]
outShorts = ""
- } else if len(flag.NoOptDefVal) > 0 {
+ } else if flag.NoOptDefVal != "" {
+ // '-f' (arg was optional)
value = flag.NoOptDefVal
} else if len(shorthands) > 1 {
+ // '-farg'
value = shorthands[1:]
outShorts = ""
} else if len(args) > 0 {
+ // '-f arg'
value = args[0]
outArgs = args[1:]
} else {
+ // '-f' (arg was required)
err = f.failf("flag needs an argument: %q in -%s", c, shorthands)
return
}
- err = fn(flag, value, shorthands)
+
+ if flag.ShorthandDeprecated != "" {
+ fmt.Fprintf(f.out(), "Flag shorthand -%s has been deprecated, %s\n", flag.Shorthand, flag.ShorthandDeprecated)
+ }
+
+ err = fn(flag, value)
+ if err != nil {
+ f.failf(err.Error())
+ }
return
}
@@ -935,6 +991,7 @@ func (f *FlagSet) parseShortArg(s string, args []string, fn parseFunc) (a []stri
a = args
shorthands := s[1:]
+ // "shorthands" can be a series of shorthand letters of flags (e.g. "-vvv").
for len(shorthands) > 0 {
shorthands, a, err = f.parseSingleShortArg(shorthands, args, fn)
if err != nil {
@@ -982,13 +1039,18 @@ func (f *FlagSet) parseArgs(args []string, fn parseFunc) (err error) {
// The return value will be ErrHelp if -help was set but not defined.
func (f *FlagSet) Parse(arguments []string) error {
f.parsed = true
+
+ if len(arguments) < 0 {
+ return nil
+ }
+
f.args = make([]string, 0, len(arguments))
- assign := func(flag *Flag, value, origArg string) error {
- return f.setFlag(flag, value, origArg)
+ set := func(flag *Flag, value string) error {
+ return f.Set(flag.Name, value)
}
- err := f.parseArgs(arguments, assign)
+ err := f.parseArgs(arguments, set)
if err != nil {
switch f.errorHandling {
case ContinueOnError:
@@ -1002,7 +1064,7 @@ func (f *FlagSet) Parse(arguments []string) error {
return nil
}
-type parseFunc func(flag *Flag, value, origArg string) error
+type parseFunc func(flag *Flag, value string) error
// ParseAll parses flag definitions from the argument list, which should not
// include the command name. The arguments for fn are flag and value. Must be
@@ -1013,11 +1075,7 @@ func (f *FlagSet) ParseAll(arguments []string, fn func(flag *Flag, value string)
f.parsed = true
f.args = make([]string, 0, len(arguments))
- assign := func(flag *Flag, value, origArg string) error {
- return fn(flag, value)
- }
-
- err := f.parseArgs(arguments, assign)
+ err := f.parseArgs(arguments, fn)
if err != nil {
switch f.errorHandling {
case ContinueOnError: