Add configuration and CLI foundation
This commit is contained in:
68
internal/config/load.go
Normal file
68
internal/config/load.go
Normal file
@@ -0,0 +1,68 @@
|
||||
package config
|
||||
|
||||
import (
|
||||
"errors"
|
||||
"fmt"
|
||||
"os"
|
||||
|
||||
"gopkg.in/yaml.v3"
|
||||
)
|
||||
|
||||
type LoadOptions struct {
|
||||
Path string
|
||||
Units string
|
||||
Timezone string
|
||||
Output string
|
||||
}
|
||||
|
||||
func Load(opts LoadOptions) (Config, error) {
|
||||
cfg := Defaults()
|
||||
|
||||
path := opts.Path
|
||||
if path == "" {
|
||||
path = DefaultPath
|
||||
}
|
||||
|
||||
if err := mergeFile(&cfg, path); err != nil {
|
||||
if opts.Path != "" || !errors.Is(err, os.ErrNotExist) {
|
||||
return Config{}, err
|
||||
}
|
||||
}
|
||||
|
||||
if opts.Units != "" {
|
||||
cfg.WeatherAPI.Units = opts.Units
|
||||
}
|
||||
if opts.Timezone != "" {
|
||||
cfg.WeatherAPI.Timezone = opts.Timezone
|
||||
}
|
||||
if opts.Output != "" {
|
||||
cfg.Reports.OutputDir = opts.Output
|
||||
}
|
||||
|
||||
if err := Validate(cfg); err != nil {
|
||||
return Config{}, err
|
||||
}
|
||||
|
||||
return cfg, nil
|
||||
}
|
||||
|
||||
func LoadFile(path string) (Config, error) {
|
||||
return Load(LoadOptions{Path: path})
|
||||
}
|
||||
|
||||
func mergeFile(cfg *Config, path string) error {
|
||||
data, err := os.ReadFile(path)
|
||||
if err != nil {
|
||||
return fmt.Errorf("read config %q: %w", path, err)
|
||||
}
|
||||
if err := yaml.Unmarshal(data, cfg); err != nil {
|
||||
return fmt.Errorf("parse config %q: %w", path, err)
|
||||
}
|
||||
if cfg.MissingSource.Sources == nil {
|
||||
cfg.MissingSource.Sources = map[string]MissingSourcePolicy{}
|
||||
}
|
||||
if cfg.Reports.Paths == nil {
|
||||
cfg.Reports.Paths = map[string]string{}
|
||||
}
|
||||
return nil
|
||||
}
|
||||
Reference in New Issue
Block a user