package config import ( "errors" "fmt" "log/slog" "strings" "github.com/spf13/cobra" "github.com/spf13/viper" ) var ( CfgFile string Verbose int Overwrite bool ServerName string Mediatype MediaType Config CliConfig ServerConfig ServerConfiguration DryRun bool FileName string ) const ( mediaTypeMedia MediaType = "media" mediaTypeVideo MediaType = "video" mediaTypeLofi MediaType = "lofi" ) type MediaType string func (e *MediaType) String() string { return string(*e) } func (e *MediaType) Set(v string) error { switch v { case "media", "video", "lofi": *e = MediaType(v) return nil default: return errors.New(`must be one of "media", "video", "lofi"`) } } func (e *MediaType) Type() string { return "MediaType" } func myEnumCompletion(cmd *cobra.Command, args []string, toComplete string) ([]string, cobra.ShellCompDirective) { return []string{ "media\thelp text for media", "video\thelp text for video", "lofi\thelp text for lofi", }, cobra.ShellCompDirectiveDefault } type Server struct { Url string `mapstructure:"url"` Username string `mapstructure:"username"` Password string `mapstructure:"password"` } type Database struct { Type string `mapstructure:"type" validate:"required"` Path string `mapstructure:"path" validate:"required"` Host string `mapstructure:"host" validate:"required"` Name string `mapstructure:"name" validate:"required"` Port int `mapstructure:"port" validate:"required"` Password string `mapstructure:"password" validate:"required"` User string `mapstructure:"user" validate:"required"` } type CliConfig struct { ApiVersion string Server map[string]Server `mapstructure:"server"` DB Database `mapstructure:"db"` } type ServerConfiguration struct { Server struct { Port int `mapstructure:"port" validate:"required"` Host string `mapstructure:"host"` } `mapstructure:"server"` DB Database `mapstructure:"db"` Gin struct { Mode string `mapstructure:"mode" validate:"required"` } `mapstructure:"gin"` ApiSecret []byte `mapstructure:"api_secret"` } func InitCliConfig() { slog.Info("InitCliConfig") if CfgFile != "" { viper.SetConfigFile(CfgFile) } else { viper.SetConfigName("kli") // without extension viper.SetConfigType("yaml") viper.AddConfigPath(".") // look for config in working directory viper.AddConfigPath("/home/tpeetz/.config") } Mediatype = mediaTypeMedia // Read the configuration file if err := viper.ReadInConfig(); err != nil { // Handle the case where config file is not found if _, ok := err.(viper.ConfigFileNotFoundError); ok { slog.Info("No config file found, using defaults") if err := viper.SafeWriteConfig(); err != nil { slog.Info("error writing config file", "error", err.Error()) } } else { slog.Info("error reading config file", "error", err.Error()) } } else { slog.Info("InitCliConfig", "Using config file: ", viper.ConfigFileUsed()) if err := viper.Unmarshal(&Config); err != nil { slog.Info("parsing of config file failed", "error", err.Error()) } } } func InitConfig() error { viper.SetConfigName("kontor-gin") viper.SetConfigType("yaml") viper.AddConfigPath(".") viper.AddConfigPath("/home/tpeetz/.config") viper.AddConfigPath("/etc/kontor") viper.SetEnvKeyReplacer(strings.NewReplacer(".", "_")) viper.AutomaticEnv() viper.SetDefault("db.type", "postgres") viper.SetDefault("db.host", "localhost") viper.SetDefault("db.port", 5432) viper.SetDefault("db.name", "kontor") viper.SetDefault("db.user", "kontor") viper.SetDefault("db.password", "kontor") viper.SetDefault("db.path", "data/kontor.db") viper.SetDefault("server.port", 8550) viper.SetDefault("gin.mode", "release") // Read the config file if err := viper.ReadInConfig(); err != nil { // Handle the case where config file is not found if _, ok := err.(viper.ConfigFileNotFoundError); ok { slog.Info("No config file found, using defaults") if err := viper.SafeWriteConfig(); err != nil { slog.Info("error writing config file", "error", err.Error()) return fmt.Errorf("error writing config file: %w", err) } } else { return fmt.Errorf("error reading config file: %w", err) } } else { slog.Info("InitConfig", "Using config file: ", viper.ConfigFileUsed()) if err := viper.Unmarshal(&ServerConfig); err != nil { slog.Info("parsing of config file failed", "error", err.Error()) } } return nil }