83 lines
2 KiB
Go
83 lines
2 KiB
Go
package config
|
|
|
|
import (
|
|
"fmt"
|
|
"os"
|
|
"path/filepath"
|
|
|
|
"github.com/BurntSushi/toml"
|
|
)
|
|
|
|
// Load baut die Config aus allen Schichten auf (spätere gewinnt): Defaults,
|
|
// ~/.config/nub/config.toml, <repoRoot>/.nub/config.toml, NUB_*-Umgebungs-
|
|
// variablen. Flags folgen erst, wenn cmd/nub welche anbietet.
|
|
func Load(repoRoot string) (Config, error) {
|
|
cfg := Defaults()
|
|
|
|
if home, err := os.UserHomeDir(); err == nil {
|
|
if err := mergeFile(&cfg, filepath.Join(home, ".config", "nub", "config.toml")); err != nil {
|
|
return Config{}, err
|
|
}
|
|
}
|
|
if err := mergeFile(&cfg, filepath.Join(repoRoot, ".nub", "config.toml")); err != nil {
|
|
return Config{}, err
|
|
}
|
|
|
|
applyEnvOverrides(&cfg)
|
|
|
|
if cfg.Version != 1 {
|
|
return Config{}, fmt.Errorf("config: unsupported version %d (nub unterstützt nur version 1)", cfg.Version)
|
|
}
|
|
return cfg, nil
|
|
}
|
|
|
|
func mergeFile(cfg *Config, path string) error {
|
|
if _, err := os.Stat(path); err != nil {
|
|
return nil // Datei fehlt -> Schicht wird übersprungen
|
|
}
|
|
if _, err := toml.DecodeFile(path, cfg); err != nil {
|
|
return fmt.Errorf("config: %s: %w", path, err)
|
|
}
|
|
return nil
|
|
}
|
|
|
|
// applyEnvOverrides deckt den kleinen, konkreten Satz an NUB_*-Variablen ab,
|
|
// der v1 als letzte Schicht vor den (noch nicht existierenden) Flags dient.
|
|
func applyEnvOverrides(cfg *Config) {
|
|
if v := os.Getenv("NUB_MODEL"); v != "" {
|
|
cfg.Model.Default = v
|
|
}
|
|
|
|
baseURL := os.Getenv("NUB_BASE_URL")
|
|
apiKey := firstNonEmpty(os.Getenv("NUB_API_KEY"), os.Getenv("OPENAI_API_KEY"))
|
|
if baseURL == "" && apiKey == "" {
|
|
return
|
|
}
|
|
|
|
idx := -1
|
|
for i, e := range cfg.Endpoints {
|
|
if e.Name == cfg.Model.Endpoint {
|
|
idx = i
|
|
break
|
|
}
|
|
}
|
|
if idx == -1 {
|
|
cfg.Endpoints = append(cfg.Endpoints, Endpoint{Name: cfg.Model.Endpoint})
|
|
idx = len(cfg.Endpoints) - 1
|
|
}
|
|
if baseURL != "" {
|
|
cfg.Endpoints[idx].BaseURL = baseURL
|
|
}
|
|
if apiKey != "" {
|
|
cfg.Endpoints[idx].APIKey = apiKey
|
|
}
|
|
}
|
|
|
|
func firstNonEmpty(vals ...string) string {
|
|
for _, v := range vals {
|
|
if v != "" {
|
|
return v
|
|
}
|
|
}
|
|
return ""
|
|
}
|