Browse Source

etcd: Replace ghodss/yaml with sigs.k8s.io/yaml

Rohit Sardesai 6 years ago
parent
commit
8ed3e70d7c
44 changed files with 3767 additions and 321 deletions
  1. 9 9
      bill-of-materials.json
  2. 2 2
      bill-of-materials.override.json
  3. 1 1
      clientv3/yaml/config.go
  4. 1 1
      clientv3/yaml/config_test.go
  5. 12 0
      cmd/vendor/gopkg.in/yaml.v2/.travis.yml
  6. 198 10
      cmd/vendor/gopkg.in/yaml.v2/LICENSE
  7. 13 0
      cmd/vendor/gopkg.in/yaml.v2/NOTICE
  8. 133 0
      cmd/vendor/gopkg.in/yaml.v2/README.md
  9. 26 29
      cmd/vendor/gopkg.in/yaml.v2/apic.go
  10. 169 76
      cmd/vendor/gopkg.in/yaml.v2/decode.go
  11. 1334 0
      cmd/vendor/gopkg.in/yaml.v2/decode_test.go
  12. 10 9
      cmd/vendor/gopkg.in/yaml.v2/emitterc.go
  13. 124 40
      cmd/vendor/gopkg.in/yaml.v2/encode.go
  14. 625 0
      cmd/vendor/gopkg.in/yaml.v2/encode_test.go
  15. 41 0
      cmd/vendor/gopkg.in/yaml.v2/example_embedded_test.go
  16. 5 0
      cmd/vendor/gopkg.in/yaml.v2/go.mod
  17. 19 1
      cmd/vendor/gopkg.in/yaml.v2/readerc.go
  18. 65 15
      cmd/vendor/gopkg.in/yaml.v2/resolve.go
  19. 12 26
      cmd/vendor/gopkg.in/yaml.v2/scannerc.go
  20. 9 0
      cmd/vendor/gopkg.in/yaml.v2/sorter.go
  21. 12 0
      cmd/vendor/gopkg.in/yaml.v2/suite_test.go
  22. 1 64
      cmd/vendor/gopkg.in/yaml.v2/writerc.go
  23. 128 8
      cmd/vendor/gopkg.in/yaml.v2/yaml.go
  24. 27 5
      cmd/vendor/gopkg.in/yaml.v2/yamlh.go
  25. 20 0
      cmd/vendor/sigs.k8s.io/yaml/.gitignore
  26. 14 0
      cmd/vendor/sigs.k8s.io/yaml/.travis.yml
  27. 31 0
      cmd/vendor/sigs.k8s.io/yaml/CONTRIBUTING.md
  28. 0 0
      cmd/vendor/sigs.k8s.io/yaml/LICENSE
  29. 25 0
      cmd/vendor/sigs.k8s.io/yaml/OWNERS
  30. 121 0
      cmd/vendor/sigs.k8s.io/yaml/README.md
  31. 9 0
      cmd/vendor/sigs.k8s.io/yaml/RELEASE.md
  32. 17 0
      cmd/vendor/sigs.k8s.io/yaml/SECURITY_CONTACTS
  33. 3 0
      cmd/vendor/sigs.k8s.io/yaml/code-of-conduct.md
  34. 1 0
      cmd/vendor/sigs.k8s.io/yaml/fields.go
  35. 55 13
      cmd/vendor/sigs.k8s.io/yaml/yaml.go
  36. 14 0
      cmd/vendor/sigs.k8s.io/yaml/yaml_go110.go
  37. 46 0
      cmd/vendor/sigs.k8s.io/yaml/yaml_go110_test.go
  38. 423 0
      cmd/vendor/sigs.k8s.io/yaml/yaml_test.go
  39. 1 1
      embed/config.go
  40. 1 1
      embed/config_test.go
  41. 1 1
      etcdmain/config.go
  42. 1 1
      etcdmain/config_test.go
  43. 5 5
      glide.lock
  44. 3 3
      glide.yaml

+ 9 - 9
bill-of-materials.json

@@ -98,15 +98,6 @@
 			}
 			}
 		]
 		]
 	},
 	},
-	{
-		"project": "github.com/ghodss/yaml",
-		"licenses": [
-			{
-				"type": "MIT License and BSD 3-clause \"New\" or \"Revised\" License",
-				"confidence": 1
-			}
-		]
-	},
 	{
 	{
 		"project": "github.com/gogo/protobuf",
 		"project": "github.com/gogo/protobuf",
 		"licenses": [
 		"licenses": [
@@ -465,5 +456,14 @@
 				"confidence": 0.8975609756097561
 				"confidence": 0.8975609756097561
 			}
 			}
 		]
 		]
+	},
+	{
+		"project": "sigs.k8s.io/yaml",
+		"licenses": [
+			{
+				"type": "BSD 3-clause \"New\" or \"Revised\" License",
+				"confidence": 1
+			}
+		]
 	}
 	}
 ]
 ]

+ 2 - 2
bill-of-materials.override.json

@@ -8,10 +8,10 @@
 		]
 		]
 	},
 	},
 	{
 	{
-		"project": "github.com/ghodss/yaml",
+		"project": "sigs.k8s.io/yaml",
 		"licenses": [
 		"licenses": [
 			{
 			{
-				"type": "MIT License and BSD 3-clause \"New\" or \"Revised\" License"
+				"type": "BSD 3-clause \"New\" or \"Revised\" License"
 			}
 			}
 		]
 		]
 	},
 	},

+ 1 - 1
clientv3/yaml/config.go

