config
config copied to clipboard
Breaking change for NewProviderGroup in 1.3.0?
I'm reading a single config file where I want to override values based on priority. My initial code below worked with 1.1.0, but does not with 1.3.0. I understand that some functions have been marked deprecated in 1.3.0, but the README explicitly states that "no breaking changes will be made in the 1.x series of releases".
I see that the new NewYAML
function can take multiple files with priority, but I want to read and merge a single file. Is there another way to do this in 1.3.0?
Reproduction:
config.yml file:
---
default:
foo: Base
other:
foo: Override
main.go:
package main
import (
"fmt"
"go.uber.org/config"
)
func main() {
var conf struct {
Foo string `yaml:"foo"`
}
provider, err := fromSpecificEnvs("config.yml", "default", "other")
if err != nil {
panic(err)
}
if err := provider.Get(config.Root).Populate(&conf); err != nil {
panic(err)
}
fmt.Printf("Foo: %q\n", conf.Foo)
}
func fromSpecificEnvs(filepath string, envs ...string) (config.Provider, error) {
baseProvider, err := config.NewYAMLProviderFromFiles(filepath)
if err != nil {
return nil, fmt.Errorf("error parsing config file: %v", err)
}
var subProviders []config.Provider
for _, env := range envs {
sp := config.NewScopedProvider(env, baseProvider)
subProviders = append(subProviders, sp)
}
return config.NewProviderGroup("config", subProviders...)
}
Result using 1.1.0:
Foo: "Override"
Result using 1.3.0:
Foo: ""
Any suggestions on what I'm doing wrong/how to adjust?
@tormoder Apologies for a long turn-around. This seems to have slipped under the cracks.
It's not entirely clear what you are trying to do since you're doing overrides in the same file. I can only assume that you have some sort of a base configuration object and you introduce new flavors as you go along. If that is the case, you can use YAML itself, rather than relying on the config library.
The Go yaml parser supports anchors as far as I can tell (although I've never used it in any meaningful capacity).
Here is an example.
Config file that has an object with base values and a,b that inherit and override values.
❯ cat config.yaml
base: &base
foo: bar
herp: derp
a:
<<: *base
foo: baz
b:
<<: *base
herp: NOPE
❯ cat main.go
package main
import (
"fmt"
"go.uber.org/config"
)
func main() {
type obj struct {
Foo string `yaml:"foo"`
Herp string `yaml:"herp"`
}
var conf struct {
A obj `yaml:"a"`
B obj `yaml:"b"`
}
provider, err := config.NewYAMLProviderFromFiles("config.yaml")
if err != nil {
panic(err)
}
if err := provider.Get(config.Root).Populate(&conf); err != nil {
panic(err)
}
fmt.Println("A >>", conf.A)
fmt.Println("B >>", conf.B)
}
As you can see running it produces the correct A,B structs that contain the override values, and the inheritance from default.
❯ go run main.go
A >> {baz derp}
B >> {bar NOPE}
Perhaps that is what you are looking for?