1
0
Fork 0
forked from 0x2E/fusion
fusion/conf/conf.go
Michael Lynch 41784ec681 Make conf settings read-only
It feels a bit messy that the entire program has write access to the configuration as a shared global object. Shared globals make it more difficult to reason about a program's behavior.

This rewrite reduces the problem a bit by making the shared global state read-only after the client calls conf.Load.
2025-01-02 20:24:36 -05:00

70 lines
1.5 KiB
Go

package conf
import (
"errors"
"fmt"
"log"
"os"
"github.com/caarlos0/env/v11"
"github.com/joho/godotenv"
)
const (
Debug = false
dotEnvFilename = ".env"
)
var conf struct {
Host string `env:"HOST" envDefault:"0.0.0.0"`
Port int `env:"PORT" envDefault:"8080"`
Password string `env:"PASSWORD"`
DB string `env:"DB" envDefault:"fusion.db"`
SecureCookie bool `env:"SECURE_COOKIE" envDefault:"false"`
TLSCert string `env:"TLS_CERT"`
TLSKey string `env:"TLS_KEY"`
}
func Host() string { return conf.Host }
func Port() int { return conf.Port }
func Password() string { return conf.Password }
func DB() string { return conf.DB }
func SecureCookie() bool { return conf.SecureCookie }
func TLSCert() string { return conf.TLSCert }
func TLSKey() string { return conf.TLSKey }
func Load() {
if err := godotenv.Load(dotEnvFilename); err != nil {
if !os.IsNotExist(err) {
panic(err)
}
log.Printf("no configuration file found at %s", dotEnvFilename)
} else {
log.Printf("read configuration from %s", dotEnvFilename)
}
if err := env.Parse(&conf); err != nil {
panic(err)
}
if err := validate(); err != nil {
panic(err)
}
if Debug {
fmt.Println(conf)
}
}
func validate() error {
if conf.Password == "" {
return errors.New("password is required")
}
if (conf.TLSCert == "") != (conf.TLSKey == "") {
return errors.New("missing TLS cert or key file")
}
if conf.TLSCert != "" {
conf.SecureCookie = true
}
return nil
}