Repository: spf13/viper
Pull request #1217 (2021-09-15 17:21:26)

build(deps): bump github.com/mitchellh/mapstructure from 1.4.1 to 1.4.2
Bumps [github.com/mitchellh/mapstructure](https://github.com/mitchellh/mapstructure) from 1.4.1 to 1.4.2.
<details>
<summary>Changelog</summary>
<p><em>Sourced from <a href="https://github.com/mitchellh/mapstructure/blob/master/CHANGELOG.md">github.com/mitchellh/mapstructure's changelog</a>.</em></p>
<blockquote>
<h2>1.4.2</h2>
<ul>
<li>Custom name matchers to support any sort of casing, formatting, etc. for
field names. <a href="https://github-redirect.dependabot.com/mitchellh/mapstructure/issues/250">GH-250</a></li>
<li>Fix possible panic in ComposeDecodeHookFunc <a href="https://github-redirect.dependabot.com/mitchellh/mapstructure/issues/251">GH-251</a></li>
</ul>
</blockquote>
</details>
<details>
<summary>Commits</summary>
<ul>
<li><a href="https://github.com/mitchellh/mapstructure/commit/5ac1f6aa4011ece0c4df24a4fe8020a9cc21e393"><code>5ac1f6a</code></a> CHANGELOG</li>
<li><a href="https://github.com/mitchellh/mapstructure/commit/18f04e66072764ddcfc0efc002cee13ac8b940c7"><code>18f04e6</code></a> Default MatchName in NewDecoder</li>
<li><a href="https://github.com/mitchellh/mapstructure/commit/14df28dba025bef20f337c91c1112bb0bbe8f6ed"><code>14df28d</code></a> Merge pull request <a href="https://github-redirect.dependabot.com/mitchellh/mapstructure/issues/247">#247</a> from veikokaap/fix-doc-typo-decodehook</li>
<li><a href="https://github.com/mitchellh/mapstructure/commit/251d52b1614527b43b2d47dbf01efdff059aa04e"><code>251d52b</code></a> improve comments for matchname</li>
<li><a href="https://github.com/mitchellh/mapstructure/commit/1b7c3d8e219d00abb1d9267545c50c6c12fee562"><code>1b7c3d8</code></a> Merge pull request <a href="https://github-redirect.dependabot.com/mitchellh/mapstructure/issues/250">#250</a> from abeMedia/feat/custom-name-matchers</li>
<li><a href="https://github.com/mitchellh/mapstructure/commit/381a76bfee37d3610cfc2f58703864cff5967769"><code>381a76b</code></a> initialize data to interface for decode hook (tested)</li>
<li><a href="https://github.com/mitchellh/mapstructure/commit/6577afadac6c1e18ca4358261c14f3904868e855"><code>6577afa</code></a> Merge pull request <a href="https://github-redirect.dependabot.com/mitchellh/mapstructure/issues/251">#251</a> from eh-steve/bugfix-panic-with-empty-composed-decode...</li>
<li><a href="https://github.com/mitchellh/mapstructure/commit/edc56495e150df241791bf5db02b83f66000686a"><code>edc5649</code></a> Fix possible panic when using ComposeDecodeHookFunc() with no funcs</li>
<li><a href="https://github.com/mitchellh/mapstructure/commit/fd87e0d409d50fecde297a7932ae3215f2493f64"><code>fd87e0d</code></a> Support custom name matchers</li>
<li><a href="https://github.com/mitchellh/mapstructure/commit/963925de5a82054ecff25f1ba8f5c42d8658c1d7"><code>963925d</code></a> fix typo in documentation</li>
<li>Additional commits viewable in <a href="https://github.com/mitchellh/mapstructure/compare/v1.4.1...v1.4.2">compare view</a></li>
</ul>
</details>
<br />


[![Dependabot compatibility score](https://dependabot-badges.githubapp.com/badges/compatibility_score?dependency-name=github.com/mitchellh/mapstructure&package-manager=go_modules&previous-version=1.4.1&new-version=1.4.2)](https://docs.github.com/en/github/managing-security-vulnerabilities/about-dependabot-security-updates#about-compatibility-scores)

Dependabot will resolve any conflicts with this PR as long as you don't alter it yourself. You can also trigger a rebase manually by commenting `@dependabot rebase`.

[//]: # (dependabot-automerge-start)
Dependabot will merge this PR once CI passes on it, as requested by @sagikazarmark.

[//]: # (dependabot-automerge-end)

---

<details>
<summary>Dependabot commands and options</summary>
<br />

You can trigger Dependabot actions by commenting on this PR:
- `@dependabot rebase` will rebase this PR
- `@dependabot recreate` will recreate this PR, overwriting any edits that have been made to it
- `@dependabot merge` will merge this PR after your CI passes on it
- `@dependabot squash and merge` will squash and merge this PR after your CI passes on it
- `@dependabot cancel merge` will cancel a previously requested merge and block automerging
- `@dependabot reopen` will reopen this PR if it is closed
- `@dependabot close` will close this PR and stop Dependabot recreating it. You can achieve the same result by closing it manually
- `@dependabot ignore this major version` will close this PR and stop Dependabot creating any more for this major version (unless you reopen the PR or upgrade to it yourself)
- `@dependabot ignore this minor version` will close this PR and stop Dependabot creating any more for this minor version (unless you reopen the PR or upgrade to it yourself)
- `@dependabot ignore this dependency` will close this PR and stop Dependabot creating any more for this dependency (unless you reopen the PR or upgrade to it yourself)


</details>

CLAassistant: [![CLA assistant check](https://cla-assistant.io/pull/badge/not_signed)](https://cla-assistant.io/spf13/viper?pullRequest=1217) <br/>Thank you for your submission! We really appreciate it. Like many open source projects, we ask that you sign our [Contributor License Agreement](https://cla-assistant.io/spf13/viper?pullRequest=1217) before we can accept your contribution.<br/><sub>You have signed the CLA already but the status is still pending? Let us [recheck](https://cla-assistant.io/check/spf13/viper?pullRequest=1217) it.</sub>
github-actions[bot]: 👋 Thanks for contributing to Viper! You are awesome! 🎉

A maintainer will take a look at your pull request 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!** ❤️


Patch:
diff --git a/go.mod b/go.mod
index aa00f70..fcc1a5d 100644
--- a/go.mod
+++ b/go.mod
@@ -6,7 +6,7 @@ require (
 	github.com/fsnotify/fsnotify v1.5.1
 	github.com/hashicorp/hcl v1.0.0
 	github.com/magiconair/properties v1.8.5
-	github.com/mitchellh/mapstructure v1.4.1
+	github.com/mitchellh/mapstructure v1.4.2
 	github.com/pelletier/go-toml v1.9.4
 	github.com/sagikazarmark/crypt v0.1.0
 	github.com/spf13/afero v1.6.0
@@ -15,6 +15,6 @@ require (
 	github.com/spf13/pflag v1.0.5
 	github.com/stretchr/testify v1.7.0
 	github.com/subosito/gotenv v1.2.0
-	gopkg.in/ini.v1 v1.63.1
+	gopkg.in/ini.v1 v1.63.2
 	gopkg.in/yaml.v2 v2.4.0
 )
diff --git a/go.sum b/go.sum
index 62cdb0b..3e0a13e 100644
--- a/go.sum
+++ b/go.sum
@@ -237,8 +237,8 @@ github.com/mitchellh/go-testing-interface v1.0.0 h1:fzU/JVNcaqHQEcVFAKeR41fkiLdI
 github.com/mitchellh/go-testing-interface v1.0.0/go.mod h1:kRemZodwjscx+RGhAo8eIhFbs2+BFgRtFPeD/KE+zxI=
 github.com/mitchellh/mapstructure v0.0.0-20160808181253-ca63d7c062ee/go.mod h1:FVVH3fgwuzCH5S8UJGiWEs2h04kUh9fWfEaFds41c1Y=
 github.com/mitchellh/mapstructure v1.1.2/go.mod h1:FVVH3fgwuzCH5S8UJGiWEs2h04kUh9fWfEaFds41c1Y=
-github.com/mitchellh/mapstructure v1.4.1 h1:CpVNEelQCZBooIPDn+AR3NpivK/TIKU8bDxdASFVQag=
-github.com/mitchellh/mapstructure v1.4.1/go.mod h1:bFUtVrKA4DC2yAKiSyO/QUcy7e+RRV2QTWOzhPopBRo=
+github.com/mitchellh/mapstructure v1.4.2 h1:6h7AQ0yhTcIsmFmnAwQls75jp2Gzs4iB8W7pjMO+rqo=
+github.com/mitchellh/mapstructure v1.4.2/go.mod h1:bFUtVrKA4DC2yAKiSyO/QUcy7e+RRV2QTWOzhPopBRo=
 github.com/modern-go/concurrent v0.0.0-20180228061459-e0a39a4cb421 h1:ZqeYNhU3OHLH3mGKHDcjJRFFRrJa6eAM5H+CtDdOsPc=
 github.com/modern-go/concurrent v0.0.0-20180228061459-e0a39a4cb421/go.mod h1:6dJC0mAP4ikYIbvyc7fijjWJddQyLn8Ig3JB5CqoB9Q=
 github.com/modern-go/reflect2 v0.0.0-20180701023420-4b7aa43c6742/go.mod h1:bx2lNnkwVCuqBIxFjflWJWanXIb3RllmbCylyMrvgv0=
@@ -680,8 +680,8 @@ gopkg.in/check.v1 v1.0.0-20180628173108-788fd7840127/go.mod h1:Co6ibVJAznAaIkqp8
 gopkg.in/check.v1 v1.0.0-20190902080502-41f04d3bba15 h1:YR8cESwS4TdDjEe65xsg0ogRM/Nc3DYOhEAlW+xobZo=
 gopkg.in/check.v1 v1.0.0-20190902080502-41f04d3bba15/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=
 gopkg.in/errgo.v2 v2.1.0/go.mod h1:hNsd1EY+bozCKY1Ytp96fpM3vjJbqLJn88ws8XvfDNI=
-gopkg.in/ini.v1 v1.63.1 h1:WlmD2fPTg4maPpRITalGs62TK7VMMtP5E9CHH7aFy6Y=
-gopkg.in/ini.v1 v1.63.1/go.mod h1:pNLf8WUiyNEtQjuu5G5vTm06TEv9tsIgeAvK8hOrP4k=
+gopkg.in/ini.v1 v1.63.2 h1:tGK/CyBg7SMzb60vP1M03vNZ3VDu3wGQJwn7Sxi9r3c=
+gopkg.in/ini.v1 v1.63.2/go.mod h1:pNLf8WUiyNEtQjuu5G5vTm06TEv9tsIgeAvK8hOrP4k=
 gopkg.in/yaml.v2 v2.2.2/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI=
 gopkg.in/yaml.v2 v2.2.3/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI=
 gopkg.in/yaml.v2 v2.2.8/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI=
diff --git a/util.go b/util.go
index cee6b24..09d051a 100644
--- a/util.go
+++ b/util.go
@@ -95,19 +95,7 @@ func absPathify(inPath string) string {
 		inPath = userHomeDir() + inPath[5:]
 	}
 
-	if strings.HasPrefix(inPath, "$") {
-		end := strings.Index(inPath, string(os.PathSeparator))
-
-		var value, suffix string
-		if end == -1 {
-			value = os.Getenv(inPath[1:])
-		} else {
-			value = os.Getenv(inPath[1:end])
-			suffix = inPath[end:]
-		}
-
-		inPath = value + suffix
-	}
+	inPath = os.ExpandEnv(inPath)
 
 	if filepath.IsAbs(inPath) {
 		return filepath.Clean(inPath)
diff --git a/viper.go b/viper.go
index 46b1a85..6c1bcae 100644
--- a/viper.go
+++ b/viper.go
@@ -1404,11 +1404,13 @@ func (v *Viper) realKey(key string) string {
 func InConfig(key string) bool { return v.InConfig(key) }
 
 func (v *Viper) InConfig(key string) bool {
+	lcaseKey := strings.ToLower(key)
+
 	// if the requested key is an alias, then return the proper key
-	key = v.realKey(key)
+	lcaseKey = v.realKey(lcaseKey)
+	path := strings.Split(lcaseKey, v.keyDelim)
 
-	_, exists := v.config[key]
-	return exists
+	return v.searchIndexableWithPathPrefixes(v.config, path) != nil
 }
 
 // SetDefault sets the default value for this key.
@@ -1579,7 +1581,7 @@ func (v *Viper) writeConfig(filename string, force bool) error {
 	var configType string
 
 	ext := filepath.Ext(filename)
-	if ext != "" {
+	if ext != "" && ext != filepath.Base(filename) {
 		configType = ext[1:]
 	} else {
 		configType = v.configType


Test patch:
diff --git a/viper_test.go b/viper_test.go
index 4192748..c371c07 100644
--- a/viper_test.go
+++ b/viper_test.go
@@ -382,7 +382,9 @@ func TestUnmarshaling(t *testing.T) {
 
 	unmarshalReader(r, v.config)
 	assert.True(t, InConfig("name"))
+	assert.True(t, InConfig("clothing.jacket"))
 	assert.False(t, InConfig("state"))
+	assert.False(t, InConfig("clothing.hat"))
 	assert.Equal(t, "steve", Get("name"))
 	assert.Equal(t, []interface{}{"skateboarding", "snowboarding", "go"}, Get("hobbies"))
 	assert.Equal(t, map[string]interface{}{"jacket": "leather", "trousers": "denim", "pants": map[string]interface{}{"size": "large"}}, Get("clothing"))
@@ -1239,7 +1241,9 @@ func TestReadBufConfig(t *testing.T) {
 	t.Log(v.AllKeys())
 
 	assert.True(t, v.InConfig("name"))
+	assert.True(t, v.InConfig("clothing.jacket"))
 	assert.False(t, v.InConfig("state"))
+	assert.False(t, v.InConfig("clothing.hat"))
 	assert.Equal(t, "steve", v.Get("name"))
 	assert.Equal(t, []interface{}{"skateboarding", "snowboarding", "go"}, v.Get("hobbies"))
 	assert.Equal(t, map[string]interface{}{"jacket": "leather", "trousers": "denim", "pants": map[string]interface{}{"size": "large"}}, v.Get("clothing"))
@@ -1738,6 +1742,23 @@ func TestSafeWriteConfigAsWithExistingFile(t *testing.T) {
 	assert.True(t, ok, "Expected ConfigFileAlreadyExistsError")
 }
 
+func TestWriteHiddenFile(t *testing.T) {
+	v := New()
+	fs := afero.NewMemMapFs()
+	fs.Create("/test/.config")
+	v.SetFs(fs)
+
+	v.SetConfigName(".config")
+	v.SetConfigType("yaml")
+	v.AddConfigPath("/test")
+
+	err := v.ReadInConfig()
+	require.NoError(t, err)
+
+	err = v.WriteConfig()
+	require.NoError(t, err)
+}
+
 var yamlMergeExampleTgt = []byte(`
 hello:
     pop: 37890