package global import ( "errors" "fmt" "os" "strconv" "github.com/jmoiron/sqlx" "github.com/pelletier/go-toml/v2" ) type ( dbConfig struct { Host string `toml:"host"` Port int64 `toml:"port"` Name string `toml:"name"` User string `toml:"user"` Pass string `toml:"pass"` } discordConfig struct { AdminID string `toml:"admin_id" comment:"NOTE: admin_id to be deprecated in favour of local accounts and SSO."` ClientID string `toml:"client_id"` Secret string `toml:"secret"` } config struct { BaseUrl string `toml:"base_url" comment:"Used for OAuth redirects."` Port int64 `toml:"port"` DataDirectory string `toml:"data_dir"` DB dbConfig `toml:"db"` Discord discordConfig `toml:"discord"` } ) var Config = func() config { configFile := os.Getenv("ARIMELODY_CONFIG") if configFile == "" { configFile = "config.toml" } config := config{ BaseUrl: "https://arimelody.me", Port: 8080, DB: dbConfig{ Host: "127.0.0.1", Port: 5432, User: "arimelody", Name: "arimelody", }, } data, err := os.ReadFile(configFile) if err != nil { configOut, _ := toml.Marshal(&config) os.WriteFile(configFile, configOut, os.ModePerm) fmt.Printf( "A default config.toml has been created. " + "Please configure before running again!\n") os.Exit(0) } err = toml.Unmarshal([]byte(data), &config) if err != nil { fmt.Fprintf(os.Stderr, "FATAL: Failed to parse configuration file: %v\n", err) os.Exit(1) } err = handleConfigOverrides(&config) if err != nil { fmt.Fprintf(os.Stderr, "FATAL: Failed to parse environment variable %v\n", err) os.Exit(1) } return config }() func handleConfigOverrides(config *config) error { var err error if env, has := os.LookupEnv("ARIMELODY_BASE_URL"); has { config.BaseUrl = env } if env, has := os.LookupEnv("ARIMELODY_PORT"); has { config.Port, err = strconv.ParseInt(env, 10, 0) if err != nil { return errors.New("ARIMELODY_PORT: " + err.Error()) } } if env, has := os.LookupEnv("ARIMELODY_DATA_DIR"); has { config.DataDirectory = env } if env, has := os.LookupEnv("ARIMELODY_DB_HOST"); has { config.DB.Host = env } if env, has := os.LookupEnv("ARIMELODY_DB_PORT"); has { config.DB.Port, err = strconv.ParseInt(env, 10, 0) if err != nil { return errors.New("ARIMELODY_DB_PORT: " + err.Error()) } } if env, has := os.LookupEnv("ARIMELODY_DB_NAME"); has { config.DB.Name = env } if env, has := os.LookupEnv("ARIMELODY_DB_USER"); has { config.DB.User = env } if env, has := os.LookupEnv("ARIMELODY_DB_PASS"); has { config.DB.Pass = env } if env, has := os.LookupEnv("ARIMELODY_DISCORD_ADMIN_ID"); has { config.Discord.AdminID = env } if env, has := os.LookupEnv("ARIMELODY_DISCORD_CLIENT_ID"); has { config.Discord.ClientID = env } if env, has := os.LookupEnv("ARIMELODY_DISCORD_SECRET"); has { config.Discord.Secret = env } return nil } var DB *sqlx.DB