mirror of
https://github.com/spf13/viper
synced 2024-12-23 03:57:01 +00:00
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:
parent
3a19b6e0d9
commit
351bfe9719
2 changed files with 91 additions and 4 deletions
38
viper.go
38
viper.go
|
@ -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
|
||||||
}
|
}
|
||||||
|
|
|
@ -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{}{
|
||||||
|
|
Loading…
Reference in a new issue