package config import ( "fmt" "github.com/rs/zerolog" "github.com/spf13/viper" "go.uber.org/fx" "sneak.berlin/go/directory/internal/globals" "sneak.berlin/go/directory/internal/logger" // spooky action at a distance! // this populates the environment // from a ./.env file automatically // for development configuration. // .env contents should be things like // `DBURL=postgres://user:pass@.../` // (without the backticks, of course) _ "github.com/joho/godotenv/autoload" ) type ConfigParams struct { fx.In Globals *globals.Globals Logger *logger.Logger } type Config struct { DBURL string Debug bool MaintenanceMode bool DevelopmentMode bool DevAdminUsername string DevAdminPassword string MetricsPassword string MetricsUsername string Port int SentryDSN string params *ConfigParams log *zerolog.Logger } func New(lc fx.Lifecycle, params ConfigParams) (*Config, error) { log := params.Logger.Get() name := params.Globals.Appname viper.SetConfigName(name) viper.SetConfigType("yaml") // path to look for the config file in: viper.AddConfigPath(fmt.Sprintf("/etc/%s", name)) // call multiple times to add many search paths: viper.AddConfigPath(fmt.Sprintf("$HOME/.config/%s", name)) // viper.SetEnvPrefix(strings.ToUpper(s.appname)) viper.AutomaticEnv() viper.SetDefault("DEBUG", "false") viper.SetDefault("MAINTENANCE_MODE", "false") viper.SetDefault("DEVELOPMENT_MODE", "false") viper.SetDefault("DEV_ADMIN_USERNAME", "") viper.SetDefault("DEV_ADMIN_PASSWORD", "") viper.SetDefault("PORT", "8080") viper.SetDefault("DBURL", "") viper.SetDefault("SENTRY_DSN", "") viper.SetDefault("METRICS_USERNAME", "") viper.SetDefault("METRICS_PASSWORD", "") if err := viper.ReadInConfig(); err != nil { if _, ok := err.(viper.ConfigFileNotFoundError); ok { // Config file not found; ignore error if desired } else { // Config file was found but another error was produced log.Panic(). Err(err). Msg("config file malformed") } } s := &Config{ DBURL: viper.GetString("DBURL"), Debug: viper.GetBool("debug"), Port: viper.GetInt("PORT"), SentryDSN: viper.GetString("SENTRY_DSN"), MaintenanceMode: viper.GetBool("MAINTENANCE_MODE"), DevelopmentMode: viper.GetBool("DEVELOPMENT_MODE"), DevAdminUsername: viper.GetString("DEV_ADMIN_USERNAME"), DevAdminPassword: viper.GetString("DEV_ADMIN_PASSWORD"), MetricsUsername: viper.GetString("METRICS_USERNAME"), MetricsPassword: viper.GetString("METRICS_PASSWORD"), log: log, params: ¶ms, } if s.Debug { params.Logger.EnableDebugLogging() s.log = params.Logger.Get() } return s, nil }