feat(skel): config loader with YAML + SMARTMUSIC_* env overlay

This commit is contained in:
2026-04-18 21:19:50 +00:00
parent be181f8245
commit d2d8612e06
+67
View File
@@ -0,0 +1,67 @@
package config
import (
"fmt"
"os"
"strings"
"gopkg.in/yaml.v3"
)
type Config struct {
Server ServerConfig `yaml:"server"`
Database DatabaseConfig `yaml:"database"`
Log LogConfig `yaml:"log"`
}
type ServerConfig struct {
Address string `yaml:"address"`
}
type DatabaseConfig struct {
URL string `yaml:"url"`
}
type LogConfig struct {
Level string `yaml:"level"`
Format string `yaml:"format"`
}
func Default() Config {
return Config{
Server: ServerConfig{Address: ":4533"},
Database: DatabaseConfig{URL: ""},
Log: LogConfig{Level: "info", Format: "text"},
}
}
func Load(path string) (Config, error) {
cfg := Default()
if path != "" {
data, err := os.ReadFile(path)
if err != nil {
if !os.IsNotExist(err) {
return cfg, fmt.Errorf("read config %q: %w", path, err)
}
} else if err := yaml.Unmarshal(data, &cfg); err != nil {
return cfg, fmt.Errorf("parse config %q: %w", path, err)
}
}
applyEnv(&cfg)
return cfg, nil
}
func applyEnv(cfg *Config) {
if v, ok := os.LookupEnv("SMARTMUSIC_SERVER_ADDRESS"); ok {
cfg.Server.Address = v
}
if v, ok := os.LookupEnv("SMARTMUSIC_DATABASE_URL"); ok {
cfg.Database.URL = v
}
if v, ok := os.LookupEnv("SMARTMUSIC_LOG_LEVEL"); ok {
cfg.Log.Level = strings.ToLower(v)
}
if v, ok := os.LookupEnv("SMARTMUSIC_LOG_FORMAT"); ok {
cfg.Log.Format = strings.ToLower(v)
}
}