mirror of
https://github.com/spf13/viper
synced 2024-11-05 04:37:02 +00:00
feat: add finder
Signed-off-by: Mark Sagi-Kazar <mark.sagikazar@gmail.com>
This commit is contained in:
parent
272344e426
commit
f452b09dd9
6 changed files with 120 additions and 13 deletions
2
.github/workflows/ci.yaml
vendored
2
.github/workflows/ci.yaml
vendored
|
@ -45,7 +45,7 @@ jobs:
|
|||
matrix:
|
||||
os: [ubuntu-latest, macos-latest, windows-latest]
|
||||
go: ["1.21", "1.22"]
|
||||
tags: ["", "finder", "viper_bind_struct"]
|
||||
tags: ["", "viper_finder", "viper_bind_struct"]
|
||||
|
||||
steps:
|
||||
- name: Checkout repository
|
||||
|
|
2
file.go
2
file.go
|
@ -1,4 +1,4 @@
|
|||
//go:build !finder
|
||||
//go:build !viper_finder
|
||||
|
||||
package viper
|
||||
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
//go:build finder
|
||||
//go:build viper_finder
|
||||
|
||||
package viper
|
||||
|
||||
|
@ -11,18 +11,22 @@ import (
|
|||
// Search all configPaths for any config file.
|
||||
// Returns the first path that exists (and is a config file).
|
||||
func (v *Viper) findConfigFile() (string, error) {
|
||||
var names []string
|
||||
finder := v.finder
|
||||
|
||||
if v.configType != "" {
|
||||
names = locafero.NameWithOptionalExtensions(v.configName, SupportedExts...)
|
||||
} else {
|
||||
names = locafero.NameWithExtensions(v.configName, SupportedExts...)
|
||||
}
|
||||
if finder == nil {
|
||||
var names []string
|
||||
|
||||
finder := locafero.Finder{
|
||||
Paths: v.configPaths,
|
||||
Names: names,
|
||||
Type: locafero.FileTypeFile,
|
||||
if v.configType != "" {
|
||||
names = locafero.NameWithOptionalExtensions(v.configName, SupportedExts...)
|
||||
} else {
|
||||
names = locafero.NameWithExtensions(v.configName, SupportedExts...)
|
||||
}
|
||||
|
||||
finder = locafero.Finder{
|
||||
Paths: v.configPaths,
|
||||
Names: names,
|
||||
Type: locafero.FileTypeFile,
|
||||
}
|
||||
}
|
||||
|
||||
results, err := finder.Find(v.fs)
|
||||
|
|
47
finder.go
Normal file
47
finder.go
Normal file
|
@ -0,0 +1,47 @@
|
|||
package viper
|
||||
|
||||
import (
|
||||
"errors"
|
||||
|
||||
"github.com/spf13/afero"
|
||||
)
|
||||
|
||||
// WithFinder sets a custom [Finder].
|
||||
func WithFinder(f Finder) Option {
|
||||
return optionFunc(func(v *Viper) {
|
||||
v.finder = f
|
||||
})
|
||||
}
|
||||
|
||||
// Finder looks for files and directories in an [afero.Fs] filesystem.
|
||||
type Finder interface {
|
||||
Find(fsys afero.Fs) ([]string, error)
|
||||
}
|
||||
|
||||
// Finders combines multiple finders into one.
|
||||
func Finders(finders ...Finder) Finder {
|
||||
return &CombinedFinder{finders: finders}
|
||||
}
|
||||
|
||||
// CombinedFinder is a Finder that combines multiple finders.
|
||||
type CombinedFinder struct {
|
||||
finders []Finder
|
||||
}
|
||||
|
||||
// Find implements the [Finder] interface.
|
||||
func (c *CombinedFinder) Find(fsys afero.Fs) ([]string, error) {
|
||||
var results []string
|
||||
var errs []error
|
||||
|
||||
for _, finder := range c.finders {
|
||||
r, err := finder.Find(fsys)
|
||||
if err != nil {
|
||||
errs = append(errs, err)
|
||||
continue
|
||||
}
|
||||
|
||||
results = append(results, r...)
|
||||
}
|
||||
|
||||
return results, errors.Join(errs...)
|
||||
}
|
42
finder_test.go
Normal file
42
finder_test.go
Normal file
|
@ -0,0 +1,42 @@
|
|||
package viper
|
||||
|
||||
import (
|
||||
"testing"
|
||||
|
||||
"github.com/spf13/afero"
|
||||
"github.com/stretchr/testify/assert"
|
||||
"github.com/stretchr/testify/require"
|
||||
)
|
||||
|
||||
type finderStub struct {
|
||||
results []string
|
||||
}
|
||||
|
||||
func (f finderStub) Find(_ afero.Fs) ([]string, error) {
|
||||
return f.results, nil
|
||||
}
|
||||
|
||||
func TestFinders(t *testing.T) {
|
||||
finder := Finders(
|
||||
finderStub{
|
||||
results: []string{
|
||||
"/home/user/.viper.yaml",
|
||||
},
|
||||
},
|
||||
finderStub{
|
||||
results: []string{
|
||||
"/etc/viper/config.yaml",
|
||||
},
|
||||
},
|
||||
)
|
||||
|
||||
results, err := finder.Find(afero.NewMemMapFs())
|
||||
require.NoError(t, err)
|
||||
|
||||
expected := []string{
|
||||
"/home/user/.viper.yaml",
|
||||
"/etc/viper/config.yaml",
|
||||
}
|
||||
|
||||
assert.Equal(t, expected, results)
|
||||
}
|
14
viper.go
14
viper.go
|
@ -158,6 +158,8 @@ type Viper struct {
|
|||
// The filesystem to read config from.
|
||||
fs afero.Fs
|
||||
|
||||
finder Finder
|
||||
|
||||
// A set of remote providers to search for the configuration
|
||||
remoteProviders []*defaultRemoteProvider
|
||||
|
||||
|
@ -506,6 +508,12 @@ func (v *Viper) ConfigFileUsed() string { return v.configFile }
|
|||
func AddConfigPath(in string) { v.AddConfigPath(in) }
|
||||
|
||||
func (v *Viper) AddConfigPath(in string) {
|
||||
if v.finder != nil {
|
||||
v.logger.Warn("call to AddConfigPath is ineffective when a custom finder is configured")
|
||||
|
||||
return
|
||||
}
|
||||
|
||||
if in != "" {
|
||||
absin := absPathify(v.logger, in)
|
||||
|
||||
|
@ -1955,6 +1963,12 @@ func (v *Viper) SetFs(fs afero.Fs) {
|
|||
func SetConfigName(in string) { v.SetConfigName(in) }
|
||||
|
||||
func (v *Viper) SetConfigName(in string) {
|
||||
if v.finder != nil {
|
||||
v.logger.Warn("call to SetConfigName is ineffective when a custom finder is configured")
|
||||
|
||||
return
|
||||
}
|
||||
|
||||
if in != "" {
|
||||
v.configName = in
|
||||
v.configFile = ""
|
||||
|
|
Loading…
Reference in a new issue