~bigbes/huntsman

ref: 783841b91eafd678cb3895cfcc8dfd89f290ece7 huntsman/internal/config/loader.go -rw-r--r-- 1.2 KiB
783841b9 — Eugene Blikh Initial commit: multi-provider search router 6 days ago
                                                                                
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
package config

import (
	"strings"
	"time"

	"github.com/spf13/viper"
	"go.bigb.es/auxilia/culpa"
)

// Load reads YAML config from path, overlays APP_* env vars, and validates.
//
// Strict mode is enabled — unknown keys cause a load failure rather than
// being silently ignored, which catches typos in production config.
func Load(path string) (*Config, error) {
	v := viper.New()
	v.SetConfigFile(path)
	v.SetConfigType("yaml")

	v.SetEnvPrefix("APP")
	v.SetEnvKeyReplacer(strings.NewReplacer(".", "_"))
	v.AutomaticEnv()

	// Defaults — keep these in sync with config.example.yaml.
	v.SetDefault("server.host", "0.0.0.0")
	v.SetDefault("server.port", 8080)
	v.SetDefault("server.read_timeout", 15*time.Second)
	v.SetDefault("server.write_timeout", 15*time.Second)
	v.SetDefault("log.level", "info")
	v.SetDefault("log.format", "human")
	v.SetDefault("search.default_provider", "gh")

	if err := v.ReadInConfig(); err != nil {
		return nil, culpa.Wrap(err, "read config")
	}

	var cfg Config
	if err := v.UnmarshalExact(&cfg); err != nil {
		return nil, culpa.Wrap(err, "unmarshal config")
	}

	if err := cfg.Validate(); err != nil {
		return nil, culpa.Wrap(err, "validate config")
	}

	return &cfg, nil
}