Compare commits
2 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
| 8f6d0d8be7 | |||
| 3c4b709fed |
@@ -35,11 +35,11 @@ jobs:
|
|||||||
|
|
||||||
steps:
|
steps:
|
||||||
- name: Checkout repository
|
- name: Checkout repository
|
||||||
uses: actions/checkout@v3
|
uses: actions/checkout@v2
|
||||||
|
|
||||||
# Initializes the CodeQL tools for scanning.
|
# Initializes the CodeQL tools for scanning.
|
||||||
- name: Initialize CodeQL
|
- name: Initialize CodeQL
|
||||||
uses: github/codeql-action/init@v2
|
uses: github/codeql-action/init@v1
|
||||||
with:
|
with:
|
||||||
languages: ${{ matrix.language }}
|
languages: ${{ matrix.language }}
|
||||||
# If you wish to specify custom queries, you can do so here or in a config file.
|
# If you wish to specify custom queries, you can do so here or in a config file.
|
||||||
@@ -50,7 +50,7 @@ jobs:
|
|||||||
# Autobuild attempts to build any compiled languages (C/C++, C#, or Java).
|
# Autobuild attempts to build any compiled languages (C/C++, C#, or Java).
|
||||||
# If this step fails, then you should remove it and run the build manually (see below)
|
# If this step fails, then you should remove it and run the build manually (see below)
|
||||||
- name: Autobuild
|
- name: Autobuild
|
||||||
uses: github/codeql-action/autobuild@v2
|
uses: github/codeql-action/autobuild@v1
|
||||||
|
|
||||||
# ℹ️ Command-line programs to run using the OS shell.
|
# ℹ️ Command-line programs to run using the OS shell.
|
||||||
# 📚 https://git.io/JvXDl
|
# 📚 https://git.io/JvXDl
|
||||||
@@ -64,4 +64,4 @@ jobs:
|
|||||||
# make release
|
# make release
|
||||||
|
|
||||||
- name: Perform CodeQL Analysis
|
- name: Perform CodeQL Analysis
|
||||||
uses: github/codeql-action/analyze@v2
|
uses: github/codeql-action/analyze@v1
|
||||||
|
|||||||
@@ -9,7 +9,7 @@ jobs:
|
|||||||
runs-on: "ubuntu-latest"
|
runs-on: "ubuntu-latest"
|
||||||
name: report
|
name: report
|
||||||
steps:
|
steps:
|
||||||
- uses: actions/checkout@v3
|
- uses: actions/checkout@master
|
||||||
with:
|
with:
|
||||||
fetch-depth: 0
|
fetch-depth: 0
|
||||||
- name: Setup go
|
- name: Setup go
|
||||||
|
|||||||
@@ -16,7 +16,7 @@ jobs:
|
|||||||
runs-on: ubuntu-latest
|
runs-on: ubuntu-latest
|
||||||
steps:
|
steps:
|
||||||
- name: Checkout
|
- name: Checkout
|
||||||
uses: actions/checkout@v3
|
uses: actions/checkout@v2
|
||||||
with:
|
with:
|
||||||
fetch-depth: 0
|
fetch-depth: 0
|
||||||
- name: Set up Go
|
- name: Set up Go
|
||||||
@@ -24,7 +24,7 @@ jobs:
|
|||||||
with:
|
with:
|
||||||
go-version: 1.18
|
go-version: 1.18
|
||||||
- name: Login to GitHub Container Registry
|
- name: Login to GitHub Container Registry
|
||||||
uses: docker/login-action@v2
|
uses: docker/login-action@v1
|
||||||
with:
|
with:
|
||||||
registry: ghcr.io
|
registry: ghcr.io
|
||||||
username: ${{ github.actor }}
|
username: ${{ github.actor }}
|
||||||
|
|||||||
@@ -16,7 +16,7 @@ jobs:
|
|||||||
runs-on: ${{ matrix.os }}
|
runs-on: ${{ matrix.os }}
|
||||||
name: ${{ matrix.go }}/${{ matrix.os }}
|
name: ${{ matrix.go }}/${{ matrix.os }}
|
||||||
steps:
|
steps:
|
||||||
- uses: actions/checkout@v3
|
- uses: actions/checkout@master
|
||||||
with:
|
with:
|
||||||
fetch-depth: 0
|
fetch-depth: 0
|
||||||
- name: Setup go ${{ matrix.go }}
|
- name: Setup go ${{ matrix.go }}
|
||||||
|
|||||||
@@ -1,6 +1,6 @@
|
|||||||
The MIT License (MIT)
|
The MIT License (MIT)
|
||||||
|
|
||||||
Copyright (c) 2013 - 2022 Thomas Pelletier, Eric Anderton
|
Copyright (c) 2013 - 2021 Thomas Pelletier, Eric Anderton
|
||||||
|
|
||||||
Permission is hereby granted, free of charge, to any person obtaining a copy
|
Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||||
of this software and associated documentation files (the "Software"), to deal
|
of this software and associated documentation files (the "Software"), to deal
|
||||||
|
|||||||
@@ -4,6 +4,17 @@ Go library for the [TOML](https://toml.io/en/) format.
|
|||||||
|
|
||||||
This library supports [TOML v1.0.0](https://toml.io/en/v1.0.0).
|
This library supports [TOML v1.0.0](https://toml.io/en/v1.0.0).
|
||||||
|
|
||||||
|
## Development status
|
||||||
|
|
||||||
|
This is the upcoming major version of go-toml. It is currently in active
|
||||||
|
development. As of release v2.0.0-beta.1, the library has reached feature parity
|
||||||
|
with v1, and fixes a lot known bugs and performance issues along the way.
|
||||||
|
|
||||||
|
If you do not need the advanced document editing features of v1, you are
|
||||||
|
encouraged to try out this version.
|
||||||
|
|
||||||
|
[👉 Roadmap for v2](https://github.com/pelletier/go-toml/discussions/506)
|
||||||
|
|
||||||
[🐞 Bug Reports](https://github.com/pelletier/go-toml/issues)
|
[🐞 Bug Reports](https://github.com/pelletier/go-toml/issues)
|
||||||
|
|
||||||
[💬 Anything else](https://github.com/pelletier/go-toml/discussions)
|
[💬 Anything else](https://github.com/pelletier/go-toml/discussions)
|
||||||
@@ -38,7 +49,7 @@ operations should not be shockingly slow. See [benchmarks](#benchmarks).
|
|||||||
### Strict mode
|
### Strict mode
|
||||||
|
|
||||||
`Decoder` can be set to "strict mode", which makes it error when some parts of
|
`Decoder` can be set to "strict mode", which makes it error when some parts of
|
||||||
the TOML document was not present in the target structure. This is a great way
|
the TOML document was not prevent in the target structure. This is a great way
|
||||||
to check for typos. [See example in the documentation][strict].
|
to check for typos. [See example in the documentation][strict].
|
||||||
|
|
||||||
[strict]: https://pkg.go.dev/github.com/pelletier/go-toml/v2#example-Decoder.DisallowUnknownFields
|
[strict]: https://pkg.go.dev/github.com/pelletier/go-toml/v2#example-Decoder.DisallowUnknownFields
|
||||||
@@ -540,13 +551,6 @@ complete solutions exist out there.
|
|||||||
[query]: https://github.com/pelletier/go-toml/tree/f99d6bbca119636aeafcf351ee52b3d202782627/query
|
[query]: https://github.com/pelletier/go-toml/tree/f99d6bbca119636aeafcf351ee52b3d202782627/query
|
||||||
[dasel]: https://github.com/TomWright/dasel
|
[dasel]: https://github.com/TomWright/dasel
|
||||||
|
|
||||||
## Versioning
|
|
||||||
|
|
||||||
Go-toml follows [Semantic Versioning](http://semver.org/). The supported version
|
|
||||||
of [TOML](https://github.com/toml-lang/toml) is indicated at the beginning of
|
|
||||||
this document. The last two major versions of Go are supported
|
|
||||||
(see [Go Release Policy](https://golang.org/doc/devel/release.html#policy)).
|
|
||||||
|
|
||||||
## License
|
## License
|
||||||
|
|
||||||
The MIT License (MIT). Read [LICENSE](LICENSE).
|
The MIT License (MIT). Read [LICENSE](LICENSE).
|
||||||
|
|||||||
@@ -11,6 +11,5 @@ func TestEntrySize(t *testing.T) {
|
|||||||
// Validate no regression on the size of entry{}. This is a critical bit for
|
// Validate no regression on the size of entry{}. This is a critical bit for
|
||||||
// performance of unmarshaling documents. Should only be increased with care
|
// performance of unmarshaling documents. Should only be increased with care
|
||||||
// and a very good reason.
|
// and a very good reason.
|
||||||
maxExpectedEntrySize := 48
|
require.LessOrEqual(t, 48, int(unsafe.Sizeof(entry{})))
|
||||||
require.LessOrEqual(t, int(unsafe.Sizeof(entry{})), maxExpectedEntrySize)
|
|
||||||
}
|
}
|
||||||
|
|||||||
+3
-15
@@ -128,8 +128,7 @@ func (enc *Encoder) SetIndentTables(indent bool) *Encoder {
|
|||||||
//
|
//
|
||||||
// In addition to the "toml" tag struct tag, a "comment" tag can be used to emit
|
// In addition to the "toml" tag struct tag, a "comment" tag can be used to emit
|
||||||
// a TOML comment before the value being annotated. Comments are ignored inside
|
// a TOML comment before the value being annotated. Comments are ignored inside
|
||||||
// inline tables. For array tables, the comment is only present before the first
|
// inline tables.
|
||||||
// element of the array.
|
|
||||||
func (enc *Encoder) Encode(v interface{}) error {
|
func (enc *Encoder) Encode(v interface{}) error {
|
||||||
var (
|
var (
|
||||||
b []byte
|
b []byte
|
||||||
@@ -653,19 +652,10 @@ func (enc *Encoder) encodeStruct(b []byte, ctx encoderCtx, v reflect.Value) ([]b
|
|||||||
}
|
}
|
||||||
|
|
||||||
func (enc *Encoder) encodeComment(indent int, comment string, b []byte) []byte {
|
func (enc *Encoder) encodeComment(indent int, comment string, b []byte) []byte {
|
||||||
for len(comment) > 0 {
|
if comment != "" {
|
||||||
var line string
|
|
||||||
idx := strings.IndexByte(comment, '\n')
|
|
||||||
if idx >= 0 {
|
|
||||||
line = comment[:idx]
|
|
||||||
comment = comment[idx+1:]
|
|
||||||
} else {
|
|
||||||
line = comment
|
|
||||||
comment = ""
|
|
||||||
}
|
|
||||||
b = enc.indent(indent, b)
|
b = enc.indent(indent, b)
|
||||||
b = append(b, "# "...)
|
b = append(b, "# "...)
|
||||||
b = append(b, line...)
|
b = append(b, comment...)
|
||||||
b = append(b, '\n')
|
b = append(b, '\n')
|
||||||
}
|
}
|
||||||
return b
|
return b
|
||||||
@@ -891,8 +881,6 @@ func (enc *Encoder) encodeSliceAsArrayTable(b []byte, ctx encoderCtx, v reflect.
|
|||||||
scratch = append(scratch, "]]\n"...)
|
scratch = append(scratch, "]]\n"...)
|
||||||
ctx.skipTableHeader = true
|
ctx.skipTableHeader = true
|
||||||
|
|
||||||
b = enc.encodeComment(ctx.indent, ctx.options.comment, b)
|
|
||||||
|
|
||||||
for i := 0; i < v.Len(); i++ {
|
for i := 0; i < v.Len(); i++ {
|
||||||
b = append(b, scratch...)
|
b = append(b, scratch...)
|
||||||
|
|
||||||
|
|||||||
@@ -1004,22 +1004,6 @@ func TestIssue752(t *testing.T) {
|
|||||||
require.Equal(t, "", string(out))
|
require.Equal(t, "", string(out))
|
||||||
}
|
}
|
||||||
|
|
||||||
func TestIssue768(t *testing.T) {
|
|
||||||
type cfg struct {
|
|
||||||
Name string `comment:"This is a multiline comment.\nThis is line 2."`
|
|
||||||
}
|
|
||||||
|
|
||||||
out, err := toml.Marshal(&cfg{})
|
|
||||||
require.NoError(t, err)
|
|
||||||
|
|
||||||
expected := `# This is a multiline comment.
|
|
||||||
# This is line 2.
|
|
||||||
Name = ''
|
|
||||||
`
|
|
||||||
|
|
||||||
require.Equal(t, expected, string(out))
|
|
||||||
}
|
|
||||||
|
|
||||||
func TestMarshalNestedAnonymousStructs(t *testing.T) {
|
func TestMarshalNestedAnonymousStructs(t *testing.T) {
|
||||||
type Embedded struct {
|
type Embedded struct {
|
||||||
Value string `toml:"value" json:"value"`
|
Value string `toml:"value" json:"value"`
|
||||||
|
|||||||
+98
-37
@@ -230,15 +230,6 @@ func (d *decoder) fromParser(root reflect.Value) error {
|
|||||||
return d.p.Error()
|
return d.p.Error()
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
|
||||||
Rules for the unmarshal code:
|
|
||||||
|
|
||||||
- The stack is used to keep track of which values need to be set where.
|
|
||||||
- handle* functions <=> switch on a given ast.Kind.
|
|
||||||
- unmarshalX* functions need to unmarshal a node of kind X.
|
|
||||||
- An "object" is either a struct or a map.
|
|
||||||
*/
|
|
||||||
|
|
||||||
func (d *decoder) handleRootExpression(expr *ast.Node, v reflect.Value) error {
|
func (d *decoder) handleRootExpression(expr *ast.Node, v reflect.Value) error {
|
||||||
var x reflect.Value
|
var x reflect.Value
|
||||||
var err error
|
var err error
|
||||||
@@ -400,6 +391,84 @@ func (d *decoder) handleArrayTableCollection(key ast.Iterator, v reflect.Value)
|
|||||||
return d.handleArrayTable(key, v)
|
return d.handleArrayTable(key, v)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func (d *decoder) handleKeyValuePartMapStringInterface(key ast.Iterator, value *ast.Node, m map[string]interface{}) (reflect.Value, error) {
|
||||||
|
k := string(key.Node().Data)
|
||||||
|
|
||||||
|
newMap := false
|
||||||
|
if m == nil {
|
||||||
|
newMap = true
|
||||||
|
m = make(map[string]interface{}, 8)
|
||||||
|
}
|
||||||
|
|
||||||
|
set := false
|
||||||
|
v, ok := m[k]
|
||||||
|
if !ok || key.IsLast() {
|
||||||
|
set = true
|
||||||
|
v = nil
|
||||||
|
}
|
||||||
|
|
||||||
|
mv := reflect.ValueOf(&v).Elem()
|
||||||
|
|
||||||
|
x, err := d.handleKeyValueInner(key, value, mv)
|
||||||
|
if err != nil {
|
||||||
|
return reflect.Value{}, err
|
||||||
|
}
|
||||||
|
if x.IsValid() {
|
||||||
|
mv = x
|
||||||
|
set = true
|
||||||
|
}
|
||||||
|
|
||||||
|
if set {
|
||||||
|
m[k] = mv.Interface()
|
||||||
|
}
|
||||||
|
|
||||||
|
if newMap {
|
||||||
|
return reflect.ValueOf(m), nil
|
||||||
|
}
|
||||||
|
|
||||||
|
return reflect.Value{}, nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func (d *decoder) handleKeyPartMapStringInterface(key ast.Iterator, m map[string]interface{}, nextFn handlerFn, makeFn valueMakerFn) (reflect.Value, error) {
|
||||||
|
newMap := false
|
||||||
|
|
||||||
|
k := string(key.Node().Data)
|
||||||
|
if m == nil {
|
||||||
|
newMap = true
|
||||||
|
m = make(map[string]interface{}, 8)
|
||||||
|
}
|
||||||
|
|
||||||
|
v, ok := m[k]
|
||||||
|
set := false
|
||||||
|
|
||||||
|
if !ok || v == nil {
|
||||||
|
set = true
|
||||||
|
v = makeFn().Interface()
|
||||||
|
}
|
||||||
|
|
||||||
|
mv := reflect.ValueOf(v)
|
||||||
|
|
||||||
|
x, err := nextFn(key, mv)
|
||||||
|
if err != nil {
|
||||||
|
return reflect.Value{}, err
|
||||||
|
}
|
||||||
|
|
||||||
|
if x.IsValid() {
|
||||||
|
mv = x
|
||||||
|
set = true
|
||||||
|
}
|
||||||
|
|
||||||
|
if set {
|
||||||
|
m[k] = mv.Interface()
|
||||||
|
}
|
||||||
|
|
||||||
|
if newMap {
|
||||||
|
return reflect.ValueOf(m), nil
|
||||||
|
}
|
||||||
|
|
||||||
|
return reflect.Value{}, nil
|
||||||
|
}
|
||||||
|
|
||||||
func (d *decoder) handleKeyPart(key ast.Iterator, v reflect.Value, nextFn handlerFn, makeFn valueMakerFn) (reflect.Value, error) {
|
func (d *decoder) handleKeyPart(key ast.Iterator, v reflect.Value, nextFn handlerFn, makeFn valueMakerFn) (reflect.Value, error) {
|
||||||
var rv reflect.Value
|
var rv reflect.Value
|
||||||
|
|
||||||
@@ -416,6 +485,11 @@ func (d *decoder) handleKeyPart(key ast.Iterator, v reflect.Value, nextFn handle
|
|||||||
case reflect.Map:
|
case reflect.Map:
|
||||||
vt := v.Type()
|
vt := v.Type()
|
||||||
|
|
||||||
|
if vt == mapStringInterfaceType {
|
||||||
|
m := v.Interface().(map[string]interface{})
|
||||||
|
return d.handleKeyPartMapStringInterface(key, m, nextFn, makeFn)
|
||||||
|
}
|
||||||
|
|
||||||
// Create the key for the map element. Convert to key type.
|
// Create the key for the map element. Convert to key type.
|
||||||
mk := reflect.ValueOf(string(key.Node().Data)).Convert(vt.Key())
|
mk := reflect.ValueOf(string(key.Node().Data)).Convert(vt.Key())
|
||||||
|
|
||||||
@@ -866,27 +940,12 @@ func (d *decoder) unmarshalFloat(value *ast.Node, v reflect.Value) error {
|
|||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
const (
|
func (d *decoder) unmarshalInteger(value *ast.Node, v reflect.Value) error {
|
||||||
|
const (
|
||||||
maxInt = int64(^uint(0) >> 1)
|
maxInt = int64(^uint(0) >> 1)
|
||||||
minInt = -maxInt - 1
|
minInt = -maxInt - 1
|
||||||
)
|
)
|
||||||
|
|
||||||
// Maximum value of uint for decoding. Currently the decoder parses the integer
|
|
||||||
// into an int64. As a result, on architectures where uint is 64 bits, the
|
|
||||||
// effective maximum uint we can decode is the maximum of int64. On
|
|
||||||
// architectures where uint is 32 bits, the maximum value we can decode is
|
|
||||||
// lower: the maximum of uint32. I didn't find a way to figure out this value at
|
|
||||||
// compile time, so it is computed during initialization.
|
|
||||||
var maxUint int64 = math.MaxInt64
|
|
||||||
|
|
||||||
func init() {
|
|
||||||
m := uint64(^uint(0))
|
|
||||||
if m < uint64(maxUint) {
|
|
||||||
maxUint = int64(m)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
func (d *decoder) unmarshalInteger(value *ast.Node, v reflect.Value) error {
|
|
||||||
i, err := parseInteger(value.Data)
|
i, err := parseInteger(value.Data)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
@@ -947,7 +1006,7 @@ func (d *decoder) unmarshalInteger(value *ast.Node, v reflect.Value) error {
|
|||||||
|
|
||||||
r = reflect.ValueOf(uint8(i))
|
r = reflect.ValueOf(uint8(i))
|
||||||
case reflect.Uint:
|
case reflect.Uint:
|
||||||
if i < 0 || i > maxUint {
|
if i < 0 {
|
||||||
return fmt.Errorf("toml: negative number %d does not fit in an uint", i)
|
return fmt.Errorf("toml: negative number %d does not fit in an uint", i)
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -1014,6 +1073,11 @@ func (d *decoder) handleKeyValuePart(key ast.Iterator, value *ast.Node, v reflec
|
|||||||
case reflect.Map:
|
case reflect.Map:
|
||||||
vt := v.Type()
|
vt := v.Type()
|
||||||
|
|
||||||
|
if vt == mapStringInterfaceType {
|
||||||
|
m := v.Interface().(map[string]interface{})
|
||||||
|
return d.handleKeyValuePartMapStringInterface(key, value, m)
|
||||||
|
}
|
||||||
|
|
||||||
mk := reflect.ValueOf(string(key.Node().Data))
|
mk := reflect.ValueOf(string(key.Node().Data))
|
||||||
mkt := stringType
|
mkt := stringType
|
||||||
|
|
||||||
@@ -1037,13 +1101,11 @@ func (d *decoder) handleKeyValuePart(key ast.Iterator, value *ast.Node, v reflec
|
|||||||
if !mv.IsValid() {
|
if !mv.IsValid() {
|
||||||
set = true
|
set = true
|
||||||
mv = reflect.New(v.Type().Elem()).Elem()
|
mv = reflect.New(v.Type().Elem()).Elem()
|
||||||
} else {
|
} else if key.IsLast() {
|
||||||
if key.IsLast() {
|
|
||||||
var x interface{}
|
var x interface{}
|
||||||
mv = reflect.ValueOf(&x).Elem()
|
mv = reflect.ValueOf(&x).Elem()
|
||||||
set = true
|
set = true
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
|
||||||
nv, err := d.handleKeyValueInner(key, value, mv)
|
nv, err := d.handleKeyValueInner(key, value, mv)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
@@ -1182,6 +1244,11 @@ func forEachField(t reflect.Type, path []int, do func(name string, path []int))
|
|||||||
fieldPath := append(path, i)
|
fieldPath := append(path, i)
|
||||||
fieldPath = fieldPath[:len(fieldPath):len(fieldPath)]
|
fieldPath = fieldPath[:len(fieldPath):len(fieldPath)]
|
||||||
|
|
||||||
|
if f.Anonymous {
|
||||||
|
forEachField(f.Type, fieldPath, do)
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
|
||||||
name := f.Tag.Get("toml")
|
name := f.Tag.Get("toml")
|
||||||
if name == "-" {
|
if name == "-" {
|
||||||
continue
|
continue
|
||||||
@@ -1190,12 +1257,6 @@ func forEachField(t reflect.Type, path []int, do func(name string, path []int))
|
|||||||
if i := strings.IndexByte(name, ','); i >= 0 {
|
if i := strings.IndexByte(name, ','); i >= 0 {
|
||||||
name = name[:i]
|
name = name[:i]
|
||||||
}
|
}
|
||||||
|
|
||||||
if f.Anonymous && name == "" {
|
|
||||||
forEachField(f.Type, fieldPath, do)
|
|
||||||
continue
|
|
||||||
}
|
|
||||||
|
|
||||||
if name == "" {
|
if name == "" {
|
||||||
name = f.Name
|
name = f.Name
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -2380,49 +2380,6 @@ func TestIssue714(t *testing.T) {
|
|||||||
require.Error(t, err)
|
require.Error(t, err)
|
||||||
}
|
}
|
||||||
|
|
||||||
func TestIssue772(t *testing.T) {
|
|
||||||
type FileHandling struct {
|
|
||||||
FilePattern string `toml:"pattern"`
|
|
||||||
}
|
|
||||||
|
|
||||||
type Config struct {
|
|
||||||
FileHandling `toml:"filehandling"`
|
|
||||||
}
|
|
||||||
|
|
||||||
var defaultConfigFile = []byte(`
|
|
||||||
[filehandling]
|
|
||||||
pattern = "reach-masterdev-"`)
|
|
||||||
|
|
||||||
config := Config{}
|
|
||||||
err := toml.Unmarshal(defaultConfigFile, &config)
|
|
||||||
require.NoError(t, err)
|
|
||||||
require.Equal(t, "reach-masterdev-", config.FileHandling.FilePattern)
|
|
||||||
}
|
|
||||||
|
|
||||||
func TestIssue774(t *testing.T) {
|
|
||||||
type ScpData struct {
|
|
||||||
Host string `json:"host"`
|
|
||||||
}
|
|
||||||
|
|
||||||
type GenConfig struct {
|
|
||||||
SCP []ScpData `toml:"scp" comment:"Array of Secure Copy Configurations"`
|
|
||||||
}
|
|
||||||
|
|
||||||
c := &GenConfig{}
|
|
||||||
c.SCP = []ScpData{{Host: "main.domain.com"}}
|
|
||||||
|
|
||||||
b, err := toml.Marshal(c)
|
|
||||||
require.NoError(t, err)
|
|
||||||
|
|
||||||
expected := `# Array of Secure Copy Configurations
|
|
||||||
[[scp]]
|
|
||||||
Host = 'main.domain.com'
|
|
||||||
|
|
||||||
`
|
|
||||||
|
|
||||||
require.Equal(t, expected, string(b))
|
|
||||||
}
|
|
||||||
|
|
||||||
func TestUnmarshalDecodeErrors(t *testing.T) {
|
func TestUnmarshalDecodeErrors(t *testing.T) {
|
||||||
examples := []struct {
|
examples := []struct {
|
||||||
desc string
|
desc string
|
||||||
|
|||||||
Reference in New Issue
Block a user