@@ -20,7 +20,7 @@ import (
 	"crypto/x509"
 	"crypto/x509"
 	"io/ioutil"
 	"io/ioutil"
 
 
-	"github.com/ghodss/yaml"
+	"sigs.k8s.io/yaml"
 
 
 	"github.com/coreos/etcd/clientv3"
 	"github.com/coreos/etcd/clientv3"
 	"github.com/coreos/etcd/pkg/tlsutil"
 	"github.com/coreos/etcd/pkg/tlsutil"

+ 1 - 1
clientv3/yaml/config_test.go

@@ -21,7 +21,7 @@ import (
 	"reflect"
 	"reflect"
 	"testing"
 	"testing"
 
 
-	"github.com/ghodss/yaml"
+	"sigs.k8s.io/yaml"
 )
 )
 
 
 var (
 var (

+ 12 - 0
cmd/vendor/gopkg.in/yaml.v2/.travis.yml

@@ -0,0 +1,12 @@
+language: go
+
+go:
+    - 1.4
+    - 1.5
+    - 1.6
+    - 1.7
+    - 1.8
+    - 1.9
+    - tip
+
+go_import_path: gopkg.in/yaml.v2

+ 198 - 10
cmd/vendor/gopkg.in/yaml.v2/LICENSE

@@ -1,13 +1,201 @@
-Copyright 2011-2016 Canonical Ltd.
+                                 Apache License
+                           Version 2.0, January 2004
+                        http://www.apache.org/licenses/
 
 
-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
+   TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION
 
 
-    http://www.apache.org/licenses/LICENSE-2.0
+   1. Definitions.
 
 
-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.
+      "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.

+ 13 - 0
cmd/vendor/gopkg.in/yaml.v2/NOTICE

@@ -0,0 +1,13 @@
+Copyright 2011-2016 Canonical Ltd.
+
+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.

+ 133 - 0
cmd/vendor/gopkg.in/yaml.v2/README.md

@@ -0,0 +1,133 @@
+# 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 Apache License 2.0. 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]
+`
+
+// Note: struct fields must be public in order for unmarshal to
+// correctly populate the data.
+type T struct {
+        A string
+        B struct {
+                RenamedC int   `yaml:"c"`
+                D        []int `yaml:",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
+```
+

+ 26 - 29
cmd/vendor/gopkg.in/yaml.v2/apic.go

@@ -2,7 +2,6 @@ package yaml
 
 
 import (
 import (
 	"io"
 	"io"
-	"os"
 )
 )
 
 
 func yaml_insert_token(parser *yaml_parser_t, pos int, token *yaml_token_t) {
 func yaml_insert_token(parser *yaml_parser_t, pos int, token *yaml_token_t) {
@@ -48,9 +47,9 @@ func yaml_string_read_handler(parser *yaml_parser_t, buffer []byte) (n int, err
 	return n, nil
 	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)
+// Reader read handler.
+func yaml_reader_read_handler(parser *yaml_parser_t, buffer []byte) (n int, err error) {
+	return parser.input_reader.Read(buffer)
 }
 }
 
 
 // Set a string input.
 // Set a string input.
@@ -64,12 +63,12 @@ func yaml_parser_set_input_string(parser *yaml_parser_t, input []byte) {
 }
 }
 
 
 // Set a file input.
 // Set a file input.
-func yaml_parser_set_input_file(parser *yaml_parser_t, file *os.File) {
+func yaml_parser_set_input_reader(parser *yaml_parser_t, r io.Reader) {
 	if parser.read_handler != nil {
 	if parser.read_handler != nil {
 		panic("must set the input source only once")
 		panic("must set the input source only once")
 	}
 	}
-	parser.read_handler = yaml_file_read_handler
-	parser.input_file = file
+	parser.read_handler = yaml_reader_read_handler
+	parser.input_reader = r
 }
 }
 
 
 // Set the source encoding.
 // Set the source encoding.
@@ -81,14 +80,13 @@ func yaml_parser_set_encoding(parser *yaml_parser_t, encoding yaml_encoding_t) {
 }
 }
 
 
 // Create a new emitter object.
 // Create a new emitter object.
-func yaml_emitter_initialize(emitter *yaml_emitter_t) bool {
+func yaml_emitter_initialize(emitter *yaml_emitter_t) {
 	*emitter = yaml_emitter_t{
 	*emitter = yaml_emitter_t{
 		buffer:     make([]byte, output_buffer_size),
 		buffer:     make([]byte, output_buffer_size),
 		raw_buffer: make([]byte, 0, output_raw_buffer_size),
 		raw_buffer: make([]byte, 0, output_raw_buffer_size),
 		states:     make([]yaml_emitter_state_t, 0, initial_stack_size),
 		states:     make([]yaml_emitter_state_t, 0, initial_stack_size),
 		events:     make([]yaml_event_t, 0, initial_queue_size),
 		events:     make([]yaml_event_t, 0, initial_queue_size),
 	}
 	}
-	return true
 }
 }
 
 
 // Destroy an emitter object.
 // Destroy an emitter object.
@@ -102,9 +100,10 @@ func yaml_string_write_handler(emitter *yaml_emitter_t, buffer []byte) error {
 	return nil
 	return nil
 }
 }
 
 
-// File write handler.
-func yaml_file_write_handler(emitter *yaml_emitter_t, buffer []byte) error {
-	_, err := emitter.output_file.Write(buffer)
+// yaml_writer_write_handler uses emitter.output_writer to write the
+// emitted text.
+func yaml_writer_write_handler(emitter *yaml_emitter_t, buffer []byte) error {
+	_, err := emitter.output_writer.Write(buffer)
 	return err
 	return err
 }
 }
 
 
@@ -118,12 +117,12 @@ func yaml_emitter_set_output_string(emitter *yaml_emitter_t, output_buffer *[]by
 }
 }
 
 
 // Set a file output.
 // Set a file output.
-func yaml_emitter_set_output_file(emitter *yaml_emitter_t, file io.Writer) {
+func yaml_emitter_set_output_writer(emitter *yaml_emitter_t, w io.Writer) {
 	if emitter.write_handler != nil {
 	if emitter.write_handler != nil {
 		panic("must set the output target only once")
 		panic("must set the output target only once")
 	}
 	}
-	emitter.write_handler = yaml_file_write_handler
-	emitter.output_file = file
+	emitter.write_handler = yaml_writer_write_handler
+	emitter.output_writer = w
 }
 }
 
 
 // Set the output encoding.
 // Set the output encoding.
@@ -252,41 +251,41 @@ func yaml_emitter_set_break(emitter *yaml_emitter_t, line_break yaml_break_t) {
 //
 //
 
 
 // Create STREAM-START.
 // Create STREAM-START.
-func yaml_stream_start_event_initialize(event *yaml_event_t, encoding yaml_encoding_t) bool {
+func yaml_stream_start_event_initialize(event *yaml_event_t, encoding yaml_encoding_t) {
 	*event = yaml_event_t{
 	*event = yaml_event_t{
 		typ:      yaml_STREAM_START_EVENT,
 		typ:      yaml_STREAM_START_EVENT,
 		encoding: encoding,
 		encoding: encoding,
 	}
 	}
-	return true
 }
 }
 
 
 // Create STREAM-END.
 // Create STREAM-END.
-func yaml_stream_end_event_initialize(event *yaml_event_t) bool {
+func yaml_stream_end_event_initialize(event *yaml_event_t) {
 	*event = yaml_event_t{
 	*event = yaml_event_t{
 		typ: yaml_STREAM_END_EVENT,
 		typ: yaml_STREAM_END_EVENT,
 	}
 	}
-	return true
 }
 }
 
 
 // Create DOCUMENT-START.
 // 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 {
+func yaml_document_start_event_initialize(
+	event *yaml_event_t,
+	version_directive *yaml_version_directive_t,
+	tag_directives []yaml_tag_directive_t,
+	implicit bool,
+) {
 	*event = yaml_event_t{
 	*event = yaml_event_t{
 		typ:               yaml_DOCUMENT_START_EVENT,
 		typ:               yaml_DOCUMENT_START_EVENT,
 		version_directive: version_directive,
 		version_directive: version_directive,
 		tag_directives:    tag_directives,
 		tag_directives:    tag_directives,
 		implicit:          implicit,
 		implicit:          implicit,
 	}
 	}
-	return true
 }
 }
 
 
 // Create DOCUMENT-END.
 // Create DOCUMENT-END.
-func yaml_document_end_event_initialize(event *yaml_event_t, implicit bool) bool {
+func yaml_document_end_event_initialize(event *yaml_event_t, implicit bool) {
 	*event = yaml_event_t{
 	*event = yaml_event_t{
 		typ:      yaml_DOCUMENT_END_EVENT,
 		typ:      yaml_DOCUMENT_END_EVENT,
 		implicit: implicit,
 		implicit: implicit,
 	}
 	}
-	return true
 }
 }
 
 
 ///*
 ///*
@@ -348,7 +347,7 @@ func yaml_sequence_end_event_initialize(event *yaml_event_t) bool {
 }
 }
 
 
 // Create MAPPING-START.
 // Create MAPPING-START.
-func yaml_mapping_start_event_initialize(event *yaml_event_t, anchor, tag []byte, implicit bool, style yaml_mapping_style_t) bool {
+func yaml_mapping_start_event_initialize(event *yaml_event_t, anchor, tag []byte, implicit bool, style yaml_mapping_style_t) {
 	*event = yaml_event_t{
 	*event = yaml_event_t{
 		typ:      yaml_MAPPING_START_EVENT,
 		typ:      yaml_MAPPING_START_EVENT,
 		anchor:   anchor,
 		anchor:   anchor,
@@ -356,15 +355,13 @@ func yaml_mapping_start_event_initialize(event *yaml_event_t, anchor, tag []byte
 		implicit: implicit,
 		implicit: implicit,
 		style:    yaml_style_t(style),
 		style:    yaml_style_t(style),
 	}
 	}
-	return true
 }
 }
 
 
 // Create MAPPING-END.
 // Create MAPPING-END.
-func yaml_mapping_end_event_initialize(event *yaml_event_t) bool {
+func yaml_mapping_end_event_initialize(event *yaml_event_t) {
 	*event = yaml_event_t{
 	*event = yaml_event_t{
 		typ: yaml_MAPPING_END_EVENT,
 		typ: yaml_MAPPING_END_EVENT,
 	}
 	}
-	return true
 }
 }
 
 
 // Destroy an event object.
 // Destroy an event object.
@@ -471,7 +468,7 @@ func yaml_event_delete(event *yaml_event_t) {
 //    } context
 //    } context
 //    tag_directive *yaml_tag_directive_t
 //    tag_directive *yaml_tag_directive_t
 //
 //
-//    context.error = YAML_NO_ERROR // Eliminate a compliler warning.
+//    context.error = YAML_NO_ERROR // Eliminate a compiler warning.
 //
 //
 //    assert(document) // Non-NULL document object is expected.
 //    assert(document) // Non-NULL document object is expected.
 //
 //

+ 169 - 76
cmd/vendor/gopkg.in/yaml.v2/decode.go

@@ -4,6 +4,7 @@ import (
 	"encoding"
 	"encoding"
 	"encoding/base64"
 	"encoding/base64"
 	"fmt"
 	"fmt"
+	"io"
 	"math"
 	"math"
 	"reflect"
 	"reflect"
 	"strconv"
 	"strconv"
@@ -22,19 +23,22 @@ type node struct {
 	kind         int
 	kind         int
 	line, column int
 	line, column int
 	tag          string
 	tag          string
-	value        string
-	implicit     bool
-	children     []*node
-	anchors      map[string]*node
+	// For an alias node, alias holds the resolved alias.
+	alias    *node
+	value    string
+	implicit bool
+	children []*node
+	anchors  map[string]*node
 }
 }
 
 
 // ----------------------------------------------------------------------------
 // ----------------------------------------------------------------------------
 // Parser, produces a node tree out of a libyaml event stream.
 // Parser, produces a node tree out of a libyaml event stream.
 
 
 type parser struct {
 type parser struct {
-	parser yaml_parser_t
-	event  yaml_event_t
-	doc    *node
+	parser   yaml_parser_t
+	event    yaml_event_t
+	doc      *node
+	doneInit bool
 }
 }
 
 
 func newParser(b []byte) *parser {
 func newParser(b []byte) *parser {
@@ -42,21 +46,30 @@ func newParser(b []byte) *parser {
 	if !yaml_parser_initialize(&p.parser) {
 	if !yaml_parser_initialize(&p.parser) {
 		panic("failed to initialize YAML emitter")
 		panic("failed to initialize YAML emitter")
 	}
 	}
-
 	if len(b) == 0 {
 	if len(b) == 0 {
 		b = []byte{'\n'}
 		b = []byte{'\n'}
 	}
 	}
-
 	yaml_parser_set_input_string(&p.parser, b)
 	yaml_parser_set_input_string(&p.parser, b)
+	return &p
+}
 
 
-	p.skip()
-	if p.event.typ != yaml_STREAM_START_EVENT {
-		panic("expected stream start event, got " + strconv.Itoa(int(p.event.typ)))
+func newParserFromReader(r io.Reader) *parser {
+	p := parser{}
+	if !yaml_parser_initialize(&p.parser) {
+		panic("failed to initialize YAML emitter")
 	}
 	}
-	p.skip()
+	yaml_parser_set_input_reader(&p.parser, r)
 	return &p
 	return &p
 }
 }
 
 
+func (p *parser) init() {
+	if p.doneInit {
+		return
+	}
+	p.expect(yaml_STREAM_START_EVENT)
+	p.doneInit = true
+}
+
 func (p *parser) destroy() {
 func (p *parser) destroy() {
 	if p.event.typ != yaml_NO_EVENT {
 	if p.event.typ != yaml_NO_EVENT {
 		yaml_event_delete(&p.event)
 		yaml_event_delete(&p.event)
@@ -64,16 +77,35 @@ func (p *parser) destroy() {
 	yaml_parser_delete(&p.parser)
 	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?")
+// expect consumes an event from the event stream and
+// checks that it's of the expected type.
+func (p *parser) expect(e yaml_event_type_t) {
+	if p.event.typ == yaml_NO_EVENT {
+		if !yaml_parser_parse(&p.parser, &p.event) {
+			p.fail()
 		}
 		}
-		yaml_event_delete(&p.event)
+	}
+	if p.event.typ == yaml_STREAM_END_EVENT {
+		failf("attempted to go past the end of stream; corrupted value?")
+	}
+	if p.event.typ != e {
+		p.parser.problem = fmt.Sprintf("expected %s event but got %s", e, p.event.typ)
+		p.fail()
+	}
+	yaml_event_delete(&p.event)
+	p.event.typ = yaml_NO_EVENT
+}
+
+// peek peeks at the next event in the event stream,
+// puts the results into p.event and returns the event type.
+func (p *parser) peek() yaml_event_type_t {
+	if p.event.typ != yaml_NO_EVENT {
+		return p.event.typ
 	}
 	}
 	if !yaml_parser_parse(&p.parser, &p.event) {
 	if !yaml_parser_parse(&p.parser, &p.event) {
 		p.fail()
 		p.fail()
 	}
 	}
+	return p.event.typ
 }
 }
 
 
 func (p *parser) fail() {
 func (p *parser) fail() {
@@ -81,6 +113,10 @@ func (p *parser) fail() {
 	var line int
 	var line int
 	if p.parser.problem_mark.line != 0 {
 	if p.parser.problem_mark.line != 0 {
 		line = p.parser.problem_mark.line
 		line = p.parser.problem_mark.line
+		// Scanner errors don't iterate line before returning error
+		if p.parser.error == yaml_SCANNER_ERROR {
+			line++
+		}
 	} else if p.parser.context_mark.line != 0 {
 	} else if p.parser.context_mark.line != 0 {
 		line = p.parser.context_mark.line
 		line = p.parser.context_mark.line
 	}
 	}
@@ -103,7 +139,8 @@ func (p *parser) anchor(n *node, anchor []byte) {
 }
 }
 
 
 func (p *parser) parse() *node {
 func (p *parser) parse() *node {
-	switch p.event.typ {
+	p.init()
+	switch p.peek() {
 	case yaml_SCALAR_EVENT:
 	case yaml_SCALAR_EVENT:
 		return p.scalar()
 		return p.scalar()
 	case yaml_ALIAS_EVENT:
 	case yaml_ALIAS_EVENT:
@@ -118,7 +155,7 @@ func (p *parser) parse() *node {
 		// Happens when attempting to decode an empty buffer.
 		// Happens when attempting to decode an empty buffer.
 		return nil
 		return nil
 	default:
 	default:
-		panic("attempted to parse unknown event: " + strconv.Itoa(int(p.event.typ)))
+		panic("attempted to parse unknown event: " + p.event.typ.String())
 	}
 	}
 }
 }
 
 
@@ -134,19 +171,20 @@ func (p *parser) document() *node {
 	n := p.node(documentNode)
 	n := p.node(documentNode)
 	n.anchors = make(map[string]*node)
 	n.anchors = make(map[string]*node)
 	p.doc = n
 	p.doc = n
-	p.skip()
+	p.expect(yaml_DOCUMENT_START_EVENT)
 	n.children = append(n.children, p.parse())
 	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()
+	p.expect(yaml_DOCUMENT_END_EVENT)
 	return n
 	return n
 }
 }
 
 
 func (p *parser) alias() *node {
 func (p *parser) alias() *node {
 	n := p.node(aliasNode)
 	n := p.node(aliasNode)
 	n.value = string(p.event.anchor)
 	n.value = string(p.event.anchor)
-	p.skip()
+	n.alias = p.doc.anchors[n.value]
+	if n.alias == nil {
+		failf("unknown anchor '%s' referenced", n.value)
+	}
+	p.expect(yaml_ALIAS_EVENT)
 	return n
 	return n
 }
 }
 
 
@@ -156,29 +194,29 @@ func (p *parser) scalar() *node {
 	n.tag = string(p.event.tag)
 	n.tag = string(p.event.tag)
 	n.implicit = p.event.implicit
 	n.implicit = p.event.implicit
 	p.anchor(n, p.event.anchor)
 	p.anchor(n, p.event.anchor)
-	p.skip()
+	p.expect(yaml_SCALAR_EVENT)
 	return n
 	return n
 }
 }
 
 
 func (p *parser) sequence() *node {
 func (p *parser) sequence() *node {
 	n := p.node(sequenceNode)
 	n := p.node(sequenceNode)
 	p.anchor(n, p.event.anchor)
 	p.anchor(n, p.event.anchor)
-	p.skip()
-	for p.event.typ != yaml_SEQUENCE_END_EVENT {
+	p.expect(yaml_SEQUENCE_START_EVENT)
+	for p.peek() != yaml_SEQUENCE_END_EVENT {
 		n.children = append(n.children, p.parse())
 		n.children = append(n.children, p.parse())
 	}
 	}
-	p.skip()
+	p.expect(yaml_SEQUENCE_END_EVENT)
 	return n
 	return n
 }
 }
 
 
 func (p *parser) mapping() *node {
 func (p *parser) mapping() *node {
 	n := p.node(mappingNode)
 	n := p.node(mappingNode)
 	p.anchor(n, p.event.anchor)
 	p.anchor(n, p.event.anchor)
-	p.skip()
-	for p.event.typ != yaml_MAPPING_END_EVENT {
+	p.expect(yaml_MAPPING_START_EVENT)
+	for p.peek() != yaml_MAPPING_END_EVENT {
 		n.children = append(n.children, p.parse(), p.parse())
 		n.children = append(n.children, p.parse(), p.parse())
 	}
 	}
-	p.skip()
+	p.expect(yaml_MAPPING_END_EVENT)
 	return n
 	return n
 }
 }
 
 
@@ -187,9 +225,10 @@ func (p *parser) mapping() *node {
 
 
 type decoder struct {
 type decoder struct {
 	doc     *node
 	doc     *node
-	aliases map[string]bool
+	aliases map[*node]bool
 	mapType reflect.Type
 	mapType reflect.Type
 	terrors []string
 	terrors []string
+	strict  bool
 }
 }
 
 
 var (
 var (
@@ -197,11 +236,13 @@ var (
 	durationType   = reflect.TypeOf(time.Duration(0))
 	durationType   = reflect.TypeOf(time.Duration(0))
 	defaultMapType = reflect.TypeOf(map[interface{}]interface{}{})
 	defaultMapType = reflect.TypeOf(map[interface{}]interface{}{})
 	ifaceType      = defaultMapType.Elem()
 	ifaceType      = defaultMapType.Elem()
+	timeType       = reflect.TypeOf(time.Time{})
+	ptrTimeType    = reflect.TypeOf(&time.Time{})
 )
 )
 
 
-func newDecoder() *decoder {
-	d := &decoder{mapType: defaultMapType}
-	d.aliases = make(map[string]bool)
+func newDecoder(strict bool) *decoder {
+	d := &decoder{mapType: defaultMapType, strict: strict}
+	d.aliases = make(map[*node]bool)
 	return d
 	return d
 }
 }
 
 
@@ -250,7 +291,7 @@ func (d *decoder) callUnmarshaler(n *node, u Unmarshaler) (good bool) {
 //
 //
 // If n holds a null value, prepare returns before doing anything.
 // 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) {
 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 == "" && n.implicit) {
+	if n.tag == yaml_NULL_TAG || n.kind == scalarNode && n.tag == "" && (n.value == "null" || n.value == "~" || n.value == "" && n.implicit) {
 		return out, false, false
 		return out, false, false
 	}
 	}
 	again := true
 	again := true
@@ -307,16 +348,13 @@ func (d *decoder) document(n *node, out reflect.Value) (good bool) {
 }
 }
 
 
 func (d *decoder) alias(n *node, out reflect.Value) (good bool) {
 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] {
+	if d.aliases[n] {
+		// TODO this could actually be allowed in some circumstances.
 		failf("anchor '%s' value contains itself", 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)
+	d.aliases[n] = true
+	good = d.unmarshal(n.alias, out)
+	delete(d.aliases, n)
 	return good
 	return good
 }
 }
 
 
@@ -328,7 +366,7 @@ func resetMap(out reflect.Value) {
 	}
 	}
 }
 }
 
 
-func (d *decoder) scalar(n *node, out reflect.Value) (good bool) {
+func (d *decoder) scalar(n *node, out reflect.Value) bool {
 	var tag string
 	var tag string
 	var resolved interface{}
 	var resolved interface{}
 	if n.tag == "" && !n.implicit {
 	if n.tag == "" && !n.implicit {
@@ -352,9 +390,26 @@ func (d *decoder) scalar(n *node, out reflect.Value) (good bool) {
 		}
 		}
 		return true
 		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 resolvedv := reflect.ValueOf(resolved); out.Type() == resolvedv.Type() {
+		// We've resolved to exactly the type we want, so use that.
+		out.Set(resolvedv)
+		return true
+	}
+	// Perhaps we can use the value as a TextUnmarshaler to
+	// set its value.
+	if out.CanAddr() {
+		u, ok := out.Addr().Interface().(encoding.TextUnmarshaler)
+		if ok {
+			var text []byte
+			if tag == yaml_BINARY_TAG {
+				text = []byte(resolved.(string))
+			} else {
+				// We let any value be unmarshaled into TextUnmarshaler.
+				// That might be more lax than we'd like, but the
+				// TextUnmarshaler itself should bowl out any dubious values.
+				text = []byte(n.value)
+			}
+			err := u.UnmarshalText(text)
 			if err != nil {
 			if err != nil {
 				fail(err)
 				fail(err)
 			}
 			}
@@ -365,46 +420,54 @@ func (d *decoder) scalar(n *node, out reflect.Value) (good bool) {
 	case reflect.String:
 	case reflect.String:
 		if tag == yaml_BINARY_TAG {
 		if tag == yaml_BINARY_TAG {
 			out.SetString(resolved.(string))
 			out.SetString(resolved.(string))
-			good = true
-		} else if resolved != nil {
+			return true
+		}
+		if resolved != nil {
 			out.SetString(n.value)
 			out.SetString(n.value)
-			good = true
+			return true
 		}
 		}
 	case reflect.Interface:
 	case reflect.Interface:
 		if resolved == nil {
 		if resolved == nil {
 			out.Set(reflect.Zero(out.Type()))
 			out.Set(reflect.Zero(out.Type()))
+		} else if tag == yaml_TIMESTAMP_TAG {
+			// It looks like a timestamp but for backward compatibility
+			// reasons we set it as a string, so that code that unmarshals
+			// timestamp-like values into interface{} will continue to
+			// see a string and not a time.Time.
+			// TODO(v3) Drop this.
+			out.Set(reflect.ValueOf(n.value))
 		} else {
 		} else {
 			out.Set(reflect.ValueOf(resolved))
 			out.Set(reflect.ValueOf(resolved))
 		}
 		}
-		good = true
+		return true
 	case reflect.Int, reflect.Int8, reflect.Int16, reflect.Int32, reflect.Int64:
 	case reflect.Int, reflect.Int8, reflect.Int16, reflect.Int32, reflect.Int64:
 		switch resolved := resolved.(type) {
 		switch resolved := resolved.(type) {
 		case int:
 		case int:
 			if !out.OverflowInt(int64(resolved)) {
 			if !out.OverflowInt(int64(resolved)) {
 				out.SetInt(int64(resolved))
 				out.SetInt(int64(resolved))
-				good = true
+				return true
 			}
 			}
 		case int64:
 		case int64:
 			if !out.OverflowInt(resolved) {
 			if !out.OverflowInt(resolved) {
 				out.SetInt(resolved)
 				out.SetInt(resolved)
-				good = true
+				return true
 			}
 			}
 		case uint64:
 		case uint64:
 			if resolved <= math.MaxInt64 && !out.OverflowInt(int64(resolved)) {
 			if resolved <= math.MaxInt64 && !out.OverflowInt(int64(resolved)) {
 				out.SetInt(int64(resolved))
 				out.SetInt(int64(resolved))
-				good = true
+				return true
 			}
 			}
 		case float64:
 		case float64:
 			if resolved <= math.MaxInt64 && !out.OverflowInt(int64(resolved)) {
 			if resolved <= math.MaxInt64 && !out.OverflowInt(int64(resolved)) {
 				out.SetInt(int64(resolved))
 				out.SetInt(int64(resolved))
-				good = true
+				return true
 			}
 			}
 		case string:
 		case string:
 			if out.Type() == durationType {
 			if out.Type() == durationType {
 				d, err := time.ParseDuration(resolved)
 				d, err := time.ParseDuration(resolved)
 				if err == nil {
 				if err == nil {
 					out.SetInt(int64(d))
 					out.SetInt(int64(d))
-					good = true
+					return true
 				}
 				}
 			}
 			}
 		}
 		}
@@ -413,44 +476,49 @@ func (d *decoder) scalar(n *node, out reflect.Value) (good bool) {
 		case int:
 		case int:
 			if resolved >= 0 && !out.OverflowUint(uint64(resolved)) {
 			if resolved >= 0 && !out.OverflowUint(uint64(resolved)) {
 				out.SetUint(uint64(resolved))
 				out.SetUint(uint64(resolved))
-				good = true
+				return true
 			}
 			}
 		case int64:
 		case int64:
 			if resolved >= 0 && !out.OverflowUint(uint64(resolved)) {
 			if resolved >= 0 && !out.OverflowUint(uint64(resolved)) {
 				out.SetUint(uint64(resolved))
 				out.SetUint(uint64(resolved))
-				good = true
+				return true
 			}
 			}
 		case uint64:
 		case uint64:
 			if !out.OverflowUint(uint64(resolved)) {
 			if !out.OverflowUint(uint64(resolved)) {
 				out.SetUint(uint64(resolved))
 				out.SetUint(uint64(resolved))
-				good = true
+				return true
 			}
 			}
 		case float64:
 		case float64:
 			if resolved <= math.MaxUint64 && !out.OverflowUint(uint64(resolved)) {
 			if resolved <= math.MaxUint64 && !out.OverflowUint(uint64(resolved)) {
 				out.SetUint(uint64(resolved))
 				out.SetUint(uint64(resolved))
-				good = true
+				return true
 			}
 			}
 		}
 		}
 	case reflect.Bool:
 	case reflect.Bool:
 		switch resolved := resolved.(type) {
 		switch resolved := resolved.(type) {
 		case bool:
 		case bool:
 			out.SetBool(resolved)
 			out.SetBool(resolved)
-			good = true
+			return true
 		}
 		}
 	case reflect.Float32, reflect.Float64:
 	case reflect.Float32, reflect.Float64:
 		switch resolved := resolved.(type) {
 		switch resolved := resolved.(type) {
 		case int:
 		case int:
 			out.SetFloat(float64(resolved))
 			out.SetFloat(float64(resolved))
-			good = true
+			return true
 		case int64:
 		case int64:
 			out.SetFloat(float64(resolved))
 			out.SetFloat(float64(resolved))
-			good = true
+			return true
 		case uint64:
 		case uint64:
 			out.SetFloat(float64(resolved))
 			out.SetFloat(float64(resolved))
-			good = true
+			return true
 		case float64:
 		case float64:
 			out.SetFloat(resolved)
 			out.SetFloat(resolved)
-			good = true
+			return true
+		}
+	case reflect.Struct:
+		if resolvedv := reflect.ValueOf(resolved); out.Type() == resolvedv.Type() {
+			out.Set(resolvedv)
+			return true
 		}
 		}
 	case reflect.Ptr:
 	case reflect.Ptr:
 		if out.Type().Elem() == reflect.TypeOf(resolved) {
 		if out.Type().Elem() == reflect.TypeOf(resolved) {
@@ -458,13 +526,11 @@ func (d *decoder) scalar(n *node, out reflect.Value) (good bool) {
 			elem := reflect.New(out.Type().Elem())
 			elem := reflect.New(out.Type().Elem())
 			elem.Elem().Set(reflect.ValueOf(resolved))
 			elem.Elem().Set(reflect.ValueOf(resolved))
 			out.Set(elem)
 			out.Set(elem)
-			good = true
+			return true
 		}
 		}
 	}
 	}
-	if !good {
-		d.terror(n, tag, out)
-	}
-	return good
+	d.terror(n, tag, out)
+	return false
 }
 }
 
 
 func settableValueOf(i interface{}) reflect.Value {
 func settableValueOf(i interface{}) reflect.Value {
@@ -481,6 +547,10 @@ func (d *decoder) sequence(n *node, out reflect.Value) (good bool) {
 	switch out.Kind() {
 	switch out.Kind() {
 	case reflect.Slice:
 	case reflect.Slice:
 		out.Set(reflect.MakeSlice(out.Type(), l, l))
 		out.Set(reflect.MakeSlice(out.Type(), l, l))
+	case reflect.Array:
+		if l != out.Len() {
+			failf("invalid array: want %d elements but got %d", out.Len(), l)
+		}
 	case reflect.Interface:
 	case reflect.Interface:
 		// No type hints. Will have to use a generic sequence.
 		// No type hints. Will have to use a generic sequence.
 		iface = out
 		iface = out
@@ -499,7 +569,9 @@ func (d *decoder) sequence(n *node, out reflect.Value) (good bool) {
 			j++
 			j++
 		}
 		}
 	}
 	}
-	out.Set(out.Slice(0, j))
+	if out.Kind() != reflect.Array {
+		out.Set(out.Slice(0, j))
+	}
 	if iface.IsValid() {
 	if iface.IsValid() {
 		iface.Set(out)
 		iface.Set(out)
 	}
 	}
@@ -560,7 +632,7 @@ func (d *decoder) mapping(n *node, out reflect.Value) (good bool) {
 			}
 			}
 			e := reflect.New(et).Elem()
 			e := reflect.New(et).Elem()
 			if d.unmarshal(n.children[i+1], e) {
 			if d.unmarshal(n.children[i+1], e) {
-				out.SetMapIndex(k, e)
+				d.setMapIndex(n.children[i+1], out, k, e)
 			}
 			}
 		}
 		}
 	}
 	}
@@ -568,6 +640,14 @@ func (d *decoder) mapping(n *node, out reflect.Value) (good bool) {
 	return true
 	return true
 }
 }
 
 
+func (d *decoder) setMapIndex(n *node, out, k, v reflect.Value) {
+	if d.strict && out.MapIndex(k) != zeroValue {
+		d.terrors = append(d.terrors, fmt.Sprintf("line %d: key %#v already set in map", n.line+1, k.Interface()))
+		return
+	}
+	out.SetMapIndex(k, v)
+}
+
 func (d *decoder) mappingSlice(n *node, out reflect.Value) (good bool) {
 func (d *decoder) mappingSlice(n *node, out reflect.Value) (good bool) {
 	outt := out.Type()
 	outt := out.Type()
 	if outt.Elem() != mapItemType {
 	if outt.Elem() != mapItemType {
@@ -615,6 +695,10 @@ func (d *decoder) mappingStruct(n *node, out reflect.Value) (good bool) {
 		elemType = inlineMap.Type().Elem()
 		elemType = inlineMap.Type().Elem()
 	}
 	}
 
 
+	var doneFields []bool
+	if d.strict {
+		doneFields = make([]bool, len(sinfo.FieldsList))
+	}
 	for i := 0; i < l; i += 2 {
 	for i := 0; i < l; i += 2 {
 		ni := n.children[i]
 		ni := n.children[i]
 		if isMerge(ni) {
 		if isMerge(ni) {
@@ -625,6 +709,13 @@ func (d *decoder) mappingStruct(n *node, out reflect.Value) (good bool) {
 			continue
 			continue
 		}
 		}
 		if info, ok := sinfo.FieldsMap[name.String()]; ok {
 		if info, ok := sinfo.FieldsMap[name.String()]; ok {
+			if d.strict {
+				if doneFields[info.Id] {
+					d.terrors = append(d.terrors, fmt.Sprintf("line %d: field %s already set in type %s", ni.line+1, name.String(), out.Type()))
+					continue
+				}
+				doneFields[info.Id] = true
+			}
 			var field reflect.Value
 			var field reflect.Value
 			if info.Inline == nil {
 			if info.Inline == nil {
 				field = out.Field(info.Num)
 				field = out.Field(info.Num)
@@ -638,7 +729,9 @@ func (d *decoder) mappingStruct(n *node, out reflect.Value) (good bool) {
 			}
 			}
 			value := reflect.New(elemType).Elem()
 			value := reflect.New(elemType).Elem()
 			d.unmarshal(n.children[i+1], value)
 			d.unmarshal(n.children[i+1], value)
-			inlineMap.SetMapIndex(name, value)
+			d.setMapIndex(n.children[i+1], inlineMap, name, value)
+		} else if d.strict {
+			d.terrors = append(d.terrors, fmt.Sprintf("line %d: field %s not found in type %s", ni.line+1, name.String(), out.Type()))
 		}
 		}
 	}
 	}
 	return true
 	return true

+ 1334 - 0
cmd/vendor/gopkg.in/yaml.v2/decode_test.go

@@ -0,0 +1,1334 @@
+package yaml_test
+
+import (
+	"errors"
+	"io"
+	"math"
+	"reflect"
+	"strings"
+	"time"
+
+	. "gopkg.in/check.v1"
+	"gopkg.in/yaml.v2"
+)
+
+var unmarshalIntTest = 123
+
+var unmarshalTests = []struct {
+	data  string
+	value interface{}
+}{
+	{
+		"",
+		(*struct{})(nil),
+	},
+	{
+		"{}", &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},
+	}, {
+		"bin: -0b1000000000000000000000000000000000000000000000000000000000000000",
+		map[string]interface{}{"bin": -9223372036854775808},
+	}, {
+		"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, 2]",
+		&struct{ A [2]int }{[2]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: !!float 0",
+		map[string]interface{}{"v": float64(0)},
+	}, {
+		"v: !!float -1",
+		map[string]interface{}{"v": float64(-1)},
+	}, {
+		"v: !!null ''",
+		map[string]interface{}{"v": nil},
+	}, {
+		"%TAG !y! tag:yaml.org,2002:\n---\nv: !y!int '1'",
+		map[string]interface{}{"v": 1},
+	},
+
+	// Non-specific tag (Issue #75)
+	{
+		"v: ! test",
+		map[string]interface{}{"v": "test"},
+	},
+
+	// 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}},
+	},
+
+	// Bug #1133337
+	{
+		"foo: ''",
+		map[string]*string{"foo": new(string)},
+	}, {
+		"foo: null",
+		map[string]*string{"foo": nil},
+	}, {
+		"foo: null",
+		map[string]string{"foo": ""},
+	}, {
+		"foo: null",
+		map[string]interface{}{"foo": nil},
+	},
+
+	// Support for ~
+	{
+		"foo: ~",
+		map[string]*string{"foo": nil},
+	}, {
+		"foo: ~",
+		map[string]string{"foo": ""},
+	}, {
+		"foo: ~",
+		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"},
+	},
+
+	// issue #295 (allow scalars with colons in flow mappings and sequences)
+	{
+		"a: {b: https://github.com/go-yaml/yaml}",
+		map[string]interface{}{"a": map[interface{}]interface{}{
+			"b": "https://github.com/go-yaml/yaml",
+		}},
+	},
+	{
+		"a: [https://github.com/go-yaml/yaml]",
+		map[string]interface{}{"a": []interface{}{"https://github.com/go-yaml/yaml"}},
+	},
+
+	// Duration
+	{
+		"a: 3s",
+		map[string]time.Duration{"a": 3 * time.Second},
+	},
+
+	// Issue #24.
+	{
+		"a: <foo>",
+		map[string]string{"a": "<foo>"},
+	},
+
+	// 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]textUnmarshaler{"a": textUnmarshaler{S: "1.2.3.4"}},
+	},
+	{
+		"a: 2015-02-24T18:19:39Z\n",
+		map[string]textUnmarshaler{"a": textUnmarshaler{"2015-02-24T18:19:39Z"}},
+	},
+
+	// Timestamps
+	{
+		// Date only.
+		"a: 2015-01-01\n",
+		map[string]time.Time{"a": time.Date(2015, 1, 1, 0, 0, 0, 0, time.UTC)},
+	},
+	{
+		// RFC3339
+		"a: 2015-02-24T18:19:39.12Z\n",
+		map[string]time.Time{"a": time.Date(2015, 2, 24, 18, 19, 39, .12e9, time.UTC)},
+	},
+	{
+		// RFC3339 with short dates.
+		"a: 2015-2-3T3:4:5Z",
+		map[string]time.Time{"a": time.Date(2015, 2, 3, 3, 4, 5, 0, time.UTC)},
+	},
+	{
+		// ISO8601 lower case t
+		"a: 2015-02-24t18:19:39Z\n",
+		map[string]time.Time{"a": time.Date(2015, 2, 24, 18, 19, 39, 0, time.UTC)},
+	},
+	{
+		// space separate, no time zone
+		"a: 2015-02-24 18:19:39\n",
+		map[string]time.Time{"a": time.Date(2015, 2, 24, 18, 19, 39, 0, time.UTC)},
+	},
+	// Some cases not currently handled. Uncomment these when
+	// the code is fixed.
+	//	{
+	//		// space separated with time zone
+	//		"a: 2001-12-14 21:59:43.10 -5",
+	//		map[string]interface{}{"a": time.Date(2001, 12, 14, 21, 59, 43, .1e9, time.UTC)},
+	//	},
+	//	{
+	//		// arbitrary whitespace between fields
+	//		"a: 2001-12-14 \t\t \t21:59:43.10 \t Z",
+	//		map[string]interface{}{"a": time.Date(2001, 12, 14, 21, 59, 43, .1e9, time.UTC)},
+	//	},
+	{
+		// explicit string tag
+		"a: !!str 2015-01-01",
+		map[string]interface{}{"a": "2015-01-01"},
+	},
+	{
+		// explicit timestamp tag on quoted string
+		"a: !!timestamp \"2015-01-01\"",
+		map[string]time.Time{"a": time.Date(2015, 1, 1, 0, 0, 0, 0, time.UTC)},
+	},
+	{
+		// explicit timestamp tag on unquoted string
+		"a: !!timestamp 2015-01-01",
+		map[string]time.Time{"a": time.Date(2015, 1, 1, 0, 0, 0, 0, time.UTC)},
+	},
+	{
+		// quoted string that's a valid timestamp
+		"a: \"2015-01-01\"",
+		map[string]interface{}{"a": "2015-01-01"},
+	},
+	{
+		// explicit timestamp tag into interface.
+		"a: !!timestamp \"2015-01-01\"",
+		map[string]interface{}{"a": "2015-01-01"},
+	},
+	{
+		// implicit timestamp tag into interface.
+		"a: 2015-01-01",
+		map[string]interface{}{"a": "2015-01-01"},
+	},
+
+	// Encode empty lists as zero-length slices.
+	{
+		"a: []",
+		&struct{ A []int }{[]int{}},
+	},
+
+	// UTF-16-LE
+	{
+		"\xff\xfe\xf1\x00o\x00\xf1\x00o\x00:\x00 \x00v\x00e\x00r\x00y\x00 \x00y\x00e\x00s\x00\n\x00",
+		M{"ñoño": "very yes"},
+	},
+	// UTF-16-LE with surrogate.
+	{
+		"\xff\xfe\xf1\x00o\x00\xf1\x00o\x00:\x00 \x00v\x00e\x00r\x00y\x00 \x00y\x00e\x00s\x00 \x00=\xd8\xd4\xdf\n\x00",
+		M{"ñoño": "very yes 🟔"},
+	},
+
+	// UTF-16-BE
+	{
+		"\xfe\xff\x00\xf1\x00o\x00\xf1\x00o\x00:\x00 \x00v\x00e\x00r\x00y\x00 \x00y\x00e\x00s\x00\n",
+		M{"ñoño": "very yes"},
+	},
+	// UTF-16-BE with surrogate.
+	{
+		"\xfe\xff\x00\xf1\x00o\x00\xf1\x00o\x00:\x00 \x00v\x00e\x00r\x00y\x00 \x00y\x00e\x00s\x00 \xd8=\xdf\xd4\x00\n",
+		M{"ñoño": "very yes 🟔"},
+	},
+
+	// YAML Float regex shouldn't match this
+	{
+		"a: 123456e1\n",
+		M{"a": "123456e1"},
+	}, {
+		"a: 123456E1\n",
+		M{"a": "123456E1"},
+	},
+	// yaml-test-suite 3GZX: Spec Example 7.1. Alias Nodes
+	{
+		"First occurrence: &anchor Foo\nSecond occurrence: *anchor\nOverride anchor: &anchor Bar\nReuse anchor: *anchor\n",
+		map[interface{}]interface{}{
+			"Reuse anchor":      "Bar",
+			"First occurrence":  "Foo",
+			"Second occurrence": "Foo",
+			"Override anchor":   "Bar",
+		},
+	},
+	// Single document with garbage following it.
+	{
+		"---\nhello\n...\n}not yaml",
+		"hello",
+	},
+	{
+		"a: 5\n",
+		&struct{ A jsonNumberT }{"5"},
+	},
+	{
+		"a: 5.5\n",
+		&struct{ A jsonNumberT }{"5.5"},
+	},
+}
+
+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 i, item := range unmarshalTests {
+		c.Logf("test %d: %q", i, item.data)
+		t := reflect.ValueOf(item.value).Type()
+		value := reflect.New(t)
+		err := yaml.Unmarshal([]byte(item.data), value.Interface())
+		if _, ok := err.(*yaml.TypeError); !ok {
+			c.Assert(err, IsNil)
+		}
+		c.Assert(value.Elem().Interface(), DeepEquals, item.value, Commentf("error: %v", err))
+	}
+}
+
+// TODO(v3): This test should also work when unmarshaling onto an interface{}.
+func (s *S) TestUnmarshalFullTimestamp(c *C) {
+	// Full timestamp in same format as encoded. This is confirmed to be
+	// properly decoded by Python as a timestamp as well.
+	var str = "2015-02-24T18:19:39.123456789-03:00"
+	var t time.Time
+	err := yaml.Unmarshal([]byte(str), &t)
+	c.Assert(err, IsNil)
+	c.Assert(t, Equals, time.Date(2015, 2, 24, 18, 19, 39, 123456789, t.Location()))
+	c.Assert(t.In(time.UTC), Equals, time.Date(2015, 2, 24, 21, 19, 39, 123456789, time.UTC))
+}
+
+func (s *S) TestDecoderSingleDocument(c *C) {
+	// Test that Decoder.Decode works as expected on
+	// all the unmarshal tests.
+	for i, item := range unmarshalTests {
+		c.Logf("test %d: %q", i, item.data)
+		if item.data == "" {
+			// Behaviour differs when there's no YAML.
+			continue
+		}
+		t := reflect.ValueOf(item.value).Type()
+		value := reflect.New(t)
+		err := yaml.NewDecoder(strings.NewReader(item.data)).Decode(value.Interface())
+		if _, ok := err.(*yaml.TypeError); !ok {
+			c.Assert(err, IsNil)
+		}
+		c.Assert(value.Elem().Interface(), DeepEquals, item.value)
+	}
+}
+
+var decoderTests = []struct {
+	data   string
+	values []interface{}
+}{{
+	"",
+	nil,
+}, {
+	"a: b",
+	[]interface{}{
+		map[interface{}]interface{}{"a": "b"},
+	},
+}, {
+	"---\na: b\n...\n",
+	[]interface{}{
+		map[interface{}]interface{}{"a": "b"},
+	},
+}, {
+	"---\n'hello'\n...\n---\ngoodbye\n...\n",
+	[]interface{}{
+		"hello",
+		"goodbye",
+	},
+}}
+
+func (s *S) TestDecoder(c *C) {
+	for i, item := range decoderTests {
+		c.Logf("test %d: %q", i, item.data)
+		var values []interface{}
+		dec := yaml.NewDecoder(strings.NewReader(item.data))
+		for {
+			var value interface{}
+			err := dec.Decode(&value)
+			if err == io.EOF {
+				break
+			}
+			c.Assert(err, IsNil)
+			values = append(values, value)
+		}
+		c.Assert(values, DeepEquals, item.values)
+	}
+}
+
+type errReader struct{}
+
+func (errReader) Read([]byte) (int, error) {
+	return 0, errors.New("some read error")
+}
+
+func (s *S) TestDecoderReadError(c *C) {
+	err := yaml.NewDecoder(errReader{}).Decode(&struct{}{})
+	c.Assert(err, ErrorMatches, `yaml: input error: some read error`)
+}
+
+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:\n- b: *,", "yaml: line 2: did not find expected alphabetic or numeric character"},
+	{"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\)\}`},
+	{"b: *a\na: &a {c: 1}", `yaml: unknown anchor 'a' referenced`},
+	{"%TAG !%79! tag:yaml.org,2002:\n---\nv: !%79!int '1'", "yaml: did not find expected whitespace"},
+}
+
+func (s *S) TestUnmarshalErrors(c *C) {
+	for i, item := range unmarshalErrorTests {
+		c.Logf("test %d: %q", i, item.data)
+		var value interface{}
+		err := yaml.Unmarshal([]byte(item.data), &value)
+		c.Assert(err, ErrorMatches, item.error, Commentf("Partial unmarshal: %#v", value))
+	}
+}
+
+func (s *S) TestDecoderErrors(c *C) {
+	for _, item := range unmarshalErrorTests {
+		var value interface{}
+		err := yaml.NewDecoder(strings.NewReader(item.data)).Decode(&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!"},
+	{`_: ""`, "!!str", ""},
+}
+
+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
+  !<tag:yaml.org,2002:merge> "<<" : [ *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 unmarshalStrictTests = []struct {
+	data  string
+	value interface{}
+	error string
+}{{
+	data:  "a: 1\nc: 2\n",
+	value: struct{ A, B int }{A: 1},
+	error: `yaml: unmarshal errors:\n  line 2: field c not found in type struct { A int; B int }`,
+}, {
+	data:  "a: 1\nb: 2\na: 3\n",
+	value: struct{ A, B int }{A: 3, B: 2},
+	error: `yaml: unmarshal errors:\n  line 3: field a already set in type struct { A int; B int }`,
+}, {
+	data: "c: 3\na: 1\nb: 2\nc: 4\n",
+	value: struct {
+		A       int
+		inlineB `yaml:",inline"`
+	}{
+		A: 1,
+		inlineB: inlineB{
+			B: 2,
+			inlineC: inlineC{
+				C: 4,
+			},
+		},
+	},
+	error: `yaml: unmarshal errors:\n  line 4: field c already set in type struct { A int; yaml_test.inlineB "yaml:\\",inline\\"" }`,
+}, {
+	data: "c: 0\na: 1\nb: 2\nc: 1\n",
+	value: struct {
+		A       int
+		inlineB `yaml:",inline"`
+	}{
+		A: 1,
+		inlineB: inlineB{
+			B: 2,
+			inlineC: inlineC{
+				C: 1,
+			},
+		},
+	},
+	error: `yaml: unmarshal errors:\n  line 4: field c already set in type struct { A int; yaml_test.inlineB "yaml:\\",inline\\"" }`,
+}, {
+	data: "c: 1\na: 1\nb: 2\nc: 3\n",
+	value: struct {
+		A int
+		M map[string]interface{} `yaml:",inline"`
+	}{
+		A: 1,
+		M: map[string]interface{}{
+			"b": 2,
+			"c": 3,
+		},
+	},
+	error: `yaml: unmarshal errors:\n  line 4: key "c" already set in map`,
+}, {
+	data: "a: 1\n9: 2\nnull: 3\n9: 4",
+	value: map[interface{}]interface{}{
+		"a": 1,
+		nil: 3,
+		9:   4,
+	},
+	error: `yaml: unmarshal errors:\n  line 4: key 9 already set in map`,
+}}
+
+func (s *S) TestUnmarshalStrict(c *C) {
+	for i, item := range unmarshalStrictTests {
+		c.Logf("test %d: %q", i, item.data)
+		// First test that normal Unmarshal unmarshals to the expected value.
+		t := reflect.ValueOf(item.value).Type()
+		value := reflect.New(t)
+		err := yaml.Unmarshal([]byte(item.data), value.Interface())
+		c.Assert(err, Equals, nil)
+		c.Assert(value.Elem().Interface(), DeepEquals, item.value)
+
+		// Then test that UnmarshalStrict fails on the same thing.
+		t = reflect.ValueOf(item.value).Type()
+		value = reflect.New(t)
+		err = yaml.UnmarshalStrict([]byte(item.data), value.Interface())
+		c.Assert(err, ErrorMatches, item.error)
+	}
+}
+
+type textUnmarshaler struct {
+	S string
+}
+
+func (t *textUnmarshaler) UnmarshalText(s []byte) error {
+	t.S = string(s)
+	return nil
+}
+
+func (s *S) TestFuzzCrashers(c *C) {
+	cases := []string{
+		// runtime error: index out of range
+		"\"\\0\\\r\n",
+
+		// should not happen
+		"  0: [\n] 0",
+		"? ? \"\n\" 0",
+		"    - {\n000}0",
+		"0:\n  0: [0\n] 0",
+		"    - \"\n000\"0",
+		"    - \"\n000\"\"",
+		"0:\n    - {\n000}0",
+		"0:\n    - \"\n000\"0",
+		"0:\n    - \"\n000\"\"",
+
+		// runtime error: index out of range
+		" \ufeff\n",
+		"? \ufeff\n",
+		"? \ufeff:\n",
+		"0: \ufeff\n",
+		"? \ufeff: \ufeff\n",
+	}
+	for _, data := range cases {
+		var v interface{}
+		_ = yaml.Unmarshal([]byte(data), &v)
+	}
+}
+
+//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)
+//	}
+//}

+ 10 - 9
cmd/vendor/gopkg.in/yaml.v2/emitterc.go

@@ -2,6 +2,7 @@ package yaml
 
 
 import (
 import (
 	"bytes"
 	"bytes"
+	"fmt"
 )
 )
 
 
 // Flush the buffer if needed.
 // Flush the buffer if needed.
@@ -664,7 +665,7 @@ func yaml_emitter_emit_node(emitter *yaml_emitter_t, event *yaml_event_t,
 		return yaml_emitter_emit_mapping_start(emitter, event)
 		return yaml_emitter_emit_mapping_start(emitter, event)
 	default:
 	default:
 		return yaml_emitter_set_emitter_error(emitter,
 		return yaml_emitter_set_emitter_error(emitter,
-			"expected SCALAR, SEQUENCE-START, MAPPING-START, or ALIAS")
+			fmt.Sprintf("expected SCALAR, SEQUENCE-START, MAPPING-START, or ALIAS, but got %v", event.typ))
 	}
 	}
 }
 }
 
 
