in e2etest/newe2e_config.go [517:602]
func ReadConfig(config reflect.Value, fieldName string, tag EnvTag) *ConfigReaderError {
if tag.EnvName != "" { // This needs to be fulfilled
return SetValue(fieldName, config, tag)
} else if config.Kind() == reflect.Struct {
fieldCt := config.NumField()
sType := config.Type()
hasRequiredFlags := false
successfulSetCount := uint(0)
baseError := NewConfigReaderError(fieldName)
for i := 0; i < fieldCt; i++ {
envTag := ParseEnvTag(sType.Field(i).Tag.Get("env"))
if tag.MutuallyExclusive { // all semantically get treated as required for consistency.
envTag.Required = true
}
if envTag.Required {
hasRequiredFlags = true
}
err := ReadConfig(config.Field(i), sType.Field(i).Name, envTag)
if err != nil && envTag.Required {
baseError.Combine(err)
} else if err == nil && envTag.Required {
successfulSetCount++
}
}
// The definition of "Required" is simply that all underlying conditions must satisfy.
// If this _is_ required, it is a structure error to have an issue.
// If it is not required, but is mutually exclusive, it is still a structure error to fulfill more than one condition.
if tag.Required {
if tag.MutuallyExclusive {
// When we're mutually exclusive, everything is required, but only one must satisfy.
if successfulSetCount > 1 {
baseError.CoreError = errors.New("mutually exclusive struct satisfies more than one field")
return baseError.Finalize()
} else if successfulSetCount == 0 {
baseError.CoreError = errors.New("mutually exclusive struct does not satisfy at least one field")
return baseError.Finalize()
}
baseError = NewConfigReaderError(fieldName) // No error if only one got set
} else if tag.MinimumRequired != 0 {
if successfulSetCount < tag.MinimumRequired {
baseError.CoreError = fmt.Errorf("required struct fails to fulfill at least %d conditions", tag.MinimumRequired)
return baseError.Finalize()
}
baseError = NewConfigReaderError(fieldName) // No error if the required amount got set
} else if !baseError.Empty() {
baseError.CoreError = errors.New("required struct fails to fulfill one or more conditions")
return baseError.Finalize()
}
} else {
// when we're not required, but we see required flags, and at least one is set, all required flags under us must succeed.
if !tag.MutuallyExclusive && hasRequiredFlags && successfulSetCount >= 1 {
if !baseError.Empty() {
baseError.CoreError = errors.New("required struct fails to fulfill one or more conditions")
return baseError.Finalize()
}
} else if tag.MutuallyExclusive {
// When we're mutually exclusive, everything is required, but only one must satisfy.
if successfulSetCount > 1 {
baseError.CoreError = errors.New("mutually exclusive struct satisfies more than one field")
return baseError.Finalize()
} else if successfulSetCount == 0 {
baseError.CoreError = errors.New("mutually exclusive struct does not satisfy at least one field")
return baseError.Finalize()
}
baseError = NewConfigReaderError(fieldName) // No error if only one got set
}
}
return baseError.Finalize() // Assuming we're not required or mutually exclusive, and everything under us satisfies,
} else {
return &ConfigReaderError{
StructName: fieldName,
CoreError: errors.New("struct field was not assigned an environment variable and is not traversable"),
}
}
}