spf13 / viper

Go configuration with fangs
MIT License
26.38k stars 2.01k forks source link

Can't get value from MergeConfigMap type map[string]string #1350

Open cxy1cxy2cxy3 opened 2 years ago

cxy1cxy2cxy3 commented 2 years ago

Preflight Checklist

Viper Version

1.11.0

Go Version

1.17

Config Source

Defaults

Format

Other (specify below)

Repl.it link

No response

Code reproducing the issue

package arrow

import (
    "testing"

    "github.com/stretchr/testify/assert"
)

func TestConfig(t *testing.T) {
    assert := assert.New(t)
    config := NewConfig()
    config.MergeConfigMap(map[string]interface{}{
        "zoo": "default",
        "foo": 123,
        "mad": map[string]string{
            "a": "a",
            "b": "b",
            "c": "c",
        },
    })
    config.MergeConfigMap(map[string]interface{}{
        "foo": "123",
        "doo": "new",
        "mad": map[string]string{
            "a": "b",
            "b": "a",
            "d": "d",
        },
    })
    assert.Equal(config.GetString("zoo"), "default")
    assert.Equal(config.GetString("foo"), "123")
    assert.Equal(config.GetString("doo"), "new")
    assert.Equal(config.GetString("mad.a"), "b")
    assert.Equal(config.GetString("mad.b"), "a")
    assert.Equal(config.GetString("mad.c"), "c")
    assert.Equal(config.GetString("mad.d"), "d")
}

Expected Behavior

TestConfig

  Config (pass: 3 / 3)
     ✔ test load config.yml
     ✔ test load HC_APP_CONFIG
     ✔ test merge config

ALL PASS, TOTAL: 3

Actual Behavior

TestConfig

  Config (pass: 2 / 3)
     ✔ test load config.yml
     ✔ test load HC_APP_CONFIG
     X test merge config

ALL PASS, TOTAL: 3

Steps To Reproduce

run test case

Additional Information

func (v *Viper) searchMapWithPathPrefixes( sourceMap map[string]interface{}, prefixKey string, pathIndex int, path []string, ) interface{} { next, ok := sourceMap[prefixKey] if !ok { return nil }

// Fast path
if pathIndex == len(path) {
    return next
}

// Nested case
switch n := next.(type) {
case map[interface{}]interface{}:
    return v.searchIndexableWithPathPrefixes(cast.ToStringMap(n), path[pathIndex:])

    **### // TODO: Add more cases like map[string]string**

case map[string]interface{}, []interface{}:
    return v.searchIndexableWithPathPrefixes(n, path[pathIndex:])
default:
    // got a value but nested key expected, do nothing and look for next prefix
}

// not found
return nil

}

github-actions[bot] commented 2 years ago

👋 Thanks for reporting!

A maintainer will take a look at your issue shortly. 👀

In the meantime: We are working on Viper v2 and we would love to hear your thoughts about what you like or don't like about Viper, so we can improve or fix those issues.

⏰ If you have a couple minutes, please take some time and share your thoughts: https://forms.gle/R6faU74qPRPAzchZ9

📣 If you've already given us your feedback, you can still help by spreading the news, either by sharing the above link or telling people about this on Twitter:

https://twitter.com/sagikazarmark/status/1306904078967074816

Thank you! ❤️

panda8z commented 1 year ago

I got this error too, same case

oohook commented 1 year ago

other choice to do so, declare a new viper and merge in the old one

v := viper.New()
v.Set(key, val)
viper.MergeConfigMap(v.AllSettings())