@@ -842,7 +843,7 @@ func yaml_emitter_select_scalar_style(emitter *yaml_emitter_t, event *yaml_event
 	return true
 	return true
 }
 }
 
 
-// Write an achor.
+// Write an anchor.
 func yaml_emitter_process_anchor(emitter *yaml_emitter_t) bool {
 func yaml_emitter_process_anchor(emitter *yaml_emitter_t) bool {
 	if emitter.anchor_data.anchor == nil {
 	if emitter.anchor_data.anchor == nil {
 		return true
 		return true
@@ -994,10 +995,10 @@ func yaml_emitter_analyze_scalar(emitter *yaml_emitter_t, value []byte) bool {
 		break_space    = false
 		break_space    = false
 		space_break    = false
 		space_break    = false
 
 
-		preceeded_by_whitespace = false
-		followed_by_whitespace  = false
-		previous_space          = false
-		previous_break          = false
+		preceded_by_whitespace = false
+		followed_by_whitespace = false
+		previous_space         = false
+		previous_break         = false
 	)
 	)
 
 
 	emitter.scalar_data.value = value
 	emitter.scalar_data.value = value
@@ -1016,7 +1017,7 @@ func yaml_emitter_analyze_scalar(emitter *yaml_emitter_t, value []byte) bool {
 		flow_indicators = true
 		flow_indicators = true
 	}
 	}
 
 
-	preceeded_by_whitespace = true
+	preceded_by_whitespace = true
 	for i, w := 0, 0; i < len(value); i += w {
 	for i, w := 0, 0; i < len(value); i += w {
 		w = width(value[i])
 		w = width(value[i])
 		followed_by_whitespace = i+w >= len(value) || is_blank(value, i+w)
 		followed_by_whitespace = i+w >= len(value) || is_blank(value, i+w)
@@ -1047,7 +1048,7 @@ func yaml_emitter_analyze_scalar(emitter *yaml_emitter_t, value []byte) bool {
 					block_indicators = true
 					block_indicators = true
 				}
 				}
 			case '#':
 			case '#':
-				if preceeded_by_whitespace {
+				if preceded_by_whitespace {
 					flow_indicators = true
 					flow_indicators = true
 					block_indicators = true
 					block_indicators = true
 				}
 				}
@@ -1088,7 +1089,7 @@ func yaml_emitter_analyze_scalar(emitter *yaml_emitter_t, value []byte) bool {
 		}
 		}
 
 
 		// [Go]: Why 'z'? Couldn't be the end of the string as that's the loop condition.
 		// [Go]: Why 'z'? Couldn't be the end of the string as that's the loop condition.
-		preceeded_by_whitespace = is_blankz(value, i)
+		preceded_by_whitespace = is_blankz(value, i)
 	}
 	}
 
 
 	emitter.scalar_data.multiline = line_breaks
 	emitter.scalar_data.multiline = line_breaks

