package config import ( "fmt" "os" "path/filepath" "strings" "github.com/spf13/viper" ) // Config holds the application configuration type Config struct { AppName string `mapstructure:"APP_NAME"` AppDescription string `mapstructure:"APP_DESCRIPTION"` AppVersion string `mapstructure:"APP_VERSION"` ServerPort string `mapstructure:"SERVER_PORT"` DBPath string `mapstructure:"DB_PATH"` DBName string `mapstructure:"DB_NAME"` } // LoadConfig reads the configuration from environment variables or config file func LoadConfig() (*Config, error) { // Set default values config := &Config{ AppName: "Go Todo App", AppDescription: "A simple Todo application API built with Go, Gin and SQLite", AppVersion: "0.1.0", ServerPort: "8000", DBPath: "/app/storage/db", DBName: "db.sqlite", } // Set up viper v := viper.New() v.SetConfigName("config") v.SetConfigType("yaml") v.AddConfigPath(".") v.AddConfigPath("./config") // Match environment variables with config fields v.SetEnvKeyReplacer(strings.NewReplacer(".", "_")) v.AutomaticEnv() // Try to read from config file (optional) if err := v.ReadInConfig(); err != nil { if _, ok := err.(viper.ConfigFileNotFoundError); !ok { return nil, fmt.Errorf("error reading config file: %v", err) } } // Override config from environment variables if err := v.Unmarshal(config); err != nil { return nil, fmt.Errorf("error unmarshaling config: %v", err) } // Ensure DB directory exists dbDir := config.DBPath if err := os.MkdirAll(dbDir, 0755); err != nil { return nil, fmt.Errorf("error creating DB directory: %v", err) } return config, nil } // GetDatabaseURL returns the full SQLite database connection string func (c *Config) GetDatabaseURL() string { return fmt.Sprintf("file:%s", filepath.Join(c.DBPath, c.DBName)) }