131 lines
3.2 KiB
Go
131 lines
3.2 KiB
Go
package config
|
|
|
|
import (
|
|
"encoding/json"
|
|
"fmt"
|
|
"os"
|
|
"path/filepath"
|
|
"strconv"
|
|
)
|
|
|
|
type Config struct {
|
|
Server ServerConfig `json:"server"`
|
|
Database DatabaseConfig `json:"database"`
|
|
Content ContentConfig `json:"content"`
|
|
Auth AuthConfig `json:"auth"`
|
|
Email EmailConfig `json:"email"`
|
|
LogLevel string `json:"logLevel"`
|
|
DevMode bool `json:"devMode"`
|
|
}
|
|
|
|
type ServerConfig struct {
|
|
Addr string `json:"addr"`
|
|
}
|
|
|
|
type DatabaseConfig struct {
|
|
Path string `json:"path"`
|
|
PrimaryURL string `json:"primaryUrl"`
|
|
AuthToken string `json:"authToken"`
|
|
}
|
|
|
|
type ContentConfig struct {
|
|
SourceDir string `json:"sourceDir"`
|
|
StoreDir string `json:"storeDir"`
|
|
}
|
|
|
|
type AuthConfig struct {
|
|
PublicOrigin string `json:"publicOrigin"`
|
|
}
|
|
|
|
type EmailConfig struct {
|
|
SMTPHost string `json:"smtpHost"`
|
|
SMTPPort int `json:"smtpPort"`
|
|
From string `json:"from"`
|
|
}
|
|
|
|
func Default() Config {
|
|
return Config{
|
|
Server: ServerConfig{
|
|
Addr: ":8080",
|
|
},
|
|
Database: DatabaseConfig{
|
|
Path: filepath.Join("..", "..", "data", "db.sqlite"),
|
|
},
|
|
Content: ContentConfig{
|
|
SourceDir: filepath.Join("..", "..", "content"),
|
|
StoreDir: filepath.Join("..", "..", "data", "files"),
|
|
},
|
|
Auth: AuthConfig{
|
|
PublicOrigin: "http://localhost:8080",
|
|
},
|
|
Email: EmailConfig{
|
|
SMTPHost: "localhost",
|
|
SMTPPort: 1025,
|
|
From: "notifications@cairnquire.local",
|
|
},
|
|
LogLevel: "INFO",
|
|
}
|
|
}
|
|
|
|
func Load() (Config, error) {
|
|
cfg := Default()
|
|
|
|
if configPath := os.Getenv("CAIRNQUIRE_CONFIG"); configPath != "" {
|
|
if err := loadFile(configPath, &cfg); err != nil {
|
|
return Config{}, err
|
|
}
|
|
}
|
|
|
|
overrideString(&cfg.Server.Addr, "CAIRNQUIRE_SERVER_ADDR")
|
|
if port := os.Getenv("PORT"); port != "" {
|
|
cfg.Server.Addr = ":" + port
|
|
}
|
|
overrideString(&cfg.Database.Path, "CAIRNQUIRE_DATABASE_PATH")
|
|
overrideString(&cfg.Database.PrimaryURL, "CAIRNQUIRE_DATABASE_PRIMARY_URL")
|
|
overrideString(&cfg.Database.AuthToken, "CAIRNQUIRE_DATABASE_AUTH_TOKEN")
|
|
overrideString(&cfg.Content.SourceDir, "CAIRNQUIRE_CONTENT_SOURCE_DIR")
|
|
overrideString(&cfg.Content.StoreDir, "CAIRNQUIRE_CONTENT_STORE_DIR")
|
|
overrideString(&cfg.Auth.PublicOrigin, "CAIRNQUIRE_PUBLIC_ORIGIN")
|
|
overrideString(&cfg.Email.SMTPHost, "CAIRNQUIRE_EMAIL_SMTP_HOST")
|
|
if port := os.Getenv("CAIRNQUIRE_EMAIL_SMTP_PORT"); port != "" {
|
|
if p, err := strconv.Atoi(port); err == nil {
|
|
cfg.Email.SMTPPort = p
|
|
}
|
|
}
|
|
overrideString(&cfg.Email.From, "CAIRNQUIRE_EMAIL_FROM")
|
|
overrideString(&cfg.LogLevel, "CAIRNQUIRE_LOG_LEVEL")
|
|
if devMode := os.Getenv("CAIRNQUIRE_DEV_MODE"); devMode != "" {
|
|
parsed, err := strconv.ParseBool(devMode)
|
|
if err != nil {
|
|
return Config{}, fmt.Errorf("parse CAIRNQUIRE_DEV_MODE: %w", err)
|
|
}
|
|
cfg.DevMode = parsed
|
|
}
|
|
|
|
if cfg.Server.Addr == "" {
|
|
return Config{}, fmt.Errorf("server.addr must not be empty")
|
|
}
|
|
|
|
return cfg, nil
|
|
}
|
|
|
|
func loadFile(path string, cfg *Config) error {
|
|
file, err := os.Open(path)
|
|
if err != nil {
|
|
return fmt.Errorf("open config file %q: %w", path, err)
|
|
}
|
|
defer file.Close()
|
|
|
|
if err := json.NewDecoder(file).Decode(cfg); err != nil {
|
|
return fmt.Errorf("decode config file %q: %w", path, err)
|
|
}
|
|
|
|
return nil
|
|
}
|
|
|
|
func overrideString(target *string, key string) {
|
|
if value := os.Getenv(key); value != "" {
|
|
*target = value
|
|
}
|
|
}
|