diff --git a/internal/config/config.go b/internal/config/config.go new file mode 100644 index 00000000..4f69369e --- /dev/null +++ b/internal/config/config.go @@ -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) + } +}