internal/config/environment_reference.go
Rama main · réplica de lectura del repositorio original.
package config
import (
"encoding/json"
"fmt"
"os"
"regexp"
"sort"
"strings"
)
var environmentReferencePattern = regexp.MustCompile(`\$\{([A-Za-z_][A-Za-z0-9_]*)\}`)
func expandEnvironmentReferences(document []byte) ([]byte, error) {
var value any
if errorValue := json.Unmarshal(document, &value); errorValue != nil {
return nil, errorValue
}
missing := map[string]bool{}
expanded := expandValue(value, missing)
if len(missing) > 0 {
return nil, fmt.Errorf("the runtime configuration refers to environment variables that are not set: %s", strings.Join(sortedNames(missing), ", "))
}
return json.Marshal(expanded)
}
func expandValue(value any, missing map[string]bool) any {
switch typedValue := value.(type) {
case string:
return expandString(typedValue, missing)
case []any:
for index, element := range typedValue {
typedValue[index] = expandValue(element, missing)
}
return typedValue
case map[string]any:
for key, element := range typedValue {
typedValue[key] = expandValue(element, missing)
}
return typedValue
default:
return value
}
}
func expandString(text string, missing map[string]bool) string {
return environmentReferencePattern.ReplaceAllStringFunc(text, func(reference string) string {
name := environmentReferencePattern.FindStringSubmatch(reference)[1]
environmentValue, isSet := os.LookupEnv(name)
if !isSet || environmentValue == "" {
missing[name] = true
}
return environmentValue
})
}
func sortedNames(names map[string]bool) []string {
sorted := make([]string, 0, len(names))
for name := range names {
sorted = append(sorted, name)
}
sort.Strings(sorted)
return sorted
}