/
cloudservices
/
common
Обзор
Документация
Войти
/
cloudservices
/
common
Код
Запросы
0
Задачи
Вики
Пакеты
0
Релизы
0
CI/CD
Аналитика
master
config.go
111 строк
2 KB
Ivan
init
26 июл 2026, 11:34
26 июл 2026, 11:34
46b4481
Код
Авторство
О чём код?
package common import ( "os" "path/filepath" "regexp" "go.yaml.in/yaml/v2" ) var envVarPattern = regexp.MustCompile(`\$\{([^}]+)\}|\$(\w+)`) func LoadConfig(src string, dst any) error { path, err := filepath.Abs(src) if err != nil { return err } data, err := os.ReadFile(path) if err != nil { return err } // Unmarshal into a generic map first to extract env_file before other fields. var raw map[string]any if err := yaml.Unmarshal(data, &raw); err != nil { return err } // Load .env file if specified (before expanding env vars). if envFile, ok := raw["env_file"].(string); ok && envFile != "" { envPath := envFile if !filepath.IsAbs(envPath) { envPath = filepath.Join(filepath.Dir(path), envFile) } if err := LoadDotEnv(envPath); err != nil { return err } } // Expand env vars in all string values. expandStringMap(raw) // Re-marshal to YAML and unmarshal into Config. expandedData, err := yaml.Marshal(raw) if err != nil { return err } if err := yaml.Unmarshal(expandedData, dst); err != nil { return err } return nil } // expandStringMap recursively expands env vars in all string values of a map. func expandStringMap(m map[string]interface{}) { for k, v := range m { switch val := v.(type) { case string: m[k] = expandEnv(val) case map[string]interface{}: expandStringMap(val) case map[interface{}]interface{}: for key, item := range val { if s, ok := item.(string); ok { val[key] = expandEnv(s) } else if nested, ok := item.(map[interface{}]interface{}); ok { expandStringMapInterface(nested) } } case []interface{}: for i, item := range val { if s, ok := item.(string); ok { val[i] = expandEnv(s) } } } } } func expandStringMapInterface(m map[interface{}]interface{}) { for key, value := range m { switch val := value.(type) { case string: m[key] = expandEnv(val) case map[interface{}]interface{}: expandStringMapInterface(val) case []interface{}: for i, item := range val { if s, ok := item.(string); ok { val[i] = expandEnv(s) } } } } } func expandEnv(s string) string { return envVarPattern.ReplaceAllStringFunc(s, func(match string) string { // ${VAR} if len(match) > 3 && match[1] == '{' { name := match[2 : len(match)-1] return os.Getenv(name) } // $VAR name := match[1:] return os.Getenv(name) }) }