Merge pull request #13702 from ghodss/ghodss-yaml-upgrade

Auto commit by PR queue bot
This commit is contained in:
k8s-merge-robot 2015-09-16 22:27:24 -07:00
commit f44432ae7b
6 changed files with 66 additions and 15 deletions

2
Godeps/Godeps.json generated
View File

@ -236,7 +236,7 @@
},
{
"ImportPath": "github.com/ghodss/yaml",
"Rev": "588cb435e59ee8b6c2795482887755841ad67207"
"Rev": "73d445a93680fa1a78ae23a5839bad48f32ba1ee"
},
{
"ImportPath": "github.com/godbus/dbus",

View File

@ -0,0 +1,7 @@
language: go
go:
- 1.3
- 1.4
script:
- go test
- go build

View File

@ -1,5 +1,7 @@
# YAML marshaling and unmarshaling support for Go
[![Build Status](https://travis-ci.org/ghodss/yaml.svg)](https://travis-ci.org/ghodss/yaml)
## Introduction
A wrapper around [go-yaml](https://github.com/go-yaml/yaml) designed to enable a better way of handling YAML when marshaling to and from structs.

View File

@ -113,12 +113,11 @@ func convertToJSONableObject(yamlObj interface{}, jsonTarget *reflect.Value) (in
}
}
// If yamlObj is a number, check if jsonTarget is a string - if so, coerce.
// Else return normal.
// If yamlObj is a number or a boolean, check if jsonTarget is a string -
// if so, coerce. Else return normal.
// If yamlObj is a map or array, find the field that each key is
// unmarshaling to, and when you recurse pass the reflect.Value for that
// field back into this function.
switch typedYAMLObj := yamlObj.(type) {
case map[interface{}]interface{}:
// JSON does not support arbitrary keys in a map, so we must convert
@ -155,14 +154,22 @@ func convertToJSONableObject(yamlObj interface{}, jsonTarget *reflect.Value) (in
s = ".nan"
}
keyString = s
case bool:
if typedKey {
keyString = "true"
} else {
keyString = "false"
}
default:
return nil, fmt.Errorf("Unsupported map key of type: %s, key: %+#v, value: %+#v",
reflect.TypeOf(k), k, v)
}
// If jsonTarget is a struct (which it really should be), find the
// field it's going to map to. If it's not a struct, just pass nil
// - JSON conversion will error for us if it's a real issue.
// jsonTarget should be a struct or a map. If it's a struct, find
// the field it's going to map to and pass its reflect.Value. If
// it's a map, find the element type of the map and pass the
// reflect.Value created from that type. If it's neither, just pass
// nil - JSON conversion will error for us if it's a real issue.
if jsonTarget != nil {
t := *jsonTarget
if t.Kind() == reflect.Struct {
@ -191,6 +198,15 @@ func convertToJSONableObject(yamlObj interface{}, jsonTarget *reflect.Value) (in
}
continue
}
} else if t.Kind() == reflect.Map {
// Create a zero value of the map's element type to use as
// the JSON target.
jtv := reflect.Zero(t.Type().Elem())
strMap[keyString], err = convertToJSONableObject(v, &jtv)
if err != nil {
return nil, err
}
continue
}
}
strMap[keyString], err = convertToJSONableObject(v, nil)
@ -234,15 +250,21 @@ func convertToJSONableObject(yamlObj interface{}, jsonTarget *reflect.Value) (in
// Based on my reading of go-yaml, it may return int, int64,
// float64, or uint64.
var s string
switch num := typedYAMLObj.(type) {
switch typedVal := typedYAMLObj.(type) {
case int:
s = strconv.FormatInt(int64(num), 10)
s = strconv.FormatInt(int64(typedVal), 10)
case int64:
s = strconv.FormatInt(num, 10)
s = strconv.FormatInt(typedVal, 10)
case float64:
s = strconv.FormatFloat(num, 'g', -1, 32)
s = strconv.FormatFloat(typedVal, 'g', -1, 32)
case uint64:
s = strconv.FormatUint(num, 10)
s = strconv.FormatUint(typedVal, 10)
case bool:
if typedVal {
s = "true"
} else {
s = "false"
}
}
if len(s) > 0 {
yamlObj = interface{}(s)

View File

@ -33,7 +33,12 @@ func TestMarshal(t *testing.T) {
}
type UnmarshalString struct {
A string
A string
True string
}
type UnmarshalStringMap struct {
A map[string]string
}
type UnmarshalNestedString struct {
@ -56,7 +61,17 @@ type NestedSlice struct {
func TestUnmarshal(t *testing.T) {
y := []byte("a: 1")
s1 := UnmarshalString{}
e1 := UnmarshalString{"1"}
e1 := UnmarshalString{A: "1"}
unmarshal(t, y, &s1, &e1)
y = []byte("a: true")
s1 = UnmarshalString{}
e1 = UnmarshalString{A: "true"}
unmarshal(t, y, &s1, &e1)
y = []byte("true: 1")
s1 = UnmarshalString{}
e1 = UnmarshalString{True: "1"}
unmarshal(t, y, &s1, &e1)
y = []byte("a:\n a: 1")
@ -68,6 +83,11 @@ func TestUnmarshal(t *testing.T) {
s3 := UnmarshalSlice{}
e3 := UnmarshalSlice{[]NestedSlice{NestedSlice{"abc", strPtr("def")}, NestedSlice{"123", strPtr("456")}}}
unmarshal(t, y, &s3, &e3)
y = []byte("a:\n b: 1")
s4 := UnmarshalStringMap{}
e4 := UnmarshalStringMap{map[string]string{"b": "1"}}
unmarshal(t, y, &s4, &e4)
}
func unmarshal(t *testing.T, y []byte, s, e interface{}) {

View File

@ -44,7 +44,7 @@ const (
// of expectations, without it the controller could stay asleep forever. This should
// be set based on the expected latency of watch events.
//
// Currently an controller can service (create *and* observe the watch events for said
// Currently a controller can service (create *and* observe the watch events for said
// creation) about 10-20 pods a second, so it takes about 1 min to service
// 500 pods. Just creation is limited to 20qps, and watching happens with ~10-30s
// latency/pod at the scale of 3000 pods over 100 nodes.