+ 124 - 40
cmd/vendor/gopkg.in/yaml.v2/encode.go

@@ -3,38 +3,67 @@ package yaml
 import (
 import (
 	"encoding"
 	"encoding"
 	"fmt"
 	"fmt"
+	"io"
 	"reflect"
 	"reflect"
 	"regexp"
 	"regexp"
 	"sort"
 	"sort"
 	"strconv"
 	"strconv"
 	"strings"
 	"strings"
 	"time"
 	"time"
+	"unicode/utf8"
 )
 )
 
 
+// jsonNumber is the interface of the encoding/json.Number datatype.
+// Repeating the interface here avoids a dependency on encoding/json, and also
+// supports other libraries like jsoniter, which use a similar datatype with
+// the same interface. Detecting this interface is useful when dealing with
+// structures containing json.Number, which is a string under the hood. The
+// encoder should prefer the use of Int64(), Float64() and string(), in that
+// order, when encoding this type.
+type jsonNumber interface {
+	Float64() (float64, error)
+	Int64() (int64, error)
+	String() string
+}
+
 type encoder struct {
 type encoder struct {
 	emitter yaml_emitter_t
 	emitter yaml_emitter_t
 	event   yaml_event_t
 	event   yaml_event_t
 	out     []byte
 	out     []byte
 	flow    bool
 	flow    bool
+	// doneInit holds whether the initial stream_start_event has been
+	// emitted.
+	doneInit bool
 }
 }
 
 
-func newEncoder() (e *encoder) {
-	e = &encoder{}
-	e.must(yaml_emitter_initialize(&e.emitter))
+func newEncoder() *encoder {
+	e := &encoder{}
+	yaml_emitter_initialize(&e.emitter)
 	yaml_emitter_set_output_string(&e.emitter, &e.out)
 	yaml_emitter_set_output_string(&e.emitter, &e.out)
 	yaml_emitter_set_unicode(&e.emitter, true)
 	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
 	return e
 }
 }
 
 
-func (e *encoder) finish() {
-	e.must(yaml_document_end_event_initialize(&e.event, true))
+func newEncoderWithWriter(w io.Writer) *encoder {
+	e := &encoder{}
+	yaml_emitter_initialize(&e.emitter)
+	yaml_emitter_set_output_writer(&e.emitter, w)
+	yaml_emitter_set_unicode(&e.emitter, true)
+	return e
+}
+
+func (e *encoder) init() {
+	if e.doneInit {
+		return
+	}
+	yaml_stream_start_event_initialize(&e.event, yaml_UTF8_ENCODING)
 	e.emit()
 	e.emit()
+	e.doneInit = true
+}
+
+func (e *encoder) finish() {
 	e.emitter.open_ended = false
 	e.emitter.open_ended = false
-	e.must(yaml_stream_end_event_initialize(&e.event))
+	yaml_stream_end_event_initialize(&e.event)
 	e.emit()
 	e.emit()
 }
 }
 
 
@@ -44,9 +73,7 @@ func (e *encoder) destroy() {
 
 
 func (e *encoder) emit() {
 func (e *encoder) emit() {
 	// This will internally delete the e.event value.
 	// 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)
-	}
+	e.must(yaml_emitter_emit(&e.emitter, &e.event))
 }
 }
 
 
 func (e *encoder) must(ok bool) {
 func (e *encoder) must(ok bool) {
@@ -59,13 +86,43 @@ func (e *encoder) must(ok bool) {
 	}
 	}
 }
 }
 
 
