Compare commits

...

2 commits

Author SHA1 Message Date
Mark Sagi-Kazar
9568cfcfd6 fix: config type check when loading any config
Signed-off-by: Mark Sagi-Kazar <mark.sagikazar@gmail.com>
2025-03-26 18:30:02 +01:00
GuillaumeBAECHLER
fd05140cd6 fix(config): get config type from v.configType or config file ext 2025-03-26 18:30:02 +01:00
2 changed files with 36 additions and 12 deletions

View file

@ -1535,27 +1535,29 @@ func (v *Viper) MergeInConfig() error {
func ReadConfig(in io.Reader) error { return v.ReadConfig(in) } func ReadConfig(in io.Reader) error { return v.ReadConfig(in) }
func (v *Viper) ReadConfig(in io.Reader) error { func (v *Viper) ReadConfig(in io.Reader) error {
if v.configType == "" { config := make(map[string]any)
return errors.New("cannot decode configuration: config type is not set")
err := v.unmarshalReader(in, config)
if err != nil {
return err
} }
v.config = make(map[string]any) v.config = config
return v.unmarshalReader(in, v.config)
return nil
} }
// MergeConfig merges a new configuration with an existing config. // MergeConfig merges a new configuration with an existing config.
func MergeConfig(in io.Reader) error { return v.MergeConfig(in) } func MergeConfig(in io.Reader) error { return v.MergeConfig(in) }
func (v *Viper) MergeConfig(in io.Reader) error { func (v *Viper) MergeConfig(in io.Reader) error {
if v.configType == "" { config := make(map[string]any)
return errors.New("cannot decode configuration: config type is not set")
}
cfg := make(map[string]any) if err := v.unmarshalReader(in, config); err != nil {
if err := v.unmarshalReader(in, cfg); err != nil {
return err return err
} }
return v.MergeConfigMap(cfg)
return v.MergeConfigMap(config)
} }
// MergeConfigMap merges the configuration from the map given with an existing config. // MergeConfigMap merges the configuration from the map given with an existing config.
@ -1662,15 +1664,21 @@ func (v *Viper) writeConfig(filename string, force bool) error {
} }
func (v *Viper) unmarshalReader(in io.Reader, c map[string]any) error { func (v *Viper) unmarshalReader(in io.Reader, c map[string]any) error {
format := strings.ToLower(v.getConfigType())
if format == "" {
return errors.New("cannot decode configuration: unable to determine config type")
}
buf := new(bytes.Buffer) buf := new(bytes.Buffer)
buf.ReadFrom(in) buf.ReadFrom(in)
format := strings.ToLower(v.getConfigType()) // TODO: remove this once SupportedExts is deprecated/removed
if !slices.Contains(SupportedExts, format) { if !slices.Contains(SupportedExts, format) {
return UnsupportedConfigError(format) return UnsupportedConfigError(format)
} }
// TODO: return [UnsupportedConfigError] if the registry does not contain the format
// TODO: consider deprecating this error type
decoder, err := v.decoderRegistry.Decoder(format) decoder, err := v.decoderRegistry.Decoder(format)
if err != nil { if err != nil {
return ConfigParseError{err} return ConfigParseError{err}

View file

@ -1542,6 +1542,14 @@ func TestReadConfig(t *testing.T) {
}) })
} }
func TestReadConfigWithSetConfigFile(t *testing.T) {
v := New()
v.SetConfigFile("config.yaml") // Dummy value to infer config type from file extension
err := v.ReadConfig(bytes.NewBuffer(yamlMergeExampleSrc))
require.NoError(t, err)
assert.Equal(t, 45000, v.GetInt("hello.pop"))
}
func TestIsSet(t *testing.T) { func TestIsSet(t *testing.T) {
v := New() v := New()
v.SetConfigType("yaml") v.SetConfigType("yaml")
@ -2059,6 +2067,14 @@ func TestMergeConfig(t *testing.T) {
assert.Equal(t, "bar", v.GetString("fu")) assert.Equal(t, "bar", v.GetString("fu"))
} }
func TestMergeConfigWithSetConfigFile(t *testing.T) {
v := New()
v.SetConfigFile("config.yaml") // Dummy value to infer config type from file extension
err := v.MergeConfig(bytes.NewBuffer(yamlMergeExampleSrc))
require.NoError(t, err)
assert.Equal(t, 45000, v.GetInt("hello.pop"))
}
func TestMergeConfigOverrideType(t *testing.T) { func TestMergeConfigOverrideType(t *testing.T) {
v := New() v := New()
v.SetConfigType("json") v.SetConfigType("json")