mirror of
https://github.com/spf13/viper
synced 2025-05-06 20:27:17 +00:00
cloudconfig: bringing updated viper
This commit is contained in:
parent
84f2946712
commit
d80342619e
4 changed files with 190 additions and 68 deletions
|
@ -62,5 +62,4 @@ func TestBindFlagValue(t *testing.T) {
|
||||||
flag.Changed = true //hack for pflag usage
|
flag.Changed = true //hack for pflag usage
|
||||||
|
|
||||||
assert.Equal(t, "testing_mutate", Get("testvalue"))
|
assert.Equal(t, "testing_mutate", Get("testvalue"))
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
67
util.go
67
util.go
|
@ -11,22 +11,16 @@
|
||||||
package viper
|
package viper
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"bytes"
|
|
||||||
"encoding/json"
|
|
||||||
"fmt"
|
"fmt"
|
||||||
"io"
|
|
||||||
"os"
|
"os"
|
||||||
"path/filepath"
|
"path/filepath"
|
||||||
"runtime"
|
"runtime"
|
||||||
"strings"
|
"strings"
|
||||||
"unicode"
|
"unicode"
|
||||||
|
|
||||||
"github.com/hashicorp/hcl"
|
"github.com/spf13/afero"
|
||||||
"github.com/magiconair/properties"
|
|
||||||
toml "github.com/pelletier/go-toml"
|
|
||||||
"github.com/spf13/cast"
|
"github.com/spf13/cast"
|
||||||
jww "github.com/spf13/jwalterweatherman"
|
jww "github.com/spf13/jwalterweatherman"
|
||||||
"gopkg.in/yaml.v2"
|
|
||||||
)
|
)
|
||||||
|
|
||||||
// ConfigParseError denotes failing to parse configuration file.
|
// ConfigParseError denotes failing to parse configuration file.
|
||||||
|
@ -121,8 +115,8 @@ func absPathify(inPath string) string {
|
||||||
}
|
}
|
||||||
|
|
||||||
// Check if File / Directory Exists
|
// Check if File / Directory Exists
|
||||||
func exists(path string) (bool, error) {
|
func exists(fs afero.Fs, path string) (bool, error) {
|
||||||
_, err := v.fs.Stat(path)
|
_, err := fs.Stat(path)
|
||||||
if err == nil {
|
if err == nil {
|
||||||
return true, nil
|
return true, nil
|
||||||
}
|
}
|
||||||
|
@ -152,61 +146,6 @@ func userHomeDir() string {
|
||||||
return os.Getenv("HOME")
|
return os.Getenv("HOME")
|
||||||
}
|
}
|
||||||
|
|
||||||
func unmarshallConfigReader(in io.Reader, c map[string]interface{}, configType string) error {
|
|
||||||
buf := new(bytes.Buffer)
|
|
||||||
buf.ReadFrom(in)
|
|
||||||
|
|
||||||
switch strings.ToLower(configType) {
|
|
||||||
case "yaml", "yml":
|
|
||||||
if err := yaml.Unmarshal(buf.Bytes(), &c); err != nil {
|
|
||||||
return ConfigParseError{err}
|
|
||||||
}
|
|
||||||
|
|
||||||
case "json":
|
|
||||||
if err := json.Unmarshal(buf.Bytes(), &c); err != nil {
|
|
||||||
return ConfigParseError{err}
|
|
||||||
}
|
|
||||||
|
|
||||||
case "hcl":
|
|
||||||
obj, err := hcl.Parse(string(buf.Bytes()))
|
|
||||||
if err != nil {
|
|
||||||
return ConfigParseError{err}
|
|
||||||
}
|
|
||||||
if err = hcl.DecodeObject(&c, obj); err != nil {
|
|
||||||
return ConfigParseError{err}
|
|
||||||
}
|
|
||||||
|
|
||||||
case "toml":
|
|
||||||
tree, err := toml.LoadReader(buf)
|
|
||||||
if err != nil {
|
|
||||||
return ConfigParseError{err}
|
|
||||||
}
|
|
||||||
tmap := tree.ToMap()
|
|
||||||
for k, v := range tmap {
|
|
||||||
c[k] = v
|
|
||||||
}
|
|
||||||
|
|
||||||
case "properties", "props", "prop":
|
|
||||||
var p *properties.Properties
|
|
||||||
var err error
|
|
||||||
if p, err = properties.Load(buf.Bytes(), properties.UTF8); err != nil {
|
|
||||||
return ConfigParseError{err}
|
|
||||||
}
|
|
||||||
for _, key := range p.Keys() {
|
|
||||||
value, _ := p.Get(key)
|
|
||||||
// recursively build nested maps
|
|
||||||
path := strings.Split(key, ".")
|
|
||||||
lastKey := strings.ToLower(path[len(path)-1])
|
|
||||||
deepestMap := deepSearch(c, path[0:len(path)-1])
|
|
||||||
// set innermost value
|
|
||||||
deepestMap[lastKey] = value
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
insensitiviseMap(c)
|
|
||||||
return nil
|
|
||||||
}
|
|
||||||
|
|
||||||
func safeMul(a, b uint) uint {
|
func safeMul(a, b uint) uint {
|
||||||
c := a * b
|
c := a * b
|
||||||
if a > 1 && b > 1 && c/b != a {
|
if a > 1 && b > 1 && c/b != a {
|
||||||
|
|
|
@ -16,7 +16,6 @@ import (
|
||||||
)
|
)
|
||||||
|
|
||||||
func TestCopyAndInsensitiviseMap(t *testing.T) {
|
func TestCopyAndInsensitiviseMap(t *testing.T) {
|
||||||
|
|
||||||
var (
|
var (
|
||||||
given = map[string]interface{}{
|
given = map[string]interface{}{
|
||||||
"Foo": 32,
|
"Foo": 32,
|
||||||
|
|
189
viper_test.go
189
viper_test.go
|
@ -18,6 +18,7 @@ import (
|
||||||
"testing"
|
"testing"
|
||||||
"time"
|
"time"
|
||||||
|
|
||||||
|
"github.com/spf13/afero"
|
||||||
"github.com/spf13/cast"
|
"github.com/spf13/cast"
|
||||||
|
|
||||||
"github.com/spf13/pflag"
|
"github.com/spf13/pflag"
|
||||||
|
@ -262,7 +263,7 @@ func TestDefault(t *testing.T) {
|
||||||
assert.Equal(t, "leather", Get("clothing.jacket"))
|
assert.Equal(t, "leather", Get("clothing.jacket"))
|
||||||
}
|
}
|
||||||
|
|
||||||
func TestUnmarshalling(t *testing.T) {
|
func TestUnmarshaling(t *testing.T) {
|
||||||
SetConfigType("yaml")
|
SetConfigType("yaml")
|
||||||
r := bytes.NewReader(yamlExample)
|
r := bytes.NewReader(yamlExample)
|
||||||
|
|
||||||
|
@ -417,7 +418,7 @@ func TestAutoEnvWithPrefix(t *testing.T) {
|
||||||
assert.Equal(t, "13", Get("bar"))
|
assert.Equal(t, "13", Get("bar"))
|
||||||
}
|
}
|
||||||
|
|
||||||
func TestSetEnvReplacer(t *testing.T) {
|
func TestSetEnvKeyReplacer(t *testing.T) {
|
||||||
Reset()
|
Reset()
|
||||||
|
|
||||||
AutomaticEnv()
|
AutomaticEnv()
|
||||||
|
@ -847,6 +848,190 @@ func TestSub(t *testing.T) {
|
||||||
assert.Equal(t, (*Viper)(nil), subv)
|
assert.Equal(t, (*Viper)(nil), subv)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
var hclWriteExpected = []byte(`"foos" = {
|
||||||
|
"foo" = {
|
||||||
|
"key" = 1
|
||||||
|
}
|
||||||
|
|
||||||
|
"foo" = {
|
||||||
|
"key" = 2
|
||||||
|
}
|
||||||
|
|
||||||
|
"foo" = {
|
||||||
|
"key" = 3
|
||||||
|
}
|
||||||
|
|
||||||
|
"foo" = {
|
||||||
|
"key" = 4
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
"id" = "0001"
|
||||||
|
|
||||||
|
"name" = "Cake"
|
||||||
|
|
||||||
|
"ppu" = 0.55
|
||||||
|
|
||||||
|
"type" = "donut"`)
|
||||||
|
|
||||||
|
func TestWriteConfigHCL(t *testing.T) {
|
||||||
|
v := New()
|
||||||
|
fs := afero.NewMemMapFs()
|
||||||
|
v.SetFs(fs)
|
||||||
|
v.SetConfigName("c")
|
||||||
|
v.SetConfigType("hcl")
|
||||||
|
err := v.ReadConfig(bytes.NewBuffer(hclExample))
|
||||||
|
if err != nil {
|
||||||
|
t.Fatal(err)
|
||||||
|
}
|
||||||
|
if err := v.WriteConfigAs("c.hcl"); err != nil {
|
||||||
|
t.Fatal(err)
|
||||||
|
}
|
||||||
|
read, err := afero.ReadFile(fs, "c.hcl")
|
||||||
|
if err != nil {
|
||||||
|
t.Fatal(err)
|
||||||
|
}
|
||||||
|
assert.Equal(t, hclWriteExpected, read)
|
||||||
|
}
|
||||||
|
|
||||||
|
var jsonWriteExpected = []byte(`{
|
||||||
|
"batters": {
|
||||||
|
"batter": [
|
||||||
|
{
|
||||||
|
"type": "Regular"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"type": "Chocolate"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"type": "Blueberry"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"type": "Devil's Food"
|
||||||
|
}
|
||||||
|
]
|
||||||
|
},
|
||||||
|
"id": "0001",
|
||||||
|
"name": "Cake",
|
||||||
|
"ppu": 0.55,
|
||||||
|
"type": "donut"
|
||||||
|
}`)
|
||||||
|
|
||||||
|
func TestWriteConfigJson(t *testing.T) {
|
||||||
|
v := New()
|
||||||
|
fs := afero.NewMemMapFs()
|
||||||
|
v.SetFs(fs)
|
||||||
|
v.SetConfigName("c")
|
||||||
|
v.SetConfigType("json")
|
||||||
|
err := v.ReadConfig(bytes.NewBuffer(jsonExample))
|
||||||
|
if err != nil {
|
||||||
|
t.Fatal(err)
|
||||||
|
}
|
||||||
|
if err := v.WriteConfigAs("c.json"); err != nil {
|
||||||
|
t.Fatal(err)
|
||||||
|
}
|
||||||
|
read, err := afero.ReadFile(fs, "c.json")
|
||||||
|
if err != nil {
|
||||||
|
t.Fatal(err)
|
||||||
|
}
|
||||||
|
assert.Equal(t, jsonWriteExpected, read)
|
||||||
|
}
|
||||||
|
|
||||||
|
var propertiesWriteExpected = []byte(`p_id = 0001
|
||||||
|
p_type = donut
|
||||||
|
p_name = Cake
|
||||||
|
p_ppu = 0.55
|
||||||
|
p_batters.batter.type = Regular
|
||||||
|
`)
|
||||||
|
|
||||||
|
func TestWriteConfigProperties(t *testing.T) {
|
||||||
|
v := New()
|
||||||
|
fs := afero.NewMemMapFs()
|
||||||
|
v.SetFs(fs)
|
||||||
|
v.SetConfigName("c")
|
||||||
|
v.SetConfigType("properties")
|
||||||
|
err := v.ReadConfig(bytes.NewBuffer(propertiesExample))
|
||||||
|
if err != nil {
|
||||||
|
t.Fatal(err)
|
||||||
|
}
|
||||||
|
if err := v.WriteConfigAs("c.properties"); err != nil {
|
||||||
|
t.Fatal(err)
|
||||||
|
}
|
||||||
|
read, err := afero.ReadFile(fs, "c.properties")
|
||||||
|
if err != nil {
|
||||||
|
t.Fatal(err)
|
||||||
|
}
|
||||||
|
assert.Equal(t, propertiesWriteExpected, read)
|
||||||
|
}
|
||||||
|
|
||||||
|
func TestWriteConfigTOML(t *testing.T) {
|
||||||
|
fs := afero.NewMemMapFs()
|
||||||
|
v := New()
|
||||||
|
v.SetFs(fs)
|
||||||
|
v.SetConfigName("c")
|
||||||
|
v.SetConfigType("toml")
|
||||||
|
err := v.ReadConfig(bytes.NewBuffer(tomlExample))
|
||||||
|
if err != nil {
|
||||||
|
t.Fatal(err)
|
||||||
|
}
|
||||||
|
if err := v.WriteConfigAs("c.toml"); err != nil {
|
||||||
|
t.Fatal(err)
|
||||||
|
}
|
||||||
|
|
||||||
|
// The TOML String method does not order the contents.
|
||||||
|
// Therefore, we must read the generated file and compare the data.
|
||||||
|
v2 := New()
|
||||||
|
v2.SetFs(fs)
|
||||||
|
v2.SetConfigName("c")
|
||||||
|
v2.SetConfigType("toml")
|
||||||
|
v2.SetConfigFile("c.toml")
|
||||||
|
err = v2.ReadInConfig()
|
||||||
|
if err != nil {
|
||||||
|
t.Fatal(err)
|
||||||
|
}
|
||||||
|
|
||||||
|
assert.Equal(t, v.GetString("title"), v2.GetString("title"))
|
||||||
|
assert.Equal(t, v.GetString("owner.bio"), v2.GetString("owner.bio"))
|
||||||
|
assert.Equal(t, v.GetString("owner.dob"), v2.GetString("owner.dob"))
|
||||||
|
assert.Equal(t, v.GetString("owner.organization"), v2.GetString("owner.organization"))
|
||||||
|
}
|
||||||
|
|
||||||
|
var yamlWriteExpected = []byte(`age: 35
|
||||||
|
beard: true
|
||||||
|
clothing:
|
||||||
|
jacket: leather
|
||||||
|
pants:
|
||||||
|
size: large
|
||||||
|
trousers: denim
|
||||||
|
eyes: brown
|
||||||
|
hacker: true
|
||||||
|
hobbies:
|
||||||
|
- skateboarding
|
||||||
|
- snowboarding
|
||||||
|
- go
|
||||||
|
name: steve
|
||||||
|
`)
|
||||||
|
|
||||||
|
func TestWriteConfigYAML(t *testing.T) {
|
||||||
|
v := New()
|
||||||
|
fs := afero.NewMemMapFs()
|
||||||
|
v.SetFs(fs)
|
||||||
|
v.SetConfigName("c")
|
||||||
|
v.SetConfigType("yaml")
|
||||||
|
err := v.ReadConfig(bytes.NewBuffer(yamlExample))
|
||||||
|
if err != nil {
|
||||||
|
t.Fatal(err)
|
||||||
|
}
|
||||||
|
if err := v.WriteConfigAs("c.yaml"); err != nil {
|
||||||
|
t.Fatal(err)
|
||||||
|
}
|
||||||
|
read, err := afero.ReadFile(fs, "c.yaml")
|
||||||
|
if err != nil {
|
||||||
|
t.Fatal(err)
|
||||||
|
}
|
||||||
|
assert.Equal(t, yamlWriteExpected, read)
|
||||||
|
}
|
||||||
|
|
||||||
var yamlMergeExampleTgt = []byte(`
|
var yamlMergeExampleTgt = []byte(`
|
||||||
hello:
|
hello:
|
||||||
pop: 37890
|
pop: 37890
|
||||||
|
|
Loading…
Add table
Reference in a new issue