refactor(encoding): initialize codecs per Viper

Some codecs might have options that rely on Viper in the future
(eg. key delimiter) which requires initializing codecs
for each Viper instance.

Signed-off-by: Mark Sagi-Kazar <mark.sagikazar@gmail.com>
This commit is contained in:
Mark Sagi-Kazar 2021-07-16 03:09:43 +02:00 committed by Márk Sági-Kazár
parent 38a4fbd769
commit dd62da434f
1 changed files with 53 additions and 41 deletions

View File

@ -67,47 +67,8 @@ type RemoteResponse struct {
Error error Error error
} }
var (
encoderRegistry = encoding.NewEncoderRegistry()
decoderRegistry = encoding.NewDecoderRegistry()
)
func init() { func init() {
v = New() v = New()
{
codec := yaml.Codec{}
encoderRegistry.RegisterEncoder("yaml", codec)
decoderRegistry.RegisterDecoder("yaml", codec)
encoderRegistry.RegisterEncoder("yml", codec)
decoderRegistry.RegisterDecoder("yml", codec)
}
{
codec := json.Codec{}
encoderRegistry.RegisterEncoder("json", codec)
decoderRegistry.RegisterDecoder("json", codec)
}
{
codec := toml.Codec{}
encoderRegistry.RegisterEncoder("toml", codec)
decoderRegistry.RegisterDecoder("toml", codec)
}
{
codec := hcl.Codec{}
encoderRegistry.RegisterEncoder("hcl", codec)
decoderRegistry.RegisterDecoder("hcl", codec)
encoderRegistry.RegisterEncoder("tfvars", codec)
decoderRegistry.RegisterDecoder("tfvars", codec)
}
} }
type remoteConfigFactory interface { type remoteConfigFactory interface {
@ -261,6 +222,10 @@ type Viper struct {
onConfigChange func(fsnotify.Event) onConfigChange func(fsnotify.Event)
logger Logger logger Logger
// TODO: should probably be protected with a mutex
encoderRegistry *encoding.EncoderRegistry
decoderRegistry *encoding.DecoderRegistry
} }
// New returns an initialized Viper instance. // New returns an initialized Viper instance.
@ -280,6 +245,8 @@ func New() *Viper {
v.typeByDefValue = false v.typeByDefValue = false
v.logger = jwwLogger{} v.logger = jwwLogger{}
v.resetEncoding()
return v return v
} }
@ -326,6 +293,8 @@ func NewWithOptions(opts ...Option) *Viper {
opt.apply(v) opt.apply(v)
} }
v.resetEncoding()
return v return v
} }
@ -338,6 +307,49 @@ func Reset() {
SupportedRemoteProviders = []string{"etcd", "consul", "firestore"} SupportedRemoteProviders = []string{"etcd", "consul", "firestore"}
} }
// TODO: make this lazy initialization instead
func (v *Viper) resetEncoding() {
encoderRegistry := encoding.NewEncoderRegistry()
decoderRegistry := encoding.NewDecoderRegistry()
{
codec := yaml.Codec{}
encoderRegistry.RegisterEncoder("yaml", codec)
decoderRegistry.RegisterDecoder("yaml", codec)
encoderRegistry.RegisterEncoder("yml", codec)
decoderRegistry.RegisterDecoder("yml", codec)
}
{
codec := json.Codec{}
encoderRegistry.RegisterEncoder("json", codec)
decoderRegistry.RegisterDecoder("json", codec)
}
{
codec := toml.Codec{}
encoderRegistry.RegisterEncoder("toml", codec)
decoderRegistry.RegisterDecoder("toml", codec)
}
{
codec := hcl.Codec{}
encoderRegistry.RegisterEncoder("hcl", codec)
decoderRegistry.RegisterDecoder("hcl", codec)
encoderRegistry.RegisterEncoder("tfvars", codec)
decoderRegistry.RegisterDecoder("tfvars", codec)
}
v.encoderRegistry = encoderRegistry
v.decoderRegistry = decoderRegistry
}
type defaultRemoteProvider struct { type defaultRemoteProvider struct {
provider string provider string
endpoint string endpoint string
@ -1635,7 +1647,7 @@ func (v *Viper) unmarshalReader(in io.Reader, c map[string]interface{}) error {
switch format := strings.ToLower(v.getConfigType()); format { switch format := strings.ToLower(v.getConfigType()); format {
case "yaml", "yml", "json", "toml", "hcl", "tfvars": case "yaml", "yml", "json", "toml", "hcl", "tfvars":
err := decoderRegistry.Decode(format, buf.Bytes(), c) err := v.decoderRegistry.Decode(format, buf.Bytes(), c)
if err != nil { if err != nil {
return ConfigParseError{err} return ConfigParseError{err}
} }
@ -1692,7 +1704,7 @@ func (v *Viper) marshalWriter(f afero.File, configType string) error {
c := v.AllSettings() c := v.AllSettings()
switch configType { switch configType {
case "yaml", "yml", "json", "toml", "hcl", "tfvars": case "yaml", "yml", "json", "toml", "hcl", "tfvars":
b, err := encoderRegistry.Encode(configType, c) b, err := v.encoderRegistry.Encode(configType, c)
if err != nil { if err != nil {
return ConfigMarshalError{err} return ConfigMarshalError{err}
} }