Пример #1
0
// processField gets leading name for the env variable and combines the current
// field's name and generates environemnt variable names recursively
func (e *EnvironmentLoader) processField(prefix string, field *structs.Field) error {
	fieldName := e.generateFieldName(prefix, field)

	switch field.Kind() {
	case reflect.Struct:
		for _, f := range field.Fields() {
			if err := e.processField(fieldName, f); err != nil {
				return err
			}
		}
	default:
		envTag := field.Tag(e.EnvTagName)
		var v string
		if envTag != "" {
			v = os.Getenv(envTag)
		}
		if v == "" {
			v = os.Getenv(fieldName)
		}
		if v == "" {
			return nil
		}

		if err := fieldSet(field, v); err != nil {
			return err
		}
	}

	return nil
}
Пример #2
0
// processField gets tagName and the field, recursively checks if the field has the given
// tag, if yes, sets it otherwise ignores
func (t *TagLoader) processField(tagName string, field *structs.Field) error {
	switch {
	case field.Kind() == reflect.Struct && !implementsTextUnmarshaler(field):
		for _, f := range field.Fields() {
			if err := t.processField(tagName, f); err != nil {
				return err
			}
		}
	case field.Kind() == reflect.Ptr:
		field.InitElem()
		return t.processField(tagName, field)
	default:
		defaultVal := field.Tag(t.DefaultTagName)
		if defaultVal == "" {
			return nil
		}

		err := fieldSet(field, defaultVal)
		if err != nil {
			return err
		}
	}

	return nil
}
Пример #3
0
func (e *SelectionValidator) processField(fieldName string, field *structs.Field) error {
	fieldName += field.Name()
	switch field.Kind() {
	case reflect.Struct:
		// this is used for error messages below, when we have an error at the
		// child properties add parent properties into the error message as well
		fieldName += "."

		for _, f := range field.Fields() {
			if err := e.processField(fieldName, f); err != nil {
				return err
			}
		}
	default:
		if field.IsZero() {
			return nil
		}
		selectionStr := field.Tag(e.SelectTagName)
		if selectionStr == "" {
			return nil
		}

		err := validateSelection(field, selectionStr)
		if err != nil {
			return err
		}
	}

	return nil
}
Пример #4
0
func (e *RequiredValidator) processField(fieldName string, field *structs.Field) error {
	fieldName += field.Name()
	switch field.Kind() {
	case reflect.Struct:
		// this is used for error messages below, when we have an error at the
		// child properties add parent properties into the error message as well
		fieldName += "."

		for _, f := range field.Fields() {
			if err := e.processField(fieldName, f); err != nil {
				return err
			}
		}
	default:
		val := field.Tag(e.RequiredTagName)
		if val != "true" && val != "1" {
			return nil
		}
		if field.IsZero() {
			return fmt.Errorf("Field '%s' is required", fieldName)
		}
	}

	return nil
}
Пример #5
0
// processField gets tagName and the field, recursively checks if the field has the given
// tag, if yes, sets it otherwise ignores
func (t *TagLoader) processFieldDefaultValue(field *structs.Field) error {

	//first process each subfield of a struct field
	switch field.Kind() {
	case reflect.Struct:
		for _, f := range field.Fields() {
			if err := t.processFieldDefaultValue(f); err != nil {
				return err
			}
		}
	default:
		//Set default value for the field itself, including struct field
		// If there's a default value tag for struct field, it should be in Json format
		defaultVal := field.Tag(t.DefaultTagName)
		if defaultVal == "" {
			return nil
		}

		err := fieldSet(field, defaultVal)
		if err != nil {
			return err
		}
	}

	return nil
}
Пример #6
0
func (e *RangeValidator) processField(fieldName string, field *structs.Field) error {
	fieldName += field.Name()
	switch field.Kind() {
	case reflect.Struct:
		// this is used for error messages below, when we have an error at the
		// child properties add parent properties into the error message as well
		fieldName += "."

		for _, f := range field.Fields() {
			if err := e.processField(fieldName, f); err != nil {
				return err
			}
		}
	default:
		if field.IsZero() { //if not initialized, we won't validate it
			return nil
		}
		minStr := field.Tag(e.MinTagName)
		maxStr := field.Tag(e.MaxTagName)
		if minStr == "" && maxStr == "" {
			return nil
		}

		err := validateRange(field, minStr, maxStr)
		if err != nil {
			return err
		}
	}

	return nil
}
Пример #7
0
// processField gets leading name for the env variable and combines the current
// field's name and generates environemnt variable names recursively
func (e *EnvironmentLoader) processField(prefix string, field *structs.Field) error {
	fieldName := e.generateFieldName(prefix, field)

	switch {
	case field.Kind() == reflect.Struct && !implementsTextUnmarshaler(field):
		for _, f := range field.Fields() {
			if err := e.processField(fieldName, f); err != nil {
				return err
			}
		}
	case field.Kind() == reflect.Ptr:
		field.InitElem()
		return e.processField(prefix, field)
	default:
		v := os.Getenv(fieldName)
		if v == "" {
			return nil
		}

		if err := fieldSet(field, v); err != nil {
			return err
		}
	}

	return nil
}
Пример #8
0
func (i *INILoader) setField(field *structs.Field, c *goconfig.ConfigFile, section string) error {
	//first process each subfield of a struct field
	switch field.Kind() {
	case reflect.Struct:
		for _, f := range field.Fields() {
			var subsection string
			if section == "" {
				subsection = field.Name()
			} else {
				subsection = section + "." + field.Name()
			}
			if err := i.setField(f, c, subsection); err != nil {
				return err
			}
		}
	default:
		v, err := c.GetValue(section, field.Name())
		if err == nil && v != "" {
			err := fieldSet(field, v)
			if err != nil {
				return err
			}
		}
	}

	return nil
}
Пример #9
0
// 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)

	switch field.Kind() {
	case reflect.Struct:
		for _, f := range field.Fields() {
			e.printField(fieldName, f)
		}
	default:
		fmt.Println("  ", fieldName)
	}
}
Пример #10
0
// 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)
		}
	}
}
Пример #11
0
// 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
}
Пример #12
0
// 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
}
Пример #13
0
// processField gets tagName and the field, recursively checks if the field has the given
// tag, if yes, sets it otherwise ignores
func (t *TagLoader) processField(tagName string, field *structs.Field) error {
	switch field.Kind() {
	case reflect.Struct:
		for _, f := range field.Fields() {
			if err := t.processField(tagName, f); err != nil {
				return err
			}
		}
	default:
		defaultVal := field.Tag(t.DefaultTagName)
		if defaultVal == "" {
			return nil
		}

		err := fieldSet(field, defaultVal)
		if err != nil {
			return err
		}
	}

	return nil
}