+func (e *encoder) marshalDoc(tag string, in reflect.Value) {
+	e.init()
+	yaml_document_start_event_initialize(&e.event, nil, nil, true)
+	e.emit()
+	e.marshal(tag, in)
+	yaml_document_end_event_initialize(&e.event, true)
+	e.emit()
+}
+
 func (e *encoder) marshal(tag string, in reflect.Value) {
 func (e *encoder) marshal(tag string, in reflect.Value) {
-	if !in.IsValid() {
+	if !in.IsValid() || in.Kind() == reflect.Ptr && in.IsNil() {
 		e.nilv()
 		e.nilv()
 		return
 		return
 	}
 	}
 	iface := in.Interface()
 	iface := in.Interface()
-	if m, ok := iface.(Marshaler); ok {
+	switch m := iface.(type) {
+	case jsonNumber:
+		integer, err := m.Int64()
+		if err == nil {
+			// In this case the json.Number is a valid int64
+			in = reflect.ValueOf(integer)
+			break
+		}
+		float, err := m.Float64()
+		if err == nil {
+			// In this case the json.Number is a valid float64
+			in = reflect.ValueOf(float)
+			break
+		}
+		// fallback case - no number could be obtained
+		in = reflect.ValueOf(m.String())
+	case time.Time, *time.Time:
+		// Although time.Time implements TextMarshaler,
+		// we don't want to treat it as a string for YAML
+		// purposes because YAML has special support for
+		// timestamps.
+	case Marshaler:
 		v, err := m.MarshalYAML()
 		v, err := m.MarshalYAML()
 		if err != nil {
 		if err != nil {
 			fail(err)
 			fail(err)
@@ -75,31 +132,34 @@ func (e *encoder) marshal(tag string, in reflect.Value) {
 			return
 			return
 		}
 		}
 		in = reflect.ValueOf(v)
 		in = reflect.ValueOf(v)
-	} else if m, ok := iface.(encoding.TextMarshaler); ok {
+	case encoding.TextMarshaler:
 		text, err := m.MarshalText()
 		text, err := m.MarshalText()
 		if err != nil {
 		if err != nil {
 			fail(err)
 			fail(err)
 		}
 		}
 		in = reflect.ValueOf(string(text))
 		in = reflect.ValueOf(string(text))
+	case nil:
+		e.nilv()
+		return
 	}
 	}
 	switch in.Kind() {
 	switch in.Kind() {
 	case reflect.Interface:
 	case reflect.Interface:
-		if in.IsNil() {
-			e.nilv()
-		} else {
-			e.marshal(tag, in.Elem())
-		}
+		e.marshal(tag, in.Elem())
 	case reflect.Map:
 	case reflect.Map:
 		e.mapv(tag, in)
 		e.mapv(tag, in)
 	case reflect.Ptr:
 	case reflect.Ptr:
-		if in.IsNil() {
-			e.nilv()
+		if in.Type() == ptrTimeType {
+			e.timev(tag, in.Elem())
 		} else {
 		} else {
 			e.marshal(tag, in.Elem())
 			e.marshal(tag, in.Elem())
 		}
 		}
 	case reflect.Struct:
 	case reflect.Struct:
-		e.structv(tag, in)
-	case reflect.Slice:
+		if in.Type() == timeType {
+			e.timev(tag, in)
+		} else {
+			e.structv(tag, in)
+		}
+	case reflect.Slice, reflect.Array:
 		if in.Type().Elem() == mapItemType {
 		if in.Type().Elem() == mapItemType {
 			e.itemsv(tag, in)
 			e.itemsv(tag, in)
 		} else {
 		} else {
@@ -191,10 +251,10 @@ func (e *encoder) mappingv(tag string, f func()) {
 		e.flow = false
 		e.flow = false
 		style = yaml_FLOW_MAPPING_STYLE
 		style = yaml_FLOW_MAPPING_STYLE
 	}
 	}
-	e.must(yaml_mapping_start_event_initialize(&e.event, nil, []byte(tag), implicit, style))
+	yaml_mapping_start_event_initialize(&e.event, nil, []byte(tag), implicit, style)
 	e.emit()
 	e.emit()
 	f()
 	f()
-	e.must(yaml_mapping_end_event_initialize(&e.event))
+	yaml_mapping_end_event_initialize(&e.event)
 	e.emit()
 	e.emit()
 }
 }
 
 
@@ -240,23 +300,36 @@ var base60float = regexp.MustCompile(`^[-+]?[0-9][0-9_]*(?::[0-5]?[0-9])+(?:\.[0
 func (e *encoder) stringv(tag string, in reflect.Value) {
 func (e *encoder) stringv(tag string, in reflect.Value) {
 	var style yaml_scalar_style_t
 	var style yaml_scalar_style_t
 	s := in.String()
 	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 {
+	canUsePlain := true
+	switch {
+	case !utf8.ValidString(s):
+		if tag == yaml_BINARY_TAG {
 			failf("explicitly tagged !!binary data must be base64-encoded")
 			failf("explicitly tagged !!binary data must be base64-encoded")
-		} else {
+		}
+		if tag != "" {
 			failf("cannot marshal invalid UTF-8 data as %s", shortTag(tag))
 			failf("cannot marshal invalid UTF-8 data as %s", shortTag(tag))
 		}
 		}
+		// It can't be encoded directly as YAML so use a binary tag
+		// and encode it as base64.
+		tag = yaml_BINARY_TAG
+		s = encodeBase64(s)
+	case tag == "":
+		// Check to see if it would resolve to a specific
+		// tag when encoded unquoted. If it doesn't,
+		// there's no need to quote it.
+		rtag, _ := resolve("", s)
+		canUsePlain = rtag == yaml_STR_TAG && !isBase60Float(s)
 	}
 	}
-	if tag == "" && (rtag != yaml_STR_TAG || isBase60Float(s)) {
-		style = yaml_DOUBLE_QUOTED_SCALAR_STYLE
-	} else if strings.Contains(s, "\n") {
+	// Note: it's possible for user code to emit invalid YAML
+	// if they explicitly specify a tag and a string containing
+	// text that's incompatible with that tag.
+	switch {
+	case strings.Contains(s, "\n"):
 		style = yaml_LITERAL_SCALAR_STYLE
 		style = yaml_LITERAL_SCALAR_STYLE
-	} else {
+	case canUsePlain:
 		style = yaml_PLAIN_SCALAR_STYLE
 		style = yaml_PLAIN_SCALAR_STYLE
+	default:
+		style = yaml_DOUBLE_QUOTED_SCALAR_STYLE
 	}
 	}
 	e.emitScalar(s, "", tag, style)
 	e.emitScalar(s, "", tag, style)
 }
 }
@@ -281,9 +354,20 @@ func (e *encoder) uintv(tag string, in reflect.Value) {
 	e.emitScalar(s, "", tag, yaml_PLAIN_SCALAR_STYLE)
 	e.emitScalar(s, "", tag, yaml_PLAIN_SCALAR_STYLE)
 }
 }
 
 
+func (e *encoder) timev(tag string, in reflect.Value) {
+	t := in.Interface().(time.Time)
+	s := t.Format(time.RFC3339Nano)
+	e.emitScalar(s, "", tag, yaml_PLAIN_SCALAR_STYLE)
+}
+
 func (e *encoder) floatv(tag string, in reflect.Value) {
 func (e *encoder) floatv(tag string, in reflect.Value) {
-	// FIXME: Handle 64 bits here.
-	s := strconv.FormatFloat(float64(in.Float()), 'g', -1, 32)
+	// Issue #352: When formatting, use the precision of the underlying value
+	precision := 64
+	if in.Kind() == reflect.Float32 {
+		precision = 32
+	}
+
+	s := strconv.FormatFloat(in.Float(), 'g', -1, precision)
 	switch s {
 	switch s {
 	case "+Inf":
 	case "+Inf":
 		s = ".inf"
 		s = ".inf"

+ 625 - 0
cmd/vendor/gopkg.in/yaml.v2/encode_test.go

@@ -0,0 +1,625 @@
+package yaml_test
+
+import (
+	"bytes"
+	"fmt"
+	"math"
+	"strconv"
+	"strings"
+	"time"
+
+	"net"
+	"os"
+
+	. "gopkg.in/check.v1"
+	"gopkg.in/yaml.v2"
+)
+
+type jsonNumberT string
+
+func (j jsonNumberT) Int64() (int64, error) {
+	val, err := strconv.Atoi(string(j))
+	if err != nil {
+		return 0, err
+	}
+	return int64(val), nil
+}
+
+func (j jsonNumberT) Float64() (float64, error) {
+	return strconv.ParseFloat(string(j), 64)
+}
+
+func (j jsonNumberT) String() string {
+	return string(j)
+}
+
+var marshalIntTest = 123
+
+var marshalTests = []struct {
+	value interface{}
+	data  string
+}{
+	{
+		nil,
+		"null\n",
+	}, {
+		(*marshalerType)(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": float32(0.99)},
+		"v: 0.99\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{ A [2]int }{[2]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",
+	}, {
+		&struct {
+			A float64 "a,omitempty"
+			B float64 "b,omitempty"
+		}{1, 0},
+		"a: 1\n",
+	},
+	{
+		&struct {
+			T1 time.Time  "t1,omitempty"
+			T2 time.Time  "t2,omitempty"
+			T3 *time.Time "t3,omitempty"
+			T4 *time.Time "t4,omitempty"
+		}{
+			T2: time.Date(2018, 1, 9, 10, 40, 47, 0, time.UTC),
+			T4: newTime(time.Date(2098, 1, 9, 10, 40, 47, 0, time.UTC)),
+		},
+		"t2: 2018-01-09T10:40:47Z\nt4: 2098-01-09T10:40:47Z\n",
+	},
+	// Nil interface that implements Marshaler.
+	{
+		map[string]yaml.Marshaler{
+			"a": nil,
+		},
+		"a: null\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": "<foo>"},
+		"a: <foo>\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",
+	},
+	// time.Time gets a timestamp tag.
+	{
+		map[string]time.Time{"a": time.Date(2015, 2, 24, 18, 19, 39, 0, time.UTC)},
+		"a: 2015-02-24T18:19:39Z\n",
+	},
+	{
+		map[string]*time.Time{"a": newTime(time.Date(2015, 2, 24, 18, 19, 39, 0, time.UTC))},
+		"a: 2015-02-24T18:19:39Z\n",
+	},
+	{
+		// This is confirmed to be properly decoded in Python (libyaml) without a timestamp tag.
+		map[string]time.Time{"a": time.Date(2015, 2, 24, 18, 19, 39, 123456789, time.FixedZone("FOO", -3*60*60))},
+		"a: 2015-02-24T18:19:39.123456789-03:00\n",
+	},
+	// Ensure timestamp-like strings are quoted.
+	{
+		map[string]string{"a": "2015-02-24T18:19:39Z"},
+		"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",
+	},
+
+	// Containing hash mark ('#') in string should be quoted
+	{
+		map[string]string{"a": "Hello #comment"},
+		"a: 'Hello #comment'\n",
+	},
+	{
+		map[string]string{"a": "你好 #comment"},
+		"a: '你好 #comment'\n",
+	},
+	{
+		map[string]interface{}{"a": jsonNumberT("5")},
+		"a: 5\n",
+	},
+	{
+		map[string]interface{}{"a": jsonNumberT("100.5")},
+		"a: 100.5\n",
+	},
+	{
+		map[string]interface{}{"a": jsonNumberT("bogus")},
+		"a: bogus\n",
+	},
+}
+
+func (s *S) TestMarshal(c *C) {
+	defer os.Setenv("TZ", os.Getenv("TZ"))
+	os.Setenv("TZ", "UTC")
+	for i, item := range marshalTests {
+		c.Logf("test %d: %q", i, item.data)
+		data, err := yaml.Marshal(item.value)
+		c.Assert(err, IsNil)
+		c.Assert(string(data), Equals, item.data)
+	}
+}
+
+func (s *S) TestEncoderSingleDocument(c *C) {
+	for i, item := range marshalTests {
+		c.Logf("test %d. %q", i, item.data)
+		var buf bytes.Buffer
+		enc := yaml.NewEncoder(&buf)
+		err := enc.Encode(item.value)
+		c.Assert(err, Equals, nil)
+		err = enc.Close()
+		c.Assert(err, Equals, nil)
+		c.Assert(buf.String(), Equals, item.data)
+	}
+}
+
+func (s *S) TestEncoderMultipleDocuments(c *C) {
+	var buf bytes.Buffer
+	enc := yaml.NewEncoder(&buf)
+	err := enc.Encode(map[string]string{"a": "b"})
+	c.Assert(err, Equals, nil)
+	err = enc.Encode(map[string]string{"c": "d"})
+	c.Assert(err, Equals, nil)
+	err = enc.Close()
+	c.Assert(err, Equals, nil)
+	c.Assert(buf.String(), Equals, "a: b\n---\nc: d\n")
+}
+
+func (s *S) TestEncoderWriteError(c *C) {
+	enc := yaml.NewEncoder(errorWriter{})
+	err := enc.Encode(map[string]string{"a": "b"})
+	c.Assert(err, ErrorMatches, `yaml: write error: some write error`) // Data not flushed yet
+}
+
+type errorWriter struct{}
+
+func (errorWriter) Write([]byte) (int, error) {
+	return 0, fmt.Errorf("some write error")
+}
+
+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/0001",
+		"a/002",
+		"a/3",
+		"a/10",
+		"a/11",
+		"a/0012",
+		"a/100",
+		"a~10",
+		"ab/1",
+		"b/1",
+		"b/01",
+		"b/2",
+		"b/02",
+		"b/3",
+		"b/03",
+		"b1",
+		"b01",
+		"b3",
+		"c2.10",
+		"c10.2",
+		"d1",
+		"d7",
+		"d7abc",
+		"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
+	}
+}
+
+func newTime(t time.Time) *time.Time {
+	return &t
+}

+ 41 - 0
cmd/vendor/gopkg.in/yaml.v2/example_embedded_test.go

@@ -0,0 +1,41 @@
+package yaml_test
+
+import (
+	"fmt"
+	"log"
+
+	"gopkg.in/yaml.v2"
+)
+
+// An example showing how to unmarshal embedded
+// structs from YAML.
+
+type StructA struct {
+	A string `yaml:"a"`
+}
+
+type StructB struct {
+	// Embedded structs are not treated as embedded in YAML by default. To do that,
+	// add the ",inline" annotation below
+	StructA `yaml:",inline"`
+	B       string `yaml:"b"`
+}
+
+var data = `
+a: a string from struct A
+b: a string from struct B
+`
+
+func ExampleUnmarshal_embedded() {
+	var b StructB
+
+	err := yaml.Unmarshal([]byte(data), &b)
+	if err != nil {
+		log.Fatalf("cannot unmarshal data: %v", err)
+	}
+	fmt.Println(b.A)
+	fmt.Println(b.B)
+	// Output:
+	// a string from struct A
+	// a string from struct B
+}

+ 5 - 0
cmd/vendor/gopkg.in/yaml.v2/go.mod

@@ -0,0 +1,5 @@
+module "gopkg.in/yaml.v2"
+
+require (
+	"gopkg.in/check.v1" v0.0.0-20161208181325-20d25e280405
+)

+ 19 - 1
cmd/vendor/gopkg.in/yaml.v2/readerc.go

@@ -93,9 +93,18 @@ func yaml_parser_update_buffer(parser *yaml_parser_t, length int) bool {
 		panic("read handler must be set")
 		panic("read handler must be set")
 	}
 	}
 
 
+	// [Go] This function was changed to guarantee the requested length size at EOF.
+	// The fact we need to do this is pretty awful, but the description above implies
+	// for that to be the case, and there are tests 
+
 	// If the EOF flag is set and the raw buffer is empty, do nothing.
 	// 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) {
 	if parser.eof && parser.raw_buffer_pos == len(parser.raw_buffer) {
-		return true
+		// [Go] ACTUALLY! Read the documentation of this function above.
+		// This is just broken. To return true, we need to have the
+		// given length in the buffer. Not doing that means every single
+		// check that calls this function to make sure the buffer has a
+		// given length is Go) panicking; or C) accessing invalid memory.
+		//return true
 	}
 	}
 
 
 	// Return if the buffer contains enough characters.
 	// Return if the buffer contains enough characters.
@@ -389,6 +398,15 @@ func yaml_parser_update_buffer(parser *yaml_parser_t, length int) bool {
 			break
 			break
 		}
 		}
 	}
 	}
+	// [Go] Read the documentation of this function above. To return true,
+	// we need to have the given length in the buffer. Not doing that means
+	// every single check that calls this function to make sure the buffer
+	// has a given length is Go) panicking; or C) accessing invalid memory.
+	// This happens here due to the EOF above breaking early.
+	for buffer_len < length {
+		parser.buffer[buffer_len] = 0
+		buffer_len++
+	}
 	parser.buffer = parser.buffer[:buffer_len]
 	parser.buffer = parser.buffer[:buffer_len]
 	return true
 	return true
 }
 }

+ 65 - 15
cmd/vendor/gopkg.in/yaml.v2/resolve.go

@@ -6,7 +6,7 @@ import (
 	"regexp"
 	"regexp"
 	"strconv"
 	"strconv"
 	"strings"
 	"strings"
-	"unicode/utf8"
+	"time"
 )
 )
 
 
 type resolveMapItem struct {
 type resolveMapItem struct {
@@ -75,7 +75,7 @@ func longTag(tag string) string {
 
 
 func resolvableTag(tag string) bool {
 func resolvableTag(tag string) bool {
 	switch tag {
 	switch tag {
-	case "", yaml_STR_TAG, yaml_BOOL_TAG, yaml_INT_TAG, yaml_FLOAT_TAG, yaml_NULL_TAG:
+	case "", yaml_STR_TAG, yaml_BOOL_TAG, yaml_INT_TAG, yaml_FLOAT_TAG, yaml_NULL_TAG, yaml_TIMESTAMP_TAG:
 		return true
 		return true
 	}
 	}
 	return false
 	return false
@@ -92,6 +92,19 @@ func resolve(tag string, in string) (rtag string, out interface{}) {
 		switch tag {
 		switch tag {
 		case "", rtag, yaml_STR_TAG, yaml_BINARY_TAG:
 		case "", rtag, yaml_STR_TAG, yaml_BINARY_TAG:
 			return
 			return
+		case yaml_FLOAT_TAG:
+			if rtag == yaml_INT_TAG {
+				switch v := out.(type) {
+				case int64:
+					rtag = yaml_FLOAT_TAG
+					out = float64(v)
+					return
+				case int:
+					rtag = yaml_FLOAT_TAG
+					out = float64(v)
+					return
+				}
+			}
 		}
 		}
 		failf("cannot decode %s `%s` as a %s", shortTag(rtag), in, shortTag(tag))
 		failf("cannot decode %s `%s` as a %s", shortTag(rtag), in, shortTag(tag))
 	}()
 	}()
@@ -125,6 +138,15 @@ func resolve(tag string, in string) (rtag string, out interface{}) {
 
 
 		case 'D', 'S':
 		case 'D', 'S':
 			// Int, float, or timestamp.
 			// Int, float, or timestamp.
+			// Only try values as a timestamp if the value is unquoted or there's an explicit
+			// !!timestamp tag.
+			if tag == "" || tag == yaml_TIMESTAMP_TAG {
+				t, ok := parseTimestamp(in)
+				if ok {
+					return yaml_TIMESTAMP_TAG, t
+				}
+			}
+
 			plain := strings.Replace(in, "_", "", -1)
 			plain := strings.Replace(in, "_", "", -1)
 			intv, err := strconv.ParseInt(plain, 0, 64)
 			intv, err := strconv.ParseInt(plain, 0, 64)
 			if err == nil {
 			if err == nil {
@@ -158,28 +180,20 @@ func resolve(tag string, in string) (rtag string, out interface{}) {
 					return yaml_INT_TAG, uintv
 					return yaml_INT_TAG, uintv
 				}
 				}
 			} else if strings.HasPrefix(plain, "-0b") {
 			} else if strings.HasPrefix(plain, "-0b") {
-				intv, err := strconv.ParseInt(plain[3:], 2, 64)
+				intv, err := strconv.ParseInt("-" + plain[3:], 2, 64)
 				if err == nil {
 				if err == nil {
-					if intv == int64(int(intv)) {
-						return yaml_INT_TAG, -int(intv)
+					if true || intv == int64(int(intv)) {
+						return yaml_INT_TAG, int(intv)
 					} else {
 					} else {
-						return yaml_INT_TAG, -intv
+						return yaml_INT_TAG, intv
 					}
 					}
 				}
 				}
 			}
 			}
-			// XXX Handle timestamps here.
-
 		default:
 		default:
 			panic("resolveTable item not yet handled: " + string(rune(hint)) + " (with " + in + ")")
 			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)
+	return yaml_STR_TAG, in
 }
 }
 
 
 // encodeBase64 encodes s as base64 that is broken up into multiple lines
 // encodeBase64 encodes s as base64 that is broken up into multiple lines
@@ -206,3 +220,39 @@ func encodeBase64(s string) string {
 	}
 	}
 	return string(out[:k])
 	return string(out[:k])
 }
 }
+
+// This is a subset of the formats allowed by the regular expression
+// defined at http://yaml.org/type/timestamp.html.
+var allowedTimestampFormats = []string{
+	"2006-1-2T15:4:5.999999999Z07:00", // RCF3339Nano with short date fields.
+	"2006-1-2t15:4:5.999999999Z07:00", // RFC3339Nano with short date fields and lower-case "t".
+	"2006-1-2 15:4:5.999999999",       // space separated with no time zone
+	"2006-1-2",                        // date only
+	// Notable exception: time.Parse cannot handle: "2001-12-14 21:59:43.10 -5"
+	// from the set of examples.
+}
+
+// parseTimestamp parses s as a timestamp string and
+// returns the timestamp and reports whether it succeeded.
+// Timestamp formats are defined at http://yaml.org/type/timestamp.html
+func parseTimestamp(s string) (time.Time, bool) {
+	// TODO write code to check all the formats supported by
+	// http://yaml.org/type/timestamp.html instead of using time.Parse.
+
+	// Quick check: all date formats start with YYYY-.
+	i := 0
+	for ; i < len(s); i++ {
+		if c := s[i]; c < '0' || c > '9' {
+			break
+		}
+	}
+	if i != 4 || i == len(s) || s[i] != '-' {
+		return time.Time{}, false
+	}
+	for _, format := range allowedTimestampFormats {
+		if t, err := time.Parse(format, s); err == nil {
+			return t, true
+		}
+	}
+	return time.Time{}, false
+}

+ 12 - 26
cmd/vendor/gopkg.in/yaml.v2/scannerc.go

@@ -611,7 +611,7 @@ func yaml_parser_set_scanner_tag_error(parser *yaml_parser_t, directive bool, co
 	if directive {
 	if directive {
 		context = "while parsing a %TAG directive"
 		context = "while parsing a %TAG directive"
 	}
 	}
-	return yaml_parser_set_scanner_error(parser, context, context_mark, "did not find URI escaped octet")
+	return yaml_parser_set_scanner_error(parser, context, context_mark, problem)
 }
 }
 
 
 func trace(args ...interface{}) func() {
 func trace(args ...interface{}) func() {
@@ -871,12 +871,6 @@ func yaml_parser_save_simple_key(parser *yaml_parser_t) bool {
 
 
 	required := parser.flow_level == 0 && parser.indent == parser.mark.column
 	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 the current position may start a simple key, save it.
 	//
 	//
@@ -1944,7 +1938,7 @@ func yaml_parser_scan_tag_handle(parser *yaml_parser_t, directive bool, start_ma
 	} else {
 	} else {
 		// It's either the '!' tag or not really a tag handle.  If it's a %TAG
 		// 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.
 		// 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) {
+		if directive && string(s) != "!" {
 			yaml_parser_set_scanner_tag_error(parser, directive,
 			yaml_parser_set_scanner_tag_error(parser, directive,
 				start_mark, "did not find expected '!'")
 				start_mark, "did not find expected '!'")
 			return false
 			return false
@@ -1959,6 +1953,7 @@ func yaml_parser_scan_tag_handle(parser *yaml_parser_t, directive bool, start_ma
 func yaml_parser_scan_tag_uri(parser *yaml_parser_t, directive bool, head []byte, start_mark yaml_mark_t, uri *[]byte) bool {
 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
 	//size_t length = head ? strlen((char *)head) : 0
 	var s []byte
 	var s []byte
+	hasTag := len(head) > 0
 
 
 	// Copy the head if needed.
 	// Copy the head if needed.
 	//
 	//
@@ -2000,10 +1995,10 @@ func yaml_parser_scan_tag_uri(parser *yaml_parser_t, directive bool, head []byte
 		if parser.unread < 1 && !yaml_parser_update_buffer(parser, 1) {
 		if parser.unread < 1 && !yaml_parser_update_buffer(parser, 1) {
 			return false
 			return false
 		}
 		}
+		hasTag = true
 	}
 	}
 
 
-	// Check if the tag is non-empty.
-	if len(s) == 0 {
+	if !hasTag {
 		yaml_parser_set_scanner_tag_error(parser, directive,
 		yaml_parser_set_scanner_tag_error(parser, directive,
 			start_mark, "did not find expected tag URI")
 			start_mark, "did not find expected tag URI")
 		return false
 		return false
@@ -2474,6 +2469,10 @@ func yaml_parser_scan_flow_scalar(parser *yaml_parser_t, token *yaml_token_t, si
 			}
 			}
 		}
 		}
 
 
+		if parser.unread < 1 && !yaml_parser_update_buffer(parser, 1) {
+			return false
+		}
+
 		// Check if we are at the end of the scalar.
 		// Check if we are at the end of the scalar.
 		if single {
 		if single {
 			if parser.buffer[parser.buffer_pos] == '\'' {
 			if parser.buffer[parser.buffer_pos] == '\'' {
@@ -2486,10 +2485,6 @@ func yaml_parser_scan_flow_scalar(parser *yaml_parser_t, token *yaml_token_t, si
 		}
 		}
 
 
 		// Consume blank characters.
 		// 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) {
 		for is_blank(parser.buffer, parser.buffer_pos) || is_break(parser.buffer, parser.buffer_pos) {
 			if is_blank(parser.buffer, parser.buffer_pos) {
 			if is_blank(parser.buffer, parser.buffer_pos) {
 				// Consume a space or a tab character.
 				// Consume a space or a tab character.
@@ -2591,19 +2586,10 @@ func yaml_parser_scan_plain_scalar(parser *yaml_parser_t, token *yaml_token_t) b
 		// Consume non-blank characters.
 		// Consume non-blank characters.
 		for !is_blankz(parser.buffer, parser.buffer_pos) {
 		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.
 			// Check for indicators that may end a plain scalar.
 			if (parser.buffer[parser.buffer_pos] == ':' && is_blankz(parser.buffer, parser.buffer_pos+1)) ||
 			if (parser.buffer[parser.buffer_pos] == ':' && is_blankz(parser.buffer, parser.buffer_pos+1)) ||
 				(parser.flow_level > 0 &&
 				(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] == '[' ||
 						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] == '}')) {
@@ -2655,10 +2641,10 @@ func yaml_parser_scan_plain_scalar(parser *yaml_parser_t, token *yaml_token_t) b
 		for is_blank(parser.buffer, parser.buffer_pos) || is_break(parser.buffer, parser.buffer_pos) {
 		for is_blank(parser.buffer, parser.buffer_pos) || is_break(parser.buffer, parser.buffer_pos) {
 			if is_blank(parser.buffer, parser.buffer_pos) {
 			if is_blank(parser.buffer, parser.buffer_pos) {
 
 
-				// Check for tab character that abuse indentation.
+				// Check for tab characters that abuse indentation.
 				if leading_blanks && parser.mark.column < indent && is_tab(parser.buffer, parser.buffer_pos) {
 				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",
 					yaml_parser_set_scanner_error(parser, "while scanning a plain scalar",
-						start_mark, "found a tab character that violate indentation")
+						start_mark, "found a tab character that violates indentation")
 					return false
 					return false
 				}
 				}
 
 

+ 9 - 0
cmd/vendor/gopkg.in/yaml.v2/sorter.go

@@ -51,6 +51,15 @@ func (l keyList) Less(i, j int) bool {
 		}
 		}
 		var ai, bi int
 		var ai, bi int
 		var an, bn int64
 		var an, bn int64
+		if ar[i] == '0' || br[i] == '0' {
+			for j := i-1; j >= 0 && unicode.IsDigit(ar[j]); j-- {
+				if ar[j] != '0' {
+					an = 1
+					bn = 1
+					break
+				}
+			}
+		}
 		for ai = i; ai < len(ar) && unicode.IsDigit(ar[ai]); ai++ {
 		for ai = i; ai < len(ar) && unicode.IsDigit(ar[ai]); ai++ {
 			an = an*10 + int64(ar[ai]-'0')
 			an = an*10 + int64(ar[ai]-'0')
 		}
 		}

+ 12 - 0
cmd/vendor/gopkg.in/yaml.v2/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{})

+ 1 - 64
cmd/vendor/gopkg.in/yaml.v2/writerc.go

@@ -18,72 +18,9 @@ func yaml_emitter_flush(emitter *yaml_emitter_t) bool {
 		return true
 		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 {
+	if err := emitter.write_handler(emitter, emitter.buffer[:emitter.buffer_pos]); err != nil {
 		return yaml_emitter_set_writer_error(emitter, "write error: "+err.Error())
 		return yaml_emitter_set_writer_error(emitter, "write error: "+err.Error())
 	}
 	}
 	emitter.buffer_pos = 0
 	emitter.buffer_pos = 0
-	emitter.raw_buffer = emitter.raw_buffer[:0]
 	return true
 	return true
 }
 }

+ 128 - 8
cmd/vendor/gopkg.in/yaml.v2/yaml.go

@@ -9,6 +9,7 @@ package yaml
 import (
 import (
 	"errors"
 	"errors"
 	"fmt"
 	"fmt"
+	"io"
 	"reflect"
 	"reflect"
 	"strings"
 	"strings"
 	"sync"
 	"sync"
@@ -77,8 +78,65 @@ type Marshaler interface {
 // supported tag options.
 // supported tag options.
 //
 //
 func Unmarshal(in []byte, out interface{}) (err error) {
 func Unmarshal(in []byte, out interface{}) (err error) {
+	return unmarshal(in, out, false)
+}
+
+// UnmarshalStrict is like Unmarshal except that any fields that are found
+// in the data that do not have corresponding struct members, or mapping
+// keys that are duplicates, will result in
+// an error.
+func UnmarshalStrict(in []byte, out interface{}) (err error) {
+	return unmarshal(in, out, true)
+}
+
+// A Decorder reads and decodes YAML values from an input stream.
+type Decoder struct {
+	strict bool
+	parser *parser
+}
+
+// NewDecoder returns a new decoder that reads from r.
+//
+// The decoder introduces its own buffering and may read
+// data from r beyond the YAML values requested.
+func NewDecoder(r io.Reader) *Decoder {
+	return &Decoder{
+		parser: newParserFromReader(r),
+	}
+}
+
+// SetStrict sets whether strict decoding behaviour is enabled when
+// decoding items in the data (see UnmarshalStrict). By default, decoding is not strict.
+func (dec *Decoder) SetStrict(strict bool) {
+	dec.strict = strict
+}
+
+// Decode reads the next YAML-encoded value from its input
+// and stores it in the value pointed to by v.
+//
+// See the documentation for Unmarshal for details about the
+// conversion of YAML into a Go value.
+func (dec *Decoder) Decode(v interface{}) (err error) {
+	d := newDecoder(dec.strict)
+	defer handleErr(&err)
+	node := dec.parser.parse()
+	if node == nil {
+		return io.EOF
+	}
+	out := reflect.ValueOf(v)
+	if out.Kind() == reflect.Ptr && !out.IsNil() {
+		out = out.Elem()
+	}
+	d.unmarshal(node, out)
+	if len(d.terrors) > 0 {
+		return &TypeError{d.terrors}
+	}
+	return nil
+}
+
+func unmarshal(in []byte, out interface{}, strict bool) (err error) {
 	defer handleErr(&err)
 	defer handleErr(&err)
-	d := newDecoder()
+	d := newDecoder(strict)
 	p := newParser(in)
 	p := newParser(in)
 	defer p.destroy()
 	defer p.destroy()
 	node := p.parse()
 	node := p.parse()
@@ -99,8 +157,8 @@ func Unmarshal(in []byte, out interface{}) (err error) {
 // of the generated document will reflect the structure of the value itself.
 // 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.
 // 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
+// Struct fields are only marshalled if they are exported (have an upper case
+// first letter), and are marshalled using the field name lowercased as the
 // default key. Custom keys may be defined via the "yaml" name in the field
 // 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
 // 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.
 // following comma-separated options are used to tweak the marshalling process.
@@ -114,7 +172,10 @@ func Unmarshal(in []byte, out interface{}) (err error) {
 //
 //
 //     omitempty    Only include the field if it's not set to the zero
 //     omitempty    Only include the field if it's not set to the zero
 //                  value for the type or to empty slices or maps.
 //                  value for the type or to empty slices or maps.
-//                  Does not apply to zero valued structs.
+//                  Zero valued structs will be omitted if all their public
+//                  fields are zero, unless they implement an IsZero
+//                  method (see the IsZeroer interface type), in which
+//                  case the field will be included if that method returns true.
 //
 //
 //     flow         Marshal using a flow style (useful for structs,
 //     flow         Marshal using a flow style (useful for structs,
 //                  sequences and maps).
 //                  sequences and maps).
@@ -129,7 +190,7 @@ func Unmarshal(in []byte, out interface{}) (err error) {
 // For example:
 // For example:
 //
 //
 //     type T struct {
 //     type T struct {
-//         F int "a,omitempty"
+//         F int `yaml:"a,omitempty"`
 //         B int
 //         B int
 //     }
 //     }
 //     yaml.Marshal(&T{B: 2}) // Returns "b: 2\n"
 //     yaml.Marshal(&T{B: 2}) // Returns "b: 2\n"
@@ -139,12 +200,47 @@ func Marshal(in interface{}) (out []byte, err error) {
 	defer handleErr(&err)
 	defer handleErr(&err)
 	e := newEncoder()
 	e := newEncoder()
 	defer e.destroy()
 	defer e.destroy()
-	e.marshal("", reflect.ValueOf(in))
+	e.marshalDoc("", reflect.ValueOf(in))
 	e.finish()
 	e.finish()
 	out = e.out
 	out = e.out
 	return
 	return
 }
 }
 
 
+// An Encoder writes YAML values to an output stream.
+type Encoder struct {
+	encoder *encoder
+}
+
+// NewEncoder returns a new encoder that writes to w.
+// The Encoder should be closed after use to flush all data
+// to w.
+func NewEncoder(w io.Writer) *Encoder {
+	return &Encoder{
+		encoder: newEncoderWithWriter(w),
+	}
+}
+
+// Encode writes the YAML encoding of v to the stream.
+// If multiple items are encoded to the stream, the
+// second and subsequent document will be preceded
+// with a "---" document separator, but the first will not.
+//
+// See the documentation for Marshal for details about the conversion of Go
+// values to YAML.
+func (e *Encoder) Encode(v interface{}) (err error) {
+	defer handleErr(&err)
+	e.encoder.marshalDoc("", reflect.ValueOf(v))
+	return nil
+}
+
+// Close closes the encoder by writing any remaining data.
+// It does not write a stream terminating string "...".
+func (e *Encoder) Close() (err error) {
+	defer handleErr(&err)
+	e.encoder.finish()
+	return nil
+}
+
 func handleErr(err *error) {
 func handleErr(err *error) {
 	if v := recover(); v != nil {
 	if v := recover(); v != nil {
 		if e, ok := v.(yamlError); ok {
 		if e, ok := v.(yamlError); ok {
@@ -200,6 +296,9 @@ type fieldInfo struct {
 	Num       int
 	Num       int
 	OmitEmpty bool
 	OmitEmpty bool
 	Flow      bool
 	Flow      bool
+	// Id holds the unique field identifier, so we can cheaply
+	// check for field duplicates without maintaining an extra map.
+	Id int
 
 
 	// Inline holds the field index if the field is part of an inlined struct.
 	// Inline holds the field index if the field is part of an inlined struct.
 	Inline []int
 	Inline []int
@@ -279,6 +378,7 @@ func getStructInfo(st reflect.Type) (*structInfo, error) {
 					} else {
 					} else {
 						finfo.Inline = append([]int{i}, finfo.Inline...)
 						finfo.Inline = append([]int{i}, finfo.Inline...)
 					}
 					}
+					finfo.Id = len(fieldsList)
 					fieldsMap[finfo.Key] = finfo
 					fieldsMap[finfo.Key] = finfo
 					fieldsList = append(fieldsList, finfo)
 					fieldsList = append(fieldsList, finfo)
 				}
 				}
@@ -300,11 +400,16 @@ func getStructInfo(st reflect.Type) (*structInfo, error) {
 			return nil, errors.New(msg)
 			return nil, errors.New(msg)
 		}
 		}
 
 
+		info.Id = len(fieldsList)
 		fieldsList = append(fieldsList, info)
 		fieldsList = append(fieldsList, info)
 		fieldsMap[info.Key] = info
 		fieldsMap[info.Key] = info
 	}
 	}
 
 
-	sinfo = &structInfo{fieldsMap, fieldsList, inlineMap}
+	sinfo = &structInfo{
+		FieldsMap:  fieldsMap,
+		FieldsList: fieldsList,
+		InlineMap:  inlineMap,
+	}
 
 
 	fieldMapMutex.Lock()
 	fieldMapMutex.Lock()
 	structMap[st] = sinfo
 	structMap[st] = sinfo
@@ -312,8 +417,23 @@ func getStructInfo(st reflect.Type) (*structInfo, error) {
 	return sinfo, nil
 	return sinfo, nil
 }
 }
 
 
+// IsZeroer is used to check whether an object is zero to
+// determine whether it should be omitted when marshaling
+// with the omitempty flag. One notable implementation
+// is time.Time.
+type IsZeroer interface {
+	IsZero() bool
+}
+
 func isZero(v reflect.Value) bool {
 func isZero(v reflect.Value) bool {
-	switch v.Kind() {
+	kind := v.Kind()
+	if z, ok := v.Interface().(IsZeroer); ok {
+		if (kind == reflect.Ptr || kind == reflect.Interface) && v.IsNil() {
+			return true
+		}
+		return z.IsZero()
+	}
+	switch kind {
 	case reflect.String:
 	case reflect.String:
 		return len(v.String()) == 0
 		return len(v.String()) == 0
 	case reflect.Interface, reflect.Ptr:
 	case reflect.Interface, reflect.Ptr:

+ 27 - 5
cmd/vendor/gopkg.in/yaml.v2/yamlh.go

@@ -1,6 +1,7 @@
 package yaml
 package yaml
 
 
 import (
 import (
+	"fmt"
 	"io"
 	"io"
 )
 )
 
 
@@ -239,6 +240,27 @@ const (
 	yaml_MAPPING_END_EVENT    // A MAPPING-END event.
 	yaml_MAPPING_END_EVENT    // A MAPPING-END event.
 )
 )
 
 
+var eventStrings = []string{
+	yaml_NO_EVENT:             "none",
+	yaml_STREAM_START_EVENT:   "stream start",
+	yaml_STREAM_END_EVENT:     "stream end",
+	yaml_DOCUMENT_START_EVENT: "document start",
+	yaml_DOCUMENT_END_EVENT:   "document end",
+	yaml_ALIAS_EVENT:          "alias",
+	yaml_SCALAR_EVENT:         "scalar",
+	yaml_SEQUENCE_START_EVENT: "sequence start",
+	yaml_SEQUENCE_END_EVENT:   "sequence end",
+	yaml_MAPPING_START_EVENT:  "mapping start",
+	yaml_MAPPING_END_EVENT:    "mapping end",
+}
+
+func (e yaml_event_type_t) String() string {
+	if e < 0 || int(e) >= len(eventStrings) {
+		return fmt.Sprintf("unknown event %d", e)
+	}
+	return eventStrings[e]
+}
+
 // The event structure.
 // The event structure.
 type yaml_event_t struct {
 type yaml_event_t struct {
 
 
@@ -508,7 +530,7 @@ type yaml_parser_t struct {
 
 
 	problem string // Error description.
 	problem string // Error description.
 
 
-	// The byte about which the problem occured.
+	// The byte about which the problem occurred.
 	problem_offset int
 	problem_offset int
 	problem_value  int
 	problem_value  int
 	problem_mark   yaml_mark_t
 	problem_mark   yaml_mark_t
@@ -521,9 +543,9 @@ type yaml_parser_t struct {
 
 
 	read_handler yaml_read_handler_t // Read handler.
 	read_handler yaml_read_handler_t // Read handler.
 
 
-	input_file io.Reader // File input data.
-	input      []byte    // String input data.
-	input_pos  int
+	input_reader io.Reader // File input data.
+	input        []byte    // String input data.
+	input_pos    int
 
 
 	eof bool // EOF flag
 	eof bool // EOF flag
 
 
@@ -632,7 +654,7 @@ type yaml_emitter_t struct {
 	write_handler yaml_write_handler_t // Write handler.
 	write_handler yaml_write_handler_t // Write handler.
 
 
 	output_buffer *[]byte   // String output data.
 	output_buffer *[]byte   // String output data.
-	output_file   io.Writer // File output data.
+	output_writer io.Writer // File output data.
 
 
 	buffer     []byte // The working buffer.
 	buffer     []byte // The working buffer.
 	buffer_pos int    // The current position of the buffer.
 	buffer_pos int    // The current position of the buffer.

+ 20 - 0
cmd/vendor/sigs.k8s.io/yaml/.gitignore

@@ -0,0 +1,20 @@
+# OSX leaves these everywhere on SMB shares
+._*
+
+# Eclipse files
+.classpath
+.project
+.settings/**
+
+# Emacs save files
+*~
+
+# Vim-related files
+[._]*.s[a-w][a-z]
+[._]s[a-w][a-z]
+*.un~
+Session.vim
+.netrwhist
+
+# Go test binaries
+*.test

+ 14 - 0
cmd/vendor/sigs.k8s.io/yaml/.travis.yml

@@ -0,0 +1,14 @@
+language: go
+dist: xenial
+go:
+  - 1.9.x
+  - 1.10.x
+  - 1.11.x
+script:
+  - go get -t -v ./...
+  - diff -u <(echo -n) <(gofmt -d .)
+  - diff -u <(echo -n) <(golint $(go list -e ./...) | grep -v YAMLToJSON)
+  - go tool vet .
+  - go test -v -race ./...
+install:
+  - go get golang.org/x/lint/golint

+ 31 - 0
cmd/vendor/sigs.k8s.io/yaml/CONTRIBUTING.md

@@ -0,0 +1,31 @@
+# Contributing Guidelines
+
+Welcome to Kubernetes. We are excited about the prospect of you joining our [community](https://github.com/kubernetes/community)! The Kubernetes community abides by the CNCF [code of conduct](code-of-conduct.md). Here is an excerpt:
+
+_As contributors and maintainers of this project, and in the interest of fostering an open and welcoming community, we pledge to respect all people who contribute through reporting issues, posting feature requests, updating documentation, submitting pull requests or patches, and other activities._
+
+## Getting Started
+
+We have full documentation on how to get started contributing here:
+
+<!---
+If your repo has certain guidelines for contribution, put them here ahead of the general k8s resources
+-->
+
+- [Contributor License Agreement](https://git.k8s.io/community/CLA.md) Kubernetes projects require that you sign a Contributor License Agreement (CLA) before we can accept your pull requests
+- [Kubernetes Contributor Guide](http://git.k8s.io/community/contributors/guide) - Main contributor documentation, or you can just jump directly to the [contributing section](http://git.k8s.io/community/contributors/guide#contributing)
+- [Contributor Cheat Sheet](https://git.k8s.io/community/contributors/guide/contributor-cheatsheet.md) - Common resources for existing developers
+
+## Mentorship
+
+- [Mentoring Initiatives](https://git.k8s.io/community/mentoring) - We have a diverse set of mentorship programs available that are always looking for volunteers!
+
+<!---
+Custom Information - if you're copying this template for the first time you can add custom content here, for example:
+
+## Contact Information
+
+- [Slack channel](https://kubernetes.slack.com/messages/kubernetes-users) - Replace `kubernetes-users` with your slack channel string, this will send users directly to your channel. 
+- [Mailing list](URL)
+
+-->

+ 0 - 0
cmd/vendor/github.com/ghodss/yaml/LICENSE → cmd/vendor/sigs.k8s.io/yaml/LICENSE


+ 25 - 0
cmd/vendor/sigs.k8s.io/yaml/OWNERS

@@ -0,0 +1,25 @@
+approvers:
+- dims
+- lavalamp
+- smarterclayton
+- deads2k
+- sttts
+- liggitt
+- caesarxuchao
+reviewers:
+- dims
+- thockin
+- lavalamp
+- smarterclayton
+- wojtek-t
+- deads2k
+- derekwaynecarr
+- caesarxuchao
+- mikedanese
+- liggitt
+- gmarek
+- sttts
+- ncdc
+- tallclair
+labels:
+- sig/api-machinery

+ 121 - 0
cmd/vendor/sigs.k8s.io/yaml/README.md

@@ -0,0 +1,121 @@
+# YAML marshaling and unmarshaling support for Go
+
+[![Build Status](https://travis-ci.org/ghodss/yaml.svg)](https://travis-ci.org/ghodss/yaml)
+
+## Introduction
+
+A wrapper around [go-yaml](https://github.com/go-yaml/yaml) designed to enable a better way of handling YAML when marshaling to and from structs.
+
+In short, this library first converts YAML to JSON using go-yaml and then uses `json.Marshal` and `json.Unmarshal` to convert to or from the struct. This means that it effectively reuses the JSON struct tags as well as the custom JSON methods `MarshalJSON` and `UnmarshalJSON` unlike go-yaml. For a detailed overview of the rationale behind this method, [see this blog post](http://ghodss.com/2014/the-right-way-to-handle-yaml-in-golang/).
+
+## Compatibility
+
+This package uses [go-yaml](https://github.com/go-yaml/yaml) and therefore supports [everything go-yaml supports](https://github.com/go-yaml/yaml#compatibility).
+
+## Caveats
+
+**Caveat #1:** When using `yaml.Marshal` and `yaml.Unmarshal`, binary data should NOT be preceded with the `!!binary` YAML tag. If you do, go-yaml will convert the binary data from base64 to native binary data, which is not compatible with JSON. You can still use binary in your YAML files though - just store them without the `!!binary` tag and decode the base64 in your code (e.g. in the custom JSON methods `MarshalJSON` and `UnmarshalJSON`). This also has the benefit that your YAML and your JSON binary data will be decoded exactly the same way. As an example:
+
+```
+BAD:
+	exampleKey: !!binary gIGC
+
+GOOD:
+	exampleKey: gIGC
+... and decode the base64 data in your code.
+```
+
+**Caveat #2:** When using `YAMLToJSON` directly, maps with keys that are maps will result in an error since this is not supported by JSON. This error will occur in `Unmarshal` as well since you can't unmarshal map keys anyways since struct fields can't be keys.
+
+## Installation and usage
+
+To install, run:
+
+```
+$ go get github.com/ghodss/yaml
+```
+
+And import using:
+
+```
+import "github.com/ghodss/yaml"
+```
+
+Usage is very similar to the JSON library:
+
+```go
+package main
+
+import (
+	"fmt"
+
+	"github.com/ghodss/yaml"
+)
+
+type Person struct {
+	Name string `json:"name"` // Affects YAML field names too.
+	Age  int    `json:"age"`
+}
+
+func main() {
+	// Marshal a Person struct to YAML.
+	p := Person{"John", 30}
+	y, err := yaml.Marshal(p)
+	if err != nil {
+		fmt.Printf("err: %v\n", err)
+		return
+	}
+	fmt.Println(string(y))
+	/* Output:
+	age: 30
+	name: John
+	*/
+
+	// Unmarshal the YAML back into a Person struct.
+	var p2 Person
+	err = yaml.Unmarshal(y, &p2)
+	if err != nil {
+		fmt.Printf("err: %v\n", err)
+		return
+	}
+	fmt.Println(p2)
+	/* Output:
+	{John 30}
+	*/
+}
+```
+
+`yaml.YAMLToJSON` and `yaml.JSONToYAML` methods are also available:
+
+```go
+package main
+
+import (
+	"fmt"
+
+	"github.com/ghodss/yaml"
+)
+
+func main() {
+	j := []byte(`{"name": "John", "age": 30}`)
+	y, err := yaml.JSONToYAML(j)
+	if err != nil {
+		fmt.Printf("err: %v\n", err)
+		return
+	}
+	fmt.Println(string(y))
+	/* Output:
+	name: John
+	age: 30
+	*/
+	j2, err := yaml.YAMLToJSON(y)
+	if err != nil {
+		fmt.Printf("err: %v\n", err)
+		return
+	}
+	fmt.Println(string(j2))
+	/* Output:
+	{"age":30,"name":"John"}
+	*/
+}
+```

+ 9 - 0
cmd/vendor/sigs.k8s.io/yaml/RELEASE.md

@@ -0,0 +1,9 @@
+# Release Process
+
+The `yaml` Project is released on an as-needed basis. The process is as follows:
+
+1. An issue is proposing a new release with a changelog since the last release
+1. All [OWNERS](OWNERS) must LGTM this release
+1. An OWNER runs `git tag -s $VERSION` and inserts the changelog and pushes the tag with `git push $VERSION`
+1. The release issue is closed
+1. An announcement email is sent to `kubernetes-dev@googlegroups.com` with the subject `[ANNOUNCE] kubernetes-template-project $VERSION is released`

+ 17 - 0
cmd/vendor/sigs.k8s.io/yaml/SECURITY_CONTACTS

@@ -0,0 +1,17 @@
+# Defined below are the security contacts for this repo.
+#
+# They are the contact point for the Product Security Team to reach out
+# to for triaging and handling of incoming issues.
+#
+# The below names agree to abide by the
+# [Embargo Policy](https://github.com/kubernetes/sig-release/blob/master/security-release-process-documentation/security-release-process.md#embargo-policy)
+# and will be removed and replaced if they violate that agreement.
+#
+# DO NOT REPORT SECURITY VULNERABILITIES DIRECTLY TO THESE NAMES, FOLLOW THE
+# INSTRUCTIONS AT https://kubernetes.io/security/
+
+cjcullen
+jessfraz
+liggitt
+philips
+tallclair

+ 3 - 0
cmd/vendor/sigs.k8s.io/yaml/code-of-conduct.md

@@ -0,0 +1,3 @@
+# Kubernetes Community Code of Conduct
+
+Please refer to our [Kubernetes Community Code of Conduct](https://git.k8s.io/community/code-of-conduct.md)

+ 1 - 0
cmd/vendor/github.com/ghodss/yaml/fields.go → cmd/vendor/sigs.k8s.io/yaml/fields.go

@@ -1,6 +1,7 @@
 // Copyright 2013 The Go Authors. All rights reserved.
 // Copyright 2013 The Go Authors. All rights reserved.
 // Use of this source code is governed by a BSD-style
 // Use of this source code is governed by a BSD-style
 // license that can be found in the LICENSE file.
 // license that can be found in the LICENSE file.
+
 package yaml
 package yaml
 
 
 import (
 import (

+ 55 - 13
cmd/vendor/github.com/ghodss/yaml/yaml.go → cmd/vendor/sigs.k8s.io/yaml/yaml.go

@@ -4,13 +4,14 @@ import (
 	"bytes"
 	"bytes"
 	"encoding/json"
 	"encoding/json"
 	"fmt"
 	"fmt"
+	"io"
 	"reflect"
 	"reflect"
 	"strconv"
 	"strconv"
 
 
 	"gopkg.in/yaml.v2"
 	"gopkg.in/yaml.v2"
 )
 )
 
 
-// Marshals the object into JSON then converts JSON to YAML and returns the
+// Marshal marshals the object into JSON then converts JSON to YAML and returns the
 // YAML.
 // YAML.
 func Marshal(o interface{}) ([]byte, error) {
 func Marshal(o interface{}) ([]byte, error) {
 	j, err := json.Marshal(o)
 	j, err := json.Marshal(o)
@@ -26,15 +27,35 @@ func Marshal(o interface{}) ([]byte, error) {
 	return y, nil
 	return y, nil
 }
 }
 
 
-// Converts YAML to JSON then uses JSON to unmarshal into an object.
-func Unmarshal(y []byte, o interface{}) error {
+// JSONOpt is a decoding option for decoding from JSON format.
+type JSONOpt func(*json.Decoder) *json.Decoder
+
+// Unmarshal converts YAML to JSON then uses JSON to unmarshal into an object,
+// optionally configuring the behavior of the JSON unmarshal.
+func Unmarshal(y []byte, o interface{}, opts ...JSONOpt) error {
+	return yamlUnmarshal(y, o, false, opts...)
+}
+
+// UnmarshalStrict strictly converts YAML to JSON then uses JSON to unmarshal
+// into an object, optionally configuring the behavior of the JSON unmarshal.
+func UnmarshalStrict(y []byte, o interface{}, opts ...JSONOpt) error {
+	return yamlUnmarshal(y, o, true, append(opts, DisallowUnknownFields)...)
+}
+
+// yamlUnmarshal unmarshals the given YAML byte stream into the given interface,
+// optionally performing the unmarshalling strictly
+func yamlUnmarshal(y []byte, o interface{}, strict bool, opts ...JSONOpt) error {
 	vo := reflect.ValueOf(o)
 	vo := reflect.ValueOf(o)
-	j, err := yamlToJSON(y, &vo)
+	unmarshalFn := yaml.Unmarshal
+	if strict {
+		unmarshalFn = yaml.UnmarshalStrict
+	}
+	j, err := yamlToJSON(y, &vo, unmarshalFn)
 	if err != nil {
 	if err != nil {
 		return fmt.Errorf("error converting YAML to JSON: %v", err)
 		return fmt.Errorf("error converting YAML to JSON: %v", err)
 	}
 	}
 
 
-	err = json.Unmarshal(j, o)
+	err = jsonUnmarshal(bytes.NewReader(j), o, opts...)
 	if err != nil {
 	if err != nil {
 		return fmt.Errorf("error unmarshaling JSON: %v", err)
 		return fmt.Errorf("error unmarshaling JSON: %v", err)
 	}
 	}
@@ -42,7 +63,22 @@ func Unmarshal(y []byte, o interface{}) error {
 	return nil
 	return nil
 }
 }
 
 
-// Convert JSON to YAML.
+// jsonUnmarshal unmarshals the JSON byte stream from the given reader into the
+// object, optionally applying decoder options prior to decoding.  We are not
+// using json.Unmarshal directly as we want the chance to pass in non-default
+// options.
+func jsonUnmarshal(r io.Reader, o interface{}, opts ...JSONOpt) error {
+	d := json.NewDecoder(r)
+	for _, opt := range opts {
+		d = opt(d)
+	}
+	if err := d.Decode(&o); err != nil {
+		return fmt.Errorf("while decoding JSON: %v", err)
+	}
+	return nil
+}
+
+// JSONToYAML Converts JSON to YAML.
 func JSONToYAML(j []byte) ([]byte, error) {
 func JSONToYAML(j []byte) ([]byte, error) {
 	// Convert the JSON to an object.
 	// Convert the JSON to an object.
 	var jsonObj interface{}
 	var jsonObj interface{}
@@ -60,8 +96,8 @@ func JSONToYAML(j []byte) ([]byte, error) {
 	return yaml.Marshal(jsonObj)
 	return yaml.Marshal(jsonObj)
 }
 }
 
 
-// Convert YAML to JSON. Since JSON is a subset of YAML, passing JSON through
-// this method should be a no-op.
+// YAMLToJSON converts YAML to JSON. Since JSON is a subset of YAML,
+// passing JSON through this method should be a no-op.
 //
 //
 // Things YAML can do that are not supported by JSON:
 // Things YAML can do that are not supported by JSON:
 // * In YAML you can have binary and null keys in your maps. These are invalid
 // * In YAML you can have binary and null keys in your maps. These are invalid
@@ -70,14 +106,22 @@ func JSONToYAML(j []byte) ([]byte, error) {
 //   use binary data with this library, encode the data as base64 as usual but do
 //   use binary data with this library, encode the data as base64 as usual but do
 //   not use the !!binary tag in your YAML. This will ensure the original base64
 //   not use the !!binary tag in your YAML. This will ensure the original base64
 //   encoded data makes it all the way through to the JSON.
 //   encoded data makes it all the way through to the JSON.
+//
+// For strict decoding of YAML, use YAMLToJSONStrict.
 func YAMLToJSON(y []byte) ([]byte, error) {
 func YAMLToJSON(y []byte) ([]byte, error) {
-	return yamlToJSON(y, nil)
+	return yamlToJSON(y, nil, yaml.Unmarshal)
 }
 }
 
 
-func yamlToJSON(y []byte, jsonTarget *reflect.Value) ([]byte, error) {
+// YAMLToJSONStrict is like YAMLToJSON but enables strict YAML decoding,
+// returning an error on any duplicate field names.
+func YAMLToJSONStrict(y []byte) ([]byte, error) {
+	return yamlToJSON(y, nil, yaml.UnmarshalStrict)
+}
+
+func yamlToJSON(y []byte, jsonTarget *reflect.Value, yamlUnmarshal func([]byte, interface{}) error) ([]byte, error) {
 	// Convert the YAML to an object.
 	// Convert the YAML to an object.
 	var yamlObj interface{}
 	var yamlObj interface{}
-	err := yaml.Unmarshal(y, &yamlObj)
+	err := yamlUnmarshal(y, &yamlObj)
 	if err != nil {
 	if err != nil {
 		return nil, err
 		return nil, err
 	}
 	}
@@ -272,6 +316,4 @@ func convertToJSONableObject(yamlObj interface{}, jsonTarget *reflect.Value) (in
 		}
 		}
 		return yamlObj, nil
 		return yamlObj, nil
 	}
 	}
-
-	return nil, nil
 }
 }

+ 14 - 0
cmd/vendor/sigs.k8s.io/yaml/yaml_go110.go

@@ -0,0 +1,14 @@
+// This file contains changes that are only compatible with go 1.10 and onwards.
+
+// +build go1.10
+
+package yaml
+
+import "encoding/json"
+
+// DisallowUnknownFields configures the JSON decoder to error out if unknown
+// fields come along, instead of dropping them by default.
+func DisallowUnknownFields(d *json.Decoder) *json.Decoder {
+	d.DisallowUnknownFields()
+	return d
+}

+ 46 - 0
cmd/vendor/sigs.k8s.io/yaml/yaml_go110_test.go

@@ -0,0 +1,46 @@
+// +build go1.10
+
+package yaml
+
+import (
+	"fmt"
+	"testing"
+)
+
+func TestUnmarshalWithTags(t *testing.T) {
+	type WithTaggedField struct {
+		Field string `json:"field"`
+	}
+
+	t.Run("Known tagged field", func(t *testing.T) {
+		y := []byte(`field: "hello"`)
+		v := WithTaggedField{}
+		if err := Unmarshal(y, &v, DisallowUnknownFields); err != nil {
+			t.Errorf("unexpected error: %v", err)
+		}
+		if v.Field != "hello" {
+			t.Errorf("v.Field=%v, want 'hello'", v.Field)
+		}
+
+	})
+	t.Run("With unknown tagged field", func(t *testing.T) {
+		y := []byte(`unknown: "hello"`)
+		v := WithTaggedField{}
+		err := Unmarshal(y, &v, DisallowUnknownFields)
+		if err == nil {
+			t.Errorf("want error because of unknown field, got <nil>: v=%#v", v)
+		}
+	})
+
+}
+
+func exampleUnknown() {
+	type WithTaggedField struct {
+		Field string `json:"field"`
+	}
+	y := []byte(`unknown: "hello"`)
+	v := WithTaggedField{}
+	fmt.Printf("%v\n", Unmarshal(y, &v, DisallowUnknownFields))
+	// Ouptut:
+	// unmarshaling JSON: while decoding JSON: json: unknown field "unknown"
+}

+ 423 - 0
cmd/vendor/sigs.k8s.io/yaml/yaml_test.go

@@ -0,0 +1,423 @@
+package yaml
+
+import (
+	"fmt"
+	"math"
+	"reflect"
+	"strconv"
+	"testing"
+)
+
+type MarshalTest struct {
+	A string
+	B int64
+	// Would like to test float64, but it's not supported in go-yaml.
+	// (See https://github.com/go-yaml/yaml/issues/83.)
+	C float32
+}
+
+func TestMarshal(t *testing.T) {
+	f32String := strconv.FormatFloat(math.MaxFloat32, 'g', -1, 32)
+	s := MarshalTest{"a", math.MaxInt64, math.MaxFloat32}
+	e := []byte(fmt.Sprintf("A: a\nB: %d\nC: %s\n", math.MaxInt64, f32String))
+
+	y, err := Marshal(s)
+	if err != nil {
+		t.Errorf("error marshaling YAML: %v", err)
+	}
+
+	if !reflect.DeepEqual(y, e) {
+		t.Errorf("marshal YAML was unsuccessful, expected: %#v, got: %#v",
+			string(e), string(y))
+	}
+}
+
+type UnmarshalString struct {
+	A    string
+	True string
+}
+
+type UnmarshalStringMap struct {
+	A map[string]string
+}
+
+type UnmarshalNestedString struct {
+	A NestedString
+}
+
+type NestedString struct {
+	A string
+}
+
+type UnmarshalSlice struct {
+	A []NestedSlice
+}
+
+type NestedSlice struct {
+	B string
+	C *string
+}
+
+func TestUnmarshal(t *testing.T) {
+	y := []byte("a: 1")
+	s1 := UnmarshalString{}
+	e1 := UnmarshalString{A: "1"}
+	unmarshal(t, y, &s1, &e1)
+
+	y = []byte("a: true")
+	s1 = UnmarshalString{}
+	e1 = UnmarshalString{A: "true"}
+	unmarshal(t, y, &s1, &e1)
+
+	y = []byte("true: 1")
+	s1 = UnmarshalString{}
+	e1 = UnmarshalString{True: "1"}
+	unmarshal(t, y, &s1, &e1)
+
+	y = []byte("a:\n  a: 1")
+	s2 := UnmarshalNestedString{}
+	e2 := UnmarshalNestedString{NestedString{"1"}}
+	unmarshal(t, y, &s2, &e2)
+
+	y = []byte("a:\n  - b: abc\n    c: def\n  - b: 123\n    c: 456\n")
+	s3 := UnmarshalSlice{}
+	e3 := UnmarshalSlice{[]NestedSlice{NestedSlice{"abc", strPtr("def")}, NestedSlice{"123", strPtr("456")}}}
+	unmarshal(t, y, &s3, &e3)
+
+	y = []byte("a:\n  b: 1")
+	s4 := UnmarshalStringMap{}
+	e4 := UnmarshalStringMap{map[string]string{"b": "1"}}
+	unmarshal(t, y, &s4, &e4)
+
+	y = []byte(`
+a:
+  name: TestA
+b:
+  name: TestB
+`)
+	type NamedThing struct {
+		Name string `json:"name"`
+	}
+	s5 := map[string]*NamedThing{}
+	e5 := map[string]*NamedThing{
+		"a": &NamedThing{Name: "TestA"},
+		"b": &NamedThing{Name: "TestB"},
+	}
+	unmarshal(t, y, &s5, &e5)
+}
+
+func unmarshal(t *testing.T, y []byte, s, e interface{}, opts ...JSONOpt) {
+	err := Unmarshal(y, s, opts...)
+	if err != nil {
+		t.Errorf("error unmarshaling YAML: %v", err)
+	}
+
+	if !reflect.DeepEqual(s, e) {
+		t.Errorf("unmarshal YAML was unsuccessful, expected: %+#v, got: %+#v",
+			e, s)
+	}
+}
+
+func TestUnmarshalStrict(t *testing.T) {
+	y := []byte("a: 1")
+	s1 := UnmarshalString{}
+	e1 := UnmarshalString{A: "1"}
+	unmarshalStrict(t, y, &s1, &e1)
+
+	y = []byte("a: true")
+	s1 = UnmarshalString{}
+	e1 = UnmarshalString{A: "true"}
+	unmarshalStrict(t, y, &s1, &e1)
+
+	y = []byte("true: 1")
+	s1 = UnmarshalString{}
+	e1 = UnmarshalString{True: "1"}
+	unmarshalStrict(t, y, &s1, &e1)
+
+	y = []byte("a:\n  a: 1")
+	s2 := UnmarshalNestedString{}
+	e2 := UnmarshalNestedString{NestedString{"1"}}
+	unmarshalStrict(t, y, &s2, &e2)
+
+	y = []byte("a:\n  - b: abc\n    c: def\n  - b: 123\n    c: 456\n")
+	s3 := UnmarshalSlice{}
+	e3 := UnmarshalSlice{[]NestedSlice{NestedSlice{"abc", strPtr("def")}, NestedSlice{"123", strPtr("456")}}}
+	unmarshalStrict(t, y, &s3, &e3)
+
+	y = []byte("a:\n  b: 1")
+	s4 := UnmarshalStringMap{}
+	e4 := UnmarshalStringMap{map[string]string{"b": "1"}}
+	unmarshalStrict(t, y, &s4, &e4)
+
+	y = []byte(`
+a:
+  name: TestA
+b:
+  name: TestB
+`)
+	type NamedThing struct {
+		Name string `json:"name"`
+	}
+	s5 := map[string]*NamedThing{}
+	e5 := map[string]*NamedThing{
+		"a": &NamedThing{Name: "TestA"},
+		"b": &NamedThing{Name: "TestB"},
+	}
+	unmarshal(t, y, &s5, &e5)
+
+	// When using not-so-strict unmarshal, we should
+	// be picking up the ID-1 as the value in the "id" field
+	y = []byte(`
+a:
+  name: TestA
+  id: ID-A
+  id: ID-1
+`)
+	type NamedThing2 struct {
+		Name string `json:"name"`
+		ID   string `json:"id"`
+	}
+	s6 := map[string]*NamedThing2{}
+	e6 := map[string]*NamedThing2{
+		"a": {Name: "TestA", ID: "ID-1"},
+	}
+	unmarshal(t, y, &s6, &e6)
+}
+
+func TestUnmarshalStrictFails(t *testing.T) {
+	y := []byte("a: true\na: false")
+	s1 := UnmarshalString{}
+	unmarshalStrictFail(t, y, &s1)
+
+	y = []byte("a:\n  - b: abc\n    c: 32\n      b: 123")
+	s2 := UnmarshalSlice{}
+	unmarshalStrictFail(t, y, &s2)
+
+	y = []byte("a:\n  b: 1\n    c: 3")
+	s3 := UnmarshalStringMap{}
+	unmarshalStrictFail(t, y, &s3)
+
+	type NamedThing struct {
+		Name string `json:"name"`
+		ID   string `json:"id"`
+	}
+	// When using strict unmarshal, we should see
+	// the unmarshal fail if there are multiple keys
+	y = []byte(`
+a:
+  name: TestA
+  id: ID-A
+  id: ID-1
+`)
+	s4 := NamedThing{}
+	unmarshalStrictFail(t, y, &s4)
+
+	// Strict unmarshal should fail for unknown fields
+	y = []byte(`
+name: TestB
+id: ID-B
+unknown: Some-Value
+`)
+	s5 := NamedThing{}
+	unmarshalStrictFail(t, y, &s5)
+}
+
+func unmarshalStrict(t *testing.T, y []byte, s, e interface{}, opts ...JSONOpt) {
+	err := UnmarshalStrict(y, s, opts...)
+	if err != nil {
+		t.Errorf("error unmarshaling YAML: %v", err)
+	}
+
+	if !reflect.DeepEqual(s, e) {
+		t.Errorf("unmarshal YAML was unsuccessful, expected: %+#v, got: %+#v",
+			e, s)
+	}
+}
+
+func unmarshalStrictFail(t *testing.T, y []byte, s interface{}, opts ...JSONOpt) {
+	err := UnmarshalStrict(y, s, opts...)
+	if err == nil {
+		t.Errorf("error unmarshaling YAML: %v", err)
+	}
+}
+
+type Case struct {
+	input  string
+	output string
+	// By default we test that reversing the output == input. But if there is a
+	// difference in the reversed output, you can optionally specify it here.
+	reverse *string
+}
+
+type RunType int
+
+const (
+	RunTypeJSONToYAML RunType = iota
+	RunTypeYAMLToJSON
+)
+
+func TestJSONToYAML(t *testing.T) {
+	cases := []Case{
+		{
+			`{"t":"a"}`,
+			"t: a\n",
+			nil,
+		}, {
+			`{"t":null}`,
+			"t: null\n",
+			nil,
+		},
+	}
+
+	runCases(t, RunTypeJSONToYAML, cases)
+}
+
+func TestYAMLToJSON(t *testing.T) {
+	cases := []Case{
+		{
+			"t: a\n",
+			`{"t":"a"}`,
+			nil,
+		}, {
+			"t: \n",
+			`{"t":null}`,
+			strPtr("t: null\n"),
+		}, {
+			"t: null\n",
+			`{"t":null}`,
+			nil,
+		}, {
+			"1: a\n",
+			`{"1":"a"}`,
+			strPtr("\"1\": a\n"),
+		}, {
+			"1000000000000000000000000000000000000: a\n",
+			`{"1e+36":"a"}`,
+			strPtr("\"1e+36\": a\n"),
+		}, {
+			"1e+36: a\n",
+			`{"1e+36":"a"}`,
+			strPtr("\"1e+36\": a\n"),
+		}, {
+			"\"1e+36\": a\n",
+			`{"1e+36":"a"}`,
+			nil,
+		}, {
+			"\"1.2\": a\n",
+			`{"1.2":"a"}`,
+			nil,
+		}, {
+			"- t: a\n",
+			`[{"t":"a"}]`,
+			nil,
+		}, {
+			"- t: a\n" +
+				"- t:\n" +
+				"    b: 1\n" +
+				"    c: 2\n",
+			`[{"t":"a"},{"t":{"b":1,"c":2}}]`,
+			nil,
+		}, {
+			`[{t: a}, {t: {b: 1, c: 2}}]`,
+			`[{"t":"a"},{"t":{"b":1,"c":2}}]`,
+			strPtr("- t: a\n" +
+				"- t:\n" +
+				"    b: 1\n" +
+				"    c: 2\n"),
+		}, {
+			"- t: \n",
+			`[{"t":null}]`,
+			strPtr("- t: null\n"),
+		}, {
+			"- t: null\n",
+			`[{"t":null}]`,
+			nil,
+		},
+	}
+
+	// Cases that should produce errors.
+	_ = []Case{
+		{
+			"~: a",
+			`{"null":"a"}`,
+			nil,
+		}, {
+			"a: !!binary gIGC\n",
+			"{\"a\":\"\x80\x81\x82\"}",
+			nil,
+		},
+	}
+
+	runCases(t, RunTypeYAMLToJSON, cases)
+}
+
+func runCases(t *testing.T, runType RunType, cases []Case) {
+	var f func([]byte) ([]byte, error)
+	var invF func([]byte) ([]byte, error)
+	var msg string
+	var invMsg string
+	if runType == RunTypeJSONToYAML {
+		f = JSONToYAML
+		invF = YAMLToJSON
+		msg = "JSON to YAML"
+		invMsg = "YAML back to JSON"
+	} else {
+		f = YAMLToJSON
+		invF = JSONToYAML
+		msg = "YAML to JSON"
+		invMsg = "JSON back to YAML"
+	}
+
+	for _, c := range cases {
+		// Convert the string.
+		t.Logf("converting %s\n", c.input)
+		output, err := f([]byte(c.input))
+		if err != nil {
+			t.Errorf("Failed to convert %s, input: `%s`, err: %v", msg, c.input, err)
+		}
+
+		// Check it against the expected output.
+		if string(output) != c.output {
+			t.Errorf("Failed to convert %s, input: `%s`, expected `%s`, got `%s`",
+				msg, c.input, c.output, string(output))
+		}
+
+		// Set the string that we will compare the reversed output to.
+		reverse := c.input
+		// If a special reverse string was specified, use that instead.
+		if c.reverse != nil {
+			reverse = *c.reverse
+		}
+
+		// Reverse the output.
+		input, err := invF(output)
+		if err != nil {
+			t.Errorf("Failed to convert %s, input: `%s`, err: %v", invMsg, string(output), err)
+		}
+
+		// Check the reverse is equal to the input (or to *c.reverse).
+		if string(input) != reverse {
+			t.Errorf("Failed to convert %s, input: `%s`, expected `%s`, got `%s`",
+				invMsg, string(output), reverse, string(input))
+		}
+	}
+
+}
+
+// To be able to easily fill in the *Case.reverse string above.
+func strPtr(s string) *string {
+	return &s
+}
+
+func TestYAMLToJSONStrict(t *testing.T) {
+	const data = `
+foo: bar
+foo: baz
+`
+	if _, err := YAMLToJSON([]byte(data)); err != nil {
+		t.Error("expected YAMLtoJSON to pass on duplicate field names")
+	}
+	if _, err := YAMLToJSONStrict([]byte(data)); err == nil {
+		t.Error("expected YAMLtoJSONStrict to fail on duplicate field names")
+	}
+}

+ 1 - 1
embed/config.go

@@ -36,9 +36,9 @@ import (
 	"github.com/coreos/etcd/pkg/types"
 	"github.com/coreos/etcd/pkg/types"
 
 
 	"github.com/coreos/pkg/capnslog"
 	"github.com/coreos/pkg/capnslog"
-	"github.com/ghodss/yaml"
 	"google.golang.org/grpc"
 	"google.golang.org/grpc"
 	"google.golang.org/grpc/grpclog"
 	"google.golang.org/grpc/grpclog"
+	"sigs.k8s.io/yaml"
 )
 )
 
 
 const (
 const (

+ 1 - 1
embed/config_test.go

@@ -23,7 +23,7 @@ import (
 
 
 	"github.com/coreos/etcd/pkg/transport"
 	"github.com/coreos/etcd/pkg/transport"
 
 
-	"github.com/ghodss/yaml"
+	"sigs.k8s.io/yaml"
 )
 )
 
 
 func TestConfigFileOtherFields(t *testing.T) {
 func TestConfigFileOtherFields(t *testing.T) {

+ 1 - 1
etcdmain/config.go

@@ -30,7 +30,7 @@ import (
 	"github.com/coreos/etcd/pkg/types"
 	"github.com/coreos/etcd/pkg/types"
 	"github.com/coreos/etcd/version"
 	"github.com/coreos/etcd/version"
 
 
-	"github.com/ghodss/yaml"
+	"sigs.k8s.io/yaml"
 )
 )
 
 
 var (
 var (

+ 1 - 1
etcdmain/config_test.go

@@ -24,7 +24,7 @@ import (
 	"testing"
 	"testing"
 
 
 	"github.com/coreos/etcd/embed"
 	"github.com/coreos/etcd/embed"
-	"github.com/ghodss/yaml"
+	"sigs.k8s.io/yaml"
 )
 )
 
 
 func TestConfigParsingMemberFlags(t *testing.T) {
 func TestConfigParsingMemberFlags(t *testing.T) {

+ 5 - 5
glide.lock

@@ -1,5 +1,5 @@
-hash: f0697416d74e4c0fb9d6471c39c3e005ecdeccc8a864c1b0b65e0087b3242027
-updated: 2018-04-10T23:45:04.40596807-07:00
+hash: e4e6496ba18b18f0f6a2c486f28eb9590571c772ba13cdaefe616b1445807187
+updated: 2019-05-29T20:06:14.737777704+05:30
 imports:
 imports:
 - name: github.com/beorn7/perks
 - name: github.com/beorn7/perks
   version: 3a771d992973f24aa725d07868b467d1ddfceafb
   version: 3a771d992973f24aa725d07868b467d1ddfceafb
@@ -32,8 +32,6 @@ imports:
   version: d2709f9f1f31ebcda9651b03077758c1f3a0018c
   version: d2709f9f1f31ebcda9651b03077758c1f3a0018c
 - name: github.com/dustin/go-humanize
 - name: github.com/dustin/go-humanize
   version: bb3d318650d48840a39aa21a027c6630e198e626
   version: bb3d318650d48840a39aa21a027c6630e198e626
-- name: github.com/ghodss/yaml
-  version: 0ca9ea5df5451ffdf184b4428c902747c2c11cd7
 - name: github.com/gogo/protobuf
 - name: github.com/gogo/protobuf
   version: 342cbe0a04158f6dcb03ca0079991a51a4248c02
   version: 342cbe0a04158f6dcb03ca0079991a51a4248c02
   subpackages:
   subpackages:
@@ -195,5 +193,7 @@ imports:
 - name: gopkg.in/cheggaaa/pb.v1
 - name: gopkg.in/cheggaaa/pb.v1
   version: 226d21d43a305fac52b3a104ef83e721b15275e0
   version: 226d21d43a305fac52b3a104ef83e721b15275e0
 - name: gopkg.in/yaml.v2
 - name: gopkg.in/yaml.v2
-  version: cd8b52f8269e0feb286dfeef29f8fe4d5b397e0b
+  version: 51d6538a90f86fe93ac480b35f37b2be17fef232
+- name: sigs.k8s.io/yaml
+  version: fd68e9863619f6ec2fdd8625fe1f02e7c877e480
 testImports: []
 testImports: []

+ 3 - 3
glide.yaml

@@ -26,8 +26,8 @@ import:
   version: 23709d0847197db6021a51fdb193e66e9222d4e7
   version: 23709d0847197db6021a51fdb193e66e9222d4e7
 - package: github.com/dustin/go-humanize
 - package: github.com/dustin/go-humanize
   version: bb3d318650d48840a39aa21a027c6630e198e626
   version: bb3d318650d48840a39aa21a027c6630e198e626
-- package: github.com/ghodss/yaml
-  version: v1.0.0
+- package: sigs.k8s.io/yaml
+  version: v1.1.0
 - package: github.com/gogo/protobuf
 - package: github.com/gogo/protobuf
   version: v0.5
   version: v0.5
   subpackages:
   subpackages:
@@ -126,7 +126,7 @@ import:
 - package: gopkg.in/cheggaaa/pb.v1
 - package: gopkg.in/cheggaaa/pb.v1
   version: v1.0.2
   version: v1.0.2
 - package: gopkg.in/yaml.v2
 - package: gopkg.in/yaml.v2
-  version: cd8b52f8269e0feb286dfeef29f8fe4d5b397e0b
+  version: 51d6538a90f86fe93ac480b35f37b2be17fef232
 - package: github.com/dgrijalva/jwt-go
 - package: github.com/dgrijalva/jwt-go
   version: v3.0.0
   version: v3.0.0
 - package: google.golang.org/genproto
 - package: google.golang.org/genproto