package config import ( "fmt" "os" "strings" "github.com/BurntSushi/toml" ) type Config struct { Server ServerConfig `toml:"server"` Datasource DatasourceConfig `toml:"datasource"` } type ServerConfig struct { Listen string `toml:"listen"` StorageDir string `toml:"storage_dir"` } type DatasourceConfig struct { Stub StubConfig `toml:"stub"` EPICS EPICSConfig `toml:"epics"` PVA PVAConfig `toml:"pva"` Synthetic SyntheticConfig `toml:"synthetic"` } type StubConfig struct { Enabled bool `toml:"enabled"` } type EPICSConfig struct { Enabled bool `toml:"enabled"` CAAddrList string `toml:"ca_addr_list"` ArchiveURL string `toml:"archive_url"` ChannelFinderURL string `toml:"channel_finder_url"` PVNames []string `toml:"pv_names"` } type PVAConfig struct { Enabled bool `toml:"enabled"` AddrList []string `toml:"addr_list"` } type SyntheticConfig struct { Enabled bool `toml:"enabled"` } func Default() Config { return Config{ Server: ServerConfig{ Listen: ":8080", StorageDir: "./interfaces", }, Datasource: DatasourceConfig{ Stub: StubConfig{Enabled: true}, EPICS: EPICSConfig{Enabled: true}, PVA: PVAConfig{Enabled: true}, Synthetic: SyntheticConfig{Enabled: true}, }, } } // Load reads a TOML config file and applies environment variable overrides. // Environment variables use the prefix UOPI_ with __ as separator, e.g. // UOPI_SERVER_LISTEN=":9090". func Load(path string) (Config, error) { cfg := Default() if path != "" { if _, err := toml.DecodeFile(path, &cfg); err != nil { return cfg, fmt.Errorf("reading config %q: %w", path, err) } } applyEnv(&cfg) return cfg, nil } func applyEnv(cfg *Config) { if v := env("UOPI_SERVER_LISTEN"); v != "" { cfg.Server.Listen = v } if v := env("UOPI_SERVER_STORAGE_DIR"); v != "" { cfg.Server.StorageDir = v } if v := env("UOPI_EPICS_CA_ADDR_LIST"); v != "" { cfg.Datasource.EPICS.CAAddrList = v } if v := env("UOPI_EPICS_ARCHIVE_URL"); v != "" { cfg.Datasource.EPICS.ArchiveURL = v } if v := env("UOPI_EPICS_CHANNEL_FINDER_URL"); v != "" { cfg.Datasource.EPICS.ChannelFinderURL = v } if v := env("EPICS_PVA_ADDR_LIST"); v != "" { cfg.Datasource.PVA.AddrList = strings.Fields(v) } } func env(key string) string { return strings.TrimSpace(os.Getenv(key)) }