Ctrl K
ComunidadGuías…

internal/config/environment_reference.go

Rama main · réplica de lectura del repositorio original.

Archivo original ↗Preguntar a KiBot
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
}