mirror of https://github.com/spf13/viper.git
feat(encoding): experimental toml v2 support
Signed-off-by: Mark Sagi-Kazar <mark.sagikazar@gmail.com>
This commit is contained in:
parent
98c10c3c31
commit
b13f0963f6
|
@ -17,7 +17,7 @@ jobs:
|
||||||
matrix:
|
matrix:
|
||||||
os: [ubuntu-latest, macos-latest, windows-latest]
|
os: [ubuntu-latest, macos-latest, windows-latest]
|
||||||
go: ['1.14', '1.15', '1.16', '1.17']
|
go: ['1.14', '1.15', '1.16', '1.17']
|
||||||
tags: ['', 'viper_yaml3']
|
tags: ['', 'viper_yaml3', 'viper_toml2']
|
||||||
env:
|
env:
|
||||||
GOFLAGS: -mod=readonly
|
GOFLAGS: -mod=readonly
|
||||||
|
|
||||||
|
|
3
go.mod
3
go.mod
|
@ -8,12 +8,13 @@ require (
|
||||||
github.com/magiconair/properties v1.8.5
|
github.com/magiconair/properties v1.8.5
|
||||||
github.com/mitchellh/mapstructure v1.4.3
|
github.com/mitchellh/mapstructure v1.4.3
|
||||||
github.com/pelletier/go-toml v1.9.4
|
github.com/pelletier/go-toml v1.9.4
|
||||||
|
github.com/pelletier/go-toml/v2 v2.0.0-beta.6
|
||||||
github.com/sagikazarmark/crypt v0.4.0
|
github.com/sagikazarmark/crypt v0.4.0
|
||||||
github.com/spf13/afero v1.7.1
|
github.com/spf13/afero v1.7.1
|
||||||
github.com/spf13/cast v1.4.1
|
github.com/spf13/cast v1.4.1
|
||||||
github.com/spf13/jwalterweatherman v1.1.0
|
github.com/spf13/jwalterweatherman v1.1.0
|
||||||
github.com/spf13/pflag v1.0.5
|
github.com/spf13/pflag v1.0.5
|
||||||
github.com/stretchr/testify v1.7.0
|
github.com/stretchr/testify v1.7.1-0.20210427113832-6241f9ab9942
|
||||||
github.com/subosito/gotenv v1.2.0
|
github.com/subosito/gotenv v1.2.0
|
||||||
gopkg.in/ini.v1 v1.66.2
|
gopkg.in/ini.v1 v1.66.2
|
||||||
gopkg.in/yaml.v2 v2.4.0
|
gopkg.in/yaml.v2 v2.4.0
|
||||||
|
|
5
go.sum
5
go.sum
|
@ -318,6 +318,8 @@ github.com/pascaldekloe/goe v0.1.0 h1:cBOtyMzM9HTpWjXfbbunk26uA6nG3a8n06Wieeh0Mw
|
||||||
github.com/pascaldekloe/goe v0.1.0/go.mod h1:lzWF7FIEvWOWxwDKqyGYQf6ZUaNfKdP144TG7ZOy1lc=
|
github.com/pascaldekloe/goe v0.1.0/go.mod h1:lzWF7FIEvWOWxwDKqyGYQf6ZUaNfKdP144TG7ZOy1lc=
|
||||||
github.com/pelletier/go-toml v1.9.4 h1:tjENF6MfZAg8e4ZmZTeWaWiT2vXtsoO6+iuOjFhECwM=
|
github.com/pelletier/go-toml v1.9.4 h1:tjENF6MfZAg8e4ZmZTeWaWiT2vXtsoO6+iuOjFhECwM=
|
||||||
github.com/pelletier/go-toml v1.9.4/go.mod h1:u1nR/EPcESfeI/szUZKdtJ0xRNbUoANCkoOuaOx1Y+c=
|
github.com/pelletier/go-toml v1.9.4/go.mod h1:u1nR/EPcESfeI/szUZKdtJ0xRNbUoANCkoOuaOx1Y+c=
|
||||||
|
github.com/pelletier/go-toml/v2 v2.0.0-beta.6 h1:JFNqj2afbbhCqTiyN16D7Tudc/aaDzE2FBDk+VlBQnE=
|
||||||
|
github.com/pelletier/go-toml/v2 v2.0.0-beta.6/go.mod h1:ke6xncR3W76Ba8xnVxkrZG0js6Rd2BsQEAYrfgJ6eQA=
|
||||||
github.com/pkg/errors v0.8.0/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0=
|
github.com/pkg/errors v0.8.0/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0=
|
||||||
github.com/pkg/errors v0.8.1/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0=
|
github.com/pkg/errors v0.8.1/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0=
|
||||||
github.com/pkg/errors v0.9.1 h1:FEBLx1zS214owpjy7qsBeixbURkuhQAwrK5UwLGTwt4=
|
github.com/pkg/errors v0.9.1 h1:FEBLx1zS214owpjy7qsBeixbURkuhQAwrK5UwLGTwt4=
|
||||||
|
@ -368,8 +370,9 @@ github.com/stretchr/testify v1.3.0/go.mod h1:M5WIy9Dh21IEIfnGCwXGc5bZfKNJtfHm1UV
|
||||||
github.com/stretchr/testify v1.4.0/go.mod h1:j7eGeouHqKxXV5pUuKE4zz7dFj8WfuZ+81PSLYec5m4=
|
github.com/stretchr/testify v1.4.0/go.mod h1:j7eGeouHqKxXV5pUuKE4zz7dFj8WfuZ+81PSLYec5m4=
|
||||||
github.com/stretchr/testify v1.5.1/go.mod h1:5W2xD1RspED5o8YsWQXVCued0rvSQ+mT+I5cxcmMvtA=
|
github.com/stretchr/testify v1.5.1/go.mod h1:5W2xD1RspED5o8YsWQXVCued0rvSQ+mT+I5cxcmMvtA=
|
||||||
github.com/stretchr/testify v1.6.1/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg=
|
github.com/stretchr/testify v1.6.1/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg=
|
||||||
github.com/stretchr/testify v1.7.0 h1:nwc3DEeHmmLAfoZucVR881uASk0Mfjw8xYJ99tb5CcY=
|
|
||||||
github.com/stretchr/testify v1.7.0/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg=
|
github.com/stretchr/testify v1.7.0/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg=
|
||||||
|
github.com/stretchr/testify v1.7.1-0.20210427113832-6241f9ab9942 h1:t0lM6y/M5IiUZyvbBTcngso8SZEZICH7is9B6g/obVU=
|
||||||
|
github.com/stretchr/testify v1.7.1-0.20210427113832-6241f9ab9942/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg=
|
||||||
github.com/subosito/gotenv v1.2.0 h1:Slr1R9HxAlEKefgq5jn9U+DnETlIUa6HfgEzj0g5d7s=
|
github.com/subosito/gotenv v1.2.0 h1:Slr1R9HxAlEKefgq5jn9U+DnETlIUa6HfgEzj0g5d7s=
|
||||||
github.com/subosito/gotenv v1.2.0/go.mod h1:N0PQaV/YGNqwC0u51sEeR/aUtSLEXKX9iv69rRypqCw=
|
github.com/subosito/gotenv v1.2.0/go.mod h1:N0PQaV/YGNqwC0u51sEeR/aUtSLEXKX9iv69rRypqCw=
|
||||||
github.com/tv42/httpunix v0.0.0-20150427012821-b75d8614f926/go.mod h1:9ESjWnEqriFuLhtthL60Sar/7RFoluCcXsuvEwTV5KM=
|
github.com/tv42/httpunix v0.0.0-20150427012821-b75d8614f926/go.mod h1:9ESjWnEqriFuLhtthL60Sar/7RFoluCcXsuvEwTV5KM=
|
||||||
|
|
|
@ -1,3 +1,6 @@
|
||||||
|
//go:build !viper_toml2
|
||||||
|
// +build !viper_toml2
|
||||||
|
|
||||||
package toml
|
package toml
|
||||||
|
|
||||||
import (
|
import (
|
||||||
|
|
|
@ -0,0 +1,19 @@
|
||||||
|
//go:build viper_toml2
|
||||||
|
// +build viper_toml2
|
||||||
|
|
||||||
|
package toml
|
||||||
|
|
||||||
|
import (
|
||||||
|
"github.com/pelletier/go-toml/v2"
|
||||||
|
)
|
||||||
|
|
||||||
|
// Codec implements the encoding.Encoder and encoding.Decoder interfaces for TOML encoding.
|
||||||
|
type Codec struct{}
|
||||||
|
|
||||||
|
func (Codec) Encode(v map[string]interface{}) ([]byte, error) {
|
||||||
|
return toml.Marshal(v)
|
||||||
|
}
|
||||||
|
|
||||||
|
func (Codec) Decode(b []byte, v map[string]interface{}) error {
|
||||||
|
return toml.Unmarshal(b, &v)
|
||||||
|
}
|
|
@ -0,0 +1,109 @@
|
||||||
|
//go:build viper_toml2
|
||||||
|
// +build viper_toml2
|
||||||
|
|
||||||
|
package toml
|
||||||
|
|
||||||
|
import (
|
||||||
|
"reflect"
|
||||||
|
"testing"
|
||||||
|
)
|
||||||
|
|
||||||
|
// original form of the data
|
||||||
|
const original = `# key-value pair
|
||||||
|
key = "value"
|
||||||
|
list = ["item1", "item2", "item3"]
|
||||||
|
|
||||||
|
[map]
|
||||||
|
key = "value"
|
||||||
|
|
||||||
|
# nested
|
||||||
|
# map
|
||||||
|
[nested_map]
|
||||||
|
[nested_map.map]
|
||||||
|
key = "value"
|
||||||
|
list = [
|
||||||
|
"item1",
|
||||||
|
"item2",
|
||||||
|
"item3",
|
||||||
|
]
|
||||||
|
`
|
||||||
|
|
||||||
|
// encoded form of the data
|
||||||
|
const encoded = `key = 'value'
|
||||||
|
list = ['item1', 'item2', 'item3']
|
||||||
|
[map]
|
||||||
|
key = 'value'
|
||||||
|
|
||||||
|
[nested_map]
|
||||||
|
[nested_map.map]
|
||||||
|
key = 'value'
|
||||||
|
list = ['item1', 'item2', 'item3']
|
||||||
|
|
||||||
|
|
||||||
|
`
|
||||||
|
|
||||||
|
// Viper's internal representation
|
||||||
|
var data = map[string]interface{}{
|
||||||
|
"key": "value",
|
||||||
|
"list": []interface{}{
|
||||||
|
"item1",
|
||||||
|
"item2",
|
||||||
|
"item3",
|
||||||
|
},
|
||||||
|
"map": map[string]interface{}{
|
||||||
|
"key": "value",
|
||||||
|
},
|
||||||
|
"nested_map": map[string]interface{}{
|
||||||
|
"map": map[string]interface{}{
|
||||||
|
"key": "value",
|
||||||
|
"list": []interface{}{
|
||||||
|
"item1",
|
||||||
|
"item2",
|
||||||
|
"item3",
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
}
|
||||||
|
|
||||||
|
func TestCodec_Encode(t *testing.T) {
|
||||||
|
codec := Codec{}
|
||||||
|
|
||||||
|
b, err := codec.Encode(data)
|
||||||
|
if err != nil {
|
||||||
|
t.Fatal(err)
|
||||||
|
}
|
||||||
|
|
||||||
|
if encoded != string(b) {
|
||||||
|
t.Fatalf("decoded value does not match the expected one\nactual: %#v\nexpected: %#v", string(b), encoded)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func TestCodec_Decode(t *testing.T) {
|
||||||
|
t.Run("OK", func(t *testing.T) {
|
||||||
|
codec := Codec{}
|
||||||
|
|
||||||
|
v := map[string]interface{}{}
|
||||||
|
|
||||||
|
err := codec.Decode([]byte(original), v)
|
||||||
|
if err != nil {
|
||||||
|
t.Fatal(err)
|
||||||
|
}
|
||||||
|
|
||||||
|
if !reflect.DeepEqual(data, v) {
|
||||||
|
t.Fatalf("decoded value does not match the expected one\nactual: %#v\nexpected: %#v", v, data)
|
||||||
|
}
|
||||||
|
})
|
||||||
|
|
||||||
|
t.Run("InvalidData", func(t *testing.T) {
|
||||||
|
codec := Codec{}
|
||||||
|
|
||||||
|
v := map[string]interface{}{}
|
||||||
|
|
||||||
|
err := codec.Decode([]byte(`invalid data`), v)
|
||||||
|
if err == nil {
|
||||||
|
t.Fatal("expected decoding to fail")
|
||||||
|
}
|
||||||
|
|
||||||
|
t.Logf("decoding failed as expected: %s", err)
|
||||||
|
})
|
||||||
|
}
|
|
@ -1,3 +1,6 @@
|
||||||
|
//go:build !viper_toml2
|
||||||
|
// +build !viper_toml2
|
||||||
|
|
||||||
package toml
|
package toml
|
||||||
|
|
||||||
import (
|
import (
|
||||||
|
|
Loading…
Reference in New Issue