loop through ini sections

pass tests

write out ini file & tests

go fmt

Update viper_test.go
fix test

gofmt
This commit is contained in:
Matti R 2019-12-03 10:46:17 -05:00 committed by Márk Sági-Kazár
parent 3a19b6e0d9
commit 351bfe9719
2 changed files with 91 additions and 4 deletions

View file

@ -47,6 +47,7 @@ import (
jww "github.com/spf13/jwalterweatherman" jww "github.com/spf13/jwalterweatherman"
"github.com/spf13/pflag" "github.com/spf13/pflag"
"github.com/subosito/gotenv" "github.com/subosito/gotenv"
"gopkg.in/ini.v1"
) )
// ConfigMarshalError happens when failing to marshal the configuration. // ConfigMarshalError happens when failing to marshal the configuration.
@ -240,7 +241,7 @@ func New() *Viper {
// can use it in their testing as well. // can use it in their testing as well.
func Reset() { func Reset() {
v = New() v = New()
SupportedExts = []string{"json", "toml", "yaml", "yml", "properties", "props", "prop", "hcl", "dotenv", "env"} SupportedExts = []string{"json", "toml", "yaml", "yml", "properties", "props", "prop", "hcl", "dotenv", "env", "ini"}
SupportedRemoteProviders = []string{"etcd", "consul"} SupportedRemoteProviders = []string{"etcd", "consul"}
} }
@ -279,7 +280,7 @@ type RemoteProvider interface {
} }
// SupportedExts are universally supported extensions. // SupportedExts are universally supported extensions.
var SupportedExts = []string{"json", "toml", "yaml", "yml", "properties", "props", "prop", "hcl", "dotenv", "env"} var SupportedExts = []string{"json", "toml", "yaml", "yml", "properties", "props", "prop", "hcl", "dotenv", "env", "ini"}
// SupportedRemoteProviders are universally supported remote providers. // SupportedRemoteProviders are universally supported remote providers.
var SupportedRemoteProviders = []string{"etcd", "consul"} var SupportedRemoteProviders = []string{"etcd", "consul"}
@ -1462,6 +1463,23 @@ func (v *Viper) unmarshalReader(in io.Reader, c map[string]interface{}) error {
// set innermost value // set innermost value
deepestMap[lastKey] = value deepestMap[lastKey] = value
} }
case "ini":
cfg := ini.Empty()
err := cfg.Append(buf.Bytes())
if err != nil {
return ConfigParseError{err}
}
sections := cfg.Sections()
for i := 0; i < len(sections); i++ {
section := sections[i]
keys := section.Keys()
for j := 0; j < len(keys); j++ {
key := keys[j]
value := cfg.Section(section.Name()).Key(key.Name()).String()
c[section.Name()+"."+key.Name()] = value
}
}
} }
insensitiviseMap(c) insensitiviseMap(c)
@ -1545,6 +1563,22 @@ func (v *Viper) marshalWriter(f afero.File, configType string) error {
if _, err = f.WriteString(string(b)); err != nil { if _, err = f.WriteString(string(b)); err != nil {
return ConfigMarshalError{err} return ConfigMarshalError{err}
} }
case "ini":
keys := v.AllKeys()
cfg := ini.Empty()
ini.PrettyFormat = false
for i := 0; i < len(keys); i++ {
key := keys[i]
lastSep := strings.LastIndex(key, ".")
sectionName := key[:(lastSep)]
keyName := key[(lastSep + 1):]
if sectionName == "default" {
sectionName = ""
}
cfg.Section(sectionName).Key(keyName).SetValue(Get(key).(string))
}
cfg.WriteTo(f)
} }
return nil return nil
} }

View file

@ -118,6 +118,24 @@ var remoteExample = []byte(`{
"newkey":"remote" "newkey":"remote"
}`) }`)
var iniExample = []byte(`; Package name
NAME = ini
; Package version
VERSION = v1
; Package import path
IMPORT_PATH = gopkg.in/%(NAME)s.%(VERSION)s
# Information about package author
# Bio can be written in multiple lines.
[author]
NAME = Unknwon ; Succeeding comment
E-MAIL = fake@localhost
GITHUB = https://github.com/%(NAME)s
BIO = """Gopher.
Coding addict.
Good man.
""" # Succeeding comment`)
func initConfigs() { func initConfigs() {
Reset() Reset()
var r io.Reader var r io.Reader
@ -148,6 +166,10 @@ func initConfigs() {
SetConfigType("json") SetConfigType("json")
remote := bytes.NewReader(remoteExample) remote := bytes.NewReader(remoteExample)
unmarshalReader(remote, v.kvstore) unmarshalReader(remote, v.kvstore)
SetConfigType("ini")
r = bytes.NewReader(iniExample)
unmarshalReader(r, v.config)
} }
func initConfig(typ, config string) { func initConfig(typ, config string) {
@ -204,6 +226,14 @@ func initHcl() {
unmarshalReader(r, v.config) unmarshalReader(r, v.config)
} }
func initIni() {
Reset()
SetConfigType("ini")
r := bytes.NewReader(iniExample)
unmarshalReader(r, v.config)
}
// make directories for testing // make directories for testing
func initDirs(t *testing.T) (string, string, func()) { func initDirs(t *testing.T) (string, string, func()) {
@ -396,6 +426,11 @@ func TestHCL(t *testing.T) {
assert.NotEqual(t, "cronut", Get("type")) assert.NotEqual(t, "cronut", Get("type"))
} }
func TestIni(t *testing.T) {
initIni()
assert.Equal(t, "ini", Get("default.name"))
}
func TestRemotePrecedence(t *testing.T) { func TestRemotePrecedence(t *testing.T) {
initJSON() initJSON()
@ -521,6 +556,10 @@ func TestAllKeys(t *testing.T) {
ks := sort.StringSlice{ ks := sort.StringSlice{
"title", "title",
"author.bio",
"author.e-mail",
"author.github",
"author.name",
"newkey", "newkey",
"owner.organization", "owner.organization",
"owner.dob", "owner.dob",
@ -532,6 +571,9 @@ func TestAllKeys(t *testing.T) {
"hobbies", "hobbies",
"clothing.jacket", "clothing.jacket",
"clothing.trousers", "clothing.trousers",
"default.import_path",
"default.name",
"default.version",
"clothing.pants.size", "clothing.pants.size",
"age", "age",
"hacker", "hacker",
@ -556,6 +598,12 @@ func TestAllKeys(t *testing.T) {
"dob": dob, "dob": dob,
}, },
"title": "TOML Example", "title": "TOML Example",
"author": map[string]interface{}{
"e-mail": "fake@localhost",
"github": "https://github.com/Unknwon",
"name": "Unknwon",
"bio": "Gopher.\nCoding addict.\nGood man.\n",
},
"ppu": 0.55, "ppu": 0.55,
"eyes": "brown", "eyes": "brown",
"clothing": map[string]interface{}{ "clothing": map[string]interface{}{
@ -563,6 +611,11 @@ func TestAllKeys(t *testing.T) {
"jacket": "leather", "jacket": "leather",
"pants": map[string]interface{}{"size": "large"}, "pants": map[string]interface{}{"size": "large"},
}, },
"default": map[string]interface{}{
"import_path": "gopkg.in/ini.v1",
"name": "ini",
"version": "v1",
},
"id": "0001", "id": "0001",
"batters": map[string]interface{}{ "batters": map[string]interface{}{
"batter": []interface{}{ "batter": []interface{}{