// printField prints the field of the config struct for the flag.Usage func (e *EnvironmentLoader) printField(prefix string, field *structs.Field) { fieldName := e.generateFieldName(prefix, field) if field.IsExported() { switch { case field.Kind() == reflect.Struct && !implementsTextUnmarshaler(field): for _, f := range field.Fields() { e.printField(fieldName, f) } default: fmt.Println(" ", fieldName) } } }
// processField generates a flag based on the given field and fieldName. If a // nested struct is detected, a flag for each field of that nested struct is // generated too. func (f *FlagLoader) processField(fieldName string, field *structs.Field) error { if f.CamelCase { fieldName = strings.Join(camelcase.Split(fieldName), "-") } switch field.Kind() { case reflect.Struct: for _, ff := range field.Fields() { flagName := field.Name() + "-" + ff.Name() if f.Flatten { // first check if it's set or not, because if we have duplicate // we don't want to break the flag. Panic by giving a readable // output f.flagSet.VisitAll(func(fl *flag.Flag) { if strings.ToLower(ff.Name()) == fl.Name { // already defined panic(fmt.Sprintf("flag '%s' is already defined in outer struct", fl.Name)) } }) flagName = ff.Name() } if err := f.processField(flagName, ff); err != nil { return err } } default: // Add custom prefix to the flag if it's set if f.Prefix != "" { fieldName = f.Prefix + "-" + fieldName } // we only can get the value from expored fields, unexported fields panics if field.IsExported() { // use built-in or custom flag usage message flagUsageFunc := flagUsageDefault if f.FlagUsageFunc != nil { flagUsageFunc = f.FlagUsageFunc } f.flagSet.Var(newFieldValue(field), flagName(fieldName), flagUsageFunc(fieldName)) } } return nil }
// processField generates a flag based on the given field and fieldName. If a // nested struct is detected, a flag for each field of that nested struct is // generated too. func (f *FlagLoader) processField(flagSet *flag.FlagSet, fieldName string, field *structs.Field) error { if !field.IsExported() { return nil } if f.CamelCase { fieldName = strings.Join(camelcase.Split(fieldName), "-") } switch { case field.Kind() == reflect.Struct && !implementsTextUnmarshaler(field): for _, ff := range field.Fields() { flagName := fieldName + "-" + ff.Name() if f.Flatten { // first check if it's set or not, because if we have duplicate // we don't want to break the flag. Panic by giving a readable // output flagSet.VisitAll(func(fl *flag.Flag) { if strings.ToLower(ff.Name()) == fl.Name { // already defined panic(fmt.Sprintf("flag '%s' is already defined in outer struct", fl.Name)) } }) flagName = ff.Name() } if err := f.processField(flagSet, flagName, ff); err != nil { return err } } case field.Kind() == reflect.Ptr: field.InitElem() return f.processField(flagSet, fieldName, field) default: // Add custom prefix to the flag if it's set if f.Prefix != "" { fieldName = f.Prefix + "-" + fieldName } flagSet.Var(newFieldValue(field), flagName(fieldName), flagUsage(fieldName)) } return nil }