From 95072a9d7fe8270a4ee0b7b179e26aab8a600719 Mon Sep 17 00:00:00 2001 From: Sebastiaan van Stijn Date: Sun, 6 Oct 2019 02:35:01 +0200 Subject: [PATCH] bump imdario/mergo v0.3.8 full diff: https://github.com/imdario/mergo/compare/v0.3.7...v0.3.8 includes: - imdario/mergo#112 Add strict override - fixes imdario/mergo#111 WithOverride should be able to check types - imdario/mergo#106 Fix merging of interface types with concrete values - imdario/mergo#120 should not overwrite pointers directly, instead check embedded values - fixes imdario/mergo#114 Embedded struct of pointer types will overwrite the whole destination struct - imdario/mergo#125 added WithOverrideEmptySlice config flag Signed-off-by: Sebastiaan van Stijn Upstream-commit: 9bd1b1a8eca97a2403bc7a2ed9a52427d8c27078 Component: engine --- components/engine/vendor.conf | 2 +- .../vendor/github.com/imdario/mergo/merge.go | 50 +++++++++++++++---- 2 files changed, 40 insertions(+), 12 deletions(-) diff --git a/components/engine/vendor.conf b/components/engine/vendor.conf index 7e6e44f27f9..43229affaf2 100644 --- a/components/engine/vendor.conf +++ b/components/engine/vendor.conf @@ -22,7 +22,7 @@ github.com/google/go-cmp 3af367b6b30c263d47e8895973ed github.com/syndtr/gocapability d98352740cb2c55f81556b63d4a1ec64c5a319c2 github.com/RackSec/srslog a4725f04ec91af1a91b380da679d6e0c2f061e59 -github.com/imdario/mergo 7c29201646fa3de8506f701213473dd407f19646 # v0.3.7 +github.com/imdario/mergo 1afb36080aec31e0d1528973ebe6721b191b0369 # v0.3.8 golang.org/x/sync e225da77a7e68af35c70ccbf71af2b83e6acac3c # buildkit diff --git a/components/engine/vendor/github.com/imdario/mergo/merge.go b/components/engine/vendor/github.com/imdario/mergo/merge.go index f8de6c54305..3fb6c64d05b 100644 --- a/components/engine/vendor/github.com/imdario/mergo/merge.go +++ b/components/engine/vendor/github.com/imdario/mergo/merge.go @@ -26,10 +26,12 @@ func hasExportedField(dst reflect.Value) (exported bool) { } type Config struct { - Overwrite bool - AppendSlice bool - Transformers Transformers - overwriteWithEmptyValue bool + Overwrite bool + AppendSlice bool + TypeCheck bool + Transformers Transformers + overwriteWithEmptyValue bool + overwriteSliceWithEmptyValue bool } type Transformers interface { @@ -41,7 +43,9 @@ type Transformers interface { // short circuiting on recursive types. func deepMerge(dst, src reflect.Value, visited map[uintptr]*visit, depth int, config *Config) (err error) { overwrite := config.Overwrite + typeCheck := config.TypeCheck overwriteWithEmptySrc := config.overwriteWithEmptyValue + overwriteSliceWithEmptySrc := config.overwriteSliceWithEmptyValue config.overwriteWithEmptyValue = false if !src.IsValid() { @@ -128,11 +132,14 @@ func deepMerge(dst, src reflect.Value, visited map[uintptr]*visit, depth int, co dstSlice = reflect.ValueOf(dstElement.Interface()) } - if (!isEmptyValue(src) || overwriteWithEmptySrc) && (overwrite || isEmptyValue(dst)) && !config.AppendSlice { + if (!isEmptyValue(src) || overwriteWithEmptySrc || overwriteSliceWithEmptySrc) && (overwrite || isEmptyValue(dst)) && !config.AppendSlice { + if typeCheck && srcSlice.Type() != dstSlice.Type() { + return fmt.Errorf("cannot override two slices with different type (%s, %s)", srcSlice.Type(), dstSlice.Type()) + } dstSlice = srcSlice } else if config.AppendSlice { if srcSlice.Type() != dstSlice.Type() { - return fmt.Errorf("cannot append two slice with different type (%s, %s)", srcSlice.Type(), dstSlice.Type()) + return fmt.Errorf("cannot append two slices with different type (%s, %s)", srcSlice.Type(), dstSlice.Type()) } dstSlice = reflect.AppendSlice(dstSlice, srcSlice) } @@ -143,7 +150,7 @@ func deepMerge(dst, src reflect.Value, visited map[uintptr]*visit, depth int, co continue } - if srcElement.IsValid() && (overwrite || (!dstElement.IsValid() || isEmptyValue(dstElement))) { + if srcElement.IsValid() && ((srcElement.Kind() != reflect.Ptr && overwrite) || !dstElement.IsValid() || isEmptyValue(dstElement)) { if dst.IsNil() { dst.Set(reflect.MakeMap(dst.Type())) } @@ -154,7 +161,7 @@ func deepMerge(dst, src reflect.Value, visited map[uintptr]*visit, depth int, co if !dst.CanSet() { break } - if (!isEmptyValue(src) || overwriteWithEmptySrc) && (overwrite || isEmptyValue(dst)) && !config.AppendSlice { + if (!isEmptyValue(src) || overwriteWithEmptySrc || overwriteSliceWithEmptySrc) && (overwrite || isEmptyValue(dst)) && !config.AppendSlice { dst.Set(src) } else if config.AppendSlice { if src.Type() != dst.Type() { @@ -168,11 +175,21 @@ func deepMerge(dst, src reflect.Value, visited map[uintptr]*visit, depth int, co if src.IsNil() { break } - if src.Kind() != reflect.Interface { + + if dst.Kind() != reflect.Ptr && src.Type().AssignableTo(dst.Type()) { if dst.IsNil() || overwrite { if dst.CanSet() && (overwrite || isEmptyValue(dst)) { dst.Set(src) } + } + break + } + + if src.Kind() != reflect.Interface { + if dst.IsNil() || (src.Kind() != reflect.Ptr && overwrite) { + if dst.CanSet() && (overwrite || isEmptyValue(dst)) { + dst.Set(src) + } } else if src.Kind() == reflect.Ptr { if err = deepMerge(dst.Elem(), src.Elem(), visited, depth+1, config); err != nil { return @@ -198,6 +215,7 @@ func deepMerge(dst, src reflect.Value, visited map[uintptr]*visit, depth int, co dst.Set(src) } } + return } @@ -209,7 +227,7 @@ func Merge(dst, src interface{}, opts ...func(*Config)) error { return merge(dst, src, opts...) } -// MergeWithOverwrite will do the same as Merge except that non-empty dst attributes will be overriden by +// MergeWithOverwrite will do the same as Merge except that non-empty dst attributes will be overridden by // non-empty src attribute values. // Deprecated: use Merge(…) with WithOverride func MergeWithOverwrite(dst, src interface{}, opts ...func(*Config)) error { @@ -228,11 +246,21 @@ func WithOverride(config *Config) { config.Overwrite = true } -// WithAppendSlice will make merge append slices instead of overwriting it +// WithOverride will make merge override empty dst slice with empty src slice. +func WithOverrideEmptySlice(config *Config) { + config.overwriteSliceWithEmptyValue = true +} + +// WithAppendSlice will make merge append slices instead of overwriting it. func WithAppendSlice(config *Config) { config.AppendSlice = true } +// WithTypeCheck will make merge check types while overwriting it (must be used with WithOverride). +func WithTypeCheck(config *Config) { + config.TypeCheck = true +} + func merge(dst, src interface{}, opts ...func(*Config)) error { var ( vDst, vSrc reflect.Value