From 47056bde161650c5b056a86b28dbc28f271f3339 Mon Sep 17 00:00:00 2001 From: Alfonso Acosta Date: Thu, 18 Aug 2016 14:20:30 +0000 Subject: [PATCH] Vendor the exact same version of mergo used by k8s Merging is buggy in master: https://github.com/imdario/mergo/issues/33 --- vendor/github.com/imdario/mergo/map.go | 22 +++------ vendor/github.com/imdario/mergo/merge.go | 62 ++++++++---------------- vendor/manifest | 4 +- 3 files changed, 27 insertions(+), 61 deletions(-) diff --git a/vendor/github.com/imdario/mergo/map.go b/vendor/github.com/imdario/mergo/map.go index 8e8c4ba8e..44361e88b 100644 --- a/vendor/github.com/imdario/mergo/map.go +++ b/vendor/github.com/imdario/mergo/map.go @@ -31,7 +31,7 @@ func isExported(field reflect.StructField) bool { // Traverses recursively both values, assigning src's fields values to dst. // The map argument tracks comparisons that have already been seen, which allows // short circuiting on recursive types. -func deepMap(dst, src reflect.Value, visited map[uintptr]*visit, depth int, overwrite bool) (err error) { +func deepMap(dst, src reflect.Value, visited map[uintptr]*visit, depth int) (err error) { if dst.CanAddr() { addr := dst.UnsafeAddr() h := 17 * addr @@ -57,7 +57,7 @@ func deepMap(dst, src reflect.Value, visited map[uintptr]*visit, depth int, over } fieldName := field.Name fieldName = changeInitialCase(fieldName, unicode.ToLower) - if v, ok := dstMap[fieldName]; !ok || (isEmptyValue(reflect.ValueOf(v)) || overwrite) { + if v, ok := dstMap[fieldName]; !ok || isEmptyValue(reflect.ValueOf(v)) { dstMap[fieldName] = src.Field(i).Interface() } } @@ -89,12 +89,12 @@ func deepMap(dst, src reflect.Value, visited map[uintptr]*visit, depth int, over continue } if srcKind == dstKind { - if err = deepMerge(dstElement, srcElement, visited, depth+1, overwrite); err != nil { + if err = deepMerge(dstElement, srcElement, visited, depth+1); err != nil { return } } else { if srcKind == reflect.Map { - if err = deepMap(dstElement, srcElement, visited, depth+1, overwrite); err != nil { + if err = deepMap(dstElement, srcElement, visited, depth+1); err != nil { return } } else { @@ -118,16 +118,6 @@ func deepMap(dst, src reflect.Value, visited map[uintptr]*visit, depth int, over // This is separated method from Merge because it is cleaner and it keeps sane // semantics: merging equal types, mapping different (restricted) types. func Map(dst, src interface{}) error { - return _map(dst, src, false) -} - -// MapWithOverwrite will do the same as Map except that non-empty dst attributes will be overriden by -// non-empty src attribute values. -func MapWithOverwrite(dst, src interface{}) error { - return _map(dst, src, true) -} - -func _map(dst, src interface{}, overwrite bool) error { var ( vDst, vSrc reflect.Value err error @@ -138,7 +128,7 @@ func _map(dst, src interface{}, overwrite bool) error { // To be friction-less, we redirect equal-type arguments // to deepMerge. Only because arguments can be anything. if vSrc.Kind() == vDst.Kind() { - return deepMerge(vDst, vSrc, make(map[uintptr]*visit), 0, overwrite) + return deepMerge(vDst, vSrc, make(map[uintptr]*visit), 0) } switch vSrc.Kind() { case reflect.Struct: @@ -152,5 +142,5 @@ func _map(dst, src interface{}, overwrite bool) error { default: return ErrNotSupported } - return deepMap(vDst, vSrc, make(map[uintptr]*visit), 0, overwrite) + return deepMap(vDst, vSrc, make(map[uintptr]*visit), 0) } diff --git a/vendor/github.com/imdario/mergo/merge.go b/vendor/github.com/imdario/mergo/merge.go index 513774f4c..5d328b1fe 100644 --- a/vendor/github.com/imdario/mergo/merge.go +++ b/vendor/github.com/imdario/mergo/merge.go @@ -15,7 +15,7 @@ import ( // Traverses recursively both values, assigning src's fields values to dst. // The map argument tracks comparisons that have already been seen, which allows // short circuiting on recursive types. -func deepMerge(dst, src reflect.Value, visited map[uintptr]*visit, depth int, overwrite bool) (err error) { +func deepMerge(dst, src reflect.Value, visited map[uintptr]*visit, depth int) (err error) { if !src.IsValid() { return } @@ -35,7 +35,7 @@ func deepMerge(dst, src reflect.Value, visited map[uintptr]*visit, depth int, ov switch dst.Kind() { case reflect.Struct: for i, n := 0, dst.NumField(); i < n; i++ { - if err = deepMerge(dst.Field(i), src.Field(i), visited, depth+1, overwrite); err != nil { + if err = deepMerge(dst.Field(i), src.Field(i), visited, depth+1); err != nil { return } } @@ -46,31 +46,15 @@ func deepMerge(dst, src reflect.Value, visited map[uintptr]*visit, depth int, ov continue } dstElement := dst.MapIndex(key) - switch srcElement.Kind() { - case reflect.Chan, reflect.Func, reflect.Map, reflect.Ptr, reflect.Interface, reflect.Slice: - if srcElement.IsNil() { - continue - } + switch reflect.TypeOf(srcElement.Interface()).Kind() { + case reflect.Struct: fallthrough - default: - if !srcElement.CanInterface() { - continue - } - switch reflect.TypeOf(srcElement.Interface()).Kind() { - case reflect.Struct: - fallthrough - case reflect.Ptr: - fallthrough - case reflect.Map: - if err = deepMerge(dstElement, srcElement, visited, depth+1, overwrite); err != nil { - return - } + case reflect.Map: + if err = deepMerge(dstElement, srcElement, visited, depth+1); err != nil { + return } } - if !isEmptyValue(srcElement) && (overwrite || (!dstElement.IsValid() || isEmptyValue(dst))) { - if dst.IsNil() { - dst.Set(reflect.MakeMap(dst.Type())) - } + if !dstElement.IsValid() { dst.SetMapIndex(key, srcElement) } } @@ -79,36 +63,28 @@ func deepMerge(dst, src reflect.Value, visited map[uintptr]*visit, depth int, ov case reflect.Interface: if src.IsNil() { break - } else if dst.IsNil() || overwrite { - if dst.CanSet() && (overwrite || isEmptyValue(dst)) { + } else if dst.IsNil() { + if dst.CanSet() && isEmptyValue(dst) { dst.Set(src) } - } else if err = deepMerge(dst.Elem(), src.Elem(), visited, depth+1, overwrite); err != nil { + } else if err = deepMerge(dst.Elem(), src.Elem(), visited, depth+1); err != nil { return } default: - if dst.CanSet() && !isEmptyValue(src) && (overwrite || isEmptyValue(dst)) { + if dst.CanSet() && !isEmptyValue(src) { dst.Set(src) } } return } -// Merge will fill any empty for value type attributes on the dst struct using corresponding -// src attributes if they themselves are not empty. dst and src must be valid same-type structs -// and dst must be a pointer to struct. -// It won't merge unexported (private) fields and will do recursively any exported field. +// Merge sets fields' values in dst from src if they have a zero +// value of their type. +// dst and src must be valid same-type structs and dst must be +// a pointer to struct. +// It won't merge unexported (private) fields and will do recursively +// any exported field. func Merge(dst, src interface{}) error { - return merge(dst, src, false) -} - -// MergeWithOverwrite will do the same as Merge except that non-empty dst attributes will be overriden by -// non-empty src attribute values. -func MergeWithOverwrite(dst, src interface{}) error { - return merge(dst, src, true) -} - -func merge(dst, src interface{}, overwrite bool) error { var ( vDst, vSrc reflect.Value err error @@ -119,5 +95,5 @@ func merge(dst, src interface{}, overwrite bool) error { if vDst.Type() != vSrc.Type() { return ErrDifferentArgumentsTypes } - return deepMerge(vDst, vSrc, make(map[uintptr]*visit), 0, overwrite) + return deepMerge(vDst, vSrc, make(map[uintptr]*visit), 0) } diff --git a/vendor/manifest b/vendor/manifest index fd08d7d14..423514b6b 100644 --- a/vendor/manifest +++ b/vendor/manifest @@ -893,8 +893,8 @@ "importpath": "github.com/imdario/mergo", "repository": "https://github.com/imdario/mergo", "vcs": "git", - "revision": "50d4dbd4eb0e84778abe37cefef140271d96fade", - "branch": "master", + "revision": "6633656539c1639d9d78127b7d47c622b5d7b6dc", + "branch": "HEAD", "notests": true }, {