瀏覽代碼

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 <github@gone.nl>
Sebastiaan van Stijn 5 年之前
父節點
當前提交
9bd1b1a8ec
共有 2 個文件被更改,包括 40 次插入12 次删除
  1. 1 1
      vendor.conf
  2. 39 11
      vendor/github.com/imdario/mergo/merge.go

+ 1 - 1
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

+ 39 - 11
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