diff options
Diffstat (limited to 'vendor/github.com/jessevdk/go-flags/option.go')
-rw-r--r-- | vendor/github.com/jessevdk/go-flags/option.go | 569 |
1 files changed, 0 insertions, 569 deletions
diff --git a/vendor/github.com/jessevdk/go-flags/option.go b/vendor/github.com/jessevdk/go-flags/option.go deleted file mode 100644 index f6d694181..000000000 --- a/vendor/github.com/jessevdk/go-flags/option.go +++ /dev/null @@ -1,569 +0,0 @@ -package flags - -import ( - "bytes" - "fmt" - "os" - "reflect" - "strings" - "unicode/utf8" -) - -// Option flag information. Contains a description of the option, short and -// long name as well as a default value and whether an argument for this -// flag is optional. -type Option struct { - // The description of the option flag. This description is shown - // automatically in the built-in help. - Description string - - // The short name of the option (a single character). If not 0, the - // option flag can be 'activated' using -<ShortName>. Either ShortName - // or LongName needs to be non-empty. - ShortName rune - - // The long name of the option. If not "", the option flag can be - // activated using --<LongName>. Either ShortName or LongName needs - // to be non-empty. - LongName string - - // The default value of the option. - Default []string - - // The optional environment default value key name. - EnvDefaultKey string - - // The optional delimiter string for EnvDefaultKey values. - EnvDefaultDelim string - - // If true, specifies that the argument to an option flag is optional. - // When no argument to the flag is specified on the command line, the - // value of OptionalValue will be set in the field this option represents. - // This is only valid for non-boolean options. - OptionalArgument bool - - // The optional value of the option. The optional value is used when - // the option flag is marked as having an OptionalArgument. This means - // that when the flag is specified, but no option argument is given, - // the value of the field this option represents will be set to - // OptionalValue. This is only valid for non-boolean options. - OptionalValue []string - - // If true, the option _must_ be specified on the command line. If the - // option is not specified, the parser will generate an ErrRequired type - // error. - Required bool - - // A name for the value of an option shown in the Help as --flag [ValueName] - ValueName string - - // A mask value to show in the help instead of the default value. This - // is useful for hiding sensitive information in the help, such as - // passwords. - DefaultMask string - - // If non empty, only a certain set of values is allowed for an option. - Choices []string - - // If true, the option is not displayed in the help or man page - Hidden bool - - // The group which the option belongs to - group *Group - - // The struct field which the option represents. - field reflect.StructField - - // The struct field value which the option represents. - value reflect.Value - - // Determines if the option will be always quoted in the INI output - iniQuote bool - - tag multiTag - isSet bool - isSetDefault bool - preventDefault bool - clearReferenceBeforeSet bool - - defaultLiteral string -} - -// LongNameWithNamespace returns the option's long name with the group namespaces -// prepended by walking up the option's group tree. Namespaces and the long name -// itself are separated by the parser's namespace delimiter. If the long name is -// empty an empty string is returned. -func (option *Option) LongNameWithNamespace() string { - if len(option.LongName) == 0 { - return "" - } - - // fetch the namespace delimiter from the parser which is always at the - // end of the group hierarchy - namespaceDelimiter := "" - g := option.group - - for { - if p, ok := g.parent.(*Parser); ok { - namespaceDelimiter = p.NamespaceDelimiter - - break - } - - switch i := g.parent.(type) { - case *Command: - g = i.Group - case *Group: - g = i - } - } - - // concatenate long name with namespace - longName := option.LongName - g = option.group - - for g != nil { - if g.Namespace != "" { - longName = g.Namespace + namespaceDelimiter + longName - } - - switch i := g.parent.(type) { - case *Command: - g = i.Group - case *Group: - g = i - case *Parser: - g = nil - } - } - - return longName -} - -// EnvKeyWithNamespace returns the option's env key with the group namespaces -// prepended by walking up the option's group tree. Namespaces and the env key -// itself are separated by the parser's namespace delimiter. If the env key is -// empty an empty string is returned. -func (option *Option) EnvKeyWithNamespace() string { - if len(option.EnvDefaultKey) == 0 { - return "" - } - - // fetch the namespace delimiter from the parser which is always at the - // end of the group hierarchy - namespaceDelimiter := "" - g := option.group - - for { - if p, ok := g.parent.(*Parser); ok { - namespaceDelimiter = p.EnvNamespaceDelimiter - - break - } - - switch i := g.parent.(type) { - case *Command: - g = i.Group - case *Group: - g = i - } - } - - // concatenate long name with namespace - key := option.EnvDefaultKey - g = option.group - - for g != nil { - if g.EnvNamespace != "" { - key = g.EnvNamespace + namespaceDelimiter + key - } - - switch i := g.parent.(type) { - case *Command: - g = i.Group - case *Group: - g = i - case *Parser: - g = nil - } - } - - return key -} - -// String converts an option to a human friendly readable string describing the -// option. -func (option *Option) String() string { - var s string - var short string - - if option.ShortName != 0 { - data := make([]byte, utf8.RuneLen(option.ShortName)) - utf8.EncodeRune(data, option.ShortName) - short = string(data) - - if len(option.LongName) != 0 { - s = fmt.Sprintf("%s%s, %s%s", - string(defaultShortOptDelimiter), short, - defaultLongOptDelimiter, option.LongNameWithNamespace()) - } else { - s = fmt.Sprintf("%s%s", string(defaultShortOptDelimiter), short) - } - } else if len(option.LongName) != 0 { - s = fmt.Sprintf("%s%s", defaultLongOptDelimiter, option.LongNameWithNamespace()) - } - - return s -} - -// Value returns the option value as an interface{}. -func (option *Option) Value() interface{} { - return option.value.Interface() -} - -// Field returns the reflect struct field of the option. -func (option *Option) Field() reflect.StructField { - return option.field -} - -// IsSet returns true if option has been set -func (option *Option) IsSet() bool { - return option.isSet -} - -// IsSetDefault returns true if option has been set via the default option tag -func (option *Option) IsSetDefault() bool { - return option.isSetDefault -} - -// Set the value of an option to the specified value. An error will be returned -// if the specified value could not be converted to the corresponding option -// value type. -func (option *Option) set(value *string) error { - kind := option.value.Type().Kind() - - if (kind == reflect.Map || kind == reflect.Slice) && option.clearReferenceBeforeSet { - option.empty() - } - - option.isSet = true - option.preventDefault = true - option.clearReferenceBeforeSet = false - - if len(option.Choices) != 0 { - found := false - - for _, choice := range option.Choices { - if choice == *value { - found = true - break - } - } - - if !found { - allowed := strings.Join(option.Choices[0:len(option.Choices)-1], ", ") - - if len(option.Choices) > 1 { - allowed += " or " + option.Choices[len(option.Choices)-1] - } - - return newErrorf(ErrInvalidChoice, - "Invalid value `%s' for option `%s'. Allowed values are: %s", - *value, option, allowed) - } - } - - if option.isFunc() { - return option.call(value) - } else if value != nil { - return convert(*value, option.value, option.tag) - } - - return convert("", option.value, option.tag) -} - -func (option *Option) setDefault(value *string) error { - if option.preventDefault { - return nil - } - - if err := option.set(value); err != nil { - return err - } - - option.isSetDefault = true - option.preventDefault = false - - return nil -} - -func (option *Option) showInHelp() bool { - return !option.Hidden && (option.ShortName != 0 || len(option.LongName) != 0) -} - -func (option *Option) canArgument() bool { - if u := option.isUnmarshaler(); u != nil { - return true - } - - return !option.isBool() -} - -func (option *Option) emptyValue() reflect.Value { - tp := option.value.Type() - - if tp.Kind() == reflect.Map { - return reflect.MakeMap(tp) - } - - return reflect.Zero(tp) -} - -func (option *Option) empty() { - if !option.isFunc() { - option.value.Set(option.emptyValue()) - } -} - -func (option *Option) clearDefault() error { - if option.preventDefault { - return nil - } - - usedDefault := option.Default - - if envKey := option.EnvKeyWithNamespace(); envKey != "" { - if value, ok := os.LookupEnv(envKey); ok { - if option.EnvDefaultDelim != "" { - usedDefault = strings.Split(value, option.EnvDefaultDelim) - } else { - usedDefault = []string{value} - } - } - } - - option.isSetDefault = true - - if len(usedDefault) > 0 { - option.empty() - - for _, d := range usedDefault { - err := option.setDefault(&d) - - if err != nil { - return err - } - } - } else { - tp := option.value.Type() - - switch tp.Kind() { - case reflect.Map: - if option.value.IsNil() { - option.empty() - } - case reflect.Slice: - if option.value.IsNil() { - option.empty() - } - } - } - - return nil -} - -func (option *Option) valueIsDefault() bool { - // Check if the value of the option corresponds to its - // default value - emptyval := option.emptyValue() - - checkvalptr := reflect.New(emptyval.Type()) - checkval := reflect.Indirect(checkvalptr) - - checkval.Set(emptyval) - - if len(option.Default) != 0 { - for _, v := range option.Default { - convert(v, checkval, option.tag) - } - } - - return reflect.DeepEqual(option.value.Interface(), checkval.Interface()) -} - -func (option *Option) isUnmarshaler() Unmarshaler { - v := option.value - - for { - if !v.CanInterface() { - break - } - - i := v.Interface() - - if u, ok := i.(Unmarshaler); ok { - return u - } - - if !v.CanAddr() { - break - } - - v = v.Addr() - } - - return nil -} - -func (option *Option) isValueValidator() ValueValidator { - v := option.value - - for { - if !v.CanInterface() { - break - } - - i := v.Interface() - - if u, ok := i.(ValueValidator); ok { - return u - } - - if !v.CanAddr() { - break - } - - v = v.Addr() - } - - return nil -} - -func (option *Option) isBool() bool { - tp := option.value.Type() - - for { - switch tp.Kind() { - case reflect.Slice, reflect.Ptr: - tp = tp.Elem() - case reflect.Bool: - return true - case reflect.Func: - return tp.NumIn() == 0 - default: - return false - } - } -} - -func (option *Option) isSignedNumber() bool { - tp := option.value.Type() - - for { - switch tp.Kind() { - case reflect.Slice, reflect.Ptr: - tp = tp.Elem() - case reflect.Int, reflect.Int8, reflect.Int16, reflect.Int32, reflect.Int64, reflect.Float32, reflect.Float64: - return true - default: - return false - } - } -} - -func (option *Option) isFunc() bool { - return option.value.Type().Kind() == reflect.Func -} - -func (option *Option) call(value *string) error { - var retval []reflect.Value - - if value == nil { - retval = option.value.Call(nil) - } else { - tp := option.value.Type().In(0) - - val := reflect.New(tp) - val = reflect.Indirect(val) - - if err := convert(*value, val, option.tag); err != nil { - return err - } - - retval = option.value.Call([]reflect.Value{val}) - } - - if len(retval) == 1 && retval[0].Type() == reflect.TypeOf((*error)(nil)).Elem() { - if retval[0].Interface() == nil { - return nil - } - - return retval[0].Interface().(error) - } - - return nil -} - -func (option *Option) updateDefaultLiteral() { - defs := option.Default - def := "" - - if len(defs) == 0 && option.canArgument() { - var showdef bool - - switch option.field.Type.Kind() { - case reflect.Func, reflect.Ptr: - showdef = !option.value.IsNil() - case reflect.Slice, reflect.String, reflect.Array: - showdef = option.value.Len() > 0 - case reflect.Map: - showdef = !option.value.IsNil() && option.value.Len() > 0 - default: - zeroval := reflect.Zero(option.field.Type) - showdef = !reflect.DeepEqual(zeroval.Interface(), option.value.Interface()) - } - - if showdef { - def, _ = convertToString(option.value, option.tag) - } - } else if len(defs) != 0 { - l := len(defs) - 1 - - for i := 0; i < l; i++ { - def += quoteIfNeeded(defs[i]) + ", " - } - - def += quoteIfNeeded(defs[l]) - } - - option.defaultLiteral = def -} - -func (option *Option) shortAndLongName() string { - ret := &bytes.Buffer{} - - if option.ShortName != 0 { - ret.WriteRune(defaultShortOptDelimiter) - ret.WriteRune(option.ShortName) - } - - if len(option.LongName) != 0 { - if option.ShortName != 0 { - ret.WriteRune('/') - } - - ret.WriteString(option.LongName) - } - - return ret.String() -} - -func (option *Option) isValidValue(arg string) error { - if validator := option.isValueValidator(); validator != nil { - return validator.IsValidValue(arg) - } - if argumentIsOption(arg) && !(option.isSignedNumber() && len(arg) > 1 && arg[0] == '-' && arg[1] >= '0' && arg[1] <= '9') { - return fmt.Errorf("expected argument for flag `%s', but got option `%s'", option, arg) - } - return nil -} |