Support for loading from a directory tree where each file represents one setting

This commit is contained in:
Dana NicCaluim 2015-07-14 17:12:54 -07:00
parent db7ff930a1
commit 5adc40fc58
2 changed files with 65 additions and 0 deletions

View file

@ -749,6 +749,42 @@ func (v *Viper) ReadConfig(in io.Reader) error {
return nil return nil
} }
// Loads configuration from a directory tree where filenames are keys
// and file contents are values.
func ReadDir(dirname string) error { return v.ReadDir(dirname) }
func (v *Viper) ReadDir(dirname string) error {
config, err := v.readDir(dirname, "")
if err == nil {
v.config = config
}
return err
}
func (v *Viper) readDir(dirname, keyPrefix string) (map[string]interface{}, error) {
entries, err := ioutil.ReadDir(dirname)
if err != nil {
return nil, err
}
node := make(map[string]interface{})
for _, entry := range entries {
path := filepath.Join(dirname, entry.Name())
if entry.IsDir() {
node[entry.Name()], err = v.readDir(path, keyPrefix+v.keyDelim+entry.Name())
if err != nil {
return nil, err
}
} else {
value, err := ioutil.ReadFile(path)
if err != nil {
return nil, err
}
node[entry.Name()] = strings.TrimRight(string(value), "\r\n")
}
}
return node, nil
}
// func ReadBufConfig(buf *bytes.Buffer) error { return v.ReadBufConfig(buf) } // func ReadBufConfig(buf *bytes.Buffer) error { return v.ReadBufConfig(buf) }
// func (v *Viper) ReadBufConfig(buf *bytes.Buffer) error { // func (v *Viper) ReadBufConfig(buf *bytes.Buffer) error {
// v.config = make(map[string]interface{}) // v.config = make(map[string]interface{})

View file

@ -8,7 +8,9 @@ package viper
import ( import (
"bytes" "bytes"
"fmt" "fmt"
"io/ioutil"
"os" "os"
"path/filepath"
"sort" "sort"
"strings" "strings"
"testing" "testing"
@ -557,3 +559,30 @@ func TestReadBufConfig(t *testing.T) {
assert.Equal(t, map[interface{}]interface{}{"jacket": "leather", "trousers": "denim", "pants": map[interface{}]interface{}{"size": "large"}}, v.Get("clothing")) assert.Equal(t, map[interface{}]interface{}{"jacket": "leather", "trousers": "denim", "pants": map[interface{}]interface{}{"size": "large"}}, v.Get("clothing"))
assert.Equal(t, 35, v.Get("age")) assert.Equal(t, 35, v.Get("age"))
} }
func TestReadDir(t *testing.T) {
dir, err := ioutil.TempDir("", "viper_test")
if err != nil {
t.Fatalf("unable to create temporary directory, %v", err)
}
if err := os.MkdirAll(filepath.Join(dir, "app", "service"), 0700); err != nil {
t.Fatalf("unable to create directory, %v", err)
}
if err := ioutil.WriteFile(filepath.Join(dir, "app", "service", "url"), []byte(`https://donuts/api/1/`), 0600); err != nil {
t.Fatalf("unable to create file, %v", err)
}
if err := ioutil.WriteFile(filepath.Join(dir, "app", "service", "key"), []byte(`0123456789abcdef`), 0600); err != nil {
t.Fatalf("unable to create file, %v", err)
}
if err := ioutil.WriteFile(filepath.Join(dir, "app", "debug"), []byte(`true`), 0600); err != nil {
t.Fatalf("unable to create file, %v", err)
}
v := New()
v.ReadDir(dir)
t.Log(v.AllSettings())
assert.True(t, v.GetBool("app.debug"))
assert.Equal(t, "https://donuts/api/1/", v.Get("app.service.url"))
assert.Equal(t, "0123456789abcdef", v.Get("app.service.key"))
}