diff --git a/Gopkg.lock b/Gopkg.lock index b0664c667..479704dda 100644 --- a/Gopkg.lock +++ b/Gopkg.lock @@ -210,9 +210,12 @@ [[projects]] name = "github.com/containous/flaeg" - packages = ["."] - revision = "60c87a513a955ca7225e1b1c772581cea8420cb4" - version = "v1.0.1" + packages = [ + ".", + "parse" + ] + revision = "963366c29a7acc2d6e02f4f9bcf260d5a1cf4968" + version = "v1.1.1" [[projects]] branch = "master" @@ -1387,6 +1390,6 @@ [solve-meta] analyzer-name = "dep" analyzer-version = 1 - inputs-digest = "bd1e7a1b07d95ff85c675468bbfc4bc7a91c39cf1feceeb58dfcdba9592180a5" + inputs-digest = "7122deb7b2056ecfa444c5fb64437c1b0723afae528a331c4b032b841039383b" solver-name = "gps-cdcl" solver-version = 1 diff --git a/vendor/github.com/containous/flaeg/flaeg.go b/vendor/github.com/containous/flaeg/flaeg.go index fb4512537..8b1421d31 100644 --- a/vendor/github.com/containous/flaeg/flaeg.go +++ b/vendor/github.com/containous/flaeg/flaeg.go @@ -12,64 +12,63 @@ import ( "strings" "text/tabwriter" "text/template" - "time" + "github.com/containous/flaeg/parse" flag "github.com/ogier/pflag" ) // ErrParserNotFound is thrown when a field is flaged but not parser match its type -var ErrParserNotFound = errors.New("Parser not found or custom parser missing") +var ErrParserNotFound = errors.New("parser not found or custom parser missing") -// GetTypesRecursive links in flagmap a flag with its reflect.StructField +// GetTypesRecursive links in flagMap a flag with its reflect.StructField // You can whether provide objValue on a structure or a pointer to structure as first argument -// Flags are genereted from field name or from StructTag -func getTypesRecursive(objValue reflect.Value, flagmap map[string]reflect.StructField, key string) error { +// Flags are generated from field name or from StructTag +func getTypesRecursive(objValue reflect.Value, flagMap map[string]reflect.StructField, key string) error { name := key switch objValue.Kind() { case reflect.Struct: - for i := 0; i < objValue.NumField(); i++ { if objValue.Type().Field(i).Anonymous { - if err := getTypesRecursive(objValue.Field(i), flagmap, name); err != nil { + if err := getTypesRecursive(objValue.Field(i), flagMap, name); err != nil { return err } } else if len(objValue.Type().Field(i).Tag.Get("description")) > 0 { fieldName := objValue.Type().Field(i).Name if !isExported(fieldName) { - return fmt.Errorf("Field %s is an unexported field", fieldName) + return fmt.Errorf("field %s is an unexported field", fieldName) } - name += objValue.Type().Name() if tag := objValue.Type().Field(i).Tag.Get("long"); len(tag) > 0 { fieldName = tag } + if len(key) == 0 { - //Lower Camel Case - //name = strings.ToLower(string(fieldName[0])) + fieldName[1:] name = strings.ToLower(fieldName) } else { name = key + "." + strings.ToLower(fieldName) } - if _, ok := flagmap[name]; ok { - return errors.New("Tag already exists: " + name) - } - flagmap[name] = objValue.Type().Field(i) - if err := getTypesRecursive(objValue.Field(i), flagmap, name); err != nil { + if _, ok := flagMap[name]; ok { + return fmt.Errorf("tag already exists: %s", name) + } + flagMap[name] = objValue.Type().Field(i) + + if err := getTypesRecursive(objValue.Field(i), flagMap, name); err != nil { return err } } - } case reflect.Ptr: if len(key) > 0 { - field := flagmap[name] + field := flagMap[name] field.Type = reflect.TypeOf(false) - flagmap[name] = field + flagMap[name] = field } + typ := objValue.Type().Elem() inst := reflect.New(typ).Elem() - if err := getTypesRecursive(inst, flagmap, name); err != nil { + + if err := getTypesRecursive(inst, flagMap, name); err != nil { return err } default: @@ -78,14 +77,15 @@ func getTypesRecursive(objValue reflect.Value, flagmap map[string]reflect.Struct return nil } -//GetPointerFlags returns flags on pointers +// GetBoolFlags returns flags on pointers func GetBoolFlags(config interface{}) ([]string, error) { - flagmap := make(map[string]reflect.StructField) - if err := getTypesRecursive(reflect.ValueOf(config), flagmap, ""); err != nil { + flagMap := make(map[string]reflect.StructField) + if err := getTypesRecursive(reflect.ValueOf(config), flagMap, ""); err != nil { return []string{}, err } - flags := make([]string, 0, len(flagmap)) - for f, structField := range flagmap { + + flags := make([]string, 0, len(flagMap)) + for f, structField := range flagMap { if structField.Type.Kind() == reflect.Bool { flags = append(flags, f) } @@ -93,86 +93,42 @@ func GetBoolFlags(config interface{}) ([]string, error) { return flags, nil } -//GetFlags returns flags +// GetFlags returns flags func GetFlags(config interface{}) ([]string, error) { - flagmap := make(map[string]reflect.StructField) - if err := getTypesRecursive(reflect.ValueOf(config), flagmap, ""); err != nil { + flagMap := make(map[string]reflect.StructField) + if err := getTypesRecursive(reflect.ValueOf(config), flagMap, ""); err != nil { return []string{}, err } - flags := make([]string, 0, len(flagmap)) - for f := range flagmap { + + flags := make([]string, 0, len(flagMap)) + for f := range flagMap { flags = append(flags, f) } return flags, nil } -//loadParsers loads default parsers and custom parsers given as parameter. Return a map [reflect.Type]parsers -// bool, int, int64, uint, uint64, float64, -func loadParsers(customParsers map[reflect.Type]Parser) (map[reflect.Type]Parser, error) { - parsers := map[reflect.Type]Parser{} - - var boolParser boolValue - parsers[reflect.TypeOf(true)] = &boolParser - - var intParser intValue - parsers[reflect.TypeOf(1)] = &intParser - - var int64Parser int64Value - parsers[reflect.TypeOf(int64(1))] = &int64Parser - - var uintParser uintValue - parsers[reflect.TypeOf(uint(1))] = &uintParser - - var uint64Parser uint64Value - parsers[reflect.TypeOf(uint64(1))] = &uint64Parser - - var stringParser stringValue - parsers[reflect.TypeOf("")] = &stringParser - - var float64Parser float64Value - parsers[reflect.TypeOf(float64(1.5))] = &float64Parser - - var durationParser Duration - parsers[reflect.TypeOf(Duration(time.Second))] = &durationParser - - var timeParser timeValue - parsers[reflect.TypeOf(time.Now())] = &timeParser - - for rType, parser := range customParsers { - parsers[rType] = parser - } - return parsers, nil -} - -//ParseArgs : parses args return valmap map[flag]Getter, using parsers map[type]Getter -//args must be formated as like as flag documentation. See https://golang.org/pkg/flag -func parseArgs(args []string, flagmap map[string]reflect.StructField, parsers map[reflect.Type]Parser) (map[string]Parser, error) { - //Return var - valmap := make(map[string]Parser) - //Visitor in flag.Parse - flagList := []*flag.Flag{} - visitor := func(fl *flag.Flag) { - flagList = append(flagList, fl) - } - newParsers := map[string]Parser{} +// ParseArgs : parses args return a map[flag]Getter, using parsers map[type]Getter +// args must be formatted as like as flag documentation. See https://golang.org/pkg/flag +func parseArgs(args []string, flagMap map[string]reflect.StructField, parsers map[reflect.Type]parse.Parser) (map[string]parse.Parser, error) { + newParsers := map[string]parse.Parser{} flagSet := flag.NewFlagSet("flaeg.Load", flag.ContinueOnError) - //Disable output + + // Disable output flagSet.SetOutput(ioutil.Discard) + var err error - for flag, structField := range flagmap { - //for _, flag := range flags { - //structField := flagmap[flag] + for flg, structField := range flagMap { if parser, ok := parsers[structField.Type]; ok { - newparserValue := reflect.New(reflect.TypeOf(parser).Elem()) - newparserValue.Elem().Set(reflect.ValueOf(parser).Elem()) - newparser := newparserValue.Interface().(Parser) + newParserValue := reflect.New(reflect.TypeOf(parser).Elem()) + newParserValue.Elem().Set(reflect.ValueOf(parser).Elem()) + newParser := newParserValue.Interface().(parse.Parser) + if short := structField.Tag.Get("short"); len(short) == 1 { - // fmt.Printf("short : %s long : %s\n", short, flag) - flagSet.VarP(newparser, flag, short, structField.Tag.Get("description")) + flagSet.VarP(newParser, flg, short, structField.Tag.Get("description")) } else { - flagSet.Var(newparser, flag, structField.Tag.Get("description")) + flagSet.Var(newParser, flg, structField.Tag.Get("description")) } - newParsers[flag] = newparser + newParsers[flg] = newParser } else { err = ErrParserNotFound } @@ -180,24 +136,35 @@ func parseArgs(args []string, flagmap map[string]reflect.StructField, parsers ma // prevents case sensitivity issue args = argsToLower(args) - if err := flagSet.Parse(args); err != nil { - return nil, err + if errParse := flagSet.Parse(args); errParse != nil { + return nil, errParse } - //Fill flagList with parsed flags + // Visitor in flag.Parse + var flagList []*flag.Flag + visitor := func(fl *flag.Flag) { + flagList = append(flagList, fl) + } + + // Fill flagList with parsed flags flagSet.Visit(visitor) - //Return parsers on parsed flag - for _, flag := range flagList { - valmap[flag.Name] = newParsers[flag.Name] + + // Return var + valMap := make(map[string]parse.Parser) + + // Return parsers on parsed flag + for _, flg := range flagList { + valMap[flg.Name] = newParsers[flg.Name] } - return valmap, err + return valMap, err } func getDefaultValue(defaultValue reflect.Value, defaultPointersValue reflect.Value, defaultValmap map[string]reflect.Value, key string) error { if defaultValue.Type() != defaultPointersValue.Type() { - return fmt.Errorf("Parameters defaultValue and defaultPointersValue must be the same struct. defaultValue type : %s is not defaultPointersValue type : %s", defaultValue.Type().String(), defaultPointersValue.Type().String()) + return fmt.Errorf("parameters defaultValue and defaultPointersValue must be the same struct. defaultValue type: %s is not defaultPointersValue type: %s", defaultValue.Type().String(), defaultPointersValue.Type().String()) } + name := key switch defaultValue.Kind() { case reflect.Struct: @@ -207,22 +174,19 @@ func getDefaultValue(defaultValue reflect.Value, defaultPointersValue reflect.Va return err } } else if len(defaultValue.Type().Field(i).Tag.Get("description")) > 0 { - name += defaultValue.Type().Name() fieldName := defaultValue.Type().Field(i).Name if tag := defaultValue.Type().Field(i).Tag.Get("long"); len(tag) > 0 { fieldName = tag } + if len(key) == 0 { name = strings.ToLower(fieldName) } else { name = key + "." + strings.ToLower(fieldName) } + if defaultValue.Field(i).Kind() != reflect.Ptr { - // if _, ok := defaultValmap[name]; ok { - // return errors.New("Tag already exists: " + name) - // } defaultValmap[name] = defaultValue.Field(i) - // fmt.Printf("%s: got default value %+v\n", name, defaultValue.Field(i)) } if err := getDefaultValue(defaultValue.Field(i), defaultPointersValue.Field(i), defaultValmap, name); err != nil { return err @@ -232,14 +196,14 @@ func getDefaultValue(defaultValue reflect.Value, defaultPointersValue reflect.Va case reflect.Ptr: if !defaultPointersValue.IsNil() { if len(key) != 0 { - //turn ptr fields to nil + // turn ptr fields to nil defaultPointersNilValue, err := setPointersNil(defaultPointersValue) if err != nil { return err } defaultValmap[name] = defaultPointersNilValue - // fmt.Printf("%s: got default value %+v\n", name, defaultPointersNilValue) } + if !defaultValue.IsNil() { if err := getDefaultValue(defaultValue.Elem(), defaultPointersValue.Elem(), defaultValmap, name); err != nil { return err @@ -253,8 +217,8 @@ func getDefaultValue(defaultValue reflect.Value, defaultPointersValue reflect.Va instValue := reflect.New(defaultPointersValue.Type().Elem()) if len(key) != 0 { defaultValmap[name] = instValue - // fmt.Printf("%s: got default value %+v\n", name, instValue) } + if !defaultValue.IsNil() { if err := getDefaultValue(defaultValue.Elem(), instValue.Elem(), defaultValmap, name); err != nil { return err @@ -271,17 +235,18 @@ func getDefaultValue(defaultValue reflect.Value, defaultPointersValue reflect.Va return nil } -//objValue a reflect.Value of a not-nil pointer on a struct +// objValue a reflect.Value of a not-nil pointer on a struct func setPointersNil(objValue reflect.Value) (reflect.Value, error) { if objValue.Kind() != reflect.Ptr { - return objValue, fmt.Errorf("Parameters objValue must be a not-nil pointer on a struct, not a %s", objValue.Kind().String()) + return objValue, fmt.Errorf("parameters objValue must be a not-nil pointer on a struct, not a %s", objValue.Kind()) } else if objValue.IsNil() { - return objValue, fmt.Errorf("Parameters objValue must be a not-nil pointer") + return objValue, errors.New("parameters objValue must be a not-nil pointer") } else if objValue.Elem().Kind() != reflect.Struct { // fmt.Printf("Parameters objValue must be a not-nil pointer on a struct, not a pointer on a %s\n", objValue.Elem().Kind().String()) return objValue, nil } - //Clone + + // Clone starObjValue := objValue.Elem() nilPointersObjVal := reflect.New(starObjValue.Type()) starNilPointersObjVal := nilPointersObjVal.Elem() @@ -295,39 +260,38 @@ func setPointersNil(objValue reflect.Value) (reflect.Value, error) { return nilPointersObjVal, nil } -//FillStructRecursive initialize a value of any taged Struct given by reference -func fillStructRecursive(objValue reflect.Value, defaultPointerValmap map[string]reflect.Value, valmap map[string]Parser, key string) error { +// FillStructRecursive initialize a value of any tagged Struct given by reference +func fillStructRecursive(objValue reflect.Value, defaultPointerValMap map[string]reflect.Value, valMap map[string]parse.Parser, key string) error { name := key switch objValue.Kind() { case reflect.Struct: for i := 0; i < objValue.Type().NumField(); i++ { if objValue.Type().Field(i).Anonymous { - if err := fillStructRecursive(objValue.Field(i), defaultPointerValmap, valmap, name); err != nil { + if err := fillStructRecursive(objValue.Field(i), defaultPointerValMap, valMap, name); err != nil { return err } } else if len(objValue.Type().Field(i).Tag.Get("description")) > 0 { - name += objValue.Type().Name() fieldName := objValue.Type().Field(i).Name if tag := objValue.Type().Field(i).Tag.Get("long"); len(tag) > 0 { fieldName = tag } + if len(key) == 0 { name = strings.ToLower(fieldName) } else { name = key + "." + strings.ToLower(fieldName) } - // fmt.Println(name) - if objValue.Field(i).Kind() != reflect.Ptr { - if val, ok := valmap[name]; ok { - // fmt.Printf("%s : set def val\n", name) + if objValue.Field(i).Kind() != reflect.Ptr { + if val, ok := valMap[name]; ok { if err := setFields(objValue.Field(i), val); err != nil { return err } } } - if err := fillStructRecursive(objValue.Field(i), defaultPointerValmap, valmap, name); err != nil { + + if err := fillStructRecursive(objValue.Field(i), defaultPointerValMap, valMap, name); err != nil { return err } } @@ -335,39 +299,38 @@ func fillStructRecursive(objValue reflect.Value, defaultPointerValmap map[string case reflect.Ptr: if len(key) == 0 && !objValue.IsNil() { - if err := fillStructRecursive(objValue.Elem(), defaultPointerValmap, valmap, name); err != nil { - return err - } - return nil + return fillStructRecursive(objValue.Elem(), defaultPointerValMap, valMap, name) } + contains := false - for flag := range valmap { + for flg := range valMap { // TODO replace by regexp - if strings.HasPrefix(flag, name+".") { + if strings.HasPrefix(flg, name+".") { contains = true break } } + needDefault := false - if _, ok := valmap[name]; ok { - needDefault = valmap[name].Get().(bool) + if _, ok := valMap[name]; ok { + needDefault = valMap[name].Get().(bool) } if contains && objValue.IsNil() { needDefault = true } if needDefault { - if defVal, ok := defaultPointerValmap[name]; ok { - //set default pointer value - // fmt.Printf("%s : set default value %+v\n", name, defVal) + if defVal, ok := defaultPointerValMap[name]; ok { + // set default pointer value objValue.Set(defVal) } else { return fmt.Errorf("flag %s default value not provided", name) } } + if !objValue.IsNil() && contains { if objValue.Type().Elem().Kind() == reflect.Struct { - if err := fillStructRecursive(objValue.Elem(), defaultPointerValmap, valmap, name); err != nil { + if err := fillStructRecursive(objValue.Elem(), defaultPointerValMap, valMap, name); err != nil { return err } } @@ -378,35 +341,35 @@ func fillStructRecursive(objValue reflect.Value, defaultPointerValmap map[string return nil } -// SetFields sets value to fieldValue using tag as key in valmap -func setFields(fieldValue reflect.Value, val Parser) error { +// SetFields sets value to fieldValue using tag as key in valMap +func setFields(fieldValue reflect.Value, val parse.Parser) error { if fieldValue.CanSet() { fieldValue.Set(reflect.ValueOf(val).Elem().Convert(fieldValue.Type())) } else { - return errors.New(fieldValue.Type().String() + " is not settable.") + return fmt.Errorf("%s is not settable", fieldValue.Type().String()) } return nil } -//PrintHelp generates and prints command line help -func PrintHelp(flagmap map[string]reflect.StructField, defaultValmap map[string]reflect.Value, parsers map[reflect.Type]Parser) error { - return PrintHelpWithCommand(flagmap, defaultValmap, parsers, nil, nil) +// PrintHelp generates and prints command line help +func PrintHelp(flagMap map[string]reflect.StructField, defaultValmap map[string]reflect.Value, parsers map[reflect.Type]parse.Parser) error { + return PrintHelpWithCommand(flagMap, defaultValmap, parsers, nil, nil) } -//PrintError takes a not nil error and prints command line help -func PrintError(err error, flagmap map[string]reflect.StructField, defaultValmap map[string]reflect.Value, parsers map[reflect.Type]Parser) error { +// PrintError takes a not nil error and prints command line help +func PrintError(err error, flagMap map[string]reflect.StructField, defaultValmap map[string]reflect.Value, parsers map[reflect.Type]parse.Parser) error { if err != flag.ErrHelp { - fmt.Printf("Error : %s\n", err) + fmt.Printf("Error: %s\n", err) } if !strings.Contains(err.Error(), ":No parser for type") { - PrintHelp(flagmap, defaultValmap, parsers) + PrintHelp(flagMap, defaultValmap, parsers) } return err } -//LoadWithParsers initializes config : struct fields given by reference, with args : arguments. -//Some custom parsers may be given. -func LoadWithParsers(config interface{}, defaultValue interface{}, args []string, customParsers map[reflect.Type]Parser) error { +// LoadWithParsers initializes config : struct fields given by reference, with args : arguments. +// Some custom parsers may be given. +func LoadWithParsers(config interface{}, defaultValue interface{}, args []string, customParsers map[reflect.Type]parse.Parser) error { cmd := &Command{ Config: config, DefaultPointersConfig: defaultValue, @@ -415,8 +378,8 @@ func LoadWithParsers(config interface{}, defaultValue interface{}, args []string return LoadWithCommand(cmd, args, customParsers, nil) } -//Load initializes config : struct fields given by reference, with args : arguments. -//Some custom parsers may be given. +// Load initializes config : struct fields given by reference, with args : arguments. +// Some custom parsers may be given. func Load(config interface{}, defaultValue interface{}, args []string) error { return LoadWithParsers(config, defaultValue, args, nil) } @@ -430,35 +393,34 @@ type Command struct { Name string Description string Config interface{} - DefaultPointersConfig interface{} //TODO:case DefaultPointersConfig is nil + DefaultPointersConfig interface{} // TODO: case DefaultPointersConfig is nil Run func() error Metadata map[string]string } -//LoadWithCommand initializes config : struct fields given by reference, with args : arguments. -//Some custom parsers and some subCommand may be given. -func LoadWithCommand(cmd *Command, cmdArgs []string, customParsers map[reflect.Type]Parser, subCommand []*Command) error { - - parsers, err := loadParsers(customParsers) +// LoadWithCommand initializes config : struct fields given by reference, with args : arguments. +// Some custom parsers and some subCommand may be given. +func LoadWithCommand(cmd *Command, cmdArgs []string, customParsers map[reflect.Type]parse.Parser, subCommand []*Command) error { + parsers, err := parse.LoadParsers(customParsers) if err != nil { return err } - tagsmap := make(map[string]reflect.StructField) - if err := getTypesRecursive(reflect.ValueOf(cmd.Config), tagsmap, ""); err != nil { + tagsMap := make(map[string]reflect.StructField) + if err := getTypesRecursive(reflect.ValueOf(cmd.Config), tagsMap, ""); err != nil { return err } - defaultValmap := make(map[string]reflect.Value) - if err := getDefaultValue(reflect.ValueOf(cmd.Config), reflect.ValueOf(cmd.DefaultPointersConfig), defaultValmap, ""); err != nil { + defaultValMap := make(map[string]reflect.Value) + if err := getDefaultValue(reflect.ValueOf(cmd.Config), reflect.ValueOf(cmd.DefaultPointersConfig), defaultValMap, ""); err != nil { return err } - valmap, errParseArgs := parseArgs(cmdArgs, tagsmap, parsers) + valMap, errParseArgs := parseArgs(cmdArgs, tagsMap, parsers) if errParseArgs != nil && errParseArgs != ErrParserNotFound { - return PrintErrorWithCommand(errParseArgs, tagsmap, defaultValmap, parsers, cmd, subCommand) + return PrintErrorWithCommand(errParseArgs, tagsMap, defaultValMap, parsers, cmd, subCommand) } - if err := fillStructRecursive(reflect.ValueOf(cmd.Config), defaultValmap, valmap, ""); err != nil { + if err := fillStructRecursive(reflect.ValueOf(cmd.Config), defaultValMap, valMap, ""); err != nil { return err } @@ -469,8 +431,8 @@ func LoadWithCommand(cmd *Command, cmdArgs []string, customParsers map[reflect.T return nil } -//PrintHelpWithCommand generates and prints command line help for a Command -func PrintHelpWithCommand(flagmap map[string]reflect.StructField, defaultValmap map[string]reflect.Value, parsers map[reflect.Type]Parser, cmd *Command, subCmd []*Command) error { +// PrintHelpWithCommand generates and prints command line help for a Command +func PrintHelpWithCommand(flagMap map[string]reflect.StructField, defaultValMap map[string]reflect.Value, parsers map[reflect.Type]parse.Parser, cmd *Command, subCmd []*Command) error { // Define a templates // Using POSXE STD : http://pubs.opengroup.org/onlinepubs/9699919799/ const helper = `{{if .ProgDescription}}{{.ProgDescription}} @@ -504,7 +466,7 @@ Flags: _, tempStruct.ProgName = path.Split(os.Args[0]) } - //Run Template + // Run Template tmplHelper, err := template.New("helper").Parse(helper) if err != nil { return err @@ -514,38 +476,38 @@ Flags: return err } - return printFlagsDescriptionsDefaultValues(flagmap, defaultValmap, parsers, os.Stdout) + return printFlagsDescriptionsDefaultValues(flagMap, defaultValMap, parsers, os.Stdout) } -func printFlagsDescriptionsDefaultValues(flagmap map[string]reflect.StructField, defaultValmap map[string]reflect.Value, parsers map[reflect.Type]Parser, output io.Writer) error { +func printFlagsDescriptionsDefaultValues(flagMap map[string]reflect.StructField, defaultValMap map[string]reflect.Value, parsers map[reflect.Type]parse.Parser, output io.Writer) error { // Sort alphabetically & Delete unparsable flags in a slice - flags := []string{} - for flag, field := range flagmap { + var flags []string + for flg, field := range flagMap { if _, ok := parsers[field.Type]; ok { - flags = append(flags, flag) + flags = append(flags, flg) } } sort.Strings(flags) // Process data - descriptions := []string{} - defaultValues := []string{} - flagsWithDashs := []string{} - shortFlagsWithDash := []string{} - for _, flag := range flags { - field := flagmap[flag] + var descriptions []string + var defaultValues []string + var flagsWithDash []string + var shortFlagsWithDash []string + for _, flg := range flags { + field := flagMap[flg] if short := field.Tag.Get("short"); len(short) == 1 { shortFlagsWithDash = append(shortFlagsWithDash, "-"+short+",") } else { shortFlagsWithDash = append(shortFlagsWithDash, "") } - flagsWithDashs = append(flagsWithDashs, "--"+flag) + flagsWithDash = append(flagsWithDash, "--"+flg) - //flag on pointer ? - if defVal, ok := defaultValmap[flag]; ok { + // flag on pointer ? + if defVal, ok := defaultValMap[flg]; ok { if defVal.Kind() != reflect.Ptr { // Set defaultValue on parsers - parsers[field.Type].SetValue(defaultValmap[flag].Interface()) + parsers[field.Type].SetValue(defaultValMap[flg].Interface()) } if defVal := parsers[field.Type].String(); len(defVal) > 0 { @@ -560,17 +522,19 @@ func printFlagsDescriptionsDefaultValues(flagmap map[string]reflect.StructField, descriptions = append(descriptions, description) if i != 0 { defaultValues = append(defaultValues, "") - flagsWithDashs = append(flagsWithDashs, "") + flagsWithDash = append(flagsWithDash, "") shortFlagsWithDash = append(shortFlagsWithDash, "") } } } + //add help flag shortFlagsWithDash = append(shortFlagsWithDash, "-h,") - flagsWithDashs = append(flagsWithDashs, "--help") + flagsWithDash = append(flagsWithDash, "--help") descriptions = append(descriptions, "Print Help (this message) and exit") defaultValues = append(defaultValues, "") - return displayTab(output, shortFlagsWithDash, flagsWithDashs, descriptions, defaultValues) + + return displayTab(output, shortFlagsWithDash, flagsWithDash, descriptions, defaultValues) } func split(str string, width int) []string { if len(str) > width { @@ -578,16 +542,19 @@ func split(str string, width int) []string { if index == -1 { index = width } + return append([]string{strings.TrimSpace(str[:index])}, split(strings.TrimSpace(str[index:]), width)...) } return []string{str} } func displayTab(output io.Writer, columns ...[]string) error { - nbRow := len(columns[0]) - nbCol := len(columns) w := new(tabwriter.Writer) w.Init(output, 0, 4, 1, ' ', 0) + + nbRow := len(columns[0]) + nbCol := len(columns) + for i := 0; i < nbRow; i++ { row := "" for j, col := range columns { @@ -598,56 +565,58 @@ func displayTab(output io.Writer, columns ...[]string) error { } fmt.Fprintln(w, row) } - w.Flush() - return nil + + return w.Flush() } -//PrintErrorWithCommand takes a not nil error and prints command line help -func PrintErrorWithCommand(err error, flagmap map[string]reflect.StructField, defaultValmap map[string]reflect.Value, parsers map[reflect.Type]Parser, cmd *Command, subCmd []*Command) error { +// PrintErrorWithCommand takes a not nil error and prints command line help +func PrintErrorWithCommand(err error, flagMap map[string]reflect.StructField, defaultValMap map[string]reflect.Value, parsers map[reflect.Type]parse.Parser, cmd *Command, subCmd []*Command) error { if err != flag.ErrHelp { fmt.Printf("Error here : %s\n", err) } - PrintHelpWithCommand(flagmap, defaultValmap, parsers, cmd, subCmd) + + PrintHelpWithCommand(flagMap, defaultValMap, parsers, cmd, subCmd) return err } -//Flaeg struct contains commands (at least the root one) -//and row arguments (command and/or flags) -//a map of custom parsers could be use +// Flaeg struct contains commands (at least the root one) +// and row arguments (command and/or flags) +// a map of custom parsers could be use type Flaeg struct { calledCommand *Command commands []*Command ///rootCommand is th fist one in this slice args []string - commmandArgs []string - customParsers map[reflect.Type]Parser + commandArgs []string + customParsers map[reflect.Type]parse.Parser } -//New creats and initialize a pointer on Flaeg +// New creates and initialize a pointer on Flaeg func New(rootCommand *Command, args []string) *Flaeg { var f Flaeg f.commands = []*Command{rootCommand} f.args = args - f.customParsers = map[reflect.Type]Parser{} + f.customParsers = map[reflect.Type]parse.Parser{} return &f } -//AddCommand adds sub-command to the root command +// AddCommand adds sub-command to the root command func (f *Flaeg) AddCommand(command *Command) { f.commands = append(f.commands, command) } -//AddParser adds custom parser for a type to the map of custom parsers -func (f *Flaeg) AddParser(typ reflect.Type, parser Parser) { +// AddParser adds custom parser for a type to the map of custom parsers +func (f *Flaeg) AddParser(typ reflect.Type, parser parse.Parser) { f.customParsers[typ] = parser } -// Run calls the command with flags given as agruments +// Run calls the command with flags given as arguments func (f *Flaeg) Run() error { if f.calledCommand == nil { if _, _, err := f.findCommandWithCommandArgs(); err != nil { return err } } + if _, err := f.Parse(f.calledCommand); err != nil { return err } @@ -658,15 +627,16 @@ func (f *Flaeg) Run() error { // It returns nil and a not nil error if it fails func (f *Flaeg) Parse(cmd *Command) (*Command, error) { if f.calledCommand == nil { - f.commmandArgs = f.args + f.commandArgs = f.args } - if err := LoadWithCommand(cmd, f.commmandArgs, f.customParsers, f.commands); err != nil { + + if err := LoadWithCommand(cmd, f.commandArgs, f.customParsers, f.commands); err != nil { return cmd, err } return cmd, nil } -//splitArgs takes args (type []string) and return command ("" if rootCommand) and command's args +// splitArgs takes args (type []string) and return command ("" if rootCommand) and command's args func splitArgs(args []string) (string, []string) { if len(args) >= 1 && len(args[0]) >= 1 && string(args[0][0]) != "-" { if len(args) == 1 { @@ -680,20 +650,20 @@ func splitArgs(args []string) (string, []string) { // findCommandWithCommandArgs returns the called command (by reference) and command's args // the error returned is not nil if it fails func (f *Flaeg) findCommandWithCommandArgs() (*Command, []string, error) { - commandName := "" - commandName, f.commmandArgs = splitArgs(f.args) + var commandName string + commandName, f.commandArgs = splitArgs(f.args) if len(commandName) > 0 { for _, command := range f.commands { if commandName == command.Name { f.calledCommand = command - return f.calledCommand, f.commmandArgs, nil + return f.calledCommand, f.commandArgs, nil } } - return nil, []string{}, fmt.Errorf("Command %s not found", commandName) + return nil, []string{}, fmt.Errorf("command %s not found", commandName) } f.calledCommand = f.commands[0] - return f.calledCommand, f.commmandArgs, nil + return f.calledCommand, f.commandArgs, nil } // GetCommand splits args and returns the called command (by reference) @@ -706,15 +676,17 @@ func (f *Flaeg) GetCommand() (*Command, error) { return f.calledCommand, nil } -//isExported return true is the field (from fieldName) is exported, -//else false +// isExported return true is the field (from fieldName) is exported, +// else false func isExported(fieldName string) bool { if len(fieldName) < 1 { return false } + if string(fieldName[0]) == strings.ToUpper(string(fieldName[0])) { return true } + return false } @@ -722,22 +694,24 @@ func argToLower(inArg string) string { if len(inArg) < 2 { return strings.ToLower(inArg) } + var outArg string dashIndex := strings.Index(inArg, "--") if dashIndex == -1 { if dashIndex = strings.Index(inArg, "-"); dashIndex == -1 { return inArg } - //-fValue + // -fValue outArg = strings.ToLower(inArg[dashIndex:dashIndex+2]) + inArg[dashIndex+2:] return outArg } - //--flag + + // --flag if equalIndex := strings.Index(inArg, "="); equalIndex != -1 { - //--flag=value + // --flag=value outArg = strings.ToLower(inArg[dashIndex:equalIndex]) + inArg[equalIndex:] } else { - //--boolflag + // --boolflag outArg = strings.ToLower(inArg[dashIndex:]) } @@ -745,7 +719,7 @@ func argToLower(inArg string) string { } func argsToLower(inArgs []string) []string { - outArgs := make([]string, len(inArgs), len(inArgs)) + outArgs := make([]string, len(inArgs)) for i, inArg := range inArgs { outArgs[i] = argToLower(inArg) } diff --git a/vendor/github.com/containous/flaeg/flaeg_types.go b/vendor/github.com/containous/flaeg/flaeg_types.go new file mode 100644 index 000000000..54ee8f600 --- /dev/null +++ b/vendor/github.com/containous/flaeg/flaeg_types.go @@ -0,0 +1,7 @@ +package flaeg + +import "github.com/containous/flaeg/parse" + +// Duration is deprecated use parse.Duration instead +// Deprecated +type Duration = parse.Duration diff --git a/vendor/github.com/containous/flaeg/parse/parse.go b/vendor/github.com/containous/flaeg/parse/parse.go new file mode 100644 index 000000000..4db67b10d --- /dev/null +++ b/vendor/github.com/containous/flaeg/parse/parse.go @@ -0,0 +1,301 @@ +package parse + +import ( + "flag" + "fmt" + "reflect" + "strconv" + "strings" + "time" +) + +// Parser is an interface that allows the contents of a flag.Getter to be set. +type Parser interface { + flag.Getter + SetValue(interface{}) +} + +// BoolValue bool Value type +type BoolValue bool + +// Set sets bool value from the given string value. +func (b *BoolValue) Set(s string) error { + v, err := strconv.ParseBool(s) + *b = BoolValue(v) + return err +} + +// Get returns the bool value. +func (b *BoolValue) Get() interface{} { return bool(*b) } + +func (b *BoolValue) String() string { return fmt.Sprintf("%v", *b) } + +// IsBoolFlag return true +func (b *BoolValue) IsBoolFlag() bool { return true } + +// SetValue sets the duration from the given bool-asserted value. +func (b *BoolValue) SetValue(val interface{}) { + *b = BoolValue(val.(bool)) +} + +// BoolFlag optional interface to indicate boolean flags that can be +// supplied without "=value" text +type BoolFlag interface { + flag.Value + IsBoolFlag() bool +} + +// IntValue int Value +type IntValue int + +// Set sets int value from the given string value. +func (i *IntValue) Set(s string) error { + v, err := strconv.ParseInt(s, 0, 64) + *i = IntValue(v) + return err +} + +// Get returns the int value. +func (i *IntValue) Get() interface{} { return int(*i) } + +func (i *IntValue) String() string { return fmt.Sprintf("%v", *i) } + +// SetValue sets the IntValue from the given int-asserted value. +func (i *IntValue) SetValue(val interface{}) { + *i = IntValue(val.(int)) +} + +// Int64Value int64 Value +type Int64Value int64 + +// Set sets int64 value from the given string value. +func (i *Int64Value) Set(s string) error { + v, err := strconv.ParseInt(s, 0, 64) + *i = Int64Value(v) + return err +} + +// Get returns the int64 value. +func (i *Int64Value) Get() interface{} { return int64(*i) } + +func (i *Int64Value) String() string { return fmt.Sprintf("%v", *i) } + +// SetValue sets the Int64Value from the given int64-asserted value. +func (i *Int64Value) SetValue(val interface{}) { + *i = Int64Value(val.(int64)) +} + +// UintValue uint Value +type UintValue uint + +// Set sets uint value from the given string value. +func (i *UintValue) Set(s string) error { + v, err := strconv.ParseUint(s, 0, 64) + *i = UintValue(v) + return err +} + +// Get returns the uint value. +func (i *UintValue) Get() interface{} { return uint(*i) } + +func (i *UintValue) String() string { return fmt.Sprintf("%v", *i) } + +// SetValue sets the UintValue from the given uint-asserted value. +func (i *UintValue) SetValue(val interface{}) { + *i = UintValue(val.(uint)) +} + +// Uint64Value uint64 Value +type Uint64Value uint64 + +// Set sets uint64 value from the given string value. +func (i *Uint64Value) Set(s string) error { + v, err := strconv.ParseUint(s, 0, 64) + *i = Uint64Value(v) + return err +} + +// Get returns the uint64 value. +func (i *Uint64Value) Get() interface{} { return uint64(*i) } + +func (i *Uint64Value) String() string { return fmt.Sprintf("%v", *i) } + +// SetValue sets the Uint64Value from the given uint64-asserted value. +func (i *Uint64Value) SetValue(val interface{}) { + *i = Uint64Value(val.(uint64)) +} + +// StringValue string Value +type StringValue string + +// Set sets string value from the given string value. +func (s *StringValue) Set(val string) error { + *s = StringValue(val) + return nil +} + +// Get returns the string value. +func (s *StringValue) Get() interface{} { return string(*s) } + +func (s *StringValue) String() string { return string(*s) } + +// SetValue sets the StringValue from the given string-asserted value. +func (s *StringValue) SetValue(val interface{}) { + *s = StringValue(val.(string)) +} + +// Float64Value float64 Value +type Float64Value float64 + +// Set sets float64 value from the given string value. +func (f *Float64Value) Set(s string) error { + v, err := strconv.ParseFloat(s, 64) + *f = Float64Value(v) + return err +} + +// Get returns the float64 value. +func (f *Float64Value) Get() interface{} { return float64(*f) } + +func (f *Float64Value) String() string { return fmt.Sprintf("%v", *f) } + +// SetValue sets the Float64Value from the given float64-asserted value. +func (f *Float64Value) SetValue(val interface{}) { + *f = Float64Value(val.(float64)) +} + +// Duration is a custom type suitable for parsing duration values. +// It supports `time.ParseDuration`-compatible values and suffix-less digits; in +// the latter case, seconds are assumed. +type Duration time.Duration + +// Set sets the duration from the given string value. +func (d *Duration) Set(s string) error { + if v, err := strconv.Atoi(s); err == nil { + *d = Duration(time.Duration(v) * time.Second) + return nil + } + + v, err := time.ParseDuration(s) + *d = Duration(v) + return err +} + +// Get returns the duration value. +func (d *Duration) Get() interface{} { return time.Duration(*d) } + +// String returns a string representation of the duration value. +func (d *Duration) String() string { return (*time.Duration)(d).String() } + +// SetValue sets the duration from the given Duration-asserted value. +func (d *Duration) SetValue(val interface{}) { + *d = val.(Duration) +} + +// MarshalText serialize the given duration value into a text. +func (d *Duration) MarshalText() ([]byte, error) { + return []byte(d.String()), nil +} + +// UnmarshalText deserializes the given text into a duration value. +// It is meant to support TOML decoding of durations. +func (d *Duration) UnmarshalText(text []byte) error { + return d.Set(string(text)) +} + +// UnmarshalJSON deserializes the given text into a duration value. +func (d *Duration) UnmarshalJSON(text []byte) error { + if v, err := strconv.Atoi(string(text)); err == nil { + *d = Duration(time.Duration(v)) + return nil + } + + v, err := time.ParseDuration(string(text)) + *d = Duration(v) + return err +} + +// TimeValue time.Time Value +type TimeValue time.Time + +// Set sets time.Time value from the given string value. +func (t *TimeValue) Set(s string) error { + v, err := time.Parse(time.RFC3339, s) + *t = TimeValue(v) + return err +} + +// Get returns the time.Time value. +func (t *TimeValue) Get() interface{} { return time.Time(*t) } + +func (t *TimeValue) String() string { return (*time.Time)(t).String() } + +// SetValue sets the TimeValue from the given time.Time-asserted value. +func (t *TimeValue) SetValue(val interface{}) { + *t = TimeValue(val.(time.Time)) +} + +// SliceStrings parse slice of strings +type SliceStrings []string + +// Set adds strings elem into the the parser. +// It splits str on , and ; +func (s *SliceStrings) Set(str string) error { + fargs := func(c rune) bool { + return c == ',' || c == ';' + } + // get function + slice := strings.FieldsFunc(str, fargs) + *s = append(*s, slice...) + return nil +} + +// Get []string +func (s *SliceStrings) Get() interface{} { return []string(*s) } + +// String return slice in a string +func (s *SliceStrings) String() string { return fmt.Sprintf("%v", *s) } + +// SetValue sets []string into the parser +func (s *SliceStrings) SetValue(val interface{}) { + *s = SliceStrings(val.([]string)) +} + +// LoadParsers loads default parsers and custom parsers given as parameter. +// Return a map [reflect.Type]parsers +// bool, int, int64, uint, uint64, float64, +func LoadParsers(customParsers map[reflect.Type]Parser) (map[reflect.Type]Parser, error) { + parsers := map[reflect.Type]Parser{} + + var boolParser BoolValue + parsers[reflect.TypeOf(true)] = &boolParser + + var intParser IntValue + parsers[reflect.TypeOf(1)] = &intParser + + var int64Parser Int64Value + parsers[reflect.TypeOf(int64(1))] = &int64Parser + + var uintParser UintValue + parsers[reflect.TypeOf(uint(1))] = &uintParser + + var uint64Parser Uint64Value + parsers[reflect.TypeOf(uint64(1))] = &uint64Parser + + var stringParser StringValue + parsers[reflect.TypeOf("")] = &stringParser + + var float64Parser Float64Value + parsers[reflect.TypeOf(float64(1.5))] = &float64Parser + + var durationParser Duration + parsers[reflect.TypeOf(Duration(time.Second))] = &durationParser + + var timeParser TimeValue + parsers[reflect.TypeOf(time.Now())] = &timeParser + + for rType, parser := range customParsers { + parsers[rType] = parser + } + return parsers, nil +} diff --git a/vendor/github.com/containous/flaeg/parsers.go b/vendor/github.com/containous/flaeg/parsers.go deleted file mode 100644 index 7b99d2d2c..000000000 --- a/vendor/github.com/containous/flaeg/parsers.go +++ /dev/null @@ -1,221 +0,0 @@ -package flaeg - -import ( - "flag" - "fmt" - "strconv" - "strings" - "time" -) - -//TODO : add parsers on all types in https://golang.org/pkg/builtin/ - -// Parser is an interface that allows the contents of a flag.Getter to be set. -type Parser interface { - flag.Getter - SetValue(interface{}) -} - -// -- bool Value -type boolValue bool - -func (b *boolValue) Set(s string) error { - v, err := strconv.ParseBool(s) - *b = boolValue(v) - return err -} - -func (b *boolValue) Get() interface{} { return bool(*b) } - -func (b *boolValue) String() string { return fmt.Sprintf("%v", *b) } - -func (b *boolValue) IsBoolFlag() bool { return true } - -func (b *boolValue) SetValue(val interface{}) { - *b = boolValue(val.(bool)) -} - -// optional interface to indicate boolean flags that can be -// supplied without "=value" text -type boolFlag interface { - flag.Value - IsBoolFlag() bool -} - -// -- int Value -type intValue int - -func (i *intValue) Set(s string) error { - v, err := strconv.ParseInt(s, 0, 64) - *i = intValue(v) - return err -} - -func (i *intValue) Get() interface{} { return int(*i) } - -func (i *intValue) String() string { return fmt.Sprintf("%v", *i) } - -func (i *intValue) SetValue(val interface{}) { - *i = intValue(val.(int)) -} - -// -- int64 Value -type int64Value int64 - -func (i *int64Value) Set(s string) error { - v, err := strconv.ParseInt(s, 0, 64) - *i = int64Value(v) - return err -} - -func (i *int64Value) Get() interface{} { return int64(*i) } - -func (i *int64Value) String() string { return fmt.Sprintf("%v", *i) } - -func (i *int64Value) SetValue(val interface{}) { - *i = int64Value(val.(int64)) -} - -// -- uint Value -type uintValue uint - -func (i *uintValue) Set(s string) error { - v, err := strconv.ParseUint(s, 0, 64) - *i = uintValue(v) - return err -} - -func (i *uintValue) Get() interface{} { return uint(*i) } - -func (i *uintValue) String() string { return fmt.Sprintf("%v", *i) } - -func (i *uintValue) SetValue(val interface{}) { - *i = uintValue(val.(uint)) -} - -// -- uint64 Value -type uint64Value uint64 - -func (i *uint64Value) Set(s string) error { - v, err := strconv.ParseUint(s, 0, 64) - *i = uint64Value(v) - return err -} - -func (i *uint64Value) Get() interface{} { return uint64(*i) } - -func (i *uint64Value) String() string { return fmt.Sprintf("%v", *i) } - -func (i *uint64Value) SetValue(val interface{}) { - *i = uint64Value(val.(uint64)) -} - -// -- string Value -type stringValue string - -func (s *stringValue) Set(val string) error { - *s = stringValue(val) - return nil -} - -func (s *stringValue) Get() interface{} { return string(*s) } - -func (s *stringValue) String() string { return fmt.Sprintf("%s", *s) } - -func (s *stringValue) SetValue(val interface{}) { - *s = stringValue(val.(string)) -} - -// -- float64 Value -type float64Value float64 - -func (f *float64Value) Set(s string) error { - v, err := strconv.ParseFloat(s, 64) - *f = float64Value(v) - return err -} - -func (f *float64Value) Get() interface{} { return float64(*f) } - -func (f *float64Value) String() string { return fmt.Sprintf("%v", *f) } - -func (f *float64Value) SetValue(val interface{}) { - *f = float64Value(val.(float64)) -} - -// Duration is a custom type suitable for parsing duration values. -// It supports `time.ParseDuration`-compatible values and suffix-less digits; in -// the latter case, seconds are assumed. -type Duration time.Duration - -// Set sets the duration from the given string value. -func (d *Duration) Set(s string) error { - if v, err := strconv.Atoi(s); err == nil { - *d = Duration(time.Duration(v) * time.Second) - return nil - } - - v, err := time.ParseDuration(s) - *d = Duration(v) - return err -} - -// Get returns the duration value. -func (d *Duration) Get() interface{} { return time.Duration(*d) } - -// String returns a string representation of the duration value. -func (d *Duration) String() string { return (*time.Duration)(d).String() } - -// SetValue sets the duration from the given Duration-asserted value. -func (d *Duration) SetValue(val interface{}) { - *d = Duration(val.(Duration)) -} - -// UnmarshalText deserializes the given text into a duration value. -// It is meant to support TOML decoding of durations. -func (d *Duration) UnmarshalText(text []byte) error { - return d.Set(string(text)) -} - -// -- time.Time Value -type timeValue time.Time - -func (t *timeValue) Set(s string) error { - v, err := time.Parse(time.RFC3339, s) - *t = timeValue(v) - return err -} - -func (t *timeValue) Get() interface{} { return time.Time(*t) } - -func (t *timeValue) String() string { return (*time.Time)(t).String() } - -func (t *timeValue) SetValue(val interface{}) { - *t = timeValue(val.(time.Time)) -} - -//SliceStrings parse slice of strings -type SliceStrings []string - -//Set adds strings elem into the the parser -//it splits str on , and ; -func (s *SliceStrings) Set(str string) error { - fargs := func(c rune) bool { - return c == ',' || c == ';' - } - // get function - slice := strings.FieldsFunc(str, fargs) - *s = append(*s, slice...) - return nil -} - -//Get []string -func (s *SliceStrings) Get() interface{} { return []string(*s) } - -//String return slice in a string -func (s *SliceStrings) String() string { return fmt.Sprintf("%v", *s) } - -//SetValue sets []string into the parser -func (s *SliceStrings) SetValue(val interface{}) { - *s = SliceStrings(val.([]string)) -}