diff --git a/util.go b/util.go index b78896963..cee6b2429 100644 --- a/util.go +++ b/util.go @@ -91,13 +91,22 @@ func insensitiviseMap(m map[string]interface{}) { func absPathify(inPath string) string { jww.INFO.Println("Trying to resolve absolute path to", inPath) - if strings.HasPrefix(inPath, "$HOME") { + if inPath == "$HOME" || strings.HasPrefix(inPath, "$HOME"+string(os.PathSeparator)) { inPath = userHomeDir() + inPath[5:] } if strings.HasPrefix(inPath, "$") { end := strings.Index(inPath, string(os.PathSeparator)) - inPath = os.Getenv(inPath[1:end]) + inPath[end:] + + 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 } if filepath.IsAbs(inPath) { diff --git a/util_test.go b/util_test.go index 0af80bb63..01d932d4e 100644 --- a/util_test.go +++ b/util_test.go @@ -11,6 +11,8 @@ package viper import ( + "os" + "path/filepath" "reflect" "testing" ) @@ -52,3 +54,38 @@ func TestCopyAndInsensitiviseMap(t *testing.T) { t.Fatal("Input map changed") } } + +func TestAbsPathify(t *testing.T) { + home := userHomeDir() + homer := filepath.Join(home, "homer") + wd, _ := os.Getwd() + + os.Setenv("HOMER_ABSOLUTE_PATH", homer) + os.Setenv("VAR_WITH_RELATIVE_PATH", "relative") + + tests := []struct { + input string + output string + }{ + {"", wd}, + {"sub", filepath.Join(wd, "sub")}, + {"./", wd}, + {"./sub", filepath.Join(wd, "sub")}, + {"$HOME", home}, + {"$HOME/", home}, + {"$HOME/sub", filepath.Join(home, "sub")}, + {"$HOMER_ABSOLUTE_PATH", homer}, + {"$HOMER_ABSOLUTE_PATH/", homer}, + {"$HOMER_ABSOLUTE_PATH/sub", filepath.Join(homer, "sub")}, + {"$VAR_WITH_RELATIVE_PATH", filepath.Join(wd, "relative")}, + {"$VAR_WITH_RELATIVE_PATH/", filepath.Join(wd, "relative")}, + {"$VAR_WITH_RELATIVE_PATH/sub", filepath.Join(wd, "relative", "sub")}, + } + + for _, test := range tests { + got := absPathify(test.input) + if got != test.output { + t.Errorf("Got %v\nexpected\n%q", got, test.output) + } + } +}