diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index bf19b1b..250abff 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -13,7 +13,7 @@ jobs: strategy: matrix: os: [ubuntu-latest, macos-latest] - go: ['1.14', '1.15', '1.16'] + go: ['1.17', '1.18'] env: VERBOSE: 1 GOFLAGS: -mod=readonly diff --git a/go.mod b/go.mod index 76db260..f839cd6 100644 --- a/go.mod +++ b/go.mod @@ -30,6 +30,7 @@ require ( github.com/xordataexchange/crypt v0.0.3-0.20170626215501-b2862e3d0a77 go.uber.org/zap v1.14.0 // indirect golang.org/x/net v0.0.0-20200226121028-0de0cce0169b // indirect + golang.org/x/sys v0.0.0-20220829200755-d48e67d00261 // indirect golang.org/x/text v0.3.0 // indirect golang.org/x/time v0.0.0-20191024005414-555d28b269f0 // indirect google.golang.org/grpc v1.27.1 // indirect diff --git a/go.sum b/go.sum index ca70bf0..5d088c9 100644 --- a/go.sum +++ b/go.sum @@ -253,6 +253,8 @@ golang.org/x/sys v0.0.0-20190412213103-97732733099d/go.mod h1:h1NjWce9XRLGQEsW7w golang.org/x/sys v0.0.0-20190422165155-953cdadca894/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20200122134326-e047566fdf82 h1:ywK/j/KkyTHcdyYSZNXGjMwgmDSfjglYZ3vStQ/gSCU= golang.org/x/sys v0.0.0-20200122134326-e047566fdf82/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20220829200755-d48e67d00261 h1:v6hYoSR9T5oet+pMXwUWkbiVqx/63mlHjefrHmxwfeY= +golang.org/x/sys v0.0.0-20220829200755-d48e67d00261/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/text v0.3.0 h1:g61tztE5qeGQ89tm6NTjjM9VPIm088od1l6aSorWRWg= golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ= golang.org/x/time v0.0.0-20190308202827-9d24e82272b4/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ= diff --git a/viper.go b/viper.go index 5d26730..c106c53 100644 --- a/viper.go +++ b/viper.go @@ -1941,17 +1941,21 @@ func (v *Viper) getConfigFile() (string, error) { return v.configFile, nil } -func (v *Viper) searchInPath(in string) (filename string) { +func (v *Viper) searchInPath(in string) (filename string, err error) { + var lastError error jww.DEBUG.Println("Searching for config in ", in) for _, ext := range SupportedExts { jww.DEBUG.Println("Checking for", filepath.Join(in, v.configName+"."+ext)) - if b, _ := exists(v.fs, filepath.Join(in, v.configName+"."+ext)); b { + b, err := exists(v.fs, filepath.Join(in, v.configName+"."+ext)) + if err != nil { + lastError = err + } else if b { jww.DEBUG.Println("Found: ", filepath.Join(in, v.configName+"."+ext)) - return filepath.Join(in, v.configName+"."+ext) + return filepath.Join(in, v.configName+"."+ext), nil } } - return "" + return "", lastError } // Search all configPaths for any config file. @@ -1959,13 +1963,23 @@ func (v *Viper) searchInPath(in string) (filename string) { func (v *Viper) findConfigFile() (string, error) { jww.INFO.Println("Searching for config in ", v.configPaths) + var lastError error for _, cp := range v.configPaths { - file := v.searchInPath(cp) + file, err := v.searchInPath(cp) if file != "" { return file, nil } + if err != nil { + lastError = err + } } - return "", ConfigFileNotFoundError{v.configName, fmt.Sprintf("%s", v.configPaths)} + + // If there was no more-specific error, assume this was a not-found error + if lastError == nil { + lastError = ConfigFileNotFoundError{v.configName, fmt.Sprintf("%s", v.configPaths)} + } + + return "", lastError } // Debug prints all configuration registries for debugging diff --git a/viper_test.go b/viper_test.go index 8bbba76..2016561 100644 --- a/viper_test.go +++ b/viper_test.go @@ -8,6 +8,7 @@ package viper import ( "bytes" "encoding/json" + "errors" "fmt" "io" "io/ioutil" @@ -1018,6 +1019,31 @@ func TestWrongDirsSearchNotFound(t *testing.T) { assert.Equal(t, `default`, v.GetString(`key`)) } +func TestNoPermissionDirs(t *testing.T) { + tmpdir := t.TempDir() + + v := New() + v.SetDefault(`key`, `default`) + + // Make an fs with an un-readable /directory + v.fs = afero.NewBasePathFs(afero.NewOsFs(), tmpdir) + err := v.fs.Mkdir("/directory", 000) + if err != nil { + t.Fatalf("Error from fs.Mkdir: %v", err) + } + + v.AddConfigPath("/directory") + err = v.ReadInConfig() + + if !errors.Is(err, os.ErrPermission) { + t.Fatalf("error should have been a permissions error") + } + + // Even though config did not load and the error might have + // been ignored by the client, the default still loads + assert.Equal(t, `default`, v.GetString(`key`)) +} + func TestWrongDirsSearchNotFoundForMerge(t *testing.T) { _, config, cleanup := initDirs(t)