package config import ( "fmt" "strings" "github.com/spf13/viper" ) // Load loads configuration from file and environment variables func Load(configPath string) (*Config, error) { v := viper.New() // Set config file if provided if configPath != "" { v.SetConfigFile(configPath) } else { // Look for config.yaml in current directory and /etc/gohoarder v.SetConfigName("config") v.SetConfigType("yaml") v.AddConfigPath(".") v.AddConfigPath("/etc/gohoarder") v.AddConfigPath("$HOME/.gohoarder") } // Set environment variable prefix v.SetEnvPrefix("GOHOARDER") v.SetEnvKeyReplacer(strings.NewReplacer(".", "_")) v.AutomaticEnv() // Read config file if err := v.ReadInConfig(); err != nil { // If no config file found, use defaults if _, ok := err.(viper.ConfigFileNotFoundError); !ok { return nil, fmt.Errorf("failed to read config file: %w", err) } } // Start with defaults cfg := Default() // Unmarshal into config struct if err := v.Unmarshal(cfg); err != nil { return nil, fmt.Errorf("failed to unmarshal config: %w", err) } // Validate configuration if err := cfg.Validate(); err != nil { return nil, fmt.Errorf("config validation failed: %w", err) } return cfg, nil }