summaryrefslogtreecommitdiffstats
path: root/vendor/github.com/pelletier/go-toml
diff options
context:
space:
mode:
Diffstat (limited to 'vendor/github.com/pelletier/go-toml')
-rw-r--r--vendor/github.com/pelletier/go-toml/.travis.yml6
-rw-r--r--vendor/github.com/pelletier/go-toml/README.md80
-rwxr-xr-xvendor/github.com/pelletier/go-toml/benchmark.sh32
-rw-r--r--vendor/github.com/pelletier/go-toml/cmd/tomljson/main.go5
-rw-r--r--vendor/github.com/pelletier/go-toml/cmd/tomll/main.go5
-rw-r--r--vendor/github.com/pelletier/go-toml/doc.go77
-rw-r--r--vendor/github.com/pelletier/go-toml/doc_test.go28
-rw-r--r--vendor/github.com/pelletier/go-toml/lexer.go13
-rw-r--r--vendor/github.com/pelletier/go-toml/lexer_test.go29
-rw-r--r--vendor/github.com/pelletier/go-toml/marshal.go36
-rw-r--r--vendor/github.com/pelletier/go-toml/marshal_test.go19
-rw-r--r--vendor/github.com/pelletier/go-toml/query/lexer.go8
-rw-r--r--vendor/github.com/pelletier/go-toml/query/lexer_test.go2
-rw-r--r--vendor/github.com/pelletier/go-toml/query/match_test.go2
-rw-r--r--vendor/github.com/pelletier/go-toml/query/parser_test.go2
-rw-r--r--vendor/github.com/pelletier/go-toml/query/tokens.go7
-rw-r--r--vendor/github.com/pelletier/go-toml/toml.go3
-rw-r--r--vendor/github.com/pelletier/go-toml/tomltree_create.go17
-rw-r--r--vendor/github.com/pelletier/go-toml/tomltree_write.go55
-rw-r--r--vendor/github.com/pelletier/go-toml/tomltree_write_test.go87
20 files changed, 332 insertions, 181 deletions
diff --git a/vendor/github.com/pelletier/go-toml/.travis.yml b/vendor/github.com/pelletier/go-toml/.travis.yml
index 64f03809a..1f8b41ffe 100644
--- a/vendor/github.com/pelletier/go-toml/.travis.yml
+++ b/vendor/github.com/pelletier/go-toml/.travis.yml
@@ -2,15 +2,17 @@ sudo: false
language: go
go:
- 1.6.4
- - 1.7.5
- - 1.8
+ - 1.7.6
+ - 1.8.3
- tip
matrix:
allow_failures:
- go: tip
fast_finish: true
script:
+ - if [ -n "$(go fmt ./...)" ]; then exit 1; fi
- ./test.sh
+ - ./benchmark.sh $TRAVIS_BRANCH https://github.com/$TRAVIS_REPO_SLUG.git
before_install:
- go get github.com/axw/gocov/gocov
- go get github.com/mattn/goveralls
diff --git a/vendor/github.com/pelletier/go-toml/README.md b/vendor/github.com/pelletier/go-toml/README.md
index 8279102b1..22da41a81 100644
--- a/vendor/github.com/pelletier/go-toml/README.md
+++ b/vendor/github.com/pelletier/go-toml/README.md
@@ -17,64 +17,62 @@ Go-toml provides the following features for using data parsed from TOML document
* Load TOML documents from files and string data
* Easily navigate TOML structure using Tree
+* Mashaling and unmarshaling to and from data structures
* Line & column position data for all parsed elements
* [Query support similar to JSON-Path](query/)
* Syntax errors contain line and column numbers
-Go-toml is designed to help cover use-cases not covered by reflection-based TOML parsing:
+## Import
-* Semantic evaluation of parsed TOML
-* Informing a user of mistakes in the source document, after it has been parsed
-* Programatic handling of default values on a case-by-case basis
-* Using a TOML document as a flexible data-store
+```go
+import "github.com/pelletier/go-toml"
+```
-## Import
+## Usage example
- import "github.com/pelletier/go-toml"
+Read a TOML document:
-## Usage
+```go
+config, _ := toml.LoadString(`
+[postgres]
+user = "pelletier"
+password = "mypassword"`)
+// retrieve data directly
+user := config.Get("postgres.user").(string)
-### Example
+// or using an intermediate object
+postgresConfig := config.Get("postgres").(*toml.Tree)
+password = postgresConfig.Get("password").(string)
+```
+
+Or use Unmarshal:
-Say you have a TOML file that looks like this:
+```go
+type Postgres struct {
+ User string
+ Password string
+}
+type Config struct {
+ Postgres Postgres
+}
-```toml
+doc := []byte(`
[postgres]
user = "pelletier"
-password = "mypassword"
+password = "mypassword"`)
+
+config := Config{}
+Unmarshal(doc, &config)
+fmt.Println("user=", config.Postgres.User)
```
-Read the username and password like this:
+Or use a query:
```go
-import (
- "fmt"
- "github.com/pelletier/go-toml"
-)
-
-config, err := toml.LoadFile("config.toml")
-if err != nil {
- fmt.Println("Error ", err.Error())
-} else {
- // retrieve data directly
- user := config.Get("postgres.user").(string)
- password := config.Get("postgres.password").(string)
-
- // or using an intermediate object
- configTree := config.Get("postgres").(*toml.Tree)
- user = configTree.Get("user").(string)
- password = configTree.Get("password").(string)
- fmt.Println("User is ", user, ". Password is ", password)
-
- // show where elements are in the file
- fmt.Println("User position: %v", configTree.GetPosition("user"))
- fmt.Println("Password position: %v", configTree.GetPosition("password"))
-
- // use a query to gather elements without walking the tree
- results, _ := config.Query("$..[user,password]")
- for ii, item := range results.Values() {
- fmt.Println("Query result %d: %v", ii, item)
- }
+// use a query to gather elements without walking the tree
+results, _ := config.Query("$..[user,password]")
+for ii, item := range results.Values() {
+ fmt.Println("Query result %d: %v", ii, item)
}
```
diff --git a/vendor/github.com/pelletier/go-toml/benchmark.sh b/vendor/github.com/pelletier/go-toml/benchmark.sh
new file mode 100755
index 000000000..cf1dabb4a
--- /dev/null
+++ b/vendor/github.com/pelletier/go-toml/benchmark.sh
@@ -0,0 +1,32 @@
+#!/bin/bash
+
+set -e
+
+reference_ref=${1:-master}
+reference_git=${2:-.}
+
+if ! `hash benchstat 2>/dev/null`; then
+ echo "Installing benchstat"
+ go get golang.org/x/perf/cmd/benchstat
+ go install golang.org/x/perf/cmd/benchstat
+fi
+
+tempdir=`mktemp -d /tmp/go-toml-benchmark-XXXXXX`
+ref_tempdir="${tempdir}/ref"
+ref_benchmark="${ref_tempdir}/benchmark-${reference_ref}.txt"
+local_benchmark="`pwd`/benchmark-local.txt"
+
+echo "=== ${reference_ref} (${ref_tempdir})"
+git clone ${reference_git} ${ref_tempdir} >/dev/null 2>/dev/null
+pushd ${ref_tempdir} >/dev/null
+git checkout ${reference_ref} >/dev/null 2>/dev/null
+go test -bench=. -benchmem | tee ${ref_benchmark}
+popd >/dev/null
+
+echo ""
+echo "=== local"
+go test -bench=. -benchmem | tee ${local_benchmark}
+
+echo ""
+echo "=== diff"
+benchstat -delta-test=none ${ref_benchmark} ${local_benchmark} \ No newline at end of file
diff --git a/vendor/github.com/pelletier/go-toml/cmd/tomljson/main.go b/vendor/github.com/pelletier/go-toml/cmd/tomljson/main.go
index 8bfe46210..b2d6fc673 100644
--- a/vendor/github.com/pelletier/go-toml/cmd/tomljson/main.go
+++ b/vendor/github.com/pelletier/go-toml/cmd/tomljson/main.go
@@ -1,3 +1,8 @@
+// Tomljson reads TOML and converts to JSON.
+//
+// Usage:
+// cat file.toml | tomljson > file.json
+// tomljson file1.toml > file.json
package main
import (
diff --git a/vendor/github.com/pelletier/go-toml/cmd/tomll/main.go b/vendor/github.com/pelletier/go-toml/cmd/tomll/main.go
index f185c56b9..36c7e3759 100644
--- a/vendor/github.com/pelletier/go-toml/cmd/tomll/main.go
+++ b/vendor/github.com/pelletier/go-toml/cmd/tomll/main.go
@@ -1,3 +1,8 @@
+// Tomll is a linter for TOML
+//
+// Usage:
+// cat file.toml | tomll > file_linted.toml
+// tomll file1.toml file2.toml # lint the two files in place
package main
import (
diff --git a/vendor/github.com/pelletier/go-toml/doc.go b/vendor/github.com/pelletier/go-toml/doc.go
index cfa5e4abe..3c89619e8 100644
--- a/vendor/github.com/pelletier/go-toml/doc.go
+++ b/vendor/github.com/pelletier/go-toml/doc.go
@@ -1,79 +1,18 @@
-// Package toml is a TOML markup language parser.
+// Package toml is a TOML parser and manipulation library.
//
// This version supports the specification as described in
// https://github.com/toml-lang/toml/blob/master/versions/en/toml-v0.4.0.md
//
-// TOML Parsing
+// Marshaling
//
-// TOML data may be parsed in two ways: by file, or by string.
+// Go-toml can marshal and unmarshal TOML documents from and to data
+// structures.
//
-// // load TOML data by filename
-// tree, err := toml.LoadFile("filename.toml")
+// TOML document as a tree
//
-// // load TOML data stored in a string
-// tree, err := toml.Load(stringContainingTomlData)
-//
-// Either way, the result is a Tree object that can be used to navigate the
-// structure and data within the original document.
-//
-//
-// Getting data from the Tree
-//
-// After parsing TOML data with Load() or LoadFile(), use the Has() and Get()
-// methods on the returned Tree, to find your way through the document data.
-//
-// if tree.Has("foo") {
-// fmt.Println("foo is:", tree.Get("foo"))
-// }
-//
-// Working with Paths
-//
-// Go-toml has support for basic dot-separated key paths on the Has(), Get(), Set()
-// and GetDefault() methods. These are the same kind of key paths used within the
-// TOML specification for struct tames.
-//
-// // looks for a key named 'baz', within struct 'bar', within struct 'foo'
-// tree.Has("foo.bar.baz")
-//
-// // returns the key at this path, if it is there
-// tree.Get("foo.bar.baz")
-//
-// TOML allows keys to contain '.', which can cause this syntax to be problematic
-// for some documents. In such cases, use the GetPath(), HasPath(), and SetPath(),
-// methods to explicitly define the path. This form is also faster, since
-// it avoids having to parse the passed key for '.' delimiters.
-//
-// // looks for a key named 'baz', within struct 'bar', within struct 'foo'
-// tree.HasPath([]string{"foo","bar","baz"})
-//
-// // returns the key at this path, if it is there
-// tree.GetPath([]string{"foo","bar","baz"})
-//
-// Note that this is distinct from the heavyweight query syntax supported by
-// Tree.Query() and the Query() struct (see below).
-//
-// Position Support
-//
-// Each element within the Tree is stored with position metadata, which is
-// invaluable for providing semantic feedback to a user. This helps in
-// situations where the TOML file parses correctly, but contains data that is
-// not correct for the application. In such cases, an error message can be
-// generated that indicates the problem line and column number in the source
-// TOML document.
-//
-// // load TOML data
-// tree, _ := toml.Load("filename.toml")
-//
-// // get an entry and report an error if it's the wrong type
-// element := tree.Get("foo")
-// if value, ok := element.(int64); !ok {
-// return fmt.Errorf("%v: Element 'foo' must be an integer", tree.GetPosition("foo"))
-// }
-//
-// // report an error if an expected element is missing
-// if !tree.Has("bar") {
-// return fmt.Errorf("%v: Expected 'bar' element", tree.GetPosition(""))
-// }
+// Go-toml can operate on a TOML document as a tree. Use one of the Load*
+// functions to parse TOML data and obtain a Tree instance, then one of its
+// methods to manipulate the tree.
//
// JSONPath-like queries
//
diff --git a/vendor/github.com/pelletier/go-toml/doc_test.go b/vendor/github.com/pelletier/go-toml/doc_test.go
index 31b4f40b5..9dd773899 100644
--- a/vendor/github.com/pelletier/go-toml/doc_test.go
+++ b/vendor/github.com/pelletier/go-toml/doc_test.go
@@ -6,7 +6,7 @@ import (
"fmt"
)
-func Example_comprehensiveExample() {
+func Example_tree() {
config, err := LoadFile("config.toml")
if err != nil {
@@ -20,10 +20,34 @@ func Example_comprehensiveExample() {
configTree := config.Get("postgres").(*Tree)
user = configTree.Get("user").(string)
password = configTree.Get("password").(string)
- fmt.Println("User is ", user, ". Password is ", password)
+ fmt.Println("User is", user, " and password is", password)
// show where elements are in the file
fmt.Printf("User position: %v\n", configTree.GetPosition("user"))
fmt.Printf("Password position: %v\n", configTree.GetPosition("password"))
}
}
+
+func Example_unmarshal() {
+ type Employer struct {
+ Name string
+ Phone string
+ }
+ type Person struct {
+ Name string
+ Age int64
+ Employer Employer
+ }
+
+ document := []byte(`
+ name = "John"
+ age = 30
+ [employer]
+ name = "Company Inc."
+ phone = "+1 234 567 89012"
+ `)
+
+ person := Person{}
+ Unmarshal(document, &person)
+ fmt.Println(person.Name, "is", person.Age, "and works at", person.Employer.Name)
+}
diff --git a/vendor/github.com/pelletier/go-toml/lexer.go b/vendor/github.com/pelletier/go-toml/lexer.go
index 104f3b1f4..db3ab4e54 100644
--- a/vendor/github.com/pelletier/go-toml/lexer.go
+++ b/vendor/github.com/pelletier/go-toml/lexer.go
@@ -6,6 +6,7 @@
package toml
import (
+ "bytes"
"errors"
"fmt"
"io"
@@ -24,7 +25,7 @@ type tomlLexStateFn func() tomlLexStateFn
// Define lexer
type tomlLexer struct {
input *buffruneio.Reader // Textual source
- buffer []rune // Runes composing the current token
+ buffer bytes.Buffer // Runes composing the current token
tokens chan token
depth int
line int
@@ -53,13 +54,13 @@ func (l *tomlLexer) next() rune {
r := l.read()
if r != eof {
- l.buffer = append(l.buffer, r)
+ l.buffer.WriteRune(r)
}
return r
}
func (l *tomlLexer) ignore() {
- l.buffer = make([]rune, 0)
+ l.buffer.Reset()
l.line = l.endbufferLine
l.col = l.endbufferCol
}
@@ -85,7 +86,7 @@ func (l *tomlLexer) emitWithValue(t tokenType, value string) {
}
func (l *tomlLexer) emit(t tokenType) {
- l.emitWithValue(t, string(l.buffer))
+ l.emitWithValue(t, l.buffer.String())
}
func (l *tomlLexer) peek() rune {
@@ -536,7 +537,7 @@ func (l *tomlLexer) lexInsideTableArrayKey() tomlLexStateFn {
for r := l.peek(); r != eof; r = l.peek() {
switch r {
case ']':
- if len(l.buffer) > 0 {
+ if l.buffer.Len() > 0 {
l.emit(tokenKeyGroupArray)
}
l.next()
@@ -559,7 +560,7 @@ func (l *tomlLexer) lexInsideTableKey() tomlLexStateFn {
for r := l.peek(); r != eof; r = l.peek() {
switch r {
case ']':
- if len(l.buffer) > 0 {
+ if l.buffer.Len() > 0 {
l.emit(tokenKeyGroup)
}
l.next()
diff --git a/vendor/github.com/pelletier/go-toml/lexer_test.go b/vendor/github.com/pelletier/go-toml/lexer_test.go
index 6b324ea0e..dce7a630a 100644
--- a/vendor/github.com/pelletier/go-toml/lexer_test.go
+++ b/vendor/github.com/pelletier/go-toml/lexer_test.go
@@ -1,6 +1,7 @@
package toml
import (
+ "os"
"strings"
"testing"
)
@@ -748,3 +749,31 @@ func TestLexUnknownRvalue(t *testing.T) {
{Position{1, 5}, tokenError, `no value can start with \`},
})
}
+
+func BenchmarkLexer(b *testing.B) {
+ sample := `title = "Hugo: A Fast and Flexible Website Generator"
+baseurl = "http://gohugo.io/"
+MetaDataFormat = "yaml"
+pluralizeListTitles = false
+
+[params]
+ description = "Documentation of Hugo, a fast and flexible static site generator built with love by spf13, bep and friends in Go"
+ author = "Steve Francia (spf13) and friends"
+ release = "0.22-DEV"
+
+[[menu.main]]
+ name = "Download Hugo"
+ pre = "<i class='fa fa-download'></i>"
+ url = "https://github.com/spf13/hugo/releases"
+ weight = -200
+`
+ rd := strings.NewReader(sample)
+
+ b.ResetTimer()
+ for i := 0; i < b.N; i++ {
+ rd.Seek(0, os.SEEK_SET)
+ ch := lexToml(rd)
+ for _ = range ch {
+ }
+ }
+}
diff --git a/vendor/github.com/pelletier/go-toml/marshal.go b/vendor/github.com/pelletier/go-toml/marshal.go
index 358425aea..9bf6fb988 100644
--- a/vendor/github.com/pelletier/go-toml/marshal.go
+++ b/vendor/github.com/pelletier/go-toml/marshal.go
@@ -9,24 +9,6 @@ import (
"time"
)
-/*
-Tree structural types and corresponding marshal types
--------------------------------------------------------------------------------
-*Tree (*)struct, (*)map[string]interface{}
-[]*Tree (*)[](*)struct, (*)[](*)map[string]interface{}
-[]interface{} (as interface{}) (*)[]primitive, (*)[]([]interface{})
-interface{} (*)primitive
-
-Tree primitive types and corresponding marshal types
------------------------------------------------------------
-uint64 uint, uint8-uint64, pointers to same
-int64 int, int8-uint64, pointers to same
-float64 float32, float64, pointers to same
-string string, pointers to same
-bool bool, pointers to same
-time.Time time.Time{}, pointers to same
-*/
-
type tomlOpts struct {
name string
include bool
@@ -115,6 +97,22 @@ function for sub-structs, and currently only definite types can be marshaled
Note that pointers are automatically assigned the "omitempty" option, as TOML
explicity does not handle null values (saying instead the label should be
dropped).
+
+Tree structural types and corresponding marshal types:
+
+ *Tree (*)struct, (*)map[string]interface{}
+ []*Tree (*)[](*)struct, (*)[](*)map[string]interface{}
+ []interface{} (as interface{}) (*)[]primitive, (*)[]([]interface{})
+ interface{} (*)primitive
+
+Tree primitive types and corresponding marshal types:
+
+ uint64 uint, uint8-uint64, pointers to same
+ int64 int, int8-uint64, pointers to same
+ float64 float32, float64, pointers to same
+ string string, pointers to same
+ bool bool, pointers to same
+ time.Time time.Time{}, pointers to same
*/
func Marshal(v interface{}) ([]byte, error) {
mtype := reflect.TypeOf(v)
@@ -247,6 +245,8 @@ func (t *Tree) Unmarshal(v interface{}) error {
// is no concept of an Unmarshaler interface or UnmarshalTOML function for
// sub-structs, and currently only definite types can be unmarshaled to (i.e. no
// `interface{}`).
+//
+// See Marshal() documentation for types mapping table.
func Unmarshal(data []byte, v interface{}) error {
t, err := LoadReader(bytes.NewReader(data))
if err != nil {
diff --git a/vendor/github.com/pelletier/go-toml/marshal_test.go b/vendor/github.com/pelletier/go-toml/marshal_test.go
index dbfc7c1d1..a3fa128d2 100644
--- a/vendor/github.com/pelletier/go-toml/marshal_test.go
+++ b/vendor/github.com/pelletier/go-toml/marshal_test.go
@@ -177,6 +177,25 @@ func TestDocUnmarshal(t *testing.T) {
}
}
+func ExampleUnmarshal() {
+ type Postgres struct {
+ User string
+ Password string
+ }
+ type Config struct {
+ Postgres Postgres
+ }
+
+ doc := []byte(`
+ [postgres]
+ user = "pelletier"
+ password = "mypassword"`)
+
+ config := Config{}
+ Unmarshal(doc, &config)
+ fmt.Println("user=", config.Postgres.User)
+}
+
func TestDocPartialUnmarshal(t *testing.T) {
result := testDocSubs{}
diff --git a/vendor/github.com/pelletier/go-toml/query/lexer.go b/vendor/github.com/pelletier/go-toml/query/lexer.go
index 6336d52cd..2dc319408 100644
--- a/vendor/github.com/pelletier/go-toml/query/lexer.go
+++ b/vendor/github.com/pelletier/go-toml/query/lexer.go
@@ -7,10 +7,10 @@ package query
import (
"fmt"
+ "github.com/pelletier/go-toml"
"strconv"
"strings"
"unicode/utf8"
- "github.com/pelletier/go-toml"
)
// Lexer state function
@@ -55,7 +55,7 @@ func (l *queryLexer) nextStart() {
func (l *queryLexer) emit(t tokenType) {
l.tokens <- token{
- Position: toml.Position{Line:l.line, Col:l.col},
+ Position: toml.Position{Line: l.line, Col: l.col},
typ: t,
val: l.input[l.start:l.pos],
}
@@ -64,7 +64,7 @@ func (l *queryLexer) emit(t tokenType) {
func (l *queryLexer) emitWithValue(t tokenType, value string) {
l.tokens <- token{
- Position: toml.Position{Line:l.line, Col:l.col},
+ Position: toml.Position{Line: l.line, Col: l.col},
typ: t,
val: value,
}
@@ -92,7 +92,7 @@ func (l *queryLexer) backup() {
func (l *queryLexer) errorf(format string, args ...interface{}) queryLexStateFn {
l.tokens <- token{
- Position: toml.Position{Line:l.line, Col:l.col},
+ Position: toml.Position{Line: l.line, Col: l.col},
typ: tokenError,
val: fmt.Sprintf(format, args...),
}
diff --git a/vendor/github.com/pelletier/go-toml/query/lexer_test.go b/vendor/github.com/pelletier/go-toml/query/lexer_test.go
index e2b733a34..8ce0501fe 100644
--- a/vendor/github.com/pelletier/go-toml/query/lexer_test.go
+++ b/vendor/github.com/pelletier/go-toml/query/lexer_test.go
@@ -1,8 +1,8 @@
package query
import (
- "testing"
"github.com/pelletier/go-toml"
+ "testing"
)
func testQLFlow(t *testing.T, input string, expectedFlow []token) {
diff --git a/vendor/github.com/pelletier/go-toml/query/match_test.go b/vendor/github.com/pelletier/go-toml/query/match_test.go
index 567b11cd7..429b8f6b9 100644
--- a/vendor/github.com/pelletier/go-toml/query/match_test.go
+++ b/vendor/github.com/pelletier/go-toml/query/match_test.go
@@ -2,8 +2,8 @@ package query
import (
"fmt"
- "testing"
"github.com/pelletier/go-toml"
+ "testing"
)
// dump path tree to a string
diff --git a/vendor/github.com/pelletier/go-toml/query/parser_test.go b/vendor/github.com/pelletier/go-toml/query/parser_test.go
index b1d0a3ece..473896a02 100644
--- a/vendor/github.com/pelletier/go-toml/query/parser_test.go
+++ b/vendor/github.com/pelletier/go-toml/query/parser_test.go
@@ -2,12 +2,12 @@ package query
import (
"fmt"
+ "github.com/pelletier/go-toml"
"io/ioutil"
"sort"
"strings"
"testing"
"time"
- "github.com/pelletier/go-toml"
)
type queryTestNode struct {
diff --git a/vendor/github.com/pelletier/go-toml/query/tokens.go b/vendor/github.com/pelletier/go-toml/query/tokens.go
index 429e289ab..9ae579de2 100644
--- a/vendor/github.com/pelletier/go-toml/query/tokens.go
+++ b/vendor/github.com/pelletier/go-toml/query/tokens.go
@@ -1,10 +1,10 @@
package query
import (
-"fmt"
-"strconv"
-"unicode"
+ "fmt"
"github.com/pelletier/go-toml"
+ "strconv"
+ "unicode"
)
// Define tokens
@@ -104,4 +104,3 @@ func isHexDigit(r rune) bool {
(r >= 'a' && r <= 'f') ||
(r >= 'A' && r <= 'F')
}
-
diff --git a/vendor/github.com/pelletier/go-toml/toml.go b/vendor/github.com/pelletier/go-toml/toml.go
index 99663217e..2d2f64049 100644
--- a/vendor/github.com/pelletier/go-toml/toml.go
+++ b/vendor/github.com/pelletier/go-toml/toml.go
@@ -54,8 +54,7 @@ func (t *Tree) HasPath(keys []string) bool {
return t.GetPath(keys) != nil
}
-// Keys returns the keys of the toplevel tree.
-// Warning: this is a costly operation.
+// Keys returns the keys of the toplevel tree (does not recurse).
func (t *Tree) Keys() []string {
keys := make([]string, len(t.values))
i := 0
diff --git a/vendor/github.com/pelletier/go-toml/tomltree_create.go b/vendor/github.com/pelletier/go-toml/tomltree_create.go
index ee7114ed8..19d1c0dc6 100644
--- a/vendor/github.com/pelletier/go-toml/tomltree_create.go
+++ b/vendor/github.com/pelletier/go-toml/tomltree_create.go
@@ -6,10 +6,7 @@ import (
"time"
)
-// supported values:
-// string, bool, int64, uint64, float64, time.Time, int, int8, int16, int32, uint, uint8, uint16, uint32, float32
-
-var kindToTypeMapping = map[reflect.Kind]reflect.Type{
+var kindToType = [reflect.String + 1]reflect.Type{
reflect.Bool: reflect.TypeOf(true),
reflect.String: reflect.TypeOf(""),
reflect.Float32: reflect.TypeOf(float64(1)),
@@ -26,6 +23,16 @@ var kindToTypeMapping = map[reflect.Kind]reflect.Type{
reflect.Uint64: reflect.TypeOf(uint64(1)),
}
+// typeFor returns a reflect.Type for a reflect.Kind, or nil if none is found.
+// supported values:
+// string, bool, int64, uint64, float64, time.Time, int, int8, int16, int32, uint, uint8, uint16, uint32, float32
+func typeFor(k reflect.Kind) reflect.Type {
+ if k > 0 && int(k) < len(kindToType) {
+ return kindToType[k]
+ }
+ return nil
+}
+
func simpleValueCoercion(object interface{}) (interface{}, error) {
switch original := object.(type) {
case string, bool, int64, uint64, float64, time.Time:
@@ -82,7 +89,7 @@ func sliceToTree(object interface{}) (interface{}, error) {
return tablesArray, nil
}
- sliceType := kindToTypeMapping[insideType.Kind()]
+ sliceType := typeFor(insideType.Kind())
if sliceType == nil {
sliceType = insideType
}
diff --git a/vendor/github.com/pelletier/go-toml/tomltree_write.go b/vendor/github.com/pelletier/go-toml/tomltree_write.go
index d27afc118..cd03f9dba 100644
--- a/vendor/github.com/pelletier/go-toml/tomltree_write.go
+++ b/vendor/github.com/pelletier/go-toml/tomltree_write.go
@@ -4,6 +4,7 @@ import (
"bytes"
"fmt"
"io"
+ "math"
"reflect"
"sort"
"strconv"
@@ -13,33 +14,34 @@ import (
// encodes a string to a TOML-compliant string value
func encodeTomlString(value string) string {
- result := ""
+ var b bytes.Buffer
+
for _, rr := range value {
switch rr {
case '\b':
- result += "\\b"
+ b.WriteString(`\b`)
case '\t':
- result += "\\t"
+ b.WriteString(`\t`)
case '\n':
- result += "\\n"
+ b.WriteString(`\n`)
case '\f':
- result += "\\f"
+ b.WriteString(`\f`)
case '\r':
- result += "\\r"
+ b.WriteString(`\r`)
case '"':
- result += "\\\""
+ b.WriteString(`\"`)
case '\\':
- result += "\\\\"
+ b.WriteString(`\\`)
default:
intRr := uint16(rr)
if intRr < 0x001F {
- result += fmt.Sprintf("\\u%0.4X", intRr)
+ b.WriteString(fmt.Sprintf("\\u%0.4X", intRr))
} else {
- result += string(rr)
+ b.WriteRune(rr)
}
}
}
- return result
+ return b.String()
}
func tomlValueStringRepresentation(v interface{}) (string, error) {
@@ -49,6 +51,11 @@ func tomlValueStringRepresentation(v interface{}) (string, error) {
case int64:
return strconv.FormatInt(value, 10), nil
case float64:
+ // Ensure a round float does contain a decimal point. Otherwise feeding
+ // the output back to the parser would convert to an integer.
+ if math.Trunc(value) == value {
+ return strconv.FormatFloat(value, 'f', 1, 32), nil
+ }
return strconv.FormatFloat(value, 'f', -1, 32), nil
case string:
return "\"" + encodeTomlString(value) + "\"", nil
@@ -111,7 +118,7 @@ func (t *Tree) writeTo(w io.Writer, indent, keyspace string, bytesCount int64) (
return bytesCount, err
}
- kvRepr := fmt.Sprintf("%s%s = %s\n", indent, k, repr)
+ kvRepr := indent + k + " = " + repr + "\n"
writtenBytesCount, err := w.Write([]byte(kvRepr))
bytesCount += int64(writtenBytesCount)
if err != nil {
@@ -130,7 +137,7 @@ func (t *Tree) writeTo(w io.Writer, indent, keyspace string, bytesCount int64) (
switch node := v.(type) {
// node has to be of those two types given how keys are sorted above
case *Tree:
- tableName := fmt.Sprintf("\n%s[%s]\n", indent, combinedKey)
+ tableName := "\n" + indent + "[" + combinedKey + "]\n"
writtenBytesCount, err := w.Write([]byte(tableName))
bytesCount += int64(writtenBytesCount)
if err != nil {
@@ -142,18 +149,16 @@ func (t *Tree) writeTo(w io.Writer, indent, keyspace string, bytesCount int64) (
}
case []*Tree:
for _, subTree := range node {
- if len(subTree.values) > 0 {
- tableArrayName := fmt.Sprintf("\n%s[[%s]]\n", indent, combinedKey)
- writtenBytesCount, err := w.Write([]byte(tableArrayName))
- bytesCount += int64(writtenBytesCount)
- if err != nil {
- return bytesCount, err
- }
-
- bytesCount, err = subTree.writeTo(w, indent+" ", combinedKey, bytesCount)
- if err != nil {
- return bytesCount, err
- }
+ tableArrayName := "\n" + indent + "[[" + combinedKey + "]]\n"
+ writtenBytesCount, err := w.Write([]byte(tableArrayName))
+ bytesCount += int64(writtenBytesCount)
+ if err != nil {
+ return bytesCount, err
+ }
+
+ bytesCount, err = subTree.writeTo(w, indent+" ", combinedKey, bytesCount)
+ if err != nil {
+ return bytesCount, err
}
}
}
diff --git a/vendor/github.com/pelletier/go-toml/tomltree_write_test.go b/vendor/github.com/pelletier/go-toml/tomltree_write_test.go
index 1a006da3c..0edf1be46 100644
--- a/vendor/github.com/pelletier/go-toml/tomltree_write_test.go
+++ b/vendor/github.com/pelletier/go-toml/tomltree_write_test.go
@@ -40,6 +40,30 @@ func assertErrorString(t *testing.T, expected string, err error) {
}
}
+func TestTreeWriteToEmptyTable(t *testing.T) {
+ doc := `[[empty-tables]]
+[[empty-tables]]`
+
+ toml, err := Load(doc)
+ if err != nil {
+ t.Fatal("Unexpected Load error:", err)
+ }
+ tomlString, err := toml.ToTomlString()
+ if err != nil {
+ t.Fatal("Unexpected ToTomlString error:", err)
+ }
+
+ expected := `
+[[empty-tables]]
+
+[[empty-tables]]
+`
+
+ if tomlString != expected {
+ t.Fatalf("Expected:\n%s\nGot:\n%s", expected, tomlString)
+ }
+}
+
func TestTreeWriteToTomlString(t *testing.T) {
toml, err := Load(`name = { first = "Tom", last = "Preston-Werner" }
points = { x = 1, y = 2 }`)
@@ -269,3 +293,66 @@ func TestTreeWriteToMapWithArrayOfInlineTables(t *testing.T) {
treeMap := tree.ToMap()
testMaps(t, treeMap, expected)
}
+
+func TestTreeWriteToFloat(t *testing.T) {
+ tree, err := Load(`a = 3.0`)
+ if err != nil {
+ t.Fatal(err)
+ }
+ str, err := tree.ToTomlString()
+ if err != nil {
+ t.Fatal(err)
+ }
+ expected := `a = 3.0`
+ if strings.TrimSpace(str) != strings.TrimSpace(expected) {
+ t.Fatalf("Expected:\n%s\nGot:\n%s", expected, str)
+ }
+}
+
+func BenchmarkTreeToTomlString(b *testing.B) {
+ toml, err := Load(sampleHard)
+ if err != nil {
+ b.Fatal("Unexpected error:", err)
+ }
+
+ for i := 0; i < b.N; i++ {
+ _, err := toml.ToTomlString()
+ if err != nil {
+ b.Fatal(err)
+ }
+ }
+}
+
+var sampleHard = `# Test file for TOML
+# Only this one tries to emulate a TOML file written by a user of the kind of parser writers probably hate
+# This part you'll really hate
+
+[the]
+test_string = "You'll hate me after this - #" # " Annoying, isn't it?
+
+ [the.hard]
+ test_array = [ "] ", " # "] # ] There you go, parse this!
+ test_array2 = [ "Test #11 ]proved that", "Experiment #9 was a success" ]
+ # You didn't think it'd as easy as chucking out the last #, did you?
+ another_test_string = " Same thing, but with a string #"
+ harder_test_string = " And when \"'s are in the string, along with # \"" # "and comments are there too"
+ # Things will get harder
+
+ [the.hard."bit#"]
+ "what?" = "You don't think some user won't do that?"
+ multi_line_array = [
+ "]",
+ # ] Oh yes I did
+ ]
+
+# Each of the following keygroups/key value pairs should produce an error. Uncomment to them to test
+
+#[error] if you didn't catch this, your parser is broken
+#string = "Anything other than tabs, spaces and newline after a keygroup or key value pair has ended should produce an error unless it is a comment" like this
+#array = [
+# "This might most likely happen in multiline arrays",
+# Like here,
+# "or here,
+# and here"
+# ] End of array comment, forgot the #
+#number = 3.14 pi <--again forgot the # `