diff --git a/viper.go b/viper.go index a58d757..e3e7296 100644 --- a/viper.go +++ b/viper.go @@ -1476,6 +1476,28 @@ func (v *Viper) Set(key string, value any) { deepestMap[lastKey] = value } +// Unset deletes a key from Viper. +// Unset is case-insensitive for a key. +func Unset(key string) { v.Unset(key) } + +func (v *Viper) Unset(key string) { + // If alias passed in, then set the proper override + key = v.realKey(strings.ToLower(key)) + + path := strings.Split(key, v.keyDelim) + lastKey := strings.ToLower(path[len(path)-1]) + + for _, cfgMap := range []map[string]interface{}{ + v.override, v.config, v.defaults, + v.kvstore, + } { + cfg := deepSearch(cfgMap, path[0:len(path)-1]) + delete(cfg, lastKey) + } + + delete(v.aliases, key) +} + // ReadInConfig will discover and load the configuration file from disk // and key/value stores, searching in one of the defined paths. func ReadInConfig() error { return v.ReadInConfig() } diff --git a/viper_test.go b/viper_test.go index f7e0787..9ccf1f1 100644 --- a/viper_test.go +++ b/viper_test.go @@ -513,6 +513,17 @@ func TestOverrides(t *testing.T) { assert.Equal(t, 40, v.Get("age")) } +func TestUnset(t *testing.T) { + SetDefault("unset", 20) + Set("unset", 10) + RegisterAlias("unset_alias", "unset") + + Unset("unset") + + assert.Equal(t, nil, Get("unset")) + assert.Equal(t, nil, Get("unset_alias")) +} + func TestDefaultPost(t *testing.T) { v := New() assert.NotEqual(t, "NYC", v.Get("state"))