diff --git a/Godeps/Godeps.json b/Godeps/Godeps.json
index c16bc7f8..c57521e6 100644
--- a/Godeps/Godeps.json
+++ b/Godeps/Godeps.json
@@ -1,10 +1,19 @@
{
"ImportPath": "github.com/coreos/coreos-baremetal",
- "GoVersion": "go1.5.3",
+ "GoVersion": "go1.6.1",
"Packages": [
"./..."
],
"Deps": [
+ {
+ "ImportPath": "github.com/alecthomas/units",
+ "Rev": "2efee857e7cfd4f3d0138cc3cbb1b4966962b93a"
+ },
+ {
+ "ImportPath": "github.com/camlistore/camlistore/pkg/errorutil",
+ "Comment": "0.9-207-g7ec2b0a",
+ "Rev": "7ec2b0ac2e64f2c0e474258f0cf3a0ab0831796e"
+ },
{
"ImportPath": "github.com/coreos/coreos-cloudinit/Godeps/_workspace/src/github.com/coreos/yaml",
"Comment": "v1.9.1",
@@ -15,30 +24,19 @@
"Comment": "v1.9.1",
"Rev": "b3f805dee6a4aa5ed298a1f370284df470eecf43"
},
+ {
+ "ImportPath": "github.com/coreos/go-semver/semver",
+ "Rev": "294930c1e79c64e7dbe360054274fdad492c8cf5"
+ },
{
"ImportPath": "github.com/coreos/go-systemd/journal",
"Comment": "v4-42-g7b2428f",
"Rev": "7b2428fec40033549c68f54e26e89e7ca9a9ce31"
},
{
- "ImportPath": "github.com/coreos/ignition/src/config",
- "Comment": "v0.3.0-6-g699adeb",
- "Rev": "699adeba84898259868cef779a45293a49935500"
- },
- {
- "ImportPath": "github.com/coreos/ignition/third_party/github.com/alecthomas/units",
- "Comment": "v0.3.0-6-g699adeb",
- "Rev": "699adeba84898259868cef779a45293a49935500"
- },
- {
- "ImportPath": "github.com/coreos/ignition/third_party/github.com/camlistore/camlistore/pkg/errorutil",
- "Comment": "v0.3.0-6-g699adeb",
- "Rev": "699adeba84898259868cef779a45293a49935500"
- },
- {
- "ImportPath": "github.com/coreos/ignition/third_party/github.com/go-yaml/yaml",
- "Comment": "v0.3.0-6-g699adeb",
- "Rev": "699adeba84898259868cef779a45293a49935500"
+ "ImportPath": "github.com/coreos/ignition/config",
+ "Comment": "v0.4.0-20-g44c274a",
+ "Rev": "44c274ab414294a8e34b3a940e0ec1afe6b6c610"
},
{
"ImportPath": "github.com/coreos/pkg/capnslog",
@@ -52,22 +50,14 @@
"ImportPath": "github.com/davecgh/go-spew/spew",
"Rev": "5215b55f46b2b919f50a1df0eaa5886afe4e3b3d"
},
- {
- "ImportPath": "github.com/golang/glog",
- "Rev": "fca8c8854093a154ff1eb580aae10276ad6b1b5f"
- },
{
"ImportPath": "github.com/golang/protobuf/proto",
- "Rev": "552c7b9542c194800fd493123b3798ef0a832032"
+ "Rev": "f0a097ddac24fb00e07d2ac17f8671423f3ea47c"
},
{
"ImportPath": "github.com/pmezard/go-difflib/difflib",
"Rev": "792786c7400a136282c1664665ae0a8db921c6c2"
},
- {
- "ImportPath": "github.com/satori/go.uuid",
- "Rev": "e673fdd4dea8a7334adbbe7f57b7e4b00bdc5502"
- },
{
"ImportPath": "github.com/spf13/cobra",
"Rev": "65a708cee0a4424f4e353d031ce440643e312f92"
@@ -81,6 +71,14 @@
"Comment": "v1.1.3-4-g1f4a164",
"Rev": "1f4a1643a57e798696635ea4c126e9127adb7d3c"
},
+ {
+ "ImportPath": "github.com/vincent-petithory/dataurl",
+ "Rev": "9a301d65acbb728fcc3ace14f45f511a4cfeea9c"
+ },
+ {
+ "ImportPath": "go4.org/errorutil",
+ "Rev": "03efcb870d84809319ea509714dd6d19a1498483"
+ },
{
"ImportPath": "golang.org/x/crypto/cast5",
"Rev": "5dc8cb4b8a8eb076cbb5a06bc3b8682c15bdbbd3"
@@ -89,49 +87,25 @@
"ImportPath": "golang.org/x/crypto/openpgp",
"Rev": "5dc8cb4b8a8eb076cbb5a06bc3b8682c15bdbbd3"
},
- {
- "ImportPath": "golang.org/x/crypto/ripemd160",
- "Rev": "5dc8cb4b8a8eb076cbb5a06bc3b8682c15bdbbd3"
- },
- {
- "ImportPath": "golang.org/x/crypto/ssh/terminal",
- "Rev": "5dc8cb4b8a8eb076cbb5a06bc3b8682c15bdbbd3"
- },
{
"ImportPath": "golang.org/x/net/context",
- "Rev": "6acef71eb69611914f7a30939ea9f6e194c78172"
+ "Rev": "fb93926129b8ec0056f2f458b1f519654814edf0"
},
{
"ImportPath": "golang.org/x/net/http2",
- "Rev": "6acef71eb69611914f7a30939ea9f6e194c78172"
+ "Rev": "fb93926129b8ec0056f2f458b1f519654814edf0"
},
{
"ImportPath": "golang.org/x/net/internal/timeseries",
- "Rev": "6acef71eb69611914f7a30939ea9f6e194c78172"
+ "Rev": "fb93926129b8ec0056f2f458b1f519654814edf0"
},
{
"ImportPath": "golang.org/x/net/trace",
- "Rev": "6acef71eb69611914f7a30939ea9f6e194c78172"
- },
- {
- "ImportPath": "golang.org/x/oauth2",
- "Rev": "c30abeebd1a0c41f6e0d9ad6d26fd9daf8aff7d6"
- },
- {
- "ImportPath": "google.golang.org/cloud/compute/metadata",
- "Rev": "3fb76bc404703eddc53d1e407eaa665ab3881362"
- },
- {
- "ImportPath": "google.golang.org/cloud/internal",
- "Rev": "3fb76bc404703eddc53d1e407eaa665ab3881362"
+ "Rev": "fb93926129b8ec0056f2f458b1f519654814edf0"
},
{
"ImportPath": "google.golang.org/grpc",
- "Rev": "986912c9070a060e59e0f28ac7c87f89f72b9388"
- },
- {
- "ImportPath": "gopkg.in/check.v1",
- "Rev": "4f90aeace3a26ad7021961c297b22c42160c7b25"
+ "Rev": "8eeecf2291de9d171d0b1392a27ff3975679f4f5"
},
{
"ImportPath": "gopkg.in/yaml.v2",
diff --git a/vendor/github.com/coreos/ignition/third_party/github.com/alecthomas/units/COPYING b/vendor/github.com/alecthomas/units/COPYING
similarity index 100%
rename from vendor/github.com/coreos/ignition/third_party/github.com/alecthomas/units/COPYING
rename to vendor/github.com/alecthomas/units/COPYING
diff --git a/vendor/github.com/coreos/ignition/third_party/github.com/alecthomas/units/README.md b/vendor/github.com/alecthomas/units/README.md
similarity index 100%
rename from vendor/github.com/coreos/ignition/third_party/github.com/alecthomas/units/README.md
rename to vendor/github.com/alecthomas/units/README.md
diff --git a/vendor/github.com/coreos/ignition/third_party/github.com/alecthomas/units/bytes.go b/vendor/github.com/alecthomas/units/bytes.go
similarity index 100%
rename from vendor/github.com/coreos/ignition/third_party/github.com/alecthomas/units/bytes.go
rename to vendor/github.com/alecthomas/units/bytes.go
diff --git a/vendor/github.com/alecthomas/units/bytes_test.go b/vendor/github.com/alecthomas/units/bytes_test.go
new file mode 100644
index 00000000..6cbc79de
--- /dev/null
+++ b/vendor/github.com/alecthomas/units/bytes_test.go
@@ -0,0 +1,49 @@
+package units
+
+import (
+ "testing"
+
+ "github.com/stretchr/testify/assert"
+)
+
+func TestBase2BytesString(t *testing.T) {
+ assert.Equal(t, Base2Bytes(0).String(), "0B")
+ assert.Equal(t, Base2Bytes(1025).String(), "1KiB1B")
+ assert.Equal(t, Base2Bytes(1048577).String(), "1MiB1B")
+}
+
+func TestParseBase2Bytes(t *testing.T) {
+ n, err := ParseBase2Bytes("0B")
+ assert.NoError(t, err)
+ assert.Equal(t, 0, int(n))
+ n, err = ParseBase2Bytes("1KB")
+ assert.NoError(t, err)
+ assert.Equal(t, 1024, int(n))
+ n, err = ParseBase2Bytes("1MB1KB25B")
+ assert.NoError(t, err)
+ assert.Equal(t, 1049625, int(n))
+ n, err = ParseBase2Bytes("1.5MB")
+ assert.NoError(t, err)
+ assert.Equal(t, 1572864, int(n))
+}
+
+func TestMetricBytesString(t *testing.T) {
+ assert.Equal(t, MetricBytes(0).String(), "0B")
+ assert.Equal(t, MetricBytes(1001).String(), "1KB1B")
+ assert.Equal(t, MetricBytes(1001025).String(), "1MB1KB25B")
+}
+
+func TestParseMetricBytes(t *testing.T) {
+ n, err := ParseMetricBytes("0B")
+ assert.NoError(t, err)
+ assert.Equal(t, 0, int(n))
+ n, err = ParseMetricBytes("1KB1B")
+ assert.NoError(t, err)
+ assert.Equal(t, 1001, int(n))
+ n, err = ParseMetricBytes("1MB1KB25B")
+ assert.NoError(t, err)
+ assert.Equal(t, 1001025, int(n))
+ n, err = ParseMetricBytes("1.5MB")
+ assert.NoError(t, err)
+ assert.Equal(t, 1500000, int(n))
+}
diff --git a/vendor/github.com/coreos/ignition/third_party/github.com/alecthomas/units/doc.go b/vendor/github.com/alecthomas/units/doc.go
similarity index 100%
rename from vendor/github.com/coreos/ignition/third_party/github.com/alecthomas/units/doc.go
rename to vendor/github.com/alecthomas/units/doc.go
diff --git a/vendor/github.com/coreos/ignition/third_party/github.com/alecthomas/units/si.go b/vendor/github.com/alecthomas/units/si.go
similarity index 100%
rename from vendor/github.com/coreos/ignition/third_party/github.com/alecthomas/units/si.go
rename to vendor/github.com/alecthomas/units/si.go
diff --git a/vendor/github.com/coreos/ignition/third_party/github.com/alecthomas/units/util.go b/vendor/github.com/alecthomas/units/util.go
similarity index 100%
rename from vendor/github.com/coreos/ignition/third_party/github.com/alecthomas/units/util.go
rename to vendor/github.com/alecthomas/units/util.go
diff --git a/vendor/github.com/coreos/ignition/third_party/github.com/camlistore/camlistore/pkg/errorutil/highlight.go b/vendor/github.com/camlistore/camlistore/pkg/errorutil/highlight.go
similarity index 100%
rename from vendor/github.com/coreos/ignition/third_party/github.com/camlistore/camlistore/pkg/errorutil/highlight.go
rename to vendor/github.com/camlistore/camlistore/pkg/errorutil/highlight.go
diff --git a/vendor/github.com/coreos/go-semver/semver/semver.go b/vendor/github.com/coreos/go-semver/semver/semver.go
new file mode 100644
index 00000000..000a0205
--- /dev/null
+++ b/vendor/github.com/coreos/go-semver/semver/semver.go
@@ -0,0 +1,257 @@
+// Copyright 2013-2015 CoreOS, Inc.
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+// http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+// Semantic Versions http://semver.org
+package semver
+
+import (
+ "bytes"
+ "errors"
+ "fmt"
+ "strconv"
+ "strings"
+)
+
+type Version struct {
+ Major int64
+ Minor int64
+ Patch int64
+ PreRelease PreRelease
+ Metadata string
+}
+
+type PreRelease string
+
+func splitOff(input *string, delim string) (val string) {
+ parts := strings.SplitN(*input, delim, 2)
+
+ if len(parts) == 2 {
+ *input = parts[0]
+ val = parts[1]
+ }
+
+ return val
+}
+
+func NewVersion(version string) (*Version, error) {
+ v := Version{}
+
+ v.Metadata = splitOff(&version, "+")
+ v.PreRelease = PreRelease(splitOff(&version, "-"))
+
+ dotParts := strings.SplitN(version, ".", 3)
+
+ if len(dotParts) != 3 {
+ return nil, errors.New(fmt.Sprintf("%s is not in dotted-tri format", version))
+ }
+
+ parsed := make([]int64, 3, 3)
+
+ for i, v := range dotParts[:3] {
+ val, err := strconv.ParseInt(v, 10, 64)
+ parsed[i] = val
+ if err != nil {
+ return nil, err
+ }
+ }
+
+ v.Major = parsed[0]
+ v.Minor = parsed[1]
+ v.Patch = parsed[2]
+
+ return &v, nil
+}
+
+func Must(v *Version, err error) *Version {
+ if err != nil {
+ panic(err)
+ }
+ return v
+}
+
+func (v Version) String() string {
+ var buffer bytes.Buffer
+
+ fmt.Fprintf(&buffer, "%d.%d.%d", v.Major, v.Minor, v.Patch)
+
+ if v.PreRelease != "" {
+ fmt.Fprintf(&buffer, "-%s", v.PreRelease)
+ }
+
+ if v.Metadata != "" {
+ fmt.Fprintf(&buffer, "+%s", v.Metadata)
+ }
+
+ return buffer.String()
+}
+
+func (v *Version) UnmarshalYAML(unmarshal func(interface{}) error) error {
+ var data string
+ if err := unmarshal(&data); err != nil {
+ return err
+ }
+ vv, err := NewVersion(data)
+ if err != nil {
+ return err
+ }
+ *v = *vv
+ return nil
+}
+
+func (v Version) MarshalJSON() ([]byte, error) {
+ return []byte(`"` + v.String() + `"`), nil
+}
+
+func (v *Version) UnmarshalJSON(data []byte) error {
+ l := len(data)
+ if l == 0 || string(data) == `""` {
+ return nil
+ }
+ if l < 2 || data[0] != '"' || data[l-1] != '"' {
+ return errors.New("invalid semver string")
+ }
+ vv, err := NewVersion(string(data[1 : l-1]))
+ if err != nil {
+ return err
+ }
+ *v = *vv
+ return nil
+}
+
+func (v Version) LessThan(versionB Version) bool {
+ versionA := v
+ cmp := recursiveCompare(versionA.Slice(), versionB.Slice())
+
+ if cmp == 0 {
+ cmp = preReleaseCompare(versionA, versionB)
+ }
+
+ if cmp == -1 {
+ return true
+ }
+
+ return false
+}
+
+/* Slice converts the comparable parts of the semver into a slice of strings */
+func (v Version) Slice() []int64 {
+ return []int64{v.Major, v.Minor, v.Patch}
+}
+
+func (p PreRelease) Slice() []string {
+ preRelease := string(p)
+ return strings.Split(preRelease, ".")
+}
+
+func preReleaseCompare(versionA Version, versionB Version) int {
+ a := versionA.PreRelease
+ b := versionB.PreRelease
+
+ /* Handle the case where if two versions are otherwise equal it is the
+ * one without a PreRelease that is greater */
+ if len(a) == 0 && (len(b) > 0) {
+ return 1
+ } else if len(b) == 0 && (len(a) > 0) {
+ return -1
+ }
+
+ // If there is a prelease, check and compare each part.
+ return recursivePreReleaseCompare(a.Slice(), b.Slice())
+}
+
+func recursiveCompare(versionA []int64, versionB []int64) int {
+ if len(versionA) == 0 {
+ return 0
+ }
+
+ a := versionA[0]
+ b := versionB[0]
+
+ if a > b {
+ return 1
+ } else if a < b {
+ return -1
+ }
+
+ return recursiveCompare(versionA[1:], versionB[1:])
+}
+
+func recursivePreReleaseCompare(versionA []string, versionB []string) int {
+ // Handle slice length disparity.
+ if len(versionA) == 0 {
+ // Nothing to compare too, so we return 0
+ return 0
+ } else if len(versionB) == 0 {
+ // We're longer than versionB so return 1.
+ return 1
+ }
+
+ a := versionA[0]
+ b := versionB[0]
+
+ aInt := false
+ bInt := false
+
+ aI, err := strconv.Atoi(versionA[0])
+ if err == nil {
+ aInt = true
+ }
+
+ bI, err := strconv.Atoi(versionB[0])
+ if err == nil {
+ bInt = true
+ }
+
+ // Handle Integer Comparison
+ if aInt && bInt {
+ if aI > bI {
+ return 1
+ } else if aI < bI {
+ return -1
+ }
+ }
+
+ // Handle String Comparison
+ if a > b {
+ return 1
+ } else if a < b {
+ return -1
+ }
+
+ return recursivePreReleaseCompare(versionA[1:], versionB[1:])
+}
+
+// BumpMajor increments the Major field by 1 and resets all other fields to their default values
+func (v *Version) BumpMajor() {
+ v.Major += 1
+ v.Minor = 0
+ v.Patch = 0
+ v.PreRelease = PreRelease("")
+ v.Metadata = ""
+}
+
+// BumpMinor increments the Minor field by 1 and resets all other fields to their default values
+func (v *Version) BumpMinor() {
+ v.Minor += 1
+ v.Patch = 0
+ v.PreRelease = PreRelease("")
+ v.Metadata = ""
+}
+
+// BumpPatch increments the Patch field by 1 and resets all other fields to their default values
+func (v *Version) BumpPatch() {
+ v.Patch += 1
+ v.PreRelease = PreRelease("")
+ v.Metadata = ""
+}
diff --git a/vendor/github.com/coreos/go-semver/semver/semver_test.go b/vendor/github.com/coreos/go-semver/semver/semver_test.go
new file mode 100644
index 00000000..8a6e200a
--- /dev/null
+++ b/vendor/github.com/coreos/go-semver/semver/semver_test.go
@@ -0,0 +1,330 @@
+// Copyright 2013-2015 CoreOS, Inc.
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+// http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+package semver
+
+import (
+ "bytes"
+ "encoding/json"
+ "errors"
+ "math/rand"
+ "reflect"
+ "testing"
+ "time"
+
+ "gopkg.in/yaml.v2"
+)
+
+type fixture struct {
+ GreaterVersion string
+ LesserVersion string
+}
+
+var fixtures = []fixture{
+ fixture{"0.0.0", "0.0.0-foo"},
+ fixture{"0.0.1", "0.0.0"},
+ fixture{"1.0.0", "0.9.9"},
+ fixture{"0.10.0", "0.9.0"},
+ fixture{"0.99.0", "0.10.0"},
+ fixture{"2.0.0", "1.2.3"},
+ fixture{"0.0.0", "0.0.0-foo"},
+ fixture{"0.0.1", "0.0.0"},
+ fixture{"1.0.0", "0.9.9"},
+ fixture{"0.10.0", "0.9.0"},
+ fixture{"0.99.0", "0.10.0"},
+ fixture{"2.0.0", "1.2.3"},
+ fixture{"0.0.0", "0.0.0-foo"},
+ fixture{"0.0.1", "0.0.0"},
+ fixture{"1.0.0", "0.9.9"},
+ fixture{"0.10.0", "0.9.0"},
+ fixture{"0.99.0", "0.10.0"},
+ fixture{"2.0.0", "1.2.3"},
+ fixture{"1.2.3", "1.2.3-asdf"},
+ fixture{"1.2.3", "1.2.3-4"},
+ fixture{"1.2.3", "1.2.3-4-foo"},
+ fixture{"1.2.3-5-foo", "1.2.3-5"},
+ fixture{"1.2.3-5", "1.2.3-4"},
+ fixture{"1.2.3-5-foo", "1.2.3-5-Foo"},
+ fixture{"3.0.0", "2.7.2+asdf"},
+ fixture{"3.0.0+foobar", "2.7.2"},
+ fixture{"1.2.3-a.10", "1.2.3-a.5"},
+ fixture{"1.2.3-a.b", "1.2.3-a.5"},
+ fixture{"1.2.3-a.b", "1.2.3-a"},
+ fixture{"1.2.3-a.b.c.10.d.5", "1.2.3-a.b.c.5.d.100"},
+ fixture{"1.0.0", "1.0.0-rc.1"},
+ fixture{"1.0.0-rc.2", "1.0.0-rc.1"},
+ fixture{"1.0.0-rc.1", "1.0.0-beta.11"},
+ fixture{"1.0.0-beta.11", "1.0.0-beta.2"},
+ fixture{"1.0.0-beta.2", "1.0.0-beta"},
+ fixture{"1.0.0-beta", "1.0.0-alpha.beta"},
+ fixture{"1.0.0-alpha.beta", "1.0.0-alpha.1"},
+ fixture{"1.0.0-alpha.1", "1.0.0-alpha"},
+}
+
+func TestCompare(t *testing.T) {
+ for _, v := range fixtures {
+ gt, err := NewVersion(v.GreaterVersion)
+ if err != nil {
+ t.Error(err)
+ }
+
+ lt, err := NewVersion(v.LesserVersion)
+ if err != nil {
+ t.Error(err)
+ }
+
+ if gt.LessThan(*lt) == true {
+ t.Errorf("%s should not be less than %s", gt, lt)
+ }
+ }
+}
+
+func testString(t *testing.T, orig string, version *Version) {
+ if orig != version.String() {
+ t.Errorf("%s != %s", orig, version)
+ }
+}
+
+func TestString(t *testing.T) {
+ for _, v := range fixtures {
+ gt, err := NewVersion(v.GreaterVersion)
+ if err != nil {
+ t.Error(err)
+ }
+ testString(t, v.GreaterVersion, gt)
+
+ lt, err := NewVersion(v.LesserVersion)
+ if err != nil {
+ t.Error(err)
+ }
+ testString(t, v.LesserVersion, lt)
+ }
+}
+
+func shuffleStringSlice(src []string) []string {
+ dest := make([]string, len(src))
+ rand.Seed(time.Now().Unix())
+ perm := rand.Perm(len(src))
+ for i, v := range perm {
+ dest[v] = src[i]
+ }
+ return dest
+}
+
+func TestSort(t *testing.T) {
+ sortedVersions := []string{"1.0.0", "1.0.2", "1.2.0", "3.1.1"}
+ unsortedVersions := shuffleStringSlice(sortedVersions)
+
+ semvers := []*Version{}
+ for _, v := range unsortedVersions {
+ sv, err := NewVersion(v)
+ if err != nil {
+ t.Fatal(err)
+ }
+ semvers = append(semvers, sv)
+ }
+
+ Sort(semvers)
+
+ for idx, sv := range semvers {
+ if sv.String() != sortedVersions[idx] {
+ t.Fatalf("incorrect sort at index %v", idx)
+ }
+ }
+}
+
+func TestBumpMajor(t *testing.T) {
+ version, _ := NewVersion("1.0.0")
+ version.BumpMajor()
+ if version.Major != 2 {
+ t.Fatalf("bumping major on 1.0.0 resulted in %v", version)
+ }
+
+ version, _ = NewVersion("1.5.2")
+ version.BumpMajor()
+ if version.Minor != 0 && version.Patch != 0 {
+ t.Fatalf("bumping major on 1.5.2 resulted in %v", version)
+ }
+
+ version, _ = NewVersion("1.0.0+build.1-alpha.1")
+ version.BumpMajor()
+ if version.PreRelease != "" && version.PreRelease != "" {
+ t.Fatalf("bumping major on 1.0.0+build.1-alpha.1 resulted in %v", version)
+ }
+}
+
+func TestBumpMinor(t *testing.T) {
+ version, _ := NewVersion("1.0.0")
+ version.BumpMinor()
+
+ if version.Major != 1 {
+ t.Fatalf("bumping minor on 1.0.0 resulted in %v", version)
+ }
+
+ if version.Minor != 1 {
+ t.Fatalf("bumping major on 1.0.0 resulted in %v", version)
+ }
+
+ version, _ = NewVersion("1.0.0+build.1-alpha.1")
+ version.BumpMinor()
+ if version.PreRelease != "" && version.PreRelease != "" {
+ t.Fatalf("bumping major on 1.0.0+build.1-alpha.1 resulted in %v", version)
+ }
+}
+
+func TestBumpPatch(t *testing.T) {
+ version, _ := NewVersion("1.0.0")
+ version.BumpPatch()
+
+ if version.Major != 1 {
+ t.Fatalf("bumping minor on 1.0.0 resulted in %v", version)
+ }
+
+ if version.Minor != 0 {
+ t.Fatalf("bumping major on 1.0.0 resulted in %v", version)
+ }
+
+ if version.Patch != 1 {
+ t.Fatalf("bumping major on 1.0.0 resulted in %v", version)
+ }
+
+ version, _ = NewVersion("1.0.0+build.1-alpha.1")
+ version.BumpPatch()
+ if version.PreRelease != "" && version.PreRelease != "" {
+ t.Fatalf("bumping major on 1.0.0+build.1-alpha.1 resulted in %v", version)
+ }
+}
+
+func TestMust(t *testing.T) {
+ tests := []struct {
+ versionStr string
+
+ version *Version
+ recov interface{}
+ }{
+ {
+ versionStr: "1.0.0",
+ version: &Version{Major: 1},
+ },
+ {
+ versionStr: "version number",
+ recov: errors.New("version number is not in dotted-tri format"),
+ },
+ }
+
+ for _, tt := range tests {
+ func() {
+ defer func() {
+ recov := recover()
+ if !reflect.DeepEqual(tt.recov, recov) {
+ t.Fatalf("incorrect panic for %q: want %v, got %v", tt.versionStr, tt.recov, recov)
+ }
+ }()
+
+ version := Must(NewVersion(tt.versionStr))
+ if !reflect.DeepEqual(tt.version, version) {
+ t.Fatalf("incorrect version for %q: want %+v, got %+v", tt.versionStr, tt.version, version)
+ }
+ }()
+ }
+}
+
+type fixtureJSON struct {
+ GreaterVersion *Version
+ LesserVersion *Version
+}
+
+func TestJSON(t *testing.T) {
+ fj := make([]fixtureJSON, len(fixtures))
+ for i, v := range fixtures {
+ var err error
+ fj[i].GreaterVersion, err = NewVersion(v.GreaterVersion)
+ if err != nil {
+ t.Fatal(err)
+ }
+ fj[i].LesserVersion, err = NewVersion(v.LesserVersion)
+ if err != nil {
+ t.Fatal(err)
+ }
+ }
+
+ fromStrings, err := json.Marshal(fixtures)
+ if err != nil {
+ t.Fatal(err)
+ }
+ fromVersions, err := json.Marshal(fj)
+ if err != nil {
+ t.Fatal(err)
+ }
+ if !bytes.Equal(fromStrings, fromVersions) {
+ t.Errorf("Expected: %s", fromStrings)
+ t.Errorf("Unexpected: %s", fromVersions)
+ }
+
+ fromJson := make([]fixtureJSON, 0, len(fj))
+ err = json.Unmarshal(fromStrings, &fromJson)
+ if err != nil {
+ t.Fatal(err)
+ }
+ if !reflect.DeepEqual(fromJson, fj) {
+ t.Error("Expected: ", fj)
+ t.Error("Unexpected: ", fromJson)
+ }
+}
+
+func TestYAML(t *testing.T) {
+ document, err := yaml.Marshal(fixtures)
+ if err != nil {
+ t.Fatal(err)
+ }
+
+ expected := make([]fixtureJSON, len(fixtures))
+ for i, v := range fixtures {
+ var err error
+ expected[i].GreaterVersion, err = NewVersion(v.GreaterVersion)
+ if err != nil {
+ t.Fatal(err)
+ }
+ expected[i].LesserVersion, err = NewVersion(v.LesserVersion)
+ if err != nil {
+ t.Fatal(err)
+ }
+ }
+
+ fromYAML := make([]fixtureJSON, 0, len(fixtures))
+ err = yaml.Unmarshal(document, &fromYAML)
+ if err != nil {
+ t.Fatal(err)
+ }
+
+ if !reflect.DeepEqual(fromYAML, expected) {
+ t.Error("Expected: ", expected)
+ t.Error("Unexpected: ", fromYAML)
+ }
+}
+
+func TestBadInput(t *testing.T) {
+ bad := []string{
+ "1.2",
+ "1.2.3x",
+ "0x1.3.4",
+ "-1.2.3",
+ "1.2.3.4",
+ }
+ for _, b := range bad {
+ if _, err := NewVersion(b); err == nil {
+ t.Error("Improperly accepted value: ", b)
+ }
+ }
+}
diff --git a/vendor/github.com/coreos/go-semver/semver/sort.go b/vendor/github.com/coreos/go-semver/semver/sort.go
new file mode 100644
index 00000000..e256b41a
--- /dev/null
+++ b/vendor/github.com/coreos/go-semver/semver/sort.go
@@ -0,0 +1,38 @@
+// Copyright 2013-2015 CoreOS, Inc.
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+// http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+package semver
+
+import (
+ "sort"
+)
+
+type Versions []*Version
+
+func (s Versions) Len() int {
+ return len(s)
+}
+
+func (s Versions) Swap(i, j int) {
+ s[i], s[j] = s[j], s[i]
+}
+
+func (s Versions) Less(i, j int) bool {
+ return s[i].LessThan(*s[j])
+}
+
+// Sort sorts the given slice of Version
+func Sort(versions []*Version) {
+ sort.Sort(Versions(versions))
+}
diff --git a/vendor/github.com/coreos/ignition/config/append.go b/vendor/github.com/coreos/ignition/config/append.go
new file mode 100644
index 00000000..10915bc1
--- /dev/null
+++ b/vendor/github.com/coreos/ignition/config/append.go
@@ -0,0 +1,73 @@
+// Copyright 2016 CoreOS, Inc.
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+// http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+package config
+
+import (
+ "reflect"
+
+ "github.com/coreos/ignition/config/types"
+)
+
+// Append appends newConfig to oldConfig and returns the result. Appending one
+// config to another is accomplished by iterating over every field in the
+// config structure, appending slices, recursively appending structs, and
+// overwriting old values with new values for all other types.
+func Append(oldConfig, newConfig types.Config) types.Config {
+ vOld := reflect.ValueOf(oldConfig)
+ vNew := reflect.ValueOf(newConfig)
+
+ vResult := appendStruct(vOld, vNew)
+
+ return vResult.Interface().(types.Config)
+}
+
+// appendStruct is an internal helper function to AppendConfig. Given two values
+// of structures (assumed to be the same type), recursively iterate over every
+// field in the struct, appending slices, recursively appending structs, and
+// overwriting old values with the new for all other types. Individual fields
+// are able to override their merge strategy using the "merge" tag. Accepted
+// values are "new" or "old": "new" uses the new value, "old" uses the old
+// value. These are currently only used for "ignition.config" and
+// "ignition.version".
+func appendStruct(vOld, vNew reflect.Value) reflect.Value {
+ tOld := vOld.Type()
+ vRes := reflect.New(tOld)
+
+ for i := 0; i < tOld.NumField(); i++ {
+ vfOld := vOld.Field(i)
+ vfNew := vNew.Field(i)
+ vfRes := vRes.Elem().Field(i)
+
+ switch tOld.Field(i).Tag.Get("merge") {
+ case "old":
+ vfRes.Set(vfOld)
+ continue
+ case "new":
+ vfRes.Set(vfNew)
+ continue
+ }
+
+ switch vfOld.Type().Kind() {
+ case reflect.Struct:
+ vfRes.Set(appendStruct(vfOld, vfNew))
+ case reflect.Slice:
+ vfRes.Set(reflect.AppendSlice(vfOld, vfNew))
+ default:
+ vfRes.Set(vfNew)
+ }
+ }
+
+ return vRes.Elem()
+}
diff --git a/vendor/github.com/coreos/ignition/config/append_test.go b/vendor/github.com/coreos/ignition/config/append_test.go
new file mode 100644
index 00000000..fb7f9a20
--- /dev/null
+++ b/vendor/github.com/coreos/ignition/config/append_test.go
@@ -0,0 +1,197 @@
+// Copyright 2016 CoreOS, Inc.
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+// http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+package config
+
+import (
+ "reflect"
+ "testing"
+
+ "github.com/coreos/ignition/config/types"
+)
+
+func TestAppend(t *testing.T) {
+ type in struct {
+ oldConfig types.Config
+ newConfig types.Config
+ }
+ type out struct {
+ config types.Config
+ }
+
+ tests := []struct {
+ in in
+ out out
+ }{
+ // empty
+ {
+ in: in{
+ oldConfig: types.Config{},
+ newConfig: types.Config{},
+ },
+ out: out{config: types.Config{}},
+ },
+
+ // merge tags
+ {
+ in: in{
+ oldConfig: types.Config{},
+ newConfig: types.Config{
+ Ignition: types.Ignition{
+ Version: types.IgnitionVersion{Major: 2},
+ },
+ },
+ },
+ out: out{config: types.Config{}},
+ },
+ {
+ in: in{
+ oldConfig: types.Config{
+ Ignition: types.Ignition{
+ Version: types.IgnitionVersion{Major: 2},
+ },
+ },
+ newConfig: types.Config{},
+ },
+ out: out{config: types.Config{
+ Ignition: types.Ignition{
+ Version: types.IgnitionVersion{Major: 2},
+ },
+ }},
+ },
+ {
+ in: in{
+ oldConfig: types.Config{},
+ newConfig: types.Config{
+ Ignition: types.Ignition{
+ Config: types.IgnitionConfig{
+ Replace: &types.ConfigReference{},
+ },
+ },
+ },
+ },
+ out: out{config: types.Config{
+ Ignition: types.Ignition{
+ Config: types.IgnitionConfig{
+ Replace: &types.ConfigReference{},
+ },
+ },
+ }},
+ },
+ {
+ in: in{
+ oldConfig: types.Config{
+ Ignition: types.Ignition{
+ Config: types.IgnitionConfig{
+ Replace: &types.ConfigReference{},
+ },
+ },
+ },
+ newConfig: types.Config{},
+ },
+ out: out{config: types.Config{}},
+ },
+
+ // old
+ {
+ in: in{
+ oldConfig: types.Config{
+ Storage: types.Storage{
+ Disks: []types.Disk{
+ {
+ WipeTable: true,
+ Partitions: []types.Partition{
+ {Number: 1},
+ {Number: 2},
+ },
+ },
+ },
+ },
+ },
+ newConfig: types.Config{},
+ },
+ out: out{config: types.Config{
+ Storage: types.Storage{
+ Disks: []types.Disk{
+ {
+ WipeTable: true,
+ Partitions: []types.Partition{
+ {Number: 1},
+ {Number: 2},
+ },
+ },
+ },
+ },
+ }},
+ },
+
+ // new
+ {
+ in: in{
+ oldConfig: types.Config{},
+ newConfig: types.Config{
+ Systemd: types.Systemd{
+ Units: []types.SystemdUnit{
+ {Name: "test1.service"},
+ {Name: "test2.service"},
+ },
+ },
+ },
+ },
+ out: out{config: types.Config{
+ Systemd: types.Systemd{
+ Units: []types.SystemdUnit{
+ {Name: "test1.service"},
+ {Name: "test2.service"},
+ },
+ },
+ }},
+ },
+
+ // both
+ {
+ in: in{
+ oldConfig: types.Config{
+ Passwd: types.Passwd{
+ Users: []types.User{
+ {Name: "oldUser"},
+ },
+ },
+ },
+ newConfig: types.Config{
+ Passwd: types.Passwd{
+ Users: []types.User{
+ {Name: "newUser"},
+ },
+ },
+ },
+ },
+ out: out{config: types.Config{
+ Passwd: types.Passwd{
+ Users: []types.User{
+ {Name: "oldUser"},
+ {Name: "newUser"},
+ },
+ },
+ }},
+ },
+ }
+
+ for i, test := range tests {
+ config := Append(test.in.oldConfig, test.in.newConfig)
+ if !reflect.DeepEqual(test.out.config, config) {
+ t.Errorf("#%d: bad config: want %+v, got %+v", i, test.out.config, config)
+ }
+ }
+}
diff --git a/vendor/github.com/coreos/ignition/src/config/cloudinit.go b/vendor/github.com/coreos/ignition/config/cloudinit.go
similarity index 66%
rename from vendor/github.com/coreos/ignition/src/config/cloudinit.go
rename to vendor/github.com/coreos/ignition/config/cloudinit.go
index 9937eaa9..8f1f5fb7 100644
--- a/vendor/github.com/coreos/ignition/src/config/cloudinit.go
+++ b/vendor/github.com/coreos/ignition/config/cloudinit.go
@@ -17,12 +17,15 @@
package config
import (
+ "bytes"
+ "compress/gzip"
+ "io/ioutil"
"strings"
"unicode"
)
func isCloudConfig(userdata []byte) bool {
- header := strings.SplitN(string(userdata), "\n", 2)[0]
+ header := strings.SplitN(string(decompressIfGzipped(userdata)), "\n", 2)[0]
// Trim trailing whitespaces
header = strings.TrimRightFunc(header, unicode.IsSpace)
@@ -31,6 +34,20 @@ func isCloudConfig(userdata []byte) bool {
}
func isScript(userdata []byte) bool {
- header := strings.SplitN(string(userdata), "\n", 2)[0]
+ header := strings.SplitN(string(decompressIfGzipped(userdata)), "\n", 2)[0]
return strings.HasPrefix(header, "#!")
}
+
+func decompressIfGzipped(data []byte) []byte {
+ if reader, err := gzip.NewReader(bytes.NewReader(data)); err == nil {
+ uncompressedData, err := ioutil.ReadAll(reader)
+ reader.Close()
+ if err == nil {
+ return uncompressedData
+ } else {
+ return data
+ }
+ } else {
+ return data
+ }
+}
diff --git a/vendor/github.com/coreos/ignition/config/config.go b/vendor/github.com/coreos/ignition/config/config.go
new file mode 100644
index 00000000..14d3788d
--- /dev/null
+++ b/vendor/github.com/coreos/ignition/config/config.go
@@ -0,0 +1,101 @@
+// Copyright 2015 CoreOS, Inc.
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+// http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+package config
+
+import (
+ "bytes"
+ "encoding/json"
+ "errors"
+ "fmt"
+
+ "github.com/coreos/ignition/config/types"
+ "github.com/coreos/ignition/config/v1"
+
+ "go4.org/errorutil"
+)
+
+var (
+ ErrCloudConfig = errors.New("not a config (found coreos-cloudconfig)")
+ ErrEmpty = errors.New("not a config (empty)")
+ ErrScript = errors.New("not a config (found coreos-cloudinit script)")
+ ErrDeprecated = errors.New("config format deprecated")
+)
+
+func Parse(rawConfig []byte) (types.Config, error) {
+ switch majorVersion(rawConfig) {
+ case 1:
+ config, err := ParseFromV1(rawConfig)
+ if err != nil {
+ return types.Config{}, err
+ }
+
+ return config, ErrDeprecated
+ default:
+ return ParseFromLatest(rawConfig)
+ }
+}
+
+func ParseFromLatest(rawConfig []byte) (config types.Config, err error) {
+ if err = json.Unmarshal(rawConfig, &config); err == nil {
+ err = config.Ignition.Version.AssertValid()
+ } else if isEmpty(rawConfig) {
+ err = ErrEmpty
+ } else if isCloudConfig(rawConfig) {
+ err = ErrCloudConfig
+ } else if isScript(rawConfig) {
+ err = ErrScript
+ }
+ if serr, ok := err.(*json.SyntaxError); ok {
+ line, col, highlight := errorutil.HighlightBytePosition(bytes.NewReader(rawConfig), serr.Offset)
+ err = fmt.Errorf("error at line %d, column %d\n%s%v", line, col, highlight, err)
+ }
+
+ return
+}
+
+func ParseFromV1(rawConfig []byte) (types.Config, error) {
+ config, err := v1.Parse(rawConfig)
+ if err != nil {
+ return types.Config{}, err
+ }
+
+ return TranslateFromV1(config)
+}
+
+func majorVersion(rawConfig []byte) int64 {
+ var composite struct {
+ Version *int `json:"ignitionVersion"`
+ Ignition struct {
+ Version *types.IgnitionVersion `json:"version"`
+ } `json:"ignition"`
+ }
+
+ if json.Unmarshal(rawConfig, &composite) != nil {
+ return 0
+ }
+
+ var major int64
+ if composite.Ignition.Version != nil {
+ major = composite.Ignition.Version.Major
+ } else if composite.Version != nil {
+ major = int64(*composite.Version)
+ }
+
+ return major
+}
+
+func isEmpty(userdata []byte) bool {
+ return len(userdata) == 0
+}
diff --git a/vendor/github.com/coreos/ignition/config/config_test.go b/vendor/github.com/coreos/ignition/config/config_test.go
new file mode 100644
index 00000000..eb32d87d
--- /dev/null
+++ b/vendor/github.com/coreos/ignition/config/config_test.go
@@ -0,0 +1,102 @@
+// Copyright 2015 CoreOS, Inc.
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+// http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+package config
+
+import (
+ "reflect"
+ "testing"
+
+ "github.com/coreos/ignition/config/types"
+ v1 "github.com/coreos/ignition/config/v1"
+)
+
+func TestParse(t *testing.T) {
+ type in struct {
+ config []byte
+ }
+ type out struct {
+ config types.Config
+ err error
+ }
+
+ tests := []struct {
+ in in
+ out out
+ }{
+ {
+ in: in{config: []byte(`{"ignitionVersion": 1}`)},
+ out: out{err: ErrDeprecated},
+ },
+ {
+ in: in{config: []byte(`{"ignition": {"version": "1.0.0"}}`)},
+ out: out{err: v1.ErrVersion},
+ },
+ {
+ in: in{config: []byte(`{"ignition": {"version": "2.0.0"}}`)},
+ out: out{config: types.Config{Ignition: types.Ignition{Version: types.IgnitionVersion{Major: 2, Minor: 0}}}},
+ },
+ {
+ in: in{config: []byte(`{"ignition": {"version": "2.1.0"}}`)},
+ out: out{err: types.ErrNewVersion},
+ },
+ {
+ in: in{config: []byte(`{}`)},
+ out: out{err: types.ErrOldVersion},
+ },
+ {
+ in: in{config: []byte{}},
+ out: out{err: ErrEmpty},
+ },
+ {
+ in: in{config: []byte("#cloud-config")},
+ out: out{err: ErrCloudConfig},
+ },
+ {
+ in: in{config: []byte("#cloud-config ")},
+ out: out{err: ErrCloudConfig},
+ },
+ {
+ in: in{config: []byte("#cloud-config\n\r")},
+ out: out{err: ErrCloudConfig},
+ },
+ {
+ in: in{config: []byte{0x1f, 0x8b, 0x08, 0x00, 0x03, 0xd6, 0x79, 0x56,
+ 0x00, 0x03, 0x53, 0x4e, 0xce, 0xc9, 0x2f, 0x4d, 0xd1, 0x4d, 0xce,
+ 0xcf, 0x4b, 0xcb, 0x4c, 0xe7, 0x02, 0x00, 0x05, 0x56, 0xb3, 0xb8,
+ 0x0e, 0x00, 0x00, 0x00}},
+ out: out{err: ErrCloudConfig},
+ },
+ {
+ in: in{config: []byte("#!/bin/sh")},
+ out: out{err: ErrScript},
+ },
+ {
+ in: in{config: []byte{0x1f, 0x8b, 0x08, 0x00, 0x48, 0xda, 0x79, 0x56,
+ 0x00, 0x03, 0x53, 0x56, 0xd4, 0x4f, 0xca, 0xcc, 0xd3, 0x2f, 0xce,
+ 0xe0, 0x02, 0x00, 0x1d, 0x9d, 0xfb, 0x04, 0x0a, 0x00, 0x00, 0x00}},
+ out: out{err: ErrScript},
+ },
+ }
+
+ for i, test := range tests {
+ config, err := Parse(test.in.config)
+ if test.out.err != err {
+ t.Errorf("#%d: bad error: want %v, got %v", i, test.out.err, err)
+ }
+ if test.out.err == nil && !reflect.DeepEqual(test.out.config, config) {
+ t.Errorf("#%d: bad config: want %+v, got %+v", i, test.out.config, config)
+ }
+ }
+}
diff --git a/vendor/github.com/coreos/ignition/config/translate.go b/vendor/github.com/coreos/ignition/config/translate.go
new file mode 100644
index 00000000..f0875455
--- /dev/null
+++ b/vendor/github.com/coreos/ignition/config/translate.go
@@ -0,0 +1,163 @@
+// Copyright 2016 CoreOS, Inc.
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+// http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+package config
+
+import (
+ "fmt"
+
+ "github.com/coreos/ignition/config/types"
+ v1 "github.com/coreos/ignition/config/v1/types"
+
+ "github.com/vincent-petithory/dataurl"
+)
+
+func TranslateFromV1(old v1.Config) (types.Config, error) {
+ config := types.Config{
+ Ignition: types.Ignition{
+ Version: types.IgnitionVersion{Major: 2},
+ },
+ }
+
+ for _, oldDisk := range old.Storage.Disks {
+ disk := types.Disk{
+ Device: types.Path(oldDisk.Device),
+ WipeTable: oldDisk.WipeTable,
+ }
+
+ for _, oldPartition := range oldDisk.Partitions {
+ disk.Partitions = append(disk.Partitions, types.Partition{
+ Label: types.PartitionLabel(oldPartition.Label),
+ Number: oldPartition.Number,
+ Size: types.PartitionDimension(oldPartition.Size),
+ Start: types.PartitionDimension(oldPartition.Start),
+ TypeGUID: types.PartitionTypeGUID(oldPartition.TypeGUID),
+ })
+ }
+
+ config.Storage.Disks = append(config.Storage.Disks, disk)
+ }
+
+ for _, oldArray := range old.Storage.Arrays {
+ array := types.Raid{
+ Name: oldArray.Name,
+ Level: oldArray.Level,
+ Spares: oldArray.Spares,
+ }
+
+ for _, oldDevice := range oldArray.Devices {
+ array.Devices = append(array.Devices, types.Path(oldDevice))
+ }
+
+ config.Storage.Arrays = append(config.Storage.Arrays, array)
+ }
+
+ for i, oldFilesystem := range old.Storage.Filesystems {
+ filesystem := types.Filesystem{
+ Name: fmt.Sprintf("_translate-filesystem-%d", i),
+ Mount: &types.FilesystemMount{
+ Device: types.Path(oldFilesystem.Device),
+ Format: types.FilesystemFormat(oldFilesystem.Format),
+ },
+ }
+
+ if oldFilesystem.Create != nil {
+ filesystem.Mount.Create = &types.FilesystemCreate{
+ Force: oldFilesystem.Create.Force,
+ Options: types.MkfsOptions(oldFilesystem.Create.Options),
+ }
+ }
+
+ config.Storage.Filesystems = append(config.Storage.Filesystems, filesystem)
+
+ for _, oldFile := range oldFilesystem.Files {
+ file := types.File{
+ Filesystem: filesystem.Name,
+ Path: types.Path(oldFile.Path),
+ Contents: types.FileContents{
+ Source: types.Url{
+ Scheme: "data",
+ Opaque: "," + dataurl.EscapeString(oldFile.Contents),
+ },
+ },
+ Mode: types.FileMode(oldFile.Mode),
+ User: types.FileUser{Id: oldFile.Uid},
+ Group: types.FileGroup{Id: oldFile.Gid},
+ }
+
+ config.Storage.Files = append(config.Storage.Files, file)
+ }
+ }
+
+ for _, oldUnit := range old.Systemd.Units {
+ unit := types.SystemdUnit{
+ Name: types.SystemdUnitName(oldUnit.Name),
+ Enable: oldUnit.Enable,
+ Mask: oldUnit.Mask,
+ Contents: oldUnit.Contents,
+ }
+
+ for _, oldDropIn := range oldUnit.DropIns {
+ unit.DropIns = append(unit.DropIns, types.SystemdUnitDropIn{
+ Name: types.SystemdUnitDropInName(oldDropIn.Name),
+ Contents: oldDropIn.Contents,
+ })
+ }
+
+ config.Systemd.Units = append(config.Systemd.Units, unit)
+ }
+
+ for _, oldUnit := range old.Networkd.Units {
+ config.Networkd.Units = append(config.Networkd.Units, types.NetworkdUnit{
+ Name: types.NetworkdUnitName(oldUnit.Name),
+ Contents: oldUnit.Contents,
+ })
+ }
+
+ for _, oldUser := range old.Passwd.Users {
+ user := types.User{
+ Name: oldUser.Name,
+ PasswordHash: oldUser.PasswordHash,
+ SSHAuthorizedKeys: oldUser.SSHAuthorizedKeys,
+ }
+
+ if oldUser.Create != nil {
+ user.Create = &types.UserCreate{
+ Uid: oldUser.Create.Uid,
+ GECOS: oldUser.Create.GECOS,
+ Homedir: oldUser.Create.Homedir,
+ NoCreateHome: oldUser.Create.NoCreateHome,
+ PrimaryGroup: oldUser.Create.PrimaryGroup,
+ Groups: oldUser.Create.Groups,
+ NoUserGroup: oldUser.Create.NoUserGroup,
+ System: oldUser.Create.System,
+ NoLogInit: oldUser.Create.NoLogInit,
+ Shell: oldUser.Create.Shell,
+ }
+ }
+
+ config.Passwd.Users = append(config.Passwd.Users, user)
+ }
+
+ for _, oldGroup := range old.Passwd.Groups {
+ config.Passwd.Groups = append(config.Passwd.Groups, types.Group{
+ Name: oldGroup.Name,
+ Gid: oldGroup.Gid,
+ PasswordHash: oldGroup.PasswordHash,
+ System: oldGroup.System,
+ })
+ }
+
+ return config, nil
+}
diff --git a/vendor/github.com/coreos/ignition/config/translate_test.go b/vendor/github.com/coreos/ignition/config/translate_test.go
new file mode 100644
index 00000000..bea1a42c
--- /dev/null
+++ b/vendor/github.com/coreos/ignition/config/translate_test.go
@@ -0,0 +1,425 @@
+// Copyright 2016 CoreOS, Inc.
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+// http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+package config
+
+import (
+ "reflect"
+ "testing"
+
+ "github.com/coreos/ignition/config/types"
+ v1 "github.com/coreos/ignition/config/v1/types"
+)
+
+func TestTranslateFromV1(t *testing.T) {
+ type in struct {
+ config v1.Config
+ }
+ type out struct {
+ config types.Config
+ err error
+ }
+
+ tests := []struct {
+ in in
+ out out
+ }{
+ {
+ in: in{},
+ out: out{config: types.Config{Ignition: types.Ignition{Version: types.IgnitionVersion{Major: 2}}}},
+ },
+ {
+ in: in{config: v1.Config{
+ Storage: v1.Storage{
+ Disks: []v1.Disk{
+ {
+ Device: v1.Path("/dev/sda"),
+ WipeTable: true,
+ Partitions: []v1.Partition{
+ {
+ Label: v1.PartitionLabel("ROOT"),
+ Number: 7,
+ Size: v1.PartitionDimension(100),
+ Start: v1.PartitionDimension(50),
+ TypeGUID: "HI",
+ },
+ {
+ Label: v1.PartitionLabel("DATA"),
+ Number: 12,
+ Size: v1.PartitionDimension(1000),
+ Start: v1.PartitionDimension(300),
+ TypeGUID: "LO",
+ },
+ },
+ },
+ {
+ Device: v1.Path("/dev/sdb"),
+ WipeTable: true,
+ },
+ },
+ Arrays: []v1.Raid{
+ {
+ Name: "fast",
+ Level: "raid0",
+ Devices: []v1.Path{v1.Path("/dev/sdc"), v1.Path("/dev/sdd")},
+ Spares: 2,
+ },
+ {
+ Name: "durable",
+ Level: "raid1",
+ Devices: []v1.Path{v1.Path("/dev/sde"), v1.Path("/dev/sdf")},
+ Spares: 3,
+ },
+ },
+ Filesystems: []v1.Filesystem{
+ {
+ Device: v1.Path("/dev/disk/by-partlabel/ROOT"),
+ Format: v1.FilesystemFormat("btrfs"),
+ Create: &v1.FilesystemCreate{
+ Force: true,
+ Options: v1.MkfsOptions([]string{"-L", "ROOT"}),
+ },
+ Files: []v1.File{
+ {
+ Path: v1.Path("/opt/file1"),
+ Contents: "file1",
+ Mode: v1.FileMode(0664),
+ Uid: 500,
+ Gid: 501,
+ },
+ {
+ Path: v1.Path("/opt/file2"),
+ Contents: "file2",
+ Mode: v1.FileMode(0644),
+ Uid: 502,
+ Gid: 503,
+ },
+ },
+ },
+ {
+ Device: v1.Path("/dev/disk/by-partlabel/DATA"),
+ Format: v1.FilesystemFormat("ext4"),
+ Files: []v1.File{
+ {
+ Path: v1.Path("/opt/file3"),
+ Contents: "file3",
+ Mode: v1.FileMode(0400),
+ Uid: 1000,
+ Gid: 1001,
+ },
+ },
+ },
+ },
+ },
+ }},
+ out: out{config: types.Config{
+ Ignition: types.Ignition{Version: types.IgnitionVersion{Major: 2}},
+ Storage: types.Storage{
+ Disks: []types.Disk{
+ {
+ Device: types.Path("/dev/sda"),
+ WipeTable: true,
+ Partitions: []types.Partition{
+ {
+ Label: types.PartitionLabel("ROOT"),
+ Number: 7,
+ Size: types.PartitionDimension(100),
+ Start: types.PartitionDimension(50),
+ TypeGUID: "HI",
+ },
+ {
+ Label: types.PartitionLabel("DATA"),
+ Number: 12,
+ Size: types.PartitionDimension(1000),
+ Start: types.PartitionDimension(300),
+ TypeGUID: "LO",
+ },
+ },
+ },
+ {
+ Device: types.Path("/dev/sdb"),
+ WipeTable: true,
+ },
+ },
+ Arrays: []types.Raid{
+ {
+ Name: "fast",
+ Level: "raid0",
+ Devices: []types.Path{types.Path("/dev/sdc"), types.Path("/dev/sdd")},
+ Spares: 2,
+ },
+ {
+ Name: "durable",
+ Level: "raid1",
+ Devices: []types.Path{types.Path("/dev/sde"), types.Path("/dev/sdf")},
+ Spares: 3,
+ },
+ },
+ Filesystems: []types.Filesystem{
+ {
+ Name: "_translate-filesystem-0",
+ Mount: &types.FilesystemMount{
+ Device: types.Path("/dev/disk/by-partlabel/ROOT"),
+ Format: types.FilesystemFormat("btrfs"),
+ Create: &types.FilesystemCreate{
+ Force: true,
+ Options: types.MkfsOptions([]string{"-L", "ROOT"}),
+ },
+ },
+ },
+ {
+ Name: "_translate-filesystem-1",
+ Mount: &types.FilesystemMount{
+ Device: types.Path("/dev/disk/by-partlabel/DATA"),
+ Format: types.FilesystemFormat("ext4"),
+ },
+ },
+ },
+ Files: []types.File{
+ {
+ Filesystem: "_translate-filesystem-0",
+ Path: types.Path("/opt/file1"),
+ Contents: types.FileContents{
+ Source: types.Url{
+ Scheme: "data",
+ Opaque: ",file1",
+ },
+ },
+ Mode: types.FileMode(0664),
+ User: types.FileUser{Id: 500},
+ Group: types.FileGroup{Id: 501},
+ },
+ {
+ Filesystem: "_translate-filesystem-0",
+ Path: types.Path("/opt/file2"),
+ Contents: types.FileContents{
+ Source: types.Url{
+ Scheme: "data",
+ Opaque: ",file2",
+ },
+ },
+ Mode: types.FileMode(0644),
+ User: types.FileUser{Id: 502},
+ Group: types.FileGroup{Id: 503},
+ },
+ {
+ Filesystem: "_translate-filesystem-1",
+ Path: types.Path("/opt/file3"),
+ Contents: types.FileContents{
+ Source: types.Url{
+ Scheme: "data",
+ Opaque: ",file3",
+ },
+ },
+ Mode: types.FileMode(0400),
+ User: types.FileUser{Id: 1000},
+ Group: types.FileGroup{Id: 1001},
+ },
+ },
+ },
+ }},
+ },
+ {
+ in: in{v1.Config{
+ Systemd: v1.Systemd{
+ Units: []v1.SystemdUnit{
+ {
+ Name: "test1.service",
+ Enable: true,
+ Contents: "test1 contents",
+ DropIns: []v1.SystemdUnitDropIn{
+ {
+ Name: "conf1.conf",
+ Contents: "conf1 contents",
+ },
+ {
+ Name: "conf2.conf",
+ Contents: "conf2 contents",
+ },
+ },
+ },
+ {
+ Name: "test2.service",
+ Mask: true,
+ Contents: "test2 contents",
+ },
+ },
+ },
+ }},
+ out: out{config: types.Config{
+ Ignition: types.Ignition{Version: types.IgnitionVersion{Major: 2}},
+ Systemd: types.Systemd{
+ Units: []types.SystemdUnit{
+ {
+ Name: "test1.service",
+ Enable: true,
+ Contents: "test1 contents",
+ DropIns: []types.SystemdUnitDropIn{
+ {
+ Name: "conf1.conf",
+ Contents: "conf1 contents",
+ },
+ {
+ Name: "conf2.conf",
+ Contents: "conf2 contents",
+ },
+ },
+ },
+ {
+ Name: "test2.service",
+ Mask: true,
+ Contents: "test2 contents",
+ },
+ },
+ },
+ }},
+ },
+ {
+ in: in{v1.Config{
+ Networkd: v1.Networkd{
+ Units: []v1.NetworkdUnit{
+ {
+ Name: "test1.network",
+ Contents: "test1 contents",
+ },
+ {
+ Name: "test2.network",
+ Contents: "test2 contents",
+ },
+ },
+ },
+ }},
+ out: out{config: types.Config{
+ Ignition: types.Ignition{Version: types.IgnitionVersion{Major: 2}},
+ Networkd: types.Networkd{
+ Units: []types.NetworkdUnit{
+ {
+ Name: "test1.network",
+ Contents: "test1 contents",
+ },
+ {
+ Name: "test2.network",
+ Contents: "test2 contents",
+ },
+ },
+ },
+ }},
+ },
+ {
+ in: in{v1.Config{
+ Passwd: v1.Passwd{
+ Users: []v1.User{
+ {
+ Name: "user 1",
+ PasswordHash: "password 1",
+ SSHAuthorizedKeys: []string{"key1", "key2"},
+ },
+ {
+ Name: "user 2",
+ PasswordHash: "password 2",
+ SSHAuthorizedKeys: []string{"key3", "key4"},
+ Create: &v1.UserCreate{
+ Uid: func(i uint) *uint { return &i }(123),
+ GECOS: "gecos",
+ Homedir: "/home/user 2",
+ NoCreateHome: true,
+ PrimaryGroup: "wheel",
+ Groups: []string{"wheel", "plugdev"},
+ NoUserGroup: true,
+ System: true,
+ NoLogInit: true,
+ Shell: "/bin/zsh",
+ },
+ },
+ {
+ Name: "user 3",
+ PasswordHash: "password 3",
+ SSHAuthorizedKeys: []string{"key5", "key6"},
+ Create: &v1.UserCreate{},
+ },
+ },
+ Groups: []v1.Group{
+ {
+ Name: "group 1",
+ Gid: func(i uint) *uint { return &i }(1000),
+ PasswordHash: "password 1",
+ System: true,
+ },
+ {
+ Name: "group 2",
+ PasswordHash: "password 2",
+ },
+ },
+ },
+ }},
+ out: out{config: types.Config{
+ Ignition: types.Ignition{Version: types.IgnitionVersion{Major: 2}},
+ Passwd: types.Passwd{
+ Users: []types.User{
+ {
+ Name: "user 1",
+ PasswordHash: "password 1",
+ SSHAuthorizedKeys: []string{"key1", "key2"},
+ },
+ {
+ Name: "user 2",
+ PasswordHash: "password 2",
+ SSHAuthorizedKeys: []string{"key3", "key4"},
+ Create: &types.UserCreate{
+ Uid: func(i uint) *uint { return &i }(123),
+ GECOS: "gecos",
+ Homedir: "/home/user 2",
+ NoCreateHome: true,
+ PrimaryGroup: "wheel",
+ Groups: []string{"wheel", "plugdev"},
+ NoUserGroup: true,
+ System: true,
+ NoLogInit: true,
+ Shell: "/bin/zsh",
+ },
+ },
+ {
+ Name: "user 3",
+ PasswordHash: "password 3",
+ SSHAuthorizedKeys: []string{"key5", "key6"},
+ Create: &types.UserCreate{},
+ },
+ },
+ Groups: []types.Group{
+ {
+ Name: "group 1",
+ Gid: func(i uint) *uint { return &i }(1000),
+ PasswordHash: "password 1",
+ System: true,
+ },
+ {
+ Name: "group 2",
+ PasswordHash: "password 2",
+ },
+ },
+ },
+ }},
+ },
+ }
+
+ for i, test := range tests {
+ config, err := TranslateFromV1(test.in.config)
+ if test.out.err != err {
+ t.Errorf("#%d: bad error: want %v, got %v", i, test.out.err, err)
+ }
+ if !reflect.DeepEqual(test.out.config, config) {
+ t.Errorf("#%d: bad config: want %+v, got %+v", i, test.out.config, config)
+ }
+ }
+}
diff --git a/vendor/github.com/coreos/ignition/config/types/compression.go b/vendor/github.com/coreos/ignition/config/types/compression.go
new file mode 100644
index 00000000..a8069756
--- /dev/null
+++ b/vendor/github.com/coreos/ignition/config/types/compression.go
@@ -0,0 +1,54 @@
+// Copyright 2016 CoreOS, Inc.
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+// http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+package types
+
+import (
+ "encoding/json"
+ "errors"
+)
+
+var (
+ ErrCompressionInvalid = errors.New("invalid compression method")
+)
+
+type Compression string
+
+func (c *Compression) UnmarshalYAML(unmarshal func(interface{}) error) error {
+ return c.unmarshal(unmarshal)
+}
+
+func (c *Compression) UnmarshalJSON(data []byte) error {
+ return c.unmarshal(func(tc interface{}) error {
+ return json.Unmarshal(data, tc)
+ })
+}
+
+func (c *Compression) unmarshal(unmarshal func(interface{}) error) error {
+ var tc string
+ if err := unmarshal(&tc); err != nil {
+ return err
+ }
+ *c = Compression(tc)
+ return c.assertValid()
+}
+
+func (c Compression) assertValid() error {
+ switch c {
+ case "gzip":
+ default:
+ return ErrCompressionInvalid
+ }
+ return nil
+}
diff --git a/vendor/github.com/coreos/ignition/config/types/config.go b/vendor/github.com/coreos/ignition/config/types/config.go
new file mode 100644
index 00000000..7d7b60fa
--- /dev/null
+++ b/vendor/github.com/coreos/ignition/config/types/config.go
@@ -0,0 +1,34 @@
+// Copyright 2015 CoreOS, Inc.
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+// http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+package types
+
+import (
+ "github.com/coreos/go-semver/semver"
+)
+
+var (
+ MaxVersion = semver.Version{
+ Major: 2,
+ Minor: 0,
+ }
+)
+
+type Config struct {
+ Ignition Ignition `json:"ignition" yaml:"ignition"`
+ Storage Storage `json:"storage,omitempty" yaml:"storage"`
+ Systemd Systemd `json:"systemd,omitempty" yaml:"systemd"`
+ Networkd Networkd `json:"networkd,omitempty" yaml:"networkd"`
+ Passwd Passwd `json:"passwd,omitempty" yaml:"passwd"`
+}
diff --git a/vendor/github.com/coreos/ignition/src/config/disk.go b/vendor/github.com/coreos/ignition/config/types/disk.go
similarity index 97%
rename from vendor/github.com/coreos/ignition/src/config/disk.go
rename to vendor/github.com/coreos/ignition/config/types/disk.go
index c2c0e09b..e0f39483 100644
--- a/vendor/github.com/coreos/ignition/src/config/disk.go
+++ b/vendor/github.com/coreos/ignition/config/types/disk.go
@@ -1,4 +1,4 @@
-// Copyright 2015 CoreOS, Inc.
+// Copyright 2016 CoreOS, Inc.
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
@@ -12,7 +12,7 @@
// See the License for the specific language governing permissions and
// limitations under the License.
-package config
+package types
import (
"encoding/json"
@@ -20,7 +20,7 @@ import (
)
type Disk struct {
- Device DevicePath `json:"device,omitempty" yaml:"device"`
+ Device Path `json:"device,omitempty" yaml:"device"`
WipeTable bool `json:"wipeTable,omitempty" yaml:"wipe_table"`
Partitions []Partition `json:"partitions,omitempty" yaml:"partitions"`
}
diff --git a/vendor/github.com/coreos/ignition/config/types/file.go b/vendor/github.com/coreos/ignition/config/types/file.go
new file mode 100644
index 00000000..528531f0
--- /dev/null
+++ b/vendor/github.com/coreos/ignition/config/types/file.go
@@ -0,0 +1,78 @@
+// Copyright 2016 CoreOS, Inc.
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+// http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+package types
+
+import (
+ "encoding/json"
+ "errors"
+ "os"
+)
+
+var (
+ ErrFileIllegalMode = errors.New("illegal file mode")
+)
+
+type File struct {
+ Filesystem string `json:"filesystem,omitempty" yaml:"filesystem"`
+ Path Path `json:"path,omitempty" yaml:"path"`
+ Contents FileContents `json:"contents,omitempty" yaml:"contents"`
+ Mode FileMode `json:"mode,omitempty" yaml:"mode"`
+ User FileUser `json:"user,omitempty" yaml:"uid"`
+ Group FileGroup `json:"group,omitempty" yaml:"gid"`
+}
+
+type FileUser struct {
+ Id int `json:"id,omitempty" yaml:"id"`
+}
+
+type FileGroup struct {
+ Id int `json:"id,omitempty" yaml:"id"`
+}
+
+type FileContents struct {
+ Compression Compression `json:"compression,omitempty" yaml:"compression"`
+ Source Url `json:"source,omitempty" yaml:"source"`
+ Verification Verification `json:"verification,omitempty" yaml:"verification"`
+}
+
+type FileMode os.FileMode
+
+func (m *FileMode) UnmarshalYAML(unmarshal func(interface{}) error) error {
+ return m.unmarshal(unmarshal)
+}
+
+func (m *FileMode) UnmarshalJSON(data []byte) error {
+ return m.unmarshal(func(tm interface{}) error {
+ return json.Unmarshal(data, tm)
+ })
+}
+
+type fileMode FileMode
+
+func (m *FileMode) unmarshal(unmarshal func(interface{}) error) error {
+ tm := fileMode(*m)
+ if err := unmarshal(&tm); err != nil {
+ return err
+ }
+ *m = FileMode(tm)
+ return m.assertValid()
+}
+
+func (m FileMode) assertValid() error {
+ if (m &^ 07777) != 0 {
+ return ErrFileIllegalMode
+ }
+ return nil
+}
diff --git a/vendor/github.com/coreos/ignition/src/config/file_test.go b/vendor/github.com/coreos/ignition/config/types/file_test.go
similarity index 96%
rename from vendor/github.com/coreos/ignition/src/config/file_test.go
rename to vendor/github.com/coreos/ignition/config/types/file_test.go
index 74d7e1f3..8b56f003 100644
--- a/vendor/github.com/coreos/ignition/src/config/file_test.go
+++ b/vendor/github.com/coreos/ignition/config/types/file_test.go
@@ -1,4 +1,4 @@
-// Copyright 2015 CoreOS, Inc.
+// Copyright 2016 CoreOS, Inc.
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
@@ -12,14 +12,14 @@
// See the License for the specific language governing permissions and
// limitations under the License.
-package config
+package types
import (
"encoding/json"
"reflect"
"testing"
- "github.com/coreos/ignition/third_party/github.com/go-yaml/yaml"
+ "github.com/go-yaml/yaml"
)
func TestFileModeUnmarshalJSON(t *testing.T) {
diff --git a/vendor/github.com/coreos/ignition/config/types/filesystem.go b/vendor/github.com/coreos/ignition/config/types/filesystem.go
new file mode 100644
index 00000000..44e8eaf3
--- /dev/null
+++ b/vendor/github.com/coreos/ignition/config/types/filesystem.go
@@ -0,0 +1,181 @@
+// Copyright 2016 CoreOS, Inc.
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+// http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+package types
+
+import (
+ "encoding/json"
+ "errors"
+)
+
+var (
+ ErrFilesystemInvalidFormat = errors.New("invalid filesystem format")
+ ErrFilesystemNoMountPath = errors.New("filesystem is missing mount or path")
+ ErrFilesystemMountAndPath = errors.New("filesystem has both mount and path defined")
+)
+
+type Filesystem struct {
+ Name string `json:"name,omitempty" yaml:"name"`
+ Mount *FilesystemMount `json:"mount,omitempty" yaml:"mount"`
+ Path Path `json:"path,omitempty" yaml:"path"`
+}
+
+type FilesystemMount struct {
+ Device Path `json:"device,omitempty" yaml:"device"`
+ Format FilesystemFormat `json:"format,omitempty" yaml:"format"`
+ Create *FilesystemCreate `json:"create,omitempty" yaml:"create"`
+}
+
+type FilesystemCreate struct {
+ Force bool `json:"force,omitempty" yaml:"force"`
+ Options MkfsOptions `json:"options,omitempty" yaml:"options"`
+}
+
+func (f *Filesystem) UnmarshalYAML(unmarshal func(interface{}) error) error {
+ return f.unmarshal(unmarshal)
+}
+
+func (f *Filesystem) UnmarshalJSON(data []byte) error {
+ return f.unmarshal(func(tf interface{}) error {
+ return json.Unmarshal(data, tf)
+ })
+}
+
+type filesystem Filesystem
+
+func (f *Filesystem) unmarshal(unmarshal func(interface{}) error) error {
+ tf := filesystem(*f)
+ if err := unmarshal(&tf); err != nil {
+ return err
+ }
+ *f = Filesystem(tf)
+ return f.assertValid()
+}
+
+func (f Filesystem) assertValid() error {
+ hasMount := false
+ hasPath := false
+
+ if f.Mount != nil {
+ hasMount = true
+ if err := f.Mount.assertValid(); err != nil {
+ return err
+ }
+ }
+
+ if len(f.Path) != 0 {
+ hasPath = true
+ if err := f.Path.assertValid(); err != nil {
+ return err
+ }
+ }
+
+ if !hasMount && !hasPath {
+ return ErrFilesystemNoMountPath
+ } else if hasMount && hasPath {
+ return ErrFilesystemMountAndPath
+ }
+
+ return nil
+}
+
+func (f *FilesystemMount) UnmarshalYAML(unmarshal func(interface{}) error) error {
+ return f.unmarshal(unmarshal)
+}
+
+func (f *FilesystemMount) UnmarshalJSON(data []byte) error {
+ return f.unmarshal(func(tf interface{}) error {
+ return json.Unmarshal(data, tf)
+ })
+}
+
+type filesystemMount FilesystemMount
+
+func (f *FilesystemMount) unmarshal(unmarshal func(interface{}) error) error {
+ tf := filesystemMount(*f)
+ if err := unmarshal(&tf); err != nil {
+ return err
+ }
+ *f = FilesystemMount(tf)
+ return f.assertValid()
+}
+
+func (f FilesystemMount) assertValid() error {
+ if err := f.Device.assertValid(); err != nil {
+ return err
+ }
+ if err := f.Format.assertValid(); err != nil {
+ return err
+ }
+ return nil
+}
+
+type FilesystemFormat string
+
+func (f *FilesystemFormat) UnmarshalYAML(unmarshal func(interface{}) error) error {
+ return f.unmarshal(unmarshal)
+}
+
+func (f *FilesystemFormat) UnmarshalJSON(data []byte) error {
+ return f.unmarshal(func(tf interface{}) error {
+ return json.Unmarshal(data, tf)
+ })
+}
+
+type filesystemFormat FilesystemFormat
+
+func (f *FilesystemFormat) unmarshal(unmarshal func(interface{}) error) error {
+ tf := filesystemFormat(*f)
+ if err := unmarshal(&tf); err != nil {
+ return err
+ }
+ *f = FilesystemFormat(tf)
+ return f.assertValid()
+}
+
+func (f FilesystemFormat) assertValid() error {
+ switch f {
+ case "ext4", "btrfs", "xfs":
+ return nil
+ default:
+ return ErrFilesystemInvalidFormat
+ }
+}
+
+type MkfsOptions []string
+
+func (o *MkfsOptions) UnmarshalYAML(unmarshal func(interface{}) error) error {
+ return o.unmarshal(unmarshal)
+}
+
+func (o *MkfsOptions) UnmarshalJSON(data []byte) error {
+ return o.unmarshal(func(to interface{}) error {
+ return json.Unmarshal(data, to)
+ })
+}
+
+type mkfsOptions MkfsOptions
+
+func (o *MkfsOptions) unmarshal(unmarshal func(interface{}) error) error {
+ to := mkfsOptions(*o)
+ if err := unmarshal(&to); err != nil {
+ return err
+ }
+ *o = MkfsOptions(to)
+ return o.assertValid()
+}
+
+func (o MkfsOptions) assertValid() error {
+ return nil
+}
diff --git a/vendor/github.com/coreos/ignition/config/types/filesystem_test.go b/vendor/github.com/coreos/ignition/config/types/filesystem_test.go
new file mode 100644
index 00000000..4aedb2bf
--- /dev/null
+++ b/vendor/github.com/coreos/ignition/config/types/filesystem_test.go
@@ -0,0 +1,309 @@
+// Copyright 2016 CoreOS, Inc.
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+// http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+package types
+
+import (
+ "encoding/json"
+ "reflect"
+ "testing"
+
+ "github.com/go-yaml/yaml"
+)
+
+func TestFilesystemFormatUnmarshalJSON(t *testing.T) {
+ type in struct {
+ data string
+ }
+ type out struct {
+ format FilesystemFormat
+ err error
+ }
+
+ tests := []struct {
+ in in
+ out out
+ }{
+ {
+ in: in{data: `"ext4"`},
+ out: out{format: FilesystemFormat("ext4")},
+ },
+ {
+ in: in{data: `"bad"`},
+ out: out{format: FilesystemFormat("bad"), err: ErrFilesystemInvalidFormat},
+ },
+ }
+
+ for i, test := range tests {
+ var format FilesystemFormat
+ err := json.Unmarshal([]byte(test.in.data), &format)
+ if !reflect.DeepEqual(test.out.err, err) {
+ t.Errorf("#%d: bad error: want %v, got %v", i, test.out.err, err)
+ }
+ if !reflect.DeepEqual(test.out.format, format) {
+ t.Errorf("#%d: bad format: want %#v, got %#v", i, test.out.format, format)
+ }
+ }
+}
+
+func TestFilesystemFormatUnmarshalYAML(t *testing.T) {
+ type in struct {
+ data string
+ }
+ type out struct {
+ format FilesystemFormat
+ err error
+ }
+
+ tests := []struct {
+ in in
+ out out
+ }{
+ {
+ in: in{data: `"ext4"`},
+ out: out{format: FilesystemFormat("ext4")},
+ },
+ {
+ in: in{data: `"bad"`},
+ out: out{format: FilesystemFormat("bad"), err: ErrFilesystemInvalidFormat},
+ },
+ }
+
+ for i, test := range tests {
+ var format FilesystemFormat
+ err := yaml.Unmarshal([]byte(test.in.data), &format)
+ if !reflect.DeepEqual(test.out.err, err) {
+ t.Errorf("#%d: bad error: want %v, got %v", i, test.out.err, err)
+ }
+ if !reflect.DeepEqual(test.out.format, format) {
+ t.Errorf("#%d: bad format: want %#v, got %#v", i, test.out.format, format)
+ }
+ }
+}
+
+func TestFilesystemFormatAssertValid(t *testing.T) {
+ type in struct {
+ format FilesystemFormat
+ }
+ type out struct {
+ err error
+ }
+
+ tests := []struct {
+ in in
+ out out
+ }{
+ {
+ in: in{format: FilesystemFormat("ext4")},
+ out: out{},
+ },
+ {
+ in: in{format: FilesystemFormat("btrfs")},
+ out: out{},
+ },
+ {
+ in: in{format: FilesystemFormat("")},
+ out: out{err: ErrFilesystemInvalidFormat},
+ },
+ }
+
+ for i, test := range tests {
+ err := test.in.format.assertValid()
+ if !reflect.DeepEqual(test.out.err, err) {
+ t.Errorf("#%d: bad error: want %v, got %v", i, test.out.err, err)
+ }
+ }
+}
+
+func TestMkfsOptionsUnmarshalJSON(t *testing.T) {
+ type in struct {
+ data string
+ }
+ type out struct {
+ options MkfsOptions
+ err error
+ }
+
+ tests := []struct {
+ in in
+ out out
+ }{
+ {
+ in: in{data: `["--label=ROOT"]`},
+ out: out{options: MkfsOptions([]string{"--label=ROOT"})},
+ },
+ }
+
+ for i, test := range tests {
+ var options MkfsOptions
+ err := json.Unmarshal([]byte(test.in.data), &options)
+ if !reflect.DeepEqual(test.out.err, err) {
+ t.Errorf("#%d: bad error: want %v, got %v", i, test.out.err, err)
+ }
+ if !reflect.DeepEqual(test.out.options, options) {
+ t.Errorf("#%d: bad format: want %#v, got %#v", i, test.out.options, options)
+ }
+ }
+}
+
+func TestMkfsOptionsUnmarshalYAML(t *testing.T) {
+ type in struct {
+ data string
+ }
+ type out struct {
+ options MkfsOptions
+ err error
+ }
+
+ tests := []struct {
+ in in
+ out out
+ }{
+ {
+ in: in{data: `["--label=ROOT"]`},
+ out: out{options: MkfsOptions([]string{"--label=ROOT"})},
+ },
+ }
+
+ for i, test := range tests {
+ var options MkfsOptions
+ err := yaml.Unmarshal([]byte(test.in.data), &options)
+ if !reflect.DeepEqual(test.out.err, err) {
+ t.Errorf("#%d: bad error: want %v, got %v", i, test.out.err, err)
+ }
+ if !reflect.DeepEqual(test.out.options, options) {
+ t.Errorf("#%d: bad device: want %#v, got %#v", i, test.out.options, options)
+ }
+ }
+}
+
+func TestFilesystemUnmarshalJSON(t *testing.T) {
+ type in struct {
+ data string
+ }
+ type out struct {
+ filesystem Filesystem
+ err error
+ }
+
+ tests := []struct {
+ in in
+ out out
+ }{
+ {
+ in: in{data: `{"mount": {"device": "/foo", "format": "ext4"}}`},
+ out: out{filesystem: Filesystem{Mount: &FilesystemMount{Device: "/foo", Format: "ext4"}}},
+ },
+ {
+ in: in{data: `{"mount": {"format": "ext4"}}`},
+ out: out{err: ErrPathRelative},
+ },
+ }
+
+ for i, test := range tests {
+ var filesystem Filesystem
+ err := json.Unmarshal([]byte(test.in.data), &filesystem)
+ if !reflect.DeepEqual(test.out.err, err) {
+ t.Errorf("#%d: bad error: want %v, got %v", i, test.out.err, err)
+ }
+ if !reflect.DeepEqual(test.out.filesystem, filesystem) {
+ t.Errorf("#%d: bad filesystem: want %#v, got %#v", i, test.out.filesystem, filesystem)
+ }
+ }
+}
+
+func TestFilesystemUnmarshalYAML(t *testing.T) {
+ type in struct {
+ data string
+ }
+ type out struct {
+ filesystem Filesystem
+ err error
+ }
+
+ tests := []struct {
+ in in
+ out out
+ }{
+ {
+ in: in{data: "mount:\n device: /foo\n format: ext4"},
+ out: out{filesystem: Filesystem{Mount: &FilesystemMount{Device: "/foo", Format: "ext4"}}},
+ },
+ {
+ in: in{data: "mount:\n format: ext4"},
+ out: out{err: ErrPathRelative},
+ },
+ }
+
+ for i, test := range tests {
+ var filesystem Filesystem
+ err := yaml.Unmarshal([]byte(test.in.data), &filesystem)
+ if !reflect.DeepEqual(test.out.err, err) {
+ t.Errorf("#%d: bad error: want %v, got %v", i, test.out.err, err)
+ }
+ if !reflect.DeepEqual(test.out.filesystem, filesystem) {
+ t.Errorf("#%d: bad filesystem: want %#v, got %#v", i, test.out.filesystem, filesystem)
+ }
+ }
+}
+
+func TestFilesystemAssertValid(t *testing.T) {
+ type in struct {
+ filesystem Filesystem
+ }
+ type out struct {
+ err error
+ }
+
+ tests := []struct {
+ in in
+ out out
+ }{
+ {
+ in: in{filesystem: Filesystem{Mount: &FilesystemMount{Device: "/foo", Format: "ext4"}}},
+ out: out{},
+ },
+ {
+ in: in{filesystem: Filesystem{Mount: &FilesystemMount{Device: "/foo"}}},
+ out: out{err: ErrFilesystemInvalidFormat},
+ },
+ {
+ in: in{filesystem: Filesystem{Mount: &FilesystemMount{Format: "ext4"}}},
+ out: out{err: ErrPathRelative},
+ },
+ {
+ in: in{filesystem: Filesystem{Path: Path("/mount")}},
+ out: out{},
+ },
+ {
+ in: in{filesystem: Filesystem{Path: Path("mount")}},
+ out: out{err: ErrPathRelative},
+ },
+ {
+ in: in{filesystem: Filesystem{Path: Path("/mount"), Mount: &FilesystemMount{Device: "/foo", Format: "ext4"}}},
+ out: out{err: ErrFilesystemMountAndPath},
+ },
+ {
+ in: in{filesystem: Filesystem{}},
+ out: out{err: ErrFilesystemNoMountPath},
+ },
+ }
+
+ for i, test := range tests {
+ err := test.in.filesystem.assertValid()
+ if !reflect.DeepEqual(test.out.err, err) {
+ t.Errorf("#%d: bad error: want %v, got %v", i, test.out.err, err)
+ }
+ }
+}
diff --git a/vendor/github.com/coreos/ignition/src/config/group.go b/vendor/github.com/coreos/ignition/config/types/group.go
similarity index 94%
rename from vendor/github.com/coreos/ignition/src/config/group.go
rename to vendor/github.com/coreos/ignition/config/types/group.go
index d91c4ca9..eb393398 100644
--- a/vendor/github.com/coreos/ignition/src/config/group.go
+++ b/vendor/github.com/coreos/ignition/config/types/group.go
@@ -1,4 +1,4 @@
-// Copyright 2015 CoreOS, Inc.
+// Copyright 2016 CoreOS, Inc.
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
@@ -12,7 +12,7 @@
// See the License for the specific language governing permissions and
// limitations under the License.
-package config
+package types
type Group struct {
Name string `json:"name,omitempty" yaml:"name"`
diff --git a/vendor/github.com/coreos/ignition/config/types/hash.go b/vendor/github.com/coreos/ignition/config/types/hash.go
new file mode 100644
index 00000000..064dfdd9
--- /dev/null
+++ b/vendor/github.com/coreos/ignition/config/types/hash.go
@@ -0,0 +1,81 @@
+// Copyright 2016 CoreOS, Inc.
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+// http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+package types
+
+import (
+ "crypto"
+ "encoding/hex"
+ "encoding/json"
+ "errors"
+ "strings"
+)
+
+var (
+ ErrHashMalformed = errors.New("malformed hash specifier")
+ ErrHashWrongSize = errors.New("incorrect size for hash sum")
+ ErrHashUnrecognized = errors.New("unrecognized hash function")
+)
+
+type Hash struct {
+ Function string
+ Sum string
+}
+
+func (h *Hash) UnmarshalYAML(unmarshal func(interface{}) error) error {
+ return h.unmarshal(unmarshal)
+}
+
+func (h *Hash) UnmarshalJSON(data []byte) error {
+ return h.unmarshal(func(th interface{}) error {
+ return json.Unmarshal(data, th)
+ })
+}
+
+func (h Hash) MarshalJSON() ([]byte, error) {
+ return []byte(`"` + h.Function + "-" + h.Sum + `"`), nil
+}
+
+func (h *Hash) unmarshal(unmarshal func(interface{}) error) error {
+ var th string
+ if err := unmarshal(&th); err != nil {
+ return err
+ }
+
+ parts := strings.SplitN(th, "-", 2)
+ if len(parts) != 2 {
+ return ErrHashMalformed
+ }
+
+ h.Function = parts[0]
+ h.Sum = parts[1]
+
+ return h.assertValid()
+}
+
+func (h Hash) assertValid() error {
+ var hash crypto.Hash
+ switch h.Function {
+ case "sha512":
+ hash = crypto.SHA512
+ default:
+ return ErrHashUnrecognized
+ }
+
+ if len(h.Sum) != hex.EncodedLen(hash.Size()) {
+ return ErrHashWrongSize
+ }
+
+ return nil
+}
diff --git a/vendor/github.com/coreos/ignition/config/types/hash_test.go b/vendor/github.com/coreos/ignition/config/types/hash_test.go
new file mode 100644
index 00000000..ceebf024
--- /dev/null
+++ b/vendor/github.com/coreos/ignition/config/types/hash_test.go
@@ -0,0 +1,131 @@
+// Copyright 2016 CoreOS, Inc.
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+// http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+package types
+
+import (
+ "encoding/json"
+ "reflect"
+ "testing"
+
+ "github.com/go-yaml/yaml"
+)
+
+func TestHashUnmarshalJSON(t *testing.T) {
+ type in struct {
+ data string
+ }
+ type out struct {
+ hash Hash
+ err error
+ }
+
+ tests := []struct {
+ in in
+ out out
+ }{
+ {
+ in: in{data: `"sha512-0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef"`},
+ out: out{hash: Hash{Function: "sha512", Sum: "0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef"}},
+ },
+ {
+ in: in{data: `"xor01234567"`},
+ out: out{err: ErrHashMalformed},
+ },
+ }
+
+ for i, test := range tests {
+ var hash Hash
+ err := json.Unmarshal([]byte(test.in.data), &hash)
+ if !reflect.DeepEqual(test.out.err, err) {
+ t.Errorf("#%d: bad error: want %v, got %v", i, test.out.err, err)
+ }
+ if !reflect.DeepEqual(test.out.hash, hash) {
+ t.Errorf("#%d: bad hash: want %+v, got %+v", i, test.out.hash, hash)
+ }
+ }
+}
+
+func TestHashUnmarshalYAML(t *testing.T) {
+ type in struct {
+ data string
+ }
+ type out struct {
+ hash Hash
+ err error
+ }
+
+ tests := []struct {
+ in in
+ out out
+ }{
+ {
+ in: in{data: `sha512-0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef`},
+ out: out{hash: Hash{Function: "sha512", Sum: "0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef"}},
+ },
+ {
+ in: in{data: `xor01234567`},
+ out: out{err: ErrHashMalformed},
+ },
+ }
+
+ for i, test := range tests {
+ var hash Hash
+ err := yaml.Unmarshal([]byte(test.in.data), &hash)
+ if !reflect.DeepEqual(test.out.err, err) {
+ t.Errorf("#%d: bad error: want %v, got %v", i, test.out.err, err)
+ }
+ if !reflect.DeepEqual(test.out.hash, hash) {
+ t.Errorf("#%d: bad hash: want %+v, got %+v", i, test.out.hash, hash)
+ }
+ }
+}
+
+func TestHashAssertValid(t *testing.T) {
+ type in struct {
+ hash Hash
+ }
+ type out struct {
+ err error
+ }
+
+ tests := []struct {
+ in in
+ out out
+ }{
+ {
+ in: in{hash: Hash{}},
+ out: out{err: ErrHashUnrecognized},
+ },
+ {
+ in: in{hash: Hash{Function: "xor"}},
+ out: out{err: ErrHashUnrecognized},
+ },
+ {
+ in: in{hash: Hash{Function: "sha512", Sum: "123"}},
+ out: out{err: ErrHashWrongSize},
+ },
+ {
+ in: in{hash: Hash{Function: "sha512", Sum: "0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef"}},
+ out: out{},
+ },
+ }
+
+ for i, test := range tests {
+ err := test.in.hash.assertValid()
+ if !reflect.DeepEqual(test.out.err, err) {
+ t.Errorf("#%d: bad error: want %v, got %v", i, test.out.err, err)
+ }
+ }
+}
diff --git a/vendor/github.com/coreos/ignition/config/types/ignition.go b/vendor/github.com/coreos/ignition/config/types/ignition.go
new file mode 100644
index 00000000..9d5f9f96
--- /dev/null
+++ b/vendor/github.com/coreos/ignition/config/types/ignition.go
@@ -0,0 +1,77 @@
+// Copyright 2015 CoreOS, Inc.
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+// http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+package types
+
+import (
+ "encoding/json"
+ "errors"
+
+ "github.com/coreos/go-semver/semver"
+)
+
+var (
+ ErrOldVersion = errors.New("incorrect config version (too old)")
+ ErrNewVersion = errors.New("incorrect config version (too new)")
+)
+
+type Ignition struct {
+ Version IgnitionVersion `json:"version,omitempty" yaml:"version" merge:"old"`
+ Config IgnitionConfig `json:"config,omitempty" yaml:"config" merge:"new"`
+}
+
+type IgnitionConfig struct {
+ Append []ConfigReference `json:"append,omitempty" yaml:"append"`
+ Replace *ConfigReference `json:"replace,omitempty" yaml:"replace"`
+}
+
+type ConfigReference struct {
+ Source Url `json:"source,omitempty" yaml:"source"`
+ Verification Verification `json:"verification,omitempty" yaml:"verification"`
+}
+
+type IgnitionVersion semver.Version
+
+func (v *IgnitionVersion) UnmarshalYAML(unmarshal func(interface{}) error) error {
+ return v.unmarshal(unmarshal)
+}
+
+func (v *IgnitionVersion) UnmarshalJSON(data []byte) error {
+ return v.unmarshal(func(tv interface{}) error {
+ return json.Unmarshal(data, tv)
+ })
+}
+
+func (v IgnitionVersion) MarshalJSON() ([]byte, error) {
+ return semver.Version(v).MarshalJSON()
+}
+
+func (v *IgnitionVersion) unmarshal(unmarshal func(interface{}) error) error {
+ tv := semver.Version(*v)
+ if err := unmarshal(&tv); err != nil {
+ return err
+ }
+ *v = IgnitionVersion(tv)
+ return nil
+}
+
+func (v IgnitionVersion) AssertValid() error {
+ if MaxVersion.Major > v.Major {
+ return ErrOldVersion
+ }
+ if MaxVersion.LessThan(semver.Version(v)) {
+ return ErrNewVersion
+ }
+ return nil
+}
diff --git a/vendor/github.com/coreos/ignition/src/config/networkd.go b/vendor/github.com/coreos/ignition/config/types/networkd.go
similarity index 93%
rename from vendor/github.com/coreos/ignition/src/config/networkd.go
rename to vendor/github.com/coreos/ignition/config/types/networkd.go
index b17b3179..2dbbdc3d 100644
--- a/vendor/github.com/coreos/ignition/src/config/networkd.go
+++ b/vendor/github.com/coreos/ignition/config/types/networkd.go
@@ -1,4 +1,4 @@
-// Copyright 2015 CoreOS, Inc.
+// Copyright 2016 CoreOS, Inc.
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
@@ -12,7 +12,7 @@
// See the License for the specific language governing permissions and
// limitations under the License.
-package config
+package types
type Networkd struct {
Units []NetworkdUnit `json:"units,omitempty" yaml:"units"`
diff --git a/vendor/github.com/coreos/ignition/src/config/partition.go b/vendor/github.com/coreos/ignition/config/types/partition.go
similarity index 97%
rename from vendor/github.com/coreos/ignition/src/config/partition.go
rename to vendor/github.com/coreos/ignition/config/types/partition.go
index e1a935ee..228ece4d 100644
--- a/vendor/github.com/coreos/ignition/src/config/partition.go
+++ b/vendor/github.com/coreos/ignition/config/types/partition.go
@@ -1,4 +1,4 @@
-// Copyright 2015 CoreOS, Inc.
+// Copyright 2016 CoreOS, Inc.
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
@@ -12,14 +12,14 @@
// See the License for the specific language governing permissions and
// limitations under the License.
-package config
+package types
import (
"encoding/json"
"fmt"
"regexp"
- "github.com/coreos/ignition/third_party/github.com/alecthomas/units"
+ "github.com/alecthomas/units"
)
type Partition struct {
diff --git a/vendor/github.com/coreos/ignition/src/config/passwd.go b/vendor/github.com/coreos/ignition/config/types/passwd.go
similarity index 93%
rename from vendor/github.com/coreos/ignition/src/config/passwd.go
rename to vendor/github.com/coreos/ignition/config/types/passwd.go
index 7633aa34..f1436874 100644
--- a/vendor/github.com/coreos/ignition/src/config/passwd.go
+++ b/vendor/github.com/coreos/ignition/config/types/passwd.go
@@ -1,4 +1,4 @@
-// Copyright 2015 CoreOS, Inc.
+// Copyright 2016 CoreOS, Inc.
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
@@ -12,7 +12,7 @@
// See the License for the specific language governing permissions and
// limitations under the License.
-package config
+package types
type Passwd struct {
Users []User `json:"users,omitempty" yaml:"users"`
diff --git a/vendor/github.com/coreos/ignition/config/types/path.go b/vendor/github.com/coreos/ignition/config/types/path.go
new file mode 100644
index 00000000..eb8e3c2c
--- /dev/null
+++ b/vendor/github.com/coreos/ignition/config/types/path.go
@@ -0,0 +1,59 @@
+// Copyright 2016 CoreOS, Inc.
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+// http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+package types
+
+import (
+ "encoding/json"
+ "errors"
+ "path/filepath"
+)
+
+var (
+ ErrPathRelative = errors.New("path not absolute")
+)
+
+type Path string
+
+func (p *Path) UnmarshalYAML(unmarshal func(interface{}) error) error {
+ return p.unmarshal(unmarshal)
+}
+
+func (p *Path) UnmarshalJSON(data []byte) error {
+ return p.unmarshal(func(td interface{}) error {
+ return json.Unmarshal(data, td)
+ })
+}
+
+func (p Path) MarshalJSON() ([]byte, error) {
+ return []byte(`"` + string(p) + `"`), nil
+}
+
+type path Path
+
+func (p *Path) unmarshal(unmarshal func(interface{}) error) error {
+ td := path(*p)
+ if err := unmarshal(&td); err != nil {
+ return err
+ }
+ *p = Path(td)
+ return p.assertValid()
+}
+
+func (p Path) assertValid() error {
+ if !filepath.IsAbs(string(p)) {
+ return ErrPathRelative
+ }
+ return nil
+}
diff --git a/vendor/github.com/coreos/ignition/config/types/path_test.go b/vendor/github.com/coreos/ignition/config/types/path_test.go
new file mode 100644
index 00000000..bdf0708f
--- /dev/null
+++ b/vendor/github.com/coreos/ignition/config/types/path_test.go
@@ -0,0 +1,135 @@
+// Copyright 2016 CoreOS, Inc.
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+// http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+package types
+
+import (
+ "encoding/json"
+ "reflect"
+ "testing"
+
+ "github.com/go-yaml/yaml"
+)
+
+func TestPathUnmarshalJSON(t *testing.T) {
+ type in struct {
+ data string
+ }
+ type out struct {
+ device Path
+ err error
+ }
+
+ tests := []struct {
+ in in
+ out out
+ }{
+ {
+ in: in{data: `"/path"`},
+ out: out{device: Path("/path")},
+ },
+ {
+ in: in{data: `"bad"`},
+ out: out{device: Path("bad"), err: ErrPathRelative},
+ },
+ }
+
+ for i, test := range tests {
+ var device Path
+ err := json.Unmarshal([]byte(test.in.data), &device)
+ if !reflect.DeepEqual(test.out.err, err) {
+ t.Errorf("#%d: bad error: want %v, got %v", i, test.out.err, err)
+ }
+ if !reflect.DeepEqual(test.out.device, device) {
+ t.Errorf("#%d: bad device: want %#v, got %#v", i, test.out.device, device)
+ }
+ }
+}
+
+func TestPathUnmarshalYAML(t *testing.T) {
+ type in struct {
+ data string
+ }
+ type out struct {
+ device Path
+ err error
+ }
+
+ tests := []struct {
+ in in
+ out out
+ }{
+ {
+ in: in{data: `"/path"`},
+ out: out{device: Path("/path")},
+ },
+ {
+ in: in{data: `"bad"`},
+ out: out{device: Path("bad"), err: ErrPathRelative},
+ },
+ }
+
+ for i, test := range tests {
+ var device Path
+ err := yaml.Unmarshal([]byte(test.in.data), &device)
+ if !reflect.DeepEqual(test.out.err, err) {
+ t.Errorf("#%d: bad error: want %v, got %v", i, test.out.err, err)
+ }
+ if !reflect.DeepEqual(test.out.device, device) {
+ t.Errorf("#%d: bad device: want %#v, got %#v", i, test.out.device, device)
+ }
+ }
+}
+
+func TestPathAssertValid(t *testing.T) {
+ type in struct {
+ device Path
+ }
+ type out struct {
+ err error
+ }
+
+ tests := []struct {
+ in in
+ out out
+ }{
+ {
+ in: in{device: Path("/good/path")},
+ out: out{},
+ },
+ {
+ in: in{device: Path("/name")},
+ out: out{},
+ },
+ {
+ in: in{device: Path("/this/is/a/fairly/long/path/to/a/device.")},
+ out: out{},
+ },
+ {
+ in: in{device: Path("/this one has spaces")},
+ out: out{},
+ },
+ {
+ in: in{device: Path("relative/path")},
+ out: out{err: ErrPathRelative},
+ },
+ }
+
+ for i, test := range tests {
+ err := test.in.device.assertValid()
+ if !reflect.DeepEqual(test.out.err, err) {
+ t.Errorf("#%d: bad error: want %v, got %v", i, test.out.err, err)
+ }
+ }
+}
diff --git a/vendor/github.com/coreos/ignition/src/config/raid.go b/vendor/github.com/coreos/ignition/config/types/raid.go
similarity index 83%
rename from vendor/github.com/coreos/ignition/src/config/raid.go
rename to vendor/github.com/coreos/ignition/config/types/raid.go
index 96fe2cf7..62fe65ef 100644
--- a/vendor/github.com/coreos/ignition/src/config/raid.go
+++ b/vendor/github.com/coreos/ignition/config/types/raid.go
@@ -1,4 +1,4 @@
-// Copyright 2015 CoreOS, Inc.
+// Copyright 2016 CoreOS, Inc.
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
@@ -12,7 +12,7 @@
// See the License for the specific language governing permissions and
// limitations under the License.
-package config
+package types
import (
"encoding/json"
@@ -20,10 +20,10 @@ import (
)
type Raid struct {
- Name string `json:"name" yaml:"name"`
- Level string `json:"level" yaml:"level"`
- Devices []DevicePath `json:"devices,omitempty" yaml:"devices"`
- Spares int `json:"spares,omitempty" yaml:"spares"`
+ Name string `json:"name" yaml:"name"`
+ Level string `json:"level" yaml:"level"`
+ Devices []Path `json:"devices,omitempty" yaml:"devices"`
+ Spares int `json:"spares,omitempty" yaml:"spares"`
}
func (n *Raid) UnmarshalYAML(unmarshal func(interface{}) error) error {
diff --git a/vendor/github.com/coreos/ignition/config/types/storage.go b/vendor/github.com/coreos/ignition/config/types/storage.go
new file mode 100644
index 00000000..75bff070
--- /dev/null
+++ b/vendor/github.com/coreos/ignition/config/types/storage.go
@@ -0,0 +1,22 @@
+// Copyright 2016 CoreOS, Inc.
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+// http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+package types
+
+type Storage struct {
+ Disks []Disk `json:"disks,omitempty" yaml:"disks"`
+ Arrays []Raid `json:"raid,omitempty" yaml:"raid"`
+ Filesystems []Filesystem `json:"filesystems,omitempty" yaml:"filesystems"`
+ Files []File `json:"files,omitempty" yaml:"files"`
+}
diff --git a/vendor/github.com/coreos/ignition/src/config/systemd.go b/vendor/github.com/coreos/ignition/config/types/systemd.go
similarity index 93%
rename from vendor/github.com/coreos/ignition/src/config/systemd.go
rename to vendor/github.com/coreos/ignition/config/types/systemd.go
index f18c0397..ec764850 100644
--- a/vendor/github.com/coreos/ignition/src/config/systemd.go
+++ b/vendor/github.com/coreos/ignition/config/types/systemd.go
@@ -1,4 +1,4 @@
-// Copyright 2015 CoreOS, Inc.
+// Copyright 2016 CoreOS, Inc.
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
@@ -12,7 +12,7 @@
// See the License for the specific language governing permissions and
// limitations under the License.
-package config
+package types
type Systemd struct {
Units []SystemdUnit `json:"units,omitempty" yaml:"units"`
diff --git a/vendor/github.com/coreos/ignition/src/config/unit.go b/vendor/github.com/coreos/ignition/config/types/unit.go
similarity index 98%
rename from vendor/github.com/coreos/ignition/src/config/unit.go
rename to vendor/github.com/coreos/ignition/config/types/unit.go
index c1b94b10..3fd6a194 100644
--- a/vendor/github.com/coreos/ignition/src/config/unit.go
+++ b/vendor/github.com/coreos/ignition/config/types/unit.go
@@ -1,4 +1,4 @@
-// Copyright 2015 CoreOS, Inc.
+// Copyright 2016 CoreOS, Inc.
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
@@ -12,7 +12,7 @@
// See the License for the specific language governing permissions and
// limitations under the License.
-package config
+package types
import (
"encoding/json"
diff --git a/vendor/github.com/coreos/ignition/src/config/unit_test.go b/vendor/github.com/coreos/ignition/config/types/unit_test.go
similarity index 97%
rename from vendor/github.com/coreos/ignition/src/config/unit_test.go
rename to vendor/github.com/coreos/ignition/config/types/unit_test.go
index c4260bd5..0ee8d33c 100644
--- a/vendor/github.com/coreos/ignition/src/config/unit_test.go
+++ b/vendor/github.com/coreos/ignition/config/types/unit_test.go
@@ -1,4 +1,4 @@
-// Copyright 2015 CoreOS, Inc.
+// Copyright 2016 CoreOS, Inc.
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
@@ -12,7 +12,7 @@
// See the License for the specific language governing permissions and
// limitations under the License.
-package config
+package types
import (
"encoding/json"
@@ -20,7 +20,7 @@ import (
"reflect"
"testing"
- "github.com/coreos/ignition/third_party/github.com/go-yaml/yaml"
+ "github.com/go-yaml/yaml"
)
func TestSystemdUnitNameUnmarshalJSON(t *testing.T) {
diff --git a/vendor/github.com/coreos/ignition/config/types/url.go b/vendor/github.com/coreos/ignition/config/types/url.go
new file mode 100644
index 00000000..83d03385
--- /dev/null
+++ b/vendor/github.com/coreos/ignition/config/types/url.go
@@ -0,0 +1,52 @@
+// Copyright 2016 CoreOS, Inc.
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+// http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+package types
+
+import (
+ "encoding/json"
+ "net/url"
+)
+
+type Url url.URL
+
+func (u *Url) UnmarshalYAML(unmarshal func(interface{}) error) error {
+ return u.unmarshal(unmarshal)
+}
+
+func (u *Url) UnmarshalJSON(data []byte) error {
+ return u.unmarshal(func(tu interface{}) error {
+ return json.Unmarshal(data, tu)
+ })
+}
+
+func (u Url) MarshalJSON() ([]byte, error) {
+ return []byte(`"` + u.String() + `"`), nil
+}
+
+func (u *Url) unmarshal(unmarshal func(interface{}) error) error {
+ var tu string
+ if err := unmarshal(&tu); err != nil {
+ return err
+ }
+
+ pu, err := url.Parse(tu)
+ *u = Url(*pu)
+ return err
+}
+
+func (u Url) String() string {
+ tu := url.URL(u)
+ return (&tu).String()
+}
diff --git a/vendor/github.com/coreos/ignition/src/config/user.go b/vendor/github.com/coreos/ignition/config/types/user.go
similarity index 97%
rename from vendor/github.com/coreos/ignition/src/config/user.go
rename to vendor/github.com/coreos/ignition/config/types/user.go
index 2e73d78c..80c3336c 100644
--- a/vendor/github.com/coreos/ignition/src/config/user.go
+++ b/vendor/github.com/coreos/ignition/config/types/user.go
@@ -1,4 +1,4 @@
-// Copyright 2015 CoreOS, Inc.
+// Copyright 2016 CoreOS, Inc.
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
@@ -12,7 +12,7 @@
// See the License for the specific language governing permissions and
// limitations under the License.
-package config
+package types
type User struct {
Name string `json:"name,omitempty" yaml:"name"`
diff --git a/vendor/github.com/coreos/ignition/config/types/verification.go b/vendor/github.com/coreos/ignition/config/types/verification.go
new file mode 100644
index 00000000..f6093d61
--- /dev/null
+++ b/vendor/github.com/coreos/ignition/config/types/verification.go
@@ -0,0 +1,19 @@
+// Copyright 2016 CoreOS, Inc.
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+// http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+package types
+
+type Verification struct {
+ Hash *Hash `json:"hash,omitempty" yaml:"hash"`
+}
diff --git a/vendor/github.com/coreos/ignition/config/v1/cloudinit.go b/vendor/github.com/coreos/ignition/config/v1/cloudinit.go
new file mode 100644
index 00000000..7cfeb455
--- /dev/null
+++ b/vendor/github.com/coreos/ignition/config/v1/cloudinit.go
@@ -0,0 +1,53 @@
+// Copyright 2015 CoreOS, Inc.
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+// http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+// These functions are copied from github.com/coreos/coreos-cloudinit/config.
+
+package v1
+
+import (
+ "bytes"
+ "compress/gzip"
+ "io/ioutil"
+ "strings"
+ "unicode"
+)
+
+func isCloudConfig(userdata []byte) bool {
+ header := strings.SplitN(string(decompressIfGzipped(userdata)), "\n", 2)[0]
+
+ // Trim trailing whitespaces
+ header = strings.TrimRightFunc(header, unicode.IsSpace)
+
+ return (header == "#cloud-config")
+}
+
+func isScript(userdata []byte) bool {
+ header := strings.SplitN(string(decompressIfGzipped(userdata)), "\n", 2)[0]
+ return strings.HasPrefix(header, "#!")
+}
+
+func decompressIfGzipped(data []byte) []byte {
+ if reader, err := gzip.NewReader(bytes.NewReader(data)); err == nil {
+ uncompressedData, err := ioutil.ReadAll(reader)
+ reader.Close()
+ if err == nil {
+ return uncompressedData
+ } else {
+ return data
+ }
+ } else {
+ return data
+ }
+}
diff --git a/vendor/github.com/coreos/ignition/src/config/config.go b/vendor/github.com/coreos/ignition/config/v1/config.go
similarity index 53%
rename from vendor/github.com/coreos/ignition/src/config/config.go
rename to vendor/github.com/coreos/ignition/config/v1/config.go
index d3a8a8e1..8e2b1065 100644
--- a/vendor/github.com/coreos/ignition/src/config/config.go
+++ b/vendor/github.com/coreos/ignition/config/v1/config.go
@@ -12,52 +12,40 @@
// See the License for the specific language governing permissions and
// limitations under the License.
-package config
+package v1
import (
"bytes"
- "compress/gzip"
"encoding/json"
"errors"
"fmt"
- "io/ioutil"
- "github.com/coreos/ignition/third_party/github.com/camlistore/camlistore/pkg/errorutil"
-)
+ "github.com/coreos/ignition/config/v1/types"
-type Config struct {
- Version int `json:"ignitionVersion" yaml:"ignition_version"`
- Storage Storage `json:"storage,omitempty" yaml:"storage"`
- Systemd Systemd `json:"systemd,omitempty" yaml:"systemd"`
- Networkd Networkd `json:"networkd,omitempty" yaml:"networkd"`
- Passwd Passwd `json:"passwd,omitempty" yaml:"passwd"`
-}
-
-const (
- Version = 1
+ "github.com/camlistore/camlistore/pkg/errorutil"
)
var (
ErrVersion = errors.New("incorrect config version")
ErrCloudConfig = errors.New("not a config (found coreos-cloudconfig)")
- ErrScript = errors.New("not a config (found coreos-cloudinit script)")
ErrEmpty = errors.New("not a config (empty)")
+ ErrScript = errors.New("not a config (found coreos-cloudinit script)")
)
-func Parse(config []byte) (cfg Config, err error) {
- if err = json.Unmarshal(config, &cfg); err == nil {
- if cfg.Version != Version {
+func Parse(rawConfig []byte) (config types.Config, err error) {
+ if err = json.Unmarshal(rawConfig, &config); err == nil {
+ if config.Version != types.Version {
err = ErrVersion
}
- } else if isCloudConfig(decompressIfGzipped(config)) {
- err = ErrCloudConfig
- } else if isScript(decompressIfGzipped(config)) {
- err = ErrScript
- } else if isEmpty(config) {
+ } else if isEmpty(rawConfig) {
err = ErrEmpty
+ } else if isCloudConfig(rawConfig) {
+ err = ErrCloudConfig
+ } else if isScript(rawConfig) {
+ err = ErrScript
}
if serr, ok := err.(*json.SyntaxError); ok {
- line, col, highlight := errorutil.HighlightBytePosition(bytes.NewReader(config), serr.Offset)
+ line, col, highlight := errorutil.HighlightBytePosition(bytes.NewReader(rawConfig), serr.Offset)
err = fmt.Errorf("error at line %d, column %d\n%s%v", line, col, highlight, err)
}
@@ -67,17 +55,3 @@ func Parse(config []byte) (cfg Config, err error) {
func isEmpty(userdata []byte) bool {
return len(userdata) == 0
}
-
-func decompressIfGzipped(data []byte) []byte {
- if reader, err := gzip.NewReader(bytes.NewReader(data)); err == nil {
- uncompressedData, err := ioutil.ReadAll(reader)
- reader.Close()
- if err == nil {
- return uncompressedData
- } else {
- return data
- }
- } else {
- return data
- }
-}
diff --git a/vendor/github.com/coreos/ignition/src/config/config_test.go b/vendor/github.com/coreos/ignition/config/v1/config_test.go
similarity index 94%
rename from vendor/github.com/coreos/ignition/src/config/config_test.go
rename to vendor/github.com/coreos/ignition/config/v1/config_test.go
index c0bf650b..15ec10bb 100644
--- a/vendor/github.com/coreos/ignition/src/config/config_test.go
+++ b/vendor/github.com/coreos/ignition/config/v1/config_test.go
@@ -12,11 +12,13 @@
// See the License for the specific language governing permissions and
// limitations under the License.
-package config
+package v1
import (
"reflect"
"testing"
+
+ "github.com/coreos/ignition/config/v1/types"
)
func TestParse(t *testing.T) {
@@ -24,7 +26,7 @@ func TestParse(t *testing.T) {
config []byte
}
type out struct {
- config Config
+ config types.Config
err error
}
@@ -34,7 +36,7 @@ func TestParse(t *testing.T) {
}{
{
in: in{config: []byte(`{"ignitionVersion": 1}`)},
- out: out{config: Config{Version: 1}},
+ out: out{config: types.Config{Version: 1}},
},
{
in: in{config: []byte(`{}`)},
diff --git a/vendor/github.com/coreos/ignition/config/v1/types/config.go b/vendor/github.com/coreos/ignition/config/v1/types/config.go
new file mode 100644
index 00000000..9f50dedb
--- /dev/null
+++ b/vendor/github.com/coreos/ignition/config/v1/types/config.go
@@ -0,0 +1,27 @@
+// Copyright 2016 CoreOS, Inc.
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+// http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+package types
+
+const (
+ Version = 1
+)
+
+type Config struct {
+ Version int `json:"ignitionVersion" yaml:"ignition_version"`
+ Storage Storage `json:"storage,omitempty" yaml:"storage"`
+ Systemd Systemd `json:"systemd,omitempty" yaml:"systemd"`
+ Networkd Networkd `json:"networkd,omitempty" yaml:"networkd"`
+ Passwd Passwd `json:"passwd,omitempty" yaml:"passwd"`
+}
diff --git a/vendor/github.com/coreos/ignition/config/v1/types/disk.go b/vendor/github.com/coreos/ignition/config/v1/types/disk.go
new file mode 100644
index 00000000..e0f39483
--- /dev/null
+++ b/vendor/github.com/coreos/ignition/config/v1/types/disk.go
@@ -0,0 +1,167 @@
+// Copyright 2016 CoreOS, Inc.
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+// http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+package types
+
+import (
+ "encoding/json"
+ "fmt"
+)
+
+type Disk struct {
+ Device Path `json:"device,omitempty" yaml:"device"`
+ WipeTable bool `json:"wipeTable,omitempty" yaml:"wipe_table"`
+ Partitions []Partition `json:"partitions,omitempty" yaml:"partitions"`
+}
+
+func (n *Disk) UnmarshalYAML(unmarshal func(interface{}) error) error {
+ if err := n.unmarshal(unmarshal); err != nil {
+ return err
+ }
+ if err := n.preparePartitions(); err != nil {
+ return err
+ }
+ return n.assertValid()
+}
+
+func (n *Disk) UnmarshalJSON(data []byte) error {
+ err := n.unmarshal(func(tn interface{}) error {
+ return json.Unmarshal(data, tn)
+ })
+ if err != nil {
+ return err
+ }
+ return n.assertValid()
+}
+
+type disk Disk
+
+func (n *Disk) unmarshal(unmarshal func(interface{}) error) error {
+ tn := disk(*n)
+ if err := unmarshal(&tn); err != nil {
+ return err
+ }
+ *n = Disk(tn)
+ return nil
+}
+
+func (n Disk) assertValid() error {
+ // This applies to YAML (post-prepare) and JSON unmarshals equally:
+ if len(n.Device) == 0 {
+ return fmt.Errorf("disk device is required")
+ }
+ if n.partitionNumbersCollide() {
+ return fmt.Errorf("disk %q: partition numbers collide", n.Device)
+ }
+ if n.partitionsOverlap() {
+ return fmt.Errorf("disk %q: partitions overlap", n.Device)
+ }
+ if n.partitionsMisaligned() {
+ return fmt.Errorf("disk %q: partitions misaligned", n.Device)
+ }
+ // Disks which get to this point will likely succeed in sgdisk
+ return nil
+}
+
+// partitionNumbersCollide returns true if partition numbers in n.Partitions are not unique.
+func (n Disk) partitionNumbersCollide() bool {
+ m := map[int][]Partition{}
+ for _, p := range n.Partitions {
+ m[p.Number] = append(m[p.Number], p)
+ }
+ for _, n := range m {
+ if len(n) > 1 {
+ // TODO(vc): return information describing the collision for logging
+ return true
+ }
+ }
+ return false
+}
+
+// end returns the last sector of a partition.
+func (p Partition) end() PartitionDimension {
+ if p.Size == 0 {
+ // a size of 0 means "fill available", just return the start as the end for those.
+ return p.Start
+ }
+ return p.Start + p.Size - 1
+}
+
+// partitionsOverlap returns true if any explicitly dimensioned partitions overlap
+func (n Disk) partitionsOverlap() bool {
+ for _, p := range n.Partitions {
+ // Starts of 0 are placed by sgdisk into the "largest available block" at that time.
+ // We aren't going to check those for overlap since we don't have the disk geometry.
+ if p.Start == 0 {
+ continue
+ }
+
+ for _, o := range n.Partitions {
+ if p == o || o.Start == 0 {
+ continue
+ }
+
+ // is p.Start within o?
+ if p.Start >= o.Start && p.Start <= o.end() {
+ return true
+ }
+
+ // is p.end() within o?
+ if p.end() >= o.Start && p.end() <= o.end() {
+ return true
+ }
+
+ // do p.Start and p.end() straddle o?
+ if p.Start < o.Start && p.end() > o.end() {
+ return true
+ }
+ }
+ }
+ return false
+}
+
+// partitionsMisaligned returns true if any of the partitions don't start on a 2048-sector (1MiB) boundary.
+func (n Disk) partitionsMisaligned() bool {
+ for _, p := range n.Partitions {
+ if (p.Start & (2048 - 1)) != 0 {
+ return true
+ }
+ }
+ return false
+}
+
+// preparePartitions performs some checks and potentially adjusts the partitions for alignment.
+// This is only invoked when unmarshalling YAML, since there we parse human-friendly units.
+func (n *Disk) preparePartitions() error {
+ // On the YAML side we accept human-friendly units which may require massaging.
+
+ // align partition starts
+ for i := range n.Partitions {
+ // skip automatically placed partitions
+ if n.Partitions[i].Start == 0 {
+ continue
+ }
+
+ // keep partitions out of the first 2048 sectors
+ if n.Partitions[i].Start < 2048 {
+ n.Partitions[i].Start = 2048
+ }
+
+ // toss the bottom 11 bits
+ n.Partitions[i].Start &= ^PartitionDimension(2048 - 1)
+ }
+
+ // TODO(vc): may be interesting to do something about potentially overlapping partitions
+ return nil
+}
diff --git a/vendor/github.com/coreos/ignition/src/config/file.go b/vendor/github.com/coreos/ignition/config/v1/types/file.go
similarity index 93%
rename from vendor/github.com/coreos/ignition/src/config/file.go
rename to vendor/github.com/coreos/ignition/config/v1/types/file.go
index 8d785e29..d99c2a94 100644
--- a/vendor/github.com/coreos/ignition/src/config/file.go
+++ b/vendor/github.com/coreos/ignition/config/v1/types/file.go
@@ -1,4 +1,4 @@
-// Copyright 2015 CoreOS, Inc.
+// Copyright 2016 CoreOS, Inc.
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
@@ -12,7 +12,7 @@
// See the License for the specific language governing permissions and
// limitations under the License.
-package config
+package types
import (
"encoding/json"
@@ -27,7 +27,7 @@ var (
type FileMode os.FileMode
type File struct {
- Path string `json:"path,omitempty" yaml:"path"`
+ Path Path `json:"path,omitempty" yaml:"path"`
Contents string `json:"contents,omitempty" yaml:"contents"`
Mode FileMode `json:"mode,omitempty" yaml:"mode"`
Uid int `json:"uid,omitempty" yaml:"uid"`
diff --git a/vendor/github.com/coreos/ignition/config/v1/types/file_test.go b/vendor/github.com/coreos/ignition/config/v1/types/file_test.go
new file mode 100644
index 00000000..8b56f003
--- /dev/null
+++ b/vendor/github.com/coreos/ignition/config/v1/types/file_test.go
@@ -0,0 +1,139 @@
+// Copyright 2016 CoreOS, Inc.
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+// http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+package types
+
+import (
+ "encoding/json"
+ "reflect"
+ "testing"
+
+ "github.com/go-yaml/yaml"
+)
+
+func TestFileModeUnmarshalJSON(t *testing.T) {
+ type in struct {
+ data string
+ }
+ type out struct {
+ mode FileMode
+ err error
+ }
+
+ tests := []struct {
+ in in
+ out out
+ }{
+ {
+ in: in{data: `420`},
+ out: out{mode: FileMode(420)},
+ },
+ {
+ in: in{data: `9999`},
+ out: out{mode: FileMode(9999), err: ErrFileIllegalMode},
+ },
+ }
+
+ for i, test := range tests {
+ var mode FileMode
+ err := json.Unmarshal([]byte(test.in.data), &mode)
+ if !reflect.DeepEqual(test.out.err, err) {
+ t.Errorf("#%d: bad error: want %v, got %v", i, test.out.err, err)
+ }
+ if !reflect.DeepEqual(test.out.mode, mode) {
+ t.Errorf("#%d: bad mode: want %#o, got %#o", i, test.out.mode, mode)
+ }
+ }
+}
+
+func TestFileModeUnmarshalYAML(t *testing.T) {
+ type in struct {
+ data string
+ }
+ type out struct {
+ mode FileMode
+ err error
+ }
+
+ tests := []struct {
+ in in
+ out out
+ }{
+ {
+ in: in{data: `0644`},
+ out: out{mode: FileMode(0644)},
+ },
+ {
+ in: in{data: `0420`},
+ out: out{mode: FileMode(0420)},
+ },
+ {
+ in: in{data: `017777`},
+ out: out{mode: FileMode(017777), err: ErrFileIllegalMode},
+ },
+ }
+
+ for i, test := range tests {
+ var mode FileMode
+ err := yaml.Unmarshal([]byte(test.in.data), &mode)
+ if !reflect.DeepEqual(test.out.err, err) {
+ t.Errorf("#%d: bad error: want %v, got %v", i, test.out.err, err)
+ }
+ if !reflect.DeepEqual(test.out.mode, mode) {
+ t.Errorf("#%d: bad mode: want %#o, got %#o", i, test.out.mode, mode)
+ }
+ }
+}
+
+func TestFileAssertValid(t *testing.T) {
+ type in struct {
+ mode FileMode
+ }
+ type out struct {
+ err error
+ }
+
+ tests := []struct {
+ in in
+ out out
+ }{
+ {
+ in: in{mode: FileMode(0)},
+ out: out{},
+ },
+ {
+ in: in{mode: FileMode(0644)},
+ out: out{},
+ },
+ {
+ in: in{mode: FileMode(01755)},
+ out: out{},
+ },
+ {
+ in: in{mode: FileMode(07777)},
+ out: out{},
+ },
+ {
+ in: in{mode: FileMode(010000)},
+ out: out{err: ErrFileIllegalMode},
+ },
+ }
+
+ for i, test := range tests {
+ err := test.in.mode.assertValid()
+ if !reflect.DeepEqual(test.out.err, err) {
+ t.Errorf("#%d: bad error: want %v, got %v", i, test.out.err, err)
+ }
+ }
+}
diff --git a/vendor/github.com/coreos/ignition/src/config/filesystem.go b/vendor/github.com/coreos/ignition/config/v1/types/filesystem.go
similarity index 94%
rename from vendor/github.com/coreos/ignition/src/config/filesystem.go
rename to vendor/github.com/coreos/ignition/config/v1/types/filesystem.go
index 163339b7..3fc707fd 100644
--- a/vendor/github.com/coreos/ignition/src/config/filesystem.go
+++ b/vendor/github.com/coreos/ignition/config/v1/types/filesystem.go
@@ -1,4 +1,4 @@
-// Copyright 2015 CoreOS, Inc.
+// Copyright 2016 CoreOS, Inc.
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
@@ -12,7 +12,7 @@
// See the License for the specific language governing permissions and
// limitations under the License.
-package config
+package types
import (
"encoding/json"
@@ -20,12 +20,11 @@ import (
)
var (
- ErrFilesystemRelativePath = errors.New("device path not absolute")
ErrFilesystemInvalidFormat = errors.New("invalid filesystem format")
)
type Filesystem struct {
- Device DevicePath `json:"device,omitempty" yaml:"device"`
+ Device Path `json:"device,omitempty" yaml:"device"`
Format FilesystemFormat `json:"format,omitempty" yaml:"format"`
Create *FilesystemCreate `json:"create,omitempty" yaml:"create"`
Files []File `json:"files,omitempty" yaml:"files"`
diff --git a/vendor/github.com/coreos/ignition/src/config/filesystem_test.go b/vendor/github.com/coreos/ignition/config/v1/types/filesystem_test.go
similarity index 70%
rename from vendor/github.com/coreos/ignition/src/config/filesystem_test.go
rename to vendor/github.com/coreos/ignition/config/v1/types/filesystem_test.go
index 63f7730f..01101c44 100644
--- a/vendor/github.com/coreos/ignition/src/config/filesystem_test.go
+++ b/vendor/github.com/coreos/ignition/config/v1/types/filesystem_test.go
@@ -1,4 +1,4 @@
-// Copyright 2015 CoreOS, Inc.
+// Copyright 2016 CoreOS, Inc.
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
@@ -12,128 +12,16 @@
// See the License for the specific language governing permissions and
// limitations under the License.
-package config
+package types
import (
"encoding/json"
"reflect"
"testing"
- "github.com/coreos/ignition/third_party/github.com/go-yaml/yaml"
+ "github.com/go-yaml/yaml"
)
-func TestDevicePathUnmarshalJSON(t *testing.T) {
- type in struct {
- data string
- }
- type out struct {
- device DevicePath
- err error
- }
-
- tests := []struct {
- in in
- out out
- }{
- {
- in: in{data: `"/path"`},
- out: out{device: DevicePath("/path")},
- },
- {
- in: in{data: `"bad"`},
- out: out{device: DevicePath("bad"), err: ErrFilesystemRelativePath},
- },
- }
-
- for i, test := range tests {
- var device DevicePath
- err := json.Unmarshal([]byte(test.in.data), &device)
- if !reflect.DeepEqual(test.out.err, err) {
- t.Errorf("#%d: bad error: want %v, got %v", i, test.out.err, err)
- }
- if !reflect.DeepEqual(test.out.device, device) {
- t.Errorf("#%d: bad device: want %#v, got %#v", i, test.out.device, device)
- }
- }
-}
-
-func TestDevicePathUnmarshalYAML(t *testing.T) {
- type in struct {
- data string
- }
- type out struct {
- device DevicePath
- err error
- }
-
- tests := []struct {
- in in
- out out
- }{
- {
- in: in{data: `"/path"`},
- out: out{device: DevicePath("/path")},
- },
- {
- in: in{data: `"bad"`},
- out: out{device: DevicePath("bad"), err: ErrFilesystemRelativePath},
- },
- }
-
- for i, test := range tests {
- var device DevicePath
- err := yaml.Unmarshal([]byte(test.in.data), &device)
- if !reflect.DeepEqual(test.out.err, err) {
- t.Errorf("#%d: bad error: want %v, got %v", i, test.out.err, err)
- }
- if !reflect.DeepEqual(test.out.device, device) {
- t.Errorf("#%d: bad device: want %#v, got %#v", i, test.out.device, device)
- }
- }
-}
-
-func TestDevicePathAssertValid(t *testing.T) {
- type in struct {
- device DevicePath
- }
- type out struct {
- err error
- }
-
- tests := []struct {
- in in
- out out
- }{
- {
- in: in{device: DevicePath("/good/path")},
- out: out{},
- },
- {
- in: in{device: DevicePath("/name")},
- out: out{},
- },
- {
- in: in{device: DevicePath("/this/is/a/fairly/long/path/to/a/device.")},
- out: out{},
- },
- {
- in: in{device: DevicePath("/this one has spaces")},
- out: out{},
- },
- {
- in: in{device: DevicePath("relative/path")},
- out: out{err: ErrFilesystemRelativePath},
- },
- }
-
- for i, test := range tests {
- err := test.in.device.assertValid()
- if !reflect.DeepEqual(test.out.err, err) {
- t.Errorf("#%d: bad error: want %v, got %v", i, test.out.err, err)
- }
- }
-}
-
func TestFilesystemFormatUnmarshalJSON(t *testing.T) {
type in struct {
data string
@@ -319,7 +207,7 @@ func TestFilesystemUnmarshalJSON(t *testing.T) {
},
{
in: in{data: `{"format": "ext4"}`},
- out: out{filesystem: Filesystem{Format: "ext4"}, err: ErrFilesystemRelativePath},
+ out: out{filesystem: Filesystem{Format: "ext4"}, err: ErrPathRelative},
},
}
@@ -354,7 +242,7 @@ func TestFilesystemUnmarshalYAML(t *testing.T) {
},
{
in: in{data: "format: ext4"},
- out: out{filesystem: Filesystem{Format: "ext4"}, err: ErrFilesystemRelativePath},
+ out: out{filesystem: Filesystem{Format: "ext4"}, err: ErrPathRelative},
},
}
@@ -392,11 +280,11 @@ func TestFilesystemAssertValid(t *testing.T) {
},
{
in: in{filesystem: Filesystem{Format: "ext4"}},
- out: out{err: ErrFilesystemRelativePath},
+ out: out{err: ErrPathRelative},
},
{
in: in{filesystem: Filesystem{}},
- out: out{err: ErrFilesystemRelativePath},
+ out: out{err: ErrPathRelative},
},
}
diff --git a/vendor/github.com/coreos/ignition/config/v1/types/group.go b/vendor/github.com/coreos/ignition/config/v1/types/group.go
new file mode 100644
index 00000000..eb393398
--- /dev/null
+++ b/vendor/github.com/coreos/ignition/config/v1/types/group.go
@@ -0,0 +1,22 @@
+// Copyright 2016 CoreOS, Inc.
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+// http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+package types
+
+type Group struct {
+ Name string `json:"name,omitempty" yaml:"name"`
+ Gid *uint `json:"gid,omitempty" yaml:"gid"`
+ PasswordHash string `json:"passwordHash,omitempty" yaml:"password_hash"`
+ System bool `json:"system,omitempty" yaml:"system"`
+}
diff --git a/vendor/github.com/coreos/ignition/config/v1/types/networkd.go b/vendor/github.com/coreos/ignition/config/v1/types/networkd.go
new file mode 100644
index 00000000..2dbbdc3d
--- /dev/null
+++ b/vendor/github.com/coreos/ignition/config/v1/types/networkd.go
@@ -0,0 +1,19 @@
+// Copyright 2016 CoreOS, Inc.
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+// http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+package types
+
+type Networkd struct {
+ Units []NetworkdUnit `json:"units,omitempty" yaml:"units"`
+}
diff --git a/vendor/github.com/coreos/ignition/config/v1/types/partition.go b/vendor/github.com/coreos/ignition/config/v1/types/partition.go
new file mode 100644
index 00000000..228ece4d
--- /dev/null
+++ b/vendor/github.com/coreos/ignition/config/v1/types/partition.go
@@ -0,0 +1,137 @@
+// Copyright 2016 CoreOS, Inc.
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+// http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+package types
+
+import (
+ "encoding/json"
+ "fmt"
+ "regexp"
+
+ "github.com/alecthomas/units"
+)
+
+type Partition struct {
+ Label PartitionLabel `json:"label,omitempty" yaml:"label"`
+ Number int `json:"number" yaml:"number"`
+ Size PartitionDimension `json:"size" yaml:"size"`
+ Start PartitionDimension `json:"start" yaml:"start"`
+ TypeGUID PartitionTypeGUID `json:"typeGuid,omitempty" yaml:"type_guid"`
+}
+
+type PartitionLabel string
+
+func (n *PartitionLabel) UnmarshalYAML(unmarshal func(interface{}) error) error {
+ return n.unmarshal(unmarshal)
+}
+
+func (n *PartitionLabel) UnmarshalJSON(data []byte) error {
+ return n.unmarshal(func(tn interface{}) error {
+ return json.Unmarshal(data, tn)
+ })
+}
+
+type partitionLabel PartitionLabel
+
+func (n *PartitionLabel) unmarshal(unmarshal func(interface{}) error) error {
+ tn := partitionLabel(*n)
+ if err := unmarshal(&tn); err != nil {
+ return err
+ }
+ *n = PartitionLabel(tn)
+ return n.assertValid()
+}
+
+func (n PartitionLabel) assertValid() error {
+ // http://en.wikipedia.org/wiki/GUID_Partition_Table#Partition_entries:
+ // 56 (0x38) 72 bytes Partition name (36 UTF-16LE code units)
+
+ // XXX(vc): note GPT calls it a name, we're using label for consistency
+ // with udev naming /dev/disk/by-partlabel/*.
+ if len(string(n)) > 36 {
+ return fmt.Errorf("partition labels may not exceed 36 characters")
+ }
+ return nil
+}
+
+type PartitionDimension uint64
+
+func (n *PartitionDimension) UnmarshalYAML(unmarshal func(interface{}) error) error {
+ // In YAML we allow human-readable dimensions like GiB/TiB etc.
+ var str string
+ if err := unmarshal(&str); err != nil {
+ return err
+ }
+
+ b2b, err := units.ParseBase2Bytes(str) // TODO(vc): replace the units package
+ if err != nil {
+ return err
+ }
+ if b2b < 0 {
+ return fmt.Errorf("negative value inappropriate: %q", str)
+ }
+
+ // Translate bytes into sectors
+ sectors := (b2b / 512)
+ if b2b%512 != 0 {
+ sectors++
+ }
+ *n = PartitionDimension(uint64(sectors))
+ return nil
+}
+
+func (n *PartitionDimension) UnmarshalJSON(data []byte) error {
+ // In JSON we expect plain integral sectors.
+ // The YAML->JSON conversion is responsible for normalizing human units to sectors.
+ var pd uint64
+ if err := json.Unmarshal(data, &pd); err != nil {
+ return err
+ }
+ *n = PartitionDimension(pd)
+ return nil
+}
+
+type PartitionTypeGUID string
+
+func (d *PartitionTypeGUID) UnmarshalYAML(unmarshal func(interface{}) error) error {
+ return d.unmarshal(unmarshal)
+}
+
+func (d *PartitionTypeGUID) UnmarshalJSON(data []byte) error {
+ return d.unmarshal(func(td interface{}) error {
+ return json.Unmarshal(data, td)
+ })
+}
+
+type partitionTypeGUID PartitionTypeGUID
+
+func (d *PartitionTypeGUID) unmarshal(unmarshal func(interface{}) error) error {
+ td := partitionTypeGUID(*d)
+ if err := unmarshal(&td); err != nil {
+ return err
+ }
+ *d = PartitionTypeGUID(td)
+ return d.assertValid()
+}
+
+func (d PartitionTypeGUID) assertValid() error {
+ ok, err := regexp.MatchString("[[:xdigit:]]{8}-[[:xdigit:]]{4}-[[:xdigit:]]{4}-[[:xdigit:]]{4}-[[:xdigit:]]{12}", string(d))
+ if err != nil {
+ return fmt.Errorf("error matching type-guid regexp: %v", err)
+ }
+ if !ok {
+ return fmt.Errorf(`partition type-guid must have the form "01234567-89AB-CDEF-EDCB-A98765432101", got: %q`, string(d))
+ }
+ return nil
+}
diff --git a/vendor/github.com/coreos/ignition/config/v1/types/passwd.go b/vendor/github.com/coreos/ignition/config/v1/types/passwd.go
new file mode 100644
index 00000000..f1436874
--- /dev/null
+++ b/vendor/github.com/coreos/ignition/config/v1/types/passwd.go
@@ -0,0 +1,20 @@
+// Copyright 2016 CoreOS, Inc.
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+// http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+package types
+
+type Passwd struct {
+ Users []User `json:"users,omitempty" yaml:"users"`
+ Groups []Group `json:"groups,omitempty" yaml:"groups"`
+}
diff --git a/vendor/github.com/coreos/ignition/src/config/devicepath.go b/vendor/github.com/coreos/ignition/config/v1/types/path.go
similarity index 66%
rename from vendor/github.com/coreos/ignition/src/config/devicepath.go
rename to vendor/github.com/coreos/ignition/config/v1/types/path.go
index 8f932b87..1b1231a0 100644
--- a/vendor/github.com/coreos/ignition/src/config/devicepath.go
+++ b/vendor/github.com/coreos/ignition/config/v1/types/path.go
@@ -1,4 +1,4 @@
-// Copyright 2015 CoreOS, Inc.
+// Copyright 2016 CoreOS, Inc.
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
@@ -12,39 +12,44 @@
// See the License for the specific language governing permissions and
// limitations under the License.
-package config
+package types
import (
"encoding/json"
+ "errors"
"path/filepath"
)
-type DevicePath string
+var (
+ ErrPathRelative = errors.New("path not absolute")
+)
-func (d *DevicePath) UnmarshalYAML(unmarshal func(interface{}) error) error {
+type Path string
+
+func (d *Path) UnmarshalYAML(unmarshal func(interface{}) error) error {
return d.unmarshal(unmarshal)
}
-func (d *DevicePath) UnmarshalJSON(data []byte) error {
+func (d *Path) UnmarshalJSON(data []byte) error {
return d.unmarshal(func(td interface{}) error {
return json.Unmarshal(data, td)
})
}
-type devicePath DevicePath
+type path Path
-func (d *DevicePath) unmarshal(unmarshal func(interface{}) error) error {
- td := devicePath(*d)
+func (d *Path) unmarshal(unmarshal func(interface{}) error) error {
+ td := path(*d)
if err := unmarshal(&td); err != nil {
return err
}
- *d = DevicePath(td)
+ *d = Path(td)
return d.assertValid()
}
-func (d DevicePath) assertValid() error {
+func (d Path) assertValid() error {
if !filepath.IsAbs(string(d)) {
- return ErrFilesystemRelativePath
+ return ErrPathRelative
}
return nil
}
diff --git a/vendor/github.com/coreos/ignition/config/v1/types/path_test.go b/vendor/github.com/coreos/ignition/config/v1/types/path_test.go
new file mode 100644
index 00000000..bdf0708f
--- /dev/null
+++ b/vendor/github.com/coreos/ignition/config/v1/types/path_test.go
@@ -0,0 +1,135 @@
+// Copyright 2016 CoreOS, Inc.
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+// http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+package types
+
+import (
+ "encoding/json"
+ "reflect"
+ "testing"
+
+ "github.com/go-yaml/yaml"
+)
+
+func TestPathUnmarshalJSON(t *testing.T) {
+ type in struct {
+ data string
+ }
+ type out struct {
+ device Path
+ err error
+ }
+
+ tests := []struct {
+ in in
+ out out
+ }{
+ {
+ in: in{data: `"/path"`},
+ out: out{device: Path("/path")},
+ },
+ {
+ in: in{data: `"bad"`},
+ out: out{device: Path("bad"), err: ErrPathRelative},
+ },
+ }
+
+ for i, test := range tests {
+ var device Path
+ err := json.Unmarshal([]byte(test.in.data), &device)
+ if !reflect.DeepEqual(test.out.err, err) {
+ t.Errorf("#%d: bad error: want %v, got %v", i, test.out.err, err)
+ }
+ if !reflect.DeepEqual(test.out.device, device) {
+ t.Errorf("#%d: bad device: want %#v, got %#v", i, test.out.device, device)
+ }
+ }
+}
+
+func TestPathUnmarshalYAML(t *testing.T) {
+ type in struct {
+ data string
+ }
+ type out struct {
+ device Path
+ err error
+ }
+
+ tests := []struct {
+ in in
+ out out
+ }{
+ {
+ in: in{data: `"/path"`},
+ out: out{device: Path("/path")},
+ },
+ {
+ in: in{data: `"bad"`},
+ out: out{device: Path("bad"), err: ErrPathRelative},
+ },
+ }
+
+ for i, test := range tests {
+ var device Path
+ err := yaml.Unmarshal([]byte(test.in.data), &device)
+ if !reflect.DeepEqual(test.out.err, err) {
+ t.Errorf("#%d: bad error: want %v, got %v", i, test.out.err, err)
+ }
+ if !reflect.DeepEqual(test.out.device, device) {
+ t.Errorf("#%d: bad device: want %#v, got %#v", i, test.out.device, device)
+ }
+ }
+}
+
+func TestPathAssertValid(t *testing.T) {
+ type in struct {
+ device Path
+ }
+ type out struct {
+ err error
+ }
+
+ tests := []struct {
+ in in
+ out out
+ }{
+ {
+ in: in{device: Path("/good/path")},
+ out: out{},
+ },
+ {
+ in: in{device: Path("/name")},
+ out: out{},
+ },
+ {
+ in: in{device: Path("/this/is/a/fairly/long/path/to/a/device.")},
+ out: out{},
+ },
+ {
+ in: in{device: Path("/this one has spaces")},
+ out: out{},
+ },
+ {
+ in: in{device: Path("relative/path")},
+ out: out{err: ErrPathRelative},
+ },
+ }
+
+ for i, test := range tests {
+ err := test.in.device.assertValid()
+ if !reflect.DeepEqual(test.out.err, err) {
+ t.Errorf("#%d: bad error: want %v, got %v", i, test.out.err, err)
+ }
+ }
+}
diff --git a/vendor/github.com/coreos/ignition/config/v1/types/raid.go b/vendor/github.com/coreos/ignition/config/v1/types/raid.go
new file mode 100644
index 00000000..62fe65ef
--- /dev/null
+++ b/vendor/github.com/coreos/ignition/config/v1/types/raid.go
@@ -0,0 +1,65 @@
+// Copyright 2016 CoreOS, Inc.
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+// http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+package types
+
+import (
+ "encoding/json"
+ "fmt"
+)
+
+type Raid struct {
+ Name string `json:"name" yaml:"name"`
+ Level string `json:"level" yaml:"level"`
+ Devices []Path `json:"devices,omitempty" yaml:"devices"`
+ Spares int `json:"spares,omitempty" yaml:"spares"`
+}
+
+func (n *Raid) UnmarshalYAML(unmarshal func(interface{}) error) error {
+ return n.unmarshal(unmarshal)
+}
+
+func (n *Raid) UnmarshalJSON(data []byte) error {
+ return n.unmarshal(func(tn interface{}) error {
+ return json.Unmarshal(data, tn)
+ })
+}
+
+type raid Raid
+
+func (n *Raid) unmarshal(unmarshal func(interface{}) error) error {
+ tn := raid(*n)
+ if err := unmarshal(&tn); err != nil {
+ return err
+ }
+ *n = Raid(tn)
+ return n.assertValid()
+}
+
+func (n Raid) assertValid() error {
+ switch n.Level {
+ case "linear", "raid0", "0", "stripe":
+ if n.Spares != 0 {
+ return fmt.Errorf("spares unsupported for %q arrays", n.Level)
+ }
+ case "raid1", "1", "mirror":
+ case "raid4", "4":
+ case "raid5", "5":
+ case "raid6", "6":
+ case "raid10", "10":
+ default:
+ return fmt.Errorf("unrecognized raid level: %q", n.Level)
+ }
+ return nil
+}
diff --git a/vendor/github.com/coreos/ignition/src/config/storage.go b/vendor/github.com/coreos/ignition/config/v1/types/storage.go
similarity index 94%
rename from vendor/github.com/coreos/ignition/src/config/storage.go
rename to vendor/github.com/coreos/ignition/config/v1/types/storage.go
index 17d3a7e7..ae58cffc 100644
--- a/vendor/github.com/coreos/ignition/src/config/storage.go
+++ b/vendor/github.com/coreos/ignition/config/v1/types/storage.go
@@ -1,4 +1,4 @@
-// Copyright 2015 CoreOS, Inc.
+// Copyright 2016 CoreOS, Inc.
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
@@ -12,7 +12,7 @@
// See the License for the specific language governing permissions and
// limitations under the License.
-package config
+package types
type Storage struct {
Disks []Disk `json:"disks,omitempty" yaml:"disks"`
diff --git a/vendor/github.com/coreos/ignition/config/v1/types/systemd.go b/vendor/github.com/coreos/ignition/config/v1/types/systemd.go
new file mode 100644
index 00000000..ec764850
--- /dev/null
+++ b/vendor/github.com/coreos/ignition/config/v1/types/systemd.go
@@ -0,0 +1,19 @@
+// Copyright 2016 CoreOS, Inc.
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+// http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+package types
+
+type Systemd struct {
+ Units []SystemdUnit `json:"units,omitempty" yaml:"units"`
+}
diff --git a/vendor/github.com/coreos/ignition/config/v1/types/unit.go b/vendor/github.com/coreos/ignition/config/v1/types/unit.go
new file mode 100644
index 00000000..3fd6a194
--- /dev/null
+++ b/vendor/github.com/coreos/ignition/config/v1/types/unit.go
@@ -0,0 +1,135 @@
+// Copyright 2016 CoreOS, Inc.
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+// http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+package types
+
+import (
+ "encoding/json"
+ "errors"
+ "path/filepath"
+)
+
+type SystemdUnit struct {
+ Name SystemdUnitName `json:"name,omitempty" yaml:"name"`
+ Enable bool `json:"enable,omitempty" yaml:"enable"`
+ Mask bool `json:"mask,omitempty" yaml:"mask"`
+ Contents string `json:"contents,omitempty" yaml:"contents"`
+ DropIns []SystemdUnitDropIn `json:"dropins,omitempty" yaml:"dropins"`
+}
+
+type SystemdUnitDropIn struct {
+ Name SystemdUnitDropInName `json:"name,omitempty" yaml:"name"`
+ Contents string `json:"contents,omitempty" yaml:"contents"`
+}
+
+type SystemdUnitName string
+
+func (n *SystemdUnitName) UnmarshalYAML(unmarshal func(interface{}) error) error {
+ return n.unmarshal(unmarshal)
+}
+
+func (n *SystemdUnitName) UnmarshalJSON(data []byte) error {
+ return n.unmarshal(func(tn interface{}) error {
+ return json.Unmarshal(data, tn)
+ })
+}
+
+type systemdUnitName SystemdUnitName
+
+func (n *SystemdUnitName) unmarshal(unmarshal func(interface{}) error) error {
+ tn := systemdUnitName(*n)
+ if err := unmarshal(&tn); err != nil {
+ return err
+ }
+ *n = SystemdUnitName(tn)
+ return n.assertValid()
+}
+
+func (n SystemdUnitName) assertValid() error {
+ switch filepath.Ext(string(n)) {
+ case ".service", ".socket", ".device", ".mount", ".automount", ".swap", ".target", ".path", ".timer", ".snapshot", ".slice", ".scope":
+ return nil
+ default:
+ return errors.New("invalid systemd unit extension")
+ }
+}
+
+type SystemdUnitDropInName string
+
+func (n *SystemdUnitDropInName) UnmarshalYAML(unmarshal func(interface{}) error) error {
+ return n.unmarshal(unmarshal)
+}
+
+func (n *SystemdUnitDropInName) UnmarshalJSON(data []byte) error {
+ return n.unmarshal(func(tn interface{}) error {
+ return json.Unmarshal(data, tn)
+ })
+}
+
+type systemdUnitDropInName SystemdUnitDropInName
+
+func (n *SystemdUnitDropInName) unmarshal(unmarshal func(interface{}) error) error {
+ tn := systemdUnitDropInName(*n)
+ if err := unmarshal(&tn); err != nil {
+ return err
+ }
+ *n = SystemdUnitDropInName(tn)
+ return n.assertValid()
+}
+
+func (n SystemdUnitDropInName) assertValid() error {
+ switch filepath.Ext(string(n)) {
+ case ".conf":
+ return nil
+ default:
+ return errors.New("invalid systemd unit drop-in extension")
+ }
+}
+
+type NetworkdUnit struct {
+ Name NetworkdUnitName `json:"name,omitempty" yaml:"name"`
+ Contents string `json:"contents,omitempty" yaml:"contents"`
+}
+
+type NetworkdUnitName string
+
+func (n *NetworkdUnitName) UnmarshalYAML(unmarshal func(interface{}) error) error {
+ return n.unmarshal(unmarshal)
+}
+
+func (n *NetworkdUnitName) UnmarshalJSON(data []byte) error {
+ return n.unmarshal(func(tn interface{}) error {
+ return json.Unmarshal(data, tn)
+ })
+}
+
+type networkdUnitName NetworkdUnitName
+
+func (n *NetworkdUnitName) unmarshal(unmarshal func(interface{}) error) error {
+ tn := networkdUnitName(*n)
+ if err := unmarshal(&tn); err != nil {
+ return err
+ }
+ *n = NetworkdUnitName(tn)
+ return n.assertValid()
+}
+
+func (n NetworkdUnitName) assertValid() error {
+ switch filepath.Ext(string(n)) {
+ case ".link", ".netdev", ".network":
+ return nil
+ default:
+ return errors.New("invalid networkd unit extension")
+ }
+}
diff --git a/vendor/github.com/coreos/ignition/config/v1/types/unit_test.go b/vendor/github.com/coreos/ignition/config/v1/types/unit_test.go
new file mode 100644
index 00000000..0ee8d33c
--- /dev/null
+++ b/vendor/github.com/coreos/ignition/config/v1/types/unit_test.go
@@ -0,0 +1,204 @@
+// Copyright 2016 CoreOS, Inc.
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+// http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+package types
+
+import (
+ "encoding/json"
+ "errors"
+ "reflect"
+ "testing"
+
+ "github.com/go-yaml/yaml"
+)
+
+func TestSystemdUnitNameUnmarshalJSON(t *testing.T) {
+ type in struct {
+ data string
+ }
+ type out struct {
+ unit SystemdUnitName
+ err error
+ }
+
+ tests := []struct {
+ in in
+ out out
+ }{
+ {
+ in: in{data: `"test.service"`},
+ out: out{unit: SystemdUnitName("test.service")},
+ },
+ {
+ in: in{data: `"test.socket"`},
+ out: out{unit: SystemdUnitName("test.socket")},
+ },
+ {
+ in: in{data: `"test.blah"`},
+ out: out{err: errors.New("invalid systemd unit extension")},
+ },
+ }
+
+ for i, test := range tests {
+ var unit SystemdUnitName
+ err := json.Unmarshal([]byte(test.in.data), &unit)
+ if !reflect.DeepEqual(test.out.err, err) {
+ t.Errorf("#%d: bad error: want %v, got %v", i, test.out.err, err)
+ }
+ if err != nil {
+ continue
+ }
+
+ if !reflect.DeepEqual(test.out.unit, unit) {
+ t.Errorf("#%d: bad unit: want %#v, got %#v", i, test.out.unit, unit)
+ }
+ }
+}
+
+func TestSystemdUnitNameUnmarshalYAML(t *testing.T) {
+ type in struct {
+ data string
+ }
+ type out struct {
+ unit SystemdUnitName
+ err error
+ }
+
+ tests := []struct {
+ in in
+ out out
+ }{
+ {
+ in: in{data: `"test.service"`},
+ out: out{unit: SystemdUnitName("test.service")},
+ },
+ {
+ in: in{data: `"test.socket"`},
+ out: out{unit: SystemdUnitName("test.socket")},
+ },
+ {
+ in: in{data: `"test.blah"`},
+ out: out{err: errors.New("invalid systemd unit extension")},
+ },
+ }
+
+ for i, test := range tests {
+ var unit SystemdUnitName
+ err := yaml.Unmarshal([]byte(test.in.data), &unit)
+ if !reflect.DeepEqual(test.out.err, err) {
+ t.Errorf("#%d: bad error: want %v, got %v", i, test.out.err, err)
+ }
+ if err != nil {
+ continue
+ }
+
+ if !reflect.DeepEqual(test.out.unit, unit) {
+ t.Errorf("#%d: bad unit: want %#v, got %#v", i, test.out.unit, unit)
+ }
+ }
+}
+
+func TestNetworkdUnitNameUnmarshalJSON(t *testing.T) {
+ type in struct {
+ data string
+ }
+ type out struct {
+ unit NetworkdUnitName
+ err error
+ }
+
+ tests := []struct {
+ in in
+ out out
+ }{
+ {
+ in: in{data: `"test.network"`},
+ out: out{unit: NetworkdUnitName("test.network")},
+ },
+ {
+ in: in{data: `"test.link"`},
+ out: out{unit: NetworkdUnitName("test.link")},
+ },
+ {
+ in: in{data: `"test.netdev"`},
+ out: out{unit: NetworkdUnitName("test.netdev")},
+ },
+ {
+ in: in{data: `"test.blah"`},
+ out: out{err: errors.New("invalid networkd unit extension")},
+ },
+ }
+
+ for i, test := range tests {
+ var unit NetworkdUnitName
+ err := json.Unmarshal([]byte(test.in.data), &unit)
+ if !reflect.DeepEqual(test.out.err, err) {
+ t.Errorf("#%d: bad error: want %v, got %v", i, test.out.err, err)
+ }
+ if err != nil {
+ continue
+ }
+
+ if !reflect.DeepEqual(test.out.unit, unit) {
+ t.Errorf("#%d: bad unit: want %#v, got %#v", i, test.out.unit, unit)
+ }
+ }
+}
+
+func TestNetworkdUnitNameUnmarshalYAML(t *testing.T) {
+ type in struct {
+ data string
+ }
+ type out struct {
+ unit NetworkdUnitName
+ err error
+ }
+
+ tests := []struct {
+ in in
+ out out
+ }{
+ {
+ in: in{data: `"test.network"`},
+ out: out{unit: NetworkdUnitName("test.network")},
+ },
+ {
+ in: in{data: `"test.link"`},
+ out: out{unit: NetworkdUnitName("test.link")},
+ },
+ {
+ in: in{data: `"test.netdev"`},
+ out: out{unit: NetworkdUnitName("test.netdev")},
+ },
+ {
+ in: in{data: `"test.blah"`},
+ out: out{err: errors.New("invalid networkd unit extension")},
+ },
+ }
+
+ for i, test := range tests {
+ var unit NetworkdUnitName
+ err := yaml.Unmarshal([]byte(test.in.data), &unit)
+ if !reflect.DeepEqual(test.out.err, err) {
+ t.Errorf("#%d: bad error: want %v, got %v", i, test.out.err, err)
+ }
+ if err != nil {
+ continue
+ }
+
+ if !reflect.DeepEqual(test.out.unit, unit) {
+ t.Errorf("#%d: bad unit: want %#v, got %#v", i, test.out.unit, unit)
+ }
+ }
+}
diff --git a/vendor/github.com/coreos/ignition/config/v1/types/user.go b/vendor/github.com/coreos/ignition/config/v1/types/user.go
new file mode 100644
index 00000000..80c3336c
--- /dev/null
+++ b/vendor/github.com/coreos/ignition/config/v1/types/user.go
@@ -0,0 +1,35 @@
+// Copyright 2016 CoreOS, Inc.
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+// http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+package types
+
+type User struct {
+ Name string `json:"name,omitempty" yaml:"name"`
+ PasswordHash string `json:"passwordHash,omitempty" yaml:"password_hash"`
+ SSHAuthorizedKeys []string `json:"sshAuthorizedKeys,omitempty" yaml:"ssh_authorized_keys"`
+ Create *UserCreate `json:"create,omitempty" yaml:"create"`
+}
+
+type UserCreate struct {
+ Uid *uint `json:"uid,omitempty" yaml:"uid"`
+ GECOS string `json:"gecos,omitempty" yaml:"gecos"`
+ Homedir string `json:"homeDir,omitempty" yaml:"home_dir"`
+ NoCreateHome bool `json:"noCreateHome,omitempty" yaml:"no_create_home"`
+ PrimaryGroup string `json:"primaryGroup,omitempty" yaml:"primary_group"`
+ Groups []string `json:"groups,omitempty" yaml:"groups"`
+ NoUserGroup bool `json:"noUserGroup,omitempty" yaml:"no_user_group"`
+ System bool `json:"system,omitempty" yaml:"system"`
+ NoLogInit bool `json:"noLogInit,omitempty" yaml:"no_log_init"`
+ Shell string `json:"shell,omitempty" yaml:"shell"`
+}
diff --git a/vendor/github.com/coreos/ignition/config/v1/vendor.manifest b/vendor/github.com/coreos/ignition/config/v1/vendor.manifest
new file mode 100644
index 00000000..c61eed28
--- /dev/null
+++ b/vendor/github.com/coreos/ignition/config/v1/vendor.manifest
@@ -0,0 +1,5 @@
+# If you manipulate the contents of third_party/, amend this accordingly.
+# pkg version
+github.com/alecthomas/units 6b4e7dc5e3143b85ea77909c72caf89416fc2915
+github.com/camlistore/camlistore/pkg/errorutil 9106ce829629773474c689b34aacd7d3aaa99426
+github.com/go-yaml/yaml 49c95bdc21843256fb6c4e0d370a05f24a0bf213
diff --git a/vendor/github.com/coreos/ignition/config/v1/vendor/github.com/alecthomas/units/COPYING b/vendor/github.com/coreos/ignition/config/v1/vendor/github.com/alecthomas/units/COPYING
new file mode 100644
index 00000000..2993ec08
--- /dev/null
+++ b/vendor/github.com/coreos/ignition/config/v1/vendor/github.com/alecthomas/units/COPYING
@@ -0,0 +1,19 @@
+Copyright (C) 2014 Alec Thomas
+
+Permission is hereby granted, free of charge, to any person obtaining a copy of
+this software and associated documentation files (the "Software"), to deal in
+the Software without restriction, including without limitation the rights to
+use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies
+of the Software, and to permit persons to whom the Software is furnished to do
+so, subject to the following conditions:
+
+The above copyright notice and this permission notice shall be included in all
+copies or substantial portions of the Software.
+
+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
+SOFTWARE.
diff --git a/vendor/github.com/coreos/ignition/config/v1/vendor/github.com/alecthomas/units/README.md b/vendor/github.com/coreos/ignition/config/v1/vendor/github.com/alecthomas/units/README.md
new file mode 100644
index 00000000..bee884e3
--- /dev/null
+++ b/vendor/github.com/coreos/ignition/config/v1/vendor/github.com/alecthomas/units/README.md
@@ -0,0 +1,11 @@
+# Units - Helpful unit multipliers and functions for Go
+
+The goal of this package is to have functionality similar to the [time](http://golang.org/pkg/time/) package.
+
+It allows for code like this:
+
+```go
+n, err := ParseBase2Bytes("1KB")
+// n == 1024
+n = units.Mebibyte * 512
+```
diff --git a/vendor/github.com/coreos/ignition/config/v1/vendor/github.com/alecthomas/units/bytes.go b/vendor/github.com/coreos/ignition/config/v1/vendor/github.com/alecthomas/units/bytes.go
new file mode 100644
index 00000000..eaadeb80
--- /dev/null
+++ b/vendor/github.com/coreos/ignition/config/v1/vendor/github.com/alecthomas/units/bytes.go
@@ -0,0 +1,83 @@
+package units
+
+// Base2Bytes is the old non-SI power-of-2 byte scale (1024 bytes in a kilobyte,
+// etc.).
+type Base2Bytes int64
+
+// Base-2 byte units.
+const (
+ Kibibyte Base2Bytes = 1024
+ KiB = Kibibyte
+ Mebibyte = Kibibyte * 1024
+ MiB = Mebibyte
+ Gibibyte = Mebibyte * 1024
+ GiB = Gibibyte
+ Tebibyte = Gibibyte * 1024
+ TiB = Tebibyte
+ Pebibyte = Tebibyte * 1024
+ PiB = Pebibyte
+ Exbibyte = Pebibyte * 1024
+ EiB = Exbibyte
+)
+
+var (
+ bytesUnitMap = MakeUnitMap("iB", "B", 1024)
+ oldBytesUnitMap = MakeUnitMap("B", "B", 1024)
+)
+
+// ParseBase2Bytes supports both iB and B in base-2 multipliers. That is, KB
+// and KiB are both 1024.
+func ParseBase2Bytes(s string) (Base2Bytes, error) {
+ n, err := ParseUnit(s, bytesUnitMap)
+ if err != nil {
+ n, err = ParseUnit(s, oldBytesUnitMap)
+ }
+ return Base2Bytes(n), err
+}
+
+func (b Base2Bytes) String() string {
+ return ToString(int64(b), 1024, "iB", "B")
+}
+
+var (
+ metricBytesUnitMap = MakeUnitMap("B", "B", 1000)
+)
+
+// MetricBytes are SI byte units (1000 bytes in a kilobyte).
+type MetricBytes SI
+
+// SI base-10 byte units.
+const (
+ Kilobyte MetricBytes = 1000
+ KB = Kilobyte
+ Megabyte = Kilobyte * 1000
+ MB = Megabyte
+ Gigabyte = Megabyte * 1000
+ GB = Gigabyte
+ Terabyte = Gigabyte * 1000
+ TB = Terabyte
+ Petabyte = Terabyte * 1000
+ PB = Petabyte
+ Exabyte = Petabyte * 1000
+ EB = Exabyte
+)
+
+// ParseMetricBytes parses base-10 metric byte units. That is, KB is 1000 bytes.
+func ParseMetricBytes(s string) (MetricBytes, error) {
+ n, err := ParseUnit(s, metricBytesUnitMap)
+ return MetricBytes(n), err
+}
+
+func (m MetricBytes) String() string {
+ return ToString(int64(m), 1000, "B", "B")
+}
+
+// ParseStrictBytes supports both iB and B suffixes for base 2 and metric,
+// respectively. That is, KiB represents 1024 and KB represents 1000.
+func ParseStrictBytes(s string) (int64, error) {
+ n, err := ParseUnit(s, bytesUnitMap)
+ if err != nil {
+ n, err = ParseUnit(s, metricBytesUnitMap)
+ }
+ return int64(n), err
+}
diff --git a/vendor/github.com/coreos/ignition/third_party/github.com/alecthomas/units/bytes_test.go b/vendor/github.com/coreos/ignition/config/v1/vendor/github.com/alecthomas/units/bytes_test.go
similarity index 100%
rename from vendor/github.com/coreos/ignition/third_party/github.com/alecthomas/units/bytes_test.go
rename to vendor/github.com/coreos/ignition/config/v1/vendor/github.com/alecthomas/units/bytes_test.go
diff --git a/vendor/github.com/coreos/ignition/config/v1/vendor/github.com/alecthomas/units/doc.go b/vendor/github.com/coreos/ignition/config/v1/vendor/github.com/alecthomas/units/doc.go
new file mode 100644
index 00000000..156ae386
--- /dev/null
+++ b/vendor/github.com/coreos/ignition/config/v1/vendor/github.com/alecthomas/units/doc.go
@@ -0,0 +1,13 @@
+// Package units provides helpful unit multipliers and functions for Go.
+//
+// The goal of this package is to have functionality similar to the time [1] package.
+//
+//
+// [1] http://golang.org/pkg/time/
+//
+// It allows for code like this:
+//
+// n, err := ParseBase2Bytes("1KB")
+// // n == 1024
+// n = units.Mebibyte * 512
+package units
diff --git a/vendor/github.com/coreos/ignition/config/v1/vendor/github.com/alecthomas/units/si.go b/vendor/github.com/coreos/ignition/config/v1/vendor/github.com/alecthomas/units/si.go
new file mode 100644
index 00000000..8234a9d5
--- /dev/null
+++ b/vendor/github.com/coreos/ignition/config/v1/vendor/github.com/alecthomas/units/si.go
@@ -0,0 +1,26 @@
+package units
+
+// SI units.
+type SI int64
+
+// SI unit multiples.
+const (
+ Kilo SI = 1000
+ Mega = Kilo * 1000
+ Giga = Mega * 1000
+ Tera = Giga * 1000
+ Peta = Tera * 1000
+ Exa = Peta * 1000
+)
+
+func MakeUnitMap(suffix, shortSuffix string, scale int64) map[string]float64 {
+ return map[string]float64{
+ shortSuffix: 1,
+ "K" + suffix: float64(scale),
+ "M" + suffix: float64(scale * scale),
+ "G" + suffix: float64(scale * scale * scale),
+ "T" + suffix: float64(scale * scale * scale * scale),
+ "P" + suffix: float64(scale * scale * scale * scale * scale),
+ "E" + suffix: float64(scale * scale * scale * scale * scale * scale),
+ }
+}
diff --git a/vendor/github.com/coreos/ignition/config/v1/vendor/github.com/alecthomas/units/util.go b/vendor/github.com/coreos/ignition/config/v1/vendor/github.com/alecthomas/units/util.go
new file mode 100644
index 00000000..6527e92d
--- /dev/null
+++ b/vendor/github.com/coreos/ignition/config/v1/vendor/github.com/alecthomas/units/util.go
@@ -0,0 +1,138 @@
+package units
+
+import (
+ "errors"
+ "fmt"
+ "strings"
+)
+
+var (
+ siUnits = []string{"", "K", "M", "G", "T", "P", "E"}
+)
+
+func ToString(n int64, scale int64, suffix, baseSuffix string) string {
+ mn := len(siUnits)
+ out := make([]string, mn)
+ for i, m := range siUnits {
+ if n%scale != 0 || i == 0 && n == 0 {
+ s := suffix
+ if i == 0 {
+ s = baseSuffix
+ }
+ out[mn-1-i] = fmt.Sprintf("%d%s%s", n%scale, m, s)
+ }
+ n /= scale
+ if n == 0 {
+ break
+ }
+ }
+ return strings.Join(out, "")
+}
+
+// Below code ripped straight from http://golang.org/src/pkg/time/format.go?s=33392:33438#L1123
+var errLeadingInt = errors.New("units: bad [0-9]*") // never printed
+
+// leadingInt consumes the leading [0-9]* from s.
+func leadingInt(s string) (x int64, rem string, err error) {
+ i := 0
+ for ; i < len(s); i++ {
+ c := s[i]
+ if c < '0' || c > '9' {
+ break
+ }
+ if x >= (1<<63-10)/10 {
+ // overflow
+ return 0, "", errLeadingInt
+ }
+ x = x*10 + int64(c) - '0'
+ }
+ return x, s[i:], nil
+}
+
+func ParseUnit(s string, unitMap map[string]float64) (int64, error) {
+ // [-+]?([0-9]*(\.[0-9]*)?[a-z]+)+
+ orig := s
+ f := float64(0)
+ neg := false
+
+ // Consume [-+]?
+ if s != "" {
+ c := s[0]
+ if c == '-' || c == '+' {
+ neg = c == '-'
+ s = s[1:]
+ }
+ }
+ // Special case: if all that is left is "0", this is zero.
+ if s == "0" {
+ return 0, nil
+ }
+ if s == "" {
+ return 0, errors.New("units: invalid " + orig)
+ }
+ for s != "" {
+ g := float64(0) // this element of the sequence
+
+ var x int64
+ var err error
+
+ // The next character must be [0-9.]
+ if !(s[0] == '.' || ('0' <= s[0] && s[0] <= '9')) {
+ return 0, errors.New("units: invalid " + orig)
+ }
+ // Consume [0-9]*
+ pl := len(s)
+ x, s, err = leadingInt(s)
+ if err != nil {
+ return 0, errors.New("units: invalid " + orig)
+ }
+ g = float64(x)
+ pre := pl != len(s) // whether we consumed anything before a period
+
+ // Consume (\.[0-9]*)?
+ post := false
+ if s != "" && s[0] == '.' {
+ s = s[1:]
+ pl := len(s)
+ x, s, err = leadingInt(s)
+ if err != nil {
+ return 0, errors.New("units: invalid " + orig)
+ }
+ scale := 1.0
+ for n := pl - len(s); n > 0; n-- {
+ scale *= 10
+ }
+ g += float64(x) / scale
+ post = pl != len(s)
+ }
+ if !pre && !post {
+ // no digits (e.g. ".s" or "-.s")
+ return 0, errors.New("units: invalid " + orig)
+ }
+
+ // Consume unit.
+ i := 0
+ for ; i < len(s); i++ {
+ c := s[i]
+ if c == '.' || ('0' <= c && c <= '9') {
+ break
+ }
+ }
+ u := s[:i]
+ s = s[i:]
+ unit, ok := unitMap[u]
+ if !ok {
+ return 0, errors.New("units: unknown unit " + u + " in " + orig)
+ }
+
+ f += g * unit
+ }
+
+ if neg {
+ f = -f
+ }
+ if f < float64(-1<<63) || f > float64(1<<63-1) {
+ return 0, errors.New("units: overflow parsing unit")
+ }
+ return int64(f), nil
+}
diff --git a/vendor/github.com/coreos/ignition/config/v1/vendor/github.com/camlistore/camlistore/pkg/errorutil/highlight.go b/vendor/github.com/coreos/ignition/config/v1/vendor/github.com/camlistore/camlistore/pkg/errorutil/highlight.go
new file mode 100644
index 00000000..aace6a46
--- /dev/null
+++ b/vendor/github.com/coreos/ignition/config/v1/vendor/github.com/camlistore/camlistore/pkg/errorutil/highlight.go
@@ -0,0 +1,58 @@
+/*
+Copyright 2011 Google Inc.
+
+Licensed under the Apache License, Version 2.0 (the "License");
+you may not use this file except in compliance with the License.
+You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+Unless required by applicable law or agreed to in writing, software
+distributed under the License is distributed on an "AS IS" BASIS,
+WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+See the License for the specific language governing permissions and
+limitations under the License.
+*/
+
+// Package errorutil helps make better error messages.
+package errorutil
+
+import (
+ "bufio"
+ "bytes"
+ "fmt"
+ "io"
+ "strings"
+)
+
+// HighlightBytePosition takes a reader and the location in bytes of a parse
+// error (for instance, from json.SyntaxError.Offset) and returns the line, column,
+// and pretty-printed context around the error with an arrow indicating the exact
+// position of the syntax error.
+func HighlightBytePosition(f io.Reader, pos int64) (line, col int, highlight string) {
+ line = 1
+ br := bufio.NewReader(f)
+ lastLine := ""
+ thisLine := new(bytes.Buffer)
+ for n := int64(0); n < pos; n++ {
+ b, err := br.ReadByte()
+ if err != nil {
+ break
+ }
+ if b == '\n' {
+ lastLine = thisLine.String()
+ thisLine.Reset()
+ line++
+ col = 1
+ } else {
+ col++
+ thisLine.WriteByte(b)
+ }
+ }
+ if line > 1 {
+ highlight += fmt.Sprintf("%5d: %s\n", line-1, lastLine)
+ }
+ highlight += fmt.Sprintf("%5d: %s\n", line, thisLine.String())
+ highlight += fmt.Sprintf("%s^\n", strings.Repeat(" ", col+5))
+ return
+}
diff --git a/vendor/github.com/coreos/ignition/third_party/github.com/go-yaml/yaml/LICENSE b/vendor/github.com/coreos/ignition/config/v1/vendor/github.com/go-yaml/yaml/LICENSE
similarity index 100%
rename from vendor/github.com/coreos/ignition/third_party/github.com/go-yaml/yaml/LICENSE
rename to vendor/github.com/coreos/ignition/config/v1/vendor/github.com/go-yaml/yaml/LICENSE
diff --git a/vendor/github.com/coreos/ignition/third_party/github.com/go-yaml/yaml/LICENSE.libyaml b/vendor/github.com/coreos/ignition/config/v1/vendor/github.com/go-yaml/yaml/LICENSE.libyaml
similarity index 100%
rename from vendor/github.com/coreos/ignition/third_party/github.com/go-yaml/yaml/LICENSE.libyaml
rename to vendor/github.com/coreos/ignition/config/v1/vendor/github.com/go-yaml/yaml/LICENSE.libyaml
diff --git a/vendor/github.com/coreos/ignition/third_party/github.com/go-yaml/yaml/README.md b/vendor/github.com/coreos/ignition/config/v1/vendor/github.com/go-yaml/yaml/README.md
similarity index 100%
rename from vendor/github.com/coreos/ignition/third_party/github.com/go-yaml/yaml/README.md
rename to vendor/github.com/coreos/ignition/config/v1/vendor/github.com/go-yaml/yaml/README.md
diff --git a/vendor/github.com/coreos/ignition/third_party/github.com/go-yaml/yaml/apic.go b/vendor/github.com/coreos/ignition/config/v1/vendor/github.com/go-yaml/yaml/apic.go
similarity index 100%
rename from vendor/github.com/coreos/ignition/third_party/github.com/go-yaml/yaml/apic.go
rename to vendor/github.com/coreos/ignition/config/v1/vendor/github.com/go-yaml/yaml/apic.go
diff --git a/vendor/github.com/coreos/ignition/third_party/github.com/go-yaml/yaml/decode.go b/vendor/github.com/coreos/ignition/config/v1/vendor/github.com/go-yaml/yaml/decode.go
similarity index 100%
rename from vendor/github.com/coreos/ignition/third_party/github.com/go-yaml/yaml/decode.go
rename to vendor/github.com/coreos/ignition/config/v1/vendor/github.com/go-yaml/yaml/decode.go
diff --git a/vendor/github.com/coreos/ignition/third_party/github.com/go-yaml/yaml/decode_test.go b/vendor/github.com/coreos/ignition/config/v1/vendor/github.com/go-yaml/yaml/decode_test.go
similarity index 100%
rename from vendor/github.com/coreos/ignition/third_party/github.com/go-yaml/yaml/decode_test.go
rename to vendor/github.com/coreos/ignition/config/v1/vendor/github.com/go-yaml/yaml/decode_test.go
diff --git a/vendor/github.com/coreos/ignition/third_party/github.com/go-yaml/yaml/emitterc.go b/vendor/github.com/coreos/ignition/config/v1/vendor/github.com/go-yaml/yaml/emitterc.go
similarity index 100%
rename from vendor/github.com/coreos/ignition/third_party/github.com/go-yaml/yaml/emitterc.go
rename to vendor/github.com/coreos/ignition/config/v1/vendor/github.com/go-yaml/yaml/emitterc.go
diff --git a/vendor/github.com/coreos/ignition/third_party/github.com/go-yaml/yaml/encode.go b/vendor/github.com/coreos/ignition/config/v1/vendor/github.com/go-yaml/yaml/encode.go
similarity index 100%
rename from vendor/github.com/coreos/ignition/third_party/github.com/go-yaml/yaml/encode.go
rename to vendor/github.com/coreos/ignition/config/v1/vendor/github.com/go-yaml/yaml/encode.go
diff --git a/vendor/github.com/coreos/ignition/third_party/github.com/go-yaml/yaml/encode_test.go b/vendor/github.com/coreos/ignition/config/v1/vendor/github.com/go-yaml/yaml/encode_test.go
similarity index 100%
rename from vendor/github.com/coreos/ignition/third_party/github.com/go-yaml/yaml/encode_test.go
rename to vendor/github.com/coreos/ignition/config/v1/vendor/github.com/go-yaml/yaml/encode_test.go
diff --git a/vendor/github.com/coreos/ignition/third_party/github.com/go-yaml/yaml/parserc.go b/vendor/github.com/coreos/ignition/config/v1/vendor/github.com/go-yaml/yaml/parserc.go
similarity index 100%
rename from vendor/github.com/coreos/ignition/third_party/github.com/go-yaml/yaml/parserc.go
rename to vendor/github.com/coreos/ignition/config/v1/vendor/github.com/go-yaml/yaml/parserc.go
diff --git a/vendor/github.com/coreos/ignition/third_party/github.com/go-yaml/yaml/readerc.go b/vendor/github.com/coreos/ignition/config/v1/vendor/github.com/go-yaml/yaml/readerc.go
similarity index 100%
rename from vendor/github.com/coreos/ignition/third_party/github.com/go-yaml/yaml/readerc.go
rename to vendor/github.com/coreos/ignition/config/v1/vendor/github.com/go-yaml/yaml/readerc.go
diff --git a/vendor/github.com/coreos/ignition/third_party/github.com/go-yaml/yaml/resolve.go b/vendor/github.com/coreos/ignition/config/v1/vendor/github.com/go-yaml/yaml/resolve.go
similarity index 100%
rename from vendor/github.com/coreos/ignition/third_party/github.com/go-yaml/yaml/resolve.go
rename to vendor/github.com/coreos/ignition/config/v1/vendor/github.com/go-yaml/yaml/resolve.go
diff --git a/vendor/github.com/coreos/ignition/third_party/github.com/go-yaml/yaml/scannerc.go b/vendor/github.com/coreos/ignition/config/v1/vendor/github.com/go-yaml/yaml/scannerc.go
similarity index 100%
rename from vendor/github.com/coreos/ignition/third_party/github.com/go-yaml/yaml/scannerc.go
rename to vendor/github.com/coreos/ignition/config/v1/vendor/github.com/go-yaml/yaml/scannerc.go
diff --git a/vendor/github.com/coreos/ignition/third_party/github.com/go-yaml/yaml/sorter.go b/vendor/github.com/coreos/ignition/config/v1/vendor/github.com/go-yaml/yaml/sorter.go
similarity index 100%
rename from vendor/github.com/coreos/ignition/third_party/github.com/go-yaml/yaml/sorter.go
rename to vendor/github.com/coreos/ignition/config/v1/vendor/github.com/go-yaml/yaml/sorter.go
diff --git a/vendor/github.com/coreos/ignition/third_party/github.com/go-yaml/yaml/suite_test.go b/vendor/github.com/coreos/ignition/config/v1/vendor/github.com/go-yaml/yaml/suite_test.go
similarity index 100%
rename from vendor/github.com/coreos/ignition/third_party/github.com/go-yaml/yaml/suite_test.go
rename to vendor/github.com/coreos/ignition/config/v1/vendor/github.com/go-yaml/yaml/suite_test.go
diff --git a/vendor/github.com/coreos/ignition/third_party/github.com/go-yaml/yaml/writerc.go b/vendor/github.com/coreos/ignition/config/v1/vendor/github.com/go-yaml/yaml/writerc.go
similarity index 100%
rename from vendor/github.com/coreos/ignition/third_party/github.com/go-yaml/yaml/writerc.go
rename to vendor/github.com/coreos/ignition/config/v1/vendor/github.com/go-yaml/yaml/writerc.go
diff --git a/vendor/github.com/coreos/ignition/third_party/github.com/go-yaml/yaml/yaml.go b/vendor/github.com/coreos/ignition/config/v1/vendor/github.com/go-yaml/yaml/yaml.go
similarity index 100%
rename from vendor/github.com/coreos/ignition/third_party/github.com/go-yaml/yaml/yaml.go
rename to vendor/github.com/coreos/ignition/config/v1/vendor/github.com/go-yaml/yaml/yaml.go
diff --git a/vendor/github.com/coreos/ignition/third_party/github.com/go-yaml/yaml/yamlh.go b/vendor/github.com/coreos/ignition/config/v1/vendor/github.com/go-yaml/yaml/yamlh.go
similarity index 100%
rename from vendor/github.com/coreos/ignition/third_party/github.com/go-yaml/yaml/yamlh.go
rename to vendor/github.com/coreos/ignition/config/v1/vendor/github.com/go-yaml/yaml/yamlh.go
diff --git a/vendor/github.com/coreos/ignition/third_party/github.com/go-yaml/yaml/yamlprivateh.go b/vendor/github.com/coreos/ignition/config/v1/vendor/github.com/go-yaml/yaml/yamlprivateh.go
similarity index 100%
rename from vendor/github.com/coreos/ignition/third_party/github.com/go-yaml/yaml/yamlprivateh.go
rename to vendor/github.com/coreos/ignition/config/v1/vendor/github.com/go-yaml/yaml/yamlprivateh.go
diff --git a/vendor/github.com/coreos/ignition/config/vendor.manifest b/vendor/github.com/coreos/ignition/config/vendor.manifest
new file mode 100644
index 00000000..a754b680
--- /dev/null
+++ b/vendor/github.com/coreos/ignition/config/vendor.manifest
@@ -0,0 +1,7 @@
+# If you manipulate the contents of vendor/, amend this accordingly.
+# pkg version
+github.com/alecthomas/units 6b4e7dc5e3143b85ea77909c72caf89416fc2915
+github.com/coreos/go-semver 294930c1e79c64e7dbe360054274fdad492c8cf5
+github.com/go-yaml/yaml 49c95bdc21843256fb6c4e0d370a05f24a0bf213
+github.com/vincent-petithory/dataurl 9a301d65acbb728fcc3ace14f45f511a4cfeea9c
+go4.org/errorutil 03efcb870d84809319ea509714dd6d19a1498483
diff --git a/vendor/github.com/coreos/ignition/config/vendor/github.com/alecthomas/units/COPYING b/vendor/github.com/coreos/ignition/config/vendor/github.com/alecthomas/units/COPYING
new file mode 100644
index 00000000..2993ec08
--- /dev/null
+++ b/vendor/github.com/coreos/ignition/config/vendor/github.com/alecthomas/units/COPYING
@@ -0,0 +1,19 @@
+Copyright (C) 2014 Alec Thomas
+
+Permission is hereby granted, free of charge, to any person obtaining a copy of
+this software and associated documentation files (the "Software"), to deal in
+the Software without restriction, including without limitation the rights to
+use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies
+of the Software, and to permit persons to whom the Software is furnished to do
+so, subject to the following conditions:
+
+The above copyright notice and this permission notice shall be included in all
+copies or substantial portions of the Software.
+
+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
+SOFTWARE.
diff --git a/vendor/github.com/coreos/ignition/config/vendor/github.com/alecthomas/units/README.md b/vendor/github.com/coreos/ignition/config/vendor/github.com/alecthomas/units/README.md
new file mode 100644
index 00000000..bee884e3
--- /dev/null
+++ b/vendor/github.com/coreos/ignition/config/vendor/github.com/alecthomas/units/README.md
@@ -0,0 +1,11 @@
+# Units - Helpful unit multipliers and functions for Go
+
+The goal of this package is to have functionality similar to the [time](http://golang.org/pkg/time/) package.
+
+It allows for code like this:
+
+```go
+n, err := ParseBase2Bytes("1KB")
+// n == 1024
+n = units.Mebibyte * 512
+```
diff --git a/vendor/github.com/coreos/ignition/config/vendor/github.com/alecthomas/units/bytes.go b/vendor/github.com/coreos/ignition/config/vendor/github.com/alecthomas/units/bytes.go
new file mode 100644
index 00000000..eaadeb80
--- /dev/null
+++ b/vendor/github.com/coreos/ignition/config/vendor/github.com/alecthomas/units/bytes.go
@@ -0,0 +1,83 @@
+package units
+
+// Base2Bytes is the old non-SI power-of-2 byte scale (1024 bytes in a kilobyte,
+// etc.).
+type Base2Bytes int64
+
+// Base-2 byte units.
+const (
+ Kibibyte Base2Bytes = 1024
+ KiB = Kibibyte
+ Mebibyte = Kibibyte * 1024
+ MiB = Mebibyte
+ Gibibyte = Mebibyte * 1024
+ GiB = Gibibyte
+ Tebibyte = Gibibyte * 1024
+ TiB = Tebibyte
+ Pebibyte = Tebibyte * 1024
+ PiB = Pebibyte
+ Exbibyte = Pebibyte * 1024
+ EiB = Exbibyte
+)
+
+var (
+ bytesUnitMap = MakeUnitMap("iB", "B", 1024)
+ oldBytesUnitMap = MakeUnitMap("B", "B", 1024)
+)
+
+// ParseBase2Bytes supports both iB and B in base-2 multipliers. That is, KB
+// and KiB are both 1024.
+func ParseBase2Bytes(s string) (Base2Bytes, error) {
+ n, err := ParseUnit(s, bytesUnitMap)
+ if err != nil {
+ n, err = ParseUnit(s, oldBytesUnitMap)
+ }
+ return Base2Bytes(n), err
+}
+
+func (b Base2Bytes) String() string {
+ return ToString(int64(b), 1024, "iB", "B")
+}
+
+var (
+ metricBytesUnitMap = MakeUnitMap("B", "B", 1000)
+)
+
+// MetricBytes are SI byte units (1000 bytes in a kilobyte).
+type MetricBytes SI
+
+// SI base-10 byte units.
+const (
+ Kilobyte MetricBytes = 1000
+ KB = Kilobyte
+ Megabyte = Kilobyte * 1000
+ MB = Megabyte
+ Gigabyte = Megabyte * 1000
+ GB = Gigabyte
+ Terabyte = Gigabyte * 1000
+ TB = Terabyte
+ Petabyte = Terabyte * 1000
+ PB = Petabyte
+ Exabyte = Petabyte * 1000
+ EB = Exabyte
+)
+
+// ParseMetricBytes parses base-10 metric byte units. That is, KB is 1000 bytes.
+func ParseMetricBytes(s string) (MetricBytes, error) {
+ n, err := ParseUnit(s, metricBytesUnitMap)
+ return MetricBytes(n), err
+}
+
+func (m MetricBytes) String() string {
+ return ToString(int64(m), 1000, "B", "B")
+}
+
+// ParseStrictBytes supports both iB and B suffixes for base 2 and metric,
+// respectively. That is, KiB represents 1024 and KB represents 1000.
+func ParseStrictBytes(s string) (int64, error) {
+ n, err := ParseUnit(s, bytesUnitMap)
+ if err != nil {
+ n, err = ParseUnit(s, metricBytesUnitMap)
+ }
+ return int64(n), err
+}
diff --git a/vendor/github.com/coreos/ignition/config/vendor/github.com/alecthomas/units/bytes_test.go b/vendor/github.com/coreos/ignition/config/vendor/github.com/alecthomas/units/bytes_test.go
new file mode 100644
index 00000000..d4317aa5
--- /dev/null
+++ b/vendor/github.com/coreos/ignition/config/vendor/github.com/alecthomas/units/bytes_test.go
@@ -0,0 +1,49 @@
+package units
+
+import (
+ "testing"
+
+ "github.com/stretchr/testify/assert"
+)
+
+func TestBase2BytesString(t *testing.T) {
+ assert.Equal(t, Base2Bytes(0).String(), "0B")
+ assert.Equal(t, Base2Bytes(1025).String(), "1KiB1B")
+ assert.Equal(t, Base2Bytes(1048577).String(), "1MiB1B")
+}
+
+func TestParseBase2Bytes(t *testing.T) {
+ n, err := ParseBase2Bytes("0B")
+ assert.NoError(t, err)
+ assert.Equal(t, 0, n)
+ n, err = ParseBase2Bytes("1KB")
+ assert.NoError(t, err)
+ assert.Equal(t, 1024, n)
+ n, err = ParseBase2Bytes("1MB1KB25B")
+ assert.NoError(t, err)
+ assert.Equal(t, 1049625, n)
+ n, err = ParseBase2Bytes("1.5MB")
+ assert.NoError(t, err)
+ assert.Equal(t, 1572864, n)
+}
+
+func TestMetricBytesString(t *testing.T) {
+ assert.Equal(t, MetricBytes(0).String(), "0B")
+ assert.Equal(t, MetricBytes(1001).String(), "1KB1B")
+ assert.Equal(t, MetricBytes(1001025).String(), "1MB1KB25B")
+}
+
+func TestParseMetricBytes(t *testing.T) {
+ n, err := ParseMetricBytes("0B")
+ assert.NoError(t, err)
+ assert.Equal(t, 0, n)
+ n, err = ParseMetricBytes("1KB1B")
+ assert.NoError(t, err)
+ assert.Equal(t, 1001, n)
+ n, err = ParseMetricBytes("1MB1KB25B")
+ assert.NoError(t, err)
+ assert.Equal(t, 1001025, n)
+ n, err = ParseMetricBytes("1.5MB")
+ assert.NoError(t, err)
+ assert.Equal(t, 1500000, n)
+}
diff --git a/vendor/github.com/coreos/ignition/config/vendor/github.com/alecthomas/units/doc.go b/vendor/github.com/coreos/ignition/config/vendor/github.com/alecthomas/units/doc.go
new file mode 100644
index 00000000..156ae386
--- /dev/null
+++ b/vendor/github.com/coreos/ignition/config/vendor/github.com/alecthomas/units/doc.go
@@ -0,0 +1,13 @@
+// Package units provides helpful unit multipliers and functions for Go.
+//
+// The goal of this package is to have functionality similar to the time [1] package.
+//
+//
+// [1] http://golang.org/pkg/time/
+//
+// It allows for code like this:
+//
+// n, err := ParseBase2Bytes("1KB")
+// // n == 1024
+// n = units.Mebibyte * 512
+package units
diff --git a/vendor/github.com/coreos/ignition/config/vendor/github.com/alecthomas/units/si.go b/vendor/github.com/coreos/ignition/config/vendor/github.com/alecthomas/units/si.go
new file mode 100644
index 00000000..8234a9d5
--- /dev/null
+++ b/vendor/github.com/coreos/ignition/config/vendor/github.com/alecthomas/units/si.go
@@ -0,0 +1,26 @@
+package units
+
+// SI units.
+type SI int64
+
+// SI unit multiples.
+const (
+ Kilo SI = 1000
+ Mega = Kilo * 1000
+ Giga = Mega * 1000
+ Tera = Giga * 1000
+ Peta = Tera * 1000
+ Exa = Peta * 1000
+)
+
+func MakeUnitMap(suffix, shortSuffix string, scale int64) map[string]float64 {
+ return map[string]float64{
+ shortSuffix: 1,
+ "K" + suffix: float64(scale),
+ "M" + suffix: float64(scale * scale),
+ "G" + suffix: float64(scale * scale * scale),
+ "T" + suffix: float64(scale * scale * scale * scale),
+ "P" + suffix: float64(scale * scale * scale * scale * scale),
+ "E" + suffix: float64(scale * scale * scale * scale * scale * scale),
+ }
+}
diff --git a/vendor/github.com/coreos/ignition/config/vendor/github.com/alecthomas/units/util.go b/vendor/github.com/coreos/ignition/config/vendor/github.com/alecthomas/units/util.go
new file mode 100644
index 00000000..6527e92d
--- /dev/null
+++ b/vendor/github.com/coreos/ignition/config/vendor/github.com/alecthomas/units/util.go
@@ -0,0 +1,138 @@
+package units
+
+import (
+ "errors"
+ "fmt"
+ "strings"
+)
+
+var (
+ siUnits = []string{"", "K", "M", "G", "T", "P", "E"}
+)
+
+func ToString(n int64, scale int64, suffix, baseSuffix string) string {
+ mn := len(siUnits)
+ out := make([]string, mn)
+ for i, m := range siUnits {
+ if n%scale != 0 || i == 0 && n == 0 {
+ s := suffix
+ if i == 0 {
+ s = baseSuffix
+ }
+ out[mn-1-i] = fmt.Sprintf("%d%s%s", n%scale, m, s)
+ }
+ n /= scale
+ if n == 0 {
+ break
+ }
+ }
+ return strings.Join(out, "")
+}
+
+// Below code ripped straight from http://golang.org/src/pkg/time/format.go?s=33392:33438#L1123
+var errLeadingInt = errors.New("units: bad [0-9]*") // never printed
+
+// leadingInt consumes the leading [0-9]* from s.
+func leadingInt(s string) (x int64, rem string, err error) {
+ i := 0
+ for ; i < len(s); i++ {
+ c := s[i]
+ if c < '0' || c > '9' {
+ break
+ }
+ if x >= (1<<63-10)/10 {
+ // overflow
+ return 0, "", errLeadingInt
+ }
+ x = x*10 + int64(c) - '0'
+ }
+ return x, s[i:], nil
+}
+
+func ParseUnit(s string, unitMap map[string]float64) (int64, error) {
+ // [-+]?([0-9]*(\.[0-9]*)?[a-z]+)+
+ orig := s
+ f := float64(0)
+ neg := false
+
+ // Consume [-+]?
+ if s != "" {
+ c := s[0]
+ if c == '-' || c == '+' {
+ neg = c == '-'
+ s = s[1:]
+ }
+ }
+ // Special case: if all that is left is "0", this is zero.
+ if s == "0" {
+ return 0, nil
+ }
+ if s == "" {
+ return 0, errors.New("units: invalid " + orig)
+ }
+ for s != "" {
+ g := float64(0) // this element of the sequence
+
+ var x int64
+ var err error
+
+ // The next character must be [0-9.]
+ if !(s[0] == '.' || ('0' <= s[0] && s[0] <= '9')) {
+ return 0, errors.New("units: invalid " + orig)
+ }
+ // Consume [0-9]*
+ pl := len(s)
+ x, s, err = leadingInt(s)
+ if err != nil {
+ return 0, errors.New("units: invalid " + orig)
+ }
+ g = float64(x)
+ pre := pl != len(s) // whether we consumed anything before a period
+
+ // Consume (\.[0-9]*)?
+ post := false
+ if s != "" && s[0] == '.' {
+ s = s[1:]
+ pl := len(s)
+ x, s, err = leadingInt(s)
+ if err != nil {
+ return 0, errors.New("units: invalid " + orig)
+ }
+ scale := 1.0
+ for n := pl - len(s); n > 0; n-- {
+ scale *= 10
+ }
+ g += float64(x) / scale
+ post = pl != len(s)
+ }
+ if !pre && !post {
+ // no digits (e.g. ".s" or "-.s")
+ return 0, errors.New("units: invalid " + orig)
+ }
+
+ // Consume unit.
+ i := 0
+ for ; i < len(s); i++ {
+ c := s[i]
+ if c == '.' || ('0' <= c && c <= '9') {
+ break
+ }
+ }
+ u := s[:i]
+ s = s[i:]
+ unit, ok := unitMap[u]
+ if !ok {
+ return 0, errors.New("units: unknown unit " + u + " in " + orig)
+ }
+
+ f += g * unit
+ }
+
+ if neg {
+ f = -f
+ }
+ if f < float64(-1<<63) || f > float64(1<<63-1) {
+ return 0, errors.New("units: overflow parsing unit")
+ }
+ return int64(f), nil
+}
diff --git a/vendor/github.com/coreos/ignition/config/vendor/github.com/coreos/go-semver/.travis.yml b/vendor/github.com/coreos/ignition/config/vendor/github.com/coreos/go-semver/.travis.yml
new file mode 100644
index 00000000..7f9a0e6b
--- /dev/null
+++ b/vendor/github.com/coreos/ignition/config/vendor/github.com/coreos/go-semver/.travis.yml
@@ -0,0 +1,7 @@
+language: go
+go:
+ - 1.4
+ - 1.5
+ - 1.6
+ - tip
+script: cd semver && go test
diff --git a/vendor/github.com/coreos/ignition/config/vendor/github.com/coreos/go-semver/LICENSE b/vendor/github.com/coreos/ignition/config/vendor/github.com/coreos/go-semver/LICENSE
new file mode 100644
index 00000000..d6456956
--- /dev/null
+++ b/vendor/github.com/coreos/ignition/config/vendor/github.com/coreos/go-semver/LICENSE
@@ -0,0 +1,202 @@
+
+ Apache License
+ Version 2.0, January 2004
+ http://www.apache.org/licenses/
+
+ TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION
+
+ 1. Definitions.
+
+ "License" shall mean the terms and conditions for use, reproduction,
+ and distribution as defined by Sections 1 through 9 of this document.
+
+ "Licensor" shall mean the copyright owner or entity authorized by
+ the copyright owner that is granting the License.
+
+ "Legal Entity" shall mean the union of the acting entity and all
+ other entities that control, are controlled by, or are under common
+ control with that entity. For the purposes of this definition,
+ "control" means (i) the power, direct or indirect, to cause the
+ direction or management of such entity, whether by contract or
+ otherwise, or (ii) ownership of fifty percent (50%) or more of the
+ outstanding shares, or (iii) beneficial ownership of such entity.
+
+ "You" (or "Your") shall mean an individual or Legal Entity
+ exercising permissions granted by this License.
+
+ "Source" form shall mean the preferred form for making modifications,
+ including but not limited to software source code, documentation
+ source, and configuration files.
+
+ "Object" form shall mean any form resulting from mechanical
+ transformation or translation of a Source form, including but
+ not limited to compiled object code, generated documentation,
+ and conversions to other media types.
+
+ "Work" shall mean the work of authorship, whether in Source or
+ Object form, made available under the License, as indicated by a
+ copyright notice that is included in or attached to the work
+ (an example is provided in the Appendix below).
+
+ "Derivative Works" shall mean any work, whether in Source or Object
+ form, that is based on (or derived from) the Work and for which the
+ editorial revisions, annotations, elaborations, or other modifications
+ represent, as a whole, an original work of authorship. For the purposes
+ of this License, Derivative Works shall not include works that remain
+ separable from, or merely link (or bind by name) to the interfaces of,
+ the Work and Derivative Works thereof.
+
+ "Contribution" shall mean any work of authorship, including
+ the original version of the Work and any modifications or additions
+ to that Work or Derivative Works thereof, that is intentionally
+ submitted to Licensor for inclusion in the Work by the copyright owner
+ or by an individual or Legal Entity authorized to submit on behalf of
+ the copyright owner. For the purposes of this definition, "submitted"
+ means any form of electronic, verbal, or written communication sent
+ to the Licensor or its representatives, including but not limited to
+ communication on electronic mailing lists, source code control systems,
+ and issue tracking systems that are managed by, or on behalf of, the
+ Licensor for the purpose of discussing and improving the Work, but
+ excluding communication that is conspicuously marked or otherwise
+ designated in writing by the copyright owner as "Not a Contribution."
+
+ "Contributor" shall mean Licensor and any individual or Legal Entity
+ on behalf of whom a Contribution has been received by Licensor and
+ subsequently incorporated within the Work.
+
+ 2. Grant of Copyright License. Subject to the terms and conditions of
+ this License, each Contributor hereby grants to You a perpetual,
+ worldwide, non-exclusive, no-charge, royalty-free, irrevocable
+ copyright license to reproduce, prepare Derivative Works of,
+ publicly display, publicly perform, sublicense, and distribute the
+ Work and such Derivative Works in Source or Object form.
+
+ 3. Grant of Patent License. Subject to the terms and conditions of
+ this License, each Contributor hereby grants to You a perpetual,
+ worldwide, non-exclusive, no-charge, royalty-free, irrevocable
+ (except as stated in this section) patent license to make, have made,
+ use, offer to sell, sell, import, and otherwise transfer the Work,
+ where such license applies only to those patent claims licensable
+ by such Contributor that are necessarily infringed by their
+ Contribution(s) alone or by combination of their Contribution(s)
+ with the Work to which such Contribution(s) was submitted. If You
+ institute patent litigation against any entity (including a
+ cross-claim or counterclaim in a lawsuit) alleging that the Work
+ or a Contribution incorporated within the Work constitutes direct
+ or contributory patent infringement, then any patent licenses
+ granted to You under this License for that Work shall terminate
+ as of the date such litigation is filed.
+
+ 4. Redistribution. You may reproduce and distribute copies of the
+ Work or Derivative Works thereof in any medium, with or without
+ modifications, and in Source or Object form, provided that You
+ meet the following conditions:
+
+ (a) You must give any other recipients of the Work or
+ Derivative Works a copy of this License; and
+
+ (b) You must cause any modified files to carry prominent notices
+ stating that You changed the files; and
+
+ (c) You must retain, in the Source form of any Derivative Works
+ that You distribute, all copyright, patent, trademark, and
+ attribution notices from the Source form of the Work,
+ excluding those notices that do not pertain to any part of
+ the Derivative Works; and
+
+ (d) If the Work includes a "NOTICE" text file as part of its
+ distribution, then any Derivative Works that You distribute must
+ include a readable copy of the attribution notices contained
+ within such NOTICE file, excluding those notices that do not
+ pertain to any part of the Derivative Works, in at least one
+ of the following places: within a NOTICE text file distributed
+ as part of the Derivative Works; within the Source form or
+ documentation, if provided along with the Derivative Works; or,
+ within a display generated by the Derivative Works, if and
+ wherever such third-party notices normally appear. The contents
+ of the NOTICE file are for informational purposes only and
+ do not modify the License. You may add Your own attribution
+ notices within Derivative Works that You distribute, alongside
+ or as an addendum to the NOTICE text from the Work, provided
+ that such additional attribution notices cannot be construed
+ as modifying the License.
+
+ You may add Your own copyright statement to Your modifications and
+ may provide additional or different license terms and conditions
+ for use, reproduction, or distribution of Your modifications, or
+ for any such Derivative Works as a whole, provided Your use,
+ reproduction, and distribution of the Work otherwise complies with
+ the conditions stated in this License.
+
+ 5. Submission of Contributions. Unless You explicitly state otherwise,
+ any Contribution intentionally submitted for inclusion in the Work
+ by You to the Licensor shall be under the terms and conditions of
+ this License, without any additional terms or conditions.
+ Notwithstanding the above, nothing herein shall supersede or modify
+ the terms of any separate license agreement you may have executed
+ with Licensor regarding such Contributions.
+
+ 6. Trademarks. This License does not grant permission to use the trade
+ names, trademarks, service marks, or product names of the Licensor,
+ except as required for reasonable and customary use in describing the
+ origin of the Work and reproducing the content of the NOTICE file.
+
+ 7. Disclaimer of Warranty. Unless required by applicable law or
+ agreed to in writing, Licensor provides the Work (and each
+ Contributor provides its Contributions) on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
+ implied, including, without limitation, any warranties or conditions
+ of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A
+ PARTICULAR PURPOSE. You are solely responsible for determining the
+ appropriateness of using or redistributing the Work and assume any
+ risks associated with Your exercise of permissions under this License.
+
+ 8. Limitation of Liability. In no event and under no legal theory,
+ whether in tort (including negligence), contract, or otherwise,
+ unless required by applicable law (such as deliberate and grossly
+ negligent acts) or agreed to in writing, shall any Contributor be
+ liable to You for damages, including any direct, indirect, special,
+ incidental, or consequential damages of any character arising as a
+ result of this License or out of the use or inability to use the
+ Work (including but not limited to damages for loss of goodwill,
+ work stoppage, computer failure or malfunction, or any and all
+ other commercial damages or losses), even if such Contributor
+ has been advised of the possibility of such damages.
+
+ 9. Accepting Warranty or Additional Liability. While redistributing
+ the Work or Derivative Works thereof, You may choose to offer,
+ and charge a fee for, acceptance of support, warranty, indemnity,
+ or other liability obligations and/or rights consistent with this
+ License. However, in accepting such obligations, You may act only
+ on Your own behalf and on Your sole responsibility, not on behalf
+ of any other Contributor, and only if You agree to indemnify,
+ defend, and hold each Contributor harmless for any liability
+ incurred by, or claims asserted against, such Contributor by reason
+ of your accepting any such warranty or additional liability.
+
+ END OF TERMS AND CONDITIONS
+
+ APPENDIX: How to apply the Apache License to your work.
+
+ To apply the Apache License to your work, attach the following
+ boilerplate notice, with the fields enclosed by brackets "[]"
+ replaced with your own identifying information. (Don't include
+ the brackets!) The text should be enclosed in the appropriate
+ comment syntax for the file format. We also recommend that a
+ file or class name and description of purpose be included on the
+ same "printed page" as the copyright notice for easier
+ identification within third-party archives.
+
+ Copyright [yyyy] [name of copyright owner]
+
+ Licensed under the Apache License, Version 2.0 (the "License");
+ you may not use this file except in compliance with the License.
+ You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License.
diff --git a/vendor/github.com/coreos/ignition/config/vendor/github.com/coreos/go-semver/README.md b/vendor/github.com/coreos/ignition/config/vendor/github.com/coreos/go-semver/README.md
new file mode 100644
index 00000000..80006334
--- /dev/null
+++ b/vendor/github.com/coreos/ignition/config/vendor/github.com/coreos/go-semver/README.md
@@ -0,0 +1,31 @@
+# go-semver - Semantic Versioning Library
+
+[](https://travis-ci.org/coreos/go-semver)
+
+go-semver is a [semantic versioning][semver] library for Go. It lets you parse
+and compare two semantic version strings.
+
+[semver]: http://semver.org/
+
+## Usage
+
+```
+vA, err := semver.NewVersion("1.2.3")
+vB, err := semver.NewVersion("3.2.1")
+
+fmt.Printf("%s < %s == %t\n", vA, vB, vA.LessThan(*vB))
+```
+
+## Example Application
+
+```
+$ go run example.go 1.2.3 3.2.1
+1.2.3 < 3.2.1 == true
+
+$ go run example.go 5.2.3 3.2.1
+5.2.3 < 3.2.1 == false
+```
+
+## TODO
+
+- Richer comparision operations
diff --git a/vendor/github.com/coreos/ignition/config/vendor/github.com/coreos/go-semver/example.go b/vendor/github.com/coreos/ignition/config/vendor/github.com/coreos/go-semver/example.go
new file mode 100644
index 00000000..fd2ee5af
--- /dev/null
+++ b/vendor/github.com/coreos/ignition/config/vendor/github.com/coreos/go-semver/example.go
@@ -0,0 +1,20 @@
+package main
+
+import (
+ "fmt"
+ "github.com/coreos/go-semver/semver"
+ "os"
+)
+
+func main() {
+ vA, err := semver.NewVersion(os.Args[1])
+ if err != nil {
+ fmt.Println(err.Error())
+ }
+ vB, err := semver.NewVersion(os.Args[2])
+ if err != nil {
+ fmt.Println(err.Error())
+ }
+
+ fmt.Printf("%s < %s == %t\n", vA, vB, vA.LessThan(*vB))
+}
diff --git a/vendor/github.com/coreos/ignition/config/vendor/github.com/coreos/go-semver/semver/semver.go b/vendor/github.com/coreos/ignition/config/vendor/github.com/coreos/go-semver/semver/semver.go
new file mode 100644
index 00000000..000a0205
--- /dev/null
+++ b/vendor/github.com/coreos/ignition/config/vendor/github.com/coreos/go-semver/semver/semver.go
@@ -0,0 +1,257 @@
+// Copyright 2013-2015 CoreOS, Inc.
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+// http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+// Semantic Versions http://semver.org
+package semver
+
+import (
+ "bytes"
+ "errors"
+ "fmt"
+ "strconv"
+ "strings"
+)
+
+type Version struct {
+ Major int64
+ Minor int64
+ Patch int64
+ PreRelease PreRelease
+ Metadata string
+}
+
+type PreRelease string
+
+func splitOff(input *string, delim string) (val string) {
+ parts := strings.SplitN(*input, delim, 2)
+
+ if len(parts) == 2 {
+ *input = parts[0]
+ val = parts[1]
+ }
+
+ return val
+}
+
+func NewVersion(version string) (*Version, error) {
+ v := Version{}
+
+ v.Metadata = splitOff(&version, "+")
+ v.PreRelease = PreRelease(splitOff(&version, "-"))
+
+ dotParts := strings.SplitN(version, ".", 3)
+
+ if len(dotParts) != 3 {
+ return nil, errors.New(fmt.Sprintf("%s is not in dotted-tri format", version))
+ }
+
+ parsed := make([]int64, 3, 3)
+
+ for i, v := range dotParts[:3] {
+ val, err := strconv.ParseInt(v, 10, 64)
+ parsed[i] = val
+ if err != nil {
+ return nil, err
+ }
+ }
+
+ v.Major = parsed[0]
+ v.Minor = parsed[1]
+ v.Patch = parsed[2]
+
+ return &v, nil
+}
+
+func Must(v *Version, err error) *Version {
+ if err != nil {
+ panic(err)
+ }
+ return v
+}
+
+func (v Version) String() string {
+ var buffer bytes.Buffer
+
+ fmt.Fprintf(&buffer, "%d.%d.%d", v.Major, v.Minor, v.Patch)
+
+ if v.PreRelease != "" {
+ fmt.Fprintf(&buffer, "-%s", v.PreRelease)
+ }
+
+ if v.Metadata != "" {
+ fmt.Fprintf(&buffer, "+%s", v.Metadata)
+ }
+
+ return buffer.String()
+}
+
+func (v *Version) UnmarshalYAML(unmarshal func(interface{}) error) error {
+ var data string
+ if err := unmarshal(&data); err != nil {
+ return err
+ }
+ vv, err := NewVersion(data)
+ if err != nil {
+ return err
+ }
+ *v = *vv
+ return nil
+}
+
+func (v Version) MarshalJSON() ([]byte, error) {
+ return []byte(`"` + v.String() + `"`), nil
+}
+
+func (v *Version) UnmarshalJSON(data []byte) error {
+ l := len(data)
+ if l == 0 || string(data) == `""` {
+ return nil
+ }
+ if l < 2 || data[0] != '"' || data[l-1] != '"' {
+ return errors.New("invalid semver string")
+ }
+ vv, err := NewVersion(string(data[1 : l-1]))
+ if err != nil {
+ return err
+ }
+ *v = *vv
+ return nil
+}
+
+func (v Version) LessThan(versionB Version) bool {
+ versionA := v
+ cmp := recursiveCompare(versionA.Slice(), versionB.Slice())
+
+ if cmp == 0 {
+ cmp = preReleaseCompare(versionA, versionB)
+ }
+
+ if cmp == -1 {
+ return true
+ }
+
+ return false
+}
+
+/* Slice converts the comparable parts of the semver into a slice of strings */
+func (v Version) Slice() []int64 {
+ return []int64{v.Major, v.Minor, v.Patch}
+}
+
+func (p PreRelease) Slice() []string {
+ preRelease := string(p)
+ return strings.Split(preRelease, ".")
+}
+
+func preReleaseCompare(versionA Version, versionB Version) int {
+ a := versionA.PreRelease
+ b := versionB.PreRelease
+
+ /* Handle the case where if two versions are otherwise equal it is the
+ * one without a PreRelease that is greater */
+ if len(a) == 0 && (len(b) > 0) {
+ return 1
+ } else if len(b) == 0 && (len(a) > 0) {
+ return -1
+ }
+
+ // If there is a prelease, check and compare each part.
+ return recursivePreReleaseCompare(a.Slice(), b.Slice())
+}
+
+func recursiveCompare(versionA []int64, versionB []int64) int {
+ if len(versionA) == 0 {
+ return 0
+ }
+
+ a := versionA[0]
+ b := versionB[0]
+
+ if a > b {
+ return 1
+ } else if a < b {
+ return -1
+ }
+
+ return recursiveCompare(versionA[1:], versionB[1:])
+}
+
+func recursivePreReleaseCompare(versionA []string, versionB []string) int {
+ // Handle slice length disparity.
+ if len(versionA) == 0 {
+ // Nothing to compare too, so we return 0
+ return 0
+ } else if len(versionB) == 0 {
+ // We're longer than versionB so return 1.
+ return 1
+ }
+
+ a := versionA[0]
+ b := versionB[0]
+
+ aInt := false
+ bInt := false
+
+ aI, err := strconv.Atoi(versionA[0])
+ if err == nil {
+ aInt = true
+ }
+
+ bI, err := strconv.Atoi(versionB[0])
+ if err == nil {
+ bInt = true
+ }
+
+ // Handle Integer Comparison
+ if aInt && bInt {
+ if aI > bI {
+ return 1
+ } else if aI < bI {
+ return -1
+ }
+ }
+
+ // Handle String Comparison
+ if a > b {
+ return 1
+ } else if a < b {
+ return -1
+ }
+
+ return recursivePreReleaseCompare(versionA[1:], versionB[1:])
+}
+
+// BumpMajor increments the Major field by 1 and resets all other fields to their default values
+func (v *Version) BumpMajor() {
+ v.Major += 1
+ v.Minor = 0
+ v.Patch = 0
+ v.PreRelease = PreRelease("")
+ v.Metadata = ""
+}
+
+// BumpMinor increments the Minor field by 1 and resets all other fields to their default values
+func (v *Version) BumpMinor() {
+ v.Minor += 1
+ v.Patch = 0
+ v.PreRelease = PreRelease("")
+ v.Metadata = ""
+}
+
+// BumpPatch increments the Patch field by 1 and resets all other fields to their default values
+func (v *Version) BumpPatch() {
+ v.Patch += 1
+ v.PreRelease = PreRelease("")
+ v.Metadata = ""
+}
diff --git a/vendor/github.com/coreos/ignition/config/vendor/github.com/coreos/go-semver/semver/semver_test.go b/vendor/github.com/coreos/ignition/config/vendor/github.com/coreos/go-semver/semver/semver_test.go
new file mode 100644
index 00000000..8a6e200a
--- /dev/null
+++ b/vendor/github.com/coreos/ignition/config/vendor/github.com/coreos/go-semver/semver/semver_test.go
@@ -0,0 +1,330 @@
+// Copyright 2013-2015 CoreOS, Inc.
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+// http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+package semver
+
+import (
+ "bytes"
+ "encoding/json"
+ "errors"
+ "math/rand"
+ "reflect"
+ "testing"
+ "time"
+
+ "gopkg.in/yaml.v2"
+)
+
+type fixture struct {
+ GreaterVersion string
+ LesserVersion string
+}
+
+var fixtures = []fixture{
+ fixture{"0.0.0", "0.0.0-foo"},
+ fixture{"0.0.1", "0.0.0"},
+ fixture{"1.0.0", "0.9.9"},
+ fixture{"0.10.0", "0.9.0"},
+ fixture{"0.99.0", "0.10.0"},
+ fixture{"2.0.0", "1.2.3"},
+ fixture{"0.0.0", "0.0.0-foo"},
+ fixture{"0.0.1", "0.0.0"},
+ fixture{"1.0.0", "0.9.9"},
+ fixture{"0.10.0", "0.9.0"},
+ fixture{"0.99.0", "0.10.0"},
+ fixture{"2.0.0", "1.2.3"},
+ fixture{"0.0.0", "0.0.0-foo"},
+ fixture{"0.0.1", "0.0.0"},
+ fixture{"1.0.0", "0.9.9"},
+ fixture{"0.10.0", "0.9.0"},
+ fixture{"0.99.0", "0.10.0"},
+ fixture{"2.0.0", "1.2.3"},
+ fixture{"1.2.3", "1.2.3-asdf"},
+ fixture{"1.2.3", "1.2.3-4"},
+ fixture{"1.2.3", "1.2.3-4-foo"},
+ fixture{"1.2.3-5-foo", "1.2.3-5"},
+ fixture{"1.2.3-5", "1.2.3-4"},
+ fixture{"1.2.3-5-foo", "1.2.3-5-Foo"},
+ fixture{"3.0.0", "2.7.2+asdf"},
+ fixture{"3.0.0+foobar", "2.7.2"},
+ fixture{"1.2.3-a.10", "1.2.3-a.5"},
+ fixture{"1.2.3-a.b", "1.2.3-a.5"},
+ fixture{"1.2.3-a.b", "1.2.3-a"},
+ fixture{"1.2.3-a.b.c.10.d.5", "1.2.3-a.b.c.5.d.100"},
+ fixture{"1.0.0", "1.0.0-rc.1"},
+ fixture{"1.0.0-rc.2", "1.0.0-rc.1"},
+ fixture{"1.0.0-rc.1", "1.0.0-beta.11"},
+ fixture{"1.0.0-beta.11", "1.0.0-beta.2"},
+ fixture{"1.0.0-beta.2", "1.0.0-beta"},
+ fixture{"1.0.0-beta", "1.0.0-alpha.beta"},
+ fixture{"1.0.0-alpha.beta", "1.0.0-alpha.1"},
+ fixture{"1.0.0-alpha.1", "1.0.0-alpha"},
+}
+
+func TestCompare(t *testing.T) {
+ for _, v := range fixtures {
+ gt, err := NewVersion(v.GreaterVersion)
+ if err != nil {
+ t.Error(err)
+ }
+
+ lt, err := NewVersion(v.LesserVersion)
+ if err != nil {
+ t.Error(err)
+ }
+
+ if gt.LessThan(*lt) == true {
+ t.Errorf("%s should not be less than %s", gt, lt)
+ }
+ }
+}
+
+func testString(t *testing.T, orig string, version *Version) {
+ if orig != version.String() {
+ t.Errorf("%s != %s", orig, version)
+ }
+}
+
+func TestString(t *testing.T) {
+ for _, v := range fixtures {
+ gt, err := NewVersion(v.GreaterVersion)
+ if err != nil {
+ t.Error(err)
+ }
+ testString(t, v.GreaterVersion, gt)
+
+ lt, err := NewVersion(v.LesserVersion)
+ if err != nil {
+ t.Error(err)
+ }
+ testString(t, v.LesserVersion, lt)
+ }
+}
+
+func shuffleStringSlice(src []string) []string {
+ dest := make([]string, len(src))
+ rand.Seed(time.Now().Unix())
+ perm := rand.Perm(len(src))
+ for i, v := range perm {
+ dest[v] = src[i]
+ }
+ return dest
+}
+
+func TestSort(t *testing.T) {
+ sortedVersions := []string{"1.0.0", "1.0.2", "1.2.0", "3.1.1"}
+ unsortedVersions := shuffleStringSlice(sortedVersions)
+
+ semvers := []*Version{}
+ for _, v := range unsortedVersions {
+ sv, err := NewVersion(v)
+ if err != nil {
+ t.Fatal(err)
+ }
+ semvers = append(semvers, sv)
+ }
+
+ Sort(semvers)
+
+ for idx, sv := range semvers {
+ if sv.String() != sortedVersions[idx] {
+ t.Fatalf("incorrect sort at index %v", idx)
+ }
+ }
+}
+
+func TestBumpMajor(t *testing.T) {
+ version, _ := NewVersion("1.0.0")
+ version.BumpMajor()
+ if version.Major != 2 {
+ t.Fatalf("bumping major on 1.0.0 resulted in %v", version)
+ }
+
+ version, _ = NewVersion("1.5.2")
+ version.BumpMajor()
+ if version.Minor != 0 && version.Patch != 0 {
+ t.Fatalf("bumping major on 1.5.2 resulted in %v", version)
+ }
+
+ version, _ = NewVersion("1.0.0+build.1-alpha.1")
+ version.BumpMajor()
+ if version.PreRelease != "" && version.PreRelease != "" {
+ t.Fatalf("bumping major on 1.0.0+build.1-alpha.1 resulted in %v", version)
+ }
+}
+
+func TestBumpMinor(t *testing.T) {
+ version, _ := NewVersion("1.0.0")
+ version.BumpMinor()
+
+ if version.Major != 1 {
+ t.Fatalf("bumping minor on 1.0.0 resulted in %v", version)
+ }
+
+ if version.Minor != 1 {
+ t.Fatalf("bumping major on 1.0.0 resulted in %v", version)
+ }
+
+ version, _ = NewVersion("1.0.0+build.1-alpha.1")
+ version.BumpMinor()
+ if version.PreRelease != "" && version.PreRelease != "" {
+ t.Fatalf("bumping major on 1.0.0+build.1-alpha.1 resulted in %v", version)
+ }
+}
+
+func TestBumpPatch(t *testing.T) {
+ version, _ := NewVersion("1.0.0")
+ version.BumpPatch()
+
+ if version.Major != 1 {
+ t.Fatalf("bumping minor on 1.0.0 resulted in %v", version)
+ }
+
+ if version.Minor != 0 {
+ t.Fatalf("bumping major on 1.0.0 resulted in %v", version)
+ }
+
+ if version.Patch != 1 {
+ t.Fatalf("bumping major on 1.0.0 resulted in %v", version)
+ }
+
+ version, _ = NewVersion("1.0.0+build.1-alpha.1")
+ version.BumpPatch()
+ if version.PreRelease != "" && version.PreRelease != "" {
+ t.Fatalf("bumping major on 1.0.0+build.1-alpha.1 resulted in %v", version)
+ }
+}
+
+func TestMust(t *testing.T) {
+ tests := []struct {
+ versionStr string
+
+ version *Version
+ recov interface{}
+ }{
+ {
+ versionStr: "1.0.0",
+ version: &Version{Major: 1},
+ },
+ {
+ versionStr: "version number",
+ recov: errors.New("version number is not in dotted-tri format"),
+ },
+ }
+
+ for _, tt := range tests {
+ func() {
+ defer func() {
+ recov := recover()
+ if !reflect.DeepEqual(tt.recov, recov) {
+ t.Fatalf("incorrect panic for %q: want %v, got %v", tt.versionStr, tt.recov, recov)
+ }
+ }()
+
+ version := Must(NewVersion(tt.versionStr))
+ if !reflect.DeepEqual(tt.version, version) {
+ t.Fatalf("incorrect version for %q: want %+v, got %+v", tt.versionStr, tt.version, version)
+ }
+ }()
+ }
+}
+
+type fixtureJSON struct {
+ GreaterVersion *Version
+ LesserVersion *Version
+}
+
+func TestJSON(t *testing.T) {
+ fj := make([]fixtureJSON, len(fixtures))
+ for i, v := range fixtures {
+ var err error
+ fj[i].GreaterVersion, err = NewVersion(v.GreaterVersion)
+ if err != nil {
+ t.Fatal(err)
+ }
+ fj[i].LesserVersion, err = NewVersion(v.LesserVersion)
+ if err != nil {
+ t.Fatal(err)
+ }
+ }
+
+ fromStrings, err := json.Marshal(fixtures)
+ if err != nil {
+ t.Fatal(err)
+ }
+ fromVersions, err := json.Marshal(fj)
+ if err != nil {
+ t.Fatal(err)
+ }
+ if !bytes.Equal(fromStrings, fromVersions) {
+ t.Errorf("Expected: %s", fromStrings)
+ t.Errorf("Unexpected: %s", fromVersions)
+ }
+
+ fromJson := make([]fixtureJSON, 0, len(fj))
+ err = json.Unmarshal(fromStrings, &fromJson)
+ if err != nil {
+ t.Fatal(err)
+ }
+ if !reflect.DeepEqual(fromJson, fj) {
+ t.Error("Expected: ", fj)
+ t.Error("Unexpected: ", fromJson)
+ }
+}
+
+func TestYAML(t *testing.T) {
+ document, err := yaml.Marshal(fixtures)
+ if err != nil {
+ t.Fatal(err)
+ }
+
+ expected := make([]fixtureJSON, len(fixtures))
+ for i, v := range fixtures {
+ var err error
+ expected[i].GreaterVersion, err = NewVersion(v.GreaterVersion)
+ if err != nil {
+ t.Fatal(err)
+ }
+ expected[i].LesserVersion, err = NewVersion(v.LesserVersion)
+ if err != nil {
+ t.Fatal(err)
+ }
+ }
+
+ fromYAML := make([]fixtureJSON, 0, len(fixtures))
+ err = yaml.Unmarshal(document, &fromYAML)
+ if err != nil {
+ t.Fatal(err)
+ }
+
+ if !reflect.DeepEqual(fromYAML, expected) {
+ t.Error("Expected: ", expected)
+ t.Error("Unexpected: ", fromYAML)
+ }
+}
+
+func TestBadInput(t *testing.T) {
+ bad := []string{
+ "1.2",
+ "1.2.3x",
+ "0x1.3.4",
+ "-1.2.3",
+ "1.2.3.4",
+ }
+ for _, b := range bad {
+ if _, err := NewVersion(b); err == nil {
+ t.Error("Improperly accepted value: ", b)
+ }
+ }
+}
diff --git a/vendor/github.com/coreos/ignition/config/vendor/github.com/coreos/go-semver/semver/sort.go b/vendor/github.com/coreos/ignition/config/vendor/github.com/coreos/go-semver/semver/sort.go
new file mode 100644
index 00000000..e256b41a
--- /dev/null
+++ b/vendor/github.com/coreos/ignition/config/vendor/github.com/coreos/go-semver/semver/sort.go
@@ -0,0 +1,38 @@
+// Copyright 2013-2015 CoreOS, Inc.
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+// http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+package semver
+
+import (
+ "sort"
+)
+
+type Versions []*Version
+
+func (s Versions) Len() int {
+ return len(s)
+}
+
+func (s Versions) Swap(i, j int) {
+ s[i], s[j] = s[j], s[i]
+}
+
+func (s Versions) Less(i, j int) bool {
+ return s[i].LessThan(*s[j])
+}
+
+// Sort sorts the given slice of Version
+func Sort(versions []*Version) {
+ sort.Sort(Versions(versions))
+}
diff --git a/vendor/github.com/coreos/ignition/config/vendor/github.com/go-yaml/yaml/LICENSE b/vendor/github.com/coreos/ignition/config/vendor/github.com/go-yaml/yaml/LICENSE
new file mode 100644
index 00000000..a68e67f0
--- /dev/null
+++ b/vendor/github.com/coreos/ignition/config/vendor/github.com/go-yaml/yaml/LICENSE
@@ -0,0 +1,188 @@
+
+Copyright (c) 2011-2014 - Canonical Inc.
+
+This software is licensed under the LGPLv3, included below.
+
+As a special exception to the GNU Lesser General Public License version 3
+("LGPL3"), the copyright holders of this Library give you permission to
+convey to a third party a Combined Work that links statically or dynamically
+to this Library without providing any Minimal Corresponding Source or
+Minimal Application Code as set out in 4d or providing the installation
+information set out in section 4e, provided that you comply with the other
+provisions of LGPL3 and provided that you meet, for the Application the
+terms and conditions of the license(s) which apply to the Application.
+
+Except as stated in this special exception, the provisions of LGPL3 will
+continue to comply in full to this Library. If you modify this Library, you
+may apply this exception to your version of this Library, but you are not
+obliged to do so. If you do not wish to do so, delete this exception
+statement from your version. This exception does not (and cannot) modify any
+license terms which apply to the Application, with which you must still
+comply.
+
+
+ GNU LESSER GENERAL PUBLIC LICENSE
+ Version 3, 29 June 2007
+
+ Copyright (C) 2007 Free Software Foundation, Inc.
+ Everyone is permitted to copy and distribute verbatim copies
+ of this license document, but changing it is not allowed.
+
+
+ This version of the GNU Lesser General Public License incorporates
+the terms and conditions of version 3 of the GNU General Public
+License, supplemented by the additional permissions listed below.
+
+ 0. Additional Definitions.
+
+ As used herein, "this License" refers to version 3 of the GNU Lesser
+General Public License, and the "GNU GPL" refers to version 3 of the GNU
+General Public License.
+
+ "The Library" refers to a covered work governed by this License,
+other than an Application or a Combined Work as defined below.
+
+ An "Application" is any work that makes use of an interface provided
+by the Library, but which is not otherwise based on the Library.
+Defining a subclass of a class defined by the Library is deemed a mode
+of using an interface provided by the Library.
+
+ A "Combined Work" is a work produced by combining or linking an
+Application with the Library. The particular version of the Library
+with which the Combined Work was made is also called the "Linked
+Version".
+
+ The "Minimal Corresponding Source" for a Combined Work means the
+Corresponding Source for the Combined Work, excluding any source code
+for portions of the Combined Work that, considered in isolation, are
+based on the Application, and not on the Linked Version.
+
+ The "Corresponding Application Code" for a Combined Work means the
+object code and/or source code for the Application, including any data
+and utility programs needed for reproducing the Combined Work from the
+Application, but excluding the System Libraries of the Combined Work.
+
+ 1. Exception to Section 3 of the GNU GPL.
+
+ You may convey a covered work under sections 3 and 4 of this License
+without being bound by section 3 of the GNU GPL.
+
+ 2. Conveying Modified Versions.
+
+ If you modify a copy of the Library, and, in your modifications, a
+facility refers to a function or data to be supplied by an Application
+that uses the facility (other than as an argument passed when the
+facility is invoked), then you may convey a copy of the modified
+version:
+
+ a) under this License, provided that you make a good faith effort to
+ ensure that, in the event an Application does not supply the
+ function or data, the facility still operates, and performs
+ whatever part of its purpose remains meaningful, or
+
+ b) under the GNU GPL, with none of the additional permissions of
+ this License applicable to that copy.
+
+ 3. Object Code Incorporating Material from Library Header Files.
+
+ The object code form of an Application may incorporate material from
+a header file that is part of the Library. You may convey such object
+code under terms of your choice, provided that, if the incorporated
+material is not limited to numerical parameters, data structure
+layouts and accessors, or small macros, inline functions and templates
+(ten or fewer lines in length), you do both of the following:
+
+ a) Give prominent notice with each copy of the object code that the
+ Library is used in it and that the Library and its use are
+ covered by this License.
+
+ b) Accompany the object code with a copy of the GNU GPL and this license
+ document.
+
+ 4. Combined Works.
+
+ You may convey a Combined Work under terms of your choice that,
+taken together, effectively do not restrict modification of the
+portions of the Library contained in the Combined Work and reverse
+engineering for debugging such modifications, if you also do each of
+the following:
+
+ a) Give prominent notice with each copy of the Combined Work that
+ the Library is used in it and that the Library and its use are
+ covered by this License.
+
+ b) Accompany the Combined Work with a copy of the GNU GPL and this license
+ document.
+
+ c) For a Combined Work that displays copyright notices during
+ execution, include the copyright notice for the Library among
+ these notices, as well as a reference directing the user to the
+ copies of the GNU GPL and this license document.
+
+ d) Do one of the following:
+
+ 0) Convey the Minimal Corresponding Source under the terms of this
+ License, and the Corresponding Application Code in a form
+ suitable for, and under terms that permit, the user to
+ recombine or relink the Application with a modified version of
+ the Linked Version to produce a modified Combined Work, in the
+ manner specified by section 6 of the GNU GPL for conveying
+ Corresponding Source.
+
+ 1) Use a suitable shared library mechanism for linking with the
+ Library. A suitable mechanism is one that (a) uses at run time
+ a copy of the Library already present on the user's computer
+ system, and (b) will operate properly with a modified version
+ of the Library that is interface-compatible with the Linked
+ Version.
+
+ e) Provide Installation Information, but only if you would otherwise
+ be required to provide such information under section 6 of the
+ GNU GPL, and only to the extent that such information is
+ necessary to install and execute a modified version of the
+ Combined Work produced by recombining or relinking the
+ Application with a modified version of the Linked Version. (If
+ you use option 4d0, the Installation Information must accompany
+ the Minimal Corresponding Source and Corresponding Application
+ Code. If you use option 4d1, you must provide the Installation
+ Information in the manner specified by section 6 of the GNU GPL
+ for conveying Corresponding Source.)
+
+ 5. Combined Libraries.
+
+ You may place library facilities that are a work based on the
+Library side by side in a single library together with other library
+facilities that are not Applications and are not covered by this
+License, and convey such a combined library under terms of your
+choice, if you do both of the following:
+
+ a) Accompany the combined library with a copy of the same work based
+ on the Library, uncombined with any other library facilities,
+ conveyed under the terms of this License.
+
+ b) Give prominent notice with the combined library that part of it
+ is a work based on the Library, and explaining where to find the
+ accompanying uncombined form of the same work.
+
+ 6. Revised Versions of the GNU Lesser General Public License.
+
+ The Free Software Foundation may publish revised and/or new versions
+of the GNU Lesser General Public License from time to time. Such new
+versions will be similar in spirit to the present version, but may
+differ in detail to address new problems or concerns.
+
+ Each version is given a distinguishing version number. If the
+Library as you received it specifies that a certain numbered version
+of the GNU Lesser General Public License "or any later version"
+applies to it, you have the option of following the terms and
+conditions either of that published version or of any later version
+published by the Free Software Foundation. If the Library as you
+received it does not specify a version number of the GNU Lesser
+General Public License, you may choose any version of the GNU Lesser
+General Public License ever published by the Free Software Foundation.
+
+ If the Library as you received it specifies that a proxy can decide
+whether future versions of the GNU Lesser General Public License shall
+apply, that proxy's public statement of acceptance of any version is
+permanent authorization for you to choose that version for the
+Library.
diff --git a/vendor/github.com/coreos/ignition/config/vendor/github.com/go-yaml/yaml/LICENSE.libyaml b/vendor/github.com/coreos/ignition/config/vendor/github.com/go-yaml/yaml/LICENSE.libyaml
new file mode 100644
index 00000000..8da58fbf
--- /dev/null
+++ b/vendor/github.com/coreos/ignition/config/vendor/github.com/go-yaml/yaml/LICENSE.libyaml
@@ -0,0 +1,31 @@
+The following files were ported to Go from C files of libyaml, and thus
+are still covered by their original copyright and license:
+
+ apic.go
+ emitterc.go
+ parserc.go
+ readerc.go
+ scannerc.go
+ writerc.go
+ yamlh.go
+ yamlprivateh.go
+
+Copyright (c) 2006 Kirill Simonov
+
+Permission is hereby granted, free of charge, to any person obtaining a copy of
+this software and associated documentation files (the "Software"), to deal in
+the Software without restriction, including without limitation the rights to
+use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies
+of the Software, and to permit persons to whom the Software is furnished to do
+so, subject to the following conditions:
+
+The above copyright notice and this permission notice shall be included in all
+copies or substantial portions of the Software.
+
+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
+SOFTWARE.
diff --git a/vendor/github.com/coreos/ignition/config/vendor/github.com/go-yaml/yaml/README.md b/vendor/github.com/coreos/ignition/config/vendor/github.com/go-yaml/yaml/README.md
new file mode 100644
index 00000000..d6c919e6
--- /dev/null
+++ b/vendor/github.com/coreos/ignition/config/vendor/github.com/go-yaml/yaml/README.md
@@ -0,0 +1,128 @@
+# YAML support for the Go language
+
+Introduction
+------------
+
+The yaml package enables Go programs to comfortably encode and decode YAML
+values. It was developed within [Canonical](https://www.canonical.com) as
+part of the [juju](https://juju.ubuntu.com) project, and is based on a
+pure Go port of the well-known [libyaml](http://pyyaml.org/wiki/LibYAML)
+C library to parse and generate YAML data quickly and reliably.
+
+Compatibility
+-------------
+
+The yaml package supports most of YAML 1.1 and 1.2, including support for
+anchors, tags, map merging, etc. Multi-document unmarshalling is not yet
+implemented, and base-60 floats from YAML 1.1 are purposefully not
+supported since they're a poor design and are gone in YAML 1.2.
+
+Installation and usage
+----------------------
+
+The import path for the package is *gopkg.in/yaml.v2*.
+
+To install it, run:
+
+ go get gopkg.in/yaml.v2
+
+API documentation
+-----------------
+
+If opened in a browser, the import path itself leads to the API documentation:
+
+ * [https://gopkg.in/yaml.v2](https://gopkg.in/yaml.v2)
+
+API stability
+-------------
+
+The package API for yaml v2 will remain stable as described in [gopkg.in](https://gopkg.in).
+
+
+License
+-------
+
+The yaml package is licensed under the LGPL with an exception that allows it to be linked statically. Please see the LICENSE file for details.
+
+
+Example
+-------
+
+```Go
+package main
+
+import (
+ "fmt"
+ "log"
+
+ "gopkg.in/yaml.v2"
+)
+
+var data = `
+a: Easy!
+b:
+ c: 2
+ d: [3, 4]
+`
+
+type T struct {
+ A string
+ B struct{C int; D []int ",flow"}
+}
+
+func main() {
+ t := T{}
+
+ err := yaml.Unmarshal([]byte(data), &t)
+ if err != nil {
+ log.Fatalf("error: %v", err)
+ }
+ fmt.Printf("--- t:\n%v\n\n", t)
+
+ d, err := yaml.Marshal(&t)
+ if err != nil {
+ log.Fatalf("error: %v", err)
+ }
+ fmt.Printf("--- t dump:\n%s\n\n", string(d))
+
+ m := make(map[interface{}]interface{})
+
+ err = yaml.Unmarshal([]byte(data), &m)
+ if err != nil {
+ log.Fatalf("error: %v", err)
+ }
+ fmt.Printf("--- m:\n%v\n\n", m)
+
+ d, err = yaml.Marshal(&m)
+ if err != nil {
+ log.Fatalf("error: %v", err)
+ }
+ fmt.Printf("--- m dump:\n%s\n\n", string(d))
+}
+```
+
+This example will generate the following output:
+
+```
+--- t:
+{Easy! {2 [3 4]}}
+
+--- t dump:
+a: Easy!
+b:
+ c: 2
+ d: [3, 4]
+
+
+--- m:
+map[a:Easy! b:map[c:2 d:[3 4]]]
+
+--- m dump:
+a: Easy!
+b:
+ c: 2
+ d:
+ - 3
+ - 4
+```
+
diff --git a/vendor/github.com/coreos/ignition/config/vendor/github.com/go-yaml/yaml/apic.go b/vendor/github.com/coreos/ignition/config/vendor/github.com/go-yaml/yaml/apic.go
new file mode 100644
index 00000000..95ec014e
--- /dev/null
+++ b/vendor/github.com/coreos/ignition/config/vendor/github.com/go-yaml/yaml/apic.go
@@ -0,0 +1,742 @@
+package yaml
+
+import (
+ "io"
+ "os"
+)
+
+func yaml_insert_token(parser *yaml_parser_t, pos int, token *yaml_token_t) {
+ //fmt.Println("yaml_insert_token", "pos:", pos, "typ:", token.typ, "head:", parser.tokens_head, "len:", len(parser.tokens))
+
+ // Check if we can move the queue at the beginning of the buffer.
+ if parser.tokens_head > 0 && len(parser.tokens) == cap(parser.tokens) {
+ if parser.tokens_head != len(parser.tokens) {
+ copy(parser.tokens, parser.tokens[parser.tokens_head:])
+ }
+ parser.tokens = parser.tokens[:len(parser.tokens)-parser.tokens_head]
+ parser.tokens_head = 0
+ }
+ parser.tokens = append(parser.tokens, *token)
+ if pos < 0 {
+ return
+ }
+ copy(parser.tokens[parser.tokens_head+pos+1:], parser.tokens[parser.tokens_head+pos:])
+ parser.tokens[parser.tokens_head+pos] = *token
+}
+
+// Create a new parser object.
+func yaml_parser_initialize(parser *yaml_parser_t) bool {
+ *parser = yaml_parser_t{
+ raw_buffer: make([]byte, 0, input_raw_buffer_size),
+ buffer: make([]byte, 0, input_buffer_size),
+ }
+ return true
+}
+
+// Destroy a parser object.
+func yaml_parser_delete(parser *yaml_parser_t) {
+ *parser = yaml_parser_t{}
+}
+
+// String read handler.
+func yaml_string_read_handler(parser *yaml_parser_t, buffer []byte) (n int, err error) {
+ if parser.input_pos == len(parser.input) {
+ return 0, io.EOF
+ }
+ n = copy(buffer, parser.input[parser.input_pos:])
+ parser.input_pos += n
+ return n, nil
+}
+
+// File read handler.
+func yaml_file_read_handler(parser *yaml_parser_t, buffer []byte) (n int, err error) {
+ return parser.input_file.Read(buffer)
+}
+
+// Set a string input.
+func yaml_parser_set_input_string(parser *yaml_parser_t, input []byte) {
+ if parser.read_handler != nil {
+ panic("must set the input source only once")
+ }
+ parser.read_handler = yaml_string_read_handler
+ parser.input = input
+ parser.input_pos = 0
+}
+
+// Set a file input.
+func yaml_parser_set_input_file(parser *yaml_parser_t, file *os.File) {
+ if parser.read_handler != nil {
+ panic("must set the input source only once")
+ }
+ parser.read_handler = yaml_file_read_handler
+ parser.input_file = file
+}
+
+// Set the source encoding.
+func yaml_parser_set_encoding(parser *yaml_parser_t, encoding yaml_encoding_t) {
+ if parser.encoding != yaml_ANY_ENCODING {
+ panic("must set the encoding only once")
+ }
+ parser.encoding = encoding
+}
+
+// Create a new emitter object.
+func yaml_emitter_initialize(emitter *yaml_emitter_t) bool {
+ *emitter = yaml_emitter_t{
+ buffer: make([]byte, output_buffer_size),
+ raw_buffer: make([]byte, 0, output_raw_buffer_size),
+ states: make([]yaml_emitter_state_t, 0, initial_stack_size),
+ events: make([]yaml_event_t, 0, initial_queue_size),
+ }
+ return true
+}
+
+// Destroy an emitter object.
+func yaml_emitter_delete(emitter *yaml_emitter_t) {
+ *emitter = yaml_emitter_t{}
+}
+
+// String write handler.
+func yaml_string_write_handler(emitter *yaml_emitter_t, buffer []byte) error {
+ *emitter.output_buffer = append(*emitter.output_buffer, buffer...)
+ return nil
+}
+
+// File write handler.
+func yaml_file_write_handler(emitter *yaml_emitter_t, buffer []byte) error {
+ _, err := emitter.output_file.Write(buffer)
+ return err
+}
+
+// Set a string output.
+func yaml_emitter_set_output_string(emitter *yaml_emitter_t, output_buffer *[]byte) {
+ if emitter.write_handler != nil {
+ panic("must set the output target only once")
+ }
+ emitter.write_handler = yaml_string_write_handler
+ emitter.output_buffer = output_buffer
+}
+
+// Set a file output.
+func yaml_emitter_set_output_file(emitter *yaml_emitter_t, file io.Writer) {
+ if emitter.write_handler != nil {
+ panic("must set the output target only once")
+ }
+ emitter.write_handler = yaml_file_write_handler
+ emitter.output_file = file
+}
+
+// Set the output encoding.
+func yaml_emitter_set_encoding(emitter *yaml_emitter_t, encoding yaml_encoding_t) {
+ if emitter.encoding != yaml_ANY_ENCODING {
+ panic("must set the output encoding only once")
+ }
+ emitter.encoding = encoding
+}
+
+// Set the canonical output style.
+func yaml_emitter_set_canonical(emitter *yaml_emitter_t, canonical bool) {
+ emitter.canonical = canonical
+}
+
+//// Set the indentation increment.
+func yaml_emitter_set_indent(emitter *yaml_emitter_t, indent int) {
+ if indent < 2 || indent > 9 {
+ indent = 2
+ }
+ emitter.best_indent = indent
+}
+
+// Set the preferred line width.
+func yaml_emitter_set_width(emitter *yaml_emitter_t, width int) {
+ if width < 0 {
+ width = -1
+ }
+ emitter.best_width = width
+}
+
+// Set if unescaped non-ASCII characters are allowed.
+func yaml_emitter_set_unicode(emitter *yaml_emitter_t, unicode bool) {
+ emitter.unicode = unicode
+}
+
+// Set the preferred line break character.
+func yaml_emitter_set_break(emitter *yaml_emitter_t, line_break yaml_break_t) {
+ emitter.line_break = line_break
+}
+
+///*
+// * Destroy a token object.
+// */
+//
+//YAML_DECLARE(void)
+//yaml_token_delete(yaml_token_t *token)
+//{
+// assert(token); // Non-NULL token object expected.
+//
+// switch (token.type)
+// {
+// case YAML_TAG_DIRECTIVE_TOKEN:
+// yaml_free(token.data.tag_directive.handle);
+// yaml_free(token.data.tag_directive.prefix);
+// break;
+//
+// case YAML_ALIAS_TOKEN:
+// yaml_free(token.data.alias.value);
+// break;
+//
+// case YAML_ANCHOR_TOKEN:
+// yaml_free(token.data.anchor.value);
+// break;
+//
+// case YAML_TAG_TOKEN:
+// yaml_free(token.data.tag.handle);
+// yaml_free(token.data.tag.suffix);
+// break;
+//
+// case YAML_SCALAR_TOKEN:
+// yaml_free(token.data.scalar.value);
+// break;
+//
+// default:
+// break;
+// }
+//
+// memset(token, 0, sizeof(yaml_token_t));
+//}
+//
+///*
+// * Check if a string is a valid UTF-8 sequence.
+// *
+// * Check 'reader.c' for more details on UTF-8 encoding.
+// */
+//
+//static int
+//yaml_check_utf8(yaml_char_t *start, size_t length)
+//{
+// yaml_char_t *end = start+length;
+// yaml_char_t *pointer = start;
+//
+// while (pointer < end) {
+// unsigned char octet;
+// unsigned int width;
+// unsigned int value;
+// size_t k;
+//
+// octet = pointer[0];
+// width = (octet & 0x80) == 0x00 ? 1 :
+// (octet & 0xE0) == 0xC0 ? 2 :
+// (octet & 0xF0) == 0xE0 ? 3 :
+// (octet & 0xF8) == 0xF0 ? 4 : 0;
+// value = (octet & 0x80) == 0x00 ? octet & 0x7F :
+// (octet & 0xE0) == 0xC0 ? octet & 0x1F :
+// (octet & 0xF0) == 0xE0 ? octet & 0x0F :
+// (octet & 0xF8) == 0xF0 ? octet & 0x07 : 0;
+// if (!width) return 0;
+// if (pointer+width > end) return 0;
+// for (k = 1; k < width; k ++) {
+// octet = pointer[k];
+// if ((octet & 0xC0) != 0x80) return 0;
+// value = (value << 6) + (octet & 0x3F);
+// }
+// if (!((width == 1) ||
+// (width == 2 && value >= 0x80) ||
+// (width == 3 && value >= 0x800) ||
+// (width == 4 && value >= 0x10000))) return 0;
+//
+// pointer += width;
+// }
+//
+// return 1;
+//}
+//
+
+// Create STREAM-START.
+func yaml_stream_start_event_initialize(event *yaml_event_t, encoding yaml_encoding_t) bool {
+ *event = yaml_event_t{
+ typ: yaml_STREAM_START_EVENT,
+ encoding: encoding,
+ }
+ return true
+}
+
+// Create STREAM-END.
+func yaml_stream_end_event_initialize(event *yaml_event_t) bool {
+ *event = yaml_event_t{
+ typ: yaml_STREAM_END_EVENT,
+ }
+ return true
+}
+
+// Create DOCUMENT-START.
+func yaml_document_start_event_initialize(event *yaml_event_t, version_directive *yaml_version_directive_t,
+ tag_directives []yaml_tag_directive_t, implicit bool) bool {
+ *event = yaml_event_t{
+ typ: yaml_DOCUMENT_START_EVENT,
+ version_directive: version_directive,
+ tag_directives: tag_directives,
+ implicit: implicit,
+ }
+ return true
+}
+
+// Create DOCUMENT-END.
+func yaml_document_end_event_initialize(event *yaml_event_t, implicit bool) bool {
+ *event = yaml_event_t{
+ typ: yaml_DOCUMENT_END_EVENT,
+ implicit: implicit,
+ }
+ return true
+}
+
+///*
+// * Create ALIAS.
+// */
+//
+//YAML_DECLARE(int)
+//yaml_alias_event_initialize(event *yaml_event_t, anchor *yaml_char_t)
+//{
+// mark yaml_mark_t = { 0, 0, 0 }
+// anchor_copy *yaml_char_t = NULL
+//
+// assert(event) // Non-NULL event object is expected.
+// assert(anchor) // Non-NULL anchor is expected.
+//
+// if (!yaml_check_utf8(anchor, strlen((char *)anchor))) return 0
+//
+// anchor_copy = yaml_strdup(anchor)
+// if (!anchor_copy)
+// return 0
+//
+// ALIAS_EVENT_INIT(*event, anchor_copy, mark, mark)
+//
+// return 1
+//}
+
+// Create SCALAR.
+func yaml_scalar_event_initialize(event *yaml_event_t, anchor, tag, value []byte, plain_implicit, quoted_implicit bool, style yaml_scalar_style_t) bool {
+ *event = yaml_event_t{
+ typ: yaml_SCALAR_EVENT,
+ anchor: anchor,
+ tag: tag,
+ value: value,
+ implicit: plain_implicit,
+ quoted_implicit: quoted_implicit,
+ style: yaml_style_t(style),
+ }
+ return true
+}
+
+// Create SEQUENCE-START.
+func yaml_sequence_start_event_initialize(event *yaml_event_t, anchor, tag []byte, implicit bool, style yaml_sequence_style_t) bool {
+ *event = yaml_event_t{
+ typ: yaml_SEQUENCE_START_EVENT,
+ anchor: anchor,
+ tag: tag,
+ implicit: implicit,
+ style: yaml_style_t(style),
+ }
+ return true
+}
+
+// Create SEQUENCE-END.
+func yaml_sequence_end_event_initialize(event *yaml_event_t) bool {
+ *event = yaml_event_t{
+ typ: yaml_SEQUENCE_END_EVENT,
+ }
+ return true
+}
+
+// Create MAPPING-START.
+func yaml_mapping_start_event_initialize(event *yaml_event_t, anchor, tag []byte, implicit bool, style yaml_mapping_style_t) bool {
+ *event = yaml_event_t{
+ typ: yaml_MAPPING_START_EVENT,
+ anchor: anchor,
+ tag: tag,
+ implicit: implicit,
+ style: yaml_style_t(style),
+ }
+ return true
+}
+
+// Create MAPPING-END.
+func yaml_mapping_end_event_initialize(event *yaml_event_t) bool {
+ *event = yaml_event_t{
+ typ: yaml_MAPPING_END_EVENT,
+ }
+ return true
+}
+
+// Destroy an event object.
+func yaml_event_delete(event *yaml_event_t) {
+ *event = yaml_event_t{}
+}
+
+///*
+// * Create a document object.
+// */
+//
+//YAML_DECLARE(int)
+//yaml_document_initialize(document *yaml_document_t,
+// version_directive *yaml_version_directive_t,
+// tag_directives_start *yaml_tag_directive_t,
+// tag_directives_end *yaml_tag_directive_t,
+// start_implicit int, end_implicit int)
+//{
+// struct {
+// error yaml_error_type_t
+// } context
+// struct {
+// start *yaml_node_t
+// end *yaml_node_t
+// top *yaml_node_t
+// } nodes = { NULL, NULL, NULL }
+// version_directive_copy *yaml_version_directive_t = NULL
+// struct {
+// start *yaml_tag_directive_t
+// end *yaml_tag_directive_t
+// top *yaml_tag_directive_t
+// } tag_directives_copy = { NULL, NULL, NULL }
+// value yaml_tag_directive_t = { NULL, NULL }
+// mark yaml_mark_t = { 0, 0, 0 }
+//
+// assert(document) // Non-NULL document object is expected.
+// assert((tag_directives_start && tag_directives_end) ||
+// (tag_directives_start == tag_directives_end))
+// // Valid tag directives are expected.
+//
+// if (!STACK_INIT(&context, nodes, INITIAL_STACK_SIZE)) goto error
+//
+// if (version_directive) {
+// version_directive_copy = yaml_malloc(sizeof(yaml_version_directive_t))
+// if (!version_directive_copy) goto error
+// version_directive_copy.major = version_directive.major
+// version_directive_copy.minor = version_directive.minor
+// }
+//
+// if (tag_directives_start != tag_directives_end) {
+// tag_directive *yaml_tag_directive_t
+// if (!STACK_INIT(&context, tag_directives_copy, INITIAL_STACK_SIZE))
+// goto error
+// for (tag_directive = tag_directives_start
+// tag_directive != tag_directives_end; tag_directive ++) {
+// assert(tag_directive.handle)
+// assert(tag_directive.prefix)
+// if (!yaml_check_utf8(tag_directive.handle,
+// strlen((char *)tag_directive.handle)))
+// goto error
+// if (!yaml_check_utf8(tag_directive.prefix,
+// strlen((char *)tag_directive.prefix)))
+// goto error
+// value.handle = yaml_strdup(tag_directive.handle)
+// value.prefix = yaml_strdup(tag_directive.prefix)
+// if (!value.handle || !value.prefix) goto error
+// if (!PUSH(&context, tag_directives_copy, value))
+// goto error
+// value.handle = NULL
+// value.prefix = NULL
+// }
+// }
+//
+// DOCUMENT_INIT(*document, nodes.start, nodes.end, version_directive_copy,
+// tag_directives_copy.start, tag_directives_copy.top,
+// start_implicit, end_implicit, mark, mark)
+//
+// return 1
+//
+//error:
+// STACK_DEL(&context, nodes)
+// yaml_free(version_directive_copy)
+// while (!STACK_EMPTY(&context, tag_directives_copy)) {
+// value yaml_tag_directive_t = POP(&context, tag_directives_copy)
+// yaml_free(value.handle)
+// yaml_free(value.prefix)
+// }
+// STACK_DEL(&context, tag_directives_copy)
+// yaml_free(value.handle)
+// yaml_free(value.prefix)
+//
+// return 0
+//}
+//
+///*
+// * Destroy a document object.
+// */
+//
+//YAML_DECLARE(void)
+//yaml_document_delete(document *yaml_document_t)
+//{
+// struct {
+// error yaml_error_type_t
+// } context
+// tag_directive *yaml_tag_directive_t
+//
+// context.error = YAML_NO_ERROR // Eliminate a compliler warning.
+//
+// assert(document) // Non-NULL document object is expected.
+//
+// while (!STACK_EMPTY(&context, document.nodes)) {
+// node yaml_node_t = POP(&context, document.nodes)
+// yaml_free(node.tag)
+// switch (node.type) {
+// case YAML_SCALAR_NODE:
+// yaml_free(node.data.scalar.value)
+// break
+// case YAML_SEQUENCE_NODE:
+// STACK_DEL(&context, node.data.sequence.items)
+// break
+// case YAML_MAPPING_NODE:
+// STACK_DEL(&context, node.data.mapping.pairs)
+// break
+// default:
+// assert(0) // Should not happen.
+// }
+// }
+// STACK_DEL(&context, document.nodes)
+//
+// yaml_free(document.version_directive)
+// for (tag_directive = document.tag_directives.start
+// tag_directive != document.tag_directives.end
+// tag_directive++) {
+// yaml_free(tag_directive.handle)
+// yaml_free(tag_directive.prefix)
+// }
+// yaml_free(document.tag_directives.start)
+//
+// memset(document, 0, sizeof(yaml_document_t))
+//}
+//
+///**
+// * Get a document node.
+// */
+//
+//YAML_DECLARE(yaml_node_t *)
+//yaml_document_get_node(document *yaml_document_t, index int)
+//{
+// assert(document) // Non-NULL document object is expected.
+//
+// if (index > 0 && document.nodes.start + index <= document.nodes.top) {
+// return document.nodes.start + index - 1
+// }
+// return NULL
+//}
+//
+///**
+// * Get the root object.
+// */
+//
+//YAML_DECLARE(yaml_node_t *)
+//yaml_document_get_root_node(document *yaml_document_t)
+//{
+// assert(document) // Non-NULL document object is expected.
+//
+// if (document.nodes.top != document.nodes.start) {
+// return document.nodes.start
+// }
+// return NULL
+//}
+//
+///*
+// * Add a scalar node to a document.
+// */
+//
+//YAML_DECLARE(int)
+//yaml_document_add_scalar(document *yaml_document_t,
+// tag *yaml_char_t, value *yaml_char_t, length int,
+// style yaml_scalar_style_t)
+//{
+// struct {
+// error yaml_error_type_t
+// } context
+// mark yaml_mark_t = { 0, 0, 0 }
+// tag_copy *yaml_char_t = NULL
+// value_copy *yaml_char_t = NULL
+// node yaml_node_t
+//
+// assert(document) // Non-NULL document object is expected.
+// assert(value) // Non-NULL value is expected.
+//
+// if (!tag) {
+// tag = (yaml_char_t *)YAML_DEFAULT_SCALAR_TAG
+// }
+//
+// if (!yaml_check_utf8(tag, strlen((char *)tag))) goto error
+// tag_copy = yaml_strdup(tag)
+// if (!tag_copy) goto error
+//
+// if (length < 0) {
+// length = strlen((char *)value)
+// }
+//
+// if (!yaml_check_utf8(value, length)) goto error
+// value_copy = yaml_malloc(length+1)
+// if (!value_copy) goto error
+// memcpy(value_copy, value, length)
+// value_copy[length] = '\0'
+//
+// SCALAR_NODE_INIT(node, tag_copy, value_copy, length, style, mark, mark)
+// if (!PUSH(&context, document.nodes, node)) goto error
+//
+// return document.nodes.top - document.nodes.start
+//
+//error:
+// yaml_free(tag_copy)
+// yaml_free(value_copy)
+//
+// return 0
+//}
+//
+///*
+// * Add a sequence node to a document.
+// */
+//
+//YAML_DECLARE(int)
+//yaml_document_add_sequence(document *yaml_document_t,
+// tag *yaml_char_t, style yaml_sequence_style_t)
+//{
+// struct {
+// error yaml_error_type_t
+// } context
+// mark yaml_mark_t = { 0, 0, 0 }
+// tag_copy *yaml_char_t = NULL
+// struct {
+// start *yaml_node_item_t
+// end *yaml_node_item_t
+// top *yaml_node_item_t
+// } items = { NULL, NULL, NULL }
+// node yaml_node_t
+//
+// assert(document) // Non-NULL document object is expected.
+//
+// if (!tag) {
+// tag = (yaml_char_t *)YAML_DEFAULT_SEQUENCE_TAG
+// }
+//
+// if (!yaml_check_utf8(tag, strlen((char *)tag))) goto error
+// tag_copy = yaml_strdup(tag)
+// if (!tag_copy) goto error
+//
+// if (!STACK_INIT(&context, items, INITIAL_STACK_SIZE)) goto error
+//
+// SEQUENCE_NODE_INIT(node, tag_copy, items.start, items.end,
+// style, mark, mark)
+// if (!PUSH(&context, document.nodes, node)) goto error
+//
+// return document.nodes.top - document.nodes.start
+//
+//error:
+// STACK_DEL(&context, items)
+// yaml_free(tag_copy)
+//
+// return 0
+//}
+//
+///*
+// * Add a mapping node to a document.
+// */
+//
+//YAML_DECLARE(int)
+//yaml_document_add_mapping(document *yaml_document_t,
+// tag *yaml_char_t, style yaml_mapping_style_t)
+//{
+// struct {
+// error yaml_error_type_t
+// } context
+// mark yaml_mark_t = { 0, 0, 0 }
+// tag_copy *yaml_char_t = NULL
+// struct {
+// start *yaml_node_pair_t
+// end *yaml_node_pair_t
+// top *yaml_node_pair_t
+// } pairs = { NULL, NULL, NULL }
+// node yaml_node_t
+//
+// assert(document) // Non-NULL document object is expected.
+//
+// if (!tag) {
+// tag = (yaml_char_t *)YAML_DEFAULT_MAPPING_TAG
+// }
+//
+// if (!yaml_check_utf8(tag, strlen((char *)tag))) goto error
+// tag_copy = yaml_strdup(tag)
+// if (!tag_copy) goto error
+//
+// if (!STACK_INIT(&context, pairs, INITIAL_STACK_SIZE)) goto error
+//
+// MAPPING_NODE_INIT(node, tag_copy, pairs.start, pairs.end,
+// style, mark, mark)
+// if (!PUSH(&context, document.nodes, node)) goto error
+//
+// return document.nodes.top - document.nodes.start
+//
+//error:
+// STACK_DEL(&context, pairs)
+// yaml_free(tag_copy)
+//
+// return 0
+//}
+//
+///*
+// * Append an item to a sequence node.
+// */
+//
+//YAML_DECLARE(int)
+//yaml_document_append_sequence_item(document *yaml_document_t,
+// sequence int, item int)
+//{
+// struct {
+// error yaml_error_type_t
+// } context
+//
+// assert(document) // Non-NULL document is required.
+// assert(sequence > 0
+// && document.nodes.start + sequence <= document.nodes.top)
+// // Valid sequence id is required.
+// assert(document.nodes.start[sequence-1].type == YAML_SEQUENCE_NODE)
+// // A sequence node is required.
+// assert(item > 0 && document.nodes.start + item <= document.nodes.top)
+// // Valid item id is required.
+//
+// if (!PUSH(&context,
+// document.nodes.start[sequence-1].data.sequence.items, item))
+// return 0
+//
+// return 1
+//}
+//
+///*
+// * Append a pair of a key and a value to a mapping node.
+// */
+//
+//YAML_DECLARE(int)
+//yaml_document_append_mapping_pair(document *yaml_document_t,
+// mapping int, key int, value int)
+//{
+// struct {
+// error yaml_error_type_t
+// } context
+//
+// pair yaml_node_pair_t
+//
+// assert(document) // Non-NULL document is required.
+// assert(mapping > 0
+// && document.nodes.start + mapping <= document.nodes.top)
+// // Valid mapping id is required.
+// assert(document.nodes.start[mapping-1].type == YAML_MAPPING_NODE)
+// // A mapping node is required.
+// assert(key > 0 && document.nodes.start + key <= document.nodes.top)
+// // Valid key id is required.
+// assert(value > 0 && document.nodes.start + value <= document.nodes.top)
+// // Valid value id is required.
+//
+// pair.key = key
+// pair.value = value
+//
+// if (!PUSH(&context,
+// document.nodes.start[mapping-1].data.mapping.pairs, pair))
+// return 0
+//
+// return 1
+//}
+//
+//
diff --git a/vendor/github.com/coreos/ignition/config/vendor/github.com/go-yaml/yaml/decode.go b/vendor/github.com/coreos/ignition/config/vendor/github.com/go-yaml/yaml/decode.go
new file mode 100644
index 00000000..085cddc4
--- /dev/null
+++ b/vendor/github.com/coreos/ignition/config/vendor/github.com/go-yaml/yaml/decode.go
@@ -0,0 +1,683 @@
+package yaml
+
+import (
+ "encoding"
+ "encoding/base64"
+ "fmt"
+ "math"
+ "reflect"
+ "strconv"
+ "time"
+)
+
+const (
+ documentNode = 1 << iota
+ mappingNode
+ sequenceNode
+ scalarNode
+ aliasNode
+)
+
+type node struct {
+ kind int
+ line, column int
+ tag string
+ value string
+ implicit bool
+ children []*node
+ anchors map[string]*node
+}
+
+// ----------------------------------------------------------------------------
+// Parser, produces a node tree out of a libyaml event stream.
+
+type parser struct {
+ parser yaml_parser_t
+ event yaml_event_t
+ doc *node
+}
+
+func newParser(b []byte) *parser {
+ p := parser{}
+ if !yaml_parser_initialize(&p.parser) {
+ panic("failed to initialize YAML emitter")
+ }
+
+ if len(b) == 0 {
+ b = []byte{'\n'}
+ }
+
+ yaml_parser_set_input_string(&p.parser, b)
+
+ p.skip()
+ if p.event.typ != yaml_STREAM_START_EVENT {
+ panic("expected stream start event, got " + strconv.Itoa(int(p.event.typ)))
+ }
+ p.skip()
+ return &p
+}
+
+func (p *parser) destroy() {
+ if p.event.typ != yaml_NO_EVENT {
+ yaml_event_delete(&p.event)
+ }
+ yaml_parser_delete(&p.parser)
+}
+
+func (p *parser) skip() {
+ if p.event.typ != yaml_NO_EVENT {
+ if p.event.typ == yaml_STREAM_END_EVENT {
+ failf("attempted to go past the end of stream; corrupted value?")
+ }
+ yaml_event_delete(&p.event)
+ }
+ if !yaml_parser_parse(&p.parser, &p.event) {
+ p.fail()
+ }
+}
+
+func (p *parser) fail() {
+ var where string
+ var line int
+ if p.parser.problem_mark.line != 0 {
+ line = p.parser.problem_mark.line
+ } else if p.parser.context_mark.line != 0 {
+ line = p.parser.context_mark.line
+ }
+ if line != 0 {
+ where = "line " + strconv.Itoa(line) + ": "
+ }
+ var msg string
+ if len(p.parser.problem) > 0 {
+ msg = p.parser.problem
+ } else {
+ msg = "unknown problem parsing YAML content"
+ }
+ failf("%s%s", where, msg)
+}
+
+func (p *parser) anchor(n *node, anchor []byte) {
+ if anchor != nil {
+ p.doc.anchors[string(anchor)] = n
+ }
+}
+
+func (p *parser) parse() *node {
+ switch p.event.typ {
+ case yaml_SCALAR_EVENT:
+ return p.scalar()
+ case yaml_ALIAS_EVENT:
+ return p.alias()
+ case yaml_MAPPING_START_EVENT:
+ return p.mapping()
+ case yaml_SEQUENCE_START_EVENT:
+ return p.sequence()
+ case yaml_DOCUMENT_START_EVENT:
+ return p.document()
+ case yaml_STREAM_END_EVENT:
+ // Happens when attempting to decode an empty buffer.
+ return nil
+ default:
+ panic("attempted to parse unknown event: " + strconv.Itoa(int(p.event.typ)))
+ }
+ panic("unreachable")
+}
+
+func (p *parser) node(kind int) *node {
+ return &node{
+ kind: kind,
+ line: p.event.start_mark.line,
+ column: p.event.start_mark.column,
+ }
+}
+
+func (p *parser) document() *node {
+ n := p.node(documentNode)
+ n.anchors = make(map[string]*node)
+ p.doc = n
+ p.skip()
+ n.children = append(n.children, p.parse())
+ if p.event.typ != yaml_DOCUMENT_END_EVENT {
+ panic("expected end of document event but got " + strconv.Itoa(int(p.event.typ)))
+ }
+ p.skip()
+ return n
+}
+
+func (p *parser) alias() *node {
+ n := p.node(aliasNode)
+ n.value = string(p.event.anchor)
+ p.skip()
+ return n
+}
+
+func (p *parser) scalar() *node {
+ n := p.node(scalarNode)
+ n.value = string(p.event.value)
+ n.tag = string(p.event.tag)
+ n.implicit = p.event.implicit
+ p.anchor(n, p.event.anchor)
+ p.skip()
+ return n
+}
+
+func (p *parser) sequence() *node {
+ n := p.node(sequenceNode)
+ p.anchor(n, p.event.anchor)
+ p.skip()
+ for p.event.typ != yaml_SEQUENCE_END_EVENT {
+ n.children = append(n.children, p.parse())
+ }
+ p.skip()
+ return n
+}
+
+func (p *parser) mapping() *node {
+ n := p.node(mappingNode)
+ p.anchor(n, p.event.anchor)
+ p.skip()
+ for p.event.typ != yaml_MAPPING_END_EVENT {
+ n.children = append(n.children, p.parse(), p.parse())
+ }
+ p.skip()
+ return n
+}
+
+// ----------------------------------------------------------------------------
+// Decoder, unmarshals a node into a provided value.
+
+type decoder struct {
+ doc *node
+ aliases map[string]bool
+ mapType reflect.Type
+ terrors []string
+}
+
+var (
+ mapItemType = reflect.TypeOf(MapItem{})
+ durationType = reflect.TypeOf(time.Duration(0))
+ defaultMapType = reflect.TypeOf(map[interface{}]interface{}{})
+ ifaceType = defaultMapType.Elem()
+)
+
+func newDecoder() *decoder {
+ d := &decoder{mapType: defaultMapType}
+ d.aliases = make(map[string]bool)
+ return d
+}
+
+func (d *decoder) terror(n *node, tag string, out reflect.Value) {
+ if n.tag != "" {
+ tag = n.tag
+ }
+ value := n.value
+ if tag != yaml_SEQ_TAG && tag != yaml_MAP_TAG {
+ if len(value) > 10 {
+ value = " `" + value[:7] + "...`"
+ } else {
+ value = " `" + value + "`"
+ }
+ }
+ d.terrors = append(d.terrors, fmt.Sprintf("line %d: cannot unmarshal %s%s into %s", n.line+1, shortTag(tag), value, out.Type()))
+}
+
+func (d *decoder) callUnmarshaler(n *node, u Unmarshaler) (good bool) {
+ terrlen := len(d.terrors)
+ err := u.UnmarshalYAML(func(v interface{}) (err error) {
+ defer handleErr(&err)
+ d.unmarshal(n, reflect.ValueOf(v))
+ if len(d.terrors) > terrlen {
+ issues := d.terrors[terrlen:]
+ d.terrors = d.terrors[:terrlen]
+ return &TypeError{issues}
+ }
+ return nil
+ })
+ if e, ok := err.(*TypeError); ok {
+ d.terrors = append(d.terrors, e.Errors...)
+ return false
+ }
+ if err != nil {
+ fail(err)
+ }
+ return true
+}
+
+// d.prepare initializes and dereferences pointers and calls UnmarshalYAML
+// if a value is found to implement it.
+// It returns the initialized and dereferenced out value, whether
+// unmarshalling was already done by UnmarshalYAML, and if so whether
+// its types unmarshalled appropriately.
+//
+// If n holds a null value, prepare returns before doing anything.
+func (d *decoder) prepare(n *node, out reflect.Value) (newout reflect.Value, unmarshaled, good bool) {
+ if n.tag == yaml_NULL_TAG || n.kind == scalarNode && n.tag == "" && (n.value == "null" || n.value == "") {
+ return out, false, false
+ }
+ again := true
+ for again {
+ again = false
+ if out.Kind() == reflect.Ptr {
+ if out.IsNil() {
+ out.Set(reflect.New(out.Type().Elem()))
+ }
+ out = out.Elem()
+ again = true
+ }
+ if out.CanAddr() {
+ if u, ok := out.Addr().Interface().(Unmarshaler); ok {
+ good = d.callUnmarshaler(n, u)
+ return out, true, good
+ }
+ }
+ }
+ return out, false, false
+}
+
+func (d *decoder) unmarshal(n *node, out reflect.Value) (good bool) {
+ switch n.kind {
+ case documentNode:
+ return d.document(n, out)
+ case aliasNode:
+ return d.alias(n, out)
+ }
+ out, unmarshaled, good := d.prepare(n, out)
+ if unmarshaled {
+ return good
+ }
+ switch n.kind {
+ case scalarNode:
+ good = d.scalar(n, out)
+ case mappingNode:
+ good = d.mapping(n, out)
+ case sequenceNode:
+ good = d.sequence(n, out)
+ default:
+ panic("internal error: unknown node kind: " + strconv.Itoa(n.kind))
+ }
+ return good
+}
+
+func (d *decoder) document(n *node, out reflect.Value) (good bool) {
+ if len(n.children) == 1 {
+ d.doc = n
+ d.unmarshal(n.children[0], out)
+ return true
+ }
+ return false
+}
+
+func (d *decoder) alias(n *node, out reflect.Value) (good bool) {
+ an, ok := d.doc.anchors[n.value]
+ if !ok {
+ failf("unknown anchor '%s' referenced", n.value)
+ }
+ if d.aliases[n.value] {
+ failf("anchor '%s' value contains itself", n.value)
+ }
+ d.aliases[n.value] = true
+ good = d.unmarshal(an, out)
+ delete(d.aliases, n.value)
+ return good
+}
+
+var zeroValue reflect.Value
+
+func resetMap(out reflect.Value) {
+ for _, k := range out.MapKeys() {
+ out.SetMapIndex(k, zeroValue)
+ }
+}
+
+func (d *decoder) scalar(n *node, out reflect.Value) (good bool) {
+ var tag string
+ var resolved interface{}
+ if n.tag == "" && !n.implicit {
+ tag = yaml_STR_TAG
+ resolved = n.value
+ } else {
+ tag, resolved = resolve(n.tag, n.value)
+ if tag == yaml_BINARY_TAG {
+ data, err := base64.StdEncoding.DecodeString(resolved.(string))
+ if err != nil {
+ failf("!!binary value contains invalid base64 data")
+ }
+ resolved = string(data)
+ }
+ }
+ if resolved == nil {
+ if out.Kind() == reflect.Map && !out.CanAddr() {
+ resetMap(out)
+ } else {
+ out.Set(reflect.Zero(out.Type()))
+ }
+ return true
+ }
+ if s, ok := resolved.(string); ok && out.CanAddr() {
+ if u, ok := out.Addr().Interface().(encoding.TextUnmarshaler); ok {
+ err := u.UnmarshalText([]byte(s))
+ if err != nil {
+ fail(err)
+ }
+ return true
+ }
+ }
+ switch out.Kind() {
+ case reflect.String:
+ if tag == yaml_BINARY_TAG {
+ out.SetString(resolved.(string))
+ good = true
+ } else if resolved != nil {
+ out.SetString(n.value)
+ good = true
+ }
+ case reflect.Interface:
+ if resolved == nil {
+ out.Set(reflect.Zero(out.Type()))
+ } else {
+ out.Set(reflect.ValueOf(resolved))
+ }
+ good = true
+ case reflect.Int, reflect.Int8, reflect.Int16, reflect.Int32, reflect.Int64:
+ switch resolved := resolved.(type) {
+ case int:
+ if !out.OverflowInt(int64(resolved)) {
+ out.SetInt(int64(resolved))
+ good = true
+ }
+ case int64:
+ if !out.OverflowInt(resolved) {
+ out.SetInt(resolved)
+ good = true
+ }
+ case uint64:
+ if resolved <= math.MaxInt64 && !out.OverflowInt(int64(resolved)) {
+ out.SetInt(int64(resolved))
+ good = true
+ }
+ case float64:
+ if resolved <= math.MaxInt64 && !out.OverflowInt(int64(resolved)) {
+ out.SetInt(int64(resolved))
+ good = true
+ }
+ case string:
+ if out.Type() == durationType {
+ d, err := time.ParseDuration(resolved)
+ if err == nil {
+ out.SetInt(int64(d))
+ good = true
+ }
+ }
+ }
+ case reflect.Uint, reflect.Uint8, reflect.Uint16, reflect.Uint32, reflect.Uint64, reflect.Uintptr:
+ switch resolved := resolved.(type) {
+ case int:
+ if resolved >= 0 && !out.OverflowUint(uint64(resolved)) {
+ out.SetUint(uint64(resolved))
+ good = true
+ }
+ case int64:
+ if resolved >= 0 && !out.OverflowUint(uint64(resolved)) {
+ out.SetUint(uint64(resolved))
+ good = true
+ }
+ case uint64:
+ if !out.OverflowUint(uint64(resolved)) {
+ out.SetUint(uint64(resolved))
+ good = true
+ }
+ case float64:
+ if resolved <= math.MaxUint64 && !out.OverflowUint(uint64(resolved)) {
+ out.SetUint(uint64(resolved))
+ good = true
+ }
+ }
+ case reflect.Bool:
+ switch resolved := resolved.(type) {
+ case bool:
+ out.SetBool(resolved)
+ good = true
+ }
+ case reflect.Float32, reflect.Float64:
+ switch resolved := resolved.(type) {
+ case int:
+ out.SetFloat(float64(resolved))
+ good = true
+ case int64:
+ out.SetFloat(float64(resolved))
+ good = true
+ case uint64:
+ out.SetFloat(float64(resolved))
+ good = true
+ case float64:
+ out.SetFloat(resolved)
+ good = true
+ }
+ case reflect.Ptr:
+ if out.Type().Elem() == reflect.TypeOf(resolved) {
+ // TODO DOes this make sense? When is out a Ptr except when decoding a nil value?
+ elem := reflect.New(out.Type().Elem())
+ elem.Elem().Set(reflect.ValueOf(resolved))
+ out.Set(elem)
+ good = true
+ }
+ }
+ if !good {
+ d.terror(n, tag, out)
+ }
+ return good
+}
+
+func settableValueOf(i interface{}) reflect.Value {
+ v := reflect.ValueOf(i)
+ sv := reflect.New(v.Type()).Elem()
+ sv.Set(v)
+ return sv
+}
+
+func (d *decoder) sequence(n *node, out reflect.Value) (good bool) {
+ l := len(n.children)
+
+ var iface reflect.Value
+ switch out.Kind() {
+ case reflect.Slice:
+ out.Set(reflect.MakeSlice(out.Type(), l, l))
+ case reflect.Interface:
+ // No type hints. Will have to use a generic sequence.
+ iface = out
+ out = settableValueOf(make([]interface{}, l))
+ default:
+ d.terror(n, yaml_SEQ_TAG, out)
+ return false
+ }
+ et := out.Type().Elem()
+
+ j := 0
+ for i := 0; i < l; i++ {
+ e := reflect.New(et).Elem()
+ if ok := d.unmarshal(n.children[i], e); ok {
+ out.Index(j).Set(e)
+ j++
+ }
+ }
+ out.Set(out.Slice(0, j))
+ if iface.IsValid() {
+ iface.Set(out)
+ }
+ return true
+}
+
+func (d *decoder) mapping(n *node, out reflect.Value) (good bool) {
+ switch out.Kind() {
+ case reflect.Struct:
+ return d.mappingStruct(n, out)
+ case reflect.Slice:
+ return d.mappingSlice(n, out)
+ case reflect.Map:
+ // okay
+ case reflect.Interface:
+ if d.mapType.Kind() == reflect.Map {
+ iface := out
+ out = reflect.MakeMap(d.mapType)
+ iface.Set(out)
+ } else {
+ slicev := reflect.New(d.mapType).Elem()
+ if !d.mappingSlice(n, slicev) {
+ return false
+ }
+ out.Set(slicev)
+ return true
+ }
+ default:
+ d.terror(n, yaml_MAP_TAG, out)
+ return false
+ }
+ outt := out.Type()
+ kt := outt.Key()
+ et := outt.Elem()
+
+ mapType := d.mapType
+ if outt.Key() == ifaceType && outt.Elem() == ifaceType {
+ d.mapType = outt
+ }
+
+ if out.IsNil() {
+ out.Set(reflect.MakeMap(outt))
+ }
+ l := len(n.children)
+ for i := 0; i < l; i += 2 {
+ if isMerge(n.children[i]) {
+ d.merge(n.children[i+1], out)
+ continue
+ }
+ k := reflect.New(kt).Elem()
+ if d.unmarshal(n.children[i], k) {
+ kkind := k.Kind()
+ if kkind == reflect.Interface {
+ kkind = k.Elem().Kind()
+ }
+ if kkind == reflect.Map || kkind == reflect.Slice {
+ failf("invalid map key: %#v", k.Interface())
+ }
+ e := reflect.New(et).Elem()
+ if d.unmarshal(n.children[i+1], e) {
+ out.SetMapIndex(k, e)
+ }
+ }
+ }
+ d.mapType = mapType
+ return true
+}
+
+func (d *decoder) mappingSlice(n *node, out reflect.Value) (good bool) {
+ outt := out.Type()
+ if outt.Elem() != mapItemType {
+ d.terror(n, yaml_MAP_TAG, out)
+ return false
+ }
+
+ mapType := d.mapType
+ d.mapType = outt
+
+ var slice []MapItem
+ var l = len(n.children)
+ for i := 0; i < l; i += 2 {
+ if isMerge(n.children[i]) {
+ d.merge(n.children[i+1], out)
+ continue
+ }
+ item := MapItem{}
+ k := reflect.ValueOf(&item.Key).Elem()
+ if d.unmarshal(n.children[i], k) {
+ v := reflect.ValueOf(&item.Value).Elem()
+ if d.unmarshal(n.children[i+1], v) {
+ slice = append(slice, item)
+ }
+ }
+ }
+ out.Set(reflect.ValueOf(slice))
+ d.mapType = mapType
+ return true
+}
+
+func (d *decoder) mappingStruct(n *node, out reflect.Value) (good bool) {
+ sinfo, err := getStructInfo(out.Type())
+ if err != nil {
+ panic(err)
+ }
+ name := settableValueOf("")
+ l := len(n.children)
+
+ var inlineMap reflect.Value
+ var elemType reflect.Type
+ if sinfo.InlineMap != -1 {
+ inlineMap = out.Field(sinfo.InlineMap)
+ inlineMap.Set(reflect.New(inlineMap.Type()).Elem())
+ elemType = inlineMap.Type().Elem()
+ }
+
+ for i := 0; i < l; i += 2 {
+ ni := n.children[i]
+ if isMerge(ni) {
+ d.merge(n.children[i+1], out)
+ continue
+ }
+ if !d.unmarshal(ni, name) {
+ continue
+ }
+ if info, ok := sinfo.FieldsMap[name.String()]; ok {
+ var field reflect.Value
+ if info.Inline == nil {
+ field = out.Field(info.Num)
+ } else {
+ field = out.FieldByIndex(info.Inline)
+ }
+ d.unmarshal(n.children[i+1], field)
+ } else if sinfo.InlineMap != -1 {
+ if inlineMap.IsNil() {
+ inlineMap.Set(reflect.MakeMap(inlineMap.Type()))
+ }
+ value := reflect.New(elemType).Elem()
+ d.unmarshal(n.children[i+1], value)
+ inlineMap.SetMapIndex(name, value)
+ }
+ }
+ return true
+}
+
+func failWantMap() {
+ failf("map merge requires map or sequence of maps as the value")
+}
+
+func (d *decoder) merge(n *node, out reflect.Value) {
+ switch n.kind {
+ case mappingNode:
+ d.unmarshal(n, out)
+ case aliasNode:
+ an, ok := d.doc.anchors[n.value]
+ if ok && an.kind != mappingNode {
+ failWantMap()
+ }
+ d.unmarshal(n, out)
+ case sequenceNode:
+ // Step backwards as earlier nodes take precedence.
+ for i := len(n.children) - 1; i >= 0; i-- {
+ ni := n.children[i]
+ if ni.kind == aliasNode {
+ an, ok := d.doc.anchors[ni.value]
+ if ok && an.kind != mappingNode {
+ failWantMap()
+ }
+ } else if ni.kind != mappingNode {
+ failWantMap()
+ }
+ d.unmarshal(ni, out)
+ }
+ default:
+ failWantMap()
+ }
+}
+
+func isMerge(n *node) bool {
+ return n.kind == scalarNode && n.value == "<<" && (n.implicit == true || n.tag == yaml_MERGE_TAG)
+}
diff --git a/vendor/github.com/coreos/ignition/config/vendor/github.com/go-yaml/yaml/decode_test.go b/vendor/github.com/coreos/ignition/config/vendor/github.com/go-yaml/yaml/decode_test.go
new file mode 100644
index 00000000..04fdd9e7
--- /dev/null
+++ b/vendor/github.com/coreos/ignition/config/vendor/github.com/go-yaml/yaml/decode_test.go
@@ -0,0 +1,966 @@
+package yaml_test
+
+import (
+ "errors"
+ . "gopkg.in/check.v1"
+ "gopkg.in/yaml.v2"
+ "math"
+ "net"
+ "reflect"
+ "strings"
+ "time"
+)
+
+var unmarshalIntTest = 123
+
+var unmarshalTests = []struct {
+ data string
+ value interface{}
+}{
+ {
+ "",
+ &struct{}{},
+ }, {
+ "{}", &struct{}{},
+ }, {
+ "v: hi",
+ map[string]string{"v": "hi"},
+ }, {
+ "v: hi", map[string]interface{}{"v": "hi"},
+ }, {
+ "v: true",
+ map[string]string{"v": "true"},
+ }, {
+ "v: true",
+ map[string]interface{}{"v": true},
+ }, {
+ "v: 10",
+ map[string]interface{}{"v": 10},
+ }, {
+ "v: 0b10",
+ map[string]interface{}{"v": 2},
+ }, {
+ "v: 0xA",
+ map[string]interface{}{"v": 10},
+ }, {
+ "v: 4294967296",
+ map[string]int64{"v": 4294967296},
+ }, {
+ "v: 0.1",
+ map[string]interface{}{"v": 0.1},
+ }, {
+ "v: .1",
+ map[string]interface{}{"v": 0.1},
+ }, {
+ "v: .Inf",
+ map[string]interface{}{"v": math.Inf(+1)},
+ }, {
+ "v: -.Inf",
+ map[string]interface{}{"v": math.Inf(-1)},
+ }, {
+ "v: -10",
+ map[string]interface{}{"v": -10},
+ }, {
+ "v: -.1",
+ map[string]interface{}{"v": -0.1},
+ },
+
+ // Simple values.
+ {
+ "123",
+ &unmarshalIntTest,
+ },
+
+ // Floats from spec
+ {
+ "canonical: 6.8523e+5",
+ map[string]interface{}{"canonical": 6.8523e+5},
+ }, {
+ "expo: 685.230_15e+03",
+ map[string]interface{}{"expo": 685.23015e+03},
+ }, {
+ "fixed: 685_230.15",
+ map[string]interface{}{"fixed": 685230.15},
+ }, {
+ "neginf: -.inf",
+ map[string]interface{}{"neginf": math.Inf(-1)},
+ }, {
+ "fixed: 685_230.15",
+ map[string]float64{"fixed": 685230.15},
+ },
+ //{"sexa: 190:20:30.15", map[string]interface{}{"sexa": 0}}, // Unsupported
+ //{"notanum: .NaN", map[string]interface{}{"notanum": math.NaN()}}, // Equality of NaN fails.
+
+ // Bools from spec
+ {
+ "canonical: y",
+ map[string]interface{}{"canonical": true},
+ }, {
+ "answer: NO",
+ map[string]interface{}{"answer": false},
+ }, {
+ "logical: True",
+ map[string]interface{}{"logical": true},
+ }, {
+ "option: on",
+ map[string]interface{}{"option": true},
+ }, {
+ "option: on",
+ map[string]bool{"option": true},
+ },
+ // Ints from spec
+ {
+ "canonical: 685230",
+ map[string]interface{}{"canonical": 685230},
+ }, {
+ "decimal: +685_230",
+ map[string]interface{}{"decimal": 685230},
+ }, {
+ "octal: 02472256",
+ map[string]interface{}{"octal": 685230},
+ }, {
+ "hexa: 0x_0A_74_AE",
+ map[string]interface{}{"hexa": 685230},
+ }, {
+ "bin: 0b1010_0111_0100_1010_1110",
+ map[string]interface{}{"bin": 685230},
+ }, {
+ "bin: -0b101010",
+ map[string]interface{}{"bin": -42},
+ }, {
+ "decimal: +685_230",
+ map[string]int{"decimal": 685230},
+ },
+
+ //{"sexa: 190:20:30", map[string]interface{}{"sexa": 0}}, // Unsupported
+
+ // Nulls from spec
+ {
+ "empty:",
+ map[string]interface{}{"empty": nil},
+ }, {
+ "canonical: ~",
+ map[string]interface{}{"canonical": nil},
+ }, {
+ "english: null",
+ map[string]interface{}{"english": nil},
+ }, {
+ "~: null key",
+ map[interface{}]string{nil: "null key"},
+ }, {
+ "empty:",
+ map[string]*bool{"empty": nil},
+ },
+
+ // Flow sequence
+ {
+ "seq: [A,B]",
+ map[string]interface{}{"seq": []interface{}{"A", "B"}},
+ }, {
+ "seq: [A,B,C,]",
+ map[string][]string{"seq": []string{"A", "B", "C"}},
+ }, {
+ "seq: [A,1,C]",
+ map[string][]string{"seq": []string{"A", "1", "C"}},
+ }, {
+ "seq: [A,1,C]",
+ map[string][]int{"seq": []int{1}},
+ }, {
+ "seq: [A,1,C]",
+ map[string]interface{}{"seq": []interface{}{"A", 1, "C"}},
+ },
+ // Block sequence
+ {
+ "seq:\n - A\n - B",
+ map[string]interface{}{"seq": []interface{}{"A", "B"}},
+ }, {
+ "seq:\n - A\n - B\n - C",
+ map[string][]string{"seq": []string{"A", "B", "C"}},
+ }, {
+ "seq:\n - A\n - 1\n - C",
+ map[string][]string{"seq": []string{"A", "1", "C"}},
+ }, {
+ "seq:\n - A\n - 1\n - C",
+ map[string][]int{"seq": []int{1}},
+ }, {
+ "seq:\n - A\n - 1\n - C",
+ map[string]interface{}{"seq": []interface{}{"A", 1, "C"}},
+ },
+
+ // Literal block scalar
+ {
+ "scalar: | # Comment\n\n literal\n\n \ttext\n\n",
+ map[string]string{"scalar": "\nliteral\n\n\ttext\n"},
+ },
+
+ // Folded block scalar
+ {
+ "scalar: > # Comment\n\n folded\n line\n \n next\n line\n * one\n * two\n\n last\n line\n\n",
+ map[string]string{"scalar": "\nfolded line\nnext line\n * one\n * two\n\nlast line\n"},
+ },
+
+ // Map inside interface with no type hints.
+ {
+ "a: {b: c}",
+ map[interface{}]interface{}{"a": map[interface{}]interface{}{"b": "c"}},
+ },
+
+ // Structs and type conversions.
+ {
+ "hello: world",
+ &struct{ Hello string }{"world"},
+ }, {
+ "a: {b: c}",
+ &struct{ A struct{ B string } }{struct{ B string }{"c"}},
+ }, {
+ "a: {b: c}",
+ &struct{ A *struct{ B string } }{&struct{ B string }{"c"}},
+ }, {
+ "a: {b: c}",
+ &struct{ A map[string]string }{map[string]string{"b": "c"}},
+ }, {
+ "a: {b: c}",
+ &struct{ A *map[string]string }{&map[string]string{"b": "c"}},
+ }, {
+ "a:",
+ &struct{ A map[string]string }{},
+ }, {
+ "a: 1",
+ &struct{ A int }{1},
+ }, {
+ "a: 1",
+ &struct{ A float64 }{1},
+ }, {
+ "a: 1.0",
+ &struct{ A int }{1},
+ }, {
+ "a: 1.0",
+ &struct{ A uint }{1},
+ }, {
+ "a: [1, 2]",
+ &struct{ A []int }{[]int{1, 2}},
+ }, {
+ "a: 1",
+ &struct{ B int }{0},
+ }, {
+ "a: 1",
+ &struct {
+ B int "a"
+ }{1},
+ }, {
+ "a: y",
+ &struct{ A bool }{true},
+ },
+
+ // Some cross type conversions
+ {
+ "v: 42",
+ map[string]uint{"v": 42},
+ }, {
+ "v: -42",
+ map[string]uint{},
+ }, {
+ "v: 4294967296",
+ map[string]uint64{"v": 4294967296},
+ }, {
+ "v: -4294967296",
+ map[string]uint64{},
+ },
+
+ // int
+ {
+ "int_max: 2147483647",
+ map[string]int{"int_max": math.MaxInt32},
+ },
+ {
+ "int_min: -2147483648",
+ map[string]int{"int_min": math.MinInt32},
+ },
+ {
+ "int_overflow: 9223372036854775808", // math.MaxInt64 + 1
+ map[string]int{},
+ },
+
+ // int64
+ {
+ "int64_max: 9223372036854775807",
+ map[string]int64{"int64_max": math.MaxInt64},
+ },
+ {
+ "int64_max_base2: 0b111111111111111111111111111111111111111111111111111111111111111",
+ map[string]int64{"int64_max_base2": math.MaxInt64},
+ },
+ {
+ "int64_min: -9223372036854775808",
+ map[string]int64{"int64_min": math.MinInt64},
+ },
+ {
+ "int64_neg_base2: -0b111111111111111111111111111111111111111111111111111111111111111",
+ map[string]int64{"int64_neg_base2": -math.MaxInt64},
+ },
+ {
+ "int64_overflow: 9223372036854775808", // math.MaxInt64 + 1
+ map[string]int64{},
+ },
+
+ // uint
+ {
+ "uint_min: 0",
+ map[string]uint{"uint_min": 0},
+ },
+ {
+ "uint_max: 4294967295",
+ map[string]uint{"uint_max": math.MaxUint32},
+ },
+ {
+ "uint_underflow: -1",
+ map[string]uint{},
+ },
+
+ // uint64
+ {
+ "uint64_min: 0",
+ map[string]uint{"uint64_min": 0},
+ },
+ {
+ "uint64_max: 18446744073709551615",
+ map[string]uint64{"uint64_max": math.MaxUint64},
+ },
+ {
+ "uint64_max_base2: 0b1111111111111111111111111111111111111111111111111111111111111111",
+ map[string]uint64{"uint64_max_base2": math.MaxUint64},
+ },
+ {
+ "uint64_maxint64: 9223372036854775807",
+ map[string]uint64{"uint64_maxint64": math.MaxInt64},
+ },
+ {
+ "uint64_underflow: -1",
+ map[string]uint64{},
+ },
+
+ // float32
+ {
+ "float32_max: 3.40282346638528859811704183484516925440e+38",
+ map[string]float32{"float32_max": math.MaxFloat32},
+ },
+ {
+ "float32_nonzero: 1.401298464324817070923729583289916131280e-45",
+ map[string]float32{"float32_nonzero": math.SmallestNonzeroFloat32},
+ },
+ {
+ "float32_maxuint64: 18446744073709551615",
+ map[string]float32{"float32_maxuint64": float32(math.MaxUint64)},
+ },
+ {
+ "float32_maxuint64+1: 18446744073709551616",
+ map[string]float32{"float32_maxuint64+1": float32(math.MaxUint64 + 1)},
+ },
+
+ // float64
+ {
+ "float64_max: 1.797693134862315708145274237317043567981e+308",
+ map[string]float64{"float64_max": math.MaxFloat64},
+ },
+ {
+ "float64_nonzero: 4.940656458412465441765687928682213723651e-324",
+ map[string]float64{"float64_nonzero": math.SmallestNonzeroFloat64},
+ },
+ {
+ "float64_maxuint64: 18446744073709551615",
+ map[string]float64{"float64_maxuint64": float64(math.MaxUint64)},
+ },
+ {
+ "float64_maxuint64+1: 18446744073709551616",
+ map[string]float64{"float64_maxuint64+1": float64(math.MaxUint64 + 1)},
+ },
+
+ // Overflow cases.
+ {
+ "v: 4294967297",
+ map[string]int32{},
+ }, {
+ "v: 128",
+ map[string]int8{},
+ },
+
+ // Quoted values.
+ {
+ "'1': '\"2\"'",
+ map[interface{}]interface{}{"1": "\"2\""},
+ }, {
+ "v:\n- A\n- 'B\n\n C'\n",
+ map[string][]string{"v": []string{"A", "B\nC"}},
+ },
+
+ // Explicit tags.
+ {
+ "v: !!float '1.1'",
+ map[string]interface{}{"v": 1.1},
+ }, {
+ "v: !!null ''",
+ map[string]interface{}{"v": nil},
+ }, {
+ "%TAG !y! tag:yaml.org,2002:\n---\nv: !y!int '1'",
+ map[string]interface{}{"v": 1},
+ },
+
+ // Anchors and aliases.
+ {
+ "a: &x 1\nb: &y 2\nc: *x\nd: *y\n",
+ &struct{ A, B, C, D int }{1, 2, 1, 2},
+ }, {
+ "a: &a {c: 1}\nb: *a",
+ &struct {
+ A, B struct {
+ C int
+ }
+ }{struct{ C int }{1}, struct{ C int }{1}},
+ }, {
+ "a: &a [1, 2]\nb: *a",
+ &struct{ B []int }{[]int{1, 2}},
+ }, {
+ "b: *a\na: &a {c: 1}",
+ &struct {
+ A, B struct {
+ C int
+ }
+ }{struct{ C int }{1}, struct{ C int }{1}},
+ },
+
+ // Bug #1133337
+ {
+ "foo: ''",
+ map[string]*string{"foo": new(string)},
+ }, {
+ "foo: null",
+ map[string]string{"foo": ""},
+ }, {
+ "foo: null",
+ map[string]interface{}{"foo": nil},
+ },
+
+ // Ignored field
+ {
+ "a: 1\nb: 2\n",
+ &struct {
+ A int
+ B int "-"
+ }{1, 0},
+ },
+
+ // Bug #1191981
+ {
+ "" +
+ "%YAML 1.1\n" +
+ "--- !!str\n" +
+ `"Generic line break (no glyph)\n\` + "\n" +
+ ` Generic line break (glyphed)\n\` + "\n" +
+ ` Line separator\u2028\` + "\n" +
+ ` Paragraph separator\u2029"` + "\n",
+ "" +
+ "Generic line break (no glyph)\n" +
+ "Generic line break (glyphed)\n" +
+ "Line separator\u2028Paragraph separator\u2029",
+ },
+
+ // Struct inlining
+ {
+ "a: 1\nb: 2\nc: 3\n",
+ &struct {
+ A int
+ C inlineB `yaml:",inline"`
+ }{1, inlineB{2, inlineC{3}}},
+ },
+
+ // Map inlining
+ {
+ "a: 1\nb: 2\nc: 3\n",
+ &struct {
+ A int
+ C map[string]int `yaml:",inline"`
+ }{1, map[string]int{"b": 2, "c": 3}},
+ },
+
+ // bug 1243827
+ {
+ "a: -b_c",
+ map[string]interface{}{"a": "-b_c"},
+ },
+ {
+ "a: +b_c",
+ map[string]interface{}{"a": "+b_c"},
+ },
+ {
+ "a: 50cent_of_dollar",
+ map[string]interface{}{"a": "50cent_of_dollar"},
+ },
+
+ // Duration
+ {
+ "a: 3s",
+ map[string]time.Duration{"a": 3 * time.Second},
+ },
+
+ // Issue #24.
+ {
+ "a: ",
+ map[string]string{"a": ""},
+ },
+
+ // Base 60 floats are obsolete and unsupported.
+ {
+ "a: 1:1\n",
+ map[string]string{"a": "1:1"},
+ },
+
+ // Binary data.
+ {
+ "a: !!binary gIGC\n",
+ map[string]string{"a": "\x80\x81\x82"},
+ }, {
+ "a: !!binary |\n " + strings.Repeat("kJCQ", 17) + "kJ\n CQ\n",
+ map[string]string{"a": strings.Repeat("\x90", 54)},
+ }, {
+ "a: !!binary |\n " + strings.Repeat("A", 70) + "\n ==\n",
+ map[string]string{"a": strings.Repeat("\x00", 52)},
+ },
+
+ // Ordered maps.
+ {
+ "{b: 2, a: 1, d: 4, c: 3, sub: {e: 5}}",
+ &yaml.MapSlice{{"b", 2}, {"a", 1}, {"d", 4}, {"c", 3}, {"sub", yaml.MapSlice{{"e", 5}}}},
+ },
+
+ // Issue #39.
+ {
+ "a:\n b:\n c: d\n",
+ map[string]struct{ B interface{} }{"a": {map[interface{}]interface{}{"c": "d"}}},
+ },
+
+ // Custom map type.
+ {
+ "a: {b: c}",
+ M{"a": M{"b": "c"}},
+ },
+
+ // Support encoding.TextUnmarshaler.
+ {
+ "a: 1.2.3.4\n",
+ map[string]net.IP{"a": net.IPv4(1, 2, 3, 4)},
+ },
+ {
+ "a: 2015-02-24T18:19:39Z\n",
+ map[string]time.Time{"a": time.Unix(1424801979, 0)},
+ },
+
+ // Encode empty lists as zero-length slices.
+ {
+ "a: []",
+ &struct{ A []int }{[]int{}},
+ },
+}
+
+type M map[interface{}]interface{}
+
+type inlineB struct {
+ B int
+ inlineC `yaml:",inline"`
+}
+
+type inlineC struct {
+ C int
+}
+
+func (s *S) TestUnmarshal(c *C) {
+ for _, item := range unmarshalTests {
+ t := reflect.ValueOf(item.value).Type()
+ var value interface{}
+ switch t.Kind() {
+ case reflect.Map:
+ value = reflect.MakeMap(t).Interface()
+ case reflect.String:
+ value = reflect.New(t).Interface()
+ case reflect.Ptr:
+ value = reflect.New(t.Elem()).Interface()
+ default:
+ c.Fatalf("missing case for %s", t)
+ }
+ err := yaml.Unmarshal([]byte(item.data), value)
+ if _, ok := err.(*yaml.TypeError); !ok {
+ c.Assert(err, IsNil)
+ }
+ if t.Kind() == reflect.String {
+ c.Assert(*value.(*string), Equals, item.value)
+ } else {
+ c.Assert(value, DeepEquals, item.value)
+ }
+ }
+}
+
+func (s *S) TestUnmarshalNaN(c *C) {
+ value := map[string]interface{}{}
+ err := yaml.Unmarshal([]byte("notanum: .NaN"), &value)
+ c.Assert(err, IsNil)
+ c.Assert(math.IsNaN(value["notanum"].(float64)), Equals, true)
+}
+
+var unmarshalErrorTests = []struct {
+ data, error string
+}{
+ {"v: !!float 'error'", "yaml: cannot decode !!str `error` as a !!float"},
+ {"v: [A,", "yaml: line 1: did not find expected node content"},
+ {"v:\n- [A,", "yaml: line 2: did not find expected node content"},
+ {"a: *b\n", "yaml: unknown anchor 'b' referenced"},
+ {"a: &a\n b: *a\n", "yaml: anchor 'a' value contains itself"},
+ {"value: -", "yaml: block sequence entries are not allowed in this context"},
+ {"a: !!binary ==", "yaml: !!binary value contains invalid base64 data"},
+ {"{[.]}", `yaml: invalid map key: \[\]interface \{\}\{"\."\}`},
+ {"{{.}}", `yaml: invalid map key: map\[interface\ \{\}\]interface \{\}\{".":interface \{\}\(nil\)\}`},
+}
+
+func (s *S) TestUnmarshalErrors(c *C) {
+ for _, item := range unmarshalErrorTests {
+ var value interface{}
+ err := yaml.Unmarshal([]byte(item.data), &value)
+ c.Assert(err, ErrorMatches, item.error, Commentf("Partial unmarshal: %#v", value))
+ }
+}
+
+var unmarshalerTests = []struct {
+ data, tag string
+ value interface{}
+}{
+ {"_: {hi: there}", "!!map", map[interface{}]interface{}{"hi": "there"}},
+ {"_: [1,A]", "!!seq", []interface{}{1, "A"}},
+ {"_: 10", "!!int", 10},
+ {"_: null", "!!null", nil},
+ {`_: BAR!`, "!!str", "BAR!"},
+ {`_: "BAR!"`, "!!str", "BAR!"},
+ {"_: !!foo 'BAR!'", "!!foo", "BAR!"},
+}
+
+var unmarshalerResult = map[int]error{}
+
+type unmarshalerType struct {
+ value interface{}
+}
+
+func (o *unmarshalerType) UnmarshalYAML(unmarshal func(v interface{}) error) error {
+ if err := unmarshal(&o.value); err != nil {
+ return err
+ }
+ if i, ok := o.value.(int); ok {
+ if result, ok := unmarshalerResult[i]; ok {
+ return result
+ }
+ }
+ return nil
+}
+
+type unmarshalerPointer struct {
+ Field *unmarshalerType "_"
+}
+
+type unmarshalerValue struct {
+ Field unmarshalerType "_"
+}
+
+func (s *S) TestUnmarshalerPointerField(c *C) {
+ for _, item := range unmarshalerTests {
+ obj := &unmarshalerPointer{}
+ err := yaml.Unmarshal([]byte(item.data), obj)
+ c.Assert(err, IsNil)
+ if item.value == nil {
+ c.Assert(obj.Field, IsNil)
+ } else {
+ c.Assert(obj.Field, NotNil, Commentf("Pointer not initialized (%#v)", item.value))
+ c.Assert(obj.Field.value, DeepEquals, item.value)
+ }
+ }
+}
+
+func (s *S) TestUnmarshalerValueField(c *C) {
+ for _, item := range unmarshalerTests {
+ obj := &unmarshalerValue{}
+ err := yaml.Unmarshal([]byte(item.data), obj)
+ c.Assert(err, IsNil)
+ c.Assert(obj.Field, NotNil, Commentf("Pointer not initialized (%#v)", item.value))
+ c.Assert(obj.Field.value, DeepEquals, item.value)
+ }
+}
+
+func (s *S) TestUnmarshalerWholeDocument(c *C) {
+ obj := &unmarshalerType{}
+ err := yaml.Unmarshal([]byte(unmarshalerTests[0].data), obj)
+ c.Assert(err, IsNil)
+ value, ok := obj.value.(map[interface{}]interface{})
+ c.Assert(ok, Equals, true, Commentf("value: %#v", obj.value))
+ c.Assert(value["_"], DeepEquals, unmarshalerTests[0].value)
+}
+
+func (s *S) TestUnmarshalerTypeError(c *C) {
+ unmarshalerResult[2] = &yaml.TypeError{[]string{"foo"}}
+ unmarshalerResult[4] = &yaml.TypeError{[]string{"bar"}}
+ defer func() {
+ delete(unmarshalerResult, 2)
+ delete(unmarshalerResult, 4)
+ }()
+
+ type T struct {
+ Before int
+ After int
+ M map[string]*unmarshalerType
+ }
+ var v T
+ data := `{before: A, m: {abc: 1, def: 2, ghi: 3, jkl: 4}, after: B}`
+ err := yaml.Unmarshal([]byte(data), &v)
+ c.Assert(err, ErrorMatches, ""+
+ "yaml: unmarshal errors:\n"+
+ " line 1: cannot unmarshal !!str `A` into int\n"+
+ " foo\n"+
+ " bar\n"+
+ " line 1: cannot unmarshal !!str `B` into int")
+ c.Assert(v.M["abc"], NotNil)
+ c.Assert(v.M["def"], IsNil)
+ c.Assert(v.M["ghi"], NotNil)
+ c.Assert(v.M["jkl"], IsNil)
+
+ c.Assert(v.M["abc"].value, Equals, 1)
+ c.Assert(v.M["ghi"].value, Equals, 3)
+}
+
+type proxyTypeError struct{}
+
+func (v *proxyTypeError) UnmarshalYAML(unmarshal func(interface{}) error) error {
+ var s string
+ var a int32
+ var b int64
+ if err := unmarshal(&s); err != nil {
+ panic(err)
+ }
+ if s == "a" {
+ if err := unmarshal(&b); err == nil {
+ panic("should have failed")
+ }
+ return unmarshal(&a)
+ }
+ if err := unmarshal(&a); err == nil {
+ panic("should have failed")
+ }
+ return unmarshal(&b)
+}
+
+func (s *S) TestUnmarshalerTypeErrorProxying(c *C) {
+ type T struct {
+ Before int
+ After int
+ M map[string]*proxyTypeError
+ }
+ var v T
+ data := `{before: A, m: {abc: a, def: b}, after: B}`
+ err := yaml.Unmarshal([]byte(data), &v)
+ c.Assert(err, ErrorMatches, ""+
+ "yaml: unmarshal errors:\n"+
+ " line 1: cannot unmarshal !!str `A` into int\n"+
+ " line 1: cannot unmarshal !!str `a` into int32\n"+
+ " line 1: cannot unmarshal !!str `b` into int64\n"+
+ " line 1: cannot unmarshal !!str `B` into int")
+}
+
+type failingUnmarshaler struct{}
+
+var failingErr = errors.New("failingErr")
+
+func (ft *failingUnmarshaler) UnmarshalYAML(unmarshal func(interface{}) error) error {
+ return failingErr
+}
+
+func (s *S) TestUnmarshalerError(c *C) {
+ err := yaml.Unmarshal([]byte("a: b"), &failingUnmarshaler{})
+ c.Assert(err, Equals, failingErr)
+}
+
+type sliceUnmarshaler []int
+
+func (su *sliceUnmarshaler) UnmarshalYAML(unmarshal func(interface{}) error) error {
+ var slice []int
+ err := unmarshal(&slice)
+ if err == nil {
+ *su = slice
+ return nil
+ }
+
+ var intVal int
+ err = unmarshal(&intVal)
+ if err == nil {
+ *su = []int{intVal}
+ return nil
+ }
+
+ return err
+}
+
+func (s *S) TestUnmarshalerRetry(c *C) {
+ var su sliceUnmarshaler
+ err := yaml.Unmarshal([]byte("[1, 2, 3]"), &su)
+ c.Assert(err, IsNil)
+ c.Assert(su, DeepEquals, sliceUnmarshaler([]int{1, 2, 3}))
+
+ err = yaml.Unmarshal([]byte("1"), &su)
+ c.Assert(err, IsNil)
+ c.Assert(su, DeepEquals, sliceUnmarshaler([]int{1}))
+}
+
+// From http://yaml.org/type/merge.html
+var mergeTests = `
+anchors:
+ list:
+ - &CENTER { "x": 1, "y": 2 }
+ - &LEFT { "x": 0, "y": 2 }
+ - &BIG { "r": 10 }
+ - &SMALL { "r": 1 }
+
+# All the following maps are equal:
+
+plain:
+ # Explicit keys
+ "x": 1
+ "y": 2
+ "r": 10
+ label: center/big
+
+mergeOne:
+ # Merge one map
+ << : *CENTER
+ "r": 10
+ label: center/big
+
+mergeMultiple:
+ # Merge multiple maps
+ << : [ *CENTER, *BIG ]
+ label: center/big
+
+override:
+ # Override
+ << : [ *BIG, *LEFT, *SMALL ]
+ "x": 1
+ label: center/big
+
+shortTag:
+ # Explicit short merge tag
+ !!merge "<<" : [ *CENTER, *BIG ]
+ label: center/big
+
+longTag:
+ # Explicit merge long tag
+ ! "<<" : [ *CENTER, *BIG ]
+ label: center/big
+
+inlineMap:
+ # Inlined map
+ << : {"x": 1, "y": 2, "r": 10}
+ label: center/big
+
+inlineSequenceMap:
+ # Inlined map in sequence
+ << : [ *CENTER, {"r": 10} ]
+ label: center/big
+`
+
+func (s *S) TestMerge(c *C) {
+ var want = map[interface{}]interface{}{
+ "x": 1,
+ "y": 2,
+ "r": 10,
+ "label": "center/big",
+ }
+
+ var m map[interface{}]interface{}
+ err := yaml.Unmarshal([]byte(mergeTests), &m)
+ c.Assert(err, IsNil)
+ for name, test := range m {
+ if name == "anchors" {
+ continue
+ }
+ c.Assert(test, DeepEquals, want, Commentf("test %q failed", name))
+ }
+}
+
+func (s *S) TestMergeStruct(c *C) {
+ type Data struct {
+ X, Y, R int
+ Label string
+ }
+ want := Data{1, 2, 10, "center/big"}
+
+ var m map[string]Data
+ err := yaml.Unmarshal([]byte(mergeTests), &m)
+ c.Assert(err, IsNil)
+ for name, test := range m {
+ if name == "anchors" {
+ continue
+ }
+ c.Assert(test, Equals, want, Commentf("test %q failed", name))
+ }
+}
+
+var unmarshalNullTests = []func() interface{}{
+ func() interface{} { var v interface{}; v = "v"; return &v },
+ func() interface{} { var s = "s"; return &s },
+ func() interface{} { var s = "s"; sptr := &s; return &sptr },
+ func() interface{} { var i = 1; return &i },
+ func() interface{} { var i = 1; iptr := &i; return &iptr },
+ func() interface{} { m := map[string]int{"s": 1}; return &m },
+ func() interface{} { m := map[string]int{"s": 1}; return m },
+}
+
+func (s *S) TestUnmarshalNull(c *C) {
+ for _, test := range unmarshalNullTests {
+ item := test()
+ zero := reflect.Zero(reflect.TypeOf(item).Elem()).Interface()
+ err := yaml.Unmarshal([]byte("null"), item)
+ c.Assert(err, IsNil)
+ if reflect.TypeOf(item).Kind() == reflect.Map {
+ c.Assert(reflect.ValueOf(item).Interface(), DeepEquals, reflect.MakeMap(reflect.TypeOf(item)).Interface())
+ } else {
+ c.Assert(reflect.ValueOf(item).Elem().Interface(), DeepEquals, zero)
+ }
+ }
+}
+
+func (s *S) TestUnmarshalSliceOnPreset(c *C) {
+ // Issue #48.
+ v := struct{ A []int }{[]int{1}}
+ yaml.Unmarshal([]byte("a: [2]"), &v)
+ c.Assert(v.A, DeepEquals, []int{2})
+}
+
+//var data []byte
+//func init() {
+// var err error
+// data, err = ioutil.ReadFile("/tmp/file.yaml")
+// if err != nil {
+// panic(err)
+// }
+//}
+//
+//func (s *S) BenchmarkUnmarshal(c *C) {
+// var err error
+// for i := 0; i < c.N; i++ {
+// var v map[string]interface{}
+// err = yaml.Unmarshal(data, &v)
+// }
+// if err != nil {
+// panic(err)
+// }
+//}
+//
+//func (s *S) BenchmarkMarshal(c *C) {
+// var v map[string]interface{}
+// yaml.Unmarshal(data, &v)
+// c.ResetTimer()
+// for i := 0; i < c.N; i++ {
+// yaml.Marshal(&v)
+// }
+//}
diff --git a/vendor/github.com/coreos/ignition/config/vendor/github.com/go-yaml/yaml/emitterc.go b/vendor/github.com/coreos/ignition/config/vendor/github.com/go-yaml/yaml/emitterc.go
new file mode 100644
index 00000000..9b3dc4a4
--- /dev/null
+++ b/vendor/github.com/coreos/ignition/config/vendor/github.com/go-yaml/yaml/emitterc.go
@@ -0,0 +1,1685 @@
+package yaml
+
+import (
+ "bytes"
+)
+
+// Flush the buffer if needed.
+func flush(emitter *yaml_emitter_t) bool {
+ if emitter.buffer_pos+5 >= len(emitter.buffer) {
+ return yaml_emitter_flush(emitter)
+ }
+ return true
+}
+
+// Put a character to the output buffer.
+func put(emitter *yaml_emitter_t, value byte) bool {
+ if emitter.buffer_pos+5 >= len(emitter.buffer) && !yaml_emitter_flush(emitter) {
+ return false
+ }
+ emitter.buffer[emitter.buffer_pos] = value
+ emitter.buffer_pos++
+ emitter.column++
+ return true
+}
+
+// Put a line break to the output buffer.
+func put_break(emitter *yaml_emitter_t) bool {
+ if emitter.buffer_pos+5 >= len(emitter.buffer) && !yaml_emitter_flush(emitter) {
+ return false
+ }
+ switch emitter.line_break {
+ case yaml_CR_BREAK:
+ emitter.buffer[emitter.buffer_pos] = '\r'
+ emitter.buffer_pos += 1
+ case yaml_LN_BREAK:
+ emitter.buffer[emitter.buffer_pos] = '\n'
+ emitter.buffer_pos += 1
+ case yaml_CRLN_BREAK:
+ emitter.buffer[emitter.buffer_pos+0] = '\r'
+ emitter.buffer[emitter.buffer_pos+1] = '\n'
+ emitter.buffer_pos += 2
+ default:
+ panic("unknown line break setting")
+ }
+ emitter.column = 0
+ emitter.line++
+ return true
+}
+
+// Copy a character from a string into buffer.
+func write(emitter *yaml_emitter_t, s []byte, i *int) bool {
+ if emitter.buffer_pos+5 >= len(emitter.buffer) && !yaml_emitter_flush(emitter) {
+ return false
+ }
+ p := emitter.buffer_pos
+ w := width(s[*i])
+ switch w {
+ case 4:
+ emitter.buffer[p+3] = s[*i+3]
+ fallthrough
+ case 3:
+ emitter.buffer[p+2] = s[*i+2]
+ fallthrough
+ case 2:
+ emitter.buffer[p+1] = s[*i+1]
+ fallthrough
+ case 1:
+ emitter.buffer[p+0] = s[*i+0]
+ default:
+ panic("unknown character width")
+ }
+ emitter.column++
+ emitter.buffer_pos += w
+ *i += w
+ return true
+}
+
+// Write a whole string into buffer.
+func write_all(emitter *yaml_emitter_t, s []byte) bool {
+ for i := 0; i < len(s); {
+ if !write(emitter, s, &i) {
+ return false
+ }
+ }
+ return true
+}
+
+// Copy a line break character from a string into buffer.
+func write_break(emitter *yaml_emitter_t, s []byte, i *int) bool {
+ if s[*i] == '\n' {
+ if !put_break(emitter) {
+ return false
+ }
+ *i++
+ } else {
+ if !write(emitter, s, i) {
+ return false
+ }
+ emitter.column = 0
+ emitter.line++
+ }
+ return true
+}
+
+// Set an emitter error and return false.
+func yaml_emitter_set_emitter_error(emitter *yaml_emitter_t, problem string) bool {
+ emitter.error = yaml_EMITTER_ERROR
+ emitter.problem = problem
+ return false
+}
+
+// Emit an event.
+func yaml_emitter_emit(emitter *yaml_emitter_t, event *yaml_event_t) bool {
+ emitter.events = append(emitter.events, *event)
+ for !yaml_emitter_need_more_events(emitter) {
+ event := &emitter.events[emitter.events_head]
+ if !yaml_emitter_analyze_event(emitter, event) {
+ return false
+ }
+ if !yaml_emitter_state_machine(emitter, event) {
+ return false
+ }
+ yaml_event_delete(event)
+ emitter.events_head++
+ }
+ return true
+}
+
+// Check if we need to accumulate more events before emitting.
+//
+// We accumulate extra
+// - 1 event for DOCUMENT-START
+// - 2 events for SEQUENCE-START
+// - 3 events for MAPPING-START
+//
+func yaml_emitter_need_more_events(emitter *yaml_emitter_t) bool {
+ if emitter.events_head == len(emitter.events) {
+ return true
+ }
+ var accumulate int
+ switch emitter.events[emitter.events_head].typ {
+ case yaml_DOCUMENT_START_EVENT:
+ accumulate = 1
+ break
+ case yaml_SEQUENCE_START_EVENT:
+ accumulate = 2
+ break
+ case yaml_MAPPING_START_EVENT:
+ accumulate = 3
+ break
+ default:
+ return false
+ }
+ if len(emitter.events)-emitter.events_head > accumulate {
+ return false
+ }
+ var level int
+ for i := emitter.events_head; i < len(emitter.events); i++ {
+ switch emitter.events[i].typ {
+ case yaml_STREAM_START_EVENT, yaml_DOCUMENT_START_EVENT, yaml_SEQUENCE_START_EVENT, yaml_MAPPING_START_EVENT:
+ level++
+ case yaml_STREAM_END_EVENT, yaml_DOCUMENT_END_EVENT, yaml_SEQUENCE_END_EVENT, yaml_MAPPING_END_EVENT:
+ level--
+ }
+ if level == 0 {
+ return false
+ }
+ }
+ return true
+}
+
+// Append a directive to the directives stack.
+func yaml_emitter_append_tag_directive(emitter *yaml_emitter_t, value *yaml_tag_directive_t, allow_duplicates bool) bool {
+ for i := 0; i < len(emitter.tag_directives); i++ {
+ if bytes.Equal(value.handle, emitter.tag_directives[i].handle) {
+ if allow_duplicates {
+ return true
+ }
+ return yaml_emitter_set_emitter_error(emitter, "duplicate %TAG directive")
+ }
+ }
+
+ // [Go] Do we actually need to copy this given garbage collection
+ // and the lack of deallocating destructors?
+ tag_copy := yaml_tag_directive_t{
+ handle: make([]byte, len(value.handle)),
+ prefix: make([]byte, len(value.prefix)),
+ }
+ copy(tag_copy.handle, value.handle)
+ copy(tag_copy.prefix, value.prefix)
+ emitter.tag_directives = append(emitter.tag_directives, tag_copy)
+ return true
+}
+
+// Increase the indentation level.
+func yaml_emitter_increase_indent(emitter *yaml_emitter_t, flow, indentless bool) bool {
+ emitter.indents = append(emitter.indents, emitter.indent)
+ if emitter.indent < 0 {
+ if flow {
+ emitter.indent = emitter.best_indent
+ } else {
+ emitter.indent = 0
+ }
+ } else if !indentless {
+ emitter.indent += emitter.best_indent
+ }
+ return true
+}
+
+// State dispatcher.
+func yaml_emitter_state_machine(emitter *yaml_emitter_t, event *yaml_event_t) bool {
+ switch emitter.state {
+ default:
+ case yaml_EMIT_STREAM_START_STATE:
+ return yaml_emitter_emit_stream_start(emitter, event)
+
+ case yaml_EMIT_FIRST_DOCUMENT_START_STATE:
+ return yaml_emitter_emit_document_start(emitter, event, true)
+
+ case yaml_EMIT_DOCUMENT_START_STATE:
+ return yaml_emitter_emit_document_start(emitter, event, false)
+
+ case yaml_EMIT_DOCUMENT_CONTENT_STATE:
+ return yaml_emitter_emit_document_content(emitter, event)
+
+ case yaml_EMIT_DOCUMENT_END_STATE:
+ return yaml_emitter_emit_document_end(emitter, event)
+
+ case yaml_EMIT_FLOW_SEQUENCE_FIRST_ITEM_STATE:
+ return yaml_emitter_emit_flow_sequence_item(emitter, event, true)
+
+ case yaml_EMIT_FLOW_SEQUENCE_ITEM_STATE:
+ return yaml_emitter_emit_flow_sequence_item(emitter, event, false)
+
+ case yaml_EMIT_FLOW_MAPPING_FIRST_KEY_STATE:
+ return yaml_emitter_emit_flow_mapping_key(emitter, event, true)
+
+ case yaml_EMIT_FLOW_MAPPING_KEY_STATE:
+ return yaml_emitter_emit_flow_mapping_key(emitter, event, false)
+
+ case yaml_EMIT_FLOW_MAPPING_SIMPLE_VALUE_STATE:
+ return yaml_emitter_emit_flow_mapping_value(emitter, event, true)
+
+ case yaml_EMIT_FLOW_MAPPING_VALUE_STATE:
+ return yaml_emitter_emit_flow_mapping_value(emitter, event, false)
+
+ case yaml_EMIT_BLOCK_SEQUENCE_FIRST_ITEM_STATE:
+ return yaml_emitter_emit_block_sequence_item(emitter, event, true)
+
+ case yaml_EMIT_BLOCK_SEQUENCE_ITEM_STATE:
+ return yaml_emitter_emit_block_sequence_item(emitter, event, false)
+
+ case yaml_EMIT_BLOCK_MAPPING_FIRST_KEY_STATE:
+ return yaml_emitter_emit_block_mapping_key(emitter, event, true)
+
+ case yaml_EMIT_BLOCK_MAPPING_KEY_STATE:
+ return yaml_emitter_emit_block_mapping_key(emitter, event, false)
+
+ case yaml_EMIT_BLOCK_MAPPING_SIMPLE_VALUE_STATE:
+ return yaml_emitter_emit_block_mapping_value(emitter, event, true)
+
+ case yaml_EMIT_BLOCK_MAPPING_VALUE_STATE:
+ return yaml_emitter_emit_block_mapping_value(emitter, event, false)
+
+ case yaml_EMIT_END_STATE:
+ return yaml_emitter_set_emitter_error(emitter, "expected nothing after STREAM-END")
+ }
+ panic("invalid emitter state")
+}
+
+// Expect STREAM-START.
+func yaml_emitter_emit_stream_start(emitter *yaml_emitter_t, event *yaml_event_t) bool {
+ if event.typ != yaml_STREAM_START_EVENT {
+ return yaml_emitter_set_emitter_error(emitter, "expected STREAM-START")
+ }
+ if emitter.encoding == yaml_ANY_ENCODING {
+ emitter.encoding = event.encoding
+ if emitter.encoding == yaml_ANY_ENCODING {
+ emitter.encoding = yaml_UTF8_ENCODING
+ }
+ }
+ if emitter.best_indent < 2 || emitter.best_indent > 9 {
+ emitter.best_indent = 2
+ }
+ if emitter.best_width >= 0 && emitter.best_width <= emitter.best_indent*2 {
+ emitter.best_width = 80
+ }
+ if emitter.best_width < 0 {
+ emitter.best_width = 1<<31 - 1
+ }
+ if emitter.line_break == yaml_ANY_BREAK {
+ emitter.line_break = yaml_LN_BREAK
+ }
+
+ emitter.indent = -1
+ emitter.line = 0
+ emitter.column = 0
+ emitter.whitespace = true
+ emitter.indention = true
+
+ if emitter.encoding != yaml_UTF8_ENCODING {
+ if !yaml_emitter_write_bom(emitter) {
+ return false
+ }
+ }
+ emitter.state = yaml_EMIT_FIRST_DOCUMENT_START_STATE
+ return true
+}
+
+// Expect DOCUMENT-START or STREAM-END.
+func yaml_emitter_emit_document_start(emitter *yaml_emitter_t, event *yaml_event_t, first bool) bool {
+
+ if event.typ == yaml_DOCUMENT_START_EVENT {
+
+ if event.version_directive != nil {
+ if !yaml_emitter_analyze_version_directive(emitter, event.version_directive) {
+ return false
+ }
+ }
+
+ for i := 0; i < len(event.tag_directives); i++ {
+ tag_directive := &event.tag_directives[i]
+ if !yaml_emitter_analyze_tag_directive(emitter, tag_directive) {
+ return false
+ }
+ if !yaml_emitter_append_tag_directive(emitter, tag_directive, false) {
+ return false
+ }
+ }
+
+ for i := 0; i < len(default_tag_directives); i++ {
+ tag_directive := &default_tag_directives[i]
+ if !yaml_emitter_append_tag_directive(emitter, tag_directive, true) {
+ return false
+ }
+ }
+
+ implicit := event.implicit
+ if !first || emitter.canonical {
+ implicit = false
+ }
+
+ if emitter.open_ended && (event.version_directive != nil || len(event.tag_directives) > 0) {
+ if !yaml_emitter_write_indicator(emitter, []byte("..."), true, false, false) {
+ return false
+ }
+ if !yaml_emitter_write_indent(emitter) {
+ return false
+ }
+ }
+
+ if event.version_directive != nil {
+ implicit = false
+ if !yaml_emitter_write_indicator(emitter, []byte("%YAML"), true, false, false) {
+ return false
+ }
+ if !yaml_emitter_write_indicator(emitter, []byte("1.1"), true, false, false) {
+ return false
+ }
+ if !yaml_emitter_write_indent(emitter) {
+ return false
+ }
+ }
+
+ if len(event.tag_directives) > 0 {
+ implicit = false
+ for i := 0; i < len(event.tag_directives); i++ {
+ tag_directive := &event.tag_directives[i]
+ if !yaml_emitter_write_indicator(emitter, []byte("%TAG"), true, false, false) {
+ return false
+ }
+ if !yaml_emitter_write_tag_handle(emitter, tag_directive.handle) {
+ return false
+ }
+ if !yaml_emitter_write_tag_content(emitter, tag_directive.prefix, true) {
+ return false
+ }
+ if !yaml_emitter_write_indent(emitter) {
+ return false
+ }
+ }
+ }
+
+ if yaml_emitter_check_empty_document(emitter) {
+ implicit = false
+ }
+ if !implicit {
+ if !yaml_emitter_write_indent(emitter) {
+ return false
+ }
+ if !yaml_emitter_write_indicator(emitter, []byte("---"), true, false, false) {
+ return false
+ }
+ if emitter.canonical {
+ if !yaml_emitter_write_indent(emitter) {
+ return false
+ }
+ }
+ }
+
+ emitter.state = yaml_EMIT_DOCUMENT_CONTENT_STATE
+ return true
+ }
+
+ if event.typ == yaml_STREAM_END_EVENT {
+ if emitter.open_ended {
+ if !yaml_emitter_write_indicator(emitter, []byte("..."), true, false, false) {
+ return false
+ }
+ if !yaml_emitter_write_indent(emitter) {
+ return false
+ }
+ }
+ if !yaml_emitter_flush(emitter) {
+ return false
+ }
+ emitter.state = yaml_EMIT_END_STATE
+ return true
+ }
+
+ return yaml_emitter_set_emitter_error(emitter, "expected DOCUMENT-START or STREAM-END")
+}
+
+// Expect the root node.
+func yaml_emitter_emit_document_content(emitter *yaml_emitter_t, event *yaml_event_t) bool {
+ emitter.states = append(emitter.states, yaml_EMIT_DOCUMENT_END_STATE)
+ return yaml_emitter_emit_node(emitter, event, true, false, false, false)
+}
+
+// Expect DOCUMENT-END.
+func yaml_emitter_emit_document_end(emitter *yaml_emitter_t, event *yaml_event_t) bool {
+ if event.typ != yaml_DOCUMENT_END_EVENT {
+ return yaml_emitter_set_emitter_error(emitter, "expected DOCUMENT-END")
+ }
+ if !yaml_emitter_write_indent(emitter) {
+ return false
+ }
+ if !event.implicit {
+ // [Go] Allocate the slice elsewhere.
+ if !yaml_emitter_write_indicator(emitter, []byte("..."), true, false, false) {
+ return false
+ }
+ if !yaml_emitter_write_indent(emitter) {
+ return false
+ }
+ }
+ if !yaml_emitter_flush(emitter) {
+ return false
+ }
+ emitter.state = yaml_EMIT_DOCUMENT_START_STATE
+ emitter.tag_directives = emitter.tag_directives[:0]
+ return true
+}
+
+// Expect a flow item node.
+func yaml_emitter_emit_flow_sequence_item(emitter *yaml_emitter_t, event *yaml_event_t, first bool) bool {
+ if first {
+ if !yaml_emitter_write_indicator(emitter, []byte{'['}, true, true, false) {
+ return false
+ }
+ if !yaml_emitter_increase_indent(emitter, true, false) {
+ return false
+ }
+ emitter.flow_level++
+ }
+
+ if event.typ == yaml_SEQUENCE_END_EVENT {
+ emitter.flow_level--
+ emitter.indent = emitter.indents[len(emitter.indents)-1]
+ emitter.indents = emitter.indents[:len(emitter.indents)-1]
+ if emitter.canonical && !first {
+ if !yaml_emitter_write_indicator(emitter, []byte{','}, false, false, false) {
+ return false
+ }
+ if !yaml_emitter_write_indent(emitter) {
+ return false
+ }
+ }
+ if !yaml_emitter_write_indicator(emitter, []byte{']'}, false, false, false) {
+ return false
+ }
+ emitter.state = emitter.states[len(emitter.states)-1]
+ emitter.states = emitter.states[:len(emitter.states)-1]
+
+ return true
+ }
+
+ if !first {
+ if !yaml_emitter_write_indicator(emitter, []byte{','}, false, false, false) {
+ return false
+ }
+ }
+
+ if emitter.canonical || emitter.column > emitter.best_width {
+ if !yaml_emitter_write_indent(emitter) {
+ return false
+ }
+ }
+ emitter.states = append(emitter.states, yaml_EMIT_FLOW_SEQUENCE_ITEM_STATE)
+ return yaml_emitter_emit_node(emitter, event, false, true, false, false)
+}
+
+// Expect a flow key node.
+func yaml_emitter_emit_flow_mapping_key(emitter *yaml_emitter_t, event *yaml_event_t, first bool) bool {
+ if first {
+ if !yaml_emitter_write_indicator(emitter, []byte{'{'}, true, true, false) {
+ return false
+ }
+ if !yaml_emitter_increase_indent(emitter, true, false) {
+ return false
+ }
+ emitter.flow_level++
+ }
+
+ if event.typ == yaml_MAPPING_END_EVENT {
+ emitter.flow_level--
+ emitter.indent = emitter.indents[len(emitter.indents)-1]
+ emitter.indents = emitter.indents[:len(emitter.indents)-1]
+ if emitter.canonical && !first {
+ if !yaml_emitter_write_indicator(emitter, []byte{','}, false, false, false) {
+ return false
+ }
+ if !yaml_emitter_write_indent(emitter) {
+ return false
+ }
+ }
+ if !yaml_emitter_write_indicator(emitter, []byte{'}'}, false, false, false) {
+ return false
+ }
+ emitter.state = emitter.states[len(emitter.states)-1]
+ emitter.states = emitter.states[:len(emitter.states)-1]
+ return true
+ }
+
+ if !first {
+ if !yaml_emitter_write_indicator(emitter, []byte{','}, false, false, false) {
+ return false
+ }
+ }
+ if emitter.canonical || emitter.column > emitter.best_width {
+ if !yaml_emitter_write_indent(emitter) {
+ return false
+ }
+ }
+
+ if !emitter.canonical && yaml_emitter_check_simple_key(emitter) {
+ emitter.states = append(emitter.states, yaml_EMIT_FLOW_MAPPING_SIMPLE_VALUE_STATE)
+ return yaml_emitter_emit_node(emitter, event, false, false, true, true)
+ }
+ if !yaml_emitter_write_indicator(emitter, []byte{'?'}, true, false, false) {
+ return false
+ }
+ emitter.states = append(emitter.states, yaml_EMIT_FLOW_MAPPING_VALUE_STATE)
+ return yaml_emitter_emit_node(emitter, event, false, false, true, false)
+}
+
+// Expect a flow value node.
+func yaml_emitter_emit_flow_mapping_value(emitter *yaml_emitter_t, event *yaml_event_t, simple bool) bool {
+ if simple {
+ if !yaml_emitter_write_indicator(emitter, []byte{':'}, false, false, false) {
+ return false
+ }
+ } else {
+ if emitter.canonical || emitter.column > emitter.best_width {
+ if !yaml_emitter_write_indent(emitter) {
+ return false
+ }
+ }
+ if !yaml_emitter_write_indicator(emitter, []byte{':'}, true, false, false) {
+ return false
+ }
+ }
+ emitter.states = append(emitter.states, yaml_EMIT_FLOW_MAPPING_KEY_STATE)
+ return yaml_emitter_emit_node(emitter, event, false, false, true, false)
+}
+
+// Expect a block item node.
+func yaml_emitter_emit_block_sequence_item(emitter *yaml_emitter_t, event *yaml_event_t, first bool) bool {
+ if first {
+ if !yaml_emitter_increase_indent(emitter, false, emitter.mapping_context && !emitter.indention) {
+ return false
+ }
+ }
+ if event.typ == yaml_SEQUENCE_END_EVENT {
+ emitter.indent = emitter.indents[len(emitter.indents)-1]
+ emitter.indents = emitter.indents[:len(emitter.indents)-1]
+ emitter.state = emitter.states[len(emitter.states)-1]
+ emitter.states = emitter.states[:len(emitter.states)-1]
+ return true
+ }
+ if !yaml_emitter_write_indent(emitter) {
+ return false
+ }
+ if !yaml_emitter_write_indicator(emitter, []byte{'-'}, true, false, true) {
+ return false
+ }
+ emitter.states = append(emitter.states, yaml_EMIT_BLOCK_SEQUENCE_ITEM_STATE)
+ return yaml_emitter_emit_node(emitter, event, false, true, false, false)
+}
+
+// Expect a block key node.
+func yaml_emitter_emit_block_mapping_key(emitter *yaml_emitter_t, event *yaml_event_t, first bool) bool {
+ if first {
+ if !yaml_emitter_increase_indent(emitter, false, false) {
+ return false
+ }
+ }
+ if event.typ == yaml_MAPPING_END_EVENT {
+ emitter.indent = emitter.indents[len(emitter.indents)-1]
+ emitter.indents = emitter.indents[:len(emitter.indents)-1]
+ emitter.state = emitter.states[len(emitter.states)-1]
+ emitter.states = emitter.states[:len(emitter.states)-1]
+ return true
+ }
+ if !yaml_emitter_write_indent(emitter) {
+ return false
+ }
+ if yaml_emitter_check_simple_key(emitter) {
+ emitter.states = append(emitter.states, yaml_EMIT_BLOCK_MAPPING_SIMPLE_VALUE_STATE)
+ return yaml_emitter_emit_node(emitter, event, false, false, true, true)
+ }
+ if !yaml_emitter_write_indicator(emitter, []byte{'?'}, true, false, true) {
+ return false
+ }
+ emitter.states = append(emitter.states, yaml_EMIT_BLOCK_MAPPING_VALUE_STATE)
+ return yaml_emitter_emit_node(emitter, event, false, false, true, false)
+}
+
+// Expect a block value node.
+func yaml_emitter_emit_block_mapping_value(emitter *yaml_emitter_t, event *yaml_event_t, simple bool) bool {
+ if simple {
+ if !yaml_emitter_write_indicator(emitter, []byte{':'}, false, false, false) {
+ return false
+ }
+ } else {
+ if !yaml_emitter_write_indent(emitter) {
+ return false
+ }
+ if !yaml_emitter_write_indicator(emitter, []byte{':'}, true, false, true) {
+ return false
+ }
+ }
+ emitter.states = append(emitter.states, yaml_EMIT_BLOCK_MAPPING_KEY_STATE)
+ return yaml_emitter_emit_node(emitter, event, false, false, true, false)
+}
+
+// Expect a node.
+func yaml_emitter_emit_node(emitter *yaml_emitter_t, event *yaml_event_t,
+ root bool, sequence bool, mapping bool, simple_key bool) bool {
+
+ emitter.root_context = root
+ emitter.sequence_context = sequence
+ emitter.mapping_context = mapping
+ emitter.simple_key_context = simple_key
+
+ switch event.typ {
+ case yaml_ALIAS_EVENT:
+ return yaml_emitter_emit_alias(emitter, event)
+ case yaml_SCALAR_EVENT:
+ return yaml_emitter_emit_scalar(emitter, event)
+ case yaml_SEQUENCE_START_EVENT:
+ return yaml_emitter_emit_sequence_start(emitter, event)
+ case yaml_MAPPING_START_EVENT:
+ return yaml_emitter_emit_mapping_start(emitter, event)
+ default:
+ return yaml_emitter_set_emitter_error(emitter,
+ "expected SCALAR, SEQUENCE-START, MAPPING-START, or ALIAS")
+ }
+ return false
+}
+
+// Expect ALIAS.
+func yaml_emitter_emit_alias(emitter *yaml_emitter_t, event *yaml_event_t) bool {
+ if !yaml_emitter_process_anchor(emitter) {
+ return false
+ }
+ emitter.state = emitter.states[len(emitter.states)-1]
+ emitter.states = emitter.states[:len(emitter.states)-1]
+ return true
+}
+
+// Expect SCALAR.
+func yaml_emitter_emit_scalar(emitter *yaml_emitter_t, event *yaml_event_t) bool {
+ if !yaml_emitter_select_scalar_style(emitter, event) {
+ return false
+ }
+ if !yaml_emitter_process_anchor(emitter) {
+ return false
+ }
+ if !yaml_emitter_process_tag(emitter) {
+ return false
+ }
+ if !yaml_emitter_increase_indent(emitter, true, false) {
+ return false
+ }
+ if !yaml_emitter_process_scalar(emitter) {
+ return false
+ }
+ emitter.indent = emitter.indents[len(emitter.indents)-1]
+ emitter.indents = emitter.indents[:len(emitter.indents)-1]
+ emitter.state = emitter.states[len(emitter.states)-1]
+ emitter.states = emitter.states[:len(emitter.states)-1]
+ return true
+}
+
+// Expect SEQUENCE-START.
+func yaml_emitter_emit_sequence_start(emitter *yaml_emitter_t, event *yaml_event_t) bool {
+ if !yaml_emitter_process_anchor(emitter) {
+ return false
+ }
+ if !yaml_emitter_process_tag(emitter) {
+ return false
+ }
+ if emitter.flow_level > 0 || emitter.canonical || event.sequence_style() == yaml_FLOW_SEQUENCE_STYLE ||
+ yaml_emitter_check_empty_sequence(emitter) {
+ emitter.state = yaml_EMIT_FLOW_SEQUENCE_FIRST_ITEM_STATE
+ } else {
+ emitter.state = yaml_EMIT_BLOCK_SEQUENCE_FIRST_ITEM_STATE
+ }
+ return true
+}
+
+// Expect MAPPING-START.
+func yaml_emitter_emit_mapping_start(emitter *yaml_emitter_t, event *yaml_event_t) bool {
+ if !yaml_emitter_process_anchor(emitter) {
+ return false
+ }
+ if !yaml_emitter_process_tag(emitter) {
+ return false
+ }
+ if emitter.flow_level > 0 || emitter.canonical || event.mapping_style() == yaml_FLOW_MAPPING_STYLE ||
+ yaml_emitter_check_empty_mapping(emitter) {
+ emitter.state = yaml_EMIT_FLOW_MAPPING_FIRST_KEY_STATE
+ } else {
+ emitter.state = yaml_EMIT_BLOCK_MAPPING_FIRST_KEY_STATE
+ }
+ return true
+}
+
+// Check if the document content is an empty scalar.
+func yaml_emitter_check_empty_document(emitter *yaml_emitter_t) bool {
+ return false // [Go] Huh?
+}
+
+// Check if the next events represent an empty sequence.
+func yaml_emitter_check_empty_sequence(emitter *yaml_emitter_t) bool {
+ if len(emitter.events)-emitter.events_head < 2 {
+ return false
+ }
+ return emitter.events[emitter.events_head].typ == yaml_SEQUENCE_START_EVENT &&
+ emitter.events[emitter.events_head+1].typ == yaml_SEQUENCE_END_EVENT
+}
+
+// Check if the next events represent an empty mapping.
+func yaml_emitter_check_empty_mapping(emitter *yaml_emitter_t) bool {
+ if len(emitter.events)-emitter.events_head < 2 {
+ return false
+ }
+ return emitter.events[emitter.events_head].typ == yaml_MAPPING_START_EVENT &&
+ emitter.events[emitter.events_head+1].typ == yaml_MAPPING_END_EVENT
+}
+
+// Check if the next node can be expressed as a simple key.
+func yaml_emitter_check_simple_key(emitter *yaml_emitter_t) bool {
+ length := 0
+ switch emitter.events[emitter.events_head].typ {
+ case yaml_ALIAS_EVENT:
+ length += len(emitter.anchor_data.anchor)
+ case yaml_SCALAR_EVENT:
+ if emitter.scalar_data.multiline {
+ return false
+ }
+ length += len(emitter.anchor_data.anchor) +
+ len(emitter.tag_data.handle) +
+ len(emitter.tag_data.suffix) +
+ len(emitter.scalar_data.value)
+ case yaml_SEQUENCE_START_EVENT:
+ if !yaml_emitter_check_empty_sequence(emitter) {
+ return false
+ }
+ length += len(emitter.anchor_data.anchor) +
+ len(emitter.tag_data.handle) +
+ len(emitter.tag_data.suffix)
+ case yaml_MAPPING_START_EVENT:
+ if !yaml_emitter_check_empty_mapping(emitter) {
+ return false
+ }
+ length += len(emitter.anchor_data.anchor) +
+ len(emitter.tag_data.handle) +
+ len(emitter.tag_data.suffix)
+ default:
+ return false
+ }
+ return length <= 128
+}
+
+// Determine an acceptable scalar style.
+func yaml_emitter_select_scalar_style(emitter *yaml_emitter_t, event *yaml_event_t) bool {
+
+ no_tag := len(emitter.tag_data.handle) == 0 && len(emitter.tag_data.suffix) == 0
+ if no_tag && !event.implicit && !event.quoted_implicit {
+ return yaml_emitter_set_emitter_error(emitter, "neither tag nor implicit flags are specified")
+ }
+
+ style := event.scalar_style()
+ if style == yaml_ANY_SCALAR_STYLE {
+ style = yaml_PLAIN_SCALAR_STYLE
+ }
+ if emitter.canonical {
+ style = yaml_DOUBLE_QUOTED_SCALAR_STYLE
+ }
+ if emitter.simple_key_context && emitter.scalar_data.multiline {
+ style = yaml_DOUBLE_QUOTED_SCALAR_STYLE
+ }
+
+ if style == yaml_PLAIN_SCALAR_STYLE {
+ if emitter.flow_level > 0 && !emitter.scalar_data.flow_plain_allowed ||
+ emitter.flow_level == 0 && !emitter.scalar_data.block_plain_allowed {
+ style = yaml_SINGLE_QUOTED_SCALAR_STYLE
+ }
+ if len(emitter.scalar_data.value) == 0 && (emitter.flow_level > 0 || emitter.simple_key_context) {
+ style = yaml_SINGLE_QUOTED_SCALAR_STYLE
+ }
+ if no_tag && !event.implicit {
+ style = yaml_SINGLE_QUOTED_SCALAR_STYLE
+ }
+ }
+ if style == yaml_SINGLE_QUOTED_SCALAR_STYLE {
+ if !emitter.scalar_data.single_quoted_allowed {
+ style = yaml_DOUBLE_QUOTED_SCALAR_STYLE
+ }
+ }
+ if style == yaml_LITERAL_SCALAR_STYLE || style == yaml_FOLDED_SCALAR_STYLE {
+ if !emitter.scalar_data.block_allowed || emitter.flow_level > 0 || emitter.simple_key_context {
+ style = yaml_DOUBLE_QUOTED_SCALAR_STYLE
+ }
+ }
+
+ if no_tag && !event.quoted_implicit && style != yaml_PLAIN_SCALAR_STYLE {
+ emitter.tag_data.handle = []byte{'!'}
+ }
+ emitter.scalar_data.style = style
+ return true
+}
+
+// Write an achor.
+func yaml_emitter_process_anchor(emitter *yaml_emitter_t) bool {
+ if emitter.anchor_data.anchor == nil {
+ return true
+ }
+ c := []byte{'&'}
+ if emitter.anchor_data.alias {
+ c[0] = '*'
+ }
+ if !yaml_emitter_write_indicator(emitter, c, true, false, false) {
+ return false
+ }
+ return yaml_emitter_write_anchor(emitter, emitter.anchor_data.anchor)
+}
+
+// Write a tag.
+func yaml_emitter_process_tag(emitter *yaml_emitter_t) bool {
+ if len(emitter.tag_data.handle) == 0 && len(emitter.tag_data.suffix) == 0 {
+ return true
+ }
+ if len(emitter.tag_data.handle) > 0 {
+ if !yaml_emitter_write_tag_handle(emitter, emitter.tag_data.handle) {
+ return false
+ }
+ if len(emitter.tag_data.suffix) > 0 {
+ if !yaml_emitter_write_tag_content(emitter, emitter.tag_data.suffix, false) {
+ return false
+ }
+ }
+ } else {
+ // [Go] Allocate these slices elsewhere.
+ if !yaml_emitter_write_indicator(emitter, []byte("!<"), true, false, false) {
+ return false
+ }
+ if !yaml_emitter_write_tag_content(emitter, emitter.tag_data.suffix, false) {
+ return false
+ }
+ if !yaml_emitter_write_indicator(emitter, []byte{'>'}, false, false, false) {
+ return false
+ }
+ }
+ return true
+}
+
+// Write a scalar.
+func yaml_emitter_process_scalar(emitter *yaml_emitter_t) bool {
+ switch emitter.scalar_data.style {
+ case yaml_PLAIN_SCALAR_STYLE:
+ return yaml_emitter_write_plain_scalar(emitter, emitter.scalar_data.value, !emitter.simple_key_context)
+
+ case yaml_SINGLE_QUOTED_SCALAR_STYLE:
+ return yaml_emitter_write_single_quoted_scalar(emitter, emitter.scalar_data.value, !emitter.simple_key_context)
+
+ case yaml_DOUBLE_QUOTED_SCALAR_STYLE:
+ return yaml_emitter_write_double_quoted_scalar(emitter, emitter.scalar_data.value, !emitter.simple_key_context)
+
+ case yaml_LITERAL_SCALAR_STYLE:
+ return yaml_emitter_write_literal_scalar(emitter, emitter.scalar_data.value)
+
+ case yaml_FOLDED_SCALAR_STYLE:
+ return yaml_emitter_write_folded_scalar(emitter, emitter.scalar_data.value)
+ }
+ panic("unknown scalar style")
+}
+
+// Check if a %YAML directive is valid.
+func yaml_emitter_analyze_version_directive(emitter *yaml_emitter_t, version_directive *yaml_version_directive_t) bool {
+ if version_directive.major != 1 || version_directive.minor != 1 {
+ return yaml_emitter_set_emitter_error(emitter, "incompatible %YAML directive")
+ }
+ return true
+}
+
+// Check if a %TAG directive is valid.
+func yaml_emitter_analyze_tag_directive(emitter *yaml_emitter_t, tag_directive *yaml_tag_directive_t) bool {
+ handle := tag_directive.handle
+ prefix := tag_directive.prefix
+ if len(handle) == 0 {
+ return yaml_emitter_set_emitter_error(emitter, "tag handle must not be empty")
+ }
+ if handle[0] != '!' {
+ return yaml_emitter_set_emitter_error(emitter, "tag handle must start with '!'")
+ }
+ if handle[len(handle)-1] != '!' {
+ return yaml_emitter_set_emitter_error(emitter, "tag handle must end with '!'")
+ }
+ for i := 1; i < len(handle)-1; i += width(handle[i]) {
+ if !is_alpha(handle, i) {
+ return yaml_emitter_set_emitter_error(emitter, "tag handle must contain alphanumerical characters only")
+ }
+ }
+ if len(prefix) == 0 {
+ return yaml_emitter_set_emitter_error(emitter, "tag prefix must not be empty")
+ }
+ return true
+}
+
+// Check if an anchor is valid.
+func yaml_emitter_analyze_anchor(emitter *yaml_emitter_t, anchor []byte, alias bool) bool {
+ if len(anchor) == 0 {
+ problem := "anchor value must not be empty"
+ if alias {
+ problem = "alias value must not be empty"
+ }
+ return yaml_emitter_set_emitter_error(emitter, problem)
+ }
+ for i := 0; i < len(anchor); i += width(anchor[i]) {
+ if !is_alpha(anchor, i) {
+ problem := "anchor value must contain alphanumerical characters only"
+ if alias {
+ problem = "alias value must contain alphanumerical characters only"
+ }
+ return yaml_emitter_set_emitter_error(emitter, problem)
+ }
+ }
+ emitter.anchor_data.anchor = anchor
+ emitter.anchor_data.alias = alias
+ return true
+}
+
+// Check if a tag is valid.
+func yaml_emitter_analyze_tag(emitter *yaml_emitter_t, tag []byte) bool {
+ if len(tag) == 0 {
+ return yaml_emitter_set_emitter_error(emitter, "tag value must not be empty")
+ }
+ for i := 0; i < len(emitter.tag_directives); i++ {
+ tag_directive := &emitter.tag_directives[i]
+ if bytes.HasPrefix(tag, tag_directive.prefix) {
+ emitter.tag_data.handle = tag_directive.handle
+ emitter.tag_data.suffix = tag[len(tag_directive.prefix):]
+ return true
+ }
+ }
+ emitter.tag_data.suffix = tag
+ return true
+}
+
+// Check if a scalar is valid.
+func yaml_emitter_analyze_scalar(emitter *yaml_emitter_t, value []byte) bool {
+ var (
+ block_indicators = false
+ flow_indicators = false
+ line_breaks = false
+ special_characters = false
+
+ leading_space = false
+ leading_break = false
+ trailing_space = false
+ trailing_break = false
+ break_space = false
+ space_break = false
+
+ preceeded_by_whitespace = false
+ followed_by_whitespace = false
+ previous_space = false
+ previous_break = false
+ )
+
+ emitter.scalar_data.value = value
+
+ if len(value) == 0 {
+ emitter.scalar_data.multiline = false
+ emitter.scalar_data.flow_plain_allowed = false
+ emitter.scalar_data.block_plain_allowed = true
+ emitter.scalar_data.single_quoted_allowed = true
+ emitter.scalar_data.block_allowed = false
+ return true
+ }
+
+ if len(value) >= 3 && ((value[0] == '-' && value[1] == '-' && value[2] == '-') || (value[0] == '.' && value[1] == '.' && value[2] == '.')) {
+ block_indicators = true
+ flow_indicators = true
+ }
+
+ preceeded_by_whitespace = true
+ for i, w := 0, 0; i < len(value); i += w {
+ w = width(value[0])
+ followed_by_whitespace = i+w >= len(value) || is_blank(value, i+w)
+
+ if i == 0 {
+ switch value[i] {
+ case '#', ',', '[', ']', '{', '}', '&', '*', '!', '|', '>', '\'', '"', '%', '@', '`':
+ flow_indicators = true
+ block_indicators = true
+ case '?', ':':
+ flow_indicators = true
+ if followed_by_whitespace {
+ block_indicators = true
+ }
+ case '-':
+ if followed_by_whitespace {
+ flow_indicators = true
+ block_indicators = true
+ }
+ }
+ } else {
+ switch value[i] {
+ case ',', '?', '[', ']', '{', '}':
+ flow_indicators = true
+ case ':':
+ flow_indicators = true
+ if followed_by_whitespace {
+ block_indicators = true
+ }
+ case '#':
+ if preceeded_by_whitespace {
+ flow_indicators = true
+ block_indicators = true
+ }
+ }
+ }
+
+ if !is_printable(value, i) || !is_ascii(value, i) && !emitter.unicode {
+ special_characters = true
+ }
+ if is_space(value, i) {
+ if i == 0 {
+ leading_space = true
+ }
+ if i+width(value[i]) == len(value) {
+ trailing_space = true
+ }
+ if previous_break {
+ break_space = true
+ }
+ previous_space = true
+ previous_break = false
+ } else if is_break(value, i) {
+ line_breaks = true
+ if i == 0 {
+ leading_break = true
+ }
+ if i+width(value[i]) == len(value) {
+ trailing_break = true
+ }
+ if previous_space {
+ space_break = true
+ }
+ previous_space = false
+ previous_break = true
+ } else {
+ previous_space = false
+ previous_break = false
+ }
+
+ // [Go]: Why 'z'? Couldn't be the end of the string as that's the loop condition.
+ preceeded_by_whitespace = is_blankz(value, i)
+ }
+
+ emitter.scalar_data.multiline = line_breaks
+ emitter.scalar_data.flow_plain_allowed = true
+ emitter.scalar_data.block_plain_allowed = true
+ emitter.scalar_data.single_quoted_allowed = true
+ emitter.scalar_data.block_allowed = true
+
+ if leading_space || leading_break || trailing_space || trailing_break {
+ emitter.scalar_data.flow_plain_allowed = false
+ emitter.scalar_data.block_plain_allowed = false
+ }
+ if trailing_space {
+ emitter.scalar_data.block_allowed = false
+ }
+ if break_space {
+ emitter.scalar_data.flow_plain_allowed = false
+ emitter.scalar_data.block_plain_allowed = false
+ emitter.scalar_data.single_quoted_allowed = false
+ }
+ if space_break || special_characters {
+ emitter.scalar_data.flow_plain_allowed = false
+ emitter.scalar_data.block_plain_allowed = false
+ emitter.scalar_data.single_quoted_allowed = false
+ emitter.scalar_data.block_allowed = false
+ }
+ if line_breaks {
+ emitter.scalar_data.flow_plain_allowed = false
+ emitter.scalar_data.block_plain_allowed = false
+ }
+ if flow_indicators {
+ emitter.scalar_data.flow_plain_allowed = false
+ }
+ if block_indicators {
+ emitter.scalar_data.block_plain_allowed = false
+ }
+ return true
+}
+
+// Check if the event data is valid.
+func yaml_emitter_analyze_event(emitter *yaml_emitter_t, event *yaml_event_t) bool {
+
+ emitter.anchor_data.anchor = nil
+ emitter.tag_data.handle = nil
+ emitter.tag_data.suffix = nil
+ emitter.scalar_data.value = nil
+
+ switch event.typ {
+ case yaml_ALIAS_EVENT:
+ if !yaml_emitter_analyze_anchor(emitter, event.anchor, true) {
+ return false
+ }
+
+ case yaml_SCALAR_EVENT:
+ if len(event.anchor) > 0 {
+ if !yaml_emitter_analyze_anchor(emitter, event.anchor, false) {
+ return false
+ }
+ }
+ if len(event.tag) > 0 && (emitter.canonical || (!event.implicit && !event.quoted_implicit)) {
+ if !yaml_emitter_analyze_tag(emitter, event.tag) {
+ return false
+ }
+ }
+ if !yaml_emitter_analyze_scalar(emitter, event.value) {
+ return false
+ }
+
+ case yaml_SEQUENCE_START_EVENT:
+ if len(event.anchor) > 0 {
+ if !yaml_emitter_analyze_anchor(emitter, event.anchor, false) {
+ return false
+ }
+ }
+ if len(event.tag) > 0 && (emitter.canonical || !event.implicit) {
+ if !yaml_emitter_analyze_tag(emitter, event.tag) {
+ return false
+ }
+ }
+
+ case yaml_MAPPING_START_EVENT:
+ if len(event.anchor) > 0 {
+ if !yaml_emitter_analyze_anchor(emitter, event.anchor, false) {
+ return false
+ }
+ }
+ if len(event.tag) > 0 && (emitter.canonical || !event.implicit) {
+ if !yaml_emitter_analyze_tag(emitter, event.tag) {
+ return false
+ }
+ }
+ }
+ return true
+}
+
+// Write the BOM character.
+func yaml_emitter_write_bom(emitter *yaml_emitter_t) bool {
+ if !flush(emitter) {
+ return false
+ }
+ pos := emitter.buffer_pos
+ emitter.buffer[pos+0] = '\xEF'
+ emitter.buffer[pos+1] = '\xBB'
+ emitter.buffer[pos+2] = '\xBF'
+ emitter.buffer_pos += 3
+ return true
+}
+
+func yaml_emitter_write_indent(emitter *yaml_emitter_t) bool {
+ indent := emitter.indent
+ if indent < 0 {
+ indent = 0
+ }
+ if !emitter.indention || emitter.column > indent || (emitter.column == indent && !emitter.whitespace) {
+ if !put_break(emitter) {
+ return false
+ }
+ }
+ for emitter.column < indent {
+ if !put(emitter, ' ') {
+ return false
+ }
+ }
+ emitter.whitespace = true
+ emitter.indention = true
+ return true
+}
+
+func yaml_emitter_write_indicator(emitter *yaml_emitter_t, indicator []byte, need_whitespace, is_whitespace, is_indention bool) bool {
+ if need_whitespace && !emitter.whitespace {
+ if !put(emitter, ' ') {
+ return false
+ }
+ }
+ if !write_all(emitter, indicator) {
+ return false
+ }
+ emitter.whitespace = is_whitespace
+ emitter.indention = (emitter.indention && is_indention)
+ emitter.open_ended = false
+ return true
+}
+
+func yaml_emitter_write_anchor(emitter *yaml_emitter_t, value []byte) bool {
+ if !write_all(emitter, value) {
+ return false
+ }
+ emitter.whitespace = false
+ emitter.indention = false
+ return true
+}
+
+func yaml_emitter_write_tag_handle(emitter *yaml_emitter_t, value []byte) bool {
+ if !emitter.whitespace {
+ if !put(emitter, ' ') {
+ return false
+ }
+ }
+ if !write_all(emitter, value) {
+ return false
+ }
+ emitter.whitespace = false
+ emitter.indention = false
+ return true
+}
+
+func yaml_emitter_write_tag_content(emitter *yaml_emitter_t, value []byte, need_whitespace bool) bool {
+ if need_whitespace && !emitter.whitespace {
+ if !put(emitter, ' ') {
+ return false
+ }
+ }
+ for i := 0; i < len(value); {
+ var must_write bool
+ switch value[i] {
+ case ';', '/', '?', ':', '@', '&', '=', '+', '$', ',', '_', '.', '~', '*', '\'', '(', ')', '[', ']':
+ must_write = true
+ default:
+ must_write = is_alpha(value, i)
+ }
+ if must_write {
+ if !write(emitter, value, &i) {
+ return false
+ }
+ } else {
+ w := width(value[i])
+ for k := 0; k < w; k++ {
+ octet := value[i]
+ i++
+ if !put(emitter, '%') {
+ return false
+ }
+
+ c := octet >> 4
+ if c < 10 {
+ c += '0'
+ } else {
+ c += 'A' - 10
+ }
+ if !put(emitter, c) {
+ return false
+ }
+
+ c = octet & 0x0f
+ if c < 10 {
+ c += '0'
+ } else {
+ c += 'A' - 10
+ }
+ if !put(emitter, c) {
+ return false
+ }
+ }
+ }
+ }
+ emitter.whitespace = false
+ emitter.indention = false
+ return true
+}
+
+func yaml_emitter_write_plain_scalar(emitter *yaml_emitter_t, value []byte, allow_breaks bool) bool {
+ if !emitter.whitespace {
+ if !put(emitter, ' ') {
+ return false
+ }
+ }
+
+ spaces := false
+ breaks := false
+ for i := 0; i < len(value); {
+ if is_space(value, i) {
+ if allow_breaks && !spaces && emitter.column > emitter.best_width && !is_space(value, i+1) {
+ if !yaml_emitter_write_indent(emitter) {
+ return false
+ }
+ i += width(value[i])
+ } else {
+ if !write(emitter, value, &i) {
+ return false
+ }
+ }
+ spaces = true
+ } else if is_break(value, i) {
+ if !breaks && value[i] == '\n' {
+ if !put_break(emitter) {
+ return false
+ }
+ }
+ if !write_break(emitter, value, &i) {
+ return false
+ }
+ emitter.indention = true
+ breaks = true
+ } else {
+ if breaks {
+ if !yaml_emitter_write_indent(emitter) {
+ return false
+ }
+ }
+ if !write(emitter, value, &i) {
+ return false
+ }
+ emitter.indention = false
+ spaces = false
+ breaks = false
+ }
+ }
+
+ emitter.whitespace = false
+ emitter.indention = false
+ if emitter.root_context {
+ emitter.open_ended = true
+ }
+
+ return true
+}
+
+func yaml_emitter_write_single_quoted_scalar(emitter *yaml_emitter_t, value []byte, allow_breaks bool) bool {
+
+ if !yaml_emitter_write_indicator(emitter, []byte{'\''}, true, false, false) {
+ return false
+ }
+
+ spaces := false
+ breaks := false
+ for i := 0; i < len(value); {
+ if is_space(value, i) {
+ if allow_breaks && !spaces && emitter.column > emitter.best_width && i > 0 && i < len(value)-1 && !is_space(value, i+1) {
+ if !yaml_emitter_write_indent(emitter) {
+ return false
+ }
+ i += width(value[i])
+ } else {
+ if !write(emitter, value, &i) {
+ return false
+ }
+ }
+ spaces = true
+ } else if is_break(value, i) {
+ if !breaks && value[i] == '\n' {
+ if !put_break(emitter) {
+ return false
+ }
+ }
+ if !write_break(emitter, value, &i) {
+ return false
+ }
+ emitter.indention = true
+ breaks = true
+ } else {
+ if breaks {
+ if !yaml_emitter_write_indent(emitter) {
+ return false
+ }
+ }
+ if value[i] == '\'' {
+ if !put(emitter, '\'') {
+ return false
+ }
+ }
+ if !write(emitter, value, &i) {
+ return false
+ }
+ emitter.indention = false
+ spaces = false
+ breaks = false
+ }
+ }
+ if !yaml_emitter_write_indicator(emitter, []byte{'\''}, false, false, false) {
+ return false
+ }
+ emitter.whitespace = false
+ emitter.indention = false
+ return true
+}
+
+func yaml_emitter_write_double_quoted_scalar(emitter *yaml_emitter_t, value []byte, allow_breaks bool) bool {
+ spaces := false
+ if !yaml_emitter_write_indicator(emitter, []byte{'"'}, true, false, false) {
+ return false
+ }
+
+ for i := 0; i < len(value); {
+ if !is_printable(value, i) || (!emitter.unicode && !is_ascii(value, i)) ||
+ is_bom(value, i) || is_break(value, i) ||
+ value[i] == '"' || value[i] == '\\' {
+
+ octet := value[i]
+
+ var w int
+ var v rune
+ switch {
+ case octet&0x80 == 0x00:
+ w, v = 1, rune(octet&0x7F)
+ case octet&0xE0 == 0xC0:
+ w, v = 2, rune(octet&0x1F)
+ case octet&0xF0 == 0xE0:
+ w, v = 3, rune(octet&0x0F)
+ case octet&0xF8 == 0xF0:
+ w, v = 4, rune(octet&0x07)
+ }
+ for k := 1; k < w; k++ {
+ octet = value[i+k]
+ v = (v << 6) + (rune(octet) & 0x3F)
+ }
+ i += w
+
+ if !put(emitter, '\\') {
+ return false
+ }
+
+ var ok bool
+ switch v {
+ case 0x00:
+ ok = put(emitter, '0')
+ case 0x07:
+ ok = put(emitter, 'a')
+ case 0x08:
+ ok = put(emitter, 'b')
+ case 0x09:
+ ok = put(emitter, 't')
+ case 0x0A:
+ ok = put(emitter, 'n')
+ case 0x0b:
+ ok = put(emitter, 'v')
+ case 0x0c:
+ ok = put(emitter, 'f')
+ case 0x0d:
+ ok = put(emitter, 'r')
+ case 0x1b:
+ ok = put(emitter, 'e')
+ case 0x22:
+ ok = put(emitter, '"')
+ case 0x5c:
+ ok = put(emitter, '\\')
+ case 0x85:
+ ok = put(emitter, 'N')
+ case 0xA0:
+ ok = put(emitter, '_')
+ case 0x2028:
+ ok = put(emitter, 'L')
+ case 0x2029:
+ ok = put(emitter, 'P')
+ default:
+ if v <= 0xFF {
+ ok = put(emitter, 'x')
+ w = 2
+ } else if v <= 0xFFFF {
+ ok = put(emitter, 'u')
+ w = 4
+ } else {
+ ok = put(emitter, 'U')
+ w = 8
+ }
+ for k := (w - 1) * 4; ok && k >= 0; k -= 4 {
+ digit := byte((v >> uint(k)) & 0x0F)
+ if digit < 10 {
+ ok = put(emitter, digit+'0')
+ } else {
+ ok = put(emitter, digit+'A'-10)
+ }
+ }
+ }
+ if !ok {
+ return false
+ }
+ spaces = false
+ } else if is_space(value, i) {
+ if allow_breaks && !spaces && emitter.column > emitter.best_width && i > 0 && i < len(value)-1 {
+ if !yaml_emitter_write_indent(emitter) {
+ return false
+ }
+ if is_space(value, i+1) {
+ if !put(emitter, '\\') {
+ return false
+ }
+ }
+ i += width(value[i])
+ } else if !write(emitter, value, &i) {
+ return false
+ }
+ spaces = true
+ } else {
+ if !write(emitter, value, &i) {
+ return false
+ }
+ spaces = false
+ }
+ }
+ if !yaml_emitter_write_indicator(emitter, []byte{'"'}, false, false, false) {
+ return false
+ }
+ emitter.whitespace = false
+ emitter.indention = false
+ return true
+}
+
+func yaml_emitter_write_block_scalar_hints(emitter *yaml_emitter_t, value []byte) bool {
+ if is_space(value, 0) || is_break(value, 0) {
+ indent_hint := []byte{'0' + byte(emitter.best_indent)}
+ if !yaml_emitter_write_indicator(emitter, indent_hint, false, false, false) {
+ return false
+ }
+ }
+
+ emitter.open_ended = false
+
+ var chomp_hint [1]byte
+ if len(value) == 0 {
+ chomp_hint[0] = '-'
+ } else {
+ i := len(value) - 1
+ for value[i]&0xC0 == 0x80 {
+ i--
+ }
+ if !is_break(value, i) {
+ chomp_hint[0] = '-'
+ } else if i == 0 {
+ chomp_hint[0] = '+'
+ emitter.open_ended = true
+ } else {
+ i--
+ for value[i]&0xC0 == 0x80 {
+ i--
+ }
+ if is_break(value, i) {
+ chomp_hint[0] = '+'
+ emitter.open_ended = true
+ }
+ }
+ }
+ if chomp_hint[0] != 0 {
+ if !yaml_emitter_write_indicator(emitter, chomp_hint[:], false, false, false) {
+ return false
+ }
+ }
+ return true
+}
+
+func yaml_emitter_write_literal_scalar(emitter *yaml_emitter_t, value []byte) bool {
+ if !yaml_emitter_write_indicator(emitter, []byte{'|'}, true, false, false) {
+ return false
+ }
+ if !yaml_emitter_write_block_scalar_hints(emitter, value) {
+ return false
+ }
+ if !put_break(emitter) {
+ return false
+ }
+ emitter.indention = true
+ emitter.whitespace = true
+ breaks := true
+ for i := 0; i < len(value); {
+ if is_break(value, i) {
+ if !write_break(emitter, value, &i) {
+ return false
+ }
+ emitter.indention = true
+ breaks = true
+ } else {
+ if breaks {
+ if !yaml_emitter_write_indent(emitter) {
+ return false
+ }
+ }
+ if !write(emitter, value, &i) {
+ return false
+ }
+ emitter.indention = false
+ breaks = false
+ }
+ }
+
+ return true
+}
+
+func yaml_emitter_write_folded_scalar(emitter *yaml_emitter_t, value []byte) bool {
+ if !yaml_emitter_write_indicator(emitter, []byte{'>'}, true, false, false) {
+ return false
+ }
+ if !yaml_emitter_write_block_scalar_hints(emitter, value) {
+ return false
+ }
+
+ if !put_break(emitter) {
+ return false
+ }
+ emitter.indention = true
+ emitter.whitespace = true
+
+ breaks := true
+ leading_spaces := true
+ for i := 0; i < len(value); {
+ if is_break(value, i) {
+ if !breaks && !leading_spaces && value[i] == '\n' {
+ k := 0
+ for is_break(value, k) {
+ k += width(value[k])
+ }
+ if !is_blankz(value, k) {
+ if !put_break(emitter) {
+ return false
+ }
+ }
+ }
+ if !write_break(emitter, value, &i) {
+ return false
+ }
+ emitter.indention = true
+ breaks = true
+ } else {
+ if breaks {
+ if !yaml_emitter_write_indent(emitter) {
+ return false
+ }
+ leading_spaces = is_blank(value, i)
+ }
+ if !breaks && is_space(value, i) && !is_space(value, i+1) && emitter.column > emitter.best_width {
+ if !yaml_emitter_write_indent(emitter) {
+ return false
+ }
+ i += width(value[i])
+ } else {
+ if !write(emitter, value, &i) {
+ return false
+ }
+ }
+ emitter.indention = false
+ breaks = false
+ }
+ }
+ return true
+}
diff --git a/vendor/github.com/coreos/ignition/config/vendor/github.com/go-yaml/yaml/encode.go b/vendor/github.com/coreos/ignition/config/vendor/github.com/go-yaml/yaml/encode.go
new file mode 100644
index 00000000..84f84995
--- /dev/null
+++ b/vendor/github.com/coreos/ignition/config/vendor/github.com/go-yaml/yaml/encode.go
@@ -0,0 +1,306 @@
+package yaml
+
+import (
+ "encoding"
+ "fmt"
+ "reflect"
+ "regexp"
+ "sort"
+ "strconv"
+ "strings"
+ "time"
+)
+
+type encoder struct {
+ emitter yaml_emitter_t
+ event yaml_event_t
+ out []byte
+ flow bool
+}
+
+func newEncoder() (e *encoder) {
+ e = &encoder{}
+ e.must(yaml_emitter_initialize(&e.emitter))
+ yaml_emitter_set_output_string(&e.emitter, &e.out)
+ yaml_emitter_set_unicode(&e.emitter, true)
+ e.must(yaml_stream_start_event_initialize(&e.event, yaml_UTF8_ENCODING))
+ e.emit()
+ e.must(yaml_document_start_event_initialize(&e.event, nil, nil, true))
+ e.emit()
+ return e
+}
+
+func (e *encoder) finish() {
+ e.must(yaml_document_end_event_initialize(&e.event, true))
+ e.emit()
+ e.emitter.open_ended = false
+ e.must(yaml_stream_end_event_initialize(&e.event))
+ e.emit()
+}
+
+func (e *encoder) destroy() {
+ yaml_emitter_delete(&e.emitter)
+}
+
+func (e *encoder) emit() {
+ // This will internally delete the e.event value.
+ if !yaml_emitter_emit(&e.emitter, &e.event) && e.event.typ != yaml_DOCUMENT_END_EVENT && e.event.typ != yaml_STREAM_END_EVENT {
+ e.must(false)
+ }
+}
+
+func (e *encoder) must(ok bool) {
+ if !ok {
+ msg := e.emitter.problem
+ if msg == "" {
+ msg = "unknown problem generating YAML content"
+ }
+ failf("%s", msg)
+ }
+}
+
+func (e *encoder) marshal(tag string, in reflect.Value) {
+ if !in.IsValid() {
+ e.nilv()
+ return
+ }
+ iface := in.Interface()
+ if m, ok := iface.(Marshaler); ok {
+ v, err := m.MarshalYAML()
+ if err != nil {
+ fail(err)
+ }
+ if v == nil {
+ e.nilv()
+ return
+ }
+ in = reflect.ValueOf(v)
+ } else if m, ok := iface.(encoding.TextMarshaler); ok {
+ text, err := m.MarshalText()
+ if err != nil {
+ fail(err)
+ }
+ in = reflect.ValueOf(string(text))
+ }
+ switch in.Kind() {
+ case reflect.Interface:
+ if in.IsNil() {
+ e.nilv()
+ } else {
+ e.marshal(tag, in.Elem())
+ }
+ case reflect.Map:
+ e.mapv(tag, in)
+ case reflect.Ptr:
+ if in.IsNil() {
+ e.nilv()
+ } else {
+ e.marshal(tag, in.Elem())
+ }
+ case reflect.Struct:
+ e.structv(tag, in)
+ case reflect.Slice:
+ if in.Type().Elem() == mapItemType {
+ e.itemsv(tag, in)
+ } else {
+ e.slicev(tag, in)
+ }
+ case reflect.String:
+ e.stringv(tag, in)
+ case reflect.Int, reflect.Int8, reflect.Int16, reflect.Int32, reflect.Int64:
+ if in.Type() == durationType {
+ e.stringv(tag, reflect.ValueOf(iface.(time.Duration).String()))
+ } else {
+ e.intv(tag, in)
+ }
+ case reflect.Uint, reflect.Uint8, reflect.Uint16, reflect.Uint32, reflect.Uint64, reflect.Uintptr:
+ e.uintv(tag, in)
+ case reflect.Float32, reflect.Float64:
+ e.floatv(tag, in)
+ case reflect.Bool:
+ e.boolv(tag, in)
+ default:
+ panic("cannot marshal type: " + in.Type().String())
+ }
+}
+
+func (e *encoder) mapv(tag string, in reflect.Value) {
+ e.mappingv(tag, func() {
+ keys := keyList(in.MapKeys())
+ sort.Sort(keys)
+ for _, k := range keys {
+ e.marshal("", k)
+ e.marshal("", in.MapIndex(k))
+ }
+ })
+}
+
+func (e *encoder) itemsv(tag string, in reflect.Value) {
+ e.mappingv(tag, func() {
+ slice := in.Convert(reflect.TypeOf([]MapItem{})).Interface().([]MapItem)
+ for _, item := range slice {
+ e.marshal("", reflect.ValueOf(item.Key))
+ e.marshal("", reflect.ValueOf(item.Value))
+ }
+ })
+}
+
+func (e *encoder) structv(tag string, in reflect.Value) {
+ sinfo, err := getStructInfo(in.Type())
+ if err != nil {
+ panic(err)
+ }
+ e.mappingv(tag, func() {
+ for _, info := range sinfo.FieldsList {
+ var value reflect.Value
+ if info.Inline == nil {
+ value = in.Field(info.Num)
+ } else {
+ value = in.FieldByIndex(info.Inline)
+ }
+ if info.OmitEmpty && isZero(value) {
+ continue
+ }
+ e.marshal("", reflect.ValueOf(info.Key))
+ e.flow = info.Flow
+ e.marshal("", value)
+ }
+ if sinfo.InlineMap >= 0 {
+ m := in.Field(sinfo.InlineMap)
+ if m.Len() > 0 {
+ e.flow = false
+ keys := keyList(m.MapKeys())
+ sort.Sort(keys)
+ for _, k := range keys {
+ if _, found := sinfo.FieldsMap[k.String()]; found {
+ panic(fmt.Sprintf("Can't have key %q in inlined map; conflicts with struct field", k.String()))
+ }
+ e.marshal("", k)
+ e.flow = false
+ e.marshal("", m.MapIndex(k))
+ }
+ }
+ }
+ })
+}
+
+func (e *encoder) mappingv(tag string, f func()) {
+ implicit := tag == ""
+ style := yaml_BLOCK_MAPPING_STYLE
+ if e.flow {
+ e.flow = false
+ style = yaml_FLOW_MAPPING_STYLE
+ }
+ e.must(yaml_mapping_start_event_initialize(&e.event, nil, []byte(tag), implicit, style))
+ e.emit()
+ f()
+ e.must(yaml_mapping_end_event_initialize(&e.event))
+ e.emit()
+}
+
+func (e *encoder) slicev(tag string, in reflect.Value) {
+ implicit := tag == ""
+ style := yaml_BLOCK_SEQUENCE_STYLE
+ if e.flow {
+ e.flow = false
+ style = yaml_FLOW_SEQUENCE_STYLE
+ }
+ e.must(yaml_sequence_start_event_initialize(&e.event, nil, []byte(tag), implicit, style))
+ e.emit()
+ n := in.Len()
+ for i := 0; i < n; i++ {
+ e.marshal("", in.Index(i))
+ }
+ e.must(yaml_sequence_end_event_initialize(&e.event))
+ e.emit()
+}
+
+// isBase60 returns whether s is in base 60 notation as defined in YAML 1.1.
+//
+// The base 60 float notation in YAML 1.1 is a terrible idea and is unsupported
+// in YAML 1.2 and by this package, but these should be marshalled quoted for
+// the time being for compatibility with other parsers.
+func isBase60Float(s string) (result bool) {
+ // Fast path.
+ if s == "" {
+ return false
+ }
+ c := s[0]
+ if !(c == '+' || c == '-' || c >= '0' && c <= '9') || strings.IndexByte(s, ':') < 0 {
+ return false
+ }
+ // Do the full match.
+ return base60float.MatchString(s)
+}
+
+// From http://yaml.org/type/float.html, except the regular expression there
+// is bogus. In practice parsers do not enforce the "\.[0-9_]*" suffix.
+var base60float = regexp.MustCompile(`^[-+]?[0-9][0-9_]*(?::[0-5]?[0-9])+(?:\.[0-9_]*)?$`)
+
+func (e *encoder) stringv(tag string, in reflect.Value) {
+ var style yaml_scalar_style_t
+ s := in.String()
+ rtag, rs := resolve("", s)
+ if rtag == yaml_BINARY_TAG {
+ if tag == "" || tag == yaml_STR_TAG {
+ tag = rtag
+ s = rs.(string)
+ } else if tag == yaml_BINARY_TAG {
+ failf("explicitly tagged !!binary data must be base64-encoded")
+ } else {
+ failf("cannot marshal invalid UTF-8 data as %s", shortTag(tag))
+ }
+ }
+ if tag == "" && (rtag != yaml_STR_TAG || isBase60Float(s)) {
+ style = yaml_DOUBLE_QUOTED_SCALAR_STYLE
+ } else if strings.Contains(s, "\n") {
+ style = yaml_LITERAL_SCALAR_STYLE
+ } else {
+ style = yaml_PLAIN_SCALAR_STYLE
+ }
+ e.emitScalar(s, "", tag, style)
+}
+
+func (e *encoder) boolv(tag string, in reflect.Value) {
+ var s string
+ if in.Bool() {
+ s = "true"
+ } else {
+ s = "false"
+ }
+ e.emitScalar(s, "", tag, yaml_PLAIN_SCALAR_STYLE)
+}
+
+func (e *encoder) intv(tag string, in reflect.Value) {
+ s := strconv.FormatInt(in.Int(), 10)
+ e.emitScalar(s, "", tag, yaml_PLAIN_SCALAR_STYLE)
+}
+
+func (e *encoder) uintv(tag string, in reflect.Value) {
+ s := strconv.FormatUint(in.Uint(), 10)
+ e.emitScalar(s, "", tag, yaml_PLAIN_SCALAR_STYLE)
+}
+
+func (e *encoder) floatv(tag string, in reflect.Value) {
+ // FIXME: Handle 64 bits here.
+ s := strconv.FormatFloat(float64(in.Float()), 'g', -1, 32)
+ switch s {
+ case "+Inf":
+ s = ".inf"
+ case "-Inf":
+ s = "-.inf"
+ case "NaN":
+ s = ".nan"
+ }
+ e.emitScalar(s, "", tag, yaml_PLAIN_SCALAR_STYLE)
+}
+
+func (e *encoder) nilv() {
+ e.emitScalar("null", "", "", yaml_PLAIN_SCALAR_STYLE)
+}
+
+func (e *encoder) emitScalar(value, anchor, tag string, style yaml_scalar_style_t) {
+ implicit := tag == ""
+ e.must(yaml_scalar_event_initialize(&e.event, []byte(anchor), []byte(tag), []byte(value), implicit, implicit, style))
+ e.emit()
+}
diff --git a/vendor/github.com/coreos/ignition/config/vendor/github.com/go-yaml/yaml/encode_test.go b/vendor/github.com/coreos/ignition/config/vendor/github.com/go-yaml/yaml/encode_test.go
new file mode 100644
index 00000000..ba68ad29
--- /dev/null
+++ b/vendor/github.com/coreos/ignition/config/vendor/github.com/go-yaml/yaml/encode_test.go
@@ -0,0 +1,485 @@
+package yaml_test
+
+import (
+ "fmt"
+ "math"
+ "strconv"
+ "strings"
+ "time"
+
+ . "gopkg.in/check.v1"
+ "gopkg.in/yaml.v2"
+ "net"
+ "os"
+)
+
+var marshalIntTest = 123
+
+var marshalTests = []struct {
+ value interface{}
+ data string
+}{
+ {
+ nil,
+ "null\n",
+ }, {
+ &struct{}{},
+ "{}\n",
+ }, {
+ map[string]string{"v": "hi"},
+ "v: hi\n",
+ }, {
+ map[string]interface{}{"v": "hi"},
+ "v: hi\n",
+ }, {
+ map[string]string{"v": "true"},
+ "v: \"true\"\n",
+ }, {
+ map[string]string{"v": "false"},
+ "v: \"false\"\n",
+ }, {
+ map[string]interface{}{"v": true},
+ "v: true\n",
+ }, {
+ map[string]interface{}{"v": false},
+ "v: false\n",
+ }, {
+ map[string]interface{}{"v": 10},
+ "v: 10\n",
+ }, {
+ map[string]interface{}{"v": -10},
+ "v: -10\n",
+ }, {
+ map[string]uint{"v": 42},
+ "v: 42\n",
+ }, {
+ map[string]interface{}{"v": int64(4294967296)},
+ "v: 4294967296\n",
+ }, {
+ map[string]int64{"v": int64(4294967296)},
+ "v: 4294967296\n",
+ }, {
+ map[string]uint64{"v": 4294967296},
+ "v: 4294967296\n",
+ }, {
+ map[string]interface{}{"v": "10"},
+ "v: \"10\"\n",
+ }, {
+ map[string]interface{}{"v": 0.1},
+ "v: 0.1\n",
+ }, {
+ map[string]interface{}{"v": float64(0.1)},
+ "v: 0.1\n",
+ }, {
+ map[string]interface{}{"v": -0.1},
+ "v: -0.1\n",
+ }, {
+ map[string]interface{}{"v": math.Inf(+1)},
+ "v: .inf\n",
+ }, {
+ map[string]interface{}{"v": math.Inf(-1)},
+ "v: -.inf\n",
+ }, {
+ map[string]interface{}{"v": math.NaN()},
+ "v: .nan\n",
+ }, {
+ map[string]interface{}{"v": nil},
+ "v: null\n",
+ }, {
+ map[string]interface{}{"v": ""},
+ "v: \"\"\n",
+ }, {
+ map[string][]string{"v": []string{"A", "B"}},
+ "v:\n- A\n- B\n",
+ }, {
+ map[string][]string{"v": []string{"A", "B\nC"}},
+ "v:\n- A\n- |-\n B\n C\n",
+ }, {
+ map[string][]interface{}{"v": []interface{}{"A", 1, map[string][]int{"B": []int{2, 3}}}},
+ "v:\n- A\n- 1\n- B:\n - 2\n - 3\n",
+ }, {
+ map[string]interface{}{"a": map[interface{}]interface{}{"b": "c"}},
+ "a:\n b: c\n",
+ }, {
+ map[string]interface{}{"a": "-"},
+ "a: '-'\n",
+ },
+
+ // Simple values.
+ {
+ &marshalIntTest,
+ "123\n",
+ },
+
+ // Structures
+ {
+ &struct{ Hello string }{"world"},
+ "hello: world\n",
+ }, {
+ &struct {
+ A struct {
+ B string
+ }
+ }{struct{ B string }{"c"}},
+ "a:\n b: c\n",
+ }, {
+ &struct {
+ A *struct {
+ B string
+ }
+ }{&struct{ B string }{"c"}},
+ "a:\n b: c\n",
+ }, {
+ &struct {
+ A *struct {
+ B string
+ }
+ }{},
+ "a: null\n",
+ }, {
+ &struct{ A int }{1},
+ "a: 1\n",
+ }, {
+ &struct{ A []int }{[]int{1, 2}},
+ "a:\n- 1\n- 2\n",
+ }, {
+ &struct {
+ B int "a"
+ }{1},
+ "a: 1\n",
+ }, {
+ &struct{ A bool }{true},
+ "a: true\n",
+ },
+
+ // Conditional flag
+ {
+ &struct {
+ A int "a,omitempty"
+ B int "b,omitempty"
+ }{1, 0},
+ "a: 1\n",
+ }, {
+ &struct {
+ A int "a,omitempty"
+ B int "b,omitempty"
+ }{0, 0},
+ "{}\n",
+ }, {
+ &struct {
+ A *struct{ X, y int } "a,omitempty,flow"
+ }{&struct{ X, y int }{1, 2}},
+ "a: {x: 1}\n",
+ }, {
+ &struct {
+ A *struct{ X, y int } "a,omitempty,flow"
+ }{nil},
+ "{}\n",
+ }, {
+ &struct {
+ A *struct{ X, y int } "a,omitempty,flow"
+ }{&struct{ X, y int }{}},
+ "a: {x: 0}\n",
+ }, {
+ &struct {
+ A struct{ X, y int } "a,omitempty,flow"
+ }{struct{ X, y int }{1, 2}},
+ "a: {x: 1}\n",
+ }, {
+ &struct {
+ A struct{ X, y int } "a,omitempty,flow"
+ }{struct{ X, y int }{0, 1}},
+ "{}\n",
+ },
+
+ // Flow flag
+ {
+ &struct {
+ A []int "a,flow"
+ }{[]int{1, 2}},
+ "a: [1, 2]\n",
+ }, {
+ &struct {
+ A map[string]string "a,flow"
+ }{map[string]string{"b": "c", "d": "e"}},
+ "a: {b: c, d: e}\n",
+ }, {
+ &struct {
+ A struct {
+ B, D string
+ } "a,flow"
+ }{struct{ B, D string }{"c", "e"}},
+ "a: {b: c, d: e}\n",
+ },
+
+ // Unexported field
+ {
+ &struct {
+ u int
+ A int
+ }{0, 1},
+ "a: 1\n",
+ },
+
+ // Ignored field
+ {
+ &struct {
+ A int
+ B int "-"
+ }{1, 2},
+ "a: 1\n",
+ },
+
+ // Struct inlining
+ {
+ &struct {
+ A int
+ C inlineB `yaml:",inline"`
+ }{1, inlineB{2, inlineC{3}}},
+ "a: 1\nb: 2\nc: 3\n",
+ },
+
+ // Map inlining
+ {
+ &struct {
+ A int
+ C map[string]int `yaml:",inline"`
+ }{1, map[string]int{"b": 2, "c": 3}},
+ "a: 1\nb: 2\nc: 3\n",
+ },
+
+ // Duration
+ {
+ map[string]time.Duration{"a": 3 * time.Second},
+ "a: 3s\n",
+ },
+
+ // Issue #24: bug in map merging logic.
+ {
+ map[string]string{"a": ""},
+ "a: \n",
+ },
+
+ // Issue #34: marshal unsupported base 60 floats quoted for compatibility
+ // with old YAML 1.1 parsers.
+ {
+ map[string]string{"a": "1:1"},
+ "a: \"1:1\"\n",
+ },
+
+ // Binary data.
+ {
+ map[string]string{"a": "\x00"},
+ "a: \"\\0\"\n",
+ }, {
+ map[string]string{"a": "\x80\x81\x82"},
+ "a: !!binary gIGC\n",
+ }, {
+ map[string]string{"a": strings.Repeat("\x90", 54)},
+ "a: !!binary |\n " + strings.Repeat("kJCQ", 17) + "kJ\n CQ\n",
+ },
+
+ // Ordered maps.
+ {
+ &yaml.MapSlice{{"b", 2}, {"a", 1}, {"d", 4}, {"c", 3}, {"sub", yaml.MapSlice{{"e", 5}}}},
+ "b: 2\na: 1\nd: 4\nc: 3\nsub:\n e: 5\n",
+ },
+
+ // Encode unicode as utf-8 rather than in escaped form.
+ {
+ map[string]string{"a": "ä½ å¥½"},
+ "a: ä½ å¥½\n",
+ },
+
+ // Support encoding.TextMarshaler.
+ {
+ map[string]net.IP{"a": net.IPv4(1, 2, 3, 4)},
+ "a: 1.2.3.4\n",
+ },
+ {
+ map[string]time.Time{"a": time.Unix(1424801979, 0)},
+ "a: 2015-02-24T18:19:39Z\n",
+ },
+
+ // Ensure strings containing ": " are quoted (reported as PR #43, but not reproducible).
+ {
+ map[string]string{"a": "b: c"},
+ "a: 'b: c'\n",
+ },
+}
+
+func (s *S) TestMarshal(c *C) {
+ defer os.Setenv("TZ", os.Getenv("TZ"))
+ os.Setenv("TZ", "UTC")
+ for _, item := range marshalTests {
+ data, err := yaml.Marshal(item.value)
+ c.Assert(err, IsNil)
+ c.Assert(string(data), Equals, item.data)
+ }
+}
+
+var marshalErrorTests = []struct {
+ value interface{}
+ error string
+ panic string
+}{{
+ value: &struct {
+ B int
+ inlineB ",inline"
+ }{1, inlineB{2, inlineC{3}}},
+ panic: `Duplicated key 'b' in struct struct \{ B int; .*`,
+}, {
+ value: &struct {
+ A int
+ B map[string]int ",inline"
+ }{1, map[string]int{"a": 2}},
+ panic: `Can't have key "a" in inlined map; conflicts with struct field`,
+}}
+
+func (s *S) TestMarshalErrors(c *C) {
+ for _, item := range marshalErrorTests {
+ if item.panic != "" {
+ c.Assert(func() { yaml.Marshal(item.value) }, PanicMatches, item.panic)
+ } else {
+ _, err := yaml.Marshal(item.value)
+ c.Assert(err, ErrorMatches, item.error)
+ }
+ }
+}
+
+func (s *S) TestMarshalTypeCache(c *C) {
+ var data []byte
+ var err error
+ func() {
+ type T struct{ A int }
+ data, err = yaml.Marshal(&T{})
+ c.Assert(err, IsNil)
+ }()
+ func() {
+ type T struct{ B int }
+ data, err = yaml.Marshal(&T{})
+ c.Assert(err, IsNil)
+ }()
+ c.Assert(string(data), Equals, "b: 0\n")
+}
+
+var marshalerTests = []struct {
+ data string
+ value interface{}
+}{
+ {"_:\n hi: there\n", map[interface{}]interface{}{"hi": "there"}},
+ {"_:\n- 1\n- A\n", []interface{}{1, "A"}},
+ {"_: 10\n", 10},
+ {"_: null\n", nil},
+ {"_: BAR!\n", "BAR!"},
+}
+
+type marshalerType struct {
+ value interface{}
+}
+
+func (o marshalerType) MarshalText() ([]byte, error) {
+ panic("MarshalText called on type with MarshalYAML")
+}
+
+func (o marshalerType) MarshalYAML() (interface{}, error) {
+ return o.value, nil
+}
+
+type marshalerValue struct {
+ Field marshalerType "_"
+}
+
+func (s *S) TestMarshaler(c *C) {
+ for _, item := range marshalerTests {
+ obj := &marshalerValue{}
+ obj.Field.value = item.value
+ data, err := yaml.Marshal(obj)
+ c.Assert(err, IsNil)
+ c.Assert(string(data), Equals, string(item.data))
+ }
+}
+
+func (s *S) TestMarshalerWholeDocument(c *C) {
+ obj := &marshalerType{}
+ obj.value = map[string]string{"hello": "world!"}
+ data, err := yaml.Marshal(obj)
+ c.Assert(err, IsNil)
+ c.Assert(string(data), Equals, "hello: world!\n")
+}
+
+type failingMarshaler struct{}
+
+func (ft *failingMarshaler) MarshalYAML() (interface{}, error) {
+ return nil, failingErr
+}
+
+func (s *S) TestMarshalerError(c *C) {
+ _, err := yaml.Marshal(&failingMarshaler{})
+ c.Assert(err, Equals, failingErr)
+}
+
+func (s *S) TestSortedOutput(c *C) {
+ order := []interface{}{
+ false,
+ true,
+ 1,
+ uint(1),
+ 1.0,
+ 1.1,
+ 1.2,
+ 2,
+ uint(2),
+ 2.0,
+ 2.1,
+ "",
+ ".1",
+ ".2",
+ ".a",
+ "1",
+ "2",
+ "a!10",
+ "a/2",
+ "a/10",
+ "a~10",
+ "ab/1",
+ "b/1",
+ "b/01",
+ "b/2",
+ "b/02",
+ "b/3",
+ "b/03",
+ "b1",
+ "b01",
+ "b3",
+ "c2.10",
+ "c10.2",
+ "d1",
+ "d12",
+ "d12a",
+ }
+ m := make(map[interface{}]int)
+ for _, k := range order {
+ m[k] = 1
+ }
+ data, err := yaml.Marshal(m)
+ c.Assert(err, IsNil)
+ out := "\n" + string(data)
+ last := 0
+ for i, k := range order {
+ repr := fmt.Sprint(k)
+ if s, ok := k.(string); ok {
+ if _, err = strconv.ParseFloat(repr, 32); s == "" || err == nil {
+ repr = `"` + repr + `"`
+ }
+ }
+ index := strings.Index(out, "\n"+repr+":")
+ if index == -1 {
+ c.Fatalf("%#v is not in the output: %#v", k, out)
+ }
+ if index < last {
+ c.Fatalf("%#v was generated before %#v: %q", k, order[i-1], out)
+ }
+ last = index
+ }
+}
diff --git a/vendor/github.com/coreos/ignition/config/vendor/github.com/go-yaml/yaml/parserc.go b/vendor/github.com/coreos/ignition/config/vendor/github.com/go-yaml/yaml/parserc.go
new file mode 100644
index 00000000..0a7037ad
--- /dev/null
+++ b/vendor/github.com/coreos/ignition/config/vendor/github.com/go-yaml/yaml/parserc.go
@@ -0,0 +1,1096 @@
+package yaml
+
+import (
+ "bytes"
+)
+
+// The parser implements the following grammar:
+//
+// stream ::= STREAM-START implicit_document? explicit_document* STREAM-END
+// implicit_document ::= block_node DOCUMENT-END*
+// explicit_document ::= DIRECTIVE* DOCUMENT-START block_node? DOCUMENT-END*
+// block_node_or_indentless_sequence ::=
+// ALIAS
+// | properties (block_content | indentless_block_sequence)?
+// | block_content
+// | indentless_block_sequence
+// block_node ::= ALIAS
+// | properties block_content?
+// | block_content
+// flow_node ::= ALIAS
+// | properties flow_content?
+// | flow_content
+// properties ::= TAG ANCHOR? | ANCHOR TAG?
+// block_content ::= block_collection | flow_collection | SCALAR
+// flow_content ::= flow_collection | SCALAR
+// block_collection ::= block_sequence | block_mapping
+// flow_collection ::= flow_sequence | flow_mapping
+// block_sequence ::= BLOCK-SEQUENCE-START (BLOCK-ENTRY block_node?)* BLOCK-END
+// indentless_sequence ::= (BLOCK-ENTRY block_node?)+
+// block_mapping ::= BLOCK-MAPPING_START
+// ((KEY block_node_or_indentless_sequence?)?
+// (VALUE block_node_or_indentless_sequence?)?)*
+// BLOCK-END
+// flow_sequence ::= FLOW-SEQUENCE-START
+// (flow_sequence_entry FLOW-ENTRY)*
+// flow_sequence_entry?
+// FLOW-SEQUENCE-END
+// flow_sequence_entry ::= flow_node | KEY flow_node? (VALUE flow_node?)?
+// flow_mapping ::= FLOW-MAPPING-START
+// (flow_mapping_entry FLOW-ENTRY)*
+// flow_mapping_entry?
+// FLOW-MAPPING-END
+// flow_mapping_entry ::= flow_node | KEY flow_node? (VALUE flow_node?)?
+
+// Peek the next token in the token queue.
+func peek_token(parser *yaml_parser_t) *yaml_token_t {
+ if parser.token_available || yaml_parser_fetch_more_tokens(parser) {
+ return &parser.tokens[parser.tokens_head]
+ }
+ return nil
+}
+
+// Remove the next token from the queue (must be called after peek_token).
+func skip_token(parser *yaml_parser_t) {
+ parser.token_available = false
+ parser.tokens_parsed++
+ parser.stream_end_produced = parser.tokens[parser.tokens_head].typ == yaml_STREAM_END_TOKEN
+ parser.tokens_head++
+}
+
+// Get the next event.
+func yaml_parser_parse(parser *yaml_parser_t, event *yaml_event_t) bool {
+ // Erase the event object.
+ *event = yaml_event_t{}
+
+ // No events after the end of the stream or error.
+ if parser.stream_end_produced || parser.error != yaml_NO_ERROR || parser.state == yaml_PARSE_END_STATE {
+ return true
+ }
+
+ // Generate the next event.
+ return yaml_parser_state_machine(parser, event)
+}
+
+// Set parser error.
+func yaml_parser_set_parser_error(parser *yaml_parser_t, problem string, problem_mark yaml_mark_t) bool {
+ parser.error = yaml_PARSER_ERROR
+ parser.problem = problem
+ parser.problem_mark = problem_mark
+ return false
+}
+
+func yaml_parser_set_parser_error_context(parser *yaml_parser_t, context string, context_mark yaml_mark_t, problem string, problem_mark yaml_mark_t) bool {
+ parser.error = yaml_PARSER_ERROR
+ parser.context = context
+ parser.context_mark = context_mark
+ parser.problem = problem
+ parser.problem_mark = problem_mark
+ return false
+}
+
+// State dispatcher.
+func yaml_parser_state_machine(parser *yaml_parser_t, event *yaml_event_t) bool {
+ //trace("yaml_parser_state_machine", "state:", parser.state.String())
+
+ switch parser.state {
+ case yaml_PARSE_STREAM_START_STATE:
+ return yaml_parser_parse_stream_start(parser, event)
+
+ case yaml_PARSE_IMPLICIT_DOCUMENT_START_STATE:
+ return yaml_parser_parse_document_start(parser, event, true)
+
+ case yaml_PARSE_DOCUMENT_START_STATE:
+ return yaml_parser_parse_document_start(parser, event, false)
+
+ case yaml_PARSE_DOCUMENT_CONTENT_STATE:
+ return yaml_parser_parse_document_content(parser, event)
+
+ case yaml_PARSE_DOCUMENT_END_STATE:
+ return yaml_parser_parse_document_end(parser, event)
+
+ case yaml_PARSE_BLOCK_NODE_STATE:
+ return yaml_parser_parse_node(parser, event, true, false)
+
+ case yaml_PARSE_BLOCK_NODE_OR_INDENTLESS_SEQUENCE_STATE:
+ return yaml_parser_parse_node(parser, event, true, true)
+
+ case yaml_PARSE_FLOW_NODE_STATE:
+ return yaml_parser_parse_node(parser, event, false, false)
+
+ case yaml_PARSE_BLOCK_SEQUENCE_FIRST_ENTRY_STATE:
+ return yaml_parser_parse_block_sequence_entry(parser, event, true)
+
+ case yaml_PARSE_BLOCK_SEQUENCE_ENTRY_STATE:
+ return yaml_parser_parse_block_sequence_entry(parser, event, false)
+
+ case yaml_PARSE_INDENTLESS_SEQUENCE_ENTRY_STATE:
+ return yaml_parser_parse_indentless_sequence_entry(parser, event)
+
+ case yaml_PARSE_BLOCK_MAPPING_FIRST_KEY_STATE:
+ return yaml_parser_parse_block_mapping_key(parser, event, true)
+
+ case yaml_PARSE_BLOCK_MAPPING_KEY_STATE:
+ return yaml_parser_parse_block_mapping_key(parser, event, false)
+
+ case yaml_PARSE_BLOCK_MAPPING_VALUE_STATE:
+ return yaml_parser_parse_block_mapping_value(parser, event)
+
+ case yaml_PARSE_FLOW_SEQUENCE_FIRST_ENTRY_STATE:
+ return yaml_parser_parse_flow_sequence_entry(parser, event, true)
+
+ case yaml_PARSE_FLOW_SEQUENCE_ENTRY_STATE:
+ return yaml_parser_parse_flow_sequence_entry(parser, event, false)
+
+ case yaml_PARSE_FLOW_SEQUENCE_ENTRY_MAPPING_KEY_STATE:
+ return yaml_parser_parse_flow_sequence_entry_mapping_key(parser, event)
+
+ case yaml_PARSE_FLOW_SEQUENCE_ENTRY_MAPPING_VALUE_STATE:
+ return yaml_parser_parse_flow_sequence_entry_mapping_value(parser, event)
+
+ case yaml_PARSE_FLOW_SEQUENCE_ENTRY_MAPPING_END_STATE:
+ return yaml_parser_parse_flow_sequence_entry_mapping_end(parser, event)
+
+ case yaml_PARSE_FLOW_MAPPING_FIRST_KEY_STATE:
+ return yaml_parser_parse_flow_mapping_key(parser, event, true)
+
+ case yaml_PARSE_FLOW_MAPPING_KEY_STATE:
+ return yaml_parser_parse_flow_mapping_key(parser, event, false)
+
+ case yaml_PARSE_FLOW_MAPPING_VALUE_STATE:
+ return yaml_parser_parse_flow_mapping_value(parser, event, false)
+
+ case yaml_PARSE_FLOW_MAPPING_EMPTY_VALUE_STATE:
+ return yaml_parser_parse_flow_mapping_value(parser, event, true)
+
+ default:
+ panic("invalid parser state")
+ }
+ return false
+}
+
+// Parse the production:
+// stream ::= STREAM-START implicit_document? explicit_document* STREAM-END
+// ************
+func yaml_parser_parse_stream_start(parser *yaml_parser_t, event *yaml_event_t) bool {
+ token := peek_token(parser)
+ if token == nil {
+ return false
+ }
+ if token.typ != yaml_STREAM_START_TOKEN {
+ return yaml_parser_set_parser_error(parser, "did not find expected ", token.start_mark)
+ }
+ parser.state = yaml_PARSE_IMPLICIT_DOCUMENT_START_STATE
+ *event = yaml_event_t{
+ typ: yaml_STREAM_START_EVENT,
+ start_mark: token.start_mark,
+ end_mark: token.end_mark,
+ encoding: token.encoding,
+ }
+ skip_token(parser)
+ return true
+}
+
+// Parse the productions:
+// implicit_document ::= block_node DOCUMENT-END*
+// *
+// explicit_document ::= DIRECTIVE* DOCUMENT-START block_node? DOCUMENT-END*
+// *************************
+func yaml_parser_parse_document_start(parser *yaml_parser_t, event *yaml_event_t, implicit bool) bool {
+
+ token := peek_token(parser)
+ if token == nil {
+ return false
+ }
+
+ // Parse extra document end indicators.
+ if !implicit {
+ for token.typ == yaml_DOCUMENT_END_TOKEN {
+ skip_token(parser)
+ token = peek_token(parser)
+ if token == nil {
+ return false
+ }
+ }
+ }
+
+ if implicit && token.typ != yaml_VERSION_DIRECTIVE_TOKEN &&
+ token.typ != yaml_TAG_DIRECTIVE_TOKEN &&
+ token.typ != yaml_DOCUMENT_START_TOKEN &&
+ token.typ != yaml_STREAM_END_TOKEN {
+ // Parse an implicit document.
+ if !yaml_parser_process_directives(parser, nil, nil) {
+ return false
+ }
+ parser.states = append(parser.states, yaml_PARSE_DOCUMENT_END_STATE)
+ parser.state = yaml_PARSE_BLOCK_NODE_STATE
+
+ *event = yaml_event_t{
+ typ: yaml_DOCUMENT_START_EVENT,
+ start_mark: token.start_mark,
+ end_mark: token.end_mark,
+ }
+
+ } else if token.typ != yaml_STREAM_END_TOKEN {
+ // Parse an explicit document.
+ var version_directive *yaml_version_directive_t
+ var tag_directives []yaml_tag_directive_t
+ start_mark := token.start_mark
+ if !yaml_parser_process_directives(parser, &version_directive, &tag_directives) {
+ return false
+ }
+ token = peek_token(parser)
+ if token == nil {
+ return false
+ }
+ if token.typ != yaml_DOCUMENT_START_TOKEN {
+ yaml_parser_set_parser_error(parser,
+ "did not find expected ", token.start_mark)
+ return false
+ }
+ parser.states = append(parser.states, yaml_PARSE_DOCUMENT_END_STATE)
+ parser.state = yaml_PARSE_DOCUMENT_CONTENT_STATE
+ end_mark := token.end_mark
+
+ *event = yaml_event_t{
+ typ: yaml_DOCUMENT_START_EVENT,
+ start_mark: start_mark,
+ end_mark: end_mark,
+ version_directive: version_directive,
+ tag_directives: tag_directives,
+ implicit: false,
+ }
+ skip_token(parser)
+
+ } else {
+ // Parse the stream end.
+ parser.state = yaml_PARSE_END_STATE
+ *event = yaml_event_t{
+ typ: yaml_STREAM_END_EVENT,
+ start_mark: token.start_mark,
+ end_mark: token.end_mark,
+ }
+ skip_token(parser)
+ }
+
+ return true
+}
+
+// Parse the productions:
+// explicit_document ::= DIRECTIVE* DOCUMENT-START block_node? DOCUMENT-END*
+// ***********
+//
+func yaml_parser_parse_document_content(parser *yaml_parser_t, event *yaml_event_t) bool {
+ token := peek_token(parser)
+ if token == nil {
+ return false
+ }
+ if token.typ == yaml_VERSION_DIRECTIVE_TOKEN ||
+ token.typ == yaml_TAG_DIRECTIVE_TOKEN ||
+ token.typ == yaml_DOCUMENT_START_TOKEN ||
+ token.typ == yaml_DOCUMENT_END_TOKEN ||
+ token.typ == yaml_STREAM_END_TOKEN {
+ parser.state = parser.states[len(parser.states)-1]
+ parser.states = parser.states[:len(parser.states)-1]
+ return yaml_parser_process_empty_scalar(parser, event,
+ token.start_mark)
+ }
+ return yaml_parser_parse_node(parser, event, true, false)
+}
+
+// Parse the productions:
+// implicit_document ::= block_node DOCUMENT-END*
+// *************
+// explicit_document ::= DIRECTIVE* DOCUMENT-START block_node? DOCUMENT-END*
+//
+func yaml_parser_parse_document_end(parser *yaml_parser_t, event *yaml_event_t) bool {
+ token := peek_token(parser)
+ if token == nil {
+ return false
+ }
+
+ start_mark := token.start_mark
+ end_mark := token.start_mark
+
+ implicit := true
+ if token.typ == yaml_DOCUMENT_END_TOKEN {
+ end_mark = token.end_mark
+ skip_token(parser)
+ implicit = false
+ }
+
+ parser.tag_directives = parser.tag_directives[:0]
+
+ parser.state = yaml_PARSE_DOCUMENT_START_STATE
+ *event = yaml_event_t{
+ typ: yaml_DOCUMENT_END_EVENT,
+ start_mark: start_mark,
+ end_mark: end_mark,
+ implicit: implicit,
+ }
+ return true
+}
+
+// Parse the productions:
+// block_node_or_indentless_sequence ::=
+// ALIAS
+// *****
+// | properties (block_content | indentless_block_sequence)?
+// ********** *
+// | block_content | indentless_block_sequence
+// *
+// block_node ::= ALIAS
+// *****
+// | properties block_content?
+// ********** *
+// | block_content
+// *
+// flow_node ::= ALIAS
+// *****
+// | properties flow_content?
+// ********** *
+// | flow_content
+// *
+// properties ::= TAG ANCHOR? | ANCHOR TAG?
+// *************************
+// block_content ::= block_collection | flow_collection | SCALAR
+// ******
+// flow_content ::= flow_collection | SCALAR
+// ******
+func yaml_parser_parse_node(parser *yaml_parser_t, event *yaml_event_t, block, indentless_sequence bool) bool {
+ //defer trace("yaml_parser_parse_node", "block:", block, "indentless_sequence:", indentless_sequence)()
+
+ token := peek_token(parser)
+ if token == nil {
+ return false
+ }
+
+ if token.typ == yaml_ALIAS_TOKEN {
+ parser.state = parser.states[len(parser.states)-1]
+ parser.states = parser.states[:len(parser.states)-1]
+ *event = yaml_event_t{
+ typ: yaml_ALIAS_EVENT,
+ start_mark: token.start_mark,
+ end_mark: token.end_mark,
+ anchor: token.value,
+ }
+ skip_token(parser)
+ return true
+ }
+
+ start_mark := token.start_mark
+ end_mark := token.start_mark
+
+ var tag_token bool
+ var tag_handle, tag_suffix, anchor []byte
+ var tag_mark yaml_mark_t
+ if token.typ == yaml_ANCHOR_TOKEN {
+ anchor = token.value
+ start_mark = token.start_mark
+ end_mark = token.end_mark
+ skip_token(parser)
+ token = peek_token(parser)
+ if token == nil {
+ return false
+ }
+ if token.typ == yaml_TAG_TOKEN {
+ tag_token = true
+ tag_handle = token.value
+ tag_suffix = token.suffix
+ tag_mark = token.start_mark
+ end_mark = token.end_mark
+ skip_token(parser)
+ token = peek_token(parser)
+ if token == nil {
+ return false
+ }
+ }
+ } else if token.typ == yaml_TAG_TOKEN {
+ tag_token = true
+ tag_handle = token.value
+ tag_suffix = token.suffix
+ start_mark = token.start_mark
+ tag_mark = token.start_mark
+ end_mark = token.end_mark
+ skip_token(parser)
+ token = peek_token(parser)
+ if token == nil {
+ return false
+ }
+ if token.typ == yaml_ANCHOR_TOKEN {
+ anchor = token.value
+ end_mark = token.end_mark
+ skip_token(parser)
+ token = peek_token(parser)
+ if token == nil {
+ return false
+ }
+ }
+ }
+
+ var tag []byte
+ if tag_token {
+ if len(tag_handle) == 0 {
+ tag = tag_suffix
+ tag_suffix = nil
+ } else {
+ for i := range parser.tag_directives {
+ if bytes.Equal(parser.tag_directives[i].handle, tag_handle) {
+ tag = append([]byte(nil), parser.tag_directives[i].prefix...)
+ tag = append(tag, tag_suffix...)
+ break
+ }
+ }
+ if len(tag) == 0 {
+ yaml_parser_set_parser_error_context(parser,
+ "while parsing a node", start_mark,
+ "found undefined tag handle", tag_mark)
+ return false
+ }
+ }
+ }
+
+ implicit := len(tag) == 0
+ if indentless_sequence && token.typ == yaml_BLOCK_ENTRY_TOKEN {
+ end_mark = token.end_mark
+ parser.state = yaml_PARSE_INDENTLESS_SEQUENCE_ENTRY_STATE
+ *event = yaml_event_t{
+ typ: yaml_SEQUENCE_START_EVENT,
+ start_mark: start_mark,
+ end_mark: end_mark,
+ anchor: anchor,
+ tag: tag,
+ implicit: implicit,
+ style: yaml_style_t(yaml_BLOCK_SEQUENCE_STYLE),
+ }
+ return true
+ }
+ if token.typ == yaml_SCALAR_TOKEN {
+ var plain_implicit, quoted_implicit bool
+ end_mark = token.end_mark
+ if (len(tag) == 0 && token.style == yaml_PLAIN_SCALAR_STYLE) || (len(tag) == 1 && tag[0] == '!') {
+ plain_implicit = true
+ } else if len(tag) == 0 {
+ quoted_implicit = true
+ }
+ parser.state = parser.states[len(parser.states)-1]
+ parser.states = parser.states[:len(parser.states)-1]
+
+ *event = yaml_event_t{
+ typ: yaml_SCALAR_EVENT,
+ start_mark: start_mark,
+ end_mark: end_mark,
+ anchor: anchor,
+ tag: tag,
+ value: token.value,
+ implicit: plain_implicit,
+ quoted_implicit: quoted_implicit,
+ style: yaml_style_t(token.style),
+ }
+ skip_token(parser)
+ return true
+ }
+ if token.typ == yaml_FLOW_SEQUENCE_START_TOKEN {
+ // [Go] Some of the events below can be merged as they differ only on style.
+ end_mark = token.end_mark
+ parser.state = yaml_PARSE_FLOW_SEQUENCE_FIRST_ENTRY_STATE
+ *event = yaml_event_t{
+ typ: yaml_SEQUENCE_START_EVENT,
+ start_mark: start_mark,
+ end_mark: end_mark,
+ anchor: anchor,
+ tag: tag,
+ implicit: implicit,
+ style: yaml_style_t(yaml_FLOW_SEQUENCE_STYLE),
+ }
+ return true
+ }
+ if token.typ == yaml_FLOW_MAPPING_START_TOKEN {
+ end_mark = token.end_mark
+ parser.state = yaml_PARSE_FLOW_MAPPING_FIRST_KEY_STATE
+ *event = yaml_event_t{
+ typ: yaml_MAPPING_START_EVENT,
+ start_mark: start_mark,
+ end_mark: end_mark,
+ anchor: anchor,
+ tag: tag,
+ implicit: implicit,
+ style: yaml_style_t(yaml_FLOW_MAPPING_STYLE),
+ }
+ return true
+ }
+ if block && token.typ == yaml_BLOCK_SEQUENCE_START_TOKEN {
+ end_mark = token.end_mark
+ parser.state = yaml_PARSE_BLOCK_SEQUENCE_FIRST_ENTRY_STATE
+ *event = yaml_event_t{
+ typ: yaml_SEQUENCE_START_EVENT,
+ start_mark: start_mark,
+ end_mark: end_mark,
+ anchor: anchor,
+ tag: tag,
+ implicit: implicit,
+ style: yaml_style_t(yaml_BLOCK_SEQUENCE_STYLE),
+ }
+ return true
+ }
+ if block && token.typ == yaml_BLOCK_MAPPING_START_TOKEN {
+ end_mark = token.end_mark
+ parser.state = yaml_PARSE_BLOCK_MAPPING_FIRST_KEY_STATE
+ *event = yaml_event_t{
+ typ: yaml_MAPPING_START_EVENT,
+ start_mark: start_mark,
+ end_mark: end_mark,
+ anchor: anchor,
+ tag: tag,
+ implicit: implicit,
+ style: yaml_style_t(yaml_BLOCK_MAPPING_STYLE),
+ }
+ return true
+ }
+ if len(anchor) > 0 || len(tag) > 0 {
+ parser.state = parser.states[len(parser.states)-1]
+ parser.states = parser.states[:len(parser.states)-1]
+
+ *event = yaml_event_t{
+ typ: yaml_SCALAR_EVENT,
+ start_mark: start_mark,
+ end_mark: end_mark,
+ anchor: anchor,
+ tag: tag,
+ implicit: implicit,
+ quoted_implicit: false,
+ style: yaml_style_t(yaml_PLAIN_SCALAR_STYLE),
+ }
+ return true
+ }
+
+ context := "while parsing a flow node"
+ if block {
+ context = "while parsing a block node"
+ }
+ yaml_parser_set_parser_error_context(parser, context, start_mark,
+ "did not find expected node content", token.start_mark)
+ return false
+}
+
+// Parse the productions:
+// block_sequence ::= BLOCK-SEQUENCE-START (BLOCK-ENTRY block_node?)* BLOCK-END
+// ******************** *********** * *********
+//
+func yaml_parser_parse_block_sequence_entry(parser *yaml_parser_t, event *yaml_event_t, first bool) bool {
+ if first {
+ token := peek_token(parser)
+ parser.marks = append(parser.marks, token.start_mark)
+ skip_token(parser)
+ }
+
+ token := peek_token(parser)
+ if token == nil {
+ return false
+ }
+
+ if token.typ == yaml_BLOCK_ENTRY_TOKEN {
+ mark := token.end_mark
+ skip_token(parser)
+ token = peek_token(parser)
+ if token == nil {
+ return false
+ }
+ if token.typ != yaml_BLOCK_ENTRY_TOKEN && token.typ != yaml_BLOCK_END_TOKEN {
+ parser.states = append(parser.states, yaml_PARSE_BLOCK_SEQUENCE_ENTRY_STATE)
+ return yaml_parser_parse_node(parser, event, true, false)
+ } else {
+ parser.state = yaml_PARSE_BLOCK_SEQUENCE_ENTRY_STATE
+ return yaml_parser_process_empty_scalar(parser, event, mark)
+ }
+ }
+ if token.typ == yaml_BLOCK_END_TOKEN {
+ parser.state = parser.states[len(parser.states)-1]
+ parser.states = parser.states[:len(parser.states)-1]
+ parser.marks = parser.marks[:len(parser.marks)-1]
+
+ *event = yaml_event_t{
+ typ: yaml_SEQUENCE_END_EVENT,
+ start_mark: token.start_mark,
+ end_mark: token.end_mark,
+ }
+
+ skip_token(parser)
+ return true
+ }
+
+ context_mark := parser.marks[len(parser.marks)-1]
+ parser.marks = parser.marks[:len(parser.marks)-1]
+ return yaml_parser_set_parser_error_context(parser,
+ "while parsing a block collection", context_mark,
+ "did not find expected '-' indicator", token.start_mark)
+}
+
+// Parse the productions:
+// indentless_sequence ::= (BLOCK-ENTRY block_node?)+
+// *********** *
+func yaml_parser_parse_indentless_sequence_entry(parser *yaml_parser_t, event *yaml_event_t) bool {
+ token := peek_token(parser)
+ if token == nil {
+ return false
+ }
+
+ if token.typ == yaml_BLOCK_ENTRY_TOKEN {
+ mark := token.end_mark
+ skip_token(parser)
+ token = peek_token(parser)
+ if token == nil {
+ return false
+ }
+ if token.typ != yaml_BLOCK_ENTRY_TOKEN &&
+ token.typ != yaml_KEY_TOKEN &&
+ token.typ != yaml_VALUE_TOKEN &&
+ token.typ != yaml_BLOCK_END_TOKEN {
+ parser.states = append(parser.states, yaml_PARSE_INDENTLESS_SEQUENCE_ENTRY_STATE)
+ return yaml_parser_parse_node(parser, event, true, false)
+ }
+ parser.state = yaml_PARSE_INDENTLESS_SEQUENCE_ENTRY_STATE
+ return yaml_parser_process_empty_scalar(parser, event, mark)
+ }
+ parser.state = parser.states[len(parser.states)-1]
+ parser.states = parser.states[:len(parser.states)-1]
+
+ *event = yaml_event_t{
+ typ: yaml_SEQUENCE_END_EVENT,
+ start_mark: token.start_mark,
+ end_mark: token.start_mark, // [Go] Shouldn't this be token.end_mark?
+ }
+ return true
+}
+
+// Parse the productions:
+// block_mapping ::= BLOCK-MAPPING_START
+// *******************
+// ((KEY block_node_or_indentless_sequence?)?
+// *** *
+// (VALUE block_node_or_indentless_sequence?)?)*
+//
+// BLOCK-END
+// *********
+//
+func yaml_parser_parse_block_mapping_key(parser *yaml_parser_t, event *yaml_event_t, first bool) bool {
+ if first {
+ token := peek_token(parser)
+ parser.marks = append(parser.marks, token.start_mark)
+ skip_token(parser)
+ }
+
+ token := peek_token(parser)
+ if token == nil {
+ return false
+ }
+
+ if token.typ == yaml_KEY_TOKEN {
+ mark := token.end_mark
+ skip_token(parser)
+ token = peek_token(parser)
+ if token == nil {
+ return false
+ }
+ if token.typ != yaml_KEY_TOKEN &&
+ token.typ != yaml_VALUE_TOKEN &&
+ token.typ != yaml_BLOCK_END_TOKEN {
+ parser.states = append(parser.states, yaml_PARSE_BLOCK_MAPPING_VALUE_STATE)
+ return yaml_parser_parse_node(parser, event, true, true)
+ } else {
+ parser.state = yaml_PARSE_BLOCK_MAPPING_VALUE_STATE
+ return yaml_parser_process_empty_scalar(parser, event, mark)
+ }
+ } else if token.typ == yaml_BLOCK_END_TOKEN {
+ parser.state = parser.states[len(parser.states)-1]
+ parser.states = parser.states[:len(parser.states)-1]
+ parser.marks = parser.marks[:len(parser.marks)-1]
+ *event = yaml_event_t{
+ typ: yaml_MAPPING_END_EVENT,
+ start_mark: token.start_mark,
+ end_mark: token.end_mark,
+ }
+ skip_token(parser)
+ return true
+ }
+
+ context_mark := parser.marks[len(parser.marks)-1]
+ parser.marks = parser.marks[:len(parser.marks)-1]
+ return yaml_parser_set_parser_error_context(parser,
+ "while parsing a block mapping", context_mark,
+ "did not find expected key", token.start_mark)
+}
+
+// Parse the productions:
+// block_mapping ::= BLOCK-MAPPING_START
+//
+// ((KEY block_node_or_indentless_sequence?)?
+//
+// (VALUE block_node_or_indentless_sequence?)?)*
+// ***** *
+// BLOCK-END
+//
+//
+func yaml_parser_parse_block_mapping_value(parser *yaml_parser_t, event *yaml_event_t) bool {
+ token := peek_token(parser)
+ if token == nil {
+ return false
+ }
+ if token.typ == yaml_VALUE_TOKEN {
+ mark := token.end_mark
+ skip_token(parser)
+ token = peek_token(parser)
+ if token == nil {
+ return false
+ }
+ if token.typ != yaml_KEY_TOKEN &&
+ token.typ != yaml_VALUE_TOKEN &&
+ token.typ != yaml_BLOCK_END_TOKEN {
+ parser.states = append(parser.states, yaml_PARSE_BLOCK_MAPPING_KEY_STATE)
+ return yaml_parser_parse_node(parser, event, true, true)
+ }
+ parser.state = yaml_PARSE_BLOCK_MAPPING_KEY_STATE
+ return yaml_parser_process_empty_scalar(parser, event, mark)
+ }
+ parser.state = yaml_PARSE_BLOCK_MAPPING_KEY_STATE
+ return yaml_parser_process_empty_scalar(parser, event, token.start_mark)
+}
+
+// Parse the productions:
+// flow_sequence ::= FLOW-SEQUENCE-START
+// *******************
+// (flow_sequence_entry FLOW-ENTRY)*
+// * **********
+// flow_sequence_entry?
+// *
+// FLOW-SEQUENCE-END
+// *****************
+// flow_sequence_entry ::= flow_node | KEY flow_node? (VALUE flow_node?)?
+// *
+//
+func yaml_parser_parse_flow_sequence_entry(parser *yaml_parser_t, event *yaml_event_t, first bool) bool {
+ if first {
+ token := peek_token(parser)
+ parser.marks = append(parser.marks, token.start_mark)
+ skip_token(parser)
+ }
+ token := peek_token(parser)
+ if token == nil {
+ return false
+ }
+ if token.typ != yaml_FLOW_SEQUENCE_END_TOKEN {
+ if !first {
+ if token.typ == yaml_FLOW_ENTRY_TOKEN {
+ skip_token(parser)
+ token = peek_token(parser)
+ if token == nil {
+ return false
+ }
+ } else {
+ context_mark := parser.marks[len(parser.marks)-1]
+ parser.marks = parser.marks[:len(parser.marks)-1]
+ return yaml_parser_set_parser_error_context(parser,
+ "while parsing a flow sequence", context_mark,
+ "did not find expected ',' or ']'", token.start_mark)
+ }
+ }
+
+ if token.typ == yaml_KEY_TOKEN {
+ parser.state = yaml_PARSE_FLOW_SEQUENCE_ENTRY_MAPPING_KEY_STATE
+ *event = yaml_event_t{
+ typ: yaml_MAPPING_START_EVENT,
+ start_mark: token.start_mark,
+ end_mark: token.end_mark,
+ implicit: true,
+ style: yaml_style_t(yaml_FLOW_MAPPING_STYLE),
+ }
+ skip_token(parser)
+ return true
+ } else if token.typ != yaml_FLOW_SEQUENCE_END_TOKEN {
+ parser.states = append(parser.states, yaml_PARSE_FLOW_SEQUENCE_ENTRY_STATE)
+ return yaml_parser_parse_node(parser, event, false, false)
+ }
+ }
+
+ parser.state = parser.states[len(parser.states)-1]
+ parser.states = parser.states[:len(parser.states)-1]
+ parser.marks = parser.marks[:len(parser.marks)-1]
+
+ *event = yaml_event_t{
+ typ: yaml_SEQUENCE_END_EVENT,
+ start_mark: token.start_mark,
+ end_mark: token.end_mark,
+ }
+
+ skip_token(parser)
+ return true
+}
+
+//
+// Parse the productions:
+// flow_sequence_entry ::= flow_node | KEY flow_node? (VALUE flow_node?)?
+// *** *
+//
+func yaml_parser_parse_flow_sequence_entry_mapping_key(parser *yaml_parser_t, event *yaml_event_t) bool {
+ token := peek_token(parser)
+ if token == nil {
+ return false
+ }
+ if token.typ != yaml_VALUE_TOKEN &&
+ token.typ != yaml_FLOW_ENTRY_TOKEN &&
+ token.typ != yaml_FLOW_SEQUENCE_END_TOKEN {
+ parser.states = append(parser.states, yaml_PARSE_FLOW_SEQUENCE_ENTRY_MAPPING_VALUE_STATE)
+ return yaml_parser_parse_node(parser, event, false, false)
+ }
+ mark := token.end_mark
+ skip_token(parser)
+ parser.state = yaml_PARSE_FLOW_SEQUENCE_ENTRY_MAPPING_VALUE_STATE
+ return yaml_parser_process_empty_scalar(parser, event, mark)
+}
+
+// Parse the productions:
+// flow_sequence_entry ::= flow_node | KEY flow_node? (VALUE flow_node?)?
+// ***** *
+//
+func yaml_parser_parse_flow_sequence_entry_mapping_value(parser *yaml_parser_t, event *yaml_event_t) bool {
+ token := peek_token(parser)
+ if token == nil {
+ return false
+ }
+ if token.typ == yaml_VALUE_TOKEN {
+ skip_token(parser)
+ token := peek_token(parser)
+ if token == nil {
+ return false
+ }
+ if token.typ != yaml_FLOW_ENTRY_TOKEN && token.typ != yaml_FLOW_SEQUENCE_END_TOKEN {
+ parser.states = append(parser.states, yaml_PARSE_FLOW_SEQUENCE_ENTRY_MAPPING_END_STATE)
+ return yaml_parser_parse_node(parser, event, false, false)
+ }
+ }
+ parser.state = yaml_PARSE_FLOW_SEQUENCE_ENTRY_MAPPING_END_STATE
+ return yaml_parser_process_empty_scalar(parser, event, token.start_mark)
+}
+
+// Parse the productions:
+// flow_sequence_entry ::= flow_node | KEY flow_node? (VALUE flow_node?)?
+// *
+//
+func yaml_parser_parse_flow_sequence_entry_mapping_end(parser *yaml_parser_t, event *yaml_event_t) bool {
+ token := peek_token(parser)
+ if token == nil {
+ return false
+ }
+ parser.state = yaml_PARSE_FLOW_SEQUENCE_ENTRY_STATE
+ *event = yaml_event_t{
+ typ: yaml_MAPPING_END_EVENT,
+ start_mark: token.start_mark,
+ end_mark: token.start_mark, // [Go] Shouldn't this be end_mark?
+ }
+ return true
+}
+
+// Parse the productions:
+// flow_mapping ::= FLOW-MAPPING-START
+// ******************
+// (flow_mapping_entry FLOW-ENTRY)*
+// * **********
+// flow_mapping_entry?
+// ******************
+// FLOW-MAPPING-END
+// ****************
+// flow_mapping_entry ::= flow_node | KEY flow_node? (VALUE flow_node?)?
+// * *** *
+//
+func yaml_parser_parse_flow_mapping_key(parser *yaml_parser_t, event *yaml_event_t, first bool) bool {
+ if first {
+ token := peek_token(parser)
+ parser.marks = append(parser.marks, token.start_mark)
+ skip_token(parser)
+ }
+
+ token := peek_token(parser)
+ if token == nil {
+ return false
+ }
+
+ if token.typ != yaml_FLOW_MAPPING_END_TOKEN {
+ if !first {
+ if token.typ == yaml_FLOW_ENTRY_TOKEN {
+ skip_token(parser)
+ token = peek_token(parser)
+ if token == nil {
+ return false
+ }
+ } else {
+ context_mark := parser.marks[len(parser.marks)-1]
+ parser.marks = parser.marks[:len(parser.marks)-1]
+ return yaml_parser_set_parser_error_context(parser,
+ "while parsing a flow mapping", context_mark,
+ "did not find expected ',' or '}'", token.start_mark)
+ }
+ }
+
+ if token.typ == yaml_KEY_TOKEN {
+ skip_token(parser)
+ token = peek_token(parser)
+ if token == nil {
+ return false
+ }
+ if token.typ != yaml_VALUE_TOKEN &&
+ token.typ != yaml_FLOW_ENTRY_TOKEN &&
+ token.typ != yaml_FLOW_MAPPING_END_TOKEN {
+ parser.states = append(parser.states, yaml_PARSE_FLOW_MAPPING_VALUE_STATE)
+ return yaml_parser_parse_node(parser, event, false, false)
+ } else {
+ parser.state = yaml_PARSE_FLOW_MAPPING_VALUE_STATE
+ return yaml_parser_process_empty_scalar(parser, event, token.start_mark)
+ }
+ } else if token.typ != yaml_FLOW_MAPPING_END_TOKEN {
+ parser.states = append(parser.states, yaml_PARSE_FLOW_MAPPING_EMPTY_VALUE_STATE)
+ return yaml_parser_parse_node(parser, event, false, false)
+ }
+ }
+
+ parser.state = parser.states[len(parser.states)-1]
+ parser.states = parser.states[:len(parser.states)-1]
+ parser.marks = parser.marks[:len(parser.marks)-1]
+ *event = yaml_event_t{
+ typ: yaml_MAPPING_END_EVENT,
+ start_mark: token.start_mark,
+ end_mark: token.end_mark,
+ }
+ skip_token(parser)
+ return true
+}
+
+// Parse the productions:
+// flow_mapping_entry ::= flow_node | KEY flow_node? (VALUE flow_node?)?
+// * ***** *
+//
+func yaml_parser_parse_flow_mapping_value(parser *yaml_parser_t, event *yaml_event_t, empty bool) bool {
+ token := peek_token(parser)
+ if token == nil {
+ return false
+ }
+ if empty {
+ parser.state = yaml_PARSE_FLOW_MAPPING_KEY_STATE
+ return yaml_parser_process_empty_scalar(parser, event, token.start_mark)
+ }
+ if token.typ == yaml_VALUE_TOKEN {
+ skip_token(parser)
+ token = peek_token(parser)
+ if token == nil {
+ return false
+ }
+ if token.typ != yaml_FLOW_ENTRY_TOKEN && token.typ != yaml_FLOW_MAPPING_END_TOKEN {
+ parser.states = append(parser.states, yaml_PARSE_FLOW_MAPPING_KEY_STATE)
+ return yaml_parser_parse_node(parser, event, false, false)
+ }
+ }
+ parser.state = yaml_PARSE_FLOW_MAPPING_KEY_STATE
+ return yaml_parser_process_empty_scalar(parser, event, token.start_mark)
+}
+
+// Generate an empty scalar event.
+func yaml_parser_process_empty_scalar(parser *yaml_parser_t, event *yaml_event_t, mark yaml_mark_t) bool {
+ *event = yaml_event_t{
+ typ: yaml_SCALAR_EVENT,
+ start_mark: mark,
+ end_mark: mark,
+ value: nil, // Empty
+ implicit: true,
+ style: yaml_style_t(yaml_PLAIN_SCALAR_STYLE),
+ }
+ return true
+}
+
+var default_tag_directives = []yaml_tag_directive_t{
+ {[]byte("!"), []byte("!")},
+ {[]byte("!!"), []byte("tag:yaml.org,2002:")},
+}
+
+// Parse directives.
+func yaml_parser_process_directives(parser *yaml_parser_t,
+ version_directive_ref **yaml_version_directive_t,
+ tag_directives_ref *[]yaml_tag_directive_t) bool {
+
+ var version_directive *yaml_version_directive_t
+ var tag_directives []yaml_tag_directive_t
+
+ token := peek_token(parser)
+ if token == nil {
+ return false
+ }
+
+ for token.typ == yaml_VERSION_DIRECTIVE_TOKEN || token.typ == yaml_TAG_DIRECTIVE_TOKEN {
+ if token.typ == yaml_VERSION_DIRECTIVE_TOKEN {
+ if version_directive != nil {
+ yaml_parser_set_parser_error(parser,
+ "found duplicate %YAML directive", token.start_mark)
+ return false
+ }
+ if token.major != 1 || token.minor != 1 {
+ yaml_parser_set_parser_error(parser,
+ "found incompatible YAML document", token.start_mark)
+ return false
+ }
+ version_directive = &yaml_version_directive_t{
+ major: token.major,
+ minor: token.minor,
+ }
+ } else if token.typ == yaml_TAG_DIRECTIVE_TOKEN {
+ value := yaml_tag_directive_t{
+ handle: token.value,
+ prefix: token.prefix,
+ }
+ if !yaml_parser_append_tag_directive(parser, value, false, token.start_mark) {
+ return false
+ }
+ tag_directives = append(tag_directives, value)
+ }
+
+ skip_token(parser)
+ token = peek_token(parser)
+ if token == nil {
+ return false
+ }
+ }
+
+ for i := range default_tag_directives {
+ if !yaml_parser_append_tag_directive(parser, default_tag_directives[i], true, token.start_mark) {
+ return false
+ }
+ }
+
+ if version_directive_ref != nil {
+ *version_directive_ref = version_directive
+ }
+ if tag_directives_ref != nil {
+ *tag_directives_ref = tag_directives
+ }
+ return true
+}
+
+// Append a tag directive to the directives stack.
+func yaml_parser_append_tag_directive(parser *yaml_parser_t, value yaml_tag_directive_t, allow_duplicates bool, mark yaml_mark_t) bool {
+ for i := range parser.tag_directives {
+ if bytes.Equal(value.handle, parser.tag_directives[i].handle) {
+ if allow_duplicates {
+ return true
+ }
+ return yaml_parser_set_parser_error(parser, "found duplicate %TAG directive", mark)
+ }
+ }
+
+ // [Go] I suspect the copy is unnecessary. This was likely done
+ // because there was no way to track ownership of the data.
+ value_copy := yaml_tag_directive_t{
+ handle: make([]byte, len(value.handle)),
+ prefix: make([]byte, len(value.prefix)),
+ }
+ copy(value_copy.handle, value.handle)
+ copy(value_copy.prefix, value.prefix)
+ parser.tag_directives = append(parser.tag_directives, value_copy)
+ return true
+}
diff --git a/vendor/github.com/coreos/ignition/config/vendor/github.com/go-yaml/yaml/readerc.go b/vendor/github.com/coreos/ignition/config/vendor/github.com/go-yaml/yaml/readerc.go
new file mode 100644
index 00000000..d5fb0972
--- /dev/null
+++ b/vendor/github.com/coreos/ignition/config/vendor/github.com/go-yaml/yaml/readerc.go
@@ -0,0 +1,391 @@
+package yaml
+
+import (
+ "io"
+)
+
+// Set the reader error and return 0.
+func yaml_parser_set_reader_error(parser *yaml_parser_t, problem string, offset int, value int) bool {
+ parser.error = yaml_READER_ERROR
+ parser.problem = problem
+ parser.problem_offset = offset
+ parser.problem_value = value
+ return false
+}
+
+// Byte order marks.
+const (
+ bom_UTF8 = "\xef\xbb\xbf"
+ bom_UTF16LE = "\xff\xfe"
+ bom_UTF16BE = "\xfe\xff"
+)
+
+// Determine the input stream encoding by checking the BOM symbol. If no BOM is
+// found, the UTF-8 encoding is assumed. Return 1 on success, 0 on failure.
+func yaml_parser_determine_encoding(parser *yaml_parser_t) bool {
+ // Ensure that we had enough bytes in the raw buffer.
+ for !parser.eof && len(parser.raw_buffer)-parser.raw_buffer_pos < 3 {
+ if !yaml_parser_update_raw_buffer(parser) {
+ return false
+ }
+ }
+
+ // Determine the encoding.
+ buf := parser.raw_buffer
+ pos := parser.raw_buffer_pos
+ avail := len(buf) - pos
+ if avail >= 2 && buf[pos] == bom_UTF16LE[0] && buf[pos+1] == bom_UTF16LE[1] {
+ parser.encoding = yaml_UTF16LE_ENCODING
+ parser.raw_buffer_pos += 2
+ parser.offset += 2
+ } else if avail >= 2 && buf[pos] == bom_UTF16BE[0] && buf[pos+1] == bom_UTF16BE[1] {
+ parser.encoding = yaml_UTF16BE_ENCODING
+ parser.raw_buffer_pos += 2
+ parser.offset += 2
+ } else if avail >= 3 && buf[pos] == bom_UTF8[0] && buf[pos+1] == bom_UTF8[1] && buf[pos+2] == bom_UTF8[2] {
+ parser.encoding = yaml_UTF8_ENCODING
+ parser.raw_buffer_pos += 3
+ parser.offset += 3
+ } else {
+ parser.encoding = yaml_UTF8_ENCODING
+ }
+ return true
+}
+
+// Update the raw buffer.
+func yaml_parser_update_raw_buffer(parser *yaml_parser_t) bool {
+ size_read := 0
+
+ // Return if the raw buffer is full.
+ if parser.raw_buffer_pos == 0 && len(parser.raw_buffer) == cap(parser.raw_buffer) {
+ return true
+ }
+
+ // Return on EOF.
+ if parser.eof {
+ return true
+ }
+
+ // Move the remaining bytes in the raw buffer to the beginning.
+ if parser.raw_buffer_pos > 0 && parser.raw_buffer_pos < len(parser.raw_buffer) {
+ copy(parser.raw_buffer, parser.raw_buffer[parser.raw_buffer_pos:])
+ }
+ parser.raw_buffer = parser.raw_buffer[:len(parser.raw_buffer)-parser.raw_buffer_pos]
+ parser.raw_buffer_pos = 0
+
+ // Call the read handler to fill the buffer.
+ size_read, err := parser.read_handler(parser, parser.raw_buffer[len(parser.raw_buffer):cap(parser.raw_buffer)])
+ parser.raw_buffer = parser.raw_buffer[:len(parser.raw_buffer)+size_read]
+ if err == io.EOF {
+ parser.eof = true
+ } else if err != nil {
+ return yaml_parser_set_reader_error(parser, "input error: "+err.Error(), parser.offset, -1)
+ }
+ return true
+}
+
+// Ensure that the buffer contains at least `length` characters.
+// Return true on success, false on failure.
+//
+// The length is supposed to be significantly less that the buffer size.
+func yaml_parser_update_buffer(parser *yaml_parser_t, length int) bool {
+ if parser.read_handler == nil {
+ panic("read handler must be set")
+ }
+
+ // If the EOF flag is set and the raw buffer is empty, do nothing.
+ if parser.eof && parser.raw_buffer_pos == len(parser.raw_buffer) {
+ return true
+ }
+
+ // Return if the buffer contains enough characters.
+ if parser.unread >= length {
+ return true
+ }
+
+ // Determine the input encoding if it is not known yet.
+ if parser.encoding == yaml_ANY_ENCODING {
+ if !yaml_parser_determine_encoding(parser) {
+ return false
+ }
+ }
+
+ // Move the unread characters to the beginning of the buffer.
+ buffer_len := len(parser.buffer)
+ if parser.buffer_pos > 0 && parser.buffer_pos < buffer_len {
+ copy(parser.buffer, parser.buffer[parser.buffer_pos:])
+ buffer_len -= parser.buffer_pos
+ parser.buffer_pos = 0
+ } else if parser.buffer_pos == buffer_len {
+ buffer_len = 0
+ parser.buffer_pos = 0
+ }
+
+ // Open the whole buffer for writing, and cut it before returning.
+ parser.buffer = parser.buffer[:cap(parser.buffer)]
+
+ // Fill the buffer until it has enough characters.
+ first := true
+ for parser.unread < length {
+
+ // Fill the raw buffer if necessary.
+ if !first || parser.raw_buffer_pos == len(parser.raw_buffer) {
+ if !yaml_parser_update_raw_buffer(parser) {
+ parser.buffer = parser.buffer[:buffer_len]
+ return false
+ }
+ }
+ first = false
+
+ // Decode the raw buffer.
+ inner:
+ for parser.raw_buffer_pos != len(parser.raw_buffer) {
+ var value rune
+ var width int
+
+ raw_unread := len(parser.raw_buffer) - parser.raw_buffer_pos
+
+ // Decode the next character.
+ switch parser.encoding {
+ case yaml_UTF8_ENCODING:
+ // Decode a UTF-8 character. Check RFC 3629
+ // (http://www.ietf.org/rfc/rfc3629.txt) for more details.
+ //
+ // The following table (taken from the RFC) is used for
+ // decoding.
+ //
+ // Char. number range | UTF-8 octet sequence
+ // (hexadecimal) | (binary)
+ // --------------------+------------------------------------
+ // 0000 0000-0000 007F | 0xxxxxxx
+ // 0000 0080-0000 07FF | 110xxxxx 10xxxxxx
+ // 0000 0800-0000 FFFF | 1110xxxx 10xxxxxx 10xxxxxx
+ // 0001 0000-0010 FFFF | 11110xxx 10xxxxxx 10xxxxxx 10xxxxxx
+ //
+ // Additionally, the characters in the range 0xD800-0xDFFF
+ // are prohibited as they are reserved for use with UTF-16
+ // surrogate pairs.
+
+ // Determine the length of the UTF-8 sequence.
+ octet := parser.raw_buffer[parser.raw_buffer_pos]
+ switch {
+ case octet&0x80 == 0x00:
+ width = 1
+ case octet&0xE0 == 0xC0:
+ width = 2
+ case octet&0xF0 == 0xE0:
+ width = 3
+ case octet&0xF8 == 0xF0:
+ width = 4
+ default:
+ // The leading octet is invalid.
+ return yaml_parser_set_reader_error(parser,
+ "invalid leading UTF-8 octet",
+ parser.offset, int(octet))
+ }
+
+ // Check if the raw buffer contains an incomplete character.
+ if width > raw_unread {
+ if parser.eof {
+ return yaml_parser_set_reader_error(parser,
+ "incomplete UTF-8 octet sequence",
+ parser.offset, -1)
+ }
+ break inner
+ }
+
+ // Decode the leading octet.
+ switch {
+ case octet&0x80 == 0x00:
+ value = rune(octet & 0x7F)
+ case octet&0xE0 == 0xC0:
+ value = rune(octet & 0x1F)
+ case octet&0xF0 == 0xE0:
+ value = rune(octet & 0x0F)
+ case octet&0xF8 == 0xF0:
+ value = rune(octet & 0x07)
+ default:
+ value = 0
+ }
+
+ // Check and decode the trailing octets.
+ for k := 1; k < width; k++ {
+ octet = parser.raw_buffer[parser.raw_buffer_pos+k]
+
+ // Check if the octet is valid.
+ if (octet & 0xC0) != 0x80 {
+ return yaml_parser_set_reader_error(parser,
+ "invalid trailing UTF-8 octet",
+ parser.offset+k, int(octet))
+ }
+
+ // Decode the octet.
+ value = (value << 6) + rune(octet&0x3F)
+ }
+
+ // Check the length of the sequence against the value.
+ switch {
+ case width == 1:
+ case width == 2 && value >= 0x80:
+ case width == 3 && value >= 0x800:
+ case width == 4 && value >= 0x10000:
+ default:
+ return yaml_parser_set_reader_error(parser,
+ "invalid length of a UTF-8 sequence",
+ parser.offset, -1)
+ }
+
+ // Check the range of the value.
+ if value >= 0xD800 && value <= 0xDFFF || value > 0x10FFFF {
+ return yaml_parser_set_reader_error(parser,
+ "invalid Unicode character",
+ parser.offset, int(value))
+ }
+
+ case yaml_UTF16LE_ENCODING, yaml_UTF16BE_ENCODING:
+ var low, high int
+ if parser.encoding == yaml_UTF16LE_ENCODING {
+ low, high = 0, 1
+ } else {
+ high, low = 1, 0
+ }
+
+ // The UTF-16 encoding is not as simple as one might
+ // naively think. Check RFC 2781
+ // (http://www.ietf.org/rfc/rfc2781.txt).
+ //
+ // Normally, two subsequent bytes describe a Unicode
+ // character. However a special technique (called a
+ // surrogate pair) is used for specifying character
+ // values larger than 0xFFFF.
+ //
+ // A surrogate pair consists of two pseudo-characters:
+ // high surrogate area (0xD800-0xDBFF)
+ // low surrogate area (0xDC00-0xDFFF)
+ //
+ // The following formulas are used for decoding
+ // and encoding characters using surrogate pairs:
+ //
+ // U = U' + 0x10000 (0x01 00 00 <= U <= 0x10 FF FF)
+ // U' = yyyyyyyyyyxxxxxxxxxx (0 <= U' <= 0x0F FF FF)
+ // W1 = 110110yyyyyyyyyy
+ // W2 = 110111xxxxxxxxxx
+ //
+ // where U is the character value, W1 is the high surrogate
+ // area, W2 is the low surrogate area.
+
+ // Check for incomplete UTF-16 character.
+ if raw_unread < 2 {
+ if parser.eof {
+ return yaml_parser_set_reader_error(parser,
+ "incomplete UTF-16 character",
+ parser.offset, -1)
+ }
+ break inner
+ }
+
+ // Get the character.
+ value = rune(parser.raw_buffer[parser.raw_buffer_pos+low]) +
+ (rune(parser.raw_buffer[parser.raw_buffer_pos+high]) << 8)
+
+ // Check for unexpected low surrogate area.
+ if value&0xFC00 == 0xDC00 {
+ return yaml_parser_set_reader_error(parser,
+ "unexpected low surrogate area",
+ parser.offset, int(value))
+ }
+
+ // Check for a high surrogate area.
+ if value&0xFC00 == 0xD800 {
+ width = 4
+
+ // Check for incomplete surrogate pair.
+ if raw_unread < 4 {
+ if parser.eof {
+ return yaml_parser_set_reader_error(parser,
+ "incomplete UTF-16 surrogate pair",
+ parser.offset, -1)
+ }
+ break inner
+ }
+
+ // Get the next character.
+ value2 := rune(parser.raw_buffer[parser.raw_buffer_pos+low+2]) +
+ (rune(parser.raw_buffer[parser.raw_buffer_pos+high+2]) << 8)
+
+ // Check for a low surrogate area.
+ if value2&0xFC00 != 0xDC00 {
+ return yaml_parser_set_reader_error(parser,
+ "expected low surrogate area",
+ parser.offset+2, int(value2))
+ }
+
+ // Generate the value of the surrogate pair.
+ value = 0x10000 + ((value & 0x3FF) << 10) + (value2 & 0x3FF)
+ } else {
+ width = 2
+ }
+
+ default:
+ panic("impossible")
+ }
+
+ // Check if the character is in the allowed range:
+ // #x9 | #xA | #xD | [#x20-#x7E] (8 bit)
+ // | #x85 | [#xA0-#xD7FF] | [#xE000-#xFFFD] (16 bit)
+ // | [#x10000-#x10FFFF] (32 bit)
+ switch {
+ case value == 0x09:
+ case value == 0x0A:
+ case value == 0x0D:
+ case value >= 0x20 && value <= 0x7E:
+ case value == 0x85:
+ case value >= 0xA0 && value <= 0xD7FF:
+ case value >= 0xE000 && value <= 0xFFFD:
+ case value >= 0x10000 && value <= 0x10FFFF:
+ default:
+ return yaml_parser_set_reader_error(parser,
+ "control characters are not allowed",
+ parser.offset, int(value))
+ }
+
+ // Move the raw pointers.
+ parser.raw_buffer_pos += width
+ parser.offset += width
+
+ // Finally put the character into the buffer.
+ if value <= 0x7F {
+ // 0000 0000-0000 007F . 0xxxxxxx
+ parser.buffer[buffer_len+0] = byte(value)
+ } else if value <= 0x7FF {
+ // 0000 0080-0000 07FF . 110xxxxx 10xxxxxx
+ parser.buffer[buffer_len+0] = byte(0xC0 + (value >> 6))
+ parser.buffer[buffer_len+1] = byte(0x80 + (value & 0x3F))
+ } else if value <= 0xFFFF {
+ // 0000 0800-0000 FFFF . 1110xxxx 10xxxxxx 10xxxxxx
+ parser.buffer[buffer_len+0] = byte(0xE0 + (value >> 12))
+ parser.buffer[buffer_len+1] = byte(0x80 + ((value >> 6) & 0x3F))
+ parser.buffer[buffer_len+2] = byte(0x80 + (value & 0x3F))
+ } else {
+ // 0001 0000-0010 FFFF . 11110xxx 10xxxxxx 10xxxxxx 10xxxxxx
+ parser.buffer[buffer_len+0] = byte(0xF0 + (value >> 18))
+ parser.buffer[buffer_len+1] = byte(0x80 + ((value >> 12) & 0x3F))
+ parser.buffer[buffer_len+2] = byte(0x80 + ((value >> 6) & 0x3F))
+ parser.buffer[buffer_len+3] = byte(0x80 + (value & 0x3F))
+ }
+ buffer_len += width
+
+ parser.unread++
+ }
+
+ // On EOF, put NUL into the buffer and return.
+ if parser.eof {
+ parser.buffer[buffer_len] = 0
+ buffer_len++
+ parser.unread++
+ break
+ }
+ }
+ parser.buffer = parser.buffer[:buffer_len]
+ return true
+}
diff --git a/vendor/github.com/coreos/ignition/config/vendor/github.com/go-yaml/yaml/resolve.go b/vendor/github.com/coreos/ignition/config/vendor/github.com/go-yaml/yaml/resolve.go
new file mode 100644
index 00000000..93a86327
--- /dev/null
+++ b/vendor/github.com/coreos/ignition/config/vendor/github.com/go-yaml/yaml/resolve.go
@@ -0,0 +1,203 @@
+package yaml
+
+import (
+ "encoding/base64"
+ "math"
+ "strconv"
+ "strings"
+ "unicode/utf8"
+)
+
+type resolveMapItem struct {
+ value interface{}
+ tag string
+}
+
+var resolveTable = make([]byte, 256)
+var resolveMap = make(map[string]resolveMapItem)
+
+func init() {
+ t := resolveTable
+ t[int('+')] = 'S' // Sign
+ t[int('-')] = 'S'
+ for _, c := range "0123456789" {
+ t[int(c)] = 'D' // Digit
+ }
+ for _, c := range "yYnNtTfFoO~" {
+ t[int(c)] = 'M' // In map
+ }
+ t[int('.')] = '.' // Float (potentially in map)
+
+ var resolveMapList = []struct {
+ v interface{}
+ tag string
+ l []string
+ }{
+ {true, yaml_BOOL_TAG, []string{"y", "Y", "yes", "Yes", "YES"}},
+ {true, yaml_BOOL_TAG, []string{"true", "True", "TRUE"}},
+ {true, yaml_BOOL_TAG, []string{"on", "On", "ON"}},
+ {false, yaml_BOOL_TAG, []string{"n", "N", "no", "No", "NO"}},
+ {false, yaml_BOOL_TAG, []string{"false", "False", "FALSE"}},
+ {false, yaml_BOOL_TAG, []string{"off", "Off", "OFF"}},
+ {nil, yaml_NULL_TAG, []string{"", "~", "null", "Null", "NULL"}},
+ {math.NaN(), yaml_FLOAT_TAG, []string{".nan", ".NaN", ".NAN"}},
+ {math.Inf(+1), yaml_FLOAT_TAG, []string{".inf", ".Inf", ".INF"}},
+ {math.Inf(+1), yaml_FLOAT_TAG, []string{"+.inf", "+.Inf", "+.INF"}},
+ {math.Inf(-1), yaml_FLOAT_TAG, []string{"-.inf", "-.Inf", "-.INF"}},
+ {"<<", yaml_MERGE_TAG, []string{"<<"}},
+ }
+
+ m := resolveMap
+ for _, item := range resolveMapList {
+ for _, s := range item.l {
+ m[s] = resolveMapItem{item.v, item.tag}
+ }
+ }
+}
+
+const longTagPrefix = "tag:yaml.org,2002:"
+
+func shortTag(tag string) string {
+ // TODO This can easily be made faster and produce less garbage.
+ if strings.HasPrefix(tag, longTagPrefix) {
+ return "!!" + tag[len(longTagPrefix):]
+ }
+ return tag
+}
+
+func longTag(tag string) string {
+ if strings.HasPrefix(tag, "!!") {
+ return longTagPrefix + tag[2:]
+ }
+ return tag
+}
+
+func resolvableTag(tag string) bool {
+ switch tag {
+ case "", yaml_STR_TAG, yaml_BOOL_TAG, yaml_INT_TAG, yaml_FLOAT_TAG, yaml_NULL_TAG:
+ return true
+ }
+ return false
+}
+
+func resolve(tag string, in string) (rtag string, out interface{}) {
+ if !resolvableTag(tag) {
+ return tag, in
+ }
+
+ defer func() {
+ switch tag {
+ case "", rtag, yaml_STR_TAG, yaml_BINARY_TAG:
+ return
+ }
+ failf("cannot decode %s `%s` as a %s", shortTag(rtag), in, shortTag(tag))
+ }()
+
+ // Any data is accepted as a !!str or !!binary.
+ // Otherwise, the prefix is enough of a hint about what it might be.
+ hint := byte('N')
+ if in != "" {
+ hint = resolveTable[in[0]]
+ }
+ if hint != 0 && tag != yaml_STR_TAG && tag != yaml_BINARY_TAG {
+ // Handle things we can lookup in a map.
+ if item, ok := resolveMap[in]; ok {
+ return item.tag, item.value
+ }
+
+ // Base 60 floats are a bad idea, were dropped in YAML 1.2, and
+ // are purposefully unsupported here. They're still quoted on
+ // the way out for compatibility with other parser, though.
+
+ switch hint {
+ case 'M':
+ // We've already checked the map above.
+
+ case '.':
+ // Not in the map, so maybe a normal float.
+ floatv, err := strconv.ParseFloat(in, 64)
+ if err == nil {
+ return yaml_FLOAT_TAG, floatv
+ }
+
+ case 'D', 'S':
+ // Int, float, or timestamp.
+ plain := strings.Replace(in, "_", "", -1)
+ intv, err := strconv.ParseInt(plain, 0, 64)
+ if err == nil {
+ if intv == int64(int(intv)) {
+ return yaml_INT_TAG, int(intv)
+ } else {
+ return yaml_INT_TAG, intv
+ }
+ }
+ uintv, err := strconv.ParseUint(plain, 0, 64)
+ if err == nil {
+ return yaml_INT_TAG, uintv
+ }
+ floatv, err := strconv.ParseFloat(plain, 64)
+ if err == nil {
+ return yaml_FLOAT_TAG, floatv
+ }
+ if strings.HasPrefix(plain, "0b") {
+ intv, err := strconv.ParseInt(plain[2:], 2, 64)
+ if err == nil {
+ if intv == int64(int(intv)) {
+ return yaml_INT_TAG, int(intv)
+ } else {
+ return yaml_INT_TAG, intv
+ }
+ }
+ uintv, err := strconv.ParseUint(plain[2:], 2, 64)
+ if err == nil {
+ return yaml_INT_TAG, uintv
+ }
+ } else if strings.HasPrefix(plain, "-0b") {
+ intv, err := strconv.ParseInt(plain[3:], 2, 64)
+ if err == nil {
+ if intv == int64(int(intv)) {
+ return yaml_INT_TAG, -int(intv)
+ } else {
+ return yaml_INT_TAG, -intv
+ }
+ }
+ }
+ // XXX Handle timestamps here.
+
+ default:
+ panic("resolveTable item not yet handled: " + string(rune(hint)) + " (with " + in + ")")
+ }
+ }
+ if tag == yaml_BINARY_TAG {
+ return yaml_BINARY_TAG, in
+ }
+ if utf8.ValidString(in) {
+ return yaml_STR_TAG, in
+ }
+ return yaml_BINARY_TAG, encodeBase64(in)
+}
+
+// encodeBase64 encodes s as base64 that is broken up into multiple lines
+// as appropriate for the resulting length.
+func encodeBase64(s string) string {
+ const lineLen = 70
+ encLen := base64.StdEncoding.EncodedLen(len(s))
+ lines := encLen/lineLen + 1
+ buf := make([]byte, encLen*2+lines)
+ in := buf[0:encLen]
+ out := buf[encLen:]
+ base64.StdEncoding.Encode(in, []byte(s))
+ k := 0
+ for i := 0; i < len(in); i += lineLen {
+ j := i + lineLen
+ if j > len(in) {
+ j = len(in)
+ }
+ k += copy(out[k:], in[i:j])
+ if lines > 1 {
+ out[k] = '\n'
+ k++
+ }
+ }
+ return string(out[:k])
+}
diff --git a/vendor/github.com/coreos/ignition/config/vendor/github.com/go-yaml/yaml/scannerc.go b/vendor/github.com/coreos/ignition/config/vendor/github.com/go-yaml/yaml/scannerc.go
new file mode 100644
index 00000000..fe93b190
--- /dev/null
+++ b/vendor/github.com/coreos/ignition/config/vendor/github.com/go-yaml/yaml/scannerc.go
@@ -0,0 +1,2710 @@
+package yaml
+
+import (
+ "bytes"
+ "fmt"
+)
+
+// Introduction
+// ************
+//
+// The following notes assume that you are familiar with the YAML specification
+// (http://yaml.org/spec/cvs/current.html). We mostly follow it, although in
+// some cases we are less restrictive that it requires.
+//
+// The process of transforming a YAML stream into a sequence of events is
+// divided on two steps: Scanning and Parsing.
+//
+// The Scanner transforms the input stream into a sequence of tokens, while the
+// parser transform the sequence of tokens produced by the Scanner into a
+// sequence of parsing events.
+//
+// The Scanner is rather clever and complicated. The Parser, on the contrary,
+// is a straightforward implementation of a recursive-descendant parser (or,
+// LL(1) parser, as it is usually called).
+//
+// Actually there are two issues of Scanning that might be called "clever", the
+// rest is quite straightforward. The issues are "block collection start" and
+// "simple keys". Both issues are explained below in details.
+//
+// Here the Scanning step is explained and implemented. We start with the list
+// of all the tokens produced by the Scanner together with short descriptions.
+//
+// Now, tokens:
+//
+// STREAM-START(encoding) # The stream start.
+// STREAM-END # The stream end.
+// VERSION-DIRECTIVE(major,minor) # The '%YAML' directive.
+// TAG-DIRECTIVE(handle,prefix) # The '%TAG' directive.
+// DOCUMENT-START # '---'
+// DOCUMENT-END # '...'
+// BLOCK-SEQUENCE-START # Indentation increase denoting a block
+// BLOCK-MAPPING-START # sequence or a block mapping.
+// BLOCK-END # Indentation decrease.
+// FLOW-SEQUENCE-START # '['
+// FLOW-SEQUENCE-END # ']'
+// BLOCK-SEQUENCE-START # '{'
+// BLOCK-SEQUENCE-END # '}'
+// BLOCK-ENTRY # '-'
+// FLOW-ENTRY # ','
+// KEY # '?' or nothing (simple keys).
+// VALUE # ':'
+// ALIAS(anchor) # '*anchor'
+// ANCHOR(anchor) # '&anchor'
+// TAG(handle,suffix) # '!handle!suffix'
+// SCALAR(value,style) # A scalar.
+//
+// The following two tokens are "virtual" tokens denoting the beginning and the
+// end of the stream:
+//
+// STREAM-START(encoding)
+// STREAM-END
+//
+// We pass the information about the input stream encoding with the
+// STREAM-START token.
+//
+// The next two tokens are responsible for tags:
+//
+// VERSION-DIRECTIVE(major,minor)
+// TAG-DIRECTIVE(handle,prefix)
+//
+// Example:
+//
+// %YAML 1.1
+// %TAG ! !foo
+// %TAG !yaml! tag:yaml.org,2002:
+// ---
+//
+// The correspoding sequence of tokens:
+//
+// STREAM-START(utf-8)
+// VERSION-DIRECTIVE(1,1)
+// TAG-DIRECTIVE("!","!foo")
+// TAG-DIRECTIVE("!yaml","tag:yaml.org,2002:")
+// DOCUMENT-START
+// STREAM-END
+//
+// Note that the VERSION-DIRECTIVE and TAG-DIRECTIVE tokens occupy a whole
+// line.
+//
+// The document start and end indicators are represented by:
+//
+// DOCUMENT-START
+// DOCUMENT-END
+//
+// Note that if a YAML stream contains an implicit document (without '---'
+// and '...' indicators), no DOCUMENT-START and DOCUMENT-END tokens will be
+// produced.
+//
+// In the following examples, we present whole documents together with the
+// produced tokens.
+//
+// 1. An implicit document:
+//
+// 'a scalar'
+//
+// Tokens:
+//
+// STREAM-START(utf-8)
+// SCALAR("a scalar",single-quoted)
+// STREAM-END
+//
+// 2. An explicit document:
+//
+// ---
+// 'a scalar'
+// ...
+//
+// Tokens:
+//
+// STREAM-START(utf-8)
+// DOCUMENT-START
+// SCALAR("a scalar",single-quoted)
+// DOCUMENT-END
+// STREAM-END
+//
+// 3. Several documents in a stream:
+//
+// 'a scalar'
+// ---
+// 'another scalar'
+// ---
+// 'yet another scalar'
+//
+// Tokens:
+//
+// STREAM-START(utf-8)
+// SCALAR("a scalar",single-quoted)
+// DOCUMENT-START
+// SCALAR("another scalar",single-quoted)
+// DOCUMENT-START
+// SCALAR("yet another scalar",single-quoted)
+// STREAM-END
+//
+// We have already introduced the SCALAR token above. The following tokens are
+// used to describe aliases, anchors, tag, and scalars:
+//
+// ALIAS(anchor)
+// ANCHOR(anchor)
+// TAG(handle,suffix)
+// SCALAR(value,style)
+//
+// The following series of examples illustrate the usage of these tokens:
+//
+// 1. A recursive sequence:
+//
+// &A [ *A ]
+//
+// Tokens:
+//
+// STREAM-START(utf-8)
+// ANCHOR("A")
+// FLOW-SEQUENCE-START
+// ALIAS("A")
+// FLOW-SEQUENCE-END
+// STREAM-END
+//
+// 2. A tagged scalar:
+//
+// !!float "3.14" # A good approximation.
+//
+// Tokens:
+//
+// STREAM-START(utf-8)
+// TAG("!!","float")
+// SCALAR("3.14",double-quoted)
+// STREAM-END
+//
+// 3. Various scalar styles:
+//
+// --- # Implicit empty plain scalars do not produce tokens.
+// --- a plain scalar
+// --- 'a single-quoted scalar'
+// --- "a double-quoted scalar"
+// --- |-
+// a literal scalar
+// --- >-
+// a folded
+// scalar
+//
+// Tokens:
+//
+// STREAM-START(utf-8)
+// DOCUMENT-START
+// DOCUMENT-START
+// SCALAR("a plain scalar",plain)
+// DOCUMENT-START
+// SCALAR("a single-quoted scalar",single-quoted)
+// DOCUMENT-START
+// SCALAR("a double-quoted scalar",double-quoted)
+// DOCUMENT-START
+// SCALAR("a literal scalar",literal)
+// DOCUMENT-START
+// SCALAR("a folded scalar",folded)
+// STREAM-END
+//
+// Now it's time to review collection-related tokens. We will start with
+// flow collections:
+//
+// FLOW-SEQUENCE-START
+// FLOW-SEQUENCE-END
+// FLOW-MAPPING-START
+// FLOW-MAPPING-END
+// FLOW-ENTRY
+// KEY
+// VALUE
+//
+// The tokens FLOW-SEQUENCE-START, FLOW-SEQUENCE-END, FLOW-MAPPING-START, and
+// FLOW-MAPPING-END represent the indicators '[', ']', '{', and '}'
+// correspondingly. FLOW-ENTRY represent the ',' indicator. Finally the
+// indicators '?' and ':', which are used for denoting mapping keys and values,
+// are represented by the KEY and VALUE tokens.
+//
+// The following examples show flow collections:
+//
+// 1. A flow sequence:
+//
+// [item 1, item 2, item 3]
+//
+// Tokens:
+//
+// STREAM-START(utf-8)
+// FLOW-SEQUENCE-START
+// SCALAR("item 1",plain)
+// FLOW-ENTRY
+// SCALAR("item 2",plain)
+// FLOW-ENTRY
+// SCALAR("item 3",plain)
+// FLOW-SEQUENCE-END
+// STREAM-END
+//
+// 2. A flow mapping:
+//
+// {
+// a simple key: a value, # Note that the KEY token is produced.
+// ? a complex key: another value,
+// }
+//
+// Tokens:
+//
+// STREAM-START(utf-8)
+// FLOW-MAPPING-START
+// KEY
+// SCALAR("a simple key",plain)
+// VALUE
+// SCALAR("a value",plain)
+// FLOW-ENTRY
+// KEY
+// SCALAR("a complex key",plain)
+// VALUE
+// SCALAR("another value",plain)
+// FLOW-ENTRY
+// FLOW-MAPPING-END
+// STREAM-END
+//
+// A simple key is a key which is not denoted by the '?' indicator. Note that
+// the Scanner still produce the KEY token whenever it encounters a simple key.
+//
+// For scanning block collections, the following tokens are used (note that we
+// repeat KEY and VALUE here):
+//
+// BLOCK-SEQUENCE-START
+// BLOCK-MAPPING-START
+// BLOCK-END
+// BLOCK-ENTRY
+// KEY
+// VALUE
+//
+// The tokens BLOCK-SEQUENCE-START and BLOCK-MAPPING-START denote indentation
+// increase that precedes a block collection (cf. the INDENT token in Python).
+// The token BLOCK-END denote indentation decrease that ends a block collection
+// (cf. the DEDENT token in Python). However YAML has some syntax pecularities
+// that makes detections of these tokens more complex.
+//
+// The tokens BLOCK-ENTRY, KEY, and VALUE are used to represent the indicators
+// '-', '?', and ':' correspondingly.
+//
+// The following examples show how the tokens BLOCK-SEQUENCE-START,
+// BLOCK-MAPPING-START, and BLOCK-END are emitted by the Scanner:
+//
+// 1. Block sequences:
+//
+// - item 1
+// - item 2
+// -
+// - item 3.1
+// - item 3.2
+// -
+// key 1: value 1
+// key 2: value 2
+//
+// Tokens:
+//
+// STREAM-START(utf-8)
+// BLOCK-SEQUENCE-START
+// BLOCK-ENTRY
+// SCALAR("item 1",plain)
+// BLOCK-ENTRY
+// SCALAR("item 2",plain)
+// BLOCK-ENTRY
+// BLOCK-SEQUENCE-START
+// BLOCK-ENTRY
+// SCALAR("item 3.1",plain)
+// BLOCK-ENTRY
+// SCALAR("item 3.2",plain)
+// BLOCK-END
+// BLOCK-ENTRY
+// BLOCK-MAPPING-START
+// KEY
+// SCALAR("key 1",plain)
+// VALUE
+// SCALAR("value 1",plain)
+// KEY
+// SCALAR("key 2",plain)
+// VALUE
+// SCALAR("value 2",plain)
+// BLOCK-END
+// BLOCK-END
+// STREAM-END
+//
+// 2. Block mappings:
+//
+// a simple key: a value # The KEY token is produced here.
+// ? a complex key
+// : another value
+// a mapping:
+// key 1: value 1
+// key 2: value 2
+// a sequence:
+// - item 1
+// - item 2
+//
+// Tokens:
+//
+// STREAM-START(utf-8)
+// BLOCK-MAPPING-START
+// KEY
+// SCALAR("a simple key",plain)
+// VALUE
+// SCALAR("a value",plain)
+// KEY
+// SCALAR("a complex key",plain)
+// VALUE
+// SCALAR("another value",plain)
+// KEY
+// SCALAR("a mapping",plain)
+// BLOCK-MAPPING-START
+// KEY
+// SCALAR("key 1",plain)
+// VALUE
+// SCALAR("value 1",plain)
+// KEY
+// SCALAR("key 2",plain)
+// VALUE
+// SCALAR("value 2",plain)
+// BLOCK-END
+// KEY
+// SCALAR("a sequence",plain)
+// VALUE
+// BLOCK-SEQUENCE-START
+// BLOCK-ENTRY
+// SCALAR("item 1",plain)
+// BLOCK-ENTRY
+// SCALAR("item 2",plain)
+// BLOCK-END
+// BLOCK-END
+// STREAM-END
+//
+// YAML does not always require to start a new block collection from a new
+// line. If the current line contains only '-', '?', and ':' indicators, a new
+// block collection may start at the current line. The following examples
+// illustrate this case:
+//
+// 1. Collections in a sequence:
+//
+// - - item 1
+// - item 2
+// - key 1: value 1
+// key 2: value 2
+// - ? complex key
+// : complex value
+//
+// Tokens:
+//
+// STREAM-START(utf-8)
+// BLOCK-SEQUENCE-START
+// BLOCK-ENTRY
+// BLOCK-SEQUENCE-START
+// BLOCK-ENTRY
+// SCALAR("item 1",plain)
+// BLOCK-ENTRY
+// SCALAR("item 2",plain)
+// BLOCK-END
+// BLOCK-ENTRY
+// BLOCK-MAPPING-START
+// KEY
+// SCALAR("key 1",plain)
+// VALUE
+// SCALAR("value 1",plain)
+// KEY
+// SCALAR("key 2",plain)
+// VALUE
+// SCALAR("value 2",plain)
+// BLOCK-END
+// BLOCK-ENTRY
+// BLOCK-MAPPING-START
+// KEY
+// SCALAR("complex key")
+// VALUE
+// SCALAR("complex value")
+// BLOCK-END
+// BLOCK-END
+// STREAM-END
+//
+// 2. Collections in a mapping:
+//
+// ? a sequence
+// : - item 1
+// - item 2
+// ? a mapping
+// : key 1: value 1
+// key 2: value 2
+//
+// Tokens:
+//
+// STREAM-START(utf-8)
+// BLOCK-MAPPING-START
+// KEY
+// SCALAR("a sequence",plain)
+// VALUE
+// BLOCK-SEQUENCE-START
+// BLOCK-ENTRY
+// SCALAR("item 1",plain)
+// BLOCK-ENTRY
+// SCALAR("item 2",plain)
+// BLOCK-END
+// KEY
+// SCALAR("a mapping",plain)
+// VALUE
+// BLOCK-MAPPING-START
+// KEY
+// SCALAR("key 1",plain)
+// VALUE
+// SCALAR("value 1",plain)
+// KEY
+// SCALAR("key 2",plain)
+// VALUE
+// SCALAR("value 2",plain)
+// BLOCK-END
+// BLOCK-END
+// STREAM-END
+//
+// YAML also permits non-indented sequences if they are included into a block
+// mapping. In this case, the token BLOCK-SEQUENCE-START is not produced:
+//
+// key:
+// - item 1 # BLOCK-SEQUENCE-START is NOT produced here.
+// - item 2
+//
+// Tokens:
+//
+// STREAM-START(utf-8)
+// BLOCK-MAPPING-START
+// KEY
+// SCALAR("key",plain)
+// VALUE
+// BLOCK-ENTRY
+// SCALAR("item 1",plain)
+// BLOCK-ENTRY
+// SCALAR("item 2",plain)
+// BLOCK-END
+//
+
+// Ensure that the buffer contains the required number of characters.
+// Return true on success, false on failure (reader error or memory error).
+func cache(parser *yaml_parser_t, length int) bool {
+ // [Go] This was inlined: !cache(A, B) -> unread < B && !update(A, B)
+ return parser.unread >= length || yaml_parser_update_buffer(parser, length)
+}
+
+// Advance the buffer pointer.
+func skip(parser *yaml_parser_t) {
+ parser.mark.index++
+ parser.mark.column++
+ parser.unread--
+ parser.buffer_pos += width(parser.buffer[parser.buffer_pos])
+}
+
+func skip_line(parser *yaml_parser_t) {
+ if is_crlf(parser.buffer, parser.buffer_pos) {
+ parser.mark.index += 2
+ parser.mark.column = 0
+ parser.mark.line++
+ parser.unread -= 2
+ parser.buffer_pos += 2
+ } else if is_break(parser.buffer, parser.buffer_pos) {
+ parser.mark.index++
+ parser.mark.column = 0
+ parser.mark.line++
+ parser.unread--
+ parser.buffer_pos += width(parser.buffer[parser.buffer_pos])
+ }
+}
+
+// Copy a character to a string buffer and advance pointers.
+func read(parser *yaml_parser_t, s []byte) []byte {
+ w := width(parser.buffer[parser.buffer_pos])
+ if w == 0 {
+ panic("invalid character sequence")
+ }
+ if len(s) == 0 {
+ s = make([]byte, 0, 32)
+ }
+ if w == 1 && len(s)+w <= cap(s) {
+ s = s[:len(s)+1]
+ s[len(s)-1] = parser.buffer[parser.buffer_pos]
+ parser.buffer_pos++
+ } else {
+ s = append(s, parser.buffer[parser.buffer_pos:parser.buffer_pos+w]...)
+ parser.buffer_pos += w
+ }
+ parser.mark.index++
+ parser.mark.column++
+ parser.unread--
+ return s
+}
+
+// Copy a line break character to a string buffer and advance pointers.
+func read_line(parser *yaml_parser_t, s []byte) []byte {
+ buf := parser.buffer
+ pos := parser.buffer_pos
+ switch {
+ case buf[pos] == '\r' && buf[pos+1] == '\n':
+ // CR LF . LF
+ s = append(s, '\n')
+ parser.buffer_pos += 2
+ parser.mark.index++
+ parser.unread--
+ case buf[pos] == '\r' || buf[pos] == '\n':
+ // CR|LF . LF
+ s = append(s, '\n')
+ parser.buffer_pos += 1
+ case buf[pos] == '\xC2' && buf[pos+1] == '\x85':
+ // NEL . LF
+ s = append(s, '\n')
+ parser.buffer_pos += 2
+ case buf[pos] == '\xE2' && buf[pos+1] == '\x80' && (buf[pos+2] == '\xA8' || buf[pos+2] == '\xA9'):
+ // LS|PS . LS|PS
+ s = append(s, buf[parser.buffer_pos:pos+3]...)
+ parser.buffer_pos += 3
+ default:
+ return s
+ }
+ parser.mark.index++
+ parser.mark.column = 0
+ parser.mark.line++
+ parser.unread--
+ return s
+}
+
+// Get the next token.
+func yaml_parser_scan(parser *yaml_parser_t, token *yaml_token_t) bool {
+ // Erase the token object.
+ *token = yaml_token_t{} // [Go] Is this necessary?
+
+ // No tokens after STREAM-END or error.
+ if parser.stream_end_produced || parser.error != yaml_NO_ERROR {
+ return true
+ }
+
+ // Ensure that the tokens queue contains enough tokens.
+ if !parser.token_available {
+ if !yaml_parser_fetch_more_tokens(parser) {
+ return false
+ }
+ }
+
+ // Fetch the next token from the queue.
+ *token = parser.tokens[parser.tokens_head]
+ parser.tokens_head++
+ parser.tokens_parsed++
+ parser.token_available = false
+
+ if token.typ == yaml_STREAM_END_TOKEN {
+ parser.stream_end_produced = true
+ }
+ return true
+}
+
+// Set the scanner error and return false.
+func yaml_parser_set_scanner_error(parser *yaml_parser_t, context string, context_mark yaml_mark_t, problem string) bool {
+ parser.error = yaml_SCANNER_ERROR
+ parser.context = context
+ parser.context_mark = context_mark
+ parser.problem = problem
+ parser.problem_mark = parser.mark
+ return false
+}
+
+func yaml_parser_set_scanner_tag_error(parser *yaml_parser_t, directive bool, context_mark yaml_mark_t, problem string) bool {
+ context := "while parsing a tag"
+ if directive {
+ context = "while parsing a %TAG directive"
+ }
+ return yaml_parser_set_scanner_error(parser, context, context_mark, "did not find URI escaped octet")
+}
+
+func trace(args ...interface{}) func() {
+ pargs := append([]interface{}{"+++"}, args...)
+ fmt.Println(pargs...)
+ pargs = append([]interface{}{"---"}, args...)
+ return func() { fmt.Println(pargs...) }
+}
+
+// Ensure that the tokens queue contains at least one token which can be
+// returned to the Parser.
+func yaml_parser_fetch_more_tokens(parser *yaml_parser_t) bool {
+ // While we need more tokens to fetch, do it.
+ for {
+ // Check if we really need to fetch more tokens.
+ need_more_tokens := false
+
+ if parser.tokens_head == len(parser.tokens) {
+ // Queue is empty.
+ need_more_tokens = true
+ } else {
+ // Check if any potential simple key may occupy the head position.
+ if !yaml_parser_stale_simple_keys(parser) {
+ return false
+ }
+
+ for i := range parser.simple_keys {
+ simple_key := &parser.simple_keys[i]
+ if simple_key.possible && simple_key.token_number == parser.tokens_parsed {
+ need_more_tokens = true
+ break
+ }
+ }
+ }
+
+ // We are finished.
+ if !need_more_tokens {
+ break
+ }
+ // Fetch the next token.
+ if !yaml_parser_fetch_next_token(parser) {
+ return false
+ }
+ }
+
+ parser.token_available = true
+ return true
+}
+
+// The dispatcher for token fetchers.
+func yaml_parser_fetch_next_token(parser *yaml_parser_t) bool {
+ // Ensure that the buffer is initialized.
+ if parser.unread < 1 && !yaml_parser_update_buffer(parser, 1) {
+ return false
+ }
+
+ // Check if we just started scanning. Fetch STREAM-START then.
+ if !parser.stream_start_produced {
+ return yaml_parser_fetch_stream_start(parser)
+ }
+
+ // Eat whitespaces and comments until we reach the next token.
+ if !yaml_parser_scan_to_next_token(parser) {
+ return false
+ }
+
+ // Remove obsolete potential simple keys.
+ if !yaml_parser_stale_simple_keys(parser) {
+ return false
+ }
+
+ // Check the indentation level against the current column.
+ if !yaml_parser_unroll_indent(parser, parser.mark.column) {
+ return false
+ }
+
+ // Ensure that the buffer contains at least 4 characters. 4 is the length
+ // of the longest indicators ('--- ' and '... ').
+ if parser.unread < 4 && !yaml_parser_update_buffer(parser, 4) {
+ return false
+ }
+
+ // Is it the end of the stream?
+ if is_z(parser.buffer, parser.buffer_pos) {
+ return yaml_parser_fetch_stream_end(parser)
+ }
+
+ // Is it a directive?
+ if parser.mark.column == 0 && parser.buffer[parser.buffer_pos] == '%' {
+ return yaml_parser_fetch_directive(parser)
+ }
+
+ buf := parser.buffer
+ pos := parser.buffer_pos
+
+ // Is it the document start indicator?
+ if parser.mark.column == 0 && buf[pos] == '-' && buf[pos+1] == '-' && buf[pos+2] == '-' && is_blankz(buf, pos+3) {
+ return yaml_parser_fetch_document_indicator(parser, yaml_DOCUMENT_START_TOKEN)
+ }
+
+ // Is it the document end indicator?
+ if parser.mark.column == 0 && buf[pos] == '.' && buf[pos+1] == '.' && buf[pos+2] == '.' && is_blankz(buf, pos+3) {
+ return yaml_parser_fetch_document_indicator(parser, yaml_DOCUMENT_END_TOKEN)
+ }
+
+ // Is it the flow sequence start indicator?
+ if buf[pos] == '[' {
+ return yaml_parser_fetch_flow_collection_start(parser, yaml_FLOW_SEQUENCE_START_TOKEN)
+ }
+
+ // Is it the flow mapping start indicator?
+ if parser.buffer[parser.buffer_pos] == '{' {
+ return yaml_parser_fetch_flow_collection_start(parser, yaml_FLOW_MAPPING_START_TOKEN)
+ }
+
+ // Is it the flow sequence end indicator?
+ if parser.buffer[parser.buffer_pos] == ']' {
+ return yaml_parser_fetch_flow_collection_end(parser,
+ yaml_FLOW_SEQUENCE_END_TOKEN)
+ }
+
+ // Is it the flow mapping end indicator?
+ if parser.buffer[parser.buffer_pos] == '}' {
+ return yaml_parser_fetch_flow_collection_end(parser,
+ yaml_FLOW_MAPPING_END_TOKEN)
+ }
+
+ // Is it the flow entry indicator?
+ if parser.buffer[parser.buffer_pos] == ',' {
+ return yaml_parser_fetch_flow_entry(parser)
+ }
+
+ // Is it the block entry indicator?
+ if parser.buffer[parser.buffer_pos] == '-' && is_blankz(parser.buffer, parser.buffer_pos+1) {
+ return yaml_parser_fetch_block_entry(parser)
+ }
+
+ // Is it the key indicator?
+ if parser.buffer[parser.buffer_pos] == '?' && (parser.flow_level > 0 || is_blankz(parser.buffer, parser.buffer_pos+1)) {
+ return yaml_parser_fetch_key(parser)
+ }
+
+ // Is it the value indicator?
+ if parser.buffer[parser.buffer_pos] == ':' && (parser.flow_level > 0 || is_blankz(parser.buffer, parser.buffer_pos+1)) {
+ return yaml_parser_fetch_value(parser)
+ }
+
+ // Is it an alias?
+ if parser.buffer[parser.buffer_pos] == '*' {
+ return yaml_parser_fetch_anchor(parser, yaml_ALIAS_TOKEN)
+ }
+
+ // Is it an anchor?
+ if parser.buffer[parser.buffer_pos] == '&' {
+ return yaml_parser_fetch_anchor(parser, yaml_ANCHOR_TOKEN)
+ }
+
+ // Is it a tag?
+ if parser.buffer[parser.buffer_pos] == '!' {
+ return yaml_parser_fetch_tag(parser)
+ }
+
+ // Is it a literal scalar?
+ if parser.buffer[parser.buffer_pos] == '|' && parser.flow_level == 0 {
+ return yaml_parser_fetch_block_scalar(parser, true)
+ }
+
+ // Is it a folded scalar?
+ if parser.buffer[parser.buffer_pos] == '>' && parser.flow_level == 0 {
+ return yaml_parser_fetch_block_scalar(parser, false)
+ }
+
+ // Is it a single-quoted scalar?
+ if parser.buffer[parser.buffer_pos] == '\'' {
+ return yaml_parser_fetch_flow_scalar(parser, true)
+ }
+
+ // Is it a double-quoted scalar?
+ if parser.buffer[parser.buffer_pos] == '"' {
+ return yaml_parser_fetch_flow_scalar(parser, false)
+ }
+
+ // Is it a plain scalar?
+ //
+ // A plain scalar may start with any non-blank characters except
+ //
+ // '-', '?', ':', ',', '[', ']', '{', '}',
+ // '#', '&', '*', '!', '|', '>', '\'', '\"',
+ // '%', '@', '`'.
+ //
+ // In the block context (and, for the '-' indicator, in the flow context
+ // too), it may also start with the characters
+ //
+ // '-', '?', ':'
+ //
+ // if it is followed by a non-space character.
+ //
+ // The last rule is more restrictive than the specification requires.
+ // [Go] Make this logic more reasonable.
+ //switch parser.buffer[parser.buffer_pos] {
+ //case '-', '?', ':', ',', '?', '-', ',', ':', ']', '[', '}', '{', '&', '#', '!', '*', '>', '|', '"', '\'', '@', '%', '-', '`':
+ //}
+ if !(is_blankz(parser.buffer, parser.buffer_pos) || parser.buffer[parser.buffer_pos] == '-' ||
+ parser.buffer[parser.buffer_pos] == '?' || parser.buffer[parser.buffer_pos] == ':' ||
+ parser.buffer[parser.buffer_pos] == ',' || parser.buffer[parser.buffer_pos] == '[' ||
+ parser.buffer[parser.buffer_pos] == ']' || parser.buffer[parser.buffer_pos] == '{' ||
+ parser.buffer[parser.buffer_pos] == '}' || parser.buffer[parser.buffer_pos] == '#' ||
+ parser.buffer[parser.buffer_pos] == '&' || parser.buffer[parser.buffer_pos] == '*' ||
+ parser.buffer[parser.buffer_pos] == '!' || parser.buffer[parser.buffer_pos] == '|' ||
+ parser.buffer[parser.buffer_pos] == '>' || parser.buffer[parser.buffer_pos] == '\'' ||
+ parser.buffer[parser.buffer_pos] == '"' || parser.buffer[parser.buffer_pos] == '%' ||
+ parser.buffer[parser.buffer_pos] == '@' || parser.buffer[parser.buffer_pos] == '`') ||
+ (parser.buffer[parser.buffer_pos] == '-' && !is_blank(parser.buffer, parser.buffer_pos+1)) ||
+ (parser.flow_level == 0 &&
+ (parser.buffer[parser.buffer_pos] == '?' || parser.buffer[parser.buffer_pos] == ':') &&
+ !is_blankz(parser.buffer, parser.buffer_pos+1)) {
+ return yaml_parser_fetch_plain_scalar(parser)
+ }
+
+ // If we don't determine the token type so far, it is an error.
+ return yaml_parser_set_scanner_error(parser,
+ "while scanning for the next token", parser.mark,
+ "found character that cannot start any token")
+}
+
+// Check the list of potential simple keys and remove the positions that
+// cannot contain simple keys anymore.
+func yaml_parser_stale_simple_keys(parser *yaml_parser_t) bool {
+ // Check for a potential simple key for each flow level.
+ for i := range parser.simple_keys {
+ simple_key := &parser.simple_keys[i]
+
+ // The specification requires that a simple key
+ //
+ // - is limited to a single line,
+ // - is shorter than 1024 characters.
+ if simple_key.possible && (simple_key.mark.line < parser.mark.line || simple_key.mark.index+1024 < parser.mark.index) {
+
+ // Check if the potential simple key to be removed is required.
+ if simple_key.required {
+ return yaml_parser_set_scanner_error(parser,
+ "while scanning a simple key", simple_key.mark,
+ "could not find expected ':'")
+ }
+ simple_key.possible = false
+ }
+ }
+ return true
+}
+
+// Check if a simple key may start at the current position and add it if
+// needed.
+func yaml_parser_save_simple_key(parser *yaml_parser_t) bool {
+ // A simple key is required at the current position if the scanner is in
+ // the block context and the current column coincides with the indentation
+ // level.
+
+ required := parser.flow_level == 0 && parser.indent == parser.mark.column
+
+ // A simple key is required only when it is the first token in the current
+ // line. Therefore it is always allowed. But we add a check anyway.
+ if required && !parser.simple_key_allowed {
+ panic("should not happen")
+ }
+
+ //
+ // If the current position may start a simple key, save it.
+ //
+ if parser.simple_key_allowed {
+ simple_key := yaml_simple_key_t{
+ possible: true,
+ required: required,
+ token_number: parser.tokens_parsed + (len(parser.tokens) - parser.tokens_head),
+ }
+ simple_key.mark = parser.mark
+
+ if !yaml_parser_remove_simple_key(parser) {
+ return false
+ }
+ parser.simple_keys[len(parser.simple_keys)-1] = simple_key
+ }
+ return true
+}
+
+// Remove a potential simple key at the current flow level.
+func yaml_parser_remove_simple_key(parser *yaml_parser_t) bool {
+ i := len(parser.simple_keys) - 1
+ if parser.simple_keys[i].possible {
+ // If the key is required, it is an error.
+ if parser.simple_keys[i].required {
+ return yaml_parser_set_scanner_error(parser,
+ "while scanning a simple key", parser.simple_keys[i].mark,
+ "could not find expected ':'")
+ }
+ }
+ // Remove the key from the stack.
+ parser.simple_keys[i].possible = false
+ return true
+}
+
+// Increase the flow level and resize the simple key list if needed.
+func yaml_parser_increase_flow_level(parser *yaml_parser_t) bool {
+ // Reset the simple key on the next level.
+ parser.simple_keys = append(parser.simple_keys, yaml_simple_key_t{})
+
+ // Increase the flow level.
+ parser.flow_level++
+ return true
+}
+
+// Decrease the flow level.
+func yaml_parser_decrease_flow_level(parser *yaml_parser_t) bool {
+ if parser.flow_level > 0 {
+ parser.flow_level--
+ parser.simple_keys = parser.simple_keys[:len(parser.simple_keys)-1]
+ }
+ return true
+}
+
+// Push the current indentation level to the stack and set the new level
+// the current column is greater than the indentation level. In this case,
+// append or insert the specified token into the token queue.
+func yaml_parser_roll_indent(parser *yaml_parser_t, column, number int, typ yaml_token_type_t, mark yaml_mark_t) bool {
+ // In the flow context, do nothing.
+ if parser.flow_level > 0 {
+ return true
+ }
+
+ if parser.indent < column {
+ // Push the current indentation level to the stack and set the new
+ // indentation level.
+ parser.indents = append(parser.indents, parser.indent)
+ parser.indent = column
+
+ // Create a token and insert it into the queue.
+ token := yaml_token_t{
+ typ: typ,
+ start_mark: mark,
+ end_mark: mark,
+ }
+ if number > -1 {
+ number -= parser.tokens_parsed
+ }
+ yaml_insert_token(parser, number, &token)
+ }
+ return true
+}
+
+// Pop indentation levels from the indents stack until the current level
+// becomes less or equal to the column. For each intendation level, append
+// the BLOCK-END token.
+func yaml_parser_unroll_indent(parser *yaml_parser_t, column int) bool {
+ // In the flow context, do nothing.
+ if parser.flow_level > 0 {
+ return true
+ }
+
+ // Loop through the intendation levels in the stack.
+ for parser.indent > column {
+ // Create a token and append it to the queue.
+ token := yaml_token_t{
+ typ: yaml_BLOCK_END_TOKEN,
+ start_mark: parser.mark,
+ end_mark: parser.mark,
+ }
+ yaml_insert_token(parser, -1, &token)
+
+ // Pop the indentation level.
+ parser.indent = parser.indents[len(parser.indents)-1]
+ parser.indents = parser.indents[:len(parser.indents)-1]
+ }
+ return true
+}
+
+// Initialize the scanner and produce the STREAM-START token.
+func yaml_parser_fetch_stream_start(parser *yaml_parser_t) bool {
+
+ // Set the initial indentation.
+ parser.indent = -1
+
+ // Initialize the simple key stack.
+ parser.simple_keys = append(parser.simple_keys, yaml_simple_key_t{})
+
+ // A simple key is allowed at the beginning of the stream.
+ parser.simple_key_allowed = true
+
+ // We have started.
+ parser.stream_start_produced = true
+
+ // Create the STREAM-START token and append it to the queue.
+ token := yaml_token_t{
+ typ: yaml_STREAM_START_TOKEN,
+ start_mark: parser.mark,
+ end_mark: parser.mark,
+ encoding: parser.encoding,
+ }
+ yaml_insert_token(parser, -1, &token)
+ return true
+}
+
+// Produce the STREAM-END token and shut down the scanner.
+func yaml_parser_fetch_stream_end(parser *yaml_parser_t) bool {
+
+ // Force new line.
+ if parser.mark.column != 0 {
+ parser.mark.column = 0
+ parser.mark.line++
+ }
+
+ // Reset the indentation level.
+ if !yaml_parser_unroll_indent(parser, -1) {
+ return false
+ }
+
+ // Reset simple keys.
+ if !yaml_parser_remove_simple_key(parser) {
+ return false
+ }
+
+ parser.simple_key_allowed = false
+
+ // Create the STREAM-END token and append it to the queue.
+ token := yaml_token_t{
+ typ: yaml_STREAM_END_TOKEN,
+ start_mark: parser.mark,
+ end_mark: parser.mark,
+ }
+ yaml_insert_token(parser, -1, &token)
+ return true
+}
+
+// Produce a VERSION-DIRECTIVE or TAG-DIRECTIVE token.
+func yaml_parser_fetch_directive(parser *yaml_parser_t) bool {
+ // Reset the indentation level.
+ if !yaml_parser_unroll_indent(parser, -1) {
+ return false
+ }
+
+ // Reset simple keys.
+ if !yaml_parser_remove_simple_key(parser) {
+ return false
+ }
+
+ parser.simple_key_allowed = false
+
+ // Create the YAML-DIRECTIVE or TAG-DIRECTIVE token.
+ token := yaml_token_t{}
+ if !yaml_parser_scan_directive(parser, &token) {
+ return false
+ }
+ // Append the token to the queue.
+ yaml_insert_token(parser, -1, &token)
+ return true
+}
+
+// Produce the DOCUMENT-START or DOCUMENT-END token.
+func yaml_parser_fetch_document_indicator(parser *yaml_parser_t, typ yaml_token_type_t) bool {
+ // Reset the indentation level.
+ if !yaml_parser_unroll_indent(parser, -1) {
+ return false
+ }
+
+ // Reset simple keys.
+ if !yaml_parser_remove_simple_key(parser) {
+ return false
+ }
+
+ parser.simple_key_allowed = false
+
+ // Consume the token.
+ start_mark := parser.mark
+
+ skip(parser)
+ skip(parser)
+ skip(parser)
+
+ end_mark := parser.mark
+
+ // Create the DOCUMENT-START or DOCUMENT-END token.
+ token := yaml_token_t{
+ typ: typ,
+ start_mark: start_mark,
+ end_mark: end_mark,
+ }
+ // Append the token to the queue.
+ yaml_insert_token(parser, -1, &token)
+ return true
+}
+
+// Produce the FLOW-SEQUENCE-START or FLOW-MAPPING-START token.
+func yaml_parser_fetch_flow_collection_start(parser *yaml_parser_t, typ yaml_token_type_t) bool {
+ // The indicators '[' and '{' may start a simple key.
+ if !yaml_parser_save_simple_key(parser) {
+ return false
+ }
+
+ // Increase the flow level.
+ if !yaml_parser_increase_flow_level(parser) {
+ return false
+ }
+
+ // A simple key may follow the indicators '[' and '{'.
+ parser.simple_key_allowed = true
+
+ // Consume the token.
+ start_mark := parser.mark
+ skip(parser)
+ end_mark := parser.mark
+
+ // Create the FLOW-SEQUENCE-START of FLOW-MAPPING-START token.
+ token := yaml_token_t{
+ typ: typ,
+ start_mark: start_mark,
+ end_mark: end_mark,
+ }
+ // Append the token to the queue.
+ yaml_insert_token(parser, -1, &token)
+ return true
+}
+
+// Produce the FLOW-SEQUENCE-END or FLOW-MAPPING-END token.
+func yaml_parser_fetch_flow_collection_end(parser *yaml_parser_t, typ yaml_token_type_t) bool {
+ // Reset any potential simple key on the current flow level.
+ if !yaml_parser_remove_simple_key(parser) {
+ return false
+ }
+
+ // Decrease the flow level.
+ if !yaml_parser_decrease_flow_level(parser) {
+ return false
+ }
+
+ // No simple keys after the indicators ']' and '}'.
+ parser.simple_key_allowed = false
+
+ // Consume the token.
+
+ start_mark := parser.mark
+ skip(parser)
+ end_mark := parser.mark
+
+ // Create the FLOW-SEQUENCE-END of FLOW-MAPPING-END token.
+ token := yaml_token_t{
+ typ: typ,
+ start_mark: start_mark,
+ end_mark: end_mark,
+ }
+ // Append the token to the queue.
+ yaml_insert_token(parser, -1, &token)
+ return true
+}
+
+// Produce the FLOW-ENTRY token.
+func yaml_parser_fetch_flow_entry(parser *yaml_parser_t) bool {
+ // Reset any potential simple keys on the current flow level.
+ if !yaml_parser_remove_simple_key(parser) {
+ return false
+ }
+
+ // Simple keys are allowed after ','.
+ parser.simple_key_allowed = true
+
+ // Consume the token.
+ start_mark := parser.mark
+ skip(parser)
+ end_mark := parser.mark
+
+ // Create the FLOW-ENTRY token and append it to the queue.
+ token := yaml_token_t{
+ typ: yaml_FLOW_ENTRY_TOKEN,
+ start_mark: start_mark,
+ end_mark: end_mark,
+ }
+ yaml_insert_token(parser, -1, &token)
+ return true
+}
+
+// Produce the BLOCK-ENTRY token.
+func yaml_parser_fetch_block_entry(parser *yaml_parser_t) bool {
+ // Check if the scanner is in the block context.
+ if parser.flow_level == 0 {
+ // Check if we are allowed to start a new entry.
+ if !parser.simple_key_allowed {
+ return yaml_parser_set_scanner_error(parser, "", parser.mark,
+ "block sequence entries are not allowed in this context")
+ }
+ // Add the BLOCK-SEQUENCE-START token if needed.
+ if !yaml_parser_roll_indent(parser, parser.mark.column, -1, yaml_BLOCK_SEQUENCE_START_TOKEN, parser.mark) {
+ return false
+ }
+ } else {
+ // It is an error for the '-' indicator to occur in the flow context,
+ // but we let the Parser detect and report about it because the Parser
+ // is able to point to the context.
+ }
+
+ // Reset any potential simple keys on the current flow level.
+ if !yaml_parser_remove_simple_key(parser) {
+ return false
+ }
+
+ // Simple keys are allowed after '-'.
+ parser.simple_key_allowed = true
+
+ // Consume the token.
+ start_mark := parser.mark
+ skip(parser)
+ end_mark := parser.mark
+
+ // Create the BLOCK-ENTRY token and append it to the queue.
+ token := yaml_token_t{
+ typ: yaml_BLOCK_ENTRY_TOKEN,
+ start_mark: start_mark,
+ end_mark: end_mark,
+ }
+ yaml_insert_token(parser, -1, &token)
+ return true
+}
+
+// Produce the KEY token.
+func yaml_parser_fetch_key(parser *yaml_parser_t) bool {
+
+ // In the block context, additional checks are required.
+ if parser.flow_level == 0 {
+ // Check if we are allowed to start a new key (not nessesary simple).
+ if !parser.simple_key_allowed {
+ return yaml_parser_set_scanner_error(parser, "", parser.mark,
+ "mapping keys are not allowed in this context")
+ }
+ // Add the BLOCK-MAPPING-START token if needed.
+ if !yaml_parser_roll_indent(parser, parser.mark.column, -1, yaml_BLOCK_MAPPING_START_TOKEN, parser.mark) {
+ return false
+ }
+ }
+
+ // Reset any potential simple keys on the current flow level.
+ if !yaml_parser_remove_simple_key(parser) {
+ return false
+ }
+
+ // Simple keys are allowed after '?' in the block context.
+ parser.simple_key_allowed = parser.flow_level == 0
+
+ // Consume the token.
+ start_mark := parser.mark
+ skip(parser)
+ end_mark := parser.mark
+
+ // Create the KEY token and append it to the queue.
+ token := yaml_token_t{
+ typ: yaml_KEY_TOKEN,
+ start_mark: start_mark,
+ end_mark: end_mark,
+ }
+ yaml_insert_token(parser, -1, &token)
+ return true
+}
+
+// Produce the VALUE token.
+func yaml_parser_fetch_value(parser *yaml_parser_t) bool {
+
+ simple_key := &parser.simple_keys[len(parser.simple_keys)-1]
+
+ // Have we found a simple key?
+ if simple_key.possible {
+ // Create the KEY token and insert it into the queue.
+ token := yaml_token_t{
+ typ: yaml_KEY_TOKEN,
+ start_mark: simple_key.mark,
+ end_mark: simple_key.mark,
+ }
+ yaml_insert_token(parser, simple_key.token_number-parser.tokens_parsed, &token)
+
+ // In the block context, we may need to add the BLOCK-MAPPING-START token.
+ if !yaml_parser_roll_indent(parser, simple_key.mark.column,
+ simple_key.token_number,
+ yaml_BLOCK_MAPPING_START_TOKEN, simple_key.mark) {
+ return false
+ }
+
+ // Remove the simple key.
+ simple_key.possible = false
+
+ // A simple key cannot follow another simple key.
+ parser.simple_key_allowed = false
+
+ } else {
+ // The ':' indicator follows a complex key.
+
+ // In the block context, extra checks are required.
+ if parser.flow_level == 0 {
+
+ // Check if we are allowed to start a complex value.
+ if !parser.simple_key_allowed {
+ return yaml_parser_set_scanner_error(parser, "", parser.mark,
+ "mapping values are not allowed in this context")
+ }
+
+ // Add the BLOCK-MAPPING-START token if needed.
+ if !yaml_parser_roll_indent(parser, parser.mark.column, -1, yaml_BLOCK_MAPPING_START_TOKEN, parser.mark) {
+ return false
+ }
+ }
+
+ // Simple keys after ':' are allowed in the block context.
+ parser.simple_key_allowed = parser.flow_level == 0
+ }
+
+ // Consume the token.
+ start_mark := parser.mark
+ skip(parser)
+ end_mark := parser.mark
+
+ // Create the VALUE token and append it to the queue.
+ token := yaml_token_t{
+ typ: yaml_VALUE_TOKEN,
+ start_mark: start_mark,
+ end_mark: end_mark,
+ }
+ yaml_insert_token(parser, -1, &token)
+ return true
+}
+
+// Produce the ALIAS or ANCHOR token.
+func yaml_parser_fetch_anchor(parser *yaml_parser_t, typ yaml_token_type_t) bool {
+ // An anchor or an alias could be a simple key.
+ if !yaml_parser_save_simple_key(parser) {
+ return false
+ }
+
+ // A simple key cannot follow an anchor or an alias.
+ parser.simple_key_allowed = false
+
+ // Create the ALIAS or ANCHOR token and append it to the queue.
+ var token yaml_token_t
+ if !yaml_parser_scan_anchor(parser, &token, typ) {
+ return false
+ }
+ yaml_insert_token(parser, -1, &token)
+ return true
+}
+
+// Produce the TAG token.
+func yaml_parser_fetch_tag(parser *yaml_parser_t) bool {
+ // A tag could be a simple key.
+ if !yaml_parser_save_simple_key(parser) {
+ return false
+ }
+
+ // A simple key cannot follow a tag.
+ parser.simple_key_allowed = false
+
+ // Create the TAG token and append it to the queue.
+ var token yaml_token_t
+ if !yaml_parser_scan_tag(parser, &token) {
+ return false
+ }
+ yaml_insert_token(parser, -1, &token)
+ return true
+}
+
+// Produce the SCALAR(...,literal) or SCALAR(...,folded) tokens.
+func yaml_parser_fetch_block_scalar(parser *yaml_parser_t, literal bool) bool {
+ // Remove any potential simple keys.
+ if !yaml_parser_remove_simple_key(parser) {
+ return false
+ }
+
+ // A simple key may follow a block scalar.
+ parser.simple_key_allowed = true
+
+ // Create the SCALAR token and append it to the queue.
+ var token yaml_token_t
+ if !yaml_parser_scan_block_scalar(parser, &token, literal) {
+ return false
+ }
+ yaml_insert_token(parser, -1, &token)
+ return true
+}
+
+// Produce the SCALAR(...,single-quoted) or SCALAR(...,double-quoted) tokens.
+func yaml_parser_fetch_flow_scalar(parser *yaml_parser_t, single bool) bool {
+ // A plain scalar could be a simple key.
+ if !yaml_parser_save_simple_key(parser) {
+ return false
+ }
+
+ // A simple key cannot follow a flow scalar.
+ parser.simple_key_allowed = false
+
+ // Create the SCALAR token and append it to the queue.
+ var token yaml_token_t
+ if !yaml_parser_scan_flow_scalar(parser, &token, single) {
+ return false
+ }
+ yaml_insert_token(parser, -1, &token)
+ return true
+}
+
+// Produce the SCALAR(...,plain) token.
+func yaml_parser_fetch_plain_scalar(parser *yaml_parser_t) bool {
+ // A plain scalar could be a simple key.
+ if !yaml_parser_save_simple_key(parser) {
+ return false
+ }
+
+ // A simple key cannot follow a flow scalar.
+ parser.simple_key_allowed = false
+
+ // Create the SCALAR token and append it to the queue.
+ var token yaml_token_t
+ if !yaml_parser_scan_plain_scalar(parser, &token) {
+ return false
+ }
+ yaml_insert_token(parser, -1, &token)
+ return true
+}
+
+// Eat whitespaces and comments until the next token is found.
+func yaml_parser_scan_to_next_token(parser *yaml_parser_t) bool {
+
+ // Until the next token is not found.
+ for {
+ // Allow the BOM mark to start a line.
+ if parser.unread < 1 && !yaml_parser_update_buffer(parser, 1) {
+ return false
+ }
+ if parser.mark.column == 0 && is_bom(parser.buffer, parser.buffer_pos) {
+ skip(parser)
+ }
+
+ // Eat whitespaces.
+ // Tabs are allowed:
+ // - in the flow context
+ // - in the block context, but not at the beginning of the line or
+ // after '-', '?', or ':' (complex value).
+ if parser.unread < 1 && !yaml_parser_update_buffer(parser, 1) {
+ return false
+ }
+
+ for parser.buffer[parser.buffer_pos] == ' ' || ((parser.flow_level > 0 || !parser.simple_key_allowed) && parser.buffer[parser.buffer_pos] == '\t') {
+ skip(parser)
+ if parser.unread < 1 && !yaml_parser_update_buffer(parser, 1) {
+ return false
+ }
+ }
+
+ // Eat a comment until a line break.
+ if parser.buffer[parser.buffer_pos] == '#' {
+ for !is_breakz(parser.buffer, parser.buffer_pos) {
+ skip(parser)
+ if parser.unread < 1 && !yaml_parser_update_buffer(parser, 1) {
+ return false
+ }
+ }
+ }
+
+ // If it is a line break, eat it.
+ if is_break(parser.buffer, parser.buffer_pos) {
+ if parser.unread < 2 && !yaml_parser_update_buffer(parser, 2) {
+ return false
+ }
+ skip_line(parser)
+
+ // In the block context, a new line may start a simple key.
+ if parser.flow_level == 0 {
+ parser.simple_key_allowed = true
+ }
+ } else {
+ break // We have found a token.
+ }
+ }
+
+ return true
+}
+
+// Scan a YAML-DIRECTIVE or TAG-DIRECTIVE token.
+//
+// Scope:
+// %YAML 1.1 # a comment \n
+// ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+// %TAG !yaml! tag:yaml.org,2002: \n
+// ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+//
+func yaml_parser_scan_directive(parser *yaml_parser_t, token *yaml_token_t) bool {
+ // Eat '%'.
+ start_mark := parser.mark
+ skip(parser)
+
+ // Scan the directive name.
+ var name []byte
+ if !yaml_parser_scan_directive_name(parser, start_mark, &name) {
+ return false
+ }
+
+ // Is it a YAML directive?
+ if bytes.Equal(name, []byte("YAML")) {
+ // Scan the VERSION directive value.
+ var major, minor int8
+ if !yaml_parser_scan_version_directive_value(parser, start_mark, &major, &minor) {
+ return false
+ }
+ end_mark := parser.mark
+
+ // Create a VERSION-DIRECTIVE token.
+ *token = yaml_token_t{
+ typ: yaml_VERSION_DIRECTIVE_TOKEN,
+ start_mark: start_mark,
+ end_mark: end_mark,
+ major: major,
+ minor: minor,
+ }
+
+ // Is it a TAG directive?
+ } else if bytes.Equal(name, []byte("TAG")) {
+ // Scan the TAG directive value.
+ var handle, prefix []byte
+ if !yaml_parser_scan_tag_directive_value(parser, start_mark, &handle, &prefix) {
+ return false
+ }
+ end_mark := parser.mark
+
+ // Create a TAG-DIRECTIVE token.
+ *token = yaml_token_t{
+ typ: yaml_TAG_DIRECTIVE_TOKEN,
+ start_mark: start_mark,
+ end_mark: end_mark,
+ value: handle,
+ prefix: prefix,
+ }
+
+ // Unknown directive.
+ } else {
+ yaml_parser_set_scanner_error(parser, "while scanning a directive",
+ start_mark, "found uknown directive name")
+ return false
+ }
+
+ // Eat the rest of the line including any comments.
+ if parser.unread < 1 && !yaml_parser_update_buffer(parser, 1) {
+ return false
+ }
+
+ for is_blank(parser.buffer, parser.buffer_pos) {
+ skip(parser)
+ if parser.unread < 1 && !yaml_parser_update_buffer(parser, 1) {
+ return false
+ }
+ }
+
+ if parser.buffer[parser.buffer_pos] == '#' {
+ for !is_breakz(parser.buffer, parser.buffer_pos) {
+ skip(parser)
+ if parser.unread < 1 && !yaml_parser_update_buffer(parser, 1) {
+ return false
+ }
+ }
+ }
+
+ // Check if we are at the end of the line.
+ if !is_breakz(parser.buffer, parser.buffer_pos) {
+ yaml_parser_set_scanner_error(parser, "while scanning a directive",
+ start_mark, "did not find expected comment or line break")
+ return false
+ }
+
+ // Eat a line break.
+ if is_break(parser.buffer, parser.buffer_pos) {
+ if parser.unread < 2 && !yaml_parser_update_buffer(parser, 2) {
+ return false
+ }
+ skip_line(parser)
+ }
+
+ return true
+}
+
+// Scan the directive name.
+//
+// Scope:
+// %YAML 1.1 # a comment \n
+// ^^^^
+// %TAG !yaml! tag:yaml.org,2002: \n
+// ^^^
+//
+func yaml_parser_scan_directive_name(parser *yaml_parser_t, start_mark yaml_mark_t, name *[]byte) bool {
+ // Consume the directive name.
+ if parser.unread < 1 && !yaml_parser_update_buffer(parser, 1) {
+ return false
+ }
+
+ var s []byte
+ for is_alpha(parser.buffer, parser.buffer_pos) {
+ s = read(parser, s)
+ if parser.unread < 1 && !yaml_parser_update_buffer(parser, 1) {
+ return false
+ }
+ }
+
+ // Check if the name is empty.
+ if len(s) == 0 {
+ yaml_parser_set_scanner_error(parser, "while scanning a directive",
+ start_mark, "could not find expected directive name")
+ return false
+ }
+
+ // Check for an blank character after the name.
+ if !is_blankz(parser.buffer, parser.buffer_pos) {
+ yaml_parser_set_scanner_error(parser, "while scanning a directive",
+ start_mark, "found unexpected non-alphabetical character")
+ return false
+ }
+ *name = s
+ return true
+}
+
+// Scan the value of VERSION-DIRECTIVE.
+//
+// Scope:
+// %YAML 1.1 # a comment \n
+// ^^^^^^
+func yaml_parser_scan_version_directive_value(parser *yaml_parser_t, start_mark yaml_mark_t, major, minor *int8) bool {
+ // Eat whitespaces.
+ if parser.unread < 1 && !yaml_parser_update_buffer(parser, 1) {
+ return false
+ }
+ for is_blank(parser.buffer, parser.buffer_pos) {
+ skip(parser)
+ if parser.unread < 1 && !yaml_parser_update_buffer(parser, 1) {
+ return false
+ }
+ }
+
+ // Consume the major version number.
+ if !yaml_parser_scan_version_directive_number(parser, start_mark, major) {
+ return false
+ }
+
+ // Eat '.'.
+ if parser.buffer[parser.buffer_pos] != '.' {
+ return yaml_parser_set_scanner_error(parser, "while scanning a %YAML directive",
+ start_mark, "did not find expected digit or '.' character")
+ }
+
+ skip(parser)
+
+ // Consume the minor version number.
+ if !yaml_parser_scan_version_directive_number(parser, start_mark, minor) {
+ return false
+ }
+ return true
+}
+
+const max_number_length = 2
+
+// Scan the version number of VERSION-DIRECTIVE.
+//
+// Scope:
+// %YAML 1.1 # a comment \n
+// ^
+// %YAML 1.1 # a comment \n
+// ^
+func yaml_parser_scan_version_directive_number(parser *yaml_parser_t, start_mark yaml_mark_t, number *int8) bool {
+
+ // Repeat while the next character is digit.
+ if parser.unread < 1 && !yaml_parser_update_buffer(parser, 1) {
+ return false
+ }
+ var value, length int8
+ for is_digit(parser.buffer, parser.buffer_pos) {
+ // Check if the number is too long.
+ length++
+ if length > max_number_length {
+ return yaml_parser_set_scanner_error(parser, "while scanning a %YAML directive",
+ start_mark, "found extremely long version number")
+ }
+ value = value*10 + int8(as_digit(parser.buffer, parser.buffer_pos))
+ skip(parser)
+ if parser.unread < 1 && !yaml_parser_update_buffer(parser, 1) {
+ return false
+ }
+ }
+
+ // Check if the number was present.
+ if length == 0 {
+ return yaml_parser_set_scanner_error(parser, "while scanning a %YAML directive",
+ start_mark, "did not find expected version number")
+ }
+ *number = value
+ return true
+}
+
+// Scan the value of a TAG-DIRECTIVE token.
+//
+// Scope:
+// %TAG !yaml! tag:yaml.org,2002: \n
+// ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+//
+func yaml_parser_scan_tag_directive_value(parser *yaml_parser_t, start_mark yaml_mark_t, handle, prefix *[]byte) bool {
+ var handle_value, prefix_value []byte
+
+ // Eat whitespaces.
+ if parser.unread < 1 && !yaml_parser_update_buffer(parser, 1) {
+ return false
+ }
+
+ for is_blank(parser.buffer, parser.buffer_pos) {
+ skip(parser)
+ if parser.unread < 1 && !yaml_parser_update_buffer(parser, 1) {
+ return false
+ }
+ }
+
+ // Scan a handle.
+ if !yaml_parser_scan_tag_handle(parser, true, start_mark, &handle_value) {
+ return false
+ }
+
+ // Expect a whitespace.
+ if parser.unread < 1 && !yaml_parser_update_buffer(parser, 1) {
+ return false
+ }
+ if !is_blank(parser.buffer, parser.buffer_pos) {
+ yaml_parser_set_scanner_error(parser, "while scanning a %TAG directive",
+ start_mark, "did not find expected whitespace")
+ return false
+ }
+
+ // Eat whitespaces.
+ for is_blank(parser.buffer, parser.buffer_pos) {
+ skip(parser)
+ if parser.unread < 1 && !yaml_parser_update_buffer(parser, 1) {
+ return false
+ }
+ }
+
+ // Scan a prefix.
+ if !yaml_parser_scan_tag_uri(parser, true, nil, start_mark, &prefix_value) {
+ return false
+ }
+
+ // Expect a whitespace or line break.
+ if parser.unread < 1 && !yaml_parser_update_buffer(parser, 1) {
+ return false
+ }
+ if !is_blankz(parser.buffer, parser.buffer_pos) {
+ yaml_parser_set_scanner_error(parser, "while scanning a %TAG directive",
+ start_mark, "did not find expected whitespace or line break")
+ return false
+ }
+
+ *handle = handle_value
+ *prefix = prefix_value
+ return true
+}
+
+func yaml_parser_scan_anchor(parser *yaml_parser_t, token *yaml_token_t, typ yaml_token_type_t) bool {
+ var s []byte
+
+ // Eat the indicator character.
+ start_mark := parser.mark
+ skip(parser)
+
+ // Consume the value.
+ if parser.unread < 1 && !yaml_parser_update_buffer(parser, 1) {
+ return false
+ }
+
+ for is_alpha(parser.buffer, parser.buffer_pos) {
+ s = read(parser, s)
+ if parser.unread < 1 && !yaml_parser_update_buffer(parser, 1) {
+ return false
+ }
+ }
+
+ end_mark := parser.mark
+
+ /*
+ * Check if length of the anchor is greater than 0 and it is followed by
+ * a whitespace character or one of the indicators:
+ *
+ * '?', ':', ',', ']', '}', '%', '@', '`'.
+ */
+
+ if len(s) == 0 ||
+ !(is_blankz(parser.buffer, parser.buffer_pos) || parser.buffer[parser.buffer_pos] == '?' ||
+ parser.buffer[parser.buffer_pos] == ':' || parser.buffer[parser.buffer_pos] == ',' ||
+ parser.buffer[parser.buffer_pos] == ']' || parser.buffer[parser.buffer_pos] == '}' ||
+ parser.buffer[parser.buffer_pos] == '%' || parser.buffer[parser.buffer_pos] == '@' ||
+ parser.buffer[parser.buffer_pos] == '`') {
+ context := "while scanning an alias"
+ if typ == yaml_ANCHOR_TOKEN {
+ context = "while scanning an anchor"
+ }
+ yaml_parser_set_scanner_error(parser, context, start_mark,
+ "did not find expected alphabetic or numeric character")
+ return false
+ }
+
+ // Create a token.
+ *token = yaml_token_t{
+ typ: typ,
+ start_mark: start_mark,
+ end_mark: end_mark,
+ value: s,
+ }
+
+ return true
+}
+
+/*
+ * Scan a TAG token.
+ */
+
+func yaml_parser_scan_tag(parser *yaml_parser_t, token *yaml_token_t) bool {
+ var handle, suffix []byte
+
+ start_mark := parser.mark
+
+ // Check if the tag is in the canonical form.
+ if parser.unread < 2 && !yaml_parser_update_buffer(parser, 2) {
+ return false
+ }
+
+ if parser.buffer[parser.buffer_pos+1] == '<' {
+ // Keep the handle as ''
+
+ // Eat '!<'
+ skip(parser)
+ skip(parser)
+
+ // Consume the tag value.
+ if !yaml_parser_scan_tag_uri(parser, false, nil, start_mark, &suffix) {
+ return false
+ }
+
+ // Check for '>' and eat it.
+ if parser.buffer[parser.buffer_pos] != '>' {
+ yaml_parser_set_scanner_error(parser, "while scanning a tag",
+ start_mark, "did not find the expected '>'")
+ return false
+ }
+
+ skip(parser)
+ } else {
+ // The tag has either the '!suffix' or the '!handle!suffix' form.
+
+ // First, try to scan a handle.
+ if !yaml_parser_scan_tag_handle(parser, false, start_mark, &handle) {
+ return false
+ }
+
+ // Check if it is, indeed, handle.
+ if handle[0] == '!' && len(handle) > 1 && handle[len(handle)-1] == '!' {
+ // Scan the suffix now.
+ if !yaml_parser_scan_tag_uri(parser, false, nil, start_mark, &suffix) {
+ return false
+ }
+ } else {
+ // It wasn't a handle after all. Scan the rest of the tag.
+ if !yaml_parser_scan_tag_uri(parser, false, handle, start_mark, &suffix) {
+ return false
+ }
+
+ // Set the handle to '!'.
+ handle = []byte{'!'}
+
+ // A special case: the '!' tag. Set the handle to '' and the
+ // suffix to '!'.
+ if len(suffix) == 0 {
+ handle, suffix = suffix, handle
+ }
+ }
+ }
+
+ // Check the character which ends the tag.
+ if parser.unread < 1 && !yaml_parser_update_buffer(parser, 1) {
+ return false
+ }
+ if !is_blankz(parser.buffer, parser.buffer_pos) {
+ yaml_parser_set_scanner_error(parser, "while scanning a tag",
+ start_mark, "did not find expected whitespace or line break")
+ return false
+ }
+
+ end_mark := parser.mark
+
+ // Create a token.
+ *token = yaml_token_t{
+ typ: yaml_TAG_TOKEN,
+ start_mark: start_mark,
+ end_mark: end_mark,
+ value: handle,
+ suffix: suffix,
+ }
+ return true
+}
+
+// Scan a tag handle.
+func yaml_parser_scan_tag_handle(parser *yaml_parser_t, directive bool, start_mark yaml_mark_t, handle *[]byte) bool {
+ // Check the initial '!' character.
+ if parser.unread < 1 && !yaml_parser_update_buffer(parser, 1) {
+ return false
+ }
+ if parser.buffer[parser.buffer_pos] != '!' {
+ yaml_parser_set_scanner_tag_error(parser, directive,
+ start_mark, "did not find expected '!'")
+ return false
+ }
+
+ var s []byte
+
+ // Copy the '!' character.
+ s = read(parser, s)
+
+ // Copy all subsequent alphabetical and numerical characters.
+ if parser.unread < 1 && !yaml_parser_update_buffer(parser, 1) {
+ return false
+ }
+ for is_alpha(parser.buffer, parser.buffer_pos) {
+ s = read(parser, s)
+ if parser.unread < 1 && !yaml_parser_update_buffer(parser, 1) {
+ return false
+ }
+ }
+
+ // Check if the trailing character is '!' and copy it.
+ if parser.buffer[parser.buffer_pos] == '!' {
+ s = read(parser, s)
+ } else {
+ // It's either the '!' tag or not really a tag handle. If it's a %TAG
+ // directive, it's an error. If it's a tag token, it must be a part of URI.
+ if directive && !(s[0] == '!' && s[1] == 0) {
+ yaml_parser_set_scanner_tag_error(parser, directive,
+ start_mark, "did not find expected '!'")
+ return false
+ }
+ }
+
+ *handle = s
+ return true
+}
+
+// Scan a tag.
+func yaml_parser_scan_tag_uri(parser *yaml_parser_t, directive bool, head []byte, start_mark yaml_mark_t, uri *[]byte) bool {
+ //size_t length = head ? strlen((char *)head) : 0
+ var s []byte
+
+ // Copy the head if needed.
+ //
+ // Note that we don't copy the leading '!' character.
+ if len(head) > 1 {
+ s = append(s, head[1:]...)
+ }
+
+ // Scan the tag.
+ if parser.unread < 1 && !yaml_parser_update_buffer(parser, 1) {
+ return false
+ }
+
+ // The set of characters that may appear in URI is as follows:
+ //
+ // '0'-'9', 'A'-'Z', 'a'-'z', '_', '-', ';', '/', '?', ':', '@', '&',
+ // '=', '+', '$', ',', '.', '!', '~', '*', '\'', '(', ')', '[', ']',
+ // '%'.
+ // [Go] Convert this into more reasonable logic.
+ for is_alpha(parser.buffer, parser.buffer_pos) || parser.buffer[parser.buffer_pos] == ';' ||
+ parser.buffer[parser.buffer_pos] == '/' || parser.buffer[parser.buffer_pos] == '?' ||
+ parser.buffer[parser.buffer_pos] == ':' || parser.buffer[parser.buffer_pos] == '@' ||
+ parser.buffer[parser.buffer_pos] == '&' || parser.buffer[parser.buffer_pos] == '=' ||
+ parser.buffer[parser.buffer_pos] == '+' || parser.buffer[parser.buffer_pos] == '$' ||
+ parser.buffer[parser.buffer_pos] == ',' || parser.buffer[parser.buffer_pos] == '.' ||
+ parser.buffer[parser.buffer_pos] == '!' || parser.buffer[parser.buffer_pos] == '~' ||
+ parser.buffer[parser.buffer_pos] == '*' || parser.buffer[parser.buffer_pos] == '\'' ||
+ parser.buffer[parser.buffer_pos] == '(' || parser.buffer[parser.buffer_pos] == ')' ||
+ parser.buffer[parser.buffer_pos] == '[' || parser.buffer[parser.buffer_pos] == ']' ||
+ parser.buffer[parser.buffer_pos] == '%' {
+ // Check if it is a URI-escape sequence.
+ if parser.buffer[parser.buffer_pos] == '%' {
+ if !yaml_parser_scan_uri_escapes(parser, directive, start_mark, &s) {
+ return false
+ }
+ } else {
+ s = read(parser, s)
+ }
+ if parser.unread < 1 && !yaml_parser_update_buffer(parser, 1) {
+ return false
+ }
+ }
+
+ // Check if the tag is non-empty.
+ if len(s) == 0 {
+ yaml_parser_set_scanner_tag_error(parser, directive,
+ start_mark, "did not find expected tag URI")
+ return false
+ }
+ *uri = s
+ return true
+}
+
+// Decode an URI-escape sequence corresponding to a single UTF-8 character.
+func yaml_parser_scan_uri_escapes(parser *yaml_parser_t, directive bool, start_mark yaml_mark_t, s *[]byte) bool {
+
+ // Decode the required number of characters.
+ w := 1024
+ for w > 0 {
+ // Check for a URI-escaped octet.
+ if parser.unread < 3 && !yaml_parser_update_buffer(parser, 3) {
+ return false
+ }
+
+ if !(parser.buffer[parser.buffer_pos] == '%' &&
+ is_hex(parser.buffer, parser.buffer_pos+1) &&
+ is_hex(parser.buffer, parser.buffer_pos+2)) {
+ return yaml_parser_set_scanner_tag_error(parser, directive,
+ start_mark, "did not find URI escaped octet")
+ }
+
+ // Get the octet.
+ octet := byte((as_hex(parser.buffer, parser.buffer_pos+1) << 4) + as_hex(parser.buffer, parser.buffer_pos+2))
+
+ // If it is the leading octet, determine the length of the UTF-8 sequence.
+ if w == 1024 {
+ w = width(octet)
+ if w == 0 {
+ return yaml_parser_set_scanner_tag_error(parser, directive,
+ start_mark, "found an incorrect leading UTF-8 octet")
+ }
+ } else {
+ // Check if the trailing octet is correct.
+ if octet&0xC0 != 0x80 {
+ return yaml_parser_set_scanner_tag_error(parser, directive,
+ start_mark, "found an incorrect trailing UTF-8 octet")
+ }
+ }
+
+ // Copy the octet and move the pointers.
+ *s = append(*s, octet)
+ skip(parser)
+ skip(parser)
+ skip(parser)
+ w--
+ }
+ return true
+}
+
+// Scan a block scalar.
+func yaml_parser_scan_block_scalar(parser *yaml_parser_t, token *yaml_token_t, literal bool) bool {
+ // Eat the indicator '|' or '>'.
+ start_mark := parser.mark
+ skip(parser)
+
+ // Scan the additional block scalar indicators.
+ if parser.unread < 1 && !yaml_parser_update_buffer(parser, 1) {
+ return false
+ }
+
+ // Check for a chomping indicator.
+ var chomping, increment int
+ if parser.buffer[parser.buffer_pos] == '+' || parser.buffer[parser.buffer_pos] == '-' {
+ // Set the chomping method and eat the indicator.
+ if parser.buffer[parser.buffer_pos] == '+' {
+ chomping = +1
+ } else {
+ chomping = -1
+ }
+ skip(parser)
+
+ // Check for an indentation indicator.
+ if parser.unread < 1 && !yaml_parser_update_buffer(parser, 1) {
+ return false
+ }
+ if is_digit(parser.buffer, parser.buffer_pos) {
+ // Check that the intendation is greater than 0.
+ if parser.buffer[parser.buffer_pos] == '0' {
+ yaml_parser_set_scanner_error(parser, "while scanning a block scalar",
+ start_mark, "found an intendation indicator equal to 0")
+ return false
+ }
+
+ // Get the intendation level and eat the indicator.
+ increment = as_digit(parser.buffer, parser.buffer_pos)
+ skip(parser)
+ }
+
+ } else if is_digit(parser.buffer, parser.buffer_pos) {
+ // Do the same as above, but in the opposite order.
+
+ if parser.buffer[parser.buffer_pos] == '0' {
+ yaml_parser_set_scanner_error(parser, "while scanning a block scalar",
+ start_mark, "found an intendation indicator equal to 0")
+ return false
+ }
+ increment = as_digit(parser.buffer, parser.buffer_pos)
+ skip(parser)
+
+ if parser.unread < 1 && !yaml_parser_update_buffer(parser, 1) {
+ return false
+ }
+ if parser.buffer[parser.buffer_pos] == '+' || parser.buffer[parser.buffer_pos] == '-' {
+ if parser.buffer[parser.buffer_pos] == '+' {
+ chomping = +1
+ } else {
+ chomping = -1
+ }
+ skip(parser)
+ }
+ }
+
+ // Eat whitespaces and comments to the end of the line.
+ if parser.unread < 1 && !yaml_parser_update_buffer(parser, 1) {
+ return false
+ }
+ for is_blank(parser.buffer, parser.buffer_pos) {
+ skip(parser)
+ if parser.unread < 1 && !yaml_parser_update_buffer(parser, 1) {
+ return false
+ }
+ }
+ if parser.buffer[parser.buffer_pos] == '#' {
+ for !is_breakz(parser.buffer, parser.buffer_pos) {
+ skip(parser)
+ if parser.unread < 1 && !yaml_parser_update_buffer(parser, 1) {
+ return false
+ }
+ }
+ }
+
+ // Check if we are at the end of the line.
+ if !is_breakz(parser.buffer, parser.buffer_pos) {
+ yaml_parser_set_scanner_error(parser, "while scanning a block scalar",
+ start_mark, "did not find expected comment or line break")
+ return false
+ }
+
+ // Eat a line break.
+ if is_break(parser.buffer, parser.buffer_pos) {
+ if parser.unread < 2 && !yaml_parser_update_buffer(parser, 2) {
+ return false
+ }
+ skip_line(parser)
+ }
+
+ end_mark := parser.mark
+
+ // Set the intendation level if it was specified.
+ var indent int
+ if increment > 0 {
+ if parser.indent >= 0 {
+ indent = parser.indent + increment
+ } else {
+ indent = increment
+ }
+ }
+
+ // Scan the leading line breaks and determine the indentation level if needed.
+ var s, leading_break, trailing_breaks []byte
+ if !yaml_parser_scan_block_scalar_breaks(parser, &indent, &trailing_breaks, start_mark, &end_mark) {
+ return false
+ }
+
+ // Scan the block scalar content.
+ if parser.unread < 1 && !yaml_parser_update_buffer(parser, 1) {
+ return false
+ }
+ var leading_blank, trailing_blank bool
+ for parser.mark.column == indent && !is_z(parser.buffer, parser.buffer_pos) {
+ // We are at the beginning of a non-empty line.
+
+ // Is it a trailing whitespace?
+ trailing_blank = is_blank(parser.buffer, parser.buffer_pos)
+
+ // Check if we need to fold the leading line break.
+ if !literal && !leading_blank && !trailing_blank && len(leading_break) > 0 && leading_break[0] == '\n' {
+ // Do we need to join the lines by space?
+ if len(trailing_breaks) == 0 {
+ s = append(s, ' ')
+ }
+ } else {
+ s = append(s, leading_break...)
+ }
+ leading_break = leading_break[:0]
+
+ // Append the remaining line breaks.
+ s = append(s, trailing_breaks...)
+ trailing_breaks = trailing_breaks[:0]
+
+ // Is it a leading whitespace?
+ leading_blank = is_blank(parser.buffer, parser.buffer_pos)
+
+ // Consume the current line.
+ for !is_breakz(parser.buffer, parser.buffer_pos) {
+ s = read(parser, s)
+ if parser.unread < 1 && !yaml_parser_update_buffer(parser, 1) {
+ return false
+ }
+ }
+
+ // Consume the line break.
+ if parser.unread < 2 && !yaml_parser_update_buffer(parser, 2) {
+ return false
+ }
+
+ leading_break = read_line(parser, leading_break)
+
+ // Eat the following intendation spaces and line breaks.
+ if !yaml_parser_scan_block_scalar_breaks(parser, &indent, &trailing_breaks, start_mark, &end_mark) {
+ return false
+ }
+ }
+
+ // Chomp the tail.
+ if chomping != -1 {
+ s = append(s, leading_break...)
+ }
+ if chomping == 1 {
+ s = append(s, trailing_breaks...)
+ }
+
+ // Create a token.
+ *token = yaml_token_t{
+ typ: yaml_SCALAR_TOKEN,
+ start_mark: start_mark,
+ end_mark: end_mark,
+ value: s,
+ style: yaml_LITERAL_SCALAR_STYLE,
+ }
+ if !literal {
+ token.style = yaml_FOLDED_SCALAR_STYLE
+ }
+ return true
+}
+
+// Scan intendation spaces and line breaks for a block scalar. Determine the
+// intendation level if needed.
+func yaml_parser_scan_block_scalar_breaks(parser *yaml_parser_t, indent *int, breaks *[]byte, start_mark yaml_mark_t, end_mark *yaml_mark_t) bool {
+ *end_mark = parser.mark
+
+ // Eat the intendation spaces and line breaks.
+ max_indent := 0
+ for {
+ // Eat the intendation spaces.
+ if parser.unread < 1 && !yaml_parser_update_buffer(parser, 1) {
+ return false
+ }
+ for (*indent == 0 || parser.mark.column < *indent) && is_space(parser.buffer, parser.buffer_pos) {
+ skip(parser)
+ if parser.unread < 1 && !yaml_parser_update_buffer(parser, 1) {
+ return false
+ }
+ }
+ if parser.mark.column > max_indent {
+ max_indent = parser.mark.column
+ }
+
+ // Check for a tab character messing the intendation.
+ if (*indent == 0 || parser.mark.column < *indent) && is_tab(parser.buffer, parser.buffer_pos) {
+ return yaml_parser_set_scanner_error(parser, "while scanning a block scalar",
+ start_mark, "found a tab character where an intendation space is expected")
+ }
+
+ // Have we found a non-empty line?
+ if !is_break(parser.buffer, parser.buffer_pos) {
+ break
+ }
+
+ // Consume the line break.
+ if parser.unread < 2 && !yaml_parser_update_buffer(parser, 2) {
+ return false
+ }
+ // [Go] Should really be returning breaks instead.
+ *breaks = read_line(parser, *breaks)
+ *end_mark = parser.mark
+ }
+
+ // Determine the indentation level if needed.
+ if *indent == 0 {
+ *indent = max_indent
+ if *indent < parser.indent+1 {
+ *indent = parser.indent + 1
+ }
+ if *indent < 1 {
+ *indent = 1
+ }
+ }
+ return true
+}
+
+// Scan a quoted scalar.
+func yaml_parser_scan_flow_scalar(parser *yaml_parser_t, token *yaml_token_t, single bool) bool {
+ // Eat the left quote.
+ start_mark := parser.mark
+ skip(parser)
+
+ // Consume the content of the quoted scalar.
+ var s, leading_break, trailing_breaks, whitespaces []byte
+ for {
+ // Check that there are no document indicators at the beginning of the line.
+ if parser.unread < 4 && !yaml_parser_update_buffer(parser, 4) {
+ return false
+ }
+
+ if parser.mark.column == 0 &&
+ ((parser.buffer[parser.buffer_pos+0] == '-' &&
+ parser.buffer[parser.buffer_pos+1] == '-' &&
+ parser.buffer[parser.buffer_pos+2] == '-') ||
+ (parser.buffer[parser.buffer_pos+0] == '.' &&
+ parser.buffer[parser.buffer_pos+1] == '.' &&
+ parser.buffer[parser.buffer_pos+2] == '.')) &&
+ is_blankz(parser.buffer, parser.buffer_pos+3) {
+ yaml_parser_set_scanner_error(parser, "while scanning a quoted scalar",
+ start_mark, "found unexpected document indicator")
+ return false
+ }
+
+ // Check for EOF.
+ if is_z(parser.buffer, parser.buffer_pos) {
+ yaml_parser_set_scanner_error(parser, "while scanning a quoted scalar",
+ start_mark, "found unexpected end of stream")
+ return false
+ }
+
+ // Consume non-blank characters.
+ leading_blanks := false
+ for !is_blankz(parser.buffer, parser.buffer_pos) {
+ if single && parser.buffer[parser.buffer_pos] == '\'' && parser.buffer[parser.buffer_pos+1] == '\'' {
+ // Is is an escaped single quote.
+ s = append(s, '\'')
+ skip(parser)
+ skip(parser)
+
+ } else if single && parser.buffer[parser.buffer_pos] == '\'' {
+ // It is a right single quote.
+ break
+ } else if !single && parser.buffer[parser.buffer_pos] == '"' {
+ // It is a right double quote.
+ break
+
+ } else if !single && parser.buffer[parser.buffer_pos] == '\\' && is_break(parser.buffer, parser.buffer_pos+1) {
+ // It is an escaped line break.
+ if parser.unread < 3 && !yaml_parser_update_buffer(parser, 3) {
+ return false
+ }
+ skip(parser)
+ skip_line(parser)
+ leading_blanks = true
+ break
+
+ } else if !single && parser.buffer[parser.buffer_pos] == '\\' {
+ // It is an escape sequence.
+ code_length := 0
+
+ // Check the escape character.
+ switch parser.buffer[parser.buffer_pos+1] {
+ case '0':
+ s = append(s, 0)
+ case 'a':
+ s = append(s, '\x07')
+ case 'b':
+ s = append(s, '\x08')
+ case 't', '\t':
+ s = append(s, '\x09')
+ case 'n':
+ s = append(s, '\x0A')
+ case 'v':
+ s = append(s, '\x0B')
+ case 'f':
+ s = append(s, '\x0C')
+ case 'r':
+ s = append(s, '\x0D')
+ case 'e':
+ s = append(s, '\x1B')
+ case ' ':
+ s = append(s, '\x20')
+ case '"':
+ s = append(s, '"')
+ case '\'':
+ s = append(s, '\'')
+ case '\\':
+ s = append(s, '\\')
+ case 'N': // NEL (#x85)
+ s = append(s, '\xC2')
+ s = append(s, '\x85')
+ case '_': // #xA0
+ s = append(s, '\xC2')
+ s = append(s, '\xA0')
+ case 'L': // LS (#x2028)
+ s = append(s, '\xE2')
+ s = append(s, '\x80')
+ s = append(s, '\xA8')
+ case 'P': // PS (#x2029)
+ s = append(s, '\xE2')
+ s = append(s, '\x80')
+ s = append(s, '\xA9')
+ case 'x':
+ code_length = 2
+ case 'u':
+ code_length = 4
+ case 'U':
+ code_length = 8
+ default:
+ yaml_parser_set_scanner_error(parser, "while parsing a quoted scalar",
+ start_mark, "found unknown escape character")
+ return false
+ }
+
+ skip(parser)
+ skip(parser)
+
+ // Consume an arbitrary escape code.
+ if code_length > 0 {
+ var value int
+
+ // Scan the character value.
+ if parser.unread < code_length && !yaml_parser_update_buffer(parser, code_length) {
+ return false
+ }
+ for k := 0; k < code_length; k++ {
+ if !is_hex(parser.buffer, parser.buffer_pos+k) {
+ yaml_parser_set_scanner_error(parser, "while parsing a quoted scalar",
+ start_mark, "did not find expected hexdecimal number")
+ return false
+ }
+ value = (value << 4) + as_hex(parser.buffer, parser.buffer_pos+k)
+ }
+
+ // Check the value and write the character.
+ if (value >= 0xD800 && value <= 0xDFFF) || value > 0x10FFFF {
+ yaml_parser_set_scanner_error(parser, "while parsing a quoted scalar",
+ start_mark, "found invalid Unicode character escape code")
+ return false
+ }
+ if value <= 0x7F {
+ s = append(s, byte(value))
+ } else if value <= 0x7FF {
+ s = append(s, byte(0xC0+(value>>6)))
+ s = append(s, byte(0x80+(value&0x3F)))
+ } else if value <= 0xFFFF {
+ s = append(s, byte(0xE0+(value>>12)))
+ s = append(s, byte(0x80+((value>>6)&0x3F)))
+ s = append(s, byte(0x80+(value&0x3F)))
+ } else {
+ s = append(s, byte(0xF0+(value>>18)))
+ s = append(s, byte(0x80+((value>>12)&0x3F)))
+ s = append(s, byte(0x80+((value>>6)&0x3F)))
+ s = append(s, byte(0x80+(value&0x3F)))
+ }
+
+ // Advance the pointer.
+ for k := 0; k < code_length; k++ {
+ skip(parser)
+ }
+ }
+ } else {
+ // It is a non-escaped non-blank character.
+ s = read(parser, s)
+ }
+ if parser.unread < 2 && !yaml_parser_update_buffer(parser, 2) {
+ return false
+ }
+ }
+
+ // Check if we are at the end of the scalar.
+ if single {
+ if parser.buffer[parser.buffer_pos] == '\'' {
+ break
+ }
+ } else {
+ if parser.buffer[parser.buffer_pos] == '"' {
+ break
+ }
+ }
+
+ // Consume blank characters.
+ if parser.unread < 1 && !yaml_parser_update_buffer(parser, 1) {
+ return false
+ }
+
+ for is_blank(parser.buffer, parser.buffer_pos) || is_break(parser.buffer, parser.buffer_pos) {
+ if is_blank(parser.buffer, parser.buffer_pos) {
+ // Consume a space or a tab character.
+ if !leading_blanks {
+ whitespaces = read(parser, whitespaces)
+ } else {
+ skip(parser)
+ }
+ } else {
+ if parser.unread < 2 && !yaml_parser_update_buffer(parser, 2) {
+ return false
+ }
+
+ // Check if it is a first line break.
+ if !leading_blanks {
+ whitespaces = whitespaces[:0]
+ leading_break = read_line(parser, leading_break)
+ leading_blanks = true
+ } else {
+ trailing_breaks = read_line(parser, trailing_breaks)
+ }
+ }
+ if parser.unread < 1 && !yaml_parser_update_buffer(parser, 1) {
+ return false
+ }
+ }
+
+ // Join the whitespaces or fold line breaks.
+ if leading_blanks {
+ // Do we need to fold line breaks?
+ if len(leading_break) > 0 && leading_break[0] == '\n' {
+ if len(trailing_breaks) == 0 {
+ s = append(s, ' ')
+ } else {
+ s = append(s, trailing_breaks...)
+ }
+ } else {
+ s = append(s, leading_break...)
+ s = append(s, trailing_breaks...)
+ }
+ trailing_breaks = trailing_breaks[:0]
+ leading_break = leading_break[:0]
+ } else {
+ s = append(s, whitespaces...)
+ whitespaces = whitespaces[:0]
+ }
+ }
+
+ // Eat the right quote.
+ skip(parser)
+ end_mark := parser.mark
+
+ // Create a token.
+ *token = yaml_token_t{
+ typ: yaml_SCALAR_TOKEN,
+ start_mark: start_mark,
+ end_mark: end_mark,
+ value: s,
+ style: yaml_SINGLE_QUOTED_SCALAR_STYLE,
+ }
+ if !single {
+ token.style = yaml_DOUBLE_QUOTED_SCALAR_STYLE
+ }
+ return true
+}
+
+// Scan a plain scalar.
+func yaml_parser_scan_plain_scalar(parser *yaml_parser_t, token *yaml_token_t) bool {
+
+ var s, leading_break, trailing_breaks, whitespaces []byte
+ var leading_blanks bool
+ var indent = parser.indent + 1
+
+ start_mark := parser.mark
+ end_mark := parser.mark
+
+ // Consume the content of the plain scalar.
+ for {
+ // Check for a document indicator.
+ if parser.unread < 4 && !yaml_parser_update_buffer(parser, 4) {
+ return false
+ }
+ if parser.mark.column == 0 &&
+ ((parser.buffer[parser.buffer_pos+0] == '-' &&
+ parser.buffer[parser.buffer_pos+1] == '-' &&
+ parser.buffer[parser.buffer_pos+2] == '-') ||
+ (parser.buffer[parser.buffer_pos+0] == '.' &&
+ parser.buffer[parser.buffer_pos+1] == '.' &&
+ parser.buffer[parser.buffer_pos+2] == '.')) &&
+ is_blankz(parser.buffer, parser.buffer_pos+3) {
+ break
+ }
+
+ // Check for a comment.
+ if parser.buffer[parser.buffer_pos] == '#' {
+ break
+ }
+
+ // Consume non-blank characters.
+ for !is_blankz(parser.buffer, parser.buffer_pos) {
+
+ // Check for 'x:x' in the flow context. TODO: Fix the test "spec-08-13".
+ if parser.flow_level > 0 &&
+ parser.buffer[parser.buffer_pos] == ':' &&
+ !is_blankz(parser.buffer, parser.buffer_pos+1) {
+ yaml_parser_set_scanner_error(parser, "while scanning a plain scalar",
+ start_mark, "found unexpected ':'")
+ return false
+ }
+
+ // Check for indicators that may end a plain scalar.
+ if (parser.buffer[parser.buffer_pos] == ':' && is_blankz(parser.buffer, parser.buffer_pos+1)) ||
+ (parser.flow_level > 0 &&
+ (parser.buffer[parser.buffer_pos] == ',' || parser.buffer[parser.buffer_pos] == ':' ||
+ parser.buffer[parser.buffer_pos] == '?' || parser.buffer[parser.buffer_pos] == '[' ||
+ parser.buffer[parser.buffer_pos] == ']' || parser.buffer[parser.buffer_pos] == '{' ||
+ parser.buffer[parser.buffer_pos] == '}')) {
+ break
+ }
+
+ // Check if we need to join whitespaces and breaks.
+ if leading_blanks || len(whitespaces) > 0 {
+ if leading_blanks {
+ // Do we need to fold line breaks?
+ if leading_break[0] == '\n' {
+ if len(trailing_breaks) == 0 {
+ s = append(s, ' ')
+ } else {
+ s = append(s, trailing_breaks...)
+ }
+ } else {
+ s = append(s, leading_break...)
+ s = append(s, trailing_breaks...)
+ }
+ trailing_breaks = trailing_breaks[:0]
+ leading_break = leading_break[:0]
+ leading_blanks = false
+ } else {
+ s = append(s, whitespaces...)
+ whitespaces = whitespaces[:0]
+ }
+ }
+
+ // Copy the character.
+ s = read(parser, s)
+
+ end_mark = parser.mark
+ if parser.unread < 2 && !yaml_parser_update_buffer(parser, 2) {
+ return false
+ }
+ }
+
+ // Is it the end?
+ if !(is_blank(parser.buffer, parser.buffer_pos) || is_break(parser.buffer, parser.buffer_pos)) {
+ break
+ }
+
+ // Consume blank characters.
+ if parser.unread < 1 && !yaml_parser_update_buffer(parser, 1) {
+ return false
+ }
+
+ for is_blank(parser.buffer, parser.buffer_pos) || is_break(parser.buffer, parser.buffer_pos) {
+ if is_blank(parser.buffer, parser.buffer_pos) {
+
+ // Check for tab character that abuse intendation.
+ if leading_blanks && parser.mark.column < indent && is_tab(parser.buffer, parser.buffer_pos) {
+ yaml_parser_set_scanner_error(parser, "while scanning a plain scalar",
+ start_mark, "found a tab character that violate intendation")
+ return false
+ }
+
+ // Consume a space or a tab character.
+ if !leading_blanks {
+ whitespaces = read(parser, whitespaces)
+ } else {
+ skip(parser)
+ }
+ } else {
+ if parser.unread < 2 && !yaml_parser_update_buffer(parser, 2) {
+ return false
+ }
+
+ // Check if it is a first line break.
+ if !leading_blanks {
+ whitespaces = whitespaces[:0]
+ leading_break = read_line(parser, leading_break)
+ leading_blanks = true
+ } else {
+ trailing_breaks = read_line(parser, trailing_breaks)
+ }
+ }
+ if parser.unread < 1 && !yaml_parser_update_buffer(parser, 1) {
+ return false
+ }
+ }
+
+ // Check intendation level.
+ if parser.flow_level == 0 && parser.mark.column < indent {
+ break
+ }
+ }
+
+ // Create a token.
+ *token = yaml_token_t{
+ typ: yaml_SCALAR_TOKEN,
+ start_mark: start_mark,
+ end_mark: end_mark,
+ value: s,
+ style: yaml_PLAIN_SCALAR_STYLE,
+ }
+
+ // Note that we change the 'simple_key_allowed' flag.
+ if leading_blanks {
+ parser.simple_key_allowed = true
+ }
+ return true
+}
diff --git a/vendor/github.com/coreos/ignition/config/vendor/github.com/go-yaml/yaml/sorter.go b/vendor/github.com/coreos/ignition/config/vendor/github.com/go-yaml/yaml/sorter.go
new file mode 100644
index 00000000..5958822f
--- /dev/null
+++ b/vendor/github.com/coreos/ignition/config/vendor/github.com/go-yaml/yaml/sorter.go
@@ -0,0 +1,104 @@
+package yaml
+
+import (
+ "reflect"
+ "unicode"
+)
+
+type keyList []reflect.Value
+
+func (l keyList) Len() int { return len(l) }
+func (l keyList) Swap(i, j int) { l[i], l[j] = l[j], l[i] }
+func (l keyList) Less(i, j int) bool {
+ a := l[i]
+ b := l[j]
+ ak := a.Kind()
+ bk := b.Kind()
+ for (ak == reflect.Interface || ak == reflect.Ptr) && !a.IsNil() {
+ a = a.Elem()
+ ak = a.Kind()
+ }
+ for (bk == reflect.Interface || bk == reflect.Ptr) && !b.IsNil() {
+ b = b.Elem()
+ bk = b.Kind()
+ }
+ af, aok := keyFloat(a)
+ bf, bok := keyFloat(b)
+ if aok && bok {
+ if af != bf {
+ return af < bf
+ }
+ if ak != bk {
+ return ak < bk
+ }
+ return numLess(a, b)
+ }
+ if ak != reflect.String || bk != reflect.String {
+ return ak < bk
+ }
+ ar, br := []rune(a.String()), []rune(b.String())
+ for i := 0; i < len(ar) && i < len(br); i++ {
+ if ar[i] == br[i] {
+ continue
+ }
+ al := unicode.IsLetter(ar[i])
+ bl := unicode.IsLetter(br[i])
+ if al && bl {
+ return ar[i] < br[i]
+ }
+ if al || bl {
+ return bl
+ }
+ var ai, bi int
+ var an, bn int64
+ for ai = i; ai < len(ar) && unicode.IsDigit(ar[ai]); ai++ {
+ an = an*10 + int64(ar[ai]-'0')
+ }
+ for bi = i; bi < len(br) && unicode.IsDigit(br[bi]); bi++ {
+ bn = bn*10 + int64(br[bi]-'0')
+ }
+ if an != bn {
+ return an < bn
+ }
+ if ai != bi {
+ return ai < bi
+ }
+ return ar[i] < br[i]
+ }
+ return len(ar) < len(br)
+}
+
+// keyFloat returns a float value for v if it is a number/bool
+// and whether it is a number/bool or not.
+func keyFloat(v reflect.Value) (f float64, ok bool) {
+ switch v.Kind() {
+ case reflect.Int, reflect.Int8, reflect.Int16, reflect.Int32, reflect.Int64:
+ return float64(v.Int()), true
+ case reflect.Float32, reflect.Float64:
+ return v.Float(), true
+ case reflect.Uint, reflect.Uint8, reflect.Uint16, reflect.Uint32, reflect.Uint64, reflect.Uintptr:
+ return float64(v.Uint()), true
+ case reflect.Bool:
+ if v.Bool() {
+ return 1, true
+ }
+ return 0, true
+ }
+ return 0, false
+}
+
+// numLess returns whether a < b.
+// a and b must necessarily have the same kind.
+func numLess(a, b reflect.Value) bool {
+ switch a.Kind() {
+ case reflect.Int, reflect.Int8, reflect.Int16, reflect.Int32, reflect.Int64:
+ return a.Int() < b.Int()
+ case reflect.Float32, reflect.Float64:
+ return a.Float() < b.Float()
+ case reflect.Uint, reflect.Uint8, reflect.Uint16, reflect.Uint32, reflect.Uint64, reflect.Uintptr:
+ return a.Uint() < b.Uint()
+ case reflect.Bool:
+ return !a.Bool() && b.Bool()
+ }
+ panic("not a number")
+}
diff --git a/vendor/github.com/coreos/ignition/config/vendor/github.com/go-yaml/yaml/suite_test.go b/vendor/github.com/coreos/ignition/config/vendor/github.com/go-yaml/yaml/suite_test.go
new file mode 100644
index 00000000..c5cf1ed4
--- /dev/null
+++ b/vendor/github.com/coreos/ignition/config/vendor/github.com/go-yaml/yaml/suite_test.go
@@ -0,0 +1,12 @@
+package yaml_test
+
+import (
+ . "gopkg.in/check.v1"
+ "testing"
+)
+
+func Test(t *testing.T) { TestingT(t) }
+
+type S struct{}
+
+var _ = Suite(&S{})
diff --git a/vendor/github.com/coreos/ignition/config/vendor/github.com/go-yaml/yaml/writerc.go b/vendor/github.com/coreos/ignition/config/vendor/github.com/go-yaml/yaml/writerc.go
new file mode 100644
index 00000000..190362f2
--- /dev/null
+++ b/vendor/github.com/coreos/ignition/config/vendor/github.com/go-yaml/yaml/writerc.go
@@ -0,0 +1,89 @@
+package yaml
+
+// Set the writer error and return false.
+func yaml_emitter_set_writer_error(emitter *yaml_emitter_t, problem string) bool {
+ emitter.error = yaml_WRITER_ERROR
+ emitter.problem = problem
+ return false
+}
+
+// Flush the output buffer.
+func yaml_emitter_flush(emitter *yaml_emitter_t) bool {
+ if emitter.write_handler == nil {
+ panic("write handler not set")
+ }
+
+ // Check if the buffer is empty.
+ if emitter.buffer_pos == 0 {
+ return true
+ }
+
+ // If the output encoding is UTF-8, we don't need to recode the buffer.
+ if emitter.encoding == yaml_UTF8_ENCODING {
+ if err := emitter.write_handler(emitter, emitter.buffer[:emitter.buffer_pos]); err != nil {
+ return yaml_emitter_set_writer_error(emitter, "write error: "+err.Error())
+ }
+ emitter.buffer_pos = 0
+ return true
+ }
+
+ // Recode the buffer into the raw buffer.
+ var low, high int
+ if emitter.encoding == yaml_UTF16LE_ENCODING {
+ low, high = 0, 1
+ } else {
+ high, low = 1, 0
+ }
+
+ pos := 0
+ for pos < emitter.buffer_pos {
+ // See the "reader.c" code for more details on UTF-8 encoding. Note
+ // that we assume that the buffer contains a valid UTF-8 sequence.
+
+ // Read the next UTF-8 character.
+ octet := emitter.buffer[pos]
+
+ var w int
+ var value rune
+ switch {
+ case octet&0x80 == 0x00:
+ w, value = 1, rune(octet&0x7F)
+ case octet&0xE0 == 0xC0:
+ w, value = 2, rune(octet&0x1F)
+ case octet&0xF0 == 0xE0:
+ w, value = 3, rune(octet&0x0F)
+ case octet&0xF8 == 0xF0:
+ w, value = 4, rune(octet&0x07)
+ }
+ for k := 1; k < w; k++ {
+ octet = emitter.buffer[pos+k]
+ value = (value << 6) + (rune(octet) & 0x3F)
+ }
+ pos += w
+
+ // Write the character.
+ if value < 0x10000 {
+ var b [2]byte
+ b[high] = byte(value >> 8)
+ b[low] = byte(value & 0xFF)
+ emitter.raw_buffer = append(emitter.raw_buffer, b[0], b[1])
+ } else {
+ // Write the character using a surrogate pair (check "reader.c").
+ var b [4]byte
+ value -= 0x10000
+ b[high] = byte(0xD8 + (value >> 18))
+ b[low] = byte((value >> 10) & 0xFF)
+ b[high+2] = byte(0xDC + ((value >> 8) & 0xFF))
+ b[low+2] = byte(value & 0xFF)
+ emitter.raw_buffer = append(emitter.raw_buffer, b[0], b[1], b[2], b[3])
+ }
+ }
+
+ // Write the raw buffer.
+ if err := emitter.write_handler(emitter, emitter.raw_buffer); err != nil {
+ return yaml_emitter_set_writer_error(emitter, "write error: "+err.Error())
+ }
+ emitter.buffer_pos = 0
+ emitter.raw_buffer = emitter.raw_buffer[:0]
+ return true
+}
diff --git a/vendor/github.com/coreos/ignition/config/vendor/github.com/go-yaml/yaml/yaml.go b/vendor/github.com/coreos/ignition/config/vendor/github.com/go-yaml/yaml/yaml.go
new file mode 100644
index 00000000..af4df8a4
--- /dev/null
+++ b/vendor/github.com/coreos/ignition/config/vendor/github.com/go-yaml/yaml/yaml.go
@@ -0,0 +1,344 @@
+// Package yaml implements YAML support for the Go language.
+//
+// Source code and other details for the project are available at GitHub:
+//
+// https://github.com/go-yaml/yaml
+//
+package yaml
+
+import (
+ "errors"
+ "fmt"
+ "reflect"
+ "strings"
+ "sync"
+)
+
+// MapSlice encodes and decodes as a YAML map.
+// The order of keys is preserved when encoding and decoding.
+type MapSlice []MapItem
+
+// MapItem is an item in a MapSlice.
+type MapItem struct {
+ Key, Value interface{}
+}
+
+// The Unmarshaler interface may be implemented by types to customize their
+// behavior when being unmarshaled from a YAML document. The UnmarshalYAML
+// method receives a function that may be called to unmarshal the original
+// YAML value into a field or variable. It is safe to call the unmarshal
+// function parameter more than once if necessary.
+type Unmarshaler interface {
+ UnmarshalYAML(unmarshal func(interface{}) error) error
+}
+
+// The Marshaler interface may be implemented by types to customize their
+// behavior when being marshaled into a YAML document. The returned value
+// is marshaled in place of the original value implementing Marshaler.
+//
+// If an error is returned by MarshalYAML, the marshaling procedure stops
+// and returns with the provided error.
+type Marshaler interface {
+ MarshalYAML() (interface{}, error)
+}
+
+// Unmarshal decodes the first document found within the in byte slice
+// and assigns decoded values into the out value.
+//
+// Maps and pointers (to a struct, string, int, etc) are accepted as out
+// values. If an internal pointer within a struct is not initialized,
+// the yaml package will initialize it if necessary for unmarshalling
+// the provided data. The out parameter must not be nil.
+//
+// The type of the decoded values should be compatible with the respective
+// values in out. If one or more values cannot be decoded due to a type
+// mismatches, decoding continues partially until the end of the YAML
+// content, and a *yaml.TypeError is returned with details for all
+// missed values.
+//
+// Struct fields are only unmarshalled if they are exported (have an
+// upper case first letter), and are unmarshalled using the field name
+// lowercased as the default key. Custom keys may be defined via the
+// "yaml" name in the field tag: the content preceding the first comma
+// is used as the key, and the following comma-separated options are
+// used to tweak the marshalling process (see Marshal).
+// Conflicting names result in a runtime error.
+//
+// For example:
+//
+// type T struct {
+// F int `yaml:"a,omitempty"`
+// B int
+// }
+// var t T
+// yaml.Unmarshal([]byte("a: 1\nb: 2"), &t)
+//
+// See the documentation of Marshal for the format of tags and a list of
+// supported tag options.
+//
+func Unmarshal(in []byte, out interface{}) (err error) {
+ defer handleErr(&err)
+ d := newDecoder()
+ p := newParser(in)
+ defer p.destroy()
+ node := p.parse()
+ if node != nil {
+ v := reflect.ValueOf(out)
+ if v.Kind() == reflect.Ptr && !v.IsNil() {
+ v = v.Elem()
+ }
+ d.unmarshal(node, v)
+ }
+ if len(d.terrors) > 0 {
+ return &TypeError{d.terrors}
+ }
+ return nil
+}
+
+// Marshal serializes the value provided into a YAML document. The structure
+// of the generated document will reflect the structure of the value itself.
+// Maps and pointers (to struct, string, int, etc) are accepted as the in value.
+//
+// Struct fields are only unmarshalled if they are exported (have an upper case
+// first letter), and are unmarshalled using the field name lowercased as the
+// default key. Custom keys may be defined via the "yaml" name in the field
+// tag: the content preceding the first comma is used as the key, and the
+// following comma-separated options are used to tweak the marshalling process.
+// Conflicting names result in a runtime error.
+//
+// The field tag format accepted is:
+//
+// `(...) yaml:"[][,[,]]" (...)`
+//
+// The following flags are currently supported:
+//
+// omitempty Only include the field if it's not set to the zero
+// value for the type or to empty slices or maps.
+// Does not apply to zero valued structs.
+//
+// flow Marshal using a flow style (useful for structs,
+// sequences and maps).
+//
+// inline Inline the field, which must be a struct or a map,
+// causing all of its fields or keys to be processed as if
+// they were part of the outer struct. For maps, keys must
+// not conflict with the yaml keys of other struct fields.
+//
+// In addition, if the key is "-", the field is ignored.
+//
+// For example:
+//
+// type T struct {
+// F int "a,omitempty"
+// B int
+// }
+// yaml.Marshal(&T{B: 2}) // Returns "b: 2\n"
+// yaml.Marshal(&T{F: 1}} // Returns "a: 1\nb: 0\n"
+//
+func Marshal(in interface{}) (out []byte, err error) {
+ defer handleErr(&err)
+ e := newEncoder()
+ defer e.destroy()
+ e.marshal("", reflect.ValueOf(in))
+ e.finish()
+ out = e.out
+ return
+}
+
+func handleErr(err *error) {
+ if v := recover(); v != nil {
+ if e, ok := v.(yamlError); ok {
+ *err = e.err
+ } else {
+ panic(v)
+ }
+ }
+}
+
+type yamlError struct {
+ err error
+}
+
+func fail(err error) {
+ panic(yamlError{err})
+}
+
+func failf(format string, args ...interface{}) {
+ panic(yamlError{fmt.Errorf("yaml: "+format, args...)})
+}
+
+// A TypeError is returned by Unmarshal when one or more fields in
+// the YAML document cannot be properly decoded into the requested
+// types. When this error is returned, the value is still
+// unmarshaled partially.
+type TypeError struct {
+ Errors []string
+}
+
+func (e *TypeError) Error() string {
+ return fmt.Sprintf("yaml: unmarshal errors:\n %s", strings.Join(e.Errors, "\n "))
+}
+
+// --------------------------------------------------------------------------
+// Maintain a mapping of keys to structure field indexes
+
+// The code in this section was copied from mgo/bson.
+
+// structInfo holds details for the serialization of fields of
+// a given struct.
+type structInfo struct {
+ FieldsMap map[string]fieldInfo
+ FieldsList []fieldInfo
+
+ // InlineMap is the number of the field in the struct that
+ // contains an ,inline map, or -1 if there's none.
+ InlineMap int
+}
+
+type fieldInfo struct {
+ Key string
+ Num int
+ OmitEmpty bool
+ Flow bool
+
+ // Inline holds the field index if the field is part of an inlined struct.
+ Inline []int
+}
+
+var structMap = make(map[reflect.Type]*structInfo)
+var fieldMapMutex sync.RWMutex
+
+func getStructInfo(st reflect.Type) (*structInfo, error) {
+ fieldMapMutex.RLock()
+ sinfo, found := structMap[st]
+ fieldMapMutex.RUnlock()
+ if found {
+ return sinfo, nil
+ }
+
+ n := st.NumField()
+ fieldsMap := make(map[string]fieldInfo)
+ fieldsList := make([]fieldInfo, 0, n)
+ inlineMap := -1
+ for i := 0; i != n; i++ {
+ field := st.Field(i)
+ if field.PkgPath != "" {
+ continue // Private field
+ }
+
+ info := fieldInfo{Num: i}
+
+ tag := field.Tag.Get("yaml")
+ if tag == "" && strings.Index(string(field.Tag), ":") < 0 {
+ tag = string(field.Tag)
+ }
+ if tag == "-" {
+ continue
+ }
+
+ inline := false
+ fields := strings.Split(tag, ",")
+ if len(fields) > 1 {
+ for _, flag := range fields[1:] {
+ switch flag {
+ case "omitempty":
+ info.OmitEmpty = true
+ case "flow":
+ info.Flow = true
+ case "inline":
+ inline = true
+ default:
+ return nil, errors.New(fmt.Sprintf("Unsupported flag %q in tag %q of type %s", flag, tag, st))
+ }
+ }
+ tag = fields[0]
+ }
+
+ if inline {
+ switch field.Type.Kind() {
+ case reflect.Map:
+ if inlineMap >= 0 {
+ return nil, errors.New("Multiple ,inline maps in struct " + st.String())
+ }
+ if field.Type.Key() != reflect.TypeOf("") {
+ return nil, errors.New("Option ,inline needs a map with string keys in struct " + st.String())
+ }
+ inlineMap = info.Num
+ case reflect.Struct:
+ sinfo, err := getStructInfo(field.Type)
+ if err != nil {
+ return nil, err
+ }
+ for _, finfo := range sinfo.FieldsList {
+ if _, found := fieldsMap[finfo.Key]; found {
+ msg := "Duplicated key '" + finfo.Key + "' in struct " + st.String()
+ return nil, errors.New(msg)
+ }
+ if finfo.Inline == nil {
+ finfo.Inline = []int{i, finfo.Num}
+ } else {
+ finfo.Inline = append([]int{i}, finfo.Inline...)
+ }
+ fieldsMap[finfo.Key] = finfo
+ fieldsList = append(fieldsList, finfo)
+ }
+ default:
+ //return nil, errors.New("Option ,inline needs a struct value or map field")
+ return nil, errors.New("Option ,inline needs a struct value field")
+ }
+ continue
+ }
+
+ if tag != "" {
+ info.Key = tag
+ } else {
+ info.Key = strings.ToLower(field.Name)
+ }
+
+ if _, found = fieldsMap[info.Key]; found {
+ msg := "Duplicated key '" + info.Key + "' in struct " + st.String()
+ return nil, errors.New(msg)
+ }
+
+ fieldsList = append(fieldsList, info)
+ fieldsMap[info.Key] = info
+ }
+
+ sinfo = &structInfo{fieldsMap, fieldsList, inlineMap}
+
+ fieldMapMutex.Lock()
+ structMap[st] = sinfo
+ fieldMapMutex.Unlock()
+ return sinfo, nil
+}
+
+func isZero(v reflect.Value) bool {
+ switch v.Kind() {
+ case reflect.String:
+ return len(v.String()) == 0
+ case reflect.Interface, reflect.Ptr:
+ return v.IsNil()
+ case reflect.Slice:
+ return v.Len() == 0
+ case reflect.Map:
+ return v.Len() == 0
+ case reflect.Int, reflect.Int8, reflect.Int16, reflect.Int32, reflect.Int64:
+ return v.Int() == 0
+ case reflect.Uint, reflect.Uint8, reflect.Uint16, reflect.Uint32, reflect.Uint64, reflect.Uintptr:
+ return v.Uint() == 0
+ case reflect.Bool:
+ return !v.Bool()
+ case reflect.Struct:
+ vt := v.Type()
+ for i := v.NumField()-1; i >= 0; i-- {
+ if vt.Field(i).PkgPath != "" {
+ continue // Private field
+ }
+ if !isZero(v.Field(i)) {
+ return false
+ }
+ }
+ return true
+ }
+ return false
+}
diff --git a/vendor/github.com/coreos/ignition/config/vendor/github.com/go-yaml/yaml/yamlh.go b/vendor/github.com/coreos/ignition/config/vendor/github.com/go-yaml/yaml/yamlh.go
new file mode 100644
index 00000000..d60a6b6b
--- /dev/null
+++ b/vendor/github.com/coreos/ignition/config/vendor/github.com/go-yaml/yaml/yamlh.go
@@ -0,0 +1,716 @@
+package yaml
+
+import (
+ "io"
+)
+
+// The version directive data.
+type yaml_version_directive_t struct {
+ major int8 // The major version number.
+ minor int8 // The minor version number.
+}
+
+// The tag directive data.
+type yaml_tag_directive_t struct {
+ handle []byte // The tag handle.
+ prefix []byte // The tag prefix.
+}
+
+type yaml_encoding_t int
+
+// The stream encoding.
+const (
+ // Let the parser choose the encoding.
+ yaml_ANY_ENCODING yaml_encoding_t = iota
+
+ yaml_UTF8_ENCODING // The default UTF-8 encoding.
+ yaml_UTF16LE_ENCODING // The UTF-16-LE encoding with BOM.
+ yaml_UTF16BE_ENCODING // The UTF-16-BE encoding with BOM.
+)
+
+type yaml_break_t int
+
+// Line break types.
+const (
+ // Let the parser choose the break type.
+ yaml_ANY_BREAK yaml_break_t = iota
+
+ yaml_CR_BREAK // Use CR for line breaks (Mac style).
+ yaml_LN_BREAK // Use LN for line breaks (Unix style).
+ yaml_CRLN_BREAK // Use CR LN for line breaks (DOS style).
+)
+
+type yaml_error_type_t int
+
+// Many bad things could happen with the parser and emitter.
+const (
+ // No error is produced.
+ yaml_NO_ERROR yaml_error_type_t = iota
+
+ yaml_MEMORY_ERROR // Cannot allocate or reallocate a block of memory.
+ yaml_READER_ERROR // Cannot read or decode the input stream.
+ yaml_SCANNER_ERROR // Cannot scan the input stream.
+ yaml_PARSER_ERROR // Cannot parse the input stream.
+ yaml_COMPOSER_ERROR // Cannot compose a YAML document.
+ yaml_WRITER_ERROR // Cannot write to the output stream.
+ yaml_EMITTER_ERROR // Cannot emit a YAML stream.
+)
+
+// The pointer position.
+type yaml_mark_t struct {
+ index int // The position index.
+ line int // The position line.
+ column int // The position column.
+}
+
+// Node Styles
+
+type yaml_style_t int8
+
+type yaml_scalar_style_t yaml_style_t
+
+// Scalar styles.
+const (
+ // Let the emitter choose the style.
+ yaml_ANY_SCALAR_STYLE yaml_scalar_style_t = iota
+
+ yaml_PLAIN_SCALAR_STYLE // The plain scalar style.
+ yaml_SINGLE_QUOTED_SCALAR_STYLE // The single-quoted scalar style.
+ yaml_DOUBLE_QUOTED_SCALAR_STYLE // The double-quoted scalar style.
+ yaml_LITERAL_SCALAR_STYLE // The literal scalar style.
+ yaml_FOLDED_SCALAR_STYLE // The folded scalar style.
+)
+
+type yaml_sequence_style_t yaml_style_t
+
+// Sequence styles.
+const (
+ // Let the emitter choose the style.
+ yaml_ANY_SEQUENCE_STYLE yaml_sequence_style_t = iota
+
+ yaml_BLOCK_SEQUENCE_STYLE // The block sequence style.
+ yaml_FLOW_SEQUENCE_STYLE // The flow sequence style.
+)
+
+type yaml_mapping_style_t yaml_style_t
+
+// Mapping styles.
+const (
+ // Let the emitter choose the style.
+ yaml_ANY_MAPPING_STYLE yaml_mapping_style_t = iota
+
+ yaml_BLOCK_MAPPING_STYLE // The block mapping style.
+ yaml_FLOW_MAPPING_STYLE // The flow mapping style.
+)
+
+// Tokens
+
+type yaml_token_type_t int
+
+// Token types.
+const (
+ // An empty token.
+ yaml_NO_TOKEN yaml_token_type_t = iota
+
+ yaml_STREAM_START_TOKEN // A STREAM-START token.
+ yaml_STREAM_END_TOKEN // A STREAM-END token.
+
+ yaml_VERSION_DIRECTIVE_TOKEN // A VERSION-DIRECTIVE token.
+ yaml_TAG_DIRECTIVE_TOKEN // A TAG-DIRECTIVE token.
+ yaml_DOCUMENT_START_TOKEN // A DOCUMENT-START token.
+ yaml_DOCUMENT_END_TOKEN // A DOCUMENT-END token.
+
+ yaml_BLOCK_SEQUENCE_START_TOKEN // A BLOCK-SEQUENCE-START token.
+ yaml_BLOCK_MAPPING_START_TOKEN // A BLOCK-SEQUENCE-END token.
+ yaml_BLOCK_END_TOKEN // A BLOCK-END token.
+
+ yaml_FLOW_SEQUENCE_START_TOKEN // A FLOW-SEQUENCE-START token.
+ yaml_FLOW_SEQUENCE_END_TOKEN // A FLOW-SEQUENCE-END token.
+ yaml_FLOW_MAPPING_START_TOKEN // A FLOW-MAPPING-START token.
+ yaml_FLOW_MAPPING_END_TOKEN // A FLOW-MAPPING-END token.
+
+ yaml_BLOCK_ENTRY_TOKEN // A BLOCK-ENTRY token.
+ yaml_FLOW_ENTRY_TOKEN // A FLOW-ENTRY token.
+ yaml_KEY_TOKEN // A KEY token.
+ yaml_VALUE_TOKEN // A VALUE token.
+
+ yaml_ALIAS_TOKEN // An ALIAS token.
+ yaml_ANCHOR_TOKEN // An ANCHOR token.
+ yaml_TAG_TOKEN // A TAG token.
+ yaml_SCALAR_TOKEN // A SCALAR token.
+)
+
+func (tt yaml_token_type_t) String() string {
+ switch tt {
+ case yaml_NO_TOKEN:
+ return "yaml_NO_TOKEN"
+ case yaml_STREAM_START_TOKEN:
+ return "yaml_STREAM_START_TOKEN"
+ case yaml_STREAM_END_TOKEN:
+ return "yaml_STREAM_END_TOKEN"
+ case yaml_VERSION_DIRECTIVE_TOKEN:
+ return "yaml_VERSION_DIRECTIVE_TOKEN"
+ case yaml_TAG_DIRECTIVE_TOKEN:
+ return "yaml_TAG_DIRECTIVE_TOKEN"
+ case yaml_DOCUMENT_START_TOKEN:
+ return "yaml_DOCUMENT_START_TOKEN"
+ case yaml_DOCUMENT_END_TOKEN:
+ return "yaml_DOCUMENT_END_TOKEN"
+ case yaml_BLOCK_SEQUENCE_START_TOKEN:
+ return "yaml_BLOCK_SEQUENCE_START_TOKEN"
+ case yaml_BLOCK_MAPPING_START_TOKEN:
+ return "yaml_BLOCK_MAPPING_START_TOKEN"
+ case yaml_BLOCK_END_TOKEN:
+ return "yaml_BLOCK_END_TOKEN"
+ case yaml_FLOW_SEQUENCE_START_TOKEN:
+ return "yaml_FLOW_SEQUENCE_START_TOKEN"
+ case yaml_FLOW_SEQUENCE_END_TOKEN:
+ return "yaml_FLOW_SEQUENCE_END_TOKEN"
+ case yaml_FLOW_MAPPING_START_TOKEN:
+ return "yaml_FLOW_MAPPING_START_TOKEN"
+ case yaml_FLOW_MAPPING_END_TOKEN:
+ return "yaml_FLOW_MAPPING_END_TOKEN"
+ case yaml_BLOCK_ENTRY_TOKEN:
+ return "yaml_BLOCK_ENTRY_TOKEN"
+ case yaml_FLOW_ENTRY_TOKEN:
+ return "yaml_FLOW_ENTRY_TOKEN"
+ case yaml_KEY_TOKEN:
+ return "yaml_KEY_TOKEN"
+ case yaml_VALUE_TOKEN:
+ return "yaml_VALUE_TOKEN"
+ case yaml_ALIAS_TOKEN:
+ return "yaml_ALIAS_TOKEN"
+ case yaml_ANCHOR_TOKEN:
+ return "yaml_ANCHOR_TOKEN"
+ case yaml_TAG_TOKEN:
+ return "yaml_TAG_TOKEN"
+ case yaml_SCALAR_TOKEN:
+ return "yaml_SCALAR_TOKEN"
+ }
+ return ""
+}
+
+// The token structure.
+type yaml_token_t struct {
+ // The token type.
+ typ yaml_token_type_t
+
+ // The start/end of the token.
+ start_mark, end_mark yaml_mark_t
+
+ // The stream encoding (for yaml_STREAM_START_TOKEN).
+ encoding yaml_encoding_t
+
+ // The alias/anchor/scalar value or tag/tag directive handle
+ // (for yaml_ALIAS_TOKEN, yaml_ANCHOR_TOKEN, yaml_SCALAR_TOKEN, yaml_TAG_TOKEN, yaml_TAG_DIRECTIVE_TOKEN).
+ value []byte
+
+ // The tag suffix (for yaml_TAG_TOKEN).
+ suffix []byte
+
+ // The tag directive prefix (for yaml_TAG_DIRECTIVE_TOKEN).
+ prefix []byte
+
+ // The scalar style (for yaml_SCALAR_TOKEN).
+ style yaml_scalar_style_t
+
+ // The version directive major/minor (for yaml_VERSION_DIRECTIVE_TOKEN).
+ major, minor int8
+}
+
+// Events
+
+type yaml_event_type_t int8
+
+// Event types.
+const (
+ // An empty event.
+ yaml_NO_EVENT yaml_event_type_t = iota
+
+ yaml_STREAM_START_EVENT // A STREAM-START event.
+ yaml_STREAM_END_EVENT // A STREAM-END event.
+ yaml_DOCUMENT_START_EVENT // A DOCUMENT-START event.
+ yaml_DOCUMENT_END_EVENT // A DOCUMENT-END event.
+ yaml_ALIAS_EVENT // An ALIAS event.
+ yaml_SCALAR_EVENT // A SCALAR event.
+ yaml_SEQUENCE_START_EVENT // A SEQUENCE-START event.
+ yaml_SEQUENCE_END_EVENT // A SEQUENCE-END event.
+ yaml_MAPPING_START_EVENT // A MAPPING-START event.
+ yaml_MAPPING_END_EVENT // A MAPPING-END event.
+)
+
+// The event structure.
+type yaml_event_t struct {
+
+ // The event type.
+ typ yaml_event_type_t
+
+ // The start and end of the event.
+ start_mark, end_mark yaml_mark_t
+
+ // The document encoding (for yaml_STREAM_START_EVENT).
+ encoding yaml_encoding_t
+
+ // The version directive (for yaml_DOCUMENT_START_EVENT).
+ version_directive *yaml_version_directive_t
+
+ // The list of tag directives (for yaml_DOCUMENT_START_EVENT).
+ tag_directives []yaml_tag_directive_t
+
+ // The anchor (for yaml_SCALAR_EVENT, yaml_SEQUENCE_START_EVENT, yaml_MAPPING_START_EVENT, yaml_ALIAS_EVENT).
+ anchor []byte
+
+ // The tag (for yaml_SCALAR_EVENT, yaml_SEQUENCE_START_EVENT, yaml_MAPPING_START_EVENT).
+ tag []byte
+
+ // The scalar value (for yaml_SCALAR_EVENT).
+ value []byte
+
+ // Is the document start/end indicator implicit, or the tag optional?
+ // (for yaml_DOCUMENT_START_EVENT, yaml_DOCUMENT_END_EVENT, yaml_SEQUENCE_START_EVENT, yaml_MAPPING_START_EVENT, yaml_SCALAR_EVENT).
+ implicit bool
+
+ // Is the tag optional for any non-plain style? (for yaml_SCALAR_EVENT).
+ quoted_implicit bool
+
+ // The style (for yaml_SCALAR_EVENT, yaml_SEQUENCE_START_EVENT, yaml_MAPPING_START_EVENT).
+ style yaml_style_t
+}
+
+func (e *yaml_event_t) scalar_style() yaml_scalar_style_t { return yaml_scalar_style_t(e.style) }
+func (e *yaml_event_t) sequence_style() yaml_sequence_style_t { return yaml_sequence_style_t(e.style) }
+func (e *yaml_event_t) mapping_style() yaml_mapping_style_t { return yaml_mapping_style_t(e.style) }
+
+// Nodes
+
+const (
+ yaml_NULL_TAG = "tag:yaml.org,2002:null" // The tag !!null with the only possible value: null.
+ yaml_BOOL_TAG = "tag:yaml.org,2002:bool" // The tag !!bool with the values: true and false.
+ yaml_STR_TAG = "tag:yaml.org,2002:str" // The tag !!str for string values.
+ yaml_INT_TAG = "tag:yaml.org,2002:int" // The tag !!int for integer values.
+ yaml_FLOAT_TAG = "tag:yaml.org,2002:float" // The tag !!float for float values.
+ yaml_TIMESTAMP_TAG = "tag:yaml.org,2002:timestamp" // The tag !!timestamp for date and time values.
+
+ yaml_SEQ_TAG = "tag:yaml.org,2002:seq" // The tag !!seq is used to denote sequences.
+ yaml_MAP_TAG = "tag:yaml.org,2002:map" // The tag !!map is used to denote mapping.
+
+ // Not in original libyaml.
+ yaml_BINARY_TAG = "tag:yaml.org,2002:binary"
+ yaml_MERGE_TAG = "tag:yaml.org,2002:merge"
+
+ yaml_DEFAULT_SCALAR_TAG = yaml_STR_TAG // The default scalar tag is !!str.
+ yaml_DEFAULT_SEQUENCE_TAG = yaml_SEQ_TAG // The default sequence tag is !!seq.
+ yaml_DEFAULT_MAPPING_TAG = yaml_MAP_TAG // The default mapping tag is !!map.
+)
+
+type yaml_node_type_t int
+
+// Node types.
+const (
+ // An empty node.
+ yaml_NO_NODE yaml_node_type_t = iota
+
+ yaml_SCALAR_NODE // A scalar node.
+ yaml_SEQUENCE_NODE // A sequence node.
+ yaml_MAPPING_NODE // A mapping node.
+)
+
+// An element of a sequence node.
+type yaml_node_item_t int
+
+// An element of a mapping node.
+type yaml_node_pair_t struct {
+ key int // The key of the element.
+ value int // The value of the element.
+}
+
+// The node structure.
+type yaml_node_t struct {
+ typ yaml_node_type_t // The node type.
+ tag []byte // The node tag.
+
+ // The node data.
+
+ // The scalar parameters (for yaml_SCALAR_NODE).
+ scalar struct {
+ value []byte // The scalar value.
+ length int // The length of the scalar value.
+ style yaml_scalar_style_t // The scalar style.
+ }
+
+ // The sequence parameters (for YAML_SEQUENCE_NODE).
+ sequence struct {
+ items_data []yaml_node_item_t // The stack of sequence items.
+ style yaml_sequence_style_t // The sequence style.
+ }
+
+ // The mapping parameters (for yaml_MAPPING_NODE).
+ mapping struct {
+ pairs_data []yaml_node_pair_t // The stack of mapping pairs (key, value).
+ pairs_start *yaml_node_pair_t // The beginning of the stack.
+ pairs_end *yaml_node_pair_t // The end of the stack.
+ pairs_top *yaml_node_pair_t // The top of the stack.
+ style yaml_mapping_style_t // The mapping style.
+ }
+
+ start_mark yaml_mark_t // The beginning of the node.
+ end_mark yaml_mark_t // The end of the node.
+
+}
+
+// The document structure.
+type yaml_document_t struct {
+
+ // The document nodes.
+ nodes []yaml_node_t
+
+ // The version directive.
+ version_directive *yaml_version_directive_t
+
+ // The list of tag directives.
+ tag_directives_data []yaml_tag_directive_t
+ tag_directives_start int // The beginning of the tag directives list.
+ tag_directives_end int // The end of the tag directives list.
+
+ start_implicit int // Is the document start indicator implicit?
+ end_implicit int // Is the document end indicator implicit?
+
+ // The start/end of the document.
+ start_mark, end_mark yaml_mark_t
+}
+
+// The prototype of a read handler.
+//
+// The read handler is called when the parser needs to read more bytes from the
+// source. The handler should write not more than size bytes to the buffer.
+// The number of written bytes should be set to the size_read variable.
+//
+// [in,out] data A pointer to an application data specified by
+// yaml_parser_set_input().
+// [out] buffer The buffer to write the data from the source.
+// [in] size The size of the buffer.
+// [out] size_read The actual number of bytes read from the source.
+//
+// On success, the handler should return 1. If the handler failed,
+// the returned value should be 0. On EOF, the handler should set the
+// size_read to 0 and return 1.
+type yaml_read_handler_t func(parser *yaml_parser_t, buffer []byte) (n int, err error)
+
+// This structure holds information about a potential simple key.
+type yaml_simple_key_t struct {
+ possible bool // Is a simple key possible?
+ required bool // Is a simple key required?
+ token_number int // The number of the token.
+ mark yaml_mark_t // The position mark.
+}
+
+// The states of the parser.
+type yaml_parser_state_t int
+
+const (
+ yaml_PARSE_STREAM_START_STATE yaml_parser_state_t = iota
+
+ yaml_PARSE_IMPLICIT_DOCUMENT_START_STATE // Expect the beginning of an implicit document.
+ yaml_PARSE_DOCUMENT_START_STATE // Expect DOCUMENT-START.
+ yaml_PARSE_DOCUMENT_CONTENT_STATE // Expect the content of a document.
+ yaml_PARSE_DOCUMENT_END_STATE // Expect DOCUMENT-END.
+ yaml_PARSE_BLOCK_NODE_STATE // Expect a block node.
+ yaml_PARSE_BLOCK_NODE_OR_INDENTLESS_SEQUENCE_STATE // Expect a block node or indentless sequence.
+ yaml_PARSE_FLOW_NODE_STATE // Expect a flow node.
+ yaml_PARSE_BLOCK_SEQUENCE_FIRST_ENTRY_STATE // Expect the first entry of a block sequence.
+ yaml_PARSE_BLOCK_SEQUENCE_ENTRY_STATE // Expect an entry of a block sequence.
+ yaml_PARSE_INDENTLESS_SEQUENCE_ENTRY_STATE // Expect an entry of an indentless sequence.
+ yaml_PARSE_BLOCK_MAPPING_FIRST_KEY_STATE // Expect the first key of a block mapping.
+ yaml_PARSE_BLOCK_MAPPING_KEY_STATE // Expect a block mapping key.
+ yaml_PARSE_BLOCK_MAPPING_VALUE_STATE // Expect a block mapping value.
+ yaml_PARSE_FLOW_SEQUENCE_FIRST_ENTRY_STATE // Expect the first entry of a flow sequence.
+ yaml_PARSE_FLOW_SEQUENCE_ENTRY_STATE // Expect an entry of a flow sequence.
+ yaml_PARSE_FLOW_SEQUENCE_ENTRY_MAPPING_KEY_STATE // Expect a key of an ordered mapping.
+ yaml_PARSE_FLOW_SEQUENCE_ENTRY_MAPPING_VALUE_STATE // Expect a value of an ordered mapping.
+ yaml_PARSE_FLOW_SEQUENCE_ENTRY_MAPPING_END_STATE // Expect the and of an ordered mapping entry.
+ yaml_PARSE_FLOW_MAPPING_FIRST_KEY_STATE // Expect the first key of a flow mapping.
+ yaml_PARSE_FLOW_MAPPING_KEY_STATE // Expect a key of a flow mapping.
+ yaml_PARSE_FLOW_MAPPING_VALUE_STATE // Expect a value of a flow mapping.
+ yaml_PARSE_FLOW_MAPPING_EMPTY_VALUE_STATE // Expect an empty value of a flow mapping.
+ yaml_PARSE_END_STATE // Expect nothing.
+)
+
+func (ps yaml_parser_state_t) String() string {
+ switch ps {
+ case yaml_PARSE_STREAM_START_STATE:
+ return "yaml_PARSE_STREAM_START_STATE"
+ case yaml_PARSE_IMPLICIT_DOCUMENT_START_STATE:
+ return "yaml_PARSE_IMPLICIT_DOCUMENT_START_STATE"
+ case yaml_PARSE_DOCUMENT_START_STATE:
+ return "yaml_PARSE_DOCUMENT_START_STATE"
+ case yaml_PARSE_DOCUMENT_CONTENT_STATE:
+ return "yaml_PARSE_DOCUMENT_CONTENT_STATE"
+ case yaml_PARSE_DOCUMENT_END_STATE:
+ return "yaml_PARSE_DOCUMENT_END_STATE"
+ case yaml_PARSE_BLOCK_NODE_STATE:
+ return "yaml_PARSE_BLOCK_NODE_STATE"
+ case yaml_PARSE_BLOCK_NODE_OR_INDENTLESS_SEQUENCE_STATE:
+ return "yaml_PARSE_BLOCK_NODE_OR_INDENTLESS_SEQUENCE_STATE"
+ case yaml_PARSE_FLOW_NODE_STATE:
+ return "yaml_PARSE_FLOW_NODE_STATE"
+ case yaml_PARSE_BLOCK_SEQUENCE_FIRST_ENTRY_STATE:
+ return "yaml_PARSE_BLOCK_SEQUENCE_FIRST_ENTRY_STATE"
+ case yaml_PARSE_BLOCK_SEQUENCE_ENTRY_STATE:
+ return "yaml_PARSE_BLOCK_SEQUENCE_ENTRY_STATE"
+ case yaml_PARSE_INDENTLESS_SEQUENCE_ENTRY_STATE:
+ return "yaml_PARSE_INDENTLESS_SEQUENCE_ENTRY_STATE"
+ case yaml_PARSE_BLOCK_MAPPING_FIRST_KEY_STATE:
+ return "yaml_PARSE_BLOCK_MAPPING_FIRST_KEY_STATE"
+ case yaml_PARSE_BLOCK_MAPPING_KEY_STATE:
+ return "yaml_PARSE_BLOCK_MAPPING_KEY_STATE"
+ case yaml_PARSE_BLOCK_MAPPING_VALUE_STATE:
+ return "yaml_PARSE_BLOCK_MAPPING_VALUE_STATE"
+ case yaml_PARSE_FLOW_SEQUENCE_FIRST_ENTRY_STATE:
+ return "yaml_PARSE_FLOW_SEQUENCE_FIRST_ENTRY_STATE"
+ case yaml_PARSE_FLOW_SEQUENCE_ENTRY_STATE:
+ return "yaml_PARSE_FLOW_SEQUENCE_ENTRY_STATE"
+ case yaml_PARSE_FLOW_SEQUENCE_ENTRY_MAPPING_KEY_STATE:
+ return "yaml_PARSE_FLOW_SEQUENCE_ENTRY_MAPPING_KEY_STATE"
+ case yaml_PARSE_FLOW_SEQUENCE_ENTRY_MAPPING_VALUE_STATE:
+ return "yaml_PARSE_FLOW_SEQUENCE_ENTRY_MAPPING_VALUE_STATE"
+ case yaml_PARSE_FLOW_SEQUENCE_ENTRY_MAPPING_END_STATE:
+ return "yaml_PARSE_FLOW_SEQUENCE_ENTRY_MAPPING_END_STATE"
+ case yaml_PARSE_FLOW_MAPPING_FIRST_KEY_STATE:
+ return "yaml_PARSE_FLOW_MAPPING_FIRST_KEY_STATE"
+ case yaml_PARSE_FLOW_MAPPING_KEY_STATE:
+ return "yaml_PARSE_FLOW_MAPPING_KEY_STATE"
+ case yaml_PARSE_FLOW_MAPPING_VALUE_STATE:
+ return "yaml_PARSE_FLOW_MAPPING_VALUE_STATE"
+ case yaml_PARSE_FLOW_MAPPING_EMPTY_VALUE_STATE:
+ return "yaml_PARSE_FLOW_MAPPING_EMPTY_VALUE_STATE"
+ case yaml_PARSE_END_STATE:
+ return "yaml_PARSE_END_STATE"
+ }
+ return ""
+}
+
+// This structure holds aliases data.
+type yaml_alias_data_t struct {
+ anchor []byte // The anchor.
+ index int // The node id.
+ mark yaml_mark_t // The anchor mark.
+}
+
+// The parser structure.
+//
+// All members are internal. Manage the structure using the
+// yaml_parser_ family of functions.
+type yaml_parser_t struct {
+
+ // Error handling
+
+ error yaml_error_type_t // Error type.
+
+ problem string // Error description.
+
+ // The byte about which the problem occured.
+ problem_offset int
+ problem_value int
+ problem_mark yaml_mark_t
+
+ // The error context.
+ context string
+ context_mark yaml_mark_t
+
+ // Reader stuff
+
+ read_handler yaml_read_handler_t // Read handler.
+
+ input_file io.Reader // File input data.
+ input []byte // String input data.
+ input_pos int
+
+ eof bool // EOF flag
+
+ buffer []byte // The working buffer.
+ buffer_pos int // The current position of the buffer.
+
+ unread int // The number of unread characters in the buffer.
+
+ raw_buffer []byte // The raw buffer.
+ raw_buffer_pos int // The current position of the buffer.
+
+ encoding yaml_encoding_t // The input encoding.
+
+ offset int // The offset of the current position (in bytes).
+ mark yaml_mark_t // The mark of the current position.
+
+ // Scanner stuff
+
+ stream_start_produced bool // Have we started to scan the input stream?
+ stream_end_produced bool // Have we reached the end of the input stream?
+
+ flow_level int // The number of unclosed '[' and '{' indicators.
+
+ tokens []yaml_token_t // The tokens queue.
+ tokens_head int // The head of the tokens queue.
+ tokens_parsed int // The number of tokens fetched from the queue.
+ token_available bool // Does the tokens queue contain a token ready for dequeueing.
+
+ indent int // The current indentation level.
+ indents []int // The indentation levels stack.
+
+ simple_key_allowed bool // May a simple key occur at the current position?
+ simple_keys []yaml_simple_key_t // The stack of simple keys.
+
+ // Parser stuff
+
+ state yaml_parser_state_t // The current parser state.
+ states []yaml_parser_state_t // The parser states stack.
+ marks []yaml_mark_t // The stack of marks.
+ tag_directives []yaml_tag_directive_t // The list of TAG directives.
+
+ // Dumper stuff
+
+ aliases []yaml_alias_data_t // The alias data.
+
+ document *yaml_document_t // The currently parsed document.
+}
+
+// Emitter Definitions
+
+// The prototype of a write handler.
+//
+// The write handler is called when the emitter needs to flush the accumulated
+// characters to the output. The handler should write @a size bytes of the
+// @a buffer to the output.
+//
+// @param[in,out] data A pointer to an application data specified by
+// yaml_emitter_set_output().
+// @param[in] buffer The buffer with bytes to be written.
+// @param[in] size The size of the buffer.
+//
+// @returns On success, the handler should return @c 1. If the handler failed,
+// the returned value should be @c 0.
+//
+type yaml_write_handler_t func(emitter *yaml_emitter_t, buffer []byte) error
+
+type yaml_emitter_state_t int
+
+// The emitter states.
+const (
+ // Expect STREAM-START.
+ yaml_EMIT_STREAM_START_STATE yaml_emitter_state_t = iota
+
+ yaml_EMIT_FIRST_DOCUMENT_START_STATE // Expect the first DOCUMENT-START or STREAM-END.
+ yaml_EMIT_DOCUMENT_START_STATE // Expect DOCUMENT-START or STREAM-END.
+ yaml_EMIT_DOCUMENT_CONTENT_STATE // Expect the content of a document.
+ yaml_EMIT_DOCUMENT_END_STATE // Expect DOCUMENT-END.
+ yaml_EMIT_FLOW_SEQUENCE_FIRST_ITEM_STATE // Expect the first item of a flow sequence.
+ yaml_EMIT_FLOW_SEQUENCE_ITEM_STATE // Expect an item of a flow sequence.
+ yaml_EMIT_FLOW_MAPPING_FIRST_KEY_STATE // Expect the first key of a flow mapping.
+ yaml_EMIT_FLOW_MAPPING_KEY_STATE // Expect a key of a flow mapping.
+ yaml_EMIT_FLOW_MAPPING_SIMPLE_VALUE_STATE // Expect a value for a simple key of a flow mapping.
+ yaml_EMIT_FLOW_MAPPING_VALUE_STATE // Expect a value of a flow mapping.
+ yaml_EMIT_BLOCK_SEQUENCE_FIRST_ITEM_STATE // Expect the first item of a block sequence.
+ yaml_EMIT_BLOCK_SEQUENCE_ITEM_STATE // Expect an item of a block sequence.
+ yaml_EMIT_BLOCK_MAPPING_FIRST_KEY_STATE // Expect the first key of a block mapping.
+ yaml_EMIT_BLOCK_MAPPING_KEY_STATE // Expect the key of a block mapping.
+ yaml_EMIT_BLOCK_MAPPING_SIMPLE_VALUE_STATE // Expect a value for a simple key of a block mapping.
+ yaml_EMIT_BLOCK_MAPPING_VALUE_STATE // Expect a value of a block mapping.
+ yaml_EMIT_END_STATE // Expect nothing.
+)
+
+// The emitter structure.
+//
+// All members are internal. Manage the structure using the @c yaml_emitter_
+// family of functions.
+type yaml_emitter_t struct {
+
+ // Error handling
+
+ error yaml_error_type_t // Error type.
+ problem string // Error description.
+
+ // Writer stuff
+
+ write_handler yaml_write_handler_t // Write handler.
+
+ output_buffer *[]byte // String output data.
+ output_file io.Writer // File output data.
+
+ buffer []byte // The working buffer.
+ buffer_pos int // The current position of the buffer.
+
+ raw_buffer []byte // The raw buffer.
+ raw_buffer_pos int // The current position of the buffer.
+
+ encoding yaml_encoding_t // The stream encoding.
+
+ // Emitter stuff
+
+ canonical bool // If the output is in the canonical style?
+ best_indent int // The number of indentation spaces.
+ best_width int // The preferred width of the output lines.
+ unicode bool // Allow unescaped non-ASCII characters?
+ line_break yaml_break_t // The preferred line break.
+
+ state yaml_emitter_state_t // The current emitter state.
+ states []yaml_emitter_state_t // The stack of states.
+
+ events []yaml_event_t // The event queue.
+ events_head int // The head of the event queue.
+
+ indents []int // The stack of indentation levels.
+
+ tag_directives []yaml_tag_directive_t // The list of tag directives.
+
+ indent int // The current indentation level.
+
+ flow_level int // The current flow level.
+
+ root_context bool // Is it the document root context?
+ sequence_context bool // Is it a sequence context?
+ mapping_context bool // Is it a mapping context?
+ simple_key_context bool // Is it a simple mapping key context?
+
+ line int // The current line.
+ column int // The current column.
+ whitespace bool // If the last character was a whitespace?
+ indention bool // If the last character was an indentation character (' ', '-', '?', ':')?
+ open_ended bool // If an explicit document end is required?
+
+ // Anchor analysis.
+ anchor_data struct {
+ anchor []byte // The anchor value.
+ alias bool // Is it an alias?
+ }
+
+ // Tag analysis.
+ tag_data struct {
+ handle []byte // The tag handle.
+ suffix []byte // The tag suffix.
+ }
+
+ // Scalar analysis.
+ scalar_data struct {
+ value []byte // The scalar value.
+ multiline bool // Does the scalar contain line breaks?
+ flow_plain_allowed bool // Can the scalar be expessed in the flow plain style?
+ block_plain_allowed bool // Can the scalar be expressed in the block plain style?
+ single_quoted_allowed bool // Can the scalar be expressed in the single quoted style?
+ block_allowed bool // Can the scalar be expressed in the literal or folded styles?
+ style yaml_scalar_style_t // The output style.
+ }
+
+ // Dumper stuff
+
+ opened bool // If the stream was already opened?
+ closed bool // If the stream was already closed?
+
+ // The information associated with the document nodes.
+ anchors *struct {
+ references int // The number of references.
+ anchor int // The anchor id.
+ serialized bool // If the node has been emitted?
+ }
+
+ last_anchor_id int // The last assigned anchor id.
+
+ document *yaml_document_t // The currently emitted document.
+}
diff --git a/vendor/github.com/coreos/ignition/config/vendor/github.com/go-yaml/yaml/yamlprivateh.go b/vendor/github.com/coreos/ignition/config/vendor/github.com/go-yaml/yaml/yamlprivateh.go
new file mode 100644
index 00000000..8110ce3c
--- /dev/null
+++ b/vendor/github.com/coreos/ignition/config/vendor/github.com/go-yaml/yaml/yamlprivateh.go
@@ -0,0 +1,173 @@
+package yaml
+
+const (
+ // The size of the input raw buffer.
+ input_raw_buffer_size = 512
+
+ // The size of the input buffer.
+ // It should be possible to decode the whole raw buffer.
+ input_buffer_size = input_raw_buffer_size * 3
+
+ // The size of the output buffer.
+ output_buffer_size = 128
+
+ // The size of the output raw buffer.
+ // It should be possible to encode the whole output buffer.
+ output_raw_buffer_size = (output_buffer_size*2 + 2)
+
+ // The size of other stacks and queues.
+ initial_stack_size = 16
+ initial_queue_size = 16
+ initial_string_size = 16
+)
+
+// Check if the character at the specified position is an alphabetical
+// character, a digit, '_', or '-'.
+func is_alpha(b []byte, i int) bool {
+ return b[i] >= '0' && b[i] <= '9' || b[i] >= 'A' && b[i] <= 'Z' || b[i] >= 'a' && b[i] <= 'z' || b[i] == '_' || b[i] == '-'
+}
+
+// Check if the character at the specified position is a digit.
+func is_digit(b []byte, i int) bool {
+ return b[i] >= '0' && b[i] <= '9'
+}
+
+// Get the value of a digit.
+func as_digit(b []byte, i int) int {
+ return int(b[i]) - '0'
+}
+
+// Check if the character at the specified position is a hex-digit.
+func is_hex(b []byte, i int) bool {
+ return b[i] >= '0' && b[i] <= '9' || b[i] >= 'A' && b[i] <= 'F' || b[i] >= 'a' && b[i] <= 'f'
+}
+
+// Get the value of a hex-digit.
+func as_hex(b []byte, i int) int {
+ bi := b[i]
+ if bi >= 'A' && bi <= 'F' {
+ return int(bi) - 'A' + 10
+ }
+ if bi >= 'a' && bi <= 'f' {
+ return int(bi) - 'a' + 10
+ }
+ return int(bi) - '0'
+}
+
+// Check if the character is ASCII.
+func is_ascii(b []byte, i int) bool {
+ return b[i] <= 0x7F
+}
+
+// Check if the character at the start of the buffer can be printed unescaped.
+func is_printable(b []byte, i int) bool {
+ return ((b[i] == 0x0A) || // . == #x0A
+ (b[i] >= 0x20 && b[i] <= 0x7E) || // #x20 <= . <= #x7E
+ (b[i] == 0xC2 && b[i+1] >= 0xA0) || // #0xA0 <= . <= #xD7FF
+ (b[i] > 0xC2 && b[i] < 0xED) ||
+ (b[i] == 0xED && b[i+1] < 0xA0) ||
+ (b[i] == 0xEE) ||
+ (b[i] == 0xEF && // #xE000 <= . <= #xFFFD
+ !(b[i+1] == 0xBB && b[i+2] == 0xBF) && // && . != #xFEFF
+ !(b[i+1] == 0xBF && (b[i+2] == 0xBE || b[i+2] == 0xBF))))
+}
+
+// Check if the character at the specified position is NUL.
+func is_z(b []byte, i int) bool {
+ return b[i] == 0x00
+}
+
+// Check if the beginning of the buffer is a BOM.
+func is_bom(b []byte, i int) bool {
+ return b[0] == 0xEF && b[1] == 0xBB && b[2] == 0xBF
+}
+
+// Check if the character at the specified position is space.
+func is_space(b []byte, i int) bool {
+ return b[i] == ' '
+}
+
+// Check if the character at the specified position is tab.
+func is_tab(b []byte, i int) bool {
+ return b[i] == '\t'
+}
+
+// Check if the character at the specified position is blank (space or tab).
+func is_blank(b []byte, i int) bool {
+ //return is_space(b, i) || is_tab(b, i)
+ return b[i] == ' ' || b[i] == '\t'
+}
+
+// Check if the character at the specified position is a line break.
+func is_break(b []byte, i int) bool {
+ return (b[i] == '\r' || // CR (#xD)
+ b[i] == '\n' || // LF (#xA)
+ b[i] == 0xC2 && b[i+1] == 0x85 || // NEL (#x85)
+ b[i] == 0xE2 && b[i+1] == 0x80 && b[i+2] == 0xA8 || // LS (#x2028)
+ b[i] == 0xE2 && b[i+1] == 0x80 && b[i+2] == 0xA9) // PS (#x2029)
+}
+
+func is_crlf(b []byte, i int) bool {
+ return b[i] == '\r' && b[i+1] == '\n'
+}
+
+// Check if the character is a line break or NUL.
+func is_breakz(b []byte, i int) bool {
+ //return is_break(b, i) || is_z(b, i)
+ return ( // is_break:
+ b[i] == '\r' || // CR (#xD)
+ b[i] == '\n' || // LF (#xA)
+ b[i] == 0xC2 && b[i+1] == 0x85 || // NEL (#x85)
+ b[i] == 0xE2 && b[i+1] == 0x80 && b[i+2] == 0xA8 || // LS (#x2028)
+ b[i] == 0xE2 && b[i+1] == 0x80 && b[i+2] == 0xA9 || // PS (#x2029)
+ // is_z:
+ b[i] == 0)
+}
+
+// Check if the character is a line break, space, or NUL.
+func is_spacez(b []byte, i int) bool {
+ //return is_space(b, i) || is_breakz(b, i)
+ return ( // is_space:
+ b[i] == ' ' ||
+ // is_breakz:
+ b[i] == '\r' || // CR (#xD)
+ b[i] == '\n' || // LF (#xA)
+ b[i] == 0xC2 && b[i+1] == 0x85 || // NEL (#x85)
+ b[i] == 0xE2 && b[i+1] == 0x80 && b[i+2] == 0xA8 || // LS (#x2028)
+ b[i] == 0xE2 && b[i+1] == 0x80 && b[i+2] == 0xA9 || // PS (#x2029)
+ b[i] == 0)
+}
+
+// Check if the character is a line break, space, tab, or NUL.
+func is_blankz(b []byte, i int) bool {
+ //return is_blank(b, i) || is_breakz(b, i)
+ return ( // is_blank:
+ b[i] == ' ' || b[i] == '\t' ||
+ // is_breakz:
+ b[i] == '\r' || // CR (#xD)
+ b[i] == '\n' || // LF (#xA)
+ b[i] == 0xC2 && b[i+1] == 0x85 || // NEL (#x85)
+ b[i] == 0xE2 && b[i+1] == 0x80 && b[i+2] == 0xA8 || // LS (#x2028)
+ b[i] == 0xE2 && b[i+1] == 0x80 && b[i+2] == 0xA9 || // PS (#x2029)
+ b[i] == 0)
+}
+
+// Determine the width of the character.
+func width(b byte) int {
+ // Don't replace these by a switch without first
+ // confirming that it is being inlined.
+ if b&0x80 == 0x00 {
+ return 1
+ }
+ if b&0xE0 == 0xC0 {
+ return 2
+ }
+ if b&0xF0 == 0xE0 {
+ return 3
+ }
+ if b&0xF8 == 0xF0 {
+ return 4
+ }
+ return 0
+
+}
diff --git a/vendor/github.com/coreos/ignition/config/vendor/github.com/vincent-petithory/dataurl/LICENSE b/vendor/github.com/coreos/ignition/config/vendor/github.com/vincent-petithory/dataurl/LICENSE
new file mode 100644
index 00000000..ae6cb62b
--- /dev/null
+++ b/vendor/github.com/coreos/ignition/config/vendor/github.com/vincent-petithory/dataurl/LICENSE
@@ -0,0 +1,20 @@
+The MIT License (MIT)
+
+Copyright (c) 2014 Vincent Petithory
+
+Permission is hereby granted, free of charge, to any person obtaining a copy of
+this software and associated documentation files (the "Software"), to deal in
+the Software without restriction, including without limitation the rights to
+use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of
+the Software, and to permit persons to whom the Software is furnished to do so,
+subject to the following conditions:
+
+The above copyright notice and this permission notice shall be included in all
+copies or substantial portions of the Software.
+
+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS
+FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR
+COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
+IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
+CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
diff --git a/vendor/github.com/coreos/ignition/config/vendor/github.com/vincent-petithory/dataurl/README.md b/vendor/github.com/coreos/ignition/config/vendor/github.com/vincent-petithory/dataurl/README.md
new file mode 100644
index 00000000..1ac59ad2
--- /dev/null
+++ b/vendor/github.com/coreos/ignition/config/vendor/github.com/vincent-petithory/dataurl/README.md
@@ -0,0 +1,81 @@
+# Data URL Schemes for Go [](https://app.wercker.com/project/bykey/6f9a2e144dfcc59e862c52459b452928) [](https://godoc.org/github.com/vincent-petithory/dataurl)
+
+This package parses and generates Data URL Schemes for the Go language, according to [RFC 2397](http://tools.ietf.org/html/rfc2397).
+
+Data URLs are small chunks of data commonly used in browsers to display inline data,
+typically like small images, or when you use the FileReader API of the browser.
+
+Common use-cases:
+
+ * generate a data URL out of a `string`, `[]byte`, `io.Reader` for inclusion in HTML templates,
+ * parse a data URL sent by a browser in a http.Handler, and do something with the data (save to disk, etc.)
+ * ...
+
+Install the package with:
+~~~
+go get github.com/vincent-petithory/dataurl
+~~~
+
+## Usage
+
+~~~ go
+package main
+
+import (
+ "github.com/vincent-petithory/dataurl"
+ "fmt"
+)
+
+func main() {
+ dataURL, err := dataurl.DecodeString(`data:text/plain;charset=utf-8;base64,aGV5YQ==`)
+ if err != nil {
+ fmt.Println(err)
+ return
+ }
+ fmt.Printf("content type: %s, data: %s\n", dataURL.MediaType.ContentType(), string(dataURL.Data))
+ // Output: content type: text/plain, data: heya
+}
+~~~
+
+From a `http.Handler`:
+
+~~~ go
+func handleDataURLUpload(w http.ResponseWriter, r *http.Request) {
+ dataURL, err := dataurl.Decode(r.Body)
+ defer r.Body.Close()
+ if err != nil {
+ http.Error(w, err.Error(), http.StatusBadRequest)
+ return
+ }
+ if dataURL.ContentType() == "image/png" {
+ ioutil.WriteFile("image.png", dataURL.Data, 0644)
+ } else {
+ http.Error(w, "not a png", http.StatusBadRequest)
+ }
+}
+~~~
+
+## Command
+
+For convenience, a `dataurl` command is provided to encode/decode dataurl streams.
+
+~~~
+dataurl - Encode or decode dataurl data and print to standard output
+
+Usage: dataurl [OPTION]... [FILE]
+
+ dataurl encodes or decodes FILE or standard input if FILE is - or omitted, and prints to standard output.
+ Unless -mimetype is used, when FILE is specified, dataurl will attempt to detect its mimetype using Go's mime.TypeByExtension (http://golang.org/pkg/mime/#TypeByExtension). If this fails or data is read from STDIN, the mimetype will default to application/octet-stream.
+
+Options:
+ -a=false: encode data using ascii instead of base64
+ -ascii=false: encode data using ascii instead of base64
+ -d=false: decode data instead of encoding
+ -decode=false: decode data instead of encoding
+ -m="": force the mimetype of the data to encode to this value
+ -mimetype="": force the mimetype of the data to encode to this value
+~~~
+
+## Contributing
+
+Feel free to file an issue/make a pull request if you find any bug, or want to suggest enhancements.
diff --git a/vendor/github.com/coreos/ignition/config/vendor/github.com/vincent-petithory/dataurl/cmd/dataurl/main.go b/vendor/github.com/coreos/ignition/config/vendor/github.com/vincent-petithory/dataurl/cmd/dataurl/main.go
new file mode 100644
index 00000000..cf764c94
--- /dev/null
+++ b/vendor/github.com/coreos/ignition/config/vendor/github.com/vincent-petithory/dataurl/cmd/dataurl/main.go
@@ -0,0 +1,142 @@
+package main
+
+import (
+ "flag"
+ "fmt"
+ "io"
+ "io/ioutil"
+ "log"
+ "mime"
+ "os"
+ "path"
+
+ "github.com/vincent-petithory/dataurl"
+)
+
+var (
+ performDecode bool
+ asciiEncoding bool
+ mimetype string
+)
+
+func init() {
+ const decodeUsage = "decode data instead of encoding"
+ flag.BoolVar(&performDecode, "decode", false, decodeUsage)
+ flag.BoolVar(&performDecode, "d", false, decodeUsage)
+
+ const mimetypeUsage = "force the mimetype of the data to encode to this value"
+ flag.StringVar(&mimetype, "mimetype", "", mimetypeUsage)
+ flag.StringVar(&mimetype, "m", "", mimetypeUsage)
+
+ const asciiUsage = "encode data using ascii instead of base64"
+ flag.BoolVar(&asciiEncoding, "ascii", false, asciiUsage)
+ flag.BoolVar(&asciiEncoding, "a", false, asciiUsage)
+
+ flag.Usage = func() {
+ fmt.Fprint(os.Stderr,
+ `dataurl - Encode or decode dataurl data and print to standard output
+
+Usage: dataurl [OPTION]... [FILE]
+
+ dataurl encodes or decodes FILE or standard input if FILE is - or omitted, and prints to standard output.
+ Unless -mimetype is used, when FILE is specified, dataurl will attempt to detect its mimetype using Go's mime.TypeByExtension (http://golang.org/pkg/mime/#TypeByExtension). If this fails or data is read from STDIN, the mimetype will default to application/octet-stream.
+
+Options:
+`)
+ flag.PrintDefaults()
+ }
+}
+
+func main() {
+ log.SetFlags(0)
+ flag.Parse()
+
+ var (
+ in io.Reader
+ out = os.Stdout
+ encoding = dataurl.EncodingBase64
+ detectedMimetype string
+ )
+ switch n := flag.NArg(); n {
+ case 0:
+ in = os.Stdin
+ case 1:
+ if flag.Arg(0) == "-" {
+ in = os.Stdin
+ return
+ }
+ if f, err := os.Open(flag.Arg(0)); err != nil {
+ log.Fatal(err)
+ } else {
+ in = f
+ defer f.Close()
+ }
+ ext := path.Ext(flag.Arg(0))
+ detectedMimetype = mime.TypeByExtension(ext)
+ }
+
+ switch {
+ case mimetype == "" && detectedMimetype == "":
+ mimetype = "application/octet-stream"
+ case mimetype == "" && detectedMimetype != "":
+ mimetype = detectedMimetype
+ }
+
+ if performDecode {
+ if err := decode(in, out); err != nil {
+ log.Fatal(err)
+ }
+ } else {
+ if asciiEncoding {
+ encoding = dataurl.EncodingASCII
+ }
+ if err := encode(in, out, encoding, mimetype); err != nil {
+ log.Fatal(err)
+ }
+ }
+}
+
+func decode(in io.Reader, out io.Writer) (err error) {
+ defer func() {
+ if e := recover(); e != nil {
+ err = e.(error)
+ }
+ }()
+
+ du, err := dataurl.Decode(in)
+ if err != nil {
+ return
+ }
+
+ _, err = out.Write(du.Data)
+ if err != nil {
+ return
+ }
+ return
+}
+
+func encode(in io.Reader, out io.Writer, encoding string, mediatype string) (err error) {
+ defer func() {
+ if e := recover(); e != nil {
+ var ok bool
+ err, ok = e.(error)
+ if !ok {
+ err = fmt.Errorf("%v", e)
+ }
+ return
+ }
+ }()
+ b, err := ioutil.ReadAll(in)
+ if err != nil {
+ return
+ }
+
+ du := dataurl.New(b, mediatype)
+ du.Encoding = encoding
+
+ _, err = du.WriteTo(out)
+ if err != nil {
+ return
+ }
+ return
+}
diff --git a/vendor/github.com/coreos/ignition/config/vendor/github.com/vincent-petithory/dataurl/dataurl.go b/vendor/github.com/coreos/ignition/config/vendor/github.com/vincent-petithory/dataurl/dataurl.go
new file mode 100644
index 00000000..bfd07654
--- /dev/null
+++ b/vendor/github.com/coreos/ignition/config/vendor/github.com/vincent-petithory/dataurl/dataurl.go
@@ -0,0 +1,280 @@
+package dataurl
+
+import (
+ "bytes"
+ "encoding/base64"
+ "errors"
+ "fmt"
+ "io"
+ "io/ioutil"
+ "net/http"
+ "strconv"
+ "strings"
+)
+
+const (
+ // EncodingBase64 is base64 encoding for the data url
+ EncodingBase64 = "base64"
+ // EncodingASCII is ascii encoding for the data url
+ EncodingASCII = "ascii"
+)
+
+func defaultMediaType() MediaType {
+ return MediaType{
+ "text",
+ "plain",
+ map[string]string{"charset": "US-ASCII"},
+ }
+}
+
+// MediaType is the combination of a media type, a media subtype
+// and optional parameters.
+type MediaType struct {
+ Type string
+ Subtype string
+ Params map[string]string
+}
+
+// ContentType returns the content type of the dataurl's data, in the form type/subtype.
+func (mt *MediaType) ContentType() string {
+ return fmt.Sprintf("%s/%s", mt.Type, mt.Subtype)
+}
+
+// String implements the Stringer interface.
+//
+// Params values are escaped with the Escape function, rather than in a quoted string.
+func (mt *MediaType) String() string {
+ var buf bytes.Buffer
+ for k, v := range mt.Params {
+ fmt.Fprintf(&buf, ";%s=%s", k, EscapeString(v))
+ }
+ return mt.ContentType() + (&buf).String()
+}
+
+// DataURL is the combination of a MediaType describing the type of its Data.
+type DataURL struct {
+ MediaType
+ Encoding string
+ Data []byte
+}
+
+// New returns a new DataURL initialized with data and
+// a MediaType parsed from mediatype and paramPairs.
+// mediatype must be of the form "type/subtype" or it will panic.
+// paramPairs must have an even number of elements or it will panic.
+// For more complex DataURL, initialize a DataURL struct.
+// The DataURL is initialized with base64 encoding.
+func New(data []byte, mediatype string, paramPairs ...string) *DataURL {
+ parts := strings.Split(mediatype, "/")
+ if len(parts) != 2 {
+ panic("dataurl: invalid mediatype")
+ }
+
+ nParams := len(paramPairs)
+ if nParams%2 != 0 {
+ panic("dataurl: requires an even number of param pairs")
+ }
+ params := make(map[string]string)
+ for i := 0; i < nParams; i += 2 {
+ params[paramPairs[i]] = paramPairs[i+1]
+ }
+
+ mt := MediaType{
+ parts[0],
+ parts[1],
+ params,
+ }
+ return &DataURL{
+ MediaType: mt,
+ Encoding: EncodingBase64,
+ Data: data,
+ }
+}
+
+// String implements the Stringer interface.
+//
+// Note: it doesn't guarantee the returned string is equal to
+// the initial source string that was used to create this DataURL.
+// The reasons for that are:
+// * Insertion of default values for MediaType that were maybe not in the initial string,
+// * Various ways to encode the MediaType parameters (quoted string or url encoded string, the latter is used),
+func (du *DataURL) String() string {
+ var buf bytes.Buffer
+ du.WriteTo(&buf)
+ return (&buf).String()
+}
+
+// WriteTo implements the WriterTo interface.
+// See the note about String().
+func (du *DataURL) WriteTo(w io.Writer) (n int64, err error) {
+ var ni int
+ ni, _ = fmt.Fprint(w, "data:")
+ n += int64(ni)
+
+ ni, _ = fmt.Fprint(w, du.MediaType.String())
+ n += int64(ni)
+
+ if du.Encoding == EncodingBase64 {
+ ni, _ = fmt.Fprint(w, ";base64")
+ n += int64(ni)
+ }
+
+ ni, _ = fmt.Fprint(w, ",")
+ n += int64(ni)
+
+ if du.Encoding == EncodingBase64 {
+ encoder := base64.NewEncoder(base64.StdEncoding, w)
+ ni, err = encoder.Write(du.Data)
+ if err != nil {
+ return
+ }
+ encoder.Close()
+ } else if du.Encoding == EncodingASCII {
+ ni, _ = fmt.Fprint(w, Escape(du.Data))
+ n += int64(ni)
+ } else {
+ err = fmt.Errorf("dataurl: invalid encoding %s", du.Encoding)
+ return
+ }
+
+ return
+}
+
+// UnmarshalText decodes a Data URL string and sets it to *du
+func (du *DataURL) UnmarshalText(text []byte) error {
+ decoded, err := DecodeString(string(text))
+ if err != nil {
+ return err
+ }
+ *du = *decoded
+ return nil
+}
+
+// MarshalText writes du as a Data URL
+func (du *DataURL) MarshalText() ([]byte, error) {
+ buf := bytes.NewBuffer(nil)
+ if _, err := du.WriteTo(buf); err != nil {
+ return nil, err
+ }
+ return buf.Bytes(), nil
+}
+
+type encodedDataReader func(string) ([]byte, error)
+
+var asciiDataReader encodedDataReader = func(s string) ([]byte, error) {
+ us, err := Unescape(s)
+ if err != nil {
+ return nil, err
+ }
+ return []byte(us), nil
+}
+
+var base64DataReader encodedDataReader = func(s string) ([]byte, error) {
+ data, err := base64.StdEncoding.DecodeString(s)
+ if err != nil {
+ return nil, err
+ }
+ return []byte(data), nil
+}
+
+type parser struct {
+ du *DataURL
+ l *lexer
+ currentAttr string
+ unquoteParamVal bool
+ encodedDataReaderFn encodedDataReader
+}
+
+func (p *parser) parse() error {
+ for item := range p.l.items {
+ switch item.t {
+ case itemError:
+ return errors.New(item.String())
+ case itemMediaType:
+ p.du.MediaType.Type = item.val
+ // Should we clear the default
+ // "charset" parameter at this point?
+ delete(p.du.MediaType.Params, "charset")
+ case itemMediaSubType:
+ p.du.MediaType.Subtype = item.val
+ case itemParamAttr:
+ p.currentAttr = item.val
+ case itemLeftStringQuote:
+ p.unquoteParamVal = true
+ case itemParamVal:
+ val := item.val
+ if p.unquoteParamVal {
+ p.unquoteParamVal = false
+ us, err := strconv.Unquote("\"" + val + "\"")
+ if err != nil {
+ return err
+ }
+ val = us
+ } else {
+ us, err := UnescapeToString(val)
+ if err != nil {
+ return err
+ }
+ val = us
+ }
+ p.du.MediaType.Params[p.currentAttr] = val
+ case itemBase64Enc:
+ p.du.Encoding = EncodingBase64
+ p.encodedDataReaderFn = base64DataReader
+ case itemDataComma:
+ if p.encodedDataReaderFn == nil {
+ p.encodedDataReaderFn = asciiDataReader
+ }
+ case itemData:
+ reader, err := p.encodedDataReaderFn(item.val)
+ if err != nil {
+ return err
+ }
+ p.du.Data = reader
+ case itemEOF:
+ if p.du.Data == nil {
+ p.du.Data = []byte("")
+ }
+ return nil
+ }
+ }
+ panic("EOF not found")
+}
+
+// DecodeString decodes a Data URL scheme string.
+func DecodeString(s string) (*DataURL, error) {
+ du := &DataURL{
+ MediaType: defaultMediaType(),
+ Encoding: EncodingASCII,
+ }
+
+ parser := &parser{
+ du: du,
+ l: lex(s),
+ }
+ if err := parser.parse(); err != nil {
+ return nil, err
+ }
+ return du, nil
+}
+
+// Decode decodes a Data URL scheme from a io.Reader.
+func Decode(r io.Reader) (*DataURL, error) {
+ data, err := ioutil.ReadAll(r)
+ if err != nil {
+ return nil, err
+ }
+ return DecodeString(string(data))
+}
+
+// EncodeBytes encodes the data bytes into a Data URL string, using base 64 encoding.
+//
+// The media type of data is detected using http.DetectContentType.
+func EncodeBytes(data []byte) string {
+ mt := http.DetectContentType(data)
+ // http.DetectContentType may add spurious spaces between ; and a parameter.
+ // The canonical way is to not have them.
+ cleanedMt := strings.Replace(mt, "; ", ";", -1)
+
+ return New(data, cleanedMt).String()
+}
diff --git a/vendor/github.com/coreos/ignition/config/vendor/github.com/vincent-petithory/dataurl/dataurl_test.go b/vendor/github.com/coreos/ignition/config/vendor/github.com/vincent-petithory/dataurl/dataurl_test.go
new file mode 100644
index 00000000..efff4f34
--- /dev/null
+++ b/vendor/github.com/coreos/ignition/config/vendor/github.com/vincent-petithory/dataurl/dataurl_test.go
@@ -0,0 +1,587 @@
+package dataurl
+
+import (
+ "bytes"
+ "encoding/base64"
+ "fmt"
+ "net/http"
+ "net/http/httptest"
+ "reflect"
+ "regexp"
+ "strings"
+ "testing"
+)
+
+type dataURLTest struct {
+ InputRawDataURL string
+ ExpectedItems []item
+ ExpectedDataURL DataURL
+}
+
+func genTestTable() []dataURLTest {
+ return []dataURLTest{
+ dataURLTest{
+ `data:;base64,aGV5YQ==`,
+ []item{
+ item{itemDataPrefix, dataPrefix},
+ item{itemParamSemicolon, ";"},
+ item{itemBase64Enc, "base64"},
+ item{itemDataComma, ","},
+ item{itemData, "aGV5YQ=="},
+ item{itemEOF, ""},
+ },
+ DataURL{
+ defaultMediaType(),
+ EncodingBase64,
+ []byte("heya"),
+ },
+ },
+ dataURLTest{
+ `data:text/plain;base64,aGV5YQ==`,
+ []item{
+ item{itemDataPrefix, dataPrefix},
+ item{itemMediaType, "text"},
+ item{itemMediaSep, "/"},
+ item{itemMediaSubType, "plain"},
+ item{itemParamSemicolon, ";"},
+ item{itemBase64Enc, "base64"},
+ item{itemDataComma, ","},
+ item{itemData, "aGV5YQ=="},
+ item{itemEOF, ""},
+ },
+ DataURL{
+ MediaType{
+ "text",
+ "plain",
+ map[string]string{},
+ },
+ EncodingBase64,
+ []byte("heya"),
+ },
+ },
+ dataURLTest{
+ `data:text/plain;charset=utf-8;base64,aGV5YQ==`,
+ []item{
+ item{itemDataPrefix, dataPrefix},
+ item{itemMediaType, "text"},
+ item{itemMediaSep, "/"},
+ item{itemMediaSubType, "plain"},
+ item{itemParamSemicolon, ";"},
+ item{itemParamAttr, "charset"},
+ item{itemParamEqual, "="},
+ item{itemParamVal, "utf-8"},
+ item{itemParamSemicolon, ";"},
+ item{itemBase64Enc, "base64"},
+ item{itemDataComma, ","},
+ item{itemData, "aGV5YQ=="},
+ item{itemEOF, ""},
+ },
+ DataURL{
+ MediaType{
+ "text",
+ "plain",
+ map[string]string{
+ "charset": "utf-8",
+ },
+ },
+ EncodingBase64,
+ []byte("heya"),
+ },
+ },
+ dataURLTest{
+ `data:text/plain;charset=utf-8;foo=bar;base64,aGV5YQ==`,
+ []item{
+ item{itemDataPrefix, dataPrefix},
+ item{itemMediaType, "text"},
+ item{itemMediaSep, "/"},
+ item{itemMediaSubType, "plain"},
+ item{itemParamSemicolon, ";"},
+ item{itemParamAttr, "charset"},
+ item{itemParamEqual, "="},
+ item{itemParamVal, "utf-8"},
+ item{itemParamSemicolon, ";"},
+ item{itemParamAttr, "foo"},
+ item{itemParamEqual, "="},
+ item{itemParamVal, "bar"},
+ item{itemParamSemicolon, ";"},
+ item{itemBase64Enc, "base64"},
+ item{itemDataComma, ","},
+ item{itemData, "aGV5YQ=="},
+ item{itemEOF, ""},
+ },
+ DataURL{
+ MediaType{
+ "text",
+ "plain",
+ map[string]string{
+ "charset": "utf-8",
+ "foo": "bar",
+ },
+ },
+ EncodingBase64,
+ []byte("heya"),
+ },
+ },
+ dataURLTest{
+ `data:application/json;charset=utf-8;foo="b\"<@>\"r";style=unformatted%20json;base64,eyJtc2ciOiAiaGV5YSJ9`,
+ []item{
+ item{itemDataPrefix, dataPrefix},
+ item{itemMediaType, "application"},
+ item{itemMediaSep, "/"},
+ item{itemMediaSubType, "json"},
+ item{itemParamSemicolon, ";"},
+ item{itemParamAttr, "charset"},
+ item{itemParamEqual, "="},
+ item{itemParamVal, "utf-8"},
+ item{itemParamSemicolon, ";"},
+ item{itemParamAttr, "foo"},
+ item{itemParamEqual, "="},
+ item{itemLeftStringQuote, "\""},
+ item{itemParamVal, `b\"<@>\"r`},
+ item{itemRightStringQuote, "\""},
+ item{itemParamSemicolon, ";"},
+ item{itemParamAttr, "style"},
+ item{itemParamEqual, "="},
+ item{itemParamVal, "unformatted%20json"},
+ item{itemParamSemicolon, ";"},
+ item{itemBase64Enc, "base64"},
+ item{itemDataComma, ","},
+ item{itemData, "eyJtc2ciOiAiaGV5YSJ9"},
+ item{itemEOF, ""},
+ },
+ DataURL{
+ MediaType{
+ "application",
+ "json",
+ map[string]string{
+ "charset": "utf-8",
+ "foo": `b"<@>"r`,
+ "style": "unformatted json",
+ },
+ },
+ EncodingBase64,
+ []byte(`{"msg": "heya"}`),
+ },
+ },
+ dataURLTest{
+ `data:xxx;base64,aGV5YQ==`,
+ []item{
+ item{itemDataPrefix, dataPrefix},
+ item{itemError, "invalid character for media type"},
+ },
+ DataURL{},
+ },
+ dataURLTest{
+ `data:,`,
+ []item{
+ item{itemDataPrefix, dataPrefix},
+ item{itemDataComma, ","},
+ item{itemEOF, ""},
+ },
+ DataURL{
+ defaultMediaType(),
+ EncodingASCII,
+ []byte(""),
+ },
+ },
+ dataURLTest{
+ `data:,A%20brief%20note`,
+ []item{
+ item{itemDataPrefix, dataPrefix},
+ item{itemDataComma, ","},
+ item{itemData, "A%20brief%20note"},
+ item{itemEOF, ""},
+ },
+ DataURL{
+ defaultMediaType(),
+ EncodingASCII,
+ []byte("A brief note"),
+ },
+ },
+ dataURLTest{
+ `data:image/svg+xml-im.a.fake;base64,cGllLXN0b2NrX1RoaXJ0eQ==`,
+ []item{
+ item{itemDataPrefix, dataPrefix},
+ item{itemMediaType, "image"},
+ item{itemMediaSep, "/"},
+ item{itemMediaSubType, "svg+xml-im.a.fake"},
+ item{itemParamSemicolon, ";"},
+ item{itemBase64Enc, "base64"},
+ item{itemDataComma, ","},
+ item{itemData, "cGllLXN0b2NrX1RoaXJ0eQ=="},
+ item{itemEOF, ""},
+ },
+ DataURL{
+ MediaType{
+ "image",
+ "svg+xml-im.a.fake",
+ map[string]string{},
+ },
+ EncodingBase64,
+ []byte("pie-stock_Thirty"),
+ },
+ },
+ }
+}
+
+func expectItems(expected, actual []item) bool {
+ if len(expected) != len(actual) {
+ return false
+ }
+ for i := range expected {
+ if expected[i].t != actual[i].t {
+ return false
+ }
+ if expected[i].val != actual[i].val {
+ return false
+ }
+ }
+ return true
+}
+
+func equal(du1, du2 *DataURL) (bool, error) {
+ if !reflect.DeepEqual(du1.MediaType, du2.MediaType) {
+ return false, nil
+ }
+ if du1.Encoding != du2.Encoding {
+ return false, nil
+ }
+
+ if du1.Data == nil || du2.Data == nil {
+ return false, fmt.Errorf("nil Data")
+ }
+
+ if !bytes.Equal(du1.Data, du2.Data) {
+ return false, nil
+ }
+ return true, nil
+}
+
+func TestLexDataURLs(t *testing.T) {
+ for _, test := range genTestTable() {
+ l := lex(test.InputRawDataURL)
+ var items []item
+ for item := range l.items {
+ items = append(items, item)
+ }
+ if !expectItems(test.ExpectedItems, items) {
+ t.Errorf("Expected %v, got %v", test.ExpectedItems, items)
+ }
+ }
+}
+
+func testDataURLs(t *testing.T, factory func(string) (*DataURL, error)) {
+ for _, test := range genTestTable() {
+ var expectedItemError string
+ for _, item := range test.ExpectedItems {
+ if item.t == itemError {
+ expectedItemError = item.String()
+ break
+ }
+ }
+ dataURL, err := factory(test.InputRawDataURL)
+ if expectedItemError == "" && err != nil {
+ t.Error(err)
+ continue
+ } else if expectedItemError != "" && err == nil {
+ t.Errorf("Expected error \"%s\", got nil", expectedItemError)
+ continue
+ } else if expectedItemError != "" && err != nil {
+ if err.Error() != expectedItemError {
+ t.Errorf("Expected error \"%s\", got \"%s\"", expectedItemError, err.Error())
+ }
+ continue
+ }
+
+ if ok, err := equal(dataURL, &test.ExpectedDataURL); err != nil {
+ t.Error(err)
+ } else if !ok {
+ t.Errorf("Expected %v, got %v", test.ExpectedDataURL, *dataURL)
+ }
+ }
+}
+
+func TestDataURLsWithDecode(t *testing.T) {
+ testDataURLs(t, func(s string) (*DataURL, error) {
+ return Decode(strings.NewReader(s))
+ })
+}
+
+func TestDataURLsWithDecodeString(t *testing.T) {
+ testDataURLs(t, func(s string) (*DataURL, error) {
+ return DecodeString(s)
+ })
+}
+
+func TestDataURLsWithUnmarshalText(t *testing.T) {
+ testDataURLs(t, func(s string) (*DataURL, error) {
+ d := &DataURL{}
+ err := d.UnmarshalText([]byte(s))
+ return d, err
+ })
+}
+
+func TestRoundTrip(t *testing.T) {
+ tests := []struct {
+ s string
+ roundTripOk bool
+ }{
+ {`data:text/plain;charset=utf-8;foo=bar;base64,aGV5YQ==`, true},
+ {`data:;charset=utf-8;foo=bar;base64,aGV5YQ==`, false},
+ {`data:text/plain;charset=utf-8;foo="bar";base64,aGV5YQ==`, false},
+ {`data:text/plain;charset=utf-8;foo="bar",A%20brief%20note`, false},
+ {`data:text/plain;charset=utf-8;foo=bar,A%20brief%20note`, true},
+ }
+ for _, test := range tests {
+ dataURL, err := DecodeString(test.s)
+ if err != nil {
+ t.Error(err)
+ continue
+ }
+ dus := dataURL.String()
+ if test.roundTripOk && dus != test.s {
+ t.Errorf("Expected %s, got %s", test.s, dus)
+ } else if !test.roundTripOk && dus == test.s {
+ t.Errorf("Found %s, expected something else", test.s)
+ }
+
+ txt, err := dataURL.MarshalText()
+ if err != nil {
+ t.Error(err)
+ continue
+ }
+ if test.roundTripOk && string(txt) != test.s {
+ t.Errorf("MarshalText roundtrip: got '%s', want '%s'", txt, test.s)
+ } else if !test.roundTripOk && string(txt) == test.s {
+ t.Errorf("MarshalText roundtrip: got '%s', want something else", txt)
+ }
+ }
+}
+
+func TestNew(t *testing.T) {
+ tests := []struct {
+ Data []byte
+ MediaType string
+ ParamPairs []string
+ WillPanic bool
+ ExpectedDataURL *DataURL
+ }{
+ {
+ []byte(`{"msg": "heya"}`),
+ "application/json",
+ []string{},
+ false,
+ &DataURL{
+ MediaType{
+ "application",
+ "json",
+ map[string]string{},
+ },
+ EncodingBase64,
+ []byte(`{"msg": "heya"}`),
+ },
+ },
+ {
+ []byte(``),
+ "application//json",
+ []string{},
+ true,
+ nil,
+ },
+ {
+ []byte(``),
+ "",
+ []string{},
+ true,
+ nil,
+ },
+ {
+ []byte(`{"msg": "heya"}`),
+ "text/plain",
+ []string{"charset", "utf-8"},
+ false,
+ &DataURL{
+ MediaType{
+ "text",
+ "plain",
+ map[string]string{
+ "charset": "utf-8",
+ },
+ },
+ EncodingBase64,
+ []byte(`{"msg": "heya"}`),
+ },
+ },
+ {
+ []byte(`{"msg": "heya"}`),
+ "text/plain",
+ []string{"charset", "utf-8", "name"},
+ true,
+ nil,
+ },
+ }
+ for _, test := range tests {
+ var dataURL *DataURL
+ func() {
+ defer func() {
+ if test.WillPanic {
+ if e := recover(); e == nil {
+ t.Error("Expected panic didn't happen")
+ }
+ } else {
+ if e := recover(); e != nil {
+ t.Errorf("Unexpected panic: %v", e)
+ }
+ }
+ }()
+ dataURL = New(test.Data, test.MediaType, test.ParamPairs...)
+ }()
+ if test.WillPanic {
+ if dataURL != nil {
+ t.Error("Expected nil DataURL")
+ }
+ } else {
+ if ok, err := equal(dataURL, test.ExpectedDataURL); err != nil {
+ t.Error(err)
+ } else if !ok {
+ t.Errorf("Expected %v, got %v", test.ExpectedDataURL, *dataURL)
+ }
+ }
+ }
+}
+
+var golangFavicon = strings.Replace(`AAABAAEAEBAAAAEAIABoBAAAFgAAACgAAAAQAAAAIAAAAAEAIAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAD///8AVE44//7hdv/+4Xb//uF2//7hdv/+4Xb//uF2//7hdv/+4Xb//uF2//7hdv/+4Xb/
+/uF2/1ROOP////8A////AFROOP/+4Xb//uF2//7hdv/+4Xb//uF2//7hdv/+4Xb//uF2//7hdv/+
+4Xb//uF2//7hdv9UTjj/////AP///wBUTjj//uF2//7hdv/+4Xb//uF2//7hdv/+4Xb//uF2//7h
+dv/+4Xb//uF2//7hdv/+4Xb/VE44/////wD///8AVE44//7hdv/+4Xb//uF2//7hdv/+4Xb//uF2
+//7hdv/+4Xb//uF2//7hdv/+4Xb//uF2/1ROOP////8A////AFROOP/+4Xb//uF2//7hdv/+4Xb/
+/uF2//7hdv/+4Xb//uF2//7hdv/+4Xb//uF2//7hdv9UTjj/////AP///wBUTjj//uF2//7hdv/+
+4Xb//uF2//7hdv/+4Xb//uF2//7hdv/+4Xb//uF2//7hdv/+4Xb/VE44/////wD///8AVE44//7h
+dv/+4Xb//uF2//7hdv/+4Xb/z7t5/8Kyev/+4Xb//993///dd///3Xf//uF2/1ROOP////8A////
+AFROOP/+4Xb//uF2//7hdv//4Hn/dIzD//v8///7/P//dIzD//7hdv//3Xf//913//7hdv9UTjj/
+////AP///wBUTjj//uF2///fd//+4Xb//uF2/6ajif90jMP/dIzD/46Zpv/+4Xb//+F1///feP/+
+4Xb/VE44/////wD///8AVE44//7hdv/z1XT////////////Is3L/HyAj/x8gI//Is3L/////////
+///z1XT//uF2/1ROOP////8A19nd/1ROOP/+4Xb/5+HS//v+//8RExf/Liwn//7hdv/+4Xb/5+HS
+//v8//8RExf/Liwn//7hdv9UTjj/19nd/1ROOP94aDT/yKdO/+fh0v//////ERMX/y4sJ//+4Xb/
+/uF2/+fh0v//////ERMX/y4sJ//Ip07/dWU3/1ROOP9UTjj/yKdO/6qSSP/Is3L/9fb7//f6///I
+s3L//uF2//7hdv/Is3L////////////Is3L/qpJI/8inTv9UTjj/19nd/1ROOP97c07/qpJI/8in
+Tv/Ip07//uF2//7hdv/+4Xb//uF2/8zBlv/Kv4//pZJU/3tzTv9UTjj/19nd/////wD///8A4eLl
+/6CcjP97c07/e3NO/1dOMf9BOiX/TkUn/2VXLf97c07/e3NO/6CcjP/h4uX/////AP///wD///8A
+////AP///wD///8A////AP///wDq6/H/3N/j/9fZ3f/q6/H/////AP///wD///8A////AP///wD/
+//8AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAA==`, "\n", "", -1)
+
+func TestEncodeBytes(t *testing.T) {
+ mustDecode := func(s string) []byte {
+ data, err := base64.StdEncoding.DecodeString(s)
+ if err != nil {
+ panic(err)
+ }
+ return data
+ }
+ tests := []struct {
+ Data []byte
+ ExpectedString string
+ }{
+ {
+ []byte(`A brief note`),
+ "data:text/plain;charset=utf-8;base64,QSBicmllZiBub3Rl",
+ },
+ {
+ []byte{0xA, 0xFF, 0x99, 0x34, 0x56, 0x34, 0x00},
+ `data:application/octet-stream;base64,Cv+ZNFY0AA==`,
+ },
+ {
+ mustDecode(golangFavicon),
+ `data:image/vnd.microsoft.icon;base64,` + golangFavicon,
+ },
+ }
+ for _, test := range tests {
+ str := EncodeBytes(test.Data)
+ if str != test.ExpectedString {
+ t.Errorf("Expected %s, got %s", test.ExpectedString, str)
+ }
+ }
+}
+
+func BenchmarkLex(b *testing.B) {
+ for i := 0; i < b.N; i++ {
+ for _, test := range genTestTable() {
+ l := lex(test.InputRawDataURL)
+ for _ = range l.items {
+ }
+ }
+ }
+}
+
+const rep = `^data:(?P\w+/[\w\+\-\.]+)?(?P(?:;[\w\-]+="?[\w\-\\<>@,";:%]*"?)+)?(?P;base64)?,(?P.*)$`
+
+func TestRegexp(t *testing.T) {
+ re, err := regexp.Compile(rep)
+ if err != nil {
+ t.Fatal(err)
+ }
+ for _, test := range genTestTable() {
+ shouldMatch := true
+ for _, item := range test.ExpectedItems {
+ if item.t == itemError {
+ shouldMatch = false
+ break
+ }
+ }
+ // just test it matches, do not parse
+ if re.MatchString(test.InputRawDataURL) && !shouldMatch {
+ t.Error("doesn't match", test.InputRawDataURL)
+ } else if !re.MatchString(test.InputRawDataURL) && shouldMatch {
+ t.Error("match", test.InputRawDataURL)
+ }
+ }
+}
+
+func BenchmarkRegexp(b *testing.B) {
+ re, err := regexp.Compile(rep)
+ if err != nil {
+ b.Fatal(err)
+ }
+ for i := 0; i < b.N; i++ {
+ for _, test := range genTestTable() {
+ _ = re.FindStringSubmatch(test.InputRawDataURL)
+ }
+ }
+}
+
+func ExampleDecodeString() {
+ dataURL, err := DecodeString(`data:text/plain;charset=utf-8;base64,aGV5YQ==`)
+ if err != nil {
+ fmt.Println(err)
+ return
+ }
+ fmt.Printf("%s, %s", dataURL.MediaType.ContentType(), string(dataURL.Data))
+ // Output: text/plain, heya
+}
+
+func ExampleDecode() {
+ r, err := http.NewRequest(
+ "POST", "/",
+ strings.NewReader(`data:image/vnd.microsoft.icon;name=golang%20favicon;base64,`+golangFavicon),
+ )
+ if err != nil {
+ fmt.Println(err)
+ return
+ }
+
+ var dataURL *DataURL
+ h := func(w http.ResponseWriter, r *http.Request) {
+ var err error
+ dataURL, err = Decode(r.Body)
+ defer r.Body.Close()
+ if err != nil {
+ fmt.Println(err)
+ }
+ }
+ w := httptest.NewRecorder()
+ h(w, r)
+ fmt.Printf("%s: %s", dataURL.Params["name"], dataURL.ContentType())
+ // Output: golang favicon: image/vnd.microsoft.icon
+}
diff --git a/vendor/github.com/coreos/ignition/config/vendor/github.com/vincent-petithory/dataurl/doc.go b/vendor/github.com/coreos/ignition/config/vendor/github.com/vincent-petithory/dataurl/doc.go
new file mode 100644
index 00000000..56461d04
--- /dev/null
+++ b/vendor/github.com/coreos/ignition/config/vendor/github.com/vincent-petithory/dataurl/doc.go
@@ -0,0 +1,28 @@
+/*
+Package dataurl parses Data URL Schemes
+according to RFC 2397
+(http://tools.ietf.org/html/rfc2397).
+
+Data URLs are small chunks of data commonly used in browsers to display inline data,
+typically like small images, or when you use the FileReader API of the browser.
+
+A dataurl looks like:
+
+ data:text/plain;charset=utf-8,A%20brief%20note
+
+Or, with base64 encoding:
+
+ data:image/vnd.microsoft.icon;name=golang%20favicon;base64,AAABAAEAEBAAAAEAIABoBAAAFgAAACgAAAAQAAAAIAAAAAEAIAAAAAAAAAAAAAAAAAAAAAAAAAAA
+ AAAAAAD///8AVE44//7hdv/+4Xb//uF2//7hdv/+4Xb//uF2//7hdv/+4Xb//uF2//7hdv/+4Xb/
+ /uF2/1ROOP////8A////AFROOP/+4Xb//uF2//7hdv/+4Xb//uF2//7hdv/+4Xb//uF2//7hdv/+
+ ...
+ /6CcjP97c07/e3NO/1dOMf9BOiX/TkUn/2VXLf97c07/e3NO/6CcjP/h4uX/////AP///wD///8A
+ ////AP///wD///8A////AP///wDq6/H/3N/j/9fZ3f/q6/H/////AP///wD///8A////AP///wD/
+ //8AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+ AAAAAAAAAAAAAA==
+
+Common functions are Decode and DecodeString to obtain a DataURL,
+and DataURL.String() and DataURL.WriteTo to generate a Data URL string.
+
+*/
+package dataurl
diff --git a/vendor/github.com/coreos/ignition/config/vendor/github.com/vincent-petithory/dataurl/lex.go b/vendor/github.com/coreos/ignition/config/vendor/github.com/vincent-petithory/dataurl/lex.go
new file mode 100644
index 00000000..1a8717f5
--- /dev/null
+++ b/vendor/github.com/coreos/ignition/config/vendor/github.com/vincent-petithory/dataurl/lex.go
@@ -0,0 +1,521 @@
+package dataurl
+
+import (
+ "fmt"
+ "strings"
+ "unicode"
+ "unicode/utf8"
+)
+
+type item struct {
+ t itemType
+ val string
+}
+
+func (i item) String() string {
+ switch i.t {
+ case itemEOF:
+ return "EOF"
+ case itemError:
+ return i.val
+ }
+ if len(i.val) > 10 {
+ return fmt.Sprintf("%.10q...", i.val)
+ }
+ return fmt.Sprintf("%q", i.val)
+}
+
+type itemType int
+
+const (
+ itemError itemType = iota
+ itemEOF
+
+ itemDataPrefix
+
+ itemMediaType
+ itemMediaSep
+ itemMediaSubType
+ itemParamSemicolon
+ itemParamAttr
+ itemParamEqual
+ itemLeftStringQuote
+ itemRightStringQuote
+ itemParamVal
+
+ itemBase64Enc
+
+ itemDataComma
+ itemData
+)
+
+const eof rune = -1
+
+func isTokenRune(r rune) bool {
+ return r <= unicode.MaxASCII &&
+ !unicode.IsControl(r) &&
+ !unicode.IsSpace(r) &&
+ !isTSpecialRune(r)
+}
+
+func isTSpecialRune(r rune) bool {
+ return r == '(' ||
+ r == ')' ||
+ r == '<' ||
+ r == '>' ||
+ r == '@' ||
+ r == ',' ||
+ r == ';' ||
+ r == ':' ||
+ r == '\\' ||
+ r == '"' ||
+ r == '/' ||
+ r == '[' ||
+ r == ']' ||
+ r == '?' ||
+ r == '='
+}
+
+// See http://tools.ietf.org/html/rfc2045
+// This doesn't include extension-token case
+// as it's handled separatly
+func isDiscreteType(s string) bool {
+ if strings.HasPrefix(s, "text") ||
+ strings.HasPrefix(s, "image") ||
+ strings.HasPrefix(s, "audio") ||
+ strings.HasPrefix(s, "video") ||
+ strings.HasPrefix(s, "application") {
+ return true
+ }
+ return false
+}
+
+// See http://tools.ietf.org/html/rfc2045
+// This doesn't include extension-token case
+// as it's handled separatly
+func isCompositeType(s string) bool {
+ if strings.HasPrefix(s, "message") ||
+ strings.HasPrefix(s, "multipart") {
+ return true
+ }
+ return false
+}
+
+func isURLCharRune(r rune) bool {
+ // We're a bit permissive here,
+ // by not including '%' in delims
+ // This is okay, since url unescaping will validate
+ // that later in the parser.
+ return r <= unicode.MaxASCII &&
+ !(r >= 0x00 && r <= 0x1F) && r != 0x7F && /* control */
+ // delims
+ r != ' ' &&
+ r != '<' &&
+ r != '>' &&
+ r != '#' &&
+ r != '"' &&
+ // unwise
+ r != '{' &&
+ r != '}' &&
+ r != '|' &&
+ r != '\\' &&
+ r != '^' &&
+ r != '[' &&
+ r != ']' &&
+ r != '`'
+}
+
+func isBase64Rune(r rune) bool {
+ return (r >= 'a' && r <= 'z') ||
+ (r >= 'A' && r <= 'Z') ||
+ (r >= '0' && r <= '9') ||
+ r == '+' ||
+ r == '/' ||
+ r == '=' ||
+ r == '\n'
+}
+
+type stateFn func(*lexer) stateFn
+
+// lexer lexes the data URL scheme input string.
+// The implementation is from the text/template/parser package.
+type lexer struct {
+ input string
+ start int
+ pos int
+ width int
+ seenBase64Item bool
+ items chan item
+}
+
+func (l *lexer) run() {
+ for state := lexBeforeDataPrefix; state != nil; {
+ state = state(l)
+ }
+ close(l.items)
+}
+
+func (l *lexer) emit(t itemType) {
+ l.items <- item{t, l.input[l.start:l.pos]}
+ l.start = l.pos
+}
+
+func (l *lexer) next() (r rune) {
+ if l.pos >= len(l.input) {
+ l.width = 0
+ return eof
+ }
+ r, l.width = utf8.DecodeRuneInString(l.input[l.pos:])
+ l.pos += l.width
+ return r
+}
+
+func (l *lexer) backup() {
+ l.pos -= l.width
+}
+
+func (l *lexer) ignore() {
+ l.start = l.pos
+}
+
+func (l *lexer) errorf(format string, args ...interface{}) stateFn {
+ l.items <- item{itemError, fmt.Sprintf(format, args...)}
+ return nil
+}
+
+func lex(input string) *lexer {
+ l := &lexer{
+ input: input,
+ items: make(chan item),
+ }
+ go l.run() // Concurrently run state machine.
+ return l
+}
+
+const (
+ dataPrefix = "data:"
+ mediaSep = '/'
+ paramSemicolon = ';'
+ paramEqual = '='
+ dataComma = ','
+)
+
+// start lexing by detecting data prefix
+func lexBeforeDataPrefix(l *lexer) stateFn {
+ if strings.HasPrefix(l.input[l.pos:], dataPrefix) {
+ return lexDataPrefix
+ }
+ return l.errorf("missing data prefix")
+}
+
+// lex data prefix
+func lexDataPrefix(l *lexer) stateFn {
+ l.pos += len(dataPrefix)
+ l.emit(itemDataPrefix)
+ return lexAfterDataPrefix
+}
+
+// lex what's after data prefix.
+// it can be the media type/subtype separator,
+// the base64 encoding, or the comma preceding the data
+func lexAfterDataPrefix(l *lexer) stateFn {
+ switch r := l.next(); {
+ case r == paramSemicolon:
+ l.backup()
+ return lexParamSemicolon
+ case r == dataComma:
+ l.backup()
+ return lexDataComma
+ case r == eof:
+ return l.errorf("missing comma before data")
+ case r == 'x' || r == 'X':
+ if l.next() == '-' {
+ return lexXTokenMediaType
+ }
+ return lexInDiscreteMediaType
+ case isTokenRune(r):
+ return lexInDiscreteMediaType
+ default:
+ return l.errorf("invalid character after data prefix")
+ }
+}
+
+func lexXTokenMediaType(l *lexer) stateFn {
+ for {
+ switch r := l.next(); {
+ case r == mediaSep:
+ l.backup()
+ return lexMediaType
+ case r == eof:
+ return l.errorf("missing media type slash")
+ case isTokenRune(r):
+ default:
+ return l.errorf("invalid character for media type")
+ }
+ }
+}
+
+func lexInDiscreteMediaType(l *lexer) stateFn {
+ for {
+ switch r := l.next(); {
+ case r == mediaSep:
+ l.backup()
+ // check it's valid discrete type
+ if !isDiscreteType(l.input[l.start:l.pos]) &&
+ !isCompositeType(l.input[l.start:l.pos]) {
+ return l.errorf("invalid media type")
+ }
+ return lexMediaType
+ case r == eof:
+ return l.errorf("missing media type slash")
+ case isTokenRune(r):
+ default:
+ return l.errorf("invalid character for media type")
+ }
+ }
+}
+
+func lexMediaType(l *lexer) stateFn {
+ if l.pos > l.start {
+ l.emit(itemMediaType)
+ }
+ return lexMediaSep
+}
+
+func lexMediaSep(l *lexer) stateFn {
+ l.next()
+ l.emit(itemMediaSep)
+ return lexAfterMediaSep
+}
+
+func lexAfterMediaSep(l *lexer) stateFn {
+ for {
+ switch r := l.next(); {
+ case r == paramSemicolon || r == dataComma:
+ l.backup()
+ return lexMediaSubType
+ case r == eof:
+ return l.errorf("incomplete media type")
+ case isTokenRune(r):
+ default:
+ return l.errorf("invalid character for media subtype")
+ }
+ }
+}
+
+func lexMediaSubType(l *lexer) stateFn {
+ if l.pos > l.start {
+ l.emit(itemMediaSubType)
+ }
+ return lexAfterMediaSubType
+}
+
+func lexAfterMediaSubType(l *lexer) stateFn {
+ switch r := l.next(); {
+ case r == paramSemicolon:
+ l.backup()
+ return lexParamSemicolon
+ case r == dataComma:
+ l.backup()
+ return lexDataComma
+ case r == eof:
+ return l.errorf("missing comma before data")
+ default:
+ return l.errorf("expected semicolon or comma")
+ }
+}
+
+func lexParamSemicolon(l *lexer) stateFn {
+ l.next()
+ l.emit(itemParamSemicolon)
+ return lexAfterParamSemicolon
+}
+
+func lexAfterParamSemicolon(l *lexer) stateFn {
+ switch r := l.next(); {
+ case r == eof:
+ return l.errorf("unterminated parameter sequence")
+ case r == paramEqual || r == dataComma:
+ return l.errorf("unterminated parameter sequence")
+ case isTokenRune(r):
+ l.backup()
+ return lexInParamAttr
+ default:
+ return l.errorf("invalid character for parameter attribute")
+ }
+}
+
+func lexBase64Enc(l *lexer) stateFn {
+ if l.pos > l.start {
+ if v := l.input[l.start:l.pos]; v != "base64" {
+ return l.errorf("expected base64, got %s", v)
+ }
+ l.seenBase64Item = true
+ l.emit(itemBase64Enc)
+ }
+ return lexDataComma
+}
+
+func lexInParamAttr(l *lexer) stateFn {
+ for {
+ switch r := l.next(); {
+ case r == paramEqual:
+ l.backup()
+ return lexParamAttr
+ case r == dataComma:
+ l.backup()
+ return lexBase64Enc
+ case r == eof:
+ return l.errorf("unterminated parameter sequence")
+ case isTokenRune(r):
+ default:
+ return l.errorf("invalid character for parameter attribute")
+ }
+ }
+}
+
+func lexParamAttr(l *lexer) stateFn {
+ if l.pos > l.start {
+ l.emit(itemParamAttr)
+ }
+ return lexParamEqual
+}
+
+func lexParamEqual(l *lexer) stateFn {
+ l.next()
+ l.emit(itemParamEqual)
+ return lexAfterParamEqual
+}
+
+func lexAfterParamEqual(l *lexer) stateFn {
+ switch r := l.next(); {
+ case r == '"':
+ l.emit(itemLeftStringQuote)
+ return lexInQuotedStringParamVal
+ case r == eof:
+ return l.errorf("missing comma before data")
+ case isTokenRune(r):
+ return lexInParamVal
+ default:
+ return l.errorf("invalid character for parameter value")
+ }
+}
+
+func lexInQuotedStringParamVal(l *lexer) stateFn {
+ for {
+ switch r := l.next(); {
+ case r == eof:
+ return l.errorf("unclosed quoted string")
+ case r == '\\':
+ return lexEscapedChar
+ case r == '"':
+ l.backup()
+ return lexQuotedStringParamVal
+ case r <= unicode.MaxASCII:
+ default:
+ return l.errorf("invalid character for parameter value")
+ }
+ }
+}
+
+func lexEscapedChar(l *lexer) stateFn {
+ switch r := l.next(); {
+ case r <= unicode.MaxASCII:
+ return lexInQuotedStringParamVal
+ case r == eof:
+ return l.errorf("unexpected eof")
+ default:
+ return l.errorf("invalid escaped character")
+ }
+}
+
+func lexInParamVal(l *lexer) stateFn {
+ for {
+ switch r := l.next(); {
+ case r == paramSemicolon || r == dataComma:
+ l.backup()
+ return lexParamVal
+ case r == eof:
+ return l.errorf("missing comma before data")
+ case isTokenRune(r):
+ default:
+ return l.errorf("invalid character for parameter value")
+ }
+ }
+}
+
+func lexQuotedStringParamVal(l *lexer) stateFn {
+ if l.pos > l.start {
+ l.emit(itemParamVal)
+ }
+ l.next()
+ l.emit(itemRightStringQuote)
+ return lexAfterParamVal
+}
+
+func lexParamVal(l *lexer) stateFn {
+ if l.pos > l.start {
+ l.emit(itemParamVal)
+ }
+ return lexAfterParamVal
+}
+
+func lexAfterParamVal(l *lexer) stateFn {
+ switch r := l.next(); {
+ case r == paramSemicolon:
+ l.backup()
+ return lexParamSemicolon
+ case r == dataComma:
+ l.backup()
+ return lexDataComma
+ case r == eof:
+ return l.errorf("missing comma before data")
+ default:
+ return l.errorf("expected semicolon or comma")
+ }
+}
+
+func lexDataComma(l *lexer) stateFn {
+ l.next()
+ l.emit(itemDataComma)
+ if l.seenBase64Item {
+ return lexBase64Data
+ }
+ return lexData
+}
+
+func lexData(l *lexer) stateFn {
+Loop:
+ for {
+ switch r := l.next(); {
+ case r == eof:
+ break Loop
+ case isURLCharRune(r):
+ default:
+ return l.errorf("invalid data character")
+ }
+ }
+ if l.pos > l.start {
+ l.emit(itemData)
+ }
+ l.emit(itemEOF)
+ return nil
+}
+
+func lexBase64Data(l *lexer) stateFn {
+Loop:
+ for {
+ switch r := l.next(); {
+ case r == eof:
+ break Loop
+ case isBase64Rune(r):
+ default:
+ return l.errorf("invalid data character")
+ }
+ }
+ if l.pos > l.start {
+ l.emit(itemData)
+ }
+ l.emit(itemEOF)
+ return nil
+}
diff --git a/vendor/github.com/coreos/ignition/config/vendor/github.com/vincent-petithory/dataurl/rfc2396.go b/vendor/github.com/coreos/ignition/config/vendor/github.com/vincent-petithory/dataurl/rfc2396.go
new file mode 100644
index 00000000..e2ea0cac
--- /dev/null
+++ b/vendor/github.com/coreos/ignition/config/vendor/github.com/vincent-petithory/dataurl/rfc2396.go
@@ -0,0 +1,130 @@
+package dataurl
+
+import (
+ "bytes"
+ "fmt"
+ "io"
+ "strings"
+)
+
+// Escape implements URL escaping, as defined in RFC 2397 (http://tools.ietf.org/html/rfc2397).
+// It differs a bit from net/url's QueryEscape and QueryUnescape, e.g how spaces are treated (+ instead of %20):
+//
+// Only ASCII chars are allowed. Reserved chars are escaped to their %xx form.
+// Unreserved chars are [a-z], [A-Z], [0-9], and -_.!~*\().
+func Escape(data []byte) string {
+ var buf = new(bytes.Buffer)
+ for _, b := range data {
+ switch {
+ case isUnreserved(b):
+ buf.WriteByte(b)
+ default:
+ fmt.Fprintf(buf, "%%%02X", b)
+ }
+ }
+ return buf.String()
+}
+
+// EscapeString is like Escape, but taking
+// a string as argument.
+func EscapeString(s string) string {
+ return Escape([]byte(s))
+}
+
+// isUnreserved return true
+// if the byte c is an unreserved char,
+// as defined in RFC 2396.
+func isUnreserved(c byte) bool {
+ return (c >= 'a' && c <= 'z') ||
+ (c >= 'A' && c <= 'Z') ||
+ (c >= '0' && c <= '9') ||
+ c == '-' ||
+ c == '_' ||
+ c == '.' ||
+ c == '!' ||
+ c == '~' ||
+ c == '*' ||
+ c == '\'' ||
+ c == '(' ||
+ c == ')'
+}
+
+func isHex(c byte) bool {
+ switch {
+ case c >= 'a' && c <= 'f':
+ return true
+ case c >= 'A' && c <= 'F':
+ return true
+ case c >= '0' && c <= '9':
+ return true
+ }
+ return false
+}
+
+// borrowed from net/url/url.go
+func unhex(c byte) byte {
+ switch {
+ case '0' <= c && c <= '9':
+ return c - '0'
+ case 'a' <= c && c <= 'f':
+ return c - 'a' + 10
+ case 'A' <= c && c <= 'F':
+ return c - 'A' + 10
+ }
+ return 0
+}
+
+// Unescape unescapes a character sequence
+// escaped with Escape(String?).
+func Unescape(s string) ([]byte, error) {
+ var buf = new(bytes.Buffer)
+ reader := strings.NewReader(s)
+
+ for {
+ r, size, err := reader.ReadRune()
+ if err == io.EOF {
+ break
+ }
+ if err != nil {
+ return nil, err
+ }
+ if size > 1 {
+ return nil, fmt.Errorf("rfc2396: non-ASCII char detected")
+ }
+
+ switch r {
+ case '%':
+ eb1, err := reader.ReadByte()
+ if err == io.EOF {
+ return nil, fmt.Errorf("rfc2396: unexpected end of unescape sequence")
+ }
+ if err != nil {
+ return nil, err
+ }
+ if !isHex(eb1) {
+ return nil, fmt.Errorf("rfc2396: invalid char 0x%x in unescape sequence", r)
+ }
+ eb0, err := reader.ReadByte()
+ if err == io.EOF {
+ return nil, fmt.Errorf("rfc2396: unexpected end of unescape sequence")
+ }
+ if err != nil {
+ return nil, err
+ }
+ if !isHex(eb0) {
+ return nil, fmt.Errorf("rfc2396: invalid char 0x%x in unescape sequence", r)
+ }
+ buf.WriteByte(unhex(eb0) + unhex(eb1)*16)
+ default:
+ buf.WriteByte(byte(r))
+ }
+ }
+ return buf.Bytes(), nil
+}
+
+// UnescapeToString is like Unescape, but returning
+// a string.
+func UnescapeToString(s string) (string, error) {
+ b, err := Unescape(s)
+ return string(b), err
+}
diff --git a/vendor/github.com/coreos/ignition/config/vendor/github.com/vincent-petithory/dataurl/rfc2396_test.go b/vendor/github.com/coreos/ignition/config/vendor/github.com/vincent-petithory/dataurl/rfc2396_test.go
new file mode 100644
index 00000000..45efbaf2
--- /dev/null
+++ b/vendor/github.com/coreos/ignition/config/vendor/github.com/vincent-petithory/dataurl/rfc2396_test.go
@@ -0,0 +1,69 @@
+package dataurl
+
+import (
+ "bytes"
+ "fmt"
+ "testing"
+)
+
+var tests = []struct {
+ escaped string
+ unescaped []byte
+}{
+ {"A%20brief%20note%0A", []byte("A brief note\n")},
+ {"%7B%5B%5Dbyte(%22A%2520brief%2520note%22)%2C%20%5B%5Dbyte(%22A%20brief%20note%22)%7D", []byte(`{[]byte("A%20brief%20note"), []byte("A brief note")}`)},
+}
+
+func TestEscape(t *testing.T) {
+ for _, test := range tests {
+ escaped := Escape(test.unescaped)
+ if string(escaped) != test.escaped {
+ t.Errorf("Expected %s, got %s", test.escaped, string(escaped))
+ }
+ }
+}
+
+func TestUnescape(t *testing.T) {
+ for _, test := range tests {
+ unescaped, err := Unescape(test.escaped)
+ if err != nil {
+ t.Error(err)
+ continue
+ }
+ if !bytes.Equal(unescaped, test.unescaped) {
+ t.Errorf("Expected %s, got %s", test.unescaped, unescaped)
+ }
+ }
+}
+
+func ExampleEscapeString() {
+ fmt.Println(EscapeString("A brief note"))
+ // Output: A%20brief%20note
+}
+
+func ExampleEscape() {
+ fmt.Println(Escape([]byte("A brief note")))
+ // Output: A%20brief%20note
+}
+
+func ExampleUnescape() {
+ data, err := Unescape("A%20brief%20note")
+ if err != nil {
+ // can fail e.g if incorrect escaped sequence
+ fmt.Println(err)
+ return
+ }
+ fmt.Println(string(data))
+ // Output: A brief note
+}
+
+func ExampleUnescapeToString() {
+ s, err := UnescapeToString("A%20brief%20note")
+ if err != nil {
+ // can fail e.g if incorrect escaped sequence
+ fmt.Println(err)
+ return
+ }
+ fmt.Println(s)
+ // Output: A brief note
+}
diff --git a/vendor/github.com/coreos/ignition/config/vendor/github.com/vincent-petithory/dataurl/wercker.yml b/vendor/github.com/coreos/ignition/config/vendor/github.com/vincent-petithory/dataurl/wercker.yml
new file mode 100644
index 00000000..3ab8084c
--- /dev/null
+++ b/vendor/github.com/coreos/ignition/config/vendor/github.com/vincent-petithory/dataurl/wercker.yml
@@ -0,0 +1 @@
+box: wercker/default
\ No newline at end of file
diff --git a/vendor/github.com/coreos/ignition/config/vendor/go4.org/errorutil/highlight.go b/vendor/github.com/coreos/ignition/config/vendor/go4.org/errorutil/highlight.go
new file mode 100644
index 00000000..aace6a46
--- /dev/null
+++ b/vendor/github.com/coreos/ignition/config/vendor/go4.org/errorutil/highlight.go
@@ -0,0 +1,58 @@
+/*
+Copyright 2011 Google Inc.
+
+Licensed under the Apache License, Version 2.0 (the "License");
+you may not use this file except in compliance with the License.
+You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+Unless required by applicable law or agreed to in writing, software
+distributed under the License is distributed on an "AS IS" BASIS,
+WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+See the License for the specific language governing permissions and
+limitations under the License.
+*/
+
+// Package errorutil helps make better error messages.
+package errorutil
+
+import (
+ "bufio"
+ "bytes"
+ "fmt"
+ "io"
+ "strings"
+)
+
+// HighlightBytePosition takes a reader and the location in bytes of a parse
+// error (for instance, from json.SyntaxError.Offset) and returns the line, column,
+// and pretty-printed context around the error with an arrow indicating the exact
+// position of the syntax error.
+func HighlightBytePosition(f io.Reader, pos int64) (line, col int, highlight string) {
+ line = 1
+ br := bufio.NewReader(f)
+ lastLine := ""
+ thisLine := new(bytes.Buffer)
+ for n := int64(0); n < pos; n++ {
+ b, err := br.ReadByte()
+ if err != nil {
+ break
+ }
+ if b == '\n' {
+ lastLine = thisLine.String()
+ thisLine.Reset()
+ line++
+ col = 1
+ } else {
+ col++
+ thisLine.WriteByte(b)
+ }
+ }
+ if line > 1 {
+ highlight += fmt.Sprintf("%5d: %s\n", line-1, lastLine)
+ }
+ highlight += fmt.Sprintf("%5d: %s\n", line, thisLine.String())
+ highlight += fmt.Sprintf("%s^\n", strings.Repeat(" ", col+5))
+ return
+}
diff --git a/vendor/github.com/golang/glog/LICENSE b/vendor/github.com/golang/glog/LICENSE
deleted file mode 100644
index 37ec93a1..00000000
--- a/vendor/github.com/golang/glog/LICENSE
+++ /dev/null
@@ -1,191 +0,0 @@
-Apache License
-Version 2.0, January 2004
-http://www.apache.org/licenses/
-
-TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION
-
-1. Definitions.
-
-"License" shall mean the terms and conditions for use, reproduction, and
-distribution as defined by Sections 1 through 9 of this document.
-
-"Licensor" shall mean the copyright owner or entity authorized by the copyright
-owner that is granting the License.
-
-"Legal Entity" shall mean the union of the acting entity and all other entities
-that control, are controlled by, or are under common control with that entity.
-For the purposes of this definition, "control" means (i) the power, direct or
-indirect, to cause the direction or management of such entity, whether by
-contract or otherwise, or (ii) ownership of fifty percent (50%) or more of the
-outstanding shares, or (iii) beneficial ownership of such entity.
-
-"You" (or "Your") shall mean an individual or Legal Entity exercising
-permissions granted by this License.
-
-"Source" form shall mean the preferred form for making modifications, including
-but not limited to software source code, documentation source, and configuration
-files.
-
-"Object" form shall mean any form resulting from mechanical transformation or
-translation of a Source form, including but not limited to compiled object code,
-generated documentation, and conversions to other media types.
-
-"Work" shall mean the work of authorship, whether in Source or Object form, made
-available under the License, as indicated by a copyright notice that is included
-in or attached to the work (an example is provided in the Appendix below).
-
-"Derivative Works" shall mean any work, whether in Source or Object form, that
-is based on (or derived from) the Work and for which the editorial revisions,
-annotations, elaborations, or other modifications represent, as a whole, an
-original work of authorship. For the purposes of this License, Derivative Works
-shall not include works that remain separable from, or merely link (or bind by
-name) to the interfaces of, the Work and Derivative Works thereof.
-
-"Contribution" shall mean any work of authorship, including the original version
-of the Work and any modifications or additions to that Work or Derivative Works
-thereof, that is intentionally submitted to Licensor for inclusion in the Work
-by the copyright owner or by an individual or Legal Entity authorized to submit
-on behalf of the copyright owner. For the purposes of this definition,
-"submitted" means any form of electronic, verbal, or written communication sent
-to the Licensor or its representatives, including but not limited to
-communication on electronic mailing lists, source code control systems, and
-issue tracking systems that are managed by, or on behalf of, the Licensor for
-the purpose of discussing and improving the Work, but excluding communication
-that is conspicuously marked or otherwise designated in writing by the copyright
-owner as "Not a Contribution."
-
-"Contributor" shall mean Licensor and any individual or Legal Entity on behalf
-of whom a Contribution has been received by Licensor and subsequently
-incorporated within the Work.
-
-2. Grant of Copyright License.
-
-Subject to the terms and conditions of this License, each Contributor hereby
-grants to You a perpetual, worldwide, non-exclusive, no-charge, royalty-free,
-irrevocable copyright license to reproduce, prepare Derivative Works of,
-publicly display, publicly perform, sublicense, and distribute the Work and such
-Derivative Works in Source or Object form.
-
-3. Grant of Patent License.
-
-Subject to the terms and conditions of this License, each Contributor hereby
-grants to You a perpetual, worldwide, non-exclusive, no-charge, royalty-free,
-irrevocable (except as stated in this section) patent license to make, have
-made, use, offer to sell, sell, import, and otherwise transfer the Work, where
-such license applies only to those patent claims licensable by such Contributor
-that are necessarily infringed by their Contribution(s) alone or by combination
-of their Contribution(s) with the Work to which such Contribution(s) was
-submitted. If You institute patent litigation against any entity (including a
-cross-claim or counterclaim in a lawsuit) alleging that the Work or a
-Contribution incorporated within the Work constitutes direct or contributory
-patent infringement, then any patent licenses granted to You under this License
-for that Work shall terminate as of the date such litigation is filed.
-
-4. Redistribution.
-
-You may reproduce and distribute copies of the Work or Derivative Works thereof
-in any medium, with or without modifications, and in Source or Object form,
-provided that You meet the following conditions:
-
-You must give any other recipients of the Work or Derivative Works a copy of
-this License; and
-You must cause any modified files to carry prominent notices stating that You
-changed the files; and
-You must retain, in the Source form of any Derivative Works that You distribute,
-all copyright, patent, trademark, and attribution notices from the Source form
-of the Work, excluding those notices that do not pertain to any part of the
-Derivative Works; and
-If the Work includes a "NOTICE" text file as part of its distribution, then any
-Derivative Works that You distribute must include a readable copy of the
-attribution notices contained within such NOTICE file, excluding those notices
-that do not pertain to any part of the Derivative Works, in at least one of the
-following places: within a NOTICE text file distributed as part of the
-Derivative Works; within the Source form or documentation, if provided along
-with the Derivative Works; or, within a display generated by the Derivative
-Works, if and wherever such third-party notices normally appear. The contents of
-the NOTICE file are for informational purposes only and do not modify the
-License. You may add Your own attribution notices within Derivative Works that
-You distribute, alongside or as an addendum to the NOTICE text from the Work,
-provided that such additional attribution notices cannot be construed as
-modifying the License.
-You may add Your own copyright statement to Your modifications and may provide
-additional or different license terms and conditions for use, reproduction, or
-distribution of Your modifications, or for any such Derivative Works as a whole,
-provided Your use, reproduction, and distribution of the Work otherwise complies
-with the conditions stated in this License.
-
-5. Submission of Contributions.
-
-Unless You explicitly state otherwise, any Contribution intentionally submitted
-for inclusion in the Work by You to the Licensor shall be under the terms and
-conditions of this License, without any additional terms or conditions.
-Notwithstanding the above, nothing herein shall supersede or modify the terms of
-any separate license agreement you may have executed with Licensor regarding
-such Contributions.
-
-6. Trademarks.
-
-This License does not grant permission to use the trade names, trademarks,
-service marks, or product names of the Licensor, except as required for
-reasonable and customary use in describing the origin of the Work and
-reproducing the content of the NOTICE file.
-
-7. Disclaimer of Warranty.
-
-Unless required by applicable law or agreed to in writing, Licensor provides the
-Work (and each Contributor provides its Contributions) on an "AS IS" BASIS,
-WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied,
-including, without limitation, any warranties or conditions of TITLE,
-NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A PARTICULAR PURPOSE. You are
-solely responsible for determining the appropriateness of using or
-redistributing the Work and assume any risks associated with Your exercise of
-permissions under this License.
-
-8. Limitation of Liability.
-
-In no event and under no legal theory, whether in tort (including negligence),
-contract, or otherwise, unless required by applicable law (such as deliberate
-and grossly negligent acts) or agreed to in writing, shall any Contributor be
-liable to You for damages, including any direct, indirect, special, incidental,
-or consequential damages of any character arising as a result of this License or
-out of the use or inability to use the Work (including but not limited to
-damages for loss of goodwill, work stoppage, computer failure or malfunction, or
-any and all other commercial damages or losses), even if such Contributor has
-been advised of the possibility of such damages.
-
-9. Accepting Warranty or Additional Liability.
-
-While redistributing the Work or Derivative Works thereof, You may choose to
-offer, and charge a fee for, acceptance of support, warranty, indemnity, or
-other liability obligations and/or rights consistent with this License. However,
-in accepting such obligations, You may act only on Your own behalf and on Your
-sole responsibility, not on behalf of any other Contributor, and only if You
-agree to indemnify, defend, and hold each Contributor harmless for any liability
-incurred by, or claims asserted against, such Contributor by reason of your
-accepting any such warranty or additional liability.
-
-END OF TERMS AND CONDITIONS
-
-APPENDIX: How to apply the Apache License to your work
-
-To apply the Apache License to your work, attach the following boilerplate
-notice, with the fields enclosed by brackets "[]" replaced with your own
-identifying information. (Don't include the brackets!) The text should be
-enclosed in the appropriate comment syntax for the file format. We also
-recommend that a file or class name and description of purpose be included on
-the same "printed page" as the copyright notice for easier identification within
-third-party archives.
-
- Copyright [yyyy] [name of copyright owner]
-
- Licensed under the Apache License, Version 2.0 (the "License");
- you may not use this file except in compliance with the License.
- You may obtain a copy of the License at
-
- http://www.apache.org/licenses/LICENSE-2.0
-
- Unless required by applicable law or agreed to in writing, software
- distributed under the License is distributed on an "AS IS" BASIS,
- WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- See the License for the specific language governing permissions and
- limitations under the License.
diff --git a/vendor/github.com/golang/glog/README b/vendor/github.com/golang/glog/README
deleted file mode 100644
index 5f9c1148..00000000
--- a/vendor/github.com/golang/glog/README
+++ /dev/null
@@ -1,44 +0,0 @@
-glog
-====
-
-Leveled execution logs for Go.
-
-This is an efficient pure Go implementation of leveled logs in the
-manner of the open source C++ package
- http://code.google.com/p/google-glog
-
-By binding methods to booleans it is possible to use the log package
-without paying the expense of evaluating the arguments to the log.
-Through the -vmodule flag, the package also provides fine-grained
-control over logging at the file level.
-
-The comment from glog.go introduces the ideas:
-
- Package glog implements logging analogous to the Google-internal
- C++ INFO/ERROR/V setup. It provides functions Info, Warning,
- Error, Fatal, plus formatting variants such as Infof. It
- also provides V-style logging controlled by the -v and
- -vmodule=file=2 flags.
-
- Basic examples:
-
- glog.Info("Prepare to repel boarders")
-
- glog.Fatalf("Initialization failed: %s", err)
-
- See the documentation for the V function for an explanation
- of these examples:
-
- if glog.V(2) {
- glog.Info("Starting transaction...")
- }
-
- glog.V(2).Infoln("Processed", nItems, "elements")
-
-
-The repository contains an open source version of the log package
-used inside Google. The master copy of the source lives inside
-Google, not here. The code in this repo is for export only and is not itself
-under development. Feature requests will be ignored.
-
-Send bug reports to golang-nuts@googlegroups.com.
diff --git a/vendor/github.com/golang/glog/glog.go b/vendor/github.com/golang/glog/glog.go
deleted file mode 100644
index 54bd7afd..00000000
--- a/vendor/github.com/golang/glog/glog.go
+++ /dev/null
@@ -1,1180 +0,0 @@
-// Go support for leveled logs, analogous to https://code.google.com/p/google-glog/
-//
-// Copyright 2013 Google Inc. All Rights Reserved.
-//
-// Licensed under the Apache License, Version 2.0 (the "License");
-// you may not use this file except in compliance with the License.
-// You may obtain a copy of the License at
-//
-// http://www.apache.org/licenses/LICENSE-2.0
-//
-// Unless required by applicable law or agreed to in writing, software
-// distributed under the License is distributed on an "AS IS" BASIS,
-// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-// See the License for the specific language governing permissions and
-// limitations under the License.
-
-// Package glog implements logging analogous to the Google-internal C++ INFO/ERROR/V setup.
-// It provides functions Info, Warning, Error, Fatal, plus formatting variants such as
-// Infof. It also provides V-style logging controlled by the -v and -vmodule=file=2 flags.
-//
-// Basic examples:
-//
-// glog.Info("Prepare to repel boarders")
-//
-// glog.Fatalf("Initialization failed: %s", err)
-//
-// See the documentation for the V function for an explanation of these examples:
-//
-// if glog.V(2) {
-// glog.Info("Starting transaction...")
-// }
-//
-// glog.V(2).Infoln("Processed", nItems, "elements")
-//
-// Log output is buffered and written periodically using Flush. Programs
-// should call Flush before exiting to guarantee all log output is written.
-//
-// By default, all log statements write to files in a temporary directory.
-// This package provides several flags that modify this behavior.
-// As a result, flag.Parse must be called before any logging is done.
-//
-// -logtostderr=false
-// Logs are written to standard error instead of to files.
-// -alsologtostderr=false
-// Logs are written to standard error as well as to files.
-// -stderrthreshold=ERROR
-// Log events at or above this severity are logged to standard
-// error as well as to files.
-// -log_dir=""
-// Log files will be written to this directory instead of the
-// default temporary directory.
-//
-// Other flags provide aids to debugging.
-//
-// -log_backtrace_at=""
-// When set to a file and line number holding a logging statement,
-// such as
-// -log_backtrace_at=gopherflakes.go:234
-// a stack trace will be written to the Info log whenever execution
-// hits that statement. (Unlike with -vmodule, the ".go" must be
-// present.)
-// -v=0
-// Enable V-leveled logging at the specified level.
-// -vmodule=""
-// The syntax of the argument is a comma-separated list of pattern=N,
-// where pattern is a literal file name (minus the ".go" suffix) or
-// "glob" pattern and N is a V level. For instance,
-// -vmodule=gopher*=3
-// sets the V level to 3 in all Go files whose names begin "gopher".
-//
-package glog
-
-import (
- "bufio"
- "bytes"
- "errors"
- "flag"
- "fmt"
- "io"
- stdLog "log"
- "os"
- "path/filepath"
- "runtime"
- "strconv"
- "strings"
- "sync"
- "sync/atomic"
- "time"
-)
-
-// severity identifies the sort of log: info, warning etc. It also implements
-// the flag.Value interface. The -stderrthreshold flag is of type severity and
-// should be modified only through the flag.Value interface. The values match
-// the corresponding constants in C++.
-type severity int32 // sync/atomic int32
-
-// These constants identify the log levels in order of increasing severity.
-// A message written to a high-severity log file is also written to each
-// lower-severity log file.
-const (
- infoLog severity = iota
- warningLog
- errorLog
- fatalLog
- numSeverity = 4
-)
-
-const severityChar = "IWEF"
-
-var severityName = []string{
- infoLog: "INFO",
- warningLog: "WARNING",
- errorLog: "ERROR",
- fatalLog: "FATAL",
-}
-
-// get returns the value of the severity.
-func (s *severity) get() severity {
- return severity(atomic.LoadInt32((*int32)(s)))
-}
-
-// set sets the value of the severity.
-func (s *severity) set(val severity) {
- atomic.StoreInt32((*int32)(s), int32(val))
-}
-
-// String is part of the flag.Value interface.
-func (s *severity) String() string {
- return strconv.FormatInt(int64(*s), 10)
-}
-
-// Get is part of the flag.Value interface.
-func (s *severity) Get() interface{} {
- return *s
-}
-
-// Set is part of the flag.Value interface.
-func (s *severity) Set(value string) error {
- var threshold severity
- // Is it a known name?
- if v, ok := severityByName(value); ok {
- threshold = v
- } else {
- v, err := strconv.Atoi(value)
- if err != nil {
- return err
- }
- threshold = severity(v)
- }
- logging.stderrThreshold.set(threshold)
- return nil
-}
-
-func severityByName(s string) (severity, bool) {
- s = strings.ToUpper(s)
- for i, name := range severityName {
- if name == s {
- return severity(i), true
- }
- }
- return 0, false
-}
-
-// OutputStats tracks the number of output lines and bytes written.
-type OutputStats struct {
- lines int64
- bytes int64
-}
-
-// Lines returns the number of lines written.
-func (s *OutputStats) Lines() int64 {
- return atomic.LoadInt64(&s.lines)
-}
-
-// Bytes returns the number of bytes written.
-func (s *OutputStats) Bytes() int64 {
- return atomic.LoadInt64(&s.bytes)
-}
-
-// Stats tracks the number of lines of output and number of bytes
-// per severity level. Values must be read with atomic.LoadInt64.
-var Stats struct {
- Info, Warning, Error OutputStats
-}
-
-var severityStats = [numSeverity]*OutputStats{
- infoLog: &Stats.Info,
- warningLog: &Stats.Warning,
- errorLog: &Stats.Error,
-}
-
-// Level is exported because it appears in the arguments to V and is
-// the type of the v flag, which can be set programmatically.
-// It's a distinct type because we want to discriminate it from logType.
-// Variables of type level are only changed under logging.mu.
-// The -v flag is read only with atomic ops, so the state of the logging
-// module is consistent.
-
-// Level is treated as a sync/atomic int32.
-
-// Level specifies a level of verbosity for V logs. *Level implements
-// flag.Value; the -v flag is of type Level and should be modified
-// only through the flag.Value interface.
-type Level int32
-
-// get returns the value of the Level.
-func (l *Level) get() Level {
- return Level(atomic.LoadInt32((*int32)(l)))
-}
-
-// set sets the value of the Level.
-func (l *Level) set(val Level) {
- atomic.StoreInt32((*int32)(l), int32(val))
-}
-
-// String is part of the flag.Value interface.
-func (l *Level) String() string {
- return strconv.FormatInt(int64(*l), 10)
-}
-
-// Get is part of the flag.Value interface.
-func (l *Level) Get() interface{} {
- return *l
-}
-
-// Set is part of the flag.Value interface.
-func (l *Level) Set(value string) error {
- v, err := strconv.Atoi(value)
- if err != nil {
- return err
- }
- logging.mu.Lock()
- defer logging.mu.Unlock()
- logging.setVState(Level(v), logging.vmodule.filter, false)
- return nil
-}
-
-// moduleSpec represents the setting of the -vmodule flag.
-type moduleSpec struct {
- filter []modulePat
-}
-
-// modulePat contains a filter for the -vmodule flag.
-// It holds a verbosity level and a file pattern to match.
-type modulePat struct {
- pattern string
- literal bool // The pattern is a literal string
- level Level
-}
-
-// match reports whether the file matches the pattern. It uses a string
-// comparison if the pattern contains no metacharacters.
-func (m *modulePat) match(file string) bool {
- if m.literal {
- return file == m.pattern
- }
- match, _ := filepath.Match(m.pattern, file)
- return match
-}
-
-func (m *moduleSpec) String() string {
- // Lock because the type is not atomic. TODO: clean this up.
- logging.mu.Lock()
- defer logging.mu.Unlock()
- var b bytes.Buffer
- for i, f := range m.filter {
- if i > 0 {
- b.WriteRune(',')
- }
- fmt.Fprintf(&b, "%s=%d", f.pattern, f.level)
- }
- return b.String()
-}
-
-// Get is part of the (Go 1.2) flag.Getter interface. It always returns nil for this flag type since the
-// struct is not exported.
-func (m *moduleSpec) Get() interface{} {
- return nil
-}
-
-var errVmoduleSyntax = errors.New("syntax error: expect comma-separated list of filename=N")
-
-// Syntax: -vmodule=recordio=2,file=1,gfs*=3
-func (m *moduleSpec) Set(value string) error {
- var filter []modulePat
- for _, pat := range strings.Split(value, ",") {
- if len(pat) == 0 {
- // Empty strings such as from a trailing comma can be ignored.
- continue
- }
- patLev := strings.Split(pat, "=")
- if len(patLev) != 2 || len(patLev[0]) == 0 || len(patLev[1]) == 0 {
- return errVmoduleSyntax
- }
- pattern := patLev[0]
- v, err := strconv.Atoi(patLev[1])
- if err != nil {
- return errors.New("syntax error: expect comma-separated list of filename=N")
- }
- if v < 0 {
- return errors.New("negative value for vmodule level")
- }
- if v == 0 {
- continue // Ignore. It's harmless but no point in paying the overhead.
- }
- // TODO: check syntax of filter?
- filter = append(filter, modulePat{pattern, isLiteral(pattern), Level(v)})
- }
- logging.mu.Lock()
- defer logging.mu.Unlock()
- logging.setVState(logging.verbosity, filter, true)
- return nil
-}
-
-// isLiteral reports whether the pattern is a literal string, that is, has no metacharacters
-// that require filepath.Match to be called to match the pattern.
-func isLiteral(pattern string) bool {
- return !strings.ContainsAny(pattern, `\*?[]`)
-}
-
-// traceLocation represents the setting of the -log_backtrace_at flag.
-type traceLocation struct {
- file string
- line int
-}
-
-// isSet reports whether the trace location has been specified.
-// logging.mu is held.
-func (t *traceLocation) isSet() bool {
- return t.line > 0
-}
-
-// match reports whether the specified file and line matches the trace location.
-// The argument file name is the full path, not the basename specified in the flag.
-// logging.mu is held.
-func (t *traceLocation) match(file string, line int) bool {
- if t.line != line {
- return false
- }
- if i := strings.LastIndex(file, "/"); i >= 0 {
- file = file[i+1:]
- }
- return t.file == file
-}
-
-func (t *traceLocation) String() string {
- // Lock because the type is not atomic. TODO: clean this up.
- logging.mu.Lock()
- defer logging.mu.Unlock()
- return fmt.Sprintf("%s:%d", t.file, t.line)
-}
-
-// Get is part of the (Go 1.2) flag.Getter interface. It always returns nil for this flag type since the
-// struct is not exported
-func (t *traceLocation) Get() interface{} {
- return nil
-}
-
-var errTraceSyntax = errors.New("syntax error: expect file.go:234")
-
-// Syntax: -log_backtrace_at=gopherflakes.go:234
-// Note that unlike vmodule the file extension is included here.
-func (t *traceLocation) Set(value string) error {
- if value == "" {
- // Unset.
- t.line = 0
- t.file = ""
- }
- fields := strings.Split(value, ":")
- if len(fields) != 2 {
- return errTraceSyntax
- }
- file, line := fields[0], fields[1]
- if !strings.Contains(file, ".") {
- return errTraceSyntax
- }
- v, err := strconv.Atoi(line)
- if err != nil {
- return errTraceSyntax
- }
- if v <= 0 {
- return errors.New("negative or zero value for level")
- }
- logging.mu.Lock()
- defer logging.mu.Unlock()
- t.line = v
- t.file = file
- return nil
-}
-
-// flushSyncWriter is the interface satisfied by logging destinations.
-type flushSyncWriter interface {
- Flush() error
- Sync() error
- io.Writer
-}
-
-func init() {
- flag.BoolVar(&logging.toStderr, "logtostderr", false, "log to standard error instead of files")
- flag.BoolVar(&logging.alsoToStderr, "alsologtostderr", false, "log to standard error as well as files")
- flag.Var(&logging.verbosity, "v", "log level for V logs")
- flag.Var(&logging.stderrThreshold, "stderrthreshold", "logs at or above this threshold go to stderr")
- flag.Var(&logging.vmodule, "vmodule", "comma-separated list of pattern=N settings for file-filtered logging")
- flag.Var(&logging.traceLocation, "log_backtrace_at", "when logging hits line file:N, emit a stack trace")
-
- // Default stderrThreshold is ERROR.
- logging.stderrThreshold = errorLog
-
- logging.setVState(0, nil, false)
- go logging.flushDaemon()
-}
-
-// Flush flushes all pending log I/O.
-func Flush() {
- logging.lockAndFlushAll()
-}
-
-// loggingT collects all the global state of the logging setup.
-type loggingT struct {
- // Boolean flags. Not handled atomically because the flag.Value interface
- // does not let us avoid the =true, and that shorthand is necessary for
- // compatibility. TODO: does this matter enough to fix? Seems unlikely.
- toStderr bool // The -logtostderr flag.
- alsoToStderr bool // The -alsologtostderr flag.
-
- // Level flag. Handled atomically.
- stderrThreshold severity // The -stderrthreshold flag.
-
- // freeList is a list of byte buffers, maintained under freeListMu.
- freeList *buffer
- // freeListMu maintains the free list. It is separate from the main mutex
- // so buffers can be grabbed and printed to without holding the main lock,
- // for better parallelization.
- freeListMu sync.Mutex
-
- // mu protects the remaining elements of this structure and is
- // used to synchronize logging.
- mu sync.Mutex
- // file holds writer for each of the log types.
- file [numSeverity]flushSyncWriter
- // pcs is used in V to avoid an allocation when computing the caller's PC.
- pcs [1]uintptr
- // vmap is a cache of the V Level for each V() call site, identified by PC.
- // It is wiped whenever the vmodule flag changes state.
- vmap map[uintptr]Level
- // filterLength stores the length of the vmodule filter chain. If greater
- // than zero, it means vmodule is enabled. It may be read safely
- // using sync.LoadInt32, but is only modified under mu.
- filterLength int32
- // traceLocation is the state of the -log_backtrace_at flag.
- traceLocation traceLocation
- // These flags are modified only under lock, although verbosity may be fetched
- // safely using atomic.LoadInt32.
- vmodule moduleSpec // The state of the -vmodule flag.
- verbosity Level // V logging level, the value of the -v flag/
-}
-
-// buffer holds a byte Buffer for reuse. The zero value is ready for use.
-type buffer struct {
- bytes.Buffer
- tmp [64]byte // temporary byte array for creating headers.
- next *buffer
-}
-
-var logging loggingT
-
-// setVState sets a consistent state for V logging.
-// l.mu is held.
-func (l *loggingT) setVState(verbosity Level, filter []modulePat, setFilter bool) {
- // Turn verbosity off so V will not fire while we are in transition.
- logging.verbosity.set(0)
- // Ditto for filter length.
- atomic.StoreInt32(&logging.filterLength, 0)
-
- // Set the new filters and wipe the pc->Level map if the filter has changed.
- if setFilter {
- logging.vmodule.filter = filter
- logging.vmap = make(map[uintptr]Level)
- }
-
- // Things are consistent now, so enable filtering and verbosity.
- // They are enabled in order opposite to that in V.
- atomic.StoreInt32(&logging.filterLength, int32(len(filter)))
- logging.verbosity.set(verbosity)
-}
-
-// getBuffer returns a new, ready-to-use buffer.
-func (l *loggingT) getBuffer() *buffer {
- l.freeListMu.Lock()
- b := l.freeList
- if b != nil {
- l.freeList = b.next
- }
- l.freeListMu.Unlock()
- if b == nil {
- b = new(buffer)
- } else {
- b.next = nil
- b.Reset()
- }
- return b
-}
-
-// putBuffer returns a buffer to the free list.
-func (l *loggingT) putBuffer(b *buffer) {
- if b.Len() >= 256 {
- // Let big buffers die a natural death.
- return
- }
- l.freeListMu.Lock()
- b.next = l.freeList
- l.freeList = b
- l.freeListMu.Unlock()
-}
-
-var timeNow = time.Now // Stubbed out for testing.
-
-/*
-header formats a log header as defined by the C++ implementation.
-It returns a buffer containing the formatted header and the user's file and line number.
-The depth specifies how many stack frames above lives the source line to be identified in the log message.
-
-Log lines have this form:
- Lmmdd hh:mm:ss.uuuuuu threadid file:line] msg...
-where the fields are defined as follows:
- L A single character, representing the log level (eg 'I' for INFO)
- mm The month (zero padded; ie May is '05')
- dd The day (zero padded)
- hh:mm:ss.uuuuuu Time in hours, minutes and fractional seconds
- threadid The space-padded thread ID as returned by GetTID()
- file The file name
- line The line number
- msg The user-supplied message
-*/
-func (l *loggingT) header(s severity, depth int) (*buffer, string, int) {
- _, file, line, ok := runtime.Caller(3 + depth)
- if !ok {
- file = "???"
- line = 1
- } else {
- slash := strings.LastIndex(file, "/")
- if slash >= 0 {
- file = file[slash+1:]
- }
- }
- return l.formatHeader(s, file, line), file, line
-}
-
-// formatHeader formats a log header using the provided file name and line number.
-func (l *loggingT) formatHeader(s severity, file string, line int) *buffer {
- now := timeNow()
- if line < 0 {
- line = 0 // not a real line number, but acceptable to someDigits
- }
- if s > fatalLog {
- s = infoLog // for safety.
- }
- buf := l.getBuffer()
-
- // Avoid Fprintf, for speed. The format is so simple that we can do it quickly by hand.
- // It's worth about 3X. Fprintf is hard.
- _, month, day := now.Date()
- hour, minute, second := now.Clock()
- // Lmmdd hh:mm:ss.uuuuuu threadid file:line]
- buf.tmp[0] = severityChar[s]
- buf.twoDigits(1, int(month))
- buf.twoDigits(3, day)
- buf.tmp[5] = ' '
- buf.twoDigits(6, hour)
- buf.tmp[8] = ':'
- buf.twoDigits(9, minute)
- buf.tmp[11] = ':'
- buf.twoDigits(12, second)
- buf.tmp[14] = '.'
- buf.nDigits(6, 15, now.Nanosecond()/1000, '0')
- buf.tmp[21] = ' '
- buf.nDigits(7, 22, pid, ' ') // TODO: should be TID
- buf.tmp[29] = ' '
- buf.Write(buf.tmp[:30])
- buf.WriteString(file)
- buf.tmp[0] = ':'
- n := buf.someDigits(1, line)
- buf.tmp[n+1] = ']'
- buf.tmp[n+2] = ' '
- buf.Write(buf.tmp[:n+3])
- return buf
-}
-
-// Some custom tiny helper functions to print the log header efficiently.
-
-const digits = "0123456789"
-
-// twoDigits formats a zero-prefixed two-digit integer at buf.tmp[i].
-func (buf *buffer) twoDigits(i, d int) {
- buf.tmp[i+1] = digits[d%10]
- d /= 10
- buf.tmp[i] = digits[d%10]
-}
-
-// nDigits formats an n-digit integer at buf.tmp[i],
-// padding with pad on the left.
-// It assumes d >= 0.
-func (buf *buffer) nDigits(n, i, d int, pad byte) {
- j := n - 1
- for ; j >= 0 && d > 0; j-- {
- buf.tmp[i+j] = digits[d%10]
- d /= 10
- }
- for ; j >= 0; j-- {
- buf.tmp[i+j] = pad
- }
-}
-
-// someDigits formats a zero-prefixed variable-width integer at buf.tmp[i].
-func (buf *buffer) someDigits(i, d int) int {
- // Print into the top, then copy down. We know there's space for at least
- // a 10-digit number.
- j := len(buf.tmp)
- for {
- j--
- buf.tmp[j] = digits[d%10]
- d /= 10
- if d == 0 {
- break
- }
- }
- return copy(buf.tmp[i:], buf.tmp[j:])
-}
-
-func (l *loggingT) println(s severity, args ...interface{}) {
- buf, file, line := l.header(s, 0)
- fmt.Fprintln(buf, args...)
- l.output(s, buf, file, line, false)
-}
-
-func (l *loggingT) print(s severity, args ...interface{}) {
- l.printDepth(s, 1, args...)
-}
-
-func (l *loggingT) printDepth(s severity, depth int, args ...interface{}) {
- buf, file, line := l.header(s, depth)
- fmt.Fprint(buf, args...)
- if buf.Bytes()[buf.Len()-1] != '\n' {
- buf.WriteByte('\n')
- }
- l.output(s, buf, file, line, false)
-}
-
-func (l *loggingT) printf(s severity, format string, args ...interface{}) {
- buf, file, line := l.header(s, 0)
- fmt.Fprintf(buf, format, args...)
- if buf.Bytes()[buf.Len()-1] != '\n' {
- buf.WriteByte('\n')
- }
- l.output(s, buf, file, line, false)
-}
-
-// printWithFileLine behaves like print but uses the provided file and line number. If
-// alsoLogToStderr is true, the log message always appears on standard error; it
-// will also appear in the log file unless --logtostderr is set.
-func (l *loggingT) printWithFileLine(s severity, file string, line int, alsoToStderr bool, args ...interface{}) {
- buf := l.formatHeader(s, file, line)
- fmt.Fprint(buf, args...)
- if buf.Bytes()[buf.Len()-1] != '\n' {
- buf.WriteByte('\n')
- }
- l.output(s, buf, file, line, alsoToStderr)
-}
-
-// output writes the data to the log files and releases the buffer.
-func (l *loggingT) output(s severity, buf *buffer, file string, line int, alsoToStderr bool) {
- l.mu.Lock()
- if l.traceLocation.isSet() {
- if l.traceLocation.match(file, line) {
- buf.Write(stacks(false))
- }
- }
- data := buf.Bytes()
- if !flag.Parsed() {
- os.Stderr.Write([]byte("ERROR: logging before flag.Parse: "))
- os.Stderr.Write(data)
- } else if l.toStderr {
- os.Stderr.Write(data)
- } else {
- if alsoToStderr || l.alsoToStderr || s >= l.stderrThreshold.get() {
- os.Stderr.Write(data)
- }
- if l.file[s] == nil {
- if err := l.createFiles(s); err != nil {
- os.Stderr.Write(data) // Make sure the message appears somewhere.
- l.exit(err)
- }
- }
- switch s {
- case fatalLog:
- l.file[fatalLog].Write(data)
- fallthrough
- case errorLog:
- l.file[errorLog].Write(data)
- fallthrough
- case warningLog:
- l.file[warningLog].Write(data)
- fallthrough
- case infoLog:
- l.file[infoLog].Write(data)
- }
- }
- if s == fatalLog {
- // If we got here via Exit rather than Fatal, print no stacks.
- if atomic.LoadUint32(&fatalNoStacks) > 0 {
- l.mu.Unlock()
- timeoutFlush(10 * time.Second)
- os.Exit(1)
- }
- // Dump all goroutine stacks before exiting.
- // First, make sure we see the trace for the current goroutine on standard error.
- // If -logtostderr has been specified, the loop below will do that anyway
- // as the first stack in the full dump.
- if !l.toStderr {
- os.Stderr.Write(stacks(false))
- }
- // Write the stack trace for all goroutines to the files.
- trace := stacks(true)
- logExitFunc = func(error) {} // If we get a write error, we'll still exit below.
- for log := fatalLog; log >= infoLog; log-- {
- if f := l.file[log]; f != nil { // Can be nil if -logtostderr is set.
- f.Write(trace)
- }
- }
- l.mu.Unlock()
- timeoutFlush(10 * time.Second)
- os.Exit(255) // C++ uses -1, which is silly because it's anded with 255 anyway.
- }
- l.putBuffer(buf)
- l.mu.Unlock()
- if stats := severityStats[s]; stats != nil {
- atomic.AddInt64(&stats.lines, 1)
- atomic.AddInt64(&stats.bytes, int64(len(data)))
- }
-}
-
-// timeoutFlush calls Flush and returns when it completes or after timeout
-// elapses, whichever happens first. This is needed because the hooks invoked
-// by Flush may deadlock when glog.Fatal is called from a hook that holds
-// a lock.
-func timeoutFlush(timeout time.Duration) {
- done := make(chan bool, 1)
- go func() {
- Flush() // calls logging.lockAndFlushAll()
- done <- true
- }()
- select {
- case <-done:
- case <-time.After(timeout):
- fmt.Fprintln(os.Stderr, "glog: Flush took longer than", timeout)
- }
-}
-
-// stacks is a wrapper for runtime.Stack that attempts to recover the data for all goroutines.
-func stacks(all bool) []byte {
- // We don't know how big the traces are, so grow a few times if they don't fit. Start large, though.
- n := 10000
- if all {
- n = 100000
- }
- var trace []byte
- for i := 0; i < 5; i++ {
- trace = make([]byte, n)
- nbytes := runtime.Stack(trace, all)
- if nbytes < len(trace) {
- return trace[:nbytes]
- }
- n *= 2
- }
- return trace
-}
-
-// logExitFunc provides a simple mechanism to override the default behavior
-// of exiting on error. Used in testing and to guarantee we reach a required exit
-// for fatal logs. Instead, exit could be a function rather than a method but that
-// would make its use clumsier.
-var logExitFunc func(error)
-
-// exit is called if there is trouble creating or writing log files.
-// It flushes the logs and exits the program; there's no point in hanging around.
-// l.mu is held.
-func (l *loggingT) exit(err error) {
- fmt.Fprintf(os.Stderr, "log: exiting because of error: %s\n", err)
- // If logExitFunc is set, we do that instead of exiting.
- if logExitFunc != nil {
- logExitFunc(err)
- return
- }
- l.flushAll()
- os.Exit(2)
-}
-
-// syncBuffer joins a bufio.Writer to its underlying file, providing access to the
-// file's Sync method and providing a wrapper for the Write method that provides log
-// file rotation. There are conflicting methods, so the file cannot be embedded.
-// l.mu is held for all its methods.
-type syncBuffer struct {
- logger *loggingT
- *bufio.Writer
- file *os.File
- sev severity
- nbytes uint64 // The number of bytes written to this file
-}
-
-func (sb *syncBuffer) Sync() error {
- return sb.file.Sync()
-}
-
-func (sb *syncBuffer) Write(p []byte) (n int, err error) {
- if sb.nbytes+uint64(len(p)) >= MaxSize {
- if err := sb.rotateFile(time.Now()); err != nil {
- sb.logger.exit(err)
- }
- }
- n, err = sb.Writer.Write(p)
- sb.nbytes += uint64(n)
- if err != nil {
- sb.logger.exit(err)
- }
- return
-}
-
-// rotateFile closes the syncBuffer's file and starts a new one.
-func (sb *syncBuffer) rotateFile(now time.Time) error {
- if sb.file != nil {
- sb.Flush()
- sb.file.Close()
- }
- var err error
- sb.file, _, err = create(severityName[sb.sev], now)
- sb.nbytes = 0
- if err != nil {
- return err
- }
-
- sb.Writer = bufio.NewWriterSize(sb.file, bufferSize)
-
- // Write header.
- var buf bytes.Buffer
- fmt.Fprintf(&buf, "Log file created at: %s\n", now.Format("2006/01/02 15:04:05"))
- fmt.Fprintf(&buf, "Running on machine: %s\n", host)
- fmt.Fprintf(&buf, "Binary: Built with %s %s for %s/%s\n", runtime.Compiler, runtime.Version(), runtime.GOOS, runtime.GOARCH)
- fmt.Fprintf(&buf, "Log line format: [IWEF]mmdd hh:mm:ss.uuuuuu threadid file:line] msg\n")
- n, err := sb.file.Write(buf.Bytes())
- sb.nbytes += uint64(n)
- return err
-}
-
-// bufferSize sizes the buffer associated with each log file. It's large
-// so that log records can accumulate without the logging thread blocking
-// on disk I/O. The flushDaemon will block instead.
-const bufferSize = 256 * 1024
-
-// createFiles creates all the log files for severity from sev down to infoLog.
-// l.mu is held.
-func (l *loggingT) createFiles(sev severity) error {
- now := time.Now()
- // Files are created in decreasing severity order, so as soon as we find one
- // has already been created, we can stop.
- for s := sev; s >= infoLog && l.file[s] == nil; s-- {
- sb := &syncBuffer{
- logger: l,
- sev: s,
- }
- if err := sb.rotateFile(now); err != nil {
- return err
- }
- l.file[s] = sb
- }
- return nil
-}
-
-const flushInterval = 30 * time.Second
-
-// flushDaemon periodically flushes the log file buffers.
-func (l *loggingT) flushDaemon() {
- for _ = range time.NewTicker(flushInterval).C {
- l.lockAndFlushAll()
- }
-}
-
-// lockAndFlushAll is like flushAll but locks l.mu first.
-func (l *loggingT) lockAndFlushAll() {
- l.mu.Lock()
- l.flushAll()
- l.mu.Unlock()
-}
-
-// flushAll flushes all the logs and attempts to "sync" their data to disk.
-// l.mu is held.
-func (l *loggingT) flushAll() {
- // Flush from fatal down, in case there's trouble flushing.
- for s := fatalLog; s >= infoLog; s-- {
- file := l.file[s]
- if file != nil {
- file.Flush() // ignore error
- file.Sync() // ignore error
- }
- }
-}
-
-// CopyStandardLogTo arranges for messages written to the Go "log" package's
-// default logs to also appear in the Google logs for the named and lower
-// severities. Subsequent changes to the standard log's default output location
-// or format may break this behavior.
-//
-// Valid names are "INFO", "WARNING", "ERROR", and "FATAL". If the name is not
-// recognized, CopyStandardLogTo panics.
-func CopyStandardLogTo(name string) {
- sev, ok := severityByName(name)
- if !ok {
- panic(fmt.Sprintf("log.CopyStandardLogTo(%q): unrecognized severity name", name))
- }
- // Set a log format that captures the user's file and line:
- // d.go:23: message
- stdLog.SetFlags(stdLog.Lshortfile)
- stdLog.SetOutput(logBridge(sev))
-}
-
-// logBridge provides the Write method that enables CopyStandardLogTo to connect
-// Go's standard logs to the logs provided by this package.
-type logBridge severity
-
-// Write parses the standard logging line and passes its components to the
-// logger for severity(lb).
-func (lb logBridge) Write(b []byte) (n int, err error) {
- var (
- file = "???"
- line = 1
- text string
- )
- // Split "d.go:23: message" into "d.go", "23", and "message".
- if parts := bytes.SplitN(b, []byte{':'}, 3); len(parts) != 3 || len(parts[0]) < 1 || len(parts[2]) < 1 {
- text = fmt.Sprintf("bad log format: %s", b)
- } else {
- file = string(parts[0])
- text = string(parts[2][1:]) // skip leading space
- line, err = strconv.Atoi(string(parts[1]))
- if err != nil {
- text = fmt.Sprintf("bad line number: %s", b)
- line = 1
- }
- }
- // printWithFileLine with alsoToStderr=true, so standard log messages
- // always appear on standard error.
- logging.printWithFileLine(severity(lb), file, line, true, text)
- return len(b), nil
-}
-
-// setV computes and remembers the V level for a given PC
-// when vmodule is enabled.
-// File pattern matching takes the basename of the file, stripped
-// of its .go suffix, and uses filepath.Match, which is a little more
-// general than the *? matching used in C++.
-// l.mu is held.
-func (l *loggingT) setV(pc uintptr) Level {
- fn := runtime.FuncForPC(pc)
- file, _ := fn.FileLine(pc)
- // The file is something like /a/b/c/d.go. We want just the d.
- if strings.HasSuffix(file, ".go") {
- file = file[:len(file)-3]
- }
- if slash := strings.LastIndex(file, "/"); slash >= 0 {
- file = file[slash+1:]
- }
- for _, filter := range l.vmodule.filter {
- if filter.match(file) {
- l.vmap[pc] = filter.level
- return filter.level
- }
- }
- l.vmap[pc] = 0
- return 0
-}
-
-// Verbose is a boolean type that implements Infof (like Printf) etc.
-// See the documentation of V for more information.
-type Verbose bool
-
-// V reports whether verbosity at the call site is at least the requested level.
-// The returned value is a boolean of type Verbose, which implements Info, Infoln
-// and Infof. These methods will write to the Info log if called.
-// Thus, one may write either
-// if glog.V(2) { glog.Info("log this") }
-// or
-// glog.V(2).Info("log this")
-// The second form is shorter but the first is cheaper if logging is off because it does
-// not evaluate its arguments.
-//
-// Whether an individual call to V generates a log record depends on the setting of
-// the -v and --vmodule flags; both are off by default. If the level in the call to
-// V is at least the value of -v, or of -vmodule for the source file containing the
-// call, the V call will log.
-func V(level Level) Verbose {
- // This function tries hard to be cheap unless there's work to do.
- // The fast path is two atomic loads and compares.
-
- // Here is a cheap but safe test to see if V logging is enabled globally.
- if logging.verbosity.get() >= level {
- return Verbose(true)
- }
-
- // It's off globally but it vmodule may still be set.
- // Here is another cheap but safe test to see if vmodule is enabled.
- if atomic.LoadInt32(&logging.filterLength) > 0 {
- // Now we need a proper lock to use the logging structure. The pcs field
- // is shared so we must lock before accessing it. This is fairly expensive,
- // but if V logging is enabled we're slow anyway.
- logging.mu.Lock()
- defer logging.mu.Unlock()
- if runtime.Callers(2, logging.pcs[:]) == 0 {
- return Verbose(false)
- }
- v, ok := logging.vmap[logging.pcs[0]]
- if !ok {
- v = logging.setV(logging.pcs[0])
- }
- return Verbose(v >= level)
- }
- return Verbose(false)
-}
-
-// Info is equivalent to the global Info function, guarded by the value of v.
-// See the documentation of V for usage.
-func (v Verbose) Info(args ...interface{}) {
- if v {
- logging.print(infoLog, args...)
- }
-}
-
-// Infoln is equivalent to the global Infoln function, guarded by the value of v.
-// See the documentation of V for usage.
-func (v Verbose) Infoln(args ...interface{}) {
- if v {
- logging.println(infoLog, args...)
- }
-}
-
-// Infof is equivalent to the global Infof function, guarded by the value of v.
-// See the documentation of V for usage.
-func (v Verbose) Infof(format string, args ...interface{}) {
- if v {
- logging.printf(infoLog, format, args...)
- }
-}
-
-// Info logs to the INFO log.
-// Arguments are handled in the manner of fmt.Print; a newline is appended if missing.
-func Info(args ...interface{}) {
- logging.print(infoLog, args...)
-}
-
-// InfoDepth acts as Info but uses depth to determine which call frame to log.
-// InfoDepth(0, "msg") is the same as Info("msg").
-func InfoDepth(depth int, args ...interface{}) {
- logging.printDepth(infoLog, depth, args...)
-}
-
-// Infoln logs to the INFO log.
-// Arguments are handled in the manner of fmt.Println; a newline is appended if missing.
-func Infoln(args ...interface{}) {
- logging.println(infoLog, args...)
-}
-
-// Infof logs to the INFO log.
-// Arguments are handled in the manner of fmt.Printf; a newline is appended if missing.
-func Infof(format string, args ...interface{}) {
- logging.printf(infoLog, format, args...)
-}
-
-// Warning logs to the WARNING and INFO logs.
-// Arguments are handled in the manner of fmt.Print; a newline is appended if missing.
-func Warning(args ...interface{}) {
- logging.print(warningLog, args...)
-}
-
-// WarningDepth acts as Warning but uses depth to determine which call frame to log.
-// WarningDepth(0, "msg") is the same as Warning("msg").
-func WarningDepth(depth int, args ...interface{}) {
- logging.printDepth(warningLog, depth, args...)
-}
-
-// Warningln logs to the WARNING and INFO logs.
-// Arguments are handled in the manner of fmt.Println; a newline is appended if missing.
-func Warningln(args ...interface{}) {
- logging.println(warningLog, args...)
-}
-
-// Warningf logs to the WARNING and INFO logs.
-// Arguments are handled in the manner of fmt.Printf; a newline is appended if missing.
-func Warningf(format string, args ...interface{}) {
- logging.printf(warningLog, format, args...)
-}
-
-// Error logs to the ERROR, WARNING, and INFO logs.
-// Arguments are handled in the manner of fmt.Print; a newline is appended if missing.
-func Error(args ...interface{}) {
- logging.print(errorLog, args...)
-}
-
-// ErrorDepth acts as Error but uses depth to determine which call frame to log.
-// ErrorDepth(0, "msg") is the same as Error("msg").
-func ErrorDepth(depth int, args ...interface{}) {
- logging.printDepth(errorLog, depth, args...)
-}
-
-// Errorln logs to the ERROR, WARNING, and INFO logs.
-// Arguments are handled in the manner of fmt.Println; a newline is appended if missing.
-func Errorln(args ...interface{}) {
- logging.println(errorLog, args...)
-}
-
-// Errorf logs to the ERROR, WARNING, and INFO logs.
-// Arguments are handled in the manner of fmt.Printf; a newline is appended if missing.
-func Errorf(format string, args ...interface{}) {
- logging.printf(errorLog, format, args...)
-}
-
-// Fatal logs to the FATAL, ERROR, WARNING, and INFO logs,
-// including a stack trace of all running goroutines, then calls os.Exit(255).
-// Arguments are handled in the manner of fmt.Print; a newline is appended if missing.
-func Fatal(args ...interface{}) {
- logging.print(fatalLog, args...)
-}
-
-// FatalDepth acts as Fatal but uses depth to determine which call frame to log.
-// FatalDepth(0, "msg") is the same as Fatal("msg").
-func FatalDepth(depth int, args ...interface{}) {
- logging.printDepth(fatalLog, depth, args...)
-}
-
-// Fatalln logs to the FATAL, ERROR, WARNING, and INFO logs,
-// including a stack trace of all running goroutines, then calls os.Exit(255).
-// Arguments are handled in the manner of fmt.Println; a newline is appended if missing.
-func Fatalln(args ...interface{}) {
- logging.println(fatalLog, args...)
-}
-
-// Fatalf logs to the FATAL, ERROR, WARNING, and INFO logs,
-// including a stack trace of all running goroutines, then calls os.Exit(255).
-// Arguments are handled in the manner of fmt.Printf; a newline is appended if missing.
-func Fatalf(format string, args ...interface{}) {
- logging.printf(fatalLog, format, args...)
-}
-
-// fatalNoStacks is non-zero if we are to exit without dumping goroutine stacks.
-// It allows Exit and relatives to use the Fatal logs.
-var fatalNoStacks uint32
-
-// Exit logs to the FATAL, ERROR, WARNING, and INFO logs, then calls os.Exit(1).
-// Arguments are handled in the manner of fmt.Print; a newline is appended if missing.
-func Exit(args ...interface{}) {
- atomic.StoreUint32(&fatalNoStacks, 1)
- logging.print(fatalLog, args...)
-}
-
-// ExitDepth acts as Exit but uses depth to determine which call frame to log.
-// ExitDepth(0, "msg") is the same as Exit("msg").
-func ExitDepth(depth int, args ...interface{}) {
- atomic.StoreUint32(&fatalNoStacks, 1)
- logging.printDepth(fatalLog, depth, args...)
-}
-
-// Exitln logs to the FATAL, ERROR, WARNING, and INFO logs, then calls os.Exit(1).
-func Exitln(args ...interface{}) {
- atomic.StoreUint32(&fatalNoStacks, 1)
- logging.println(fatalLog, args...)
-}
-
-// Exitf logs to the FATAL, ERROR, WARNING, and INFO logs, then calls os.Exit(1).
-// Arguments are handled in the manner of fmt.Printf; a newline is appended if missing.
-func Exitf(format string, args ...interface{}) {
- atomic.StoreUint32(&fatalNoStacks, 1)
- logging.printf(fatalLog, format, args...)
-}
diff --git a/vendor/github.com/golang/glog/glog_file.go b/vendor/github.com/golang/glog/glog_file.go
deleted file mode 100644
index 65075d28..00000000
--- a/vendor/github.com/golang/glog/glog_file.go
+++ /dev/null
@@ -1,124 +0,0 @@
-// Go support for leveled logs, analogous to https://code.google.com/p/google-glog/
-//
-// Copyright 2013 Google Inc. All Rights Reserved.
-//
-// Licensed under the Apache License, Version 2.0 (the "License");
-// you may not use this file except in compliance with the License.
-// You may obtain a copy of the License at
-//
-// http://www.apache.org/licenses/LICENSE-2.0
-//
-// Unless required by applicable law or agreed to in writing, software
-// distributed under the License is distributed on an "AS IS" BASIS,
-// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-// See the License for the specific language governing permissions and
-// limitations under the License.
-
-// File I/O for logs.
-
-package glog
-
-import (
- "errors"
- "flag"
- "fmt"
- "os"
- "os/user"
- "path/filepath"
- "strings"
- "sync"
- "time"
-)
-
-// MaxSize is the maximum size of a log file in bytes.
-var MaxSize uint64 = 1024 * 1024 * 1800
-
-// logDirs lists the candidate directories for new log files.
-var logDirs []string
-
-// If non-empty, overrides the choice of directory in which to write logs.
-// See createLogDirs for the full list of possible destinations.
-var logDir = flag.String("log_dir", "", "If non-empty, write log files in this directory")
-
-func createLogDirs() {
- if *logDir != "" {
- logDirs = append(logDirs, *logDir)
- }
- logDirs = append(logDirs, os.TempDir())
-}
-
-var (
- pid = os.Getpid()
- program = filepath.Base(os.Args[0])
- host = "unknownhost"
- userName = "unknownuser"
-)
-
-func init() {
- h, err := os.Hostname()
- if err == nil {
- host = shortHostname(h)
- }
-
- current, err := user.Current()
- if err == nil {
- userName = current.Username
- }
-
- // Sanitize userName since it may contain filepath separators on Windows.
- userName = strings.Replace(userName, `\`, "_", -1)
-}
-
-// shortHostname returns its argument, truncating at the first period.
-// For instance, given "www.google.com" it returns "www".
-func shortHostname(hostname string) string {
- if i := strings.Index(hostname, "."); i >= 0 {
- return hostname[:i]
- }
- return hostname
-}
-
-// logName returns a new log file name containing tag, with start time t, and
-// the name for the symlink for tag.
-func logName(tag string, t time.Time) (name, link string) {
- name = fmt.Sprintf("%s.%s.%s.log.%s.%04d%02d%02d-%02d%02d%02d.%d",
- program,
- host,
- userName,
- tag,
- t.Year(),
- t.Month(),
- t.Day(),
- t.Hour(),
- t.Minute(),
- t.Second(),
- pid)
- return name, program + "." + tag
-}
-
-var onceLogDirs sync.Once
-
-// create creates a new log file and returns the file and its filename, which
-// contains tag ("INFO", "FATAL", etc.) and t. If the file is created
-// successfully, create also attempts to update the symlink for that tag, ignoring
-// errors.
-func create(tag string, t time.Time) (f *os.File, filename string, err error) {
- onceLogDirs.Do(createLogDirs)
- if len(logDirs) == 0 {
- return nil, "", errors.New("log: no log dirs")
- }
- name, link := logName(tag, t)
- var lastErr error
- for _, dir := range logDirs {
- fname := filepath.Join(dir, name)
- f, err := os.Create(fname)
- if err == nil {
- symlink := filepath.Join(dir, link)
- os.Remove(symlink) // ignore err
- os.Symlink(name, symlink) // ignore err
- return f, fname, nil
- }
- lastErr = err
- }
- return nil, "", fmt.Errorf("log: cannot create log: %v", lastErr)
-}
diff --git a/vendor/github.com/golang/glog/glog_test.go b/vendor/github.com/golang/glog/glog_test.go
deleted file mode 100644
index 0fb376e1..00000000
--- a/vendor/github.com/golang/glog/glog_test.go
+++ /dev/null
@@ -1,415 +0,0 @@
-// Go support for leveled logs, analogous to https://code.google.com/p/google-glog/
-//
-// Copyright 2013 Google Inc. All Rights Reserved.
-//
-// Licensed under the Apache License, Version 2.0 (the "License");
-// you may not use this file except in compliance with the License.
-// You may obtain a copy of the License at
-//
-// http://www.apache.org/licenses/LICENSE-2.0
-//
-// Unless required by applicable law or agreed to in writing, software
-// distributed under the License is distributed on an "AS IS" BASIS,
-// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-// See the License for the specific language governing permissions and
-// limitations under the License.
-
-package glog
-
-import (
- "bytes"
- "fmt"
- stdLog "log"
- "path/filepath"
- "runtime"
- "strconv"
- "strings"
- "testing"
- "time"
-)
-
-// Test that shortHostname works as advertised.
-func TestShortHostname(t *testing.T) {
- for hostname, expect := range map[string]string{
- "": "",
- "host": "host",
- "host.google.com": "host",
- } {
- if got := shortHostname(hostname); expect != got {
- t.Errorf("shortHostname(%q): expected %q, got %q", hostname, expect, got)
- }
- }
-}
-
-// flushBuffer wraps a bytes.Buffer to satisfy flushSyncWriter.
-type flushBuffer struct {
- bytes.Buffer
-}
-
-func (f *flushBuffer) Flush() error {
- return nil
-}
-
-func (f *flushBuffer) Sync() error {
- return nil
-}
-
-// swap sets the log writers and returns the old array.
-func (l *loggingT) swap(writers [numSeverity]flushSyncWriter) (old [numSeverity]flushSyncWriter) {
- l.mu.Lock()
- defer l.mu.Unlock()
- old = l.file
- for i, w := range writers {
- logging.file[i] = w
- }
- return
-}
-
-// newBuffers sets the log writers to all new byte buffers and returns the old array.
-func (l *loggingT) newBuffers() [numSeverity]flushSyncWriter {
- return l.swap([numSeverity]flushSyncWriter{new(flushBuffer), new(flushBuffer), new(flushBuffer), new(flushBuffer)})
-}
-
-// contents returns the specified log value as a string.
-func contents(s severity) string {
- return logging.file[s].(*flushBuffer).String()
-}
-
-// contains reports whether the string is contained in the log.
-func contains(s severity, str string, t *testing.T) bool {
- return strings.Contains(contents(s), str)
-}
-
-// setFlags configures the logging flags how the test expects them.
-func setFlags() {
- logging.toStderr = false
-}
-
-// Test that Info works as advertised.
-func TestInfo(t *testing.T) {
- setFlags()
- defer logging.swap(logging.newBuffers())
- Info("test")
- if !contains(infoLog, "I", t) {
- t.Errorf("Info has wrong character: %q", contents(infoLog))
- }
- if !contains(infoLog, "test", t) {
- t.Error("Info failed")
- }
-}
-
-func TestInfoDepth(t *testing.T) {
- setFlags()
- defer logging.swap(logging.newBuffers())
-
- f := func() { InfoDepth(1, "depth-test1") }
-
- // The next three lines must stay together
- _, _, wantLine, _ := runtime.Caller(0)
- InfoDepth(0, "depth-test0")
- f()
-
- msgs := strings.Split(strings.TrimSuffix(contents(infoLog), "\n"), "\n")
- if len(msgs) != 2 {
- t.Fatalf("Got %d lines, expected 2", len(msgs))
- }
-
- for i, m := range msgs {
- if !strings.HasPrefix(m, "I") {
- t.Errorf("InfoDepth[%d] has wrong character: %q", i, m)
- }
- w := fmt.Sprintf("depth-test%d", i)
- if !strings.Contains(m, w) {
- t.Errorf("InfoDepth[%d] missing %q: %q", i, w, m)
- }
-
- // pull out the line number (between : and ])
- msg := m[strings.LastIndex(m, ":")+1:]
- x := strings.Index(msg, "]")
- if x < 0 {
- t.Errorf("InfoDepth[%d]: missing ']': %q", i, m)
- continue
- }
- line, err := strconv.Atoi(msg[:x])
- if err != nil {
- t.Errorf("InfoDepth[%d]: bad line number: %q", i, m)
- continue
- }
- wantLine++
- if wantLine != line {
- t.Errorf("InfoDepth[%d]: got line %d, want %d", i, line, wantLine)
- }
- }
-}
-
-func init() {
- CopyStandardLogTo("INFO")
-}
-
-// Test that CopyStandardLogTo panics on bad input.
-func TestCopyStandardLogToPanic(t *testing.T) {
- defer func() {
- if s, ok := recover().(string); !ok || !strings.Contains(s, "LOG") {
- t.Errorf(`CopyStandardLogTo("LOG") should have panicked: %v`, s)
- }
- }()
- CopyStandardLogTo("LOG")
-}
-
-// Test that using the standard log package logs to INFO.
-func TestStandardLog(t *testing.T) {
- setFlags()
- defer logging.swap(logging.newBuffers())
- stdLog.Print("test")
- if !contains(infoLog, "I", t) {
- t.Errorf("Info has wrong character: %q", contents(infoLog))
- }
- if !contains(infoLog, "test", t) {
- t.Error("Info failed")
- }
-}
-
-// Test that the header has the correct format.
-func TestHeader(t *testing.T) {
- setFlags()
- defer logging.swap(logging.newBuffers())
- defer func(previous func() time.Time) { timeNow = previous }(timeNow)
- timeNow = func() time.Time {
- return time.Date(2006, 1, 2, 15, 4, 5, .067890e9, time.Local)
- }
- pid = 1234
- Info("test")
- var line int
- format := "I0102 15:04:05.067890 1234 glog_test.go:%d] test\n"
- n, err := fmt.Sscanf(contents(infoLog), format, &line)
- if n != 1 || err != nil {
- t.Errorf("log format error: %d elements, error %s:\n%s", n, err, contents(infoLog))
- }
- // Scanf treats multiple spaces as equivalent to a single space,
- // so check for correct space-padding also.
- want := fmt.Sprintf(format, line)
- if contents(infoLog) != want {
- t.Errorf("log format error: got:\n\t%q\nwant:\t%q", contents(infoLog), want)
- }
-}
-
-// Test that an Error log goes to Warning and Info.
-// Even in the Info log, the source character will be E, so the data should
-// all be identical.
-func TestError(t *testing.T) {
- setFlags()
- defer logging.swap(logging.newBuffers())
- Error("test")
- if !contains(errorLog, "E", t) {
- t.Errorf("Error has wrong character: %q", contents(errorLog))
- }
- if !contains(errorLog, "test", t) {
- t.Error("Error failed")
- }
- str := contents(errorLog)
- if !contains(warningLog, str, t) {
- t.Error("Warning failed")
- }
- if !contains(infoLog, str, t) {
- t.Error("Info failed")
- }
-}
-
-// Test that a Warning log goes to Info.
-// Even in the Info log, the source character will be W, so the data should
-// all be identical.
-func TestWarning(t *testing.T) {
- setFlags()
- defer logging.swap(logging.newBuffers())
- Warning("test")
- if !contains(warningLog, "W", t) {
- t.Errorf("Warning has wrong character: %q", contents(warningLog))
- }
- if !contains(warningLog, "test", t) {
- t.Error("Warning failed")
- }
- str := contents(warningLog)
- if !contains(infoLog, str, t) {
- t.Error("Info failed")
- }
-}
-
-// Test that a V log goes to Info.
-func TestV(t *testing.T) {
- setFlags()
- defer logging.swap(logging.newBuffers())
- logging.verbosity.Set("2")
- defer logging.verbosity.Set("0")
- V(2).Info("test")
- if !contains(infoLog, "I", t) {
- t.Errorf("Info has wrong character: %q", contents(infoLog))
- }
- if !contains(infoLog, "test", t) {
- t.Error("Info failed")
- }
-}
-
-// Test that a vmodule enables a log in this file.
-func TestVmoduleOn(t *testing.T) {
- setFlags()
- defer logging.swap(logging.newBuffers())
- logging.vmodule.Set("glog_test=2")
- defer logging.vmodule.Set("")
- if !V(1) {
- t.Error("V not enabled for 1")
- }
- if !V(2) {
- t.Error("V not enabled for 2")
- }
- if V(3) {
- t.Error("V enabled for 3")
- }
- V(2).Info("test")
- if !contains(infoLog, "I", t) {
- t.Errorf("Info has wrong character: %q", contents(infoLog))
- }
- if !contains(infoLog, "test", t) {
- t.Error("Info failed")
- }
-}
-
-// Test that a vmodule of another file does not enable a log in this file.
-func TestVmoduleOff(t *testing.T) {
- setFlags()
- defer logging.swap(logging.newBuffers())
- logging.vmodule.Set("notthisfile=2")
- defer logging.vmodule.Set("")
- for i := 1; i <= 3; i++ {
- if V(Level(i)) {
- t.Errorf("V enabled for %d", i)
- }
- }
- V(2).Info("test")
- if contents(infoLog) != "" {
- t.Error("V logged incorrectly")
- }
-}
-
-// vGlobs are patterns that match/don't match this file at V=2.
-var vGlobs = map[string]bool{
- // Easy to test the numeric match here.
- "glog_test=1": false, // If -vmodule sets V to 1, V(2) will fail.
- "glog_test=2": true,
- "glog_test=3": true, // If -vmodule sets V to 1, V(3) will succeed.
- // These all use 2 and check the patterns. All are true.
- "*=2": true,
- "?l*=2": true,
- "????_*=2": true,
- "??[mno]?_*t=2": true,
- // These all use 2 and check the patterns. All are false.
- "*x=2": false,
- "m*=2": false,
- "??_*=2": false,
- "?[abc]?_*t=2": false,
-}
-
-// Test that vmodule globbing works as advertised.
-func testVmoduleGlob(pat string, match bool, t *testing.T) {
- setFlags()
- defer logging.swap(logging.newBuffers())
- defer logging.vmodule.Set("")
- logging.vmodule.Set(pat)
- if V(2) != Verbose(match) {
- t.Errorf("incorrect match for %q: got %t expected %t", pat, V(2), match)
- }
-}
-
-// Test that a vmodule globbing works as advertised.
-func TestVmoduleGlob(t *testing.T) {
- for glob, match := range vGlobs {
- testVmoduleGlob(glob, match, t)
- }
-}
-
-func TestRollover(t *testing.T) {
- setFlags()
- var err error
- defer func(previous func(error)) { logExitFunc = previous }(logExitFunc)
- logExitFunc = func(e error) {
- err = e
- }
- defer func(previous uint64) { MaxSize = previous }(MaxSize)
- MaxSize = 512
-
- Info("x") // Be sure we have a file.
- info, ok := logging.file[infoLog].(*syncBuffer)
- if !ok {
- t.Fatal("info wasn't created")
- }
- if err != nil {
- t.Fatalf("info has initial error: %v", err)
- }
- fname0 := info.file.Name()
- Info(strings.Repeat("x", int(MaxSize))) // force a rollover
- if err != nil {
- t.Fatalf("info has error after big write: %v", err)
- }
-
- // Make sure the next log file gets a file name with a different
- // time stamp.
- //
- // TODO: determine whether we need to support subsecond log
- // rotation. C++ does not appear to handle this case (nor does it
- // handle Daylight Savings Time properly).
- time.Sleep(1 * time.Second)
-
- Info("x") // create a new file
- if err != nil {
- t.Fatalf("error after rotation: %v", err)
- }
- fname1 := info.file.Name()
- if fname0 == fname1 {
- t.Errorf("info.f.Name did not change: %v", fname0)
- }
- if info.nbytes >= MaxSize {
- t.Errorf("file size was not reset: %d", info.nbytes)
- }
-}
-
-func TestLogBacktraceAt(t *testing.T) {
- setFlags()
- defer logging.swap(logging.newBuffers())
- // The peculiar style of this code simplifies line counting and maintenance of the
- // tracing block below.
- var infoLine string
- setTraceLocation := func(file string, line int, ok bool, delta int) {
- if !ok {
- t.Fatal("could not get file:line")
- }
- _, file = filepath.Split(file)
- infoLine = fmt.Sprintf("%s:%d", file, line+delta)
- err := logging.traceLocation.Set(infoLine)
- if err != nil {
- t.Fatal("error setting log_backtrace_at: ", err)
- }
- }
- {
- // Start of tracing block. These lines know about each other's relative position.
- _, file, line, ok := runtime.Caller(0)
- setTraceLocation(file, line, ok, +2) // Two lines between Caller and Info calls.
- Info("we want a stack trace here")
- }
- numAppearances := strings.Count(contents(infoLog), infoLine)
- if numAppearances < 2 {
- // Need 2 appearances, one in the log header and one in the trace:
- // log_test.go:281: I0511 16:36:06.952398 02238 log_test.go:280] we want a stack trace here
- // ...
- // github.com/glog/glog_test.go:280 (0x41ba91)
- // ...
- // We could be more precise but that would require knowing the details
- // of the traceback format, which may not be dependable.
- t.Fatal("got no trace back; log is ", contents(infoLog))
- }
-}
-
-func BenchmarkHeader(b *testing.B) {
- for i := 0; i < b.N; i++ {
- buf, _, _ := logging.header(infoLog, 0)
- logging.putBuffer(buf)
- }
-}
diff --git a/vendor/github.com/golang/protobuf/proto/Makefile b/vendor/github.com/golang/protobuf/proto/Makefile
index f1f06564..e2e0651a 100644
--- a/vendor/github.com/golang/protobuf/proto/Makefile
+++ b/vendor/github.com/golang/protobuf/proto/Makefile
@@ -39,5 +39,5 @@ test: install generate-test-pbs
generate-test-pbs:
make install
make -C testdata
- protoc --go_out=Mtestdata/test.proto=github.com/golang/protobuf/proto/testdata:. proto3_proto/proto3.proto
+ protoc --go_out=Mtestdata/test.proto=github.com/golang/protobuf/proto/testdata,Mgoogle/protobuf/any.proto=github.com/golang/protobuf/ptypes/any:. proto3_proto/proto3.proto
make
diff --git a/vendor/github.com/golang/protobuf/proto/all_test.go b/vendor/github.com/golang/protobuf/proto/all_test.go
index f68f913d..18eeb0fe 100644
--- a/vendor/github.com/golang/protobuf/proto/all_test.go
+++ b/vendor/github.com/golang/protobuf/proto/all_test.go
@@ -1329,9 +1329,18 @@ func TestRequiredFieldEnforcement(t *testing.T) {
func TestTypedNilMarshal(t *testing.T) {
// A typed nil should return ErrNil and not crash.
- _, err := Marshal((*GoEnum)(nil))
- if err != ErrNil {
- t.Errorf("Marshal: got err %v, want ErrNil", err)
+ {
+ var m *GoEnum
+ if _, err := Marshal(m); err != ErrNil {
+ t.Errorf("Marshal(%#v): got %v, want ErrNil", m, err)
+ }
+ }
+
+ {
+ m := &Communique{Union: &Communique_Msg{nil}}
+ if _, err := Marshal(m); err == nil || err == ErrNil {
+ t.Errorf("Marshal(%#v): got %v, want errOneofHasNil", m, err)
+ }
}
}
@@ -1958,6 +1967,40 @@ func TestMapFieldWithNil(t *testing.T) {
}
}
+func TestDecodeMapFieldMissingKey(t *testing.T) {
+ b := []byte{
+ 0x0A, 0x03, // message, tag 1 (name_mapping), of length 3 bytes
+ // no key
+ 0x12, 0x01, 0x6D, // string value of length 1 byte, value "m"
+ }
+ got := &MessageWithMap{}
+ err := Unmarshal(b, got)
+ if err != nil {
+ t.Fatalf("failed to marshal map with missing key: %v", err)
+ }
+ want := &MessageWithMap{NameMapping: map[int32]string{0: "m"}}
+ if !Equal(got, want) {
+ t.Errorf("Unmarshaled map with no key was not as expected. got: %v, want %v", got, want)
+ }
+}
+
+func TestDecodeMapFieldMissingValue(t *testing.T) {
+ b := []byte{
+ 0x0A, 0x02, // message, tag 1 (name_mapping), of length 2 bytes
+ 0x08, 0x01, // varint key, value 1
+ // no value
+ }
+ got := &MessageWithMap{}
+ err := Unmarshal(b, got)
+ if err != nil {
+ t.Fatalf("failed to marshal map with missing value: %v", err)
+ }
+ want := &MessageWithMap{NameMapping: map[int32]string{1: ""}}
+ if !Equal(got, want) {
+ t.Errorf("Unmarshaled map with no value was not as expected. got: %v, want %v", got, want)
+ }
+}
+
func TestOneof(t *testing.T) {
m := &Communique{}
b, err := Marshal(m)
diff --git a/vendor/github.com/golang/protobuf/proto/any_test.go b/vendor/github.com/golang/protobuf/proto/any_test.go
new file mode 100644
index 00000000..83492c56
--- /dev/null
+++ b/vendor/github.com/golang/protobuf/proto/any_test.go
@@ -0,0 +1,272 @@
+// Go support for Protocol Buffers - Google's data interchange format
+//
+// Copyright 2016 The Go Authors. All rights reserved.
+// https://github.com/golang/protobuf
+//
+// Redistribution and use in source and binary forms, with or without
+// modification, are permitted provided that the following conditions are
+// met:
+//
+// * Redistributions of source code must retain the above copyright
+// notice, this list of conditions and the following disclaimer.
+// * Redistributions in binary form must reproduce the above
+// copyright notice, this list of conditions and the following disclaimer
+// in the documentation and/or other materials provided with the
+// distribution.
+// * Neither the name of Google Inc. nor the names of its
+// contributors may be used to endorse or promote products derived from
+// this software without specific prior written permission.
+//
+// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+
+package proto_test
+
+import (
+ "strings"
+ "testing"
+
+ "github.com/golang/protobuf/proto"
+
+ pb "github.com/golang/protobuf/proto/proto3_proto"
+ testpb "github.com/golang/protobuf/proto/testdata"
+ anypb "github.com/golang/protobuf/ptypes/any"
+)
+
+var (
+ expandedMarshaler = proto.TextMarshaler{ExpandAny: true}
+ expandedCompactMarshaler = proto.TextMarshaler{Compact: true, ExpandAny: true}
+)
+
+// anyEqual reports whether two messages which may be google.protobuf.Any or may
+// contain google.protobuf.Any fields are equal. We can't use proto.Equal for
+// comparison, because semantically equivalent messages may be marshaled to
+// binary in different tag order. Instead, trust that TextMarshaler with
+// ExpandAny option works and compare the text marshaling results.
+func anyEqual(got, want proto.Message) bool {
+ // if messages are proto.Equal, no need to marshal.
+ if proto.Equal(got, want) {
+ return true
+ }
+ g := expandedMarshaler.Text(got)
+ w := expandedMarshaler.Text(want)
+ return g == w
+}
+
+type golden struct {
+ m proto.Message
+ t, c string
+}
+
+var goldenMessages = makeGolden()
+
+func makeGolden() []golden {
+ nested := &pb.Nested{Bunny: "Monty"}
+ nb, err := proto.Marshal(nested)
+ if err != nil {
+ panic(err)
+ }
+ m1 := &pb.Message{
+ Name: "David",
+ ResultCount: 47,
+ Anything: &anypb.Any{TypeUrl: "type.googleapis.com/" + proto.MessageName(nested), Value: nb},
+ }
+ m2 := &pb.Message{
+ Name: "David",
+ ResultCount: 47,
+ Anything: &anypb.Any{TypeUrl: "http://[::1]/type.googleapis.com/" + proto.MessageName(nested), Value: nb},
+ }
+ m3 := &pb.Message{
+ Name: "David",
+ ResultCount: 47,
+ Anything: &anypb.Any{TypeUrl: `type.googleapis.com/"/` + proto.MessageName(nested), Value: nb},
+ }
+ m4 := &pb.Message{
+ Name: "David",
+ ResultCount: 47,
+ Anything: &anypb.Any{TypeUrl: "type.googleapis.com/a/path/" + proto.MessageName(nested), Value: nb},
+ }
+ m5 := &anypb.Any{TypeUrl: "type.googleapis.com/" + proto.MessageName(nested), Value: nb}
+
+ any1 := &testpb.MyMessage{Count: proto.Int32(47), Name: proto.String("David")}
+ proto.SetExtension(any1, testpb.E_Ext_More, &testpb.Ext{Data: proto.String("foo")})
+ proto.SetExtension(any1, testpb.E_Ext_Text, proto.String("bar"))
+ any1b, err := proto.Marshal(any1)
+ if err != nil {
+ panic(err)
+ }
+ any2 := &testpb.MyMessage{Count: proto.Int32(42), Bikeshed: testpb.MyMessage_GREEN.Enum(), RepBytes: [][]byte{[]byte("roboto")}}
+ proto.SetExtension(any2, testpb.E_Ext_More, &testpb.Ext{Data: proto.String("baz")})
+ any2b, err := proto.Marshal(any2)
+ if err != nil {
+ panic(err)
+ }
+ m6 := &pb.Message{
+ Name: "David",
+ ResultCount: 47,
+ Anything: &anypb.Any{TypeUrl: "type.googleapis.com/" + proto.MessageName(any1), Value: any1b},
+ ManyThings: []*anypb.Any{
+ &anypb.Any{TypeUrl: "type.googleapis.com/" + proto.MessageName(any2), Value: any2b},
+ &anypb.Any{TypeUrl: "type.googleapis.com/" + proto.MessageName(any1), Value: any1b},
+ },
+ }
+
+ const (
+ m1Golden = `
+name: "David"
+result_count: 47
+anything: <
+ [type.googleapis.com/proto3_proto.Nested]: <
+ bunny: "Monty"
+ >
+>
+`
+ m2Golden = `
+name: "David"
+result_count: 47
+anything: <
+ ["http://[::1]/type.googleapis.com/proto3_proto.Nested"]: <
+ bunny: "Monty"
+ >
+>
+`
+ m3Golden = `
+name: "David"
+result_count: 47
+anything: <
+ ["type.googleapis.com/\"/proto3_proto.Nested"]: <
+ bunny: "Monty"
+ >
+>
+`
+ m4Golden = `
+name: "David"
+result_count: 47
+anything: <
+ [type.googleapis.com/a/path/proto3_proto.Nested]: <
+ bunny: "Monty"
+ >
+>
+`
+ m5Golden = `
+[type.googleapis.com/proto3_proto.Nested]: <
+ bunny: "Monty"
+>
+`
+ m6Golden = `
+name: "David"
+result_count: 47
+anything: <
+ [type.googleapis.com/testdata.MyMessage]: <
+ count: 47
+ name: "David"
+ [testdata.Ext.more]: <
+ data: "foo"
+ >
+ [testdata.Ext.text]: "bar"
+ >
+>
+many_things: <
+ [type.googleapis.com/testdata.MyMessage]: <
+ count: 42
+ bikeshed: GREEN
+ rep_bytes: "roboto"
+ [testdata.Ext.more]: <
+ data: "baz"
+ >
+ >
+>
+many_things: <
+ [type.googleapis.com/testdata.MyMessage]: <
+ count: 47
+ name: "David"
+ [testdata.Ext.more]: <
+ data: "foo"
+ >
+ [testdata.Ext.text]: "bar"
+ >
+>
+`
+ )
+ return []golden{
+ {m1, strings.TrimSpace(m1Golden) + "\n", strings.TrimSpace(compact(m1Golden)) + " "},
+ {m2, strings.TrimSpace(m2Golden) + "\n", strings.TrimSpace(compact(m2Golden)) + " "},
+ {m3, strings.TrimSpace(m3Golden) + "\n", strings.TrimSpace(compact(m3Golden)) + " "},
+ {m4, strings.TrimSpace(m4Golden) + "\n", strings.TrimSpace(compact(m4Golden)) + " "},
+ {m5, strings.TrimSpace(m5Golden) + "\n", strings.TrimSpace(compact(m5Golden)) + " "},
+ {m6, strings.TrimSpace(m6Golden) + "\n", strings.TrimSpace(compact(m6Golden)) + " "},
+ }
+}
+
+func TestMarshalGolden(t *testing.T) {
+ for _, tt := range goldenMessages {
+ if got, want := expandedMarshaler.Text(tt.m), tt.t; got != want {
+ t.Errorf("message %v: got:\n%s\nwant:\n%s", tt.m, got, want)
+ }
+ if got, want := expandedCompactMarshaler.Text(tt.m), tt.c; got != want {
+ t.Errorf("message %v: got:\n`%s`\nwant:\n`%s`", tt.m, got, want)
+ }
+ }
+}
+
+func TestUnmarshalGolden(t *testing.T) {
+ for _, tt := range goldenMessages {
+ want := tt.m
+ got := proto.Clone(tt.m)
+ got.Reset()
+ if err := proto.UnmarshalText(tt.t, got); err != nil {
+ t.Errorf("failed to unmarshal\n%s\nerror: %v", tt.t, err)
+ }
+ if !anyEqual(got, want) {
+ t.Errorf("message:\n%s\ngot:\n%s\nwant:\n%s", tt.t, got, want)
+ }
+ got.Reset()
+ if err := proto.UnmarshalText(tt.c, got); err != nil {
+ t.Errorf("failed to unmarshal\n%s\nerror: %v", tt.c, err)
+ }
+ if !anyEqual(got, want) {
+ t.Errorf("message:\n%s\ngot:\n%s\nwant:\n%s", tt.c, got, want)
+ }
+ }
+}
+
+func TestMarsahlUnknownAny(t *testing.T) {
+ m := &pb.Message{
+ Anything: &anypb.Any{
+ TypeUrl: "foo",
+ Value: []byte("bar"),
+ },
+ }
+ want := `anything: <
+ type_url: "foo"
+ value: "bar"
+>
+`
+ got := expandedMarshaler.Text(m)
+ if got != want {
+ t.Errorf("got\n`%s`\nwant\n`%s`", got, want)
+ }
+}
+
+func TestAmbiguousAny(t *testing.T) {
+ pb := &anypb.Any{}
+ err := proto.UnmarshalText(`
+ [type.googleapis.com/proto3_proto.Nested]: <
+ bunny: "Monty"
+ >
+ type_url: "ttt/proto3_proto.Nested"
+ `, pb)
+ t.Logf("result: %v (error: %v)", expandedMarshaler.Text(pb), err)
+ if err != nil {
+ t.Errorf("failed to parse ambiguous Any message: %v", err)
+ }
+}
diff --git a/vendor/github.com/golang/protobuf/proto/decode.go b/vendor/github.com/golang/protobuf/proto/decode.go
index 5810782f..f94b9f41 100644
--- a/vendor/github.com/golang/protobuf/proto/decode.go
+++ b/vendor/github.com/golang/protobuf/proto/decode.go
@@ -768,10 +768,11 @@ func (o *Buffer) dec_new_map(p *Properties, base structPointer) error {
}
}
keyelem, valelem := keyptr.Elem(), valptr.Elem()
- if !keyelem.IsValid() || !valelem.IsValid() {
- // We did not decode the key or the value in the map entry.
- // Either way, it's an invalid map entry.
- return fmt.Errorf("proto: bad map data: missing key/val")
+ if !keyelem.IsValid() {
+ keyelem = reflect.Zero(p.mtype.Key())
+ }
+ if !valelem.IsValid() {
+ valelem = reflect.Zero(p.mtype.Elem())
}
v.SetMapIndex(keyelem, valelem)
diff --git a/vendor/github.com/golang/protobuf/proto/encode.go b/vendor/github.com/golang/protobuf/proto/encode.go
index 231b0740..eb7e0474 100644
--- a/vendor/github.com/golang/protobuf/proto/encode.go
+++ b/vendor/github.com/golang/protobuf/proto/encode.go
@@ -64,6 +64,10 @@ var (
// a struct with a repeated field containing a nil element.
errRepeatedHasNil = errors.New("proto: repeated field has nil element")
+ // errOneofHasNil is the error returned if Marshal is called with
+ // a struct with a oneof field containing a nil element.
+ errOneofHasNil = errors.New("proto: oneof field has nil value")
+
// ErrNil is the error returned if Marshal is called with nil.
ErrNil = errors.New("proto: Marshal called with nil")
)
@@ -1222,7 +1226,9 @@ func (o *Buffer) enc_struct(prop *StructProperties, base structPointer) error {
// Do oneof fields.
if prop.oneofMarshaler != nil {
m := structPointer_Interface(base, prop.stype).(Message)
- if err := prop.oneofMarshaler(m, o); err != nil {
+ if err := prop.oneofMarshaler(m, o); err == ErrNil {
+ return errOneofHasNil
+ } else if err != nil {
return err
}
}
diff --git a/vendor/github.com/golang/protobuf/proto/pointer_reflect.go b/vendor/github.com/golang/protobuf/proto/pointer_reflect.go
index 749919d2..98991417 100644
--- a/vendor/github.com/golang/protobuf/proto/pointer_reflect.go
+++ b/vendor/github.com/golang/protobuf/proto/pointer_reflect.go
@@ -29,7 +29,7 @@
// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
-// +build appengine
+// +build appengine js
// This file contains an implementation of proto field accesses using package reflect.
// It is slower than the code in pointer_unsafe.go but it avoids package unsafe and can
diff --git a/vendor/github.com/golang/protobuf/proto/pointer_unsafe.go b/vendor/github.com/golang/protobuf/proto/pointer_unsafe.go
index e9be0fe9..ceece772 100644
--- a/vendor/github.com/golang/protobuf/proto/pointer_unsafe.go
+++ b/vendor/github.com/golang/protobuf/proto/pointer_unsafe.go
@@ -29,7 +29,7 @@
// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
-// +build !appengine
+// +build !appengine,!js
// This file contains the implementation of the proto field accesses using package unsafe.
diff --git a/vendor/github.com/golang/protobuf/proto/proto3_proto/proto3.pb.go b/vendor/github.com/golang/protobuf/proto/proto3_proto/proto3.pb.go
index 37c77820..411f17f5 100644
--- a/vendor/github.com/golang/protobuf/proto/proto3_proto/proto3.pb.go
+++ b/vendor/github.com/golang/protobuf/proto/proto3_proto/proto3.pb.go
@@ -16,10 +16,19 @@ It has these top-level messages:
package proto3_proto
import proto "github.com/golang/protobuf/proto"
+import fmt "fmt"
+import math "math"
+import google_protobuf "github.com/golang/protobuf/ptypes/any"
import testdata "github.com/golang/protobuf/proto/testdata"
// Reference imports to suppress errors if they are not otherwise used.
var _ = proto.Marshal
+var _ = fmt.Errorf
+var _ = math.Inf
+
+// This is a compile-time assertion to ensure that this generated file
+// is compatible with the proto package it is being compiled against.
+const _ = proto.ProtoPackageIsVersion1
type Message_Humour int32
@@ -46,25 +55,30 @@ var Message_Humour_value = map[string]int32{
func (x Message_Humour) String() string {
return proto.EnumName(Message_Humour_name, int32(x))
}
+func (Message_Humour) EnumDescriptor() ([]byte, []int) { return fileDescriptor0, []int{0, 0} }
type Message struct {
Name string `protobuf:"bytes,1,opt,name=name" json:"name,omitempty"`
Hilarity Message_Humour `protobuf:"varint,2,opt,name=hilarity,enum=proto3_proto.Message_Humour" json:"hilarity,omitempty"`
- HeightInCm uint32 `protobuf:"varint,3,opt,name=height_in_cm" json:"height_in_cm,omitempty"`
+ HeightInCm uint32 `protobuf:"varint,3,opt,name=height_in_cm,json=heightInCm" json:"height_in_cm,omitempty"`
Data []byte `protobuf:"bytes,4,opt,name=data,proto3" json:"data,omitempty"`
- ResultCount int64 `protobuf:"varint,7,opt,name=result_count" json:"result_count,omitempty"`
- TrueScotsman bool `protobuf:"varint,8,opt,name=true_scotsman" json:"true_scotsman,omitempty"`
+ ResultCount int64 `protobuf:"varint,7,opt,name=result_count,json=resultCount" json:"result_count,omitempty"`
+ TrueScotsman bool `protobuf:"varint,8,opt,name=true_scotsman,json=trueScotsman" json:"true_scotsman,omitempty"`
Score float32 `protobuf:"fixed32,9,opt,name=score" json:"score,omitempty"`
Key []uint64 `protobuf:"varint,5,rep,name=key" json:"key,omitempty"`
Nested *Nested `protobuf:"bytes,6,opt,name=nested" json:"nested,omitempty"`
+ RFunny []Message_Humour `protobuf:"varint,16,rep,name=r_funny,json=rFunny,enum=proto3_proto.Message_Humour" json:"r_funny,omitempty"`
Terrain map[string]*Nested `protobuf:"bytes,10,rep,name=terrain" json:"terrain,omitempty" protobuf_key:"bytes,1,opt,name=key" protobuf_val:"bytes,2,opt,name=value"`
- Proto2Field *testdata.SubDefaults `protobuf:"bytes,11,opt,name=proto2_field" json:"proto2_field,omitempty"`
- Proto2Value map[string]*testdata.SubDefaults `protobuf:"bytes,13,rep,name=proto2_value" json:"proto2_value,omitempty" protobuf_key:"bytes,1,opt,name=key" protobuf_val:"bytes,2,opt,name=value"`
+ Proto2Field *testdata.SubDefaults `protobuf:"bytes,11,opt,name=proto2_field,json=proto2Field" json:"proto2_field,omitempty"`
+ Proto2Value map[string]*testdata.SubDefaults `protobuf:"bytes,13,rep,name=proto2_value,json=proto2Value" json:"proto2_value,omitempty" protobuf_key:"bytes,1,opt,name=key" protobuf_val:"bytes,2,opt,name=value"`
+ Anything *google_protobuf.Any `protobuf:"bytes,14,opt,name=anything" json:"anything,omitempty"`
+ ManyThings []*google_protobuf.Any `protobuf:"bytes,15,rep,name=many_things,json=manyThings" json:"many_things,omitempty"`
}
-func (m *Message) Reset() { *m = Message{} }
-func (m *Message) String() string { return proto.CompactTextString(m) }
-func (*Message) ProtoMessage() {}
+func (m *Message) Reset() { *m = Message{} }
+func (m *Message) String() string { return proto.CompactTextString(m) }
+func (*Message) ProtoMessage() {}
+func (*Message) Descriptor() ([]byte, []int) { return fileDescriptor0, []int{0} }
func (m *Message) GetNested() *Nested {
if m != nil {
@@ -94,21 +108,37 @@ func (m *Message) GetProto2Value() map[string]*testdata.SubDefaults {
return nil
}
+func (m *Message) GetAnything() *google_protobuf.Any {
+ if m != nil {
+ return m.Anything
+ }
+ return nil
+}
+
+func (m *Message) GetManyThings() []*google_protobuf.Any {
+ if m != nil {
+ return m.ManyThings
+ }
+ return nil
+}
+
type Nested struct {
Bunny string `protobuf:"bytes,1,opt,name=bunny" json:"bunny,omitempty"`
}
-func (m *Nested) Reset() { *m = Nested{} }
-func (m *Nested) String() string { return proto.CompactTextString(m) }
-func (*Nested) ProtoMessage() {}
+func (m *Nested) Reset() { *m = Nested{} }
+func (m *Nested) String() string { return proto.CompactTextString(m) }
+func (*Nested) ProtoMessage() {}
+func (*Nested) Descriptor() ([]byte, []int) { return fileDescriptor0, []int{1} }
type MessageWithMap struct {
- ByteMapping map[bool][]byte `protobuf:"bytes,1,rep,name=byte_mapping" json:"byte_mapping,omitempty" protobuf_key:"varint,1,opt,name=key" protobuf_val:"bytes,2,opt,name=value,proto3"`
+ ByteMapping map[bool][]byte `protobuf:"bytes,1,rep,name=byte_mapping,json=byteMapping" json:"byte_mapping,omitempty" protobuf_key:"varint,1,opt,name=key" protobuf_val:"bytes,2,opt,name=value,proto3"`
}
-func (m *MessageWithMap) Reset() { *m = MessageWithMap{} }
-func (m *MessageWithMap) String() string { return proto.CompactTextString(m) }
-func (*MessageWithMap) ProtoMessage() {}
+func (m *MessageWithMap) Reset() { *m = MessageWithMap{} }
+func (m *MessageWithMap) String() string { return proto.CompactTextString(m) }
+func (*MessageWithMap) ProtoMessage() {}
+func (*MessageWithMap) Descriptor() ([]byte, []int) { return fileDescriptor0, []int{2} }
func (m *MessageWithMap) GetByteMapping() map[bool][]byte {
if m != nil {
@@ -118,5 +148,51 @@ func (m *MessageWithMap) GetByteMapping() map[bool][]byte {
}
func init() {
+ proto.RegisterType((*Message)(nil), "proto3_proto.Message")
+ proto.RegisterType((*Nested)(nil), "proto3_proto.Nested")
+ proto.RegisterType((*MessageWithMap)(nil), "proto3_proto.MessageWithMap")
proto.RegisterEnum("proto3_proto.Message_Humour", Message_Humour_name, Message_Humour_value)
}
+
+var fileDescriptor0 = []byte{
+ // 617 bytes of a gzipped FileDescriptorProto
+ 0x1f, 0x8b, 0x08, 0x00, 0x00, 0x09, 0x6e, 0x88, 0x02, 0xff, 0x84, 0x92, 0x5d, 0x6b, 0xdb, 0x3c,
+ 0x14, 0xc7, 0x1f, 0xc5, 0xa9, 0x93, 0x1e, 0x3b, 0xad, 0xd1, 0xd3, 0x81, 0x1a, 0xc6, 0xf0, 0x32,
+ 0x18, 0x66, 0x2f, 0xee, 0xc8, 0x28, 0x94, 0x31, 0x36, 0xda, 0xae, 0x65, 0xa1, 0x69, 0x16, 0x9c,
+ 0x76, 0x65, 0x57, 0x46, 0x49, 0x95, 0xc4, 0x2c, 0x96, 0x83, 0x2d, 0x0f, 0xfc, 0x75, 0xf6, 0x29,
+ 0x77, 0x39, 0x24, 0x39, 0xa9, 0x5b, 0xb2, 0xed, 0xca, 0xd2, 0xf1, 0xef, 0xbc, 0xe8, 0xff, 0x3f,
+ 0xb0, 0xbf, 0x4c, 0x13, 0x91, 0xbc, 0x0d, 0xd5, 0xe7, 0x40, 0x5f, 0x7c, 0xf5, 0xc1, 0x76, 0xf5,
+ 0x57, 0x7b, 0x7f, 0x96, 0x24, 0xb3, 0x05, 0xd3, 0xc8, 0x38, 0x9f, 0x1e, 0x50, 0x5e, 0x68, 0xb0,
+ 0xfd, 0xbf, 0x60, 0x99, 0xb8, 0xa5, 0x82, 0x1e, 0xc8, 0x83, 0x0e, 0x76, 0x7e, 0x99, 0xd0, 0xb8,
+ 0x64, 0x59, 0x46, 0x67, 0x0c, 0x63, 0xa8, 0x73, 0x1a, 0x33, 0x82, 0x5c, 0xe4, 0x6d, 0x07, 0xea,
+ 0x8c, 0x8f, 0xa0, 0x39, 0x8f, 0x16, 0x34, 0x8d, 0x44, 0x41, 0x6a, 0x2e, 0xf2, 0x76, 0xba, 0x8f,
+ 0xfd, 0x6a, 0x43, 0xbf, 0x4c, 0xf6, 0x3f, 0xe7, 0x71, 0x92, 0xa7, 0xc1, 0x9a, 0xc6, 0x2e, 0xd8,
+ 0x73, 0x16, 0xcd, 0xe6, 0x22, 0x8c, 0x78, 0x38, 0x89, 0x89, 0xe1, 0x22, 0xaf, 0x15, 0x80, 0x8e,
+ 0xf5, 0xf8, 0x69, 0x2c, 0xfb, 0xc9, 0x71, 0x48, 0xdd, 0x45, 0x9e, 0x1d, 0xa8, 0x33, 0x7e, 0x0a,
+ 0x76, 0xca, 0xb2, 0x7c, 0x21, 0xc2, 0x49, 0x92, 0x73, 0x41, 0x1a, 0x2e, 0xf2, 0x8c, 0xc0, 0xd2,
+ 0xb1, 0x53, 0x19, 0xc2, 0xcf, 0xa0, 0x25, 0xd2, 0x9c, 0x85, 0xd9, 0x24, 0x11, 0x59, 0x4c, 0x39,
+ 0x69, 0xba, 0xc8, 0x6b, 0x06, 0xb6, 0x0c, 0x8e, 0xca, 0x18, 0xde, 0x83, 0xad, 0x6c, 0x92, 0xa4,
+ 0x8c, 0x6c, 0xbb, 0xc8, 0xab, 0x05, 0xfa, 0x82, 0x1d, 0x30, 0xbe, 0xb3, 0x82, 0x6c, 0xb9, 0x86,
+ 0x57, 0x0f, 0xe4, 0x11, 0xbf, 0x02, 0x93, 0xb3, 0x4c, 0xb0, 0x5b, 0x62, 0xba, 0xc8, 0xb3, 0xba,
+ 0x7b, 0xf7, 0x5f, 0x37, 0x50, 0xff, 0x82, 0x92, 0xc1, 0x87, 0xd0, 0x48, 0xc3, 0x69, 0xce, 0x79,
+ 0x41, 0x1c, 0xd7, 0xf8, 0xa7, 0x18, 0x66, 0x7a, 0x2e, 0x59, 0xfc, 0x1e, 0x1a, 0x82, 0xa5, 0x29,
+ 0x8d, 0x38, 0x01, 0xd7, 0xf0, 0xac, 0x6e, 0x67, 0x73, 0xda, 0x95, 0x86, 0xce, 0xb8, 0x48, 0x8b,
+ 0x60, 0x95, 0x82, 0x8f, 0x40, 0x5b, 0xdc, 0x0d, 0xa7, 0x11, 0x5b, 0xdc, 0x12, 0x4b, 0x0d, 0xfa,
+ 0xc8, 0x5f, 0xd9, 0xe9, 0x8f, 0xf2, 0xf1, 0x27, 0x36, 0xa5, 0xf9, 0x42, 0x64, 0x81, 0xa5, 0xd1,
+ 0x73, 0x49, 0xe2, 0xde, 0x3a, 0xf3, 0x07, 0x5d, 0xe4, 0x8c, 0xb4, 0x54, 0xf3, 0xe7, 0x9b, 0x9b,
+ 0x0f, 0x15, 0xf9, 0x55, 0x82, 0x7a, 0x80, 0xb2, 0x94, 0x8a, 0xe0, 0x37, 0xd0, 0xa4, 0xbc, 0x10,
+ 0xf3, 0x88, 0xcf, 0xc8, 0x4e, 0xa9, 0x94, 0x5e, 0x35, 0x7f, 0xb5, 0x6a, 0xfe, 0x31, 0x2f, 0x82,
+ 0x35, 0x85, 0x0f, 0xc1, 0x8a, 0x29, 0x2f, 0x42, 0x75, 0xcb, 0xc8, 0xae, 0xea, 0xbd, 0x39, 0x09,
+ 0x24, 0x78, 0xa5, 0xb8, 0xf6, 0x10, 0xec, 0xaa, 0x0c, 0x2b, 0xcb, 0xf4, 0x4e, 0x2a, 0xcb, 0x5e,
+ 0xc0, 0x96, 0x7e, 0x4e, 0xed, 0x2f, 0x8e, 0x69, 0xe4, 0x5d, 0xed, 0x08, 0xb5, 0xaf, 0xc1, 0x79,
+ 0xf8, 0xb6, 0x0d, 0x55, 0x5f, 0xde, 0xaf, 0xfa, 0x07, 0x79, 0xef, 0xca, 0x76, 0x3e, 0x82, 0xa9,
+ 0x6d, 0xc6, 0x16, 0x34, 0xae, 0x07, 0x17, 0x83, 0x2f, 0x37, 0x03, 0xe7, 0x3f, 0xdc, 0x84, 0xfa,
+ 0xf0, 0x7a, 0x30, 0x72, 0x10, 0x6e, 0xc1, 0xf6, 0xa8, 0x7f, 0x3c, 0x1c, 0x5d, 0xf5, 0x4e, 0x2f,
+ 0x9c, 0x1a, 0xde, 0x05, 0xeb, 0xa4, 0xd7, 0xef, 0x87, 0x27, 0xc7, 0xbd, 0xfe, 0xd9, 0x37, 0xc7,
+ 0xe8, 0x3c, 0x01, 0x53, 0x0f, 0x2b, 0x97, 0x75, 0xac, 0x96, 0x4a, 0xcf, 0xa3, 0x2f, 0x9d, 0x9f,
+ 0x08, 0x76, 0x4a, 0x73, 0x6e, 0x22, 0x31, 0xbf, 0xa4, 0x4b, 0x3c, 0x04, 0x7b, 0x5c, 0x08, 0x16,
+ 0xc6, 0x74, 0xb9, 0x94, 0x4e, 0x20, 0x25, 0xea, 0xeb, 0x8d, 0x86, 0x96, 0x39, 0xfe, 0x49, 0x21,
+ 0xd8, 0xa5, 0xe6, 0x4b, 0x5f, 0xc7, 0x77, 0x91, 0xf6, 0x07, 0x70, 0x1e, 0x02, 0x55, 0x71, 0x9a,
+ 0x5a, 0x9c, 0xbd, 0xaa, 0x38, 0x76, 0x45, 0x85, 0xb1, 0xa9, 0x5b, 0xff, 0x0e, 0x00, 0x00, 0xff,
+ 0xff, 0x54, 0x4a, 0xfa, 0x41, 0xa1, 0x04, 0x00, 0x00,
+}
diff --git a/vendor/github.com/golang/protobuf/proto/proto3_proto/proto3.proto b/vendor/github.com/golang/protobuf/proto/proto3_proto/proto3.proto
index e2311d92..31509e48 100644
--- a/vendor/github.com/golang/protobuf/proto/proto3_proto/proto3.proto
+++ b/vendor/github.com/golang/protobuf/proto/proto3_proto/proto3.proto
@@ -31,6 +31,7 @@
syntax = "proto3";
+import "google/protobuf/any.proto";
import "testdata/test.proto";
package proto3_proto;
@@ -53,10 +54,14 @@ message Message {
repeated uint64 key = 5;
Nested nested = 6;
+ repeated Humour r_funny = 16;
map terrain = 10;
testdata.SubDefaults proto2_field = 11;
map proto2_value = 13;
+
+ google.protobuf.Any anything = 14;
+ repeated google.protobuf.Any many_things = 15;
}
message Nested {
diff --git a/vendor/github.com/golang/protobuf/proto/testdata/test.pb.go b/vendor/github.com/golang/protobuf/proto/testdata/test.pb.go
index b04d480a..772adcb6 100644
--- a/vendor/github.com/golang/protobuf/proto/testdata/test.pb.go
+++ b/vendor/github.com/golang/protobuf/proto/testdata/test.pb.go
@@ -20,6 +20,7 @@ It has these top-level messages:
NewMessage
InnerMessage
OtherMessage
+ RequiredInnerMessage
MyMessage
Ext
ComplexExtension
@@ -192,7 +193,7 @@ func (x *MyMessage_Color) UnmarshalJSON(data []byte) error {
*x = MyMessage_Color(value)
return nil
}
-func (MyMessage_Color) EnumDescriptor() ([]byte, []int) { return fileDescriptor0, []int{11, 0} }
+func (MyMessage_Color) EnumDescriptor() ([]byte, []int) { return fileDescriptor0, []int{12, 0} }
type DefaultsMessage_DefaultsEnum int32
@@ -230,7 +231,7 @@ func (x *DefaultsMessage_DefaultsEnum) UnmarshalJSON(data []byte) error {
return nil
}
func (DefaultsMessage_DefaultsEnum) EnumDescriptor() ([]byte, []int) {
- return fileDescriptor0, []int{14, 0}
+ return fileDescriptor0, []int{15, 0}
}
type Defaults_Color int32
@@ -268,7 +269,7 @@ func (x *Defaults_Color) UnmarshalJSON(data []byte) error {
*x = Defaults_Color(value)
return nil
}
-func (Defaults_Color) EnumDescriptor() ([]byte, []int) { return fileDescriptor0, []int{19, 0} }
+func (Defaults_Color) EnumDescriptor() ([]byte, []int) { return fileDescriptor0, []int{20, 0} }
type RepeatedEnum_Color int32
@@ -299,7 +300,7 @@ func (x *RepeatedEnum_Color) UnmarshalJSON(data []byte) error {
*x = RepeatedEnum_Color(value)
return nil
}
-func (RepeatedEnum_Color) EnumDescriptor() ([]byte, []int) { return fileDescriptor0, []int{21, 0} }
+func (RepeatedEnum_Color) EnumDescriptor() ([]byte, []int) { return fileDescriptor0, []int{22, 0} }
type GoEnum struct {
Foo *FOO `protobuf:"varint,1,req,name=foo,enum=testdata.FOO" json:"foo,omitempty"`
@@ -1320,16 +1321,34 @@ func (m *OtherMessage) GetInner() *InnerMessage {
return nil
}
+type RequiredInnerMessage struct {
+ LeoFinallyWonAnOscar *InnerMessage `protobuf:"bytes,1,req,name=leo_finally_won_an_oscar,json=leoFinallyWonAnOscar" json:"leo_finally_won_an_oscar,omitempty"`
+ XXX_unrecognized []byte `json:"-"`
+}
+
+func (m *RequiredInnerMessage) Reset() { *m = RequiredInnerMessage{} }
+func (m *RequiredInnerMessage) String() string { return proto.CompactTextString(m) }
+func (*RequiredInnerMessage) ProtoMessage() {}
+func (*RequiredInnerMessage) Descriptor() ([]byte, []int) { return fileDescriptor0, []int{11} }
+
+func (m *RequiredInnerMessage) GetLeoFinallyWonAnOscar() *InnerMessage {
+ if m != nil {
+ return m.LeoFinallyWonAnOscar
+ }
+ return nil
+}
+
type MyMessage struct {
- Count *int32 `protobuf:"varint,1,req,name=count" json:"count,omitempty"`
- Name *string `protobuf:"bytes,2,opt,name=name" json:"name,omitempty"`
- Quote *string `protobuf:"bytes,3,opt,name=quote" json:"quote,omitempty"`
- Pet []string `protobuf:"bytes,4,rep,name=pet" json:"pet,omitempty"`
- Inner *InnerMessage `protobuf:"bytes,5,opt,name=inner" json:"inner,omitempty"`
- Others []*OtherMessage `protobuf:"bytes,6,rep,name=others" json:"others,omitempty"`
- RepInner []*InnerMessage `protobuf:"bytes,12,rep,name=rep_inner,json=repInner" json:"rep_inner,omitempty"`
- Bikeshed *MyMessage_Color `protobuf:"varint,7,opt,name=bikeshed,enum=testdata.MyMessage_Color" json:"bikeshed,omitempty"`
- Somegroup *MyMessage_SomeGroup `protobuf:"group,8,opt,name=SomeGroup,json=somegroup" json:"somegroup,omitempty"`
+ Count *int32 `protobuf:"varint,1,req,name=count" json:"count,omitempty"`
+ Name *string `protobuf:"bytes,2,opt,name=name" json:"name,omitempty"`
+ Quote *string `protobuf:"bytes,3,opt,name=quote" json:"quote,omitempty"`
+ Pet []string `protobuf:"bytes,4,rep,name=pet" json:"pet,omitempty"`
+ Inner *InnerMessage `protobuf:"bytes,5,opt,name=inner" json:"inner,omitempty"`
+ Others []*OtherMessage `protobuf:"bytes,6,rep,name=others" json:"others,omitempty"`
+ WeMustGoDeeper *RequiredInnerMessage `protobuf:"bytes,13,opt,name=we_must_go_deeper,json=weMustGoDeeper" json:"we_must_go_deeper,omitempty"`
+ RepInner []*InnerMessage `protobuf:"bytes,12,rep,name=rep_inner,json=repInner" json:"rep_inner,omitempty"`
+ Bikeshed *MyMessage_Color `protobuf:"varint,7,opt,name=bikeshed,enum=testdata.MyMessage_Color" json:"bikeshed,omitempty"`
+ Somegroup *MyMessage_SomeGroup `protobuf:"group,8,opt,name=SomeGroup,json=somegroup" json:"somegroup,omitempty"`
// This field becomes [][]byte in the generated code.
RepBytes [][]byte `protobuf:"bytes,10,rep,name=rep_bytes,json=repBytes" json:"rep_bytes,omitempty"`
Bigfloat *float64 `protobuf:"fixed64,11,opt,name=bigfloat" json:"bigfloat,omitempty"`
@@ -1340,7 +1359,7 @@ type MyMessage struct {
func (m *MyMessage) Reset() { *m = MyMessage{} }
func (m *MyMessage) String() string { return proto.CompactTextString(m) }
func (*MyMessage) ProtoMessage() {}
-func (*MyMessage) Descriptor() ([]byte, []int) { return fileDescriptor0, []int{11} }
+func (*MyMessage) Descriptor() ([]byte, []int) { return fileDescriptor0, []int{12} }
var extRange_MyMessage = []proto.ExtensionRange{
{100, 536870911},
@@ -1398,6 +1417,13 @@ func (m *MyMessage) GetOthers() []*OtherMessage {
return nil
}
+func (m *MyMessage) GetWeMustGoDeeper() *RequiredInnerMessage {
+ if m != nil {
+ return m.WeMustGoDeeper
+ }
+ return nil
+}
+
func (m *MyMessage) GetRepInner() []*InnerMessage {
if m != nil {
return m.RepInner
@@ -1441,7 +1467,7 @@ type MyMessage_SomeGroup struct {
func (m *MyMessage_SomeGroup) Reset() { *m = MyMessage_SomeGroup{} }
func (m *MyMessage_SomeGroup) String() string { return proto.CompactTextString(m) }
func (*MyMessage_SomeGroup) ProtoMessage() {}
-func (*MyMessage_SomeGroup) Descriptor() ([]byte, []int) { return fileDescriptor0, []int{11, 0} }
+func (*MyMessage_SomeGroup) Descriptor() ([]byte, []int) { return fileDescriptor0, []int{12, 0} }
func (m *MyMessage_SomeGroup) GetGroupField() int32 {
if m != nil && m.GroupField != nil {
@@ -1458,7 +1484,7 @@ type Ext struct {
func (m *Ext) Reset() { *m = Ext{} }
func (m *Ext) String() string { return proto.CompactTextString(m) }
func (*Ext) ProtoMessage() {}
-func (*Ext) Descriptor() ([]byte, []int) { return fileDescriptor0, []int{12} }
+func (*Ext) Descriptor() ([]byte, []int) { return fileDescriptor0, []int{13} }
func (m *Ext) GetData() string {
if m != nil && m.Data != nil {
@@ -1501,7 +1527,7 @@ type ComplexExtension struct {
func (m *ComplexExtension) Reset() { *m = ComplexExtension{} }
func (m *ComplexExtension) String() string { return proto.CompactTextString(m) }
func (*ComplexExtension) ProtoMessage() {}
-func (*ComplexExtension) Descriptor() ([]byte, []int) { return fileDescriptor0, []int{13} }
+func (*ComplexExtension) Descriptor() ([]byte, []int) { return fileDescriptor0, []int{14} }
func (m *ComplexExtension) GetFirst() int32 {
if m != nil && m.First != nil {
@@ -1532,7 +1558,7 @@ type DefaultsMessage struct {
func (m *DefaultsMessage) Reset() { *m = DefaultsMessage{} }
func (m *DefaultsMessage) String() string { return proto.CompactTextString(m) }
func (*DefaultsMessage) ProtoMessage() {}
-func (*DefaultsMessage) Descriptor() ([]byte, []int) { return fileDescriptor0, []int{14} }
+func (*DefaultsMessage) Descriptor() ([]byte, []int) { return fileDescriptor0, []int{15} }
var extRange_DefaultsMessage = []proto.ExtensionRange{
{100, 536870911},
@@ -1556,7 +1582,7 @@ type MyMessageSet struct {
func (m *MyMessageSet) Reset() { *m = MyMessageSet{} }
func (m *MyMessageSet) String() string { return proto.CompactTextString(m) }
func (*MyMessageSet) ProtoMessage() {}
-func (*MyMessageSet) Descriptor() ([]byte, []int) { return fileDescriptor0, []int{15} }
+func (*MyMessageSet) Descriptor() ([]byte, []int) { return fileDescriptor0, []int{16} }
func (m *MyMessageSet) Marshal() ([]byte, error) {
return proto.MarshalMessageSet(m.ExtensionMap())
@@ -1596,7 +1622,7 @@ type Empty struct {
func (m *Empty) Reset() { *m = Empty{} }
func (m *Empty) String() string { return proto.CompactTextString(m) }
func (*Empty) ProtoMessage() {}
-func (*Empty) Descriptor() ([]byte, []int) { return fileDescriptor0, []int{16} }
+func (*Empty) Descriptor() ([]byte, []int) { return fileDescriptor0, []int{17} }
type MessageList struct {
Message []*MessageList_Message `protobuf:"group,1,rep,name=Message,json=message" json:"message,omitempty"`
@@ -1606,7 +1632,7 @@ type MessageList struct {
func (m *MessageList) Reset() { *m = MessageList{} }
func (m *MessageList) String() string { return proto.CompactTextString(m) }
func (*MessageList) ProtoMessage() {}
-func (*MessageList) Descriptor() ([]byte, []int) { return fileDescriptor0, []int{17} }
+func (*MessageList) Descriptor() ([]byte, []int) { return fileDescriptor0, []int{18} }
func (m *MessageList) GetMessage() []*MessageList_Message {
if m != nil {
@@ -1624,7 +1650,7 @@ type MessageList_Message struct {
func (m *MessageList_Message) Reset() { *m = MessageList_Message{} }
func (m *MessageList_Message) String() string { return proto.CompactTextString(m) }
func (*MessageList_Message) ProtoMessage() {}
-func (*MessageList_Message) Descriptor() ([]byte, []int) { return fileDescriptor0, []int{17, 0} }
+func (*MessageList_Message) Descriptor() ([]byte, []int) { return fileDescriptor0, []int{18, 0} }
func (m *MessageList_Message) GetName() string {
if m != nil && m.Name != nil {
@@ -1649,7 +1675,7 @@ type Strings struct {
func (m *Strings) Reset() { *m = Strings{} }
func (m *Strings) String() string { return proto.CompactTextString(m) }
func (*Strings) ProtoMessage() {}
-func (*Strings) Descriptor() ([]byte, []int) { return fileDescriptor0, []int{18} }
+func (*Strings) Descriptor() ([]byte, []int) { return fileDescriptor0, []int{19} }
func (m *Strings) GetStringField() string {
if m != nil && m.StringField != nil {
@@ -1696,7 +1722,7 @@ type Defaults struct {
func (m *Defaults) Reset() { *m = Defaults{} }
func (m *Defaults) String() string { return proto.CompactTextString(m) }
func (*Defaults) ProtoMessage() {}
-func (*Defaults) Descriptor() ([]byte, []int) { return fileDescriptor0, []int{19} }
+func (*Defaults) Descriptor() ([]byte, []int) { return fileDescriptor0, []int{20} }
const Default_Defaults_F_Bool bool = true
const Default_Defaults_F_Int32 int32 = 32
@@ -1860,7 +1886,7 @@ type SubDefaults struct {
func (m *SubDefaults) Reset() { *m = SubDefaults{} }
func (m *SubDefaults) String() string { return proto.CompactTextString(m) }
func (*SubDefaults) ProtoMessage() {}
-func (*SubDefaults) Descriptor() ([]byte, []int) { return fileDescriptor0, []int{20} }
+func (*SubDefaults) Descriptor() ([]byte, []int) { return fileDescriptor0, []int{21} }
const Default_SubDefaults_N int64 = 7
@@ -1879,7 +1905,7 @@ type RepeatedEnum struct {
func (m *RepeatedEnum) Reset() { *m = RepeatedEnum{} }
func (m *RepeatedEnum) String() string { return proto.CompactTextString(m) }
func (*RepeatedEnum) ProtoMessage() {}
-func (*RepeatedEnum) Descriptor() ([]byte, []int) { return fileDescriptor0, []int{21} }
+func (*RepeatedEnum) Descriptor() ([]byte, []int) { return fileDescriptor0, []int{22} }
func (m *RepeatedEnum) GetColor() []RepeatedEnum_Color {
if m != nil {
@@ -1902,7 +1928,7 @@ type MoreRepeated struct {
func (m *MoreRepeated) Reset() { *m = MoreRepeated{} }
func (m *MoreRepeated) String() string { return proto.CompactTextString(m) }
func (*MoreRepeated) ProtoMessage() {}
-func (*MoreRepeated) Descriptor() ([]byte, []int) { return fileDescriptor0, []int{22} }
+func (*MoreRepeated) Descriptor() ([]byte, []int) { return fileDescriptor0, []int{23} }
func (m *MoreRepeated) GetBools() []bool {
if m != nil {
@@ -1961,7 +1987,7 @@ type GroupOld struct {
func (m *GroupOld) Reset() { *m = GroupOld{} }
func (m *GroupOld) String() string { return proto.CompactTextString(m) }
func (*GroupOld) ProtoMessage() {}
-func (*GroupOld) Descriptor() ([]byte, []int) { return fileDescriptor0, []int{23} }
+func (*GroupOld) Descriptor() ([]byte, []int) { return fileDescriptor0, []int{24} }
func (m *GroupOld) GetG() *GroupOld_G {
if m != nil {
@@ -1978,7 +2004,7 @@ type GroupOld_G struct {
func (m *GroupOld_G) Reset() { *m = GroupOld_G{} }
func (m *GroupOld_G) String() string { return proto.CompactTextString(m) }
func (*GroupOld_G) ProtoMessage() {}
-func (*GroupOld_G) Descriptor() ([]byte, []int) { return fileDescriptor0, []int{23, 0} }
+func (*GroupOld_G) Descriptor() ([]byte, []int) { return fileDescriptor0, []int{24, 0} }
func (m *GroupOld_G) GetX() int32 {
if m != nil && m.X != nil {
@@ -1995,7 +2021,7 @@ type GroupNew struct {
func (m *GroupNew) Reset() { *m = GroupNew{} }
func (m *GroupNew) String() string { return proto.CompactTextString(m) }
func (*GroupNew) ProtoMessage() {}
-func (*GroupNew) Descriptor() ([]byte, []int) { return fileDescriptor0, []int{24} }
+func (*GroupNew) Descriptor() ([]byte, []int) { return fileDescriptor0, []int{25} }
func (m *GroupNew) GetG() *GroupNew_G {
if m != nil {
@@ -2013,7 +2039,7 @@ type GroupNew_G struct {
func (m *GroupNew_G) Reset() { *m = GroupNew_G{} }
func (m *GroupNew_G) String() string { return proto.CompactTextString(m) }
func (*GroupNew_G) ProtoMessage() {}
-func (*GroupNew_G) Descriptor() ([]byte, []int) { return fileDescriptor0, []int{24, 0} }
+func (*GroupNew_G) Descriptor() ([]byte, []int) { return fileDescriptor0, []int{25, 0} }
func (m *GroupNew_G) GetX() int32 {
if m != nil && m.X != nil {
@@ -2037,7 +2063,7 @@ type FloatingPoint struct {
func (m *FloatingPoint) Reset() { *m = FloatingPoint{} }
func (m *FloatingPoint) String() string { return proto.CompactTextString(m) }
func (*FloatingPoint) ProtoMessage() {}
-func (*FloatingPoint) Descriptor() ([]byte, []int) { return fileDescriptor0, []int{25} }
+func (*FloatingPoint) Descriptor() ([]byte, []int) { return fileDescriptor0, []int{26} }
func (m *FloatingPoint) GetF() float64 {
if m != nil && m.F != nil {
@@ -2057,7 +2083,7 @@ type MessageWithMap struct {
func (m *MessageWithMap) Reset() { *m = MessageWithMap{} }
func (m *MessageWithMap) String() string { return proto.CompactTextString(m) }
func (*MessageWithMap) ProtoMessage() {}
-func (*MessageWithMap) Descriptor() ([]byte, []int) { return fileDescriptor0, []int{26} }
+func (*MessageWithMap) Descriptor() ([]byte, []int) { return fileDescriptor0, []int{27} }
func (m *MessageWithMap) GetNameMapping() map[int32]string {
if m != nil {
@@ -2116,7 +2142,7 @@ type Oneof struct {
func (m *Oneof) Reset() { *m = Oneof{} }
func (m *Oneof) String() string { return proto.CompactTextString(m) }
func (*Oneof) ProtoMessage() {}
-func (*Oneof) Descriptor() ([]byte, []int) { return fileDescriptor0, []int{27} }
+func (*Oneof) Descriptor() ([]byte, []int) { return fileDescriptor0, []int{28} }
type isOneof_Union interface {
isOneof_Union()
@@ -2662,7 +2688,7 @@ type Oneof_F_Group struct {
func (m *Oneof_F_Group) Reset() { *m = Oneof_F_Group{} }
func (m *Oneof_F_Group) String() string { return proto.CompactTextString(m) }
func (*Oneof_F_Group) ProtoMessage() {}
-func (*Oneof_F_Group) Descriptor() ([]byte, []int) { return fileDescriptor0, []int{27, 0} }
+func (*Oneof_F_Group) Descriptor() ([]byte, []int) { return fileDescriptor0, []int{28, 0} }
func (m *Oneof_F_Group) GetX() int32 {
if m != nil && m.X != nil {
@@ -2689,7 +2715,7 @@ type Communique struct {
func (m *Communique) Reset() { *m = Communique{} }
func (m *Communique) String() string { return proto.CompactTextString(m) }
func (*Communique) ProtoMessage() {}
-func (*Communique) Descriptor() ([]byte, []int) { return fileDescriptor0, []int{28} }
+func (*Communique) Descriptor() ([]byte, []int) { return fileDescriptor0, []int{29} }
type isCommunique_Union interface {
isCommunique_Union()
@@ -3602,6 +3628,7 @@ func init() {
proto.RegisterType((*NewMessage_Nested)(nil), "testdata.NewMessage.Nested")
proto.RegisterType((*InnerMessage)(nil), "testdata.InnerMessage")
proto.RegisterType((*OtherMessage)(nil), "testdata.OtherMessage")
+ proto.RegisterType((*RequiredInnerMessage)(nil), "testdata.RequiredInnerMessage")
proto.RegisterType((*MyMessage)(nil), "testdata.MyMessage")
proto.RegisterType((*MyMessage_SomeGroup)(nil), "testdata.MyMessage.SomeGroup")
proto.RegisterType((*Ext)(nil), "testdata.Ext")
@@ -3722,271 +3749,281 @@ func init() {
}
var fileDescriptor0 = []byte{
- // 4253 bytes of a gzipped FileDescriptorProto
- 0x1f, 0x8b, 0x08, 0x00, 0x00, 0x09, 0x6e, 0x88, 0x02, 0xff, 0x94, 0x7a, 0xd9, 0x77, 0x1b, 0x47,
- 0x76, 0xbe, 0x1b, 0x3b, 0x0a, 0x20, 0xd1, 0x6c, 0xc9, 0x12, 0x44, 0x2d, 0x96, 0x31, 0x63, 0x5b,
- 0x92, 0x6d, 0x0e, 0xd1, 0x00, 0x49, 0x09, 0x9e, 0xdf, 0x9c, 0x23, 0x4a, 0x24, 0x87, 0x67, 0x44,
- 0x82, 0xbf, 0x26, 0xed, 0x39, 0xe3, 0x3c, 0xe0, 0x80, 0x62, 0x83, 0x84, 0x05, 0xa0, 0x21, 0x00,
- 0x8c, 0xa5, 0xe4, 0x25, 0x2f, 0xc9, 0x6b, 0xb6, 0x97, 0xbc, 0xe6, 0x29, 0x4f, 0x49, 0xce, 0xc9,
- 0x5f, 0x11, 0xdb, 0xb3, 0x7a, 0xd6, 0xac, 0x93, 0x7d, 0x99, 0xec, 0xdb, 0x4c, 0x92, 0x93, 0x73,
- 0x92, 0x7b, 0x6f, 0xdd, 0xee, 0xae, 0x6e, 0xa0, 0x9b, 0x94, 0x1e, 0x4c, 0x74, 0xd5, 0xf7, 0xdd,
- 0xba, 0x55, 0xfd, 0xd5, 0xbd, 0x75, 0xab, 0x2d, 0xc4, 0xc4, 0x1e, 0x4f, 0x96, 0x86, 0x23, 0x67,
- 0xe2, 0x18, 0x39, 0xfc, 0x7d, 0xd4, 0x9e, 0xb4, 0x2b, 0xb7, 0x45, 0x66, 0xcb, 0xd9, 0x18, 0x9c,
- 0xf6, 0x8d, 0x57, 0x44, 0xb2, 0xe3, 0x38, 0x65, 0xed, 0x66, 0xe2, 0xd6, 0xbc, 0x39, 0xb7, 0xe4,
- 0x22, 0x96, 0x36, 0x9b, 0x4d, 0x0b, 0x7b, 0x2a, 0x6b, 0xa2, 0xb0, 0xe5, 0x1c, 0x40, 0xf3, 0x66,
- 0xd7, 0xee, 0x1d, 0x19, 0x17, 0x45, 0xfa, 0x51, 0xfb, 0xd0, 0xee, 0x11, 0x23, 0x6f, 0xa5, 0x7b,
- 0xf8, 0x60, 0x18, 0x22, 0x75, 0xf0, 0x7c, 0x68, 0x97, 0x13, 0xd4, 0x98, 0x9a, 0xc0, 0xef, 0xca,
- 0x2f, 0xde, 0xc0, 0x41, 0x90, 0x69, 0xdc, 0x16, 0xa9, 0x2f, 0x75, 0x07, 0x47, 0x3c, 0xca, 0xcb,
- 0xfe, 0x28, 0xb2, 0x7f, 0xe9, 0x4b, 0xdb, 0xbb, 0x0f, 0xad, 0xd4, 0x13, 0x80, 0xa0, 0xfd, 0x83,
- 0xf6, 0x61, 0x0f, 0x4d, 0x69, 0x68, 0x7f, 0x82, 0x0f, 0xd8, 0xba, 0xd7, 0x1e, 0xb5, 0xfb, 0xe5,
- 0x24, 0xb4, 0xa6, 0xad, 0xf4, 0x10, 0x1f, 0x8c, 0x77, 0xc4, 0x9c, 0x65, 0x3f, 0x3d, 0xed, 0x8e,
- 0xec, 0x23, 0x72, 0xae, 0x9c, 0x02, 0xfb, 0x85, 0x69, 0xfb, 0xd4, 0x69, 0xcd, 0x8d, 0x54, 0xac,
- 0x24, 0x0f, 0xed, 0xf6, 0xc4, 0x25, 0xa7, 0x6f, 0x26, 0x63, 0xc9, 0x0a, 0x16, 0xc9, 0xcd, 0xe1,
- 0xa4, 0xeb, 0x0c, 0xda, 0x3d, 0x49, 0xce, 0x80, 0x5f, 0xd1, 0x64, 0x47, 0xc5, 0x1a, 0xaf, 0x8b,
- 0xd2, 0x66, 0x6b, 0xdd, 0x71, 0x7a, 0x2d, 0xd7, 0xa3, 0xb2, 0x00, 0xc7, 0x73, 0xd6, 0x5c, 0x07,
- 0x5b, 0xdd, 0x29, 0x19, 0xb7, 0x84, 0xbe, 0xd9, 0xda, 0x1e, 0x4c, 0x6a, 0xa6, 0x0f, 0x2c, 0x00,
- 0x30, 0x6d, 0xcd, 0x77, 0xa8, 0x79, 0x0a, 0xb9, 0x5a, 0xf7, 0x91, 0x45, 0x40, 0x26, 0x25, 0x72,
- 0xb5, 0xee, 0x21, 0xdf, 0x12, 0xc6, 0x66, 0x6b, 0xb3, 0xfb, 0xcc, 0x3e, 0x52, 0xad, 0xce, 0x01,
- 0x36, 0x6b, 0xe9, 0x1d, 0xee, 0x98, 0x81, 0x56, 0x2d, 0xcf, 0x03, 0x3a, 0xe3, 0xa2, 0x15, 0xdb,
- 0x77, 0xc4, 0xc2, 0x66, 0xeb, 0xdd, 0x6e, 0xd0, 0xe1, 0x12, 0x80, 0xe7, 0xac, 0x52, 0x47, 0xb6,
- 0x4f, 0x63, 0x55, 0xc3, 0x3a, 0x60, 0x53, 0x8c, 0x55, 0xec, 0xd2, 0xec, 0x36, 0x7b, 0x4e, 0x7b,
- 0xe2, 0x43, 0x17, 0x00, 0x9a, 0x80, 0xd9, 0x51, 0x73, 0xd0, 0xea, 0x43, 0xe7, 0x14, 0x24, 0xe3,
- 0x43, 0x0d, 0x80, 0x6a, 0x60, 0x55, 0xb6, 0x07, 0xb1, 0xfb, 0x93, 0x51, 0x77, 0x70, 0xec, 0x63,
- 0x2f, 0x90, 0x7e, 0x4b, 0x1d, 0xd9, 0x1e, 0xf4, 0x60, 0xfd, 0x39, 0xbc, 0x5c, 0x1f, 0x6a, 0x03,
- 0xb4, 0x08, 0x1e, 0x50, 0x73, 0xc8, 0x6a, 0x68, 0x0d, 0x3a, 0x00, 0x5d, 0x40, 0xab, 0x33, 0xd6,
- 0x60, 0x3f, 0xb4, 0x06, 0xc7, 0x80, 0x35, 0x18, 0xab, 0xac, 0x81, 0xaa, 0x19, 0x29, 0xc4, 0xf2,
- 0x45, 0xd0, 0xab, 0xaf, 0x19, 0xd9, 0x18, 0xd4, 0x0c, 0x03, 0x5f, 0x06, 0xa0, 0xa2, 0x99, 0x10,
- 0x92, 0x06, 0x67, 0xe4, 0x25, 0x40, 0x2a, 0x9a, 0x61, 0x64, 0x48, 0x33, 0x8c, 0xbd, 0x0c, 0xd8,
- 0x80, 0x66, 0xa6, 0xd0, 0xaa, 0xe5, 0x32, 0xa0, 0x03, 0x9a, 0x61, 0x74, 0x50, 0x33, 0x0c, 0xbe,
- 0x02, 0x60, 0x55, 0x33, 0x61, 0xac, 0x6a, 0x78, 0x11, 0xb0, 0xaa, 0x66, 0xd4, 0xd9, 0xb9, 0x9a,
- 0x61, 0xe8, 0x55, 0x80, 0x2a, 0x9a, 0x51, 0xad, 0x7a, 0x9a, 0x61, 0xe8, 0x35, 0x80, 0xaa, 0x9a,
- 0x51, 0xb1, 0x9e, 0x66, 0x18, 0x7b, 0x1d, 0xb0, 0xaa, 0x66, 0x18, 0x7b, 0x5b, 0xd5, 0x0c, 0x43,
- 0x3f, 0xd2, 0x00, 0xab, 0x88, 0x86, 0xa1, 0x6f, 0x06, 0x44, 0xc3, 0xd8, 0x8f, 0x11, 0xab, 0xaa,
- 0x26, 0x0c, 0x56, 0x57, 0xe1, 0x13, 0x04, 0xab, 0xb2, 0x61, 0xb0, 0x2f, 0x1b, 0x37, 0x04, 0x95,
- 0x6f, 0x40, 0xa4, 0x72, 0x65, 0xe3, 0xc6, 0x30, 0x55, 0x36, 0x1e, 0xf0, 0x15, 0x0a, 0xb5, 0x2c,
- 0x9b, 0x29, 0x24, 0x8c, 0xee, 0x21, 0x6f, 0x02, 0xd2, 0x93, 0x8d, 0x87, 0x0c, 0xc8, 0xc6, 0xc3,
- 0xbe, 0x0a, 0x58, 0x45, 0x36, 0x33, 0xd0, 0xaa, 0xe5, 0x0a, 0xa0, 0x15, 0xd9, 0x78, 0x68, 0x55,
- 0x36, 0x1e, 0xf8, 0x33, 0x00, 0xf6, 0x65, 0x33, 0x8d, 0x55, 0x0d, 0x7f, 0x16, 0xb0, 0xbe, 0x6c,
- 0x82, 0xb3, 0x93, 0xb2, 0xf1, 0xa0, 0xaf, 0x01, 0xd4, 0x93, 0x4d, 0xd0, 0x2a, 0xcb, 0xc6, 0x83,
- 0xbe, 0x0e, 0x50, 0x5f, 0x36, 0x41, 0x2c, 0xcb, 0xc6, 0xc3, 0xbe, 0x41, 0xf9, 0xcd, 0x95, 0x8d,
- 0x87, 0x55, 0x64, 0xe3, 0x41, 0x7f, 0x13, 0x73, 0xa1, 0x27, 0x1b, 0x0f, 0xaa, 0xca, 0xc6, 0xc3,
- 0xfe, 0x16, 0x62, 0x7d, 0xd9, 0x4c, 0x83, 0xd5, 0x55, 0xf8, 0x6d, 0x04, 0xfb, 0xb2, 0xf1, 0xc0,
- 0x4b, 0xe4, 0x04, 0xca, 0xe6, 0xc8, 0xee, 0xb4, 0x4f, 0x7b, 0x28, 0xb1, 0x5b, 0xa8, 0x9b, 0x46,
- 0x6a, 0x32, 0x3a, 0xb5, 0xd1, 0x13, 0xe8, 0x7c, 0xe8, 0xf6, 0x01, 0x7e, 0xc1, 0x95, 0x8f, 0x4f,
- 0xb8, 0x8d, 0xfa, 0x69, 0x24, 0x40, 0xba, 0x25, 0xa9, 0xa1, 0x69, 0x3c, 0xf8, 0xe2, 0xe3, 0xef,
- 0xa0, 0x8a, 0x1a, 0x09, 0x50, 0x6f, 0x49, 0x2a, 0xc9, 0xc7, 0xd7, 0xc4, 0x05, 0x5f, 0x4a, 0x3e,
- 0xe3, 0x4d, 0xd4, 0x52, 0x23, 0x59, 0x33, 0x97, 0xad, 0x05, 0x57, 0x50, 0xb3, 0x48, 0x81, 0x61,
- 0xde, 0x42, 0x49, 0x35, 0x92, 0xab, 0x75, 0x8f, 0xa4, 0x8e, 0x64, 0xa2, 0x0c, 0x59, 0x58, 0x3e,
- 0xe7, 0x6d, 0x54, 0x56, 0x23, 0x05, 0x03, 0x2d, 0x83, 0x18, 0x65, 0xf7, 0x0c, 0x4e, 0x60, 0x9c,
- 0x25, 0x54, 0x58, 0x23, 0x05, 0xe3, 0xb8, 0x9c, 0xe0, 0x38, 0x0b, 0xae, 0xd0, 0x7c, 0xca, 0xe7,
- 0x50, 0x69, 0x8d, 0x4c, 0xad, 0x5a, 0xaf, 0xae, 0xdc, 0x83, 0x55, 0xa0, 0x7e, 0x9f, 0x53, 0xc7,
- 0x71, 0x58, 0x72, 0x3e, 0x69, 0x19, 0x35, 0xd7, 0xc8, 0x98, 0x6b, 0xd5, 0xbb, 0xe6, 0x5d, 0x18,
- 0x49, 0x02, 0x7c, 0xd6, 0x17, 0x90, 0xc5, 0xe2, 0xf3, 0x59, 0x55, 0x54, 0x5f, 0x43, 0x3f, 0xb1,
- 0x7b, 0x3d, 0xe7, 0xad, 0x9b, 0x95, 0x0f, 0x9d, 0x51, 0xef, 0xe8, 0xd5, 0x8a, 0x00, 0xbe, 0x84,
- 0xaa, 0xa3, 0x2e, 0xb8, 0x82, 0xf4, 0xe9, 0xbf, 0x8c, 0xe7, 0xb0, 0x62, 0x23, 0xbb, 0xde, 0x3d,
- 0x1e, 0x38, 0x63, 0x1b, 0x7c, 0x25, 0x44, 0x68, 0x4d, 0xf6, 0xc3, 0xeb, 0xf8, 0x2b, 0x48, 0x5b,
- 0x68, 0x24, 0xdf, 0x06, 0x51, 0xe8, 0xac, 0xd0, 0x19, 0x9c, 0xc0, 0x3a, 0xfe, 0x2a, 0x72, 0x0c,
- 0xe0, 0x80, 0x30, 0x74, 0x16, 0xaa, 0xcf, 0x59, 0x13, 0x97, 0x42, 0x79, 0xb1, 0x35, 0x6c, 0x3f,
- 0x7e, 0x02, 0x3c, 0x13, 0xd3, 0xe3, 0x7a, 0x42, 0xd7, 0xac, 0x0b, 0x81, 0x14, 0xb9, 0x47, 0xdd,
- 0xc6, 0x3d, 0x71, 0x39, 0x9c, 0x28, 0x5d, 0x66, 0x0d, 0xf3, 0x25, 0x31, 0x2f, 0x06, 0x73, 0x66,
- 0x88, 0xaa, 0x04, 0x60, 0x97, 0x5a, 0xc7, 0x04, 0xea, 0x53, 0xfd, 0x48, 0xcc, 0xd4, 0xff, 0x27,
- 0xae, 0x4c, 0xa7, 0x52, 0x97, 0xbc, 0x82, 0x19, 0x95, 0xc8, 0x97, 0xc2, 0x59, 0x75, 0x8a, 0x3e,
- 0x63, 0xec, 0x55, 0x4c, 0xb1, 0x2a, 0x7d, 0x6a, 0xf4, 0x77, 0x44, 0x79, 0x2a, 0xd9, 0xba, 0xec,
- 0x35, 0xcc, 0xb9, 0xc4, 0x7e, 0x39, 0x94, 0x77, 0xc3, 0xe4, 0x19, 0x43, 0xdf, 0xc5, 0x24, 0xac,
- 0x90, 0xa7, 0x46, 0xa6, 0x25, 0x0b, 0xa6, 0x63, 0x97, 0x7b, 0x0f, 0xb3, 0x32, 0x2f, 0x59, 0x20,
- 0x33, 0xab, 0xe3, 0x86, 0xf2, 0xb3, 0xcb, 0x6d, 0x60, 0x9a, 0xe6, 0x71, 0x83, 0xa9, 0x9a, 0xc9,
- 0x9f, 0x47, 0xf2, 0xfe, 0xec, 0x19, 0xff, 0x38, 0x89, 0x09, 0x96, 0xd9, 0xfb, 0xb3, 0xa6, 0xec,
- 0xb1, 0x67, 0x4c, 0xf9, 0x27, 0xc8, 0x36, 0x14, 0xf6, 0xd4, 0x9c, 0x1f, 0x0a, 0xaf, 0xe2, 0x38,
- 0x1e, 0x39, 0xa7, 0xc3, 0xf2, 0x26, 0x1c, 0xed, 0x84, 0x79, 0x63, 0xaa, 0xfa, 0x71, 0x0f, 0x79,
- 0x5b, 0x88, 0xb2, 0x82, 0x24, 0x69, 0x45, 0xda, 0x95, 0x56, 0xf6, 0x60, 0xdc, 0xd9, 0x56, 0x24,
- 0xca, 0xb3, 0xa2, 0x90, 0xd0, 0x8a, 0x1b, 0xf4, 0xa5, 0x95, 0xf7, 0x61, 0x53, 0xcd, 0xb2, 0xe2,
- 0xa6, 0x00, 0xb6, 0x12, 0x20, 0x2d, 0xae, 0xf8, 0xf5, 0x16, 0xf5, 0x1b, 0x9f, 0x0d, 0x17, 0x60,
- 0x5b, 0x74, 0x7e, 0x0e, 0x56, 0x5a, 0x92, 0xa6, 0x38, 0x37, 0x4d, 0xfb, 0xff, 0x11, 0xb4, 0x80,
- 0x37, 0xd3, 0xb4, 0x9f, 0x9a, 0x41, 0xab, 0xfc, 0x9a, 0x06, 0xc5, 0x26, 0xd4, 0x93, 0x46, 0x4e,
- 0xa4, 0xde, 0x6b, 0x6e, 0x3f, 0xd4, 0x5f, 0xc2, 0x5f, 0xeb, 0xcd, 0xe6, 0x23, 0x5d, 0x33, 0xf2,
- 0x22, 0xbd, 0xfe, 0x95, 0x83, 0x8d, 0x7d, 0x3d, 0x61, 0x94, 0x44, 0x61, 0x73, 0x7b, 0x77, 0x6b,
- 0xc3, 0xda, 0xb3, 0xb6, 0x77, 0x0f, 0xf4, 0x24, 0xf6, 0x6d, 0x3e, 0x6a, 0xde, 0x3f, 0xd0, 0x53,
- 0x46, 0x56, 0x24, 0xb1, 0x2d, 0x6d, 0x08, 0x91, 0xd9, 0x3f, 0x80, 0xfe, 0x2d, 0x3d, 0x83, 0x56,
- 0x0e, 0xb6, 0x77, 0x36, 0xf4, 0x2c, 0x22, 0x0f, 0xde, 0xdd, 0x7b, 0xb4, 0xa1, 0xe7, 0xf0, 0xe7,
- 0x7d, 0xcb, 0xba, 0xff, 0x15, 0x3d, 0x8f, 0xa4, 0x9d, 0xfb, 0x7b, 0xba, 0xa0, 0xee, 0xfb, 0xeb,
- 0xd0, 0x5d, 0x30, 0x8a, 0x22, 0xb7, 0xf9, 0xee, 0xee, 0x83, 0x83, 0xed, 0xe6, 0xae, 0x5e, 0xac,
- 0xfc, 0x7a, 0x42, 0x88, 0x2d, 0x67, 0xff, 0x49, 0x77, 0x48, 0x55, 0xf1, 0x75, 0x21, 0xc6, 0xf0,
- 0xbb, 0x45, 0xd2, 0xe3, 0xca, 0x2e, 0x8f, 0x2d, 0x14, 0x74, 0x8c, 0x57, 0x45, 0x91, 0xba, 0x3b,
- 0x32, 0x14, 0x50, 0x41, 0x97, 0xb5, 0x0a, 0xd8, 0xc6, 0xd1, 0x21, 0x08, 0x59, 0xad, 0x53, 0x1d,
- 0x97, 0x51, 0x20, 0xab, 0x75, 0xa8, 0xef, 0xe9, 0xb1, 0x35, 0xa6, 0xb0, 0x4e, 0xb5, 0x5b, 0xde,
- 0xa2, 0x71, 0x65, 0xa0, 0x07, 0x91, 0xd3, 0x98, 0x52, 0x16, 0xa5, 0x69, 0x89, 0xba, 0xee, 0x2e,
- 0xe1, 0x0f, 0x29, 0x0b, 0x9f, 0xb0, 0xd8, 0x14, 0x79, 0xaf, 0x1d, 0xc7, 0xa2, 0x56, 0x9e, 0x91,
- 0x4e, 0x33, 0x12, 0xd4, 0xe4, 0x4d, 0x49, 0x02, 0xd8, 0x9b, 0x05, 0xf2, 0x46, 0x92, 0xa4, 0x3b,
- 0x95, 0xeb, 0x62, 0x6e, 0xd7, 0x19, 0xc8, 0x2d, 0x44, 0xab, 0x54, 0x14, 0x5a, 0xbb, 0xac, 0x51,
- 0x09, 0xa3, 0xb5, 0x2b, 0x37, 0x84, 0x50, 0xfa, 0x74, 0xa1, 0x1d, 0xca, 0x3e, 0xda, 0x88, 0xda,
- 0x61, 0xe5, 0x4d, 0x91, 0xd9, 0x69, 0x3f, 0x3b, 0x68, 0x1f, 0xc3, 0x58, 0xa2, 0xd7, 0x1e, 0x4f,
- 0x60, 0x6d, 0x50, 0x2a, 0xff, 0x0b, 0xff, 0x34, 0x3a, 0x71, 0xe5, 0xb1, 0x55, 0x4a, 0xe5, 0xa9,
- 0x10, 0xcd, 0xde, 0xd1, 0x8e, 0x3d, 0x1e, 0xb7, 0x8f, 0x6d, 0x38, 0x2f, 0x64, 0x06, 0x60, 0xd4,
- 0xc6, 0x6b, 0x0a, 0x2c, 0xe6, 0xaf, 0xfa, 0xab, 0xe0, 0xa3, 0x96, 0x76, 0x09, 0x62, 0x31, 0x14,
- 0x3c, 0x48, 0x0e, 0x4e, 0xfb, 0x74, 0x59, 0x91, 0xb6, 0xf0, 0xe7, 0xe2, 0x35, 0x91, 0x91, 0x18,
- 0xbc, 0x14, 0x19, 0xb4, 0xfb, 0x76, 0x59, 0x8e, 0x4b, 0xbf, 0x2b, 0xbf, 0xa4, 0x09, 0xb1, 0x6b,
- 0x7f, 0x78, 0x8e, 0x31, 0x7d, 0x54, 0xcc, 0x98, 0x49, 0x39, 0xe6, 0x3b, 0x71, 0x63, 0xa2, 0xce,
- 0x3a, 0x8e, 0x73, 0xd4, 0x92, 0xaf, 0x58, 0xde, 0xab, 0xe4, 0xb1, 0x85, 0xde, 0x5a, 0xe5, 0x7d,
- 0x51, 0xdc, 0x1e, 0x0c, 0xec, 0x91, 0xeb, 0x13, 0x98, 0x38, 0x71, 0xc6, 0x13, 0xbe, 0xe0, 0xa1,
- 0xdf, 0x46, 0x59, 0xa4, 0x86, 0xce, 0x68, 0x22, 0xe7, 0xd9, 0x48, 0xc1, 0x99, 0x66, 0xd9, 0xa2,
- 0x16, 0xe3, 0x9a, 0xc8, 0x3f, 0x76, 0x80, 0xfe, 0x18, 0x27, 0x91, 0xa4, 0xda, 0xc2, 0x6f, 0xa8,
- 0xfc, 0x82, 0x26, 0x8a, 0xcd, 0xc9, 0x89, 0x6f, 0x1c, 0x7c, 0x7f, 0x62, 0x3f, 0x27, 0xf7, 0xc0,
- 0x77, 0xf8, 0x89, 0x57, 0x3b, 0x3f, 0xdd, 0xee, 0x9d, 0xca, 0x0b, 0x9f, 0xa2, 0x25, 0x1f, 0x8c,
- 0x4b, 0x22, 0xf3, 0xa1, 0xdd, 0x3d, 0x3e, 0x99, 0x90, 0xcd, 0x84, 0xc5, 0x4f, 0x50, 0x26, 0xa4,
- 0xbb, 0xe8, 0x6c, 0x39, 0x45, 0xeb, 0x75, 0xc9, 0x5f, 0x2f, 0x75, 0x0e, 0x96, 0x04, 0xdd, 0xc9,
- 0xe5, 0x8e, 0xf4, 0x9f, 0x83, 0x7f, 0x89, 0xca, 0xff, 0x24, 0x45, 0x7e, 0xe7, 0xb9, 0xeb, 0x05,
- 0x8c, 0xf9, 0xd8, 0x39, 0x1d, 0xc8, 0x39, 0xa6, 0x2d, 0xf9, 0xe0, 0xad, 0x5d, 0x42, 0x59, 0x3b,
- 0x40, 0x3e, 0x3d, 0x75, 0x26, 0x36, 0xb9, 0x91, 0xb7, 0xe4, 0x03, 0xce, 0x62, 0x68, 0x4f, 0xc0,
- 0x07, 0xac, 0xfc, 0xf0, 0xa7, 0xef, 0x57, 0xfa, 0x1c, 0x7e, 0xc1, 0xf9, 0x37, 0xe3, 0xe0, 0xaa,
- 0x8c, 0xcb, 0x19, 0xba, 0x74, 0x52, 0xe0, 0xea, 0x6a, 0x59, 0x8c, 0x02, 0x99, 0xe4, 0x21, 0x9e,
- 0xb7, 0xe4, 0x08, 0xc5, 0x30, 0x25, 0x30, 0x42, 0x0e, 0x80, 0xd4, 0x60, 0xac, 0x88, 0xdc, 0x61,
- 0xf7, 0x89, 0x3d, 0x3e, 0x81, 0x17, 0x93, 0x05, 0xaf, 0xe6, 0xcd, 0x2b, 0x3e, 0xc7, 0x5b, 0x8b,
- 0xa5, 0x07, 0x4e, 0xcf, 0x19, 0x59, 0x1e, 0x14, 0xf2, 0x6d, 0x7e, 0xec, 0xf4, 0x6d, 0x29, 0x96,
- 0x1c, 0xa5, 0x89, 0xeb, 0xb3, 0x78, 0xfb, 0x00, 0x72, 0xc3, 0x81, 0x8b, 0x37, 0xae, 0x4a, 0x47,
- 0x0f, 0xf1, 0x30, 0x58, 0x16, 0x54, 0xec, 0xa2, 0x43, 0x74, 0x38, 0x34, 0x16, 0xd1, 0xa1, 0xe3,
- 0x0e, 0xe6, 0x78, 0x88, 0x76, 0x58, 0x29, 0x79, 0xcf, 0x8b, 0x6f, 0x41, 0x1c, 0x71, 0x0d, 0xfa,
- 0x71, 0x44, 0xee, 0xdd, 0x3c, 0x6d, 0x2e, 0x19, 0x47, 0xe4, 0xc6, 0x7d, 0x4d, 0xa4, 0xc9, 0x6d,
- 0x8c, 0xb9, 0xd6, 0x06, 0x86, 0x78, 0x88, 0xb9, 0x5b, 0xd6, 0xc6, 0xc6, 0x2e, 0xc4, 0x78, 0x8c,
- 0xf6, 0x8f, 0xde, 0xdd, 0xd0, 0x13, 0xca, 0xeb, 0xff, 0x0d, 0x4d, 0x24, 0x37, 0x9e, 0xd1, 0x2b,
- 0xc6, 0x69, 0xb8, 0xdb, 0x03, 0x7f, 0x9b, 0xab, 0x22, 0xd5, 0x77, 0x46, 0xb6, 0x71, 0x61, 0xc6,
- 0x2c, 0xcb, 0xc7, 0xf4, 0x3a, 0x95, 0x7b, 0x51, 0xb0, 0x62, 0x11, 0xde, 0x7c, 0x43, 0xa4, 0x26,
- 0x36, 0xd8, 0x9c, 0xc9, 0x3b, 0x91, 0x03, 0x20, 0xc0, 0x84, 0x98, 0x04, 0x9b, 0xf4, 0x10, 0x5e,
- 0xc9, 0x4c, 0x68, 0x97, 0xa6, 0xc7, 0x90, 0xca, 0x7b, 0x42, 0x7f, 0xe0, 0xf4, 0x87, 0x3d, 0xfb,
- 0x19, 0x8c, 0x64, 0x0f, 0xc6, 0x90, 0xff, 0x50, 0x84, 0x9d, 0xee, 0x88, 0xb6, 0x24, 0xdd, 0x7e,
- 0xd2, 0x03, 0x6e, 0x91, 0xb1, 0x0d, 0x5b, 0xed, 0x88, 0xa3, 0x0f, 0x3f, 0x21, 0x7a, 0x72, 0xd2,
- 0x1d, 0xe1, 0x6e, 0xc4, 0xa0, 0x29, 0x1f, 0x2a, 0x5b, 0xa2, 0xc4, 0xa7, 0xe6, 0x31, 0x0f, 0x5c,
- 0xb9, 0x23, 0x8a, 0x6e, 0x13, 0x5d, 0x05, 0xc3, 0xc2, 0xbd, 0xbf, 0x61, 0x35, 0x61, 0x35, 0x61,
- 0x59, 0x9b, 0xbb, 0x1b, 0xb0, 0x96, 0xf0, 0xe3, 0xe0, 0xcb, 0xcd, 0xc0, 0x52, 0x5e, 0x13, 0x45,
- 0xcf, 0xf7, 0x7d, 0x7b, 0x42, 0x3d, 0x18, 0x5d, 0xb3, 0x8d, 0x44, 0x4e, 0xab, 0x64, 0x45, 0x7a,
- 0xa3, 0x3f, 0x9c, 0x3c, 0xaf, 0xfc, 0xac, 0x28, 0x30, 0xe8, 0x51, 0x17, 0x9c, 0x5d, 0x13, 0xd9,
- 0x3e, 0xcf, 0x57, 0xa3, 0x03, 0x8c, 0xaa, 0x29, 0x1f, 0xe7, 0xfe, 0xb6, 0x5c, 0xf4, 0x62, 0x4d,
- 0x64, 0x95, 0xc0, 0xc4, 0xfb, 0x33, 0xa1, 0xee, 0x4f, 0xb9, 0x93, 0x93, 0xca, 0x4e, 0xae, 0xec,
- 0x88, 0xac, 0x4c, 0x27, 0x63, 0x4a, 0x91, 0xb2, 0xf8, 0x91, 0x62, 0x92, 0x6f, 0xbe, 0x20, 0xdb,
- 0xe4, 0x7d, 0x2c, 0xc8, 0x8d, 0x04, 0xcb, 0x08, 0x19, 0x87, 0x04, 0x35, 0x49, 0xb9, 0xfd, 0x4e,
- 0x5a, 0xe4, 0xdc, 0x95, 0x02, 0x89, 0x67, 0x64, 0xc5, 0x41, 0xa6, 0xdc, 0x8a, 0x38, 0x4d, 0x35,
- 0x06, 0x74, 0x66, 0xb9, 0xaa, 0xe0, 0x50, 0x89, 0xe5, 0x6f, 0x46, 0x56, 0x11, 0x5e, 0x27, 0x24,
- 0xea, 0xa4, 0x57, 0xeb, 0x66, 0x64, 0x9d, 0x60, 0xdc, 0x14, 0x79, 0xaf, 0x32, 0xa0, 0xe0, 0xc6,
- 0x85, 0x6d, 0xce, 0x2d, 0x05, 0x14, 0x04, 0x18, 0x48, 0xfb, 0x55, 0x6c, 0xae, 0xe3, 0xe7, 0xfa,
- 0x9c, 0x7b, 0xbe, 0xa7, 0x0b, 0x69, 0xb7, 0x64, 0xcd, 0xf2, 0x89, 0xde, 0x07, 0x80, 0x85, 0xac,
- 0x52, 0x9f, 0x66, 0xf9, 0xd4, 0x0e, 0x80, 0x2c, 0x9f, 0xd3, 0x69, 0xeb, 0xfb, 0xc5, 0x68, 0x46,
- 0x9e, 0xcd, 0x61, 0x39, 0x73, 0xee, 0x69, 0x9c, 0xf6, 0xa5, 0x5f, 0x79, 0x66, 0xf9, 0x04, 0x6e,
- 0xbc, 0x89, 0x10, 0xb9, 0xfc, 0x10, 0x02, 0x66, 0x97, 0x99, 0x59, 0x2e, 0x33, 0x61, 0x52, 0x59,
- 0xae, 0x2e, 0x29, 0x24, 0x28, 0x25, 0x65, 0x46, 0x96, 0x94, 0xc6, 0x0d, 0x32, 0x27, 0x27, 0x55,
- 0xf4, 0xcb, 0xc7, 0x2c, 0x1f, 0xd9, 0xfd, 0x7e, 0x3a, 0xff, 0x78, 0xa5, 0x62, 0x96, 0x0f, 0xe5,
- 0xc6, 0x2a, 0xbe, 0x2f, 0xd4, 0x37, 0x9c, 0x7d, 0x30, 0x08, 0x96, 0x7d, 0xe1, 0xb9, 0xef, 0x54,
- 0xc6, 0xc0, 0x86, 0x8c, 0x20, 0xf0, 0x2a, 0x69, 0x37, 0x2c, 0x22, 0x6f, 0xaf, 0x3b, 0xe8, 0xc0,
- 0xa1, 0x08, 0x57, 0x22, 0x09, 0x3f, 0xa1, 0x0f, 0x5b, 0xa4, 0x06, 0x76, 0xb1, 0x4f, 0xa7, 0xbe,
- 0xd4, 0xdb, 0xb2, 0x13, 0x9b, 0x20, 0x57, 0xa6, 0xa1, 0xb3, 0x3d, 0x80, 0xd3, 0x0d, 0xf1, 0x06,
- 0xed, 0x81, 0x95, 0xea, 0x40, 0x83, 0xf1, 0x86, 0x48, 0x8e, 0x4f, 0x0f, 0xcb, 0x46, 0xf8, 0x5b,
- 0xc1, 0xfe, 0xe9, 0xa1, 0xeb, 0x8a, 0x85, 0x08, 0xb0, 0x9f, 0x03, 0x81, 0xb6, 0x7e, 0xc6, 0x1e,
- 0x39, 0xe5, 0x0b, 0xb4, 0x84, 0x2f, 0x59, 0x59, 0x68, 0x79, 0x1f, 0x1a, 0xce, 0x19, 0xfc, 0xe0,
- 0xa4, 0x54, 0x50, 0xec, 0xc2, 0x71, 0x57, 0x1b, 0xc8, 0xb4, 0xdb, 0xd0, 0xd6, 0x2c, 0x6d, 0x50,
- 0x39, 0x10, 0x45, 0xf7, 0x54, 0x4e, 0xf3, 0x35, 0x71, 0x27, 0x81, 0x59, 0xda, 0x9f, 0xf3, 0xe6,
- 0x35, 0xdf, 0x3d, 0x15, 0xc6, 0xe9, 0x42, 0x42, 0x2b, 0x7a, 0xc8, 0x15, 0xad, 0xf2, 0x43, 0x48,
- 0xf8, 0x3b, 0x10, 0x1d, 0xbd, 0x1b, 0x48, 0xd8, 0xa0, 0x87, 0xb0, 0x33, 0xc6, 0x64, 0x36, 0x67,
- 0xc9, 0x07, 0xe3, 0x35, 0x51, 0xa4, 0x1f, 0x6e, 0x35, 0x95, 0xf0, 0x8a, 0xf5, 0x02, 0xb5, 0x73,
- 0x09, 0x05, 0x3b, 0x1e, 0x5e, 0xe2, 0x98, 0x23, 0x19, 0xfd, 0x36, 0x3e, 0x23, 0x0a, 0xf8, 0xd7,
- 0x65, 0xa6, 0xbc, 0xd3, 0x9f, 0xc0, 0x66, 0x26, 0xbe, 0x21, 0xe6, 0xe8, 0xed, 0x7b, 0xb0, 0xac,
- 0x57, 0x98, 0x17, 0x65, 0x07, 0x03, 0xcb, 0x22, 0x2b, 0x43, 0xc1, 0x98, 0xbe, 0xff, 0xe4, 0x2d,
- 0xf7, 0x11, 0xc3, 0x2b, 0x1d, 0xab, 0x65, 0x8e, 0xce, 0x5a, 0xfc, 0x54, 0xb9, 0x2f, 0x72, 0x94,
- 0xa5, 0xe0, 0x4c, 0x68, 0x54, 0x84, 0x76, 0x5c, 0xb6, 0x29, 0x47, 0x5e, 0x54, 0xce, 0xcc, 0xdc,
- 0xbd, 0xb4, 0x65, 0x69, 0xc7, 0x8b, 0x0b, 0x42, 0xdb, 0xc2, 0x43, 0xec, 0x33, 0x0e, 0xd3, 0xda,
- 0xb3, 0x4a, 0x93, 0x4d, 0xc0, 0x11, 0x2f, 0xce, 0x04, 0x74, 0x4b, 0x13, 0xaf, 0x4c, 0x99, 0xc0,
- 0xa7, 0xe7, 0xfc, 0x31, 0x4c, 0x7b, 0x8e, 0x87, 0x66, 0xda, 0x9e, 0xe0, 0xf8, 0x9e, 0x03, 0xf3,
- 0xc3, 0xee, 0x0e, 0x1d, 0x6e, 0xe0, 0x50, 0xdc, 0xa9, 0x7c, 0x9a, 0x12, 0xf3, 0x1c, 0x44, 0xbf,
- 0xdc, 0x9d, 0x9c, 0xec, 0xb4, 0x87, 0xc6, 0x23, 0x51, 0xc4, 0xf8, 0xd9, 0xea, 0xb7, 0x87, 0x43,
- 0xdc, 0xa8, 0x1a, 0x1d, 0x2a, 0x6e, 0x4f, 0x05, 0x65, 0xc6, 0x2f, 0xed, 0x02, 0x78, 0x47, 0x62,
- 0x37, 0x06, 0x93, 0xd1, 0x73, 0xab, 0x30, 0xf0, 0x5b, 0x8c, 0x6d, 0x51, 0xe8, 0x8f, 0x8f, 0x3d,
- 0x63, 0x09, 0x32, 0x76, 0x2b, 0xd2, 0xd8, 0xce, 0xf8, 0x38, 0x60, 0x4b, 0xf4, 0xbd, 0x06, 0x74,
- 0x0c, 0x23, 0xaf, 0x67, 0x2b, 0x79, 0x86, 0x63, 0x18, 0x24, 0x82, 0x8e, 0x1d, 0xfa, 0x2d, 0x50,
- 0xf7, 0x0a, 0xdc, 0x48, 0x13, 0x07, 0x2b, 0x0e, 0xd2, 0x4a, 0xc1, 0x7c, 0x3d, 0xd2, 0x16, 0xc4,
- 0xa4, 0x03, 0x07, 0xfe, 0x23, 0x0d, 0xe1, 0x16, 0xa4, 0xc7, 0xc5, 0x2f, 0x08, 0x3d, 0x3c, 0x7f,
- 0xf5, 0x20, 0x9b, 0x9e, 0x71, 0x90, 0xcd, 0xf3, 0x41, 0xb6, 0x91, 0xb8, 0xab, 0x2d, 0xbe, 0x27,
- 0x4a, 0xa1, 0x29, 0xab, 0x74, 0x43, 0xd2, 0xdf, 0x56, 0xe9, 0x05, 0xf3, 0xb2, 0xf2, 0x29, 0x56,
- 0x7d, 0xb5, 0xaa, 0x5d, 0xf0, 0x2b, 0x3c, 0x7d, 0xd5, 0x70, 0x2e, 0xe6, 0x80, 0x4d, 0xfc, 0x77,
- 0xc4, 0x5c, 0x60, 0xca, 0x2a, 0x39, 0x7f, 0xc6, 0xa4, 0x2a, 0x3f, 0x9f, 0x16, 0xe9, 0xe6, 0xc0,
- 0x76, 0x3a, 0xc6, 0xe5, 0x60, 0x46, 0xfc, 0xe2, 0x4b, 0x6e, 0x36, 0xbc, 0x12, 0xca, 0x86, 0xd0,
- 0xe3, 0xe6, 0xc2, 0x2b, 0xa1, 0x5c, 0xe8, 0x76, 0x41, 0xc0, 0xbe, 0x3e, 0x95, 0x09, 0xa1, 0xd3,
- 0x4f, 0x83, 0xd7, 0xa7, 0xd2, 0xa0, 0xdf, 0x0d, 0xec, 0xab, 0xe1, 0x1c, 0x08, 0xbd, 0x5e, 0xfe,
- 0xbb, 0x1a, 0xce, 0x7f, 0x5e, 0x27, 0x30, 0xaf, 0x84, 0x72, 0x1f, 0xb9, 0x24, 0xb3, 0xde, 0xd5,
- 0x70, 0xd6, 0x23, 0x1e, 0xe7, 0xbb, 0xab, 0xe1, 0x7c, 0x47, 0x9d, 0x9c, 0xdf, 0xae, 0x84, 0xf2,
- 0x1b, 0x19, 0x95, 0x89, 0xed, 0x6a, 0x38, 0xb1, 0x49, 0x9e, 0xe2, 0xa9, 0x9a, 0xd5, 0xbc, 0x4e,
- 0xf0, 0xd4, 0x0c, 0xa5, 0xb4, 0xe8, 0x73, 0x3d, 0xbd, 0x0b, 0x0a, 0xef, 0x75, 0x5c, 0x36, 0xf7,
- 0xc8, 0x59, 0x8a, 0xf9, 0x5a, 0x4d, 0xab, 0xe9, 0x1e, 0xb9, 0x4c, 0x91, 0xed, 0x70, 0xdd, 0xa8,
- 0x53, 0x8c, 0x52, 0x64, 0x49, 0x2f, 0x7f, 0x69, 0xb3, 0x45, 0xb1, 0x8a, 0xe6, 0x25, 0x4f, 0xef,
- 0xb7, 0x20, 0x18, 0xb5, 0x1e, 0xb5, 0x47, 0xc7, 0x00, 0x6c, 0x41, 0x25, 0xee, 0xd5, 0xde, 0xf8,
- 0xfe, 0x0b, 0x1d, 0xee, 0xc1, 0x12, 0xfd, 0x92, 0x2b, 0xae, 0x23, 0xea, 0xd5, 0x58, 0x5e, 0x8b,
- 0x97, 0x71, 0xd1, 0xa4, 0x31, 0x8a, 0x7a, 0x0b, 0x1c, 0xf5, 0xd6, 0xe1, 0x74, 0x79, 0x3a, 0x80,
- 0x13, 0xf1, 0x7a, 0x5e, 0x64, 0x27, 0xce, 0xa8, 0xdf, 0x9e, 0x38, 0x95, 0x1f, 0x41, 0x45, 0x0d,
- 0x27, 0xe6, 0x3e, 0x74, 0x3c, 0x85, 0xc2, 0x11, 0xd2, 0x5e, 0xbf, 0xfd, 0x04, 0xe2, 0x87, 0xdd,
- 0x7a, 0x3c, 0x72, 0xf7, 0x41, 0x1e, 0x9b, 0x76, 0xec, 0x07, 0x20, 0xf1, 0xb2, 0x7b, 0x18, 0x27,
- 0xed, 0x90, 0x24, 0xf9, 0x70, 0x7e, 0x91, 0x8f, 0x97, 0x19, 0x7e, 0x87, 0xee, 0x01, 0x53, 0x56,
- 0x0c, 0x59, 0x7e, 0x7b, 0xf4, 0x84, 0x92, 0x9f, 0xd8, 0xfd, 0x61, 0xeb, 0x31, 0x49, 0x05, 0xe5,
- 0x90, 0xc6, 0xe7, 0x07, 0xb0, 0x8b, 0x93, 0x90, 0x1a, 0x49, 0x24, 0x67, 0xbc, 0x17, 0xc4, 0x41,
- 0x1e, 0x4c, 0x42, 0xec, 0x23, 0xd9, 0x14, 0xcc, 0x05, 0xe5, 0x44, 0x20, 0x93, 0x10, 0xc2, 0xa0,
- 0xdf, 0x9b, 0xf7, 0x9d, 0x92, 0x48, 0x6e, 0x36, 0x9b, 0x98, 0xe5, 0xe1, 0x4f, 0x55, 0xd7, 0x1a,
- 0x9f, 0x13, 0xb9, 0xe3, 0x91, 0x6d, 0x63, 0x78, 0x98, 0x5d, 0x5d, 0x7c, 0x40, 0x59, 0xcd, 0x03,
- 0x35, 0xe0, 0x68, 0xfc, 0x58, 0xd6, 0x17, 0x46, 0x44, 0xd5, 0x59, 0xfe, 0x5d, 0x79, 0x17, 0xb1,
- 0xe8, 0x77, 0x87, 0x2b, 0x12, 0xcb, 0xb5, 0xd1, 0xd8, 0x83, 0x82, 0xaf, 0x75, 0x96, 0xc1, 0x8f,
- 0x64, 0x76, 0x89, 0x33, 0x98, 0x1b, 0x71, 0x53, 0x63, 0x43, 0x2c, 0x0c, 0x1c, 0xf7, 0xfe, 0xbf,
- 0x75, 0x24, 0xf7, 0xd8, 0x95, 0xe9, 0x43, 0x9b, 0x6b, 0xdc, 0x96, 0xdf, 0xdc, 0x06, 0x0e, 0x77,
- 0xc8, 0x5d, 0xd9, 0x78, 0x20, 0x74, 0xc5, 0x0c, 0x15, 0x99, 0x71, 0x56, 0x3a, 0xf2, 0x23, 0x9f,
- 0x67, 0x85, 0xf6, 0x7d, 0xc8, 0x88, 0xdc, 0x99, 0x31, 0x46, 0x8e, 0xe5, 0x17, 0x53, 0xcf, 0x08,
- 0x85, 0xba, 0x69, 0x23, 0x18, 0x6b, 0xa2, 0x8d, 0x9c, 0xc8, 0x8f, 0xa9, 0xaa, 0x91, 0xd5, 0x7a,
- 0x68, 0x55, 0x4e, 0xcf, 0x74, 0xa5, 0x2b, 0xbf, 0x85, 0x7a, 0x56, 0x64, 0x00, 0x9c, 0x61, 0x26,
- 0xde, 0x99, 0x0f, 0xe4, 0x67, 0xd2, 0x80, 0x99, 0x29, 0x6f, 0xc6, 0x67, 0x7a, 0xf3, 0x44, 0x7e,
- 0x93, 0xf4, 0xcc, 0xec, 0xcf, 0xf2, 0x66, 0x7c, 0xa6, 0x37, 0x3d, 0xf9, 0xb5, 0x32, 0x60, 0x06,
- 0xbc, 0xd9, 0x12, 0x86, 0xfa, 0xaa, 0x39, 0x4f, 0xc4, 0xd8, 0xe9, 0xcb, 0x6f, 0xd0, 0xfe, 0xcb,
- 0x96, 0x94, 0x59, 0x86, 0xe2, 0x1d, 0x1a, 0xc8, 0xcf, 0xd3, 0x41, 0x43, 0xe0, 0xd1, 0xb6, 0xb8,
- 0xa0, 0x4e, 0xec, 0x1c, 0x2e, 0x39, 0x60, 0xa9, 0x64, 0x2d, 0xf8, 0x53, 0x63, 0xce, 0x4c, 0x53,
- 0xf1, 0x4e, 0x0d, 0xc1, 0x94, 0x3e, 0x65, 0x0a, 0xbc, 0xba, 0x2f, 0x4a, 0x8a, 0xa9, 0x43, 0xca,
- 0xd0, 0xd1, 0x66, 0x9e, 0xca, 0xff, 0x4f, 0xc0, 0x33, 0x83, 0x19, 0x3d, 0xfc, 0xc6, 0x38, 0xc7,
- 0x45, 0x1b, 0x19, 0xc9, 0x8f, 0xdc, 0xbe, 0x2f, 0xc4, 0x08, 0x6d, 0x09, 0xaa, 0xb4, 0xe3, 0xac,
- 0x8c, 0xe5, 0xe7, 0x6f, 0xdf, 0x15, 0x24, 0x34, 0xba, 0x81, 0xe9, 0xd8, 0x98, 0xe4, 0x62, 0x6c,
- 0x4c, 0x28, 0x22, 0xbf, 0x1e, 0x09, 0x58, 0x52, 0xaf, 0x42, 0x94, 0x69, 0xe3, 0x23, 0xbc, 0x84,
- 0xf9, 0xf3, 0x07, 0xa4, 0x8f, 0x34, 0x59, 0x17, 0xd7, 0x96, 0xb0, 0x74, 0xb6, 0xe6, 0x8e, 0x02,
- 0x71, 0x69, 0x43, 0xcc, 0x9d, 0x3b, 0x28, 0x7d, 0xac, 0xc9, 0xea, 0x12, 0x2d, 0x59, 0xc5, 0xa3,
- 0x60, 0x64, 0x9a, 0x3b, 0x77, 0x58, 0xfa, 0x44, 0x93, 0x57, 0x11, 0x75, 0xd3, 0x33, 0xe2, 0x46,
- 0xa6, 0xb9, 0x73, 0x87, 0xa5, 0xaf, 0xca, 0xda, 0x31, 0x51, 0xaf, 0xa9, 0x46, 0x28, 0x16, 0xcc,
- 0x9f, 0x3f, 0x2c, 0x7d, 0x4d, 0xa3, 0x6b, 0x89, 0x44, 0xbd, 0xee, 0xad, 0x8b, 0x17, 0x99, 0xe6,
- 0xcf, 0x1f, 0x96, 0xbe, 0xae, 0xd1, 0xe5, 0x45, 0xa2, 0xbe, 0x12, 0x30, 0x13, 0xf4, 0xe6, 0xec,
- 0xb0, 0xf4, 0x0d, 0x8d, 0xee, 0x13, 0x12, 0xf5, 0x55, 0xcf, 0xcc, 0xfe, 0x94, 0x37, 0x67, 0x87,
- 0xa5, 0x6f, 0xd2, 0x29, 0x1e, 0xcc, 0xac, 0x05, 0xcc, 0x50, 0x64, 0x2a, 0xbd, 0x40, 0x58, 0xfa,
- 0x96, 0x46, 0xd7, 0x3e, 0x89, 0xfa, 0x5d, 0xcb, 0x1d, 0xdd, 0x8f, 0x4c, 0xa5, 0x17, 0x08, 0x4b,
- 0x9f, 0x6a, 0x74, 0x3b, 0x94, 0xa8, 0xdf, 0x0b, 0x1a, 0xa2, 0xc8, 0xa4, 0xbf, 0x48, 0x58, 0xfa,
- 0x36, 0x5a, 0x2a, 0x35, 0x12, 0x2b, 0xcb, 0x96, 0xeb, 0x80, 0x12, 0x99, 0xf4, 0x17, 0x09, 0x4b,
- 0xdf, 0x41, 0x53, 0x3a, 0x98, 0xaa, 0x86, 0x4c, 0x81, 0x57, 0x0f, 0x44, 0xf1, 0xbc, 0x61, 0xe9,
- 0xbb, 0xea, 0xad, 0x5b, 0xe1, 0x48, 0x89, 0x4d, 0x7b, 0xca, 0x3b, 0x3b, 0x33, 0x30, 0x7d, 0x8f,
- 0x6a, 0x9c, 0xc6, 0xdc, 0x17, 0xe5, 0xcd, 0x94, 0x24, 0xf8, 0xaf, 0x4f, 0x86, 0xa9, 0x1d, 0x7f,
- 0x7f, 0x9c, 0x19, 0xa3, 0xbe, 0xaf, 0xd1, 0xf5, 0x55, 0x91, 0x0d, 0x12, 0xde, 0xdb, 0x29, 0x32,
- 0x60, 0x7d, 0xe0, 0xcf, 0xf2, 0xac, 0x68, 0xf5, 0x03, 0xed, 0x45, 0xc2, 0x55, 0x03, 0x6f, 0x6b,
- 0xbd, 0xc5, 0xa0, 0x96, 0xcf, 0x8b, 0xd4, 0x33, 0x73, 0xb9, 0xaa, 0x1e, 0xc9, 0xd4, 0x5b, 0x5b,
- 0x19, 0xa4, 0x0a, 0x66, 0x49, 0xb9, 0xd8, 0xc6, 0x6b, 0x5b, 0x8b, 0x58, 0xcc, 0x36, 0x23, 0xd9,
- 0x1f, 0xc7, 0xb0, 0x4d, 0x66, 0xd7, 0x22, 0xd9, 0x9f, 0xc4, 0xb0, 0x6b, 0xcc, 0xae, 0x47, 0xb2,
- 0xbf, 0x1a, 0xc3, 0xae, 0x33, 0x7b, 0x25, 0x92, 0xfd, 0xb5, 0x18, 0xf6, 0x0a, 0xb3, 0x57, 0x23,
- 0xd9, 0x5f, 0x8f, 0x61, 0xaf, 0x32, 0x7b, 0x2d, 0x92, 0xfd, 0x8d, 0x18, 0xf6, 0x1a, 0xb3, 0xef,
- 0x46, 0xb2, 0xbf, 0x19, 0xc3, 0xbe, 0xcb, 0xec, 0x7b, 0x91, 0xec, 0x6f, 0xc5, 0xb0, 0xef, 0x49,
- 0x76, 0x75, 0x39, 0x92, 0xfd, 0x69, 0x34, 0xbb, 0xba, 0xcc, 0xec, 0x68, 0xad, 0x7d, 0x3b, 0x86,
- 0xcd, 0x5a, 0xab, 0x46, 0x6b, 0xed, 0x3b, 0x31, 0x6c, 0xd6, 0x5a, 0x35, 0x5a, 0x6b, 0xdf, 0x8d,
- 0x61, 0xb3, 0xd6, 0xaa, 0xd1, 0x5a, 0xfb, 0x5e, 0x0c, 0x9b, 0xb5, 0x56, 0x8d, 0xd6, 0xda, 0xf7,
- 0x63, 0xd8, 0xac, 0xb5, 0x6a, 0xb4, 0xd6, 0x7e, 0x10, 0xc3, 0x66, 0xad, 0x55, 0xa3, 0xb5, 0xf6,
- 0x7b, 0x31, 0x6c, 0xd6, 0x5a, 0x35, 0x5a, 0x6b, 0xbf, 0x1f, 0xc3, 0x66, 0xad, 0x55, 0xa3, 0xb5,
- 0xf6, 0x07, 0x31, 0x6c, 0xd6, 0x9a, 0x19, 0xad, 0xb5, 0x3f, 0x8c, 0x66, 0x9b, 0xac, 0x35, 0x33,
- 0x5a, 0x6b, 0x7f, 0x14, 0xc3, 0x66, 0xad, 0x99, 0xd1, 0x5a, 0xfb, 0xe3, 0x18, 0x36, 0x6b, 0xcd,
- 0x8c, 0xd6, 0xda, 0x0f, 0x63, 0xd8, 0xac, 0x35, 0x33, 0x5a, 0x6b, 0x7f, 0x12, 0xc3, 0x66, 0xad,
- 0x99, 0xd1, 0x5a, 0xfb, 0xd3, 0x18, 0x36, 0x6b, 0xcd, 0x8c, 0xd6, 0xda, 0x9f, 0xc5, 0xb0, 0x59,
- 0x6b, 0x66, 0xb4, 0xd6, 0xfe, 0x3c, 0x86, 0xcd, 0x5a, 0x33, 0xa3, 0xb5, 0xf6, 0x17, 0x31, 0x6c,
- 0xd6, 0x9a, 0x19, 0xad, 0xb5, 0xbf, 0x8c, 0x61, 0xb3, 0xd6, 0x6a, 0xd1, 0x5a, 0xfb, 0xab, 0x68,
- 0x76, 0x8d, 0xb5, 0x56, 0x8b, 0xd6, 0xda, 0x5f, 0xc7, 0xb0, 0x59, 0x6b, 0xb5, 0x68, 0xad, 0xfd,
- 0x4d, 0x0c, 0x9b, 0xb5, 0x56, 0x8b, 0xd6, 0xda, 0xdf, 0xc6, 0xb0, 0x59, 0x6b, 0xb5, 0x68, 0xad,
- 0xfd, 0x28, 0x86, 0xcd, 0x5a, 0xab, 0x45, 0x6b, 0xed, 0xef, 0x62, 0xd8, 0xac, 0xb5, 0x5a, 0xb4,
- 0xd6, 0xfe, 0x3e, 0x86, 0xcd, 0x5a, 0xab, 0x45, 0x6b, 0xed, 0x1f, 0x62, 0xd8, 0xac, 0xb5, 0x5a,
- 0xb4, 0xd6, 0xfe, 0x31, 0x86, 0xcd, 0x5a, 0xab, 0x45, 0x6b, 0xed, 0x9f, 0x62, 0xd8, 0xac, 0xb5,
- 0x7a, 0xb4, 0xd6, 0xfe, 0x39, 0x9a, 0x5d, 0x67, 0xad, 0xd5, 0xa3, 0xb5, 0xf6, 0x2f, 0x31, 0x6c,
- 0xd6, 0x5a, 0x3d, 0x5a, 0x6b, 0xff, 0x1a, 0xc3, 0x66, 0xad, 0xd5, 0xa3, 0xb5, 0xf6, 0x6f, 0x31,
- 0x6c, 0xd6, 0x5a, 0x3d, 0x5a, 0x6b, 0xff, 0x1e, 0xc3, 0x66, 0xad, 0xd5, 0xa3, 0xb5, 0xf6, 0x1f,
- 0x31, 0x6c, 0xd6, 0x5a, 0x3d, 0x5a, 0x6b, 0x3f, 0x8e, 0x61, 0xb3, 0xd6, 0xea, 0xd1, 0x5a, 0xfb,
- 0x49, 0x0c, 0x9b, 0xb5, 0x56, 0x8f, 0xd6, 0xda, 0x7f, 0xc6, 0xb0, 0x59, 0x6b, 0xf5, 0x68, 0xad,
- 0xfd, 0x57, 0x0c, 0x9b, 0xb5, 0xb6, 0x12, 0xad, 0xb5, 0xff, 0x8e, 0x66, 0xaf, 0x2c, 0xff, 0x5f,
- 0x00, 0x00, 0x00, 0xff, 0xff, 0x53, 0x6a, 0x15, 0xef, 0x13, 0x38, 0x00, 0x00,
+ // 4407 bytes of a gzipped FileDescriptorProto
+ 0x1f, 0x8b, 0x08, 0x00, 0x00, 0x09, 0x6e, 0x88, 0x02, 0xff, 0x94, 0x5a, 0x59, 0x77, 0xdb, 0x48,
+ 0x76, 0x36, 0xc0, 0xfd, 0x92, 0x12, 0xa1, 0xb2, 0xda, 0x4d, 0x4b, 0x5e, 0x60, 0xce, 0x74, 0x37,
+ 0xbd, 0x69, 0x24, 0x10, 0xa2, 0x6d, 0xba, 0xd3, 0xe7, 0x78, 0xa1, 0x64, 0x9d, 0xb1, 0x44, 0x05,
+ 0x52, 0x77, 0x9f, 0xe9, 0x3c, 0xf0, 0x50, 0x22, 0x48, 0xb3, 0x4d, 0x02, 0x34, 0x09, 0xc5, 0x52,
+ 0xf2, 0xd2, 0x2f, 0xc9, 0x6b, 0xb6, 0x97, 0xbc, 0xe6, 0x29, 0x4f, 0x49, 0xce, 0xc9, 0x9f, 0x48,
+ 0xba, 0x7b, 0xd6, 0x9e, 0x35, 0xeb, 0x64, 0x5f, 0x26, 0xfb, 0x36, 0x93, 0xe4, 0xa5, 0xe7, 0xd4,
+ 0xad, 0x02, 0x50, 0x00, 0x09, 0x48, 0x7e, 0x12, 0x51, 0xf5, 0x7d, 0xb7, 0x6e, 0x15, 0xbe, 0xba,
+ 0xb7, 0x6e, 0x41, 0x00, 0x8e, 0x39, 0x71, 0x56, 0x46, 0x63, 0xdb, 0xb1, 0x49, 0x96, 0xfe, 0xee,
+ 0xb4, 0x9d, 0x76, 0xf9, 0x3a, 0xa4, 0x37, 0xed, 0x86, 0x75, 0x34, 0x24, 0x57, 0x21, 0xd1, 0xb5,
+ 0xed, 0x92, 0xa4, 0xca, 0x95, 0x79, 0x6d, 0x6e, 0xc5, 0x45, 0xac, 0x6c, 0x34, 0x9b, 0x06, 0xed,
+ 0x29, 0xdf, 0x81, 0xfc, 0xa6, 0xbd, 0x6f, 0x4e, 0x9c, 0x8d, 0xbe, 0x39, 0xe8, 0x90, 0x45, 0x48,
+ 0x3d, 0x6d, 0x1f, 0x98, 0x03, 0x64, 0xe4, 0x8c, 0xd4, 0x80, 0x3e, 0x10, 0x02, 0xc9, 0xfd, 0x93,
+ 0x91, 0x59, 0x92, 0xb1, 0x31, 0xe9, 0x9c, 0x8c, 0xcc, 0xf2, 0xaf, 0x5c, 0xa1, 0x83, 0x50, 0x26,
+ 0xb9, 0x0e, 0xc9, 0x2f, 0xf7, 0xad, 0x0e, 0x1f, 0xe5, 0x35, 0x7f, 0x14, 0xd6, 0xbf, 0xf2, 0xe5,
+ 0xad, 0x9d, 0xc7, 0x46, 0xf2, 0x79, 0xdf, 0x42, 0xfb, 0xfb, 0xed, 0x83, 0x01, 0x35, 0x25, 0x51,
+ 0xfb, 0x0e, 0x7d, 0xa0, 0xad, 0xbb, 0xed, 0x71, 0x7b, 0x58, 0x4a, 0xa8, 0x52, 0x25, 0x65, 0xa4,
+ 0x46, 0xf4, 0x81, 0xdc, 0x87, 0x39, 0xc3, 0x7c, 0x71, 0xd4, 0x1f, 0x9b, 0x1d, 0x74, 0xae, 0x94,
+ 0x54, 0xe5, 0x4a, 0x7e, 0xda, 0x3e, 0x76, 0x1a, 0x73, 0x63, 0x11, 0xcb, 0xc8, 0x23, 0xb3, 0xed,
+ 0xb8, 0xe4, 0x94, 0x9a, 0x88, 0x25, 0x0b, 0x58, 0x4a, 0x6e, 0x8e, 0x9c, 0xbe, 0x6d, 0xb5, 0x07,
+ 0x8c, 0x9c, 0x56, 0xa5, 0x18, 0xb2, 0x2d, 0x62, 0xc9, 0x9b, 0x50, 0xdc, 0x68, 0x3d, 0xb4, 0xed,
+ 0x41, 0xcb, 0xf5, 0xa8, 0x04, 0xaa, 0x5c, 0xc9, 0x1a, 0x73, 0x5d, 0xda, 0xea, 0x4e, 0x89, 0x54,
+ 0x40, 0xd9, 0x68, 0x6d, 0x59, 0x4e, 0x55, 0xf3, 0x81, 0x79, 0x55, 0xae, 0xa4, 0x8c, 0xf9, 0x2e,
+ 0x36, 0x4f, 0x21, 0x6b, 0xba, 0x8f, 0x2c, 0xa8, 0x72, 0x25, 0xc1, 0x90, 0x35, 0xdd, 0x43, 0xde,
+ 0x02, 0xb2, 0xd1, 0xda, 0xe8, 0x1f, 0x9b, 0x1d, 0xd1, 0xea, 0x9c, 0x2a, 0x57, 0x32, 0x86, 0xd2,
+ 0xe5, 0x1d, 0x33, 0xd0, 0xa2, 0xe5, 0x79, 0x55, 0xae, 0xa4, 0x5d, 0xb4, 0x60, 0xfb, 0x06, 0x2c,
+ 0x6c, 0xb4, 0xde, 0xed, 0x07, 0x1d, 0x2e, 0xaa, 0x72, 0x65, 0xce, 0x28, 0x76, 0x59, 0xfb, 0x34,
+ 0x56, 0x34, 0xac, 0xa8, 0x72, 0x25, 0xc9, 0xb1, 0x82, 0x5d, 0x9c, 0xdd, 0xc6, 0xc0, 0x6e, 0x3b,
+ 0x3e, 0x74, 0x41, 0x95, 0x2b, 0xb2, 0x31, 0xdf, 0xc5, 0xe6, 0xa0, 0xd5, 0xc7, 0xf6, 0xd1, 0xc1,
+ 0xc0, 0xf4, 0xa1, 0x44, 0x95, 0x2b, 0x92, 0x51, 0xec, 0xb2, 0xf6, 0x20, 0x76, 0xcf, 0x19, 0xf7,
+ 0xad, 0x9e, 0x8f, 0x3d, 0x8f, 0xfa, 0x2d, 0x76, 0x59, 0x7b, 0xd0, 0x83, 0x87, 0x27, 0x8e, 0x39,
+ 0xf1, 0xa1, 0xa6, 0x2a, 0x57, 0x0a, 0xc6, 0x7c, 0x17, 0x9b, 0x43, 0x56, 0x43, 0x6b, 0xd0, 0x55,
+ 0xe5, 0xca, 0x02, 0xb5, 0x3a, 0x63, 0x0d, 0xf6, 0x42, 0x6b, 0xd0, 0x53, 0xe5, 0x0a, 0xe1, 0x58,
+ 0x61, 0x0d, 0x44, 0xcd, 0x30, 0x21, 0x96, 0x16, 0xd5, 0x84, 0xa0, 0x19, 0xd6, 0x18, 0xd4, 0x0c,
+ 0x07, 0xbe, 0xa6, 0x26, 0x44, 0xcd, 0x84, 0x90, 0x38, 0x38, 0x47, 0x5e, 0x50, 0x13, 0xa2, 0x66,
+ 0x38, 0x32, 0xa4, 0x19, 0x8e, 0x7d, 0x5d, 0x4d, 0x04, 0x35, 0x33, 0x85, 0x16, 0x2d, 0x97, 0xd4,
+ 0x44, 0x50, 0x33, 0x1c, 0x1d, 0xd4, 0x0c, 0x07, 0x5f, 0x54, 0x13, 0x01, 0xcd, 0x84, 0xb1, 0xa2,
+ 0xe1, 0x25, 0x35, 0x11, 0xd0, 0x8c, 0x38, 0x3b, 0x57, 0x33, 0x1c, 0xba, 0xac, 0x26, 0x44, 0xcd,
+ 0x88, 0x56, 0x3d, 0xcd, 0x70, 0xe8, 0x25, 0x35, 0x11, 0xd0, 0x8c, 0x88, 0xf5, 0x34, 0xc3, 0xb1,
+ 0x97, 0xd5, 0x44, 0x40, 0x33, 0x1c, 0x7b, 0x5d, 0xd4, 0x0c, 0x87, 0x7e, 0x2c, 0xa9, 0x09, 0x51,
+ 0x34, 0x1c, 0x7a, 0x33, 0x20, 0x1a, 0x8e, 0xfd, 0x84, 0x62, 0x45, 0xd5, 0x84, 0xc1, 0xe2, 0x2a,
+ 0x7c, 0x4a, 0xc1, 0xa2, 0x6c, 0x38, 0xd8, 0x97, 0x8d, 0x1b, 0x82, 0x4a, 0x57, 0x54, 0xc9, 0x93,
+ 0x8d, 0x1b, 0xc3, 0x44, 0xd9, 0x78, 0xc0, 0xab, 0x18, 0x6a, 0xb9, 0x6c, 0xa6, 0x90, 0x35, 0xdd,
+ 0x47, 0xaa, 0xaa, 0xe4, 0xcb, 0xc6, 0x43, 0x06, 0x64, 0xe3, 0x61, 0xaf, 0xa9, 0x92, 0x28, 0x9b,
+ 0x19, 0x68, 0xd1, 0x72, 0x59, 0x95, 0x44, 0xd9, 0x78, 0x68, 0x51, 0x36, 0x1e, 0xf8, 0x0b, 0xaa,
+ 0x24, 0xc8, 0x66, 0x1a, 0x2b, 0x1a, 0xfe, 0xa2, 0x2a, 0x09, 0xb2, 0x09, 0xce, 0x8e, 0xc9, 0xc6,
+ 0x83, 0xbe, 0xa1, 0x4a, 0xbe, 0x6c, 0x82, 0x56, 0xb9, 0x6c, 0x3c, 0xe8, 0x9b, 0xaa, 0x24, 0xc8,
+ 0x26, 0x88, 0xe5, 0xb2, 0xf1, 0xb0, 0x6f, 0x61, 0x7e, 0x73, 0x65, 0xe3, 0x61, 0x05, 0xd9, 0x78,
+ 0xd0, 0xdf, 0xa1, 0xb9, 0xd0, 0x93, 0x8d, 0x07, 0x15, 0x65, 0xe3, 0x61, 0x7f, 0x97, 0x62, 0x7d,
+ 0xd9, 0x4c, 0x83, 0xc5, 0x55, 0xf8, 0x3d, 0x0a, 0xf6, 0x65, 0xe3, 0x81, 0x57, 0xd0, 0x09, 0x2a,
+ 0x9b, 0x8e, 0xd9, 0x6d, 0x1f, 0x0d, 0xa8, 0xc4, 0x2a, 0x54, 0x37, 0xf5, 0xa4, 0x33, 0x3e, 0x32,
+ 0xa9, 0x27, 0xb6, 0x3d, 0x78, 0xec, 0xf6, 0x91, 0x15, 0x6a, 0x9c, 0xc9, 0xc7, 0x27, 0x5c, 0xa7,
+ 0xfa, 0xa9, 0xcb, 0x55, 0xcd, 0x28, 0x32, 0x0d, 0x4d, 0xe3, 0x6b, 0xba, 0x80, 0xbf, 0x41, 0x55,
+ 0x54, 0x97, 0x6b, 0x3a, 0xc3, 0xd7, 0x74, 0x1f, 0x5f, 0x85, 0xf3, 0xbe, 0x94, 0x7c, 0xc6, 0x4d,
+ 0xaa, 0xa5, 0x7a, 0xa2, 0xaa, 0xad, 0x1a, 0x0b, 0xae, 0xa0, 0x66, 0x91, 0x02, 0xc3, 0xdc, 0xa2,
+ 0x92, 0xaa, 0x27, 0x6a, 0xba, 0x47, 0x12, 0x47, 0xd2, 0xa8, 0x0c, 0xb9, 0xb0, 0x7c, 0xce, 0x6d,
+ 0xaa, 0xac, 0x7a, 0xb2, 0xaa, 0xad, 0xae, 0x1a, 0x0a, 0xd7, 0xd7, 0x0c, 0x4e, 0x60, 0x9c, 0x15,
+ 0xaa, 0xb0, 0x7a, 0xb2, 0xa6, 0x7b, 0x9c, 0xe0, 0x38, 0x0b, 0xae, 0xd0, 0x7c, 0xca, 0x97, 0xa8,
+ 0xd2, 0xea, 0xe9, 0xea, 0x9a, 0xbe, 0xb6, 0x7e, 0xcf, 0x28, 0x32, 0xc5, 0xf9, 0x1c, 0x9d, 0x8e,
+ 0xc3, 0x25, 0xe7, 0x93, 0x56, 0xa9, 0xe6, 0xea, 0x69, 0xed, 0xce, 0xda, 0x5d, 0xed, 0xae, 0xa1,
+ 0x70, 0xed, 0xf9, 0xac, 0x77, 0x28, 0x8b, 0x8b, 0xcf, 0x67, 0xad, 0x51, 0xf5, 0xd5, 0x95, 0x67,
+ 0xe6, 0x60, 0x60, 0xdf, 0x52, 0xcb, 0x2f, 0xed, 0xf1, 0xa0, 0x73, 0xad, 0x0c, 0x86, 0xc2, 0xf5,
+ 0x28, 0x8e, 0xba, 0xe0, 0x0a, 0xd2, 0xa7, 0xff, 0x1a, 0x3d, 0x87, 0x15, 0xea, 0x99, 0x87, 0xfd,
+ 0x9e, 0x65, 0x4f, 0x4c, 0xa3, 0xc8, 0xa4, 0x19, 0x5a, 0x93, 0xbd, 0xf0, 0x3a, 0xfe, 0x3a, 0xa5,
+ 0x2d, 0xd4, 0x13, 0xb7, 0xab, 0x1a, 0x1d, 0x69, 0xd6, 0x3a, 0xee, 0x85, 0xd7, 0xf1, 0x37, 0x28,
+ 0x87, 0xd4, 0x13, 0xb7, 0x6b, 0x3a, 0xe7, 0x88, 0xeb, 0x78, 0x07, 0x2e, 0x84, 0xf2, 0x62, 0x6b,
+ 0xd4, 0x3e, 0x7c, 0x6e, 0x76, 0x4a, 0x1a, 0x4d, 0x8f, 0x0f, 0x65, 0x45, 0x32, 0xce, 0x07, 0x52,
+ 0xe4, 0x2e, 0x76, 0x93, 0x7b, 0xf0, 0x7a, 0x38, 0x51, 0xba, 0xcc, 0x2a, 0xcd, 0x97, 0xc8, 0x5c,
+ 0x0c, 0xe6, 0xcc, 0x10, 0x55, 0x08, 0xc0, 0x2e, 0x55, 0xa7, 0x09, 0xd4, 0xa7, 0xfa, 0x91, 0x98,
+ 0x53, 0x7f, 0x06, 0x2e, 0x4e, 0xa7, 0x52, 0x97, 0xbc, 0x4e, 0x33, 0x2a, 0x92, 0x2f, 0x84, 0xb3,
+ 0xea, 0x14, 0x7d, 0xc6, 0xd8, 0x35, 0x9a, 0x62, 0x45, 0xfa, 0xd4, 0xe8, 0xf7, 0xa1, 0x34, 0x95,
+ 0x6c, 0x5d, 0xf6, 0x1d, 0x9a, 0x73, 0x91, 0xfd, 0x5a, 0x28, 0xef, 0x86, 0xc9, 0x33, 0x86, 0xbe,
+ 0x4b, 0x93, 0xb0, 0x40, 0x9e, 0x1a, 0x19, 0x97, 0x2c, 0x98, 0x8e, 0x5d, 0xee, 0x3d, 0x9a, 0x95,
+ 0xf9, 0x92, 0x05, 0x32, 0xb3, 0x38, 0x6e, 0x28, 0x3f, 0xbb, 0xdc, 0x3a, 0x4d, 0xd3, 0x7c, 0xdc,
+ 0x60, 0xaa, 0xe6, 0xe4, 0xb7, 0x29, 0x79, 0x6f, 0xf6, 0x8c, 0x7f, 0x9c, 0xa0, 0x09, 0x96, 0xb3,
+ 0xf7, 0x66, 0x4d, 0xd9, 0x63, 0xcf, 0x98, 0xf2, 0x4f, 0x28, 0x9b, 0x08, 0xec, 0xa9, 0x39, 0x3f,
+ 0x06, 0xaf, 0xe2, 0xe8, 0x8d, 0xed, 0xa3, 0x51, 0x69, 0x43, 0x95, 0x2b, 0xa0, 0x5d, 0x99, 0xaa,
+ 0x7e, 0xdc, 0x43, 0xde, 0x26, 0x45, 0x19, 0x41, 0x12, 0xb3, 0xc2, 0xec, 0x32, 0x2b, 0xbb, 0x6a,
+ 0x22, 0xc2, 0x0a, 0x43, 0x79, 0x56, 0x04, 0x12, 0xb5, 0xe2, 0x06, 0x7d, 0x66, 0xe5, 0x03, 0x55,
+ 0x9a, 0x69, 0xc5, 0x4d, 0x01, 0xdc, 0x4a, 0x80, 0xb4, 0xb4, 0xee, 0xd7, 0x5b, 0xd8, 0x4f, 0xbe,
+ 0x18, 0x2e, 0xc0, 0x36, 0xf1, 0xfc, 0x1c, 0xac, 0xb4, 0x18, 0x4d, 0x70, 0x6e, 0x9a, 0xf6, 0xb3,
+ 0x11, 0xb4, 0x80, 0x37, 0xd3, 0xb4, 0x9f, 0x9b, 0x41, 0x2b, 0xff, 0xa6, 0x04, 0x49, 0x5a, 0x4f,
+ 0x92, 0x2c, 0x24, 0xdf, 0x6b, 0x6e, 0x3d, 0x56, 0xce, 0xd1, 0x5f, 0x0f, 0x9b, 0xcd, 0xa7, 0x8a,
+ 0x44, 0x72, 0x90, 0x7a, 0xf8, 0x95, 0xfd, 0xc6, 0x9e, 0x22, 0x93, 0x22, 0xe4, 0x37, 0xb6, 0x76,
+ 0x36, 0x1b, 0xc6, 0xae, 0xb1, 0xb5, 0xb3, 0xaf, 0x24, 0x68, 0xdf, 0xc6, 0xd3, 0xe6, 0x83, 0x7d,
+ 0x25, 0x49, 0x32, 0x90, 0xa0, 0x6d, 0x29, 0x02, 0x90, 0xde, 0xdb, 0x37, 0xb6, 0x76, 0x36, 0x95,
+ 0x34, 0xb5, 0xb2, 0xbf, 0xb5, 0xdd, 0x50, 0x32, 0x14, 0xb9, 0xff, 0xee, 0xee, 0xd3, 0x86, 0x92,
+ 0xa5, 0x3f, 0x1f, 0x18, 0xc6, 0x83, 0xaf, 0x28, 0x39, 0x4a, 0xda, 0x7e, 0xb0, 0xab, 0x00, 0x76,
+ 0x3f, 0x78, 0xf8, 0xb4, 0xa1, 0xe4, 0x49, 0x01, 0xb2, 0x1b, 0xef, 0xee, 0x3c, 0xda, 0xdf, 0x6a,
+ 0xee, 0x28, 0x85, 0xf2, 0x6f, 0xc9, 0x00, 0x9b, 0xf6, 0xde, 0xf3, 0xfe, 0x08, 0xab, 0xe2, 0xcb,
+ 0x00, 0x93, 0xe7, 0xfd, 0x51, 0x0b, 0xa5, 0xc7, 0x2b, 0xbb, 0x1c, 0x6d, 0xc1, 0xa0, 0x43, 0xae,
+ 0x41, 0x01, 0xbb, 0xbb, 0x2c, 0x14, 0x60, 0x41, 0x97, 0x31, 0xf2, 0xb4, 0x8d, 0x47, 0x87, 0x20,
+ 0xa4, 0xa6, 0x63, 0x1d, 0x97, 0x16, 0x20, 0x35, 0x9d, 0x5c, 0x05, 0x7c, 0x6c, 0x4d, 0x30, 0xac,
+ 0x63, 0xed, 0x96, 0x33, 0x70, 0x5c, 0x16, 0xe8, 0xc9, 0xdb, 0x80, 0x63, 0x32, 0x59, 0x14, 0xa7,
+ 0x25, 0xea, 0xba, 0xbb, 0x42, 0x7f, 0x30, 0x59, 0xf8, 0x84, 0xa5, 0x26, 0xe4, 0xbc, 0x76, 0x3a,
+ 0x16, 0xb6, 0xf2, 0x19, 0x29, 0x38, 0x23, 0xc0, 0x26, 0x6f, 0x4a, 0x0c, 0xc0, 0xbd, 0x59, 0x40,
+ 0x6f, 0x18, 0x89, 0xb9, 0x53, 0xbe, 0x0c, 0x73, 0x3b, 0xb6, 0xc5, 0xb6, 0x10, 0xae, 0x52, 0x01,
+ 0xa4, 0x76, 0x49, 0xc2, 0x12, 0x46, 0x6a, 0x97, 0xaf, 0x00, 0x08, 0x7d, 0x0a, 0x48, 0x07, 0xac,
+ 0x0f, 0x37, 0xa2, 0x74, 0x50, 0xbe, 0x09, 0xe9, 0xed, 0xf6, 0xf1, 0x7e, 0xbb, 0x47, 0xae, 0x01,
+ 0x0c, 0xda, 0x13, 0xa7, 0xd5, 0x45, 0xa9, 0x7c, 0xfe, 0xf9, 0xe7, 0x9f, 0x4b, 0x78, 0xe2, 0xca,
+ 0xd1, 0x56, 0x26, 0x95, 0x17, 0x00, 0xcd, 0x41, 0x67, 0xdb, 0x9c, 0x4c, 0xda, 0x3d, 0x93, 0x54,
+ 0x21, 0x6d, 0x99, 0x13, 0x9a, 0x72, 0x24, 0x2c, 0xe6, 0x97, 0xfd, 0x55, 0xf0, 0x51, 0x2b, 0x3b,
+ 0x08, 0x31, 0x38, 0x94, 0x28, 0x90, 0xb0, 0x8e, 0x86, 0x78, 0x59, 0x91, 0x32, 0xe8, 0xcf, 0xa5,
+ 0x4b, 0x90, 0x66, 0x18, 0x42, 0x20, 0x69, 0xb5, 0x87, 0x66, 0x89, 0x8d, 0x8b, 0xbf, 0xcb, 0xbf,
+ 0x2a, 0x01, 0xec, 0x98, 0x2f, 0xcf, 0x30, 0xa6, 0x8f, 0x8a, 0x19, 0x33, 0xc1, 0xc6, 0xbc, 0x1f,
+ 0x37, 0x26, 0xd5, 0x59, 0xd7, 0xb6, 0x3b, 0x2d, 0xf6, 0x8a, 0xd9, 0xbd, 0x4a, 0x8e, 0xb6, 0xe0,
+ 0x5b, 0x2b, 0x7f, 0x00, 0x85, 0x2d, 0xcb, 0x32, 0xc7, 0xae, 0x4f, 0x04, 0x92, 0xcf, 0xec, 0x89,
+ 0xc3, 0x2f, 0x78, 0xf0, 0x37, 0x29, 0x41, 0x72, 0x64, 0x8f, 0x1d, 0x36, 0xcf, 0x7a, 0x52, 0x5f,
+ 0x5d, 0x5d, 0x35, 0xb0, 0x85, 0x5c, 0x82, 0xdc, 0xa1, 0x6d, 0x59, 0xe6, 0x21, 0x9d, 0x44, 0x02,
+ 0x6b, 0x0b, 0xbf, 0xa1, 0xfc, 0xcb, 0x12, 0x14, 0x9a, 0xce, 0x33, 0xdf, 0xb8, 0x02, 0x89, 0xe7,
+ 0xe6, 0x09, 0xba, 0x97, 0x30, 0xe8, 0x4f, 0xb2, 0x08, 0xa9, 0x9f, 0x6f, 0x0f, 0x8e, 0xd8, 0x85,
+ 0x4f, 0xc1, 0x60, 0x0f, 0xe4, 0x02, 0xa4, 0x5f, 0x9a, 0xfd, 0xde, 0x33, 0x07, 0x6d, 0xca, 0x06,
+ 0x7f, 0x22, 0xb7, 0x20, 0xd5, 0xa7, 0xce, 0x96, 0x92, 0xb8, 0x5e, 0x17, 0xfc, 0xf5, 0x12, 0xe7,
+ 0x60, 0x30, 0xd0, 0x8d, 0x6c, 0xb6, 0xa3, 0x7c, 0xf4, 0xd1, 0x47, 0x1f, 0xc9, 0xe5, 0x2e, 0x2c,
+ 0xba, 0xb1, 0x23, 0x30, 0xd9, 0x1d, 0x28, 0x0d, 0x4c, 0xbb, 0xd5, 0xed, 0x5b, 0xed, 0xc1, 0xe0,
+ 0xa4, 0xf5, 0xd2, 0xb6, 0x5a, 0x6d, 0xab, 0x65, 0x4f, 0x0e, 0xdb, 0x63, 0x5c, 0x80, 0xe8, 0x21,
+ 0x16, 0x07, 0xa6, 0xbd, 0xc1, 0x68, 0xef, 0xdb, 0xd6, 0x03, 0xab, 0x49, 0x39, 0xe5, 0x3f, 0x48,
+ 0x42, 0x6e, 0xfb, 0xc4, 0xb5, 0xbe, 0x08, 0xa9, 0x43, 0xfb, 0xc8, 0x62, 0x6b, 0x99, 0x32, 0xd8,
+ 0x83, 0xf7, 0x8e, 0x64, 0xe1, 0x1d, 0x2d, 0x42, 0xea, 0xc5, 0x91, 0xed, 0x98, 0x38, 0xdd, 0x9c,
+ 0xc1, 0x1e, 0xe8, 0x6a, 0x8d, 0x4c, 0xa7, 0x94, 0xc4, 0x0a, 0x93, 0xfe, 0xf4, 0xe7, 0x9f, 0x3a,
+ 0xc3, 0xfc, 0xc9, 0x0a, 0xa4, 0x6d, 0xba, 0xfa, 0x93, 0x52, 0x1a, 0x2f, 0xb7, 0x04, 0xb8, 0xf8,
+ 0x56, 0x0c, 0x8e, 0x22, 0x5b, 0xb0, 0xf0, 0xd2, 0x6c, 0x0d, 0x8f, 0x26, 0x4e, 0xab, 0x67, 0xb7,
+ 0x3a, 0xa6, 0x39, 0x32, 0xc7, 0xa5, 0x39, 0x1c, 0x49, 0x88, 0x09, 0xb3, 0x16, 0xd2, 0x98, 0x7f,
+ 0x69, 0x6e, 0x1f, 0x4d, 0x9c, 0x4d, 0xfb, 0x31, 0xb2, 0x48, 0x15, 0x72, 0x63, 0x93, 0x46, 0x02,
+ 0xea, 0x6c, 0x21, 0x3c, 0x7a, 0x80, 0x9a, 0x1d, 0x9b, 0x23, 0x6c, 0x20, 0xeb, 0x90, 0x3d, 0xe8,
+ 0x3f, 0x37, 0x27, 0xcf, 0xcc, 0x4e, 0x29, 0xa3, 0x4a, 0x95, 0x79, 0xed, 0xa2, 0xcf, 0xf1, 0x96,
+ 0x75, 0xe5, 0x91, 0x3d, 0xb0, 0xc7, 0x86, 0x07, 0x25, 0xf7, 0x21, 0x37, 0xb1, 0x87, 0x26, 0xd3,
+ 0x77, 0x16, 0x33, 0xdb, 0xe5, 0x59, 0xbc, 0x3d, 0x7b, 0x68, 0xba, 0x11, 0xcc, 0xc5, 0x93, 0x65,
+ 0xe6, 0xe8, 0x01, 0x3d, 0xbf, 0x96, 0x00, 0xeb, 0x73, 0xea, 0x10, 0x9e, 0x67, 0xc9, 0x12, 0x75,
+ 0xa8, 0xd7, 0xa5, 0xc7, 0x92, 0x52, 0x1e, 0x8b, 0x3b, 0xef, 0x79, 0xe9, 0x16, 0xe4, 0x3c, 0x83,
+ 0x7e, 0xe8, 0x63, 0xe1, 0x26, 0x87, 0xf1, 0x80, 0x85, 0x3e, 0x16, 0x6b, 0xde, 0x80, 0x14, 0xba,
+ 0x4d, 0xd3, 0x84, 0xd1, 0xa0, 0x59, 0x29, 0x07, 0xa9, 0x4d, 0xa3, 0xd1, 0xd8, 0x51, 0x24, 0x4c,
+ 0x50, 0x4f, 0xdf, 0x6d, 0x28, 0xb2, 0xa0, 0xd8, 0xdf, 0x96, 0x20, 0xd1, 0x38, 0x46, 0xb5, 0xd0,
+ 0x69, 0xb8, 0x3b, 0x9a, 0xfe, 0xd6, 0x6a, 0x90, 0x1c, 0xda, 0x63, 0x93, 0x9c, 0x9f, 0x31, 0xcb,
+ 0x52, 0x0f, 0xdf, 0x97, 0x70, 0x95, 0xdb, 0x38, 0x76, 0x0c, 0xc4, 0x6b, 0x6f, 0x41, 0xd2, 0x31,
+ 0x8f, 0x9d, 0xd9, 0xbc, 0x67, 0x6c, 0x00, 0x0a, 0xd0, 0x6e, 0x42, 0xda, 0x3a, 0x1a, 0x1e, 0x98,
+ 0xe3, 0xd9, 0xd0, 0x3e, 0x4e, 0x8f, 0x43, 0xca, 0xef, 0x81, 0xf2, 0xc8, 0x1e, 0x8e, 0x06, 0xe6,
+ 0x71, 0xe3, 0xd8, 0x31, 0xad, 0x49, 0xdf, 0xb6, 0xa8, 0x9e, 0xbb, 0xfd, 0x31, 0x46, 0x11, 0xbc,
+ 0xb0, 0xc5, 0x07, 0xba, 0xab, 0x27, 0xe6, 0xa1, 0x6d, 0x75, 0x78, 0xc0, 0xe4, 0x4f, 0x14, 0xed,
+ 0x3c, 0xeb, 0x8f, 0x69, 0x00, 0xa1, 0x71, 0x9e, 0x3d, 0x94, 0x37, 0xa1, 0xc8, 0x0f, 0xfa, 0x13,
+ 0x3e, 0x70, 0xf9, 0x06, 0x14, 0xdc, 0x26, 0xbc, 0xbd, 0xce, 0x42, 0xf2, 0x83, 0x86, 0xd1, 0x54,
+ 0xce, 0xd1, 0x65, 0x6d, 0xee, 0x34, 0x14, 0x89, 0xfe, 0xd8, 0x7f, 0xbf, 0x19, 0x58, 0xca, 0x4b,
+ 0x50, 0xf0, 0x7c, 0xdf, 0x33, 0x1d, 0xec, 0xa1, 0x09, 0x21, 0x53, 0x97, 0xb3, 0x52, 0x39, 0x03,
+ 0xa9, 0xc6, 0x70, 0xe4, 0x9c, 0x94, 0x7f, 0x11, 0xf2, 0x1c, 0xf4, 0xb4, 0x3f, 0x71, 0xc8, 0x1d,
+ 0xc8, 0x0c, 0xf9, 0x7c, 0x25, 0x3c, 0x73, 0x89, 0x9a, 0xf2, 0x71, 0xee, 0x6f, 0xc3, 0x45, 0x2f,
+ 0x55, 0x21, 0x23, 0xc4, 0x52, 0xbe, 0xd5, 0x65, 0x71, 0xab, 0xb3, 0xa0, 0x90, 0x10, 0x82, 0x42,
+ 0x79, 0x1b, 0x32, 0x2c, 0x03, 0x4e, 0x30, 0xab, 0xb3, 0x7a, 0x8d, 0x89, 0x89, 0xbd, 0xf9, 0x3c,
+ 0x6b, 0x63, 0x57, 0xc8, 0x57, 0x21, 0x8f, 0x82, 0xe5, 0x08, 0x16, 0x3a, 0x01, 0x9b, 0x98, 0xdc,
+ 0x7e, 0x3f, 0x05, 0x59, 0x77, 0xa5, 0xc8, 0x32, 0xa4, 0x59, 0x91, 0x84, 0xa6, 0xdc, 0x22, 0x3e,
+ 0x85, 0x65, 0x11, 0x59, 0x86, 0x0c, 0x2f, 0x84, 0x78, 0x74, 0xa7, 0x15, 0x7b, 0x9a, 0x15, 0x3e,
+ 0x5e, 0x67, 0x4d, 0xc7, 0xc0, 0xc4, 0xca, 0xf3, 0x34, 0x2b, 0x6d, 0x88, 0x0a, 0x39, 0xaf, 0x98,
+ 0xc1, 0x78, 0xcc, 0x6b, 0xf1, 0xac, 0x5b, 0xbd, 0x08, 0x88, 0x9a, 0x8e, 0x11, 0x8b, 0x17, 0xde,
+ 0xd9, 0xae, 0x7f, 0x3c, 0xc9, 0xba, 0x25, 0x09, 0xde, 0xa1, 0xbb, 0x55, 0x76, 0x86, 0x17, 0x21,
+ 0x3e, 0xa0, 0xa6, 0x63, 0x48, 0x70, 0x4b, 0xea, 0x0c, 0x2f, 0x34, 0xc8, 0x55, 0xea, 0x22, 0x16,
+ 0x0e, 0xb8, 0xf5, 0xfd, 0xfa, 0x39, 0xcd, 0xca, 0x09, 0x72, 0x8d, 0x5a, 0x60, 0xd5, 0x01, 0xee,
+ 0x4b, 0xbf, 0x58, 0xce, 0xf0, 0xa2, 0x81, 0xdc, 0xa4, 0x10, 0xb6, 0xfc, 0x25, 0x88, 0xa8, 0x8c,
+ 0x33, 0xbc, 0x32, 0x26, 0x2a, 0x1d, 0x10, 0xc3, 0x03, 0x86, 0x04, 0xa1, 0x0a, 0x4e, 0xb3, 0x2a,
+ 0x98, 0x5c, 0x41, 0x73, 0x6c, 0x52, 0x05, 0xbf, 0xe2, 0xcd, 0xf0, 0x2a, 0xc3, 0xef, 0xc7, 0x23,
+ 0x9b, 0x57, 0xdd, 0x66, 0x78, 0x1d, 0x41, 0x6a, 0xf4, 0x7d, 0x51, 0x7d, 0x97, 0xe6, 0x31, 0x08,
+ 0x96, 0x7c, 0xe1, 0xb9, 0xef, 0x94, 0xc5, 0xc0, 0x3a, 0x8b, 0x20, 0x46, 0xaa, 0x8b, 0xbb, 0x61,
+ 0x89, 0xf2, 0x76, 0xfb, 0x56, 0xb7, 0x54, 0xc4, 0x95, 0x48, 0xf4, 0xad, 0xae, 0x91, 0xea, 0xd2,
+ 0x16, 0xa6, 0x81, 0x1d, 0xda, 0xa7, 0x60, 0x5f, 0xf2, 0x36, 0xeb, 0xa4, 0x4d, 0xa4, 0x04, 0xa9,
+ 0x8d, 0xd6, 0x4e, 0xdb, 0x2a, 0x2d, 0x30, 0x9e, 0xd5, 0xb6, 0x8c, 0x64, 0x77, 0xa7, 0x6d, 0x91,
+ 0xb7, 0x20, 0x31, 0x39, 0x3a, 0x28, 0x91, 0xf0, 0xe7, 0x8d, 0xbd, 0xa3, 0x03, 0xd7, 0x15, 0x83,
+ 0x22, 0xc8, 0x32, 0x64, 0x27, 0xce, 0xb8, 0xf5, 0x0b, 0xe6, 0xd8, 0x2e, 0x9d, 0xc7, 0x25, 0x3c,
+ 0x67, 0x64, 0x26, 0xce, 0xf8, 0x03, 0x73, 0x6c, 0x9f, 0x31, 0xf8, 0x95, 0xaf, 0x40, 0x5e, 0xb0,
+ 0x4b, 0x8a, 0x20, 0x59, 0xec, 0xa4, 0x50, 0x97, 0xee, 0x18, 0x92, 0x55, 0xde, 0x87, 0x82, 0x5b,
+ 0x48, 0xe0, 0x7c, 0x35, 0xba, 0x93, 0x06, 0xf6, 0x18, 0xf7, 0xe7, 0xbc, 0x76, 0x49, 0x4c, 0x51,
+ 0x3e, 0x8c, 0xa7, 0x0b, 0x06, 0x2d, 0x2b, 0x21, 0x57, 0xa4, 0xf2, 0x0f, 0x25, 0x28, 0x6c, 0xdb,
+ 0x63, 0xff, 0x96, 0x77, 0x11, 0x52, 0x07, 0xb6, 0x3d, 0x98, 0xa0, 0xd9, 0xac, 0xc1, 0x1e, 0xc8,
+ 0x1b, 0x50, 0xc0, 0x1f, 0x6e, 0x01, 0x28, 0x7b, 0xf7, 0x0b, 0x79, 0x6c, 0xe7, 0x55, 0x1f, 0x81,
+ 0x64, 0xdf, 0x72, 0x26, 0x3c, 0x92, 0xe1, 0x6f, 0xf2, 0x05, 0xc8, 0xd3, 0xbf, 0x2e, 0x33, 0xe9,
+ 0x1d, 0x58, 0x81, 0x36, 0x73, 0xe2, 0x5b, 0x30, 0x87, 0x6f, 0xdf, 0x83, 0x65, 0xbc, 0xbb, 0x84,
+ 0x02, 0xeb, 0xe0, 0xc0, 0x12, 0x64, 0x58, 0x28, 0x98, 0xe0, 0x27, 0xab, 0x9c, 0xe1, 0x3e, 0xd2,
+ 0xf0, 0x8a, 0x95, 0x00, 0x4b, 0xf7, 0x19, 0x83, 0x3f, 0x95, 0x1f, 0x40, 0x16, 0xb3, 0x54, 0x73,
+ 0xd0, 0x21, 0x65, 0x90, 0x7a, 0x25, 0x13, 0x73, 0xe4, 0xa2, 0x70, 0xcc, 0xe7, 0xdd, 0x2b, 0x9b,
+ 0x86, 0xd4, 0x5b, 0x5a, 0x00, 0x69, 0x93, 0x9e, 0xbb, 0x8f, 0x79, 0x98, 0x96, 0x8e, 0xcb, 0x4d,
+ 0x6e, 0x62, 0xc7, 0x7c, 0x19, 0x67, 0x62, 0xc7, 0x7c, 0xc9, 0x4c, 0x5c, 0x9d, 0x32, 0x41, 0x9f,
+ 0x4e, 0xf8, 0xf7, 0x3b, 0xe9, 0x84, 0x9e, 0xf3, 0x71, 0x7b, 0xf6, 0xad, 0xde, 0xae, 0xdd, 0xb7,
+ 0xf0, 0x9c, 0xdf, 0xc5, 0x73, 0x92, 0x64, 0x48, 0xdd, 0xf2, 0x67, 0x49, 0x98, 0xe7, 0x41, 0xf4,
+ 0xfd, 0xbe, 0xf3, 0x6c, 0xbb, 0x3d, 0x22, 0x4f, 0xa1, 0x40, 0xe3, 0x67, 0x6b, 0xd8, 0x1e, 0x8d,
+ 0xe8, 0x46, 0x95, 0xf0, 0x50, 0x71, 0x7d, 0x2a, 0x28, 0x73, 0xfc, 0xca, 0x4e, 0x7b, 0x68, 0x6e,
+ 0x33, 0x6c, 0xc3, 0x72, 0xc6, 0x27, 0x46, 0xde, 0xf2, 0x5b, 0xc8, 0x16, 0xe4, 0x87, 0x93, 0x9e,
+ 0x67, 0x4c, 0x46, 0x63, 0x95, 0x48, 0x63, 0xdb, 0x93, 0x5e, 0xc0, 0x16, 0x0c, 0xbd, 0x06, 0xea,
+ 0x18, 0x8d, 0xbc, 0x9e, 0xad, 0xc4, 0x29, 0x8e, 0xd1, 0x20, 0x11, 0x74, 0xec, 0xc0, 0x6f, 0x21,
+ 0x8f, 0x01, 0xe8, 0x46, 0x72, 0x6c, 0x5a, 0x24, 0xa1, 0x56, 0xf2, 0xda, 0x9b, 0x91, 0xb6, 0xf6,
+ 0x9c, 0xf1, 0xbe, 0xbd, 0xe7, 0x8c, 0x99, 0x21, 0xba, 0x05, 0xf1, 0x71, 0xe9, 0x1d, 0x50, 0xc2,
+ 0xf3, 0x17, 0xcf, 0xde, 0xa9, 0x19, 0x67, 0xef, 0x1c, 0x3f, 0x7b, 0xd7, 0xe5, 0xbb, 0xd2, 0xd2,
+ 0x7b, 0x50, 0x0c, 0x4d, 0x59, 0xa4, 0x13, 0x46, 0xbf, 0x2d, 0xd2, 0xf3, 0xda, 0xeb, 0xc2, 0xd7,
+ 0x63, 0xf1, 0xd5, 0x8a, 0x76, 0xdf, 0x01, 0x25, 0x3c, 0x7d, 0xd1, 0x70, 0x36, 0xa6, 0x26, 0x40,
+ 0xfe, 0x7d, 0x98, 0x0b, 0x4c, 0x59, 0x24, 0xe7, 0x4e, 0x99, 0x54, 0xf9, 0x97, 0x52, 0x90, 0x6a,
+ 0x5a, 0xa6, 0xdd, 0x25, 0xaf, 0x07, 0x33, 0xe2, 0x93, 0x73, 0x6e, 0x36, 0xbc, 0x18, 0xca, 0x86,
+ 0x4f, 0xce, 0x79, 0xb9, 0xf0, 0x62, 0x28, 0x17, 0xba, 0x5d, 0x35, 0x9d, 0x5c, 0x9e, 0xca, 0x84,
+ 0x4f, 0xce, 0x09, 0x69, 0xf0, 0xf2, 0x54, 0x1a, 0xf4, 0xbb, 0x6b, 0x3a, 0x0d, 0x9d, 0xc1, 0x1c,
+ 0xf8, 0xe4, 0x9c, 0x9f, 0xff, 0x96, 0xc3, 0xf9, 0xcf, 0xeb, 0xac, 0xe9, 0xcc, 0x25, 0x21, 0xf7,
+ 0xa1, 0x4b, 0x2c, 0xeb, 0x2d, 0x87, 0xb3, 0x1e, 0xf2, 0x78, 0xbe, 0x5b, 0x0e, 0xe7, 0x3b, 0xec,
+ 0xe4, 0xf9, 0xed, 0x62, 0x28, 0xbf, 0xa1, 0x51, 0x96, 0xd8, 0x96, 0xc3, 0x89, 0x8d, 0xf1, 0x04,
+ 0x4f, 0xc5, 0xac, 0xe6, 0x75, 0xd6, 0x74, 0xa2, 0x85, 0x52, 0x5a, 0xf4, 0xb9, 0x1e, 0xdf, 0x05,
+ 0x86, 0x77, 0x9d, 0x2e, 0x9b, 0x7b, 0xe4, 0x2c, 0xc6, 0x7c, 0x60, 0xc7, 0xd5, 0x74, 0x8f, 0x5c,
+ 0x1a, 0x64, 0xba, 0xbc, 0xd4, 0x55, 0x30, 0x46, 0x09, 0xb2, 0xc4, 0x97, 0xbf, 0xb2, 0xd1, 0xc2,
+ 0x58, 0x85, 0xf3, 0x62, 0xa7, 0xf7, 0x0a, 0xcc, 0x6d, 0xb4, 0x9e, 0xb6, 0xc7, 0x3d, 0x73, 0xe2,
+ 0xb4, 0xf6, 0xdb, 0x3d, 0xef, 0xba, 0x80, 0xbe, 0xff, 0x7c, 0x97, 0xf7, 0xec, 0xb7, 0x7b, 0xe4,
+ 0x82, 0x2b, 0xae, 0x0e, 0xf6, 0x4a, 0x5c, 0x5e, 0x4b, 0xaf, 0xd3, 0x45, 0x63, 0xc6, 0x30, 0xea,
+ 0x2d, 0xf0, 0xa8, 0xf7, 0x30, 0x03, 0xa9, 0x23, 0xab, 0x6f, 0x5b, 0x0f, 0x73, 0x90, 0x71, 0xec,
+ 0xf1, 0xb0, 0xed, 0xd8, 0xe5, 0x1f, 0x49, 0x00, 0x8f, 0xec, 0xe1, 0xf0, 0xc8, 0xea, 0xbf, 0x38,
+ 0x32, 0xc9, 0x15, 0xc8, 0x0f, 0xdb, 0xcf, 0xcd, 0xd6, 0xd0, 0x6c, 0x1d, 0x8e, 0xdd, 0x7d, 0x90,
+ 0xa3, 0x4d, 0xdb, 0xe6, 0xa3, 0xf1, 0x09, 0x29, 0xb9, 0x87, 0x71, 0xd4, 0x0e, 0x4a, 0x92, 0x1f,
+ 0xce, 0x17, 0xf9, 0xf1, 0x32, 0xcd, 0xdf, 0xa1, 0x7b, 0xc0, 0x64, 0x15, 0x43, 0x86, 0xbf, 0x3d,
+ 0x7c, 0xa2, 0x92, 0x77, 0xcc, 0xe1, 0xa8, 0x75, 0x88, 0x52, 0xa1, 0x72, 0x48, 0xd1, 0xe7, 0x47,
+ 0xe4, 0x36, 0x24, 0x0e, 0xed, 0x01, 0x8a, 0xe4, 0x94, 0xf7, 0x42, 0x71, 0xe4, 0x0d, 0x48, 0x0c,
+ 0x27, 0x4c, 0x36, 0x79, 0x6d, 0x41, 0x38, 0x11, 0xb0, 0x24, 0x44, 0x61, 0xc3, 0x49, 0xcf, 0x9b,
+ 0xf7, 0x8d, 0x22, 0x24, 0x36, 0x9a, 0x4d, 0x9a, 0xe5, 0x37, 0x9a, 0xcd, 0x35, 0x45, 0xaa, 0x7f,
+ 0x09, 0xb2, 0xbd, 0xb1, 0x69, 0xd2, 0xf0, 0x30, 0xbb, 0xba, 0xf8, 0x10, 0xb3, 0x9a, 0x07, 0xaa,
+ 0x6f, 0x43, 0xe6, 0x90, 0xd5, 0x17, 0x24, 0xa2, 0x80, 0x2d, 0xfd, 0x21, 0xbb, 0x3e, 0x59, 0xf2,
+ 0xbb, 0xc3, 0x15, 0x89, 0xe1, 0xda, 0xa8, 0xef, 0x42, 0x6e, 0xdc, 0x3a, 0xcd, 0xe0, 0xc7, 0x2c,
+ 0xbb, 0xc4, 0x19, 0xcc, 0x8e, 0x79, 0x53, 0xbd, 0x01, 0x0b, 0x96, 0xed, 0x7e, 0xb2, 0x68, 0x75,
+ 0xd8, 0x1e, 0xbb, 0x38, 0x7d, 0x68, 0x73, 0x8d, 0x9b, 0xec, 0x33, 0xa1, 0x65, 0xf3, 0x0e, 0xb6,
+ 0x2b, 0xeb, 0x8f, 0x40, 0x11, 0xcc, 0x60, 0x91, 0x19, 0x67, 0xa5, 0xcb, 0xbe, 0x4b, 0x7a, 0x56,
+ 0x70, 0xdf, 0x87, 0x8c, 0xb0, 0x9d, 0x19, 0x63, 0xa4, 0xc7, 0x3e, 0xf2, 0x7a, 0x46, 0x30, 0xd4,
+ 0x4d, 0x1b, 0xa1, 0xb1, 0x26, 0xda, 0xc8, 0x33, 0xf6, 0xfd, 0x57, 0x34, 0x52, 0xd3, 0x43, 0xab,
+ 0x72, 0x74, 0xaa, 0x2b, 0x7d, 0xf6, 0xf9, 0xd6, 0xb3, 0xc2, 0x02, 0xe0, 0x0c, 0x33, 0xf1, 0xce,
+ 0x7c, 0xc8, 0xbe, 0xec, 0x06, 0xcc, 0x4c, 0x79, 0x33, 0x39, 0xd5, 0x9b, 0xe7, 0xec, 0x33, 0xaa,
+ 0x67, 0x66, 0x6f, 0x96, 0x37, 0x93, 0x53, 0xbd, 0x19, 0xb0, 0x0f, 0xac, 0x01, 0x33, 0x35, 0xbd,
+ 0xbe, 0x09, 0x44, 0x7c, 0xd5, 0x3c, 0x4f, 0xc4, 0xd8, 0x19, 0xb2, 0xcf, 0xe6, 0xfe, 0xcb, 0x66,
+ 0x94, 0x59, 0x86, 0xe2, 0x1d, 0xb2, 0xd8, 0x17, 0xf5, 0xa0, 0xa1, 0x9a, 0x5e, 0xdf, 0x82, 0xf3,
+ 0xe2, 0xc4, 0xce, 0xe0, 0x92, 0xad, 0x4a, 0x95, 0xa2, 0xb1, 0xe0, 0x4f, 0x8d, 0x73, 0x66, 0x9a,
+ 0x8a, 0x77, 0x6a, 0xa4, 0x4a, 0x15, 0x65, 0xca, 0x54, 0x4d, 0xaf, 0x3f, 0x80, 0xa2, 0x60, 0xea,
+ 0x00, 0x33, 0x74, 0xb4, 0x99, 0x17, 0xec, 0x5f, 0x1b, 0x3c, 0x33, 0x34, 0xa3, 0x87, 0xdf, 0x18,
+ 0xcf, 0x71, 0xd1, 0x46, 0xc6, 0xec, 0xbb, 0xbc, 0xef, 0x0b, 0x32, 0x42, 0x5b, 0x02, 0x2b, 0xed,
+ 0x38, 0x2b, 0x13, 0xf6, 0xc5, 0xde, 0x77, 0x85, 0x12, 0xea, 0xfd, 0xc0, 0x74, 0x4c, 0x9a, 0xe4,
+ 0x62, 0x6c, 0x38, 0x18, 0x91, 0xdf, 0x8c, 0x04, 0xac, 0x88, 0x57, 0x21, 0xc2, 0xb4, 0xe9, 0x63,
+ 0x7d, 0x0b, 0xe6, 0xcf, 0x1e, 0x90, 0x3e, 0x96, 0x58, 0x5d, 0x5c, 0x5d, 0xa1, 0xa5, 0xb3, 0x31,
+ 0xd7, 0x09, 0xc4, 0xa5, 0x06, 0xcc, 0x9d, 0x39, 0x28, 0x7d, 0x22, 0xb1, 0xea, 0x92, 0x5a, 0x32,
+ 0x0a, 0x9d, 0x60, 0x64, 0x9a, 0x3b, 0x73, 0x58, 0xfa, 0x54, 0x62, 0x57, 0x11, 0xba, 0xe6, 0x19,
+ 0x71, 0x23, 0xd3, 0xdc, 0x99, 0xc3, 0xd2, 0x57, 0x59, 0xed, 0x28, 0xeb, 0x55, 0xd1, 0x08, 0xc6,
+ 0x82, 0xf9, 0xb3, 0x87, 0xa5, 0xaf, 0x49, 0x78, 0x2d, 0x21, 0xeb, 0xba, 0xb7, 0x2e, 0x5e, 0x64,
+ 0x9a, 0x3f, 0x7b, 0x58, 0xfa, 0xba, 0x84, 0x97, 0x17, 0xb2, 0xbe, 0x1e, 0x30, 0x13, 0xf4, 0xe6,
+ 0xf4, 0xb0, 0xf4, 0x0d, 0x09, 0xef, 0x13, 0x64, 0xbd, 0xe6, 0x99, 0xd9, 0x9b, 0xf2, 0xe6, 0xf4,
+ 0xb0, 0xf4, 0x4d, 0x3c, 0xc5, 0xd7, 0x65, 0xfd, 0x4e, 0xc0, 0x0c, 0x46, 0xa6, 0xe2, 0x2b, 0x84,
+ 0xa5, 0x6f, 0x49, 0x78, 0xed, 0x23, 0xeb, 0x77, 0x0d, 0x77, 0x74, 0x3f, 0x32, 0x15, 0x5f, 0x21,
+ 0x2c, 0x7d, 0x26, 0xe1, 0xed, 0x90, 0xac, 0xdf, 0x0b, 0x1a, 0xc2, 0xc8, 0xa4, 0xbc, 0x4a, 0x58,
+ 0xfa, 0x36, 0xb5, 0x54, 0xac, 0xcb, 0xeb, 0xab, 0x86, 0xeb, 0x80, 0x10, 0x99, 0x94, 0x57, 0x09,
+ 0x4b, 0xdf, 0xa1, 0xa6, 0x94, 0xba, 0xbc, 0xbe, 0x16, 0x32, 0x55, 0xd3, 0xeb, 0x8f, 0xa0, 0x70,
+ 0xd6, 0xb0, 0xf4, 0x5d, 0xf1, 0xd6, 0x2d, 0xdf, 0x11, 0x62, 0xd3, 0xae, 0xf0, 0xce, 0x4e, 0x0d,
+ 0x4c, 0xdf, 0xc3, 0x1a, 0xa7, 0x3e, 0xf7, 0x84, 0xdd, 0x4c, 0x31, 0x82, 0xff, 0xfa, 0x58, 0x98,
+ 0xda, 0xf6, 0xf7, 0xc7, 0xa9, 0x31, 0xea, 0xfb, 0x12, 0x5e, 0x5f, 0x15, 0xb8, 0x41, 0xc4, 0x7b,
+ 0x3b, 0x85, 0x05, 0xac, 0x0f, 0xfd, 0x59, 0x9e, 0x16, 0xad, 0x7e, 0x20, 0xbd, 0x4a, 0xb8, 0xaa,
+ 0x27, 0x9a, 0x3b, 0x0d, 0x6f, 0x31, 0xb0, 0xe5, 0x6d, 0x48, 0x1e, 0x6b, 0xab, 0x6b, 0xe2, 0x91,
+ 0x4c, 0xbc, 0xb5, 0x65, 0x41, 0x2a, 0xaf, 0x15, 0x85, 0x8b, 0xed, 0xe1, 0xc8, 0x39, 0x31, 0x90,
+ 0xc5, 0xd9, 0x5a, 0x24, 0xfb, 0x93, 0x18, 0xb6, 0xc6, 0xd9, 0xd5, 0x48, 0xf6, 0xa7, 0x31, 0xec,
+ 0x2a, 0x67, 0xeb, 0x91, 0xec, 0xaf, 0xc6, 0xb0, 0x75, 0xce, 0x5e, 0x8f, 0x64, 0x7f, 0x2d, 0x86,
+ 0xbd, 0xce, 0xd9, 0xb5, 0x48, 0xf6, 0xd7, 0x63, 0xd8, 0x35, 0xce, 0xbe, 0x13, 0xc9, 0xfe, 0x46,
+ 0x0c, 0xfb, 0x0e, 0x67, 0xdf, 0x8d, 0x64, 0x7f, 0x33, 0x86, 0x7d, 0x97, 0xb3, 0xef, 0x45, 0xb2,
+ 0xbf, 0x15, 0xc3, 0xbe, 0xc7, 0xd8, 0x6b, 0xab, 0x91, 0xec, 0xcf, 0xa2, 0xd9, 0x6b, 0xab, 0x9c,
+ 0x1d, 0xad, 0xb5, 0x6f, 0xc7, 0xb0, 0xb9, 0xd6, 0xd6, 0xa2, 0xb5, 0xf6, 0x9d, 0x18, 0x36, 0xd7,
+ 0xda, 0x5a, 0xb4, 0xd6, 0xbe, 0x1b, 0xc3, 0xe6, 0x5a, 0x5b, 0x8b, 0xd6, 0xda, 0xf7, 0x62, 0xd8,
+ 0x5c, 0x6b, 0x6b, 0xd1, 0x5a, 0xfb, 0x7e, 0x0c, 0x9b, 0x6b, 0x6d, 0x2d, 0x5a, 0x6b, 0x3f, 0x88,
+ 0x61, 0x73, 0xad, 0xad, 0x45, 0x6b, 0xed, 0x8f, 0x62, 0xd8, 0x5c, 0x6b, 0x6b, 0xd1, 0x5a, 0xfb,
+ 0xe3, 0x18, 0x36, 0xd7, 0xda, 0x5a, 0xb4, 0xd6, 0xfe, 0x24, 0x86, 0xcd, 0xb5, 0xa6, 0x45, 0x6b,
+ 0xed, 0x4f, 0xa3, 0xd9, 0x1a, 0xd7, 0x9a, 0x16, 0xad, 0xb5, 0x3f, 0x8b, 0x61, 0x73, 0xad, 0x69,
+ 0xd1, 0x5a, 0xfb, 0xf3, 0x18, 0x36, 0xd7, 0x9a, 0x16, 0xad, 0xb5, 0x1f, 0xc6, 0xb0, 0xb9, 0xd6,
+ 0xb4, 0x68, 0xad, 0xfd, 0x45, 0x0c, 0x9b, 0x6b, 0x4d, 0x8b, 0xd6, 0xda, 0x5f, 0xc6, 0xb0, 0xb9,
+ 0xd6, 0xb4, 0x68, 0xad, 0xfd, 0x55, 0x0c, 0x9b, 0x6b, 0x4d, 0x8b, 0xd6, 0xda, 0x5f, 0xc7, 0xb0,
+ 0xb9, 0xd6, 0xb4, 0x68, 0xad, 0xfd, 0x4d, 0x0c, 0x9b, 0x6b, 0x4d, 0x8b, 0xd6, 0xda, 0xdf, 0xc6,
+ 0xb0, 0xb9, 0xd6, 0xaa, 0xd1, 0x5a, 0xfb, 0xbb, 0x68, 0x76, 0x95, 0x6b, 0xad, 0x1a, 0xad, 0xb5,
+ 0xbf, 0x8f, 0x61, 0x73, 0xad, 0x55, 0xa3, 0xb5, 0xf6, 0x0f, 0x31, 0x6c, 0xae, 0xb5, 0x6a, 0xb4,
+ 0xd6, 0xfe, 0x31, 0x86, 0xcd, 0xb5, 0x56, 0x8d, 0xd6, 0xda, 0x8f, 0x62, 0xd8, 0x5c, 0x6b, 0xd5,
+ 0x68, 0xad, 0xfd, 0x53, 0x0c, 0x9b, 0x6b, 0xad, 0x1a, 0xad, 0xb5, 0x7f, 0x8e, 0x61, 0x73, 0xad,
+ 0x55, 0xa3, 0xb5, 0xf6, 0x2f, 0x31, 0x6c, 0xae, 0xb5, 0x6a, 0xb4, 0xd6, 0xfe, 0x35, 0x86, 0xcd,
+ 0xb5, 0x56, 0x8d, 0xd6, 0xda, 0xbf, 0xc5, 0xb0, 0xb9, 0xd6, 0xf4, 0x68, 0xad, 0xfd, 0x7b, 0x34,
+ 0x5b, 0xe7, 0x5a, 0xd3, 0xa3, 0xb5, 0xf6, 0x1f, 0x31, 0x6c, 0xae, 0x35, 0x3d, 0x5a, 0x6b, 0xff,
+ 0x19, 0xc3, 0xe6, 0x5a, 0xd3, 0xa3, 0xb5, 0xf6, 0x5f, 0x31, 0x6c, 0xae, 0x35, 0x3d, 0x5a, 0x6b,
+ 0xff, 0x1d, 0xc3, 0xe6, 0x5a, 0xd3, 0xa3, 0xb5, 0xf6, 0x3f, 0x31, 0x6c, 0xae, 0x35, 0x3d, 0x5a,
+ 0x6b, 0x3f, 0x8e, 0x61, 0x73, 0xad, 0xe9, 0xd1, 0x5a, 0xfb, 0x49, 0x0c, 0x9b, 0x6b, 0x4d, 0x8f,
+ 0xd6, 0xda, 0xff, 0xc6, 0xb0, 0xb9, 0xd6, 0xf4, 0x68, 0xad, 0xfd, 0x5f, 0x0c, 0x9b, 0x6b, 0x6d,
+ 0x3d, 0x5a, 0x6b, 0xff, 0x1f, 0xcd, 0x5e, 0x5f, 0xfd, 0x69, 0x00, 0x00, 0x00, 0xff, 0xff, 0x81,
+ 0x23, 0xc6, 0xe6, 0xc6, 0x38, 0x00, 0x00,
}
diff --git a/vendor/github.com/golang/protobuf/proto/testdata/test.proto b/vendor/github.com/golang/protobuf/proto/testdata/test.proto
index 698c8ce2..f6071136 100644
--- a/vendor/github.com/golang/protobuf/proto/testdata/test.proto
+++ b/vendor/github.com/golang/protobuf/proto/testdata/test.proto
@@ -237,6 +237,10 @@ message OtherMessage {
extensions 100 to max;
}
+message RequiredInnerMessage {
+ required InnerMessage leo_finally_won_an_oscar = 1;
+}
+
message MyMessage {
required int32 count = 1;
optional string name = 2;
@@ -244,6 +248,7 @@ message MyMessage {
repeated string pet = 4;
optional InnerMessage inner = 5;
repeated OtherMessage others = 6;
+ optional RequiredInnerMessage we_must_go_deeper = 13;
repeated InnerMessage rep_inner = 12;
enum Color {
diff --git a/vendor/github.com/golang/protobuf/proto/text.go b/vendor/github.com/golang/protobuf/proto/text.go
index 1cbaf86d..37c95357 100644
--- a/vendor/github.com/golang/protobuf/proto/text.go
+++ b/vendor/github.com/golang/protobuf/proto/text.go
@@ -175,7 +175,93 @@ type raw interface {
Bytes() []byte
}
-func writeStruct(w *textWriter, sv reflect.Value) error {
+func requiresQuotes(u string) bool {
+ // When type URL contains any characters except [0-9A-Za-z./\-]*, it must be quoted.
+ for _, ch := range u {
+ switch {
+ case ch == '.' || ch == '/' || ch == '_':
+ continue
+ case '0' <= ch && ch <= '9':
+ continue
+ case 'A' <= ch && ch <= 'Z':
+ continue
+ case 'a' <= ch && ch <= 'z':
+ continue
+ default:
+ return true
+ }
+ }
+ return false
+}
+
+// isAny reports whether sv is a google.protobuf.Any message
+func isAny(sv reflect.Value) bool {
+ type wkt interface {
+ XXX_WellKnownType() string
+ }
+ t, ok := sv.Addr().Interface().(wkt)
+ return ok && t.XXX_WellKnownType() == "Any"
+}
+
+// writeProto3Any writes an expanded google.protobuf.Any message.
+//
+// It returns (false, nil) if sv value can't be unmarshaled (e.g. because
+// required messages are not linked in).
+//
+// It returns (true, error) when sv was written in expanded format or an error
+// was encountered.
+func (tm *TextMarshaler) writeProto3Any(w *textWriter, sv reflect.Value) (bool, error) {
+ turl := sv.FieldByName("TypeUrl")
+ val := sv.FieldByName("Value")
+ if !turl.IsValid() || !val.IsValid() {
+ return true, errors.New("proto: invalid google.protobuf.Any message")
+ }
+
+ b, ok := val.Interface().([]byte)
+ if !ok {
+ return true, errors.New("proto: invalid google.protobuf.Any message")
+ }
+
+ parts := strings.Split(turl.String(), "/")
+ mt := MessageType(parts[len(parts)-1])
+ if mt == nil {
+ return false, nil
+ }
+ m := reflect.New(mt.Elem())
+ if err := Unmarshal(b, m.Interface().(Message)); err != nil {
+ return false, nil
+ }
+ w.Write([]byte("["))
+ u := turl.String()
+ if requiresQuotes(u) {
+ writeString(w, u)
+ } else {
+ w.Write([]byte(u))
+ }
+ if w.compact {
+ w.Write([]byte("]:<"))
+ } else {
+ w.Write([]byte("]: <\n"))
+ w.ind++
+ }
+ if err := tm.writeStruct(w, m.Elem()); err != nil {
+ return true, err
+ }
+ if w.compact {
+ w.Write([]byte("> "))
+ } else {
+ w.ind--
+ w.Write([]byte(">\n"))
+ }
+ return true, nil
+}
+
+func (tm *TextMarshaler) writeStruct(w *textWriter, sv reflect.Value) error {
+ if tm.ExpandAny && isAny(sv) {
+ if canExpand, err := tm.writeProto3Any(w, sv); canExpand {
+ return err
+ }
+ }
st := sv.Type()
sprops := GetProperties(st)
for i := 0; i < sv.NumField(); i++ {
@@ -227,7 +313,7 @@ func writeStruct(w *textWriter, sv reflect.Value) error {
}
continue
}
- if err := writeAny(w, v, props); err != nil {
+ if err := tm.writeAny(w, v, props); err != nil {
return err
}
if err := w.WriteByte('\n'); err != nil {
@@ -269,7 +355,7 @@ func writeStruct(w *textWriter, sv reflect.Value) error {
return err
}
}
- if err := writeAny(w, key, props.mkeyprop); err != nil {
+ if err := tm.writeAny(w, key, props.mkeyprop); err != nil {
return err
}
if err := w.WriteByte('\n'); err != nil {
@@ -286,7 +372,7 @@ func writeStruct(w *textWriter, sv reflect.Value) error {
return err
}
}
- if err := writeAny(w, val, props.mvalprop); err != nil {
+ if err := tm.writeAny(w, val, props.mvalprop); err != nil {
return err
}
if err := w.WriteByte('\n'); err != nil {
@@ -358,7 +444,7 @@ func writeStruct(w *textWriter, sv reflect.Value) error {
}
// Enums have a String method, so writeAny will work fine.
- if err := writeAny(w, fv, props); err != nil {
+ if err := tm.writeAny(w, fv, props); err != nil {
return err
}
@@ -370,7 +456,7 @@ func writeStruct(w *textWriter, sv reflect.Value) error {
// Extensions (the XXX_extensions field).
pv := sv.Addr()
if pv.Type().Implements(extendableProtoType) {
- if err := writeExtensions(w, pv); err != nil {
+ if err := tm.writeExtensions(w, pv); err != nil {
return err
}
}
@@ -400,7 +486,7 @@ func writeRaw(w *textWriter, b []byte) error {
}
// writeAny writes an arbitrary field.
-func writeAny(w *textWriter, v reflect.Value, props *Properties) error {
+func (tm *TextMarshaler) writeAny(w *textWriter, v reflect.Value, props *Properties) error {
v = reflect.Indirect(v)
// Floats have special cases.
@@ -449,15 +535,15 @@ func writeAny(w *textWriter, v reflect.Value, props *Properties) error {
}
}
w.indent()
- if tm, ok := v.Interface().(encoding.TextMarshaler); ok {
- text, err := tm.MarshalText()
+ if etm, ok := v.Interface().(encoding.TextMarshaler); ok {
+ text, err := etm.MarshalText()
if err != nil {
return err
}
if _, err = w.Write(text); err != nil {
return err
}
- } else if err := writeStruct(w, v); err != nil {
+ } else if err := tm.writeStruct(w, v); err != nil {
return err
}
w.unindent()
@@ -601,7 +687,7 @@ func (s int32Slice) Swap(i, j int) { s[i], s[j] = s[j], s[i] }
// writeExtensions writes all the extensions in pv.
// pv is assumed to be a pointer to a protocol message struct that is extendable.
-func writeExtensions(w *textWriter, pv reflect.Value) error {
+func (tm *TextMarshaler) writeExtensions(w *textWriter, pv reflect.Value) error {
emap := extensionMaps[pv.Type().Elem()]
ep := pv.Interface().(extendableProto)
@@ -636,13 +722,13 @@ func writeExtensions(w *textWriter, pv reflect.Value) error {
// Repeated extensions will appear as a slice.
if !desc.repeated() {
- if err := writeExtension(w, desc.Name, pb); err != nil {
+ if err := tm.writeExtension(w, desc.Name, pb); err != nil {
return err
}
} else {
v := reflect.ValueOf(pb)
for i := 0; i < v.Len(); i++ {
- if err := writeExtension(w, desc.Name, v.Index(i).Interface()); err != nil {
+ if err := tm.writeExtension(w, desc.Name, v.Index(i).Interface()); err != nil {
return err
}
}
@@ -651,7 +737,7 @@ func writeExtensions(w *textWriter, pv reflect.Value) error {
return nil
}
-func writeExtension(w *textWriter, name string, pb interface{}) error {
+func (tm *TextMarshaler) writeExtension(w *textWriter, name string, pb interface{}) error {
if _, err := fmt.Fprintf(w, "[%s]:", name); err != nil {
return err
}
@@ -660,7 +746,7 @@ func writeExtension(w *textWriter, name string, pb interface{}) error {
return err
}
}
- if err := writeAny(w, reflect.ValueOf(pb), nil); err != nil {
+ if err := tm.writeAny(w, reflect.ValueOf(pb), nil); err != nil {
return err
}
if err := w.WriteByte('\n'); err != nil {
@@ -687,12 +773,13 @@ func (w *textWriter) writeIndent() {
// TextMarshaler is a configurable text format marshaler.
type TextMarshaler struct {
- Compact bool // use compact text format (one line).
+ Compact bool // use compact text format (one line).
+ ExpandAny bool // expand google.protobuf.Any messages of known types
}
// Marshal writes a given protocol buffer in text format.
// The only errors returned are from w.
-func (m *TextMarshaler) Marshal(w io.Writer, pb Message) error {
+func (tm *TextMarshaler) Marshal(w io.Writer, pb Message) error {
val := reflect.ValueOf(pb)
if pb == nil || val.IsNil() {
w.Write([]byte(""))
@@ -707,11 +794,11 @@ func (m *TextMarshaler) Marshal(w io.Writer, pb Message) error {
aw := &textWriter{
w: ww,
complete: true,
- compact: m.Compact,
+ compact: tm.Compact,
}
- if tm, ok := pb.(encoding.TextMarshaler); ok {
- text, err := tm.MarshalText()
+ if etm, ok := pb.(encoding.TextMarshaler); ok {
+ text, err := etm.MarshalText()
if err != nil {
return err
}
@@ -725,7 +812,7 @@ func (m *TextMarshaler) Marshal(w io.Writer, pb Message) error {
}
// Dereference the received pointer so we don't have outer < and >.
v := reflect.Indirect(val)
- if err := writeStruct(aw, v); err != nil {
+ if err := tm.writeStruct(aw, v); err != nil {
return err
}
if bw != nil {
@@ -735,9 +822,9 @@ func (m *TextMarshaler) Marshal(w io.Writer, pb Message) error {
}
// Text is the same as Marshal, but returns the string directly.
-func (m *TextMarshaler) Text(pb Message) string {
+func (tm *TextMarshaler) Text(pb Message) string {
var buf bytes.Buffer
- m.Marshal(&buf, pb)
+ tm.Marshal(&buf, pb)
return buf.String()
}
diff --git a/vendor/github.com/golang/protobuf/proto/text_parser.go b/vendor/github.com/golang/protobuf/proto/text_parser.go
index 45132326..b5fba5b2 100644
--- a/vendor/github.com/golang/protobuf/proto/text_parser.go
+++ b/vendor/github.com/golang/protobuf/proto/text_parser.go
@@ -163,7 +163,7 @@ func (p *textParser) advance() {
p.cur.offset, p.cur.line = p.offset, p.line
p.cur.unquoted = ""
switch p.s[0] {
- case '<', '>', '{', '}', ':', '[', ']', ';', ',':
+ case '<', '>', '{', '}', ':', '[', ']', ';', ',', '/':
// Single symbol
p.cur.value, p.s = p.s[0:1], p.s[1:len(p.s)]
case '"', '\'':
@@ -451,7 +451,10 @@ func (p *textParser) readStruct(sv reflect.Value, terminator string) error {
fieldSet := make(map[string]bool)
// A struct is a sequence of "name: value", terminated by one of
// '>' or '}', or the end of the input. A name may also be
- // "[extension]".
+ // "[extension]" or "[type/url]".
+ //
+ // The whole struct can also be an expanded Any message, like:
+ // [type/url] < ... struct contents ... >
for {
tok := p.next()
if tok.err != nil {
@@ -461,33 +464,66 @@ func (p *textParser) readStruct(sv reflect.Value, terminator string) error {
break
}
if tok.value == "[" {
- // Looks like an extension.
+ // Looks like an extension or an Any.
//
// TODO: Check whether we need to handle
// namespace rooted names (e.g. ".something.Foo").
- tok = p.next()
- if tok.err != nil {
- return tok.err
+ extName, err := p.consumeExtName()
+ if err != nil {
+ return err
}
+
+ if s := strings.LastIndex(extName, "/"); s >= 0 {
+ // If it contains a slash, it's an Any type URL.
+ messageName := extName[s+1:]
+ mt := MessageType(messageName)
+ if mt == nil {
+ return p.errorf("unrecognized message %q in google.protobuf.Any", messageName)
+ }
+ tok = p.next()
+ if tok.err != nil {
+ return tok.err
+ }
+ // consume an optional colon
+ if tok.value == ":" {
+ tok = p.next()
+ if tok.err != nil {
+ return tok.err
+ }
+ }
+ var terminator string
+ switch tok.value {
+ case "<":
+ terminator = ">"
+ case "{":
+ terminator = "}"
+ default:
+ return p.errorf("expected '{' or '<', found %q", tok.value)
+ }
+ v := reflect.New(mt.Elem())
+ if pe := p.readStruct(v.Elem(), terminator); pe != nil {
+ return pe
+ }
+ b, err := Marshal(v.Interface().(Message))
+ if err != nil {
+ return p.errorf("failed to marshal message of type %q: %v", messageName, err)
+ }
+ sv.FieldByName("TypeUrl").SetString(extName)
+ sv.FieldByName("Value").SetBytes(b)
+ continue
+ }
+
var desc *ExtensionDesc
// This could be faster, but it's functional.
// TODO: Do something smarter than a linear scan.
for _, d := range RegisteredExtensions(reflect.New(st).Interface().(Message)) {
- if d.Name == tok.value {
+ if d.Name == extName {
desc = d
break
}
}
if desc == nil {
- return p.errorf("unrecognized extension %q", tok.value)
- }
- // Check the extension terminator.
- tok = p.next()
- if tok.err != nil {
- return tok.err
- }
- if tok.value != "]" {
- return p.errorf("unrecognized extension terminator %q", tok.value)
+ return p.errorf("unrecognized extension %q", extName)
}
props := &Properties{}
@@ -627,7 +663,8 @@ func (p *textParser) readStruct(sv reflect.Value, terminator string) error {
return err
}
reqFieldErr = err
- } else if props.Required {
+ }
+ if props.Required {
reqCount--
}
@@ -643,6 +680,35 @@ func (p *textParser) readStruct(sv reflect.Value, terminator string) error {
return reqFieldErr
}
+// consumeExtName consumes extension name or expanded Any type URL and the
+// following ']'. It returns the name or URL consumed.
+func (p *textParser) consumeExtName() (string, error) {
+ tok := p.next()
+ if tok.err != nil {
+ return "", tok.err
+ }
+
+ // If extension name or type url is quoted, it's a single token.
+ if len(tok.value) > 2 && isQuote(tok.value[0]) && tok.value[len(tok.value)-1] == tok.value[0] {
+ name, err := unquoteC(tok.value[1:len(tok.value)-1], rune(tok.value[0]))
+ if err != nil {
+ return "", err
+ }
+ return name, p.consumeToken("]")
+ }
+
+ // Consume everything up to "]"
+ var parts []string
+ for tok.value != "]" {
+ parts = append(parts, tok.value)
+ tok = p.next()
+ if tok.err != nil {
+ return "", p.errorf("unrecognized type_url or extension name: %s", tok.err)
+ }
+ }
+ return strings.Join(parts, ""), nil
+}
+
// consumeOptionalSeparator consumes an optional semicolon or comma.
// It is used in readStruct to provide backward compatibility.
func (p *textParser) consumeOptionalSeparator() error {
diff --git a/vendor/github.com/golang/protobuf/proto/text_parser_test.go b/vendor/github.com/golang/protobuf/proto/text_parser_test.go
index d2e4cca0..32c41170 100644
--- a/vendor/github.com/golang/protobuf/proto/text_parser_test.go
+++ b/vendor/github.com/golang/protobuf/proto/text_parser_test.go
@@ -336,6 +336,16 @@ var unMarshalTextTests = []UnmarshalTextTest{
},
},
+ // Missing required field in a required submessage
+ {
+ in: `count: 42 we_must_go_deeper < leo_finally_won_an_oscar <> >`,
+ err: `proto: required field "testdata.InnerMessage.host" not set`,
+ out: &MyMessage{
+ Count: Int32(42),
+ WeMustGoDeeper: &RequiredInnerMessage{LeoFinallyWonAnOscar: &InnerMessage{}},
+ },
+ },
+
// Repeated non-repeated field
{
in: `name: "Rob" name: "Russ"`,
diff --git a/vendor/github.com/satori/go.uuid/.travis.yml b/vendor/github.com/satori/go.uuid/.travis.yml
deleted file mode 100644
index 5e217462..00000000
--- a/vendor/github.com/satori/go.uuid/.travis.yml
+++ /dev/null
@@ -1,12 +0,0 @@
-language: go
-go:
- - 1.0
- - 1.1
- - 1.2
- - 1.3
- - 1.4
- - 1.5
- - 1.6
-sudo: false
-notifications:
- email: false
diff --git a/vendor/github.com/satori/go.uuid/LICENSE b/vendor/github.com/satori/go.uuid/LICENSE
deleted file mode 100644
index 488357b8..00000000
--- a/vendor/github.com/satori/go.uuid/LICENSE
+++ /dev/null
@@ -1,20 +0,0 @@
-Copyright (C) 2013-2016 by Maxim Bublis
-
-Permission is hereby granted, free of charge, to any person obtaining
-a copy of this software and associated documentation files (the
-"Software"), to deal in the Software without restriction, including
-without limitation the rights to use, copy, modify, merge, publish,
-distribute, sublicense, and/or sell copies of the Software, and to
-permit persons to whom the Software is furnished to do so, subject to
-the following conditions:
-
-The above copyright notice and this permission notice shall be
-included in all copies or substantial portions of the Software.
-
-THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
-EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
-MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
-NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
-LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
-OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
-WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
diff --git a/vendor/github.com/satori/go.uuid/README.md b/vendor/github.com/satori/go.uuid/README.md
deleted file mode 100644
index b6b626b2..00000000
--- a/vendor/github.com/satori/go.uuid/README.md
+++ /dev/null
@@ -1,64 +0,0 @@
-# UUID package for Go language
-
-[](https://travis-ci.org/satori/go.uuid)
-[](http://godoc.org/github.com/satori/go.uuid)
-
-This package provides pure Go implementation of Universally Unique Identifier (UUID). Supported both creation and parsing of UUIDs.
-
-With 100% test coverage and benchmarks out of box.
-
-Supported versions:
-* Version 1, based on timestamp and MAC address (RFC 4122)
-* Version 2, based on timestamp, MAC address and POSIX UID/GID (DCE 1.1)
-* Version 3, based on MD5 hashing (RFC 4122)
-* Version 4, based on random numbers (RFC 4122)
-* Version 5, based on SHA-1 hashing (RFC 4122)
-
-## Installation
-
-Use the `go` command:
-
- $ go get github.com/satori/go.uuid
-
-## Requirements
-
-UUID package requires any stable version of Go Programming Language.
-
-## Example
-
-```go
-package main
-
-import (
- "fmt"
- "github.com/satori/go.uuid"
-)
-
-func main() {
- // Creating UUID Version 4
- u1 := uuid.NewV4()
- fmt.Printf("UUIDv4: %s\n", u1)
-
- // Parsing UUID from string input
- u2, err := uuid.FromString("6ba7b810-9dad-11d1-80b4-00c04fd430c8")
- if err != nil {
- fmt.Printf("Something gone wrong: %s", err)
- }
- fmt.Printf("Successfully parsed: %s", u2)
-}
-```
-
-## Documentation
-
-[Documentation](http://godoc.org/github.com/satori/go.uuid) is hosted at GoDoc project.
-
-## Links
-* [RFC 4122](http://tools.ietf.org/html/rfc4122)
-* [DCE 1.1: Authentication and Security Services](http://pubs.opengroup.org/onlinepubs/9696989899/chap5.htm#tagcjh_08_02_01_01)
-
-## Copyright
-
-Copyright (C) 2013-2016 by Maxim Bublis .
-
-UUID package released under MIT License.
-See [LICENSE](https://github.com/satori/go.uuid/blob/master/LICENSE) for details.
diff --git a/vendor/github.com/satori/go.uuid/benchmarks_test.go b/vendor/github.com/satori/go.uuid/benchmarks_test.go
deleted file mode 100644
index b4e567fc..00000000
--- a/vendor/github.com/satori/go.uuid/benchmarks_test.go
+++ /dev/null
@@ -1,121 +0,0 @@
-// Copyright (C) 2013-2015 by Maxim Bublis
-//
-// Permission is hereby granted, free of charge, to any person obtaining
-// a copy of this software and associated documentation files (the
-// "Software"), to deal in the Software without restriction, including
-// without limitation the rights to use, copy, modify, merge, publish,
-// distribute, sublicense, and/or sell copies of the Software, and to
-// permit persons to whom the Software is furnished to do so, subject to
-// the following conditions:
-//
-// The above copyright notice and this permission notice shall be
-// included in all copies or substantial portions of the Software.
-//
-// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
-// EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
-// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
-// NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
-// LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
-// OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
-// WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
-
-package uuid
-
-import (
- "testing"
-)
-
-func BenchmarkFromBytes(b *testing.B) {
- bytes := []byte{0x6b, 0xa7, 0xb8, 0x10, 0x9d, 0xad, 0x11, 0xd1, 0x80, 0xb4, 0x00, 0xc0, 0x4f, 0xd4, 0x30, 0xc8}
- for i := 0; i < b.N; i++ {
- FromBytes(bytes)
- }
-}
-
-func BenchmarkFromString(b *testing.B) {
- s := "6ba7b810-9dad-11d1-80b4-00c04fd430c8"
- for i := 0; i < b.N; i++ {
- FromString(s)
- }
-}
-
-func BenchmarkFromStringUrn(b *testing.B) {
- s := "urn:uuid:6ba7b810-9dad-11d1-80b4-00c04fd430c8"
- for i := 0; i < b.N; i++ {
- FromString(s)
- }
-}
-
-func BenchmarkFromStringWithBrackets(b *testing.B) {
- s := "{6ba7b810-9dad-11d1-80b4-00c04fd430c8}"
- for i := 0; i < b.N; i++ {
- FromString(s)
- }
-}
-
-func BenchmarkNewV1(b *testing.B) {
- for i := 0; i < b.N; i++ {
- NewV1()
- }
-}
-
-func BenchmarkNewV2(b *testing.B) {
- for i := 0; i < b.N; i++ {
- NewV2(DomainPerson)
- }
-}
-
-func BenchmarkNewV3(b *testing.B) {
- for i := 0; i < b.N; i++ {
- NewV3(NamespaceDNS, "www.example.com")
- }
-}
-
-func BenchmarkNewV4(b *testing.B) {
- for i := 0; i < b.N; i++ {
- NewV4()
- }
-}
-
-func BenchmarkNewV5(b *testing.B) {
- for i := 0; i < b.N; i++ {
- NewV5(NamespaceDNS, "www.example.com")
- }
-}
-
-func BenchmarkMarshalBinary(b *testing.B) {
- u := NewV4()
- for i := 0; i < b.N; i++ {
- u.MarshalBinary()
- }
-}
-
-func BenchmarkMarshalText(b *testing.B) {
- u := NewV4()
- for i := 0; i < b.N; i++ {
- u.MarshalText()
- }
-}
-
-func BenchmarkUnmarshalBinary(b *testing.B) {
- bytes := []byte{0x6b, 0xa7, 0xb8, 0x10, 0x9d, 0xad, 0x11, 0xd1, 0x80, 0xb4, 0x00, 0xc0, 0x4f, 0xd4, 0x30, 0xc8}
- u := UUID{}
- for i := 0; i < b.N; i++ {
- u.UnmarshalBinary(bytes)
- }
-}
-
-func BenchmarkUnmarshalText(b *testing.B) {
- bytes := []byte("6ba7b810-9dad-11d1-80b4-00c04fd430c8")
- u := UUID{}
- for i := 0; i < b.N; i++ {
- u.UnmarshalText(bytes)
- }
-}
-
-func BenchmarkMarshalToString(b *testing.B) {
- u := NewV4()
- for i := 0; i < b.N; i++ {
- u.String()
- }
-}
diff --git a/vendor/github.com/satori/go.uuid/uuid.go b/vendor/github.com/satori/go.uuid/uuid.go
deleted file mode 100644
index 03841d86..00000000
--- a/vendor/github.com/satori/go.uuid/uuid.go
+++ /dev/null
@@ -1,435 +0,0 @@
-// Copyright (C) 2013-2015 by Maxim Bublis
-//
-// Permission is hereby granted, free of charge, to any person obtaining
-// a copy of this software and associated documentation files (the
-// "Software"), to deal in the Software without restriction, including
-// without limitation the rights to use, copy, modify, merge, publish,
-// distribute, sublicense, and/or sell copies of the Software, and to
-// permit persons to whom the Software is furnished to do so, subject to
-// the following conditions:
-//
-// The above copyright notice and this permission notice shall be
-// included in all copies or substantial portions of the Software.
-//
-// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
-// EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
-// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
-// NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
-// LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
-// OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
-// WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
-
-// Package uuid provides implementation of Universally Unique Identifier (UUID).
-// Supported versions are 1, 3, 4 and 5 (as specified in RFC 4122) and
-// version 2 (as specified in DCE 1.1).
-package uuid
-
-import (
- "bytes"
- "crypto/md5"
- "crypto/rand"
- "crypto/sha1"
- "database/sql/driver"
- "encoding/binary"
- "encoding/hex"
- "fmt"
- "hash"
- "net"
- "os"
- "sync"
- "time"
-)
-
-// UUID layout variants.
-const (
- VariantNCS = iota
- VariantRFC4122
- VariantMicrosoft
- VariantFuture
-)
-
-// UUID DCE domains.
-const (
- DomainPerson = iota
- DomainGroup
- DomainOrg
-)
-
-// Difference in 100-nanosecond intervals between
-// UUID epoch (October 15, 1582) and Unix epoch (January 1, 1970).
-const epochStart = 122192928000000000
-
-// Used in string method conversion
-const dash byte = '-'
-
-// UUID v1/v2 storage.
-var (
- storageMutex sync.Mutex
- storageOnce sync.Once
- epochFunc = unixTimeFunc
- clockSequence uint16
- lastTime uint64
- hardwareAddr [6]byte
- posixUID = uint32(os.Getuid())
- posixGID = uint32(os.Getgid())
-)
-
-// String parse helpers.
-var (
- urnPrefix = []byte("urn:uuid:")
- byteGroups = []int{8, 4, 4, 4, 12}
-)
-
-func initClockSequence() {
- buf := make([]byte, 2)
- safeRandom(buf)
- clockSequence = binary.BigEndian.Uint16(buf)
-}
-
-func initHardwareAddr() {
- interfaces, err := net.Interfaces()
- if err == nil {
- for _, iface := range interfaces {
- if len(iface.HardwareAddr) >= 6 {
- copy(hardwareAddr[:], iface.HardwareAddr)
- return
- }
- }
- }
-
- // Initialize hardwareAddr randomly in case
- // of real network interfaces absence
- safeRandom(hardwareAddr[:])
-
- // Set multicast bit as recommended in RFC 4122
- hardwareAddr[0] |= 0x01
-}
-
-func initStorage() {
- initClockSequence()
- initHardwareAddr()
-}
-
-func safeRandom(dest []byte) {
- if _, err := rand.Read(dest); err != nil {
- panic(err)
- }
-}
-
-// Returns difference in 100-nanosecond intervals between
-// UUID epoch (October 15, 1582) and current time.
-// This is default epoch calculation function.
-func unixTimeFunc() uint64 {
- return epochStart + uint64(time.Now().UnixNano()/100)
-}
-
-// UUID representation compliant with specification
-// described in RFC 4122.
-type UUID [16]byte
-
-// The nil UUID is special form of UUID that is specified to have all
-// 128 bits set to zero.
-var Nil = UUID{}
-
-// Predefined namespace UUIDs.
-var (
- NamespaceDNS, _ = FromString("6ba7b810-9dad-11d1-80b4-00c04fd430c8")
- NamespaceURL, _ = FromString("6ba7b811-9dad-11d1-80b4-00c04fd430c8")
- NamespaceOID, _ = FromString("6ba7b812-9dad-11d1-80b4-00c04fd430c8")
- NamespaceX500, _ = FromString("6ba7b814-9dad-11d1-80b4-00c04fd430c8")
-)
-
-// And returns result of binary AND of two UUIDs.
-func And(u1 UUID, u2 UUID) UUID {
- u := UUID{}
- for i := 0; i < 16; i++ {
- u[i] = u1[i] & u2[i]
- }
- return u
-}
-
-// Or returns result of binary OR of two UUIDs.
-func Or(u1 UUID, u2 UUID) UUID {
- u := UUID{}
- for i := 0; i < 16; i++ {
- u[i] = u1[i] | u2[i]
- }
- return u
-}
-
-// Equal returns true if u1 and u2 equals, otherwise returns false.
-func Equal(u1 UUID, u2 UUID) bool {
- return bytes.Equal(u1[:], u2[:])
-}
-
-// Version returns algorithm version used to generate UUID.
-func (u UUID) Version() uint {
- return uint(u[6] >> 4)
-}
-
-// Variant returns UUID layout variant.
-func (u UUID) Variant() uint {
- switch {
- case (u[8] & 0x80) == 0x00:
- return VariantNCS
- case (u[8]&0xc0)|0x80 == 0x80:
- return VariantRFC4122
- case (u[8]&0xe0)|0xc0 == 0xc0:
- return VariantMicrosoft
- }
- return VariantFuture
-}
-
-// Bytes returns bytes slice representation of UUID.
-func (u UUID) Bytes() []byte {
- return u[:]
-}
-
-// Returns canonical string representation of UUID:
-// xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx.
-func (u UUID) String() string {
- buf := make([]byte, 36)
-
- hex.Encode(buf[0:8], u[0:4])
- buf[8] = dash
- hex.Encode(buf[9:13], u[4:6])
- buf[13] = dash
- hex.Encode(buf[14:18], u[6:8])
- buf[18] = dash
- hex.Encode(buf[19:23], u[8:10])
- buf[23] = dash
- hex.Encode(buf[24:], u[10:])
-
- return string(buf)
-}
-
-// SetVersion sets version bits.
-func (u *UUID) SetVersion(v byte) {
- u[6] = (u[6] & 0x0f) | (v << 4)
-}
-
-// SetVariant sets variant bits as described in RFC 4122.
-func (u *UUID) SetVariant() {
- u[8] = (u[8] & 0xbf) | 0x80
-}
-
-// MarshalText implements the encoding.TextMarshaler interface.
-// The encoding is the same as returned by String.
-func (u UUID) MarshalText() (text []byte, err error) {
- text = []byte(u.String())
- return
-}
-
-// UnmarshalText implements the encoding.TextUnmarshaler interface.
-// Following formats are supported:
-// "6ba7b810-9dad-11d1-80b4-00c04fd430c8",
-// "{6ba7b810-9dad-11d1-80b4-00c04fd430c8}",
-// "urn:uuid:6ba7b810-9dad-11d1-80b4-00c04fd430c8"
-func (u *UUID) UnmarshalText(text []byte) (err error) {
- if len(text) < 32 {
- err = fmt.Errorf("uuid: invalid UUID string: %s", text)
- return
- }
-
- if bytes.Equal(text[:9], urnPrefix) {
- text = text[9:]
- } else if text[0] == '{' {
- text = text[1:]
- }
-
- b := u[:]
-
- for _, byteGroup := range byteGroups {
- if text[0] == '-' {
- text = text[1:]
- }
-
- _, err = hex.Decode(b[:byteGroup/2], text[:byteGroup])
-
- if err != nil {
- return
- }
-
- text = text[byteGroup:]
- b = b[byteGroup/2:]
- }
-
- return
-}
-
-// MarshalBinary implements the encoding.BinaryMarshaler interface.
-func (u UUID) MarshalBinary() (data []byte, err error) {
- data = u.Bytes()
- return
-}
-
-// UnmarshalBinary implements the encoding.BinaryUnmarshaler interface.
-// It will return error if the slice isn't 16 bytes long.
-func (u *UUID) UnmarshalBinary(data []byte) (err error) {
- if len(data) != 16 {
- err = fmt.Errorf("uuid: UUID must be exactly 16 bytes long, got %d bytes", len(data))
- return
- }
- copy(u[:], data)
-
- return
-}
-
-// Value implements the driver.Valuer interface.
-func (u UUID) Value() (driver.Value, error) {
- return u.String(), nil
-}
-
-// Scan implements the sql.Scanner interface.
-// A 16-byte slice is handled by UnmarshalBinary, while
-// a longer byte slice or a string is handled by UnmarshalText.
-func (u *UUID) Scan(src interface{}) error {
- switch src := src.(type) {
- case []byte:
- if len(src) == 16 {
- return u.UnmarshalBinary(src)
- }
- return u.UnmarshalText(src)
-
- case string:
- return u.UnmarshalText([]byte(src))
- }
-
- return fmt.Errorf("uuid: cannot convert %T to UUID", src)
-}
-
-// FromBytes returns UUID converted from raw byte slice input.
-// It will return error if the slice isn't 16 bytes long.
-func FromBytes(input []byte) (u UUID, err error) {
- err = u.UnmarshalBinary(input)
- return
-}
-
-// FromBytesOrNil returns UUID converted from raw byte slice input.
-// Same behavior as FromBytes, but returns a Nil UUID on error.
-func FromBytesOrNil(input []byte) UUID {
- uuid, err := FromBytes(input)
- if err != nil {
- return Nil
- }
- return uuid
-}
-
-// FromString returns UUID parsed from string input.
-// Input is expected in a form accepted by UnmarshalText.
-func FromString(input string) (u UUID, err error) {
- err = u.UnmarshalText([]byte(input))
- return
-}
-
-// FromStringOrNil returns UUID parsed from string input.
-// Same behavior as FromString, but returns a Nil UUID on error.
-func FromStringOrNil(input string) UUID {
- uuid, err := FromString(input)
- if err != nil {
- return Nil
- }
- return uuid
-}
-
-// Returns UUID v1/v2 storage state.
-// Returns epoch timestamp, clock sequence, and hardware address.
-func getStorage() (uint64, uint16, []byte) {
- storageOnce.Do(initStorage)
-
- storageMutex.Lock()
- defer storageMutex.Unlock()
-
- timeNow := epochFunc()
- // Clock changed backwards since last UUID generation.
- // Should increase clock sequence.
- if timeNow <= lastTime {
- clockSequence++
- }
- lastTime = timeNow
-
- return timeNow, clockSequence, hardwareAddr[:]
-}
-
-// NewV1 returns UUID based on current timestamp and MAC address.
-func NewV1() UUID {
- u := UUID{}
-
- timeNow, clockSeq, hardwareAddr := getStorage()
-
- binary.BigEndian.PutUint32(u[0:], uint32(timeNow))
- binary.BigEndian.PutUint16(u[4:], uint16(timeNow>>32))
- binary.BigEndian.PutUint16(u[6:], uint16(timeNow>>48))
- binary.BigEndian.PutUint16(u[8:], clockSeq)
-
- copy(u[10:], hardwareAddr)
-
- u.SetVersion(1)
- u.SetVariant()
-
- return u
-}
-
-// NewV2 returns DCE Security UUID based on POSIX UID/GID.
-func NewV2(domain byte) UUID {
- u := UUID{}
-
- timeNow, clockSeq, hardwareAddr := getStorage()
-
- switch domain {
- case DomainPerson:
- binary.BigEndian.PutUint32(u[0:], posixUID)
- case DomainGroup:
- binary.BigEndian.PutUint32(u[0:], posixGID)
- }
-
- binary.BigEndian.PutUint16(u[4:], uint16(timeNow>>32))
- binary.BigEndian.PutUint16(u[6:], uint16(timeNow>>48))
- binary.BigEndian.PutUint16(u[8:], clockSeq)
- u[9] = domain
-
- copy(u[10:], hardwareAddr)
-
- u.SetVersion(2)
- u.SetVariant()
-
- return u
-}
-
-// NewV3 returns UUID based on MD5 hash of namespace UUID and name.
-func NewV3(ns UUID, name string) UUID {
- u := newFromHash(md5.New(), ns, name)
- u.SetVersion(3)
- u.SetVariant()
-
- return u
-}
-
-// NewV4 returns random generated UUID.
-func NewV4() UUID {
- u := UUID{}
- safeRandom(u[:])
- u.SetVersion(4)
- u.SetVariant()
-
- return u
-}
-
-// NewV5 returns UUID based on SHA-1 hash of namespace UUID and name.
-func NewV5(ns UUID, name string) UUID {
- u := newFromHash(sha1.New(), ns, name)
- u.SetVersion(5)
- u.SetVariant()
-
- return u
-}
-
-// Returns UUID based on hashing of namespace UUID and name.
-func newFromHash(h hash.Hash, ns UUID, name string) UUID {
- u := UUID{}
- h.Write(ns[:])
- h.Write([]byte(name))
- copy(u[:], h.Sum(nil))
-
- return u
-}
diff --git a/vendor/github.com/satori/go.uuid/uuid_test.go b/vendor/github.com/satori/go.uuid/uuid_test.go
deleted file mode 100644
index a5015031..00000000
--- a/vendor/github.com/satori/go.uuid/uuid_test.go
+++ /dev/null
@@ -1,508 +0,0 @@
-// Copyright (C) 2013, 2015 by Maxim Bublis
-//
-// Permission is hereby granted, free of charge, to any person obtaining
-// a copy of this software and associated documentation files (the
-// "Software"), to deal in the Software without restriction, including
-// without limitation the rights to use, copy, modify, merge, publish,
-// distribute, sublicense, and/or sell copies of the Software, and to
-// permit persons to whom the Software is furnished to do so, subject to
-// the following conditions:
-//
-// The above copyright notice and this permission notice shall be
-// included in all copies or substantial portions of the Software.
-//
-// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
-// EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
-// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
-// NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
-// LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
-// OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
-// WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
-
-package uuid
-
-import (
- "bytes"
- "testing"
-)
-
-func TestBytes(t *testing.T) {
- u := UUID{0x6b, 0xa7, 0xb8, 0x10, 0x9d, 0xad, 0x11, 0xd1, 0x80, 0xb4, 0x00, 0xc0, 0x4f, 0xd4, 0x30, 0xc8}
-
- bytes1 := []byte{0x6b, 0xa7, 0xb8, 0x10, 0x9d, 0xad, 0x11, 0xd1, 0x80, 0xb4, 0x00, 0xc0, 0x4f, 0xd4, 0x30, 0xc8}
-
- if !bytes.Equal(u.Bytes(), bytes1) {
- t.Errorf("Incorrect bytes representation for UUID: %s", u)
- }
-}
-
-func TestString(t *testing.T) {
- if NamespaceDNS.String() != "6ba7b810-9dad-11d1-80b4-00c04fd430c8" {
- t.Errorf("Incorrect string representation for UUID: %s", NamespaceDNS.String())
- }
-}
-
-func TestEqual(t *testing.T) {
- if !Equal(NamespaceDNS, NamespaceDNS) {
- t.Errorf("Incorrect comparison of %s and %s", NamespaceDNS, NamespaceDNS)
- }
-
- if Equal(NamespaceDNS, NamespaceURL) {
- t.Errorf("Incorrect comparison of %s and %s", NamespaceDNS, NamespaceURL)
- }
-}
-
-func TestOr(t *testing.T) {
- u1 := UUID{0x00, 0xff, 0x00, 0xff, 0x00, 0xff, 0x00, 0xff, 0x00, 0xff, 0x00, 0xff, 0x00, 0xff, 0x00, 0xff}
- u2 := UUID{0xff, 0x00, 0xff, 0x00, 0xff, 0x00, 0xff, 0x00, 0xff, 0x00, 0xff, 0x00, 0xff, 0x00, 0xff, 0x00}
-
- u := UUID{0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff}
-
- if !Equal(u, Or(u1, u2)) {
- t.Errorf("Incorrect bitwise OR result %s", Or(u1, u2))
- }
-}
-
-func TestAnd(t *testing.T) {
- u1 := UUID{0x00, 0xff, 0x00, 0xff, 0x00, 0xff, 0x00, 0xff, 0x00, 0xff, 0x00, 0xff, 0x00, 0xff, 0x00, 0xff}
- u2 := UUID{0xff, 0x00, 0xff, 0x00, 0xff, 0x00, 0xff, 0x00, 0xff, 0x00, 0xff, 0x00, 0xff, 0x00, 0xff, 0x00}
-
- u := UUID{0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}
-
- if !Equal(u, And(u1, u2)) {
- t.Errorf("Incorrect bitwise AND result %s", And(u1, u2))
- }
-}
-
-func TestVersion(t *testing.T) {
- u := UUID{0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x10, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}
-
- if u.Version() != 1 {
- t.Errorf("Incorrect version for UUID: %d", u.Version())
- }
-}
-
-func TestSetVersion(t *testing.T) {
- u := UUID{}
- u.SetVersion(4)
-
- if u.Version() != 4 {
- t.Errorf("Incorrect version for UUID after u.setVersion(4): %d", u.Version())
- }
-}
-
-func TestVariant(t *testing.T) {
- u1 := UUID{0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}
-
- if u1.Variant() != VariantNCS {
- t.Errorf("Incorrect variant for UUID variant %d: %d", VariantNCS, u1.Variant())
- }
-
- u2 := UUID{0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}
-
- if u2.Variant() != VariantRFC4122 {
- t.Errorf("Incorrect variant for UUID variant %d: %d", VariantRFC4122, u2.Variant())
- }
-
- u3 := UUID{0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xc0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}
-
- if u3.Variant() != VariantMicrosoft {
- t.Errorf("Incorrect variant for UUID variant %d: %d", VariantMicrosoft, u3.Variant())
- }
-
- u4 := UUID{0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xe0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}
-
- if u4.Variant() != VariantFuture {
- t.Errorf("Incorrect variant for UUID variant %d: %d", VariantFuture, u4.Variant())
- }
-}
-
-func TestSetVariant(t *testing.T) {
- u := new(UUID)
- u.SetVariant()
-
- if u.Variant() != VariantRFC4122 {
- t.Errorf("Incorrect variant for UUID after u.setVariant(): %d", u.Variant())
- }
-}
-
-func TestFromBytes(t *testing.T) {
- u := UUID{0x6b, 0xa7, 0xb8, 0x10, 0x9d, 0xad, 0x11, 0xd1, 0x80, 0xb4, 0x00, 0xc0, 0x4f, 0xd4, 0x30, 0xc8}
- b1 := []byte{0x6b, 0xa7, 0xb8, 0x10, 0x9d, 0xad, 0x11, 0xd1, 0x80, 0xb4, 0x00, 0xc0, 0x4f, 0xd4, 0x30, 0xc8}
-
- u1, err := FromBytes(b1)
- if err != nil {
- t.Errorf("Error parsing UUID from bytes: %s", err)
- }
-
- if !Equal(u, u1) {
- t.Errorf("UUIDs should be equal: %s and %s", u, u1)
- }
-
- b2 := []byte{}
-
- _, err = FromBytes(b2)
- if err == nil {
- t.Errorf("Should return error parsing from empty byte slice, got %s", err)
- }
-}
-
-func TestMarshalBinary(t *testing.T) {
- u := UUID{0x6b, 0xa7, 0xb8, 0x10, 0x9d, 0xad, 0x11, 0xd1, 0x80, 0xb4, 0x00, 0xc0, 0x4f, 0xd4, 0x30, 0xc8}
- b1 := []byte{0x6b, 0xa7, 0xb8, 0x10, 0x9d, 0xad, 0x11, 0xd1, 0x80, 0xb4, 0x00, 0xc0, 0x4f, 0xd4, 0x30, 0xc8}
-
- b2, err := u.MarshalBinary()
- if err != nil {
- t.Errorf("Error marshaling UUID: %s", err)
- }
-
- if !bytes.Equal(b1, b2) {
- t.Errorf("Marshaled UUID should be %s, got %s", b1, b2)
- }
-}
-
-func TestUnmarshalBinary(t *testing.T) {
- u := UUID{0x6b, 0xa7, 0xb8, 0x10, 0x9d, 0xad, 0x11, 0xd1, 0x80, 0xb4, 0x00, 0xc0, 0x4f, 0xd4, 0x30, 0xc8}
- b1 := []byte{0x6b, 0xa7, 0xb8, 0x10, 0x9d, 0xad, 0x11, 0xd1, 0x80, 0xb4, 0x00, 0xc0, 0x4f, 0xd4, 0x30, 0xc8}
-
- u1 := UUID{}
- err := u1.UnmarshalBinary(b1)
- if err != nil {
- t.Errorf("Error unmarshaling UUID: %s", err)
- }
-
- if !Equal(u, u1) {
- t.Errorf("UUIDs should be equal: %s and %s", u, u1)
- }
-
- b2 := []byte{}
- u2 := UUID{}
-
- err = u2.UnmarshalBinary(b2)
- if err == nil {
- t.Errorf("Should return error unmarshalling from empty byte slice, got %s", err)
- }
-}
-
-func TestFromString(t *testing.T) {
- u := UUID{0x6b, 0xa7, 0xb8, 0x10, 0x9d, 0xad, 0x11, 0xd1, 0x80, 0xb4, 0x00, 0xc0, 0x4f, 0xd4, 0x30, 0xc8}
-
- s1 := "6ba7b810-9dad-11d1-80b4-00c04fd430c8"
- s2 := "{6ba7b810-9dad-11d1-80b4-00c04fd430c8}"
- s3 := "urn:uuid:6ba7b810-9dad-11d1-80b4-00c04fd430c8"
-
- _, err := FromString("")
- if err == nil {
- t.Errorf("Should return error trying to parse empty string, got %s", err)
- }
-
- u1, err := FromString(s1)
- if err != nil {
- t.Errorf("Error parsing UUID from string: %s", err)
- }
-
- if !Equal(u, u1) {
- t.Errorf("UUIDs should be equal: %s and %s", u, u1)
- }
-
- u2, err := FromString(s2)
- if err != nil {
- t.Errorf("Error parsing UUID from string: %s", err)
- }
-
- if !Equal(u, u2) {
- t.Errorf("UUIDs should be equal: %s and %s", u, u2)
- }
-
- u3, err := FromString(s3)
- if err != nil {
- t.Errorf("Error parsing UUID from string: %s", err)
- }
-
- if !Equal(u, u3) {
- t.Errorf("UUIDs should be equal: %s and %s", u, u3)
- }
-}
-
-func TestFromStringOrNil(t *testing.T) {
- u := FromStringOrNil("")
- if u != Nil {
- t.Errorf("Should return Nil UUID on parse failure, got %s", u)
- }
-}
-
-func TestFromBytesOrNil(t *testing.T) {
- b := []byte{}
- u := FromBytesOrNil(b)
- if u != Nil {
- t.Errorf("Should return Nil UUID on parse failure, got %s", u)
- }
-}
-
-func TestMarshalText(t *testing.T) {
- u := UUID{0x6b, 0xa7, 0xb8, 0x10, 0x9d, 0xad, 0x11, 0xd1, 0x80, 0xb4, 0x00, 0xc0, 0x4f, 0xd4, 0x30, 0xc8}
- b1 := []byte("6ba7b810-9dad-11d1-80b4-00c04fd430c8")
-
- b2, err := u.MarshalText()
- if err != nil {
- t.Errorf("Error marshaling UUID: %s", err)
- }
-
- if !bytes.Equal(b1, b2) {
- t.Errorf("Marshaled UUID should be %s, got %s", b1, b2)
- }
-}
-
-func TestUnmarshalText(t *testing.T) {
- u := UUID{0x6b, 0xa7, 0xb8, 0x10, 0x9d, 0xad, 0x11, 0xd1, 0x80, 0xb4, 0x00, 0xc0, 0x4f, 0xd4, 0x30, 0xc8}
- b1 := []byte("6ba7b810-9dad-11d1-80b4-00c04fd430c8")
-
- u1 := UUID{}
- err := u1.UnmarshalText(b1)
- if err != nil {
- t.Errorf("Error unmarshaling UUID: %s", err)
- }
-
- if !Equal(u, u1) {
- t.Errorf("UUIDs should be equal: %s and %s", u, u1)
- }
-
- b2 := []byte("")
- u2 := UUID{}
-
- err = u2.UnmarshalText(b2)
- if err == nil {
- t.Errorf("Should return error trying to unmarshal from empty string")
- }
-}
-
-func TestValue(t *testing.T) {
- u, err := FromString("6ba7b810-9dad-11d1-80b4-00c04fd430c8")
- if err != nil {
- t.Errorf("Error parsing UUID from string: %s", err)
- }
-
- val, err := u.Value()
- if err != nil {
- t.Errorf("Error getting UUID value: %s", err)
- }
-
- if val != u.String() {
- t.Errorf("Wrong value returned, should be equal: %s and %s", val, u)
- }
-}
-
-func TestScanBinary(t *testing.T) {
- u := UUID{0x6b, 0xa7, 0xb8, 0x10, 0x9d, 0xad, 0x11, 0xd1, 0x80, 0xb4, 0x00, 0xc0, 0x4f, 0xd4, 0x30, 0xc8}
- b1 := []byte{0x6b, 0xa7, 0xb8, 0x10, 0x9d, 0xad, 0x11, 0xd1, 0x80, 0xb4, 0x00, 0xc0, 0x4f, 0xd4, 0x30, 0xc8}
-
- u1 := UUID{}
- err := u1.Scan(b1)
- if err != nil {
- t.Errorf("Error unmarshaling UUID: %s", err)
- }
-
- if !Equal(u, u1) {
- t.Errorf("UUIDs should be equal: %s and %s", u, u1)
- }
-
- b2 := []byte{}
- u2 := UUID{}
-
- err = u2.Scan(b2)
- if err == nil {
- t.Errorf("Should return error unmarshalling from empty byte slice, got %s", err)
- }
-}
-
-func TestScanString(t *testing.T) {
- u := UUID{0x6b, 0xa7, 0xb8, 0x10, 0x9d, 0xad, 0x11, 0xd1, 0x80, 0xb4, 0x00, 0xc0, 0x4f, 0xd4, 0x30, 0xc8}
- s1 := "6ba7b810-9dad-11d1-80b4-00c04fd430c8"
-
- u1 := UUID{}
- err := u1.Scan(s1)
- if err != nil {
- t.Errorf("Error unmarshaling UUID: %s", err)
- }
-
- if !Equal(u, u1) {
- t.Errorf("UUIDs should be equal: %s and %s", u, u1)
- }
-
- s2 := ""
- u2 := UUID{}
-
- err = u2.Scan(s2)
- if err == nil {
- t.Errorf("Should return error trying to unmarshal from empty string")
- }
-}
-
-func TestScanText(t *testing.T) {
- u := UUID{0x6b, 0xa7, 0xb8, 0x10, 0x9d, 0xad, 0x11, 0xd1, 0x80, 0xb4, 0x00, 0xc0, 0x4f, 0xd4, 0x30, 0xc8}
- b1 := []byte("6ba7b810-9dad-11d1-80b4-00c04fd430c8")
-
- u1 := UUID{}
- err := u1.Scan(b1)
- if err != nil {
- t.Errorf("Error unmarshaling UUID: %s", err)
- }
-
- if !Equal(u, u1) {
- t.Errorf("UUIDs should be equal: %s and %s", u, u1)
- }
-
- b2 := []byte("")
- u2 := UUID{}
-
- err = u2.Scan(b2)
- if err == nil {
- t.Errorf("Should return error trying to unmarshal from empty string")
- }
-}
-
-func TestScanUnsupported(t *testing.T) {
- u := UUID{}
-
- err := u.Scan(true)
- if err == nil {
- t.Errorf("Should return error trying to unmarshal from bool")
- }
-}
-
-func TestNewV1(t *testing.T) {
- u := NewV1()
-
- if u.Version() != 1 {
- t.Errorf("UUIDv1 generated with incorrect version: %d", u.Version())
- }
-
- if u.Variant() != VariantRFC4122 {
- t.Errorf("UUIDv1 generated with incorrect variant: %d", u.Variant())
- }
-
- u1 := NewV1()
- u2 := NewV1()
-
- if Equal(u1, u2) {
- t.Errorf("UUIDv1 generated two equal UUIDs: %s and %s", u1, u2)
- }
-
- oldFunc := epochFunc
- epochFunc = func() uint64 { return 0 }
-
- u3 := NewV1()
- u4 := NewV1()
-
- if Equal(u3, u4) {
- t.Errorf("UUIDv1 generated two equal UUIDs: %s and %s", u3, u4)
- }
-
- epochFunc = oldFunc
-}
-
-func TestNewV2(t *testing.T) {
- u1 := NewV2(DomainPerson)
-
- if u1.Version() != 2 {
- t.Errorf("UUIDv2 generated with incorrect version: %d", u1.Version())
- }
-
- if u1.Variant() != VariantRFC4122 {
- t.Errorf("UUIDv2 generated with incorrect variant: %d", u1.Variant())
- }
-
- u2 := NewV2(DomainGroup)
-
- if u2.Version() != 2 {
- t.Errorf("UUIDv2 generated with incorrect version: %d", u2.Version())
- }
-
- if u2.Variant() != VariantRFC4122 {
- t.Errorf("UUIDv2 generated with incorrect variant: %d", u2.Variant())
- }
-}
-
-func TestNewV3(t *testing.T) {
- u := NewV3(NamespaceDNS, "www.example.com")
-
- if u.Version() != 3 {
- t.Errorf("UUIDv3 generated with incorrect version: %d", u.Version())
- }
-
- if u.Variant() != VariantRFC4122 {
- t.Errorf("UUIDv3 generated with incorrect variant: %d", u.Variant())
- }
-
- if u.String() != "5df41881-3aed-3515-88a7-2f4a814cf09e" {
- t.Errorf("UUIDv3 generated incorrectly: %s", u.String())
- }
-
- u = NewV3(NamespaceDNS, "python.org")
-
- if u.String() != "6fa459ea-ee8a-3ca4-894e-db77e160355e" {
- t.Errorf("UUIDv3 generated incorrectly: %s", u.String())
- }
-
- u1 := NewV3(NamespaceDNS, "golang.org")
- u2 := NewV3(NamespaceDNS, "golang.org")
- if !Equal(u1, u2) {
- t.Errorf("UUIDv3 generated different UUIDs for same namespace and name: %s and %s", u1, u2)
- }
-
- u3 := NewV3(NamespaceDNS, "example.com")
- if Equal(u1, u3) {
- t.Errorf("UUIDv3 generated same UUIDs for different names in same namespace: %s and %s", u1, u2)
- }
-
- u4 := NewV3(NamespaceURL, "golang.org")
- if Equal(u1, u4) {
- t.Errorf("UUIDv3 generated same UUIDs for sane names in different namespaces: %s and %s", u1, u4)
- }
-}
-
-func TestNewV4(t *testing.T) {
- u := NewV4()
-
- if u.Version() != 4 {
- t.Errorf("UUIDv4 generated with incorrect version: %d", u.Version())
- }
-
- if u.Variant() != VariantRFC4122 {
- t.Errorf("UUIDv4 generated with incorrect variant: %d", u.Variant())
- }
-}
-
-func TestNewV5(t *testing.T) {
- u := NewV5(NamespaceDNS, "www.example.com")
-
- if u.Version() != 5 {
- t.Errorf("UUIDv5 generated with incorrect version: %d", u.Version())
- }
-
- if u.Variant() != VariantRFC4122 {
- t.Errorf("UUIDv5 generated with incorrect variant: %d", u.Variant())
- }
-
- u = NewV5(NamespaceDNS, "python.org")
-
- if u.String() != "886313e1-3b8a-5372-9b90-0c9aee199e5d" {
- t.Errorf("UUIDv5 generated incorrectly: %s", u.String())
- }
-
- u1 := NewV5(NamespaceDNS, "golang.org")
- u2 := NewV5(NamespaceDNS, "golang.org")
- if !Equal(u1, u2) {
- t.Errorf("UUIDv5 generated different UUIDs for same namespace and name: %s and %s", u1, u2)
- }
-
- u3 := NewV5(NamespaceDNS, "example.com")
- if Equal(u1, u3) {
- t.Errorf("UUIDv5 generated same UUIDs for different names in same namespace: %s and %s", u1, u2)
- }
-
- u4 := NewV5(NamespaceURL, "golang.org")
- if Equal(u1, u4) {
- t.Errorf("UUIDv3 generated same UUIDs for sane names in different namespaces: %s and %s", u1, u4)
- }
-}
diff --git a/vendor/github.com/vincent-petithory/dataurl/LICENSE b/vendor/github.com/vincent-petithory/dataurl/LICENSE
new file mode 100644
index 00000000..ae6cb62b
--- /dev/null
+++ b/vendor/github.com/vincent-petithory/dataurl/LICENSE
@@ -0,0 +1,20 @@
+The MIT License (MIT)
+
+Copyright (c) 2014 Vincent Petithory
+
+Permission is hereby granted, free of charge, to any person obtaining a copy of
+this software and associated documentation files (the "Software"), to deal in
+the Software without restriction, including without limitation the rights to
+use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of
+the Software, and to permit persons to whom the Software is furnished to do so,
+subject to the following conditions:
+
+The above copyright notice and this permission notice shall be included in all
+copies or substantial portions of the Software.
+
+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS
+FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR
+COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
+IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
+CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
diff --git a/vendor/github.com/vincent-petithory/dataurl/README.md b/vendor/github.com/vincent-petithory/dataurl/README.md
new file mode 100644
index 00000000..1ac59ad2
--- /dev/null
+++ b/vendor/github.com/vincent-petithory/dataurl/README.md
@@ -0,0 +1,81 @@
+# Data URL Schemes for Go [](https://app.wercker.com/project/bykey/6f9a2e144dfcc59e862c52459b452928) [](https://godoc.org/github.com/vincent-petithory/dataurl)
+
+This package parses and generates Data URL Schemes for the Go language, according to [RFC 2397](http://tools.ietf.org/html/rfc2397).
+
+Data URLs are small chunks of data commonly used in browsers to display inline data,
+typically like small images, or when you use the FileReader API of the browser.
+
+Common use-cases:
+
+ * generate a data URL out of a `string`, `[]byte`, `io.Reader` for inclusion in HTML templates,
+ * parse a data URL sent by a browser in a http.Handler, and do something with the data (save to disk, etc.)
+ * ...
+
+Install the package with:
+~~~
+go get github.com/vincent-petithory/dataurl
+~~~
+
+## Usage
+
+~~~ go
+package main
+
+import (
+ "github.com/vincent-petithory/dataurl"
+ "fmt"
+)
+
+func main() {
+ dataURL, err := dataurl.DecodeString(`data:text/plain;charset=utf-8;base64,aGV5YQ==`)
+ if err != nil {
+ fmt.Println(err)
+ return
+ }
+ fmt.Printf("content type: %s, data: %s\n", dataURL.MediaType.ContentType(), string(dataURL.Data))
+ // Output: content type: text/plain, data: heya
+}
+~~~
+
+From a `http.Handler`:
+
+~~~ go
+func handleDataURLUpload(w http.ResponseWriter, r *http.Request) {
+ dataURL, err := dataurl.Decode(r.Body)
+ defer r.Body.Close()
+ if err != nil {
+ http.Error(w, err.Error(), http.StatusBadRequest)
+ return
+ }
+ if dataURL.ContentType() == "image/png" {
+ ioutil.WriteFile("image.png", dataURL.Data, 0644)
+ } else {
+ http.Error(w, "not a png", http.StatusBadRequest)
+ }
+}
+~~~
+
+## Command
+
+For convenience, a `dataurl` command is provided to encode/decode dataurl streams.
+
+~~~
+dataurl - Encode or decode dataurl data and print to standard output
+
+Usage: dataurl [OPTION]... [FILE]
+
+ dataurl encodes or decodes FILE or standard input if FILE is - or omitted, and prints to standard output.
+ Unless -mimetype is used, when FILE is specified, dataurl will attempt to detect its mimetype using Go's mime.TypeByExtension (http://golang.org/pkg/mime/#TypeByExtension). If this fails or data is read from STDIN, the mimetype will default to application/octet-stream.
+
+Options:
+ -a=false: encode data using ascii instead of base64
+ -ascii=false: encode data using ascii instead of base64
+ -d=false: decode data instead of encoding
+ -decode=false: decode data instead of encoding
+ -m="": force the mimetype of the data to encode to this value
+ -mimetype="": force the mimetype of the data to encode to this value
+~~~
+
+## Contributing
+
+Feel free to file an issue/make a pull request if you find any bug, or want to suggest enhancements.
diff --git a/vendor/github.com/vincent-petithory/dataurl/cmd/dataurl/main.go b/vendor/github.com/vincent-petithory/dataurl/cmd/dataurl/main.go
new file mode 100644
index 00000000..cf764c94
--- /dev/null
+++ b/vendor/github.com/vincent-petithory/dataurl/cmd/dataurl/main.go
@@ -0,0 +1,142 @@
+package main
+
+import (
+ "flag"
+ "fmt"
+ "io"
+ "io/ioutil"
+ "log"
+ "mime"
+ "os"
+ "path"
+
+ "github.com/vincent-petithory/dataurl"
+)
+
+var (
+ performDecode bool
+ asciiEncoding bool
+ mimetype string
+)
+
+func init() {
+ const decodeUsage = "decode data instead of encoding"
+ flag.BoolVar(&performDecode, "decode", false, decodeUsage)
+ flag.BoolVar(&performDecode, "d", false, decodeUsage)
+
+ const mimetypeUsage = "force the mimetype of the data to encode to this value"
+ flag.StringVar(&mimetype, "mimetype", "", mimetypeUsage)
+ flag.StringVar(&mimetype, "m", "", mimetypeUsage)
+
+ const asciiUsage = "encode data using ascii instead of base64"
+ flag.BoolVar(&asciiEncoding, "ascii", false, asciiUsage)
+ flag.BoolVar(&asciiEncoding, "a", false, asciiUsage)
+
+ flag.Usage = func() {
+ fmt.Fprint(os.Stderr,
+ `dataurl - Encode or decode dataurl data and print to standard output
+
+Usage: dataurl [OPTION]... [FILE]
+
+ dataurl encodes or decodes FILE or standard input if FILE is - or omitted, and prints to standard output.
+ Unless -mimetype is used, when FILE is specified, dataurl will attempt to detect its mimetype using Go's mime.TypeByExtension (http://golang.org/pkg/mime/#TypeByExtension). If this fails or data is read from STDIN, the mimetype will default to application/octet-stream.
+
+Options:
+`)
+ flag.PrintDefaults()
+ }
+}
+
+func main() {
+ log.SetFlags(0)
+ flag.Parse()
+
+ var (
+ in io.Reader
+ out = os.Stdout
+ encoding = dataurl.EncodingBase64
+ detectedMimetype string
+ )
+ switch n := flag.NArg(); n {
+ case 0:
+ in = os.Stdin
+ case 1:
+ if flag.Arg(0) == "-" {
+ in = os.Stdin
+ return
+ }
+ if f, err := os.Open(flag.Arg(0)); err != nil {
+ log.Fatal(err)
+ } else {
+ in = f
+ defer f.Close()
+ }
+ ext := path.Ext(flag.Arg(0))
+ detectedMimetype = mime.TypeByExtension(ext)
+ }
+
+ switch {
+ case mimetype == "" && detectedMimetype == "":
+ mimetype = "application/octet-stream"
+ case mimetype == "" && detectedMimetype != "":
+ mimetype = detectedMimetype
+ }
+
+ if performDecode {
+ if err := decode(in, out); err != nil {
+ log.Fatal(err)
+ }
+ } else {
+ if asciiEncoding {
+ encoding = dataurl.EncodingASCII
+ }
+ if err := encode(in, out, encoding, mimetype); err != nil {
+ log.Fatal(err)
+ }
+ }
+}
+
+func decode(in io.Reader, out io.Writer) (err error) {
+ defer func() {
+ if e := recover(); e != nil {
+ err = e.(error)
+ }
+ }()
+
+ du, err := dataurl.Decode(in)
+ if err != nil {
+ return
+ }
+
+ _, err = out.Write(du.Data)
+ if err != nil {
+ return
+ }
+ return
+}
+
+func encode(in io.Reader, out io.Writer, encoding string, mediatype string) (err error) {
+ defer func() {
+ if e := recover(); e != nil {
+ var ok bool
+ err, ok = e.(error)
+ if !ok {
+ err = fmt.Errorf("%v", e)
+ }
+ return
+ }
+ }()
+ b, err := ioutil.ReadAll(in)
+ if err != nil {
+ return
+ }
+
+ du := dataurl.New(b, mediatype)
+ du.Encoding = encoding
+
+ _, err = du.WriteTo(out)
+ if err != nil {
+ return
+ }
+ return
+}
diff --git a/vendor/github.com/vincent-petithory/dataurl/dataurl.go b/vendor/github.com/vincent-petithory/dataurl/dataurl.go
new file mode 100644
index 00000000..bfd07654
--- /dev/null
+++ b/vendor/github.com/vincent-petithory/dataurl/dataurl.go
@@ -0,0 +1,280 @@
+package dataurl
+
+import (
+ "bytes"
+ "encoding/base64"
+ "errors"
+ "fmt"
+ "io"
+ "io/ioutil"
+ "net/http"
+ "strconv"
+ "strings"
+)
+
+const (
+ // EncodingBase64 is base64 encoding for the data url
+ EncodingBase64 = "base64"
+ // EncodingASCII is ascii encoding for the data url
+ EncodingASCII = "ascii"
+)
+
+func defaultMediaType() MediaType {
+ return MediaType{
+ "text",
+ "plain",
+ map[string]string{"charset": "US-ASCII"},
+ }
+}
+
+// MediaType is the combination of a media type, a media subtype
+// and optional parameters.
+type MediaType struct {
+ Type string
+ Subtype string
+ Params map[string]string
+}
+
+// ContentType returns the content type of the dataurl's data, in the form type/subtype.
+func (mt *MediaType) ContentType() string {
+ return fmt.Sprintf("%s/%s", mt.Type, mt.Subtype)
+}
+
+// String implements the Stringer interface.
+//
+// Params values are escaped with the Escape function, rather than in a quoted string.
+func (mt *MediaType) String() string {
+ var buf bytes.Buffer
+ for k, v := range mt.Params {
+ fmt.Fprintf(&buf, ";%s=%s", k, EscapeString(v))
+ }
+ return mt.ContentType() + (&buf).String()
+}
+
+// DataURL is the combination of a MediaType describing the type of its Data.
+type DataURL struct {
+ MediaType
+ Encoding string
+ Data []byte
+}
+
+// New returns a new DataURL initialized with data and
+// a MediaType parsed from mediatype and paramPairs.
+// mediatype must be of the form "type/subtype" or it will panic.
+// paramPairs must have an even number of elements or it will panic.
+// For more complex DataURL, initialize a DataURL struct.
+// The DataURL is initialized with base64 encoding.
+func New(data []byte, mediatype string, paramPairs ...string) *DataURL {
+ parts := strings.Split(mediatype, "/")
+ if len(parts) != 2 {
+ panic("dataurl: invalid mediatype")
+ }
+
+ nParams := len(paramPairs)
+ if nParams%2 != 0 {
+ panic("dataurl: requires an even number of param pairs")
+ }
+ params := make(map[string]string)
+ for i := 0; i < nParams; i += 2 {
+ params[paramPairs[i]] = paramPairs[i+1]
+ }
+
+ mt := MediaType{
+ parts[0],
+ parts[1],
+ params,
+ }
+ return &DataURL{
+ MediaType: mt,
+ Encoding: EncodingBase64,
+ Data: data,
+ }
+}
+
+// String implements the Stringer interface.
+//
+// Note: it doesn't guarantee the returned string is equal to
+// the initial source string that was used to create this DataURL.
+// The reasons for that are:
+// * Insertion of default values for MediaType that were maybe not in the initial string,
+// * Various ways to encode the MediaType parameters (quoted string or url encoded string, the latter is used),
+func (du *DataURL) String() string {
+ var buf bytes.Buffer
+ du.WriteTo(&buf)
+ return (&buf).String()
+}
+
+// WriteTo implements the WriterTo interface.
+// See the note about String().
+func (du *DataURL) WriteTo(w io.Writer) (n int64, err error) {
+ var ni int
+ ni, _ = fmt.Fprint(w, "data:")
+ n += int64(ni)
+
+ ni, _ = fmt.Fprint(w, du.MediaType.String())
+ n += int64(ni)
+
+ if du.Encoding == EncodingBase64 {
+ ni, _ = fmt.Fprint(w, ";base64")
+ n += int64(ni)
+ }
+
+ ni, _ = fmt.Fprint(w, ",")
+ n += int64(ni)
+
+ if du.Encoding == EncodingBase64 {
+ encoder := base64.NewEncoder(base64.StdEncoding, w)
+ ni, err = encoder.Write(du.Data)
+ if err != nil {
+ return
+ }
+ encoder.Close()
+ } else if du.Encoding == EncodingASCII {
+ ni, _ = fmt.Fprint(w, Escape(du.Data))
+ n += int64(ni)
+ } else {
+ err = fmt.Errorf("dataurl: invalid encoding %s", du.Encoding)
+ return
+ }
+
+ return
+}
+
+// UnmarshalText decodes a Data URL string and sets it to *du
+func (du *DataURL) UnmarshalText(text []byte) error {
+ decoded, err := DecodeString(string(text))
+ if err != nil {
+ return err
+ }
+ *du = *decoded
+ return nil
+}
+
+// MarshalText writes du as a Data URL
+func (du *DataURL) MarshalText() ([]byte, error) {
+ buf := bytes.NewBuffer(nil)
+ if _, err := du.WriteTo(buf); err != nil {
+ return nil, err
+ }
+ return buf.Bytes(), nil
+}
+
+type encodedDataReader func(string) ([]byte, error)
+
+var asciiDataReader encodedDataReader = func(s string) ([]byte, error) {
+ us, err := Unescape(s)
+ if err != nil {
+ return nil, err
+ }
+ return []byte(us), nil
+}
+
+var base64DataReader encodedDataReader = func(s string) ([]byte, error) {
+ data, err := base64.StdEncoding.DecodeString(s)
+ if err != nil {
+ return nil, err
+ }
+ return []byte(data), nil
+}
+
+type parser struct {
+ du *DataURL
+ l *lexer
+ currentAttr string
+ unquoteParamVal bool
+ encodedDataReaderFn encodedDataReader
+}
+
+func (p *parser) parse() error {
+ for item := range p.l.items {
+ switch item.t {
+ case itemError:
+ return errors.New(item.String())
+ case itemMediaType:
+ p.du.MediaType.Type = item.val
+ // Should we clear the default
+ // "charset" parameter at this point?
+ delete(p.du.MediaType.Params, "charset")
+ case itemMediaSubType:
+ p.du.MediaType.Subtype = item.val
+ case itemParamAttr:
+ p.currentAttr = item.val
+ case itemLeftStringQuote:
+ p.unquoteParamVal = true
+ case itemParamVal:
+ val := item.val
+ if p.unquoteParamVal {
+ p.unquoteParamVal = false
+ us, err := strconv.Unquote("\"" + val + "\"")
+ if err != nil {
+ return err
+ }
+ val = us
+ } else {
+ us, err := UnescapeToString(val)
+ if err != nil {
+ return err
+ }
+ val = us
+ }
+ p.du.MediaType.Params[p.currentAttr] = val
+ case itemBase64Enc:
+ p.du.Encoding = EncodingBase64
+ p.encodedDataReaderFn = base64DataReader
+ case itemDataComma:
+ if p.encodedDataReaderFn == nil {
+ p.encodedDataReaderFn = asciiDataReader
+ }
+ case itemData:
+ reader, err := p.encodedDataReaderFn(item.val)
+ if err != nil {
+ return err
+ }
+ p.du.Data = reader
+ case itemEOF:
+ if p.du.Data == nil {
+ p.du.Data = []byte("")
+ }
+ return nil
+ }
+ }
+ panic("EOF not found")
+}
+
+// DecodeString decodes a Data URL scheme string.
+func DecodeString(s string) (*DataURL, error) {
+ du := &DataURL{
+ MediaType: defaultMediaType(),
+ Encoding: EncodingASCII,
+ }
+
+ parser := &parser{
+ du: du,
+ l: lex(s),
+ }
+ if err := parser.parse(); err != nil {
+ return nil, err
+ }
+ return du, nil
+}
+
+// Decode decodes a Data URL scheme from a io.Reader.
+func Decode(r io.Reader) (*DataURL, error) {
+ data, err := ioutil.ReadAll(r)
+ if err != nil {
+ return nil, err
+ }
+ return DecodeString(string(data))
+}
+
+// EncodeBytes encodes the data bytes into a Data URL string, using base 64 encoding.
+//
+// The media type of data is detected using http.DetectContentType.
+func EncodeBytes(data []byte) string {
+ mt := http.DetectContentType(data)
+ // http.DetectContentType may add spurious spaces between ; and a parameter.
+ // The canonical way is to not have them.
+ cleanedMt := strings.Replace(mt, "; ", ";", -1)
+
+ return New(data, cleanedMt).String()
+}
diff --git a/vendor/github.com/vincent-petithory/dataurl/dataurl_test.go b/vendor/github.com/vincent-petithory/dataurl/dataurl_test.go
new file mode 100644
index 00000000..efff4f34
--- /dev/null
+++ b/vendor/github.com/vincent-petithory/dataurl/dataurl_test.go
@@ -0,0 +1,587 @@
+package dataurl
+
+import (
+ "bytes"
+ "encoding/base64"
+ "fmt"
+ "net/http"
+ "net/http/httptest"
+ "reflect"
+ "regexp"
+ "strings"
+ "testing"
+)
+
+type dataURLTest struct {
+ InputRawDataURL string
+ ExpectedItems []item
+ ExpectedDataURL DataURL
+}
+
+func genTestTable() []dataURLTest {
+ return []dataURLTest{
+ dataURLTest{
+ `data:;base64,aGV5YQ==`,
+ []item{
+ item{itemDataPrefix, dataPrefix},
+ item{itemParamSemicolon, ";"},
+ item{itemBase64Enc, "base64"},
+ item{itemDataComma, ","},
+ item{itemData, "aGV5YQ=="},
+ item{itemEOF, ""},
+ },
+ DataURL{
+ defaultMediaType(),
+ EncodingBase64,
+ []byte("heya"),
+ },
+ },
+ dataURLTest{
+ `data:text/plain;base64,aGV5YQ==`,
+ []item{
+ item{itemDataPrefix, dataPrefix},
+ item{itemMediaType, "text"},
+ item{itemMediaSep, "/"},
+ item{itemMediaSubType, "plain"},
+ item{itemParamSemicolon, ";"},
+ item{itemBase64Enc, "base64"},
+ item{itemDataComma, ","},
+ item{itemData, "aGV5YQ=="},
+ item{itemEOF, ""},
+ },
+ DataURL{
+ MediaType{
+ "text",
+ "plain",
+ map[string]string{},
+ },
+ EncodingBase64,
+ []byte("heya"),
+ },
+ },
+ dataURLTest{
+ `data:text/plain;charset=utf-8;base64,aGV5YQ==`,
+ []item{
+ item{itemDataPrefix, dataPrefix},
+ item{itemMediaType, "text"},
+ item{itemMediaSep, "/"},
+ item{itemMediaSubType, "plain"},
+ item{itemParamSemicolon, ";"},
+ item{itemParamAttr, "charset"},
+ item{itemParamEqual, "="},
+ item{itemParamVal, "utf-8"},
+ item{itemParamSemicolon, ";"},
+ item{itemBase64Enc, "base64"},
+ item{itemDataComma, ","},
+ item{itemData, "aGV5YQ=="},
+ item{itemEOF, ""},
+ },
+ DataURL{
+ MediaType{
+ "text",
+ "plain",
+ map[string]string{
+ "charset": "utf-8",
+ },
+ },
+ EncodingBase64,
+ []byte("heya"),
+ },
+ },
+ dataURLTest{
+ `data:text/plain;charset=utf-8;foo=bar;base64,aGV5YQ==`,
+ []item{
+ item{itemDataPrefix, dataPrefix},
+ item{itemMediaType, "text"},
+ item{itemMediaSep, "/"},
+ item{itemMediaSubType, "plain"},
+ item{itemParamSemicolon, ";"},
+ item{itemParamAttr, "charset"},
+ item{itemParamEqual, "="},
+ item{itemParamVal, "utf-8"},
+ item{itemParamSemicolon, ";"},
+ item{itemParamAttr, "foo"},
+ item{itemParamEqual, "="},
+ item{itemParamVal, "bar"},
+ item{itemParamSemicolon, ";"},
+ item{itemBase64Enc, "base64"},
+ item{itemDataComma, ","},
+ item{itemData, "aGV5YQ=="},
+ item{itemEOF, ""},
+ },
+ DataURL{
+ MediaType{
+ "text",
+ "plain",
+ map[string]string{
+ "charset": "utf-8",
+ "foo": "bar",
+ },
+ },
+ EncodingBase64,
+ []byte("heya"),
+ },
+ },
+ dataURLTest{
+ `data:application/json;charset=utf-8;foo="b\"<@>\"r";style=unformatted%20json;base64,eyJtc2ciOiAiaGV5YSJ9`,
+ []item{
+ item{itemDataPrefix, dataPrefix},
+ item{itemMediaType, "application"},
+ item{itemMediaSep, "/"},
+ item{itemMediaSubType, "json"},
+ item{itemParamSemicolon, ";"},
+ item{itemParamAttr, "charset"},
+ item{itemParamEqual, "="},
+ item{itemParamVal, "utf-8"},
+ item{itemParamSemicolon, ";"},
+ item{itemParamAttr, "foo"},
+ item{itemParamEqual, "="},
+ item{itemLeftStringQuote, "\""},
+ item{itemParamVal, `b\"<@>\"r`},
+ item{itemRightStringQuote, "\""},
+ item{itemParamSemicolon, ";"},
+ item{itemParamAttr, "style"},
+ item{itemParamEqual, "="},
+ item{itemParamVal, "unformatted%20json"},
+ item{itemParamSemicolon, ";"},
+ item{itemBase64Enc, "base64"},
+ item{itemDataComma, ","},
+ item{itemData, "eyJtc2ciOiAiaGV5YSJ9"},
+ item{itemEOF, ""},
+ },
+ DataURL{
+ MediaType{
+ "application",
+ "json",
+ map[string]string{
+ "charset": "utf-8",
+ "foo": `b"<@>"r`,
+ "style": "unformatted json",
+ },
+ },
+ EncodingBase64,
+ []byte(`{"msg": "heya"}`),
+ },
+ },
+ dataURLTest{
+ `data:xxx;base64,aGV5YQ==`,
+ []item{
+ item{itemDataPrefix, dataPrefix},
+ item{itemError, "invalid character for media type"},
+ },
+ DataURL{},
+ },
+ dataURLTest{
+ `data:,`,
+ []item{
+ item{itemDataPrefix, dataPrefix},
+ item{itemDataComma, ","},
+ item{itemEOF, ""},
+ },
+ DataURL{
+ defaultMediaType(),
+ EncodingASCII,
+ []byte(""),
+ },
+ },
+ dataURLTest{
+ `data:,A%20brief%20note`,
+ []item{
+ item{itemDataPrefix, dataPrefix},
+ item{itemDataComma, ","},
+ item{itemData, "A%20brief%20note"},
+ item{itemEOF, ""},
+ },
+ DataURL{
+ defaultMediaType(),
+ EncodingASCII,
+ []byte("A brief note"),
+ },
+ },
+ dataURLTest{
+ `data:image/svg+xml-im.a.fake;base64,cGllLXN0b2NrX1RoaXJ0eQ==`,
+ []item{
+ item{itemDataPrefix, dataPrefix},
+ item{itemMediaType, "image"},
+ item{itemMediaSep, "/"},
+ item{itemMediaSubType, "svg+xml-im.a.fake"},
+ item{itemParamSemicolon, ";"},
+ item{itemBase64Enc, "base64"},
+ item{itemDataComma, ","},
+ item{itemData, "cGllLXN0b2NrX1RoaXJ0eQ=="},
+ item{itemEOF, ""},
+ },
+ DataURL{
+ MediaType{
+ "image",
+ "svg+xml-im.a.fake",
+ map[string]string{},
+ },
+ EncodingBase64,
+ []byte("pie-stock_Thirty"),
+ },
+ },
+ }
+}
+
+func expectItems(expected, actual []item) bool {
+ if len(expected) != len(actual) {
+ return false
+ }
+ for i := range expected {
+ if expected[i].t != actual[i].t {
+ return false
+ }
+ if expected[i].val != actual[i].val {
+ return false
+ }
+ }
+ return true
+}
+
+func equal(du1, du2 *DataURL) (bool, error) {
+ if !reflect.DeepEqual(du1.MediaType, du2.MediaType) {
+ return false, nil
+ }
+ if du1.Encoding != du2.Encoding {
+ return false, nil
+ }
+
+ if du1.Data == nil || du2.Data == nil {
+ return false, fmt.Errorf("nil Data")
+ }
+
+ if !bytes.Equal(du1.Data, du2.Data) {
+ return false, nil
+ }
+ return true, nil
+}
+
+func TestLexDataURLs(t *testing.T) {
+ for _, test := range genTestTable() {
+ l := lex(test.InputRawDataURL)
+ var items []item
+ for item := range l.items {
+ items = append(items, item)
+ }
+ if !expectItems(test.ExpectedItems, items) {
+ t.Errorf("Expected %v, got %v", test.ExpectedItems, items)
+ }
+ }
+}
+
+func testDataURLs(t *testing.T, factory func(string) (*DataURL, error)) {
+ for _, test := range genTestTable() {
+ var expectedItemError string
+ for _, item := range test.ExpectedItems {
+ if item.t == itemError {
+ expectedItemError = item.String()
+ break
+ }
+ }
+ dataURL, err := factory(test.InputRawDataURL)
+ if expectedItemError == "" && err != nil {
+ t.Error(err)
+ continue
+ } else if expectedItemError != "" && err == nil {
+ t.Errorf("Expected error \"%s\", got nil", expectedItemError)
+ continue
+ } else if expectedItemError != "" && err != nil {
+ if err.Error() != expectedItemError {
+ t.Errorf("Expected error \"%s\", got \"%s\"", expectedItemError, err.Error())
+ }
+ continue
+ }
+
+ if ok, err := equal(dataURL, &test.ExpectedDataURL); err != nil {
+ t.Error(err)
+ } else if !ok {
+ t.Errorf("Expected %v, got %v", test.ExpectedDataURL, *dataURL)
+ }
+ }
+}
+
+func TestDataURLsWithDecode(t *testing.T) {
+ testDataURLs(t, func(s string) (*DataURL, error) {
+ return Decode(strings.NewReader(s))
+ })
+}
+
+func TestDataURLsWithDecodeString(t *testing.T) {
+ testDataURLs(t, func(s string) (*DataURL, error) {
+ return DecodeString(s)
+ })
+}
+
+func TestDataURLsWithUnmarshalText(t *testing.T) {
+ testDataURLs(t, func(s string) (*DataURL, error) {
+ d := &DataURL{}
+ err := d.UnmarshalText([]byte(s))
+ return d, err
+ })
+}
+
+func TestRoundTrip(t *testing.T) {
+ tests := []struct {
+ s string
+ roundTripOk bool
+ }{
+ {`data:text/plain;charset=utf-8;foo=bar;base64,aGV5YQ==`, true},
+ {`data:;charset=utf-8;foo=bar;base64,aGV5YQ==`, false},
+ {`data:text/plain;charset=utf-8;foo="bar";base64,aGV5YQ==`, false},
+ {`data:text/plain;charset=utf-8;foo="bar",A%20brief%20note`, false},
+ {`data:text/plain;charset=utf-8;foo=bar,A%20brief%20note`, true},
+ }
+ for _, test := range tests {
+ dataURL, err := DecodeString(test.s)
+ if err != nil {
+ t.Error(err)
+ continue
+ }
+ dus := dataURL.String()
+ if test.roundTripOk && dus != test.s {
+ t.Errorf("Expected %s, got %s", test.s, dus)
+ } else if !test.roundTripOk && dus == test.s {
+ t.Errorf("Found %s, expected something else", test.s)
+ }
+
+ txt, err := dataURL.MarshalText()
+ if err != nil {
+ t.Error(err)
+ continue
+ }
+ if test.roundTripOk && string(txt) != test.s {
+ t.Errorf("MarshalText roundtrip: got '%s', want '%s'", txt, test.s)
+ } else if !test.roundTripOk && string(txt) == test.s {
+ t.Errorf("MarshalText roundtrip: got '%s', want something else", txt)
+ }
+ }
+}
+
+func TestNew(t *testing.T) {
+ tests := []struct {
+ Data []byte
+ MediaType string
+ ParamPairs []string
+ WillPanic bool
+ ExpectedDataURL *DataURL
+ }{
+ {
+ []byte(`{"msg": "heya"}`),
+ "application/json",
+ []string{},
+ false,
+ &DataURL{
+ MediaType{
+ "application",
+ "json",
+ map[string]string{},
+ },
+ EncodingBase64,
+ []byte(`{"msg": "heya"}`),
+ },
+ },
+ {
+ []byte(``),
+ "application//json",
+ []string{},
+ true,
+ nil,
+ },
+ {
+ []byte(``),
+ "",
+ []string{},
+ true,
+ nil,
+ },
+ {
+ []byte(`{"msg": "heya"}`),
+ "text/plain",
+ []string{"charset", "utf-8"},
+ false,
+ &DataURL{
+ MediaType{
+ "text",
+ "plain",
+ map[string]string{
+ "charset": "utf-8",
+ },
+ },
+ EncodingBase64,
+ []byte(`{"msg": "heya"}`),
+ },
+ },
+ {
+ []byte(`{"msg": "heya"}`),
+ "text/plain",
+ []string{"charset", "utf-8", "name"},
+ true,
+ nil,
+ },
+ }
+ for _, test := range tests {
+ var dataURL *DataURL
+ func() {
+ defer func() {
+ if test.WillPanic {
+ if e := recover(); e == nil {
+ t.Error("Expected panic didn't happen")
+ }
+ } else {
+ if e := recover(); e != nil {
+ t.Errorf("Unexpected panic: %v", e)
+ }
+ }
+ }()
+ dataURL = New(test.Data, test.MediaType, test.ParamPairs...)
+ }()
+ if test.WillPanic {
+ if dataURL != nil {
+ t.Error("Expected nil DataURL")
+ }
+ } else {
+ if ok, err := equal(dataURL, test.ExpectedDataURL); err != nil {
+ t.Error(err)
+ } else if !ok {
+ t.Errorf("Expected %v, got %v", test.ExpectedDataURL, *dataURL)
+ }
+ }
+ }
+}
+
+var golangFavicon = strings.Replace(`AAABAAEAEBAAAAEAIABoBAAAFgAAACgAAAAQAAAAIAAAAAEAIAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAD///8AVE44//7hdv/+4Xb//uF2//7hdv/+4Xb//uF2//7hdv/+4Xb//uF2//7hdv/+4Xb/
+/uF2/1ROOP////8A////AFROOP/+4Xb//uF2//7hdv/+4Xb//uF2//7hdv/+4Xb//uF2//7hdv/+
+4Xb//uF2//7hdv9UTjj/////AP///wBUTjj//uF2//7hdv/+4Xb//uF2//7hdv/+4Xb//uF2//7h
+dv/+4Xb//uF2//7hdv/+4Xb/VE44/////wD///8AVE44//7hdv/+4Xb//uF2//7hdv/+4Xb//uF2
+//7hdv/+4Xb//uF2//7hdv/+4Xb//uF2/1ROOP////8A////AFROOP/+4Xb//uF2//7hdv/+4Xb/
+/uF2//7hdv/+4Xb//uF2//7hdv/+4Xb//uF2//7hdv9UTjj/////AP///wBUTjj//uF2//7hdv/+
+4Xb//uF2//7hdv/+4Xb//uF2//7hdv/+4Xb//uF2//7hdv/+4Xb/VE44/////wD///8AVE44//7h
+dv/+4Xb//uF2//7hdv/+4Xb/z7t5/8Kyev/+4Xb//993///dd///3Xf//uF2/1ROOP////8A////
+AFROOP/+4Xb//uF2//7hdv//4Hn/dIzD//v8///7/P//dIzD//7hdv//3Xf//913//7hdv9UTjj/
+////AP///wBUTjj//uF2///fd//+4Xb//uF2/6ajif90jMP/dIzD/46Zpv/+4Xb//+F1///feP/+
+4Xb/VE44/////wD///8AVE44//7hdv/z1XT////////////Is3L/HyAj/x8gI//Is3L/////////
+///z1XT//uF2/1ROOP////8A19nd/1ROOP/+4Xb/5+HS//v+//8RExf/Liwn//7hdv/+4Xb/5+HS
+//v8//8RExf/Liwn//7hdv9UTjj/19nd/1ROOP94aDT/yKdO/+fh0v//////ERMX/y4sJ//+4Xb/
+/uF2/+fh0v//////ERMX/y4sJ//Ip07/dWU3/1ROOP9UTjj/yKdO/6qSSP/Is3L/9fb7//f6///I
+s3L//uF2//7hdv/Is3L////////////Is3L/qpJI/8inTv9UTjj/19nd/1ROOP97c07/qpJI/8in
+Tv/Ip07//uF2//7hdv/+4Xb//uF2/8zBlv/Kv4//pZJU/3tzTv9UTjj/19nd/////wD///8A4eLl
+/6CcjP97c07/e3NO/1dOMf9BOiX/TkUn/2VXLf97c07/e3NO/6CcjP/h4uX/////AP///wD///8A
+////AP///wD///8A////AP///wDq6/H/3N/j/9fZ3f/q6/H/////AP///wD///8A////AP///wD/
+//8AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAA==`, "\n", "", -1)
+
+func TestEncodeBytes(t *testing.T) {
+ mustDecode := func(s string) []byte {
+ data, err := base64.StdEncoding.DecodeString(s)
+ if err != nil {
+ panic(err)
+ }
+ return data
+ }
+ tests := []struct {
+ Data []byte
+ ExpectedString string
+ }{
+ {
+ []byte(`A brief note`),
+ "data:text/plain;charset=utf-8;base64,QSBicmllZiBub3Rl",
+ },
+ {
+ []byte{0xA, 0xFF, 0x99, 0x34, 0x56, 0x34, 0x00},
+ `data:application/octet-stream;base64,Cv+ZNFY0AA==`,
+ },
+ {
+ mustDecode(golangFavicon),
+ `data:image/vnd.microsoft.icon;base64,` + golangFavicon,
+ },
+ }
+ for _, test := range tests {
+ str := EncodeBytes(test.Data)
+ if str != test.ExpectedString {
+ t.Errorf("Expected %s, got %s", test.ExpectedString, str)
+ }
+ }
+}
+
+func BenchmarkLex(b *testing.B) {
+ for i := 0; i < b.N; i++ {
+ for _, test := range genTestTable() {
+ l := lex(test.InputRawDataURL)
+ for _ = range l.items {
+ }
+ }
+ }
+}
+
+const rep = `^data:(?P\w+/[\w\+\-\.]+)?(?P(?:;[\w\-]+="?[\w\-\\<>@,";:%]*"?)+)?(?P;base64)?,(?P.*)$`
+
+func TestRegexp(t *testing.T) {
+ re, err := regexp.Compile(rep)
+ if err != nil {
+ t.Fatal(err)
+ }
+ for _, test := range genTestTable() {
+ shouldMatch := true
+ for _, item := range test.ExpectedItems {
+ if item.t == itemError {
+ shouldMatch = false
+ break
+ }
+ }
+ // just test it matches, do not parse
+ if re.MatchString(test.InputRawDataURL) && !shouldMatch {
+ t.Error("doesn't match", test.InputRawDataURL)
+ } else if !re.MatchString(test.InputRawDataURL) && shouldMatch {
+ t.Error("match", test.InputRawDataURL)
+ }
+ }
+}
+
+func BenchmarkRegexp(b *testing.B) {
+ re, err := regexp.Compile(rep)
+ if err != nil {
+ b.Fatal(err)
+ }
+ for i := 0; i < b.N; i++ {
+ for _, test := range genTestTable() {
+ _ = re.FindStringSubmatch(test.InputRawDataURL)
+ }
+ }
+}
+
+func ExampleDecodeString() {
+ dataURL, err := DecodeString(`data:text/plain;charset=utf-8;base64,aGV5YQ==`)
+ if err != nil {
+ fmt.Println(err)
+ return
+ }
+ fmt.Printf("%s, %s", dataURL.MediaType.ContentType(), string(dataURL.Data))
+ // Output: text/plain, heya
+}
+
+func ExampleDecode() {
+ r, err := http.NewRequest(
+ "POST", "/",
+ strings.NewReader(`data:image/vnd.microsoft.icon;name=golang%20favicon;base64,`+golangFavicon),
+ )
+ if err != nil {
+ fmt.Println(err)
+ return
+ }
+
+ var dataURL *DataURL
+ h := func(w http.ResponseWriter, r *http.Request) {
+ var err error
+ dataURL, err = Decode(r.Body)
+ defer r.Body.Close()
+ if err != nil {
+ fmt.Println(err)
+ }
+ }
+ w := httptest.NewRecorder()
+ h(w, r)
+ fmt.Printf("%s: %s", dataURL.Params["name"], dataURL.ContentType())
+ // Output: golang favicon: image/vnd.microsoft.icon
+}
diff --git a/vendor/github.com/vincent-petithory/dataurl/doc.go b/vendor/github.com/vincent-petithory/dataurl/doc.go
new file mode 100644
index 00000000..56461d04
--- /dev/null
+++ b/vendor/github.com/vincent-petithory/dataurl/doc.go
@@ -0,0 +1,28 @@
+/*
+Package dataurl parses Data URL Schemes
+according to RFC 2397
+(http://tools.ietf.org/html/rfc2397).
+
+Data URLs are small chunks of data commonly used in browsers to display inline data,
+typically like small images, or when you use the FileReader API of the browser.
+
+A dataurl looks like:
+
+ data:text/plain;charset=utf-8,A%20brief%20note
+
+Or, with base64 encoding:
+
+ data:image/vnd.microsoft.icon;name=golang%20favicon;base64,AAABAAEAEBAAAAEAIABoBAAAFgAAACgAAAAQAAAAIAAAAAEAIAAAAAAAAAAAAAAAAAAAAAAAAAAA
+ AAAAAAD///8AVE44//7hdv/+4Xb//uF2//7hdv/+4Xb//uF2//7hdv/+4Xb//uF2//7hdv/+4Xb/
+ /uF2/1ROOP////8A////AFROOP/+4Xb//uF2//7hdv/+4Xb//uF2//7hdv/+4Xb//uF2//7hdv/+
+ ...
+ /6CcjP97c07/e3NO/1dOMf9BOiX/TkUn/2VXLf97c07/e3NO/6CcjP/h4uX/////AP///wD///8A
+ ////AP///wD///8A////AP///wDq6/H/3N/j/9fZ3f/q6/H/////AP///wD///8A////AP///wD/
+ //8AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+ AAAAAAAAAAAAAA==
+
+Common functions are Decode and DecodeString to obtain a DataURL,
+and DataURL.String() and DataURL.WriteTo to generate a Data URL string.
+
+*/
+package dataurl
diff --git a/vendor/github.com/vincent-petithory/dataurl/lex.go b/vendor/github.com/vincent-petithory/dataurl/lex.go
new file mode 100644
index 00000000..1a8717f5
--- /dev/null
+++ b/vendor/github.com/vincent-petithory/dataurl/lex.go
@@ -0,0 +1,521 @@
+package dataurl
+
+import (
+ "fmt"
+ "strings"
+ "unicode"
+ "unicode/utf8"
+)
+
+type item struct {
+ t itemType
+ val string
+}
+
+func (i item) String() string {
+ switch i.t {
+ case itemEOF:
+ return "EOF"
+ case itemError:
+ return i.val
+ }
+ if len(i.val) > 10 {
+ return fmt.Sprintf("%.10q...", i.val)
+ }
+ return fmt.Sprintf("%q", i.val)
+}
+
+type itemType int
+
+const (
+ itemError itemType = iota
+ itemEOF
+
+ itemDataPrefix
+
+ itemMediaType
+ itemMediaSep
+ itemMediaSubType
+ itemParamSemicolon
+ itemParamAttr
+ itemParamEqual
+ itemLeftStringQuote
+ itemRightStringQuote
+ itemParamVal
+
+ itemBase64Enc
+
+ itemDataComma
+ itemData
+)
+
+const eof rune = -1
+
+func isTokenRune(r rune) bool {
+ return r <= unicode.MaxASCII &&
+ !unicode.IsControl(r) &&
+ !unicode.IsSpace(r) &&
+ !isTSpecialRune(r)
+}
+
+func isTSpecialRune(r rune) bool {
+ return r == '(' ||
+ r == ')' ||
+ r == '<' ||
+ r == '>' ||
+ r == '@' ||
+ r == ',' ||
+ r == ';' ||
+ r == ':' ||
+ r == '\\' ||
+ r == '"' ||
+ r == '/' ||
+ r == '[' ||
+ r == ']' ||
+ r == '?' ||
+ r == '='
+}
+
+// See http://tools.ietf.org/html/rfc2045
+// This doesn't include extension-token case
+// as it's handled separatly
+func isDiscreteType(s string) bool {
+ if strings.HasPrefix(s, "text") ||
+ strings.HasPrefix(s, "image") ||
+ strings.HasPrefix(s, "audio") ||
+ strings.HasPrefix(s, "video") ||
+ strings.HasPrefix(s, "application") {
+ return true
+ }
+ return false
+}
+
+// See http://tools.ietf.org/html/rfc2045
+// This doesn't include extension-token case
+// as it's handled separatly
+func isCompositeType(s string) bool {
+ if strings.HasPrefix(s, "message") ||
+ strings.HasPrefix(s, "multipart") {
+ return true
+ }
+ return false
+}
+
+func isURLCharRune(r rune) bool {
+ // We're a bit permissive here,
+ // by not including '%' in delims
+ // This is okay, since url unescaping will validate
+ // that later in the parser.
+ return r <= unicode.MaxASCII &&
+ !(r >= 0x00 && r <= 0x1F) && r != 0x7F && /* control */
+ // delims
+ r != ' ' &&
+ r != '<' &&
+ r != '>' &&
+ r != '#' &&
+ r != '"' &&
+ // unwise
+ r != '{' &&
+ r != '}' &&
+ r != '|' &&
+ r != '\\' &&
+ r != '^' &&
+ r != '[' &&
+ r != ']' &&
+ r != '`'
+}
+
+func isBase64Rune(r rune) bool {
+ return (r >= 'a' && r <= 'z') ||
+ (r >= 'A' && r <= 'Z') ||
+ (r >= '0' && r <= '9') ||
+ r == '+' ||
+ r == '/' ||
+ r == '=' ||
+ r == '\n'
+}
+
+type stateFn func(*lexer) stateFn
+
+// lexer lexes the data URL scheme input string.
+// The implementation is from the text/template/parser package.
+type lexer struct {
+ input string
+ start int
+ pos int
+ width int
+ seenBase64Item bool
+ items chan item
+}
+
+func (l *lexer) run() {
+ for state := lexBeforeDataPrefix; state != nil; {
+ state = state(l)
+ }
+ close(l.items)
+}
+
+func (l *lexer) emit(t itemType) {
+ l.items <- item{t, l.input[l.start:l.pos]}
+ l.start = l.pos
+}
+
+func (l *lexer) next() (r rune) {
+ if l.pos >= len(l.input) {
+ l.width = 0
+ return eof
+ }
+ r, l.width = utf8.DecodeRuneInString(l.input[l.pos:])
+ l.pos += l.width
+ return r
+}
+
+func (l *lexer) backup() {
+ l.pos -= l.width
+}
+
+func (l *lexer) ignore() {
+ l.start = l.pos
+}
+
+func (l *lexer) errorf(format string, args ...interface{}) stateFn {
+ l.items <- item{itemError, fmt.Sprintf(format, args...)}
+ return nil
+}
+
+func lex(input string) *lexer {
+ l := &lexer{
+ input: input,
+ items: make(chan item),
+ }
+ go l.run() // Concurrently run state machine.
+ return l
+}
+
+const (
+ dataPrefix = "data:"
+ mediaSep = '/'
+ paramSemicolon = ';'
+ paramEqual = '='
+ dataComma = ','
+)
+
+// start lexing by detecting data prefix
+func lexBeforeDataPrefix(l *lexer) stateFn {
+ if strings.HasPrefix(l.input[l.pos:], dataPrefix) {
+ return lexDataPrefix
+ }
+ return l.errorf("missing data prefix")
+}
+
+// lex data prefix
+func lexDataPrefix(l *lexer) stateFn {
+ l.pos += len(dataPrefix)
+ l.emit(itemDataPrefix)
+ return lexAfterDataPrefix
+}
+
+// lex what's after data prefix.
+// it can be the media type/subtype separator,
+// the base64 encoding, or the comma preceding the data
+func lexAfterDataPrefix(l *lexer) stateFn {
+ switch r := l.next(); {
+ case r == paramSemicolon:
+ l.backup()
+ return lexParamSemicolon
+ case r == dataComma:
+ l.backup()
+ return lexDataComma
+ case r == eof:
+ return l.errorf("missing comma before data")
+ case r == 'x' || r == 'X':
+ if l.next() == '-' {
+ return lexXTokenMediaType
+ }
+ return lexInDiscreteMediaType
+ case isTokenRune(r):
+ return lexInDiscreteMediaType
+ default:
+ return l.errorf("invalid character after data prefix")
+ }
+}
+
+func lexXTokenMediaType(l *lexer) stateFn {
+ for {
+ switch r := l.next(); {
+ case r == mediaSep:
+ l.backup()
+ return lexMediaType
+ case r == eof:
+ return l.errorf("missing media type slash")
+ case isTokenRune(r):
+ default:
+ return l.errorf("invalid character for media type")
+ }
+ }
+}
+
+func lexInDiscreteMediaType(l *lexer) stateFn {
+ for {
+ switch r := l.next(); {
+ case r == mediaSep:
+ l.backup()
+ // check it's valid discrete type
+ if !isDiscreteType(l.input[l.start:l.pos]) &&
+ !isCompositeType(l.input[l.start:l.pos]) {
+ return l.errorf("invalid media type")
+ }
+ return lexMediaType
+ case r == eof:
+ return l.errorf("missing media type slash")
+ case isTokenRune(r):
+ default:
+ return l.errorf("invalid character for media type")
+ }
+ }
+}
+
+func lexMediaType(l *lexer) stateFn {
+ if l.pos > l.start {
+ l.emit(itemMediaType)
+ }
+ return lexMediaSep
+}
+
+func lexMediaSep(l *lexer) stateFn {
+ l.next()
+ l.emit(itemMediaSep)
+ return lexAfterMediaSep
+}
+
+func lexAfterMediaSep(l *lexer) stateFn {
+ for {
+ switch r := l.next(); {
+ case r == paramSemicolon || r == dataComma:
+ l.backup()
+ return lexMediaSubType
+ case r == eof:
+ return l.errorf("incomplete media type")
+ case isTokenRune(r):
+ default:
+ return l.errorf("invalid character for media subtype")
+ }
+ }
+}
+
+func lexMediaSubType(l *lexer) stateFn {
+ if l.pos > l.start {
+ l.emit(itemMediaSubType)
+ }
+ return lexAfterMediaSubType
+}
+
+func lexAfterMediaSubType(l *lexer) stateFn {
+ switch r := l.next(); {
+ case r == paramSemicolon:
+ l.backup()
+ return lexParamSemicolon
+ case r == dataComma:
+ l.backup()
+ return lexDataComma
+ case r == eof:
+ return l.errorf("missing comma before data")
+ default:
+ return l.errorf("expected semicolon or comma")
+ }
+}
+
+func lexParamSemicolon(l *lexer) stateFn {
+ l.next()
+ l.emit(itemParamSemicolon)
+ return lexAfterParamSemicolon
+}
+
+func lexAfterParamSemicolon(l *lexer) stateFn {
+ switch r := l.next(); {
+ case r == eof:
+ return l.errorf("unterminated parameter sequence")
+ case r == paramEqual || r == dataComma:
+ return l.errorf("unterminated parameter sequence")
+ case isTokenRune(r):
+ l.backup()
+ return lexInParamAttr
+ default:
+ return l.errorf("invalid character for parameter attribute")
+ }
+}
+
+func lexBase64Enc(l *lexer) stateFn {
+ if l.pos > l.start {
+ if v := l.input[l.start:l.pos]; v != "base64" {
+ return l.errorf("expected base64, got %s", v)
+ }
+ l.seenBase64Item = true
+ l.emit(itemBase64Enc)
+ }
+ return lexDataComma
+}
+
+func lexInParamAttr(l *lexer) stateFn {
+ for {
+ switch r := l.next(); {
+ case r == paramEqual:
+ l.backup()
+ return lexParamAttr
+ case r == dataComma:
+ l.backup()
+ return lexBase64Enc
+ case r == eof:
+ return l.errorf("unterminated parameter sequence")
+ case isTokenRune(r):
+ default:
+ return l.errorf("invalid character for parameter attribute")
+ }
+ }
+}
+
+func lexParamAttr(l *lexer) stateFn {
+ if l.pos > l.start {
+ l.emit(itemParamAttr)
+ }
+ return lexParamEqual
+}
+
+func lexParamEqual(l *lexer) stateFn {
+ l.next()
+ l.emit(itemParamEqual)
+ return lexAfterParamEqual
+}
+
+func lexAfterParamEqual(l *lexer) stateFn {
+ switch r := l.next(); {
+ case r == '"':
+ l.emit(itemLeftStringQuote)
+ return lexInQuotedStringParamVal
+ case r == eof:
+ return l.errorf("missing comma before data")
+ case isTokenRune(r):
+ return lexInParamVal
+ default:
+ return l.errorf("invalid character for parameter value")
+ }
+}
+
+func lexInQuotedStringParamVal(l *lexer) stateFn {
+ for {
+ switch r := l.next(); {
+ case r == eof:
+ return l.errorf("unclosed quoted string")
+ case r == '\\':
+ return lexEscapedChar
+ case r == '"':
+ l.backup()
+ return lexQuotedStringParamVal
+ case r <= unicode.MaxASCII:
+ default:
+ return l.errorf("invalid character for parameter value")
+ }
+ }
+}
+
+func lexEscapedChar(l *lexer) stateFn {
+ switch r := l.next(); {
+ case r <= unicode.MaxASCII:
+ return lexInQuotedStringParamVal
+ case r == eof:
+ return l.errorf("unexpected eof")
+ default:
+ return l.errorf("invalid escaped character")
+ }
+}
+
+func lexInParamVal(l *lexer) stateFn {
+ for {
+ switch r := l.next(); {
+ case r == paramSemicolon || r == dataComma:
+ l.backup()
+ return lexParamVal
+ case r == eof:
+ return l.errorf("missing comma before data")
+ case isTokenRune(r):
+ default:
+ return l.errorf("invalid character for parameter value")
+ }
+ }
+}
+
+func lexQuotedStringParamVal(l *lexer) stateFn {
+ if l.pos > l.start {
+ l.emit(itemParamVal)
+ }
+ l.next()
+ l.emit(itemRightStringQuote)
+ return lexAfterParamVal
+}
+
+func lexParamVal(l *lexer) stateFn {
+ if l.pos > l.start {
+ l.emit(itemParamVal)
+ }
+ return lexAfterParamVal
+}
+
+func lexAfterParamVal(l *lexer) stateFn {
+ switch r := l.next(); {
+ case r == paramSemicolon:
+ l.backup()
+ return lexParamSemicolon
+ case r == dataComma:
+ l.backup()
+ return lexDataComma
+ case r == eof:
+ return l.errorf("missing comma before data")
+ default:
+ return l.errorf("expected semicolon or comma")
+ }
+}
+
+func lexDataComma(l *lexer) stateFn {
+ l.next()
+ l.emit(itemDataComma)
+ if l.seenBase64Item {
+ return lexBase64Data
+ }
+ return lexData
+}
+
+func lexData(l *lexer) stateFn {
+Loop:
+ for {
+ switch r := l.next(); {
+ case r == eof:
+ break Loop
+ case isURLCharRune(r):
+ default:
+ return l.errorf("invalid data character")
+ }
+ }
+ if l.pos > l.start {
+ l.emit(itemData)
+ }
+ l.emit(itemEOF)
+ return nil
+}
+
+func lexBase64Data(l *lexer) stateFn {
+Loop:
+ for {
+ switch r := l.next(); {
+ case r == eof:
+ break Loop
+ case isBase64Rune(r):
+ default:
+ return l.errorf("invalid data character")
+ }
+ }
+ if l.pos > l.start {
+ l.emit(itemData)
+ }
+ l.emit(itemEOF)
+ return nil
+}
diff --git a/vendor/github.com/vincent-petithory/dataurl/rfc2396.go b/vendor/github.com/vincent-petithory/dataurl/rfc2396.go
new file mode 100644
index 00000000..e2ea0cac
--- /dev/null
+++ b/vendor/github.com/vincent-petithory/dataurl/rfc2396.go
@@ -0,0 +1,130 @@
+package dataurl
+
+import (
+ "bytes"
+ "fmt"
+ "io"
+ "strings"
+)
+
+// Escape implements URL escaping, as defined in RFC 2397 (http://tools.ietf.org/html/rfc2397).
+// It differs a bit from net/url's QueryEscape and QueryUnescape, e.g how spaces are treated (+ instead of %20):
+//
+// Only ASCII chars are allowed. Reserved chars are escaped to their %xx form.
+// Unreserved chars are [a-z], [A-Z], [0-9], and -_.!~*\().
+func Escape(data []byte) string {
+ var buf = new(bytes.Buffer)
+ for _, b := range data {
+ switch {
+ case isUnreserved(b):
+ buf.WriteByte(b)
+ default:
+ fmt.Fprintf(buf, "%%%02X", b)
+ }
+ }
+ return buf.String()
+}
+
+// EscapeString is like Escape, but taking
+// a string as argument.
+func EscapeString(s string) string {
+ return Escape([]byte(s))
+}
+
+// isUnreserved return true
+// if the byte c is an unreserved char,
+// as defined in RFC 2396.
+func isUnreserved(c byte) bool {
+ return (c >= 'a' && c <= 'z') ||
+ (c >= 'A' && c <= 'Z') ||
+ (c >= '0' && c <= '9') ||
+ c == '-' ||
+ c == '_' ||
+ c == '.' ||
+ c == '!' ||
+ c == '~' ||
+ c == '*' ||
+ c == '\'' ||
+ c == '(' ||
+ c == ')'
+}
+
+func isHex(c byte) bool {
+ switch {
+ case c >= 'a' && c <= 'f':
+ return true
+ case c >= 'A' && c <= 'F':
+ return true
+ case c >= '0' && c <= '9':
+ return true
+ }
+ return false
+}
+
+// borrowed from net/url/url.go
+func unhex(c byte) byte {
+ switch {
+ case '0' <= c && c <= '9':
+ return c - '0'
+ case 'a' <= c && c <= 'f':
+ return c - 'a' + 10
+ case 'A' <= c && c <= 'F':
+ return c - 'A' + 10
+ }
+ return 0
+}
+
+// Unescape unescapes a character sequence
+// escaped with Escape(String?).
+func Unescape(s string) ([]byte, error) {
+ var buf = new(bytes.Buffer)
+ reader := strings.NewReader(s)
+
+ for {
+ r, size, err := reader.ReadRune()
+ if err == io.EOF {
+ break
+ }
+ if err != nil {
+ return nil, err
+ }
+ if size > 1 {
+ return nil, fmt.Errorf("rfc2396: non-ASCII char detected")
+ }
+
+ switch r {
+ case '%':
+ eb1, err := reader.ReadByte()
+ if err == io.EOF {
+ return nil, fmt.Errorf("rfc2396: unexpected end of unescape sequence")
+ }
+ if err != nil {
+ return nil, err
+ }
+ if !isHex(eb1) {
+ return nil, fmt.Errorf("rfc2396: invalid char 0x%x in unescape sequence", r)
+ }
+ eb0, err := reader.ReadByte()
+ if err == io.EOF {
+ return nil, fmt.Errorf("rfc2396: unexpected end of unescape sequence")
+ }
+ if err != nil {
+ return nil, err
+ }
+ if !isHex(eb0) {
+ return nil, fmt.Errorf("rfc2396: invalid char 0x%x in unescape sequence", r)
+ }
+ buf.WriteByte(unhex(eb0) + unhex(eb1)*16)
+ default:
+ buf.WriteByte(byte(r))
+ }
+ }
+ return buf.Bytes(), nil
+}
+
+// UnescapeToString is like Unescape, but returning
+// a string.
+func UnescapeToString(s string) (string, error) {
+ b, err := Unescape(s)
+ return string(b), err
+}
diff --git a/vendor/github.com/vincent-petithory/dataurl/rfc2396_test.go b/vendor/github.com/vincent-petithory/dataurl/rfc2396_test.go
new file mode 100644
index 00000000..45efbaf2
--- /dev/null
+++ b/vendor/github.com/vincent-petithory/dataurl/rfc2396_test.go
@@ -0,0 +1,69 @@
+package dataurl
+
+import (
+ "bytes"
+ "fmt"
+ "testing"
+)
+
+var tests = []struct {
+ escaped string
+ unescaped []byte
+}{
+ {"A%20brief%20note%0A", []byte("A brief note\n")},
+ {"%7B%5B%5Dbyte(%22A%2520brief%2520note%22)%2C%20%5B%5Dbyte(%22A%20brief%20note%22)%7D", []byte(`{[]byte("A%20brief%20note"), []byte("A brief note")}`)},
+}
+
+func TestEscape(t *testing.T) {
+ for _, test := range tests {
+ escaped := Escape(test.unescaped)
+ if string(escaped) != test.escaped {
+ t.Errorf("Expected %s, got %s", test.escaped, string(escaped))
+ }
+ }
+}
+
+func TestUnescape(t *testing.T) {
+ for _, test := range tests {
+ unescaped, err := Unescape(test.escaped)
+ if err != nil {
+ t.Error(err)
+ continue
+ }
+ if !bytes.Equal(unescaped, test.unescaped) {
+ t.Errorf("Expected %s, got %s", test.unescaped, unescaped)
+ }
+ }
+}
+
+func ExampleEscapeString() {
+ fmt.Println(EscapeString("A brief note"))
+ // Output: A%20brief%20note
+}
+
+func ExampleEscape() {
+ fmt.Println(Escape([]byte("A brief note")))
+ // Output: A%20brief%20note
+}
+
+func ExampleUnescape() {
+ data, err := Unescape("A%20brief%20note")
+ if err != nil {
+ // can fail e.g if incorrect escaped sequence
+ fmt.Println(err)
+ return
+ }
+ fmt.Println(string(data))
+ // Output: A brief note
+}
+
+func ExampleUnescapeToString() {
+ s, err := UnescapeToString("A%20brief%20note")
+ if err != nil {
+ // can fail e.g if incorrect escaped sequence
+ fmt.Println(err)
+ return
+ }
+ fmt.Println(s)
+ // Output: A brief note
+}
diff --git a/vendor/github.com/vincent-petithory/dataurl/wercker.yml b/vendor/github.com/vincent-petithory/dataurl/wercker.yml
new file mode 100644
index 00000000..3ab8084c
--- /dev/null
+++ b/vendor/github.com/vincent-petithory/dataurl/wercker.yml
@@ -0,0 +1 @@
+box: wercker/default
\ No newline at end of file
diff --git a/vendor/go4.org/errorutil/highlight.go b/vendor/go4.org/errorutil/highlight.go
new file mode 100644
index 00000000..aace6a46
--- /dev/null
+++ b/vendor/go4.org/errorutil/highlight.go
@@ -0,0 +1,58 @@
+/*
+Copyright 2011 Google Inc.
+
+Licensed under the Apache License, Version 2.0 (the "License");
+you may not use this file except in compliance with the License.
+You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+Unless required by applicable law or agreed to in writing, software
+distributed under the License is distributed on an "AS IS" BASIS,
+WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+See the License for the specific language governing permissions and
+limitations under the License.
+*/
+
+// Package errorutil helps make better error messages.
+package errorutil
+
+import (
+ "bufio"
+ "bytes"
+ "fmt"
+ "io"
+ "strings"
+)
+
+// HighlightBytePosition takes a reader and the location in bytes of a parse
+// error (for instance, from json.SyntaxError.Offset) and returns the line, column,
+// and pretty-printed context around the error with an arrow indicating the exact
+// position of the syntax error.
+func HighlightBytePosition(f io.Reader, pos int64) (line, col int, highlight string) {
+ line = 1
+ br := bufio.NewReader(f)
+ lastLine := ""
+ thisLine := new(bytes.Buffer)
+ for n := int64(0); n < pos; n++ {
+ b, err := br.ReadByte()
+ if err != nil {
+ break
+ }
+ if b == '\n' {
+ lastLine = thisLine.String()
+ thisLine.Reset()
+ line++
+ col = 1
+ } else {
+ col++
+ thisLine.WriteByte(b)
+ }
+ }
+ if line > 1 {
+ highlight += fmt.Sprintf("%5d: %s\n", line-1, lastLine)
+ }
+ highlight += fmt.Sprintf("%5d: %s\n", line, thisLine.String())
+ highlight += fmt.Sprintf("%s^\n", strings.Repeat(" ", col+5))
+ return
+}
diff --git a/vendor/golang.org/x/crypto/ripemd160/ripemd160.go b/vendor/golang.org/x/crypto/ripemd160/ripemd160.go
deleted file mode 100644
index da690f0b..00000000
--- a/vendor/golang.org/x/crypto/ripemd160/ripemd160.go
+++ /dev/null
@@ -1,120 +0,0 @@
-// Copyright 2010 The Go Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style
-// license that can be found in the LICENSE file.
-
-// Package ripemd160 implements the RIPEMD-160 hash algorithm.
-package ripemd160
-
-// RIPEMD-160 is designed by by Hans Dobbertin, Antoon Bosselaers, and Bart
-// Preneel with specifications available at:
-// http://homes.esat.kuleuven.be/~cosicart/pdf/AB-9601/AB-9601.pdf.
-
-import (
- "crypto"
- "hash"
-)
-
-func init() {
- crypto.RegisterHash(crypto.RIPEMD160, New)
-}
-
-// The size of the checksum in bytes.
-const Size = 20
-
-// The block size of the hash algorithm in bytes.
-const BlockSize = 64
-
-const (
- _s0 = 0x67452301
- _s1 = 0xefcdab89
- _s2 = 0x98badcfe
- _s3 = 0x10325476
- _s4 = 0xc3d2e1f0
-)
-
-// digest represents the partial evaluation of a checksum.
-type digest struct {
- s [5]uint32 // running context
- x [BlockSize]byte // temporary buffer
- nx int // index into x
- tc uint64 // total count of bytes processed
-}
-
-func (d *digest) Reset() {
- d.s[0], d.s[1], d.s[2], d.s[3], d.s[4] = _s0, _s1, _s2, _s3, _s4
- d.nx = 0
- d.tc = 0
-}
-
-// New returns a new hash.Hash computing the checksum.
-func New() hash.Hash {
- result := new(digest)
- result.Reset()
- return result
-}
-
-func (d *digest) Size() int { return Size }
-
-func (d *digest) BlockSize() int { return BlockSize }
-
-func (d *digest) Write(p []byte) (nn int, err error) {
- nn = len(p)
- d.tc += uint64(nn)
- if d.nx > 0 {
- n := len(p)
- if n > BlockSize-d.nx {
- n = BlockSize - d.nx
- }
- for i := 0; i < n; i++ {
- d.x[d.nx+i] = p[i]
- }
- d.nx += n
- if d.nx == BlockSize {
- _Block(d, d.x[0:])
- d.nx = 0
- }
- p = p[n:]
- }
- n := _Block(d, p)
- p = p[n:]
- if len(p) > 0 {
- d.nx = copy(d.x[:], p)
- }
- return
-}
-
-func (d0 *digest) Sum(in []byte) []byte {
- // Make a copy of d0 so that caller can keep writing and summing.
- d := *d0
-
- // Padding. Add a 1 bit and 0 bits until 56 bytes mod 64.
- tc := d.tc
- var tmp [64]byte
- tmp[0] = 0x80
- if tc%64 < 56 {
- d.Write(tmp[0 : 56-tc%64])
- } else {
- d.Write(tmp[0 : 64+56-tc%64])
- }
-
- // Length in bits.
- tc <<= 3
- for i := uint(0); i < 8; i++ {
- tmp[i] = byte(tc >> (8 * i))
- }
- d.Write(tmp[0:8])
-
- if d.nx != 0 {
- panic("d.nx != 0")
- }
-
- var digest [Size]byte
- for i, s := range d.s {
- digest[i*4] = byte(s)
- digest[i*4+1] = byte(s >> 8)
- digest[i*4+2] = byte(s >> 16)
- digest[i*4+3] = byte(s >> 24)
- }
-
- return append(in, digest[:]...)
-}
diff --git a/vendor/golang.org/x/crypto/ripemd160/ripemd160_test.go b/vendor/golang.org/x/crypto/ripemd160/ripemd160_test.go
deleted file mode 100644
index 5df1b259..00000000
--- a/vendor/golang.org/x/crypto/ripemd160/ripemd160_test.go
+++ /dev/null
@@ -1,64 +0,0 @@
-// Copyright 2010 The Go Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style
-// license that can be found in the LICENSE file.
-
-package ripemd160
-
-// Test vectors are from:
-// http://homes.esat.kuleuven.be/~bosselae/ripemd160.html
-
-import (
- "fmt"
- "io"
- "testing"
-)
-
-type mdTest struct {
- out string
- in string
-}
-
-var vectors = [...]mdTest{
- {"9c1185a5c5e9fc54612808977ee8f548b2258d31", ""},
- {"0bdc9d2d256b3ee9daae347be6f4dc835a467ffe", "a"},
- {"8eb208f7e05d987a9b044a8e98c6b087f15a0bfc", "abc"},
- {"5d0689ef49d2fae572b881b123a85ffa21595f36", "message digest"},
- {"f71c27109c692c1b56bbdceb5b9d2865b3708dbc", "abcdefghijklmnopqrstuvwxyz"},
- {"12a053384a9c0c88e405a06c27dcf49ada62eb2b", "abcdbcdecdefdefgefghfghighijhijkijkljklmklmnlmnomnopnopq"},
- {"b0e20b6e3116640286ed3a87a5713079b21f5189", "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789"},
- {"9b752e45573d4b39f4dbd3323cab82bf63326bfb", "12345678901234567890123456789012345678901234567890123456789012345678901234567890"},
-}
-
-func TestVectors(t *testing.T) {
- for i := 0; i < len(vectors); i++ {
- tv := vectors[i]
- md := New()
- for j := 0; j < 3; j++ {
- if j < 2 {
- io.WriteString(md, tv.in)
- } else {
- io.WriteString(md, tv.in[0:len(tv.in)/2])
- md.Sum(nil)
- io.WriteString(md, tv.in[len(tv.in)/2:])
- }
- s := fmt.Sprintf("%x", md.Sum(nil))
- if s != tv.out {
- t.Fatalf("RIPEMD-160[%d](%s) = %s, expected %s", j, tv.in, s, tv.out)
- }
- md.Reset()
- }
- }
-}
-
-func TestMillionA(t *testing.T) {
- md := New()
- for i := 0; i < 100000; i++ {
- io.WriteString(md, "aaaaaaaaaa")
- }
- out := "52783243c1697bdbe16d37f97f68f08325dc1528"
- s := fmt.Sprintf("%x", md.Sum(nil))
- if s != out {
- t.Fatalf("RIPEMD-160 (1 million 'a') = %s, expected %s", s, out)
- }
- md.Reset()
-}
diff --git a/vendor/golang.org/x/crypto/ripemd160/ripemd160block.go b/vendor/golang.org/x/crypto/ripemd160/ripemd160block.go
deleted file mode 100644
index 7bc8e6c4..00000000
--- a/vendor/golang.org/x/crypto/ripemd160/ripemd160block.go
+++ /dev/null
@@ -1,161 +0,0 @@
-// Copyright 2010 The Go Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style
-// license that can be found in the LICENSE file.
-
-// RIPEMD-160 block step.
-// In its own file so that a faster assembly or C version
-// can be substituted easily.
-
-package ripemd160
-
-// work buffer indices and roll amounts for one line
-var _n = [80]uint{
- 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15,
- 7, 4, 13, 1, 10, 6, 15, 3, 12, 0, 9, 5, 2, 14, 11, 8,
- 3, 10, 14, 4, 9, 15, 8, 1, 2, 7, 0, 6, 13, 11, 5, 12,
- 1, 9, 11, 10, 0, 8, 12, 4, 13, 3, 7, 15, 14, 5, 6, 2,
- 4, 0, 5, 9, 7, 12, 2, 10, 14, 1, 3, 8, 11, 6, 15, 13,
-}
-
-var _r = [80]uint{
- 11, 14, 15, 12, 5, 8, 7, 9, 11, 13, 14, 15, 6, 7, 9, 8,
- 7, 6, 8, 13, 11, 9, 7, 15, 7, 12, 15, 9, 11, 7, 13, 12,
- 11, 13, 6, 7, 14, 9, 13, 15, 14, 8, 13, 6, 5, 12, 7, 5,
- 11, 12, 14, 15, 14, 15, 9, 8, 9, 14, 5, 6, 8, 6, 5, 12,
- 9, 15, 5, 11, 6, 8, 13, 12, 5, 12, 13, 14, 11, 8, 5, 6,
-}
-
-// same for the other parallel one
-var n_ = [80]uint{
- 5, 14, 7, 0, 9, 2, 11, 4, 13, 6, 15, 8, 1, 10, 3, 12,
- 6, 11, 3, 7, 0, 13, 5, 10, 14, 15, 8, 12, 4, 9, 1, 2,
- 15, 5, 1, 3, 7, 14, 6, 9, 11, 8, 12, 2, 10, 0, 4, 13,
- 8, 6, 4, 1, 3, 11, 15, 0, 5, 12, 2, 13, 9, 7, 10, 14,
- 12, 15, 10, 4, 1, 5, 8, 7, 6, 2, 13, 14, 0, 3, 9, 11,
-}
-
-var r_ = [80]uint{
- 8, 9, 9, 11, 13, 15, 15, 5, 7, 7, 8, 11, 14, 14, 12, 6,
- 9, 13, 15, 7, 12, 8, 9, 11, 7, 7, 12, 7, 6, 15, 13, 11,
- 9, 7, 15, 11, 8, 6, 6, 14, 12, 13, 5, 14, 13, 13, 7, 5,
- 15, 5, 8, 11, 14, 14, 6, 14, 6, 9, 12, 9, 12, 5, 15, 8,
- 8, 5, 12, 9, 12, 5, 14, 6, 8, 13, 6, 5, 15, 13, 11, 11,
-}
-
-func _Block(md *digest, p []byte) int {
- n := 0
- var x [16]uint32
- var alpha, beta uint32
- for len(p) >= BlockSize {
- a, b, c, d, e := md.s[0], md.s[1], md.s[2], md.s[3], md.s[4]
- aa, bb, cc, dd, ee := a, b, c, d, e
- j := 0
- for i := 0; i < 16; i++ {
- x[i] = uint32(p[j]) | uint32(p[j+1])<<8 | uint32(p[j+2])<<16 | uint32(p[j+3])<<24
- j += 4
- }
-
- // round 1
- i := 0
- for i < 16 {
- alpha = a + (b ^ c ^ d) + x[_n[i]]
- s := _r[i]
- alpha = (alpha<>(32-s)) + e
- beta = c<<10 | c>>22
- a, b, c, d, e = e, alpha, b, beta, d
-
- // parallel line
- alpha = aa + (bb ^ (cc | ^dd)) + x[n_[i]] + 0x50a28be6
- s = r_[i]
- alpha = (alpha<>(32-s)) + ee
- beta = cc<<10 | cc>>22
- aa, bb, cc, dd, ee = ee, alpha, bb, beta, dd
-
- i++
- }
-
- // round 2
- for i < 32 {
- alpha = a + (b&c | ^b&d) + x[_n[i]] + 0x5a827999
- s := _r[i]
- alpha = (alpha<>(32-s)) + e
- beta = c<<10 | c>>22
- a, b, c, d, e = e, alpha, b, beta, d
-
- // parallel line
- alpha = aa + (bb&dd | cc&^dd) + x[n_[i]] + 0x5c4dd124
- s = r_[i]
- alpha = (alpha<>(32-s)) + ee
- beta = cc<<10 | cc>>22
- aa, bb, cc, dd, ee = ee, alpha, bb, beta, dd
-
- i++
- }
-
- // round 3
- for i < 48 {
- alpha = a + (b | ^c ^ d) + x[_n[i]] + 0x6ed9eba1
- s := _r[i]
- alpha = (alpha<>(32-s)) + e
- beta = c<<10 | c>>22
- a, b, c, d, e = e, alpha, b, beta, d
-
- // parallel line
- alpha = aa + (bb | ^cc ^ dd) + x[n_[i]] + 0x6d703ef3
- s = r_[i]
- alpha = (alpha<>(32-s)) + ee
- beta = cc<<10 | cc>>22
- aa, bb, cc, dd, ee = ee, alpha, bb, beta, dd
-
- i++
- }
-
- // round 4
- for i < 64 {
- alpha = a + (b&d | c&^d) + x[_n[i]] + 0x8f1bbcdc
- s := _r[i]
- alpha = (alpha<>(32-s)) + e
- beta = c<<10 | c>>22
- a, b, c, d, e = e, alpha, b, beta, d
-
- // parallel line
- alpha = aa + (bb&cc | ^bb&dd) + x[n_[i]] + 0x7a6d76e9
- s = r_[i]
- alpha = (alpha<>(32-s)) + ee
- beta = cc<<10 | cc>>22
- aa, bb, cc, dd, ee = ee, alpha, bb, beta, dd
-
- i++
- }
-
- // round 5
- for i < 80 {
- alpha = a + (b ^ (c | ^d)) + x[_n[i]] + 0xa953fd4e
- s := _r[i]
- alpha = (alpha<>(32-s)) + e
- beta = c<<10 | c>>22
- a, b, c, d, e = e, alpha, b, beta, d
-
- // parallel line
- alpha = aa + (bb ^ cc ^ dd) + x[n_[i]]
- s = r_[i]
- alpha = (alpha<>(32-s)) + ee
- beta = cc<<10 | cc>>22
- aa, bb, cc, dd, ee = ee, alpha, bb, beta, dd
-
- i++
- }
-
- // combine results
- dd += c + md.s[1]
- md.s[1] = md.s[2] + d + ee
- md.s[2] = md.s[3] + e + aa
- md.s[3] = md.s[4] + a + bb
- md.s[4] = md.s[0] + b + cc
- md.s[0] = dd
-
- p = p[BlockSize:]
- n += BlockSize
- }
- return n
-}
diff --git a/vendor/golang.org/x/crypto/ssh/terminal/terminal.go b/vendor/golang.org/x/crypto/ssh/terminal/terminal.go
deleted file mode 100644
index 741eeb13..00000000
--- a/vendor/golang.org/x/crypto/ssh/terminal/terminal.go
+++ /dev/null
@@ -1,892 +0,0 @@
-// Copyright 2011 The Go Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style
-// license that can be found in the LICENSE file.
-
-package terminal
-
-import (
- "bytes"
- "io"
- "sync"
- "unicode/utf8"
-)
-
-// EscapeCodes contains escape sequences that can be written to the terminal in
-// order to achieve different styles of text.
-type EscapeCodes struct {
- // Foreground colors
- Black, Red, Green, Yellow, Blue, Magenta, Cyan, White []byte
-
- // Reset all attributes
- Reset []byte
-}
-
-var vt100EscapeCodes = EscapeCodes{
- Black: []byte{keyEscape, '[', '3', '0', 'm'},
- Red: []byte{keyEscape, '[', '3', '1', 'm'},
- Green: []byte{keyEscape, '[', '3', '2', 'm'},
- Yellow: []byte{keyEscape, '[', '3', '3', 'm'},
- Blue: []byte{keyEscape, '[', '3', '4', 'm'},
- Magenta: []byte{keyEscape, '[', '3', '5', 'm'},
- Cyan: []byte{keyEscape, '[', '3', '6', 'm'},
- White: []byte{keyEscape, '[', '3', '7', 'm'},
-
- Reset: []byte{keyEscape, '[', '0', 'm'},
-}
-
-// Terminal contains the state for running a VT100 terminal that is capable of
-// reading lines of input.
-type Terminal struct {
- // AutoCompleteCallback, if non-null, is called for each keypress with
- // the full input line and the current position of the cursor (in
- // bytes, as an index into |line|). If it returns ok=false, the key
- // press is processed normally. Otherwise it returns a replacement line
- // and the new cursor position.
- AutoCompleteCallback func(line string, pos int, key rune) (newLine string, newPos int, ok bool)
-
- // Escape contains a pointer to the escape codes for this terminal.
- // It's always a valid pointer, although the escape codes themselves
- // may be empty if the terminal doesn't support them.
- Escape *EscapeCodes
-
- // lock protects the terminal and the state in this object from
- // concurrent processing of a key press and a Write() call.
- lock sync.Mutex
-
- c io.ReadWriter
- prompt []rune
-
- // line is the current line being entered.
- line []rune
- // pos is the logical position of the cursor in line
- pos int
- // echo is true if local echo is enabled
- echo bool
- // pasteActive is true iff there is a bracketed paste operation in
- // progress.
- pasteActive bool
-
- // cursorX contains the current X value of the cursor where the left
- // edge is 0. cursorY contains the row number where the first row of
- // the current line is 0.
- cursorX, cursorY int
- // maxLine is the greatest value of cursorY so far.
- maxLine int
-
- termWidth, termHeight int
-
- // outBuf contains the terminal data to be sent.
- outBuf []byte
- // remainder contains the remainder of any partial key sequences after
- // a read. It aliases into inBuf.
- remainder []byte
- inBuf [256]byte
-
- // history contains previously entered commands so that they can be
- // accessed with the up and down keys.
- history stRingBuffer
- // historyIndex stores the currently accessed history entry, where zero
- // means the immediately previous entry.
- historyIndex int
- // When navigating up and down the history it's possible to return to
- // the incomplete, initial line. That value is stored in
- // historyPending.
- historyPending string
-}
-
-// NewTerminal runs a VT100 terminal on the given ReadWriter. If the ReadWriter is
-// a local terminal, that terminal must first have been put into raw mode.
-// prompt is a string that is written at the start of each input line (i.e.
-// "> ").
-func NewTerminal(c io.ReadWriter, prompt string) *Terminal {
- return &Terminal{
- Escape: &vt100EscapeCodes,
- c: c,
- prompt: []rune(prompt),
- termWidth: 80,
- termHeight: 24,
- echo: true,
- historyIndex: -1,
- }
-}
-
-const (
- keyCtrlD = 4
- keyCtrlU = 21
- keyEnter = '\r'
- keyEscape = 27
- keyBackspace = 127
- keyUnknown = 0xd800 /* UTF-16 surrogate area */ + iota
- keyUp
- keyDown
- keyLeft
- keyRight
- keyAltLeft
- keyAltRight
- keyHome
- keyEnd
- keyDeleteWord
- keyDeleteLine
- keyClearScreen
- keyPasteStart
- keyPasteEnd
-)
-
-var pasteStart = []byte{keyEscape, '[', '2', '0', '0', '~'}
-var pasteEnd = []byte{keyEscape, '[', '2', '0', '1', '~'}
-
-// bytesToKey tries to parse a key sequence from b. If successful, it returns
-// the key and the remainder of the input. Otherwise it returns utf8.RuneError.
-func bytesToKey(b []byte, pasteActive bool) (rune, []byte) {
- if len(b) == 0 {
- return utf8.RuneError, nil
- }
-
- if !pasteActive {
- switch b[0] {
- case 1: // ^A
- return keyHome, b[1:]
- case 5: // ^E
- return keyEnd, b[1:]
- case 8: // ^H
- return keyBackspace, b[1:]
- case 11: // ^K
- return keyDeleteLine, b[1:]
- case 12: // ^L
- return keyClearScreen, b[1:]
- case 23: // ^W
- return keyDeleteWord, b[1:]
- }
- }
-
- if b[0] != keyEscape {
- if !utf8.FullRune(b) {
- return utf8.RuneError, b
- }
- r, l := utf8.DecodeRune(b)
- return r, b[l:]
- }
-
- if !pasteActive && len(b) >= 3 && b[0] == keyEscape && b[1] == '[' {
- switch b[2] {
- case 'A':
- return keyUp, b[3:]
- case 'B':
- return keyDown, b[3:]
- case 'C':
- return keyRight, b[3:]
- case 'D':
- return keyLeft, b[3:]
- case 'H':
- return keyHome, b[3:]
- case 'F':
- return keyEnd, b[3:]
- }
- }
-
- if !pasteActive && len(b) >= 6 && b[0] == keyEscape && b[1] == '[' && b[2] == '1' && b[3] == ';' && b[4] == '3' {
- switch b[5] {
- case 'C':
- return keyAltRight, b[6:]
- case 'D':
- return keyAltLeft, b[6:]
- }
- }
-
- if !pasteActive && len(b) >= 6 && bytes.Equal(b[:6], pasteStart) {
- return keyPasteStart, b[6:]
- }
-
- if pasteActive && len(b) >= 6 && bytes.Equal(b[:6], pasteEnd) {
- return keyPasteEnd, b[6:]
- }
-
- // If we get here then we have a key that we don't recognise, or a
- // partial sequence. It's not clear how one should find the end of a
- // sequence without knowing them all, but it seems that [a-zA-Z~] only
- // appears at the end of a sequence.
- for i, c := range b[0:] {
- if c >= 'a' && c <= 'z' || c >= 'A' && c <= 'Z' || c == '~' {
- return keyUnknown, b[i+1:]
- }
- }
-
- return utf8.RuneError, b
-}
-
-// queue appends data to the end of t.outBuf
-func (t *Terminal) queue(data []rune) {
- t.outBuf = append(t.outBuf, []byte(string(data))...)
-}
-
-var eraseUnderCursor = []rune{' ', keyEscape, '[', 'D'}
-var space = []rune{' '}
-
-func isPrintable(key rune) bool {
- isInSurrogateArea := key >= 0xd800 && key <= 0xdbff
- return key >= 32 && !isInSurrogateArea
-}
-
-// moveCursorToPos appends data to t.outBuf which will move the cursor to the
-// given, logical position in the text.
-func (t *Terminal) moveCursorToPos(pos int) {
- if !t.echo {
- return
- }
-
- x := visualLength(t.prompt) + pos
- y := x / t.termWidth
- x = x % t.termWidth
-
- up := 0
- if y < t.cursorY {
- up = t.cursorY - y
- }
-
- down := 0
- if y > t.cursorY {
- down = y - t.cursorY
- }
-
- left := 0
- if x < t.cursorX {
- left = t.cursorX - x
- }
-
- right := 0
- if x > t.cursorX {
- right = x - t.cursorX
- }
-
- t.cursorX = x
- t.cursorY = y
- t.move(up, down, left, right)
-}
-
-func (t *Terminal) move(up, down, left, right int) {
- movement := make([]rune, 3*(up+down+left+right))
- m := movement
- for i := 0; i < up; i++ {
- m[0] = keyEscape
- m[1] = '['
- m[2] = 'A'
- m = m[3:]
- }
- for i := 0; i < down; i++ {
- m[0] = keyEscape
- m[1] = '['
- m[2] = 'B'
- m = m[3:]
- }
- for i := 0; i < left; i++ {
- m[0] = keyEscape
- m[1] = '['
- m[2] = 'D'
- m = m[3:]
- }
- for i := 0; i < right; i++ {
- m[0] = keyEscape
- m[1] = '['
- m[2] = 'C'
- m = m[3:]
- }
-
- t.queue(movement)
-}
-
-func (t *Terminal) clearLineToRight() {
- op := []rune{keyEscape, '[', 'K'}
- t.queue(op)
-}
-
-const maxLineLength = 4096
-
-func (t *Terminal) setLine(newLine []rune, newPos int) {
- if t.echo {
- t.moveCursorToPos(0)
- t.writeLine(newLine)
- for i := len(newLine); i < len(t.line); i++ {
- t.writeLine(space)
- }
- t.moveCursorToPos(newPos)
- }
- t.line = newLine
- t.pos = newPos
-}
-
-func (t *Terminal) advanceCursor(places int) {
- t.cursorX += places
- t.cursorY += t.cursorX / t.termWidth
- if t.cursorY > t.maxLine {
- t.maxLine = t.cursorY
- }
- t.cursorX = t.cursorX % t.termWidth
-
- if places > 0 && t.cursorX == 0 {
- // Normally terminals will advance the current position
- // when writing a character. But that doesn't happen
- // for the last character in a line. However, when
- // writing a character (except a new line) that causes
- // a line wrap, the position will be advanced two
- // places.
- //
- // So, if we are stopping at the end of a line, we
- // need to write a newline so that our cursor can be
- // advanced to the next line.
- t.outBuf = append(t.outBuf, '\n')
- }
-}
-
-func (t *Terminal) eraseNPreviousChars(n int) {
- if n == 0 {
- return
- }
-
- if t.pos < n {
- n = t.pos
- }
- t.pos -= n
- t.moveCursorToPos(t.pos)
-
- copy(t.line[t.pos:], t.line[n+t.pos:])
- t.line = t.line[:len(t.line)-n]
- if t.echo {
- t.writeLine(t.line[t.pos:])
- for i := 0; i < n; i++ {
- t.queue(space)
- }
- t.advanceCursor(n)
- t.moveCursorToPos(t.pos)
- }
-}
-
-// countToLeftWord returns then number of characters from the cursor to the
-// start of the previous word.
-func (t *Terminal) countToLeftWord() int {
- if t.pos == 0 {
- return 0
- }
-
- pos := t.pos - 1
- for pos > 0 {
- if t.line[pos] != ' ' {
- break
- }
- pos--
- }
- for pos > 0 {
- if t.line[pos] == ' ' {
- pos++
- break
- }
- pos--
- }
-
- return t.pos - pos
-}
-
-// countToRightWord returns then number of characters from the cursor to the
-// start of the next word.
-func (t *Terminal) countToRightWord() int {
- pos := t.pos
- for pos < len(t.line) {
- if t.line[pos] == ' ' {
- break
- }
- pos++
- }
- for pos < len(t.line) {
- if t.line[pos] != ' ' {
- break
- }
- pos++
- }
- return pos - t.pos
-}
-
-// visualLength returns the number of visible glyphs in s.
-func visualLength(runes []rune) int {
- inEscapeSeq := false
- length := 0
-
- for _, r := range runes {
- switch {
- case inEscapeSeq:
- if (r >= 'a' && r <= 'z') || (r >= 'A' && r <= 'Z') {
- inEscapeSeq = false
- }
- case r == '\x1b':
- inEscapeSeq = true
- default:
- length++
- }
- }
-
- return length
-}
-
-// handleKey processes the given key and, optionally, returns a line of text
-// that the user has entered.
-func (t *Terminal) handleKey(key rune) (line string, ok bool) {
- if t.pasteActive && key != keyEnter {
- t.addKeyToLine(key)
- return
- }
-
- switch key {
- case keyBackspace:
- if t.pos == 0 {
- return
- }
- t.eraseNPreviousChars(1)
- case keyAltLeft:
- // move left by a word.
- t.pos -= t.countToLeftWord()
- t.moveCursorToPos(t.pos)
- case keyAltRight:
- // move right by a word.
- t.pos += t.countToRightWord()
- t.moveCursorToPos(t.pos)
- case keyLeft:
- if t.pos == 0 {
- return
- }
- t.pos--
- t.moveCursorToPos(t.pos)
- case keyRight:
- if t.pos == len(t.line) {
- return
- }
- t.pos++
- t.moveCursorToPos(t.pos)
- case keyHome:
- if t.pos == 0 {
- return
- }
- t.pos = 0
- t.moveCursorToPos(t.pos)
- case keyEnd:
- if t.pos == len(t.line) {
- return
- }
- t.pos = len(t.line)
- t.moveCursorToPos(t.pos)
- case keyUp:
- entry, ok := t.history.NthPreviousEntry(t.historyIndex + 1)
- if !ok {
- return "", false
- }
- if t.historyIndex == -1 {
- t.historyPending = string(t.line)
- }
- t.historyIndex++
- runes := []rune(entry)
- t.setLine(runes, len(runes))
- case keyDown:
- switch t.historyIndex {
- case -1:
- return
- case 0:
- runes := []rune(t.historyPending)
- t.setLine(runes, len(runes))
- t.historyIndex--
- default:
- entry, ok := t.history.NthPreviousEntry(t.historyIndex - 1)
- if ok {
- t.historyIndex--
- runes := []rune(entry)
- t.setLine(runes, len(runes))
- }
- }
- case keyEnter:
- t.moveCursorToPos(len(t.line))
- t.queue([]rune("\r\n"))
- line = string(t.line)
- ok = true
- t.line = t.line[:0]
- t.pos = 0
- t.cursorX = 0
- t.cursorY = 0
- t.maxLine = 0
- case keyDeleteWord:
- // Delete zero or more spaces and then one or more characters.
- t.eraseNPreviousChars(t.countToLeftWord())
- case keyDeleteLine:
- // Delete everything from the current cursor position to the
- // end of line.
- for i := t.pos; i < len(t.line); i++ {
- t.queue(space)
- t.advanceCursor(1)
- }
- t.line = t.line[:t.pos]
- t.moveCursorToPos(t.pos)
- case keyCtrlD:
- // Erase the character under the current position.
- // The EOF case when the line is empty is handled in
- // readLine().
- if t.pos < len(t.line) {
- t.pos++
- t.eraseNPreviousChars(1)
- }
- case keyCtrlU:
- t.eraseNPreviousChars(t.pos)
- case keyClearScreen:
- // Erases the screen and moves the cursor to the home position.
- t.queue([]rune("\x1b[2J\x1b[H"))
- t.queue(t.prompt)
- t.cursorX, t.cursorY = 0, 0
- t.advanceCursor(visualLength(t.prompt))
- t.setLine(t.line, t.pos)
- default:
- if t.AutoCompleteCallback != nil {
- prefix := string(t.line[:t.pos])
- suffix := string(t.line[t.pos:])
-
- t.lock.Unlock()
- newLine, newPos, completeOk := t.AutoCompleteCallback(prefix+suffix, len(prefix), key)
- t.lock.Lock()
-
- if completeOk {
- t.setLine([]rune(newLine), utf8.RuneCount([]byte(newLine)[:newPos]))
- return
- }
- }
- if !isPrintable(key) {
- return
- }
- if len(t.line) == maxLineLength {
- return
- }
- t.addKeyToLine(key)
- }
- return
-}
-
-// addKeyToLine inserts the given key at the current position in the current
-// line.
-func (t *Terminal) addKeyToLine(key rune) {
- if len(t.line) == cap(t.line) {
- newLine := make([]rune, len(t.line), 2*(1+len(t.line)))
- copy(newLine, t.line)
- t.line = newLine
- }
- t.line = t.line[:len(t.line)+1]
- copy(t.line[t.pos+1:], t.line[t.pos:])
- t.line[t.pos] = key
- if t.echo {
- t.writeLine(t.line[t.pos:])
- }
- t.pos++
- t.moveCursorToPos(t.pos)
-}
-
-func (t *Terminal) writeLine(line []rune) {
- for len(line) != 0 {
- remainingOnLine := t.termWidth - t.cursorX
- todo := len(line)
- if todo > remainingOnLine {
- todo = remainingOnLine
- }
- t.queue(line[:todo])
- t.advanceCursor(visualLength(line[:todo]))
- line = line[todo:]
- }
-}
-
-func (t *Terminal) Write(buf []byte) (n int, err error) {
- t.lock.Lock()
- defer t.lock.Unlock()
-
- if t.cursorX == 0 && t.cursorY == 0 {
- // This is the easy case: there's nothing on the screen that we
- // have to move out of the way.
- return t.c.Write(buf)
- }
-
- // We have a prompt and possibly user input on the screen. We
- // have to clear it first.
- t.move(0 /* up */, 0 /* down */, t.cursorX /* left */, 0 /* right */)
- t.cursorX = 0
- t.clearLineToRight()
-
- for t.cursorY > 0 {
- t.move(1 /* up */, 0, 0, 0)
- t.cursorY--
- t.clearLineToRight()
- }
-
- if _, err = t.c.Write(t.outBuf); err != nil {
- return
- }
- t.outBuf = t.outBuf[:0]
-
- if n, err = t.c.Write(buf); err != nil {
- return
- }
-
- t.writeLine(t.prompt)
- if t.echo {
- t.writeLine(t.line)
- }
-
- t.moveCursorToPos(t.pos)
-
- if _, err = t.c.Write(t.outBuf); err != nil {
- return
- }
- t.outBuf = t.outBuf[:0]
- return
-}
-
-// ReadPassword temporarily changes the prompt and reads a password, without
-// echo, from the terminal.
-func (t *Terminal) ReadPassword(prompt string) (line string, err error) {
- t.lock.Lock()
- defer t.lock.Unlock()
-
- oldPrompt := t.prompt
- t.prompt = []rune(prompt)
- t.echo = false
-
- line, err = t.readLine()
-
- t.prompt = oldPrompt
- t.echo = true
-
- return
-}
-
-// ReadLine returns a line of input from the terminal.
-func (t *Terminal) ReadLine() (line string, err error) {
- t.lock.Lock()
- defer t.lock.Unlock()
-
- return t.readLine()
-}
-
-func (t *Terminal) readLine() (line string, err error) {
- // t.lock must be held at this point
-
- if t.cursorX == 0 && t.cursorY == 0 {
- t.writeLine(t.prompt)
- t.c.Write(t.outBuf)
- t.outBuf = t.outBuf[:0]
- }
-
- lineIsPasted := t.pasteActive
-
- for {
- rest := t.remainder
- lineOk := false
- for !lineOk {
- var key rune
- key, rest = bytesToKey(rest, t.pasteActive)
- if key == utf8.RuneError {
- break
- }
- if !t.pasteActive {
- if key == keyCtrlD {
- if len(t.line) == 0 {
- return "", io.EOF
- }
- }
- if key == keyPasteStart {
- t.pasteActive = true
- if len(t.line) == 0 {
- lineIsPasted = true
- }
- continue
- }
- } else if key == keyPasteEnd {
- t.pasteActive = false
- continue
- }
- if !t.pasteActive {
- lineIsPasted = false
- }
- line, lineOk = t.handleKey(key)
- }
- if len(rest) > 0 {
- n := copy(t.inBuf[:], rest)
- t.remainder = t.inBuf[:n]
- } else {
- t.remainder = nil
- }
- t.c.Write(t.outBuf)
- t.outBuf = t.outBuf[:0]
- if lineOk {
- if t.echo {
- t.historyIndex = -1
- t.history.Add(line)
- }
- if lineIsPasted {
- err = ErrPasteIndicator
- }
- return
- }
-
- // t.remainder is a slice at the beginning of t.inBuf
- // containing a partial key sequence
- readBuf := t.inBuf[len(t.remainder):]
- var n int
-
- t.lock.Unlock()
- n, err = t.c.Read(readBuf)
- t.lock.Lock()
-
- if err != nil {
- return
- }
-
- t.remainder = t.inBuf[:n+len(t.remainder)]
- }
-
- panic("unreachable") // for Go 1.0.
-}
-
-// SetPrompt sets the prompt to be used when reading subsequent lines.
-func (t *Terminal) SetPrompt(prompt string) {
- t.lock.Lock()
- defer t.lock.Unlock()
-
- t.prompt = []rune(prompt)
-}
-
-func (t *Terminal) clearAndRepaintLinePlusNPrevious(numPrevLines int) {
- // Move cursor to column zero at the start of the line.
- t.move(t.cursorY, 0, t.cursorX, 0)
- t.cursorX, t.cursorY = 0, 0
- t.clearLineToRight()
- for t.cursorY < numPrevLines {
- // Move down a line
- t.move(0, 1, 0, 0)
- t.cursorY++
- t.clearLineToRight()
- }
- // Move back to beginning.
- t.move(t.cursorY, 0, 0, 0)
- t.cursorX, t.cursorY = 0, 0
-
- t.queue(t.prompt)
- t.advanceCursor(visualLength(t.prompt))
- t.writeLine(t.line)
- t.moveCursorToPos(t.pos)
-}
-
-func (t *Terminal) SetSize(width, height int) error {
- t.lock.Lock()
- defer t.lock.Unlock()
-
- if width == 0 {
- width = 1
- }
-
- oldWidth := t.termWidth
- t.termWidth, t.termHeight = width, height
-
- switch {
- case width == oldWidth:
- // If the width didn't change then nothing else needs to be
- // done.
- return nil
- case len(t.line) == 0 && t.cursorX == 0 && t.cursorY == 0:
- // If there is nothing on current line and no prompt printed,
- // just do nothing
- return nil
- case width < oldWidth:
- // Some terminals (e.g. xterm) will truncate lines that were
- // too long when shinking. Others, (e.g. gnome-terminal) will
- // attempt to wrap them. For the former, repainting t.maxLine
- // works great, but that behaviour goes badly wrong in the case
- // of the latter because they have doubled every full line.
-
- // We assume that we are working on a terminal that wraps lines
- // and adjust the cursor position based on every previous line
- // wrapping and turning into two. This causes the prompt on
- // xterms to move upwards, which isn't great, but it avoids a
- // huge mess with gnome-terminal.
- if t.cursorX >= t.termWidth {
- t.cursorX = t.termWidth - 1
- }
- t.cursorY *= 2
- t.clearAndRepaintLinePlusNPrevious(t.maxLine * 2)
- case width > oldWidth:
- // If the terminal expands then our position calculations will
- // be wrong in the future because we think the cursor is
- // |t.pos| chars into the string, but there will be a gap at
- // the end of any wrapped line.
- //
- // But the position will actually be correct until we move, so
- // we can move back to the beginning and repaint everything.
- t.clearAndRepaintLinePlusNPrevious(t.maxLine)
- }
-
- _, err := t.c.Write(t.outBuf)
- t.outBuf = t.outBuf[:0]
- return err
-}
-
-type pasteIndicatorError struct{}
-
-func (pasteIndicatorError) Error() string {
- return "terminal: ErrPasteIndicator not correctly handled"
-}
-
-// ErrPasteIndicator may be returned from ReadLine as the error, in addition
-// to valid line data. It indicates that bracketed paste mode is enabled and
-// that the returned line consists only of pasted data. Programs may wish to
-// interpret pasted data more literally than typed data.
-var ErrPasteIndicator = pasteIndicatorError{}
-
-// SetBracketedPasteMode requests that the terminal bracket paste operations
-// with markers. Not all terminals support this but, if it is supported, then
-// enabling this mode will stop any autocomplete callback from running due to
-// pastes. Additionally, any lines that are completely pasted will be returned
-// from ReadLine with the error set to ErrPasteIndicator.
-func (t *Terminal) SetBracketedPasteMode(on bool) {
- if on {
- io.WriteString(t.c, "\x1b[?2004h")
- } else {
- io.WriteString(t.c, "\x1b[?2004l")
- }
-}
-
-// stRingBuffer is a ring buffer of strings.
-type stRingBuffer struct {
- // entries contains max elements.
- entries []string
- max int
- // head contains the index of the element most recently added to the ring.
- head int
- // size contains the number of elements in the ring.
- size int
-}
-
-func (s *stRingBuffer) Add(a string) {
- if s.entries == nil {
- const defaultNumEntries = 100
- s.entries = make([]string, defaultNumEntries)
- s.max = defaultNumEntries
- }
-
- s.head = (s.head + 1) % s.max
- s.entries[s.head] = a
- if s.size < s.max {
- s.size++
- }
-}
-
-// NthPreviousEntry returns the value passed to the nth previous call to Add.
-// If n is zero then the immediately prior value is returned, if one, then the
-// next most recent, and so on. If such an element doesn't exist then ok is
-// false.
-func (s *stRingBuffer) NthPreviousEntry(n int) (value string, ok bool) {
- if n >= s.size {
- return "", false
- }
- index := s.head - n
- if index < 0 {
- index += s.max
- }
- return s.entries[index], true
-}
diff --git a/vendor/golang.org/x/crypto/ssh/terminal/terminal_test.go b/vendor/golang.org/x/crypto/ssh/terminal/terminal_test.go
deleted file mode 100644
index a663fe41..00000000
--- a/vendor/golang.org/x/crypto/ssh/terminal/terminal_test.go
+++ /dev/null
@@ -1,269 +0,0 @@
-// Copyright 2011 The Go Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style
-// license that can be found in the LICENSE file.
-
-package terminal
-
-import (
- "io"
- "testing"
-)
-
-type MockTerminal struct {
- toSend []byte
- bytesPerRead int
- received []byte
-}
-
-func (c *MockTerminal) Read(data []byte) (n int, err error) {
- n = len(data)
- if n == 0 {
- return
- }
- if n > len(c.toSend) {
- n = len(c.toSend)
- }
- if n == 0 {
- return 0, io.EOF
- }
- if c.bytesPerRead > 0 && n > c.bytesPerRead {
- n = c.bytesPerRead
- }
- copy(data, c.toSend[:n])
- c.toSend = c.toSend[n:]
- return
-}
-
-func (c *MockTerminal) Write(data []byte) (n int, err error) {
- c.received = append(c.received, data...)
- return len(data), nil
-}
-
-func TestClose(t *testing.T) {
- c := &MockTerminal{}
- ss := NewTerminal(c, "> ")
- line, err := ss.ReadLine()
- if line != "" {
- t.Errorf("Expected empty line but got: %s", line)
- }
- if err != io.EOF {
- t.Errorf("Error should have been EOF but got: %s", err)
- }
-}
-
-var keyPressTests = []struct {
- in string
- line string
- err error
- throwAwayLines int
-}{
- {
- err: io.EOF,
- },
- {
- in: "\r",
- line: "",
- },
- {
- in: "foo\r",
- line: "foo",
- },
- {
- in: "a\x1b[Cb\r", // right
- line: "ab",
- },
- {
- in: "a\x1b[Db\r", // left
- line: "ba",
- },
- {
- in: "a\177b\r", // backspace
- line: "b",
- },
- {
- in: "\x1b[A\r", // up
- },
- {
- in: "\x1b[B\r", // down
- },
- {
- in: "line\x1b[A\x1b[B\r", // up then down
- line: "line",
- },
- {
- in: "line1\rline2\x1b[A\r", // recall previous line.
- line: "line1",
- throwAwayLines: 1,
- },
- {
- // recall two previous lines and append.
- in: "line1\rline2\rline3\x1b[A\x1b[Axxx\r",
- line: "line1xxx",
- throwAwayLines: 2,
- },
- {
- // Ctrl-A to move to beginning of line followed by ^K to kill
- // line.
- in: "a b \001\013\r",
- line: "",
- },
- {
- // Ctrl-A to move to beginning of line, Ctrl-E to move to end,
- // finally ^K to kill nothing.
- in: "a b \001\005\013\r",
- line: "a b ",
- },
- {
- in: "\027\r",
- line: "",
- },
- {
- in: "a\027\r",
- line: "",
- },
- {
- in: "a \027\r",
- line: "",
- },
- {
- in: "a b\027\r",
- line: "a ",
- },
- {
- in: "a b \027\r",
- line: "a ",
- },
- {
- in: "one two thr\x1b[D\027\r",
- line: "one two r",
- },
- {
- in: "\013\r",
- line: "",
- },
- {
- in: "a\013\r",
- line: "a",
- },
- {
- in: "ab\x1b[D\013\r",
- line: "a",
- },
- {
- in: "Ξεσκεπάζω\r",
- line: "Ξεσκεπάζω",
- },
- {
- in: "£\r\x1b[A\177\r", // non-ASCII char, enter, up, backspace.
- line: "",
- throwAwayLines: 1,
- },
- {
- in: "£\r££\x1b[A\x1b[B\177\r", // non-ASCII char, enter, 2x non-ASCII, up, down, backspace, enter.
- line: "£",
- throwAwayLines: 1,
- },
- {
- // Ctrl-D at the end of the line should be ignored.
- in: "a\004\r",
- line: "a",
- },
- {
- // a, b, left, Ctrl-D should erase the b.
- in: "ab\x1b[D\004\r",
- line: "a",
- },
- {
- // a, b, c, d, left, left, ^U should erase to the beginning of
- // the line.
- in: "abcd\x1b[D\x1b[D\025\r",
- line: "cd",
- },
- {
- // Bracketed paste mode: control sequences should be returned
- // verbatim in paste mode.
- in: "abc\x1b[200~de\177f\x1b[201~\177\r",
- line: "abcde\177",
- },
- {
- // Enter in bracketed paste mode should still work.
- in: "abc\x1b[200~d\refg\x1b[201~h\r",
- line: "efgh",
- throwAwayLines: 1,
- },
- {
- // Lines consisting entirely of pasted data should be indicated as such.
- in: "\x1b[200~a\r",
- line: "a",
- err: ErrPasteIndicator,
- },
-}
-
-func TestKeyPresses(t *testing.T) {
- for i, test := range keyPressTests {
- for j := 1; j < len(test.in); j++ {
- c := &MockTerminal{
- toSend: []byte(test.in),
- bytesPerRead: j,
- }
- ss := NewTerminal(c, "> ")
- for k := 0; k < test.throwAwayLines; k++ {
- _, err := ss.ReadLine()
- if err != nil {
- t.Errorf("Throwaway line %d from test %d resulted in error: %s", k, i, err)
- }
- }
- line, err := ss.ReadLine()
- if line != test.line {
- t.Errorf("Line resulting from test %d (%d bytes per read) was '%s', expected '%s'", i, j, line, test.line)
- break
- }
- if err != test.err {
- t.Errorf("Error resulting from test %d (%d bytes per read) was '%v', expected '%v'", i, j, err, test.err)
- break
- }
- }
- }
-}
-
-func TestPasswordNotSaved(t *testing.T) {
- c := &MockTerminal{
- toSend: []byte("password\r\x1b[A\r"),
- bytesPerRead: 1,
- }
- ss := NewTerminal(c, "> ")
- pw, _ := ss.ReadPassword("> ")
- if pw != "password" {
- t.Fatalf("failed to read password, got %s", pw)
- }
- line, _ := ss.ReadLine()
- if len(line) > 0 {
- t.Fatalf("password was saved in history")
- }
-}
-
-var setSizeTests = []struct {
- width, height int
-}{
- {40, 13},
- {80, 24},
- {132, 43},
-}
-
-func TestTerminalSetSize(t *testing.T) {
- for _, setSize := range setSizeTests {
- c := &MockTerminal{
- toSend: []byte("password\r\x1b[A\r"),
- bytesPerRead: 1,
- }
- ss := NewTerminal(c, "> ")
- ss.SetSize(setSize.width, setSize.height)
- pw, _ := ss.ReadPassword("Password: ")
- if pw != "password" {
- t.Fatalf("failed to read password, got %s", pw)
- }
- if string(c.received) != "Password: \r\n" {
- t.Errorf("failed to set the temporary prompt expected %q, got %q", "Password: ", c.received)
- }
- }
-}
diff --git a/vendor/golang.org/x/crypto/ssh/terminal/util.go b/vendor/golang.org/x/crypto/ssh/terminal/util.go
deleted file mode 100644
index 0763c9a9..00000000
--- a/vendor/golang.org/x/crypto/ssh/terminal/util.go
+++ /dev/null
@@ -1,128 +0,0 @@
-// Copyright 2011 The Go Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style
-// license that can be found in the LICENSE file.
-
-// +build darwin dragonfly freebsd linux,!appengine netbsd openbsd
-
-// Package terminal provides support functions for dealing with terminals, as
-// commonly found on UNIX systems.
-//
-// Putting a terminal into raw mode is the most common requirement:
-//
-// oldState, err := terminal.MakeRaw(0)
-// if err != nil {
-// panic(err)
-// }
-// defer terminal.Restore(0, oldState)
-package terminal
-
-import (
- "io"
- "syscall"
- "unsafe"
-)
-
-// State contains the state of a terminal.
-type State struct {
- termios syscall.Termios
-}
-
-// IsTerminal returns true if the given file descriptor is a terminal.
-func IsTerminal(fd int) bool {
- var termios syscall.Termios
- _, _, err := syscall.Syscall6(syscall.SYS_IOCTL, uintptr(fd), ioctlReadTermios, uintptr(unsafe.Pointer(&termios)), 0, 0, 0)
- return err == 0
-}
-
-// MakeRaw put the terminal connected to the given file descriptor into raw
-// mode and returns the previous state of the terminal so that it can be
-// restored.
-func MakeRaw(fd int) (*State, error) {
- var oldState State
- if _, _, err := syscall.Syscall6(syscall.SYS_IOCTL, uintptr(fd), ioctlReadTermios, uintptr(unsafe.Pointer(&oldState.termios)), 0, 0, 0); err != 0 {
- return nil, err
- }
-
- newState := oldState.termios
- newState.Iflag &^= syscall.ISTRIP | syscall.INLCR | syscall.ICRNL | syscall.IGNCR | syscall.IXON | syscall.IXOFF
- newState.Lflag &^= syscall.ECHO | syscall.ICANON | syscall.ISIG
- if _, _, err := syscall.Syscall6(syscall.SYS_IOCTL, uintptr(fd), ioctlWriteTermios, uintptr(unsafe.Pointer(&newState)), 0, 0, 0); err != 0 {
- return nil, err
- }
-
- return &oldState, nil
-}
-
-// GetState returns the current state of a terminal which may be useful to
-// restore the terminal after a signal.
-func GetState(fd int) (*State, error) {
- var oldState State
- if _, _, err := syscall.Syscall6(syscall.SYS_IOCTL, uintptr(fd), ioctlReadTermios, uintptr(unsafe.Pointer(&oldState.termios)), 0, 0, 0); err != 0 {
- return nil, err
- }
-
- return &oldState, nil
-}
-
-// Restore restores the terminal connected to the given file descriptor to a
-// previous state.
-func Restore(fd int, state *State) error {
- _, _, err := syscall.Syscall6(syscall.SYS_IOCTL, uintptr(fd), ioctlWriteTermios, uintptr(unsafe.Pointer(&state.termios)), 0, 0, 0)
- return err
-}
-
-// GetSize returns the dimensions of the given terminal.
-func GetSize(fd int) (width, height int, err error) {
- var dimensions [4]uint16
-
- if _, _, err := syscall.Syscall6(syscall.SYS_IOCTL, uintptr(fd), uintptr(syscall.TIOCGWINSZ), uintptr(unsafe.Pointer(&dimensions)), 0, 0, 0); err != 0 {
- return -1, -1, err
- }
- return int(dimensions[1]), int(dimensions[0]), nil
-}
-
-// ReadPassword reads a line of input from a terminal without local echo. This
-// is commonly used for inputting passwords and other sensitive data. The slice
-// returned does not include the \n.
-func ReadPassword(fd int) ([]byte, error) {
- var oldState syscall.Termios
- if _, _, err := syscall.Syscall6(syscall.SYS_IOCTL, uintptr(fd), ioctlReadTermios, uintptr(unsafe.Pointer(&oldState)), 0, 0, 0); err != 0 {
- return nil, err
- }
-
- newState := oldState
- newState.Lflag &^= syscall.ECHO
- newState.Lflag |= syscall.ICANON | syscall.ISIG
- newState.Iflag |= syscall.ICRNL
- if _, _, err := syscall.Syscall6(syscall.SYS_IOCTL, uintptr(fd), ioctlWriteTermios, uintptr(unsafe.Pointer(&newState)), 0, 0, 0); err != 0 {
- return nil, err
- }
-
- defer func() {
- syscall.Syscall6(syscall.SYS_IOCTL, uintptr(fd), ioctlWriteTermios, uintptr(unsafe.Pointer(&oldState)), 0, 0, 0)
- }()
-
- var buf [16]byte
- var ret []byte
- for {
- n, err := syscall.Read(fd, buf[:])
- if err != nil {
- return nil, err
- }
- if n == 0 {
- if len(ret) == 0 {
- return nil, io.EOF
- }
- break
- }
- if buf[n-1] == '\n' {
- n--
- }
- ret = append(ret, buf[:n]...)
- if n < len(buf) {
- break
- }
- }
-
- return ret, nil
-}
diff --git a/vendor/golang.org/x/crypto/ssh/terminal/util_bsd.go b/vendor/golang.org/x/crypto/ssh/terminal/util_bsd.go
deleted file mode 100644
index 9c1ffd14..00000000
--- a/vendor/golang.org/x/crypto/ssh/terminal/util_bsd.go
+++ /dev/null
@@ -1,12 +0,0 @@
-// Copyright 2013 The Go Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style
-// license that can be found in the LICENSE file.
-
-// +build darwin dragonfly freebsd netbsd openbsd
-
-package terminal
-
-import "syscall"
-
-const ioctlReadTermios = syscall.TIOCGETA
-const ioctlWriteTermios = syscall.TIOCSETA
diff --git a/vendor/golang.org/x/crypto/ssh/terminal/util_linux.go b/vendor/golang.org/x/crypto/ssh/terminal/util_linux.go
deleted file mode 100644
index 5883b22d..00000000
--- a/vendor/golang.org/x/crypto/ssh/terminal/util_linux.go
+++ /dev/null
@@ -1,11 +0,0 @@
-// Copyright 2013 The Go Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style
-// license that can be found in the LICENSE file.
-
-package terminal
-
-// These constants are declared here, rather than importing
-// them from the syscall package as some syscall packages, even
-// on linux, for example gccgo, do not declare them.
-const ioctlReadTermios = 0x5401 // syscall.TCGETS
-const ioctlWriteTermios = 0x5402 // syscall.TCSETS
diff --git a/vendor/golang.org/x/crypto/ssh/terminal/util_windows.go b/vendor/golang.org/x/crypto/ssh/terminal/util_windows.go
deleted file mode 100644
index 2dd6c3d9..00000000
--- a/vendor/golang.org/x/crypto/ssh/terminal/util_windows.go
+++ /dev/null
@@ -1,174 +0,0 @@
-// Copyright 2011 The Go Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style
-// license that can be found in the LICENSE file.
-
-// +build windows
-
-// Package terminal provides support functions for dealing with terminals, as
-// commonly found on UNIX systems.
-//
-// Putting a terminal into raw mode is the most common requirement:
-//
-// oldState, err := terminal.MakeRaw(0)
-// if err != nil {
-// panic(err)
-// }
-// defer terminal.Restore(0, oldState)
-package terminal
-
-import (
- "io"
- "syscall"
- "unsafe"
-)
-
-const (
- enableLineInput = 2
- enableEchoInput = 4
- enableProcessedInput = 1
- enableWindowInput = 8
- enableMouseInput = 16
- enableInsertMode = 32
- enableQuickEditMode = 64
- enableExtendedFlags = 128
- enableAutoPosition = 256
- enableProcessedOutput = 1
- enableWrapAtEolOutput = 2
-)
-
-var kernel32 = syscall.NewLazyDLL("kernel32.dll")
-
-var (
- procGetConsoleMode = kernel32.NewProc("GetConsoleMode")
- procSetConsoleMode = kernel32.NewProc("SetConsoleMode")
- procGetConsoleScreenBufferInfo = kernel32.NewProc("GetConsoleScreenBufferInfo")
-)
-
-type (
- short int16
- word uint16
-
- coord struct {
- x short
- y short
- }
- smallRect struct {
- left short
- top short
- right short
- bottom short
- }
- consoleScreenBufferInfo struct {
- size coord
- cursorPosition coord
- attributes word
- window smallRect
- maximumWindowSize coord
- }
-)
-
-type State struct {
- mode uint32
-}
-
-// IsTerminal returns true if the given file descriptor is a terminal.
-func IsTerminal(fd int) bool {
- var st uint32
- r, _, e := syscall.Syscall(procGetConsoleMode.Addr(), 2, uintptr(fd), uintptr(unsafe.Pointer(&st)), 0)
- return r != 0 && e == 0
-}
-
-// MakeRaw put the terminal connected to the given file descriptor into raw
-// mode and returns the previous state of the terminal so that it can be
-// restored.
-func MakeRaw(fd int) (*State, error) {
- var st uint32
- _, _, e := syscall.Syscall(procGetConsoleMode.Addr(), 2, uintptr(fd), uintptr(unsafe.Pointer(&st)), 0)
- if e != 0 {
- return nil, error(e)
- }
- st &^= (enableEchoInput | enableProcessedInput | enableLineInput | enableProcessedOutput)
- _, _, e = syscall.Syscall(procSetConsoleMode.Addr(), 2, uintptr(fd), uintptr(st), 0)
- if e != 0 {
- return nil, error(e)
- }
- return &State{st}, nil
-}
-
-// GetState returns the current state of a terminal which may be useful to
-// restore the terminal after a signal.
-func GetState(fd int) (*State, error) {
- var st uint32
- _, _, e := syscall.Syscall(procGetConsoleMode.Addr(), 2, uintptr(fd), uintptr(unsafe.Pointer(&st)), 0)
- if e != 0 {
- return nil, error(e)
- }
- return &State{st}, nil
-}
-
-// Restore restores the terminal connected to the given file descriptor to a
-// previous state.
-func Restore(fd int, state *State) error {
- _, _, err := syscall.Syscall(procSetConsoleMode.Addr(), 2, uintptr(fd), uintptr(state.mode), 0)
- return err
-}
-
-// GetSize returns the dimensions of the given terminal.
-func GetSize(fd int) (width, height int, err error) {
- var info consoleScreenBufferInfo
- _, _, e := syscall.Syscall(procGetConsoleScreenBufferInfo.Addr(), 2, uintptr(fd), uintptr(unsafe.Pointer(&info)), 0)
- if e != 0 {
- return 0, 0, error(e)
- }
- return int(info.size.x), int(info.size.y), nil
-}
-
-// ReadPassword reads a line of input from a terminal without local echo. This
-// is commonly used for inputting passwords and other sensitive data. The slice
-// returned does not include the \n.
-func ReadPassword(fd int) ([]byte, error) {
- var st uint32
- _, _, e := syscall.Syscall(procGetConsoleMode.Addr(), 2, uintptr(fd), uintptr(unsafe.Pointer(&st)), 0)
- if e != 0 {
- return nil, error(e)
- }
- old := st
-
- st &^= (enableEchoInput)
- st |= (enableProcessedInput | enableLineInput | enableProcessedOutput)
- _, _, e = syscall.Syscall(procSetConsoleMode.Addr(), 2, uintptr(fd), uintptr(st), 0)
- if e != 0 {
- return nil, error(e)
- }
-
- defer func() {
- syscall.Syscall(procSetConsoleMode.Addr(), 2, uintptr(fd), uintptr(old), 0)
- }()
-
- var buf [16]byte
- var ret []byte
- for {
- n, err := syscall.Read(syscall.Handle(fd), buf[:])
- if err != nil {
- return nil, err
- }
- if n == 0 {
- if len(ret) == 0 {
- return nil, io.EOF
- }
- break
- }
- if buf[n-1] == '\n' {
- n--
- }
- if n > 0 && buf[n-1] == '\r' {
- n--
- }
- ret = append(ret, buf[:n]...)
- if n < len(buf) {
- break
- }
- }
-
- return ret, nil
-}
diff --git a/vendor/golang.org/x/net/context/context.go b/vendor/golang.org/x/net/context/context.go
index 11bd8d34..56efb95b 100644
--- a/vendor/golang.org/x/net/context/context.go
+++ b/vendor/golang.org/x/net/context/context.go
@@ -36,12 +36,7 @@
// Contexts.
package context
-import (
- "errors"
- "fmt"
- "sync"
- "time"
-)
+import "time"
// A Context carries a deadline, a cancelation signal, and other values across
// API boundaries.
@@ -138,48 +133,6 @@ type Context interface {
Value(key interface{}) interface{}
}
-// Canceled is the error returned by Context.Err when the context is canceled.
-var Canceled = errors.New("context canceled")
-
-// DeadlineExceeded is the error returned by Context.Err when the context's
-// deadline passes.
-var DeadlineExceeded = errors.New("context deadline exceeded")
-
-// An emptyCtx is never canceled, has no values, and has no deadline. It is not
-// struct{}, since vars of this type must have distinct addresses.
-type emptyCtx int
-
-func (*emptyCtx) Deadline() (deadline time.Time, ok bool) {
- return
-}
-
-func (*emptyCtx) Done() <-chan struct{} {
- return nil
-}
-
-func (*emptyCtx) Err() error {
- return nil
-}
-
-func (*emptyCtx) Value(key interface{}) interface{} {
- return nil
-}
-
-func (e *emptyCtx) String() string {
- switch e {
- case background:
- return "context.Background"
- case todo:
- return "context.TODO"
- }
- return "unknown empty Context"
-}
-
-var (
- background = new(emptyCtx)
- todo = new(emptyCtx)
-)
-
// Background returns a non-nil, empty Context. It is never canceled, has no
// values, and has no deadline. It is typically used by the main function,
// initialization, and tests, and as the top-level Context for incoming
@@ -201,247 +154,3 @@ func TODO() Context {
// A CancelFunc does not wait for the work to stop.
// After the first call, subsequent calls to a CancelFunc do nothing.
type CancelFunc func()
-
-// WithCancel returns a copy of parent with a new Done channel. The returned
-// context's Done channel is closed when the returned cancel function is called
-// or when the parent context's Done channel is closed, whichever happens first.
-//
-// Canceling this context releases resources associated with it, so code should
-// call cancel as soon as the operations running in this Context complete.
-func WithCancel(parent Context) (ctx Context, cancel CancelFunc) {
- c := newCancelCtx(parent)
- propagateCancel(parent, &c)
- return &c, func() { c.cancel(true, Canceled) }
-}
-
-// newCancelCtx returns an initialized cancelCtx.
-func newCancelCtx(parent Context) cancelCtx {
- return cancelCtx{
- Context: parent,
- done: make(chan struct{}),
- }
-}
-
-// propagateCancel arranges for child to be canceled when parent is.
-func propagateCancel(parent Context, child canceler) {
- if parent.Done() == nil {
- return // parent is never canceled
- }
- if p, ok := parentCancelCtx(parent); ok {
- p.mu.Lock()
- if p.err != nil {
- // parent has already been canceled
- child.cancel(false, p.err)
- } else {
- if p.children == nil {
- p.children = make(map[canceler]bool)
- }
- p.children[child] = true
- }
- p.mu.Unlock()
- } else {
- go func() {
- select {
- case <-parent.Done():
- child.cancel(false, parent.Err())
- case <-child.Done():
- }
- }()
- }
-}
-
-// parentCancelCtx follows a chain of parent references until it finds a
-// *cancelCtx. This function understands how each of the concrete types in this
-// package represents its parent.
-func parentCancelCtx(parent Context) (*cancelCtx, bool) {
- for {
- switch c := parent.(type) {
- case *cancelCtx:
- return c, true
- case *timerCtx:
- return &c.cancelCtx, true
- case *valueCtx:
- parent = c.Context
- default:
- return nil, false
- }
- }
-}
-
-// removeChild removes a context from its parent.
-func removeChild(parent Context, child canceler) {
- p, ok := parentCancelCtx(parent)
- if !ok {
- return
- }
- p.mu.Lock()
- if p.children != nil {
- delete(p.children, child)
- }
- p.mu.Unlock()
-}
-
-// A canceler is a context type that can be canceled directly. The
-// implementations are *cancelCtx and *timerCtx.
-type canceler interface {
- cancel(removeFromParent bool, err error)
- Done() <-chan struct{}
-}
-
-// A cancelCtx can be canceled. When canceled, it also cancels any children
-// that implement canceler.
-type cancelCtx struct {
- Context
-
- done chan struct{} // closed by the first cancel call.
-
- mu sync.Mutex
- children map[canceler]bool // set to nil by the first cancel call
- err error // set to non-nil by the first cancel call
-}
-
-func (c *cancelCtx) Done() <-chan struct{} {
- return c.done
-}
-
-func (c *cancelCtx) Err() error {
- c.mu.Lock()
- defer c.mu.Unlock()
- return c.err
-}
-
-func (c *cancelCtx) String() string {
- return fmt.Sprintf("%v.WithCancel", c.Context)
-}
-
-// cancel closes c.done, cancels each of c's children, and, if
-// removeFromParent is true, removes c from its parent's children.
-func (c *cancelCtx) cancel(removeFromParent bool, err error) {
- if err == nil {
- panic("context: internal error: missing cancel error")
- }
- c.mu.Lock()
- if c.err != nil {
- c.mu.Unlock()
- return // already canceled
- }
- c.err = err
- close(c.done)
- for child := range c.children {
- // NOTE: acquiring the child's lock while holding parent's lock.
- child.cancel(false, err)
- }
- c.children = nil
- c.mu.Unlock()
-
- if removeFromParent {
- removeChild(c.Context, c)
- }
-}
-
-// WithDeadline returns a copy of the parent context with the deadline adjusted
-// to be no later than d. If the parent's deadline is already earlier than d,
-// WithDeadline(parent, d) is semantically equivalent to parent. The returned
-// context's Done channel is closed when the deadline expires, when the returned
-// cancel function is called, or when the parent context's Done channel is
-// closed, whichever happens first.
-//
-// Canceling this context releases resources associated with it, so code should
-// call cancel as soon as the operations running in this Context complete.
-func WithDeadline(parent Context, deadline time.Time) (Context, CancelFunc) {
- if cur, ok := parent.Deadline(); ok && cur.Before(deadline) {
- // The current deadline is already sooner than the new one.
- return WithCancel(parent)
- }
- c := &timerCtx{
- cancelCtx: newCancelCtx(parent),
- deadline: deadline,
- }
- propagateCancel(parent, c)
- d := deadline.Sub(time.Now())
- if d <= 0 {
- c.cancel(true, DeadlineExceeded) // deadline has already passed
- return c, func() { c.cancel(true, Canceled) }
- }
- c.mu.Lock()
- defer c.mu.Unlock()
- if c.err == nil {
- c.timer = time.AfterFunc(d, func() {
- c.cancel(true, DeadlineExceeded)
- })
- }
- return c, func() { c.cancel(true, Canceled) }
-}
-
-// A timerCtx carries a timer and a deadline. It embeds a cancelCtx to
-// implement Done and Err. It implements cancel by stopping its timer then
-// delegating to cancelCtx.cancel.
-type timerCtx struct {
- cancelCtx
- timer *time.Timer // Under cancelCtx.mu.
-
- deadline time.Time
-}
-
-func (c *timerCtx) Deadline() (deadline time.Time, ok bool) {
- return c.deadline, true
-}
-
-func (c *timerCtx) String() string {
- return fmt.Sprintf("%v.WithDeadline(%s [%s])", c.cancelCtx.Context, c.deadline, c.deadline.Sub(time.Now()))
-}
-
-func (c *timerCtx) cancel(removeFromParent bool, err error) {
- c.cancelCtx.cancel(false, err)
- if removeFromParent {
- // Remove this timerCtx from its parent cancelCtx's children.
- removeChild(c.cancelCtx.Context, c)
- }
- c.mu.Lock()
- if c.timer != nil {
- c.timer.Stop()
- c.timer = nil
- }
- c.mu.Unlock()
-}
-
-// WithTimeout returns WithDeadline(parent, time.Now().Add(timeout)).
-//
-// Canceling this context releases resources associated with it, so code should
-// call cancel as soon as the operations running in this Context complete:
-//
-// func slowOperationWithTimeout(ctx context.Context) (Result, error) {
-// ctx, cancel := context.WithTimeout(ctx, 100*time.Millisecond)
-// defer cancel() // releases resources if slowOperation completes before timeout elapses
-// return slowOperation(ctx)
-// }
-func WithTimeout(parent Context, timeout time.Duration) (Context, CancelFunc) {
- return WithDeadline(parent, time.Now().Add(timeout))
-}
-
-// WithValue returns a copy of parent in which the value associated with key is
-// val.
-//
-// Use context Values only for request-scoped data that transits processes and
-// APIs, not for passing optional parameters to functions.
-func WithValue(parent Context, key interface{}, val interface{}) Context {
- return &valueCtx{parent, key, val}
-}
-
-// A valueCtx carries a key-value pair. It implements Value for that key and
-// delegates all other calls to the embedded Context.
-type valueCtx struct {
- Context
- key, val interface{}
-}
-
-func (c *valueCtx) String() string {
- return fmt.Sprintf("%v.WithValue(%#v, %#v)", c.Context, c.key, c.val)
-}
-
-func (c *valueCtx) Value(key interface{}) interface{} {
- if c.key == key {
- return c.val
- }
- return c.Context.Value(key)
-}
diff --git a/vendor/golang.org/x/net/context/context_test.go b/vendor/golang.org/x/net/context/context_test.go
index 05345fc5..4209b6ff 100644
--- a/vendor/golang.org/x/net/context/context_test.go
+++ b/vendor/golang.org/x/net/context/context_test.go
@@ -2,6 +2,8 @@
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file.
+// +build !go1.7
+
package context
import (
@@ -375,7 +377,7 @@ func TestAllocs(t *testing.T) {
<-c.Done()
},
limit: 8,
- gccgoLimit: 15,
+ gccgoLimit: 16,
},
{
desc: "WithCancel(bg)",
diff --git a/vendor/golang.org/x/net/context/ctxhttp/ctxhttp.go b/vendor/golang.org/x/net/context/ctxhttp/ctxhttp.go
index 26a5e19a..e35860a7 100644
--- a/vendor/golang.org/x/net/context/ctxhttp/ctxhttp.go
+++ b/vendor/golang.org/x/net/context/ctxhttp/ctxhttp.go
@@ -39,6 +39,11 @@ func Do(ctx context.Context, client *http.Client, req *http.Request) (*http.Resp
}
result := make(chan responseAndError, 1)
+ // Make local copies of test hooks closed over by goroutines below.
+ // Prevents data races in tests.
+ testHookDoReturned := testHookDoReturned
+ testHookDidBodyClose := testHookDidBodyClose
+
go func() {
resp, err := client.Do(req)
testHookDoReturned()
diff --git a/vendor/golang.org/x/net/context/go17.go b/vendor/golang.org/x/net/context/go17.go
new file mode 100644
index 00000000..f8cda19a
--- /dev/null
+++ b/vendor/golang.org/x/net/context/go17.go
@@ -0,0 +1,72 @@
+// Copyright 2016 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+// +build go1.7
+
+package context
+
+import (
+ "context" // standard library's context, as of Go 1.7
+ "time"
+)
+
+var (
+ todo = context.TODO()
+ background = context.Background()
+)
+
+// Canceled is the error returned by Context.Err when the context is canceled.
+var Canceled = context.Canceled
+
+// DeadlineExceeded is the error returned by Context.Err when the context's
+// deadline passes.
+var DeadlineExceeded = context.DeadlineExceeded
+
+// WithCancel returns a copy of parent with a new Done channel. The returned
+// context's Done channel is closed when the returned cancel function is called
+// or when the parent context's Done channel is closed, whichever happens first.
+//
+// Canceling this context releases resources associated with it, so code should
+// call cancel as soon as the operations running in this Context complete.
+func WithCancel(parent Context) (ctx Context, cancel CancelFunc) {
+ ctx, f := context.WithCancel(parent)
+ return ctx, CancelFunc(f)
+}
+
+// WithDeadline returns a copy of the parent context with the deadline adjusted
+// to be no later than d. If the parent's deadline is already earlier than d,
+// WithDeadline(parent, d) is semantically equivalent to parent. The returned
+// context's Done channel is closed when the deadline expires, when the returned
+// cancel function is called, or when the parent context's Done channel is
+// closed, whichever happens first.
+//
+// Canceling this context releases resources associated with it, so code should
+// call cancel as soon as the operations running in this Context complete.
+func WithDeadline(parent Context, deadline time.Time) (Context, CancelFunc) {
+ ctx, f := context.WithDeadline(parent, deadline)
+ return ctx, CancelFunc(f)
+}
+
+// WithTimeout returns WithDeadline(parent, time.Now().Add(timeout)).
+//
+// Canceling this context releases resources associated with it, so code should
+// call cancel as soon as the operations running in this Context complete:
+//
+// func slowOperationWithTimeout(ctx context.Context) (Result, error) {
+// ctx, cancel := context.WithTimeout(ctx, 100*time.Millisecond)
+// defer cancel() // releases resources if slowOperation completes before timeout elapses
+// return slowOperation(ctx)
+// }
+func WithTimeout(parent Context, timeout time.Duration) (Context, CancelFunc) {
+ return WithDeadline(parent, time.Now().Add(timeout))
+}
+
+// WithValue returns a copy of parent in which the value associated with key is
+// val.
+//
+// Use context Values only for request-scoped data that transits processes and
+// APIs, not for passing optional parameters to functions.
+func WithValue(parent Context, key interface{}, val interface{}) Context {
+ return context.WithValue(parent, key, val)
+}
diff --git a/vendor/golang.org/x/net/context/pre_go17.go b/vendor/golang.org/x/net/context/pre_go17.go
new file mode 100644
index 00000000..5a30acab
--- /dev/null
+++ b/vendor/golang.org/x/net/context/pre_go17.go
@@ -0,0 +1,300 @@
+// Copyright 2014 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+// +build !go1.7
+
+package context
+
+import (
+ "errors"
+ "fmt"
+ "sync"
+ "time"
+)
+
+// An emptyCtx is never canceled, has no values, and has no deadline. It is not
+// struct{}, since vars of this type must have distinct addresses.
+type emptyCtx int
+
+func (*emptyCtx) Deadline() (deadline time.Time, ok bool) {
+ return
+}
+
+func (*emptyCtx) Done() <-chan struct{} {
+ return nil
+}
+
+func (*emptyCtx) Err() error {
+ return nil
+}
+
+func (*emptyCtx) Value(key interface{}) interface{} {
+ return nil
+}
+
+func (e *emptyCtx) String() string {
+ switch e {
+ case background:
+ return "context.Background"
+ case todo:
+ return "context.TODO"
+ }
+ return "unknown empty Context"
+}
+
+var (
+ background = new(emptyCtx)
+ todo = new(emptyCtx)
+)
+
+// Canceled is the error returned by Context.Err when the context is canceled.
+var Canceled = errors.New("context canceled")
+
+// DeadlineExceeded is the error returned by Context.Err when the context's
+// deadline passes.
+var DeadlineExceeded = errors.New("context deadline exceeded")
+
+// WithCancel returns a copy of parent with a new Done channel. The returned
+// context's Done channel is closed when the returned cancel function is called
+// or when the parent context's Done channel is closed, whichever happens first.
+//
+// Canceling this context releases resources associated with it, so code should
+// call cancel as soon as the operations running in this Context complete.
+func WithCancel(parent Context) (ctx Context, cancel CancelFunc) {
+ c := newCancelCtx(parent)
+ propagateCancel(parent, c)
+ return c, func() { c.cancel(true, Canceled) }
+}
+
+// newCancelCtx returns an initialized cancelCtx.
+func newCancelCtx(parent Context) *cancelCtx {
+ return &cancelCtx{
+ Context: parent,
+ done: make(chan struct{}),
+ }
+}
+
+// propagateCancel arranges for child to be canceled when parent is.
+func propagateCancel(parent Context, child canceler) {
+ if parent.Done() == nil {
+ return // parent is never canceled
+ }
+ if p, ok := parentCancelCtx(parent); ok {
+ p.mu.Lock()
+ if p.err != nil {
+ // parent has already been canceled
+ child.cancel(false, p.err)
+ } else {
+ if p.children == nil {
+ p.children = make(map[canceler]bool)
+ }
+ p.children[child] = true
+ }
+ p.mu.Unlock()
+ } else {
+ go func() {
+ select {
+ case <-parent.Done():
+ child.cancel(false, parent.Err())
+ case <-child.Done():
+ }
+ }()
+ }
+}
+
+// parentCancelCtx follows a chain of parent references until it finds a
+// *cancelCtx. This function understands how each of the concrete types in this
+// package represents its parent.
+func parentCancelCtx(parent Context) (*cancelCtx, bool) {
+ for {
+ switch c := parent.(type) {
+ case *cancelCtx:
+ return c, true
+ case *timerCtx:
+ return c.cancelCtx, true
+ case *valueCtx:
+ parent = c.Context
+ default:
+ return nil, false
+ }
+ }
+}
+
+// removeChild removes a context from its parent.
+func removeChild(parent Context, child canceler) {
+ p, ok := parentCancelCtx(parent)
+ if !ok {
+ return
+ }
+ p.mu.Lock()
+ if p.children != nil {
+ delete(p.children, child)
+ }
+ p.mu.Unlock()
+}
+
+// A canceler is a context type that can be canceled directly. The
+// implementations are *cancelCtx and *timerCtx.
+type canceler interface {
+ cancel(removeFromParent bool, err error)
+ Done() <-chan struct{}
+}
+
+// A cancelCtx can be canceled. When canceled, it also cancels any children
+// that implement canceler.
+type cancelCtx struct {
+ Context
+
+ done chan struct{} // closed by the first cancel call.
+
+ mu sync.Mutex
+ children map[canceler]bool // set to nil by the first cancel call
+ err error // set to non-nil by the first cancel call
+}
+
+func (c *cancelCtx) Done() <-chan struct{} {
+ return c.done
+}
+
+func (c *cancelCtx) Err() error {
+ c.mu.Lock()
+ defer c.mu.Unlock()
+ return c.err
+}
+
+func (c *cancelCtx) String() string {
+ return fmt.Sprintf("%v.WithCancel", c.Context)
+}
+
+// cancel closes c.done, cancels each of c's children, and, if
+// removeFromParent is true, removes c from its parent's children.
+func (c *cancelCtx) cancel(removeFromParent bool, err error) {
+ if err == nil {
+ panic("context: internal error: missing cancel error")
+ }
+ c.mu.Lock()
+ if c.err != nil {
+ c.mu.Unlock()
+ return // already canceled
+ }
+ c.err = err
+ close(c.done)
+ for child := range c.children {
+ // NOTE: acquiring the child's lock while holding parent's lock.
+ child.cancel(false, err)
+ }
+ c.children = nil
+ c.mu.Unlock()
+
+ if removeFromParent {
+ removeChild(c.Context, c)
+ }
+}
+
+// WithDeadline returns a copy of the parent context with the deadline adjusted
+// to be no later than d. If the parent's deadline is already earlier than d,
+// WithDeadline(parent, d) is semantically equivalent to parent. The returned
+// context's Done channel is closed when the deadline expires, when the returned
+// cancel function is called, or when the parent context's Done channel is
+// closed, whichever happens first.
+//
+// Canceling this context releases resources associated with it, so code should
+// call cancel as soon as the operations running in this Context complete.
+func WithDeadline(parent Context, deadline time.Time) (Context, CancelFunc) {
+ if cur, ok := parent.Deadline(); ok && cur.Before(deadline) {
+ // The current deadline is already sooner than the new one.
+ return WithCancel(parent)
+ }
+ c := &timerCtx{
+ cancelCtx: newCancelCtx(parent),
+ deadline: deadline,
+ }
+ propagateCancel(parent, c)
+ d := deadline.Sub(time.Now())
+ if d <= 0 {
+ c.cancel(true, DeadlineExceeded) // deadline has already passed
+ return c, func() { c.cancel(true, Canceled) }
+ }
+ c.mu.Lock()
+ defer c.mu.Unlock()
+ if c.err == nil {
+ c.timer = time.AfterFunc(d, func() {
+ c.cancel(true, DeadlineExceeded)
+ })
+ }
+ return c, func() { c.cancel(true, Canceled) }
+}
+
+// A timerCtx carries a timer and a deadline. It embeds a cancelCtx to
+// implement Done and Err. It implements cancel by stopping its timer then
+// delegating to cancelCtx.cancel.
+type timerCtx struct {
+ *cancelCtx
+ timer *time.Timer // Under cancelCtx.mu.
+
+ deadline time.Time
+}
+
+func (c *timerCtx) Deadline() (deadline time.Time, ok bool) {
+ return c.deadline, true
+}
+
+func (c *timerCtx) String() string {
+ return fmt.Sprintf("%v.WithDeadline(%s [%s])", c.cancelCtx.Context, c.deadline, c.deadline.Sub(time.Now()))
+}
+
+func (c *timerCtx) cancel(removeFromParent bool, err error) {
+ c.cancelCtx.cancel(false, err)
+ if removeFromParent {
+ // Remove this timerCtx from its parent cancelCtx's children.
+ removeChild(c.cancelCtx.Context, c)
+ }
+ c.mu.Lock()
+ if c.timer != nil {
+ c.timer.Stop()
+ c.timer = nil
+ }
+ c.mu.Unlock()
+}
+
+// WithTimeout returns WithDeadline(parent, time.Now().Add(timeout)).
+//
+// Canceling this context releases resources associated with it, so code should
+// call cancel as soon as the operations running in this Context complete:
+//
+// func slowOperationWithTimeout(ctx context.Context) (Result, error) {
+// ctx, cancel := context.WithTimeout(ctx, 100*time.Millisecond)
+// defer cancel() // releases resources if slowOperation completes before timeout elapses
+// return slowOperation(ctx)
+// }
+func WithTimeout(parent Context, timeout time.Duration) (Context, CancelFunc) {
+ return WithDeadline(parent, time.Now().Add(timeout))
+}
+
+// WithValue returns a copy of parent in which the value associated with key is
+// val.
+//
+// Use context Values only for request-scoped data that transits processes and
+// APIs, not for passing optional parameters to functions.
+func WithValue(parent Context, key interface{}, val interface{}) Context {
+ return &valueCtx{parent, key, val}
+}
+
+// A valueCtx carries a key-value pair. It implements Value for that key and
+// delegates all other calls to the embedded Context.
+type valueCtx struct {
+ Context
+ key, val interface{}
+}
+
+func (c *valueCtx) String() string {
+ return fmt.Sprintf("%v.WithValue(%#v, %#v)", c.Context, c.key, c.val)
+}
+
+func (c *valueCtx) Value(key interface{}) interface{} {
+ if c.key == key {
+ return c.val
+ }
+ return c.Context.Value(key)
+}
diff --git a/vendor/golang.org/x/net/http2/h2demo/launch.go b/vendor/golang.org/x/net/http2/h2demo/launch.go
index 13b1cfd7..df0866a3 100644
--- a/vendor/golang.org/x/net/http2/h2demo/launch.go
+++ b/vendor/golang.org/x/net/http2/h2demo/launch.go
@@ -170,9 +170,9 @@ func main() {
},
},
NetworkInterfaces: []*compute.NetworkInterface{
- &compute.NetworkInterface{
+ {
AccessConfigs: []*compute.AccessConfig{
- &compute.AccessConfig{
+ {
Type: "ONE_TO_ONE_NAT",
Name: "External NAT",
NatIP: natIP,
diff --git a/vendor/golang.org/x/net/http2/h2i/h2i.go b/vendor/golang.org/x/net/http2/h2i/h2i.go
index cf60d56c..b70976f7 100644
--- a/vendor/golang.org/x/net/http2/h2i/h2i.go
+++ b/vendor/golang.org/x/net/http2/h2i/h2i.go
@@ -56,8 +56,8 @@ type command struct {
}
var commands = map[string]command{
- "ping": command{run: (*h2i).cmdPing},
- "settings": command{
+ "ping": {run: (*h2i).cmdPing},
+ "settings": {
run: (*h2i).cmdSettings,
complete: func() []string {
return []string{
@@ -71,8 +71,8 @@ var commands = map[string]command{
}
},
},
- "quit": command{run: (*h2i).cmdQuit},
- "headers": command{run: (*h2i).cmdHeaders},
+ "quit": {run: (*h2i).cmdQuit},
+ "headers": {run: (*h2i).cmdHeaders},
}
func usage() {
diff --git a/vendor/golang.org/x/net/http2/hpack/hpack.go b/vendor/golang.org/x/net/http2/hpack/hpack.go
index dcf257af..8aa197ad 100644
--- a/vendor/golang.org/x/net/http2/hpack/hpack.go
+++ b/vendor/golang.org/x/net/http2/hpack/hpack.go
@@ -43,7 +43,7 @@ type HeaderField struct {
// IsPseudo reports whether the header field is an http2 pseudo header.
// That is, it reports whether it starts with a colon.
-// It is not otherwise guaranteed to be a valid psuedo header field,
+// It is not otherwise guaranteed to be a valid pseudo header field,
// though.
func (hf HeaderField) IsPseudo() bool {
return len(hf.Name) != 0 && hf.Name[0] == ':'
diff --git a/vendor/golang.org/x/net/http2/http2.go b/vendor/golang.org/x/net/http2/http2.go
index 4c5e11ac..7b98e756 100644
--- a/vendor/golang.org/x/net/http2/http2.go
+++ b/vendor/golang.org/x/net/http2/http2.go
@@ -23,6 +23,7 @@ import (
"io"
"net/http"
"os"
+ "sort"
"strconv"
"strings"
"sync"
@@ -169,8 +170,9 @@ var (
// RFC 7230 says:
// header-field = field-name ":" OWS field-value OWS
// field-name = token
+// token = 1*tchar
// tchar = "!" / "#" / "$" / "%" / "&" / "'" / "*" / "+" / "-" / "." /
-// "^" / "_" / "
+// "^" / "_" / "`" / "|" / "~" / DIGIT / ALPHA
// Further, http2 says:
// "Just as in HTTP/1.x, header field names are strings of ASCII
// characters that are compared in a case-insensitive
@@ -320,7 +322,7 @@ func mustUint31(v int32) uint32 {
}
// bodyAllowedForStatus reports whether a given response status code
-// permits a body. See RFC2616, section 4.4.
+// permits a body. See RFC 2616, section 4.4.
func bodyAllowedForStatus(status int) bool {
switch {
case status >= 100 && status <= 199:
@@ -427,3 +429,36 @@ var isTokenTable = [127]bool{
type connectionStater interface {
ConnectionState() tls.ConnectionState
}
+
+var sorterPool = sync.Pool{New: func() interface{} { return new(sorter) }}
+
+type sorter struct {
+ v []string // owned by sorter
+}
+
+func (s *sorter) Len() int { return len(s.v) }
+func (s *sorter) Swap(i, j int) { s.v[i], s.v[j] = s.v[j], s.v[i] }
+func (s *sorter) Less(i, j int) bool { return s.v[i] < s.v[j] }
+
+// Keys returns the sorted keys of h.
+//
+// The returned slice is only valid until s used again or returned to
+// its pool.
+func (s *sorter) Keys(h http.Header) []string {
+ keys := s.v[:0]
+ for k := range h {
+ keys = append(keys, k)
+ }
+ s.v = keys
+ sort.Sort(s)
+ return keys
+}
+
+func (s *sorter) SortStrings(ss []string) {
+ // Our sorter works on s.v, which sorter owners, so
+ // stash it away while we sort the user's buffer.
+ save := s.v
+ s.v = ss
+ sort.Sort(s)
+ s.v = save
+}
diff --git a/vendor/golang.org/x/net/http2/http2_test.go b/vendor/golang.org/x/net/http2/http2_test.go
index 0a4da46a..549ff5e4 100644
--- a/vendor/golang.org/x/net/http2/http2_test.go
+++ b/vendor/golang.org/x/net/http2/http2_test.go
@@ -65,7 +65,7 @@ func (w twriter) Write(p []byte) (n int, err error) {
return len(p), nil
}
-// like encodeHeader, but don't add implicit psuedo headers.
+// like encodeHeader, but don't add implicit pseudo headers.
func encodeHeaderNoImplicit(t *testing.T, headers ...string) []byte {
var buf bytes.Buffer
enc := hpack.NewEncoder(&buf)
@@ -172,3 +172,27 @@ func cleanDate(res *http.Response) {
d[0] = "XXX"
}
}
+
+func TestSorterPoolAllocs(t *testing.T) {
+ ss := []string{"a", "b", "c"}
+ h := http.Header{
+ "a": nil,
+ "b": nil,
+ "c": nil,
+ }
+ sorter := new(sorter)
+
+ if allocs := testing.AllocsPerRun(100, func() {
+ sorter.SortStrings(ss)
+ }); allocs >= 1 {
+ t.Logf("SortStrings allocs = %v; want <1", allocs)
+ }
+
+ if allocs := testing.AllocsPerRun(5, func() {
+ if len(sorter.Keys(h)) != 3 {
+ t.Fatal("wrong result")
+ }
+ }); allocs > 0 {
+ t.Logf("Keys allocs = %v; want <1", allocs)
+ }
+}
diff --git a/vendor/golang.org/x/net/http2/server.go b/vendor/golang.org/x/net/http2/server.go
index 915e2571..3a46db60 100644
--- a/vendor/golang.org/x/net/http2/server.go
+++ b/vendor/golang.org/x/net/http2/server.go
@@ -51,7 +51,6 @@ import (
"os"
"reflect"
"runtime"
- "sort"
"strconv"
"strings"
"sync"
@@ -409,6 +408,7 @@ type serverConn struct {
goAwayCode ErrCode
shutdownTimerCh <-chan time.Time // nil until used
shutdownTimer *time.Timer // nil until used
+ freeRequestBodyBuf []byte // if non-nil, a free initialWindowSize buffer for getRequestBodyBuf
// Owned by the writeFrameAsync goroutine:
headerWriteBuf bytes.Buffer
@@ -453,6 +453,7 @@ type stream struct {
sentReset bool // only true once detached from streams map
gotReset bool // only true once detacted from streams map
gotTrailerHeader bool // HEADER frame for trailers was seen
+ reqBuf []byte
trailer http.Header // accumulated trailers
reqTrailer http.Header // handler's Request.Trailer
@@ -596,10 +597,11 @@ type readFrameResult struct {
// It's run on its own goroutine.
func (sc *serverConn) readFrames() {
gate := make(gate)
+ gateDone := gate.Done
for {
f, err := sc.framer.ReadFrame()
select {
- case sc.readFrameCh <- readFrameResult{f, err, gate.Done}:
+ case sc.readFrameCh <- readFrameResult{f, err, gateDone}:
case <-sc.doneServing:
return
}
@@ -1176,6 +1178,18 @@ func (sc *serverConn) closeStream(st *stream, err error) {
}
st.cw.Close() // signals Handler's CloseNotifier, unblocks writes, etc
sc.writeSched.forgetStream(st.id)
+ if st.reqBuf != nil {
+ // Stash this request body buffer (64k) away for reuse
+ // by a future POST/PUT/etc.
+ //
+ // TODO(bradfitz): share on the server? sync.Pool?
+ // Server requires locks and might hurt contention.
+ // sync.Pool might work, or might be worse, depending
+ // on goroutine CPU migrations. (get and put on
+ // separate CPUs). Maybe a mix of strategies. But
+ // this is an easy win for now.
+ sc.freeRequestBodyBuf = st.reqBuf
+ }
}
func (sc *serverConn) processSettings(f *SettingsFrame) error {
@@ -1423,6 +1437,8 @@ func (sc *serverConn) processHeaders(f *MetaHeadersFrame) error {
if f.Truncated {
// Their header list was too long. Send a 431 error.
handler = handleHeaderListTooLong
+ } else if err := checkValidHTTP2Request(req); err != nil {
+ handler = new400Handler(err)
}
go sc.runHandler(rw, req, handler)
@@ -1602,8 +1618,13 @@ func (sc *serverConn) newWriterAndRequest(st *stream, f *MetaHeadersFrame) (*res
Trailer: trailer,
}
if bodyOpen {
+ // Disabled, per golang.org/issue/14960:
+ // st.reqBuf = sc.getRequestBodyBuf()
+ // TODO: remove this 64k of garbage per request (again, but without a data race):
+ buf := make([]byte, initialWindowSize)
+
body.pipe = &pipe{
- b: &fixedBuffer{buf: make([]byte, initialWindowSize)}, // TODO: garbage
+ b: &fixedBuffer{buf: buf},
}
if vv, ok := header["Content-Length"]; ok {
@@ -1627,6 +1648,15 @@ func (sc *serverConn) newWriterAndRequest(st *stream, f *MetaHeadersFrame) (*res
return rw, req, nil
}
+func (sc *serverConn) getRequestBodyBuf() []byte {
+ sc.serveG.check()
+ if buf := sc.freeRequestBodyBuf; buf != nil {
+ sc.freeRequestBodyBuf = nil
+ return buf
+ }
+ return make([]byte, initialWindowSize)
+}
+
// Run on its own goroutine.
func (sc *serverConn) runHandler(rw *responseWriter, req *http.Request, handler func(http.ResponseWriter, *http.Request)) {
didPanic := true
@@ -2001,7 +2031,12 @@ func (rws *responseWriterState) promoteUndeclaredTrailers() {
rws.declareTrailer(trailerKey)
rws.handlerHeader[http.CanonicalHeaderKey(trailerKey)] = vv
}
- sort.Strings(rws.trailers)
+
+ if len(rws.trailers) > 1 {
+ sorter := sorterPool.Get().(*sorter)
+ sorter.SortStrings(rws.trailers)
+ sorterPool.Put(sorter)
+ }
}
func (w *responseWriter) Flush() {
@@ -2147,3 +2182,34 @@ func foreachHeaderElement(v string, fn func(string)) {
}
}
}
+
+// From http://httpwg.org/specs/rfc7540.html#rfc.section.8.1.2.2
+var connHeaders = []string{
+ "Connection",
+ "Keep-Alive",
+ "Proxy-Connection",
+ "Transfer-Encoding",
+ "Upgrade",
+}
+
+// checkValidHTTP2Request checks whether req is a valid HTTP/2 request,
+// per RFC 7540 Section 8.1.2.2.
+// The returned error is reported to users.
+func checkValidHTTP2Request(req *http.Request) error {
+ for _, h := range connHeaders {
+ if _, ok := req.Header[h]; ok {
+ return fmt.Errorf("request header %q is not valid in HTTP/2", h)
+ }
+ }
+ te := req.Header["Te"]
+ if len(te) > 0 && (len(te) > 1 || (te[0] != "trailers" && te[0] != "")) {
+ return errors.New(`request header "TE" may only be "trailers" in HTTP/2`)
+ }
+ return nil
+}
+
+func new400Handler(err error) http.HandlerFunc {
+ return func(w http.ResponseWriter, r *http.Request) {
+ http.Error(w, err.Error(), http.StatusBadRequest)
+ }
+}
diff --git a/vendor/golang.org/x/net/http2/server_test.go b/vendor/golang.org/x/net/http2/server_test.go
index cd3e91a2..15f980b4 100644
--- a/vendor/golang.org/x/net/http2/server_test.go
+++ b/vendor/golang.org/x/net/http2/server_test.go
@@ -188,7 +188,7 @@ func (st *serverTester) loopNum() int {
// awaitIdle heuristically awaits for the server conn's select loop to be idle.
// The heuristic is that the server connection's serve loop must schedule
-// 50 times in a row without any channel sends or receives occuring.
+// 50 times in a row without any channel sends or receives occurring.
func (st *serverTester) awaitIdle() {
remain := 50
last := st.loopNum()
@@ -204,6 +204,13 @@ func (st *serverTester) awaitIdle() {
}
func (st *serverTester) Close() {
+ if st.t.Failed() {
+ // If we failed already (and are likely in a Fatal,
+ // unwindowing), force close the connection, so the
+ // httptest.Server doesn't wait forever for the conn
+ // to close.
+ st.cc.Close()
+ }
st.ts.Close()
if st.cc != nil {
st.cc.Close()
@@ -2759,6 +2766,7 @@ func TestServerDoesntWriteInvalidHeaders(t *testing.T) {
}
func BenchmarkServerGets(b *testing.B) {
+ defer disableGoroutineTracking()()
b.ReportAllocs()
const msg = "Hello, world"
@@ -2790,6 +2798,7 @@ func BenchmarkServerGets(b *testing.B) {
}
func BenchmarkServerPosts(b *testing.B) {
+ defer disableGoroutineTracking()()
b.ReportAllocs()
const msg = "Hello, world"
@@ -3002,6 +3011,76 @@ func TestServerNoDuplicateContentType(t *testing.T) {
}
}
+func disableGoroutineTracking() (restore func()) {
+ old := DebugGoroutines
+ DebugGoroutines = false
+ return func() { DebugGoroutines = old }
+}
+
+func BenchmarkServer_GetRequest(b *testing.B) {
+ defer disableGoroutineTracking()()
+ b.ReportAllocs()
+ const msg = "Hello, world."
+ st := newServerTester(b, func(w http.ResponseWriter, r *http.Request) {
+ n, err := io.Copy(ioutil.Discard, r.Body)
+ if err != nil || n > 0 {
+ b.Error("Read %d bytes, error %v; want 0 bytes.", n, err)
+ }
+ io.WriteString(w, msg)
+ })
+ defer st.Close()
+
+ st.greet()
+ // Give the server quota to reply. (plus it has the the 64KB)
+ if err := st.fr.WriteWindowUpdate(0, uint32(b.N*len(msg))); err != nil {
+ b.Fatal(err)
+ }
+ hbf := st.encodeHeader(":method", "GET")
+ for i := 0; i < b.N; i++ {
+ streamID := uint32(1 + 2*i)
+ st.writeHeaders(HeadersFrameParam{
+ StreamID: streamID,
+ BlockFragment: hbf,
+ EndStream: true,
+ EndHeaders: true,
+ })
+ st.wantHeaders()
+ st.wantData()
+ }
+}
+
+func BenchmarkServer_PostRequest(b *testing.B) {
+ defer disableGoroutineTracking()()
+ b.ReportAllocs()
+ const msg = "Hello, world."
+ st := newServerTester(b, func(w http.ResponseWriter, r *http.Request) {
+ n, err := io.Copy(ioutil.Discard, r.Body)
+ if err != nil || n > 0 {
+ b.Error("Read %d bytes, error %v; want 0 bytes.", n, err)
+ }
+ io.WriteString(w, msg)
+ })
+ defer st.Close()
+ st.greet()
+ // Give the server quota to reply. (plus it has the the 64KB)
+ if err := st.fr.WriteWindowUpdate(0, uint32(b.N*len(msg))); err != nil {
+ b.Fatal(err)
+ }
+ hbf := st.encodeHeader(":method", "POST")
+ for i := 0; i < b.N; i++ {
+ streamID := uint32(1 + 2*i)
+ st.writeHeaders(HeadersFrameParam{
+ StreamID: streamID,
+ BlockFragment: hbf,
+ EndStream: false,
+ EndHeaders: true,
+ })
+ st.writeData(streamID, true, nil)
+ st.wantHeaders()
+ st.wantData()
+ }
+}
+
type connStateConn struct {
net.Conn
cs tls.ConnectionState
@@ -3077,6 +3156,27 @@ func TestServerHandleCustomConn(t *testing.T) {
}
}
+// golang.org/issue/14214
+func TestServer_Rejects_ConnHeaders(t *testing.T) {
+ testServerResponse(t, func(w http.ResponseWriter, r *http.Request) error {
+ t.Errorf("should not get to Handler")
+ return nil
+ }, func(st *serverTester) {
+ st.bodylessReq1("connection", "foo")
+ hf := st.wantHeaders()
+ goth := st.decodeHeader(hf.HeaderBlockFragment())
+ wanth := [][2]string{
+ {":status", "400"},
+ {"content-type", "text/plain; charset=utf-8"},
+ {"x-content-type-options", "nosniff"},
+ {"content-length", "51"},
+ }
+ if !reflect.DeepEqual(goth, wanth) {
+ t.Errorf("Got headers %v; want %v", goth, wanth)
+ }
+ })
+}
+
type hpackEncoder struct {
enc *hpack.Encoder
buf bytes.Buffer
@@ -3100,3 +3200,45 @@ func (he *hpackEncoder) encodeHeaderRaw(t *testing.T, headers ...string) []byte
}
return he.buf.Bytes()
}
+
+func TestCheckValidHTTP2Request(t *testing.T) {
+ tests := []struct {
+ req *http.Request
+ want error
+ }{
+ {
+ req: &http.Request{Header: http.Header{"Te": {"trailers"}}},
+ want: nil,
+ },
+ {
+ req: &http.Request{Header: http.Header{"Te": {"trailers", "bogus"}}},
+ want: errors.New(`request header "TE" may only be "trailers" in HTTP/2`),
+ },
+ {
+ req: &http.Request{Header: http.Header{"Foo": {""}}},
+ want: nil,
+ },
+ {
+ req: &http.Request{Header: http.Header{"Connection": {""}}},
+ want: errors.New(`request header "Connection" is not valid in HTTP/2`),
+ },
+ {
+ req: &http.Request{Header: http.Header{"Proxy-Connection": {""}}},
+ want: errors.New(`request header "Proxy-Connection" is not valid in HTTP/2`),
+ },
+ {
+ req: &http.Request{Header: http.Header{"Keep-Alive": {""}}},
+ want: errors.New(`request header "Keep-Alive" is not valid in HTTP/2`),
+ },
+ {
+ req: &http.Request{Header: http.Header{"Upgrade": {""}}},
+ want: errors.New(`request header "Upgrade" is not valid in HTTP/2`),
+ },
+ }
+ for i, tt := range tests {
+ got := checkValidHTTP2Request(tt.req)
+ if !reflect.DeepEqual(got, tt.want) {
+ t.Errorf("%d. checkValidHTTP2Request = %v; want %v", i, got, tt.want)
+ }
+ }
+}
diff --git a/vendor/golang.org/x/net/http2/transport.go b/vendor/golang.org/x/net/http2/transport.go
index 7fe267bb..b5907dae 100644
--- a/vendor/golang.org/x/net/http2/transport.go
+++ b/vendor/golang.org/x/net/http2/transport.go
@@ -418,8 +418,8 @@ func (t *Transport) NewClientConn(c net.Conn) (*ClientConn, error) {
}
initialSettings := []Setting{
- Setting{ID: SettingEnablePush, Val: 0},
- Setting{ID: SettingInitialWindowSize, Val: transportDefaultStreamFlow},
+ {ID: SettingEnablePush, Val: 0},
+ {ID: SettingInitialWindowSize, Val: transportDefaultStreamFlow},
}
if max := t.maxHeaderListSize(); max != 0 {
initialSettings = append(initialSettings, Setting{ID: SettingMaxHeaderListSize, Val: max})
@@ -945,14 +945,11 @@ func (cc *ClientConn) encodeHeaders(req *http.Request, addGzipHeader bool, trail
// Host is :authority, already sent.
// Content-Length is automatic, set below.
continue
- case "connection", "proxy-connection", "transfer-encoding", "upgrade":
+ case "connection", "proxy-connection", "transfer-encoding", "upgrade", "keep-alive":
// Per 8.1.2.2 Connection-Specific Header
// Fields, don't send connection-specific
- // fields. We deal with these earlier in
- // RoundTrip, deciding whether they're
- // error-worthy, but we don't want to mutate
- // the user's *Request so at this point, just
- // skip over them at this point.
+ // fields. We have already checked if any
+ // are error-worthy so just ignore the rest.
continue
case "user-agent":
// Match Go's http1 behavior: at most one
@@ -1263,7 +1260,8 @@ func (rl *clientConnReadLoop) handleResponse(cs *clientStream, f *MetaHeadersFra
}
streamEnded := f.StreamEnded()
- if !streamEnded || cs.req.Method == "HEAD" {
+ isHead := cs.req.Method == "HEAD"
+ if !streamEnded || isHead {
res.ContentLength = -1
if clens := res.Header["Content-Length"]; len(clens) == 1 {
if clen64, err := strconv.ParseInt(clens[0], 10, 64); err == nil {
@@ -1278,7 +1276,7 @@ func (rl *clientConnReadLoop) handleResponse(cs *clientStream, f *MetaHeadersFra
}
}
- if streamEnded {
+ if streamEnded || isHead {
res.Body = noBody
return res, nil
}
diff --git a/vendor/golang.org/x/net/http2/transport_test.go b/vendor/golang.org/x/net/http2/transport_test.go
index 6b77a9ed..bcc2a5ff 100644
--- a/vendor/golang.org/x/net/http2/transport_test.go
+++ b/vendor/golang.org/x/net/http2/transport_test.go
@@ -326,28 +326,28 @@ func randString(n int) string {
return string(b)
}
-var bodyTests = []struct {
- body string
- noContentLen bool
-}{
- {body: "some message"},
- {body: "some message", noContentLen: true},
- {body: ""},
- {body: "", noContentLen: true},
- {body: strings.Repeat("a", 1<<20), noContentLen: true},
- {body: strings.Repeat("a", 1<<20)},
- {body: randString(16<<10 - 1)},
- {body: randString(16 << 10)},
- {body: randString(16<<10 + 1)},
- {body: randString(512<<10 - 1)},
- {body: randString(512 << 10)},
- {body: randString(512<<10 + 1)},
- {body: randString(1<<20 - 1)},
- {body: randString(1 << 20)},
- {body: randString(1<<20 + 2)},
-}
-
func TestTransportBody(t *testing.T) {
+ bodyTests := []struct {
+ body string
+ noContentLen bool
+ }{
+ {body: "some message"},
+ {body: "some message", noContentLen: true},
+ {body: ""},
+ {body: "", noContentLen: true},
+ {body: strings.Repeat("a", 1<<20), noContentLen: true},
+ {body: strings.Repeat("a", 1<<20)},
+ {body: randString(16<<10 - 1)},
+ {body: randString(16 << 10)},
+ {body: randString(16<<10 + 1)},
+ {body: randString(512<<10 - 1)},
+ {body: randString(512 << 10)},
+ {body: randString(512<<10 + 1)},
+ {body: randString(1<<20 - 1)},
+ {body: randString(1 << 20)},
+ {body: randString(1<<20 + 2)},
+ }
+
type reqInfo struct {
req *http.Request
slurp []byte
@@ -1642,6 +1642,11 @@ func TestTransportRejectsConnHeaders(t *testing.T) {
value: []string{"123"},
want: "Accept-Encoding,User-Agent",
},
+ {
+ key: "Keep-Alive",
+ value: []string{"doop"},
+ want: "Accept-Encoding,User-Agent",
+ },
}
for _, tt := range tests {
@@ -1738,3 +1743,60 @@ func TestTransportNewTLSConfig(t *testing.T) {
}
}
}
+
+// The Google GFE responds to HEAD requests with a HEADERS frame
+// without END_STREAM, followed by a 0-length DATA frame with
+// END_STREAM. Make sure we don't get confused by that. (We did.)
+func TestTransportReadHeadResponse(t *testing.T) {
+ ct := newClientTester(t)
+ clientDone := make(chan struct{})
+ ct.client = func() error {
+ defer close(clientDone)
+ req, _ := http.NewRequest("HEAD", "https://dummy.tld/", nil)
+ res, err := ct.tr.RoundTrip(req)
+ if err != nil {
+ return err
+ }
+ if res.ContentLength != 123 {
+ return fmt.Errorf("Content-Length = %d; want 123", res.ContentLength)
+ }
+ slurp, err := ioutil.ReadAll(res.Body)
+ if err != nil {
+ return fmt.Errorf("ReadAll: %v", err)
+ }
+ if len(slurp) > 0 {
+ return fmt.Errorf("Unexpected non-empty ReadAll body: %q", slurp)
+ }
+ return nil
+ }
+ ct.server = func() error {
+ ct.greet()
+ for {
+ f, err := ct.fr.ReadFrame()
+ if err != nil {
+ t.Logf("ReadFrame: %v", err)
+ return nil
+ }
+ hf, ok := f.(*HeadersFrame)
+ if !ok {
+ continue
+ }
+ var buf bytes.Buffer
+ enc := hpack.NewEncoder(&buf)
+ enc.WriteField(hpack.HeaderField{Name: ":status", Value: "200"})
+ enc.WriteField(hpack.HeaderField{Name: "content-length", Value: "123"})
+ ct.fr.WriteHeaders(HeadersFrameParam{
+ StreamID: hf.StreamID,
+ EndHeaders: true,
+ EndStream: false, // as the GFE does
+ BlockFragment: buf.Bytes(),
+ })
+ ct.fr.WriteData(hf.StreamID, true, nil)
+
+ <-clientDone
+ return nil
+ }
+ return nil
+ }
+ ct.run()
+}
diff --git a/vendor/golang.org/x/net/http2/write.go b/vendor/golang.org/x/net/http2/write.go
index 5297a4bf..0143b24c 100644
--- a/vendor/golang.org/x/net/http2/write.go
+++ b/vendor/golang.org/x/net/http2/write.go
@@ -9,7 +9,6 @@ import (
"fmt"
"log"
"net/http"
- "sort"
"time"
"golang.org/x/net/http2/hpack"
@@ -230,13 +229,13 @@ func (wu writeWindowUpdate) writeFrame(ctx writeContext) error {
}
func encodeHeaders(enc *hpack.Encoder, h http.Header, keys []string) {
- // TODO: garbage. pool sorters like http1? hot path for 1 key?
if keys == nil {
- keys = make([]string, 0, len(h))
- for k := range h {
- keys = append(keys, k)
- }
- sort.Strings(keys)
+ sorter := sorterPool.Get().(*sorter)
+ // Using defer here, since the returned keys from the
+ // sorter.Keys method is only valid until the sorter
+ // is returned:
+ defer sorterPool.Put(sorter)
+ keys = sorter.Keys(h)
}
for _, k := range keys {
vv := h[k]
diff --git a/vendor/golang.org/x/net/http2/z_spec_test.go b/vendor/golang.org/x/net/http2/z_spec_test.go
index e0f420a1..0590cfde 100644
--- a/vendor/golang.org/x/net/http2/z_spec_test.go
+++ b/vendor/golang.org/x/net/http2/z_spec_test.go
@@ -37,7 +37,7 @@ func loadSpec() {
}
// covers marks all sentences for section sec in defaultSpecCoverage. Sentences not
-// "covered" will be included in report outputed by TestSpecCoverage.
+// "covered" will be included in report outputted by TestSpecCoverage.
func covers(sec, sentences string) {
loadSpecOnce.Do(loadSpec)
defaultSpecCoverage.cover(sec, sentences)
diff --git a/vendor/golang.org/x/net/trace/trace.go b/vendor/golang.org/x/net/trace/trace.go
index 197402e0..9ee19362 100644
--- a/vendor/golang.org/x/net/trace/trace.go
+++ b/vendor/golang.org/x/net/trace/trace.go
@@ -95,11 +95,14 @@ var DebugUseAfterFinish = false
//
// The default AuthRequest function returns (true, true) iff the request comes from localhost/127.0.0.1/[::1].
var AuthRequest = func(req *http.Request) (any, sensitive bool) {
+ // RemoteAddr is commonly in the form "IP" or "IP:port".
+ // If it is in the form "IP:port", split off the port.
host, _, err := net.SplitHostPort(req.RemoteAddr)
- switch {
- case err != nil: // Badly formed address; fail closed.
- return false, false
- case host == "localhost" || host == "127.0.0.1" || host == "::1":
+ if err != nil {
+ host = req.RemoteAddr
+ }
+ switch host {
+ case "localhost", "127.0.0.1", "::1":
return true, true
default:
return false, false
diff --git a/vendor/golang.org/x/net/trace/trace_test.go b/vendor/golang.org/x/net/trace/trace_test.go
index c2f5fcba..14d7c237 100644
--- a/vendor/golang.org/x/net/trace/trace_test.go
+++ b/vendor/golang.org/x/net/trace/trace_test.go
@@ -5,6 +5,7 @@
package trace
import (
+ "net/http"
"reflect"
"testing"
)
@@ -44,3 +45,27 @@ func TestResetLog(t *testing.T) {
t.Errorf("reset didn't clear all fields: %+v", el)
}
}
+
+func TestAuthRequest(t *testing.T) {
+ testCases := []struct {
+ host string
+ want bool
+ }{
+ {host: "192.168.23.1", want: false},
+ {host: "192.168.23.1:8080", want: false},
+ {host: "malformed remote addr", want: false},
+ {host: "localhost", want: true},
+ {host: "localhost:8080", want: true},
+ {host: "127.0.0.1", want: true},
+ {host: "127.0.0.1:8080", want: true},
+ {host: "::1", want: true},
+ {host: "[::1]:8080", want: true},
+ }
+ for _, tt := range testCases {
+ req := &http.Request{RemoteAddr: tt.host}
+ any, sensitive := AuthRequest(req)
+ if any != tt.want || sensitive != tt.want {
+ t.Errorf("AuthRequest(%q) = %t, %t; want %t, %t", tt.host, any, sensitive, tt.want, tt.want)
+ }
+ }
+}
diff --git a/vendor/golang.org/x/oauth2/.travis.yml b/vendor/golang.org/x/oauth2/.travis.yml
deleted file mode 100644
index a035125c..00000000
--- a/vendor/golang.org/x/oauth2/.travis.yml
+++ /dev/null
@@ -1,14 +0,0 @@
-language: go
-
-go:
- - 1.3
- - 1.4
-
-install:
- - export GOPATH="$HOME/gopath"
- - mkdir -p "$GOPATH/src/golang.org/x"
- - mv "$TRAVIS_BUILD_DIR" "$GOPATH/src/golang.org/x/oauth2"
- - go get -v -t -d golang.org/x/oauth2/...
-
-script:
- - go test -v golang.org/x/oauth2/...
diff --git a/vendor/golang.org/x/oauth2/AUTHORS b/vendor/golang.org/x/oauth2/AUTHORS
deleted file mode 100644
index 15167cd7..00000000
--- a/vendor/golang.org/x/oauth2/AUTHORS
+++ /dev/null
@@ -1,3 +0,0 @@
-# This source code refers to The Go Authors for copyright purposes.
-# The master list of authors is in the main Go distribution,
-# visible at http://tip.golang.org/AUTHORS.
diff --git a/vendor/golang.org/x/oauth2/CONTRIBUTING.md b/vendor/golang.org/x/oauth2/CONTRIBUTING.md
deleted file mode 100644
index 46aa2b12..00000000
--- a/vendor/golang.org/x/oauth2/CONTRIBUTING.md
+++ /dev/null
@@ -1,31 +0,0 @@
-# Contributing to Go
-
-Go is an open source project.
-
-It is the work of hundreds of contributors. We appreciate your help!
-
-
-## Filing issues
-
-When [filing an issue](https://github.com/golang/oauth2/issues), make sure to answer these five questions:
-
-1. What version of Go are you using (`go version`)?
-2. What operating system and processor architecture are you using?
-3. What did you do?
-4. What did you expect to see?
-5. What did you see instead?
-
-General questions should go to the [golang-nuts mailing list](https://groups.google.com/group/golang-nuts) instead of the issue tracker.
-The gophers there will answer or ask you to file an issue if you've tripped over a bug.
-
-## Contributing code
-
-Please read the [Contribution Guidelines](https://golang.org/doc/contribute.html)
-before sending patches.
-
-**We do not accept GitHub pull requests**
-(we use [Gerrit](https://code.google.com/p/gerrit/) instead for code review).
-
-Unless otherwise noted, the Go source files are distributed under
-the BSD-style license found in the LICENSE file.
-
diff --git a/vendor/golang.org/x/oauth2/CONTRIBUTORS b/vendor/golang.org/x/oauth2/CONTRIBUTORS
deleted file mode 100644
index 1c4577e9..00000000
--- a/vendor/golang.org/x/oauth2/CONTRIBUTORS
+++ /dev/null
@@ -1,3 +0,0 @@
-# This source code was written by the Go contributors.
-# The master list of contributors is in the main Go distribution,
-# visible at http://tip.golang.org/CONTRIBUTORS.
diff --git a/vendor/golang.org/x/oauth2/LICENSE b/vendor/golang.org/x/oauth2/LICENSE
deleted file mode 100644
index d02f24fd..00000000
--- a/vendor/golang.org/x/oauth2/LICENSE
+++ /dev/null
@@ -1,27 +0,0 @@
-Copyright (c) 2009 The oauth2 Authors. All rights reserved.
-
-Redistribution and use in source and binary forms, with or without
-modification, are permitted provided that the following conditions are
-met:
-
- * Redistributions of source code must retain the above copyright
-notice, this list of conditions and the following disclaimer.
- * Redistributions in binary form must reproduce the above
-copyright notice, this list of conditions and the following disclaimer
-in the documentation and/or other materials provided with the
-distribution.
- * Neither the name of Google Inc. nor the names of its
-contributors may be used to endorse or promote products derived from
-this software without specific prior written permission.
-
-THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
-"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
-LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
-A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
-OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
-SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
-LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
-DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
-THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
-(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
-OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
diff --git a/vendor/golang.org/x/oauth2/README.md b/vendor/golang.org/x/oauth2/README.md
deleted file mode 100644
index 0d514173..00000000
--- a/vendor/golang.org/x/oauth2/README.md
+++ /dev/null
@@ -1,64 +0,0 @@
-# OAuth2 for Go
-
-[](https://travis-ci.org/golang/oauth2)
-
-oauth2 package contains a client implementation for OAuth 2.0 spec.
-
-## Installation
-
-~~~~
-go get golang.org/x/oauth2
-~~~~
-
-See godoc for further documentation and examples.
-
-* [godoc.org/golang.org/x/oauth2](http://godoc.org/golang.org/x/oauth2)
-* [godoc.org/golang.org/x/oauth2/google](http://godoc.org/golang.org/x/oauth2/google)
-
-
-## App Engine
-
-In change 96e89be (March 2015) we removed the `oauth2.Context2` type in favor
-of the [`context.Context`](https://golang.org/x/net/context#Context) type from
-the `golang.org/x/net/context` package
-
-This means its no longer possible to use the "Classic App Engine"
-`appengine.Context` type with the `oauth2` package. (You're using
-Classic App Engine if you import the package `"appengine"`.)
-
-To work around this, you may use the new `"google.golang.org/appengine"`
-package. This package has almost the same API as the `"appengine"` package,
-but it can be fetched with `go get` and used on "Managed VMs" and well as
-Classic App Engine.
-
-See the [new `appengine` package's readme](https://github.com/golang/appengine#updating-a-go-app-engine-app)
-for information on updating your app.
-
-If you don't want to update your entire app to use the new App Engine packages,
-you may use both sets of packages in parallel, using only the new packages
-with the `oauth2` package.
-
- import (
- "golang.org/x/net/context"
- "golang.org/x/oauth2"
- "golang.org/x/oauth2/google"
- newappengine "google.golang.org/appengine"
- newurlfetch "google.golang.org/appengine/urlfetch"
-
- "appengine"
- )
-
- func handler(w http.ResponseWriter, r *http.Request) {
- var c appengine.Context = appengine.NewContext(r)
- c.Infof("Logging a message with the old package")
-
- var ctx context.Context = newappengine.NewContext(r)
- client := &http.Client{
- Transport: &oauth2.Transport{
- Source: google.AppEngineTokenSource(ctx, "scope"),
- Base: &newurlfetch.Transport{Context: ctx},
- },
- }
- client.Get("...")
- }
-
diff --git a/vendor/golang.org/x/oauth2/bitbucket/bitbucket.go b/vendor/golang.org/x/oauth2/bitbucket/bitbucket.go
deleted file mode 100644
index 44af1f1a..00000000
--- a/vendor/golang.org/x/oauth2/bitbucket/bitbucket.go
+++ /dev/null
@@ -1,16 +0,0 @@
-// Copyright 2015 The oauth2 Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style
-// license that can be found in the LICENSE file.
-
-// Package bitbucket provides constants for using OAuth2 to access Bitbucket.
-package bitbucket
-
-import (
- "golang.org/x/oauth2"
-)
-
-// Endpoint is Bitbucket's OAuth 2.0 endpoint.
-var Endpoint = oauth2.Endpoint{
- AuthURL: "https://bitbucket.org/site/oauth2/authorize",
- TokenURL: "https://bitbucket.org/site/oauth2/access_token",
-}
diff --git a/vendor/golang.org/x/oauth2/client_appengine.go b/vendor/golang.org/x/oauth2/client_appengine.go
deleted file mode 100644
index 52f8d1dd..00000000
--- a/vendor/golang.org/x/oauth2/client_appengine.go
+++ /dev/null
@@ -1,25 +0,0 @@
-// Copyright 2014 The oauth2 Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style
-// license that can be found in the LICENSE file.
-
-// +build appengine
-
-// App Engine hooks.
-
-package oauth2
-
-import (
- "net/http"
-
- "golang.org/x/net/context"
- "golang.org/x/oauth2/internal"
- "google.golang.org/appengine/urlfetch"
-)
-
-func init() {
- internal.RegisterContextClientFunc(contextClientAppEngine)
-}
-
-func contextClientAppEngine(ctx context.Context) (*http.Client, error) {
- return urlfetch.Client(ctx), nil
-}
diff --git a/vendor/golang.org/x/oauth2/clientcredentials/clientcredentials.go b/vendor/golang.org/x/oauth2/clientcredentials/clientcredentials.go
deleted file mode 100644
index 452fb8c1..00000000
--- a/vendor/golang.org/x/oauth2/clientcredentials/clientcredentials.go
+++ /dev/null
@@ -1,112 +0,0 @@
-// Copyright 2014 The oauth2 Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style
-// license that can be found in the LICENSE file.
-
-// Package clientcredentials implements the OAuth2.0 "client credentials" token flow,
-// also known as the "two-legged OAuth 2.0".
-//
-// This should be used when the client is acting on its own behalf or when the client
-// is the resource owner. It may also be used when requesting access to protected
-// resources based on an authorization previously arranged with the authorization
-// server.
-//
-// See http://tools.ietf.org/html/draft-ietf-oauth-v2-31#section-4.4
-package clientcredentials
-
-import (
- "net/http"
- "net/url"
- "strings"
-
- "golang.org/x/net/context"
- "golang.org/x/oauth2"
- "golang.org/x/oauth2/internal"
-)
-
-// tokenFromInternal maps an *internal.Token struct into
-// an *oauth2.Token struct.
-func tokenFromInternal(t *internal.Token) *oauth2.Token {
- if t == nil {
- return nil
- }
- tk := &oauth2.Token{
- AccessToken: t.AccessToken,
- TokenType: t.TokenType,
- RefreshToken: t.RefreshToken,
- Expiry: t.Expiry,
- }
- return tk.WithExtra(t.Raw)
-}
-
-// retrieveToken takes a *Config and uses that to retrieve an *internal.Token.
-// This token is then mapped from *internal.Token into an *oauth2.Token which is
-// returned along with an error.
-func retrieveToken(ctx context.Context, c *Config, v url.Values) (*oauth2.Token, error) {
- tk, err := internal.RetrieveToken(ctx, c.ClientID, c.ClientSecret, c.TokenURL, v)
- if err != nil {
- return nil, err
- }
- return tokenFromInternal(tk), nil
-}
-
-// Client Credentials Config describes a 2-legged OAuth2 flow, with both the
-// client application information and the server's endpoint URLs.
-type Config struct {
- // ClientID is the application's ID.
- ClientID string
-
- // ClientSecret is the application's secret.
- ClientSecret string
-
- // TokenURL is the resource server's token endpoint
- // URL. This is a constant specific to each server.
- TokenURL string
-
- // Scope specifies optional requested permissions.
- Scopes []string
-}
-
-// Token uses client credentials to retreive a token.
-// The HTTP client to use is derived from the context.
-// If nil, http.DefaultClient is used.
-func (c *Config) Token(ctx context.Context) (*oauth2.Token, error) {
- return retrieveToken(ctx, c, url.Values{
- "grant_type": {"client_credentials"},
- "scope": internal.CondVal(strings.Join(c.Scopes, " ")),
- })
-}
-
-// Client returns an HTTP client using the provided token.
-// The token will auto-refresh as necessary. The underlying
-// HTTP transport will be obtained using the provided context.
-// The returned client and its Transport should not be modified.
-func (c *Config) Client(ctx context.Context) *http.Client {
- return oauth2.NewClient(ctx, c.TokenSource(ctx))
-}
-
-// TokenSource returns a TokenSource that returns t until t expires,
-// automatically refreshing it as necessary using the provided context and the
-// client ID and client secret.
-//
-// Most users will use Config.Client instead.
-func (c *Config) TokenSource(ctx context.Context) oauth2.TokenSource {
- source := &tokenSource{
- ctx: ctx,
- conf: c,
- }
- return oauth2.ReuseTokenSource(nil, source)
-}
-
-type tokenSource struct {
- ctx context.Context
- conf *Config
-}
-
-// Token refreshes the token by using a new client credentials request.
-// tokens received this way do not include a refresh token
-func (c *tokenSource) Token() (*oauth2.Token, error) {
- return retrieveToken(c.ctx, c.conf, url.Values{
- "grant_type": {"client_credentials"},
- "scope": internal.CondVal(strings.Join(c.conf.Scopes, " ")),
- })
-}
diff --git a/vendor/golang.org/x/oauth2/clientcredentials/clientcredentials_test.go b/vendor/golang.org/x/oauth2/clientcredentials/clientcredentials_test.go
deleted file mode 100644
index ab319e08..00000000
--- a/vendor/golang.org/x/oauth2/clientcredentials/clientcredentials_test.go
+++ /dev/null
@@ -1,96 +0,0 @@
-// Copyright 2014 The oauth2 Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style
-// license that can be found in the LICENSE file.
-
-package clientcredentials
-
-import (
- "io/ioutil"
- "net/http"
- "net/http/httptest"
- "testing"
-
- "golang.org/x/oauth2"
-)
-
-func newConf(url string) *Config {
- return &Config{
- ClientID: "CLIENT_ID",
- ClientSecret: "CLIENT_SECRET",
- Scopes: []string{"scope1", "scope2"},
- TokenURL: url + "/token",
- }
-}
-
-type mockTransport struct {
- rt func(req *http.Request) (resp *http.Response, err error)
-}
-
-func (t *mockTransport) RoundTrip(req *http.Request) (resp *http.Response, err error) {
- return t.rt(req)
-}
-
-func TestTokenRequest(t *testing.T) {
- ts := httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
- if r.URL.String() != "/token" {
- t.Errorf("authenticate client request URL = %q; want %q", r.URL, "/token")
- }
- headerAuth := r.Header.Get("Authorization")
- if headerAuth != "Basic Q0xJRU5UX0lEOkNMSUVOVF9TRUNSRVQ=" {
- t.Errorf("Unexpected authorization header, %v is found.", headerAuth)
- }
- if got, want := r.Header.Get("Content-Type"), "application/x-www-form-urlencoded"; got != want {
- t.Errorf("Content-Type header = %q; want %q", got, want)
- }
- body, err := ioutil.ReadAll(r.Body)
- if err != nil {
- r.Body.Close()
- }
- if err != nil {
- t.Errorf("failed reading request body: %s.", err)
- }
- if string(body) != "client_id=CLIENT_ID&grant_type=client_credentials&scope=scope1+scope2" {
- t.Errorf("payload = %q; want %q", string(body), "client_id=CLIENT_ID&grant_type=client_credentials&scope=scope1+scope2")
- }
- w.Header().Set("Content-Type", "application/x-www-form-urlencoded")
- w.Write([]byte("access_token=90d64460d14870c08c81352a05dedd3465940a7c&token_type=bearer"))
- }))
- defer ts.Close()
- conf := newConf(ts.URL)
- tok, err := conf.Token(oauth2.NoContext)
- if err != nil {
- t.Error(err)
- }
- if !tok.Valid() {
- t.Fatalf("token invalid. got: %#v", tok)
- }
- if tok.AccessToken != "90d64460d14870c08c81352a05dedd3465940a7c" {
- t.Errorf("Access token = %q; want %q", tok.AccessToken, "90d64460d14870c08c81352a05dedd3465940a7c")
- }
- if tok.TokenType != "bearer" {
- t.Errorf("token type = %q; want %q", tok.TokenType, "bearer")
- }
-}
-
-func TestTokenRefreshRequest(t *testing.T) {
- ts := httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
- if r.URL.String() == "/somethingelse" {
- return
- }
- if r.URL.String() != "/token" {
- t.Errorf("Unexpected token refresh request URL, %v is found.", r.URL)
- }
- headerContentType := r.Header.Get("Content-Type")
- if headerContentType != "application/x-www-form-urlencoded" {
- t.Errorf("Unexpected Content-Type header, %v is found.", headerContentType)
- }
- body, _ := ioutil.ReadAll(r.Body)
- if string(body) != "client_id=CLIENT_ID&grant_type=client_credentials&scope=scope1+scope2" {
- t.Errorf("Unexpected refresh token payload, %v is found.", string(body))
- }
- }))
- defer ts.Close()
- conf := newConf(ts.URL)
- c := conf.Client(oauth2.NoContext)
- c.Get(ts.URL + "/somethingelse")
-}
diff --git a/vendor/golang.org/x/oauth2/example_test.go b/vendor/golang.org/x/oauth2/example_test.go
deleted file mode 100644
index 8be27885..00000000
--- a/vendor/golang.org/x/oauth2/example_test.go
+++ /dev/null
@@ -1,45 +0,0 @@
-// Copyright 2014 The oauth2 Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style
-// license that can be found in the LICENSE file.
-
-package oauth2_test
-
-import (
- "fmt"
- "log"
-
- "golang.org/x/oauth2"
-)
-
-func ExampleConfig() {
- conf := &oauth2.Config{
- ClientID: "YOUR_CLIENT_ID",
- ClientSecret: "YOUR_CLIENT_SECRET",
- Scopes: []string{"SCOPE1", "SCOPE2"},
- Endpoint: oauth2.Endpoint{
- AuthURL: "https://provider.com/o/oauth2/auth",
- TokenURL: "https://provider.com/o/oauth2/token",
- },
- }
-
- // Redirect user to consent page to ask for permission
- // for the scopes specified above.
- url := conf.AuthCodeURL("state", oauth2.AccessTypeOffline)
- fmt.Printf("Visit the URL for the auth dialog: %v", url)
-
- // Use the authorization code that is pushed to the redirect URL.
- // NewTransportWithCode will do the handshake to retrieve
- // an access token and initiate a Transport that is
- // authorized and authenticated by the retrieved token.
- var code string
- if _, err := fmt.Scan(&code); err != nil {
- log.Fatal(err)
- }
- tok, err := conf.Exchange(oauth2.NoContext, code)
- if err != nil {
- log.Fatal(err)
- }
-
- client := conf.Client(oauth2.NoContext, tok)
- client.Get("...")
-}
diff --git a/vendor/golang.org/x/oauth2/facebook/facebook.go b/vendor/golang.org/x/oauth2/facebook/facebook.go
deleted file mode 100644
index 9c816ff8..00000000
--- a/vendor/golang.org/x/oauth2/facebook/facebook.go
+++ /dev/null
@@ -1,16 +0,0 @@
-// Copyright 2015 The oauth2 Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style
-// license that can be found in the LICENSE file.
-
-// Package facebook provides constants for using OAuth2 to access Facebook.
-package facebook
-
-import (
- "golang.org/x/oauth2"
-)
-
-// Endpoint is Facebook's OAuth 2.0 endpoint.
-var Endpoint = oauth2.Endpoint{
- AuthURL: "https://www.facebook.com/dialog/oauth",
- TokenURL: "https://graph.facebook.com/oauth/access_token",
-}
diff --git a/vendor/golang.org/x/oauth2/github/github.go b/vendor/golang.org/x/oauth2/github/github.go
deleted file mode 100644
index 82ca623d..00000000
--- a/vendor/golang.org/x/oauth2/github/github.go
+++ /dev/null
@@ -1,16 +0,0 @@
-// Copyright 2014 The oauth2 Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style
-// license that can be found in the LICENSE file.
-
-// Package github provides constants for using OAuth2 to access Github.
-package github
-
-import (
- "golang.org/x/oauth2"
-)
-
-// Endpoint is Github's OAuth 2.0 endpoint.
-var Endpoint = oauth2.Endpoint{
- AuthURL: "https://github.com/login/oauth/authorize",
- TokenURL: "https://github.com/login/oauth/access_token",
-}
diff --git a/vendor/golang.org/x/oauth2/google/appengine.go b/vendor/golang.org/x/oauth2/google/appengine.go
deleted file mode 100644
index 85542215..00000000
--- a/vendor/golang.org/x/oauth2/google/appengine.go
+++ /dev/null
@@ -1,86 +0,0 @@
-// Copyright 2014 The oauth2 Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style
-// license that can be found in the LICENSE file.
-
-package google
-
-import (
- "sort"
- "strings"
- "sync"
- "time"
-
- "golang.org/x/net/context"
- "golang.org/x/oauth2"
-)
-
-// Set at init time by appenginevm_hook.go. If true, we are on App Engine Managed VMs.
-var appengineVM bool
-
-// Set at init time by appengine_hook.go. If nil, we're not on App Engine.
-var appengineTokenFunc func(c context.Context, scopes ...string) (token string, expiry time.Time, err error)
-
-// AppEngineTokenSource returns a token source that fetches tokens
-// issued to the current App Engine application's service account.
-// If you are implementing a 3-legged OAuth 2.0 flow on App Engine
-// that involves user accounts, see oauth2.Config instead.
-//
-// The provided context must have come from appengine.NewContext.
-func AppEngineTokenSource(ctx context.Context, scope ...string) oauth2.TokenSource {
- if appengineTokenFunc == nil {
- panic("google: AppEngineTokenSource can only be used on App Engine.")
- }
- scopes := append([]string{}, scope...)
- sort.Strings(scopes)
- return &appEngineTokenSource{
- ctx: ctx,
- scopes: scopes,
- key: strings.Join(scopes, " "),
- }
-}
-
-// aeTokens helps the fetched tokens to be reused until their expiration.
-var (
- aeTokensMu sync.Mutex
- aeTokens = make(map[string]*tokenLock) // key is space-separated scopes
-)
-
-type tokenLock struct {
- mu sync.Mutex // guards t; held while fetching or updating t
- t *oauth2.Token
-}
-
-type appEngineTokenSource struct {
- ctx context.Context
- scopes []string
- key string // to aeTokens map; space-separated scopes
-}
-
-func (ts *appEngineTokenSource) Token() (*oauth2.Token, error) {
- if appengineTokenFunc == nil {
- panic("google: AppEngineTokenSource can only be used on App Engine.")
- }
-
- aeTokensMu.Lock()
- tok, ok := aeTokens[ts.key]
- if !ok {
- tok = &tokenLock{}
- aeTokens[ts.key] = tok
- }
- aeTokensMu.Unlock()
-
- tok.mu.Lock()
- defer tok.mu.Unlock()
- if tok.t.Valid() {
- return tok.t, nil
- }
- access, exp, err := appengineTokenFunc(ts.ctx, ts.scopes...)
- if err != nil {
- return nil, err
- }
- tok.t = &oauth2.Token{
- AccessToken: access,
- Expiry: exp,
- }
- return tok.t, nil
-}
diff --git a/vendor/golang.org/x/oauth2/google/appengine_hook.go b/vendor/golang.org/x/oauth2/google/appengine_hook.go
deleted file mode 100644
index 362766fd..00000000
--- a/vendor/golang.org/x/oauth2/google/appengine_hook.go
+++ /dev/null
@@ -1,13 +0,0 @@
-// Copyright 2015 The oauth2 Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style
-// license that can be found in the LICENSE file.
-
-// +build appengine
-
-package google
-
-import "google.golang.org/appengine"
-
-func init() {
- appengineTokenFunc = appengine.AccessToken
-}
diff --git a/vendor/golang.org/x/oauth2/google/appenginevm_hook.go b/vendor/golang.org/x/oauth2/google/appenginevm_hook.go
deleted file mode 100644
index 633611cc..00000000
--- a/vendor/golang.org/x/oauth2/google/appenginevm_hook.go
+++ /dev/null
@@ -1,14 +0,0 @@
-// Copyright 2015 The oauth2 Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style
-// license that can be found in the LICENSE file.
-
-// +build appenginevm
-
-package google
-
-import "google.golang.org/appengine"
-
-func init() {
- appengineVM = true
- appengineTokenFunc = appengine.AccessToken
-}
diff --git a/vendor/golang.org/x/oauth2/google/default.go b/vendor/golang.org/x/oauth2/google/default.go
deleted file mode 100644
index 66daeefd..00000000
--- a/vendor/golang.org/x/oauth2/google/default.go
+++ /dev/null
@@ -1,155 +0,0 @@
-// Copyright 2015 The oauth2 Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style
-// license that can be found in the LICENSE file.
-
-package google
-
-import (
- "encoding/json"
- "errors"
- "fmt"
- "io/ioutil"
- "net/http"
- "os"
- "path/filepath"
- "runtime"
-
- "golang.org/x/net/context"
- "golang.org/x/oauth2"
- "golang.org/x/oauth2/jwt"
- "google.golang.org/cloud/compute/metadata"
-)
-
-// DefaultClient returns an HTTP Client that uses the
-// DefaultTokenSource to obtain authentication credentials.
-//
-// This client should be used when developing services
-// that run on Google App Engine or Google Compute Engine
-// and use "Application Default Credentials."
-//
-// For more details, see:
-// https://developers.google.com/accounts/docs/application-default-credentials
-//
-func DefaultClient(ctx context.Context, scope ...string) (*http.Client, error) {
- ts, err := DefaultTokenSource(ctx, scope...)
- if err != nil {
- return nil, err
- }
- return oauth2.NewClient(ctx, ts), nil
-}
-
-// DefaultTokenSource is a token source that uses
-// "Application Default Credentials".
-//
-// It looks for credentials in the following places,
-// preferring the first location found:
-//
-// 1. A JSON file whose path is specified by the
-// GOOGLE_APPLICATION_CREDENTIALS environment variable.
-// 2. A JSON file in a location known to the gcloud command-line tool.
-// On Windows, this is %APPDATA%/gcloud/application_default_credentials.json.
-// On other systems, $HOME/.config/gcloud/application_default_credentials.json.
-// 3. On Google App Engine it uses the appengine.AccessToken function.
-// 4. On Google Compute Engine and Google App Engine Managed VMs, it fetches
-// credentials from the metadata server.
-// (In this final case any provided scopes are ignored.)
-//
-// For more details, see:
-// https://developers.google.com/accounts/docs/application-default-credentials
-//
-func DefaultTokenSource(ctx context.Context, scope ...string) (oauth2.TokenSource, error) {
- // First, try the environment variable.
- const envVar = "GOOGLE_APPLICATION_CREDENTIALS"
- if filename := os.Getenv(envVar); filename != "" {
- ts, err := tokenSourceFromFile(ctx, filename, scope)
- if err != nil {
- return nil, fmt.Errorf("google: error getting credentials using %v environment variable: %v", envVar, err)
- }
- return ts, nil
- }
-
- // Second, try a well-known file.
- filename := wellKnownFile()
- _, err := os.Stat(filename)
- if err == nil {
- ts, err2 := tokenSourceFromFile(ctx, filename, scope)
- if err2 == nil {
- return ts, nil
- }
- err = err2
- } else if os.IsNotExist(err) {
- err = nil // ignore this error
- }
- if err != nil {
- return nil, fmt.Errorf("google: error getting credentials using well-known file (%v): %v", filename, err)
- }
-
- // Third, if we're on Google App Engine use those credentials.
- if appengineTokenFunc != nil && !appengineVM {
- return AppEngineTokenSource(ctx, scope...), nil
- }
-
- // Fourth, if we're on Google Compute Engine use the metadata server.
- if metadata.OnGCE() {
- return ComputeTokenSource(""), nil
- }
-
- // None are found; return helpful error.
- const url = "https://developers.google.com/accounts/docs/application-default-credentials"
- return nil, fmt.Errorf("google: could not find default credentials. See %v for more information.", url)
-}
-
-func wellKnownFile() string {
- const f = "application_default_credentials.json"
- if runtime.GOOS == "windows" {
- return filepath.Join(os.Getenv("APPDATA"), "gcloud", f)
- }
- return filepath.Join(guessUnixHomeDir(), ".config", "gcloud", f)
-}
-
-func tokenSourceFromFile(ctx context.Context, filename string, scopes []string) (oauth2.TokenSource, error) {
- b, err := ioutil.ReadFile(filename)
- if err != nil {
- return nil, err
- }
- var d struct {
- // Common fields
- Type string
- ClientID string `json:"client_id"`
-
- // User Credential fields
- ClientSecret string `json:"client_secret"`
- RefreshToken string `json:"refresh_token"`
-
- // Service Account fields
- ClientEmail string `json:"client_email"`
- PrivateKeyID string `json:"private_key_id"`
- PrivateKey string `json:"private_key"`
- }
- if err := json.Unmarshal(b, &d); err != nil {
- return nil, err
- }
- switch d.Type {
- case "authorized_user":
- cfg := &oauth2.Config{
- ClientID: d.ClientID,
- ClientSecret: d.ClientSecret,
- Scopes: append([]string{}, scopes...), // copy
- Endpoint: Endpoint,
- }
- tok := &oauth2.Token{RefreshToken: d.RefreshToken}
- return cfg.TokenSource(ctx, tok), nil
- case "service_account":
- cfg := &jwt.Config{
- Email: d.ClientEmail,
- PrivateKey: []byte(d.PrivateKey),
- Scopes: append([]string{}, scopes...), // copy
- TokenURL: JWTTokenURL,
- }
- return cfg.TokenSource(ctx), nil
- case "":
- return nil, errors.New("missing 'type' field in credentials")
- default:
- return nil, fmt.Errorf("unknown credential type: %q", d.Type)
- }
-}
diff --git a/vendor/golang.org/x/oauth2/google/example_test.go b/vendor/golang.org/x/oauth2/google/example_test.go
deleted file mode 100644
index 17262802..00000000
--- a/vendor/golang.org/x/oauth2/google/example_test.go
+++ /dev/null
@@ -1,150 +0,0 @@
-// Copyright 2014 The oauth2 Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style
-// license that can be found in the LICENSE file.
-
-// +build appenginevm !appengine
-
-package google_test
-
-import (
- "fmt"
- "io/ioutil"
- "log"
- "net/http"
-
- "golang.org/x/oauth2"
- "golang.org/x/oauth2/google"
- "golang.org/x/oauth2/jwt"
- "google.golang.org/appengine"
- "google.golang.org/appengine/urlfetch"
-)
-
-func ExampleDefaultClient() {
- client, err := google.DefaultClient(oauth2.NoContext,
- "https://www.googleapis.com/auth/devstorage.full_control")
- if err != nil {
- log.Fatal(err)
- }
- client.Get("...")
-}
-
-func Example_webServer() {
- // Your credentials should be obtained from the Google
- // Developer Console (https://console.developers.google.com).
- conf := &oauth2.Config{
- ClientID: "YOUR_CLIENT_ID",
- ClientSecret: "YOUR_CLIENT_SECRET",
- RedirectURL: "YOUR_REDIRECT_URL",
- Scopes: []string{
- "https://www.googleapis.com/auth/bigquery",
- "https://www.googleapis.com/auth/blogger",
- },
- Endpoint: google.Endpoint,
- }
- // Redirect user to Google's consent page to ask for permission
- // for the scopes specified above.
- url := conf.AuthCodeURL("state")
- fmt.Printf("Visit the URL for the auth dialog: %v", url)
-
- // Handle the exchange code to initiate a transport.
- tok, err := conf.Exchange(oauth2.NoContext, "authorization-code")
- if err != nil {
- log.Fatal(err)
- }
- client := conf.Client(oauth2.NoContext, tok)
- client.Get("...")
-}
-
-func ExampleJWTConfigFromJSON() {
- // Your credentials should be obtained from the Google
- // Developer Console (https://console.developers.google.com).
- // Navigate to your project, then see the "Credentials" page
- // under "APIs & Auth".
- // To create a service account client, click "Create new Client ID",
- // select "Service Account", and click "Create Client ID". A JSON
- // key file will then be downloaded to your computer.
- data, err := ioutil.ReadFile("/path/to/your-project-key.json")
- if err != nil {
- log.Fatal(err)
- }
- conf, err := google.JWTConfigFromJSON(data, "https://www.googleapis.com/auth/bigquery")
- if err != nil {
- log.Fatal(err)
- }
- // Initiate an http.Client. The following GET request will be
- // authorized and authenticated on the behalf of
- // your service account.
- client := conf.Client(oauth2.NoContext)
- client.Get("...")
-}
-
-func ExampleSDKConfig() {
- // The credentials will be obtained from the first account that
- // has been authorized with `gcloud auth login`.
- conf, err := google.NewSDKConfig("")
- if err != nil {
- log.Fatal(err)
- }
- // Initiate an http.Client. The following GET request will be
- // authorized and authenticated on the behalf of the SDK user.
- client := conf.Client(oauth2.NoContext)
- client.Get("...")
-}
-
-func Example_serviceAccount() {
- // Your credentials should be obtained from the Google
- // Developer Console (https://console.developers.google.com).
- conf := &jwt.Config{
- Email: "xxx@developer.gserviceaccount.com",
- // The contents of your RSA private key or your PEM file
- // that contains a private key.
- // If you have a p12 file instead, you
- // can use `openssl` to export the private key into a pem file.
- //
- // $ openssl pkcs12 -in key.p12 -passin pass:notasecret -out key.pem -nodes
- //
- // The field only supports PEM containers with no passphrase.
- // The openssl command will convert p12 keys to passphrase-less PEM containers.
- PrivateKey: []byte("-----BEGIN RSA PRIVATE KEY-----..."),
- Scopes: []string{
- "https://www.googleapis.com/auth/bigquery",
- "https://www.googleapis.com/auth/blogger",
- },
- TokenURL: google.JWTTokenURL,
- // If you would like to impersonate a user, you can
- // create a transport with a subject. The following GET
- // request will be made on the behalf of user@example.com.
- // Optional.
- Subject: "user@example.com",
- }
- // Initiate an http.Client, the following GET request will be
- // authorized and authenticated on the behalf of user@example.com.
- client := conf.Client(oauth2.NoContext)
- client.Get("...")
-}
-
-func ExampleAppEngineTokenSource() {
- var req *http.Request // from the ServeHTTP handler
- ctx := appengine.NewContext(req)
- client := &http.Client{
- Transport: &oauth2.Transport{
- Source: google.AppEngineTokenSource(ctx, "https://www.googleapis.com/auth/bigquery"),
- Base: &urlfetch.Transport{
- Context: ctx,
- },
- },
- }
- client.Get("...")
-}
-
-func ExampleComputeTokenSource() {
- client := &http.Client{
- Transport: &oauth2.Transport{
- // Fetch from Google Compute Engine's metadata server to retrieve
- // an access token for the provided account.
- // If no account is specified, "default" is used.
- Source: google.ComputeTokenSource(""),
- },
- }
- client.Get("...")
-}
diff --git a/vendor/golang.org/x/oauth2/google/google.go b/vendor/golang.org/x/oauth2/google/google.go
deleted file mode 100644
index 2077d986..00000000
--- a/vendor/golang.org/x/oauth2/google/google.go
+++ /dev/null
@@ -1,145 +0,0 @@
-// Copyright 2014 The oauth2 Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style
-// license that can be found in the LICENSE file.
-
-// Package google provides support for making OAuth2 authorized and
-// authenticated HTTP requests to Google APIs.
-// It supports the Web server flow, client-side credentials, service accounts,
-// Google Compute Engine service accounts, and Google App Engine service
-// accounts.
-//
-// For more information, please read
-// https://developers.google.com/accounts/docs/OAuth2
-// and
-// https://developers.google.com/accounts/docs/application-default-credentials.
-package google
-
-import (
- "encoding/json"
- "errors"
- "fmt"
- "strings"
- "time"
-
- "golang.org/x/oauth2"
- "golang.org/x/oauth2/jwt"
- "google.golang.org/cloud/compute/metadata"
-)
-
-// Endpoint is Google's OAuth 2.0 endpoint.
-var Endpoint = oauth2.Endpoint{
- AuthURL: "https://accounts.google.com/o/oauth2/auth",
- TokenURL: "https://accounts.google.com/o/oauth2/token",
-}
-
-// JWTTokenURL is Google's OAuth 2.0 token URL to use with the JWT flow.
-const JWTTokenURL = "https://accounts.google.com/o/oauth2/token"
-
-// ConfigFromJSON uses a Google Developers Console client_credentials.json
-// file to construct a config.
-// client_credentials.json can be downloadable from https://console.developers.google.com,
-// under "APIs & Auth" > "Credentials". Download the Web application credentials in the
-// JSON format and provide the contents of the file as jsonKey.
-func ConfigFromJSON(jsonKey []byte, scope ...string) (*oauth2.Config, error) {
- type cred struct {
- ClientID string `json:"client_id"`
- ClientSecret string `json:"client_secret"`
- RedirectURIs []string `json:"redirect_uris"`
- AuthURI string `json:"auth_uri"`
- TokenURI string `json:"token_uri"`
- }
- var j struct {
- Web *cred `json:"web"`
- Installed *cred `json:"installed"`
- }
- if err := json.Unmarshal(jsonKey, &j); err != nil {
- return nil, err
- }
- var c *cred
- switch {
- case j.Web != nil:
- c = j.Web
- case j.Installed != nil:
- c = j.Installed
- default:
- return nil, fmt.Errorf("oauth2/google: no credentials found")
- }
- if len(c.RedirectURIs) < 1 {
- return nil, errors.New("oauth2/google: missing redirect URL in the client_credentials.json")
- }
- return &oauth2.Config{
- ClientID: c.ClientID,
- ClientSecret: c.ClientSecret,
- RedirectURL: c.RedirectURIs[0],
- Scopes: scope,
- Endpoint: oauth2.Endpoint{
- AuthURL: c.AuthURI,
- TokenURL: c.TokenURI,
- },
- }, nil
-}
-
-// JWTConfigFromJSON uses a Google Developers service account JSON key file to read
-// the credentials that authorize and authenticate the requests.
-// Create a service account on "Credentials" page under "APIs & Auth" for your
-// project at https://console.developers.google.com to download a JSON key file.
-func JWTConfigFromJSON(jsonKey []byte, scope ...string) (*jwt.Config, error) {
- var key struct {
- Email string `json:"client_email"`
- PrivateKey string `json:"private_key"`
- }
- if err := json.Unmarshal(jsonKey, &key); err != nil {
- return nil, err
- }
- return &jwt.Config{
- Email: key.Email,
- PrivateKey: []byte(key.PrivateKey),
- Scopes: scope,
- TokenURL: JWTTokenURL,
- }, nil
-}
-
-// ComputeTokenSource returns a token source that fetches access tokens
-// from Google Compute Engine (GCE)'s metadata server. It's only valid to use
-// this token source if your program is running on a GCE instance.
-// If no account is specified, "default" is used.
-// Further information about retrieving access tokens from the GCE metadata
-// server can be found at https://cloud.google.com/compute/docs/authentication.
-func ComputeTokenSource(account string) oauth2.TokenSource {
- return oauth2.ReuseTokenSource(nil, computeSource{account: account})
-}
-
-type computeSource struct {
- account string
-}
-
-func (cs computeSource) Token() (*oauth2.Token, error) {
- if !metadata.OnGCE() {
- return nil, errors.New("oauth2/google: can't get a token from the metadata service; not running on GCE")
- }
- acct := cs.account
- if acct == "" {
- acct = "default"
- }
- tokenJSON, err := metadata.Get("instance/service-accounts/" + acct + "/token")
- if err != nil {
- return nil, err
- }
- var res struct {
- AccessToken string `json:"access_token"`
- ExpiresInSec int `json:"expires_in"`
- TokenType string `json:"token_type"`
- }
- err = json.NewDecoder(strings.NewReader(tokenJSON)).Decode(&res)
- if err != nil {
- return nil, fmt.Errorf("oauth2/google: invalid token JSON from metadata: %v", err)
- }
- if res.ExpiresInSec == 0 || res.AccessToken == "" {
- return nil, fmt.Errorf("oauth2/google: incomplete token received from metadata")
- }
- return &oauth2.Token{
- AccessToken: res.AccessToken,
- TokenType: res.TokenType,
- Expiry: time.Now().Add(time.Duration(res.ExpiresInSec) * time.Second),
- }, nil
-}
diff --git a/vendor/golang.org/x/oauth2/google/google_test.go b/vendor/golang.org/x/oauth2/google/google_test.go
deleted file mode 100644
index 4cc01884..00000000
--- a/vendor/golang.org/x/oauth2/google/google_test.go
+++ /dev/null
@@ -1,67 +0,0 @@
-// Copyright 2015 The oauth2 Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style
-// license that can be found in the LICENSE file.
-
-package google
-
-import (
- "strings"
- "testing"
-)
-
-var webJSONKey = []byte(`
-{
- "web": {
- "auth_uri": "https://google.com/o/oauth2/auth",
- "client_secret": "3Oknc4jS_wA2r9i",
- "token_uri": "https://google.com/o/oauth2/token",
- "client_email": "222-nprqovg5k43uum874cs9osjt2koe97g8@developer.gserviceaccount.com",
- "redirect_uris": ["https://www.example.com/oauth2callback"],
- "client_x509_cert_url": "https://www.googleapis.com/robot/v1/metadata/x509/222-nprqovg5k43uum874cs9osjt2koe97g8@developer.gserviceaccount.com",
- "client_id": "222-nprqovg5k43uum874cs9osjt2koe97g8.apps.googleusercontent.com",
- "auth_provider_x509_cert_url": "https://www.googleapis.com/oauth2/v1/certs",
- "javascript_origins": ["https://www.example.com"]
- }
-}`)
-
-var installedJSONKey = []byte(`{
- "installed": {
- "client_id": "222-installed.apps.googleusercontent.com",
- "redirect_uris": ["https://www.example.com/oauth2callback"]
- }
-}`)
-
-func TestConfigFromJSON(t *testing.T) {
- conf, err := ConfigFromJSON(webJSONKey, "scope1", "scope2")
- if err != nil {
- t.Error(err)
- }
- if got, want := conf.ClientID, "222-nprqovg5k43uum874cs9osjt2koe97g8.apps.googleusercontent.com"; got != want {
- t.Errorf("ClientID = %q; want %q", got, want)
- }
- if got, want := conf.ClientSecret, "3Oknc4jS_wA2r9i"; got != want {
- t.Errorf("ClientSecret = %q; want %q", got, want)
- }
- if got, want := conf.RedirectURL, "https://www.example.com/oauth2callback"; got != want {
- t.Errorf("RedictURL = %q; want %q", got, want)
- }
- if got, want := strings.Join(conf.Scopes, ","), "scope1,scope2"; got != want {
- t.Errorf("Scopes = %q; want %q", got, want)
- }
- if got, want := conf.Endpoint.AuthURL, "https://google.com/o/oauth2/auth"; got != want {
- t.Errorf("AuthURL = %q; want %q", got, want)
- }
- if got, want := conf.Endpoint.TokenURL, "https://google.com/o/oauth2/token"; got != want {
- t.Errorf("TokenURL = %q; want %q", got, want)
- }
-}
-
-func TestConfigFromJSON_Installed(t *testing.T) {
- conf, err := ConfigFromJSON(installedJSONKey)
- if err != nil {
- t.Error(err)
- }
- if got, want := conf.ClientID, "222-installed.apps.googleusercontent.com"; got != want {
- t.Errorf("ClientID = %q; want %q", got, want)
- }
-}
diff --git a/vendor/golang.org/x/oauth2/google/jwt.go b/vendor/golang.org/x/oauth2/google/jwt.go
deleted file mode 100644
index 6f7ec3a1..00000000
--- a/vendor/golang.org/x/oauth2/google/jwt.go
+++ /dev/null
@@ -1,71 +0,0 @@
-// Copyright 2015 The oauth2 Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style
-// license that can be found in the LICENSE file.
-
-package google
-
-import (
- "crypto/rsa"
- "fmt"
- "time"
-
- "golang.org/x/oauth2"
- "golang.org/x/oauth2/internal"
- "golang.org/x/oauth2/jws"
-)
-
-// JWTAccessTokenSourceFromJSON uses a Google Developers service account JSON
-// key file to read the credentials that authorize and authenticate the
-// requests, and returns a TokenSource that does not use any OAuth2 flow but
-// instead creates a JWT and sends that as the access token.
-// The audience is typically a URL that specifies the scope of the credentials.
-//
-// Note that this is not a standard OAuth flow, but rather an
-// optimization supported by a few Google services.
-// Unless you know otherwise, you should use JWTConfigFromJSON instead.
-func JWTAccessTokenSourceFromJSON(jsonKey []byte, audience string) (oauth2.TokenSource, error) {
- cfg, err := JWTConfigFromJSON(jsonKey)
- if err != nil {
- return nil, fmt.Errorf("google: could not parse JSON key: %v", err)
- }
- pk, err := internal.ParseKey(cfg.PrivateKey)
- if err != nil {
- return nil, fmt.Errorf("google: could not parse key: %v", err)
- }
- ts := &jwtAccessTokenSource{
- email: cfg.Email,
- audience: audience,
- pk: pk,
- }
- tok, err := ts.Token()
- if err != nil {
- return nil, err
- }
- return oauth2.ReuseTokenSource(tok, ts), nil
-}
-
-type jwtAccessTokenSource struct {
- email, audience string
- pk *rsa.PrivateKey
-}
-
-func (ts *jwtAccessTokenSource) Token() (*oauth2.Token, error) {
- iat := time.Now()
- exp := iat.Add(time.Hour)
- cs := &jws.ClaimSet{
- Iss: ts.email,
- Sub: ts.email,
- Aud: ts.audience,
- Iat: iat.Unix(),
- Exp: exp.Unix(),
- }
- hdr := &jws.Header{
- Algorithm: "RS256",
- Typ: "JWT",
- }
- msg, err := jws.Encode(hdr, cs, ts.pk)
- if err != nil {
- return nil, fmt.Errorf("google: could not encode JWT: %v", err)
- }
- return &oauth2.Token{AccessToken: msg, TokenType: "Bearer", Expiry: exp}, nil
-}
diff --git a/vendor/golang.org/x/oauth2/google/sdk.go b/vendor/golang.org/x/oauth2/google/sdk.go
deleted file mode 100644
index 01ba0ecb..00000000
--- a/vendor/golang.org/x/oauth2/google/sdk.go
+++ /dev/null
@@ -1,168 +0,0 @@
-// Copyright 2015 The oauth2 Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style
-// license that can be found in the LICENSE file.
-
-package google
-
-import (
- "encoding/json"
- "errors"
- "fmt"
- "net/http"
- "os"
- "os/user"
- "path/filepath"
- "runtime"
- "strings"
- "time"
-
- "golang.org/x/net/context"
- "golang.org/x/oauth2"
- "golang.org/x/oauth2/internal"
-)
-
-type sdkCredentials struct {
- Data []struct {
- Credential struct {
- ClientID string `json:"client_id"`
- ClientSecret string `json:"client_secret"`
- AccessToken string `json:"access_token"`
- RefreshToken string `json:"refresh_token"`
- TokenExpiry *time.Time `json:"token_expiry"`
- } `json:"credential"`
- Key struct {
- Account string `json:"account"`
- Scope string `json:"scope"`
- } `json:"key"`
- }
-}
-
-// An SDKConfig provides access to tokens from an account already
-// authorized via the Google Cloud SDK.
-type SDKConfig struct {
- conf oauth2.Config
- initialToken *oauth2.Token
-}
-
-// NewSDKConfig creates an SDKConfig for the given Google Cloud SDK
-// account. If account is empty, the account currently active in
-// Google Cloud SDK properties is used.
-// Google Cloud SDK credentials must be created by running `gcloud auth`
-// before using this function.
-// The Google Cloud SDK is available at https://cloud.google.com/sdk/.
-func NewSDKConfig(account string) (*SDKConfig, error) {
- configPath, err := sdkConfigPath()
- if err != nil {
- return nil, fmt.Errorf("oauth2/google: error getting SDK config path: %v", err)
- }
- credentialsPath := filepath.Join(configPath, "credentials")
- f, err := os.Open(credentialsPath)
- if err != nil {
- return nil, fmt.Errorf("oauth2/google: failed to load SDK credentials: %v", err)
- }
- defer f.Close()
-
- var c sdkCredentials
- if err := json.NewDecoder(f).Decode(&c); err != nil {
- return nil, fmt.Errorf("oauth2/google: failed to decode SDK credentials from %q: %v", credentialsPath, err)
- }
- if len(c.Data) == 0 {
- return nil, fmt.Errorf("oauth2/google: no credentials found in %q, run `gcloud auth login` to create one", credentialsPath)
- }
- if account == "" {
- propertiesPath := filepath.Join(configPath, "properties")
- f, err := os.Open(propertiesPath)
- if err != nil {
- return nil, fmt.Errorf("oauth2/google: failed to load SDK properties: %v", err)
- }
- defer f.Close()
- ini, err := internal.ParseINI(f)
- if err != nil {
- return nil, fmt.Errorf("oauth2/google: failed to parse SDK properties %q: %v", propertiesPath, err)
- }
- core, ok := ini["core"]
- if !ok {
- return nil, fmt.Errorf("oauth2/google: failed to find [core] section in %v", ini)
- }
- active, ok := core["account"]
- if !ok {
- return nil, fmt.Errorf("oauth2/google: failed to find %q attribute in %v", "account", core)
- }
- account = active
- }
-
- for _, d := range c.Data {
- if account == "" || d.Key.Account == account {
- if d.Credential.AccessToken == "" && d.Credential.RefreshToken == "" {
- return nil, fmt.Errorf("oauth2/google: no token available for account %q", account)
- }
- var expiry time.Time
- if d.Credential.TokenExpiry != nil {
- expiry = *d.Credential.TokenExpiry
- }
- return &SDKConfig{
- conf: oauth2.Config{
- ClientID: d.Credential.ClientID,
- ClientSecret: d.Credential.ClientSecret,
- Scopes: strings.Split(d.Key.Scope, " "),
- Endpoint: Endpoint,
- RedirectURL: "oob",
- },
- initialToken: &oauth2.Token{
- AccessToken: d.Credential.AccessToken,
- RefreshToken: d.Credential.RefreshToken,
- Expiry: expiry,
- },
- }, nil
- }
- }
- return nil, fmt.Errorf("oauth2/google: no such credentials for account %q", account)
-}
-
-// Client returns an HTTP client using Google Cloud SDK credentials to
-// authorize requests. The token will auto-refresh as necessary. The
-// underlying http.RoundTripper will be obtained using the provided
-// context. The returned client and its Transport should not be
-// modified.
-func (c *SDKConfig) Client(ctx context.Context) *http.Client {
- return &http.Client{
- Transport: &oauth2.Transport{
- Source: c.TokenSource(ctx),
- },
- }
-}
-
-// TokenSource returns an oauth2.TokenSource that retrieve tokens from
-// Google Cloud SDK credentials using the provided context.
-// It will returns the current access token stored in the credentials,
-// and refresh it when it expires, but it won't update the credentials
-// with the new access token.
-func (c *SDKConfig) TokenSource(ctx context.Context) oauth2.TokenSource {
- return c.conf.TokenSource(ctx, c.initialToken)
-}
-
-// Scopes are the OAuth 2.0 scopes the current account is authorized for.
-func (c *SDKConfig) Scopes() []string {
- return c.conf.Scopes
-}
-
-// sdkConfigPath tries to guess where the gcloud config is located.
-// It can be overridden during tests.
-var sdkConfigPath = func() (string, error) {
- if runtime.GOOS == "windows" {
- return filepath.Join(os.Getenv("APPDATA"), "gcloud"), nil
- }
- homeDir := guessUnixHomeDir()
- if homeDir == "" {
- return "", errors.New("unable to get current user home directory: os/user lookup failed; $HOME is empty")
- }
- return filepath.Join(homeDir, ".config", "gcloud"), nil
-}
-
-func guessUnixHomeDir() string {
- usr, err := user.Current()
- if err == nil {
- return usr.HomeDir
- }
- return os.Getenv("HOME")
-}
diff --git a/vendor/golang.org/x/oauth2/google/sdk_test.go b/vendor/golang.org/x/oauth2/google/sdk_test.go
deleted file mode 100644
index 79df8896..00000000
--- a/vendor/golang.org/x/oauth2/google/sdk_test.go
+++ /dev/null
@@ -1,46 +0,0 @@
-// Copyright 2015 The oauth2 Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style
-// license that can be found in the LICENSE file.
-
-package google
-
-import "testing"
-
-func TestSDKConfig(t *testing.T) {
- sdkConfigPath = func() (string, error) {
- return "testdata/gcloud", nil
- }
-
- tests := []struct {
- account string
- accessToken string
- err bool
- }{
- {"", "bar_access_token", false},
- {"foo@example.com", "foo_access_token", false},
- {"bar@example.com", "bar_access_token", false},
- {"baz@serviceaccount.example.com", "", true},
- }
- for _, tt := range tests {
- c, err := NewSDKConfig(tt.account)
- if got, want := err != nil, tt.err; got != want {
- if !tt.err {
- t.Errorf("expected no error, got error: %v", tt.err, err)
- } else {
- t.Errorf("expected error, got none")
- }
- continue
- }
- if err != nil {
- continue
- }
- tok := c.initialToken
- if tok == nil {
- t.Errorf("expected token %q, got: nil", tt.accessToken)
- continue
- }
- if tok.AccessToken != tt.accessToken {
- t.Errorf("expected token %q, got: %q", tt.accessToken, tok.AccessToken)
- }
- }
-}
diff --git a/vendor/golang.org/x/oauth2/google/testdata/gcloud/credentials b/vendor/golang.org/x/oauth2/google/testdata/gcloud/credentials
deleted file mode 100644
index ff5eefbd..00000000
--- a/vendor/golang.org/x/oauth2/google/testdata/gcloud/credentials
+++ /dev/null
@@ -1,122 +0,0 @@
-{
- "data": [
- {
- "credential": {
- "_class": "OAuth2Credentials",
- "_module": "oauth2client.client",
- "access_token": "foo_access_token",
- "client_id": "foo_client_id",
- "client_secret": "foo_client_secret",
- "id_token": {
- "at_hash": "foo_at_hash",
- "aud": "foo_aud",
- "azp": "foo_azp",
- "cid": "foo_cid",
- "email": "foo@example.com",
- "email_verified": true,
- "exp": 1420573614,
- "iat": 1420569714,
- "id": "1337",
- "iss": "accounts.google.com",
- "sub": "1337",
- "token_hash": "foo_token_hash",
- "verified_email": true
- },
- "invalid": false,
- "refresh_token": "foo_refresh_token",
- "revoke_uri": "https://accounts.google.com/o/oauth2/revoke",
- "token_expiry": "2015-01-09T00:51:51Z",
- "token_response": {
- "access_token": "foo_access_token",
- "expires_in": 3600,
- "id_token": "foo_id_token",
- "token_type": "Bearer"
- },
- "token_uri": "https://accounts.google.com/o/oauth2/token",
- "user_agent": "Cloud SDK Command Line Tool"
- },
- "key": {
- "account": "foo@example.com",
- "clientId": "foo_client_id",
- "scope": "https://www.googleapis.com/auth/appengine.admin https://www.googleapis.com/auth/bigquery https://www.googleapis.com/auth/compute https://www.googleapis.com/auth/devstorage.full_control https://www.googleapis.com/auth/userinfo.email https://www.googleapis.com/auth/ndev.cloudman https://www.googleapis.com/auth/cloud-platform https://www.googleapis.com/auth/sqlservice.admin https://www.googleapis.com/auth/prediction https://www.googleapis.com/auth/projecthosting",
- "type": "google-cloud-sdk"
- }
- },
- {
- "credential": {
- "_class": "OAuth2Credentials",
- "_module": "oauth2client.client",
- "access_token": "bar_access_token",
- "client_id": "bar_client_id",
- "client_secret": "bar_client_secret",
- "id_token": {
- "at_hash": "bar_at_hash",
- "aud": "bar_aud",
- "azp": "bar_azp",
- "cid": "bar_cid",
- "email": "bar@example.com",
- "email_verified": true,
- "exp": 1420573614,
- "iat": 1420569714,
- "id": "1337",
- "iss": "accounts.google.com",
- "sub": "1337",
- "token_hash": "bar_token_hash",
- "verified_email": true
- },
- "invalid": false,
- "refresh_token": "bar_refresh_token",
- "revoke_uri": "https://accounts.google.com/o/oauth2/revoke",
- "token_expiry": "2015-01-09T00:51:51Z",
- "token_response": {
- "access_token": "bar_access_token",
- "expires_in": 3600,
- "id_token": "bar_id_token",
- "token_type": "Bearer"
- },
- "token_uri": "https://accounts.google.com/o/oauth2/token",
- "user_agent": "Cloud SDK Command Line Tool"
- },
- "key": {
- "account": "bar@example.com",
- "clientId": "bar_client_id",
- "scope": "https://www.googleapis.com/auth/appengine.admin https://www.googleapis.com/auth/bigquery https://www.googleapis.com/auth/compute https://www.googleapis.com/auth/devstorage.full_control https://www.googleapis.com/auth/userinfo.email https://www.googleapis.com/auth/ndev.cloudman https://www.googleapis.com/auth/cloud-platform https://www.googleapis.com/auth/sqlservice.admin https://www.googleapis.com/auth/prediction https://www.googleapis.com/auth/projecthosting",
- "type": "google-cloud-sdk"
- }
- },
- {
- "credential": {
- "_class": "ServiceAccountCredentials",
- "_kwargs": {},
- "_module": "oauth2client.client",
- "_private_key_id": "00000000000000000000000000000000",
- "_private_key_pkcs8_text": "-----BEGIN RSA PRIVATE KEY-----\nMIICWwIBAAKBgQCt3fpiynPSaUhWSIKMGV331zudwJ6GkGmvQtwsoK2S2LbvnSwU\nNxgj4fp08kIDR5p26wF4+t/HrKydMwzftXBfZ9UmLVJgRdSswmS5SmChCrfDS5OE\nvFFcN5+6w1w8/Nu657PF/dse8T0bV95YrqyoR0Osy8WHrUOMSIIbC3hRuwIDAQAB\nAoGAJrGE/KFjn0sQ7yrZ6sXmdLawrM3mObo/2uI9T60+k7SpGbBX0/Pi6nFrJMWZ\nTVONG7P3Mu5aCPzzuVRYJB0j8aldSfzABTY3HKoWCczqw1OztJiEseXGiYz4QOyr\nYU3qDyEpdhS6q6wcoLKGH+hqRmz6pcSEsc8XzOOu7s4xW8kCQQDkc75HjhbarCnd\nJJGMe3U76+6UGmdK67ltZj6k6xoB5WbTNChY9TAyI2JC+ppYV89zv3ssj4L+02u3\nHIHFGxsHAkEAwtU1qYb1tScpchPobnYUFiVKJ7KA8EZaHVaJJODW/cghTCV7BxcJ\nbgVvlmk4lFKn3lPKAgWw7PdQsBTVBUcCrQJATPwoIirizrv3u5soJUQxZIkENAqV\nxmybZx9uetrzP7JTrVbFRf0SScMcyN90hdLJiQL8+i4+gaszgFht7sNMnwJAAbfj\nq0UXcauQwALQ7/h2oONfTg5S+MuGC/AxcXPSMZbMRGGoPh3D5YaCv27aIuS/ukQ+\n6dmm/9AGlCb64fsIWQJAPaokbjIifo+LwC5gyK73Mc4t8nAOSZDenzd/2f6TCq76\nS1dcnKiPxaED7W/y6LJiuBT2rbZiQ2L93NJpFZD/UA==\n-----END RSA PRIVATE KEY-----\n",
- "_revoke_uri": "https://accounts.google.com/o/oauth2/revoke",
- "_scopes": "https://www.googleapis.com/auth/appengine.admin https://www.googleapis.com/auth/bigquery https://www.googleapis.com/auth/compute https://www.googleapis.com/auth/devstorage.full_control https://www.googleapis.com/auth/userinfo.email https://www.googleapis.com/auth/ndev.cloudman https://www.googleapis.com/auth/cloud-platform https://www.googleapis.com/auth/sqlservice.admin https://www.googleapis.com/auth/prediction https://www.googleapis.com/auth/projecthosting",
- "_service_account_email": "baz@serviceaccount.example.com",
- "_service_account_id": "baz.serviceaccount.example.com",
- "_token_uri": "https://accounts.google.com/o/oauth2/token",
- "_user_agent": "Cloud SDK Command Line Tool",
- "access_token": null,
- "assertion_type": null,
- "client_id": null,
- "client_secret": null,
- "id_token": null,
- "invalid": false,
- "refresh_token": null,
- "revoke_uri": "https://accounts.google.com/o/oauth2/revoke",
- "service_account_name": "baz@serviceaccount.example.com",
- "token_expiry": null,
- "token_response": null,
- "user_agent": "Cloud SDK Command Line Tool"
- },
- "key": {
- "account": "baz@serviceaccount.example.com",
- "clientId": "baz_client_id",
- "scope": "https://www.googleapis.com/auth/appengine.admin https://www.googleapis.com/auth/bigquery https://www.googleapis.com/auth/compute https://www.googleapis.com/auth/devstorage.full_control https://www.googleapis.com/auth/userinfo.email https://www.googleapis.com/auth/ndev.cloudman https://www.googleapis.com/auth/cloud-platform https://www.googleapis.com/auth/sqlservice.admin https://www.googleapis.com/auth/prediction https://www.googleapis.com/auth/projecthosting",
- "type": "google-cloud-sdk"
- }
- }
- ],
- "file_version": 1
-}
diff --git a/vendor/golang.org/x/oauth2/google/testdata/gcloud/properties b/vendor/golang.org/x/oauth2/google/testdata/gcloud/properties
deleted file mode 100644
index 025de886..00000000
--- a/vendor/golang.org/x/oauth2/google/testdata/gcloud/properties
+++ /dev/null
@@ -1,2 +0,0 @@
-[core]
-account = bar@example.com
\ No newline at end of file
diff --git a/vendor/golang.org/x/oauth2/internal/oauth2.go b/vendor/golang.org/x/oauth2/internal/oauth2.go
deleted file mode 100644
index dc8ebfc4..00000000
--- a/vendor/golang.org/x/oauth2/internal/oauth2.go
+++ /dev/null
@@ -1,76 +0,0 @@
-// Copyright 2014 The oauth2 Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style
-// license that can be found in the LICENSE file.
-
-// Package internal contains support packages for oauth2 package.
-package internal
-
-import (
- "bufio"
- "crypto/rsa"
- "crypto/x509"
- "encoding/pem"
- "errors"
- "fmt"
- "io"
- "strings"
-)
-
-// ParseKey converts the binary contents of a private key file
-// to an *rsa.PrivateKey. It detects whether the private key is in a
-// PEM container or not. If so, it extracts the the private key
-// from PEM container before conversion. It only supports PEM
-// containers with no passphrase.
-func ParseKey(key []byte) (*rsa.PrivateKey, error) {
- block, _ := pem.Decode(key)
- if block != nil {
- key = block.Bytes
- }
- parsedKey, err := x509.ParsePKCS8PrivateKey(key)
- if err != nil {
- parsedKey, err = x509.ParsePKCS1PrivateKey(key)
- if err != nil {
- return nil, fmt.Errorf("private key should be a PEM or plain PKSC1 or PKCS8; parse error: %v", err)
- }
- }
- parsed, ok := parsedKey.(*rsa.PrivateKey)
- if !ok {
- return nil, errors.New("private key is invalid")
- }
- return parsed, nil
-}
-
-func ParseINI(ini io.Reader) (map[string]map[string]string, error) {
- result := map[string]map[string]string{
- "": map[string]string{}, // root section
- }
- scanner := bufio.NewScanner(ini)
- currentSection := ""
- for scanner.Scan() {
- line := strings.TrimSpace(scanner.Text())
- if strings.HasPrefix(line, ";") {
- // comment.
- continue
- }
- if strings.HasPrefix(line, "[") && strings.HasSuffix(line, "]") {
- currentSection = strings.TrimSpace(line[1 : len(line)-1])
- result[currentSection] = map[string]string{}
- continue
- }
- parts := strings.SplitN(line, "=", 2)
- if len(parts) == 2 && parts[0] != "" {
- result[currentSection][strings.TrimSpace(parts[0])] = strings.TrimSpace(parts[1])
- }
- }
- if err := scanner.Err(); err != nil {
- return nil, fmt.Errorf("error scanning ini: %v", err)
- }
- return result, nil
-}
-
-func CondVal(v string) []string {
- if v == "" {
- return nil
- }
- return []string{v}
-}
diff --git a/vendor/golang.org/x/oauth2/internal/oauth2_test.go b/vendor/golang.org/x/oauth2/internal/oauth2_test.go
deleted file mode 100644
index 014a351e..00000000
--- a/vendor/golang.org/x/oauth2/internal/oauth2_test.go
+++ /dev/null
@@ -1,62 +0,0 @@
-// Copyright 2014 The oauth2 Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style
-// license that can be found in the LICENSE file.
-
-// Package internal contains support packages for oauth2 package.
-package internal
-
-import (
- "reflect"
- "strings"
- "testing"
-)
-
-func TestParseINI(t *testing.T) {
- tests := []struct {
- ini string
- want map[string]map[string]string
- }{
- {
- `root = toor
-[foo]
-bar = hop
-ini = nin
-`,
- map[string]map[string]string{
- "": map[string]string{"root": "toor"},
- "foo": map[string]string{"bar": "hop", "ini": "nin"},
- },
- },
- {
- `[empty]
-[section]
-empty=
-`,
- map[string]map[string]string{
- "": map[string]string{},
- "empty": map[string]string{},
- "section": map[string]string{"empty": ""},
- },
- },
- {
- `ignore
-[invalid
-=stuff
-;comment=true
-`,
- map[string]map[string]string{
- "": map[string]string{},
- },
- },
- }
- for _, tt := range tests {
- result, err := ParseINI(strings.NewReader(tt.ini))
- if err != nil {
- t.Errorf("ParseINI(%q) error %v, want: no error", tt.ini, err)
- continue
- }
- if !reflect.DeepEqual(result, tt.want) {
- t.Errorf("ParseINI(%q) = %#v, want: %#v", tt.ini, result, tt.want)
- }
- }
-}
diff --git a/vendor/golang.org/x/oauth2/internal/token.go b/vendor/golang.org/x/oauth2/internal/token.go
deleted file mode 100644
index 75adbe51..00000000
--- a/vendor/golang.org/x/oauth2/internal/token.go
+++ /dev/null
@@ -1,213 +0,0 @@
-// Copyright 2014 The oauth2 Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style
-// license that can be found in the LICENSE file.
-
-// Package internal contains support packages for oauth2 package.
-package internal
-
-import (
- "encoding/json"
- "fmt"
- "io"
- "io/ioutil"
- "mime"
- "net/http"
- "net/url"
- "strconv"
- "strings"
- "time"
-
- "golang.org/x/net/context"
-)
-
-// Token represents the crendentials used to authorize
-// the requests to access protected resources on the OAuth 2.0
-// provider's backend.
-//
-// This type is a mirror of oauth2.Token and exists to break
-// an otherwise-circular dependency. Other internal packages
-// should convert this Token into an oauth2.Token before use.
-type Token struct {
- // AccessToken is the token that authorizes and authenticates
- // the requests.
- AccessToken string
-
- // TokenType is the type of token.
- // The Type method returns either this or "Bearer", the default.
- TokenType string
-
- // RefreshToken is a token that's used by the application
- // (as opposed to the user) to refresh the access token
- // if it expires.
- RefreshToken string
-
- // Expiry is the optional expiration time of the access token.
- //
- // If zero, TokenSource implementations will reuse the same
- // token forever and RefreshToken or equivalent
- // mechanisms for that TokenSource will not be used.
- Expiry time.Time
-
- // Raw optionally contains extra metadata from the server
- // when updating a token.
- Raw interface{}
-}
-
-// tokenJSON is the struct representing the HTTP response from OAuth2
-// providers returning a token in JSON form.
-type tokenJSON struct {
- AccessToken string `json:"access_token"`
- TokenType string `json:"token_type"`
- RefreshToken string `json:"refresh_token"`
- ExpiresIn expirationTime `json:"expires_in"` // at least PayPal returns string, while most return number
- Expires expirationTime `json:"expires"` // broken Facebook spelling of expires_in
-}
-
-func (e *tokenJSON) expiry() (t time.Time) {
- if v := e.ExpiresIn; v != 0 {
- return time.Now().Add(time.Duration(v) * time.Second)
- }
- if v := e.Expires; v != 0 {
- return time.Now().Add(time.Duration(v) * time.Second)
- }
- return
-}
-
-type expirationTime int32
-
-func (e *expirationTime) UnmarshalJSON(b []byte) error {
- var n json.Number
- err := json.Unmarshal(b, &n)
- if err != nil {
- return err
- }
- i, err := n.Int64()
- if err != nil {
- return err
- }
- *e = expirationTime(i)
- return nil
-}
-
-var brokenAuthHeaderProviders = []string{
- "https://accounts.google.com/",
- "https://www.googleapis.com/",
- "https://api.instagram.com/",
- "https://www.douban.com/",
- "https://api.dropbox.com/",
- "https://api.soundcloud.com/",
- "https://www.linkedin.com/",
- "https://api.twitch.tv/",
- "https://oauth.vk.com/",
- "https://api.odnoklassniki.ru/",
- "https://connect.stripe.com/",
- "https://api.pushbullet.com/",
- "https://oauth.sandbox.trainingpeaks.com/",
- "https://oauth.trainingpeaks.com/",
- "https://www.strava.com/oauth/",
- "https://app.box.com/",
- "https://test-sandbox.auth.corp.google.com",
- "https://user.gini.net/",
- "https://api.netatmo.net/",
-}
-
-// providerAuthHeaderWorks reports whether the OAuth2 server identified by the tokenURL
-// implements the OAuth2 spec correctly
-// See https://code.google.com/p/goauth2/issues/detail?id=31 for background.
-// In summary:
-// - Reddit only accepts client secret in the Authorization header
-// - Dropbox accepts either it in URL param or Auth header, but not both.
-// - Google only accepts URL param (not spec compliant?), not Auth header
-// - Stripe only accepts client secret in Auth header with Bearer method, not Basic
-func providerAuthHeaderWorks(tokenURL string) bool {
- for _, s := range brokenAuthHeaderProviders {
- if strings.HasPrefix(tokenURL, s) {
- // Some sites fail to implement the OAuth2 spec fully.
- return false
- }
- }
-
- // Assume the provider implements the spec properly
- // otherwise. We can add more exceptions as they're
- // discovered. We will _not_ be adding configurable hooks
- // to this package to let users select server bugs.
- return true
-}
-
-func RetrieveToken(ctx context.Context, ClientID, ClientSecret, TokenURL string, v url.Values) (*Token, error) {
- hc, err := ContextClient(ctx)
- if err != nil {
- return nil, err
- }
- v.Set("client_id", ClientID)
- bustedAuth := !providerAuthHeaderWorks(TokenURL)
- if bustedAuth && ClientSecret != "" {
- v.Set("client_secret", ClientSecret)
- }
- req, err := http.NewRequest("POST", TokenURL, strings.NewReader(v.Encode()))
- if err != nil {
- return nil, err
- }
- req.Header.Set("Content-Type", "application/x-www-form-urlencoded")
- if !bustedAuth {
- req.SetBasicAuth(ClientID, ClientSecret)
- }
- r, err := hc.Do(req)
- if err != nil {
- return nil, err
- }
- defer r.Body.Close()
- body, err := ioutil.ReadAll(io.LimitReader(r.Body, 1<<20))
- if err != nil {
- return nil, fmt.Errorf("oauth2: cannot fetch token: %v", err)
- }
- if code := r.StatusCode; code < 200 || code > 299 {
- return nil, fmt.Errorf("oauth2: cannot fetch token: %v\nResponse: %s", r.Status, body)
- }
-
- var token *Token
- content, _, _ := mime.ParseMediaType(r.Header.Get("Content-Type"))
- switch content {
- case "application/x-www-form-urlencoded", "text/plain":
- vals, err := url.ParseQuery(string(body))
- if err != nil {
- return nil, err
- }
- token = &Token{
- AccessToken: vals.Get("access_token"),
- TokenType: vals.Get("token_type"),
- RefreshToken: vals.Get("refresh_token"),
- Raw: vals,
- }
- e := vals.Get("expires_in")
- if e == "" {
- // TODO(jbd): Facebook's OAuth2 implementation is broken and
- // returns expires_in field in expires. Remove the fallback to expires,
- // when Facebook fixes their implementation.
- e = vals.Get("expires")
- }
- expires, _ := strconv.Atoi(e)
- if expires != 0 {
- token.Expiry = time.Now().Add(time.Duration(expires) * time.Second)
- }
- default:
- var tj tokenJSON
- if err = json.Unmarshal(body, &tj); err != nil {
- return nil, err
- }
- token = &Token{
- AccessToken: tj.AccessToken,
- TokenType: tj.TokenType,
- RefreshToken: tj.RefreshToken,
- Expiry: tj.expiry(),
- Raw: make(map[string]interface{}),
- }
- json.Unmarshal(body, &token.Raw) // no error checks for optional fields
- }
- // Don't overwrite `RefreshToken` with an empty value
- // if this was a token refreshing request.
- if token.RefreshToken == "" {
- token.RefreshToken = v.Get("refresh_token")
- }
- return token, nil
-}
diff --git a/vendor/golang.org/x/oauth2/internal/token_test.go b/vendor/golang.org/x/oauth2/internal/token_test.go
deleted file mode 100644
index 864f6fa0..00000000
--- a/vendor/golang.org/x/oauth2/internal/token_test.go
+++ /dev/null
@@ -1,28 +0,0 @@
-// Copyright 2014 The oauth2 Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style
-// license that can be found in the LICENSE file.
-
-// Package internal contains support packages for oauth2 package.
-package internal
-
-import (
- "fmt"
- "testing"
-)
-
-func Test_providerAuthHeaderWorks(t *testing.T) {
- for _, p := range brokenAuthHeaderProviders {
- if providerAuthHeaderWorks(p) {
- t.Errorf("URL: %s not found in list", p)
- }
- p := fmt.Sprintf("%ssomesuffix", p)
- if providerAuthHeaderWorks(p) {
- t.Errorf("URL: %s not found in list", p)
- }
- }
- p := "https://api.not-in-the-list-example.com/"
- if !providerAuthHeaderWorks(p) {
- t.Errorf("URL: %s found in list", p)
- }
-
-}
diff --git a/vendor/golang.org/x/oauth2/internal/transport.go b/vendor/golang.org/x/oauth2/internal/transport.go
deleted file mode 100644
index 521e7b49..00000000
--- a/vendor/golang.org/x/oauth2/internal/transport.go
+++ /dev/null
@@ -1,67 +0,0 @@
-// Copyright 2014 The oauth2 Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style
-// license that can be found in the LICENSE file.
-
-// Package internal contains support packages for oauth2 package.
-package internal
-
-import (
- "net/http"
-
- "golang.org/x/net/context"
-)
-
-// HTTPClient is the context key to use with golang.org/x/net/context's
-// WithValue function to associate an *http.Client value with a context.
-var HTTPClient ContextKey
-
-// ContextKey is just an empty struct. It exists so HTTPClient can be
-// an immutable public variable with a unique type. It's immutable
-// because nobody else can create a ContextKey, being unexported.
-type ContextKey struct{}
-
-// ContextClientFunc is a func which tries to return an *http.Client
-// given a Context value. If it returns an error, the search stops
-// with that error. If it returns (nil, nil), the search continues
-// down the list of registered funcs.
-type ContextClientFunc func(context.Context) (*http.Client, error)
-
-var contextClientFuncs []ContextClientFunc
-
-func RegisterContextClientFunc(fn ContextClientFunc) {
- contextClientFuncs = append(contextClientFuncs, fn)
-}
-
-func ContextClient(ctx context.Context) (*http.Client, error) {
- for _, fn := range contextClientFuncs {
- c, err := fn(ctx)
- if err != nil {
- return nil, err
- }
- if c != nil {
- return c, nil
- }
- }
- if hc, ok := ctx.Value(HTTPClient).(*http.Client); ok {
- return hc, nil
- }
- return http.DefaultClient, nil
-}
-
-func ContextTransport(ctx context.Context) http.RoundTripper {
- hc, err := ContextClient(ctx)
- // This is a rare error case (somebody using nil on App Engine).
- if err != nil {
- return ErrorTransport{err}
- }
- return hc.Transport
-}
-
-// ErrorTransport returns the specified error on RoundTrip.
-// This RoundTripper should be used in rare error cases where
-// error handling can be postponed to response handling time.
-type ErrorTransport struct{ Err error }
-
-func (t ErrorTransport) RoundTrip(*http.Request) (*http.Response, error) {
- return nil, t.Err
-}
diff --git a/vendor/golang.org/x/oauth2/jws/jws.go b/vendor/golang.org/x/oauth2/jws/jws.go
deleted file mode 100644
index a4595eb5..00000000
--- a/vendor/golang.org/x/oauth2/jws/jws.go
+++ /dev/null
@@ -1,159 +0,0 @@
-// Copyright 2014 The oauth2 Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style
-// license that can be found in the LICENSE file.
-
-// Package jws provides encoding and decoding utilities for
-// signed JWS messages.
-package jws
-
-import (
- "bytes"
- "crypto"
- "crypto/rand"
- "crypto/rsa"
- "crypto/sha256"
- "encoding/base64"
- "encoding/json"
- "errors"
- "fmt"
- "strings"
- "time"
-)
-
-// ClaimSet contains information about the JWT signature including the
-// permissions being requested (scopes), the target of the token, the issuer,
-// the time the token was issued, and the lifetime of the token.
-type ClaimSet struct {
- Iss string `json:"iss"` // email address of the client_id of the application making the access token request
- Scope string `json:"scope,omitempty"` // space-delimited list of the permissions the application requests
- Aud string `json:"aud"` // descriptor of the intended target of the assertion (Optional).
- Exp int64 `json:"exp"` // the expiration time of the assertion (seconds since Unix epoch)
- Iat int64 `json:"iat"` // the time the assertion was issued (seconds since Unix epoch)
- Typ string `json:"typ,omitempty"` // token type (Optional).
-
- // Email for which the application is requesting delegated access (Optional).
- Sub string `json:"sub,omitempty"`
-
- // The old name of Sub. Client keeps setting Prn to be
- // complaint with legacy OAuth 2.0 providers. (Optional)
- Prn string `json:"prn,omitempty"`
-
- // See http://tools.ietf.org/html/draft-jones-json-web-token-10#section-4.3
- // This array is marshalled using custom code (see (c *ClaimSet) encode()).
- PrivateClaims map[string]interface{} `json:"-"`
-}
-
-func (c *ClaimSet) encode() (string, error) {
- // Reverting time back for machines whose time is not perfectly in sync.
- // If client machine's time is in the future according
- // to Google servers, an access token will not be issued.
- now := time.Now().Add(-10 * time.Second)
- if c.Iat == 0 {
- c.Iat = now.Unix()
- }
- if c.Exp == 0 {
- c.Exp = now.Add(time.Hour).Unix()
- }
- if c.Exp < c.Iat {
- return "", fmt.Errorf("jws: invalid Exp = %v; must be later than Iat = %v", c.Exp, c.Iat)
- }
-
- b, err := json.Marshal(c)
- if err != nil {
- return "", err
- }
-
- if len(c.PrivateClaims) == 0 {
- return base64Encode(b), nil
- }
-
- // Marshal private claim set and then append it to b.
- prv, err := json.Marshal(c.PrivateClaims)
- if err != nil {
- return "", fmt.Errorf("jws: invalid map of private claims %v", c.PrivateClaims)
- }
-
- // Concatenate public and private claim JSON objects.
- if !bytes.HasSuffix(b, []byte{'}'}) {
- return "", fmt.Errorf("jws: invalid JSON %s", b)
- }
- if !bytes.HasPrefix(prv, []byte{'{'}) {
- return "", fmt.Errorf("jws: invalid JSON %s", prv)
- }
- b[len(b)-1] = ',' // Replace closing curly brace with a comma.
- b = append(b, prv[1:]...) // Append private claims.
- return base64Encode(b), nil
-}
-
-// Header represents the header for the signed JWS payloads.
-type Header struct {
- // The algorithm used for signature.
- Algorithm string `json:"alg"`
-
- // Represents the token type.
- Typ string `json:"typ"`
-}
-
-func (h *Header) encode() (string, error) {
- b, err := json.Marshal(h)
- if err != nil {
- return "", err
- }
- return base64Encode(b), nil
-}
-
-// Decode decodes a claim set from a JWS payload.
-func Decode(payload string) (*ClaimSet, error) {
- // decode returned id token to get expiry
- s := strings.Split(payload, ".")
- if len(s) < 2 {
- // TODO(jbd): Provide more context about the error.
- return nil, errors.New("jws: invalid token received")
- }
- decoded, err := base64Decode(s[1])
- if err != nil {
- return nil, err
- }
- c := &ClaimSet{}
- err = json.NewDecoder(bytes.NewBuffer(decoded)).Decode(c)
- return c, err
-}
-
-// Encode encodes a signed JWS with provided header and claim set.
-func Encode(header *Header, c *ClaimSet, signature *rsa.PrivateKey) (string, error) {
- head, err := header.encode()
- if err != nil {
- return "", err
- }
- cs, err := c.encode()
- if err != nil {
- return "", err
- }
- ss := fmt.Sprintf("%s.%s", head, cs)
- h := sha256.New()
- h.Write([]byte(ss))
- b, err := rsa.SignPKCS1v15(rand.Reader, signature, crypto.SHA256, h.Sum(nil))
- if err != nil {
- return "", err
- }
- sig := base64Encode(b)
- return fmt.Sprintf("%s.%s", ss, sig), nil
-}
-
-// base64Encode returns and Base64url encoded version of the input string with any
-// trailing "=" stripped.
-func base64Encode(b []byte) string {
- return strings.TrimRight(base64.URLEncoding.EncodeToString(b), "=")
-}
-
-// base64Decode decodes the Base64url encoded string
-func base64Decode(s string) ([]byte, error) {
- // add back missing padding
- switch len(s) % 4 {
- case 2:
- s += "=="
- case 3:
- s += "="
- }
- return base64.URLEncoding.DecodeString(s)
-}
diff --git a/vendor/golang.org/x/oauth2/jwt/example_test.go b/vendor/golang.org/x/oauth2/jwt/example_test.go
deleted file mode 100644
index 6d618836..00000000
--- a/vendor/golang.org/x/oauth2/jwt/example_test.go
+++ /dev/null
@@ -1,31 +0,0 @@
-// Copyright 2014 The oauth2 Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style
-// license that can be found in the LICENSE file.
-
-package jwt_test
-
-import (
- "golang.org/x/oauth2"
- "golang.org/x/oauth2/jwt"
-)
-
-func ExampleJWTConfig() {
- conf := &jwt.Config{
- Email: "xxx@developer.com",
- // The contents of your RSA private key or your PEM file
- // that contains a private key.
- // If you have a p12 file instead, you
- // can use `openssl` to export the private key into a pem file.
- //
- // $ openssl pkcs12 -in key.p12 -out key.pem -nodes
- //
- // It only supports PEM containers with no passphrase.
- PrivateKey: []byte("-----BEGIN RSA PRIVATE KEY-----..."),
- Subject: "user@example.com",
- TokenURL: "https://provider.com/o/oauth2/token",
- }
- // Initiate an http.Client, the following GET request will be
- // authorized and authenticated on the behalf of user@example.com.
- client := conf.Client(oauth2.NoContext)
- client.Get("...")
-}
diff --git a/vendor/golang.org/x/oauth2/jwt/jwt.go b/vendor/golang.org/x/oauth2/jwt/jwt.go
deleted file mode 100644
index 11a2687e..00000000
--- a/vendor/golang.org/x/oauth2/jwt/jwt.go
+++ /dev/null
@@ -1,153 +0,0 @@
-// Copyright 2014 The oauth2 Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style
-// license that can be found in the LICENSE file.
-
-// Package jwt implements the OAuth 2.0 JSON Web Token flow, commonly
-// known as "two-legged OAuth 2.0".
-//
-// See: https://tools.ietf.org/html/draft-ietf-oauth-jwt-bearer-12
-package jwt
-
-import (
- "encoding/json"
- "fmt"
- "io"
- "io/ioutil"
- "net/http"
- "net/url"
- "strings"
- "time"
-
- "golang.org/x/net/context"
- "golang.org/x/oauth2"
- "golang.org/x/oauth2/internal"
- "golang.org/x/oauth2/jws"
-)
-
-var (
- defaultGrantType = "urn:ietf:params:oauth:grant-type:jwt-bearer"
- defaultHeader = &jws.Header{Algorithm: "RS256", Typ: "JWT"}
-)
-
-// Config is the configuration for using JWT to fetch tokens,
-// commonly known as "two-legged OAuth 2.0".
-type Config struct {
- // Email is the OAuth client identifier used when communicating with
- // the configured OAuth provider.
- Email string
-
- // PrivateKey contains the contents of an RSA private key or the
- // contents of a PEM file that contains a private key. The provided
- // private key is used to sign JWT payloads.
- // PEM containers with a passphrase are not supported.
- // Use the following command to convert a PKCS 12 file into a PEM.
- //
- // $ openssl pkcs12 -in key.p12 -out key.pem -nodes
- //
- PrivateKey []byte
-
- // Subject is the optional user to impersonate.
- Subject string
-
- // Scopes optionally specifies a list of requested permission scopes.
- Scopes []string
-
- // TokenURL is the endpoint required to complete the 2-legged JWT flow.
- TokenURL string
-
- // Expires optionally specifies how long the token is valid for.
- Expires time.Duration
-}
-
-// TokenSource returns a JWT TokenSource using the configuration
-// in c and the HTTP client from the provided context.
-func (c *Config) TokenSource(ctx context.Context) oauth2.TokenSource {
- return oauth2.ReuseTokenSource(nil, jwtSource{ctx, c})
-}
-
-// Client returns an HTTP client wrapping the context's
-// HTTP transport and adding Authorization headers with tokens
-// obtained from c.
-//
-// The returned client and its Transport should not be modified.
-func (c *Config) Client(ctx context.Context) *http.Client {
- return oauth2.NewClient(ctx, c.TokenSource(ctx))
-}
-
-// jwtSource is a source that always does a signed JWT request for a token.
-// It should typically be wrapped with a reuseTokenSource.
-type jwtSource struct {
- ctx context.Context
- conf *Config
-}
-
-func (js jwtSource) Token() (*oauth2.Token, error) {
- pk, err := internal.ParseKey(js.conf.PrivateKey)
- if err != nil {
- return nil, err
- }
- hc := oauth2.NewClient(js.ctx, nil)
- claimSet := &jws.ClaimSet{
- Iss: js.conf.Email,
- Scope: strings.Join(js.conf.Scopes, " "),
- Aud: js.conf.TokenURL,
- }
- if subject := js.conf.Subject; subject != "" {
- claimSet.Sub = subject
- // prn is the old name of sub. Keep setting it
- // to be compatible with legacy OAuth 2.0 providers.
- claimSet.Prn = subject
- }
- if t := js.conf.Expires; t > 0 {
- claimSet.Exp = time.Now().Add(t).Unix()
- }
- payload, err := jws.Encode(defaultHeader, claimSet, pk)
- if err != nil {
- return nil, err
- }
- v := url.Values{}
- v.Set("grant_type", defaultGrantType)
- v.Set("assertion", payload)
- resp, err := hc.PostForm(js.conf.TokenURL, v)
- if err != nil {
- return nil, fmt.Errorf("oauth2: cannot fetch token: %v", err)
- }
- defer resp.Body.Close()
- body, err := ioutil.ReadAll(io.LimitReader(resp.Body, 1<<20))
- if err != nil {
- return nil, fmt.Errorf("oauth2: cannot fetch token: %v", err)
- }
- if c := resp.StatusCode; c < 200 || c > 299 {
- return nil, fmt.Errorf("oauth2: cannot fetch token: %v\nResponse: %s", resp.Status, body)
- }
- // tokenRes is the JSON response body.
- var tokenRes struct {
- AccessToken string `json:"access_token"`
- TokenType string `json:"token_type"`
- IDToken string `json:"id_token"`
- ExpiresIn int64 `json:"expires_in"` // relative seconds from now
- }
- if err := json.Unmarshal(body, &tokenRes); err != nil {
- return nil, fmt.Errorf("oauth2: cannot fetch token: %v", err)
- }
- token := &oauth2.Token{
- AccessToken: tokenRes.AccessToken,
- TokenType: tokenRes.TokenType,
- }
- raw := make(map[string]interface{})
- json.Unmarshal(body, &raw) // no error checks for optional fields
- token = token.WithExtra(raw)
-
- if secs := tokenRes.ExpiresIn; secs > 0 {
- token.Expiry = time.Now().Add(time.Duration(secs) * time.Second)
- }
- if v := tokenRes.IDToken; v != "" {
- // decode returned id token to get expiry
- claimSet, err := jws.Decode(v)
- if err != nil {
- return nil, fmt.Errorf("oauth2: error decoding JWT token: %v", err)
- }
- token.Expiry = time.Unix(claimSet.Exp, 0)
- }
- return token, nil
-}
diff --git a/vendor/golang.org/x/oauth2/jwt/jwt_test.go b/vendor/golang.org/x/oauth2/jwt/jwt_test.go
deleted file mode 100644
index da922c3d..00000000
--- a/vendor/golang.org/x/oauth2/jwt/jwt_test.go
+++ /dev/null
@@ -1,134 +0,0 @@
-// Copyright 2014 The oauth2 Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style
-// license that can be found in the LICENSE file.
-
-package jwt
-
-import (
- "net/http"
- "net/http/httptest"
- "testing"
-
- "golang.org/x/oauth2"
-)
-
-var dummyPrivateKey = []byte(`-----BEGIN RSA PRIVATE KEY-----
-MIIEpAIBAAKCAQEAx4fm7dngEmOULNmAs1IGZ9Apfzh+BkaQ1dzkmbUgpcoghucE
-DZRnAGd2aPyB6skGMXUytWQvNYav0WTR00wFtX1ohWTfv68HGXJ8QXCpyoSKSSFY
-fuP9X36wBSkSX9J5DVgiuzD5VBdzUISSmapjKm+DcbRALjz6OUIPEWi1Tjl6p5RK
-1w41qdbmt7E5/kGhKLDuT7+M83g4VWhgIvaAXtnhklDAggilPPa8ZJ1IFe31lNlr
-k4DRk38nc6sEutdf3RL7QoH7FBusI7uXV03DC6dwN1kP4GE7bjJhcRb/7jYt7CQ9
-/E9Exz3c0yAp0yrTg0Fwh+qxfH9dKwN52S7SBwIDAQABAoIBAQCaCs26K07WY5Jt
-3a2Cw3y2gPrIgTCqX6hJs7O5ByEhXZ8nBwsWANBUe4vrGaajQHdLj5OKfsIDrOvn
-2NI1MqflqeAbu/kR32q3tq8/Rl+PPiwUsW3E6Pcf1orGMSNCXxeducF2iySySzh3
-nSIhCG5uwJDWI7a4+9KiieFgK1pt/Iv30q1SQS8IEntTfXYwANQrfKUVMmVF9aIK
-6/WZE2yd5+q3wVVIJ6jsmTzoDCX6QQkkJICIYwCkglmVy5AeTckOVwcXL0jqw5Kf
-5/soZJQwLEyBoQq7Kbpa26QHq+CJONetPP8Ssy8MJJXBT+u/bSseMb3Zsr5cr43e
-DJOhwsThAoGBAPY6rPKl2NT/K7XfRCGm1sbWjUQyDShscwuWJ5+kD0yudnT/ZEJ1
-M3+KS/iOOAoHDdEDi9crRvMl0UfNa8MAcDKHflzxg2jg/QI+fTBjPP5GOX0lkZ9g
-z6VePoVoQw2gpPFVNPPTxKfk27tEzbaffvOLGBEih0Kb7HTINkW8rIlzAoGBAM9y
-1yr+jvfS1cGFtNU+Gotoihw2eMKtIqR03Yn3n0PK1nVCDKqwdUqCypz4+ml6cxRK
-J8+Pfdh7D+ZJd4LEG6Y4QRDLuv5OA700tUoSHxMSNn3q9As4+T3MUyYxWKvTeu3U
-f2NWP9ePU0lV8ttk7YlpVRaPQmc1qwooBA/z/8AdAoGAW9x0HWqmRICWTBnpjyxx
-QGlW9rQ9mHEtUotIaRSJ6K/F3cxSGUEkX1a3FRnp6kPLcckC6NlqdNgNBd6rb2rA
-cPl/uSkZP42Als+9YMoFPU/xrrDPbUhu72EDrj3Bllnyb168jKLa4VBOccUvggxr
-Dm08I1hgYgdN5huzs7y6GeUCgYEAj+AZJSOJ6o1aXS6rfV3mMRve9bQ9yt8jcKXw
-5HhOCEmMtaSKfnOF1Ziih34Sxsb7O2428DiX0mV/YHtBnPsAJidL0SdLWIapBzeg
-KHArByIRkwE6IvJvwpGMdaex1PIGhx5i/3VZL9qiq/ElT05PhIb+UXgoWMabCp84
-OgxDK20CgYAeaFo8BdQ7FmVX2+EEejF+8xSge6WVLtkaon8bqcn6P0O8lLypoOhd
-mJAYH8WU+UAy9pecUnDZj14LAGNVmYcse8HFX71MoshnvCTFEPVo4rZxIAGwMpeJ
-5jgQ3slYLpqrGlcbLgUXBUgzEO684Wk/UV9DFPlHALVqCfXQ9dpJPg==
------END RSA PRIVATE KEY-----`)
-
-func TestJWTFetch_JSONResponse(t *testing.T) {
- ts := httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
- w.Header().Set("Content-Type", "application/json")
- w.Write([]byte(`{
- "access_token": "90d64460d14870c08c81352a05dedd3465940a7c",
- "scope": "user",
- "token_type": "bearer",
- "expires_in": 3600
- }`))
- }))
- defer ts.Close()
-
- conf := &Config{
- Email: "aaa@xxx.com",
- PrivateKey: dummyPrivateKey,
- TokenURL: ts.URL,
- }
- tok, err := conf.TokenSource(oauth2.NoContext).Token()
- if err != nil {
- t.Fatal(err)
- }
- if !tok.Valid() {
- t.Errorf("Token invalid")
- }
- if tok.AccessToken != "90d64460d14870c08c81352a05dedd3465940a7c" {
- t.Errorf("Unexpected access token, %#v", tok.AccessToken)
- }
- if tok.TokenType != "bearer" {
- t.Errorf("Unexpected token type, %#v", tok.TokenType)
- }
- if tok.Expiry.IsZero() {
- t.Errorf("Unexpected token expiry, %#v", tok.Expiry)
- }
- scope := tok.Extra("scope")
- if scope != "user" {
- t.Errorf("Unexpected value for scope: %v", scope)
- }
-}
-
-func TestJWTFetch_BadResponse(t *testing.T) {
- ts := httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
- w.Header().Set("Content-Type", "application/json")
- w.Write([]byte(`{"scope": "user", "token_type": "bearer"}`))
- }))
- defer ts.Close()
-
- conf := &Config{
- Email: "aaa@xxx.com",
- PrivateKey: dummyPrivateKey,
- TokenURL: ts.URL,
- }
- tok, err := conf.TokenSource(oauth2.NoContext).Token()
- if err != nil {
- t.Fatal(err)
- }
- if tok == nil {
- t.Fatalf("token is nil")
- }
- if tok.Valid() {
- t.Errorf("token is valid. want invalid.")
- }
- if tok.AccessToken != "" {
- t.Errorf("Unexpected non-empty access token %q.", tok.AccessToken)
- }
- if want := "bearer"; tok.TokenType != want {
- t.Errorf("TokenType = %q; want %q", tok.TokenType, want)
- }
- scope := tok.Extra("scope")
- if want := "user"; scope != want {
- t.Errorf("token scope = %q; want %q", scope, want)
- }
-}
-
-func TestJWTFetch_BadResponseType(t *testing.T) {
- ts := httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
- w.Header().Set("Content-Type", "application/json")
- w.Write([]byte(`{"access_token":123, "scope": "user", "token_type": "bearer"}`))
- }))
- defer ts.Close()
- conf := &Config{
- Email: "aaa@xxx.com",
- PrivateKey: dummyPrivateKey,
- TokenURL: ts.URL,
- }
- tok, err := conf.TokenSource(oauth2.NoContext).Token()
- if err == nil {
- t.Error("got a token; expected error")
- if tok.AccessToken != "" {
- t.Errorf("Unexpected access token, %#v.", tok.AccessToken)
- }
- }
-}
diff --git a/vendor/golang.org/x/oauth2/linkedin/linkedin.go b/vendor/golang.org/x/oauth2/linkedin/linkedin.go
deleted file mode 100644
index d93fded6..00000000
--- a/vendor/golang.org/x/oauth2/linkedin/linkedin.go
+++ /dev/null
@@ -1,16 +0,0 @@
-// Copyright 2015 The oauth2 Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style
-// license that can be found in the LICENSE file.
-
-// Package linkedin provides constants for using OAuth2 to access LinkedIn.
-package linkedin
-
-import (
- "golang.org/x/oauth2"
-)
-
-// Endpoint is LinkedIn's OAuth 2.0 endpoint.
-var Endpoint = oauth2.Endpoint{
- AuthURL: "https://www.linkedin.com/uas/oauth2/authorization",
- TokenURL: "https://www.linkedin.com/uas/oauth2/accessToken",
-}
diff --git a/vendor/golang.org/x/oauth2/oauth2.go b/vendor/golang.org/x/oauth2/oauth2.go
deleted file mode 100644
index dfcf238d..00000000
--- a/vendor/golang.org/x/oauth2/oauth2.go
+++ /dev/null
@@ -1,325 +0,0 @@
-// Copyright 2014 The oauth2 Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style
-// license that can be found in the LICENSE file.
-
-// Package oauth2 provides support for making
-// OAuth2 authorized and authenticated HTTP requests.
-// It can additionally grant authorization with Bearer JWT.
-package oauth2
-
-import (
- "bytes"
- "errors"
- "net/http"
- "net/url"
- "strings"
- "sync"
-
- "golang.org/x/net/context"
- "golang.org/x/oauth2/internal"
-)
-
-// NoContext is the default context you should supply if not using
-// your own context.Context (see https://golang.org/x/net/context).
-var NoContext = context.TODO()
-
-// Config describes a typical 3-legged OAuth2 flow, with both the
-// client application information and the server's endpoint URLs.
-type Config struct {
- // ClientID is the application's ID.
- ClientID string
-
- // ClientSecret is the application's secret.
- ClientSecret string
-
- // Endpoint contains the resource server's token endpoint
- // URLs. These are constants specific to each server and are
- // often available via site-specific packages, such as
- // google.Endpoint or github.Endpoint.
- Endpoint Endpoint
-
- // RedirectURL is the URL to redirect users going through
- // the OAuth flow, after the resource owner's URLs.
- RedirectURL string
-
- // Scope specifies optional requested permissions.
- Scopes []string
-}
-
-// A TokenSource is anything that can return a token.
-type TokenSource interface {
- // Token returns a token or an error.
- // Token must be safe for concurrent use by multiple goroutines.
- // The returned Token must not be modified.
- Token() (*Token, error)
-}
-
-// Endpoint contains the OAuth 2.0 provider's authorization and token
-// endpoint URLs.
-type Endpoint struct {
- AuthURL string
- TokenURL string
-}
-
-var (
- // AccessTypeOnline and AccessTypeOffline are options passed
- // to the Options.AuthCodeURL method. They modify the
- // "access_type" field that gets sent in the URL returned by
- // AuthCodeURL.
- //
- // Online is the default if neither is specified. If your
- // application needs to refresh access tokens when the user
- // is not present at the browser, then use offline. This will
- // result in your application obtaining a refresh token the
- // first time your application exchanges an authorization
- // code for a user.
- AccessTypeOnline AuthCodeOption = SetAuthURLParam("access_type", "online")
- AccessTypeOffline AuthCodeOption = SetAuthURLParam("access_type", "offline")
-
- // ApprovalForce forces the users to view the consent dialog
- // and confirm the permissions request at the URL returned
- // from AuthCodeURL, even if they've already done so.
- ApprovalForce AuthCodeOption = SetAuthURLParam("approval_prompt", "force")
-)
-
-// An AuthCodeOption is passed to Config.AuthCodeURL.
-type AuthCodeOption interface {
- setValue(url.Values)
-}
-
-type setParam struct{ k, v string }
-
-func (p setParam) setValue(m url.Values) { m.Set(p.k, p.v) }
-
-// SetAuthURLParam builds an AuthCodeOption which passes key/value parameters
-// to a provider's authorization endpoint.
-func SetAuthURLParam(key, value string) AuthCodeOption {
- return setParam{key, value}
-}
-
-// AuthCodeURL returns a URL to OAuth 2.0 provider's consent page
-// that asks for permissions for the required scopes explicitly.
-//
-// State is a token to protect the user from CSRF attacks. You must
-// always provide a non-zero string and validate that it matches the
-// the state query parameter on your redirect callback.
-// See http://tools.ietf.org/html/rfc6749#section-10.12 for more info.
-//
-// Opts may include AccessTypeOnline or AccessTypeOffline, as well
-// as ApprovalForce.
-func (c *Config) AuthCodeURL(state string, opts ...AuthCodeOption) string {
- var buf bytes.Buffer
- buf.WriteString(c.Endpoint.AuthURL)
- v := url.Values{
- "response_type": {"code"},
- "client_id": {c.ClientID},
- "redirect_uri": internal.CondVal(c.RedirectURL),
- "scope": internal.CondVal(strings.Join(c.Scopes, " ")),
- "state": internal.CondVal(state),
- }
- for _, opt := range opts {
- opt.setValue(v)
- }
- if strings.Contains(c.Endpoint.AuthURL, "?") {
- buf.WriteByte('&')
- } else {
- buf.WriteByte('?')
- }
- buf.WriteString(v.Encode())
- return buf.String()
-}
-
-// PasswordCredentialsToken converts a resource owner username and password
-// pair into a token.
-//
-// Per the RFC, this grant type should only be used "when there is a high
-// degree of trust between the resource owner and the client (e.g., the client
-// is part of the device operating system or a highly privileged application),
-// and when other authorization grant types are not available."
-// See https://tools.ietf.org/html/rfc6749#section-4.3 for more info.
-//
-// The HTTP client to use is derived from the context.
-// If nil, http.DefaultClient is used.
-func (c *Config) PasswordCredentialsToken(ctx context.Context, username, password string) (*Token, error) {
- return retrieveToken(ctx, c, url.Values{
- "grant_type": {"password"},
- "username": {username},
- "password": {password},
- "scope": internal.CondVal(strings.Join(c.Scopes, " ")),
- })
-}
-
-// Exchange converts an authorization code into a token.
-//
-// It is used after a resource provider redirects the user back
-// to the Redirect URI (the URL obtained from AuthCodeURL).
-//
-// The HTTP client to use is derived from the context.
-// If a client is not provided via the context, http.DefaultClient is used.
-//
-// The code will be in the *http.Request.FormValue("code"). Before
-// calling Exchange, be sure to validate FormValue("state").
-func (c *Config) Exchange(ctx context.Context, code string) (*Token, error) {
- return retrieveToken(ctx, c, url.Values{
- "grant_type": {"authorization_code"},
- "code": {code},
- "redirect_uri": internal.CondVal(c.RedirectURL),
- "scope": internal.CondVal(strings.Join(c.Scopes, " ")),
- })
-}
-
-// Client returns an HTTP client using the provided token.
-// The token will auto-refresh as necessary. The underlying
-// HTTP transport will be obtained using the provided context.
-// The returned client and its Transport should not be modified.
-func (c *Config) Client(ctx context.Context, t *Token) *http.Client {
- return NewClient(ctx, c.TokenSource(ctx, t))
-}
-
-// TokenSource returns a TokenSource that returns t until t expires,
-// automatically refreshing it as necessary using the provided context.
-//
-// Most users will use Config.Client instead.
-func (c *Config) TokenSource(ctx context.Context, t *Token) TokenSource {
- tkr := &tokenRefresher{
- ctx: ctx,
- conf: c,
- }
- if t != nil {
- tkr.refreshToken = t.RefreshToken
- }
- return &reuseTokenSource{
- t: t,
- new: tkr,
- }
-}
-
-// tokenRefresher is a TokenSource that makes "grant_type"=="refresh_token"
-// HTTP requests to renew a token using a RefreshToken.
-type tokenRefresher struct {
- ctx context.Context // used to get HTTP requests
- conf *Config
- refreshToken string
-}
-
-// WARNING: Token is not safe for concurrent access, as it
-// updates the tokenRefresher's refreshToken field.
-// Within this package, it is used by reuseTokenSource which
-// synchronizes calls to this method with its own mutex.
-func (tf *tokenRefresher) Token() (*Token, error) {
- if tf.refreshToken == "" {
- return nil, errors.New("oauth2: token expired and refresh token is not set")
- }
-
- tk, err := retrieveToken(tf.ctx, tf.conf, url.Values{
- "grant_type": {"refresh_token"},
- "refresh_token": {tf.refreshToken},
- })
-
- if err != nil {
- return nil, err
- }
- if tf.refreshToken != tk.RefreshToken {
- tf.refreshToken = tk.RefreshToken
- }
- return tk, err
-}
-
-// reuseTokenSource is a TokenSource that holds a single token in memory
-// and validates its expiry before each call to retrieve it with
-// Token. If it's expired, it will be auto-refreshed using the
-// new TokenSource.
-type reuseTokenSource struct {
- new TokenSource // called when t is expired.
-
- mu sync.Mutex // guards t
- t *Token
-}
-
-// Token returns the current token if it's still valid, else will
-// refresh the current token (using r.Context for HTTP client
-// information) and return the new one.
-func (s *reuseTokenSource) Token() (*Token, error) {
- s.mu.Lock()
- defer s.mu.Unlock()
- if s.t.Valid() {
- return s.t, nil
- }
- t, err := s.new.Token()
- if err != nil {
- return nil, err
- }
- s.t = t
- return t, nil
-}
-
-// StaticTokenSource returns a TokenSource that always returns the same token.
-// Because the provided token t is never refreshed, StaticTokenSource is only
-// useful for tokens that never expire.
-func StaticTokenSource(t *Token) TokenSource {
- return staticTokenSource{t}
-}
-
-// staticTokenSource is a TokenSource that always returns the same Token.
-type staticTokenSource struct {
- t *Token
-}
-
-func (s staticTokenSource) Token() (*Token, error) {
- return s.t, nil
-}
-
-// HTTPClient is the context key to use with golang.org/x/net/context's
-// WithValue function to associate an *http.Client value with a context.
-var HTTPClient internal.ContextKey
-
-// NewClient creates an *http.Client from a Context and TokenSource.
-// The returned client is not valid beyond the lifetime of the context.
-//
-// As a special case, if src is nil, a non-OAuth2 client is returned
-// using the provided context. This exists to support related OAuth2
-// packages.
-func NewClient(ctx context.Context, src TokenSource) *http.Client {
- if src == nil {
- c, err := internal.ContextClient(ctx)
- if err != nil {
- return &http.Client{Transport: internal.ErrorTransport{err}}
- }
- return c
- }
- return &http.Client{
- Transport: &Transport{
- Base: internal.ContextTransport(ctx),
- Source: ReuseTokenSource(nil, src),
- },
- }
-}
-
-// ReuseTokenSource returns a TokenSource which repeatedly returns the
-// same token as long as it's valid, starting with t.
-// When its cached token is invalid, a new token is obtained from src.
-//
-// ReuseTokenSource is typically used to reuse tokens from a cache
-// (such as a file on disk) between runs of a program, rather than
-// obtaining new tokens unnecessarily.
-//
-// The initial token t may be nil, in which case the TokenSource is
-// wrapped in a caching version if it isn't one already. This also
-// means it's always safe to wrap ReuseTokenSource around any other
-// TokenSource without adverse effects.
-func ReuseTokenSource(t *Token, src TokenSource) TokenSource {
- // Don't wrap a reuseTokenSource in itself. That would work,
- // but cause an unnecessary number of mutex operations.
- // Just build the equivalent one.
- if rt, ok := src.(*reuseTokenSource); ok {
- if t == nil {
- // Just use it directly.
- return rt
- }
- src = rt.new
- }
- return &reuseTokenSource{
- t: t,
- new: src,
- }
-}
diff --git a/vendor/golang.org/x/oauth2/oauth2_test.go b/vendor/golang.org/x/oauth2/oauth2_test.go
deleted file mode 100644
index 2f7d731c..00000000
--- a/vendor/golang.org/x/oauth2/oauth2_test.go
+++ /dev/null
@@ -1,422 +0,0 @@
-// Copyright 2014 The oauth2 Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style
-// license that can be found in the LICENSE file.
-
-package oauth2
-
-import (
- "encoding/json"
- "errors"
- "fmt"
- "io/ioutil"
- "net/http"
- "net/http/httptest"
- "reflect"
- "strconv"
- "testing"
- "time"
-
- "golang.org/x/net/context"
-)
-
-type mockTransport struct {
- rt func(req *http.Request) (resp *http.Response, err error)
-}
-
-func (t *mockTransport) RoundTrip(req *http.Request) (resp *http.Response, err error) {
- return t.rt(req)
-}
-
-type mockCache struct {
- token *Token
- readErr error
-}
-
-func (c *mockCache) ReadToken() (*Token, error) {
- return c.token, c.readErr
-}
-
-func (c *mockCache) WriteToken(*Token) {
- // do nothing
-}
-
-func newConf(url string) *Config {
- return &Config{
- ClientID: "CLIENT_ID",
- ClientSecret: "CLIENT_SECRET",
- RedirectURL: "REDIRECT_URL",
- Scopes: []string{"scope1", "scope2"},
- Endpoint: Endpoint{
- AuthURL: url + "/auth",
- TokenURL: url + "/token",
- },
- }
-}
-
-func TestAuthCodeURL(t *testing.T) {
- conf := newConf("server")
- url := conf.AuthCodeURL("foo", AccessTypeOffline, ApprovalForce)
- if url != "server/auth?access_type=offline&approval_prompt=force&client_id=CLIENT_ID&redirect_uri=REDIRECT_URL&response_type=code&scope=scope1+scope2&state=foo" {
- t.Errorf("Auth code URL doesn't match the expected, found: %v", url)
- }
-}
-
-func TestAuthCodeURL_CustomParam(t *testing.T) {
- conf := newConf("server")
- param := SetAuthURLParam("foo", "bar")
- url := conf.AuthCodeURL("baz", param)
- if url != "server/auth?client_id=CLIENT_ID&foo=bar&redirect_uri=REDIRECT_URL&response_type=code&scope=scope1+scope2&state=baz" {
- t.Errorf("Auth code URL doesn't match the expected, found: %v", url)
- }
-}
-
-func TestAuthCodeURL_Optional(t *testing.T) {
- conf := &Config{
- ClientID: "CLIENT_ID",
- Endpoint: Endpoint{
- AuthURL: "/auth-url",
- TokenURL: "/token-url",
- },
- }
- url := conf.AuthCodeURL("")
- if url != "/auth-url?client_id=CLIENT_ID&response_type=code" {
- t.Fatalf("Auth code URL doesn't match the expected, found: %v", url)
- }
-}
-
-func TestExchangeRequest(t *testing.T) {
- ts := httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
- if r.URL.String() != "/token" {
- t.Errorf("Unexpected exchange request URL, %v is found.", r.URL)
- }
- headerAuth := r.Header.Get("Authorization")
- if headerAuth != "Basic Q0xJRU5UX0lEOkNMSUVOVF9TRUNSRVQ=" {
- t.Errorf("Unexpected authorization header, %v is found.", headerAuth)
- }
- headerContentType := r.Header.Get("Content-Type")
- if headerContentType != "application/x-www-form-urlencoded" {
- t.Errorf("Unexpected Content-Type header, %v is found.", headerContentType)
- }
- body, err := ioutil.ReadAll(r.Body)
- if err != nil {
- t.Errorf("Failed reading request body: %s.", err)
- }
- if string(body) != "client_id=CLIENT_ID&code=exchange-code&grant_type=authorization_code&redirect_uri=REDIRECT_URL&scope=scope1+scope2" {
- t.Errorf("Unexpected exchange payload, %v is found.", string(body))
- }
- w.Header().Set("Content-Type", "application/x-www-form-urlencoded")
- w.Write([]byte("access_token=90d64460d14870c08c81352a05dedd3465940a7c&scope=user&token_type=bearer"))
- }))
- defer ts.Close()
- conf := newConf(ts.URL)
- tok, err := conf.Exchange(NoContext, "exchange-code")
- if err != nil {
- t.Error(err)
- }
- if !tok.Valid() {
- t.Fatalf("Token invalid. Got: %#v", tok)
- }
- if tok.AccessToken != "90d64460d14870c08c81352a05dedd3465940a7c" {
- t.Errorf("Unexpected access token, %#v.", tok.AccessToken)
- }
- if tok.TokenType != "bearer" {
- t.Errorf("Unexpected token type, %#v.", tok.TokenType)
- }
- scope := tok.Extra("scope")
- if scope != "user" {
- t.Errorf("Unexpected value for scope: %v", scope)
- }
-}
-
-func TestExchangeRequest_JSONResponse(t *testing.T) {
- ts := httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
- if r.URL.String() != "/token" {
- t.Errorf("Unexpected exchange request URL, %v is found.", r.URL)
- }
- headerAuth := r.Header.Get("Authorization")
- if headerAuth != "Basic Q0xJRU5UX0lEOkNMSUVOVF9TRUNSRVQ=" {
- t.Errorf("Unexpected authorization header, %v is found.", headerAuth)
- }
- headerContentType := r.Header.Get("Content-Type")
- if headerContentType != "application/x-www-form-urlencoded" {
- t.Errorf("Unexpected Content-Type header, %v is found.", headerContentType)
- }
- body, err := ioutil.ReadAll(r.Body)
- if err != nil {
- t.Errorf("Failed reading request body: %s.", err)
- }
- if string(body) != "client_id=CLIENT_ID&code=exchange-code&grant_type=authorization_code&redirect_uri=REDIRECT_URL&scope=scope1+scope2" {
- t.Errorf("Unexpected exchange payload, %v is found.", string(body))
- }
- w.Header().Set("Content-Type", "application/json")
- w.Write([]byte(`{"access_token": "90d64460d14870c08c81352a05dedd3465940a7c", "scope": "user", "token_type": "bearer", "expires_in": 86400}`))
- }))
- defer ts.Close()
- conf := newConf(ts.URL)
- tok, err := conf.Exchange(NoContext, "exchange-code")
- if err != nil {
- t.Error(err)
- }
- if !tok.Valid() {
- t.Fatalf("Token invalid. Got: %#v", tok)
- }
- if tok.AccessToken != "90d64460d14870c08c81352a05dedd3465940a7c" {
- t.Errorf("Unexpected access token, %#v.", tok.AccessToken)
- }
- if tok.TokenType != "bearer" {
- t.Errorf("Unexpected token type, %#v.", tok.TokenType)
- }
- scope := tok.Extra("scope")
- if scope != "user" {
- t.Errorf("Unexpected value for scope: %v", scope)
- }
-}
-
-const day = 24 * time.Hour
-
-func TestExchangeRequest_JSONResponse_Expiry(t *testing.T) {
- seconds := int32(day.Seconds())
- jsonNumberType := reflect.TypeOf(json.Number("0"))
- for _, c := range []struct {
- expires string
- expect error
- }{
- {fmt.Sprintf(`"expires_in": %d`, seconds), nil},
- {fmt.Sprintf(`"expires_in": "%d"`, seconds), nil}, // PayPal case
- {fmt.Sprintf(`"expires": %d`, seconds), nil}, // Facebook case
- {`"expires": false`, &json.UnmarshalTypeError{Value: "bool", Type: jsonNumberType}}, // wrong type
- {`"expires": {}`, &json.UnmarshalTypeError{Value: "object", Type: jsonNumberType}}, // wrong type
- {`"expires": "zzz"`, &strconv.NumError{Func: "ParseInt", Num: "zzz", Err: strconv.ErrSyntax}}, // wrong value
- } {
- testExchangeRequest_JSONResponse_expiry(t, c.expires, c.expect)
- }
-}
-
-func testExchangeRequest_JSONResponse_expiry(t *testing.T, exp string, expect error) {
- ts := httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
- w.Header().Set("Content-Type", "application/json")
- w.Write([]byte(fmt.Sprintf(`{"access_token": "90d", "scope": "user", "token_type": "bearer", %s}`, exp)))
- }))
- defer ts.Close()
- conf := newConf(ts.URL)
- t1 := time.Now().Add(day)
- tok, err := conf.Exchange(NoContext, "exchange-code")
- t2 := time.Now().Add(day)
- // Do a fmt.Sprint comparison so either side can be
- // nil. fmt.Sprint just stringifies them to "", and no
- // non-nil expected error ever stringifies as "", so this
- // isn't terribly disgusting. We do this because Go 1.4 and
- // Go 1.5 return a different deep value for
- // json.UnmarshalTypeError. In Go 1.5, the
- // json.UnmarshalTypeError contains a new field with a new
- // non-zero value. Rather than ignore it here with reflect or
- // add new files and +build tags, just look at the strings.
- if fmt.Sprint(err) != fmt.Sprint(expect) {
- t.Errorf("Error = %v; want %v", err, expect)
- }
- if err != nil {
- return
- }
- if !tok.Valid() {
- t.Fatalf("Token invalid. Got: %#v", tok)
- }
- expiry := tok.Expiry
- if expiry.Before(t1) || expiry.After(t2) {
- t.Errorf("Unexpected value for Expiry: %v (shold be between %v and %v)", expiry, t1, t2)
- }
-}
-
-func TestExchangeRequest_BadResponse(t *testing.T) {
- ts := httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
- w.Header().Set("Content-Type", "application/json")
- w.Write([]byte(`{"scope": "user", "token_type": "bearer"}`))
- }))
- defer ts.Close()
- conf := newConf(ts.URL)
- tok, err := conf.Exchange(NoContext, "code")
- if err != nil {
- t.Fatal(err)
- }
- if tok.AccessToken != "" {
- t.Errorf("Unexpected access token, %#v.", tok.AccessToken)
- }
-}
-
-func TestExchangeRequest_BadResponseType(t *testing.T) {
- ts := httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
- w.Header().Set("Content-Type", "application/json")
- w.Write([]byte(`{"access_token":123, "scope": "user", "token_type": "bearer"}`))
- }))
- defer ts.Close()
- conf := newConf(ts.URL)
- _, err := conf.Exchange(NoContext, "exchange-code")
- if err == nil {
- t.Error("expected error from invalid access_token type")
- }
-}
-
-func TestExchangeRequest_NonBasicAuth(t *testing.T) {
- tr := &mockTransport{
- rt: func(r *http.Request) (w *http.Response, err error) {
- headerAuth := r.Header.Get("Authorization")
- if headerAuth != "" {
- t.Errorf("Unexpected authorization header, %v is found.", headerAuth)
- }
- return nil, errors.New("no response")
- },
- }
- c := &http.Client{Transport: tr}
- conf := &Config{
- ClientID: "CLIENT_ID",
- Endpoint: Endpoint{
- AuthURL: "https://accounts.google.com/auth",
- TokenURL: "https://accounts.google.com/token",
- },
- }
-
- ctx := context.WithValue(context.Background(), HTTPClient, c)
- conf.Exchange(ctx, "code")
-}
-
-func TestPasswordCredentialsTokenRequest(t *testing.T) {
- ts := httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
- defer r.Body.Close()
- expected := "/token"
- if r.URL.String() != expected {
- t.Errorf("URL = %q; want %q", r.URL, expected)
- }
- headerAuth := r.Header.Get("Authorization")
- expected = "Basic Q0xJRU5UX0lEOkNMSUVOVF9TRUNSRVQ="
- if headerAuth != expected {
- t.Errorf("Authorization header = %q; want %q", headerAuth, expected)
- }
- headerContentType := r.Header.Get("Content-Type")
- expected = "application/x-www-form-urlencoded"
- if headerContentType != expected {
- t.Errorf("Content-Type header = %q; want %q", headerContentType, expected)
- }
- body, err := ioutil.ReadAll(r.Body)
- if err != nil {
- t.Errorf("Failed reading request body: %s.", err)
- }
- expected = "client_id=CLIENT_ID&grant_type=password&password=password1&scope=scope1+scope2&username=user1"
- if string(body) != expected {
- t.Errorf("res.Body = %q; want %q", string(body), expected)
- }
- w.Header().Set("Content-Type", "application/x-www-form-urlencoded")
- w.Write([]byte("access_token=90d64460d14870c08c81352a05dedd3465940a7c&scope=user&token_type=bearer"))
- }))
- defer ts.Close()
- conf := newConf(ts.URL)
- tok, err := conf.PasswordCredentialsToken(NoContext, "user1", "password1")
- if err != nil {
- t.Error(err)
- }
- if !tok.Valid() {
- t.Fatalf("Token invalid. Got: %#v", tok)
- }
- expected := "90d64460d14870c08c81352a05dedd3465940a7c"
- if tok.AccessToken != expected {
- t.Errorf("AccessToken = %q; want %q", tok.AccessToken, expected)
- }
- expected = "bearer"
- if tok.TokenType != expected {
- t.Errorf("TokenType = %q; want %q", tok.TokenType, expected)
- }
-}
-
-func TestTokenRefreshRequest(t *testing.T) {
- ts := httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
- if r.URL.String() == "/somethingelse" {
- return
- }
- if r.URL.String() != "/token" {
- t.Errorf("Unexpected token refresh request URL, %v is found.", r.URL)
- }
- headerContentType := r.Header.Get("Content-Type")
- if headerContentType != "application/x-www-form-urlencoded" {
- t.Errorf("Unexpected Content-Type header, %v is found.", headerContentType)
- }
- body, _ := ioutil.ReadAll(r.Body)
- if string(body) != "client_id=CLIENT_ID&grant_type=refresh_token&refresh_token=REFRESH_TOKEN" {
- t.Errorf("Unexpected refresh token payload, %v is found.", string(body))
- }
- }))
- defer ts.Close()
- conf := newConf(ts.URL)
- c := conf.Client(NoContext, &Token{RefreshToken: "REFRESH_TOKEN"})
- c.Get(ts.URL + "/somethingelse")
-}
-
-func TestFetchWithNoRefreshToken(t *testing.T) {
- ts := httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
- if r.URL.String() == "/somethingelse" {
- return
- }
- if r.URL.String() != "/token" {
- t.Errorf("Unexpected token refresh request URL, %v is found.", r.URL)
- }
- headerContentType := r.Header.Get("Content-Type")
- if headerContentType != "application/x-www-form-urlencoded" {
- t.Errorf("Unexpected Content-Type header, %v is found.", headerContentType)
- }
- body, _ := ioutil.ReadAll(r.Body)
- if string(body) != "client_id=CLIENT_ID&grant_type=refresh_token&refresh_token=REFRESH_TOKEN" {
- t.Errorf("Unexpected refresh token payload, %v is found.", string(body))
- }
- }))
- defer ts.Close()
- conf := newConf(ts.URL)
- c := conf.Client(NoContext, nil)
- _, err := c.Get(ts.URL + "/somethingelse")
- if err == nil {
- t.Errorf("Fetch should return an error if no refresh token is set")
- }
-}
-
-func TestRefreshToken_RefreshTokenReplacement(t *testing.T) {
- ts := httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
- w.Header().Set("Content-Type", "application/json")
- w.Write([]byte(`{"access_token":"ACCESS TOKEN", "scope": "user", "token_type": "bearer", "refresh_token": "NEW REFRESH TOKEN"}`))
- return
- }))
- defer ts.Close()
- conf := newConf(ts.URL)
- tkr := tokenRefresher{
- conf: conf,
- ctx: NoContext,
- refreshToken: "OLD REFRESH TOKEN",
- }
- tk, err := tkr.Token()
- if err != nil {
- t.Errorf("Unexpected refreshToken error returned: %v", err)
- return
- }
- if tk.RefreshToken != tkr.refreshToken {
- t.Errorf("tokenRefresher.refresh_token = %s; want %s", tkr.refreshToken, tk.RefreshToken)
- }
-}
-
-func TestConfigClientWithToken(t *testing.T) {
- tok := &Token{
- AccessToken: "abc123",
- }
- ts := httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
- if got, want := r.Header.Get("Authorization"), fmt.Sprintf("Bearer %s", tok.AccessToken); got != want {
- t.Errorf("Authorization header = %q; want %q", got, want)
- }
- return
- }))
- defer ts.Close()
- conf := newConf(ts.URL)
-
- c := conf.Client(NoContext, tok)
- req, err := http.NewRequest("GET", ts.URL, nil)
- if err != nil {
- t.Error(err)
- }
- _, err = c.Do(req)
- if err != nil {
- t.Error(err)
- }
-}
diff --git a/vendor/golang.org/x/oauth2/odnoklassniki/odnoklassniki.go b/vendor/golang.org/x/oauth2/odnoklassniki/odnoklassniki.go
deleted file mode 100644
index f0b66f97..00000000
--- a/vendor/golang.org/x/oauth2/odnoklassniki/odnoklassniki.go
+++ /dev/null
@@ -1,16 +0,0 @@
-// Copyright 2015 The oauth2 Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style
-// license that can be found in the LICENSE file.
-
-// Package odnoklassniki provides constants for using OAuth2 to access Odnoklassniki.
-package odnoklassniki
-
-import (
- "golang.org/x/oauth2"
-)
-
-// Endpoint is Odnoklassniki's OAuth 2.0 endpoint.
-var Endpoint = oauth2.Endpoint{
- AuthURL: "https://www.odnoklassniki.ru/oauth/authorize",
- TokenURL: "https://api.odnoklassniki.ru/oauth/token.do",
-}
diff --git a/vendor/golang.org/x/oauth2/paypal/paypal.go b/vendor/golang.org/x/oauth2/paypal/paypal.go
deleted file mode 100644
index a99366b6..00000000
--- a/vendor/golang.org/x/oauth2/paypal/paypal.go
+++ /dev/null
@@ -1,22 +0,0 @@
-// Copyright 2015 The oauth2 Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style
-// license that can be found in the LICENSE file.
-
-// Package paypal provides constants for using OAuth2 to access PayPal.
-package paypal
-
-import (
- "golang.org/x/oauth2"
-)
-
-// Endpoint is PayPal's OAuth 2.0 endpoint in live (production) environment.
-var Endpoint = oauth2.Endpoint{
- AuthURL: "https://www.paypal.com/webapps/auth/protocol/openidconnect/v1/authorize",
- TokenURL: "https://api.paypal.com/v1/identity/openidconnect/tokenservice",
-}
-
-// SandboxEndpoint is PayPal's OAuth 2.0 endpoint in sandbox (testing) environment.
-var SandboxEndpoint = oauth2.Endpoint{
- AuthURL: "https://www.sandbox.paypal.com/webapps/auth/protocol/openidconnect/v1/authorize",
- TokenURL: "https://api.sandbox.paypal.com/v1/identity/openidconnect/tokenservice",
-}
diff --git a/vendor/golang.org/x/oauth2/token.go b/vendor/golang.org/x/oauth2/token.go
deleted file mode 100644
index ebbdddbd..00000000
--- a/vendor/golang.org/x/oauth2/token.go
+++ /dev/null
@@ -1,143 +0,0 @@
-// Copyright 2014 The oauth2 Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style
-// license that can be found in the LICENSE file.
-
-package oauth2
-
-import (
- "net/http"
- "net/url"
- "strings"
- "time"
-
- "golang.org/x/net/context"
- "golang.org/x/oauth2/internal"
-)
-
-// expiryDelta determines how earlier a token should be considered
-// expired than its actual expiration time. It is used to avoid late
-// expirations due to client-server time mismatches.
-const expiryDelta = 10 * time.Second
-
-// Token represents the crendentials used to authorize
-// the requests to access protected resources on the OAuth 2.0
-// provider's backend.
-//
-// Most users of this package should not access fields of Token
-// directly. They're exported mostly for use by related packages
-// implementing derivative OAuth2 flows.
-type Token struct {
- // AccessToken is the token that authorizes and authenticates
- // the requests.
- AccessToken string `json:"access_token"`
-
- // TokenType is the type of token.
- // The Type method returns either this or "Bearer", the default.
- TokenType string `json:"token_type,omitempty"`
-
- // RefreshToken is a token that's used by the application
- // (as opposed to the user) to refresh the access token
- // if it expires.
- RefreshToken string `json:"refresh_token,omitempty"`
-
- // Expiry is the optional expiration time of the access token.
- //
- // If zero, TokenSource implementations will reuse the same
- // token forever and RefreshToken or equivalent
- // mechanisms for that TokenSource will not be used.
- Expiry time.Time `json:"expiry,omitempty"`
-
- // raw optionally contains extra metadata from the server
- // when updating a token.
- raw interface{}
-}
-
-// Type returns t.TokenType if non-empty, else "Bearer".
-func (t *Token) Type() string {
- if strings.EqualFold(t.TokenType, "bearer") {
- return "Bearer"
- }
- if strings.EqualFold(t.TokenType, "mac") {
- return "MAC"
- }
- if strings.EqualFold(t.TokenType, "basic") {
- return "Basic"
- }
- if t.TokenType != "" {
- return t.TokenType
- }
- return "Bearer"
-}
-
-// SetAuthHeader sets the Authorization header to r using the access
-// token in t.
-//
-// This method is unnecessary when using Transport or an HTTP Client
-// returned by this package.
-func (t *Token) SetAuthHeader(r *http.Request) {
- r.Header.Set("Authorization", t.Type()+" "+t.AccessToken)
-}
-
-// WithExtra returns a new Token that's a clone of t, but using the
-// provided raw extra map. This is only intended for use by packages
-// implementing derivative OAuth2 flows.
-func (t *Token) WithExtra(extra interface{}) *Token {
- t2 := new(Token)
- *t2 = *t
- t2.raw = extra
- return t2
-}
-
-// Extra returns an extra field.
-// Extra fields are key-value pairs returned by the server as a
-// part of the token retrieval response.
-func (t *Token) Extra(key string) interface{} {
- if vals, ok := t.raw.(url.Values); ok {
- // TODO(jbd): Cast numeric values to int64 or float64.
- return vals.Get(key)
- }
- if raw, ok := t.raw.(map[string]interface{}); ok {
- return raw[key]
- }
- return nil
-}
-
-// expired reports whether the token is expired.
-// t must be non-nil.
-func (t *Token) expired() bool {
- if t.Expiry.IsZero() {
- return false
- }
- return t.Expiry.Add(-expiryDelta).Before(time.Now())
-}
-
-// Valid reports whether t is non-nil, has an AccessToken, and is not expired.
-func (t *Token) Valid() bool {
- return t != nil && t.AccessToken != "" && !t.expired()
-}
-
-// tokenFromInternal maps an *internal.Token struct into
-// a *Token struct.
-func tokenFromInternal(t *internal.Token) *Token {
- if t == nil {
- return nil
- }
- return &Token{
- AccessToken: t.AccessToken,
- TokenType: t.TokenType,
- RefreshToken: t.RefreshToken,
- Expiry: t.Expiry,
- raw: t.Raw,
- }
-}
-
-// retrieveToken takes a *Config and uses that to retrieve an *internal.Token.
-// This token is then mapped from *internal.Token into an *oauth2.Token which is returned along
-// with an error..
-func retrieveToken(ctx context.Context, c *Config, v url.Values) (*Token, error) {
- tk, err := internal.RetrieveToken(ctx, c.ClientID, c.ClientSecret, c.Endpoint.TokenURL, v)
- if err != nil {
- return nil, err
- }
- return tokenFromInternal(tk), nil
-}
diff --git a/vendor/golang.org/x/oauth2/token_test.go b/vendor/golang.org/x/oauth2/token_test.go
deleted file mode 100644
index 739eeb2a..00000000
--- a/vendor/golang.org/x/oauth2/token_test.go
+++ /dev/null
@@ -1,50 +0,0 @@
-// Copyright 2014 The oauth2 Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style
-// license that can be found in the LICENSE file.
-
-package oauth2
-
-import (
- "testing"
- "time"
-)
-
-func TestTokenExtra(t *testing.T) {
- type testCase struct {
- key string
- val interface{}
- want interface{}
- }
- const key = "extra-key"
- cases := []testCase{
- {key: key, val: "abc", want: "abc"},
- {key: key, val: 123, want: 123},
- {key: key, val: "", want: ""},
- {key: "other-key", val: "def", want: nil},
- }
- for _, tc := range cases {
- extra := make(map[string]interface{})
- extra[tc.key] = tc.val
- tok := &Token{raw: extra}
- if got, want := tok.Extra(key), tc.want; got != want {
- t.Errorf("Extra(%q) = %q; want %q", key, got, want)
- }
- }
-}
-
-func TestTokenExpiry(t *testing.T) {
- now := time.Now()
- cases := []struct {
- name string
- tok *Token
- want bool
- }{
- {name: "12 seconds", tok: &Token{Expiry: now.Add(12 * time.Second)}, want: false},
- {name: "10 seconds", tok: &Token{Expiry: now.Add(expiryDelta)}, want: true},
- }
- for _, tc := range cases {
- if got, want := tc.tok.expired(), tc.want; got != want {
- t.Errorf("expired (%q) = %v; want %v", tc.name, got, want)
- }
- }
-}
diff --git a/vendor/golang.org/x/oauth2/transport.go b/vendor/golang.org/x/oauth2/transport.go
deleted file mode 100644
index 90db0883..00000000
--- a/vendor/golang.org/x/oauth2/transport.go
+++ /dev/null
@@ -1,132 +0,0 @@
-// Copyright 2014 The oauth2 Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style
-// license that can be found in the LICENSE file.
-
-package oauth2
-
-import (
- "errors"
- "io"
- "net/http"
- "sync"
-)
-
-// Transport is an http.RoundTripper that makes OAuth 2.0 HTTP requests,
-// wrapping a base RoundTripper and adding an Authorization header
-// with a token from the supplied Sources.
-//
-// Transport is a low-level mechanism. Most code will use the
-// higher-level Config.Client method instead.
-type Transport struct {
- // Source supplies the token to add to outgoing requests'
- // Authorization headers.
- Source TokenSource
-
- // Base is the base RoundTripper used to make HTTP requests.
- // If nil, http.DefaultTransport is used.
- Base http.RoundTripper
-
- mu sync.Mutex // guards modReq
- modReq map[*http.Request]*http.Request // original -> modified
-}
-
-// RoundTrip authorizes and authenticates the request with an
-// access token. If no token exists or token is expired,
-// tries to refresh/fetch a new token.
-func (t *Transport) RoundTrip(req *http.Request) (*http.Response, error) {
- if t.Source == nil {
- return nil, errors.New("oauth2: Transport's Source is nil")
- }
- token, err := t.Source.Token()
- if err != nil {
- return nil, err
- }
-
- req2 := cloneRequest(req) // per RoundTripper contract
- token.SetAuthHeader(req2)
- t.setModReq(req, req2)
- res, err := t.base().RoundTrip(req2)
- if err != nil {
- t.setModReq(req, nil)
- return nil, err
- }
- res.Body = &onEOFReader{
- rc: res.Body,
- fn: func() { t.setModReq(req, nil) },
- }
- return res, nil
-}
-
-// CancelRequest cancels an in-flight request by closing its connection.
-func (t *Transport) CancelRequest(req *http.Request) {
- type canceler interface {
- CancelRequest(*http.Request)
- }
- if cr, ok := t.base().(canceler); ok {
- t.mu.Lock()
- modReq := t.modReq[req]
- delete(t.modReq, req)
- t.mu.Unlock()
- cr.CancelRequest(modReq)
- }
-}
-
-func (t *Transport) base() http.RoundTripper {
- if t.Base != nil {
- return t.Base
- }
- return http.DefaultTransport
-}
-
-func (t *Transport) setModReq(orig, mod *http.Request) {
- t.mu.Lock()
- defer t.mu.Unlock()
- if t.modReq == nil {
- t.modReq = make(map[*http.Request]*http.Request)
- }
- if mod == nil {
- delete(t.modReq, orig)
- } else {
- t.modReq[orig] = mod
- }
-}
-
-// cloneRequest returns a clone of the provided *http.Request.
-// The clone is a shallow copy of the struct and its Header map.
-func cloneRequest(r *http.Request) *http.Request {
- // shallow copy of the struct
- r2 := new(http.Request)
- *r2 = *r
- // deep copy of the Header
- r2.Header = make(http.Header, len(r.Header))
- for k, s := range r.Header {
- r2.Header[k] = append([]string(nil), s...)
- }
- return r2
-}
-
-type onEOFReader struct {
- rc io.ReadCloser
- fn func()
-}
-
-func (r *onEOFReader) Read(p []byte) (n int, err error) {
- n, err = r.rc.Read(p)
- if err == io.EOF {
- r.runFunc()
- }
- return
-}
-
-func (r *onEOFReader) Close() error {
- err := r.rc.Close()
- r.runFunc()
- return err
-}
-
-func (r *onEOFReader) runFunc() {
- if fn := r.fn; fn != nil {
- fn()
- r.fn = nil
- }
-}
diff --git a/vendor/golang.org/x/oauth2/transport_test.go b/vendor/golang.org/x/oauth2/transport_test.go
deleted file mode 100644
index 35cb25ed..00000000
--- a/vendor/golang.org/x/oauth2/transport_test.go
+++ /dev/null
@@ -1,86 +0,0 @@
-package oauth2
-
-import (
- "net/http"
- "net/http/httptest"
- "testing"
- "time"
-)
-
-type tokenSource struct{ token *Token }
-
-func (t *tokenSource) Token() (*Token, error) {
- return t.token, nil
-}
-
-func TestTransportTokenSource(t *testing.T) {
- ts := &tokenSource{
- token: &Token{
- AccessToken: "abc",
- },
- }
- tr := &Transport{
- Source: ts,
- }
- server := newMockServer(func(w http.ResponseWriter, r *http.Request) {
- if r.Header.Get("Authorization") != "Bearer abc" {
- t.Errorf("Transport doesn't set the Authorization header from the fetched token")
- }
- })
- defer server.Close()
- client := http.Client{Transport: tr}
- client.Get(server.URL)
-}
-
-// Test for case-sensitive token types, per https://github.com/golang/oauth2/issues/113
-func TestTransportTokenSourceTypes(t *testing.T) {
- const val = "abc"
- tests := []struct {
- key string
- val string
- want string
- }{
- {key: "bearer", val: val, want: "Bearer abc"},
- {key: "mac", val: val, want: "MAC abc"},
- {key: "basic", val: val, want: "Basic abc"},
- }
- for _, tc := range tests {
- ts := &tokenSource{
- token: &Token{
- AccessToken: tc.val,
- TokenType: tc.key,
- },
- }
- tr := &Transport{
- Source: ts,
- }
- server := newMockServer(func(w http.ResponseWriter, r *http.Request) {
- if got, want := r.Header.Get("Authorization"), tc.want; got != want {
- t.Errorf("Authorization header (%q) = %q; want %q", val, got, want)
- }
- })
- defer server.Close()
- client := http.Client{Transport: tr}
- client.Get(server.URL)
- }
-}
-
-func TestTokenValidNoAccessToken(t *testing.T) {
- token := &Token{}
- if token.Valid() {
- t.Errorf("Token should not be valid with no access token")
- }
-}
-
-func TestExpiredWithExpiry(t *testing.T) {
- token := &Token{
- Expiry: time.Now().Add(-5 * time.Hour),
- }
- if token.Valid() {
- t.Errorf("Token should not be valid if it expired in the past")
- }
-}
-
-func newMockServer(handler func(w http.ResponseWriter, r *http.Request)) *httptest.Server {
- return httptest.NewServer(http.HandlerFunc(handler))
-}
diff --git a/vendor/golang.org/x/oauth2/vk/vk.go b/vendor/golang.org/x/oauth2/vk/vk.go
deleted file mode 100644
index 00e92935..00000000
--- a/vendor/golang.org/x/oauth2/vk/vk.go
+++ /dev/null
@@ -1,16 +0,0 @@
-// Copyright 2015 The oauth2 Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style
-// license that can be found in the LICENSE file.
-
-// Package vk provides constants for using OAuth2 to access VK.com.
-package vk
-
-import (
- "golang.org/x/oauth2"
-)
-
-// Endpoint is VK's OAuth 2.0 endpoint.
-var Endpoint = oauth2.Endpoint{
- AuthURL: "https://oauth.vk.com/authorize",
- TokenURL: "https://oauth.vk.com/access_token",
-}
diff --git a/vendor/google.golang.org/cloud/compute/metadata/metadata.go b/vendor/google.golang.org/cloud/compute/metadata/metadata.go
deleted file mode 100644
index cb27b97e..00000000
--- a/vendor/google.golang.org/cloud/compute/metadata/metadata.go
+++ /dev/null
@@ -1,344 +0,0 @@
-// Copyright 2014 Google Inc. All Rights Reserved.
-//
-// Licensed under the Apache License, Version 2.0 (the "License");
-// you may not use this file except in compliance with the License.
-// You may obtain a copy of the License at
-//
-// http://www.apache.org/licenses/LICENSE-2.0
-//
-// Unless required by applicable law or agreed to in writing, software
-// distributed under the License is distributed on an "AS IS" BASIS,
-// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-// See the License for the specific language governing permissions and
-// limitations under the License.
-
-// Package metadata provides access to Google Compute Engine (GCE)
-// metadata and API service accounts.
-//
-// This package is a wrapper around the GCE metadata service,
-// as documented at https://developers.google.com/compute/docs/metadata.
-package metadata
-
-import (
- "encoding/json"
- "fmt"
- "io/ioutil"
- "net"
- "net/http"
- "net/url"
- "os"
- "strings"
- "sync"
- "time"
-
- "google.golang.org/cloud/internal"
-)
-
-type cachedValue struct {
- k string
- trim bool
- mu sync.Mutex
- v string
-}
-
-var (
- projID = &cachedValue{k: "project/project-id", trim: true}
- projNum = &cachedValue{k: "project/numeric-project-id", trim: true}
- instID = &cachedValue{k: "instance/id", trim: true}
-)
-
-var (
- metaClient = &http.Client{
- Transport: &internal.Transport{
- Base: &http.Transport{
- Dial: (&net.Dialer{
- Timeout: 750 * time.Millisecond,
- KeepAlive: 30 * time.Second,
- }).Dial,
- ResponseHeaderTimeout: 750 * time.Millisecond,
- },
- },
- }
- subscribeClient = &http.Client{
- Transport: &internal.Transport{
- Base: &http.Transport{
- Dial: (&net.Dialer{
- Timeout: 750 * time.Millisecond,
- KeepAlive: 30 * time.Second,
- }).Dial,
- },
- },
- }
-)
-
-// NotDefinedError is returned when requested metadata is not defined.
-//
-// The underlying string is the suffix after "/computeMetadata/v1/".
-//
-// This error is not returned if the value is defined to be the empty
-// string.
-type NotDefinedError string
-
-func (suffix NotDefinedError) Error() string {
- return fmt.Sprintf("metadata: GCE metadata %q not defined", string(suffix))
-}
-
-// Get returns a value from the metadata service.
-// The suffix is appended to "http://${GCE_METADATA_HOST}/computeMetadata/v1/".
-//
-// If the GCE_METADATA_HOST environment variable is not defined, a default of
-// 169.254.169.254 will be used instead.
-//
-// If the requested metadata is not defined, the returned error will
-// be of type NotDefinedError.
-func Get(suffix string) (string, error) {
- val, _, err := getETag(metaClient, suffix)
- return val, err
-}
-
-// getETag returns a value from the metadata service as well as the associated
-// ETag using the provided client. This func is otherwise equivalent to Get.
-func getETag(client *http.Client, suffix string) (value, etag string, err error) {
- // Using a fixed IP makes it very difficult to spoof the metadata service in
- // a container, which is an important use-case for local testing of cloud
- // deployments. To enable spoofing of the metadata service, the environment
- // variable GCE_METADATA_HOST is first inspected to decide where metadata
- // requests shall go.
- host := os.Getenv("GCE_METADATA_HOST")
- if host == "" {
- // Using 169.254.169.254 instead of "metadata" here because Go
- // binaries built with the "netgo" tag and without cgo won't
- // know the search suffix for "metadata" is
- // ".google.internal", and this IP address is documented as
- // being stable anyway.
- host = "169.254.169.254"
- }
- url := "http://" + host + "/computeMetadata/v1/" + suffix
- req, _ := http.NewRequest("GET", url, nil)
- req.Header.Set("Metadata-Flavor", "Google")
- res, err := client.Do(req)
- if err != nil {
- return "", "", err
- }
- defer res.Body.Close()
- if res.StatusCode == http.StatusNotFound {
- return "", "", NotDefinedError(suffix)
- }
- if res.StatusCode != 200 {
- return "", "", fmt.Errorf("status code %d trying to fetch %s", res.StatusCode, url)
- }
- all, err := ioutil.ReadAll(res.Body)
- if err != nil {
- return "", "", err
- }
- return string(all), res.Header.Get("Etag"), nil
-}
-
-func getTrimmed(suffix string) (s string, err error) {
- s, err = Get(suffix)
- s = strings.TrimSpace(s)
- return
-}
-
-func (c *cachedValue) get() (v string, err error) {
- defer c.mu.Unlock()
- c.mu.Lock()
- if c.v != "" {
- return c.v, nil
- }
- if c.trim {
- v, err = getTrimmed(c.k)
- } else {
- v, err = Get(c.k)
- }
- if err == nil {
- c.v = v
- }
- return
-}
-
-var onGCE struct {
- sync.Mutex
- set bool
- v bool
-}
-
-// OnGCE reports whether this process is running on Google Compute Engine.
-func OnGCE() bool {
- defer onGCE.Unlock()
- onGCE.Lock()
- if onGCE.set {
- return onGCE.v
- }
- onGCE.set = true
-
- // We use the DNS name of the metadata service here instead of the IP address
- // because we expect that to fail faster in the not-on-GCE case.
- res, err := metaClient.Get("http://metadata.google.internal")
- if err != nil {
- return false
- }
- onGCE.v = res.Header.Get("Metadata-Flavor") == "Google"
- return onGCE.v
-}
-
-// Subscribe subscribes to a value from the metadata service.
-// The suffix is appended to "http://${GCE_METADATA_HOST}/computeMetadata/v1/".
-// The suffix may contain query parameters.
-//
-// Subscribe calls fn with the latest metadata value indicated by the provided
-// suffix. If the metadata value is deleted, fn is called with the empty string
-// and ok false. Subscribe blocks until fn returns a non-nil error or the value
-// is deleted. Subscribe returns the error value returned from the last call to
-// fn, which may be nil when ok == false.
-func Subscribe(suffix string, fn func(v string, ok bool) error) error {
- const failedSubscribeSleep = time.Second * 5
-
- // First check to see if the metadata value exists at all.
- val, lastETag, err := getETag(subscribeClient, suffix)
- if err != nil {
- return err
- }
-
- if err := fn(val, true); err != nil {
- return err
- }
-
- ok := true
- if strings.ContainsRune(suffix, '?') {
- suffix += "&wait_for_change=true&last_etag="
- } else {
- suffix += "?wait_for_change=true&last_etag="
- }
- for {
- val, etag, err := getETag(subscribeClient, suffix+url.QueryEscape(lastETag))
- if err != nil {
- if _, deleted := err.(NotDefinedError); !deleted {
- time.Sleep(failedSubscribeSleep)
- continue // Retry on other errors.
- }
- ok = false
- }
- lastETag = etag
-
- if err := fn(val, ok); err != nil || !ok {
- return err
- }
- }
-}
-
-// ProjectID returns the current instance's project ID string.
-func ProjectID() (string, error) { return projID.get() }
-
-// NumericProjectID returns the current instance's numeric project ID.
-func NumericProjectID() (string, error) { return projNum.get() }
-
-// InternalIP returns the instance's primary internal IP address.
-func InternalIP() (string, error) {
- return getTrimmed("instance/network-interfaces/0/ip")
-}
-
-// ExternalIP returns the instance's primary external (public) IP address.
-func ExternalIP() (string, error) {
- return getTrimmed("instance/network-interfaces/0/access-configs/0/external-ip")
-}
-
-// Hostname returns the instance's hostname. This will be of the form
-// ".c..internal".
-func Hostname() (string, error) {
- return getTrimmed("instance/hostname")
-}
-
-// InstanceTags returns the list of user-defined instance tags,
-// assigned when initially creating a GCE instance.
-func InstanceTags() ([]string, error) {
- var s []string
- j, err := Get("instance/tags")
- if err != nil {
- return nil, err
- }
- if err := json.NewDecoder(strings.NewReader(j)).Decode(&s); err != nil {
- return nil, err
- }
- return s, nil
-}
-
-// InstanceID returns the current VM's numeric instance ID.
-func InstanceID() (string, error) {
- return instID.get()
-}
-
-// InstanceName returns the current VM's instance ID string.
-func InstanceName() (string, error) {
- host, err := Hostname()
- if err != nil {
- return "", err
- }
- return strings.Split(host, ".")[0], nil
-}
-
-// Zone returns the current VM's zone, such as "us-central1-b".
-func Zone() (string, error) {
- zone, err := getTrimmed("instance/zone")
- // zone is of the form "projects//zones/".
- if err != nil {
- return "", err
- }
- return zone[strings.LastIndex(zone, "/")+1:], nil
-}
-
-// InstanceAttributes returns the list of user-defined attributes,
-// assigned when initially creating a GCE VM instance. The value of an
-// attribute can be obtained with InstanceAttributeValue.
-func InstanceAttributes() ([]string, error) { return lines("instance/attributes/") }
-
-// ProjectAttributes returns the list of user-defined attributes
-// applying to the project as a whole, not just this VM. The value of
-// an attribute can be obtained with ProjectAttributeValue.
-func ProjectAttributes() ([]string, error) { return lines("project/attributes/") }
-
-func lines(suffix string) ([]string, error) {
- j, err := Get(suffix)
- if err != nil {
- return nil, err
- }
- s := strings.Split(strings.TrimSpace(j), "\n")
- for i := range s {
- s[i] = strings.TrimSpace(s[i])
- }
- return s, nil
-}
-
-// InstanceAttributeValue returns the value of the provided VM
-// instance attribute.
-//
-// If the requested attribute is not defined, the returned error will
-// be of type NotDefinedError.
-//
-// InstanceAttributeValue may return ("", nil) if the attribute was
-// defined to be the empty string.
-func InstanceAttributeValue(attr string) (string, error) {
- return Get("instance/attributes/" + attr)
-}
-
-// ProjectAttributeValue returns the value of the provided
-// project attribute.
-//
-// If the requested attribute is not defined, the returned error will
-// be of type NotDefinedError.
-//
-// ProjectAttributeValue may return ("", nil) if the attribute was
-// defined to be the empty string.
-func ProjectAttributeValue(attr string) (string, error) {
- return Get("project/attributes/" + attr)
-}
-
-// Scopes returns the service account scopes for the given account.
-// The account may be empty or the string "default" to use the instance's
-// main account.
-func Scopes(serviceAccount string) ([]string, error) {
- if serviceAccount == "" {
- serviceAccount = "default"
- }
- return lines("instance/service-accounts/" + serviceAccount + "/scopes")
-}
diff --git a/vendor/google.golang.org/cloud/internal/cloud.go b/vendor/google.golang.org/cloud/internal/cloud.go
deleted file mode 100644
index 59428803..00000000
--- a/vendor/google.golang.org/cloud/internal/cloud.go
+++ /dev/null
@@ -1,128 +0,0 @@
-// Copyright 2014 Google Inc. All Rights Reserved.
-//
-// Licensed under the Apache License, Version 2.0 (the "License");
-// you may not use this file except in compliance with the License.
-// You may obtain a copy of the License at
-//
-// http://www.apache.org/licenses/LICENSE-2.0
-//
-// Unless required by applicable law or agreed to in writing, software
-// distributed under the License is distributed on an "AS IS" BASIS,
-// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-// See the License for the specific language governing permissions and
-// limitations under the License.
-
-// Package internal provides support for the cloud packages.
-//
-// Users should not import this package directly.
-package internal
-
-import (
- "fmt"
- "net/http"
- "sync"
-
- "golang.org/x/net/context"
-)
-
-type contextKey struct{}
-
-func WithContext(parent context.Context, projID string, c *http.Client) context.Context {
- if c == nil {
- panic("nil *http.Client passed to WithContext")
- }
- if projID == "" {
- panic("empty project ID passed to WithContext")
- }
- return context.WithValue(parent, contextKey{}, &cloudContext{
- ProjectID: projID,
- HTTPClient: c,
- })
-}
-
-const userAgent = "gcloud-golang/0.1"
-
-type cloudContext struct {
- ProjectID string
- HTTPClient *http.Client
-
- mu sync.Mutex // guards svc
- svc map[string]interface{} // e.g. "storage" => *rawStorage.Service
-}
-
-// Service returns the result of the fill function if it's never been
-// called before for the given name (which is assumed to be an API
-// service name, like "datastore"). If it has already been cached, the fill
-// func is not run.
-// It's safe for concurrent use by multiple goroutines.
-func Service(ctx context.Context, name string, fill func(*http.Client) interface{}) interface{} {
- return cc(ctx).service(name, fill)
-}
-
-func (c *cloudContext) service(name string, fill func(*http.Client) interface{}) interface{} {
- c.mu.Lock()
- defer c.mu.Unlock()
-
- if c.svc == nil {
- c.svc = make(map[string]interface{})
- } else if v, ok := c.svc[name]; ok {
- return v
- }
- v := fill(c.HTTPClient)
- c.svc[name] = v
- return v
-}
-
-// Transport is an http.RoundTripper that appends
-// Google Cloud client's user-agent to the original
-// request's user-agent header.
-type Transport struct {
- // Base is the actual http.RoundTripper
- // requests will use. It must not be nil.
- Base http.RoundTripper
-}
-
-// RoundTrip appends a user-agent to the existing user-agent
-// header and delegates the request to the base http.RoundTripper.
-func (t *Transport) RoundTrip(req *http.Request) (*http.Response, error) {
- req = cloneRequest(req)
- ua := req.Header.Get("User-Agent")
- if ua == "" {
- ua = userAgent
- } else {
- ua = fmt.Sprintf("%s %s", ua, userAgent)
- }
- req.Header.Set("User-Agent", ua)
- return t.Base.RoundTrip(req)
-}
-
-// cloneRequest returns a clone of the provided *http.Request.
-// The clone is a shallow copy of the struct and its Header map.
-func cloneRequest(r *http.Request) *http.Request {
- // shallow copy of the struct
- r2 := new(http.Request)
- *r2 = *r
- // deep copy of the Header
- r2.Header = make(http.Header)
- for k, s := range r.Header {
- r2.Header[k] = s
- }
- return r2
-}
-
-func ProjID(ctx context.Context) string {
- return cc(ctx).ProjectID
-}
-
-func HTTPClient(ctx context.Context) *http.Client {
- return cc(ctx).HTTPClient
-}
-
-// cc returns the internal *cloudContext (cc) state for a context.Context.
-// It panics if the user did it wrong.
-func cc(ctx context.Context) *cloudContext {
- if c, ok := ctx.Value(contextKey{}).(*cloudContext); ok {
- return c
- }
- panic("invalid context.Context type; it should be created with cloud.NewContext")
-}
diff --git a/vendor/google.golang.org/cloud/internal/datastore/datastore_v1.pb.go b/vendor/google.golang.org/cloud/internal/datastore/datastore_v1.pb.go
deleted file mode 100644
index 9cb9be52..00000000
--- a/vendor/google.golang.org/cloud/internal/datastore/datastore_v1.pb.go
+++ /dev/null
@@ -1,1633 +0,0 @@
-// Code generated by protoc-gen-go.
-// source: datastore_v1.proto
-// DO NOT EDIT!
-
-/*
-Package datastore is a generated protocol buffer package.
-
-It is generated from these files:
- datastore_v1.proto
-
-It has these top-level messages:
- PartitionId
- Key
- Value
- Property
- Entity
- EntityResult
- Query
- KindExpression
- PropertyReference
- PropertyExpression
- PropertyOrder
- Filter
- CompositeFilter
- PropertyFilter
- GqlQuery
- GqlQueryArg
- QueryResultBatch
- Mutation
- MutationResult
- ReadOptions
- LookupRequest
- LookupResponse
- RunQueryRequest
- RunQueryResponse
- BeginTransactionRequest
- BeginTransactionResponse
- RollbackRequest
- RollbackResponse
- CommitRequest
- CommitResponse
- AllocateIdsRequest
- AllocateIdsResponse
-*/
-package datastore
-
-import proto "github.com/golang/protobuf/proto"
-import math "math"
-
-// Reference imports to suppress errors if they are not otherwise used.
-var _ = proto.Marshal
-var _ = math.Inf
-
-// Specifies what data the 'entity' field contains.
-// A ResultType is either implied (for example, in LookupResponse.found it
-// is always FULL) or specified by context (for example, in message
-// QueryResultBatch, field 'entity_result_type' specifies a ResultType
-// for all the values in field 'entity_result').
-type EntityResult_ResultType int32
-
-const (
- EntityResult_FULL EntityResult_ResultType = 1
- EntityResult_PROJECTION EntityResult_ResultType = 2
- // The entity may have no key.
- // A property value may have meaning 18.
- EntityResult_KEY_ONLY EntityResult_ResultType = 3
-)
-
-var EntityResult_ResultType_name = map[int32]string{
- 1: "FULL",
- 2: "PROJECTION",
- 3: "KEY_ONLY",
-}
-var EntityResult_ResultType_value = map[string]int32{
- "FULL": 1,
- "PROJECTION": 2,
- "KEY_ONLY": 3,
-}
-
-func (x EntityResult_ResultType) Enum() *EntityResult_ResultType {
- p := new(EntityResult_ResultType)
- *p = x
- return p
-}
-func (x EntityResult_ResultType) String() string {
- return proto.EnumName(EntityResult_ResultType_name, int32(x))
-}
-func (x *EntityResult_ResultType) UnmarshalJSON(data []byte) error {
- value, err := proto.UnmarshalJSONEnum(EntityResult_ResultType_value, data, "EntityResult_ResultType")
- if err != nil {
- return err
- }
- *x = EntityResult_ResultType(value)
- return nil
-}
-
-type PropertyExpression_AggregationFunction int32
-
-const (
- PropertyExpression_FIRST PropertyExpression_AggregationFunction = 1
-)
-
-var PropertyExpression_AggregationFunction_name = map[int32]string{
- 1: "FIRST",
-}
-var PropertyExpression_AggregationFunction_value = map[string]int32{
- "FIRST": 1,
-}
-
-func (x PropertyExpression_AggregationFunction) Enum() *PropertyExpression_AggregationFunction {
- p := new(PropertyExpression_AggregationFunction)
- *p = x
- return p
-}
-func (x PropertyExpression_AggregationFunction) String() string {
- return proto.EnumName(PropertyExpression_AggregationFunction_name, int32(x))
-}
-func (x *PropertyExpression_AggregationFunction) UnmarshalJSON(data []byte) error {
- value, err := proto.UnmarshalJSONEnum(PropertyExpression_AggregationFunction_value, data, "PropertyExpression_AggregationFunction")
- if err != nil {
- return err
- }
- *x = PropertyExpression_AggregationFunction(value)
- return nil
-}
-
-type PropertyOrder_Direction int32
-
-const (
- PropertyOrder_ASCENDING PropertyOrder_Direction = 1
- PropertyOrder_DESCENDING PropertyOrder_Direction = 2
-)
-
-var PropertyOrder_Direction_name = map[int32]string{
- 1: "ASCENDING",
- 2: "DESCENDING",
-}
-var PropertyOrder_Direction_value = map[string]int32{
- "ASCENDING": 1,
- "DESCENDING": 2,
-}
-
-func (x PropertyOrder_Direction) Enum() *PropertyOrder_Direction {
- p := new(PropertyOrder_Direction)
- *p = x
- return p
-}
-func (x PropertyOrder_Direction) String() string {
- return proto.EnumName(PropertyOrder_Direction_name, int32(x))
-}
-func (x *PropertyOrder_Direction) UnmarshalJSON(data []byte) error {
- value, err := proto.UnmarshalJSONEnum(PropertyOrder_Direction_value, data, "PropertyOrder_Direction")
- if err != nil {
- return err
- }
- *x = PropertyOrder_Direction(value)
- return nil
-}
-
-type CompositeFilter_Operator int32
-
-const (
- CompositeFilter_AND CompositeFilter_Operator = 1
-)
-
-var CompositeFilter_Operator_name = map[int32]string{
- 1: "AND",
-}
-var CompositeFilter_Operator_value = map[string]int32{
- "AND": 1,
-}
-
-func (x CompositeFilter_Operator) Enum() *CompositeFilter_Operator {
- p := new(CompositeFilter_Operator)
- *p = x
- return p
-}
-func (x CompositeFilter_Operator) String() string {
- return proto.EnumName(CompositeFilter_Operator_name, int32(x))
-}
-func (x *CompositeFilter_Operator) UnmarshalJSON(data []byte) error {
- value, err := proto.UnmarshalJSONEnum(CompositeFilter_Operator_value, data, "CompositeFilter_Operator")
- if err != nil {
- return err
- }
- *x = CompositeFilter_Operator(value)
- return nil
-}
-
-type PropertyFilter_Operator int32
-
-const (
- PropertyFilter_LESS_THAN PropertyFilter_Operator = 1
- PropertyFilter_LESS_THAN_OR_EQUAL PropertyFilter_Operator = 2
- PropertyFilter_GREATER_THAN PropertyFilter_Operator = 3
- PropertyFilter_GREATER_THAN_OR_EQUAL PropertyFilter_Operator = 4
- PropertyFilter_EQUAL PropertyFilter_Operator = 5
- PropertyFilter_HAS_ANCESTOR PropertyFilter_Operator = 11
-)
-
-var PropertyFilter_Operator_name = map[int32]string{
- 1: "LESS_THAN",
- 2: "LESS_THAN_OR_EQUAL",
- 3: "GREATER_THAN",
- 4: "GREATER_THAN_OR_EQUAL",
- 5: "EQUAL",
- 11: "HAS_ANCESTOR",
-}
-var PropertyFilter_Operator_value = map[string]int32{
- "LESS_THAN": 1,
- "LESS_THAN_OR_EQUAL": 2,
- "GREATER_THAN": 3,
- "GREATER_THAN_OR_EQUAL": 4,
- "EQUAL": 5,
- "HAS_ANCESTOR": 11,
-}
-
-func (x PropertyFilter_Operator) Enum() *PropertyFilter_Operator {
- p := new(PropertyFilter_Operator)
- *p = x
- return p
-}
-func (x PropertyFilter_Operator) String() string {
- return proto.EnumName(PropertyFilter_Operator_name, int32(x))
-}
-func (x *PropertyFilter_Operator) UnmarshalJSON(data []byte) error {
- value, err := proto.UnmarshalJSONEnum(PropertyFilter_Operator_value, data, "PropertyFilter_Operator")
- if err != nil {
- return err
- }
- *x = PropertyFilter_Operator(value)
- return nil
-}
-
-// The possible values for the 'more_results' field.
-type QueryResultBatch_MoreResultsType int32
-
-const (
- QueryResultBatch_NOT_FINISHED QueryResultBatch_MoreResultsType = 1
- QueryResultBatch_MORE_RESULTS_AFTER_LIMIT QueryResultBatch_MoreResultsType = 2
- // results after the limit.
- QueryResultBatch_NO_MORE_RESULTS QueryResultBatch_MoreResultsType = 3
-)
-
-var QueryResultBatch_MoreResultsType_name = map[int32]string{
- 1: "NOT_FINISHED",
- 2: "MORE_RESULTS_AFTER_LIMIT",
- 3: "NO_MORE_RESULTS",
-}
-var QueryResultBatch_MoreResultsType_value = map[string]int32{
- "NOT_FINISHED": 1,
- "MORE_RESULTS_AFTER_LIMIT": 2,
- "NO_MORE_RESULTS": 3,
-}
-
-func (x QueryResultBatch_MoreResultsType) Enum() *QueryResultBatch_MoreResultsType {
- p := new(QueryResultBatch_MoreResultsType)
- *p = x
- return p
-}
-func (x QueryResultBatch_MoreResultsType) String() string {
- return proto.EnumName(QueryResultBatch_MoreResultsType_name, int32(x))
-}
-func (x *QueryResultBatch_MoreResultsType) UnmarshalJSON(data []byte) error {
- value, err := proto.UnmarshalJSONEnum(QueryResultBatch_MoreResultsType_value, data, "QueryResultBatch_MoreResultsType")
- if err != nil {
- return err
- }
- *x = QueryResultBatch_MoreResultsType(value)
- return nil
-}
-
-type ReadOptions_ReadConsistency int32
-
-const (
- ReadOptions_DEFAULT ReadOptions_ReadConsistency = 0
- ReadOptions_STRONG ReadOptions_ReadConsistency = 1
- ReadOptions_EVENTUAL ReadOptions_ReadConsistency = 2
-)
-
-var ReadOptions_ReadConsistency_name = map[int32]string{
- 0: "DEFAULT",
- 1: "STRONG",
- 2: "EVENTUAL",
-}
-var ReadOptions_ReadConsistency_value = map[string]int32{
- "DEFAULT": 0,
- "STRONG": 1,
- "EVENTUAL": 2,
-}
-
-func (x ReadOptions_ReadConsistency) Enum() *ReadOptions_ReadConsistency {
- p := new(ReadOptions_ReadConsistency)
- *p = x
- return p
-}
-func (x ReadOptions_ReadConsistency) String() string {
- return proto.EnumName(ReadOptions_ReadConsistency_name, int32(x))
-}
-func (x *ReadOptions_ReadConsistency) UnmarshalJSON(data []byte) error {
- value, err := proto.UnmarshalJSONEnum(ReadOptions_ReadConsistency_value, data, "ReadOptions_ReadConsistency")
- if err != nil {
- return err
- }
- *x = ReadOptions_ReadConsistency(value)
- return nil
-}
-
-type BeginTransactionRequest_IsolationLevel int32
-
-const (
- BeginTransactionRequest_SNAPSHOT BeginTransactionRequest_IsolationLevel = 0
- // conflict if their mutations conflict. For example:
- // Read(A),Write(B) may not conflict with Read(B),Write(A),
- // but Read(B),Write(B) does conflict with Read(B),Write(B).
- BeginTransactionRequest_SERIALIZABLE BeginTransactionRequest_IsolationLevel = 1
-)
-
-var BeginTransactionRequest_IsolationLevel_name = map[int32]string{
- 0: "SNAPSHOT",
- 1: "SERIALIZABLE",
-}
-var BeginTransactionRequest_IsolationLevel_value = map[string]int32{
- "SNAPSHOT": 0,
- "SERIALIZABLE": 1,
-}
-
-func (x BeginTransactionRequest_IsolationLevel) Enum() *BeginTransactionRequest_IsolationLevel {
- p := new(BeginTransactionRequest_IsolationLevel)
- *p = x
- return p
-}
-func (x BeginTransactionRequest_IsolationLevel) String() string {
- return proto.EnumName(BeginTransactionRequest_IsolationLevel_name, int32(x))
-}
-func (x *BeginTransactionRequest_IsolationLevel) UnmarshalJSON(data []byte) error {
- value, err := proto.UnmarshalJSONEnum(BeginTransactionRequest_IsolationLevel_value, data, "BeginTransactionRequest_IsolationLevel")
- if err != nil {
- return err
- }
- *x = BeginTransactionRequest_IsolationLevel(value)
- return nil
-}
-
-type CommitRequest_Mode int32
-
-const (
- CommitRequest_TRANSACTIONAL CommitRequest_Mode = 1
- CommitRequest_NON_TRANSACTIONAL CommitRequest_Mode = 2
-)
-
-var CommitRequest_Mode_name = map[int32]string{
- 1: "TRANSACTIONAL",
- 2: "NON_TRANSACTIONAL",
-}
-var CommitRequest_Mode_value = map[string]int32{
- "TRANSACTIONAL": 1,
- "NON_TRANSACTIONAL": 2,
-}
-
-func (x CommitRequest_Mode) Enum() *CommitRequest_Mode {
- p := new(CommitRequest_Mode)
- *p = x
- return p
-}
-func (x CommitRequest_Mode) String() string {
- return proto.EnumName(CommitRequest_Mode_name, int32(x))
-}
-func (x *CommitRequest_Mode) UnmarshalJSON(data []byte) error {
- value, err := proto.UnmarshalJSONEnum(CommitRequest_Mode_value, data, "CommitRequest_Mode")
- if err != nil {
- return err
- }
- *x = CommitRequest_Mode(value)
- return nil
-}
-
-// An identifier for a particular subset of entities.
-//
-// Entities are partitioned into various subsets, each used by different
-// datasets and different namespaces within a dataset and so forth.
-//
-// All input partition IDs are normalized before use.
-// A partition ID is normalized as follows:
-// If the partition ID is unset or is set to an empty partition ID, replace it
-// with the context partition ID.
-// Otherwise, if the partition ID has no dataset ID, assign it the context
-// partition ID's dataset ID.
-// Unless otherwise documented, the context partition ID has the dataset ID set
-// to the context dataset ID and no other partition dimension set.
-//
-// A partition ID is empty if all of its fields are unset.
-//
-// Partition dimension:
-// A dimension may be unset.
-// A dimension's value must never be "".
-// A dimension's value must match [A-Za-z\d\.\-_]{1,100}
-// If the value of any dimension matches regex "__.*__",
-// the partition is reserved/read-only.
-// A reserved/read-only partition ID is forbidden in certain documented contexts.
-//
-// Dataset ID:
-// A dataset id's value must never be "".
-// A dataset id's value must match
-// ([a-z\d\-]{1,100}~)?([a-z\d][a-z\d\-\.]{0,99}:)?([a-z\d][a-z\d\-]{0,99}
-type PartitionId struct {
- // The dataset ID.
- DatasetId *string `protobuf:"bytes,3,opt,name=dataset_id" json:"dataset_id,omitempty"`
- // The namespace.
- Namespace *string `protobuf:"bytes,4,opt,name=namespace" json:"namespace,omitempty"`
- XXX_unrecognized []byte `json:"-"`
-}
-
-func (m *PartitionId) Reset() { *m = PartitionId{} }
-func (m *PartitionId) String() string { return proto.CompactTextString(m) }
-func (*PartitionId) ProtoMessage() {}
-
-func (m *PartitionId) GetDatasetId() string {
- if m != nil && m.DatasetId != nil {
- return *m.DatasetId
- }
- return ""
-}
-
-func (m *PartitionId) GetNamespace() string {
- if m != nil && m.Namespace != nil {
- return *m.Namespace
- }
- return ""
-}
-
-// A unique identifier for an entity.
-// If a key's partition id or any of its path kinds or names are
-// reserved/read-only, the key is reserved/read-only.
-// A reserved/read-only key is forbidden in certain documented contexts.
-type Key struct {
- // Entities are partitioned into subsets, currently identified by a dataset
- // (usually implicitly specified by the project) and namespace ID.
- // Queries are scoped to a single partition.
- PartitionId *PartitionId `protobuf:"bytes,1,opt,name=partition_id" json:"partition_id,omitempty"`
- // The entity path.
- // An entity path consists of one or more elements composed of a kind and a
- // string or numerical identifier, which identify entities. The first
- // element identifies a root entity, the second element identifies
- // a child of the root entity, the third element a child of the
- // second entity, and so forth. The entities identified by all prefixes of
- // the path are called the element's ancestors.
- // An entity path is always fully complete: ALL of the entity's ancestors
- // are required to be in the path along with the entity identifier itself.
- // The only exception is that in some documented cases, the identifier in the
- // last path element (for the entity) itself may be omitted. A path can never
- // be empty.
- PathElement []*Key_PathElement `protobuf:"bytes,2,rep,name=path_element" json:"path_element,omitempty"`
- XXX_unrecognized []byte `json:"-"`
-}
-
-func (m *Key) Reset() { *m = Key{} }
-func (m *Key) String() string { return proto.CompactTextString(m) }
-func (*Key) ProtoMessage() {}
-
-func (m *Key) GetPartitionId() *PartitionId {
- if m != nil {
- return m.PartitionId
- }
- return nil
-}
-
-func (m *Key) GetPathElement() []*Key_PathElement {
- if m != nil {
- return m.PathElement
- }
- return nil
-}
-
-// A (kind, ID/name) pair used to construct a key path.
-//
-// At most one of name or ID may be set.
-// If either is set, the element is complete.
-// If neither is set, the element is incomplete.
-type Key_PathElement struct {
- // The kind of the entity.
- // A kind matching regex "__.*__" is reserved/read-only.
- // A kind must not contain more than 500 characters.
- // Cannot be "".
- Kind *string `protobuf:"bytes,1,req,name=kind" json:"kind,omitempty"`
- // The ID of the entity.
- // Never equal to zero. Values less than zero are discouraged and will not
- // be supported in the future.
- Id *int64 `protobuf:"varint,2,opt,name=id" json:"id,omitempty"`
- // The name of the entity.
- // A name matching regex "__.*__" is reserved/read-only.
- // A name must not be more than 500 characters.
- // Cannot be "".
- Name *string `protobuf:"bytes,3,opt,name=name" json:"name,omitempty"`
- XXX_unrecognized []byte `json:"-"`
-}
-
-func (m *Key_PathElement) Reset() { *m = Key_PathElement{} }
-func (m *Key_PathElement) String() string { return proto.CompactTextString(m) }
-func (*Key_PathElement) ProtoMessage() {}
-
-func (m *Key_PathElement) GetKind() string {
- if m != nil && m.Kind != nil {
- return *m.Kind
- }
- return ""
-}
-
-func (m *Key_PathElement) GetId() int64 {
- if m != nil && m.Id != nil {
- return *m.Id
- }
- return 0
-}
-
-func (m *Key_PathElement) GetName() string {
- if m != nil && m.Name != nil {
- return *m.Name
- }
- return ""
-}
-
-// A message that can hold any of the supported value types and associated
-// metadata.
-//
-// At most one of the Value fields may be set.
-// If none are set the value is "null".
-//
-type Value struct {
- // A boolean value.
- BooleanValue *bool `protobuf:"varint,1,opt,name=boolean_value" json:"boolean_value,omitempty"`
- // An integer value.
- IntegerValue *int64 `protobuf:"varint,2,opt,name=integer_value" json:"integer_value,omitempty"`
- // A double value.
- DoubleValue *float64 `protobuf:"fixed64,3,opt,name=double_value" json:"double_value,omitempty"`
- // A timestamp value.
- TimestampMicrosecondsValue *int64 `protobuf:"varint,4,opt,name=timestamp_microseconds_value" json:"timestamp_microseconds_value,omitempty"`
- // A key value.
- KeyValue *Key `protobuf:"bytes,5,opt,name=key_value" json:"key_value,omitempty"`
- // A blob key value.
- BlobKeyValue *string `protobuf:"bytes,16,opt,name=blob_key_value" json:"blob_key_value,omitempty"`
- // A UTF-8 encoded string value.
- StringValue *string `protobuf:"bytes,17,opt,name=string_value" json:"string_value,omitempty"`
- // A blob value.
- BlobValue []byte `protobuf:"bytes,18,opt,name=blob_value" json:"blob_value,omitempty"`
- // An entity value.
- // May have no key.
- // May have a key with an incomplete key path.
- // May have a reserved/read-only key.
- EntityValue *Entity `protobuf:"bytes,6,opt,name=entity_value" json:"entity_value,omitempty"`
- // A list value.
- // Cannot contain another list value.
- // Cannot also have a meaning and indexing set.
- ListValue []*Value `protobuf:"bytes,7,rep,name=list_value" json:"list_value,omitempty"`
- // The meaning field is reserved and should not be used.
- Meaning *int32 `protobuf:"varint,14,opt,name=meaning" json:"meaning,omitempty"`
- // If the value should be indexed.
- //
- // The indexed property may be set for a
- // null value.
- // When indexed is true, stringValue
- // is limited to 500 characters and the blob value is limited to 500 bytes.
- // Exception: If meaning is set to 2, string_value is limited to 2038
- // characters regardless of indexed.
- // When indexed is true, meaning 15 and 22 are not allowed, and meaning 16
- // will be ignored on input (and will never be set on output).
- // Input values by default have indexed set to
- // true; however, you can explicitly set indexed to
- // true if you want. (An output value never has
- // indexed explicitly set to true.) If a value is
- // itself an entity, it cannot have indexed set to
- // true.
- // Exception: An entity value with meaning 9, 20 or 21 may be indexed.
- Indexed *bool `protobuf:"varint,15,opt,name=indexed,def=1" json:"indexed,omitempty"`
- XXX_unrecognized []byte `json:"-"`
-}
-
-func (m *Value) Reset() { *m = Value{} }
-func (m *Value) String() string { return proto.CompactTextString(m) }
-func (*Value) ProtoMessage() {}
-
-const Default_Value_Indexed bool = true
-
-func (m *Value) GetBooleanValue() bool {
- if m != nil && m.BooleanValue != nil {
- return *m.BooleanValue
- }
- return false
-}
-
-func (m *Value) GetIntegerValue() int64 {
- if m != nil && m.IntegerValue != nil {
- return *m.IntegerValue
- }
- return 0
-}
-
-func (m *Value) GetDoubleValue() float64 {
- if m != nil && m.DoubleValue != nil {
- return *m.DoubleValue
- }
- return 0
-}
-
-func (m *Value) GetTimestampMicrosecondsValue() int64 {
- if m != nil && m.TimestampMicrosecondsValue != nil {
- return *m.TimestampMicrosecondsValue
- }
- return 0
-}
-
-func (m *Value) GetKeyValue() *Key {
- if m != nil {
- return m.KeyValue
- }
- return nil
-}
-
-func (m *Value) GetBlobKeyValue() string {
- if m != nil && m.BlobKeyValue != nil {
- return *m.BlobKeyValue
- }
- return ""
-}
-
-func (m *Value) GetStringValue() string {
- if m != nil && m.StringValue != nil {
- return *m.StringValue
- }
- return ""
-}
-
-func (m *Value) GetBlobValue() []byte {
- if m != nil {
- return m.BlobValue
- }
- return nil
-}
-
-func (m *Value) GetEntityValue() *Entity {
- if m != nil {
- return m.EntityValue
- }
- return nil
-}
-
-func (m *Value) GetListValue() []*Value {
- if m != nil {
- return m.ListValue
- }
- return nil
-}
-
-func (m *Value) GetMeaning() int32 {
- if m != nil && m.Meaning != nil {
- return *m.Meaning
- }
- return 0
-}
-
-func (m *Value) GetIndexed() bool {
- if m != nil && m.Indexed != nil {
- return *m.Indexed
- }
- return Default_Value_Indexed
-}
-
-// An entity property.
-type Property struct {
- // The name of the property.
- // A property name matching regex "__.*__" is reserved.
- // A reserved property name is forbidden in certain documented contexts.
- // The name must not contain more than 500 characters.
- // Cannot be "".
- Name *string `protobuf:"bytes,1,req,name=name" json:"name,omitempty"`
- // The value(s) of the property.
- // Each value can have only one value property populated. For example,
- // you cannot have a values list of { value: { integerValue: 22,
- // stringValue: "a" } }, but you can have { value: { listValue:
- // [ { integerValue: 22 }, { stringValue: "a" } ] }.
- Value *Value `protobuf:"bytes,4,req,name=value" json:"value,omitempty"`
- XXX_unrecognized []byte `json:"-"`
-}
-
-func (m *Property) Reset() { *m = Property{} }
-func (m *Property) String() string { return proto.CompactTextString(m) }
-func (*Property) ProtoMessage() {}
-
-func (m *Property) GetName() string {
- if m != nil && m.Name != nil {
- return *m.Name
- }
- return ""
-}
-
-func (m *Property) GetValue() *Value {
- if m != nil {
- return m.Value
- }
- return nil
-}
-
-// An entity.
-//
-// An entity is limited to 1 megabyte when stored. That roughly
-// corresponds to a limit of 1 megabyte for the serialized form of this
-// message.
-type Entity struct {
- // The entity's key.
- //
- // An entity must have a key, unless otherwise documented (for example,
- // an entity in Value.entityValue may have no key).
- // An entity's kind is its key's path's last element's kind,
- // or null if it has no key.
- Key *Key `protobuf:"bytes,1,opt,name=key" json:"key,omitempty"`
- // The entity's properties.
- // Each property's name must be unique for its entity.
- Property []*Property `protobuf:"bytes,2,rep,name=property" json:"property,omitempty"`
- XXX_unrecognized []byte `json:"-"`
-}
-
-func (m *Entity) Reset() { *m = Entity{} }
-func (m *Entity) String() string { return proto.CompactTextString(m) }
-func (*Entity) ProtoMessage() {}
-
-func (m *Entity) GetKey() *Key {
- if m != nil {
- return m.Key
- }
- return nil
-}
-
-func (m *Entity) GetProperty() []*Property {
- if m != nil {
- return m.Property
- }
- return nil
-}
-
-// The result of fetching an entity from the datastore.
-type EntityResult struct {
- // The resulting entity.
- Entity *Entity `protobuf:"bytes,1,req,name=entity" json:"entity,omitempty"`
- XXX_unrecognized []byte `json:"-"`
-}
-
-func (m *EntityResult) Reset() { *m = EntityResult{} }
-func (m *EntityResult) String() string { return proto.CompactTextString(m) }
-func (*EntityResult) ProtoMessage() {}
-
-func (m *EntityResult) GetEntity() *Entity {
- if m != nil {
- return m.Entity
- }
- return nil
-}
-
-// A query.
-type Query struct {
- // The projection to return. If not set the entire entity is returned.
- Projection []*PropertyExpression `protobuf:"bytes,2,rep,name=projection" json:"projection,omitempty"`
- // The kinds to query (if empty, returns entities from all kinds).
- Kind []*KindExpression `protobuf:"bytes,3,rep,name=kind" json:"kind,omitempty"`
- // The filter to apply (optional).
- Filter *Filter `protobuf:"bytes,4,opt,name=filter" json:"filter,omitempty"`
- // The order to apply to the query results (if empty, order is unspecified).
- Order []*PropertyOrder `protobuf:"bytes,5,rep,name=order" json:"order,omitempty"`
- // The properties to group by (if empty, no grouping is applied to the
- // result set).
- GroupBy []*PropertyReference `protobuf:"bytes,6,rep,name=group_by" json:"group_by,omitempty"`
- // A starting point for the query results. Optional. Query cursors are
- // returned in query result batches.
- StartCursor []byte `protobuf:"bytes,7,opt,name=start_cursor" json:"start_cursor,omitempty"`
- // An ending point for the query results. Optional. Query cursors are
- // returned in query result batches.
- EndCursor []byte `protobuf:"bytes,8,opt,name=end_cursor" json:"end_cursor,omitempty"`
- // The number of results to skip. Applies before limit, but after all other
- // constraints (optional, defaults to 0).
- Offset *int32 `protobuf:"varint,10,opt,name=offset,def=0" json:"offset,omitempty"`
- // The maximum number of results to return. Applies after all other
- // constraints. Optional.
- Limit *int32 `protobuf:"varint,11,opt,name=limit" json:"limit,omitempty"`
- XXX_unrecognized []byte `json:"-"`
-}
-
-func (m *Query) Reset() { *m = Query{} }
-func (m *Query) String() string { return proto.CompactTextString(m) }
-func (*Query) ProtoMessage() {}
-
-const Default_Query_Offset int32 = 0
-
-func (m *Query) GetProjection() []*PropertyExpression {
- if m != nil {
- return m.Projection
- }
- return nil
-}
-
-func (m *Query) GetKind() []*KindExpression {
- if m != nil {
- return m.Kind
- }
- return nil
-}
-
-func (m *Query) GetFilter() *Filter {
- if m != nil {
- return m.Filter
- }
- return nil
-}
-
-func (m *Query) GetOrder() []*PropertyOrder {
- if m != nil {
- return m.Order
- }
- return nil
-}
-
-func (m *Query) GetGroupBy() []*PropertyReference {
- if m != nil {
- return m.GroupBy
- }
- return nil
-}
-
-func (m *Query) GetStartCursor() []byte {
- if m != nil {
- return m.StartCursor
- }
- return nil
-}
-
-func (m *Query) GetEndCursor() []byte {
- if m != nil {
- return m.EndCursor
- }
- return nil
-}
-
-func (m *Query) GetOffset() int32 {
- if m != nil && m.Offset != nil {
- return *m.Offset
- }
- return Default_Query_Offset
-}
-
-func (m *Query) GetLimit() int32 {
- if m != nil && m.Limit != nil {
- return *m.Limit
- }
- return 0
-}
-
-// A representation of a kind.
-type KindExpression struct {
- // The name of the kind.
- Name *string `protobuf:"bytes,1,req,name=name" json:"name,omitempty"`
- XXX_unrecognized []byte `json:"-"`
-}
-
-func (m *KindExpression) Reset() { *m = KindExpression{} }
-func (m *KindExpression) String() string { return proto.CompactTextString(m) }
-func (*KindExpression) ProtoMessage() {}
-
-func (m *KindExpression) GetName() string {
- if m != nil && m.Name != nil {
- return *m.Name
- }
- return ""
-}
-
-// A reference to a property relative to the kind expressions.
-// exactly.
-type PropertyReference struct {
- // The name of the property.
- Name *string `protobuf:"bytes,2,req,name=name" json:"name,omitempty"`
- XXX_unrecognized []byte `json:"-"`
-}
-
-func (m *PropertyReference) Reset() { *m = PropertyReference{} }
-func (m *PropertyReference) String() string { return proto.CompactTextString(m) }
-func (*PropertyReference) ProtoMessage() {}
-
-func (m *PropertyReference) GetName() string {
- if m != nil && m.Name != nil {
- return *m.Name
- }
- return ""
-}
-
-// A representation of a property in a projection.
-type PropertyExpression struct {
- // The property to project.
- Property *PropertyReference `protobuf:"bytes,1,req,name=property" json:"property,omitempty"`
- // The aggregation function to apply to the property. Optional.
- // Can only be used when grouping by at least one property. Must
- // then be set on all properties in the projection that are not
- // being grouped by.
- AggregationFunction *PropertyExpression_AggregationFunction `protobuf:"varint,2,opt,name=aggregation_function,enum=datastore.PropertyExpression_AggregationFunction" json:"aggregation_function,omitempty"`
- XXX_unrecognized []byte `json:"-"`
-}
-
-func (m *PropertyExpression) Reset() { *m = PropertyExpression{} }
-func (m *PropertyExpression) String() string { return proto.CompactTextString(m) }
-func (*PropertyExpression) ProtoMessage() {}
-
-func (m *PropertyExpression) GetProperty() *PropertyReference {
- if m != nil {
- return m.Property
- }
- return nil
-}
-
-func (m *PropertyExpression) GetAggregationFunction() PropertyExpression_AggregationFunction {
- if m != nil && m.AggregationFunction != nil {
- return *m.AggregationFunction
- }
- return PropertyExpression_FIRST
-}
-
-// The desired order for a specific property.
-type PropertyOrder struct {
- // The property to order by.
- Property *PropertyReference `protobuf:"bytes,1,req,name=property" json:"property,omitempty"`
- // The direction to order by.
- Direction *PropertyOrder_Direction `protobuf:"varint,2,opt,name=direction,enum=datastore.PropertyOrder_Direction,def=1" json:"direction,omitempty"`
- XXX_unrecognized []byte `json:"-"`
-}
-
-func (m *PropertyOrder) Reset() { *m = PropertyOrder{} }
-func (m *PropertyOrder) String() string { return proto.CompactTextString(m) }
-func (*PropertyOrder) ProtoMessage() {}
-
-const Default_PropertyOrder_Direction PropertyOrder_Direction = PropertyOrder_ASCENDING
-
-func (m *PropertyOrder) GetProperty() *PropertyReference {
- if m != nil {
- return m.Property
- }
- return nil
-}
-
-func (m *PropertyOrder) GetDirection() PropertyOrder_Direction {
- if m != nil && m.Direction != nil {
- return *m.Direction
- }
- return Default_PropertyOrder_Direction
-}
-
-// A holder for any type of filter. Exactly one field should be specified.
-type Filter struct {
- // A composite filter.
- CompositeFilter *CompositeFilter `protobuf:"bytes,1,opt,name=composite_filter" json:"composite_filter,omitempty"`
- // A filter on a property.
- PropertyFilter *PropertyFilter `protobuf:"bytes,2,opt,name=property_filter" json:"property_filter,omitempty"`
- XXX_unrecognized []byte `json:"-"`
-}
-
-func (m *Filter) Reset() { *m = Filter{} }
-func (m *Filter) String() string { return proto.CompactTextString(m) }
-func (*Filter) ProtoMessage() {}
-
-func (m *Filter) GetCompositeFilter() *CompositeFilter {
- if m != nil {
- return m.CompositeFilter
- }
- return nil
-}
-
-func (m *Filter) GetPropertyFilter() *PropertyFilter {
- if m != nil {
- return m.PropertyFilter
- }
- return nil
-}
-
-// A filter that merges the multiple other filters using the given operation.
-type CompositeFilter struct {
- // The operator for combining multiple filters.
- Operator *CompositeFilter_Operator `protobuf:"varint,1,req,name=operator,enum=datastore.CompositeFilter_Operator" json:"operator,omitempty"`
- // The list of filters to combine.
- // Must contain at least one filter.
- Filter []*Filter `protobuf:"bytes,2,rep,name=filter" json:"filter,omitempty"`
- XXX_unrecognized []byte `json:"-"`
-}
-
-func (m *CompositeFilter) Reset() { *m = CompositeFilter{} }
-func (m *CompositeFilter) String() string { return proto.CompactTextString(m) }
-func (*CompositeFilter) ProtoMessage() {}
-
-func (m *CompositeFilter) GetOperator() CompositeFilter_Operator {
- if m != nil && m.Operator != nil {
- return *m.Operator
- }
- return CompositeFilter_AND
-}
-
-func (m *CompositeFilter) GetFilter() []*Filter {
- if m != nil {
- return m.Filter
- }
- return nil
-}
-
-// A filter on a specific property.
-type PropertyFilter struct {
- // The property to filter by.
- Property *PropertyReference `protobuf:"bytes,1,req,name=property" json:"property,omitempty"`
- // The operator to filter by.
- Operator *PropertyFilter_Operator `protobuf:"varint,2,req,name=operator,enum=datastore.PropertyFilter_Operator" json:"operator,omitempty"`
- // The value to compare the property to.
- Value *Value `protobuf:"bytes,3,req,name=value" json:"value,omitempty"`
- XXX_unrecognized []byte `json:"-"`
-}
-
-func (m *PropertyFilter) Reset() { *m = PropertyFilter{} }
-func (m *PropertyFilter) String() string { return proto.CompactTextString(m) }
-func (*PropertyFilter) ProtoMessage() {}
-
-func (m *PropertyFilter) GetProperty() *PropertyReference {
- if m != nil {
- return m.Property
- }
- return nil
-}
-
-func (m *PropertyFilter) GetOperator() PropertyFilter_Operator {
- if m != nil && m.Operator != nil {
- return *m.Operator
- }
- return PropertyFilter_LESS_THAN
-}
-
-func (m *PropertyFilter) GetValue() *Value {
- if m != nil {
- return m.Value
- }
- return nil
-}
-
-// A GQL query.
-type GqlQuery struct {
- QueryString *string `protobuf:"bytes,1,req,name=query_string" json:"query_string,omitempty"`
- // When false, the query string must not contain a literal.
- AllowLiteral *bool `protobuf:"varint,2,opt,name=allow_literal,def=0" json:"allow_literal,omitempty"`
- // A named argument must set field GqlQueryArg.name.
- // No two named arguments may have the same name.
- // For each non-reserved named binding site in the query string,
- // there must be a named argument with that name,
- // but not necessarily the inverse.
- NameArg []*GqlQueryArg `protobuf:"bytes,3,rep,name=name_arg" json:"name_arg,omitempty"`
- // Numbered binding site @1 references the first numbered argument,
- // effectively using 1-based indexing, rather than the usual 0.
- // A numbered argument must NOT set field GqlQueryArg.name.
- // For each binding site numbered i in query_string,
- // there must be an ith numbered argument.
- // The inverse must also be true.
- NumberArg []*GqlQueryArg `protobuf:"bytes,4,rep,name=number_arg" json:"number_arg,omitempty"`
- XXX_unrecognized []byte `json:"-"`
-}
-
-func (m *GqlQuery) Reset() { *m = GqlQuery{} }
-func (m *GqlQuery) String() string { return proto.CompactTextString(m) }
-func (*GqlQuery) ProtoMessage() {}
-
-const Default_GqlQuery_AllowLiteral bool = false
-
-func (m *GqlQuery) GetQueryString() string {
- if m != nil && m.QueryString != nil {
- return *m.QueryString
- }
- return ""
-}
-
-func (m *GqlQuery) GetAllowLiteral() bool {
- if m != nil && m.AllowLiteral != nil {
- return *m.AllowLiteral
- }
- return Default_GqlQuery_AllowLiteral
-}
-
-func (m *GqlQuery) GetNameArg() []*GqlQueryArg {
- if m != nil {
- return m.NameArg
- }
- return nil
-}
-
-func (m *GqlQuery) GetNumberArg() []*GqlQueryArg {
- if m != nil {
- return m.NumberArg
- }
- return nil
-}
-
-// A binding argument for a GQL query.
-// Exactly one of fields value and cursor must be set.
-type GqlQueryArg struct {
- // Must match regex "[A-Za-z_$][A-Za-z_$0-9]*".
- // Must not match regex "__.*__".
- // Must not be "".
- Name *string `protobuf:"bytes,1,opt,name=name" json:"name,omitempty"`
- Value *Value `protobuf:"bytes,2,opt,name=value" json:"value,omitempty"`
- Cursor []byte `protobuf:"bytes,3,opt,name=cursor" json:"cursor,omitempty"`
- XXX_unrecognized []byte `json:"-"`
-}
-
-func (m *GqlQueryArg) Reset() { *m = GqlQueryArg{} }
-func (m *GqlQueryArg) String() string { return proto.CompactTextString(m) }
-func (*GqlQueryArg) ProtoMessage() {}
-
-func (m *GqlQueryArg) GetName() string {
- if m != nil && m.Name != nil {
- return *m.Name
- }
- return ""
-}
-
-func (m *GqlQueryArg) GetValue() *Value {
- if m != nil {
- return m.Value
- }
- return nil
-}
-
-func (m *GqlQueryArg) GetCursor() []byte {
- if m != nil {
- return m.Cursor
- }
- return nil
-}
-
-// A batch of results produced by a query.
-type QueryResultBatch struct {
- // The result type for every entity in entityResults.
- EntityResultType *EntityResult_ResultType `protobuf:"varint,1,req,name=entity_result_type,enum=datastore.EntityResult_ResultType" json:"entity_result_type,omitempty"`
- // The results for this batch.
- EntityResult []*EntityResult `protobuf:"bytes,2,rep,name=entity_result" json:"entity_result,omitempty"`
- // A cursor that points to the position after the last result in the batch.
- // May be absent.
- EndCursor []byte `protobuf:"bytes,4,opt,name=end_cursor" json:"end_cursor,omitempty"`
- // The state of the query after the current batch.
- MoreResults *QueryResultBatch_MoreResultsType `protobuf:"varint,5,req,name=more_results,enum=datastore.QueryResultBatch_MoreResultsType" json:"more_results,omitempty"`
- // The number of results skipped because of Query.offset.
- SkippedResults *int32 `protobuf:"varint,6,opt,name=skipped_results" json:"skipped_results,omitempty"`
- XXX_unrecognized []byte `json:"-"`
-}
-
-func (m *QueryResultBatch) Reset() { *m = QueryResultBatch{} }
-func (m *QueryResultBatch) String() string { return proto.CompactTextString(m) }
-func (*QueryResultBatch) ProtoMessage() {}
-
-func (m *QueryResultBatch) GetEntityResultType() EntityResult_ResultType {
- if m != nil && m.EntityResultType != nil {
- return *m.EntityResultType
- }
- return EntityResult_FULL
-}
-
-func (m *QueryResultBatch) GetEntityResult() []*EntityResult {
- if m != nil {
- return m.EntityResult
- }
- return nil
-}
-
-func (m *QueryResultBatch) GetEndCursor() []byte {
- if m != nil {
- return m.EndCursor
- }
- return nil
-}
-
-func (m *QueryResultBatch) GetMoreResults() QueryResultBatch_MoreResultsType {
- if m != nil && m.MoreResults != nil {
- return *m.MoreResults
- }
- return QueryResultBatch_NOT_FINISHED
-}
-
-func (m *QueryResultBatch) GetSkippedResults() int32 {
- if m != nil && m.SkippedResults != nil {
- return *m.SkippedResults
- }
- return 0
-}
-
-// A set of changes to apply.
-//
-// No entity in this message may have a reserved property name,
-// not even a property in an entity in a value.
-// No value in this message may have meaning 18,
-// not even a value in an entity in another value.
-//
-// If entities with duplicate keys are present, an arbitrary choice will
-// be made as to which is written.
-type Mutation struct {
- // Entities to upsert.
- // Each upserted entity's key must have a complete path and
- // must not be reserved/read-only.
- Upsert []*Entity `protobuf:"bytes,1,rep,name=upsert" json:"upsert,omitempty"`
- // Entities to update.
- // Each updated entity's key must have a complete path and
- // must not be reserved/read-only.
- Update []*Entity `protobuf:"bytes,2,rep,name=update" json:"update,omitempty"`
- // Entities to insert.
- // Each inserted entity's key must have a complete path and
- // must not be reserved/read-only.
- Insert []*Entity `protobuf:"bytes,3,rep,name=insert" json:"insert,omitempty"`
- // Insert entities with a newly allocated ID.
- // Each inserted entity's key must omit the final identifier in its path and
- // must not be reserved/read-only.
- InsertAutoId []*Entity `protobuf:"bytes,4,rep,name=insert_auto_id" json:"insert_auto_id,omitempty"`
- // Keys of entities to delete.
- // Each key must have a complete key path and must not be reserved/read-only.
- Delete []*Key `protobuf:"bytes,5,rep,name=delete" json:"delete,omitempty"`
- // Ignore a user specified read-only period. Optional.
- Force *bool `protobuf:"varint,6,opt,name=force" json:"force,omitempty"`
- XXX_unrecognized []byte `json:"-"`
-}
-
-func (m *Mutation) Reset() { *m = Mutation{} }
-func (m *Mutation) String() string { return proto.CompactTextString(m) }
-func (*Mutation) ProtoMessage() {}
-
-func (m *Mutation) GetUpsert() []*Entity {
- if m != nil {
- return m.Upsert
- }
- return nil
-}
-
-func (m *Mutation) GetUpdate() []*Entity {
- if m != nil {
- return m.Update
- }
- return nil
-}
-
-func (m *Mutation) GetInsert() []*Entity {
- if m != nil {
- return m.Insert
- }
- return nil
-}
-
-func (m *Mutation) GetInsertAutoId() []*Entity {
- if m != nil {
- return m.InsertAutoId
- }
- return nil
-}
-
-func (m *Mutation) GetDelete() []*Key {
- if m != nil {
- return m.Delete
- }
- return nil
-}
-
-func (m *Mutation) GetForce() bool {
- if m != nil && m.Force != nil {
- return *m.Force
- }
- return false
-}
-
-// The result of applying a mutation.
-type MutationResult struct {
- // Number of index writes.
- IndexUpdates *int32 `protobuf:"varint,1,req,name=index_updates" json:"index_updates,omitempty"`
- // Keys for insertAutoId entities. One per entity from the
- // request, in the same order.
- InsertAutoIdKey []*Key `protobuf:"bytes,2,rep,name=insert_auto_id_key" json:"insert_auto_id_key,omitempty"`
- XXX_unrecognized []byte `json:"-"`
-}
-
-func (m *MutationResult) Reset() { *m = MutationResult{} }
-func (m *MutationResult) String() string { return proto.CompactTextString(m) }
-func (*MutationResult) ProtoMessage() {}
-
-func (m *MutationResult) GetIndexUpdates() int32 {
- if m != nil && m.IndexUpdates != nil {
- return *m.IndexUpdates
- }
- return 0
-}
-
-func (m *MutationResult) GetInsertAutoIdKey() []*Key {
- if m != nil {
- return m.InsertAutoIdKey
- }
- return nil
-}
-
-// Options shared by read requests.
-type ReadOptions struct {
- // The read consistency to use.
- // Cannot be set when transaction is set.
- // Lookup and ancestor queries default to STRONG, global queries default to
- // EVENTUAL and cannot be set to STRONG.
- ReadConsistency *ReadOptions_ReadConsistency `protobuf:"varint,1,opt,name=read_consistency,enum=datastore.ReadOptions_ReadConsistency,def=0" json:"read_consistency,omitempty"`
- // The transaction to use. Optional.
- Transaction []byte `protobuf:"bytes,2,opt,name=transaction" json:"transaction,omitempty"`
- XXX_unrecognized []byte `json:"-"`
-}
-
-func (m *ReadOptions) Reset() { *m = ReadOptions{} }
-func (m *ReadOptions) String() string { return proto.CompactTextString(m) }
-func (*ReadOptions) ProtoMessage() {}
-
-const Default_ReadOptions_ReadConsistency ReadOptions_ReadConsistency = ReadOptions_DEFAULT
-
-func (m *ReadOptions) GetReadConsistency() ReadOptions_ReadConsistency {
- if m != nil && m.ReadConsistency != nil {
- return *m.ReadConsistency
- }
- return Default_ReadOptions_ReadConsistency
-}
-
-func (m *ReadOptions) GetTransaction() []byte {
- if m != nil {
- return m.Transaction
- }
- return nil
-}
-
-// The request for Lookup.
-type LookupRequest struct {
- // Options for this lookup request. Optional.
- ReadOptions *ReadOptions `protobuf:"bytes,1,opt,name=read_options" json:"read_options,omitempty"`
- // Keys of entities to look up from the datastore.
- Key []*Key `protobuf:"bytes,3,rep,name=key" json:"key,omitempty"`
- XXX_unrecognized []byte `json:"-"`
-}
-
-func (m *LookupRequest) Reset() { *m = LookupRequest{} }
-func (m *LookupRequest) String() string { return proto.CompactTextString(m) }
-func (*LookupRequest) ProtoMessage() {}
-
-func (m *LookupRequest) GetReadOptions() *ReadOptions {
- if m != nil {
- return m.ReadOptions
- }
- return nil
-}
-
-func (m *LookupRequest) GetKey() []*Key {
- if m != nil {
- return m.Key
- }
- return nil
-}
-
-// The response for Lookup.
-type LookupResponse struct {
- // Entities found as ResultType.FULL entities.
- Found []*EntityResult `protobuf:"bytes,1,rep,name=found" json:"found,omitempty"`
- // Entities not found as ResultType.KEY_ONLY entities.
- Missing []*EntityResult `protobuf:"bytes,2,rep,name=missing" json:"missing,omitempty"`
- // A list of keys that were not looked up due to resource constraints.
- Deferred []*Key `protobuf:"bytes,3,rep,name=deferred" json:"deferred,omitempty"`
- XXX_unrecognized []byte `json:"-"`
-}
-
-func (m *LookupResponse) Reset() { *m = LookupResponse{} }
-func (m *LookupResponse) String() string { return proto.CompactTextString(m) }
-func (*LookupResponse) ProtoMessage() {}
-
-func (m *LookupResponse) GetFound() []*EntityResult {
- if m != nil {
- return m.Found
- }
- return nil
-}
-
-func (m *LookupResponse) GetMissing() []*EntityResult {
- if m != nil {
- return m.Missing
- }
- return nil
-}
-
-func (m *LookupResponse) GetDeferred() []*Key {
- if m != nil {
- return m.Deferred
- }
- return nil
-}
-
-// The request for RunQuery.
-type RunQueryRequest struct {
- // The options for this query.
- ReadOptions *ReadOptions `protobuf:"bytes,1,opt,name=read_options" json:"read_options,omitempty"`
- // Entities are partitioned into subsets, identified by a dataset (usually
- // implicitly specified by the project) and namespace ID. Queries are scoped
- // to a single partition.
- // This partition ID is normalized with the standard default context
- // partition ID, but all other partition IDs in RunQueryRequest are
- // normalized with this partition ID as the context partition ID.
- PartitionId *PartitionId `protobuf:"bytes,2,opt,name=partition_id" json:"partition_id,omitempty"`
- // The query to run.
- // Either this field or field gql_query must be set, but not both.
- Query *Query `protobuf:"bytes,3,opt,name=query" json:"query,omitempty"`
- // The GQL query to run.
- // Either this field or field query must be set, but not both.
- GqlQuery *GqlQuery `protobuf:"bytes,7,opt,name=gql_query" json:"gql_query,omitempty"`
- XXX_unrecognized []byte `json:"-"`
-}
-
-func (m *RunQueryRequest) Reset() { *m = RunQueryRequest{} }
-func (m *RunQueryRequest) String() string { return proto.CompactTextString(m) }
-func (*RunQueryRequest) ProtoMessage() {}
-
-func (m *RunQueryRequest) GetReadOptions() *ReadOptions {
- if m != nil {
- return m.ReadOptions
- }
- return nil
-}
-
-func (m *RunQueryRequest) GetPartitionId() *PartitionId {
- if m != nil {
- return m.PartitionId
- }
- return nil
-}
-
-func (m *RunQueryRequest) GetQuery() *Query {
- if m != nil {
- return m.Query
- }
- return nil
-}
-
-func (m *RunQueryRequest) GetGqlQuery() *GqlQuery {
- if m != nil {
- return m.GqlQuery
- }
- return nil
-}
-
-// The response for RunQuery.
-type RunQueryResponse struct {
- // A batch of query results (always present).
- Batch *QueryResultBatch `protobuf:"bytes,1,opt,name=batch" json:"batch,omitempty"`
- XXX_unrecognized []byte `json:"-"`
-}
-
-func (m *RunQueryResponse) Reset() { *m = RunQueryResponse{} }
-func (m *RunQueryResponse) String() string { return proto.CompactTextString(m) }
-func (*RunQueryResponse) ProtoMessage() {}
-
-func (m *RunQueryResponse) GetBatch() *QueryResultBatch {
- if m != nil {
- return m.Batch
- }
- return nil
-}
-
-// The request for BeginTransaction.
-type BeginTransactionRequest struct {
- // The transaction isolation level.
- IsolationLevel *BeginTransactionRequest_IsolationLevel `protobuf:"varint,1,opt,name=isolation_level,enum=datastore.BeginTransactionRequest_IsolationLevel,def=0" json:"isolation_level,omitempty"`
- XXX_unrecognized []byte `json:"-"`
-}
-
-func (m *BeginTransactionRequest) Reset() { *m = BeginTransactionRequest{} }
-func (m *BeginTransactionRequest) String() string { return proto.CompactTextString(m) }
-func (*BeginTransactionRequest) ProtoMessage() {}
-
-const Default_BeginTransactionRequest_IsolationLevel BeginTransactionRequest_IsolationLevel = BeginTransactionRequest_SNAPSHOT
-
-func (m *BeginTransactionRequest) GetIsolationLevel() BeginTransactionRequest_IsolationLevel {
- if m != nil && m.IsolationLevel != nil {
- return *m.IsolationLevel
- }
- return Default_BeginTransactionRequest_IsolationLevel
-}
-
-// The response for BeginTransaction.
-type BeginTransactionResponse struct {
- // The transaction identifier (always present).
- Transaction []byte `protobuf:"bytes,1,opt,name=transaction" json:"transaction,omitempty"`
- XXX_unrecognized []byte `json:"-"`
-}
-
-func (m *BeginTransactionResponse) Reset() { *m = BeginTransactionResponse{} }
-func (m *BeginTransactionResponse) String() string { return proto.CompactTextString(m) }
-func (*BeginTransactionResponse) ProtoMessage() {}
-
-func (m *BeginTransactionResponse) GetTransaction() []byte {
- if m != nil {
- return m.Transaction
- }
- return nil
-}
-
-// The request for Rollback.
-type RollbackRequest struct {
- // The transaction identifier, returned by a call to
- // beginTransaction.
- Transaction []byte `protobuf:"bytes,1,req,name=transaction" json:"transaction,omitempty"`
- XXX_unrecognized []byte `json:"-"`
-}
-
-func (m *RollbackRequest) Reset() { *m = RollbackRequest{} }
-func (m *RollbackRequest) String() string { return proto.CompactTextString(m) }
-func (*RollbackRequest) ProtoMessage() {}
-
-func (m *RollbackRequest) GetTransaction() []byte {
- if m != nil {
- return m.Transaction
- }
- return nil
-}
-
-// The response for Rollback.
-type RollbackResponse struct {
- XXX_unrecognized []byte `json:"-"`
-}
-
-func (m *RollbackResponse) Reset() { *m = RollbackResponse{} }
-func (m *RollbackResponse) String() string { return proto.CompactTextString(m) }
-func (*RollbackResponse) ProtoMessage() {}
-
-// The request for Commit.
-type CommitRequest struct {
- // The transaction identifier, returned by a call to
- // beginTransaction. Must be set when mode is TRANSACTIONAL.
- Transaction []byte `protobuf:"bytes,1,opt,name=transaction" json:"transaction,omitempty"`
- // The mutation to perform. Optional.
- Mutation *Mutation `protobuf:"bytes,2,opt,name=mutation" json:"mutation,omitempty"`
- // The type of commit to perform. Either TRANSACTIONAL or NON_TRANSACTIONAL.
- Mode *CommitRequest_Mode `protobuf:"varint,5,opt,name=mode,enum=datastore.CommitRequest_Mode,def=1" json:"mode,omitempty"`
- XXX_unrecognized []byte `json:"-"`
-}
-
-func (m *CommitRequest) Reset() { *m = CommitRequest{} }
-func (m *CommitRequest) String() string { return proto.CompactTextString(m) }
-func (*CommitRequest) ProtoMessage() {}
-
-const Default_CommitRequest_Mode CommitRequest_Mode = CommitRequest_TRANSACTIONAL
-
-func (m *CommitRequest) GetTransaction() []byte {
- if m != nil {
- return m.Transaction
- }
- return nil
-}
-
-func (m *CommitRequest) GetMutation() *Mutation {
- if m != nil {
- return m.Mutation
- }
- return nil
-}
-
-func (m *CommitRequest) GetMode() CommitRequest_Mode {
- if m != nil && m.Mode != nil {
- return *m.Mode
- }
- return Default_CommitRequest_Mode
-}
-
-// The response for Commit.
-type CommitResponse struct {
- // The result of performing the mutation (if any).
- MutationResult *MutationResult `protobuf:"bytes,1,opt,name=mutation_result" json:"mutation_result,omitempty"`
- XXX_unrecognized []byte `json:"-"`
-}
-
-func (m *CommitResponse) Reset() { *m = CommitResponse{} }
-func (m *CommitResponse) String() string { return proto.CompactTextString(m) }
-func (*CommitResponse) ProtoMessage() {}
-
-func (m *CommitResponse) GetMutationResult() *MutationResult {
- if m != nil {
- return m.MutationResult
- }
- return nil
-}
-
-// The request for AllocateIds.
-type AllocateIdsRequest struct {
- // A list of keys with incomplete key paths to allocate IDs for.
- // No key may be reserved/read-only.
- Key []*Key `protobuf:"bytes,1,rep,name=key" json:"key,omitempty"`
- XXX_unrecognized []byte `json:"-"`
-}
-
-func (m *AllocateIdsRequest) Reset() { *m = AllocateIdsRequest{} }
-func (m *AllocateIdsRequest) String() string { return proto.CompactTextString(m) }
-func (*AllocateIdsRequest) ProtoMessage() {}
-
-func (m *AllocateIdsRequest) GetKey() []*Key {
- if m != nil {
- return m.Key
- }
- return nil
-}
-
-// The response for AllocateIds.
-type AllocateIdsResponse struct {
- // The keys specified in the request (in the same order), each with
- // its key path completed with a newly allocated ID.
- Key []*Key `protobuf:"bytes,1,rep,name=key" json:"key,omitempty"`
- XXX_unrecognized []byte `json:"-"`
-}
-
-func (m *AllocateIdsResponse) Reset() { *m = AllocateIdsResponse{} }
-func (m *AllocateIdsResponse) String() string { return proto.CompactTextString(m) }
-func (*AllocateIdsResponse) ProtoMessage() {}
-
-func (m *AllocateIdsResponse) GetKey() []*Key {
- if m != nil {
- return m.Key
- }
- return nil
-}
-
-func init() {
- proto.RegisterEnum("datastore.EntityResult_ResultType", EntityResult_ResultType_name, EntityResult_ResultType_value)
- proto.RegisterEnum("datastore.PropertyExpression_AggregationFunction", PropertyExpression_AggregationFunction_name, PropertyExpression_AggregationFunction_value)
- proto.RegisterEnum("datastore.PropertyOrder_Direction", PropertyOrder_Direction_name, PropertyOrder_Direction_value)
- proto.RegisterEnum("datastore.CompositeFilter_Operator", CompositeFilter_Operator_name, CompositeFilter_Operator_value)
- proto.RegisterEnum("datastore.PropertyFilter_Operator", PropertyFilter_Operator_name, PropertyFilter_Operator_value)
- proto.RegisterEnum("datastore.QueryResultBatch_MoreResultsType", QueryResultBatch_MoreResultsType_name, QueryResultBatch_MoreResultsType_value)
- proto.RegisterEnum("datastore.ReadOptions_ReadConsistency", ReadOptions_ReadConsistency_name, ReadOptions_ReadConsistency_value)
- proto.RegisterEnum("datastore.BeginTransactionRequest_IsolationLevel", BeginTransactionRequest_IsolationLevel_name, BeginTransactionRequest_IsolationLevel_value)
- proto.RegisterEnum("datastore.CommitRequest_Mode", CommitRequest_Mode_name, CommitRequest_Mode_value)
-}
diff --git a/vendor/google.golang.org/cloud/internal/datastore/datastore_v1.proto b/vendor/google.golang.org/cloud/internal/datastore/datastore_v1.proto
deleted file mode 100644
index d752beaa..00000000
--- a/vendor/google.golang.org/cloud/internal/datastore/datastore_v1.proto
+++ /dev/null
@@ -1,606 +0,0 @@
-// Copyright 2013 Google Inc. All Rights Reserved.
-//
-// Licensed under the Apache License, Version 2.0 (the "License");
-// you may not use this file except in compliance with the License.
-// You may obtain a copy of the License at
-//
-// http://www.apache.org/licenses/LICENSE-2.0
-//
-// Unless required by applicable law or agreed to in writing, software
-// distributed under the License is distributed on an "AS IS" BASIS,
-// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-// See the License for the specific language governing permissions and
-// limitations under the License.
-//
-// The datastore v1 service proto definitions
-
-syntax = "proto2";
-
-package datastore;
-option java_package = "com.google.api.services.datastore";
-
-
-// An identifier for a particular subset of entities.
-//
-// Entities are partitioned into various subsets, each used by different
-// datasets and different namespaces within a dataset and so forth.
-//
-// All input partition IDs are normalized before use.
-// A partition ID is normalized as follows:
-// If the partition ID is unset or is set to an empty partition ID, replace it
-// with the context partition ID.
-// Otherwise, if the partition ID has no dataset ID, assign it the context
-// partition ID's dataset ID.
-// Unless otherwise documented, the context partition ID has the dataset ID set
-// to the context dataset ID and no other partition dimension set.
-//
-// A partition ID is empty if all of its fields are unset.
-//
-// Partition dimension:
-// A dimension may be unset.
-// A dimension's value must never be "".
-// A dimension's value must match [A-Za-z\d\.\-_]{1,100}
-// If the value of any dimension matches regex "__.*__",
-// the partition is reserved/read-only.
-// A reserved/read-only partition ID is forbidden in certain documented contexts.
-//
-// Dataset ID:
-// A dataset id's value must never be "".
-// A dataset id's value must match
-// ([a-z\d\-]{1,100}~)?([a-z\d][a-z\d\-\.]{0,99}:)?([a-z\d][a-z\d\-]{0,99}
-message PartitionId {
- // The dataset ID.
- optional string dataset_id = 3;
- // The namespace.
- optional string namespace = 4;
-}
-
-// A unique identifier for an entity.
-// If a key's partition id or any of its path kinds or names are
-// reserved/read-only, the key is reserved/read-only.
-// A reserved/read-only key is forbidden in certain documented contexts.
-message Key {
- // Entities are partitioned into subsets, currently identified by a dataset
- // (usually implicitly specified by the project) and namespace ID.
- // Queries are scoped to a single partition.
- optional PartitionId partition_id = 1;
-
- // A (kind, ID/name) pair used to construct a key path.
- //
- // At most one of name or ID may be set.
- // If either is set, the element is complete.
- // If neither is set, the element is incomplete.
- message PathElement {
- // The kind of the entity.
- // A kind matching regex "__.*__" is reserved/read-only.
- // A kind must not contain more than 500 characters.
- // Cannot be "".
- required string kind = 1;
- // The ID of the entity.
- // Never equal to zero. Values less than zero are discouraged and will not
- // be supported in the future.
- optional int64 id = 2;
- // The name of the entity.
- // A name matching regex "__.*__" is reserved/read-only.
- // A name must not be more than 500 characters.
- // Cannot be "".
- optional string name = 3;
- }
-
- // The entity path.
- // An entity path consists of one or more elements composed of a kind and a
- // string or numerical identifier, which identify entities. The first
- // element identifies a root entity, the second element identifies
- // a child of the root entity, the third element a child of the
- // second entity, and so forth. The entities identified by all prefixes of
- // the path are called the element's ancestors.
- // An entity path is always fully complete: ALL of the entity's ancestors
- // are required to be in the path along with the entity identifier itself.
- // The only exception is that in some documented cases, the identifier in the
- // last path element (for the entity) itself may be omitted. A path can never
- // be empty.
- repeated PathElement path_element = 2;
-}
-
-// A message that can hold any of the supported value types and associated
-// metadata.
-//
-// At most one of the Value fields may be set.
-// If none are set the value is "null".
-//
-message Value {
- // A boolean value.
- optional bool boolean_value = 1;
- // An integer value.
- optional int64 integer_value = 2;
- // A double value.
- optional double double_value = 3;
- // A timestamp value.
- optional int64 timestamp_microseconds_value = 4;
- // A key value.
- optional Key key_value = 5;
- // A blob key value.
- optional string blob_key_value = 16;
- // A UTF-8 encoded string value.
- optional string string_value = 17;
- // A blob value.
- optional bytes blob_value = 18;
- // An entity value.
- // May have no key.
- // May have a key with an incomplete key path.
- // May have a reserved/read-only key.
- optional Entity entity_value = 6;
- // A list value.
- // Cannot contain another list value.
- // Cannot also have a meaning and indexing set.
- repeated Value list_value = 7;
-
- // The meaning field is reserved and should not be used.
- optional int32 meaning = 14;
-
- // If the value should be indexed.
- //
- // The indexed property may be set for a
- // null value.
- // When indexed is true, stringValue
- // is limited to 500 characters and the blob value is limited to 500 bytes.
- // Exception: If meaning is set to 2, string_value is limited to 2038
- // characters regardless of indexed.
- // When indexed is true, meaning 15 and 22 are not allowed, and meaning 16
- // will be ignored on input (and will never be set on output).
- // Input values by default have indexed set to
- // true; however, you can explicitly set indexed to
- // true if you want. (An output value never has
- // indexed explicitly set to true.) If a value is
- // itself an entity, it cannot have indexed set to
- // true.
- // Exception: An entity value with meaning 9, 20 or 21 may be indexed.
- optional bool indexed = 15 [default = true];
-}
-
-// An entity property.
-message Property {
- // The name of the property.
- // A property name matching regex "__.*__" is reserved.
- // A reserved property name is forbidden in certain documented contexts.
- // The name must not contain more than 500 characters.
- // Cannot be "".
- required string name = 1;
-
- // The value(s) of the property.
- // Each value can have only one value property populated. For example,
- // you cannot have a values list of { value: { integerValue: 22,
- // stringValue: "a" } }, but you can have { value: { listValue:
- // [ { integerValue: 22 }, { stringValue: "a" } ] }.
- required Value value = 4;
-}
-
-// An entity.
-//
-// An entity is limited to 1 megabyte when stored. That roughly
-// corresponds to a limit of 1 megabyte for the serialized form of this
-// message.
-message Entity {
- // The entity's key.
- //
- // An entity must have a key, unless otherwise documented (for example,
- // an entity in Value.entityValue may have no key).
- // An entity's kind is its key's path's last element's kind,
- // or null if it has no key.
- optional Key key = 1;
- // The entity's properties.
- // Each property's name must be unique for its entity.
- repeated Property property = 2;
-}
-
-// The result of fetching an entity from the datastore.
-message EntityResult {
- // Specifies what data the 'entity' field contains.
- // A ResultType is either implied (for example, in LookupResponse.found it
- // is always FULL) or specified by context (for example, in message
- // QueryResultBatch, field 'entity_result_type' specifies a ResultType
- // for all the values in field 'entity_result').
- enum ResultType {
- FULL = 1; // The entire entity.
- PROJECTION = 2; // A projected subset of properties.
- // The entity may have no key.
- // A property value may have meaning 18.
- KEY_ONLY = 3; // Only the key.
- }
-
- // The resulting entity.
- required Entity entity = 1;
-}
-
-// A query.
-message Query {
- // The projection to return. If not set the entire entity is returned.
- repeated PropertyExpression projection = 2;
-
- // The kinds to query (if empty, returns entities from all kinds).
- repeated KindExpression kind = 3;
-
- // The filter to apply (optional).
- optional Filter filter = 4;
-
- // The order to apply to the query results (if empty, order is unspecified).
- repeated PropertyOrder order = 5;
-
- // The properties to group by (if empty, no grouping is applied to the
- // result set).
- repeated PropertyReference group_by = 6;
-
- // A starting point for the query results. Optional. Query cursors are
- // returned in query result batches.
- optional bytes /* serialized QueryCursor */ start_cursor = 7;
-
- // An ending point for the query results. Optional. Query cursors are
- // returned in query result batches.
- optional bytes /* serialized QueryCursor */ end_cursor = 8;
-
- // The number of results to skip. Applies before limit, but after all other
- // constraints (optional, defaults to 0).
- optional int32 offset = 10 [default=0];
-
- // The maximum number of results to return. Applies after all other
- // constraints. Optional.
- optional int32 limit = 11;
-}
-
-// A representation of a kind.
-message KindExpression {
- // The name of the kind.
- required string name = 1;
-}
-
-// A reference to a property relative to the kind expressions.
-// exactly.
-message PropertyReference {
- // The name of the property.
- required string name = 2;
-}
-
-// A representation of a property in a projection.
-message PropertyExpression {
- enum AggregationFunction {
- FIRST = 1;
- }
- // The property to project.
- required PropertyReference property = 1;
- // The aggregation function to apply to the property. Optional.
- // Can only be used when grouping by at least one property. Must
- // then be set on all properties in the projection that are not
- // being grouped by.
- optional AggregationFunction aggregation_function = 2;
-}
-
-// The desired order for a specific property.
-message PropertyOrder {
- enum Direction {
- ASCENDING = 1;
- DESCENDING = 2;
- }
- // The property to order by.
- required PropertyReference property = 1;
- // The direction to order by.
- optional Direction direction = 2 [default=ASCENDING];
-}
-
-// A holder for any type of filter. Exactly one field should be specified.
-message Filter {
- // A composite filter.
- optional CompositeFilter composite_filter = 1;
- // A filter on a property.
- optional PropertyFilter property_filter = 2;
-}
-
-// A filter that merges the multiple other filters using the given operation.
-message CompositeFilter {
- enum Operator {
- AND = 1;
- }
-
- // The operator for combining multiple filters.
- required Operator operator = 1;
- // The list of filters to combine.
- // Must contain at least one filter.
- repeated Filter filter = 2;
-}
-
-// A filter on a specific property.
-message PropertyFilter {
- enum Operator {
- LESS_THAN = 1;
- LESS_THAN_OR_EQUAL = 2;
- GREATER_THAN = 3;
- GREATER_THAN_OR_EQUAL = 4;
- EQUAL = 5;
-
- HAS_ANCESTOR = 11;
- }
-
- // The property to filter by.
- required PropertyReference property = 1;
- // The operator to filter by.
- required Operator operator = 2;
- // The value to compare the property to.
- required Value value = 3;
-}
-
-// A GQL query.
-message GqlQuery {
- required string query_string = 1;
- // When false, the query string must not contain a literal.
- optional bool allow_literal = 2 [default = false];
- // A named argument must set field GqlQueryArg.name.
- // No two named arguments may have the same name.
- // For each non-reserved named binding site in the query string,
- // there must be a named argument with that name,
- // but not necessarily the inverse.
- repeated GqlQueryArg name_arg = 3;
- // Numbered binding site @1 references the first numbered argument,
- // effectively using 1-based indexing, rather than the usual 0.
- // A numbered argument must NOT set field GqlQueryArg.name.
- // For each binding site numbered i in query_string,
- // there must be an ith numbered argument.
- // The inverse must also be true.
- repeated GqlQueryArg number_arg = 4;
-}
-
-// A binding argument for a GQL query.
-// Exactly one of fields value and cursor must be set.
-message GqlQueryArg {
- // Must match regex "[A-Za-z_$][A-Za-z_$0-9]*".
- // Must not match regex "__.*__".
- // Must not be "".
- optional string name = 1;
- optional Value value = 2;
- optional bytes cursor = 3;
-}
-
-// A batch of results produced by a query.
-message QueryResultBatch {
- // The possible values for the 'more_results' field.
- enum MoreResultsType {
- NOT_FINISHED = 1; // There are additional batches to fetch from this query.
- MORE_RESULTS_AFTER_LIMIT = 2; // The query is finished, but there are more
- // results after the limit.
- NO_MORE_RESULTS = 3; // The query has been exhausted.
- }
-
- // The result type for every entity in entityResults.
- required EntityResult.ResultType entity_result_type = 1;
- // The results for this batch.
- repeated EntityResult entity_result = 2;
-
- // A cursor that points to the position after the last result in the batch.
- // May be absent.
- optional bytes /* serialized QueryCursor */ end_cursor = 4;
-
- // The state of the query after the current batch.
- required MoreResultsType more_results = 5;
-
- // The number of results skipped because of Query.offset.
- optional int32 skipped_results = 6;
-}
-
-// A set of changes to apply.
-//
-// No entity in this message may have a reserved property name,
-// not even a property in an entity in a value.
-// No value in this message may have meaning 18,
-// not even a value in an entity in another value.
-//
-// If entities with duplicate keys are present, an arbitrary choice will
-// be made as to which is written.
-message Mutation {
- // Entities to upsert.
- // Each upserted entity's key must have a complete path and
- // must not be reserved/read-only.
- repeated Entity upsert = 1;
- // Entities to update.
- // Each updated entity's key must have a complete path and
- // must not be reserved/read-only.
- repeated Entity update = 2;
- // Entities to insert.
- // Each inserted entity's key must have a complete path and
- // must not be reserved/read-only.
- repeated Entity insert = 3;
- // Insert entities with a newly allocated ID.
- // Each inserted entity's key must omit the final identifier in its path and
- // must not be reserved/read-only.
- repeated Entity insert_auto_id = 4;
- // Keys of entities to delete.
- // Each key must have a complete key path and must not be reserved/read-only.
- repeated Key delete = 5;
- // Ignore a user specified read-only period. Optional.
- optional bool force = 6;
-}
-
-// The result of applying a mutation.
-message MutationResult {
- // Number of index writes.
- required int32 index_updates = 1;
- // Keys for insertAutoId entities. One per entity from the
- // request, in the same order.
- repeated Key insert_auto_id_key = 2;
-}
-
-// Options shared by read requests.
-message ReadOptions {
- enum ReadConsistency {
- DEFAULT = 0;
- STRONG = 1;
- EVENTUAL = 2;
- }
-
- // The read consistency to use.
- // Cannot be set when transaction is set.
- // Lookup and ancestor queries default to STRONG, global queries default to
- // EVENTUAL and cannot be set to STRONG.
- optional ReadConsistency read_consistency = 1 [default=DEFAULT];
-
- // The transaction to use. Optional.
- optional bytes /* serialized Transaction */ transaction = 2;
-}
-
-// The request for Lookup.
-message LookupRequest {
-
- // Options for this lookup request. Optional.
- optional ReadOptions read_options = 1;
- // Keys of entities to look up from the datastore.
- repeated Key key = 3;
-}
-
-// The response for Lookup.
-message LookupResponse {
-
- // The order of results in these fields is undefined and has no relation to
- // the order of the keys in the input.
-
- // Entities found as ResultType.FULL entities.
- repeated EntityResult found = 1;
-
- // Entities not found as ResultType.KEY_ONLY entities.
- repeated EntityResult missing = 2;
-
- // A list of keys that were not looked up due to resource constraints.
- repeated Key deferred = 3;
-}
-
-
-// The request for RunQuery.
-message RunQueryRequest {
-
- // The options for this query.
- optional ReadOptions read_options = 1;
-
- // Entities are partitioned into subsets, identified by a dataset (usually
- // implicitly specified by the project) and namespace ID. Queries are scoped
- // to a single partition.
- // This partition ID is normalized with the standard default context
- // partition ID, but all other partition IDs in RunQueryRequest are
- // normalized with this partition ID as the context partition ID.
- optional PartitionId partition_id = 2;
-
- // The query to run.
- // Either this field or field gql_query must be set, but not both.
- optional Query query = 3;
- // The GQL query to run.
- // Either this field or field query must be set, but not both.
- optional GqlQuery gql_query = 7;
-}
-
-// The response for RunQuery.
-message RunQueryResponse {
-
- // A batch of query results (always present).
- optional QueryResultBatch batch = 1;
-
-}
-
-// The request for BeginTransaction.
-message BeginTransactionRequest {
-
- enum IsolationLevel {
- SNAPSHOT = 0; // Read from a consistent snapshot. Concurrent transactions
- // conflict if their mutations conflict. For example:
- // Read(A),Write(B) may not conflict with Read(B),Write(A),
- // but Read(B),Write(B) does conflict with Read(B),Write(B).
- SERIALIZABLE = 1; // Read from a consistent snapshot. Concurrent
- // transactions conflict if they cannot be serialized.
- // For example Read(A),Write(B) does conflict with
- // Read(B),Write(A) but Read(A) may not conflict with
- // Write(A).
- }
-
- // The transaction isolation level.
- optional IsolationLevel isolation_level = 1 [default=SNAPSHOT];
-}
-
-// The response for BeginTransaction.
-message BeginTransactionResponse {
-
- // The transaction identifier (always present).
- optional bytes /* serialized Transaction */ transaction = 1;
-}
-
-// The request for Rollback.
-message RollbackRequest {
-
- // The transaction identifier, returned by a call to
- // beginTransaction.
- required bytes /* serialized Transaction */ transaction = 1;
-}
-
-// The response for Rollback.
-message RollbackResponse {
-// Empty
-}
-
-// The request for Commit.
-message CommitRequest {
-
- enum Mode {
- TRANSACTIONAL = 1;
- NON_TRANSACTIONAL = 2;
- }
-
- // The transaction identifier, returned by a call to
- // beginTransaction. Must be set when mode is TRANSACTIONAL.
- optional bytes /* serialized Transaction */ transaction = 1;
- // The mutation to perform. Optional.
- optional Mutation mutation = 2;
- // The type of commit to perform. Either TRANSACTIONAL or NON_TRANSACTIONAL.
- optional Mode mode = 5 [default=TRANSACTIONAL];
-}
-
-// The response for Commit.
-message CommitResponse {
-
- // The result of performing the mutation (if any).
- optional MutationResult mutation_result = 1;
-}
-
-// The request for AllocateIds.
-message AllocateIdsRequest {
-
- // A list of keys with incomplete key paths to allocate IDs for.
- // No key may be reserved/read-only.
- repeated Key key = 1;
-}
-
-// The response for AllocateIds.
-message AllocateIdsResponse {
-
- // The keys specified in the request (in the same order), each with
- // its key path completed with a newly allocated ID.
- repeated Key key = 1;
-}
-
-// Each rpc normalizes the partition IDs of the keys in its input entities,
-// and always returns entities with keys with normalized partition IDs.
-// (Note that applies to all entities, including entities in values.)
-service DatastoreService {
- // Look up some entities by key.
- rpc Lookup(LookupRequest) returns (LookupResponse) {
- };
- // Query for entities.
- rpc RunQuery(RunQueryRequest) returns (RunQueryResponse) {
- };
- // Begin a new transaction.
- rpc BeginTransaction(BeginTransactionRequest) returns (BeginTransactionResponse) {
- };
- // Commit a transaction, optionally creating, deleting or modifying some
- // entities.
- rpc Commit(CommitRequest) returns (CommitResponse) {
- };
- // Roll back a transaction.
- rpc Rollback(RollbackRequest) returns (RollbackResponse) {
- };
- // Allocate IDs for incomplete keys (useful for referencing an entity before
- // it is inserted).
- rpc AllocateIds(AllocateIdsRequest) returns (AllocateIdsResponse) {
- };
-}
diff --git a/vendor/google.golang.org/cloud/internal/opts/option.go b/vendor/google.golang.org/cloud/internal/opts/option.go
deleted file mode 100644
index 844d3104..00000000
--- a/vendor/google.golang.org/cloud/internal/opts/option.go
+++ /dev/null
@@ -1,25 +0,0 @@
-// Package opts holds the DialOpts struct, configurable by
-// cloud.ClientOptions to set up transports for cloud packages.
-//
-// This is a separate page to prevent cycles between the core
-// cloud packages.
-package opts
-
-import (
- "net/http"
-
- "golang.org/x/oauth2"
- "google.golang.org/grpc"
-)
-
-type DialOpt struct {
- Endpoint string
- Scopes []string
- UserAgent string
-
- TokenSource oauth2.TokenSource
-
- HTTPClient *http.Client
- GRPCClient *grpc.ClientConn
- GRPCDialOpts []grpc.DialOption
-}
diff --git a/vendor/google.golang.org/cloud/internal/testutil/context.go b/vendor/google.golang.org/cloud/internal/testutil/context.go
deleted file mode 100644
index 34e60589..00000000
--- a/vendor/google.golang.org/cloud/internal/testutil/context.go
+++ /dev/null
@@ -1,60 +0,0 @@
-// Copyright 2014 Google Inc. All Rights Reserved.
-//
-// Licensed under the Apache License, Version 2.0 (the "License");
-// you may not use this file except in compliance with the License.
-// You may obtain a copy of the License at
-//
-// http://www.apache.org/licenses/LICENSE-2.0
-//
-// Unless required by applicable law or agreed to in writing, software
-// distributed under the License is distributed on an "AS IS" BASIS,
-// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-// See the License for the specific language governing permissions and
-// limitations under the License.
-
-// Package testutil contains helper functions for writing tests.
-package testutil
-
-import (
- "io/ioutil"
- "log"
- "os"
-
- "golang.org/x/net/context"
- "golang.org/x/oauth2"
- "golang.org/x/oauth2/google"
-)
-
-const (
- envProjID = "GCLOUD_TESTS_GOLANG_PROJECT_ID"
- envPrivateKey = "GCLOUD_TESTS_GOLANG_KEY"
-)
-
-// ProjID returns the project ID to use in integration tests, or the empty
-// string if none is configured.
-func ProjID() string {
- projID := os.Getenv(envProjID)
- if projID == "" {
- return ""
- }
- return projID
-}
-
-// TokenSource returns the OAuth2 token source to use in integration tests,
-// or nil if none is configured. TokenSource will log.Fatal if the token
-// source is specified but missing or invalid.
-func TokenSource(ctx context.Context, scopes ...string) oauth2.TokenSource {
- key := os.Getenv(envPrivateKey)
- if key == "" {
- return nil
- }
- jsonKey, err := ioutil.ReadFile(key)
- if err != nil {
- log.Fatalf("Cannot read the JSON key file, err: %v", err)
- }
- conf, err := google.JWTConfigFromJSON(jsonKey, scopes...)
- if err != nil {
- log.Fatalf("google.JWTConfigFromJSON: %v", err)
- }
- return conf.TokenSource(ctx)
-}
diff --git a/vendor/google.golang.org/cloud/internal/transport/cancelreq.go b/vendor/google.golang.org/cloud/internal/transport/cancelreq.go
deleted file mode 100644
index ddae71cc..00000000
--- a/vendor/google.golang.org/cloud/internal/transport/cancelreq.go
+++ /dev/null
@@ -1,29 +0,0 @@
-// Copyright 2015 Google Inc. All Rights Reserved.
-//
-// Licensed under the Apache License, Version 2.0 (the "License");
-// you may not use this file except in compliance with the License.
-// You may obtain a copy of the License at
-//
-// http://www.apache.org/licenses/LICENSE-2.0
-//
-// Unless required by applicable law or agreed to in writing, software
-// distributed under the License is distributed on an "AS IS" BASIS,
-// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-// See the License for the specific language governing permissions and
-// limitations under the License.
-
-// +build go1.5
-
-package transport
-
-import "net/http"
-
-// makeReqCancel returns a closure that cancels the given http.Request
-// when called.
-func makeReqCancel(req *http.Request) func(http.RoundTripper) {
- c := make(chan struct{})
- req.Cancel = c
- return func(http.RoundTripper) {
- close(c)
- }
-}
diff --git a/vendor/google.golang.org/cloud/internal/transport/cancelreq_legacy.go b/vendor/google.golang.org/cloud/internal/transport/cancelreq_legacy.go
deleted file mode 100644
index c11a4dde..00000000
--- a/vendor/google.golang.org/cloud/internal/transport/cancelreq_legacy.go
+++ /dev/null
@@ -1,31 +0,0 @@
-// Copyright 2015 Google Inc. All Rights Reserved.
-//
-// Licensed under the Apache License, Version 2.0 (the "License");
-// you may not use this file except in compliance with the License.
-// You may obtain a copy of the License at
-//
-// http://www.apache.org/licenses/LICENSE-2.0
-//
-// Unless required by applicable law or agreed to in writing, software
-// distributed under the License is distributed on an "AS IS" BASIS,
-// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-// See the License for the specific language governing permissions and
-// limitations under the License.
-
-// +build !go1.5
-
-package transport
-
-import "net/http"
-
-// makeReqCancel returns a closure that cancels the given http.Request
-// when called.
-func makeReqCancel(req *http.Request) func(http.RoundTripper) {
- // Go 1.4 and prior do not have a reliable way of cancelling a request.
- // Transport.CancelRequest will only work if the request is already in-flight.
- return func(r http.RoundTripper) {
- if t, ok := r.(*http.Transport); ok {
- t.CancelRequest(req)
- }
- }
-}
diff --git a/vendor/google.golang.org/cloud/internal/transport/dial.go b/vendor/google.golang.org/cloud/internal/transport/dial.go
deleted file mode 100644
index ae2baf9f..00000000
--- a/vendor/google.golang.org/cloud/internal/transport/dial.go
+++ /dev/null
@@ -1,135 +0,0 @@
-// Copyright 2015 Google Inc. All Rights Reserved.
-//
-// Licensed under the Apache License, Version 2.0 (the "License");
-// you may not use this file except in compliance with the License.
-// You may obtain a copy of the License at
-//
-// http://www.apache.org/licenses/LICENSE-2.0
-//
-// Unless required by applicable law or agreed to in writing, software
-// distributed under the License is distributed on an "AS IS" BASIS,
-// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-// See the License for the specific language governing permissions and
-// limitations under the License.
-
-package transport
-
-import (
- "errors"
- "fmt"
- "net/http"
-
- "golang.org/x/net/context"
- "golang.org/x/oauth2"
- "golang.org/x/oauth2/google"
- "google.golang.org/cloud"
- "google.golang.org/cloud/internal/opts"
- "google.golang.org/grpc"
- "google.golang.org/grpc/credentials"
- "google.golang.org/grpc/credentials/oauth"
-)
-
-// ErrHTTP is returned when on a non-200 HTTP response.
-type ErrHTTP struct {
- StatusCode int
- Body []byte
- err error
-}
-
-func (e *ErrHTTP) Error() string {
- if e.err == nil {
- return fmt.Sprintf("error during call, http status code: %v %s", e.StatusCode, e.Body)
- }
- return e.err.Error()
-}
-
-// NewHTTPClient returns an HTTP client for use communicating with a Google cloud
-// service, configured with the given ClientOptions. It also returns the endpoint
-// for the service as specified in the options.
-func NewHTTPClient(ctx context.Context, opt ...cloud.ClientOption) (*http.Client, string, error) {
- var o opts.DialOpt
- for _, opt := range opt {
- opt.Resolve(&o)
- }
- if o.GRPCClient != nil {
- return nil, "", errors.New("unsupported GRPC base transport specified")
- }
- // TODO(djd): Wrap all http.Clients with appropriate internal version to add
- // UserAgent header and prepend correct endpoint.
- if o.HTTPClient != nil {
- return o.HTTPClient, o.Endpoint, nil
- }
- if o.TokenSource == nil {
- var err error
- o.TokenSource, err = google.DefaultTokenSource(ctx, o.Scopes...)
- if err != nil {
- return nil, "", fmt.Errorf("google.DefaultTokenSource: %v", err)
- }
- }
- return oauth2.NewClient(ctx, o.TokenSource), o.Endpoint, nil
-}
-
-// NewProtoClient returns a ProtoClient for communicating with a Google cloud service,
-// configured with the given ClientOptions.
-func NewProtoClient(ctx context.Context, opt ...cloud.ClientOption) (*ProtoClient, error) {
- var o opts.DialOpt
- for _, opt := range opt {
- opt.Resolve(&o)
- }
- if o.GRPCClient != nil {
- return nil, errors.New("unsupported GRPC base transport specified")
- }
- var client *http.Client
- switch {
- case o.HTTPClient != nil:
- if o.TokenSource != nil {
- return nil, errors.New("at most one of WithTokenSource or WithBaseHTTP may be provided")
- }
- client = o.HTTPClient
- case o.TokenSource != nil:
- client = oauth2.NewClient(ctx, o.TokenSource)
- default:
- var err error
- client, err = google.DefaultClient(ctx, o.Scopes...)
- if err != nil {
- return nil, err
- }
- }
-
- return &ProtoClient{
- client: client,
- endpoint: o.Endpoint,
- userAgent: o.UserAgent,
- }, nil
-}
-
-// DialGRPC returns a GRPC connection for use communicating with a Google cloud
-// service, configured with the given ClientOptions.
-func DialGRPC(ctx context.Context, opt ...cloud.ClientOption) (*grpc.ClientConn, error) {
- var o opts.DialOpt
- for _, opt := range opt {
- opt.Resolve(&o)
- }
- if o.HTTPClient != nil {
- return nil, errors.New("unsupported HTTP base transport specified")
- }
- if o.GRPCClient != nil {
- return o.GRPCClient, nil
- }
- if o.TokenSource == nil {
- var err error
- o.TokenSource, err = google.DefaultTokenSource(ctx, o.Scopes...)
- if err != nil {
- return nil, fmt.Errorf("google.DefaultTokenSource: %v", err)
- }
- }
- grpcOpts := []grpc.DialOption{
- grpc.WithPerRPCCredentials(oauth.TokenSource{o.TokenSource}),
- grpc.WithTransportCredentials(credentials.NewClientTLSFromCert(nil, "")),
- }
- grpcOpts = append(grpcOpts, o.GRPCDialOpts...)
- if o.UserAgent != "" {
- grpcOpts = append(grpcOpts, grpc.WithUserAgent(o.UserAgent))
- }
- return grpc.Dial(o.Endpoint, grpcOpts...)
-}
diff --git a/vendor/google.golang.org/cloud/internal/transport/proto.go b/vendor/google.golang.org/cloud/internal/transport/proto.go
deleted file mode 100644
index 05b11cde..00000000
--- a/vendor/google.golang.org/cloud/internal/transport/proto.go
+++ /dev/null
@@ -1,80 +0,0 @@
-// Copyright 2015 Google Inc. All Rights Reserved.
-//
-// Licensed under the Apache License, Version 2.0 (the "License");
-// you may not use this file except in compliance with the License.
-// You may obtain a copy of the License at
-//
-// http://www.apache.org/licenses/LICENSE-2.0
-//
-// Unless required by applicable law or agreed to in writing, software
-// distributed under the License is distributed on an "AS IS" BASIS,
-// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-// See the License for the specific language governing permissions and
-// limitations under the License.
-
-package transport
-
-import (
- "bytes"
- "io/ioutil"
- "net/http"
-
- "github.com/golang/protobuf/proto"
- "golang.org/x/net/context"
-)
-
-type ProtoClient struct {
- client *http.Client
- endpoint string
- userAgent string
-}
-
-func (c *ProtoClient) Call(ctx context.Context, method string, req, resp proto.Message) error {
- payload, err := proto.Marshal(req)
- if err != nil {
- return err
- }
-
- httpReq, err := http.NewRequest("POST", c.endpoint+method, bytes.NewReader(payload))
- if err != nil {
- return err
- }
- httpReq.Header.Set("Content-Type", "application/x-protobuf")
- if ua := c.userAgent; ua != "" {
- httpReq.Header.Set("User-Agent", ua)
- }
-
- errc := make(chan error, 1)
- cancel := makeReqCancel(httpReq)
-
- go func() {
- r, err := c.client.Do(httpReq)
- if err != nil {
- errc <- err
- return
- }
- defer r.Body.Close()
-
- body, err := ioutil.ReadAll(r.Body)
- if r.StatusCode != http.StatusOK {
- err = &ErrHTTP{
- StatusCode: r.StatusCode,
- Body: body,
- err: err,
- }
- }
- if err != nil {
- errc <- err
- return
- }
- errc <- proto.Unmarshal(body, resp)
- }()
-
- select {
- case <-ctx.Done():
- cancel(c.client.Transport) // Cancel the HTTP request.
- return ctx.Err()
- case err := <-errc:
- return err
- }
-}
diff --git a/vendor/google.golang.org/grpc/.travis.yml b/vendor/google.golang.org/grpc/.travis.yml
index 055d6641..9bc2c127 100644
--- a/vendor/google.golang.org/grpc/.travis.yml
+++ b/vendor/google.golang.org/grpc/.travis.yml
@@ -1,5 +1,9 @@
language: go
+go:
+ - 1.5.3
+ - 1.6
+
before_install:
- go get github.com/axw/gocov/gocov
- go get github.com/mattn/goveralls
diff --git a/vendor/google.golang.org/grpc/CONTRIBUTING.md b/vendor/google.golang.org/grpc/CONTRIBUTING.md
index 407d384a..36cd6f75 100644
--- a/vendor/google.golang.org/grpc/CONTRIBUTING.md
+++ b/vendor/google.golang.org/grpc/CONTRIBUTING.md
@@ -1,16 +1,39 @@
# How to contribute
-We definitely welcome patches and contribution to grpc! Here is some guideline
+We definitely welcome patches and contribution to grpc! Here are some guidelines
and information about how to do so.
-## Getting started
+## Sending patches
-### Legal requirements
+### Getting started
+
+1. Check out the code:
+
+ $ go get google.golang.org/grpc
+ $ cd $GOPATH/src/google.golang.org/grpc
+
+1. Create a fork of the grpc-go repository.
+1. Add your fork as a remote:
+
+ $ git remote add fork git@github.com:$YOURGITHUBUSERNAME/grpc-go.git
+
+1. Make changes, commit them.
+1. Run the test suite:
+
+ $ make test
+
+1. Push your changes to your fork:
+
+ $ git push fork ...
+
+1. Open a pull request.
+
+## Legal requirements
In order to protect both you and ourselves, you will need to sign the
[Contributor License Agreement](https://cla.developers.google.com/clas).
-### Filing Issues
+## Filing Issues
When filing an issue, make sure to answer these five questions:
1. What version of Go are you using (`go version`)?
diff --git a/vendor/google.golang.org/grpc/Documentation/grpc-auth-support.md b/vendor/google.golang.org/grpc/Documentation/grpc-auth-support.md
index 5a075f61..5312b572 100644
--- a/vendor/google.golang.org/grpc/Documentation/grpc-auth-support.md
+++ b/vendor/google.golang.org/grpc/Documentation/grpc-auth-support.md
@@ -5,7 +5,7 @@ As outlined in the [gRPC authentication guide](http://www.grpc.io/docs/guides/au
# Enabling TLS on a gRPC client
```Go
-conn, err := grpc.Dial(serverAddr, grpc.WithTransportCredentials(credentials.NewClientTLSFromCert(nil, ""))
+conn, err := grpc.Dial(serverAddr, grpc.WithTransportCredentials(credentials.NewClientTLSFromCert(nil, "")))
```
# Enabling TLS on a gRPC server
diff --git a/vendor/google.golang.org/grpc/Documentation/grpc-metadata.md b/vendor/google.golang.org/grpc/Documentation/grpc-metadata.md
new file mode 100644
index 00000000..b387e880
--- /dev/null
+++ b/vendor/google.golang.org/grpc/Documentation/grpc-metadata.md
@@ -0,0 +1,200 @@
+# Metadata
+
+gRPC supports sending metadata between client and server.
+This doc shows how to send and receive metadata in gRPC-go.
+
+## Background
+
+Four kinds of service method:
+
+- [Unary RPC](http://www.grpc.io/docs/guides/concepts.html#unary-rpc)
+- [Server streaming RPC](http://www.grpc.io/docs/guides/concepts.html#server-streaming-rpc)
+- [Client streaming RPC](http://www.grpc.io/docs/guides/concepts.html#client-streaming-rpc)
+- [Bidirectional streaming RPC](http://www.grpc.io/docs/guides/concepts.html#bidirectional-streaming-rpc)
+
+And concept of [metadata](http://www.grpc.io/docs/guides/concepts.html#metadata).
+
+## Constructing metadata
+
+A metadata can be created using package [metadata](https://godoc.org/google.golang.org/grpc/metadata).
+The type MD is actually a map from string to a list of strings:
+
+```go
+type MD map[string][]string
+```
+
+Metadata can be read like a normal map.
+Note that the value type of this map is `[]string`,
+so that users can attach multiple values using a single key.
+
+### Creating a new metadata
+
+A metadata can be created from a `map[string]string` using function `New`:
+
+```go
+md := metadata.New(map[string]string{"key1": "val1", "key2": "val2"})
+```
+
+Another way is to use `Pairs`.
+Values with the same key will be merged into a list:
+
+```go
+md := metadata.Pairs(
+ "key1", "val1",
+ "key1", "val1-2", // "key1" will have map value []string{"val1", "val1-2"}
+ "key2", "val2",
+)
+```
+
+__Note:__ all the keys will be automatically converted to lowercase,
+so "key1" and "kEy1" will be the same key and their values will be merged into the same list.
+This happens for both `New` and `Pairs`.
+
+### Storing binary data in metadata
+
+In metadata, keys are always strings. But values can be strings or binary data.
+To store binary data value in metadata, simply add "-bin" surfix to the key.
+The values with "-bin" surffixed keys will be encoded when creating the metadata:
+
+```go
+md := metadata.Pairs(
+ "key", "string value",
+ "key-bin", string([]byte{96, 102}), // this binary data will be encoded (base64) before sending
+ // and will be decoded after being transferred.
+)
+```
+
+## Retrieving metadata from context
+
+Metadata can be retrieved from context using `FromContext`:
+
+```go
+func (s *server) SomeRPC(ctx context.Context, in *pb.SomeRequest) (*pb.SomeResponse, err) {
+ md := metadata.FromContext(ctx)
+}
+```
+
+## Sending and receiving metadata - client side
+
+[//]: # "TODO: uncomment next line after example source added"
+[//]: # "Real metadata sending and receiving examples are available [here](TODO:example_dir)."
+
+### Sending metadata
+
+To send metadata to server, the client can wrap the metadata into a context using `NewContext`, and make the RPC with this context:
+
+```go
+md := metadata.Pairs("key", "val")
+
+// create a new context with this metadata
+ctx := metadata.NewContext(context.Background(), md)
+
+// make unary RPC
+response, err := client.SomeRPC(ctx, someRequest)
+
+// or make streaming RPC
+stream, err := client.SomeStreamingRPC(ctx)
+```
+### Receiving metadata
+
+Metadata that a client can receive includes header and trailer.
+
+#### Unary call
+
+Header and trailer sent along with a unary call can be retrieved using function [Header](https://godoc.org/google.golang.org/grpc#Header) and [Trailer](https://godoc.org/google.golang.org/grpc#Trailer) in [CallOption](https://godoc.org/google.golang.org/grpc#CallOption):
+
+```go
+var header, trailer metadata.MD // variable to store header and trailer
+r, err := client.SomeRPC(
+ ctx,
+ someRequest,
+ grpc.Header(&header), // will retrieve header
+ grpc.Trailer(&trailer), // will retrieve trailer
+)
+
+// do something with header and trailer
+```
+
+#### Streaming call
+
+For streaming calls including:
+
+- Server streaming RPC
+- Client streaming RPC
+- Bidirectional streaming RPC
+
+Header and trailer can be retrieved from the returned stream using function `Header` and `Trailer` in interface [ClientStream](https://godoc.org/google.golang.org/grpc#ClientStream):
+
+```go
+stream, err := client.SomeStreamingRPC(ctx)
+
+// retrieve header
+header, err := stream.Header()
+
+// retrieve trailer
+trailer := stream.Trailer()
+
+```
+
+## Sending and receiving metadata - server side
+
+[//]: # "TODO: uncomment next line after example source added"
+[//]: # "Real metadata sending and receiving examples are available [here](TODO:example_dir)."
+
+### Receiving metadata
+
+To read metadata sent by the client, the server needs to retrieve it from RPC context.
+If it is a unary call, the RPC handler's context can be used.
+For streaming calls, the server needs to get context from the stream.
+
+#### Unary call
+
+```go
+func (s *server) SomeRPC(ctx context.Context, in *pb.someRequest) (*pb.someResponse, error) {
+ md, ok := metadata.FromContext(ctx)
+ // do something with metadata
+}
+```
+
+#### Streaming call
+
+```go
+func (s *server) SomeStreamingRPC(stream pb.Service_SomeStreamingRPCServer) error {
+ md, ok := metadata.FromContext(stream.Context()) // get context from stream
+ // do something with metadata
+}
+```
+
+### Sending metadata
+
+#### Unary call
+
+To send header and trailer to client in unary call, the server can call [SendHeader](https://godoc.org/google.golang.org/grpc#SendHeader) and [SetTrailer](https://godoc.org/google.golang.org/grpc#SetTrailer) functions in module [grpc](https://godoc.org/google.golang.org/grpc).
+These two functions take a context as the first parameter.
+It should be the RPC handler's context or one derived from it:
+
+```go
+func (s *server) SomeRPC(ctx context.Context, in *pb.someRequest) (*pb.someResponse, error) {
+ // create and send header
+ header := metadata.Pairs("header-key", "val")
+ grpc.SendHeader(ctx, header)
+ // create and set trailer
+ trailer := metadata.Pairs("trailer-key", "val")
+ grpc.SetTrailer(ctx, trailer)
+}
+```
+
+#### Streaming call
+
+For streaming calls, header and trailer can be sent using function `SendHeader` and `SetTrailer` in interface [ServerStream](https://godoc.org/google.golang.org/grpc#ServerStream):
+
+```go
+func (s *server) SomeStreamingRPC(stream pb.Service_SomeStreamingRPCServer) error {
+ // create and send header
+ header := metadata.Pairs("header-key", "val")
+ stream.SendHeader(header)
+ // create and set trailer
+ trailer := metadata.Pairs("trailer-key", "val")
+ stream.SetTrailer(trailer)
+}
+```
diff --git a/vendor/google.golang.org/grpc/Makefile b/vendor/google.golang.org/grpc/Makefile
index 12e84e4e..d26eb908 100644
--- a/vendor/google.golang.org/grpc/Makefile
+++ b/vendor/google.golang.org/grpc/Makefile
@@ -1,15 +1,3 @@
-.PHONY: \
- all \
- deps \
- updatedeps \
- testdeps \
- updatetestdeps \
- build \
- proto \
- test \
- testrace \
- clean \
-
all: test testrace
deps:
@@ -32,7 +20,7 @@ proto:
echo "error: protoc not installed" >&2; \
exit 1; \
fi
- go get -v github.com/golang/protobuf/protoc-gen-go
+ go get -u -v github.com/golang/protobuf/protoc-gen-go
for file in $$(git ls-files '*.proto'); do \
protoc -I $$(dirname $$file) --go_out=plugins=grpc:$$(dirname $$file) $$file; \
done
@@ -44,7 +32,20 @@ testrace: testdeps
go test -v -race -cpu 1,4 google.golang.org/grpc/...
clean:
- go clean google.golang.org/grpc/...
+ go clean -i google.golang.org/grpc/...
coverage: testdeps
./coverage.sh --coveralls
+
+.PHONY: \
+ all \
+ deps \
+ updatedeps \
+ testdeps \
+ updatetestdeps \
+ build \
+ proto \
+ test \
+ testrace \
+ clean \
+ coverage
diff --git a/vendor/google.golang.org/grpc/README.md b/vendor/google.golang.org/grpc/README.md
index 37b05f09..90e9453d 100644
--- a/vendor/google.golang.org/grpc/README.md
+++ b/vendor/google.golang.org/grpc/README.md
@@ -7,7 +7,7 @@ The Go implementation of [gRPC](http://www.grpc.io/): A high performance, open s
Installation
------------
-To install this package, you need to install Go 1.4 or above and setup your Go workspace on your computer. The simplest way to install the library is to run:
+To install this package, you need to install Go and setup your Go workspace on your computer. The simplest way to install the library is to run:
```
$ go get google.golang.org/grpc
@@ -16,7 +16,7 @@ $ go get google.golang.org/grpc
Prerequisites
-------------
-This requires Go 1.4 or above.
+This requires Go 1.5 or later .
Constraints
-----------
diff --git a/vendor/google.golang.org/grpc/backoff.go b/vendor/google.golang.org/grpc/backoff.go
new file mode 100644
index 00000000..d0113ec9
--- /dev/null
+++ b/vendor/google.golang.org/grpc/backoff.go
@@ -0,0 +1,68 @@
+package grpc
+
+import (
+ "math/rand"
+ "time"
+)
+
+// DefaultBackoffConfig uses values specified for backoff in
+// https://github.com/grpc/grpc/blob/master/doc/connection-backoff.md.
+var (
+ DefaultBackoffConfig = &BackoffConfig{
+ MaxDelay: 120 * time.Second,
+ baseDelay: 1.0 * time.Second,
+ factor: 1.6,
+ jitter: 0.2,
+ }
+)
+
+// backoffStrategy defines the methodology for backing off after a grpc
+// connection failure.
+//
+// This is unexported until the GRPC project decides whether or not to allow
+// alternative backoff strategies. Once a decision is made, this type and its
+// method may be exported.
+type backoffStrategy interface {
+ // backoff returns the amount of time to wait before the next retry given
+ // the number of consecutive failures.
+ backoff(retries int) time.Duration
+}
+
+// BackoffConfig defines the parameters for the default GRPC backoff strategy.
+type BackoffConfig struct {
+ // MaxDelay is the upper bound of backoff delay.
+ MaxDelay time.Duration
+
+ // TODO(stevvooe): The following fields are not exported, as allowing changes
+
+ // baseDelay is the amount of time to wait before retrying after the first
+ // failure.
+ baseDelay time.Duration
+
+ // factor is applied to the backoff after each retry.
+ factor float64
+
+ // jitter provides a range to randomize backoff delays.
+ jitter float64
+}
+
+func (bc *BackoffConfig) backoff(retries int) (t time.Duration) {
+ if retries == 0 {
+ return bc.baseDelay
+ }
+ backoff, max := float64(bc.baseDelay), float64(bc.MaxDelay)
+ for backoff < max && retries > 0 {
+ backoff *= bc.factor
+ retries--
+ }
+ if backoff > max {
+ backoff = max
+ }
+ // Randomize backoff delays so that if a cluster of requests start at
+ // the same time, they won't operate in lockstep.
+ backoff *= 1 + bc.jitter*(rand.Float64()*2-1)
+ if backoff < 0 {
+ return 0
+ }
+ return time.Duration(backoff)
+}
diff --git a/vendor/google.golang.org/grpc/call.go b/vendor/google.golang.org/grpc/call.go
index 504a6e18..9d0fc8ee 100644
--- a/vendor/google.golang.org/grpc/call.go
+++ b/vendor/google.golang.org/grpc/call.go
@@ -97,8 +97,9 @@ func sendRequest(ctx context.Context, codec Codec, compressor Compressor, callHd
return stream, nil
}
-// Invoke is called by the generated code. It sends the RPC request on the
-// wire and returns after response is received.
+// Invoke sends the RPC request on the wire and returns after response is received.
+// Invoke is called by generated code. Also users can call Invoke directly when it
+// is really needed in their use cases.
func Invoke(ctx context.Context, method string, args, reply interface{}, cc *ClientConn, opts ...CallOption) (err error) {
var c callInfo
for _, o := range opts {
@@ -185,6 +186,6 @@ func Invoke(ctx context.Context, method string, args, reply interface{}, cc *Cli
if lastErr != nil {
return toRPCErr(lastErr)
}
- return Errorf(stream.StatusCode(), stream.StatusDesc())
+ return Errorf(stream.StatusCode(), "%s", stream.StatusDesc())
}
}
diff --git a/vendor/google.golang.org/grpc/call_test.go b/vendor/google.golang.org/grpc/call_test.go
index 0a224f06..7d01f457 100644
--- a/vendor/google.golang.org/grpc/call_test.go
+++ b/vendor/google.golang.org/grpc/call_test.go
@@ -52,7 +52,9 @@ import (
var (
expectedRequest = "ping"
expectedResponse = "pong"
+ weirdError = "format verbs: %v%s"
sizeLargeErr = 1024 * 1024
+ canceled = 0
)
type testCodec struct {
@@ -95,6 +97,15 @@ func (h *testStreamHandler) handleStream(t *testing.T, s *transport.Stream) {
t.Errorf("Failed to unmarshal the received message: %v", err)
return
}
+ if v == "weird error" {
+ h.t.WriteStatus(s, codes.Internal, weirdError)
+ return
+ }
+ if v == "canceled" {
+ canceled++
+ h.t.WriteStatus(s, codes.Internal, "")
+ return
+ }
if v != expectedRequest {
h.t.WriteStatus(s, codes.Internal, strings.Repeat("A", sizeLargeErr))
return
@@ -122,7 +133,7 @@ func newTestServer() *server {
return &server{startedErr: make(chan error, 1)}
}
-// start starts server. Other goroutines should block on s.startedErr for futher operations.
+// start starts server. Other goroutines should block on s.startedErr for further operations.
func (s *server) start(t *testing.T, port int, maxStreams uint32) {
var err error
if port == 0 {
@@ -223,3 +234,36 @@ func TestInvokeLargeErr(t *testing.T) {
cc.Close()
server.stop()
}
+
+// TestInvokeErrorSpecialChars checks that error messages don't get mangled.
+func TestInvokeErrorSpecialChars(t *testing.T) {
+ server, cc := setUp(t, 0, math.MaxUint32)
+ var reply string
+ req := "weird error"
+ err := Invoke(context.Background(), "/foo/bar", &req, &reply, cc)
+ if _, ok := err.(rpcError); !ok {
+ t.Fatalf("grpc.Invoke(_, _, _, _, _) receives non rpc error.")
+ }
+ if got, want := ErrorDesc(err), weirdError; got != want {
+ t.Fatalf("grpc.Invoke(_, _, _, _, _) error = %q, want %q", got, want)
+ }
+ cc.Close()
+ server.stop()
+}
+
+// TestInvokeCancel checks that an Invoke with a canceled context is not sent.
+func TestInvokeCancel(t *testing.T) {
+ server, cc := setUp(t, 0, math.MaxUint32)
+ var reply string
+ req := "canceled"
+ for i := 0; i < 100; i++ {
+ ctx, cancel := context.WithCancel(context.Background())
+ cancel()
+ Invoke(ctx, "/foo/bar", &req, &reply, cc)
+ }
+ if canceled != 0 {
+ t.Fatalf("received %d of 100 canceled requests", canceled)
+ }
+ cc.Close()
+ server.stop()
+}
diff --git a/vendor/google.golang.org/grpc/clientconn.go b/vendor/google.golang.org/grpc/clientconn.go
index 15d7af6c..1562c0f9 100644
--- a/vendor/google.golang.org/grpc/clientconn.go
+++ b/vendor/google.golang.org/grpc/clientconn.go
@@ -52,10 +52,10 @@ var (
// ErrUnspecTarget indicates that the target address is unspecified.
ErrUnspecTarget = errors.New("grpc: target is unspecified")
// ErrNoTransportSecurity indicates that there is no transport security
- // being set for ClientConn. Users should either set one or explicityly
+ // being set for ClientConn. Users should either set one or explicitly
// call WithInsecure DialOption to disable security.
ErrNoTransportSecurity = errors.New("grpc: no transport security set (use grpc.WithInsecure() explicitly or set credentials)")
- // ErrCredentialsMisuse indicates that users want to transmit security infomation
+ // ErrCredentialsMisuse indicates that users want to transmit security information
// (e.g., oauth2 token) which requires secure connection on an insecure
// connection.
ErrCredentialsMisuse = errors.New("grpc: the credentials require transport level security (use grpc.WithTransportAuthenticator() to set)")
@@ -75,6 +75,7 @@ type dialOptions struct {
codec Codec
cp Compressor
dc Decompressor
+ bs backoffStrategy
picker Picker
block bool
insecure bool
@@ -114,6 +115,22 @@ func WithPicker(p Picker) DialOption {
}
}
+// WithBackoffConfig configures the dialer to use the provided backoff
+// parameters after connection failures.
+func WithBackoffConfig(b *BackoffConfig) DialOption {
+ return withBackoff(b)
+}
+
+// withBackoff sets the backoff strategy used for retries after a
+// failed connection attempt.
+//
+// This can be exported if arbitrary backoff strategies are allowed by GRPC.
+func withBackoff(bs backoffStrategy) DialOption {
+ return func(o *dialOptions) {
+ o.bs = bs
+ }
+}
+
// WithBlock returns a DialOption which makes caller of Dial blocks until the underlying
// connection is up. Without this, Dial returns immediately and connecting the server
// happens in background.
@@ -180,6 +197,11 @@ func Dial(target string, opts ...DialOption) (*ClientConn, error) {
// Set the default codec.
cc.dopts.codec = protoCodec{}
}
+
+ if cc.dopts.bs == nil {
+ cc.dopts.bs = DefaultBackoffConfig
+ }
+
if cc.dopts.picker == nil {
cc.dopts.picker = &unicastPicker{
target: target,
@@ -288,10 +310,9 @@ func NewConn(cc *ClientConn) (*Conn, error) {
if !c.dopts.insecure {
var ok bool
for _, cd := range c.dopts.copts.AuthOptions {
- if _, ok := cd.(credentials.TransportAuthenticator); !ok {
- continue
+ if _, ok = cd.(credentials.TransportAuthenticator); ok {
+ break
}
- ok = true
}
if !ok {
return nil, ErrNoTransportSecurity
@@ -416,7 +437,7 @@ func (cc *Conn) resetTransport(closeTransport bool) error {
return ErrClientConnTimeout
}
}
- sleepTime := backoff(retries)
+ sleepTime := cc.dopts.bs.backoff(retries)
timeout := sleepTime
if timeout < minConnectTimeout {
timeout = minConnectTimeout
diff --git a/vendor/google.golang.org/grpc/examples/helloworld/greeter_client/main.go b/vendor/google.golang.org/grpc/examples/helloworld/greeter_client/main.go
index 1e02ab15..a451c99d 100644
--- a/vendor/google.golang.org/grpc/examples/helloworld/greeter_client/main.go
+++ b/vendor/google.golang.org/grpc/examples/helloworld/greeter_client/main.go
@@ -37,9 +37,9 @@ import (
"log"
"os"
- pb "google.golang.org/grpc/examples/helloworld/helloworld"
"golang.org/x/net/context"
"google.golang.org/grpc"
+ pb "google.golang.org/grpc/examples/helloworld/helloworld"
)
const (
diff --git a/vendor/google.golang.org/grpc/examples/helloworld/greeter_server/main.go b/vendor/google.golang.org/grpc/examples/helloworld/greeter_server/main.go
index 66010a51..4dce9e07 100644
--- a/vendor/google.golang.org/grpc/examples/helloworld/greeter_server/main.go
+++ b/vendor/google.golang.org/grpc/examples/helloworld/greeter_server/main.go
@@ -37,9 +37,9 @@ import (
"log"
"net"
- pb "google.golang.org/grpc/examples/helloworld/helloworld"
"golang.org/x/net/context"
"google.golang.org/grpc"
+ pb "google.golang.org/grpc/examples/helloworld/helloworld"
)
const (
diff --git a/vendor/google.golang.org/grpc/interop/client/client.go b/vendor/google.golang.org/grpc/interop/client/client.go
index deb9c3d8..e05854c7 100644
--- a/vendor/google.golang.org/grpc/interop/client/client.go
+++ b/vendor/google.golang.org/grpc/interop/client/client.go
@@ -125,47 +125,61 @@ func main() {
switch *testCase {
case "empty_unary":
interop.DoEmptyUnaryCall(tc)
+ grpclog.Println("EmptyUnaryCall done")
case "large_unary":
interop.DoLargeUnaryCall(tc)
+ grpclog.Println("LargeUnaryCall done")
case "client_streaming":
interop.DoClientStreaming(tc)
+ grpclog.Println("ClientStreaming done")
case "server_streaming":
interop.DoServerStreaming(tc)
+ grpclog.Println("ServerStreaming done")
case "ping_pong":
interop.DoPingPong(tc)
+ grpclog.Println("Pingpong done")
case "empty_stream":
interop.DoEmptyStream(tc)
+ grpclog.Println("Emptystream done")
case "timeout_on_sleeping_server":
interop.DoTimeoutOnSleepingServer(tc)
+ grpclog.Println("TimeoutOnSleepingServer done")
case "compute_engine_creds":
if !*useTLS {
grpclog.Fatalf("TLS is not enabled. TLS is required to execute compute_engine_creds test case.")
}
interop.DoComputeEngineCreds(tc, *defaultServiceAccount, *oauthScope)
+ grpclog.Println("ComputeEngineCreds done")
case "service_account_creds":
if !*useTLS {
grpclog.Fatalf("TLS is not enabled. TLS is required to execute service_account_creds test case.")
}
interop.DoServiceAccountCreds(tc, *serviceAccountKeyFile, *oauthScope)
+ grpclog.Println("ServiceAccountCreds done")
case "jwt_token_creds":
if !*useTLS {
grpclog.Fatalf("TLS is not enabled. TLS is required to execute jwt_token_creds test case.")
}
interop.DoJWTTokenCreds(tc, *serviceAccountKeyFile)
+ grpclog.Println("JWTtokenCreds done")
case "per_rpc_creds":
if !*useTLS {
grpclog.Fatalf("TLS is not enabled. TLS is required to execute per_rpc_creds test case.")
}
interop.DoPerRPCCreds(tc, *serviceAccountKeyFile, *oauthScope)
+ grpclog.Println("PerRPCCreds done")
case "oauth2_auth_token":
if !*useTLS {
grpclog.Fatalf("TLS is not enabled. TLS is required to execute oauth2_auth_token test case.")
}
interop.DoOauth2TokenCreds(tc, *serviceAccountKeyFile, *oauthScope)
+ grpclog.Println("Oauth2TokenCreds done")
case "cancel_after_begin":
interop.DoCancelAfterBegin(tc)
+ grpclog.Println("CancelAfterBegin done")
case "cancel_after_first_response":
interop.DoCancelAfterFirstResponse(tc)
+ grpclog.Println("CancelAfterFirstResponse done")
default:
grpclog.Fatal("Unsupported test case: ", *testCase)
}
diff --git a/vendor/google.golang.org/grpc/interop/test_utils.go b/vendor/google.golang.org/grpc/interop/test_utils.go
index 6a73d6f4..23340ab8 100644
--- a/vendor/google.golang.org/grpc/interop/test_utils.go
+++ b/vendor/google.golang.org/grpc/interop/test_utils.go
@@ -85,7 +85,6 @@ func DoEmptyUnaryCall(tc testpb.TestServiceClient) {
if !proto.Equal(&testpb.Empty{}, reply) {
grpclog.Fatalf("/TestService/EmptyCall receives %v, want %v", reply, testpb.Empty{})
}
- grpclog.Println("EmptyUnaryCall done")
}
// DoLargeUnaryCall performs a unary RPC with large payload in the request and response.
@@ -105,7 +104,6 @@ func DoLargeUnaryCall(tc testpb.TestServiceClient) {
if t != testpb.PayloadType_COMPRESSABLE || s != largeRespSize {
grpclog.Fatalf("Got the reply with type %d len %d; want %d, %d", t, s, testpb.PayloadType_COMPRESSABLE, largeRespSize)
}
- grpclog.Println("LargeUnaryCall done")
}
// DoClientStreaming performs a client streaming RPC.
@@ -134,7 +132,6 @@ func DoClientStreaming(tc testpb.TestServiceClient) {
if reply.GetAggregatedPayloadSize() != int32(sum) {
grpclog.Fatalf("%v.CloseAndRecv().GetAggregatePayloadSize() = %v; want %v", stream, reply.GetAggregatedPayloadSize(), sum)
}
- grpclog.Println("ClientStreaming done")
}
// DoServerStreaming performs a server streaming RPC.
@@ -179,7 +176,6 @@ func DoServerStreaming(tc testpb.TestServiceClient) {
if respCnt != len(respSizes) {
grpclog.Fatalf("Got %d reply, want %d", len(respSizes), respCnt)
}
- grpclog.Println("ServerStreaming done")
}
// DoPingPong performs ping-pong style bi-directional streaming RPC.
@@ -224,7 +220,6 @@ func DoPingPong(tc testpb.TestServiceClient) {
if _, err := stream.Recv(); err != io.EOF {
grpclog.Fatalf("%v failed to complele the ping pong test: %v", stream, err)
}
- grpclog.Println("Pingpong done")
}
// DoEmptyStream sets up a bi-directional streaming with zero message.
@@ -239,7 +234,6 @@ func DoEmptyStream(tc testpb.TestServiceClient) {
if _, err := stream.Recv(); err != io.EOF {
grpclog.Fatalf("%v failed to complete the empty stream test: %v", stream, err)
}
- grpclog.Println("Emptystream done")
}
// DoTimeoutOnSleepingServer performs an RPC on a sleep server which causes RPC timeout.
@@ -248,7 +242,6 @@ func DoTimeoutOnSleepingServer(tc testpb.TestServiceClient) {
stream, err := tc.FullDuplexCall(ctx)
if err != nil {
if grpc.Code(err) == codes.DeadlineExceeded {
- grpclog.Println("TimeoutOnSleepingServer done")
return
}
grpclog.Fatalf("%v.FullDuplexCall(_) = _, %v", tc, err)
@@ -264,7 +257,6 @@ func DoTimeoutOnSleepingServer(tc testpb.TestServiceClient) {
if _, err := stream.Recv(); grpc.Code(err) != codes.DeadlineExceeded {
grpclog.Fatalf("%v.Recv() = _, %v, want error code %d", stream, err, codes.DeadlineExceeded)
}
- grpclog.Println("TimeoutOnSleepingServer done")
}
// DoComputeEngineCreds performs a unary RPC with compute engine auth.
@@ -289,7 +281,6 @@ func DoComputeEngineCreds(tc testpb.TestServiceClient, serviceAccount, oauthScop
if !strings.Contains(oauthScope, scope) {
grpclog.Fatalf("Got OAuth scope %q which is NOT a substring of %q.", scope, oauthScope)
}
- grpclog.Println("ComputeEngineCreds done")
}
func getServiceAccountJSONKey(keyFile string) []byte {
@@ -323,7 +314,6 @@ func DoServiceAccountCreds(tc testpb.TestServiceClient, serviceAccountKeyFile, o
if !strings.Contains(oauthScope, scope) {
grpclog.Fatalf("Got OAuth scope %q which is NOT a substring of %q.", scope, oauthScope)
}
- grpclog.Println("ServiceAccountCreds done")
}
// DoJWTTokenCreds performs a unary RPC with JWT token auth.
@@ -344,7 +334,6 @@ func DoJWTTokenCreds(tc testpb.TestServiceClient, serviceAccountKeyFile string)
if !strings.Contains(string(jsonKey), user) {
grpclog.Fatalf("Got user name %q which is NOT a substring of %q.", user, jsonKey)
}
- grpclog.Println("JWTtokenCreds done")
}
// GetToken obtains an OAUTH token from the input.
@@ -384,7 +373,6 @@ func DoOauth2TokenCreds(tc testpb.TestServiceClient, serviceAccountKeyFile, oaut
if !strings.Contains(oauthScope, scope) {
grpclog.Fatalf("Got OAuth scope %q which is NOT a substring of %q.", scope, oauthScope)
}
- grpclog.Println("Oauth2TokenCreds done")
}
// DoPerRPCCreds performs a unary RPC with per RPC OAUTH2 token.
@@ -413,7 +401,6 @@ func DoPerRPCCreds(tc testpb.TestServiceClient, serviceAccountKeyFile, oauthScop
if !strings.Contains(oauthScope, scope) {
grpclog.Fatalf("Got OAuth scope %q which is NOT a substring of %q.", scope, oauthScope)
}
- grpclog.Println("PerRPCCreds done")
}
var (
@@ -435,7 +422,6 @@ func DoCancelAfterBegin(tc testpb.TestServiceClient) {
if grpc.Code(err) != codes.Canceled {
grpclog.Fatalf("%v.CloseAndRecv() got error code %d, want %d", stream, grpc.Code(err), codes.Canceled)
}
- grpclog.Println("CancelAfterBegin done")
}
// DoCancelAfterFirstResponse cancels the RPC after receiving the first message from the server.
@@ -466,7 +452,6 @@ func DoCancelAfterFirstResponse(tc testpb.TestServiceClient) {
if _, err := stream.Recv(); grpc.Code(err) != codes.Canceled {
grpclog.Fatalf("%v compleled with error code %d, want %d", stream, grpc.Code(err), codes.Canceled)
}
- grpclog.Println("CancelAfterFirstResponse done")
}
type testServer struct {
diff --git a/vendor/google.golang.org/grpc/rpc_util.go b/vendor/google.golang.org/grpc/rpc_util.go
index 96c790be..8ad335eb 100644
--- a/vendor/google.golang.org/grpc/rpc_util.go
+++ b/vendor/google.golang.org/grpc/rpc_util.go
@@ -41,9 +41,7 @@ import (
"io"
"io/ioutil"
"math"
- "math/rand"
"os"
- "time"
"github.com/golang/protobuf/proto"
"golang.org/x/net/context"
@@ -325,7 +323,7 @@ type rpcError struct {
}
func (e rpcError) Error() string {
- return fmt.Sprintf("rpc error: code = %d desc = %q", e.code, e.desc)
+ return fmt.Sprintf("rpc error: code = %d desc = %s", e.code, e.desc)
}
// Code returns the error code for err if it was produced by the rpc system.
@@ -411,38 +409,6 @@ func convertCode(err error) codes.Code {
return codes.Unknown
}
-const (
- // how long to wait after the first failure before retrying
- baseDelay = 1.0 * time.Second
- // upper bound of backoff delay
- maxDelay = 120 * time.Second
- // backoff increases by this factor on each retry
- backoffFactor = 1.6
- // backoff is randomized downwards by this factor
- backoffJitter = 0.2
-)
-
-func backoff(retries int) (t time.Duration) {
- if retries == 0 {
- return baseDelay
- }
- backoff, max := float64(baseDelay), float64(maxDelay)
- for backoff < max && retries > 0 {
- backoff *= backoffFactor
- retries--
- }
- if backoff > max {
- backoff = max
- }
- // Randomize backoff delays so that if a cluster of requests start at
- // the same time, they won't operate in lockstep.
- backoff *= 1 + backoffJitter*(rand.Float64()*2-1)
- if backoff < 0 {
- return 0
- }
- return time.Duration(backoff)
-}
-
// SupportPackageIsVersion1 is referenced from generated protocol buffer files
// to assert that that code is compatible with this version of the grpc package.
//
diff --git a/vendor/google.golang.org/grpc/stream.go b/vendor/google.golang.org/grpc/stream.go
index dba7f6c4..b8320788 100644
--- a/vendor/google.golang.org/grpc/stream.go
+++ b/vendor/google.golang.org/grpc/stream.go
@@ -67,7 +67,8 @@ type Stream interface {
// breaks.
// On error, it aborts the stream and returns an RPC status on client
// side. On server side, it simply returns the error to the caller.
- // SendMsg is called by generated code.
+ // SendMsg is called by generated code. Also Users can call SendMsg
+ // directly when it is really needed in their use cases.
SendMsg(m interface{}) error
// RecvMsg blocks until it receives a message or the stream is
// done. On client side, it returns io.EOF when the stream is done. On
@@ -257,7 +258,7 @@ func (cs *clientStream) RecvMsg(m interface{}) (err error) {
cs.finish(err)
return nil
}
- return Errorf(cs.s.StatusCode(), cs.s.StatusDesc())
+ return Errorf(cs.s.StatusCode(), "%s", cs.s.StatusDesc())
}
return toRPCErr(err)
}
@@ -269,7 +270,7 @@ func (cs *clientStream) RecvMsg(m interface{}) (err error) {
// Returns io.EOF to indicate the end of the stream.
return
}
- return Errorf(cs.s.StatusCode(), cs.s.StatusDesc())
+ return Errorf(cs.s.StatusCode(), "%s", cs.s.StatusDesc())
}
return toRPCErr(err)
}
diff --git a/vendor/google.golang.org/grpc/test/end2end_test.go b/vendor/google.golang.org/grpc/test/end2end_test.go
index 86c921fc..88f1dce2 100644
--- a/vendor/google.golang.org/grpc/test/end2end_test.go
+++ b/vendor/google.golang.org/grpc/test/end2end_test.go
@@ -80,6 +80,10 @@ var (
"tkey1": []string{"trailerValue1"},
"tkey2": []string{"trailerValue2"},
}
+ // capital "Key" is illegal in HTTP/2.
+ malformedHTTP2Metadata = metadata.MD{
+ "Key": []string{"foo"},
+ }
testAppUA = "myApp1/1.0 myApp2/0.9"
)
@@ -333,7 +337,7 @@ func TestReconnectTimeout(t *testing.T) {
return
}
}()
- // Block untill reconnect times out.
+ // Block until reconnect times out.
<-waitC
if err := conn.Close(); err != grpc.ErrClientConnClosing {
t.Fatalf("%v.Close() = %v, want %v", conn, err, grpc.ErrClientConnClosing)
@@ -677,6 +681,10 @@ func testHealthCheckOnFailure(t *testing.T, e env) {
func TestHealthCheckOff(t *testing.T) {
defer leakCheck(t)()
for _, e := range listTestEnv() {
+ // TODO(bradfitz): Temporarily skip this env due to #619.
+ if e.name == "handler-tls" {
+ continue
+ }
testHealthCheckOff(t, e)
}
}
@@ -687,7 +695,7 @@ func testHealthCheckOff(t *testing.T, e env) {
defer te.tearDown()
want := grpc.Errorf(codes.Unimplemented, "unknown service grpc.health.v1.Health")
if _, err := healthCheck(1*time.Second, te.clientConn(), ""); err != want {
- t.Fatalf("Health/Check(_, _) = _, %v, want _, error %v", err, want)
+ t.Fatalf("Health/Check(_, _) = _, %v, want _, %v", err, want)
}
}
@@ -889,6 +897,37 @@ func testMetadataUnaryRPC(t *testing.T, e env) {
}
}
+// TestMalformedHTTP2Metedata verfies the returned error when the client
+// sends an illegal metadata.
+func TestMalformedHTTP2Metadata(t *testing.T) {
+ defer leakCheck(t)()
+ for _, e := range listTestEnv() {
+ testMalformedHTTP2Metadata(t, e)
+ }
+}
+
+func testMalformedHTTP2Metadata(t *testing.T, e env) {
+ te := newTest(t, e)
+ te.startServer()
+ defer te.tearDown()
+ tc := testpb.NewTestServiceClient(te.clientConn())
+
+ payload, err := newPayload(testpb.PayloadType_COMPRESSABLE, 2718)
+ if err != nil {
+ t.Fatal(err)
+ }
+
+ req := &testpb.SimpleRequest{
+ ResponseType: testpb.PayloadType_COMPRESSABLE.Enum(),
+ ResponseSize: proto.Int32(314),
+ Payload: payload,
+ }
+ ctx := metadata.NewContext(context.Background(), malformedHTTP2Metadata)
+ if _, err := tc.UnaryCall(ctx, req); grpc.Code(err) != codes.Internal {
+ t.Fatalf("TestService.UnaryCall(%v, _) = _, %v; want _, %q", ctx, err, codes.Internal)
+ }
+}
+
func performOneRPC(t *testing.T, tc testpb.TestServiceClient, wg *sync.WaitGroup) {
defer wg.Done()
const argSize = 2718
diff --git a/vendor/google.golang.org/grpc/transport/control.go b/vendor/google.golang.org/grpc/transport/control.go
index f6b38a5a..7e9bdf33 100644
--- a/vendor/google.golang.org/grpc/transport/control.go
+++ b/vendor/google.golang.org/grpc/transport/control.go
@@ -56,43 +56,33 @@ type windowUpdate struct {
increment uint32
}
-func (windowUpdate) isItem() bool {
- return true
-}
+func (*windowUpdate) item() {}
type settings struct {
ack bool
ss []http2.Setting
}
-func (settings) isItem() bool {
- return true
-}
+func (*settings) item() {}
type resetStream struct {
streamID uint32
code http2.ErrCode
}
-func (resetStream) isItem() bool {
- return true
-}
+func (*resetStream) item() {}
type flushIO struct {
}
-func (flushIO) isItem() bool {
- return true
-}
+func (*flushIO) item() {}
type ping struct {
ack bool
data [8]byte
}
-func (ping) isItem() bool {
- return true
-}
+func (*ping) item() {}
// quotaPool is a pool which accumulates the quota and sends it to acquire()
// when it is available.
@@ -172,10 +162,6 @@ func (qb *quotaPool) acquire() <-chan int {
type inFlow struct {
// The inbound flow control limit for pending data.
limit uint32
- // conn points to the shared connection-level inFlow that is shared
- // by all streams on that conn. It is nil for the inFlow on the conn
- // directly.
- conn *inFlow
mu sync.Mutex
// pendingData is the overall data which have been received but not been
@@ -186,75 +172,39 @@ type inFlow struct {
pendingUpdate uint32
}
-// onData is invoked when some data frame is received. It increments not only its
-// own pendingData but also that of the associated connection-level flow.
+// onData is invoked when some data frame is received. It updates pendingData.
func (f *inFlow) onData(n uint32) error {
- if n == 0 {
- return nil
- }
f.mu.Lock()
defer f.mu.Unlock()
- if f.pendingData+f.pendingUpdate+n > f.limit {
- return fmt.Errorf("recieved %d-bytes data exceeding the limit %d bytes", f.pendingData+f.pendingUpdate+n, f.limit)
- }
- if f.conn != nil {
- if err := f.conn.onData(n); err != nil {
- return ConnectionErrorf("%v", err)
- }
- }
f.pendingData += n
+ if f.pendingData+f.pendingUpdate > f.limit {
+ return fmt.Errorf("received %d-bytes data exceeding the limit %d bytes", f.pendingData+f.pendingUpdate, f.limit)
+ }
return nil
}
-// connOnRead updates the connection level states when the application consumes data.
-func (f *inFlow) connOnRead(n uint32) uint32 {
- if n == 0 || f.conn != nil {
- return 0
- }
+// onRead is invoked when the application reads the data. It returns the window size
+// to be sent to the peer.
+func (f *inFlow) onRead(n uint32) uint32 {
f.mu.Lock()
defer f.mu.Unlock()
+ if f.pendingData == 0 {
+ return 0
+ }
f.pendingData -= n
f.pendingUpdate += n
if f.pendingUpdate >= f.limit/4 {
- ret := f.pendingUpdate
+ wu := f.pendingUpdate
f.pendingUpdate = 0
- return ret
+ return wu
}
return 0
}
-// onRead is invoked when the application reads the data. It returns the window updates
-// for both stream and connection level.
-func (f *inFlow) onRead(n uint32) (swu, cwu uint32) {
- if n == 0 {
- return
- }
- f.mu.Lock()
- defer f.mu.Unlock()
- if f.pendingData == 0 {
- // pendingData has been adjusted by restoreConn.
- return
- }
- f.pendingData -= n
- f.pendingUpdate += n
- if f.pendingUpdate >= f.limit/4 {
- swu = f.pendingUpdate
- f.pendingUpdate = 0
- }
- cwu = f.conn.connOnRead(n)
- return
-}
-
-// restoreConn is invoked when a stream is terminated. It removes its stake in
-// the connection-level flow and resets its own state.
-func (f *inFlow) restoreConn() uint32 {
- if f.conn == nil {
- return 0
- }
+func (f *inFlow) resetPendingData() uint32 {
f.mu.Lock()
defer f.mu.Unlock()
n := f.pendingData
f.pendingData = 0
- f.pendingUpdate = 0
- return f.conn.connOnRead(n)
+ return n
}
diff --git a/vendor/google.golang.org/grpc/transport/handler_server.go b/vendor/google.golang.org/grpc/transport/handler_server.go
index 63ba0537..fef541db 100644
--- a/vendor/google.golang.org/grpc/transport/handler_server.go
+++ b/vendor/google.golang.org/grpc/transport/handler_server.go
@@ -118,7 +118,7 @@ func NewServerHandlerTransport(w http.ResponseWriter, r *http.Request) (ServerTr
// serverHandlerTransport is an implementation of ServerTransport
// which replies to exactly one gRPC request (exactly one HTTP request),
-// using the net/http.Handler interface. This http.Handler is guranteed
+// using the net/http.Handler interface. This http.Handler is guaranteed
// at this point to be speaking over HTTP/2, so it's able to speak valid
// gRPC.
type serverHandlerTransport struct {
@@ -313,16 +313,22 @@ func (ht *serverHandlerTransport) HandleStreams(startStream func(*Stream)) {
readerDone := make(chan struct{})
go func() {
defer close(readerDone)
- for {
- buf := make([]byte, 1024) // TODO: minimize garbage, optimize recvBuffer code/ownership
+
+ // TODO: minimize garbage, optimize recvBuffer code/ownership
+ const readSize = 8196
+ for buf := make([]byte, readSize); ; {
n, err := req.Body.Read(buf)
if n > 0 {
- s.buf.put(&recvMsg{data: buf[:n]})
+ s.buf.put(&recvMsg{data: buf[:n:n]})
+ buf = buf[n:]
}
if err != nil {
s.buf.put(&recvMsg{err: mapRecvMsgError(err)})
return
}
+ if len(buf) == 0 {
+ buf = make([]byte, readSize)
+ }
}
}()
diff --git a/vendor/google.golang.org/grpc/transport/http2_client.go b/vendor/google.golang.org/grpc/transport/http2_client.go
index 66fabbba..8fc6ed0d 100644
--- a/vendor/google.golang.org/grpc/transport/http2_client.go
+++ b/vendor/google.golang.org/grpc/transport/http2_client.go
@@ -202,17 +202,13 @@ func newHTTP2Client(addr string, opts *ConnectOptions) (_ ClientTransport, err e
}
func (t *http2Client) newStream(ctx context.Context, callHdr *CallHdr) *Stream {
- fc := &inFlow{
- limit: initialWindowSize,
- conn: t.fc,
- }
// TODO(zhaoq): Handle uint32 overflow of Stream.id.
s := &Stream{
id: t.nextID,
method: callHdr.Method,
sendCompress: callHdr.SendCompress,
buf: newRecvBuffer(),
- fc: fc,
+ fc: &inFlow{limit: initialWindowSize},
sendQuotaPool: newQuotaPool(int(t.streamSendQuota)),
headerChan: make(chan struct{}),
}
@@ -236,9 +232,9 @@ func (t *http2Client) NewStream(ctx context.Context, callHdr *CallHdr) (_ *Strea
var timeout time.Duration
if dl, ok := ctx.Deadline(); ok {
timeout = dl.Sub(time.Now())
- if timeout <= 0 {
- return nil, ContextErr(context.DeadlineExceeded)
- }
+ }
+ if err := ctx.Err(); err != nil {
+ return nil, ContextErr(err)
}
pr := &peer.Peer{
Addr: t.conn.RemoteAddr(),
@@ -330,6 +326,8 @@ func (t *http2Client) NewStream(ctx context.Context, callHdr *CallHdr) (_ *Strea
t.hEnc.WriteField(hpack.HeaderField{Name: "grpc-timeout", Value: timeoutEncode(timeout)})
}
for k, v := range authData {
+ // Capital header names are illegal in HTTP/2.
+ k = strings.ToLower(k)
t.hEnc.WriteField(hpack.HeaderField{Name: k, Value: v})
}
var (
@@ -402,8 +400,10 @@ func (t *http2Client) CloseStream(s *Stream, err error) {
// other goroutines.
s.cancel()
s.mu.Lock()
- if q := s.fc.restoreConn(); q > 0 {
- t.controlBuf.put(&windowUpdate{0, q})
+ if q := s.fc.resetPendingData(); q > 0 {
+ if n := t.fc.onRead(q); n > 0 {
+ t.controlBuf.put(&windowUpdate{0, n})
+ }
}
if s.state == streamDone {
s.mu.Unlock()
@@ -503,6 +503,10 @@ func (t *http2Client) Write(s *Stream, data []byte, opts *Options) error {
t.framer.adjustNumWriters(1)
// Got some quota. Try to acquire writing privilege on the transport.
if _, err := wait(s.ctx, t.shutdownChan, t.writableChan); err != nil {
+ if _, ok := err.(StreamError); ok {
+ // Return the connection quota back.
+ t.sendQuotaPool.add(len(p))
+ }
if t.framer.adjustNumWriters(-1) == 0 {
// This writer is the last one in this batch and has the
// responsibility to flush the buffered frames. It queues
@@ -512,6 +516,14 @@ func (t *http2Client) Write(s *Stream, data []byte, opts *Options) error {
}
return err
}
+ if s.ctx.Err() != nil {
+ t.sendQuotaPool.add(len(p))
+ if t.framer.adjustNumWriters(-1) == 0 {
+ t.controlBuf.put(&flushIO{})
+ }
+ t.writableChan <- 0
+ return ContextErr(s.ctx.Err())
+ }
if r.Len() == 0 && t.framer.adjustNumWriters(0) == 1 {
// Do a force flush iff this is last frame for the entire gRPC message
// and the caller is the only writer at this moment.
@@ -558,33 +570,39 @@ func (t *http2Client) getStream(f http2.Frame) (*Stream, bool) {
// Window updates will deliver to the controller for sending when
// the cumulative quota exceeds the corresponding threshold.
func (t *http2Client) updateWindow(s *Stream, n uint32) {
- swu, cwu := s.fc.onRead(n)
- if swu > 0 {
- t.controlBuf.put(&windowUpdate{s.id, swu})
+ if w := t.fc.onRead(n); w > 0 {
+ t.controlBuf.put(&windowUpdate{0, w})
}
- if cwu > 0 {
- t.controlBuf.put(&windowUpdate{0, cwu})
+ if w := s.fc.onRead(n); w > 0 {
+ t.controlBuf.put(&windowUpdate{s.id, w})
}
}
func (t *http2Client) handleData(f *http2.DataFrame) {
+ size := len(f.Data())
+ if err := t.fc.onData(uint32(size)); err != nil {
+ t.notifyError(ConnectionErrorf("%v", err))
+ return
+ }
// Select the right stream to dispatch.
s, ok := t.getStream(f)
if !ok {
+ if w := t.fc.onRead(uint32(size)); w > 0 {
+ t.controlBuf.put(&windowUpdate{0, w})
+ }
return
}
- size := len(f.Data())
if size > 0 {
+ s.mu.Lock()
+ if s.state == streamDone {
+ s.mu.Unlock()
+ // The stream has been closed. Release the corresponding quota.
+ if w := t.fc.onRead(uint32(size)); w > 0 {
+ t.controlBuf.put(&windowUpdate{0, w})
+ }
+ return
+ }
if err := s.fc.onData(uint32(size)); err != nil {
- if _, ok := err.(ConnectionError); ok {
- t.notifyError(err)
- return
- }
- s.mu.Lock()
- if s.state == streamDone {
- s.mu.Unlock()
- return
- }
s.state = streamDone
s.statusCode = codes.Internal
s.statusDesc = err.Error()
@@ -593,6 +611,7 @@ func (t *http2Client) handleData(f *http2.DataFrame) {
t.controlBuf.put(&resetStream{s.id, http2.ErrCodeFlowControl})
return
}
+ s.mu.Unlock()
// TODO(bradfitz, zhaoq): A copy is required here because there is no
// guarantee f.Data() is consumed before the arrival of next frame.
// Can this copy be eliminated?
@@ -634,6 +653,7 @@ func (t *http2Client) handleRSTStream(f *http2.RSTStreamFrame) {
s.statusCode, ok = http2ErrConvTab[http2.ErrCode(f.ErrCode)]
if !ok {
grpclog.Println("transport: http2Client.handleRSTStream found no mapped gRPC status for the received http2 error ", f.ErrCode)
+ s.statusCode = codes.Unknown
}
s.mu.Unlock()
s.write(recvMsg{err: io.EOF})
@@ -719,14 +739,14 @@ func (t *http2Client) operateHeaders(frame *http2.MetaHeadersFrame) {
s.write(recvMsg{err: io.EOF})
}
-func handleMalformedHTTP2(s *Stream, err http2.StreamError) {
+func handleMalformedHTTP2(s *Stream, err error) {
s.mu.Lock()
if !s.headerDone {
close(s.headerChan)
s.headerDone = true
}
s.mu.Unlock()
- s.write(recvMsg{err: StreamErrorf(http2ErrConvTab[err.Code], "%v", err)})
+ s.write(recvMsg{err: err})
}
// reader runs as a separate goroutine in charge of reading data from network
@@ -761,7 +781,8 @@ func (t *http2Client) reader() {
s := t.activeStreams[se.StreamID]
t.mu.Unlock()
if s != nil {
- handleMalformedHTTP2(s, se)
+ // use error detail to provide better err message
+ handleMalformedHTTP2(s, StreamErrorf(http2ErrConvTab[se.Code], "%v", t.framer.errorDetail()))
}
continue
} else {
diff --git a/vendor/google.golang.org/grpc/transport/http2_server.go b/vendor/google.golang.org/grpc/transport/http2_server.go
index cec441cf..df918d8d 100644
--- a/vendor/google.golang.org/grpc/transport/http2_server.go
+++ b/vendor/google.golang.org/grpc/transport/http2_server.go
@@ -139,15 +139,11 @@ func newHTTP2Server(conn net.Conn, maxStreams uint32, authInfo credentials.AuthI
// operateHeader takes action on the decoded headers.
func (t *http2Server) operateHeaders(frame *http2.MetaHeadersFrame, handle func(*Stream)) {
buf := newRecvBuffer()
- fc := &inFlow{
- limit: initialWindowSize,
- conn: t.fc,
- }
s := &Stream{
id: frame.Header().StreamID,
st: t,
buf: buf,
- fc: fc,
+ fc: &inFlow{limit: initialWindowSize},
}
var state decodeState
@@ -246,6 +242,16 @@ func (t *http2Server) HandleStreams(handle func(*Stream)) {
for {
frame, err := t.framer.readFrame()
if err != nil {
+ if se, ok := err.(http2.StreamError); ok {
+ t.mu.Lock()
+ s := t.activeStreams[se.StreamID]
+ t.mu.Unlock()
+ if s != nil {
+ t.closeStream(s)
+ }
+ t.controlBuf.put(&resetStream{se.StreamID, se.Code})
+ continue
+ }
t.Close()
return
}
@@ -297,33 +303,46 @@ func (t *http2Server) getStream(f http2.Frame) (*Stream, bool) {
// Window updates will deliver to the controller for sending when
// the cumulative quota exceeds the corresponding threshold.
func (t *http2Server) updateWindow(s *Stream, n uint32) {
- swu, cwu := s.fc.onRead(n)
- if swu > 0 {
- t.controlBuf.put(&windowUpdate{s.id, swu})
+ if w := t.fc.onRead(n); w > 0 {
+ t.controlBuf.put(&windowUpdate{0, w})
}
- if cwu > 0 {
- t.controlBuf.put(&windowUpdate{0, cwu})
+ if w := s.fc.onRead(n); w > 0 {
+ t.controlBuf.put(&windowUpdate{s.id, w})
}
}
func (t *http2Server) handleData(f *http2.DataFrame) {
+ size := len(f.Data())
+ if err := t.fc.onData(uint32(size)); err != nil {
+ grpclog.Printf("transport: http2Server %v", err)
+ t.Close()
+ return
+ }
// Select the right stream to dispatch.
s, ok := t.getStream(f)
if !ok {
+ if w := t.fc.onRead(uint32(size)); w > 0 {
+ t.controlBuf.put(&windowUpdate{0, w})
+ }
return
}
- size := len(f.Data())
if size > 0 {
- if err := s.fc.onData(uint32(size)); err != nil {
- if _, ok := err.(ConnectionError); ok {
- grpclog.Printf("transport: http2Server %v", err)
- t.Close()
- return
+ s.mu.Lock()
+ if s.state == streamDone {
+ s.mu.Unlock()
+ // The stream has been closed. Release the corresponding quota.
+ if w := t.fc.onRead(uint32(size)); w > 0 {
+ t.controlBuf.put(&windowUpdate{0, w})
}
+ return
+ }
+ if err := s.fc.onData(uint32(size)); err != nil {
+ s.mu.Unlock()
t.closeStream(s)
t.controlBuf.put(&resetStream{s.id, http2.ErrCodeFlowControl})
return
}
+ s.mu.Unlock()
// TODO(bradfitz, zhaoq): A copy is required here because there is no
// guarantee f.Data() is consumed before the arrival of next frame.
// Can this copy be eliminated?
@@ -497,6 +516,10 @@ func (t *http2Server) Write(s *Stream, data []byte, opts *Options) error {
// TODO(zhaoq): Support multi-writers for a single stream.
var writeHeaderFrame bool
s.mu.Lock()
+ if s.state == streamDone {
+ s.mu.Unlock()
+ return StreamErrorf(codes.Unknown, "the stream has been done")
+ }
if !s.headerOk {
writeHeaderFrame = true
s.headerOk = true
@@ -564,6 +587,10 @@ func (t *http2Server) Write(s *Stream, data []byte, opts *Options) error {
// Got some quota. Try to acquire writing privilege on the
// transport.
if _, err := wait(s.ctx, t.shutdownChan, t.writableChan); err != nil {
+ if _, ok := err.(StreamError); ok {
+ // Return the connection quota back.
+ t.sendQuotaPool.add(ps)
+ }
if t.framer.adjustNumWriters(-1) == 0 {
// This writer is the last one in this batch and has the
// responsibility to flush the buffered frames. It queues
@@ -573,6 +600,14 @@ func (t *http2Server) Write(s *Stream, data []byte, opts *Options) error {
}
return err
}
+ if s.ctx.Err() != nil {
+ t.sendQuotaPool.add(ps)
+ if t.framer.adjustNumWriters(-1) == 0 {
+ t.controlBuf.put(&flushIO{})
+ }
+ t.writableChan <- 0
+ return ContextErr(s.ctx.Err())
+ }
var forceFlush bool
if r.Len() == 0 && t.framer.adjustNumWriters(0) == 1 && !opts.Last {
forceFlush = true
@@ -670,20 +705,22 @@ func (t *http2Server) closeStream(s *Stream) {
t.mu.Lock()
delete(t.activeStreams, s.id)
t.mu.Unlock()
- if q := s.fc.restoreConn(); q > 0 {
- t.controlBuf.put(&windowUpdate{0, q})
- }
+ // In case stream sending and receiving are invoked in separate
+ // goroutines (e.g., bi-directional streaming), cancel needs to be
+ // called to interrupt the potential blocking on other goroutines.
+ s.cancel()
s.mu.Lock()
+ if q := s.fc.resetPendingData(); q > 0 {
+ if w := t.fc.onRead(q); w > 0 {
+ t.controlBuf.put(&windowUpdate{0, w})
+ }
+ }
if s.state == streamDone {
s.mu.Unlock()
return
}
s.state = streamDone
s.mu.Unlock()
- // In case stream sending and receiving are invoked in separate
- // goroutines (e.g., bi-directional streaming), cancel needs to be
- // called to interrupt the potential blocking on other goroutines.
- s.cancel()
}
func (t *http2Server) RemoteAddr() net.Addr {
diff --git a/vendor/google.golang.org/grpc/transport/http_util.go b/vendor/google.golang.org/grpc/transport/http_util.go
index 6aabcd4a..7a3594ac 100644
--- a/vendor/google.golang.org/grpc/transport/http_util.go
+++ b/vendor/google.golang.org/grpc/transport/http_util.go
@@ -69,6 +69,7 @@ var (
http2.ErrCodeInternal: codes.Internal,
http2.ErrCodeFlowControl: codes.ResourceExhausted,
http2.ErrCodeSettingsTimeout: codes.Internal,
+ http2.ErrCodeStreamClosed: codes.Internal,
http2.ErrCodeFrameSize: codes.Internal,
http2.ErrCodeRefusedStream: codes.Unavailable,
http2.ErrCodeCancel: codes.Canceled,
@@ -404,3 +405,7 @@ func (f *framer) flushWrite() error {
func (f *framer) readFrame() (http2.Frame, error) {
return f.fr.ReadFrame()
}
+
+func (f *framer) errorDetail() error {
+ return f.fr.ErrorDetail()
+}
diff --git a/vendor/google.golang.org/grpc/transport/transport.go b/vendor/google.golang.org/grpc/transport/transport.go
index f027cae5..d4ca0b7a 100644
--- a/vendor/google.golang.org/grpc/transport/transport.go
+++ b/vendor/google.golang.org/grpc/transport/transport.go
@@ -63,13 +63,11 @@ type recvMsg struct {
err error
}
-func (recvMsg) isItem() bool {
- return true
-}
+func (*recvMsg) item() {}
// All items in an out of a recvBuffer should be the same type.
type item interface {
- isItem() bool
+ item()
}
// recvBuffer is an unbounded channel of item.
@@ -89,12 +87,14 @@ func newRecvBuffer() *recvBuffer {
func (b *recvBuffer) put(r item) {
b.mu.Lock()
defer b.mu.Unlock()
- b.backlog = append(b.backlog, r)
- select {
- case b.c <- b.backlog[0]:
- b.backlog = b.backlog[1:]
- default:
+ if len(b.backlog) == 0 {
+ select {
+ case b.c <- r:
+ return
+ default:
+ }
}
+ b.backlog = append(b.backlog, r)
}
func (b *recvBuffer) load() {
diff --git a/vendor/google.golang.org/grpc/transport/transport_test.go b/vendor/google.golang.org/grpc/transport/transport_test.go
index b8655c02..d63dba31 100644
--- a/vendor/google.golang.org/grpc/transport/transport_test.go
+++ b/vendor/google.golang.org/grpc/transport/transport_test.go
@@ -134,7 +134,7 @@ func (h *testStreamHandler) handleStreamMalformedStatus(t *testing.T, s *Stream)
h.t.WriteStatus(s, codes.Internal, "\n")
}
-// start starts server. Other goroutines should block on s.readyChan for futher operations.
+// start starts server. Other goroutines should block on s.readyChan for further operations.
func (s *server) start(t *testing.T, port int, maxStreams uint32, ht hType) {
var err error
if port == 0 {
@@ -584,8 +584,8 @@ func TestServerWithMisbehavedClient(t *testing.T) {
t.Fatalf("%v got err %v with statusCode %d, want err with statusCode %d", s, err, s.statusCode, code)
}
- if ss.fc.pendingData != 0 || ss.fc.pendingUpdate != 0 || sc.fc.pendingData != 0 || sc.fc.pendingUpdate != initialWindowSize {
- t.Fatalf("Server mistakenly resets inbound flow control params: got %d, %d, %d, %d; want 0, 0, 0, %d", ss.fc.pendingData, ss.fc.pendingUpdate, sc.fc.pendingData, sc.fc.pendingUpdate, initialWindowSize)
+ if ss.fc.pendingData != 0 || ss.fc.pendingUpdate != 0 || sc.fc.pendingData != 0 || sc.fc.pendingUpdate <= initialWindowSize {
+ t.Fatalf("Server mistakenly resets inbound flow control params: got %d, %d, %d, %d; want 0, 0, 0, >%d", ss.fc.pendingData, ss.fc.pendingUpdate, sc.fc.pendingData, sc.fc.pendingUpdate, initialWindowSize)
}
ct.CloseStream(s, nil)
// Test server behavior for violation of connection flow control window size restriction.
@@ -631,15 +631,15 @@ func TestClientWithMisbehavedServer(t *testing.T) {
break
}
}
- if s.fc.pendingData != initialWindowSize || s.fc.pendingUpdate != 0 || conn.fc.pendingData != initialWindowSize || conn.fc.pendingUpdate != 0 {
- t.Fatalf("Client mistakenly updates inbound flow control params: got %d, %d, %d, %d; want %d, %d, %d, %d", s.fc.pendingData, s.fc.pendingUpdate, conn.fc.pendingData, conn.fc.pendingUpdate, initialWindowSize, 0, initialWindowSize, 0)
+ if s.fc.pendingData <= initialWindowSize || s.fc.pendingUpdate != 0 || conn.fc.pendingData <= initialWindowSize || conn.fc.pendingUpdate != 0 {
+ t.Fatalf("Client mistakenly updates inbound flow control params: got %d, %d, %d, %d; want >%d, %d, >%d, %d", s.fc.pendingData, s.fc.pendingUpdate, conn.fc.pendingData, conn.fc.pendingUpdate, initialWindowSize, 0, initialWindowSize, 0)
}
if err != io.EOF || s.statusCode != codes.Internal {
t.Fatalf("Got err %v and the status code %d, want and the code %d", err, s.statusCode, codes.Internal)
}
conn.CloseStream(s, err)
- if s.fc.pendingData != 0 || s.fc.pendingUpdate != 0 || conn.fc.pendingData != 0 || conn.fc.pendingUpdate != initialWindowSize {
- t.Fatalf("Client mistakenly resets inbound flow control params: got %d, %d, %d, %d; want 0, 0, 0, %d", s.fc.pendingData, s.fc.pendingUpdate, conn.fc.pendingData, conn.fc.pendingUpdate, initialWindowSize)
+ if s.fc.pendingData != 0 || s.fc.pendingUpdate != 0 || conn.fc.pendingData != 0 || conn.fc.pendingUpdate <= initialWindowSize {
+ t.Fatalf("Client mistakenly resets inbound flow control params: got %d, %d, %d, %d; want 0, 0, 0, >%d", s.fc.pendingData, s.fc.pendingUpdate, conn.fc.pendingData, conn.fc.pendingUpdate, initialWindowSize)
}
// Test the logic for the violation of the connection flow control window size restriction.
//
@@ -681,7 +681,7 @@ func TestMalformedStatus(t *testing.T) {
t.Fatalf("Failed to write the request: %v", err)
}
p := make([]byte, http2MaxFrameLen)
- expectedErr := StreamErrorf(codes.Internal, "stream error: stream ID 1; PROTOCOL_ERROR")
+ expectedErr := StreamErrorf(codes.Internal, "invalid header field value \"\\n\"")
if _, err = s.dec.Read(p); err != expectedErr {
t.Fatalf("Read the err %v, want %v", err, expectedErr)
}
diff --git a/vendor/gopkg.in/check.v1/.gitignore b/vendor/gopkg.in/check.v1/.gitignore
deleted file mode 100644
index 191a5360..00000000
--- a/vendor/gopkg.in/check.v1/.gitignore
+++ /dev/null
@@ -1,4 +0,0 @@
-_*
-*.swp
-*.[568]
-[568].out
diff --git a/vendor/gopkg.in/check.v1/LICENSE b/vendor/gopkg.in/check.v1/LICENSE
deleted file mode 100644
index 545cf2d3..00000000
--- a/vendor/gopkg.in/check.v1/LICENSE
+++ /dev/null
@@ -1,25 +0,0 @@
-Gocheck - A rich testing framework for Go
-
-Copyright (c) 2010-2013 Gustavo Niemeyer
-
-All rights reserved.
-
-Redistribution and use in source and binary forms, with or without
-modification, are permitted provided that the following conditions are met:
-
-1. Redistributions of source code must retain the above copyright notice, this
- list of conditions and the following disclaimer.
-2. Redistributions in binary form must reproduce the above copyright notice,
- this list of conditions and the following disclaimer in the documentation
- and/or other materials provided with the distribution.
-
-THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
-ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
-WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
-DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR
-ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
-(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
-LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
-ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
-(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
-SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
diff --git a/vendor/gopkg.in/check.v1/README.md b/vendor/gopkg.in/check.v1/README.md
deleted file mode 100644
index 0ca9e572..00000000
--- a/vendor/gopkg.in/check.v1/README.md
+++ /dev/null
@@ -1,20 +0,0 @@
-Instructions
-============
-
-Install the package with:
-
- go get gopkg.in/check.v1
-
-Import it with:
-
- import "gopkg.in/check.v1"
-
-and use _check_ as the package name inside the code.
-
-For more details, visit the project page:
-
-* http://labix.org/gocheck
-
-and the API documentation:
-
-* https://gopkg.in/check.v1
diff --git a/vendor/gopkg.in/check.v1/TODO b/vendor/gopkg.in/check.v1/TODO
deleted file mode 100644
index 33498270..00000000
--- a/vendor/gopkg.in/check.v1/TODO
+++ /dev/null
@@ -1,2 +0,0 @@
-- Assert(slice, Contains, item)
-- Parallel test support
diff --git a/vendor/gopkg.in/check.v1/benchmark.go b/vendor/gopkg.in/check.v1/benchmark.go
deleted file mode 100644
index 46ea9dc6..00000000
--- a/vendor/gopkg.in/check.v1/benchmark.go
+++ /dev/null
@@ -1,187 +0,0 @@
-// Copyright (c) 2012 The Go Authors. All rights reserved.
-//
-// Redistribution and use in source and binary forms, with or without
-// modification, are permitted provided that the following conditions are
-// met:
-//
-// * Redistributions of source code must retain the above copyright
-// notice, this list of conditions and the following disclaimer.
-// * Redistributions in binary form must reproduce the above
-// copyright notice, this list of conditions and the following disclaimer
-// in the documentation and/or other materials provided with the
-// distribution.
-// * Neither the name of Google Inc. nor the names of its
-// contributors may be used to endorse or promote products derived from
-// this software without specific prior written permission.
-//
-// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
-// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
-// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
-// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
-// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
-// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
-// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
-// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
-// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
-// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
-// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
-
-package check
-
-import (
- "fmt"
- "runtime"
- "time"
-)
-
-var memStats runtime.MemStats
-
-// testingB is a type passed to Benchmark functions to manage benchmark
-// timing and to specify the number of iterations to run.
-type timer struct {
- start time.Time // Time test or benchmark started
- duration time.Duration
- N int
- bytes int64
- timerOn bool
- benchTime time.Duration
- // The initial states of memStats.Mallocs and memStats.TotalAlloc.
- startAllocs uint64
- startBytes uint64
- // The net total of this test after being run.
- netAllocs uint64
- netBytes uint64
-}
-
-// StartTimer starts timing a test. This function is called automatically
-// before a benchmark starts, but it can also used to resume timing after
-// a call to StopTimer.
-func (c *C) StartTimer() {
- if !c.timerOn {
- c.start = time.Now()
- c.timerOn = true
-
- runtime.ReadMemStats(&memStats)
- c.startAllocs = memStats.Mallocs
- c.startBytes = memStats.TotalAlloc
- }
-}
-
-// StopTimer stops timing a test. This can be used to pause the timer
-// while performing complex initialization that you don't
-// want to measure.
-func (c *C) StopTimer() {
- if c.timerOn {
- c.duration += time.Now().Sub(c.start)
- c.timerOn = false
- runtime.ReadMemStats(&memStats)
- c.netAllocs += memStats.Mallocs - c.startAllocs
- c.netBytes += memStats.TotalAlloc - c.startBytes
- }
-}
-
-// ResetTimer sets the elapsed benchmark time to zero.
-// It does not affect whether the timer is running.
-func (c *C) ResetTimer() {
- if c.timerOn {
- c.start = time.Now()
- runtime.ReadMemStats(&memStats)
- c.startAllocs = memStats.Mallocs
- c.startBytes = memStats.TotalAlloc
- }
- c.duration = 0
- c.netAllocs = 0
- c.netBytes = 0
-}
-
-// SetBytes informs the number of bytes that the benchmark processes
-// on each iteration. If this is called in a benchmark it will also
-// report MB/s.
-func (c *C) SetBytes(n int64) {
- c.bytes = n
-}
-
-func (c *C) nsPerOp() int64 {
- if c.N <= 0 {
- return 0
- }
- return c.duration.Nanoseconds() / int64(c.N)
-}
-
-func (c *C) mbPerSec() float64 {
- if c.bytes <= 0 || c.duration <= 0 || c.N <= 0 {
- return 0
- }
- return (float64(c.bytes) * float64(c.N) / 1e6) / c.duration.Seconds()
-}
-
-func (c *C) timerString() string {
- if c.N <= 0 {
- return fmt.Sprintf("%3.3fs", float64(c.duration.Nanoseconds())/1e9)
- }
- mbs := c.mbPerSec()
- mb := ""
- if mbs != 0 {
- mb = fmt.Sprintf("\t%7.2f MB/s", mbs)
- }
- nsop := c.nsPerOp()
- ns := fmt.Sprintf("%10d ns/op", nsop)
- if c.N > 0 && nsop < 100 {
- // The format specifiers here make sure that
- // the ones digits line up for all three possible formats.
- if nsop < 10 {
- ns = fmt.Sprintf("%13.2f ns/op", float64(c.duration.Nanoseconds())/float64(c.N))
- } else {
- ns = fmt.Sprintf("%12.1f ns/op", float64(c.duration.Nanoseconds())/float64(c.N))
- }
- }
- memStats := ""
- if c.benchMem {
- allocedBytes := fmt.Sprintf("%8d B/op", int64(c.netBytes)/int64(c.N))
- allocs := fmt.Sprintf("%8d allocs/op", int64(c.netAllocs)/int64(c.N))
- memStats = fmt.Sprintf("\t%s\t%s", allocedBytes, allocs)
- }
- return fmt.Sprintf("%8d\t%s%s%s", c.N, ns, mb, memStats)
-}
-
-func min(x, y int) int {
- if x > y {
- return y
- }
- return x
-}
-
-func max(x, y int) int {
- if x < y {
- return y
- }
- return x
-}
-
-// roundDown10 rounds a number down to the nearest power of 10.
-func roundDown10(n int) int {
- var tens = 0
- // tens = floor(log_10(n))
- for n > 10 {
- n = n / 10
- tens++
- }
- // result = 10^tens
- result := 1
- for i := 0; i < tens; i++ {
- result *= 10
- }
- return result
-}
-
-// roundUp rounds x up to a number of the form [1eX, 2eX, 5eX].
-func roundUp(n int) int {
- base := roundDown10(n)
- if n < (2 * base) {
- return 2 * base
- }
- if n < (5 * base) {
- return 5 * base
- }
- return 10 * base
-}
diff --git a/vendor/gopkg.in/check.v1/benchmark_test.go b/vendor/gopkg.in/check.v1/benchmark_test.go
deleted file mode 100644
index 4dd827c1..00000000
--- a/vendor/gopkg.in/check.v1/benchmark_test.go
+++ /dev/null
@@ -1,91 +0,0 @@
-// These tests verify the test running logic.
-
-package check_test
-
-import (
- "time"
- . "gopkg.in/check.v1"
-)
-
-var benchmarkS = Suite(&BenchmarkS{})
-
-type BenchmarkS struct{}
-
-func (s *BenchmarkS) TestCountSuite(c *C) {
- suitesRun += 1
-}
-
-func (s *BenchmarkS) TestBasicTestTiming(c *C) {
- helper := FixtureHelper{sleepOn: "Test1", sleep: 1000000 * time.Nanosecond}
- output := String{}
- runConf := RunConf{Output: &output, Verbose: true}
- Run(&helper, &runConf)
-
- expected := "PASS: check_test\\.go:[0-9]+: FixtureHelper\\.Test1\t0\\.001s\n" +
- "PASS: check_test\\.go:[0-9]+: FixtureHelper\\.Test2\t0\\.000s\n"
- c.Assert(output.value, Matches, expected)
-}
-
-func (s *BenchmarkS) TestStreamTestTiming(c *C) {
- helper := FixtureHelper{sleepOn: "SetUpSuite", sleep: 1000000 * time.Nanosecond}
- output := String{}
- runConf := RunConf{Output: &output, Stream: true}
- Run(&helper, &runConf)
-
- expected := "(?s).*\nPASS: check_test\\.go:[0-9]+: FixtureHelper\\.SetUpSuite\t *0\\.001s\n.*"
- c.Assert(output.value, Matches, expected)
-}
-
-func (s *BenchmarkS) TestBenchmark(c *C) {
- helper := FixtureHelper{sleep: 100000}
- output := String{}
- runConf := RunConf{
- Output: &output,
- Benchmark: true,
- BenchmarkTime: 10000000,
- Filter: "Benchmark1",
- }
- Run(&helper, &runConf)
- c.Check(helper.calls[0], Equals, "SetUpSuite")
- c.Check(helper.calls[1], Equals, "SetUpTest")
- c.Check(helper.calls[2], Equals, "Benchmark1")
- c.Check(helper.calls[3], Equals, "TearDownTest")
- c.Check(helper.calls[4], Equals, "SetUpTest")
- c.Check(helper.calls[5], Equals, "Benchmark1")
- c.Check(helper.calls[6], Equals, "TearDownTest")
- // ... and more.
-
- expected := "PASS: check_test\\.go:[0-9]+: FixtureHelper\\.Benchmark1\t *100\t *[12][0-9]{5} ns/op\n"
- c.Assert(output.value, Matches, expected)
-}
-
-func (s *BenchmarkS) TestBenchmarkBytes(c *C) {
- helper := FixtureHelper{sleep: 100000}
- output := String{}
- runConf := RunConf{
- Output: &output,
- Benchmark: true,
- BenchmarkTime: 10000000,
- Filter: "Benchmark2",
- }
- Run(&helper, &runConf)
-
- expected := "PASS: check_test\\.go:[0-9]+: FixtureHelper\\.Benchmark2\t *100\t *[12][0-9]{5} ns/op\t *[4-9]\\.[0-9]{2} MB/s\n"
- c.Assert(output.value, Matches, expected)
-}
-
-func (s *BenchmarkS) TestBenchmarkMem(c *C) {
- helper := FixtureHelper{sleep: 100000}
- output := String{}
- runConf := RunConf{
- Output: &output,
- Benchmark: true,
- BenchmarkMem: true,
- BenchmarkTime: 10000000,
- Filter: "Benchmark3",
- }
- Run(&helper, &runConf)
-
- expected := "PASS: check_test\\.go:[0-9]+: FixtureHelper\\.Benchmark3\t *100\t *[12][0-9]{5} ns/op\t *[0-9]+ B/op\t *[1-9] allocs/op\n"
- c.Assert(output.value, Matches, expected)
-}
diff --git a/vendor/gopkg.in/check.v1/bootstrap_test.go b/vendor/gopkg.in/check.v1/bootstrap_test.go
deleted file mode 100644
index e55f327c..00000000
--- a/vendor/gopkg.in/check.v1/bootstrap_test.go
+++ /dev/null
@@ -1,82 +0,0 @@
-// These initial tests are for bootstrapping. They verify that we can
-// basically use the testing infrastructure itself to check if the test
-// system is working.
-//
-// These tests use will break down the test runner badly in case of
-// errors because if they simply fail, we can't be sure the developer
-// will ever see anything (because failing means the failing system
-// somehow isn't working! :-)
-//
-// Do not assume *any* internal functionality works as expected besides
-// what's actually tested here.
-
-package check_test
-
-import (
- "fmt"
- "gopkg.in/check.v1"
- "strings"
-)
-
-type BootstrapS struct{}
-
-var boostrapS = check.Suite(&BootstrapS{})
-
-func (s *BootstrapS) TestCountSuite(c *check.C) {
- suitesRun += 1
-}
-
-func (s *BootstrapS) TestFailedAndFail(c *check.C) {
- if c.Failed() {
- critical("c.Failed() must be false first!")
- }
- c.Fail()
- if !c.Failed() {
- critical("c.Fail() didn't put the test in a failed state!")
- }
- c.Succeed()
-}
-
-func (s *BootstrapS) TestFailedAndSucceed(c *check.C) {
- c.Fail()
- c.Succeed()
- if c.Failed() {
- critical("c.Succeed() didn't put the test back in a non-failed state")
- }
-}
-
-func (s *BootstrapS) TestLogAndGetTestLog(c *check.C) {
- c.Log("Hello there!")
- log := c.GetTestLog()
- if log != "Hello there!\n" {
- critical(fmt.Sprintf("Log() or GetTestLog() is not working! Got: %#v", log))
- }
-}
-
-func (s *BootstrapS) TestLogfAndGetTestLog(c *check.C) {
- c.Logf("Hello %v", "there!")
- log := c.GetTestLog()
- if log != "Hello there!\n" {
- critical(fmt.Sprintf("Logf() or GetTestLog() is not working! Got: %#v", log))
- }
-}
-
-func (s *BootstrapS) TestRunShowsErrors(c *check.C) {
- output := String{}
- check.Run(&FailHelper{}, &check.RunConf{Output: &output})
- if strings.Index(output.value, "Expected failure!") == -1 {
- critical(fmt.Sprintf("RunWithWriter() output did not contain the "+
- "expected failure! Got: %#v",
- output.value))
- }
-}
-
-func (s *BootstrapS) TestRunDoesntShowSuccesses(c *check.C) {
- output := String{}
- check.Run(&SuccessHelper{}, &check.RunConf{Output: &output})
- if strings.Index(output.value, "Expected success!") != -1 {
- critical(fmt.Sprintf("RunWithWriter() output contained a successful "+
- "test! Got: %#v",
- output.value))
- }
-}
diff --git a/vendor/gopkg.in/check.v1/check.go b/vendor/gopkg.in/check.v1/check.go
deleted file mode 100644
index 82c26fa7..00000000
--- a/vendor/gopkg.in/check.v1/check.go
+++ /dev/null
@@ -1,873 +0,0 @@
-// Package check is a rich testing extension for Go's testing package.
-//
-// For details about the project, see:
-//
-// http://labix.org/gocheck
-//
-package check
-
-import (
- "bytes"
- "errors"
- "fmt"
- "io"
- "math/rand"
- "os"
- "path"
- "path/filepath"
- "reflect"
- "regexp"
- "runtime"
- "strconv"
- "strings"
- "sync"
- "sync/atomic"
- "time"
-)
-
-// -----------------------------------------------------------------------
-// Internal type which deals with suite method calling.
-
-const (
- fixtureKd = iota
- testKd
-)
-
-type funcKind int
-
-const (
- succeededSt = iota
- failedSt
- skippedSt
- panickedSt
- fixturePanickedSt
- missedSt
-)
-
-type funcStatus uint32
-
-// A method value can't reach its own Method structure.
-type methodType struct {
- reflect.Value
- Info reflect.Method
-}
-
-func newMethod(receiver reflect.Value, i int) *methodType {
- return &methodType{receiver.Method(i), receiver.Type().Method(i)}
-}
-
-func (method *methodType) PC() uintptr {
- return method.Info.Func.Pointer()
-}
-
-func (method *methodType) suiteName() string {
- t := method.Info.Type.In(0)
- if t.Kind() == reflect.Ptr {
- t = t.Elem()
- }
- return t.Name()
-}
-
-func (method *methodType) String() string {
- return method.suiteName() + "." + method.Info.Name
-}
-
-func (method *methodType) matches(re *regexp.Regexp) bool {
- return (re.MatchString(method.Info.Name) ||
- re.MatchString(method.suiteName()) ||
- re.MatchString(method.String()))
-}
-
-type C struct {
- method *methodType
- kind funcKind
- testName string
- _status funcStatus
- logb *logger
- logw io.Writer
- done chan *C
- reason string
- mustFail bool
- tempDir *tempDir
- benchMem bool
- startTime time.Time
- timer
-}
-
-func (c *C) status() funcStatus {
- return funcStatus(atomic.LoadUint32((*uint32)(&c._status)))
-}
-
-func (c *C) setStatus(s funcStatus) {
- atomic.StoreUint32((*uint32)(&c._status), uint32(s))
-}
-
-func (c *C) stopNow() {
- runtime.Goexit()
-}
-
-// logger is a concurrency safe byte.Buffer
-type logger struct {
- sync.Mutex
- writer bytes.Buffer
-}
-
-func (l *logger) Write(buf []byte) (int, error) {
- l.Lock()
- defer l.Unlock()
- return l.writer.Write(buf)
-}
-
-func (l *logger) WriteTo(w io.Writer) (int64, error) {
- l.Lock()
- defer l.Unlock()
- return l.writer.WriteTo(w)
-}
-
-func (l *logger) String() string {
- l.Lock()
- defer l.Unlock()
- return l.writer.String()
-}
-
-// -----------------------------------------------------------------------
-// Handling of temporary files and directories.
-
-type tempDir struct {
- sync.Mutex
- path string
- counter int
-}
-
-func (td *tempDir) newPath() string {
- td.Lock()
- defer td.Unlock()
- if td.path == "" {
- var err error
- for i := 0; i != 100; i++ {
- path := fmt.Sprintf("%s%ccheck-%d", os.TempDir(), os.PathSeparator, rand.Int())
- if err = os.Mkdir(path, 0700); err == nil {
- td.path = path
- break
- }
- }
- if td.path == "" {
- panic("Couldn't create temporary directory: " + err.Error())
- }
- }
- result := filepath.Join(td.path, strconv.Itoa(td.counter))
- td.counter += 1
- return result
-}
-
-func (td *tempDir) removeAll() {
- td.Lock()
- defer td.Unlock()
- if td.path != "" {
- err := os.RemoveAll(td.path)
- if err != nil {
- fmt.Fprintf(os.Stderr, "WARNING: Error cleaning up temporaries: "+err.Error())
- }
- }
-}
-
-// Create a new temporary directory which is automatically removed after
-// the suite finishes running.
-func (c *C) MkDir() string {
- path := c.tempDir.newPath()
- if err := os.Mkdir(path, 0700); err != nil {
- panic(fmt.Sprintf("Couldn't create temporary directory %s: %s", path, err.Error()))
- }
- return path
-}
-
-// -----------------------------------------------------------------------
-// Low-level logging functions.
-
-func (c *C) log(args ...interface{}) {
- c.writeLog([]byte(fmt.Sprint(args...) + "\n"))
-}
-
-func (c *C) logf(format string, args ...interface{}) {
- c.writeLog([]byte(fmt.Sprintf(format+"\n", args...)))
-}
-
-func (c *C) logNewLine() {
- c.writeLog([]byte{'\n'})
-}
-
-func (c *C) writeLog(buf []byte) {
- c.logb.Write(buf)
- if c.logw != nil {
- c.logw.Write(buf)
- }
-}
-
-func hasStringOrError(x interface{}) (ok bool) {
- _, ok = x.(fmt.Stringer)
- if ok {
- return
- }
- _, ok = x.(error)
- return
-}
-
-func (c *C) logValue(label string, value interface{}) {
- if label == "" {
- if hasStringOrError(value) {
- c.logf("... %#v (%q)", value, value)
- } else {
- c.logf("... %#v", value)
- }
- } else if value == nil {
- c.logf("... %s = nil", label)
- } else {
- if hasStringOrError(value) {
- fv := fmt.Sprintf("%#v", value)
- qv := fmt.Sprintf("%q", value)
- if fv != qv {
- c.logf("... %s %s = %s (%s)", label, reflect.TypeOf(value), fv, qv)
- return
- }
- }
- if s, ok := value.(string); ok && isMultiLine(s) {
- c.logf(`... %s %s = "" +`, label, reflect.TypeOf(value))
- c.logMultiLine(s)
- } else {
- c.logf("... %s %s = %#v", label, reflect.TypeOf(value), value)
- }
- }
-}
-
-func (c *C) logMultiLine(s string) {
- b := make([]byte, 0, len(s)*2)
- i := 0
- n := len(s)
- for i < n {
- j := i + 1
- for j < n && s[j-1] != '\n' {
- j++
- }
- b = append(b, "... "...)
- b = strconv.AppendQuote(b, s[i:j])
- if j < n {
- b = append(b, " +"...)
- }
- b = append(b, '\n')
- i = j
- }
- c.writeLog(b)
-}
-
-func isMultiLine(s string) bool {
- for i := 0; i+1 < len(s); i++ {
- if s[i] == '\n' {
- return true
- }
- }
- return false
-}
-
-func (c *C) logString(issue string) {
- c.log("... ", issue)
-}
-
-func (c *C) logCaller(skip int) {
- // This is a bit heavier than it ought to be.
- skip += 1 // Our own frame.
- pc, callerFile, callerLine, ok := runtime.Caller(skip)
- if !ok {
- return
- }
- var testFile string
- var testLine int
- testFunc := runtime.FuncForPC(c.method.PC())
- if runtime.FuncForPC(pc) != testFunc {
- for {
- skip += 1
- if pc, file, line, ok := runtime.Caller(skip); ok {
- // Note that the test line may be different on
- // distinct calls for the same test. Showing
- // the "internal" line is helpful when debugging.
- if runtime.FuncForPC(pc) == testFunc {
- testFile, testLine = file, line
- break
- }
- } else {
- break
- }
- }
- }
- if testFile != "" && (testFile != callerFile || testLine != callerLine) {
- c.logCode(testFile, testLine)
- }
- c.logCode(callerFile, callerLine)
-}
-
-func (c *C) logCode(path string, line int) {
- c.logf("%s:%d:", nicePath(path), line)
- code, err := printLine(path, line)
- if code == "" {
- code = "..." // XXX Open the file and take the raw line.
- if err != nil {
- code += err.Error()
- }
- }
- c.log(indent(code, " "))
-}
-
-var valueGo = filepath.Join("reflect", "value.go")
-var asmGo = filepath.Join("runtime", "asm_")
-
-func (c *C) logPanic(skip int, value interface{}) {
- skip++ // Our own frame.
- initialSkip := skip
- for ; ; skip++ {
- if pc, file, line, ok := runtime.Caller(skip); ok {
- if skip == initialSkip {
- c.logf("... Panic: %s (PC=0x%X)\n", value, pc)
- }
- name := niceFuncName(pc)
- path := nicePath(file)
- if strings.Contains(path, "/gopkg.in/check.v") {
- continue
- }
- if name == "Value.call" && strings.HasSuffix(path, valueGo) {
- continue
- }
- if (name == "call16" || name == "call32") && strings.Contains(path, asmGo) {
- continue
- }
- c.logf("%s:%d\n in %s", nicePath(file), line, name)
- } else {
- break
- }
- }
-}
-
-func (c *C) logSoftPanic(issue string) {
- c.log("... Panic: ", issue)
-}
-
-func (c *C) logArgPanic(method *methodType, expectedType string) {
- c.logf("... Panic: %s argument should be %s",
- niceFuncName(method.PC()), expectedType)
-}
-
-// -----------------------------------------------------------------------
-// Some simple formatting helpers.
-
-var initWD, initWDErr = os.Getwd()
-
-func init() {
- if initWDErr == nil {
- initWD = strings.Replace(initWD, "\\", "/", -1) + "/"
- }
-}
-
-func nicePath(path string) string {
- if initWDErr == nil {
- if strings.HasPrefix(path, initWD) {
- return path[len(initWD):]
- }
- }
- return path
-}
-
-func niceFuncPath(pc uintptr) string {
- function := runtime.FuncForPC(pc)
- if function != nil {
- filename, line := function.FileLine(pc)
- return fmt.Sprintf("%s:%d", nicePath(filename), line)
- }
- return ""
-}
-
-func niceFuncName(pc uintptr) string {
- function := runtime.FuncForPC(pc)
- if function != nil {
- name := path.Base(function.Name())
- if i := strings.Index(name, "."); i > 0 {
- name = name[i+1:]
- }
- if strings.HasPrefix(name, "(*") {
- if i := strings.Index(name, ")"); i > 0 {
- name = name[2:i] + name[i+1:]
- }
- }
- if i := strings.LastIndex(name, ".*"); i != -1 {
- name = name[:i] + "." + name[i+2:]
- }
- if i := strings.LastIndex(name, "·"); i != -1 {
- name = name[:i] + "." + name[i+2:]
- }
- return name
- }
- return ""
-}
-
-// -----------------------------------------------------------------------
-// Result tracker to aggregate call results.
-
-type Result struct {
- Succeeded int
- Failed int
- Skipped int
- Panicked int
- FixturePanicked int
- ExpectedFailures int
- Missed int // Not even tried to run, related to a panic in the fixture.
- RunError error // Houston, we've got a problem.
- WorkDir string // If KeepWorkDir is true
-}
-
-type resultTracker struct {
- result Result
- _lastWasProblem bool
- _waiting int
- _missed int
- _expectChan chan *C
- _doneChan chan *C
- _stopChan chan bool
-}
-
-func newResultTracker() *resultTracker {
- return &resultTracker{_expectChan: make(chan *C), // Synchronous
- _doneChan: make(chan *C, 32), // Asynchronous
- _stopChan: make(chan bool)} // Synchronous
-}
-
-func (tracker *resultTracker) start() {
- go tracker._loopRoutine()
-}
-
-func (tracker *resultTracker) waitAndStop() {
- <-tracker._stopChan
-}
-
-func (tracker *resultTracker) expectCall(c *C) {
- tracker._expectChan <- c
-}
-
-func (tracker *resultTracker) callDone(c *C) {
- tracker._doneChan <- c
-}
-
-func (tracker *resultTracker) _loopRoutine() {
- for {
- var c *C
- if tracker._waiting > 0 {
- // Calls still running. Can't stop.
- select {
- // XXX Reindent this (not now to make diff clear)
- case c = <-tracker._expectChan:
- tracker._waiting += 1
- case c = <-tracker._doneChan:
- tracker._waiting -= 1
- switch c.status() {
- case succeededSt:
- if c.kind == testKd {
- if c.mustFail {
- tracker.result.ExpectedFailures++
- } else {
- tracker.result.Succeeded++
- }
- }
- case failedSt:
- tracker.result.Failed++
- case panickedSt:
- if c.kind == fixtureKd {
- tracker.result.FixturePanicked++
- } else {
- tracker.result.Panicked++
- }
- case fixturePanickedSt:
- // Track it as missed, since the panic
- // was on the fixture, not on the test.
- tracker.result.Missed++
- case missedSt:
- tracker.result.Missed++
- case skippedSt:
- if c.kind == testKd {
- tracker.result.Skipped++
- }
- }
- }
- } else {
- // No calls. Can stop, but no done calls here.
- select {
- case tracker._stopChan <- true:
- return
- case c = <-tracker._expectChan:
- tracker._waiting += 1
- case c = <-tracker._doneChan:
- panic("Tracker got an unexpected done call.")
- }
- }
- }
-}
-
-// -----------------------------------------------------------------------
-// The underlying suite runner.
-
-type suiteRunner struct {
- suite interface{}
- setUpSuite, tearDownSuite *methodType
- setUpTest, tearDownTest *methodType
- tests []*methodType
- tracker *resultTracker
- tempDir *tempDir
- keepDir bool
- output *outputWriter
- reportedProblemLast bool
- benchTime time.Duration
- benchMem bool
-}
-
-type RunConf struct {
- Output io.Writer
- Stream bool
- Verbose bool
- Filter string
- Benchmark bool
- BenchmarkTime time.Duration // Defaults to 1 second
- BenchmarkMem bool
- KeepWorkDir bool
-}
-
-// Create a new suiteRunner able to run all methods in the given suite.
-func newSuiteRunner(suite interface{}, runConf *RunConf) *suiteRunner {
- var conf RunConf
- if runConf != nil {
- conf = *runConf
- }
- if conf.Output == nil {
- conf.Output = os.Stdout
- }
- if conf.Benchmark {
- conf.Verbose = true
- }
-
- suiteType := reflect.TypeOf(suite)
- suiteNumMethods := suiteType.NumMethod()
- suiteValue := reflect.ValueOf(suite)
-
- runner := &suiteRunner{
- suite: suite,
- output: newOutputWriter(conf.Output, conf.Stream, conf.Verbose),
- tracker: newResultTracker(),
- benchTime: conf.BenchmarkTime,
- benchMem: conf.BenchmarkMem,
- tempDir: &tempDir{},
- keepDir: conf.KeepWorkDir,
- tests: make([]*methodType, 0, suiteNumMethods),
- }
- if runner.benchTime == 0 {
- runner.benchTime = 1 * time.Second
- }
-
- var filterRegexp *regexp.Regexp
- if conf.Filter != "" {
- if regexp, err := regexp.Compile(conf.Filter); err != nil {
- msg := "Bad filter expression: " + err.Error()
- runner.tracker.result.RunError = errors.New(msg)
- return runner
- } else {
- filterRegexp = regexp
- }
- }
-
- for i := 0; i != suiteNumMethods; i++ {
- method := newMethod(suiteValue, i)
- switch method.Info.Name {
- case "SetUpSuite":
- runner.setUpSuite = method
- case "TearDownSuite":
- runner.tearDownSuite = method
- case "SetUpTest":
- runner.setUpTest = method
- case "TearDownTest":
- runner.tearDownTest = method
- default:
- prefix := "Test"
- if conf.Benchmark {
- prefix = "Benchmark"
- }
- if !strings.HasPrefix(method.Info.Name, prefix) {
- continue
- }
- if filterRegexp == nil || method.matches(filterRegexp) {
- runner.tests = append(runner.tests, method)
- }
- }
- }
- return runner
-}
-
-// Run all methods in the given suite.
-func (runner *suiteRunner) run() *Result {
- if runner.tracker.result.RunError == nil && len(runner.tests) > 0 {
- runner.tracker.start()
- if runner.checkFixtureArgs() {
- c := runner.runFixture(runner.setUpSuite, "", nil)
- if c == nil || c.status() == succeededSt {
- for i := 0; i != len(runner.tests); i++ {
- c := runner.runTest(runner.tests[i])
- if c.status() == fixturePanickedSt {
- runner.skipTests(missedSt, runner.tests[i+1:])
- break
- }
- }
- } else if c != nil && c.status() == skippedSt {
- runner.skipTests(skippedSt, runner.tests)
- } else {
- runner.skipTests(missedSt, runner.tests)
- }
- runner.runFixture(runner.tearDownSuite, "", nil)
- } else {
- runner.skipTests(missedSt, runner.tests)
- }
- runner.tracker.waitAndStop()
- if runner.keepDir {
- runner.tracker.result.WorkDir = runner.tempDir.path
- } else {
- runner.tempDir.removeAll()
- }
- }
- return &runner.tracker.result
-}
-
-// Create a call object with the given suite method, and fork a
-// goroutine with the provided dispatcher for running it.
-func (runner *suiteRunner) forkCall(method *methodType, kind funcKind, testName string, logb *logger, dispatcher func(c *C)) *C {
- var logw io.Writer
- if runner.output.Stream {
- logw = runner.output
- }
- if logb == nil {
- logb = new(logger)
- }
- c := &C{
- method: method,
- kind: kind,
- testName: testName,
- logb: logb,
- logw: logw,
- tempDir: runner.tempDir,
- done: make(chan *C, 1),
- timer: timer{benchTime: runner.benchTime},
- startTime: time.Now(),
- benchMem: runner.benchMem,
- }
- runner.tracker.expectCall(c)
- go (func() {
- runner.reportCallStarted(c)
- defer runner.callDone(c)
- dispatcher(c)
- })()
- return c
-}
-
-// Same as forkCall(), but wait for call to finish before returning.
-func (runner *suiteRunner) runFunc(method *methodType, kind funcKind, testName string, logb *logger, dispatcher func(c *C)) *C {
- c := runner.forkCall(method, kind, testName, logb, dispatcher)
- <-c.done
- return c
-}
-
-// Handle a finished call. If there were any panics, update the call status
-// accordingly. Then, mark the call as done and report to the tracker.
-func (runner *suiteRunner) callDone(c *C) {
- value := recover()
- if value != nil {
- switch v := value.(type) {
- case *fixturePanic:
- if v.status == skippedSt {
- c.setStatus(skippedSt)
- } else {
- c.logSoftPanic("Fixture has panicked (see related PANIC)")
- c.setStatus(fixturePanickedSt)
- }
- default:
- c.logPanic(1, value)
- c.setStatus(panickedSt)
- }
- }
- if c.mustFail {
- switch c.status() {
- case failedSt:
- c.setStatus(succeededSt)
- case succeededSt:
- c.setStatus(failedSt)
- c.logString("Error: Test succeeded, but was expected to fail")
- c.logString("Reason: " + c.reason)
- }
- }
-
- runner.reportCallDone(c)
- c.done <- c
-}
-
-// Runs a fixture call synchronously. The fixture will still be run in a
-// goroutine like all suite methods, but this method will not return
-// while the fixture goroutine is not done, because the fixture must be
-// run in a desired order.
-func (runner *suiteRunner) runFixture(method *methodType, testName string, logb *logger) *C {
- if method != nil {
- c := runner.runFunc(method, fixtureKd, testName, logb, func(c *C) {
- c.ResetTimer()
- c.StartTimer()
- defer c.StopTimer()
- c.method.Call([]reflect.Value{reflect.ValueOf(c)})
- })
- return c
- }
- return nil
-}
-
-// Run the fixture method with runFixture(), but panic with a fixturePanic{}
-// in case the fixture method panics. This makes it easier to track the
-// fixture panic together with other call panics within forkTest().
-func (runner *suiteRunner) runFixtureWithPanic(method *methodType, testName string, logb *logger, skipped *bool) *C {
- if skipped != nil && *skipped {
- return nil
- }
- c := runner.runFixture(method, testName, logb)
- if c != nil && c.status() != succeededSt {
- if skipped != nil {
- *skipped = c.status() == skippedSt
- }
- panic(&fixturePanic{c.status(), method})
- }
- return c
-}
-
-type fixturePanic struct {
- status funcStatus
- method *methodType
-}
-
-// Run the suite test method, together with the test-specific fixture,
-// asynchronously.
-func (runner *suiteRunner) forkTest(method *methodType) *C {
- testName := method.String()
- return runner.forkCall(method, testKd, testName, nil, func(c *C) {
- var skipped bool
- defer runner.runFixtureWithPanic(runner.tearDownTest, testName, nil, &skipped)
- defer c.StopTimer()
- benchN := 1
- for {
- runner.runFixtureWithPanic(runner.setUpTest, testName, c.logb, &skipped)
- mt := c.method.Type()
- if mt.NumIn() != 1 || mt.In(0) != reflect.TypeOf(c) {
- // Rather than a plain panic, provide a more helpful message when
- // the argument type is incorrect.
- c.setStatus(panickedSt)
- c.logArgPanic(c.method, "*check.C")
- return
- }
- if strings.HasPrefix(c.method.Info.Name, "Test") {
- c.ResetTimer()
- c.StartTimer()
- c.method.Call([]reflect.Value{reflect.ValueOf(c)})
- return
- }
- if !strings.HasPrefix(c.method.Info.Name, "Benchmark") {
- panic("unexpected method prefix: " + c.method.Info.Name)
- }
-
- runtime.GC()
- c.N = benchN
- c.ResetTimer()
- c.StartTimer()
- c.method.Call([]reflect.Value{reflect.ValueOf(c)})
- c.StopTimer()
- if c.status() != succeededSt || c.duration >= c.benchTime || benchN >= 1e9 {
- return
- }
- perOpN := int(1e9)
- if c.nsPerOp() != 0 {
- perOpN = int(c.benchTime.Nanoseconds() / c.nsPerOp())
- }
-
- // Logic taken from the stock testing package:
- // - Run more iterations than we think we'll need for a second (1.5x).
- // - Don't grow too fast in case we had timing errors previously.
- // - Be sure to run at least one more than last time.
- benchN = max(min(perOpN+perOpN/2, 100*benchN), benchN+1)
- benchN = roundUp(benchN)
-
- skipped = true // Don't run the deferred one if this panics.
- runner.runFixtureWithPanic(runner.tearDownTest, testName, nil, nil)
- skipped = false
- }
- })
-}
-
-// Same as forkTest(), but wait for the test to finish before returning.
-func (runner *suiteRunner) runTest(method *methodType) *C {
- c := runner.forkTest(method)
- <-c.done
- return c
-}
-
-// Helper to mark tests as skipped or missed. A bit heavy for what
-// it does, but it enables homogeneous handling of tracking, including
-// nice verbose output.
-func (runner *suiteRunner) skipTests(status funcStatus, methods []*methodType) {
- for _, method := range methods {
- runner.runFunc(method, testKd, "", nil, func(c *C) {
- c.setStatus(status)
- })
- }
-}
-
-// Verify if the fixture arguments are *check.C. In case of errors,
-// log the error as a panic in the fixture method call, and return false.
-func (runner *suiteRunner) checkFixtureArgs() bool {
- succeeded := true
- argType := reflect.TypeOf(&C{})
- for _, method := range []*methodType{runner.setUpSuite, runner.tearDownSuite, runner.setUpTest, runner.tearDownTest} {
- if method != nil {
- mt := method.Type()
- if mt.NumIn() != 1 || mt.In(0) != argType {
- succeeded = false
- runner.runFunc(method, fixtureKd, "", nil, func(c *C) {
- c.logArgPanic(method, "*check.C")
- c.setStatus(panickedSt)
- })
- }
- }
- }
- return succeeded
-}
-
-func (runner *suiteRunner) reportCallStarted(c *C) {
- runner.output.WriteCallStarted("START", c)
-}
-
-func (runner *suiteRunner) reportCallDone(c *C) {
- runner.tracker.callDone(c)
- switch c.status() {
- case succeededSt:
- if c.mustFail {
- runner.output.WriteCallSuccess("FAIL EXPECTED", c)
- } else {
- runner.output.WriteCallSuccess("PASS", c)
- }
- case skippedSt:
- runner.output.WriteCallSuccess("SKIP", c)
- case failedSt:
- runner.output.WriteCallProblem("FAIL", c)
- case panickedSt:
- runner.output.WriteCallProblem("PANIC", c)
- case fixturePanickedSt:
- // That's a testKd call reporting that its fixture
- // has panicked. The fixture call which caused the
- // panic itself was tracked above. We'll report to
- // aid debugging.
- runner.output.WriteCallProblem("PANIC", c)
- case missedSt:
- runner.output.WriteCallSuccess("MISS", c)
- }
-}
diff --git a/vendor/gopkg.in/check.v1/check_test.go b/vendor/gopkg.in/check.v1/check_test.go
deleted file mode 100644
index 871b3252..00000000
--- a/vendor/gopkg.in/check.v1/check_test.go
+++ /dev/null
@@ -1,207 +0,0 @@
-// This file contains just a few generic helpers which are used by the
-// other test files.
-
-package check_test
-
-import (
- "flag"
- "fmt"
- "os"
- "regexp"
- "runtime"
- "testing"
- "time"
-
- "gopkg.in/check.v1"
-)
-
-// We count the number of suites run at least to get a vague hint that the
-// test suite is behaving as it should. Otherwise a bug introduced at the
-// very core of the system could go unperceived.
-const suitesRunExpected = 8
-
-var suitesRun int = 0
-
-func Test(t *testing.T) {
- check.TestingT(t)
- if suitesRun != suitesRunExpected && flag.Lookup("check.f").Value.String() == "" {
- critical(fmt.Sprintf("Expected %d suites to run rather than %d",
- suitesRunExpected, suitesRun))
- }
-}
-
-// -----------------------------------------------------------------------
-// Helper functions.
-
-// Break down badly. This is used in test cases which can't yet assume
-// that the fundamental bits are working.
-func critical(error string) {
- fmt.Fprintln(os.Stderr, "CRITICAL: "+error)
- os.Exit(1)
-}
-
-// Return the file line where it's called.
-func getMyLine() int {
- if _, _, line, ok := runtime.Caller(1); ok {
- return line
- }
- return -1
-}
-
-// -----------------------------------------------------------------------
-// Helper type implementing a basic io.Writer for testing output.
-
-// Type implementing the io.Writer interface for analyzing output.
-type String struct {
- value string
-}
-
-// The only function required by the io.Writer interface. Will append
-// written data to the String.value string.
-func (s *String) Write(p []byte) (n int, err error) {
- s.value += string(p)
- return len(p), nil
-}
-
-// Trivial wrapper to test errors happening on a different file
-// than the test itself.
-func checkEqualWrapper(c *check.C, obtained, expected interface{}) (result bool, line int) {
- return c.Check(obtained, check.Equals, expected), getMyLine()
-}
-
-// -----------------------------------------------------------------------
-// Helper suite for testing basic fail behavior.
-
-type FailHelper struct {
- testLine int
-}
-
-func (s *FailHelper) TestLogAndFail(c *check.C) {
- s.testLine = getMyLine() - 1
- c.Log("Expected failure!")
- c.Fail()
-}
-
-// -----------------------------------------------------------------------
-// Helper suite for testing basic success behavior.
-
-type SuccessHelper struct{}
-
-func (s *SuccessHelper) TestLogAndSucceed(c *check.C) {
- c.Log("Expected success!")
-}
-
-// -----------------------------------------------------------------------
-// Helper suite for testing ordering and behavior of fixture.
-
-type FixtureHelper struct {
- calls []string
- panicOn string
- skip bool
- skipOnN int
- sleepOn string
- sleep time.Duration
- bytes int64
-}
-
-func (s *FixtureHelper) trace(name string, c *check.C) {
- s.calls = append(s.calls, name)
- if name == s.panicOn {
- panic(name)
- }
- if s.sleep > 0 && s.sleepOn == name {
- time.Sleep(s.sleep)
- }
- if s.skip && s.skipOnN == len(s.calls)-1 {
- c.Skip("skipOnN == n")
- }
-}
-
-func (s *FixtureHelper) SetUpSuite(c *check.C) {
- s.trace("SetUpSuite", c)
-}
-
-func (s *FixtureHelper) TearDownSuite(c *check.C) {
- s.trace("TearDownSuite", c)
-}
-
-func (s *FixtureHelper) SetUpTest(c *check.C) {
- s.trace("SetUpTest", c)
-}
-
-func (s *FixtureHelper) TearDownTest(c *check.C) {
- s.trace("TearDownTest", c)
-}
-
-func (s *FixtureHelper) Test1(c *check.C) {
- s.trace("Test1", c)
-}
-
-func (s *FixtureHelper) Test2(c *check.C) {
- s.trace("Test2", c)
-}
-
-func (s *FixtureHelper) Benchmark1(c *check.C) {
- s.trace("Benchmark1", c)
- for i := 0; i < c.N; i++ {
- time.Sleep(s.sleep)
- }
-}
-
-func (s *FixtureHelper) Benchmark2(c *check.C) {
- s.trace("Benchmark2", c)
- c.SetBytes(1024)
- for i := 0; i < c.N; i++ {
- time.Sleep(s.sleep)
- }
-}
-
-func (s *FixtureHelper) Benchmark3(c *check.C) {
- var x []int64
- s.trace("Benchmark3", c)
- for i := 0; i < c.N; i++ {
- time.Sleep(s.sleep)
- x = make([]int64, 5)
- _ = x
- }
-}
-
-// -----------------------------------------------------------------------
-// Helper which checks the state of the test and ensures that it matches
-// the given expectations. Depends on c.Errorf() working, so shouldn't
-// be used to test this one function.
-
-type expectedState struct {
- name string
- result interface{}
- failed bool
- log string
-}
-
-// Verify the state of the test. Note that since this also verifies if
-// the test is supposed to be in a failed state, no other checks should
-// be done in addition to what is being tested.
-func checkState(c *check.C, result interface{}, expected *expectedState) {
- failed := c.Failed()
- c.Succeed()
- log := c.GetTestLog()
- matched, matchError := regexp.MatchString("^"+expected.log+"$", log)
- if matchError != nil {
- c.Errorf("Error in matching expression used in testing %s",
- expected.name)
- } else if !matched {
- c.Errorf("%s logged:\n----------\n%s----------\n\nExpected:\n----------\n%s\n----------",
- expected.name, log, expected.log)
- }
- if result != expected.result {
- c.Errorf("%s returned %#v rather than %#v",
- expected.name, result, expected.result)
- }
- if failed != expected.failed {
- if failed {
- c.Errorf("%s has failed when it shouldn't", expected.name)
- } else {
- c.Errorf("%s has not failed when it should", expected.name)
- }
- }
-}
diff --git a/vendor/gopkg.in/check.v1/checkers.go b/vendor/gopkg.in/check.v1/checkers.go
deleted file mode 100644
index bac33872..00000000
--- a/vendor/gopkg.in/check.v1/checkers.go
+++ /dev/null
@@ -1,458 +0,0 @@
-package check
-
-import (
- "fmt"
- "reflect"
- "regexp"
-)
-
-// -----------------------------------------------------------------------
-// CommentInterface and Commentf helper, to attach extra information to checks.
-
-type comment struct {
- format string
- args []interface{}
-}
-
-// Commentf returns an infomational value to use with Assert or Check calls.
-// If the checker test fails, the provided arguments will be passed to
-// fmt.Sprintf, and will be presented next to the logged failure.
-//
-// For example:
-//
-// c.Assert(v, Equals, 42, Commentf("Iteration #%d failed.", i))
-//
-// Note that if the comment is constant, a better option is to
-// simply use a normal comment right above or next to the line, as
-// it will also get printed with any errors:
-//
-// c.Assert(l, Equals, 8192) // Ensure buffer size is correct (bug #123)
-//
-func Commentf(format string, args ...interface{}) CommentInterface {
- return &comment{format, args}
-}
-
-// CommentInterface must be implemented by types that attach extra
-// information to failed checks. See the Commentf function for details.
-type CommentInterface interface {
- CheckCommentString() string
-}
-
-func (c *comment) CheckCommentString() string {
- return fmt.Sprintf(c.format, c.args...)
-}
-
-// -----------------------------------------------------------------------
-// The Checker interface.
-
-// The Checker interface must be provided by checkers used with
-// the Assert and Check verification methods.
-type Checker interface {
- Info() *CheckerInfo
- Check(params []interface{}, names []string) (result bool, error string)
-}
-
-// See the Checker interface.
-type CheckerInfo struct {
- Name string
- Params []string
-}
-
-func (info *CheckerInfo) Info() *CheckerInfo {
- return info
-}
-
-// -----------------------------------------------------------------------
-// Not checker logic inverter.
-
-// The Not checker inverts the logic of the provided checker. The
-// resulting checker will succeed where the original one failed, and
-// vice-versa.
-//
-// For example:
-//
-// c.Assert(a, Not(Equals), b)
-//
-func Not(checker Checker) Checker {
- return ¬Checker{checker}
-}
-
-type notChecker struct {
- sub Checker
-}
-
-func (checker *notChecker) Info() *CheckerInfo {
- info := *checker.sub.Info()
- info.Name = "Not(" + info.Name + ")"
- return &info
-}
-
-func (checker *notChecker) Check(params []interface{}, names []string) (result bool, error string) {
- result, error = checker.sub.Check(params, names)
- result = !result
- return
-}
-
-// -----------------------------------------------------------------------
-// IsNil checker.
-
-type isNilChecker struct {
- *CheckerInfo
-}
-
-// The IsNil checker tests whether the obtained value is nil.
-//
-// For example:
-//
-// c.Assert(err, IsNil)
-//
-var IsNil Checker = &isNilChecker{
- &CheckerInfo{Name: "IsNil", Params: []string{"value"}},
-}
-
-func (checker *isNilChecker) Check(params []interface{}, names []string) (result bool, error string) {
- return isNil(params[0]), ""
-}
-
-func isNil(obtained interface{}) (result bool) {
- if obtained == nil {
- result = true
- } else {
- switch v := reflect.ValueOf(obtained); v.Kind() {
- case reflect.Chan, reflect.Func, reflect.Interface, reflect.Map, reflect.Ptr, reflect.Slice:
- return v.IsNil()
- }
- }
- return
-}
-
-// -----------------------------------------------------------------------
-// NotNil checker. Alias for Not(IsNil), since it's so common.
-
-type notNilChecker struct {
- *CheckerInfo
-}
-
-// The NotNil checker verifies that the obtained value is not nil.
-//
-// For example:
-//
-// c.Assert(iface, NotNil)
-//
-// This is an alias for Not(IsNil), made available since it's a
-// fairly common check.
-//
-var NotNil Checker = ¬NilChecker{
- &CheckerInfo{Name: "NotNil", Params: []string{"value"}},
-}
-
-func (checker *notNilChecker) Check(params []interface{}, names []string) (result bool, error string) {
- return !isNil(params[0]), ""
-}
-
-// -----------------------------------------------------------------------
-// Equals checker.
-
-type equalsChecker struct {
- *CheckerInfo
-}
-
-// The Equals checker verifies that the obtained value is equal to
-// the expected value, according to usual Go semantics for ==.
-//
-// For example:
-//
-// c.Assert(value, Equals, 42)
-//
-var Equals Checker = &equalsChecker{
- &CheckerInfo{Name: "Equals", Params: []string{"obtained", "expected"}},
-}
-
-func (checker *equalsChecker) Check(params []interface{}, names []string) (result bool, error string) {
- defer func() {
- if v := recover(); v != nil {
- result = false
- error = fmt.Sprint(v)
- }
- }()
- return params[0] == params[1], ""
-}
-
-// -----------------------------------------------------------------------
-// DeepEquals checker.
-
-type deepEqualsChecker struct {
- *CheckerInfo
-}
-
-// The DeepEquals checker verifies that the obtained value is deep-equal to
-// the expected value. The check will work correctly even when facing
-// slices, interfaces, and values of different types (which always fail
-// the test).
-//
-// For example:
-//
-// c.Assert(value, DeepEquals, 42)
-// c.Assert(array, DeepEquals, []string{"hi", "there"})
-//
-var DeepEquals Checker = &deepEqualsChecker{
- &CheckerInfo{Name: "DeepEquals", Params: []string{"obtained", "expected"}},
-}
-
-func (checker *deepEqualsChecker) Check(params []interface{}, names []string) (result bool, error string) {
- return reflect.DeepEqual(params[0], params[1]), ""
-}
-
-// -----------------------------------------------------------------------
-// HasLen checker.
-
-type hasLenChecker struct {
- *CheckerInfo
-}
-
-// The HasLen checker verifies that the obtained value has the
-// provided length. In many cases this is superior to using Equals
-// in conjuction with the len function because in case the check
-// fails the value itself will be printed, instead of its length,
-// providing more details for figuring the problem.
-//
-// For example:
-//
-// c.Assert(list, HasLen, 5)
-//
-var HasLen Checker = &hasLenChecker{
- &CheckerInfo{Name: "HasLen", Params: []string{"obtained", "n"}},
-}
-
-func (checker *hasLenChecker) Check(params []interface{}, names []string) (result bool, error string) {
- n, ok := params[1].(int)
- if !ok {
- return false, "n must be an int"
- }
- value := reflect.ValueOf(params[0])
- switch value.Kind() {
- case reflect.Map, reflect.Array, reflect.Slice, reflect.Chan, reflect.String:
- default:
- return false, "obtained value type has no length"
- }
- return value.Len() == n, ""
-}
-
-// -----------------------------------------------------------------------
-// ErrorMatches checker.
-
-type errorMatchesChecker struct {
- *CheckerInfo
-}
-
-// The ErrorMatches checker verifies that the error value
-// is non nil and matches the regular expression provided.
-//
-// For example:
-//
-// c.Assert(err, ErrorMatches, "perm.*denied")
-//
-var ErrorMatches Checker = errorMatchesChecker{
- &CheckerInfo{Name: "ErrorMatches", Params: []string{"value", "regex"}},
-}
-
-func (checker errorMatchesChecker) Check(params []interface{}, names []string) (result bool, errStr string) {
- if params[0] == nil {
- return false, "Error value is nil"
- }
- err, ok := params[0].(error)
- if !ok {
- return false, "Value is not an error"
- }
- params[0] = err.Error()
- names[0] = "error"
- return matches(params[0], params[1])
-}
-
-// -----------------------------------------------------------------------
-// Matches checker.
-
-type matchesChecker struct {
- *CheckerInfo
-}
-
-// The Matches checker verifies that the string provided as the obtained
-// value (or the string resulting from obtained.String()) matches the
-// regular expression provided.
-//
-// For example:
-//
-// c.Assert(err, Matches, "perm.*denied")
-//
-var Matches Checker = &matchesChecker{
- &CheckerInfo{Name: "Matches", Params: []string{"value", "regex"}},
-}
-
-func (checker *matchesChecker) Check(params []interface{}, names []string) (result bool, error string) {
- return matches(params[0], params[1])
-}
-
-func matches(value, regex interface{}) (result bool, error string) {
- reStr, ok := regex.(string)
- if !ok {
- return false, "Regex must be a string"
- }
- valueStr, valueIsStr := value.(string)
- if !valueIsStr {
- if valueWithStr, valueHasStr := value.(fmt.Stringer); valueHasStr {
- valueStr, valueIsStr = valueWithStr.String(), true
- }
- }
- if valueIsStr {
- matches, err := regexp.MatchString("^"+reStr+"$", valueStr)
- if err != nil {
- return false, "Can't compile regex: " + err.Error()
- }
- return matches, ""
- }
- return false, "Obtained value is not a string and has no .String()"
-}
-
-// -----------------------------------------------------------------------
-// Panics checker.
-
-type panicsChecker struct {
- *CheckerInfo
-}
-
-// The Panics checker verifies that calling the provided zero-argument
-// function will cause a panic which is deep-equal to the provided value.
-//
-// For example:
-//
-// c.Assert(func() { f(1, 2) }, Panics, &SomeErrorType{"BOOM"}).
-//
-//
-var Panics Checker = &panicsChecker{
- &CheckerInfo{Name: "Panics", Params: []string{"function", "expected"}},
-}
-
-func (checker *panicsChecker) Check(params []interface{}, names []string) (result bool, error string) {
- f := reflect.ValueOf(params[0])
- if f.Kind() != reflect.Func || f.Type().NumIn() != 0 {
- return false, "Function must take zero arguments"
- }
- defer func() {
- // If the function has not panicked, then don't do the check.
- if error != "" {
- return
- }
- params[0] = recover()
- names[0] = "panic"
- result = reflect.DeepEqual(params[0], params[1])
- }()
- f.Call(nil)
- return false, "Function has not panicked"
-}
-
-type panicMatchesChecker struct {
- *CheckerInfo
-}
-
-// The PanicMatches checker verifies that calling the provided zero-argument
-// function will cause a panic with an error value matching
-// the regular expression provided.
-//
-// For example:
-//
-// c.Assert(func() { f(1, 2) }, PanicMatches, `open.*: no such file or directory`).
-//
-//
-var PanicMatches Checker = &panicMatchesChecker{
- &CheckerInfo{Name: "PanicMatches", Params: []string{"function", "expected"}},
-}
-
-func (checker *panicMatchesChecker) Check(params []interface{}, names []string) (result bool, errmsg string) {
- f := reflect.ValueOf(params[0])
- if f.Kind() != reflect.Func || f.Type().NumIn() != 0 {
- return false, "Function must take zero arguments"
- }
- defer func() {
- // If the function has not panicked, then don't do the check.
- if errmsg != "" {
- return
- }
- obtained := recover()
- names[0] = "panic"
- if e, ok := obtained.(error); ok {
- params[0] = e.Error()
- } else if _, ok := obtained.(string); ok {
- params[0] = obtained
- } else {
- errmsg = "Panic value is not a string or an error"
- return
- }
- result, errmsg = matches(params[0], params[1])
- }()
- f.Call(nil)
- return false, "Function has not panicked"
-}
-
-// -----------------------------------------------------------------------
-// FitsTypeOf checker.
-
-type fitsTypeChecker struct {
- *CheckerInfo
-}
-
-// The FitsTypeOf checker verifies that the obtained value is
-// assignable to a variable with the same type as the provided
-// sample value.
-//
-// For example:
-//
-// c.Assert(value, FitsTypeOf, int64(0))
-// c.Assert(value, FitsTypeOf, os.Error(nil))
-//
-var FitsTypeOf Checker = &fitsTypeChecker{
- &CheckerInfo{Name: "FitsTypeOf", Params: []string{"obtained", "sample"}},
-}
-
-func (checker *fitsTypeChecker) Check(params []interface{}, names []string) (result bool, error string) {
- obtained := reflect.ValueOf(params[0])
- sample := reflect.ValueOf(params[1])
- if !obtained.IsValid() {
- return false, ""
- }
- if !sample.IsValid() {
- return false, "Invalid sample value"
- }
- return obtained.Type().AssignableTo(sample.Type()), ""
-}
-
-// -----------------------------------------------------------------------
-// Implements checker.
-
-type implementsChecker struct {
- *CheckerInfo
-}
-
-// The Implements checker verifies that the obtained value
-// implements the interface specified via a pointer to an interface
-// variable.
-//
-// For example:
-//
-// var e os.Error
-// c.Assert(err, Implements, &e)
-//
-var Implements Checker = &implementsChecker{
- &CheckerInfo{Name: "Implements", Params: []string{"obtained", "ifaceptr"}},
-}
-
-func (checker *implementsChecker) Check(params []interface{}, names []string) (result bool, error string) {
- obtained := reflect.ValueOf(params[0])
- ifaceptr := reflect.ValueOf(params[1])
- if !obtained.IsValid() {
- return false, ""
- }
- if !ifaceptr.IsValid() || ifaceptr.Kind() != reflect.Ptr || ifaceptr.Elem().Kind() != reflect.Interface {
- return false, "ifaceptr should be a pointer to an interface variable"
- }
- return obtained.Type().Implements(ifaceptr.Elem().Type()), ""
-}
diff --git a/vendor/gopkg.in/check.v1/checkers_test.go b/vendor/gopkg.in/check.v1/checkers_test.go
deleted file mode 100644
index 5c697474..00000000
--- a/vendor/gopkg.in/check.v1/checkers_test.go
+++ /dev/null
@@ -1,272 +0,0 @@
-package check_test
-
-import (
- "errors"
- "gopkg.in/check.v1"
- "reflect"
- "runtime"
-)
-
-type CheckersS struct{}
-
-var _ = check.Suite(&CheckersS{})
-
-func testInfo(c *check.C, checker check.Checker, name string, paramNames []string) {
- info := checker.Info()
- if info.Name != name {
- c.Fatalf("Got name %s, expected %s", info.Name, name)
- }
- if !reflect.DeepEqual(info.Params, paramNames) {
- c.Fatalf("Got param names %#v, expected %#v", info.Params, paramNames)
- }
-}
-
-func testCheck(c *check.C, checker check.Checker, result bool, error string, params ...interface{}) ([]interface{}, []string) {
- info := checker.Info()
- if len(params) != len(info.Params) {
- c.Fatalf("unexpected param count in test; expected %d got %d", len(info.Params), len(params))
- }
- names := append([]string{}, info.Params...)
- result_, error_ := checker.Check(params, names)
- if result_ != result || error_ != error {
- c.Fatalf("%s.Check(%#v) returned (%#v, %#v) rather than (%#v, %#v)",
- info.Name, params, result_, error_, result, error)
- }
- return params, names
-}
-
-func (s *CheckersS) TestComment(c *check.C) {
- bug := check.Commentf("a %d bc", 42)
- comment := bug.CheckCommentString()
- if comment != "a 42 bc" {
- c.Fatalf("Commentf returned %#v", comment)
- }
-}
-
-func (s *CheckersS) TestIsNil(c *check.C) {
- testInfo(c, check.IsNil, "IsNil", []string{"value"})
-
- testCheck(c, check.IsNil, true, "", nil)
- testCheck(c, check.IsNil, false, "", "a")
-
- testCheck(c, check.IsNil, true, "", (chan int)(nil))
- testCheck(c, check.IsNil, false, "", make(chan int))
- testCheck(c, check.IsNil, true, "", (error)(nil))
- testCheck(c, check.IsNil, false, "", errors.New(""))
- testCheck(c, check.IsNil, true, "", ([]int)(nil))
- testCheck(c, check.IsNil, false, "", make([]int, 1))
- testCheck(c, check.IsNil, false, "", int(0))
-}
-
-func (s *CheckersS) TestNotNil(c *check.C) {
- testInfo(c, check.NotNil, "NotNil", []string{"value"})
-
- testCheck(c, check.NotNil, false, "", nil)
- testCheck(c, check.NotNil, true, "", "a")
-
- testCheck(c, check.NotNil, false, "", (chan int)(nil))
- testCheck(c, check.NotNil, true, "", make(chan int))
- testCheck(c, check.NotNil, false, "", (error)(nil))
- testCheck(c, check.NotNil, true, "", errors.New(""))
- testCheck(c, check.NotNil, false, "", ([]int)(nil))
- testCheck(c, check.NotNil, true, "", make([]int, 1))
-}
-
-func (s *CheckersS) TestNot(c *check.C) {
- testInfo(c, check.Not(check.IsNil), "Not(IsNil)", []string{"value"})
-
- testCheck(c, check.Not(check.IsNil), false, "", nil)
- testCheck(c, check.Not(check.IsNil), true, "", "a")
-}
-
-type simpleStruct struct {
- i int
-}
-
-func (s *CheckersS) TestEquals(c *check.C) {
- testInfo(c, check.Equals, "Equals", []string{"obtained", "expected"})
-
- // The simplest.
- testCheck(c, check.Equals, true, "", 42, 42)
- testCheck(c, check.Equals, false, "", 42, 43)
-
- // Different native types.
- testCheck(c, check.Equals, false, "", int32(42), int64(42))
-
- // With nil.
- testCheck(c, check.Equals, false, "", 42, nil)
-
- // Slices
- testCheck(c, check.Equals, false, "runtime error: comparing uncomparable type []uint8", []byte{1, 2}, []byte{1, 2})
-
- // Struct values
- testCheck(c, check.Equals, true, "", simpleStruct{1}, simpleStruct{1})
- testCheck(c, check.Equals, false, "", simpleStruct{1}, simpleStruct{2})
-
- // Struct pointers
- testCheck(c, check.Equals, false, "", &simpleStruct{1}, &simpleStruct{1})
- testCheck(c, check.Equals, false, "", &simpleStruct{1}, &simpleStruct{2})
-}
-
-func (s *CheckersS) TestDeepEquals(c *check.C) {
- testInfo(c, check.DeepEquals, "DeepEquals", []string{"obtained", "expected"})
-
- // The simplest.
- testCheck(c, check.DeepEquals, true, "", 42, 42)
- testCheck(c, check.DeepEquals, false, "", 42, 43)
-
- // Different native types.
- testCheck(c, check.DeepEquals, false, "", int32(42), int64(42))
-
- // With nil.
- testCheck(c, check.DeepEquals, false, "", 42, nil)
-
- // Slices
- testCheck(c, check.DeepEquals, true, "", []byte{1, 2}, []byte{1, 2})
- testCheck(c, check.DeepEquals, false, "", []byte{1, 2}, []byte{1, 3})
-
- // Struct values
- testCheck(c, check.DeepEquals, true, "", simpleStruct{1}, simpleStruct{1})
- testCheck(c, check.DeepEquals, false, "", simpleStruct{1}, simpleStruct{2})
-
- // Struct pointers
- testCheck(c, check.DeepEquals, true, "", &simpleStruct{1}, &simpleStruct{1})
- testCheck(c, check.DeepEquals, false, "", &simpleStruct{1}, &simpleStruct{2})
-}
-
-func (s *CheckersS) TestHasLen(c *check.C) {
- testInfo(c, check.HasLen, "HasLen", []string{"obtained", "n"})
-
- testCheck(c, check.HasLen, true, "", "abcd", 4)
- testCheck(c, check.HasLen, true, "", []int{1, 2}, 2)
- testCheck(c, check.HasLen, false, "", []int{1, 2}, 3)
-
- testCheck(c, check.HasLen, false, "n must be an int", []int{1, 2}, "2")
- testCheck(c, check.HasLen, false, "obtained value type has no length", nil, 2)
-}
-
-func (s *CheckersS) TestErrorMatches(c *check.C) {
- testInfo(c, check.ErrorMatches, "ErrorMatches", []string{"value", "regex"})
-
- testCheck(c, check.ErrorMatches, false, "Error value is nil", nil, "some error")
- testCheck(c, check.ErrorMatches, false, "Value is not an error", 1, "some error")
- testCheck(c, check.ErrorMatches, true, "", errors.New("some error"), "some error")
- testCheck(c, check.ErrorMatches, true, "", errors.New("some error"), "so.*or")
-
- // Verify params mutation
- params, names := testCheck(c, check.ErrorMatches, false, "", errors.New("some error"), "other error")
- c.Assert(params[0], check.Equals, "some error")
- c.Assert(names[0], check.Equals, "error")
-}
-
-func (s *CheckersS) TestMatches(c *check.C) {
- testInfo(c, check.Matches, "Matches", []string{"value", "regex"})
-
- // Simple matching
- testCheck(c, check.Matches, true, "", "abc", "abc")
- testCheck(c, check.Matches, true, "", "abc", "a.c")
-
- // Must match fully
- testCheck(c, check.Matches, false, "", "abc", "ab")
- testCheck(c, check.Matches, false, "", "abc", "bc")
-
- // String()-enabled values accepted
- testCheck(c, check.Matches, true, "", reflect.ValueOf("abc"), "a.c")
- testCheck(c, check.Matches, false, "", reflect.ValueOf("abc"), "a.d")
-
- // Some error conditions.
- testCheck(c, check.Matches, false, "Obtained value is not a string and has no .String()", 1, "a.c")
- testCheck(c, check.Matches, false, "Can't compile regex: error parsing regexp: missing closing ]: `[c$`", "abc", "a[c")
-}
-
-func (s *CheckersS) TestPanics(c *check.C) {
- testInfo(c, check.Panics, "Panics", []string{"function", "expected"})
-
- // Some errors.
- testCheck(c, check.Panics, false, "Function has not panicked", func() bool { return false }, "BOOM")
- testCheck(c, check.Panics, false, "Function must take zero arguments", 1, "BOOM")
-
- // Plain strings.
- testCheck(c, check.Panics, true, "", func() { panic("BOOM") }, "BOOM")
- testCheck(c, check.Panics, false, "", func() { panic("KABOOM") }, "BOOM")
- testCheck(c, check.Panics, true, "", func() bool { panic("BOOM") }, "BOOM")
-
- // Error values.
- testCheck(c, check.Panics, true, "", func() { panic(errors.New("BOOM")) }, errors.New("BOOM"))
- testCheck(c, check.Panics, false, "", func() { panic(errors.New("KABOOM")) }, errors.New("BOOM"))
-
- type deep struct{ i int }
- // Deep value
- testCheck(c, check.Panics, true, "", func() { panic(&deep{99}) }, &deep{99})
-
- // Verify params/names mutation
- params, names := testCheck(c, check.Panics, false, "", func() { panic(errors.New("KABOOM")) }, errors.New("BOOM"))
- c.Assert(params[0], check.ErrorMatches, "KABOOM")
- c.Assert(names[0], check.Equals, "panic")
-
- // Verify a nil panic
- testCheck(c, check.Panics, true, "", func() { panic(nil) }, nil)
- testCheck(c, check.Panics, false, "", func() { panic(nil) }, "NOPE")
-}
-
-func (s *CheckersS) TestPanicMatches(c *check.C) {
- testInfo(c, check.PanicMatches, "PanicMatches", []string{"function", "expected"})
-
- // Error matching.
- testCheck(c, check.PanicMatches, true, "", func() { panic(errors.New("BOOM")) }, "BO.M")
- testCheck(c, check.PanicMatches, false, "", func() { panic(errors.New("KABOOM")) }, "BO.M")
-
- // Some errors.
- testCheck(c, check.PanicMatches, false, "Function has not panicked", func() bool { return false }, "BOOM")
- testCheck(c, check.PanicMatches, false, "Function must take zero arguments", 1, "BOOM")
-
- // Plain strings.
- testCheck(c, check.PanicMatches, true, "", func() { panic("BOOM") }, "BO.M")
- testCheck(c, check.PanicMatches, false, "", func() { panic("KABOOM") }, "BOOM")
- testCheck(c, check.PanicMatches, true, "", func() bool { panic("BOOM") }, "BO.M")
-
- // Verify params/names mutation
- params, names := testCheck(c, check.PanicMatches, false, "", func() { panic(errors.New("KABOOM")) }, "BOOM")
- c.Assert(params[0], check.Equals, "KABOOM")
- c.Assert(names[0], check.Equals, "panic")
-
- // Verify a nil panic
- testCheck(c, check.PanicMatches, false, "Panic value is not a string or an error", func() { panic(nil) }, "")
-}
-
-func (s *CheckersS) TestFitsTypeOf(c *check.C) {
- testInfo(c, check.FitsTypeOf, "FitsTypeOf", []string{"obtained", "sample"})
-
- // Basic types
- testCheck(c, check.FitsTypeOf, true, "", 1, 0)
- testCheck(c, check.FitsTypeOf, false, "", 1, int64(0))
-
- // Aliases
- testCheck(c, check.FitsTypeOf, false, "", 1, errors.New(""))
- testCheck(c, check.FitsTypeOf, false, "", "error", errors.New(""))
- testCheck(c, check.FitsTypeOf, true, "", errors.New("error"), errors.New(""))
-
- // Structures
- testCheck(c, check.FitsTypeOf, false, "", 1, simpleStruct{})
- testCheck(c, check.FitsTypeOf, false, "", simpleStruct{42}, &simpleStruct{})
- testCheck(c, check.FitsTypeOf, true, "", simpleStruct{42}, simpleStruct{})
- testCheck(c, check.FitsTypeOf, true, "", &simpleStruct{42}, &simpleStruct{})
-
- // Some bad values
- testCheck(c, check.FitsTypeOf, false, "Invalid sample value", 1, interface{}(nil))
- testCheck(c, check.FitsTypeOf, false, "", interface{}(nil), 0)
-}
-
-func (s *CheckersS) TestImplements(c *check.C) {
- testInfo(c, check.Implements, "Implements", []string{"obtained", "ifaceptr"})
-
- var e error
- var re runtime.Error
- testCheck(c, check.Implements, true, "", errors.New(""), &e)
- testCheck(c, check.Implements, false, "", errors.New(""), &re)
-
- // Some bad values
- testCheck(c, check.Implements, false, "ifaceptr should be a pointer to an interface variable", 0, errors.New(""))
- testCheck(c, check.Implements, false, "ifaceptr should be a pointer to an interface variable", 0, interface{}(nil))
- testCheck(c, check.Implements, false, "", interface{}(nil), &e)
-}
diff --git a/vendor/gopkg.in/check.v1/export_test.go b/vendor/gopkg.in/check.v1/export_test.go
deleted file mode 100644
index abb89a2d..00000000
--- a/vendor/gopkg.in/check.v1/export_test.go
+++ /dev/null
@@ -1,19 +0,0 @@
-package check
-
-import "io"
-
-func PrintLine(filename string, line int) (string, error) {
- return printLine(filename, line)
-}
-
-func Indent(s, with string) string {
- return indent(s, with)
-}
-
-func NewOutputWriter(writer io.Writer, stream, verbose bool) *outputWriter {
- return newOutputWriter(writer, stream, verbose)
-}
-
-func (c *C) FakeSkip(reason string) {
- c.reason = reason
-}
diff --git a/vendor/gopkg.in/check.v1/fixture_test.go b/vendor/gopkg.in/check.v1/fixture_test.go
deleted file mode 100644
index 2bff9e16..00000000
--- a/vendor/gopkg.in/check.v1/fixture_test.go
+++ /dev/null
@@ -1,484 +0,0 @@
-// Tests for the behavior of the test fixture system.
-
-package check_test
-
-import (
- . "gopkg.in/check.v1"
-)
-
-// -----------------------------------------------------------------------
-// Fixture test suite.
-
-type FixtureS struct{}
-
-var fixtureS = Suite(&FixtureS{})
-
-func (s *FixtureS) TestCountSuite(c *C) {
- suitesRun += 1
-}
-
-// -----------------------------------------------------------------------
-// Basic fixture ordering verification.
-
-func (s *FixtureS) TestOrder(c *C) {
- helper := FixtureHelper{}
- Run(&helper, nil)
- c.Check(helper.calls[0], Equals, "SetUpSuite")
- c.Check(helper.calls[1], Equals, "SetUpTest")
- c.Check(helper.calls[2], Equals, "Test1")
- c.Check(helper.calls[3], Equals, "TearDownTest")
- c.Check(helper.calls[4], Equals, "SetUpTest")
- c.Check(helper.calls[5], Equals, "Test2")
- c.Check(helper.calls[6], Equals, "TearDownTest")
- c.Check(helper.calls[7], Equals, "TearDownSuite")
- c.Check(len(helper.calls), Equals, 8)
-}
-
-// -----------------------------------------------------------------------
-// Check the behavior when panics occur within tests and fixtures.
-
-func (s *FixtureS) TestPanicOnTest(c *C) {
- helper := FixtureHelper{panicOn: "Test1"}
- output := String{}
- Run(&helper, &RunConf{Output: &output})
- c.Check(helper.calls[0], Equals, "SetUpSuite")
- c.Check(helper.calls[1], Equals, "SetUpTest")
- c.Check(helper.calls[2], Equals, "Test1")
- c.Check(helper.calls[3], Equals, "TearDownTest")
- c.Check(helper.calls[4], Equals, "SetUpTest")
- c.Check(helper.calls[5], Equals, "Test2")
- c.Check(helper.calls[6], Equals, "TearDownTest")
- c.Check(helper.calls[7], Equals, "TearDownSuite")
- c.Check(len(helper.calls), Equals, 8)
-
- expected := "^\n-+\n" +
- "PANIC: check_test\\.go:[0-9]+: FixtureHelper.Test1\n\n" +
- "\\.\\.\\. Panic: Test1 \\(PC=[xA-F0-9]+\\)\n\n" +
- ".+:[0-9]+\n" +
- " in (go)?panic\n" +
- ".*check_test.go:[0-9]+\n" +
- " in FixtureHelper.trace\n" +
- ".*check_test.go:[0-9]+\n" +
- " in FixtureHelper.Test1\n" +
- "(.|\n)*$"
-
- c.Check(output.value, Matches, expected)
-}
-
-func (s *FixtureS) TestPanicOnSetUpTest(c *C) {
- helper := FixtureHelper{panicOn: "SetUpTest"}
- output := String{}
- Run(&helper, &RunConf{Output: &output})
- c.Check(helper.calls[0], Equals, "SetUpSuite")
- c.Check(helper.calls[1], Equals, "SetUpTest")
- c.Check(helper.calls[2], Equals, "TearDownTest")
- c.Check(helper.calls[3], Equals, "TearDownSuite")
- c.Check(len(helper.calls), Equals, 4)
-
- expected := "^\n-+\n" +
- "PANIC: check_test\\.go:[0-9]+: " +
- "FixtureHelper\\.SetUpTest\n\n" +
- "\\.\\.\\. Panic: SetUpTest \\(PC=[xA-F0-9]+\\)\n\n" +
- ".+:[0-9]+\n" +
- " in (go)?panic\n" +
- ".*check_test.go:[0-9]+\n" +
- " in FixtureHelper.trace\n" +
- ".*check_test.go:[0-9]+\n" +
- " in FixtureHelper.SetUpTest\n" +
- "(.|\n)*" +
- "\n-+\n" +
- "PANIC: check_test\\.go:[0-9]+: " +
- "FixtureHelper\\.Test1\n\n" +
- "\\.\\.\\. Panic: Fixture has panicked " +
- "\\(see related PANIC\\)\n$"
-
- c.Check(output.value, Matches, expected)
-}
-
-func (s *FixtureS) TestPanicOnTearDownTest(c *C) {
- helper := FixtureHelper{panicOn: "TearDownTest"}
- output := String{}
- Run(&helper, &RunConf{Output: &output})
- c.Check(helper.calls[0], Equals, "SetUpSuite")
- c.Check(helper.calls[1], Equals, "SetUpTest")
- c.Check(helper.calls[2], Equals, "Test1")
- c.Check(helper.calls[3], Equals, "TearDownTest")
- c.Check(helper.calls[4], Equals, "TearDownSuite")
- c.Check(len(helper.calls), Equals, 5)
-
- expected := "^\n-+\n" +
- "PANIC: check_test\\.go:[0-9]+: " +
- "FixtureHelper.TearDownTest\n\n" +
- "\\.\\.\\. Panic: TearDownTest \\(PC=[xA-F0-9]+\\)\n\n" +
- ".+:[0-9]+\n" +
- " in (go)?panic\n" +
- ".*check_test.go:[0-9]+\n" +
- " in FixtureHelper.trace\n" +
- ".*check_test.go:[0-9]+\n" +
- " in FixtureHelper.TearDownTest\n" +
- "(.|\n)*" +
- "\n-+\n" +
- "PANIC: check_test\\.go:[0-9]+: " +
- "FixtureHelper\\.Test1\n\n" +
- "\\.\\.\\. Panic: Fixture has panicked " +
- "\\(see related PANIC\\)\n$"
-
- c.Check(output.value, Matches, expected)
-}
-
-func (s *FixtureS) TestPanicOnSetUpSuite(c *C) {
- helper := FixtureHelper{panicOn: "SetUpSuite"}
- output := String{}
- Run(&helper, &RunConf{Output: &output})
- c.Check(helper.calls[0], Equals, "SetUpSuite")
- c.Check(helper.calls[1], Equals, "TearDownSuite")
- c.Check(len(helper.calls), Equals, 2)
-
- expected := "^\n-+\n" +
- "PANIC: check_test\\.go:[0-9]+: " +
- "FixtureHelper.SetUpSuite\n\n" +
- "\\.\\.\\. Panic: SetUpSuite \\(PC=[xA-F0-9]+\\)\n\n" +
- ".+:[0-9]+\n" +
- " in (go)?panic\n" +
- ".*check_test.go:[0-9]+\n" +
- " in FixtureHelper.trace\n" +
- ".*check_test.go:[0-9]+\n" +
- " in FixtureHelper.SetUpSuite\n" +
- "(.|\n)*$"
-
- c.Check(output.value, Matches, expected)
-}
-
-func (s *FixtureS) TestPanicOnTearDownSuite(c *C) {
- helper := FixtureHelper{panicOn: "TearDownSuite"}
- output := String{}
- Run(&helper, &RunConf{Output: &output})
- c.Check(helper.calls[0], Equals, "SetUpSuite")
- c.Check(helper.calls[1], Equals, "SetUpTest")
- c.Check(helper.calls[2], Equals, "Test1")
- c.Check(helper.calls[3], Equals, "TearDownTest")
- c.Check(helper.calls[4], Equals, "SetUpTest")
- c.Check(helper.calls[5], Equals, "Test2")
- c.Check(helper.calls[6], Equals, "TearDownTest")
- c.Check(helper.calls[7], Equals, "TearDownSuite")
- c.Check(len(helper.calls), Equals, 8)
-
- expected := "^\n-+\n" +
- "PANIC: check_test\\.go:[0-9]+: " +
- "FixtureHelper.TearDownSuite\n\n" +
- "\\.\\.\\. Panic: TearDownSuite \\(PC=[xA-F0-9]+\\)\n\n" +
- ".+:[0-9]+\n" +
- " in (go)?panic\n" +
- ".*check_test.go:[0-9]+\n" +
- " in FixtureHelper.trace\n" +
- ".*check_test.go:[0-9]+\n" +
- " in FixtureHelper.TearDownSuite\n" +
- "(.|\n)*$"
-
- c.Check(output.value, Matches, expected)
-}
-
-// -----------------------------------------------------------------------
-// A wrong argument on a test or fixture will produce a nice error.
-
-func (s *FixtureS) TestPanicOnWrongTestArg(c *C) {
- helper := WrongTestArgHelper{}
- output := String{}
- Run(&helper, &RunConf{Output: &output})
- c.Check(helper.calls[0], Equals, "SetUpSuite")
- c.Check(helper.calls[1], Equals, "SetUpTest")
- c.Check(helper.calls[2], Equals, "TearDownTest")
- c.Check(helper.calls[3], Equals, "SetUpTest")
- c.Check(helper.calls[4], Equals, "Test2")
- c.Check(helper.calls[5], Equals, "TearDownTest")
- c.Check(helper.calls[6], Equals, "TearDownSuite")
- c.Check(len(helper.calls), Equals, 7)
-
- expected := "^\n-+\n" +
- "PANIC: fixture_test\\.go:[0-9]+: " +
- "WrongTestArgHelper\\.Test1\n\n" +
- "\\.\\.\\. Panic: WrongTestArgHelper\\.Test1 argument " +
- "should be \\*check\\.C\n"
-
- c.Check(output.value, Matches, expected)
-}
-
-func (s *FixtureS) TestPanicOnWrongSetUpTestArg(c *C) {
- helper := WrongSetUpTestArgHelper{}
- output := String{}
- Run(&helper, &RunConf{Output: &output})
- c.Check(len(helper.calls), Equals, 0)
-
- expected :=
- "^\n-+\n" +
- "PANIC: fixture_test\\.go:[0-9]+: " +
- "WrongSetUpTestArgHelper\\.SetUpTest\n\n" +
- "\\.\\.\\. Panic: WrongSetUpTestArgHelper\\.SetUpTest argument " +
- "should be \\*check\\.C\n"
-
- c.Check(output.value, Matches, expected)
-}
-
-func (s *FixtureS) TestPanicOnWrongSetUpSuiteArg(c *C) {
- helper := WrongSetUpSuiteArgHelper{}
- output := String{}
- Run(&helper, &RunConf{Output: &output})
- c.Check(len(helper.calls), Equals, 0)
-
- expected :=
- "^\n-+\n" +
- "PANIC: fixture_test\\.go:[0-9]+: " +
- "WrongSetUpSuiteArgHelper\\.SetUpSuite\n\n" +
- "\\.\\.\\. Panic: WrongSetUpSuiteArgHelper\\.SetUpSuite argument " +
- "should be \\*check\\.C\n"
-
- c.Check(output.value, Matches, expected)
-}
-
-// -----------------------------------------------------------------------
-// Nice errors also when tests or fixture have wrong arg count.
-
-func (s *FixtureS) TestPanicOnWrongTestArgCount(c *C) {
- helper := WrongTestArgCountHelper{}
- output := String{}
- Run(&helper, &RunConf{Output: &output})
- c.Check(helper.calls[0], Equals, "SetUpSuite")
- c.Check(helper.calls[1], Equals, "SetUpTest")
- c.Check(helper.calls[2], Equals, "TearDownTest")
- c.Check(helper.calls[3], Equals, "SetUpTest")
- c.Check(helper.calls[4], Equals, "Test2")
- c.Check(helper.calls[5], Equals, "TearDownTest")
- c.Check(helper.calls[6], Equals, "TearDownSuite")
- c.Check(len(helper.calls), Equals, 7)
-
- expected := "^\n-+\n" +
- "PANIC: fixture_test\\.go:[0-9]+: " +
- "WrongTestArgCountHelper\\.Test1\n\n" +
- "\\.\\.\\. Panic: WrongTestArgCountHelper\\.Test1 argument " +
- "should be \\*check\\.C\n"
-
- c.Check(output.value, Matches, expected)
-}
-
-func (s *FixtureS) TestPanicOnWrongSetUpTestArgCount(c *C) {
- helper := WrongSetUpTestArgCountHelper{}
- output := String{}
- Run(&helper, &RunConf{Output: &output})
- c.Check(len(helper.calls), Equals, 0)
-
- expected :=
- "^\n-+\n" +
- "PANIC: fixture_test\\.go:[0-9]+: " +
- "WrongSetUpTestArgCountHelper\\.SetUpTest\n\n" +
- "\\.\\.\\. Panic: WrongSetUpTestArgCountHelper\\.SetUpTest argument " +
- "should be \\*check\\.C\n"
-
- c.Check(output.value, Matches, expected)
-}
-
-func (s *FixtureS) TestPanicOnWrongSetUpSuiteArgCount(c *C) {
- helper := WrongSetUpSuiteArgCountHelper{}
- output := String{}
- Run(&helper, &RunConf{Output: &output})
- c.Check(len(helper.calls), Equals, 0)
-
- expected :=
- "^\n-+\n" +
- "PANIC: fixture_test\\.go:[0-9]+: " +
- "WrongSetUpSuiteArgCountHelper\\.SetUpSuite\n\n" +
- "\\.\\.\\. Panic: WrongSetUpSuiteArgCountHelper" +
- "\\.SetUpSuite argument should be \\*check\\.C\n"
-
- c.Check(output.value, Matches, expected)
-}
-
-// -----------------------------------------------------------------------
-// Helper test suites with wrong function arguments.
-
-type WrongTestArgHelper struct {
- FixtureHelper
-}
-
-func (s *WrongTestArgHelper) Test1(t int) {
-}
-
-type WrongSetUpTestArgHelper struct {
- FixtureHelper
-}
-
-func (s *WrongSetUpTestArgHelper) SetUpTest(t int) {
-}
-
-type WrongSetUpSuiteArgHelper struct {
- FixtureHelper
-}
-
-func (s *WrongSetUpSuiteArgHelper) SetUpSuite(t int) {
-}
-
-type WrongTestArgCountHelper struct {
- FixtureHelper
-}
-
-func (s *WrongTestArgCountHelper) Test1(c *C, i int) {
-}
-
-type WrongSetUpTestArgCountHelper struct {
- FixtureHelper
-}
-
-func (s *WrongSetUpTestArgCountHelper) SetUpTest(c *C, i int) {
-}
-
-type WrongSetUpSuiteArgCountHelper struct {
- FixtureHelper
-}
-
-func (s *WrongSetUpSuiteArgCountHelper) SetUpSuite(c *C, i int) {
-}
-
-// -----------------------------------------------------------------------
-// Ensure fixture doesn't run without tests.
-
-type NoTestsHelper struct {
- hasRun bool
-}
-
-func (s *NoTestsHelper) SetUpSuite(c *C) {
- s.hasRun = true
-}
-
-func (s *NoTestsHelper) TearDownSuite(c *C) {
- s.hasRun = true
-}
-
-func (s *FixtureS) TestFixtureDoesntRunWithoutTests(c *C) {
- helper := NoTestsHelper{}
- output := String{}
- Run(&helper, &RunConf{Output: &output})
- c.Check(helper.hasRun, Equals, false)
-}
-
-// -----------------------------------------------------------------------
-// Verify that checks and assertions work correctly inside the fixture.
-
-type FixtureCheckHelper struct {
- fail string
- completed bool
-}
-
-func (s *FixtureCheckHelper) SetUpSuite(c *C) {
- switch s.fail {
- case "SetUpSuiteAssert":
- c.Assert(false, Equals, true)
- case "SetUpSuiteCheck":
- c.Check(false, Equals, true)
- }
- s.completed = true
-}
-
-func (s *FixtureCheckHelper) SetUpTest(c *C) {
- switch s.fail {
- case "SetUpTestAssert":
- c.Assert(false, Equals, true)
- case "SetUpTestCheck":
- c.Check(false, Equals, true)
- }
- s.completed = true
-}
-
-func (s *FixtureCheckHelper) Test(c *C) {
- // Do nothing.
-}
-
-func (s *FixtureS) TestSetUpSuiteCheck(c *C) {
- helper := FixtureCheckHelper{fail: "SetUpSuiteCheck"}
- output := String{}
- Run(&helper, &RunConf{Output: &output})
- c.Assert(output.value, Matches,
- "\n---+\n"+
- "FAIL: fixture_test\\.go:[0-9]+: "+
- "FixtureCheckHelper\\.SetUpSuite\n\n"+
- "fixture_test\\.go:[0-9]+:\n"+
- " c\\.Check\\(false, Equals, true\\)\n"+
- "\\.+ obtained bool = false\n"+
- "\\.+ expected bool = true\n\n")
- c.Assert(helper.completed, Equals, true)
-}
-
-func (s *FixtureS) TestSetUpSuiteAssert(c *C) {
- helper := FixtureCheckHelper{fail: "SetUpSuiteAssert"}
- output := String{}
- Run(&helper, &RunConf{Output: &output})
- c.Assert(output.value, Matches,
- "\n---+\n"+
- "FAIL: fixture_test\\.go:[0-9]+: "+
- "FixtureCheckHelper\\.SetUpSuite\n\n"+
- "fixture_test\\.go:[0-9]+:\n"+
- " c\\.Assert\\(false, Equals, true\\)\n"+
- "\\.+ obtained bool = false\n"+
- "\\.+ expected bool = true\n\n")
- c.Assert(helper.completed, Equals, false)
-}
-
-// -----------------------------------------------------------------------
-// Verify that logging within SetUpTest() persists within the test log itself.
-
-type FixtureLogHelper struct {
- c *C
-}
-
-func (s *FixtureLogHelper) SetUpTest(c *C) {
- s.c = c
- c.Log("1")
-}
-
-func (s *FixtureLogHelper) Test(c *C) {
- c.Log("2")
- s.c.Log("3")
- c.Log("4")
- c.Fail()
-}
-
-func (s *FixtureLogHelper) TearDownTest(c *C) {
- s.c.Log("5")
-}
-
-func (s *FixtureS) TestFixtureLogging(c *C) {
- helper := FixtureLogHelper{}
- output := String{}
- Run(&helper, &RunConf{Output: &output})
- c.Assert(output.value, Matches,
- "\n---+\n"+
- "FAIL: fixture_test\\.go:[0-9]+: "+
- "FixtureLogHelper\\.Test\n\n"+
- "1\n2\n3\n4\n5\n")
-}
-
-// -----------------------------------------------------------------------
-// Skip() within fixture methods.
-
-func (s *FixtureS) TestSkipSuite(c *C) {
- helper := FixtureHelper{skip: true, skipOnN: 0}
- output := String{}
- result := Run(&helper, &RunConf{Output: &output})
- c.Assert(output.value, Equals, "")
- c.Assert(helper.calls[0], Equals, "SetUpSuite")
- c.Assert(helper.calls[1], Equals, "TearDownSuite")
- c.Assert(len(helper.calls), Equals, 2)
- c.Assert(result.Skipped, Equals, 2)
-}
-
-func (s *FixtureS) TestSkipTest(c *C) {
- helper := FixtureHelper{skip: true, skipOnN: 1}
- output := String{}
- result := Run(&helper, &RunConf{Output: &output})
- c.Assert(helper.calls[0], Equals, "SetUpSuite")
- c.Assert(helper.calls[1], Equals, "SetUpTest")
- c.Assert(helper.calls[2], Equals, "SetUpTest")
- c.Assert(helper.calls[3], Equals, "Test2")
- c.Assert(helper.calls[4], Equals, "TearDownTest")
- c.Assert(helper.calls[5], Equals, "TearDownSuite")
- c.Assert(len(helper.calls), Equals, 6)
- c.Assert(result.Skipped, Equals, 1)
-}
diff --git a/vendor/gopkg.in/check.v1/foundation_test.go b/vendor/gopkg.in/check.v1/foundation_test.go
deleted file mode 100644
index 8ecf7915..00000000
--- a/vendor/gopkg.in/check.v1/foundation_test.go
+++ /dev/null
@@ -1,335 +0,0 @@
-// These tests check that the foundations of gocheck are working properly.
-// They already assume that fundamental failing is working already, though,
-// since this was tested in bootstrap_test.go. Even then, some care may
-// still have to be taken when using external functions, since they should
-// of course not rely on functionality tested here.
-
-package check_test
-
-import (
- "fmt"
- "gopkg.in/check.v1"
- "log"
- "os"
- "regexp"
- "strings"
-)
-
-// -----------------------------------------------------------------------
-// Foundation test suite.
-
-type FoundationS struct{}
-
-var foundationS = check.Suite(&FoundationS{})
-
-func (s *FoundationS) TestCountSuite(c *check.C) {
- suitesRun += 1
-}
-
-func (s *FoundationS) TestErrorf(c *check.C) {
- // Do not use checkState() here. It depends on Errorf() working.
- expectedLog := fmt.Sprintf("foundation_test.go:%d:\n"+
- " c.Errorf(\"Error %%v!\", \"message\")\n"+
- "... Error: Error message!\n\n",
- getMyLine()+1)
- c.Errorf("Error %v!", "message")
- failed := c.Failed()
- c.Succeed()
- if log := c.GetTestLog(); log != expectedLog {
- c.Logf("Errorf() logged %#v rather than %#v", log, expectedLog)
- c.Fail()
- }
- if !failed {
- c.Logf("Errorf() didn't put the test in a failed state")
- c.Fail()
- }
-}
-
-func (s *FoundationS) TestError(c *check.C) {
- expectedLog := fmt.Sprintf("foundation_test.go:%d:\n"+
- " c\\.Error\\(\"Error \", \"message!\"\\)\n"+
- "\\.\\.\\. Error: Error message!\n\n",
- getMyLine()+1)
- c.Error("Error ", "message!")
- checkState(c, nil,
- &expectedState{
- name: "Error(`Error `, `message!`)",
- failed: true,
- log: expectedLog,
- })
-}
-
-func (s *FoundationS) TestFailNow(c *check.C) {
- defer (func() {
- if !c.Failed() {
- c.Error("FailNow() didn't fail the test")
- } else {
- c.Succeed()
- if c.GetTestLog() != "" {
- c.Error("Something got logged:\n" + c.GetTestLog())
- }
- }
- })()
-
- c.FailNow()
- c.Log("FailNow() didn't stop the test")
-}
-
-func (s *FoundationS) TestSucceedNow(c *check.C) {
- defer (func() {
- if c.Failed() {
- c.Error("SucceedNow() didn't succeed the test")
- }
- if c.GetTestLog() != "" {
- c.Error("Something got logged:\n" + c.GetTestLog())
- }
- })()
-
- c.Fail()
- c.SucceedNow()
- c.Log("SucceedNow() didn't stop the test")
-}
-
-func (s *FoundationS) TestFailureHeader(c *check.C) {
- output := String{}
- failHelper := FailHelper{}
- check.Run(&failHelper, &check.RunConf{Output: &output})
- header := fmt.Sprintf(""+
- "\n-----------------------------------"+
- "-----------------------------------\n"+
- "FAIL: check_test.go:%d: FailHelper.TestLogAndFail\n",
- failHelper.testLine)
- if strings.Index(output.value, header) == -1 {
- c.Errorf(""+
- "Failure didn't print a proper header.\n"+
- "... Got:\n%s... Expected something with:\n%s",
- output.value, header)
- }
-}
-
-func (s *FoundationS) TestFatal(c *check.C) {
- var line int
- defer (func() {
- if !c.Failed() {
- c.Error("Fatal() didn't fail the test")
- } else {
- c.Succeed()
- expected := fmt.Sprintf("foundation_test.go:%d:\n"+
- " c.Fatal(\"Die \", \"now!\")\n"+
- "... Error: Die now!\n\n",
- line)
- if c.GetTestLog() != expected {
- c.Error("Incorrect log:", c.GetTestLog())
- }
- }
- })()
-
- line = getMyLine() + 1
- c.Fatal("Die ", "now!")
- c.Log("Fatal() didn't stop the test")
-}
-
-func (s *FoundationS) TestFatalf(c *check.C) {
- var line int
- defer (func() {
- if !c.Failed() {
- c.Error("Fatalf() didn't fail the test")
- } else {
- c.Succeed()
- expected := fmt.Sprintf("foundation_test.go:%d:\n"+
- " c.Fatalf(\"Die %%s!\", \"now\")\n"+
- "... Error: Die now!\n\n",
- line)
- if c.GetTestLog() != expected {
- c.Error("Incorrect log:", c.GetTestLog())
- }
- }
- })()
-
- line = getMyLine() + 1
- c.Fatalf("Die %s!", "now")
- c.Log("Fatalf() didn't stop the test")
-}
-
-func (s *FoundationS) TestCallerLoggingInsideTest(c *check.C) {
- log := fmt.Sprintf(""+
- "foundation_test.go:%d:\n"+
- " result := c.Check\\(10, check.Equals, 20\\)\n"+
- "\\.\\.\\. obtained int = 10\n"+
- "\\.\\.\\. expected int = 20\n\n",
- getMyLine()+1)
- result := c.Check(10, check.Equals, 20)
- checkState(c, result,
- &expectedState{
- name: "Check(10, Equals, 20)",
- result: false,
- failed: true,
- log: log,
- })
-}
-
-func (s *FoundationS) TestCallerLoggingInDifferentFile(c *check.C) {
- result, line := checkEqualWrapper(c, 10, 20)
- testLine := getMyLine() - 1
- log := fmt.Sprintf(""+
- "foundation_test.go:%d:\n"+
- " result, line := checkEqualWrapper\\(c, 10, 20\\)\n"+
- "check_test.go:%d:\n"+
- " return c.Check\\(obtained, check.Equals, expected\\), getMyLine\\(\\)\n"+
- "\\.\\.\\. obtained int = 10\n"+
- "\\.\\.\\. expected int = 20\n\n",
- testLine, line)
- checkState(c, result,
- &expectedState{
- name: "Check(10, Equals, 20)",
- result: false,
- failed: true,
- log: log,
- })
-}
-
-// -----------------------------------------------------------------------
-// ExpectFailure() inverts the logic of failure.
-
-type ExpectFailureSucceedHelper struct{}
-
-func (s *ExpectFailureSucceedHelper) TestSucceed(c *check.C) {
- c.ExpectFailure("It booms!")
- c.Error("Boom!")
-}
-
-type ExpectFailureFailHelper struct{}
-
-func (s *ExpectFailureFailHelper) TestFail(c *check.C) {
- c.ExpectFailure("Bug #XYZ")
-}
-
-func (s *FoundationS) TestExpectFailureFail(c *check.C) {
- helper := ExpectFailureFailHelper{}
- output := String{}
- result := check.Run(&helper, &check.RunConf{Output: &output})
-
- expected := "" +
- "^\n-+\n" +
- "FAIL: foundation_test\\.go:[0-9]+:" +
- " ExpectFailureFailHelper\\.TestFail\n\n" +
- "\\.\\.\\. Error: Test succeeded, but was expected to fail\n" +
- "\\.\\.\\. Reason: Bug #XYZ\n$"
-
- matched, err := regexp.MatchString(expected, output.value)
- if err != nil {
- c.Error("Bad expression: ", expected)
- } else if !matched {
- c.Error("ExpectFailure() didn't log properly:\n", output.value)
- }
-
- c.Assert(result.ExpectedFailures, check.Equals, 0)
-}
-
-func (s *FoundationS) TestExpectFailureSucceed(c *check.C) {
- helper := ExpectFailureSucceedHelper{}
- output := String{}
- result := check.Run(&helper, &check.RunConf{Output: &output})
-
- c.Assert(output.value, check.Equals, "")
- c.Assert(result.ExpectedFailures, check.Equals, 1)
-}
-
-func (s *FoundationS) TestExpectFailureSucceedVerbose(c *check.C) {
- helper := ExpectFailureSucceedHelper{}
- output := String{}
- result := check.Run(&helper, &check.RunConf{Output: &output, Verbose: true})
-
- expected := "" +
- "FAIL EXPECTED: foundation_test\\.go:[0-9]+:" +
- " ExpectFailureSucceedHelper\\.TestSucceed \\(It booms!\\)\t *[.0-9]+s\n"
-
- matched, err := regexp.MatchString(expected, output.value)
- if err != nil {
- c.Error("Bad expression: ", expected)
- } else if !matched {
- c.Error("ExpectFailure() didn't log properly:\n", output.value)
- }
-
- c.Assert(result.ExpectedFailures, check.Equals, 1)
-}
-
-// -----------------------------------------------------------------------
-// Skip() allows stopping a test without positive/negative results.
-
-type SkipTestHelper struct{}
-
-func (s *SkipTestHelper) TestFail(c *check.C) {
- c.Skip("Wrong platform or whatever")
- c.Error("Boom!")
-}
-
-func (s *FoundationS) TestSkip(c *check.C) {
- helper := SkipTestHelper{}
- output := String{}
- check.Run(&helper, &check.RunConf{Output: &output})
-
- if output.value != "" {
- c.Error("Skip() logged something:\n", output.value)
- }
-}
-
-func (s *FoundationS) TestSkipVerbose(c *check.C) {
- helper := SkipTestHelper{}
- output := String{}
- check.Run(&helper, &check.RunConf{Output: &output, Verbose: true})
-
- expected := "SKIP: foundation_test\\.go:[0-9]+: SkipTestHelper\\.TestFail" +
- " \\(Wrong platform or whatever\\)"
- matched, err := regexp.MatchString(expected, output.value)
- if err != nil {
- c.Error("Bad expression: ", expected)
- } else if !matched {
- c.Error("Skip() didn't log properly:\n", output.value)
- }
-}
-
-// -----------------------------------------------------------------------
-// Check minimum *log.Logger interface provided by *check.C.
-
-type minLogger interface {
- Output(calldepth int, s string) error
-}
-
-func (s *BootstrapS) TestMinLogger(c *check.C) {
- var logger minLogger
- logger = log.New(os.Stderr, "", 0)
- logger = c
- logger.Output(0, "Hello there")
- expected := `\[LOG\] [0-9]+:[0-9][0-9]\.[0-9][0-9][0-9] +Hello there\n`
- output := c.GetTestLog()
- c.Assert(output, check.Matches, expected)
-}
-
-// -----------------------------------------------------------------------
-// Ensure that suites with embedded types are working fine, including the
-// the workaround for issue 906.
-
-type EmbeddedInternalS struct {
- called bool
-}
-
-type EmbeddedS struct {
- EmbeddedInternalS
-}
-
-var embeddedS = check.Suite(&EmbeddedS{})
-
-func (s *EmbeddedS) TestCountSuite(c *check.C) {
- suitesRun += 1
-}
-
-func (s *EmbeddedInternalS) TestMethod(c *check.C) {
- c.Error("TestMethod() of the embedded type was called!?")
-}
-
-func (s *EmbeddedS) TestMethod(c *check.C) {
- // http://code.google.com/p/go/issues/detail?id=906
- c.Check(s.called, check.Equals, false) // Go issue 906 is affecting the runner?
- s.called = true
-}
diff --git a/vendor/gopkg.in/check.v1/helpers.go b/vendor/gopkg.in/check.v1/helpers.go
deleted file mode 100644
index 58a733b5..00000000
--- a/vendor/gopkg.in/check.v1/helpers.go
+++ /dev/null
@@ -1,231 +0,0 @@
-package check
-
-import (
- "fmt"
- "strings"
- "time"
-)
-
-// TestName returns the current test name in the form "SuiteName.TestName"
-func (c *C) TestName() string {
- return c.testName
-}
-
-// -----------------------------------------------------------------------
-// Basic succeeding/failing logic.
-
-// Failed returns whether the currently running test has already failed.
-func (c *C) Failed() bool {
- return c.status() == failedSt
-}
-
-// Fail marks the currently running test as failed.
-//
-// Something ought to have been previously logged so the developer can tell
-// what went wrong. The higher level helper functions will fail the test
-// and do the logging properly.
-func (c *C) Fail() {
- c.setStatus(failedSt)
-}
-
-// FailNow marks the currently running test as failed and stops running it.
-// Something ought to have been previously logged so the developer can tell
-// what went wrong. The higher level helper functions will fail the test
-// and do the logging properly.
-func (c *C) FailNow() {
- c.Fail()
- c.stopNow()
-}
-
-// Succeed marks the currently running test as succeeded, undoing any
-// previous failures.
-func (c *C) Succeed() {
- c.setStatus(succeededSt)
-}
-
-// SucceedNow marks the currently running test as succeeded, undoing any
-// previous failures, and stops running the test.
-func (c *C) SucceedNow() {
- c.Succeed()
- c.stopNow()
-}
-
-// ExpectFailure informs that the running test is knowingly broken for
-// the provided reason. If the test does not fail, an error will be reported
-// to raise attention to this fact. This method is useful to temporarily
-// disable tests which cover well known problems until a better time to
-// fix the problem is found, without forgetting about the fact that a
-// failure still exists.
-func (c *C) ExpectFailure(reason string) {
- if reason == "" {
- panic("Missing reason why the test is expected to fail")
- }
- c.mustFail = true
- c.reason = reason
-}
-
-// Skip skips the running test for the provided reason. If run from within
-// SetUpTest, the individual test being set up will be skipped, and if run
-// from within SetUpSuite, the whole suite is skipped.
-func (c *C) Skip(reason string) {
- if reason == "" {
- panic("Missing reason why the test is being skipped")
- }
- c.reason = reason
- c.setStatus(skippedSt)
- c.stopNow()
-}
-
-// -----------------------------------------------------------------------
-// Basic logging.
-
-// GetTestLog returns the current test error output.
-func (c *C) GetTestLog() string {
- return c.logb.String()
-}
-
-// Log logs some information into the test error output.
-// The provided arguments are assembled together into a string with fmt.Sprint.
-func (c *C) Log(args ...interface{}) {
- c.log(args...)
-}
-
-// Log logs some information into the test error output.
-// The provided arguments are assembled together into a string with fmt.Sprintf.
-func (c *C) Logf(format string, args ...interface{}) {
- c.logf(format, args...)
-}
-
-// Output enables *C to be used as a logger in functions that require only
-// the minimum interface of *log.Logger.
-func (c *C) Output(calldepth int, s string) error {
- d := time.Now().Sub(c.startTime)
- msec := d / time.Millisecond
- sec := d / time.Second
- min := d / time.Minute
-
- c.Logf("[LOG] %d:%02d.%03d %s", min, sec%60, msec%1000, s)
- return nil
-}
-
-// Error logs an error into the test error output and marks the test as failed.
-// The provided arguments are assembled together into a string with fmt.Sprint.
-func (c *C) Error(args ...interface{}) {
- c.logCaller(1)
- c.logString(fmt.Sprint("Error: ", fmt.Sprint(args...)))
- c.logNewLine()
- c.Fail()
-}
-
-// Errorf logs an error into the test error output and marks the test as failed.
-// The provided arguments are assembled together into a string with fmt.Sprintf.
-func (c *C) Errorf(format string, args ...interface{}) {
- c.logCaller(1)
- c.logString(fmt.Sprintf("Error: "+format, args...))
- c.logNewLine()
- c.Fail()
-}
-
-// Fatal logs an error into the test error output, marks the test as failed, and
-// stops the test execution. The provided arguments are assembled together into
-// a string with fmt.Sprint.
-func (c *C) Fatal(args ...interface{}) {
- c.logCaller(1)
- c.logString(fmt.Sprint("Error: ", fmt.Sprint(args...)))
- c.logNewLine()
- c.FailNow()
-}
-
-// Fatlaf logs an error into the test error output, marks the test as failed, and
-// stops the test execution. The provided arguments are assembled together into
-// a string with fmt.Sprintf.
-func (c *C) Fatalf(format string, args ...interface{}) {
- c.logCaller(1)
- c.logString(fmt.Sprint("Error: ", fmt.Sprintf(format, args...)))
- c.logNewLine()
- c.FailNow()
-}
-
-// -----------------------------------------------------------------------
-// Generic checks and assertions based on checkers.
-
-// Check verifies if the first value matches the expected value according
-// to the provided checker. If they do not match, an error is logged, the
-// test is marked as failed, and the test execution continues.
-//
-// Some checkers may not need the expected argument (e.g. IsNil).
-//
-// Extra arguments provided to the function are logged next to the reported
-// problem when the matching fails.
-func (c *C) Check(obtained interface{}, checker Checker, args ...interface{}) bool {
- return c.internalCheck("Check", obtained, checker, args...)
-}
-
-// Assert ensures that the first value matches the expected value according
-// to the provided checker. If they do not match, an error is logged, the
-// test is marked as failed, and the test execution stops.
-//
-// Some checkers may not need the expected argument (e.g. IsNil).
-//
-// Extra arguments provided to the function are logged next to the reported
-// problem when the matching fails.
-func (c *C) Assert(obtained interface{}, checker Checker, args ...interface{}) {
- if !c.internalCheck("Assert", obtained, checker, args...) {
- c.stopNow()
- }
-}
-
-func (c *C) internalCheck(funcName string, obtained interface{}, checker Checker, args ...interface{}) bool {
- if checker == nil {
- c.logCaller(2)
- c.logString(fmt.Sprintf("%s(obtained, nil!?, ...):", funcName))
- c.logString("Oops.. you've provided a nil checker!")
- c.logNewLine()
- c.Fail()
- return false
- }
-
- // If the last argument is a bug info, extract it out.
- var comment CommentInterface
- if len(args) > 0 {
- if c, ok := args[len(args)-1].(CommentInterface); ok {
- comment = c
- args = args[:len(args)-1]
- }
- }
-
- params := append([]interface{}{obtained}, args...)
- info := checker.Info()
-
- if len(params) != len(info.Params) {
- names := append([]string{info.Params[0], info.Name}, info.Params[1:]...)
- c.logCaller(2)
- c.logString(fmt.Sprintf("%s(%s):", funcName, strings.Join(names, ", ")))
- c.logString(fmt.Sprintf("Wrong number of parameters for %s: want %d, got %d", info.Name, len(names), len(params)+1))
- c.logNewLine()
- c.Fail()
- return false
- }
-
- // Copy since it may be mutated by Check.
- names := append([]string{}, info.Params...)
-
- // Do the actual check.
- result, error := checker.Check(params, names)
- if !result || error != "" {
- c.logCaller(2)
- for i := 0; i != len(params); i++ {
- c.logValue(names[i], params[i])
- }
- if comment != nil {
- c.logString(comment.CheckCommentString())
- }
- if error != "" {
- c.logString(error)
- }
- c.logNewLine()
- c.Fail()
- return false
- }
- return true
-}
diff --git a/vendor/gopkg.in/check.v1/helpers_test.go b/vendor/gopkg.in/check.v1/helpers_test.go
deleted file mode 100644
index 4baa656b..00000000
--- a/vendor/gopkg.in/check.v1/helpers_test.go
+++ /dev/null
@@ -1,519 +0,0 @@
-// These tests verify the inner workings of the helper methods associated
-// with check.T.
-
-package check_test
-
-import (
- "gopkg.in/check.v1"
- "os"
- "reflect"
- "runtime"
- "sync"
-)
-
-var helpersS = check.Suite(&HelpersS{})
-
-type HelpersS struct{}
-
-func (s *HelpersS) TestCountSuite(c *check.C) {
- suitesRun += 1
-}
-
-// -----------------------------------------------------------------------
-// Fake checker and bug info to verify the behavior of Assert() and Check().
-
-type MyChecker struct {
- info *check.CheckerInfo
- params []interface{}
- names []string
- result bool
- error string
-}
-
-func (checker *MyChecker) Info() *check.CheckerInfo {
- if checker.info == nil {
- return &check.CheckerInfo{Name: "MyChecker", Params: []string{"myobtained", "myexpected"}}
- }
- return checker.info
-}
-
-func (checker *MyChecker) Check(params []interface{}, names []string) (bool, string) {
- rparams := checker.params
- rnames := checker.names
- checker.params = append([]interface{}{}, params...)
- checker.names = append([]string{}, names...)
- if rparams != nil {
- copy(params, rparams)
- }
- if rnames != nil {
- copy(names, rnames)
- }
- return checker.result, checker.error
-}
-
-type myCommentType string
-
-func (c myCommentType) CheckCommentString() string {
- return string(c)
-}
-
-func myComment(s string) myCommentType {
- return myCommentType(s)
-}
-
-// -----------------------------------------------------------------------
-// Ensure a real checker actually works fine.
-
-func (s *HelpersS) TestCheckerInterface(c *check.C) {
- testHelperSuccess(c, "Check(1, Equals, 1)", true, func() interface{} {
- return c.Check(1, check.Equals, 1)
- })
-}
-
-// -----------------------------------------------------------------------
-// Tests for Check(), mostly the same as for Assert() following these.
-
-func (s *HelpersS) TestCheckSucceedWithExpected(c *check.C) {
- checker := &MyChecker{result: true}
- testHelperSuccess(c, "Check(1, checker, 2)", true, func() interface{} {
- return c.Check(1, checker, 2)
- })
- if !reflect.DeepEqual(checker.params, []interface{}{1, 2}) {
- c.Fatalf("Bad params for check: %#v", checker.params)
- }
-}
-
-func (s *HelpersS) TestCheckSucceedWithoutExpected(c *check.C) {
- checker := &MyChecker{result: true, info: &check.CheckerInfo{Params: []string{"myvalue"}}}
- testHelperSuccess(c, "Check(1, checker)", true, func() interface{} {
- return c.Check(1, checker)
- })
- if !reflect.DeepEqual(checker.params, []interface{}{1}) {
- c.Fatalf("Bad params for check: %#v", checker.params)
- }
-}
-
-func (s *HelpersS) TestCheckFailWithExpected(c *check.C) {
- checker := &MyChecker{result: false}
- log := "(?s)helpers_test\\.go:[0-9]+:.*\nhelpers_test\\.go:[0-9]+:\n" +
- " return c\\.Check\\(1, checker, 2\\)\n" +
- "\\.+ myobtained int = 1\n" +
- "\\.+ myexpected int = 2\n\n"
- testHelperFailure(c, "Check(1, checker, 2)", false, false, log,
- func() interface{} {
- return c.Check(1, checker, 2)
- })
-}
-
-func (s *HelpersS) TestCheckFailWithExpectedAndComment(c *check.C) {
- checker := &MyChecker{result: false}
- log := "(?s)helpers_test\\.go:[0-9]+:.*\nhelpers_test\\.go:[0-9]+:\n" +
- " return c\\.Check\\(1, checker, 2, myComment\\(\"Hello world!\"\\)\\)\n" +
- "\\.+ myobtained int = 1\n" +
- "\\.+ myexpected int = 2\n" +
- "\\.+ Hello world!\n\n"
- testHelperFailure(c, "Check(1, checker, 2, msg)", false, false, log,
- func() interface{} {
- return c.Check(1, checker, 2, myComment("Hello world!"))
- })
-}
-
-func (s *HelpersS) TestCheckFailWithExpectedAndStaticComment(c *check.C) {
- checker := &MyChecker{result: false}
- log := "(?s)helpers_test\\.go:[0-9]+:.*\nhelpers_test\\.go:[0-9]+:\n" +
- " // Nice leading comment\\.\n" +
- " return c\\.Check\\(1, checker, 2\\) // Hello there\n" +
- "\\.+ myobtained int = 1\n" +
- "\\.+ myexpected int = 2\n\n"
- testHelperFailure(c, "Check(1, checker, 2, msg)", false, false, log,
- func() interface{} {
- // Nice leading comment.
- return c.Check(1, checker, 2) // Hello there
- })
-}
-
-func (s *HelpersS) TestCheckFailWithoutExpected(c *check.C) {
- checker := &MyChecker{result: false, info: &check.CheckerInfo{Params: []string{"myvalue"}}}
- log := "(?s)helpers_test\\.go:[0-9]+:.*\nhelpers_test\\.go:[0-9]+:\n" +
- " return c\\.Check\\(1, checker\\)\n" +
- "\\.+ myvalue int = 1\n\n"
- testHelperFailure(c, "Check(1, checker)", false, false, log,
- func() interface{} {
- return c.Check(1, checker)
- })
-}
-
-func (s *HelpersS) TestCheckFailWithoutExpectedAndMessage(c *check.C) {
- checker := &MyChecker{result: false, info: &check.CheckerInfo{Params: []string{"myvalue"}}}
- log := "(?s)helpers_test\\.go:[0-9]+:.*\nhelpers_test\\.go:[0-9]+:\n" +
- " return c\\.Check\\(1, checker, myComment\\(\"Hello world!\"\\)\\)\n" +
- "\\.+ myvalue int = 1\n" +
- "\\.+ Hello world!\n\n"
- testHelperFailure(c, "Check(1, checker, msg)", false, false, log,
- func() interface{} {
- return c.Check(1, checker, myComment("Hello world!"))
- })
-}
-
-func (s *HelpersS) TestCheckWithMissingExpected(c *check.C) {
- checker := &MyChecker{result: true}
- log := "(?s)helpers_test\\.go:[0-9]+:.*\nhelpers_test\\.go:[0-9]+:\n" +
- " return c\\.Check\\(1, checker\\)\n" +
- "\\.+ Check\\(myobtained, MyChecker, myexpected\\):\n" +
- "\\.+ Wrong number of parameters for MyChecker: " +
- "want 3, got 2\n\n"
- testHelperFailure(c, "Check(1, checker, !?)", false, false, log,
- func() interface{} {
- return c.Check(1, checker)
- })
-}
-
-func (s *HelpersS) TestCheckWithTooManyExpected(c *check.C) {
- checker := &MyChecker{result: true}
- log := "(?s)helpers_test\\.go:[0-9]+:.*\nhelpers_test\\.go:[0-9]+:\n" +
- " return c\\.Check\\(1, checker, 2, 3\\)\n" +
- "\\.+ Check\\(myobtained, MyChecker, myexpected\\):\n" +
- "\\.+ Wrong number of parameters for MyChecker: " +
- "want 3, got 4\n\n"
- testHelperFailure(c, "Check(1, checker, 2, 3)", false, false, log,
- func() interface{} {
- return c.Check(1, checker, 2, 3)
- })
-}
-
-func (s *HelpersS) TestCheckWithError(c *check.C) {
- checker := &MyChecker{result: false, error: "Some not so cool data provided!"}
- log := "(?s)helpers_test\\.go:[0-9]+:.*\nhelpers_test\\.go:[0-9]+:\n" +
- " return c\\.Check\\(1, checker, 2\\)\n" +
- "\\.+ myobtained int = 1\n" +
- "\\.+ myexpected int = 2\n" +
- "\\.+ Some not so cool data provided!\n\n"
- testHelperFailure(c, "Check(1, checker, 2)", false, false, log,
- func() interface{} {
- return c.Check(1, checker, 2)
- })
-}
-
-func (s *HelpersS) TestCheckWithNilChecker(c *check.C) {
- log := "(?s)helpers_test\\.go:[0-9]+:.*\nhelpers_test\\.go:[0-9]+:\n" +
- " return c\\.Check\\(1, nil\\)\n" +
- "\\.+ Check\\(obtained, nil!\\?, \\.\\.\\.\\):\n" +
- "\\.+ Oops\\.\\. you've provided a nil checker!\n\n"
- testHelperFailure(c, "Check(obtained, nil)", false, false, log,
- func() interface{} {
- return c.Check(1, nil)
- })
-}
-
-func (s *HelpersS) TestCheckWithParamsAndNamesMutation(c *check.C) {
- checker := &MyChecker{result: false, params: []interface{}{3, 4}, names: []string{"newobtained", "newexpected"}}
- log := "(?s)helpers_test\\.go:[0-9]+:.*\nhelpers_test\\.go:[0-9]+:\n" +
- " return c\\.Check\\(1, checker, 2\\)\n" +
- "\\.+ newobtained int = 3\n" +
- "\\.+ newexpected int = 4\n\n"
- testHelperFailure(c, "Check(1, checker, 2) with mutation", false, false, log,
- func() interface{} {
- return c.Check(1, checker, 2)
- })
-}
-
-// -----------------------------------------------------------------------
-// Tests for Assert(), mostly the same as for Check() above.
-
-func (s *HelpersS) TestAssertSucceedWithExpected(c *check.C) {
- checker := &MyChecker{result: true}
- testHelperSuccess(c, "Assert(1, checker, 2)", nil, func() interface{} {
- c.Assert(1, checker, 2)
- return nil
- })
- if !reflect.DeepEqual(checker.params, []interface{}{1, 2}) {
- c.Fatalf("Bad params for check: %#v", checker.params)
- }
-}
-
-func (s *HelpersS) TestAssertSucceedWithoutExpected(c *check.C) {
- checker := &MyChecker{result: true, info: &check.CheckerInfo{Params: []string{"myvalue"}}}
- testHelperSuccess(c, "Assert(1, checker)", nil, func() interface{} {
- c.Assert(1, checker)
- return nil
- })
- if !reflect.DeepEqual(checker.params, []interface{}{1}) {
- c.Fatalf("Bad params for check: %#v", checker.params)
- }
-}
-
-func (s *HelpersS) TestAssertFailWithExpected(c *check.C) {
- checker := &MyChecker{result: false}
- log := "(?s)helpers_test\\.go:[0-9]+:.*\nhelpers_test\\.go:[0-9]+:\n" +
- " c\\.Assert\\(1, checker, 2\\)\n" +
- "\\.+ myobtained int = 1\n" +
- "\\.+ myexpected int = 2\n\n"
- testHelperFailure(c, "Assert(1, checker, 2)", nil, true, log,
- func() interface{} {
- c.Assert(1, checker, 2)
- return nil
- })
-}
-
-func (s *HelpersS) TestAssertFailWithExpectedAndMessage(c *check.C) {
- checker := &MyChecker{result: false}
- log := "(?s)helpers_test\\.go:[0-9]+:.*\nhelpers_test\\.go:[0-9]+:\n" +
- " c\\.Assert\\(1, checker, 2, myComment\\(\"Hello world!\"\\)\\)\n" +
- "\\.+ myobtained int = 1\n" +
- "\\.+ myexpected int = 2\n" +
- "\\.+ Hello world!\n\n"
- testHelperFailure(c, "Assert(1, checker, 2, msg)", nil, true, log,
- func() interface{} {
- c.Assert(1, checker, 2, myComment("Hello world!"))
- return nil
- })
-}
-
-func (s *HelpersS) TestAssertFailWithoutExpected(c *check.C) {
- checker := &MyChecker{result: false, info: &check.CheckerInfo{Params: []string{"myvalue"}}}
- log := "(?s)helpers_test\\.go:[0-9]+:.*\nhelpers_test\\.go:[0-9]+:\n" +
- " c\\.Assert\\(1, checker\\)\n" +
- "\\.+ myvalue int = 1\n\n"
- testHelperFailure(c, "Assert(1, checker)", nil, true, log,
- func() interface{} {
- c.Assert(1, checker)
- return nil
- })
-}
-
-func (s *HelpersS) TestAssertFailWithoutExpectedAndMessage(c *check.C) {
- checker := &MyChecker{result: false, info: &check.CheckerInfo{Params: []string{"myvalue"}}}
- log := "(?s)helpers_test\\.go:[0-9]+:.*\nhelpers_test\\.go:[0-9]+:\n" +
- " c\\.Assert\\(1, checker, myComment\\(\"Hello world!\"\\)\\)\n" +
- "\\.+ myvalue int = 1\n" +
- "\\.+ Hello world!\n\n"
- testHelperFailure(c, "Assert(1, checker, msg)", nil, true, log,
- func() interface{} {
- c.Assert(1, checker, myComment("Hello world!"))
- return nil
- })
-}
-
-func (s *HelpersS) TestAssertWithMissingExpected(c *check.C) {
- checker := &MyChecker{result: true}
- log := "(?s)helpers_test\\.go:[0-9]+:.*\nhelpers_test\\.go:[0-9]+:\n" +
- " c\\.Assert\\(1, checker\\)\n" +
- "\\.+ Assert\\(myobtained, MyChecker, myexpected\\):\n" +
- "\\.+ Wrong number of parameters for MyChecker: " +
- "want 3, got 2\n\n"
- testHelperFailure(c, "Assert(1, checker, !?)", nil, true, log,
- func() interface{} {
- c.Assert(1, checker)
- return nil
- })
-}
-
-func (s *HelpersS) TestAssertWithError(c *check.C) {
- checker := &MyChecker{result: false, error: "Some not so cool data provided!"}
- log := "(?s)helpers_test\\.go:[0-9]+:.*\nhelpers_test\\.go:[0-9]+:\n" +
- " c\\.Assert\\(1, checker, 2\\)\n" +
- "\\.+ myobtained int = 1\n" +
- "\\.+ myexpected int = 2\n" +
- "\\.+ Some not so cool data provided!\n\n"
- testHelperFailure(c, "Assert(1, checker, 2)", nil, true, log,
- func() interface{} {
- c.Assert(1, checker, 2)
- return nil
- })
-}
-
-func (s *HelpersS) TestAssertWithNilChecker(c *check.C) {
- log := "(?s)helpers_test\\.go:[0-9]+:.*\nhelpers_test\\.go:[0-9]+:\n" +
- " c\\.Assert\\(1, nil\\)\n" +
- "\\.+ Assert\\(obtained, nil!\\?, \\.\\.\\.\\):\n" +
- "\\.+ Oops\\.\\. you've provided a nil checker!\n\n"
- testHelperFailure(c, "Assert(obtained, nil)", nil, true, log,
- func() interface{} {
- c.Assert(1, nil)
- return nil
- })
-}
-
-// -----------------------------------------------------------------------
-// Ensure that values logged work properly in some interesting cases.
-
-func (s *HelpersS) TestValueLoggingWithArrays(c *check.C) {
- checker := &MyChecker{result: false}
- log := "(?s)helpers_test.go:[0-9]+:.*\nhelpers_test.go:[0-9]+:\n" +
- " return c\\.Check\\(\\[\\]byte{1, 2}, checker, \\[\\]byte{1, 3}\\)\n" +
- "\\.+ myobtained \\[\\]uint8 = \\[\\]byte{0x1, 0x2}\n" +
- "\\.+ myexpected \\[\\]uint8 = \\[\\]byte{0x1, 0x3}\n\n"
- testHelperFailure(c, "Check([]byte{1}, chk, []byte{3})", false, false, log,
- func() interface{} {
- return c.Check([]byte{1, 2}, checker, []byte{1, 3})
- })
-}
-
-func (s *HelpersS) TestValueLoggingWithMultiLine(c *check.C) {
- checker := &MyChecker{result: false}
- log := "(?s)helpers_test.go:[0-9]+:.*\nhelpers_test.go:[0-9]+:\n" +
- " return c\\.Check\\(\"a\\\\nb\\\\n\", checker, \"a\\\\nb\\\\nc\"\\)\n" +
- "\\.+ myobtained string = \"\" \\+\n" +
- "\\.+ \"a\\\\n\" \\+\n" +
- "\\.+ \"b\\\\n\"\n" +
- "\\.+ myexpected string = \"\" \\+\n" +
- "\\.+ \"a\\\\n\" \\+\n" +
- "\\.+ \"b\\\\n\" \\+\n" +
- "\\.+ \"c\"\n\n"
- testHelperFailure(c, `Check("a\nb\n", chk, "a\nb\nc")`, false, false, log,
- func() interface{} {
- return c.Check("a\nb\n", checker, "a\nb\nc")
- })
-}
-
-func (s *HelpersS) TestValueLoggingWithMultiLineException(c *check.C) {
- // If the newline is at the end of the string, don't log as multi-line.
- checker := &MyChecker{result: false}
- log := "(?s)helpers_test.go:[0-9]+:.*\nhelpers_test.go:[0-9]+:\n" +
- " return c\\.Check\\(\"a b\\\\n\", checker, \"a\\\\nb\"\\)\n" +
- "\\.+ myobtained string = \"a b\\\\n\"\n" +
- "\\.+ myexpected string = \"\" \\+\n" +
- "\\.+ \"a\\\\n\" \\+\n" +
- "\\.+ \"b\"\n\n"
- testHelperFailure(c, `Check("a b\n", chk, "a\nb")`, false, false, log,
- func() interface{} {
- return c.Check("a b\n", checker, "a\nb")
- })
-}
-
-// -----------------------------------------------------------------------
-// MakeDir() tests.
-
-type MkDirHelper struct {
- path1 string
- path2 string
- isDir1 bool
- isDir2 bool
- isDir3 bool
- isDir4 bool
-}
-
-func (s *MkDirHelper) SetUpSuite(c *check.C) {
- s.path1 = c.MkDir()
- s.isDir1 = isDir(s.path1)
-}
-
-func (s *MkDirHelper) Test(c *check.C) {
- s.path2 = c.MkDir()
- s.isDir2 = isDir(s.path2)
-}
-
-func (s *MkDirHelper) TearDownSuite(c *check.C) {
- s.isDir3 = isDir(s.path1)
- s.isDir4 = isDir(s.path2)
-}
-
-func (s *HelpersS) TestMkDir(c *check.C) {
- helper := MkDirHelper{}
- output := String{}
- check.Run(&helper, &check.RunConf{Output: &output})
- c.Assert(output.value, check.Equals, "")
- c.Check(helper.isDir1, check.Equals, true)
- c.Check(helper.isDir2, check.Equals, true)
- c.Check(helper.isDir3, check.Equals, true)
- c.Check(helper.isDir4, check.Equals, true)
- c.Check(helper.path1, check.Not(check.Equals),
- helper.path2)
- c.Check(isDir(helper.path1), check.Equals, false)
- c.Check(isDir(helper.path2), check.Equals, false)
-}
-
-func isDir(path string) bool {
- if stat, err := os.Stat(path); err == nil {
- return stat.IsDir()
- }
- return false
-}
-
-// Concurrent logging should not corrupt the underling buffer.
-// Use go test -race to detect the race in this test.
-func (s *HelpersS) TestConcurrentLogging(c *check.C) {
- defer runtime.GOMAXPROCS(runtime.GOMAXPROCS(runtime.NumCPU()))
- var start, stop sync.WaitGroup
- start.Add(1)
- for i, n := 0, runtime.NumCPU()*2; i < n; i++ {
- stop.Add(1)
- go func(i int) {
- start.Wait()
- for j := 0; j < 30; j++ {
- c.Logf("Worker %d: line %d", i, j)
- }
- stop.Done()
- }(i)
- }
- start.Done()
- stop.Wait()
-}
-
-// -----------------------------------------------------------------------
-// Test the TestName function
-
-type TestNameHelper struct {
- name1 string
- name2 string
- name3 string
- name4 string
- name5 string
-}
-
-func (s *TestNameHelper) SetUpSuite(c *check.C) { s.name1 = c.TestName() }
-func (s *TestNameHelper) SetUpTest(c *check.C) { s.name2 = c.TestName() }
-func (s *TestNameHelper) Test(c *check.C) { s.name3 = c.TestName() }
-func (s *TestNameHelper) TearDownTest(c *check.C) { s.name4 = c.TestName() }
-func (s *TestNameHelper) TearDownSuite(c *check.C) { s.name5 = c.TestName() }
-
-func (s *HelpersS) TestTestName(c *check.C) {
- helper := TestNameHelper{}
- output := String{}
- check.Run(&helper, &check.RunConf{Output: &output})
- c.Check(helper.name1, check.Equals, "")
- c.Check(helper.name2, check.Equals, "TestNameHelper.Test")
- c.Check(helper.name3, check.Equals, "TestNameHelper.Test")
- c.Check(helper.name4, check.Equals, "TestNameHelper.Test")
- c.Check(helper.name5, check.Equals, "")
-}
-
-// -----------------------------------------------------------------------
-// A couple of helper functions to test helper functions. :-)
-
-func testHelperSuccess(c *check.C, name string, expectedResult interface{}, closure func() interface{}) {
- var result interface{}
- defer (func() {
- if err := recover(); err != nil {
- panic(err)
- }
- checkState(c, result,
- &expectedState{
- name: name,
- result: expectedResult,
- failed: false,
- log: "",
- })
- })()
- result = closure()
-}
-
-func testHelperFailure(c *check.C, name string, expectedResult interface{}, shouldStop bool, log string, closure func() interface{}) {
- var result interface{}
- defer (func() {
- if err := recover(); err != nil {
- panic(err)
- }
- checkState(c, result,
- &expectedState{
- name: name,
- result: expectedResult,
- failed: true,
- log: log,
- })
- })()
- result = closure()
- if shouldStop {
- c.Logf("%s didn't stop when it should", name)
- }
-}
diff --git a/vendor/gopkg.in/check.v1/printer.go b/vendor/gopkg.in/check.v1/printer.go
deleted file mode 100644
index e0f7557b..00000000
--- a/vendor/gopkg.in/check.v1/printer.go
+++ /dev/null
@@ -1,168 +0,0 @@
-package check
-
-import (
- "bytes"
- "go/ast"
- "go/parser"
- "go/printer"
- "go/token"
- "os"
-)
-
-func indent(s, with string) (r string) {
- eol := true
- for i := 0; i != len(s); i++ {
- c := s[i]
- switch {
- case eol && c == '\n' || c == '\r':
- case c == '\n' || c == '\r':
- eol = true
- case eol:
- eol = false
- s = s[:i] + with + s[i:]
- i += len(with)
- }
- }
- return s
-}
-
-func printLine(filename string, line int) (string, error) {
- fset := token.NewFileSet()
- file, err := os.Open(filename)
- if err != nil {
- return "", err
- }
- fnode, err := parser.ParseFile(fset, filename, file, parser.ParseComments)
- if err != nil {
- return "", err
- }
- config := &printer.Config{Mode: printer.UseSpaces, Tabwidth: 4}
- lp := &linePrinter{fset: fset, fnode: fnode, line: line, config: config}
- ast.Walk(lp, fnode)
- result := lp.output.Bytes()
- // Comments leave \n at the end.
- n := len(result)
- for n > 0 && result[n-1] == '\n' {
- n--
- }
- return string(result[:n]), nil
-}
-
-type linePrinter struct {
- config *printer.Config
- fset *token.FileSet
- fnode *ast.File
- line int
- output bytes.Buffer
- stmt ast.Stmt
-}
-
-func (lp *linePrinter) emit() bool {
- if lp.stmt != nil {
- lp.trim(lp.stmt)
- lp.printWithComments(lp.stmt)
- lp.stmt = nil
- return true
- }
- return false
-}
-
-func (lp *linePrinter) printWithComments(n ast.Node) {
- nfirst := lp.fset.Position(n.Pos()).Line
- nlast := lp.fset.Position(n.End()).Line
- for _, g := range lp.fnode.Comments {
- cfirst := lp.fset.Position(g.Pos()).Line
- clast := lp.fset.Position(g.End()).Line
- if clast == nfirst-1 && lp.fset.Position(n.Pos()).Column == lp.fset.Position(g.Pos()).Column {
- for _, c := range g.List {
- lp.output.WriteString(c.Text)
- lp.output.WriteByte('\n')
- }
- }
- if cfirst >= nfirst && cfirst <= nlast && n.End() <= g.List[0].Slash {
- // The printer will not include the comment if it starts past
- // the node itself. Trick it into printing by overlapping the
- // slash with the end of the statement.
- g.List[0].Slash = n.End() - 1
- }
- }
- node := &printer.CommentedNode{n, lp.fnode.Comments}
- lp.config.Fprint(&lp.output, lp.fset, node)
-}
-
-func (lp *linePrinter) Visit(n ast.Node) (w ast.Visitor) {
- if n == nil {
- if lp.output.Len() == 0 {
- lp.emit()
- }
- return nil
- }
- first := lp.fset.Position(n.Pos()).Line
- last := lp.fset.Position(n.End()).Line
- if first <= lp.line && last >= lp.line {
- // Print the innermost statement containing the line.
- if stmt, ok := n.(ast.Stmt); ok {
- if _, ok := n.(*ast.BlockStmt); !ok {
- lp.stmt = stmt
- }
- }
- if first == lp.line && lp.emit() {
- return nil
- }
- return lp
- }
- return nil
-}
-
-func (lp *linePrinter) trim(n ast.Node) bool {
- stmt, ok := n.(ast.Stmt)
- if !ok {
- return true
- }
- line := lp.fset.Position(n.Pos()).Line
- if line != lp.line {
- return false
- }
- switch stmt := stmt.(type) {
- case *ast.IfStmt:
- stmt.Body = lp.trimBlock(stmt.Body)
- case *ast.SwitchStmt:
- stmt.Body = lp.trimBlock(stmt.Body)
- case *ast.TypeSwitchStmt:
- stmt.Body = lp.trimBlock(stmt.Body)
- case *ast.CaseClause:
- stmt.Body = lp.trimList(stmt.Body)
- case *ast.CommClause:
- stmt.Body = lp.trimList(stmt.Body)
- case *ast.BlockStmt:
- stmt.List = lp.trimList(stmt.List)
- }
- return true
-}
-
-func (lp *linePrinter) trimBlock(stmt *ast.BlockStmt) *ast.BlockStmt {
- if !lp.trim(stmt) {
- return lp.emptyBlock(stmt)
- }
- stmt.Rbrace = stmt.Lbrace
- return stmt
-}
-
-func (lp *linePrinter) trimList(stmts []ast.Stmt) []ast.Stmt {
- for i := 0; i != len(stmts); i++ {
- if !lp.trim(stmts[i]) {
- stmts[i] = lp.emptyStmt(stmts[i])
- break
- }
- }
- return stmts
-}
-
-func (lp *linePrinter) emptyStmt(n ast.Node) *ast.ExprStmt {
- return &ast.ExprStmt{&ast.Ellipsis{n.Pos(), nil}}
-}
-
-func (lp *linePrinter) emptyBlock(n ast.Node) *ast.BlockStmt {
- p := n.Pos()
- return &ast.BlockStmt{p, []ast.Stmt{lp.emptyStmt(n)}, p}
-}
diff --git a/vendor/gopkg.in/check.v1/printer_test.go b/vendor/gopkg.in/check.v1/printer_test.go
deleted file mode 100644
index 538b2d52..00000000
--- a/vendor/gopkg.in/check.v1/printer_test.go
+++ /dev/null
@@ -1,104 +0,0 @@
-package check_test
-
-import (
- . "gopkg.in/check.v1"
-)
-
-var _ = Suite(&PrinterS{})
-
-type PrinterS struct{}
-
-func (s *PrinterS) TestCountSuite(c *C) {
- suitesRun += 1
-}
-
-var printTestFuncLine int
-
-func init() {
- printTestFuncLine = getMyLine() + 3
-}
-
-func printTestFunc() {
- println(1) // Comment1
- if 2 == 2 { // Comment2
- println(3) // Comment3
- }
- switch 5 {
- case 6: println(6) // Comment6
- println(7)
- }
- switch interface{}(9).(type) {// Comment9
- case int: println(10)
- println(11)
- }
- select {
- case <-(chan bool)(nil): println(14)
- println(15)
- default: println(16)
- println(17)
- }
- println(19,
- 20)
- _ = func() { println(21)
- println(22)
- }
- println(24, func() {
- println(25)
- })
- // Leading comment
- // with multiple lines.
- println(29) // Comment29
-}
-
-var printLineTests = []struct {
- line int
- output string
-}{
- {1, "println(1) // Comment1"},
- {2, "if 2 == 2 { // Comment2\n ...\n}"},
- {3, "println(3) // Comment3"},
- {5, "switch 5 {\n...\n}"},
- {6, "case 6:\n println(6) // Comment6\n ..."},
- {7, "println(7)"},
- {9, "switch interface{}(9).(type) { // Comment9\n...\n}"},
- {10, "case int:\n println(10)\n ..."},
- {14, "case <-(chan bool)(nil):\n println(14)\n ..."},
- {15, "println(15)"},
- {16, "default:\n println(16)\n ..."},
- {17, "println(17)"},
- {19, "println(19,\n 20)"},
- {20, "println(19,\n 20)"},
- {21, "_ = func() {\n println(21)\n println(22)\n}"},
- {22, "println(22)"},
- {24, "println(24, func() {\n println(25)\n})"},
- {25, "println(25)"},
- {26, "println(24, func() {\n println(25)\n})"},
- {29, "// Leading comment\n// with multiple lines.\nprintln(29) // Comment29"},
-}
-
-func (s *PrinterS) TestPrintLine(c *C) {
- for _, test := range printLineTests {
- output, err := PrintLine("printer_test.go", printTestFuncLine+test.line)
- c.Assert(err, IsNil)
- c.Assert(output, Equals, test.output)
- }
-}
-
-var indentTests = []struct {
- in, out string
-}{
- {"", ""},
- {"\n", "\n"},
- {"a", ">>>a"},
- {"a\n", ">>>a\n"},
- {"a\nb", ">>>a\n>>>b"},
- {" ", ">>> "},
-}
-
-func (s *PrinterS) TestIndent(c *C) {
- for _, test := range indentTests {
- out := Indent(test.in, ">>>")
- c.Assert(out, Equals, test.out)
- }
-
-}
diff --git a/vendor/gopkg.in/check.v1/reporter.go b/vendor/gopkg.in/check.v1/reporter.go
deleted file mode 100644
index fb04f76f..00000000
--- a/vendor/gopkg.in/check.v1/reporter.go
+++ /dev/null
@@ -1,88 +0,0 @@
-package check
-
-import (
- "fmt"
- "io"
- "sync"
-)
-
-// -----------------------------------------------------------------------
-// Output writer manages atomic output writing according to settings.
-
-type outputWriter struct {
- m sync.Mutex
- writer io.Writer
- wroteCallProblemLast bool
- Stream bool
- Verbose bool
-}
-
-func newOutputWriter(writer io.Writer, stream, verbose bool) *outputWriter {
- return &outputWriter{writer: writer, Stream: stream, Verbose: verbose}
-}
-
-func (ow *outputWriter) Write(content []byte) (n int, err error) {
- ow.m.Lock()
- n, err = ow.writer.Write(content)
- ow.m.Unlock()
- return
-}
-
-func (ow *outputWriter) WriteCallStarted(label string, c *C) {
- if ow.Stream {
- header := renderCallHeader(label, c, "", "\n")
- ow.m.Lock()
- ow.writer.Write([]byte(header))
- ow.m.Unlock()
- }
-}
-
-func (ow *outputWriter) WriteCallProblem(label string, c *C) {
- var prefix string
- if !ow.Stream {
- prefix = "\n-----------------------------------" +
- "-----------------------------------\n"
- }
- header := renderCallHeader(label, c, prefix, "\n\n")
- ow.m.Lock()
- ow.wroteCallProblemLast = true
- ow.writer.Write([]byte(header))
- if !ow.Stream {
- c.logb.WriteTo(ow.writer)
- }
- ow.m.Unlock()
-}
-
-func (ow *outputWriter) WriteCallSuccess(label string, c *C) {
- if ow.Stream || (ow.Verbose && c.kind == testKd) {
- // TODO Use a buffer here.
- var suffix string
- if c.reason != "" {
- suffix = " (" + c.reason + ")"
- }
- if c.status() == succeededSt {
- suffix += "\t" + c.timerString()
- }
- suffix += "\n"
- if ow.Stream {
- suffix += "\n"
- }
- header := renderCallHeader(label, c, "", suffix)
- ow.m.Lock()
- // Resist temptation of using line as prefix above due to race.
- if !ow.Stream && ow.wroteCallProblemLast {
- header = "\n-----------------------------------" +
- "-----------------------------------\n" +
- header
- }
- ow.wroteCallProblemLast = false
- ow.writer.Write([]byte(header))
- ow.m.Unlock()
- }
-}
-
-func renderCallHeader(label string, c *C, prefix, suffix string) string {
- pc := c.method.PC()
- return fmt.Sprintf("%s%s: %s: %s%s", prefix, label, niceFuncPath(pc),
- niceFuncName(pc), suffix)
-}
diff --git a/vendor/gopkg.in/check.v1/reporter_test.go b/vendor/gopkg.in/check.v1/reporter_test.go
deleted file mode 100644
index 0b7ed762..00000000
--- a/vendor/gopkg.in/check.v1/reporter_test.go
+++ /dev/null
@@ -1,159 +0,0 @@
-package check_test
-
-import (
- "fmt"
- "path/filepath"
- "runtime"
-
- . "gopkg.in/check.v1"
-)
-
-var _ = Suite(&reporterS{})
-
-type reporterS struct {
- testFile string
-}
-
-func (s *reporterS) SetUpSuite(c *C) {
- _, fileName, _, ok := runtime.Caller(0)
- c.Assert(ok, Equals, true)
- s.testFile = filepath.Base(fileName)
-}
-
-func (s *reporterS) TestWrite(c *C) {
- testString := "test string"
- output := String{}
-
- dummyStream := true
- dummyVerbose := true
- o := NewOutputWriter(&output, dummyStream, dummyVerbose)
-
- o.Write([]byte(testString))
- c.Assert(output.value, Equals, testString)
-}
-
-func (s *reporterS) TestWriteCallStartedWithStreamFlag(c *C) {
- testLabel := "test started label"
- stream := true
- output := String{}
-
- dummyVerbose := true
- o := NewOutputWriter(&output, stream, dummyVerbose)
-
- o.WriteCallStarted(testLabel, c)
- expected := fmt.Sprintf("%s: %s:\\d+: %s\n", testLabel, s.testFile, c.TestName())
- c.Assert(output.value, Matches, expected)
-}
-
-func (s *reporterS) TestWriteCallStartedWithoutStreamFlag(c *C) {
- stream := false
- output := String{}
-
- dummyLabel := "dummy"
- dummyVerbose := true
- o := NewOutputWriter(&output, stream, dummyVerbose)
-
- o.WriteCallStarted(dummyLabel, c)
- c.Assert(output.value, Equals, "")
-}
-
-func (s *reporterS) TestWriteCallProblemWithStreamFlag(c *C) {
- testLabel := "test problem label"
- stream := true
- output := String{}
-
- dummyVerbose := true
- o := NewOutputWriter(&output, stream, dummyVerbose)
-
- o.WriteCallProblem(testLabel, c)
- expected := fmt.Sprintf("%s: %s:\\d+: %s\n\n", testLabel, s.testFile, c.TestName())
- c.Assert(output.value, Matches, expected)
-}
-
-func (s *reporterS) TestWriteCallProblemWithoutStreamFlag(c *C) {
- testLabel := "test problem label"
- stream := false
- output := String{}
-
- dummyVerbose := true
- o := NewOutputWriter(&output, stream, dummyVerbose)
-
- o.WriteCallProblem(testLabel, c)
- expected := fmt.Sprintf(""+
- "\n"+
- "----------------------------------------------------------------------\n"+
- "%s: %s:\\d+: %s\n\n", testLabel, s.testFile, c.TestName())
- c.Assert(output.value, Matches, expected)
-}
-
-func (s *reporterS) TestWriteCallProblemWithoutStreamFlagWithLog(c *C) {
- testLabel := "test problem label"
- testLog := "test log"
- stream := false
- output := String{}
-
- dummyVerbose := true
- o := NewOutputWriter(&output, stream, dummyVerbose)
-
- c.Log(testLog)
- o.WriteCallProblem(testLabel, c)
- expected := fmt.Sprintf(""+
- "\n"+
- "----------------------------------------------------------------------\n"+
- "%s: %s:\\d+: %s\n\n%s\n", testLabel, s.testFile, c.TestName(), testLog)
- c.Assert(output.value, Matches, expected)
-}
-
-func (s *reporterS) TestWriteCallSuccessWithStreamFlag(c *C) {
- testLabel := "test success label"
- stream := true
- output := String{}
-
- dummyVerbose := true
- o := NewOutputWriter(&output, stream, dummyVerbose)
-
- o.WriteCallSuccess(testLabel, c)
- expected := fmt.Sprintf("%s: %s:\\d+: %s\t\\d\\.\\d+s\n\n", testLabel, s.testFile, c.TestName())
- c.Assert(output.value, Matches, expected)
-}
-
-func (s *reporterS) TestWriteCallSuccessWithStreamFlagAndReason(c *C) {
- testLabel := "test success label"
- testReason := "test skip reason"
- stream := true
- output := String{}
-
- dummyVerbose := true
- o := NewOutputWriter(&output, stream, dummyVerbose)
- c.FakeSkip(testReason)
-
- o.WriteCallSuccess(testLabel, c)
- expected := fmt.Sprintf("%s: %s:\\d+: %s \\(%s\\)\t\\d\\.\\d+s\n\n",
- testLabel, s.testFile, c.TestName(), testReason)
- c.Assert(output.value, Matches, expected)
-}
-
-func (s *reporterS) TestWriteCallSuccessWithoutStreamFlagWithVerboseFlag(c *C) {
- testLabel := "test success label"
- stream := false
- verbose := true
- output := String{}
-
- o := NewOutputWriter(&output, stream, verbose)
-
- o.WriteCallSuccess(testLabel, c)
- expected := fmt.Sprintf("%s: %s:\\d+: %s\t\\d\\.\\d+s\n", testLabel, s.testFile, c.TestName())
- c.Assert(output.value, Matches, expected)
-}
-
-func (s *reporterS) TestWriteCallSuccessWithoutStreamFlagWithoutVerboseFlag(c *C) {
- testLabel := "test success label"
- stream := false
- verbose := false
- output := String{}
-
- o := NewOutputWriter(&output, stream, verbose)
-
- o.WriteCallSuccess(testLabel, c)
- c.Assert(output.value, Equals, "")
-}
diff --git a/vendor/gopkg.in/check.v1/run.go b/vendor/gopkg.in/check.v1/run.go
deleted file mode 100644
index da8fd798..00000000
--- a/vendor/gopkg.in/check.v1/run.go
+++ /dev/null
@@ -1,175 +0,0 @@
-package check
-
-import (
- "bufio"
- "flag"
- "fmt"
- "os"
- "testing"
- "time"
-)
-
-// -----------------------------------------------------------------------
-// Test suite registry.
-
-var allSuites []interface{}
-
-// Suite registers the given value as a test suite to be run. Any methods
-// starting with the Test prefix in the given value will be considered as
-// a test method.
-func Suite(suite interface{}) interface{} {
- allSuites = append(allSuites, suite)
- return suite
-}
-
-// -----------------------------------------------------------------------
-// Public running interface.
-
-var (
- oldFilterFlag = flag.String("gocheck.f", "", "Regular expression selecting which tests and/or suites to run")
- oldVerboseFlag = flag.Bool("gocheck.v", false, "Verbose mode")
- oldStreamFlag = flag.Bool("gocheck.vv", false, "Super verbose mode (disables output caching)")
- oldBenchFlag = flag.Bool("gocheck.b", false, "Run benchmarks")
- oldBenchTime = flag.Duration("gocheck.btime", 1*time.Second, "approximate run time for each benchmark")
- oldListFlag = flag.Bool("gocheck.list", false, "List the names of all tests that will be run")
- oldWorkFlag = flag.Bool("gocheck.work", false, "Display and do not remove the test working directory")
-
- newFilterFlag = flag.String("check.f", "", "Regular expression selecting which tests and/or suites to run")
- newVerboseFlag = flag.Bool("check.v", false, "Verbose mode")
- newStreamFlag = flag.Bool("check.vv", false, "Super verbose mode (disables output caching)")
- newBenchFlag = flag.Bool("check.b", false, "Run benchmarks")
- newBenchTime = flag.Duration("check.btime", 1*time.Second, "approximate run time for each benchmark")
- newBenchMem = flag.Bool("check.bmem", false, "Report memory benchmarks")
- newListFlag = flag.Bool("check.list", false, "List the names of all tests that will be run")
- newWorkFlag = flag.Bool("check.work", false, "Display and do not remove the test working directory")
-)
-
-// TestingT runs all test suites registered with the Suite function,
-// printing results to stdout, and reporting any failures back to
-// the "testing" package.
-func TestingT(testingT *testing.T) {
- benchTime := *newBenchTime
- if benchTime == 1*time.Second {
- benchTime = *oldBenchTime
- }
- conf := &RunConf{
- Filter: *oldFilterFlag + *newFilterFlag,
- Verbose: *oldVerboseFlag || *newVerboseFlag,
- Stream: *oldStreamFlag || *newStreamFlag,
- Benchmark: *oldBenchFlag || *newBenchFlag,
- BenchmarkTime: benchTime,
- BenchmarkMem: *newBenchMem,
- KeepWorkDir: *oldWorkFlag || *newWorkFlag,
- }
- if *oldListFlag || *newListFlag {
- w := bufio.NewWriter(os.Stdout)
- for _, name := range ListAll(conf) {
- fmt.Fprintln(w, name)
- }
- w.Flush()
- return
- }
- result := RunAll(conf)
- println(result.String())
- if !result.Passed() {
- testingT.Fail()
- }
-}
-
-// RunAll runs all test suites registered with the Suite function, using the
-// provided run configuration.
-func RunAll(runConf *RunConf) *Result {
- result := Result{}
- for _, suite := range allSuites {
- result.Add(Run(suite, runConf))
- }
- return &result
-}
-
-// Run runs the provided test suite using the provided run configuration.
-func Run(suite interface{}, runConf *RunConf) *Result {
- runner := newSuiteRunner(suite, runConf)
- return runner.run()
-}
-
-// ListAll returns the names of all the test functions registered with the
-// Suite function that will be run with the provided run configuration.
-func ListAll(runConf *RunConf) []string {
- var names []string
- for _, suite := range allSuites {
- names = append(names, List(suite, runConf)...)
- }
- return names
-}
-
-// List returns the names of the test functions in the given
-// suite that will be run with the provided run configuration.
-func List(suite interface{}, runConf *RunConf) []string {
- var names []string
- runner := newSuiteRunner(suite, runConf)
- for _, t := range runner.tests {
- names = append(names, t.String())
- }
- return names
-}
-
-// -----------------------------------------------------------------------
-// Result methods.
-
-func (r *Result) Add(other *Result) {
- r.Succeeded += other.Succeeded
- r.Skipped += other.Skipped
- r.Failed += other.Failed
- r.Panicked += other.Panicked
- r.FixturePanicked += other.FixturePanicked
- r.ExpectedFailures += other.ExpectedFailures
- r.Missed += other.Missed
- if r.WorkDir != "" && other.WorkDir != "" {
- r.WorkDir += ":" + other.WorkDir
- } else if other.WorkDir != "" {
- r.WorkDir = other.WorkDir
- }
-}
-
-func (r *Result) Passed() bool {
- return (r.Failed == 0 && r.Panicked == 0 &&
- r.FixturePanicked == 0 && r.Missed == 0 &&
- r.RunError == nil)
-}
-
-func (r *Result) String() string {
- if r.RunError != nil {
- return "ERROR: " + r.RunError.Error()
- }
-
- var value string
- if r.Failed == 0 && r.Panicked == 0 && r.FixturePanicked == 0 &&
- r.Missed == 0 {
- value = "OK: "
- } else {
- value = "OOPS: "
- }
- value += fmt.Sprintf("%d passed", r.Succeeded)
- if r.Skipped != 0 {
- value += fmt.Sprintf(", %d skipped", r.Skipped)
- }
- if r.ExpectedFailures != 0 {
- value += fmt.Sprintf(", %d expected failures", r.ExpectedFailures)
- }
- if r.Failed != 0 {
- value += fmt.Sprintf(", %d FAILED", r.Failed)
- }
- if r.Panicked != 0 {
- value += fmt.Sprintf(", %d PANICKED", r.Panicked)
- }
- if r.FixturePanicked != 0 {
- value += fmt.Sprintf(", %d FIXTURE-PANICKED", r.FixturePanicked)
- }
- if r.Missed != 0 {
- value += fmt.Sprintf(", %d MISSED", r.Missed)
- }
- if r.WorkDir != "" {
- value += "\nWORK=" + r.WorkDir
- }
- return value
-}
diff --git a/vendor/gopkg.in/check.v1/run_test.go b/vendor/gopkg.in/check.v1/run_test.go
deleted file mode 100644
index f41fffc3..00000000
--- a/vendor/gopkg.in/check.v1/run_test.go
+++ /dev/null
@@ -1,419 +0,0 @@
-// These tests verify the test running logic.
-
-package check_test
-
-import (
- "errors"
- . "gopkg.in/check.v1"
- "os"
- "sync"
-)
-
-var runnerS = Suite(&RunS{})
-
-type RunS struct{}
-
-func (s *RunS) TestCountSuite(c *C) {
- suitesRun += 1
-}
-
-// -----------------------------------------------------------------------
-// Tests ensuring result counting works properly.
-
-func (s *RunS) TestSuccess(c *C) {
- output := String{}
- result := Run(&SuccessHelper{}, &RunConf{Output: &output})
- c.Check(result.Succeeded, Equals, 1)
- c.Check(result.Failed, Equals, 0)
- c.Check(result.Skipped, Equals, 0)
- c.Check(result.Panicked, Equals, 0)
- c.Check(result.FixturePanicked, Equals, 0)
- c.Check(result.Missed, Equals, 0)
- c.Check(result.RunError, IsNil)
-}
-
-func (s *RunS) TestFailure(c *C) {
- output := String{}
- result := Run(&FailHelper{}, &RunConf{Output: &output})
- c.Check(result.Succeeded, Equals, 0)
- c.Check(result.Failed, Equals, 1)
- c.Check(result.Skipped, Equals, 0)
- c.Check(result.Panicked, Equals, 0)
- c.Check(result.FixturePanicked, Equals, 0)
- c.Check(result.Missed, Equals, 0)
- c.Check(result.RunError, IsNil)
-}
-
-func (s *RunS) TestFixture(c *C) {
- output := String{}
- result := Run(&FixtureHelper{}, &RunConf{Output: &output})
- c.Check(result.Succeeded, Equals, 2)
- c.Check(result.Failed, Equals, 0)
- c.Check(result.Skipped, Equals, 0)
- c.Check(result.Panicked, Equals, 0)
- c.Check(result.FixturePanicked, Equals, 0)
- c.Check(result.Missed, Equals, 0)
- c.Check(result.RunError, IsNil)
-}
-
-func (s *RunS) TestPanicOnTest(c *C) {
- output := String{}
- helper := &FixtureHelper{panicOn: "Test1"}
- result := Run(helper, &RunConf{Output: &output})
- c.Check(result.Succeeded, Equals, 1)
- c.Check(result.Failed, Equals, 0)
- c.Check(result.Skipped, Equals, 0)
- c.Check(result.Panicked, Equals, 1)
- c.Check(result.FixturePanicked, Equals, 0)
- c.Check(result.Missed, Equals, 0)
- c.Check(result.RunError, IsNil)
-}
-
-func (s *RunS) TestPanicOnSetUpTest(c *C) {
- output := String{}
- helper := &FixtureHelper{panicOn: "SetUpTest"}
- result := Run(helper, &RunConf{Output: &output})
- c.Check(result.Succeeded, Equals, 0)
- c.Check(result.Failed, Equals, 0)
- c.Check(result.Skipped, Equals, 0)
- c.Check(result.Panicked, Equals, 0)
- c.Check(result.FixturePanicked, Equals, 1)
- c.Check(result.Missed, Equals, 2)
- c.Check(result.RunError, IsNil)
-}
-
-func (s *RunS) TestPanicOnSetUpSuite(c *C) {
- output := String{}
- helper := &FixtureHelper{panicOn: "SetUpSuite"}
- result := Run(helper, &RunConf{Output: &output})
- c.Check(result.Succeeded, Equals, 0)
- c.Check(result.Failed, Equals, 0)
- c.Check(result.Skipped, Equals, 0)
- c.Check(result.Panicked, Equals, 0)
- c.Check(result.FixturePanicked, Equals, 1)
- c.Check(result.Missed, Equals, 2)
- c.Check(result.RunError, IsNil)
-}
-
-// -----------------------------------------------------------------------
-// Check result aggregation.
-
-func (s *RunS) TestAdd(c *C) {
- result := &Result{
- Succeeded: 1,
- Skipped: 2,
- Failed: 3,
- Panicked: 4,
- FixturePanicked: 5,
- Missed: 6,
- ExpectedFailures: 7,
- }
- result.Add(&Result{
- Succeeded: 10,
- Skipped: 20,
- Failed: 30,
- Panicked: 40,
- FixturePanicked: 50,
- Missed: 60,
- ExpectedFailures: 70,
- })
- c.Check(result.Succeeded, Equals, 11)
- c.Check(result.Skipped, Equals, 22)
- c.Check(result.Failed, Equals, 33)
- c.Check(result.Panicked, Equals, 44)
- c.Check(result.FixturePanicked, Equals, 55)
- c.Check(result.Missed, Equals, 66)
- c.Check(result.ExpectedFailures, Equals, 77)
- c.Check(result.RunError, IsNil)
-}
-
-// -----------------------------------------------------------------------
-// Check the Passed() method.
-
-func (s *RunS) TestPassed(c *C) {
- c.Assert((&Result{}).Passed(), Equals, true)
- c.Assert((&Result{Succeeded: 1}).Passed(), Equals, true)
- c.Assert((&Result{Skipped: 1}).Passed(), Equals, true)
- c.Assert((&Result{Failed: 1}).Passed(), Equals, false)
- c.Assert((&Result{Panicked: 1}).Passed(), Equals, false)
- c.Assert((&Result{FixturePanicked: 1}).Passed(), Equals, false)
- c.Assert((&Result{Missed: 1}).Passed(), Equals, false)
- c.Assert((&Result{RunError: errors.New("!")}).Passed(), Equals, false)
-}
-
-// -----------------------------------------------------------------------
-// Check that result printing is working correctly.
-
-func (s *RunS) TestPrintSuccess(c *C) {
- result := &Result{Succeeded: 5}
- c.Check(result.String(), Equals, "OK: 5 passed")
-}
-
-func (s *RunS) TestPrintFailure(c *C) {
- result := &Result{Failed: 5}
- c.Check(result.String(), Equals, "OOPS: 0 passed, 5 FAILED")
-}
-
-func (s *RunS) TestPrintSkipped(c *C) {
- result := &Result{Skipped: 5}
- c.Check(result.String(), Equals, "OK: 0 passed, 5 skipped")
-}
-
-func (s *RunS) TestPrintExpectedFailures(c *C) {
- result := &Result{ExpectedFailures: 5}
- c.Check(result.String(), Equals, "OK: 0 passed, 5 expected failures")
-}
-
-func (s *RunS) TestPrintPanicked(c *C) {
- result := &Result{Panicked: 5}
- c.Check(result.String(), Equals, "OOPS: 0 passed, 5 PANICKED")
-}
-
-func (s *RunS) TestPrintFixturePanicked(c *C) {
- result := &Result{FixturePanicked: 5}
- c.Check(result.String(), Equals, "OOPS: 0 passed, 5 FIXTURE-PANICKED")
-}
-
-func (s *RunS) TestPrintMissed(c *C) {
- result := &Result{Missed: 5}
- c.Check(result.String(), Equals, "OOPS: 0 passed, 5 MISSED")
-}
-
-func (s *RunS) TestPrintAll(c *C) {
- result := &Result{Succeeded: 1, Skipped: 2, ExpectedFailures: 3,
- Panicked: 4, FixturePanicked: 5, Missed: 6}
- c.Check(result.String(), Equals,
- "OOPS: 1 passed, 2 skipped, 3 expected failures, 4 PANICKED, "+
- "5 FIXTURE-PANICKED, 6 MISSED")
-}
-
-func (s *RunS) TestPrintRunError(c *C) {
- result := &Result{Succeeded: 1, Failed: 1,
- RunError: errors.New("Kaboom!")}
- c.Check(result.String(), Equals, "ERROR: Kaboom!")
-}
-
-// -----------------------------------------------------------------------
-// Verify that the method pattern flag works correctly.
-
-func (s *RunS) TestFilterTestName(c *C) {
- helper := FixtureHelper{}
- output := String{}
- runConf := RunConf{Output: &output, Filter: "Test[91]"}
- Run(&helper, &runConf)
- c.Check(helper.calls[0], Equals, "SetUpSuite")
- c.Check(helper.calls[1], Equals, "SetUpTest")
- c.Check(helper.calls[2], Equals, "Test1")
- c.Check(helper.calls[3], Equals, "TearDownTest")
- c.Check(helper.calls[4], Equals, "TearDownSuite")
- c.Check(len(helper.calls), Equals, 5)
-}
-
-func (s *RunS) TestFilterTestNameWithAll(c *C) {
- helper := FixtureHelper{}
- output := String{}
- runConf := RunConf{Output: &output, Filter: ".*"}
- Run(&helper, &runConf)
- c.Check(helper.calls[0], Equals, "SetUpSuite")
- c.Check(helper.calls[1], Equals, "SetUpTest")
- c.Check(helper.calls[2], Equals, "Test1")
- c.Check(helper.calls[3], Equals, "TearDownTest")
- c.Check(helper.calls[4], Equals, "SetUpTest")
- c.Check(helper.calls[5], Equals, "Test2")
- c.Check(helper.calls[6], Equals, "TearDownTest")
- c.Check(helper.calls[7], Equals, "TearDownSuite")
- c.Check(len(helper.calls), Equals, 8)
-}
-
-func (s *RunS) TestFilterSuiteName(c *C) {
- helper := FixtureHelper{}
- output := String{}
- runConf := RunConf{Output: &output, Filter: "FixtureHelper"}
- Run(&helper, &runConf)
- c.Check(helper.calls[0], Equals, "SetUpSuite")
- c.Check(helper.calls[1], Equals, "SetUpTest")
- c.Check(helper.calls[2], Equals, "Test1")
- c.Check(helper.calls[3], Equals, "TearDownTest")
- c.Check(helper.calls[4], Equals, "SetUpTest")
- c.Check(helper.calls[5], Equals, "Test2")
- c.Check(helper.calls[6], Equals, "TearDownTest")
- c.Check(helper.calls[7], Equals, "TearDownSuite")
- c.Check(len(helper.calls), Equals, 8)
-}
-
-func (s *RunS) TestFilterSuiteNameAndTestName(c *C) {
- helper := FixtureHelper{}
- output := String{}
- runConf := RunConf{Output: &output, Filter: "FixtureHelper\\.Test2"}
- Run(&helper, &runConf)
- c.Check(helper.calls[0], Equals, "SetUpSuite")
- c.Check(helper.calls[1], Equals, "SetUpTest")
- c.Check(helper.calls[2], Equals, "Test2")
- c.Check(helper.calls[3], Equals, "TearDownTest")
- c.Check(helper.calls[4], Equals, "TearDownSuite")
- c.Check(len(helper.calls), Equals, 5)
-}
-
-func (s *RunS) TestFilterAllOut(c *C) {
- helper := FixtureHelper{}
- output := String{}
- runConf := RunConf{Output: &output, Filter: "NotFound"}
- Run(&helper, &runConf)
- c.Check(len(helper.calls), Equals, 0)
-}
-
-func (s *RunS) TestRequirePartialMatch(c *C) {
- helper := FixtureHelper{}
- output := String{}
- runConf := RunConf{Output: &output, Filter: "est"}
- Run(&helper, &runConf)
- c.Check(len(helper.calls), Equals, 8)
-}
-
-func (s *RunS) TestFilterError(c *C) {
- helper := FixtureHelper{}
- output := String{}
- runConf := RunConf{Output: &output, Filter: "]["}
- result := Run(&helper, &runConf)
- c.Check(result.String(), Equals,
- "ERROR: Bad filter expression: error parsing regexp: missing closing ]: `[`")
- c.Check(len(helper.calls), Equals, 0)
-}
-
-// -----------------------------------------------------------------------
-// Verify that List works correctly.
-
-func (s *RunS) TestListFiltered(c *C) {
- names := List(&FixtureHelper{}, &RunConf{Filter: "1"})
- c.Assert(names, DeepEquals, []string{
- "FixtureHelper.Test1",
- })
-}
-
-func (s *RunS) TestList(c *C) {
- names := List(&FixtureHelper{}, &RunConf{})
- c.Assert(names, DeepEquals, []string{
- "FixtureHelper.Test1",
- "FixtureHelper.Test2",
- })
-}
-
-// -----------------------------------------------------------------------
-// Verify that verbose mode prints tests which pass as well.
-
-func (s *RunS) TestVerboseMode(c *C) {
- helper := FixtureHelper{}
- output := String{}
- runConf := RunConf{Output: &output, Verbose: true}
- Run(&helper, &runConf)
-
- expected := "PASS: check_test\\.go:[0-9]+: FixtureHelper\\.Test1\t *[.0-9]+s\n" +
- "PASS: check_test\\.go:[0-9]+: FixtureHelper\\.Test2\t *[.0-9]+s\n"
-
- c.Assert(output.value, Matches, expected)
-}
-
-func (s *RunS) TestVerboseModeWithFailBeforePass(c *C) {
- helper := FixtureHelper{panicOn: "Test1"}
- output := String{}
- runConf := RunConf{Output: &output, Verbose: true}
- Run(&helper, &runConf)
-
- expected := "(?s).*PANIC.*\n-+\n" + // Should have an extra line.
- "PASS: check_test\\.go:[0-9]+: FixtureHelper\\.Test2\t *[.0-9]+s\n"
-
- c.Assert(output.value, Matches, expected)
-}
-
-// -----------------------------------------------------------------------
-// Verify the stream output mode. In this mode there's no output caching.
-
-type StreamHelper struct {
- l2 sync.Mutex
- l3 sync.Mutex
-}
-
-func (s *StreamHelper) SetUpSuite(c *C) {
- c.Log("0")
-}
-
-func (s *StreamHelper) Test1(c *C) {
- c.Log("1")
- s.l2.Lock()
- s.l3.Lock()
- go func() {
- s.l2.Lock() // Wait for "2".
- c.Log("3")
- s.l3.Unlock()
- }()
-}
-
-func (s *StreamHelper) Test2(c *C) {
- c.Log("2")
- s.l2.Unlock()
- s.l3.Lock() // Wait for "3".
- c.Fail()
- c.Log("4")
-}
-
-func (s *RunS) TestStreamMode(c *C) {
- helper := &StreamHelper{}
- output := String{}
- runConf := RunConf{Output: &output, Stream: true}
- Run(helper, &runConf)
-
- expected := "START: run_test\\.go:[0-9]+: StreamHelper\\.SetUpSuite\n0\n" +
- "PASS: run_test\\.go:[0-9]+: StreamHelper\\.SetUpSuite\t *[.0-9]+s\n\n" +
- "START: run_test\\.go:[0-9]+: StreamHelper\\.Test1\n1\n" +
- "PASS: run_test\\.go:[0-9]+: StreamHelper\\.Test1\t *[.0-9]+s\n\n" +
- "START: run_test\\.go:[0-9]+: StreamHelper\\.Test2\n2\n3\n4\n" +
- "FAIL: run_test\\.go:[0-9]+: StreamHelper\\.Test2\n\n"
-
- c.Assert(output.value, Matches, expected)
-}
-
-type StreamMissHelper struct{}
-
-func (s *StreamMissHelper) SetUpSuite(c *C) {
- c.Log("0")
- c.Fail()
-}
-
-func (s *StreamMissHelper) Test1(c *C) {
- c.Log("1")
-}
-
-func (s *RunS) TestStreamModeWithMiss(c *C) {
- helper := &StreamMissHelper{}
- output := String{}
- runConf := RunConf{Output: &output, Stream: true}
- Run(helper, &runConf)
-
- expected := "START: run_test\\.go:[0-9]+: StreamMissHelper\\.SetUpSuite\n0\n" +
- "FAIL: run_test\\.go:[0-9]+: StreamMissHelper\\.SetUpSuite\n\n" +
- "START: run_test\\.go:[0-9]+: StreamMissHelper\\.Test1\n" +
- "MISS: run_test\\.go:[0-9]+: StreamMissHelper\\.Test1\n\n"
-
- c.Assert(output.value, Matches, expected)
-}
-
-// -----------------------------------------------------------------------
-// Verify that that the keep work dir request indeed does so.
-
-type WorkDirSuite struct {}
-
-func (s *WorkDirSuite) Test(c *C) {
- c.MkDir()
-}
-
-func (s *RunS) TestKeepWorkDir(c *C) {
- output := String{}
- runConf := RunConf{Output: &output, Verbose: true, KeepWorkDir: true}
- result := Run(&WorkDirSuite{}, &runConf)
-
- c.Assert(result.String(), Matches, ".*\nWORK=" + result.WorkDir)
-
- stat, err := os.Stat(result.WorkDir)
- c.Assert(err, IsNil)
- c.Assert(stat.IsDir(), Equals, true)
-}