Unverified Commit 3348f9ae authored by k8s-ci-robot's avatar k8s-ci-robot Committed by GitHub

Merge pull request #69627 from dims/updating-ghodss-yaml-to-latest-version-2

Updating ghodss/yaml and gopkg.in/yaml.v2 to latest version 2
parents 81feb2d0 6b8f2382
...@@ -1556,7 +1556,7 @@ ...@@ -1556,7 +1556,7 @@
}, },
{ {
"ImportPath": "github.com/ghodss/yaml", "ImportPath": "github.com/ghodss/yaml",
"Rev": "73d445a93680fa1a78ae23a5839bad48f32ba1ee" "Rev": "c7ce16629ff4cd059ed96ed06419dd3856fd3577"
}, },
{ {
"ImportPath": "github.com/go-ini/ini", "ImportPath": "github.com/go-ini/ini",
...@@ -3811,7 +3811,7 @@ ...@@ -3811,7 +3811,7 @@
}, },
{ {
"ImportPath": "gopkg.in/yaml.v2", "ImportPath": "gopkg.in/yaml.v2",
"Rev": "670d4cfef0544295bc27a114dbac37980d83185a" "Rev": "5420a8b6744d3b0345ab293f6fcba19c978f1183"
}, },
{ {
"ImportPath": "k8s.io/gengo/args", "ImportPath": "k8s.io/gengo/args",
......
...@@ -2,7 +2,7 @@ apiVersion: v1 ...@@ -2,7 +2,7 @@ apiVersion: v1
kind: Pod kind: Pod
metadata: metadata:
name: sorted-pod1 name: sorted-pod1
creationTimestamp: 2018-08-30T14:10:58Z creationTimestamp: "2018-08-30T14:10:58Z"
labels: labels:
name: sorted-pod3-label name: sorted-pod3-label
spec: spec:
......
...@@ -2,7 +2,7 @@ apiVersion: v1 ...@@ -2,7 +2,7 @@ apiVersion: v1
kind: Pod kind: Pod
metadata: metadata:
name: sorted-pod2 name: sorted-pod2
creationTimestamp: 2018-08-30T14:10:55Z creationTimestamp: "2018-08-30T14:10:55Z"
labels: labels:
name: sorted-pod2-label name: sorted-pod2-label
spec: spec:
......
...@@ -2,7 +2,7 @@ apiVersion: v1 ...@@ -2,7 +2,7 @@ apiVersion: v1
kind: Pod kind: Pod
metadata: metadata:
name: sorted-pod3 name: sorted-pod3
creationTimestamp: 2018-08-30T14:10:53Z creationTimestamp: "2018-08-30T14:10:53Z"
labels: labels:
name: sorted-pod1-label name: sorted-pod1-label
spec: spec:
......
...@@ -244,6 +244,29 @@ func TestEncodePtr(t *testing.T) { ...@@ -244,6 +244,29 @@ func TestEncodePtr(t *testing.T) {
} }
} }
func TestDecodeTimeStampWithoutQuotes(t *testing.T) {
testYAML := []byte(`
apiVersion: v1
kind: Pod
metadata:
creationTimestamp: 2018-08-30T14:10:58Z
name: test
spec:
containers: null
status: {}`)
if obj, err := runtime.Decode(testapi.Default.Codec(), testYAML); err != nil {
t.Fatalf("unable to decode yaml: %v", err)
} else {
if obj2, ok := obj.(*api.Pod); !ok {
t.Fatalf("Got wrong type")
} else {
if obj2.ObjectMeta.CreationTimestamp.UnixNano() != parseTimeOrDie("2018-08-30T14:10:58Z").UnixNano() {
t.Fatalf("Time stamps do not match")
}
}
}
}
// TestBadJSONRejection establishes that a JSON object without a kind or with // TestBadJSONRejection establishes that a JSON object without a kind or with
// an unknown kind will not be decoded without error. // an unknown kind will not be decoded without error.
func TestBadJSONRejection(t *testing.T) { func TestBadJSONRejection(t *testing.T) {
......
# Please edit the 'last-applied-configuration' annotations below. # Please edit the 'last-applied-configuration' annotations below.
# Lines beginning with a '#' will be ignored, and an empty file will abort the edit. # Lines beginning with a '#' will be ignored, and an empty file will abort the edit.
# #
# The edited file had a syntax error: error converting YAML to JSON: yaml: line 12: could not find expected ':' # The edited file had a syntax error: error converting YAML to JSON: yaml: line 13: could not find expected ':'
# #
kind: Service kind: Service
metadata: metadata:
......
# Please edit the 'last-applied-configuration' annotations below. # Please edit the 'last-applied-configuration' annotations below.
# Lines beginning with a '#' will be ignored, and an empty file will abort the edit. # Lines beginning with a '#' will be ignored, and an empty file will abort the edit.
# #
# The edited file had a syntax error: error parsing edited-file: error converting YAML to JSON: yaml: line 12: could not find expected ':' # The edited file had a syntax error: error parsing edited-file: error converting YAML to JSON: yaml: line 13: could not find expected ':'
# #
kind: Service kind: Service
metadata: metadata:
......
...@@ -5,7 +5,7 @@ apiVersion: v1 ...@@ -5,7 +5,7 @@ apiVersion: v1
kind: Service kind: Service
metadata: metadata:
annotations: {} annotations: {}
creationTimestamp: 2017-02-01T21:14:09Z creationTimestamp: "2017-02-01T21:14:09Z"
labels: labels:
app: svc1 app: svc1
new-label: new-value new-label: new-value
......
...@@ -5,7 +5,7 @@ apiVersion: v1 ...@@ -5,7 +5,7 @@ apiVersion: v1
kind: Service kind: Service
metadata: metadata:
annotations: {} annotations: {}
creationTimestamp: 2017-02-01T21:14:09Z creationTimestamp: "2017-02-01T21:14:09Z"
labels: labels:
app: svc1 app: svc1
new-label: new-value new-label: new-value
......
...@@ -5,7 +5,7 @@ ...@@ -5,7 +5,7 @@
apiVersion: v1 apiVersion: v1
kind: Service kind: Service
metadata: metadata:
creationTimestamp: 2017-02-03T06:44:47Z creationTimestamp: "2017-02-03T06:44:47Z"
labels: labels:
app: svc1modified app: svc1modified
name: svc1 name: svc1
......
...@@ -5,7 +5,7 @@ ...@@ -5,7 +5,7 @@
apiVersion: v1 apiVersion: v1
kind: Service kind: Service
metadata: metadata:
creationTimestamp: 2017-02-03T06:44:47Z creationTimestamp: "2017-02-03T06:44:47Z"
labels: labels:
app: svc1 app: svc1
name: svc1 name: svc1
......
...@@ -5,7 +5,7 @@ ...@@ -5,7 +5,7 @@
apiVersion: v1 apiVersion: v1
kind: Service kind: Service
metadata: metadata:
creationTimestamp: 2017-02-03T06:44:43Z creationTimestamp: "2017-02-03T06:44:43Z"
labels: labels:
app: svc2modified app: svc2modified
name: svc2 name: svc2
......
...@@ -5,7 +5,7 @@ ...@@ -5,7 +5,7 @@
apiVersion: v1 apiVersion: v1
kind: Service kind: Service
metadata: metadata:
creationTimestamp: 2017-02-03T06:44:43Z creationTimestamp: "2017-02-03T06:44:43Z"
labels: labels:
app: svc2 app: svc2
name: svc2 name: svc2
......
...@@ -3,7 +3,7 @@ items: ...@@ -3,7 +3,7 @@ items:
- apiVersion: v1 - apiVersion: v1
kind: Service kind: Service
metadata: metadata:
creationTimestamp: 2017-02-03T06:44:47Z creationTimestamp: "2017-02-03T06:44:47Z"
labels: labels:
app: svc1 app: svc1
name: svc1 name: svc1
...@@ -27,7 +27,7 @@ items: ...@@ -27,7 +27,7 @@ items:
- apiVersion: v1 - apiVersion: v1
kind: Service kind: Service
metadata: metadata:
creationTimestamp: 2017-02-03T06:44:43Z creationTimestamp: "2017-02-03T06:44:43Z"
labels: labels:
app: svc2 app: svc2
name: svc2 name: svc2
......
...@@ -5,7 +5,7 @@ ...@@ -5,7 +5,7 @@
apiVersion: v1 apiVersion: v1
kind: Service kind: Service
metadata: metadata:
creationTimestamp: 2017-02-01T21:14:09Z creationTimestamp: "2017-02-01T21:14:09Z"
labels: labels:
app: svc1 app: svc1
new-label: new-value new-label: new-value
......
...@@ -5,7 +5,7 @@ ...@@ -5,7 +5,7 @@
apiVersion: v1 apiVersion: v1
kind: Service kind: Service
metadata: metadata:
creationTimestamp: 2017-02-01T21:14:09Z creationTimestamp: "2017-02-01T21:14:09Z"
labels: labels:
app: svc1 app: svc1
new-label: new-value new-label: new-value
......
...@@ -9,7 +9,7 @@ ...@@ -9,7 +9,7 @@
apiVersion: v1 apiVersion: v1
kind: Service kind: Service
metadata: metadata:
creationTimestamp: 2017-02-01T21:14:09Z creationTimestamp: "2017-02-01T21:14:09Z"
labels: labels:
app: svc1 app: svc1
new-label: new-value new-label: new-value
......
...@@ -9,7 +9,7 @@ ...@@ -9,7 +9,7 @@
apiVersion: v1 apiVersion: v1
kind: Service kind: Service
metadata: metadata:
creationTimestamp: 2017-02-01T21:14:09Z creationTimestamp: "2017-02-01T21:14:09Z"
labels: labels:
app: svc1 app: svc1
new-label: new-value new-label: new-value
......
...@@ -8,7 +8,7 @@ metadata: ...@@ -8,7 +8,7 @@ metadata:
annotations: annotations:
kubectl.kubernetes.io/last-applied-configuration: | kubectl.kubernetes.io/last-applied-configuration: |
{"kind":"Service","apiVersion":"v1","metadata":{"name":"svc1","creationTimestamp":null,"labels":{"app":"svc1"}},"spec":{"ports":[{"name":"80","protocol":"TCP","port":80,"targetPort":80}],"selector":{"app":"svc1"},"type":"ClusterIP"},"status":{"loadBalancer":{}}} {"kind":"Service","apiVersion":"v1","metadata":{"name":"svc1","creationTimestamp":null,"labels":{"app":"svc1"}},"spec":{"ports":[{"name":"80","protocol":"TCP","port":80,"targetPort":80}],"selector":{"app":"svc1"},"type":"ClusterIP"},"status":{"loadBalancer":{}}}
creationTimestamp: 2017-02-27T19:40:53Z creationTimestamp: "2017-02-27T19:40:53Z"
labels: labels:
app: svc1 app: svc1
new-label: new-value new-label: new-value
......
...@@ -8,7 +8,7 @@ metadata: ...@@ -8,7 +8,7 @@ metadata:
annotations: annotations:
kubectl.kubernetes.io/last-applied-configuration: | kubectl.kubernetes.io/last-applied-configuration: |
{"kind":"Service","apiVersion":"v1","metadata":{"name":"svc1","creationTimestamp":null,"labels":{"app":"svc1"}},"spec":{"ports":[{"name":"80","protocol":"TCP","port":80,"targetPort":80}],"selector":{"app":"svc1"},"type":"ClusterIP"},"status":{"loadBalancer":{}}} {"kind":"Service","apiVersion":"v1","metadata":{"name":"svc1","creationTimestamp":null,"labels":{"app":"svc1"}},"spec":{"ports":[{"name":"80","protocol":"TCP","port":80,"targetPort":80}],"selector":{"app":"svc1"},"type":"ClusterIP"},"status":{"loadBalancer":{}}}
creationTimestamp: 2017-02-27T19:40:53Z creationTimestamp: "2017-02-27T19:40:53Z"
labels: labels:
app: svc1 app: svc1
name: svc1 name: svc1
......
...@@ -8,7 +8,7 @@ data: ...@@ -8,7 +8,7 @@ data:
foo: changed-value2 foo: changed-value2
kind: ConfigMap kind: ConfigMap
metadata: metadata:
creationTimestamp: 2017-02-03T06:12:07Z creationTimestamp: "2017-02-03T06:12:07Z"
name: cm1-modified name: cm1-modified
namespace: edit-test namespace: edit-test
resourceVersion: "2071" resourceVersion: "2071"
......
...@@ -8,7 +8,7 @@ data: ...@@ -8,7 +8,7 @@ data:
foo: changed-value2 foo: changed-value2
kind: ConfigMap kind: ConfigMap
metadata: metadata:
creationTimestamp: 2017-02-03T06:12:07Z creationTimestamp: "2017-02-03T06:12:07Z"
name: cm1 name: cm1
namespace: edit-test namespace: edit-test
resourceVersion: "2071" resourceVersion: "2071"
......
...@@ -7,7 +7,7 @@ items: ...@@ -7,7 +7,7 @@ items:
- apiVersion: v1 - apiVersion: v1
kind: Service kind: Service
metadata: metadata:
creationTimestamp: 2017-02-03T06:11:32Z creationTimestamp: "2017-02-03T06:11:32Z"
labels: labels:
app: svc1 app: svc1
name: svc1 name: svc1
...@@ -32,7 +32,7 @@ items: ...@@ -32,7 +32,7 @@ items:
foo: changed-value2 foo: changed-value2
kind: ConfigMap kind: ConfigMap
metadata: metadata:
creationTimestamp: 2017-02-03T06:12:07Z creationTimestamp: "2017-02-03T06:12:07Z"
name: cm1 name: cm1
namespace: edit-test namespace: edit-test
resourceVersion: "1903" resourceVersion: "1903"
......
...@@ -10,7 +10,7 @@ items: ...@@ -10,7 +10,7 @@ items:
foo: changed-value foo: changed-value
kind: ConfigMap kind: ConfigMap
metadata: metadata:
creationTimestamp: 2017-02-03T06:12:07Z creationTimestamp: "2017-02-03T06:12:07Z"
name: cm1 name: cm1
namespace: edit-test namespace: edit-test
resourceVersion: "1903" resourceVersion: "1903"
...@@ -19,7 +19,7 @@ items: ...@@ -19,7 +19,7 @@ items:
- apiVersion: v1 - apiVersion: v1
kind: Service kind: Service
metadata: metadata:
creationTimestamp: 2017-02-03T06:11:32Z creationTimestamp: "2017-02-03T06:11:32Z"
labels: labels:
app: svc1 app: svc1
name: svc1 name: svc1
......
...@@ -11,7 +11,7 @@ items: ...@@ -11,7 +11,7 @@ items:
- apiVersion: v1 - apiVersion: v1
kind: Service kind: Service
metadata: metadata:
creationTimestamp: 2017-02-03T06:11:32Z creationTimestamp: "2017-02-03T06:11:32Z"
labels: labels:
app: svc1 app: svc1
newvalue: modified newvalue: modified
...@@ -37,7 +37,7 @@ items: ...@@ -37,7 +37,7 @@ items:
foo: changed-value2 foo: changed-value2
kind: ConfigMap kind: ConfigMap
metadata: metadata:
creationTimestamp: 2017-02-03T06:12:07Z creationTimestamp: "2017-02-03T06:12:07Z"
name: cm1 name: cm1
namespace: edit-test namespace: edit-test
resourceVersion: "1903" resourceVersion: "1903"
......
...@@ -11,7 +11,7 @@ items: ...@@ -11,7 +11,7 @@ items:
- apiVersion: v1 - apiVersion: v1
kind: Service kind: Service
metadata: metadata:
creationTimestamp: 2017-02-03T06:11:32Z creationTimestamp: "2017-02-03T06:11:32Z"
labels: labels:
app: svc1 app: svc1
name: svc1 name: svc1
...@@ -36,7 +36,7 @@ items: ...@@ -36,7 +36,7 @@ items:
foo: changed-value2 foo: changed-value2
kind: ConfigMap kind: ConfigMap
metadata: metadata:
creationTimestamp: 2017-02-03T06:12:07Z creationTimestamp: "2017-02-03T06:12:07Z"
name: cm1 name: cm1
namespace: edit-test namespace: edit-test
resourceVersion: "1903" resourceVersion: "1903"
......
...@@ -10,7 +10,7 @@ items: ...@@ -10,7 +10,7 @@ items:
- apiVersion: v1 - apiVersion: v1
kind: Service kind: Service
metadata: metadata:
creationTimestamp: 2017-02-03T06:11:32Z creationTimestamp: "2017-02-03T06:11:32Z"
labels: labels:
app: svc1 app: svc1
newvalue: modified newvalue: modified
...@@ -36,7 +36,7 @@ items: ...@@ -36,7 +36,7 @@ items:
foo: changed-value2 foo: changed-value2
kind: ConfigMap kind: ConfigMap
metadata: metadata:
creationTimestamp: 2017-02-03T06:12:07Z creationTimestamp: "2017-02-03T06:12:07Z"
name: cm1 name: cm1
namespace: edit-test namespace: edit-test
resourceVersion: "1903" resourceVersion: "1903"
......
...@@ -10,7 +10,7 @@ items: ...@@ -10,7 +10,7 @@ items:
- apiVersion: v1 - apiVersion: v1
kind: Service kind: Service
metadata: metadata:
creationTimestamp: 2017-02-03T06:11:32Z creationTimestamp: "2017-02-03T06:11:32Z"
labels: labels:
app: svc1 app: svc1
newvalue: modified newvalue: modified
...@@ -36,7 +36,7 @@ items: ...@@ -36,7 +36,7 @@ items:
foo: changed-value2 foo: changed-value2
kind: ConfigMap kind: ConfigMap
metadata: metadata:
creationTimestamp: 2017-02-03T06:12:07Z creationTimestamp: "2017-02-03T06:12:07Z"
name: cm1 name: cm1
namespace: edit-test namespace: edit-test
resourceVersion: "1903" resourceVersion: "1903"
......
...@@ -15,7 +15,7 @@ items: ...@@ -15,7 +15,7 @@ items:
metadata: metadata:
annotations: annotations:
kubernetes.io/change-cause: original creating command a kubernetes.io/change-cause: original creating command a
creationTimestamp: 2017-02-03T06:12:07Z creationTimestamp: "2017-02-03T06:12:07Z"
name: cm1 name: cm1
namespace: edit-test namespace: edit-test
resourceVersion: "1414" resourceVersion: "1414"
...@@ -26,7 +26,7 @@ items: ...@@ -26,7 +26,7 @@ items:
metadata: metadata:
annotations: annotations:
kubernetes.io/change-cause: original creating command b kubernetes.io/change-cause: original creating command b
creationTimestamp: 2017-02-03T06:11:32Z creationTimestamp: "2017-02-03T06:11:32Z"
labels: labels:
app: svc1 app: svc1
new-label: foo new-label: foo
......
...@@ -14,7 +14,7 @@ items: ...@@ -14,7 +14,7 @@ items:
metadata: metadata:
annotations: annotations:
kubernetes.io/change-cause: original creating command a kubernetes.io/change-cause: original creating command a
creationTimestamp: 2017-02-03T06:12:07Z creationTimestamp: "2017-02-03T06:12:07Z"
name: cm1 name: cm1
namespace: edit-test namespace: edit-test
resourceVersion: "1414" resourceVersion: "1414"
...@@ -25,7 +25,7 @@ items: ...@@ -25,7 +25,7 @@ items:
metadata: metadata:
annotations: annotations:
kubernetes.io/change-cause: original creating command b kubernetes.io/change-cause: original creating command b
creationTimestamp: 2017-02-03T06:11:32Z creationTimestamp: "2017-02-03T06:11:32Z"
labels: labels:
app: svc1 app: svc1
new-label: foo new-label: foo
......
...@@ -13,7 +13,7 @@ items: ...@@ -13,7 +13,7 @@ items:
new-data3: newivalue new-data3: newivalue
kind: ConfigMap kind: ConfigMap
metadata: metadata:
creationTimestamp: 2017-02-03T06:12:07Z creationTimestamp: "2017-02-03T06:12:07Z"
name: cm1 name: cm1
namespace: edit-test namespace: edit-test
resourceVersion: "1414" resourceVersion: "1414"
...@@ -22,7 +22,7 @@ items: ...@@ -22,7 +22,7 @@ items:
- apiVersion: v1 - apiVersion: v1
kind: Service kind: Service
metadata: metadata:
creationTimestamp: 2017-02-03T06:11:32Z creationTimestamp: "2017-02-03T06:11:32Z"
labels: labels:
app: svc1 app: svc1
new-label: foo new-label: foo
......
...@@ -12,7 +12,7 @@ items: ...@@ -12,7 +12,7 @@ items:
new-data2: new-value new-data2: new-value
kind: ConfigMap kind: ConfigMap
metadata: metadata:
creationTimestamp: 2017-02-03T06:12:07Z creationTimestamp: "2017-02-03T06:12:07Z"
name: cm1 name: cm1
namespace: edit-test namespace: edit-test
resourceVersion: "1414" resourceVersion: "1414"
...@@ -21,7 +21,7 @@ items: ...@@ -21,7 +21,7 @@ items:
- apiVersion: v1 - apiVersion: v1
kind: Service kind: Service
metadata: metadata:
creationTimestamp: 2017-02-03T06:11:32Z creationTimestamp: "2017-02-03T06:11:32Z"
labels: labels:
app: svc1 app: svc1
new-label: foo new-label: foo
......
...@@ -5,7 +5,7 @@ ...@@ -5,7 +5,7 @@
apiVersion: v1 apiVersion: v1
kind: ConfigMap kind: ConfigMap
metadata: metadata:
creationTimestamp: 2017-02-03T05:59:00Z creationTimestamp: "2017-02-03T05:59:00Z"
name: mymap name: mymap
namespace: default namespace: default
resourceVersion: "149" resourceVersion: "149"
......
...@@ -5,7 +5,7 @@ ...@@ -5,7 +5,7 @@
apiVersion: v1 apiVersion: v1
kind: ConfigMap kind: ConfigMap
metadata: metadata:
creationTimestamp: 2017-02-03T05:59:00Z creationTimestamp: "2017-02-03T05:59:00Z"
name: mymap name: mymap
namespace: default namespace: default
resourceVersion: "149" resourceVersion: "149"
......
...@@ -8,7 +8,7 @@ metadata: ...@@ -8,7 +8,7 @@ metadata:
annotations: annotations:
kubectl.kubernetes.io/last-applied-configuration: | kubectl.kubernetes.io/last-applied-configuration: |
{"kind":"Service","apiVersion":"v1","metadata":{"name":"svc1","creationTimestamp":null,"labels":{"app":"svc1"}},"spec":{"ports":[{"name":"80","protocol":"TCP","port":80,"targetPort":80}],"selector":{"app":"svc1"},"type":"ClusterIP"},"status":{"loadBalancer":{}}} {"kind":"Service","apiVersion":"v1","metadata":{"name":"svc1","creationTimestamp":null,"labels":{"app":"svc1"}},"spec":{"ports":[{"name":"80","protocol":"TCP","port":80,"targetPort":80}],"selector":{"app":"svc1"},"type":"ClusterIP"},"status":{"loadBalancer":{}}}
creationTimestamp: 2017-02-27T19:40:53Z creationTimestamp: "2017-02-27T19:40:53Z"
labels: labels:
app: svc1 app: svc1
new-label: new-value new-label: new-value
......
...@@ -8,7 +8,7 @@ metadata: ...@@ -8,7 +8,7 @@ metadata:
annotations: annotations:
kubectl.kubernetes.io/last-applied-configuration: | kubectl.kubernetes.io/last-applied-configuration: |
{"kind":"Service","apiVersion":"v1","metadata":{"name":"svc1","creationTimestamp":null,"labels":{"app":"svc1"}},"spec":{"ports":[{"name":"80","protocol":"TCP","port":80,"targetPort":80}],"selector":{"app":"svc1"},"type":"ClusterIP"},"status":{"loadBalancer":{}}} {"kind":"Service","apiVersion":"v1","metadata":{"name":"svc1","creationTimestamp":null,"labels":{"app":"svc1"}},"spec":{"ports":[{"name":"80","protocol":"TCP","port":80,"targetPort":80}],"selector":{"app":"svc1"},"type":"ClusterIP"},"status":{"loadBalancer":{}}}
creationTimestamp: 2017-02-27T19:40:53Z creationTimestamp: "2017-02-27T19:40:53Z"
labels: labels:
app: svc1 app: svc1
name: svc1 name: svc1
......
...@@ -5,7 +5,7 @@ ...@@ -5,7 +5,7 @@
apiVersion: v1 apiVersion: v1
kind: Service kind: Service
metadata: metadata:
creationTimestamp: 2017-02-12T20:11:19Z creationTimestamp: "2017-02-12T20:11:19Z"
labels: labels:
component: apiserver component: apiserver
provider: kubernetes provider: kubernetes
......
...@@ -5,7 +5,7 @@ ...@@ -5,7 +5,7 @@
apiVersion: v1 apiVersion: v1
kind: Service kind: Service
metadata: metadata:
creationTimestamp: 2017-02-12T20:11:19Z creationTimestamp: "2017-02-12T20:11:19Z"
labels: labels:
component: apiserver component: apiserver
provider: kubernetes provider: kubernetes
......
...@@ -9,7 +9,7 @@ ...@@ -9,7 +9,7 @@
apiVersion: v1 apiVersion: v1
kind: Service kind: Service
metadata: metadata:
creationTimestamp: 2017-02-12T20:11:19Z creationTimestamp: "2017-02-12T20:11:19Z"
labels: labels:
component: apiserver component: apiserver
provider: kubernetes provider: kubernetes
......
...@@ -9,7 +9,7 @@ ...@@ -9,7 +9,7 @@
apiVersion: v1 apiVersion: v1
kind: Service kind: Service
metadata: metadata:
creationTimestamp: 2017-02-12T20:11:19Z creationTimestamp: "2017-02-12T20:11:19Z"
labels: labels:
component: apiserver component: apiserver
provider: kubernetes provider: kubernetes
......
...@@ -7,7 +7,7 @@ items: ...@@ -7,7 +7,7 @@ items:
- apiVersion: v1 - apiVersion: v1
kind: Service kind: Service
metadata: metadata:
creationTimestamp: 2017-02-12T20:11:19Z creationTimestamp: "2017-02-12T20:11:19Z"
labels: labels:
component: apiserver component: apiserver
provider: kubernetes provider: kubernetes
...@@ -31,7 +31,7 @@ items: ...@@ -31,7 +31,7 @@ items:
- apiVersion: company.com/v1 - apiVersion: company.com/v1
kind: Bar kind: Bar
metadata: metadata:
creationTimestamp: 2017-02-13T00:47:26Z creationTimestamp: "2017-02-13T00:47:26Z"
name: test name: test
namespace: default namespace: default
resourceVersion: "16954" resourceVersion: "16954"
...@@ -52,7 +52,7 @@ items: ...@@ -52,7 +52,7 @@ items:
b: false b: false
kind: Bar kind: Bar
metadata: metadata:
creationTimestamp: 2017-02-13T00:50:10Z creationTimestamp: "2017-02-13T00:50:10Z"
name: test2 name: test2
namespace: default namespace: default
resourceVersion: "16955" resourceVersion: "16955"
......
...@@ -7,7 +7,7 @@ items: ...@@ -7,7 +7,7 @@ items:
- apiVersion: v1 - apiVersion: v1
kind: Service kind: Service
metadata: metadata:
creationTimestamp: 2017-02-12T20:11:19Z creationTimestamp: "2017-02-12T20:11:19Z"
labels: labels:
component: apiserver component: apiserver
provider: kubernetes provider: kubernetes
...@@ -30,7 +30,7 @@ items: ...@@ -30,7 +30,7 @@ items:
- apiVersion: company.com/v1 - apiVersion: company.com/v1
kind: Bar kind: Bar
metadata: metadata:
creationTimestamp: 2017-02-13T00:47:26Z creationTimestamp: "2017-02-13T00:47:26Z"
name: test name: test
namespace: default namespace: default
resourceVersion: "16954" resourceVersion: "16954"
...@@ -49,7 +49,7 @@ items: ...@@ -49,7 +49,7 @@ items:
b: false b: false
kind: Bar kind: Bar
metadata: metadata:
creationTimestamp: 2017-02-13T00:50:10Z creationTimestamp: "2017-02-13T00:50:10Z"
name: test2 name: test2
namespace: default namespace: default
resourceVersion: "16955" resourceVersion: "16955"
......
...@@ -5,7 +5,7 @@ ...@@ -5,7 +5,7 @@
apiVersion: v1 apiVersion: v1
kind: Service kind: Service
metadata: metadata:
creationTimestamp: 2017-02-01T21:14:09Z creationTimestamp: "2017-02-01T21:14:09Z"
labels: labels:
app: svc1 app: svc1
new-label: new-value new-label: new-value
......
...@@ -5,7 +5,7 @@ ...@@ -5,7 +5,7 @@
apiVersion: v1 apiVersion: v1
kind: Service kind: Service
metadata: metadata:
creationTimestamp: 2017-02-01T21:14:09Z creationTimestamp: "2017-02-01T21:14:09Z"
labels: labels:
app: svc1 app: svc1
name: svc1 name: svc1
......
...@@ -5,7 +5,7 @@ ...@@ -5,7 +5,7 @@
apiVersion: v1 apiVersion: v1
kind: Service kind: Service
metadata: metadata:
creationTimestamp: 2017-02-12T20:11:19Z creationTimestamp: "2017-02-12T20:11:19Z"
labels: labels:
component: apiserver component: apiserver
provider: kubernetes provider: kubernetes
......
...@@ -5,7 +5,7 @@ ...@@ -5,7 +5,7 @@
apiVersion: v1 apiVersion: v1
kind: Service kind: Service
metadata: metadata:
creationTimestamp: 2017-02-12T20:11:19Z creationTimestamp: "2017-02-12T20:11:19Z"
labels: labels:
component: apiserver component: apiserver
provider: kubernetes provider: kubernetes
......
...@@ -7,7 +7,7 @@ ...@@ -7,7 +7,7 @@
apiVersion: v1 apiVersion: v1
kind: Service kind: Service
metadata: metadata:
creationTimestamp: 2017-02-12T20:11:19Z creationTimestamp: "2017-02-12T20:11:19Z"
labels: labels:
component: apiserver component: apiserver
provider: kubernetes provider: kubernetes
......
...@@ -2,12 +2,12 @@ ...@@ -2,12 +2,12 @@
# and an empty file will abort the edit. If an error occurs while saving this file will be # and an empty file will abort the edit. If an error occurs while saving this file will be
# reopened with the relevant failures. # reopened with the relevant failures.
# #
# The edited file had a syntax error: error parsing edited-file: error converting YAML to JSON: yaml: line 17: could not find expected ':' # The edited file had a syntax error: error parsing edited-file: error converting YAML to JSON: yaml: line 18: could not find expected ':'
# #
apiVersion: v1 apiVersion: v1
kind: Service kind: Service
metadata: metadata:
creationTimestamp: 2017-02-12T20:11:19Z creationTimestamp: "2017-02-12T20:11:19Z"
labels: labels:
component: apiserver component: apiserver
provider: kubernetes provider: kubernetes
......
...@@ -5,7 +5,7 @@ ...@@ -5,7 +5,7 @@
apiVersion: storage.k8s.io/v1beta1 apiVersion: storage.k8s.io/v1beta1
kind: StorageClass kind: StorageClass
metadata: metadata:
creationTimestamp: 2017-02-13T02:04:04Z creationTimestamp: "2017-02-13T02:04:04Z"
labels: labels:
label1: value1 label1: value1
label2: value2 label2: value2
......
...@@ -5,7 +5,7 @@ ...@@ -5,7 +5,7 @@
apiVersion: storage.k8s.io/v1beta1 apiVersion: storage.k8s.io/v1beta1
kind: StorageClass kind: StorageClass
metadata: metadata:
creationTimestamp: 2017-02-13T02:04:04Z creationTimestamp: "2017-02-13T02:04:04Z"
labels: labels:
label1: value1 label1: value1
name: foo name: foo
......
...@@ -8,7 +8,7 @@ extraField: ...@@ -8,7 +8,7 @@ extraField:
addedData: "foo" addedData: "foo"
kind: StorageClass kind: StorageClass
metadata: metadata:
creationTimestamp: 2017-02-13T02:04:04Z creationTimestamp: "2017-02-13T02:04:04Z"
labels: labels:
label1: value1 label1: value1
label2: value2 label2: value2
......
...@@ -7,7 +7,7 @@ extraField: ...@@ -7,7 +7,7 @@ extraField:
otherData: true otherData: true
kind: StorageClass kind: StorageClass
metadata: metadata:
creationTimestamp: 2017-02-13T02:04:04Z creationTimestamp: "2017-02-13T02:04:04Z"
labels: labels:
label1: value1 label1: value1
name: foo name: foo
......
...@@ -8,7 +8,7 @@ metadata: ...@@ -8,7 +8,7 @@ metadata:
annotations: annotations:
kubectl.kubernetes.io/last-applied-configuration: | kubectl.kubernetes.io/last-applied-configuration: |
{"kind":"Service","apiVersion":"v1","metadata":{"name":"svc1","creationTimestamp":null,"labels":{"app":"svc1"}},"spec":{"ports":[{"name":"80","protocol":"TCP","port":80,"targetPort":80}],"selector":{"app":"svc1"},"type":"ClusterIP"},"status":{"loadBalancer":{}}} {"kind":"Service","apiVersion":"v1","metadata":{"name":"svc1","creationTimestamp":null,"labels":{"app":"svc1"}},"spec":{"ports":[{"name":"80","protocol":"TCP","port":80,"targetPort":80}],"selector":{"app":"svc1"},"type":"ClusterIP"},"status":{"loadBalancer":{}}}
creationTimestamp: 2017-02-27T19:40:53Z creationTimestamp: "2017-02-27T19:40:53Z"
labels: labels:
app: svc1 app: svc1
new-label: new-value new-label: new-value
......
...@@ -8,7 +8,7 @@ metadata: ...@@ -8,7 +8,7 @@ metadata:
annotations: annotations:
kubectl.kubernetes.io/last-applied-configuration: | kubectl.kubernetes.io/last-applied-configuration: |
{"kind":"Service","apiVersion":"v1","metadata":{"name":"svc1","creationTimestamp":null,"labels":{"app":"svc1"}},"spec":{"ports":[{"name":"80","protocol":"TCP","port":80,"targetPort":80}],"selector":{"app":"svc1"},"type":"ClusterIP"},"status":{"loadBalancer":{}}} {"kind":"Service","apiVersion":"v1","metadata":{"name":"svc1","creationTimestamp":null,"labels":{"app":"svc1"}},"spec":{"ports":[{"name":"80","protocol":"TCP","port":80,"targetPort":80}],"selector":{"app":"svc1"},"type":"ClusterIP"},"status":{"loadBalancer":{}}}
creationTimestamp: 2017-02-27T19:40:53Z creationTimestamp: "2017-02-27T19:40:53Z"
labels: labels:
app: svc1 app: svc1
name: svc1 name: svc1
......
...@@ -257,8 +257,12 @@ func testPrinter(t *testing.T, printer printers.ResourcePrinter, unmarshalFunc f ...@@ -257,8 +257,12 @@ func testPrinter(t *testing.T, printer printers.ResourcePrinter, unmarshalFunc f
} }
} }
func yamlUnmarshal(data []byte, v interface{}) error {
return yaml.Unmarshal(data, v)
}
func TestYAMLPrinter(t *testing.T) { func TestYAMLPrinter(t *testing.T) {
testPrinter(t, genericprinters.NewTypeSetter(legacyscheme.Scheme).ToPrinter(&genericprinters.YAMLPrinter{}), yaml.Unmarshal) testPrinter(t, genericprinters.NewTypeSetter(legacyscheme.Scheme).ToPrinter(&genericprinters.YAMLPrinter{}), yamlUnmarshal)
} }
func TestJSONPrinter(t *testing.T) { func TestJSONPrinter(t *testing.T) {
......
...@@ -12,7 +12,7 @@ ...@@ -12,7 +12,7 @@
}, },
{ {
"ImportPath": "github.com/ghodss/yaml", "ImportPath": "github.com/ghodss/yaml",
"Rev": "73d445a93680fa1a78ae23a5839bad48f32ba1ee" "Rev": "c7ce16629ff4cd059ed96ed06419dd3856fd3577"
}, },
{ {
"ImportPath": "github.com/gogo/protobuf/proto", "ImportPath": "github.com/gogo/protobuf/proto",
...@@ -100,7 +100,7 @@ ...@@ -100,7 +100,7 @@
}, },
{ {
"ImportPath": "gopkg.in/yaml.v2", "ImportPath": "gopkg.in/yaml.v2",
"Rev": "670d4cfef0544295bc27a114dbac37980d83185a" "Rev": "5420a8b6744d3b0345ab293f6fcba19c978f1183"
}, },
{ {
"ImportPath": "k8s.io/apimachinery/pkg/api/apitesting", "ImportPath": "k8s.io/apimachinery/pkg/api/apitesting",
......
...@@ -388,7 +388,7 @@ ...@@ -388,7 +388,7 @@
}, },
{ {
"ImportPath": "github.com/ghodss/yaml", "ImportPath": "github.com/ghodss/yaml",
"Rev": "73d445a93680fa1a78ae23a5839bad48f32ba1ee" "Rev": "c7ce16629ff4cd059ed96ed06419dd3856fd3577"
}, },
{ {
"ImportPath": "github.com/go-openapi/analysis", "ImportPath": "github.com/go-openapi/analysis",
...@@ -856,7 +856,7 @@ ...@@ -856,7 +856,7 @@
}, },
{ {
"ImportPath": "gopkg.in/yaml.v2", "ImportPath": "gopkg.in/yaml.v2",
"Rev": "670d4cfef0544295bc27a114dbac37980d83185a" "Rev": "5420a8b6744d3b0345ab293f6fcba19c978f1183"
}, },
{ {
"ImportPath": "k8s.io/api/admission/v1beta1", "ImportPath": "k8s.io/api/admission/v1beta1",
......
...@@ -28,7 +28,7 @@ ...@@ -28,7 +28,7 @@
}, },
{ {
"ImportPath": "github.com/ghodss/yaml", "ImportPath": "github.com/ghodss/yaml",
"Rev": "73d445a93680fa1a78ae23a5839bad48f32ba1ee" "Rev": "c7ce16629ff4cd059ed96ed06419dd3856fd3577"
}, },
{ {
"ImportPath": "github.com/gogo/protobuf/proto", "ImportPath": "github.com/gogo/protobuf/proto",
...@@ -176,7 +176,7 @@ ...@@ -176,7 +176,7 @@
}, },
{ {
"ImportPath": "gopkg.in/yaml.v2", "ImportPath": "gopkg.in/yaml.v2",
"Rev": "670d4cfef0544295bc27a114dbac37980d83185a" "Rev": "5420a8b6744d3b0345ab293f6fcba19c978f1183"
}, },
{ {
"ImportPath": "k8s.io/kube-openapi/pkg/util/proto", "ImportPath": "k8s.io/kube-openapi/pkg/util/proto",
......
...@@ -35,8 +35,8 @@ func TestMicroTimeMarshalYAML(t *testing.T) { ...@@ -35,8 +35,8 @@ func TestMicroTimeMarshalYAML(t *testing.T) {
result string result string
}{ }{
{MicroTime{}, "t: null\n"}, {MicroTime{}, "t: null\n"},
{DateMicro(1998, time.May, 5, 1, 5, 5, 50, time.FixedZone("test", -4*60*60)), "t: 1998-05-05T05:05:05.000000Z\n"}, {DateMicro(1998, time.May, 5, 1, 5, 5, 50, time.FixedZone("test", -4*60*60)), "t: \"1998-05-05T05:05:05.000000Z\"\n"},
{DateMicro(1998, time.May, 5, 5, 5, 5, 0, time.UTC), "t: 1998-05-05T05:05:05.000000Z\n"}, {DateMicro(1998, time.May, 5, 5, 5, 5, 0, time.UTC), "t: \"1998-05-05T05:05:05.000000Z\"\n"},
} }
for _, c := range cases { for _, c := range cases {
......
...@@ -35,8 +35,8 @@ func TestTimeMarshalYAML(t *testing.T) { ...@@ -35,8 +35,8 @@ func TestTimeMarshalYAML(t *testing.T) {
result string result string
}{ }{
{Time{}, "t: null\n"}, {Time{}, "t: null\n"},
{Date(1998, time.May, 5, 1, 5, 5, 50, time.FixedZone("test", -4*60*60)), "t: 1998-05-05T05:05:05Z\n"}, {Date(1998, time.May, 5, 1, 5, 5, 50, time.FixedZone("test", -4*60*60)), "t: \"1998-05-05T05:05:05Z\"\n"},
{Date(1998, time.May, 5, 5, 5, 5, 0, time.UTC), "t: 1998-05-05T05:05:05Z\n"}, {Date(1998, time.May, 5, 5, 5, 5, 0, time.UTC), "t: \"1998-05-05T05:05:05Z\"\n"},
} }
for _, c := range cases { for _, c := range cases {
......
...@@ -197,8 +197,8 @@ stuff: 1 ...@@ -197,8 +197,8 @@ stuff: 1
t.Fatal("expected error with yaml: violate, got no error") t.Fatal("expected error with yaml: violate, got no error")
} }
fmt.Printf("err: %s\n", err.Error()) fmt.Printf("err: %s\n", err.Error())
if !strings.Contains(err.Error(), "yaml: line 2:") { if !strings.Contains(err.Error(), "yaml: line 3:") {
t.Fatalf("expected %q to have 'yaml: line 2:' found a tab character", err.Error()) t.Fatalf("expected %q to have 'yaml: line 3:' found a tab character", err.Error())
} }
} }
......
...@@ -388,7 +388,7 @@ ...@@ -388,7 +388,7 @@
}, },
{ {
"ImportPath": "github.com/ghodss/yaml", "ImportPath": "github.com/ghodss/yaml",
"Rev": "73d445a93680fa1a78ae23a5839bad48f32ba1ee" "Rev": "c7ce16629ff4cd059ed96ed06419dd3856fd3577"
}, },
{ {
"ImportPath": "github.com/go-openapi/jsonpointer", "ImportPath": "github.com/go-openapi/jsonpointer",
...@@ -876,7 +876,7 @@ ...@@ -876,7 +876,7 @@
}, },
{ {
"ImportPath": "gopkg.in/yaml.v2", "ImportPath": "gopkg.in/yaml.v2",
"Rev": "670d4cfef0544295bc27a114dbac37980d83185a" "Rev": "5420a8b6744d3b0345ab293f6fcba19c978f1183"
}, },
{ {
"ImportPath": "k8s.io/api/admission/v1beta1", "ImportPath": "k8s.io/api/admission/v1beta1",
......
...@@ -16,7 +16,7 @@ ...@@ -16,7 +16,7 @@
}, },
{ {
"ImportPath": "github.com/ghodss/yaml", "ImportPath": "github.com/ghodss/yaml",
"Rev": "73d445a93680fa1a78ae23a5839bad48f32ba1ee" "Rev": "c7ce16629ff4cd059ed96ed06419dd3856fd3577"
}, },
{ {
"ImportPath": "github.com/gogo/protobuf/proto", "ImportPath": "github.com/gogo/protobuf/proto",
...@@ -208,7 +208,7 @@ ...@@ -208,7 +208,7 @@
}, },
{ {
"ImportPath": "gopkg.in/yaml.v2", "ImportPath": "gopkg.in/yaml.v2",
"Rev": "670d4cfef0544295bc27a114dbac37980d83185a" "Rev": "5420a8b6744d3b0345ab293f6fcba19c978f1183"
}, },
{ {
"ImportPath": "k8s.io/api/admissionregistration/v1alpha1", "ImportPath": "k8s.io/api/admissionregistration/v1alpha1",
......
...@@ -52,7 +52,7 @@ ...@@ -52,7 +52,7 @@
}, },
{ {
"ImportPath": "github.com/ghodss/yaml", "ImportPath": "github.com/ghodss/yaml",
"Rev": "73d445a93680fa1a78ae23a5839bad48f32ba1ee" "Rev": "c7ce16629ff4cd059ed96ed06419dd3856fd3577"
}, },
{ {
"ImportPath": "github.com/gogo/protobuf/proto", "ImportPath": "github.com/gogo/protobuf/proto",
...@@ -268,7 +268,7 @@ ...@@ -268,7 +268,7 @@
}, },
{ {
"ImportPath": "gopkg.in/yaml.v2", "ImportPath": "gopkg.in/yaml.v2",
"Rev": "670d4cfef0544295bc27a114dbac37980d83185a" "Rev": "5420a8b6744d3b0345ab293f6fcba19c978f1183"
}, },
{ {
"ImportPath": "k8s.io/api/admissionregistration/v1alpha1", "ImportPath": "k8s.io/api/admissionregistration/v1alpha1",
......
...@@ -12,7 +12,7 @@ ...@@ -12,7 +12,7 @@
}, },
{ {
"ImportPath": "github.com/ghodss/yaml", "ImportPath": "github.com/ghodss/yaml",
"Rev": "73d445a93680fa1a78ae23a5839bad48f32ba1ee" "Rev": "c7ce16629ff4cd059ed96ed06419dd3856fd3577"
}, },
{ {
"ImportPath": "github.com/gogo/protobuf/proto", "ImportPath": "github.com/gogo/protobuf/proto",
...@@ -164,7 +164,7 @@ ...@@ -164,7 +164,7 @@
}, },
{ {
"ImportPath": "gopkg.in/yaml.v2", "ImportPath": "gopkg.in/yaml.v2",
"Rev": "670d4cfef0544295bc27a114dbac37980d83185a" "Rev": "5420a8b6744d3b0345ab293f6fcba19c978f1183"
}, },
{ {
"ImportPath": "k8s.io/api/admissionregistration/v1alpha1", "ImportPath": "k8s.io/api/admissionregistration/v1alpha1",
......
...@@ -216,7 +216,7 @@ ...@@ -216,7 +216,7 @@
}, },
{ {
"ImportPath": "gopkg.in/yaml.v2", "ImportPath": "gopkg.in/yaml.v2",
"Rev": "670d4cfef0544295bc27a114dbac37980d83185a" "Rev": "5420a8b6744d3b0345ab293f6fcba19c978f1183"
}, },
{ {
"ImportPath": "k8s.io/gengo/args", "ImportPath": "k8s.io/gengo/args",
......
...@@ -12,7 +12,7 @@ ...@@ -12,7 +12,7 @@
}, },
{ {
"ImportPath": "github.com/ghodss/yaml", "ImportPath": "github.com/ghodss/yaml",
"Rev": "73d445a93680fa1a78ae23a5839bad48f32ba1ee" "Rev": "c7ce16629ff4cd059ed96ed06419dd3856fd3577"
}, },
{ {
"ImportPath": "github.com/gogo/protobuf/proto", "ImportPath": "github.com/gogo/protobuf/proto",
...@@ -164,7 +164,7 @@ ...@@ -164,7 +164,7 @@
}, },
{ {
"ImportPath": "gopkg.in/yaml.v2", "ImportPath": "gopkg.in/yaml.v2",
"Rev": "670d4cfef0544295bc27a114dbac37980d83185a" "Rev": "5420a8b6744d3b0345ab293f6fcba19c978f1183"
}, },
{ {
"ImportPath": "k8s.io/api/admissionregistration/v1alpha1", "ImportPath": "k8s.io/api/admissionregistration/v1alpha1",
......
...@@ -112,7 +112,7 @@ ...@@ -112,7 +112,7 @@
}, },
{ {
"ImportPath": "github.com/ghodss/yaml", "ImportPath": "github.com/ghodss/yaml",
"Rev": "73d445a93680fa1a78ae23a5839bad48f32ba1ee" "Rev": "c7ce16629ff4cd059ed96ed06419dd3856fd3577"
}, },
{ {
"ImportPath": "github.com/go-openapi/jsonpointer", "ImportPath": "github.com/go-openapi/jsonpointer",
...@@ -500,7 +500,7 @@ ...@@ -500,7 +500,7 @@
}, },
{ {
"ImportPath": "gopkg.in/yaml.v2", "ImportPath": "gopkg.in/yaml.v2",
"Rev": "670d4cfef0544295bc27a114dbac37980d83185a" "Rev": "5420a8b6744d3b0345ab293f6fcba19c978f1183"
}, },
{ {
"ImportPath": "k8s.io/api/admission/v1beta1", "ImportPath": "k8s.io/api/admission/v1beta1",
......
...@@ -12,7 +12,7 @@ ...@@ -12,7 +12,7 @@
}, },
{ {
"ImportPath": "github.com/ghodss/yaml", "ImportPath": "github.com/ghodss/yaml",
"Rev": "73d445a93680fa1a78ae23a5839bad48f32ba1ee" "Rev": "c7ce16629ff4cd059ed96ed06419dd3856fd3577"
}, },
{ {
"ImportPath": "github.com/gogo/protobuf/proto", "ImportPath": "github.com/gogo/protobuf/proto",
...@@ -168,7 +168,7 @@ ...@@ -168,7 +168,7 @@
}, },
{ {
"ImportPath": "gopkg.in/yaml.v2", "ImportPath": "gopkg.in/yaml.v2",
"Rev": "670d4cfef0544295bc27a114dbac37980d83185a" "Rev": "5420a8b6744d3b0345ab293f6fcba19c978f1183"
}, },
{ {
"ImportPath": "k8s.io/api/admissionregistration/v1alpha1", "ImportPath": "k8s.io/api/admissionregistration/v1alpha1",
......
...@@ -104,7 +104,7 @@ ...@@ -104,7 +104,7 @@
}, },
{ {
"ImportPath": "github.com/ghodss/yaml", "ImportPath": "github.com/ghodss/yaml",
"Rev": "73d445a93680fa1a78ae23a5839bad48f32ba1ee" "Rev": "c7ce16629ff4cd059ed96ed06419dd3856fd3577"
}, },
{ {
"ImportPath": "github.com/go-openapi/jsonpointer", "ImportPath": "github.com/go-openapi/jsonpointer",
...@@ -472,7 +472,7 @@ ...@@ -472,7 +472,7 @@
}, },
{ {
"ImportPath": "gopkg.in/yaml.v2", "ImportPath": "gopkg.in/yaml.v2",
"Rev": "670d4cfef0544295bc27a114dbac37980d83185a" "Rev": "5420a8b6744d3b0345ab293f6fcba19c978f1183"
}, },
{ {
"ImportPath": "k8s.io/api/admission/v1beta1", "ImportPath": "k8s.io/api/admission/v1beta1",
......
...@@ -12,7 +12,7 @@ ...@@ -12,7 +12,7 @@
}, },
{ {
"ImportPath": "github.com/ghodss/yaml", "ImportPath": "github.com/ghodss/yaml",
"Rev": "73d445a93680fa1a78ae23a5839bad48f32ba1ee" "Rev": "c7ce16629ff4cd059ed96ed06419dd3856fd3577"
}, },
{ {
"ImportPath": "github.com/gogo/protobuf/proto", "ImportPath": "github.com/gogo/protobuf/proto",
...@@ -196,7 +196,7 @@ ...@@ -196,7 +196,7 @@
}, },
{ {
"ImportPath": "gopkg.in/yaml.v2", "ImportPath": "gopkg.in/yaml.v2",
"Rev": "670d4cfef0544295bc27a114dbac37980d83185a" "Rev": "5420a8b6744d3b0345ab293f6fcba19c978f1183"
}, },
{ {
"ImportPath": "k8s.io/api/admissionregistration/v1alpha1", "ImportPath": "k8s.io/api/admissionregistration/v1alpha1",
......
...@@ -12,7 +12,7 @@ ...@@ -12,7 +12,7 @@
}, },
{ {
"ImportPath": "github.com/ghodss/yaml", "ImportPath": "github.com/ghodss/yaml",
"Rev": "73d445a93680fa1a78ae23a5839bad48f32ba1ee" "Rev": "c7ce16629ff4cd059ed96ed06419dd3856fd3577"
}, },
{ {
"ImportPath": "github.com/gogo/protobuf/proto", "ImportPath": "github.com/gogo/protobuf/proto",
...@@ -176,7 +176,7 @@ ...@@ -176,7 +176,7 @@
}, },
{ {
"ImportPath": "gopkg.in/yaml.v2", "ImportPath": "gopkg.in/yaml.v2",
"Rev": "670d4cfef0544295bc27a114dbac37980d83185a" "Rev": "5420a8b6744d3b0345ab293f6fcba19c978f1183"
}, },
{ {
"ImportPath": "k8s.io/api/admissionregistration/v1alpha1", "ImportPath": "k8s.io/api/admissionregistration/v1alpha1",
......
...@@ -4,7 +4,7 @@ metadata: ...@@ -4,7 +4,7 @@ metadata:
annotations: annotations:
deployment.kubernetes.io/revision: "1" deployment.kubernetes.io/revision: "1"
kubectl.kubernetes.io/last-applied-configuration: '{"kind":"Deployment","apiVersion":"extensions/v1beta1","metadata":{"name":"nginx-deployment","creationTimestamp":null},"spec":{"template":{"metadata":{"creationTimestamp":null,"labels":{"name":"nginx"}},"spec":{"containers":[{"name":"nginx","image":"nginx","resources":{}}]}},"strategy":{}},"status":{}}' kubectl.kubernetes.io/last-applied-configuration: '{"kind":"Deployment","apiVersion":"extensions/v1beta1","metadata":{"name":"nginx-deployment","creationTimestamp":null},"spec":{"template":{"metadata":{"creationTimestamp":null,"labels":{"name":"nginx"}},"spec":{"containers":[{"name":"nginx","image":"nginx","resources":{}}]}},"strategy":{}},"status":{}}'
creationTimestamp: 2016-10-24T22:15:06Z creationTimestamp: "2016-10-24T22:15:06Z"
generation: 6 generation: 6
labels: labels:
name: nginx name: nginx
......
language: go language: go
go: go:
- 1.3 - "1.3"
- 1.4 - "1.4"
- "1.10"
script: script:
- go test - go test
- go build - go build
...@@ -5,6 +5,7 @@ go_library( ...@@ -5,6 +5,7 @@ go_library(
srcs = [ srcs = [
"fields.go", "fields.go",
"yaml.go", "yaml.go",
"yaml_go110.go",
], ],
importmap = "k8s.io/kubernetes/vendor/github.com/ghodss/yaml", importmap = "k8s.io/kubernetes/vendor/github.com/ghodss/yaml",
importpath = "github.com/ghodss/yaml", importpath = "github.com/ghodss/yaml",
......
...@@ -4,13 +4,13 @@ ...@@ -4,13 +4,13 @@
## Introduction ## 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. 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/). 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 ## Compatibility
This package uses [go-yaml v2](https://github.com/go-yaml/yaml) and therefore supports [everything go-yaml supports](https://github.com/go-yaml/yaml#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 ## Caveats
...@@ -44,6 +44,8 @@ import "github.com/ghodss/yaml" ...@@ -44,6 +44,8 @@ import "github.com/ghodss/yaml"
Usage is very similar to the JSON library: Usage is very similar to the JSON library:
```go ```go
package main
import ( import (
"fmt" "fmt"
...@@ -51,8 +53,8 @@ import ( ...@@ -51,8 +53,8 @@ import (
) )
type Person struct { type Person struct {
Name string `json:"name"` // Affects YAML field names too. Name string `json:"name"` // Affects YAML field names too.
Age int `json:"name"` Age int `json:"age"`
} }
func main() { func main() {
...@@ -65,13 +67,13 @@ func main() { ...@@ -65,13 +67,13 @@ func main() {
} }
fmt.Println(string(y)) fmt.Println(string(y))
/* Output: /* Output:
name: John
age: 30 age: 30
name: John
*/ */
// Unmarshal the YAML back into a Person struct. // Unmarshal the YAML back into a Person struct.
var p2 Person var p2 Person
err := yaml.Unmarshal(y, &p2) err = yaml.Unmarshal(y, &p2)
if err != nil { if err != nil {
fmt.Printf("err: %v\n", err) fmt.Printf("err: %v\n", err)
return return
...@@ -86,11 +88,14 @@ func main() { ...@@ -86,11 +88,14 @@ func main() {
`yaml.YAMLToJSON` and `yaml.JSONToYAML` methods are also available: `yaml.YAMLToJSON` and `yaml.JSONToYAML` methods are also available:
```go ```go
package main
import ( import (
"fmt" "fmt"
"github.com/ghodss/yaml" "github.com/ghodss/yaml"
) )
func main() { func main() {
j := []byte(`{"name": "John", "age": 30}`) j := []byte(`{"name": "John", "age": 30}`)
y, err := yaml.JSONToYAML(j) y, err := yaml.JSONToYAML(j)
......
...@@ -45,7 +45,11 @@ func indirect(v reflect.Value, decodingNull bool) (json.Unmarshaler, encoding.Te ...@@ -45,7 +45,11 @@ func indirect(v reflect.Value, decodingNull bool) (json.Unmarshaler, encoding.Te
break break
} }
if v.IsNil() { if v.IsNil() {
v.Set(reflect.New(v.Type().Elem())) if v.CanSet() {
v.Set(reflect.New(v.Type().Elem()))
} else {
v = reflect.New(v.Type().Elem())
}
} }
if v.Type().NumMethod() > 0 { if v.Type().NumMethod() > 0 {
if u, ok := v.Interface().(json.Unmarshaler); ok { if u, ok := v.Interface().(json.Unmarshaler); ok {
......
...@@ -4,6 +4,7 @@ import ( ...@@ -4,6 +4,7 @@ import (
"bytes" "bytes"
"encoding/json" "encoding/json"
"fmt" "fmt"
"io"
"reflect" "reflect"
"strconv" "strconv"
...@@ -15,26 +16,30 @@ import ( ...@@ -15,26 +16,30 @@ import (
func Marshal(o interface{}) ([]byte, error) { func Marshal(o interface{}) ([]byte, error) {
j, err := json.Marshal(o) j, err := json.Marshal(o)
if err != nil { if err != nil {
return nil, fmt.Errorf("error marshaling into JSON: ", err) return nil, fmt.Errorf("error marshaling into JSON: %v", err)
} }
y, err := JSONToYAML(j) y, err := JSONToYAML(j)
if err != nil { if err != nil {
return nil, fmt.Errorf("error converting JSON to YAML: ", err) return nil, fmt.Errorf("error converting JSON to YAML: %v", err)
} }
return y, nil return y, nil
} }
// Converts YAML to JSON then uses JSON to unmarshal into an object. // JSONOpt is a decoding option for decoding from JSON format.
func Unmarshal(y []byte, o interface{}) error { 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 {
vo := reflect.ValueOf(o) vo := reflect.ValueOf(o)
j, err := yamlToJSON(y, &vo) j, err := yamlToJSON(y, &vo, yaml.Unmarshal)
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,13 +47,28 @@ func Unmarshal(y []byte, o interface{}) error { ...@@ -42,13 +47,28 @@ func Unmarshal(y []byte, o interface{}) error {
return nil return nil
} }
// 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
}
// Convert JSON to YAML. // Convert 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{}
// We are using yaml.Unmarshal here (instead of json.Unmarshal) because the // We are using yaml.Unmarshal here (instead of json.Unmarshal) because the
// Go JSON library doesn't try to pick the right number type (int, float, // Go JSON library doesn't try to pick the right number type (int, float,
// etc.) when unmarshling to interface{}, it just picks float64 // etc.) when unmarshalling to interface{}, it just picks float64
// universally. go-yaml does go through the effort of picking the right // universally. go-yaml does go through the effort of picking the right
// number type, so we can preserve number type throughout this process. // number type, so we can preserve number type throughout this process.
err := yaml.Unmarshal(j, &jsonObj) err := yaml.Unmarshal(j, &jsonObj)
...@@ -60,8 +80,8 @@ func JSONToYAML(j []byte) ([]byte, error) { ...@@ -60,8 +80,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 // YAMLToJSON converts YAML to JSON. Since JSON is a subset of YAML,
// this method should be a no-op. // 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 +90,22 @@ func JSONToYAML(j []byte) ([]byte, error) { ...@@ -70,14 +90,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)
}
// 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) ([]byte, error) { 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
} }
......
// 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
}
...@@ -4,6 +4,9 @@ go: ...@@ -4,6 +4,9 @@ go:
- 1.4 - 1.4
- 1.5 - 1.5
- 1.6 - 1.6
- 1.7
- 1.8
- 1.9
- tip - tip
go_import_path: gopkg.in/yaml.v2 go_import_path: gopkg.in/yaml.v2
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.
...@@ -48,8 +48,6 @@ The yaml package is licensed under the Apache License 2.0. Please see the LICENS ...@@ -48,8 +48,6 @@ The yaml package is licensed under the Apache License 2.0. Please see the LICENS
Example Example
------- -------
Some more examples can be found in the "examples" folder.
```Go ```Go
package main package main
...@@ -67,6 +65,8 @@ b: ...@@ -67,6 +65,8 @@ b:
d: [3, 4] d: [3, 4]
` `
// Note: struct fields must be public in order for unmarshal to
// correctly populate the data.
type T struct { type T struct {
A string A string
B struct { B struct {
......
...@@ -2,7 +2,6 @@ package yaml ...@@ -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 ...@@ -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. // Reader read handler.
func yaml_file_read_handler(parser *yaml_parser_t, buffer []byte) (n int, err error) { func yaml_reader_read_handler(parser *yaml_parser_t, buffer []byte) (n int, err error) {
return parser.input_file.Read(buffer) 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) { ...@@ -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.read_handler = yaml_reader_read_handler
parser.input_file = file 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) { ...@@ -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 { ...@@ -102,9 +100,10 @@ func yaml_string_write_handler(emitter *yaml_emitter_t, buffer []byte) error {
return nil return nil
} }
// File write handler. // yaml_writer_write_handler uses emitter.output_writer to write the
func yaml_file_write_handler(emitter *yaml_emitter_t, buffer []byte) error { // emitted text.
_, err := emitter.output_file.Write(buffer) 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 ...@@ -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.write_handler = yaml_writer_write_handler
emitter.output_file = file 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) { ...@@ -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, func yaml_document_start_event_initialize(
tag_directives []yaml_tag_directive_t, implicit bool) bool { 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 { ...@@ -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 ...@@ -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) { ...@@ -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.
// //
......
...@@ -2,6 +2,7 @@ package yaml ...@@ -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, ...@@ -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 ...@@ -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
...@@ -995,9 +996,9 @@ func yaml_emitter_analyze_scalar(emitter *yaml_emitter_t, value []byte) bool { ...@@ -995,9 +996,9 @@ func yaml_emitter_analyze_scalar(emitter *yaml_emitter_t, value []byte) bool {
space_break = false space_break = false
preceded_by_whitespace = false preceded_by_whitespace = false
followed_by_whitespace = false followed_by_whitespace = false
previous_space = false previous_space = false
previous_break = false previous_break = false
) )
emitter.scalar_data.value = value emitter.scalar_data.value = value
......
...@@ -3,12 +3,14 @@ package yaml ...@@ -3,12 +3,14 @@ package yaml
import ( import (
"encoding" "encoding"
"fmt" "fmt"
"io"
"reflect" "reflect"
"regexp" "regexp"
"sort" "sort"
"strconv" "strconv"
"strings" "strings"
"time" "time"
"unicode/utf8"
) )
type encoder struct { type encoder struct {
...@@ -16,25 +18,39 @@ type encoder struct { ...@@ -16,25 +18,39 @@ type encoder struct {
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) { func newEncoder() *encoder {
e = &encoder{} e := &encoder{}
e.must(yaml_emitter_initialize(&e.emitter)) 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() { func newEncoderWithWriter(w io.Writer) *encoder {
e.must(yaml_document_end_event_initialize(&e.event, true)) 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 +60,7 @@ func (e *encoder) destroy() { ...@@ -44,9 +60,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(yaml_emitter_emit(&e.emitter, &e.event))
e.must(false)
}
} }
func (e *encoder) must(ok bool) { func (e *encoder) must(ok bool) {
...@@ -59,13 +73,28 @@ func (e *encoder) must(ok bool) { ...@@ -59,13 +73,28 @@ 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 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 +104,34 @@ func (e *encoder) marshal(tag string, in reflect.Value) { ...@@ -75,31 +104,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.marshal(tag, in.Elem())
e.nilv()
} else {
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() { if in.Type() == ptrTimeType {
e.nilv() 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) if in.Type() == timeType {
case reflect.Slice: 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 +223,10 @@ func (e *encoder) mappingv(tag string, f func()) { ...@@ -191,10 +223,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 +272,36 @@ var base60float = regexp.MustCompile(`^[-+]?[0-9][0-9_]*(?::[0-5]?[0-9])+(?:\.[0 ...@@ -240,23 +272,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) canUsePlain := true
if rtag == yaml_BINARY_TAG { switch {
if tag == "" || tag == yaml_STR_TAG { case !utf8.ValidString(s):
tag = rtag if tag == yaml_BINARY_TAG {
s = rs.(string)
} else 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)) { // Note: it's possible for user code to emit invalid YAML
style = yaml_DOUBLE_QUOTED_SCALAR_STYLE // if they explicitly specify a tag and a string containing
} else if strings.Contains(s, "\n") { // 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 +326,20 @@ func (e *encoder) uintv(tag string, in reflect.Value) { ...@@ -281,9 +326,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. // Issue #352: When formatting, use the precision of the underlying value
s := strconv.FormatFloat(float64(in.Float()), 'g', -1, 32) 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"
......
module "gopkg.in/yaml.v2"
require (
"gopkg.in/check.v1" v0.0.0-20161208181325-20d25e280405
)
...@@ -93,9 +93,18 @@ func yaml_parser_update_buffer(parser *yaml_parser_t, length int) bool { ...@@ -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 { ...@@ -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
} }
...@@ -6,7 +6,7 @@ import ( ...@@ -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 { ...@@ -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{}) { ...@@ -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{}) { ...@@ -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{}) { ...@@ -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)) { if true || intv == int64(int(intv)) {
return yaml_INT_TAG, -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_STR_TAG, in
return yaml_BINARY_TAG, in
}
if utf8.ValidString(in) {
return yaml_STR_TAG, in
}
return yaml_BINARY_TAG, encodeBase64(in)
} }
// encodeBase64 encodes s as base64 that is broken up into multiple lines // encodeBase64 encodes s as base64 that is broken up into multiple lines
...@@ -206,3 +220,39 @@ func encodeBase64(s string) string { ...@@ -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
}
...@@ -871,12 +871,6 @@ func yaml_parser_save_simple_key(parser *yaml_parser_t) bool { ...@@ -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 ...@@ -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,12 +1953,12 @@ func yaml_parser_scan_tag_handle(parser *yaml_parser_t, directive bool, start_ma ...@@ -1959,12 +1953,12 @@ 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
length := len(head) hasTag := len(head) > 0
// Copy the head if needed. // Copy the head if needed.
// //
// Note that we don't copy the leading '!' character. // Note that we don't copy the leading '!' character.
if length > 0 { if len(head) > 1 {
s = append(s, head[1:]...) s = append(s, head[1:]...)
} }
...@@ -1997,15 +1991,14 @@ func yaml_parser_scan_tag_uri(parser *yaml_parser_t, directive bool, head []byte ...@@ -1997,15 +1991,14 @@ func yaml_parser_scan_tag_uri(parser *yaml_parser_t, directive bool, head []byte
} }
} else { } else {
s = read(parser, s) s = read(parser, s)
length++
} }
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 !hasTag {
if length == 0 {
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
...@@ -2476,6 +2469,10 @@ func yaml_parser_scan_flow_scalar(parser *yaml_parser_t, token *yaml_token_t, si ...@@ -2476,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] == '\'' {
...@@ -2488,10 +2485,6 @@ func yaml_parser_scan_flow_scalar(parser *yaml_parser_t, token *yaml_token_t, si ...@@ -2488,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.
...@@ -2593,19 +2586,10 @@ func yaml_parser_scan_plain_scalar(parser *yaml_parser_t, token *yaml_token_t) b ...@@ -2593,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] == '}')) {
...@@ -2657,10 +2641,10 @@ func yaml_parser_scan_plain_scalar(parser *yaml_parser_t, token *yaml_token_t) b ...@@ -2657,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
} }
......
...@@ -51,6 +51,15 @@ func (l keyList) Less(i, j int) bool { ...@@ -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')
} }
......
...@@ -18,72 +18,9 @@ func yaml_emitter_flush(emitter *yaml_emitter_t) bool { ...@@ -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 err := emitter.write_handler(emitter, emitter.buffer[:emitter.buffer_pos]); err != nil {
if emitter.encoding == yaml_UTF8_ENCODING {
if err := emitter.write_handler(emitter, emitter.buffer[:emitter.buffer_pos]); err != nil {
return yaml_emitter_set_writer_error(emitter, "write error: "+err.Error())
}
emitter.buffer_pos = 0
return true
}
// Recode the buffer into the raw buffer.
var low, high int
if emitter.encoding == yaml_UTF16LE_ENCODING {
low, high = 0, 1
} else {
high, low = 1, 0
}
pos := 0
for pos < emitter.buffer_pos {
// See the "reader.c" code for more details on UTF-8 encoding. Note
// that we assume that the buffer contains a valid UTF-8 sequence.
// Read the next UTF-8 character.
octet := emitter.buffer[pos]
var w int
var value rune
switch {
case octet&0x80 == 0x00:
w, value = 1, rune(octet&0x7F)
case octet&0xE0 == 0xC0:
w, value = 2, rune(octet&0x1F)
case octet&0xF0 == 0xE0:
w, value = 3, rune(octet&0x0F)
case octet&0xF8 == 0xF0:
w, value = 4, rune(octet&0x07)
}
for k := 1; k < w; k++ {
octet = emitter.buffer[pos+k]
value = (value << 6) + (rune(octet) & 0x3F)
}
pos += w
// Write the character.
if value < 0x10000 {
var b [2]byte
b[high] = byte(value >> 8)
b[low] = byte(value & 0xFF)
emitter.raw_buffer = append(emitter.raw_buffer, b[0], b[1])
} else {
// Write the character using a surrogate pair (check "reader.c").
var b [4]byte
value -= 0x10000
b[high] = byte(0xD8 + (value >> 18))
b[low] = byte((value >> 10) & 0xFF)
b[high+2] = byte(0xDC + ((value >> 8) & 0xFF))
b[low+2] = byte(value & 0xFF)
emitter.raw_buffer = append(emitter.raw_buffer, b[0], b[1], b[2], b[3])
}
}
// Write the raw buffer.
if err := emitter.write_handler(emitter, emitter.raw_buffer); err != nil {
return yaml_emitter_set_writer_error(emitter, "write error: "+err.Error()) 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
} }
...@@ -9,6 +9,7 @@ package yaml ...@@ -9,6 +9,7 @@ package yaml
import ( import (
"errors" "errors"
"fmt" "fmt"
"io"
"reflect" "reflect"
"strings" "strings"
"sync" "sync"
...@@ -81,12 +82,58 @@ func Unmarshal(in []byte, out interface{}) (err error) { ...@@ -81,12 +82,58 @@ func Unmarshal(in []byte, out interface{}) (err error) {
} }
// UnmarshalStrict is like Unmarshal except that any fields that are found // UnmarshalStrict is like Unmarshal except that any fields that are found
// in the data that do not have corresponding struct members will result in // in the data that do not have corresponding struct members, or mapping
// keys that are duplicates, will result in
// an error. // an error.
func UnmarshalStrict(in []byte, out interface{}) (err error) { func UnmarshalStrict(in []byte, out interface{}) (err error) {
return unmarshal(in, out, true) 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) { func unmarshal(in []byte, out interface{}, strict bool) (err error) {
defer handleErr(&err) defer handleErr(&err)
d := newDecoder(strict) d := newDecoder(strict)
...@@ -110,8 +157,8 @@ func unmarshal(in []byte, out interface{}, strict bool) (err error) { ...@@ -110,8 +157,8 @@ func unmarshal(in []byte, out interface{}, strict bool) (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 // Struct fields are only marshalled if they are exported (have an upper case
// first letter), and are unmarshalled using the field name lowercased as the // 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.
...@@ -125,7 +172,10 @@ func unmarshal(in []byte, out interface{}, strict bool) (err error) { ...@@ -125,7 +172,10 @@ func unmarshal(in []byte, out interface{}, strict bool) (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).
...@@ -140,7 +190,7 @@ func unmarshal(in []byte, out interface{}, strict bool) (err error) { ...@@ -140,7 +190,7 @@ func unmarshal(in []byte, out interface{}, strict bool) (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"
...@@ -150,12 +200,47 @@ func Marshal(in interface{}) (out []byte, err error) { ...@@ -150,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 {
...@@ -211,6 +296,9 @@ type fieldInfo struct { ...@@ -211,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
...@@ -290,6 +378,7 @@ func getStructInfo(st reflect.Type) (*structInfo, error) { ...@@ -290,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)
} }
...@@ -311,11 +400,16 @@ func getStructInfo(st reflect.Type) (*structInfo, error) { ...@@ -311,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
...@@ -323,8 +417,23 @@ func getStructInfo(st reflect.Type) (*structInfo, error) { ...@@ -323,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:
......
package yaml package yaml
import ( import (
"fmt"
"io" "io"
) )
...@@ -239,6 +240,27 @@ const ( ...@@ -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 {
...@@ -521,9 +543,9 @@ type yaml_parser_t struct { ...@@ -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_reader io.Reader // File input data.
input []byte // String input data. input []byte // String input data.
input_pos int input_pos int
eof bool // EOF flag eof bool // EOF flag
...@@ -632,7 +654,7 @@ type yaml_emitter_t struct { ...@@ -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.
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment