draft unified mechanisms for loading config files

This commit is contained in:
5684185+vsariola@users.noreply.github.com 2025-05-20 19:34:45 +03:00
parent 448bc9f236
commit c1bd0b788e

42
tracker/config.go Normal file
View File

@ -0,0 +1,42 @@
package tracker
import (
"embed"
"fmt"
"io/fs"
"os"
"path/filepath"
"gopkg.in/yaml.v2"
)
func ReadConfig(embedFS embed.FS, path string, out any) (warning error) {
bytes := must(fs.ReadFile(embedFS, path)) // the file _must_ exist in the embedded fs; panic on purpose if not
if err := yaml.UnmarshalStrict(bytes, out); err != nil {
panic(err) // also, the embedded default config file _must_ be strictly valid yaml; panic if not
}
// now, try to read the user config file, overlapping the default one.
// Notice that the return values are just warnings - there's always the
// default config there so no harm done if the user config is missing or
// invalid.
configDir, err := os.UserConfigDir()
if err != nil {
return fmt.Errorf("ReadConfig %v: %v", path, err)
}
configPath := filepath.Join(configDir, "sointu", path)
bytesUser, err := os.ReadFile(configPath)
if err != nil {
return fmt.Errorf("ReadConfig %v: %v", path, err)
}
if err := yaml.Unmarshal(bytesUser, out); err != nil {
return fmt.Errorf("ReadConfig %v: %v", path, err)
}
return nil
}
func must[T any](ic T, err error) T {
if err != nil {
panic(err)
}
return ic
}