package config import ( "errors" "fmt" "strings" "github.com/spf13/viper" ) func defaults(v *viper.Viper) { v.SetDefault("server.host", "0.0.0.0") v.SetDefault("server.port", 10086) v.SetDefault("database.driver", "sqlite3") v.SetDefault("database.path", "data/mygo.db") v.SetDefault("storage.driver", "local") v.SetDefault("storage.local.path", "data/files") v.SetDefault("jwt.secret", "dev-secret-do-not-use-in-production") v.SetDefault("jwt.access_ttl", "15m") v.SetDefault("jwt.refresh_ttl", "168h") } func New() *viper.Viper { v := viper.New() v.SetEnvPrefix("MYGO") v.SetEnvKeyReplacer(strings.NewReplacer(".", "_")) v.AutomaticEnv() defaults(v) return v } func Load(v *viper.Viper, cfgFile string) (*Config, error) { if cfgFile != "" { v.SetConfigFile(cfgFile) } else { v.SetConfigName("config") v.SetConfigType("yaml") v.AddConfigPath(".") } if err := v.ReadInConfig(); err != nil { var notFound viper.ConfigFileNotFoundError if !errors.As(err, ¬Found) { return nil, fmt.Errorf("read config: %w", err) } } var cfg Config if err := v.Unmarshal(&cfg); err != nil { return nil, fmt.Errorf("unmarshal config: %w", err) } if err := cfg.Validate(); err != nil { return nil, fmt.Errorf("validate config: %w", err) } return &cfg, nil }