mirror of https://github.com/docker/cli.git
Merge pull request #2277 from zappy-shu/bump_mergo_v0.3.8
Bump mergo v0.3.8
This commit is contained in:
commit
7a0b138571
|
@ -57,6 +57,8 @@ func mergeServices(base, override []types.ServiceConfig) ([]types.ServiceConfig,
|
|||
reflect.TypeOf([]types.ServicePortConfig{}): mergeSlice(toServicePortConfigsMap, toServicePortConfigsSlice),
|
||||
reflect.TypeOf([]types.ServiceSecretConfig{}): mergeSlice(toServiceSecretConfigsMap, toServiceSecretConfigsSlice),
|
||||
reflect.TypeOf([]types.ServiceConfigObjConfig{}): mergeSlice(toServiceConfigObjConfigsMap, toSServiceConfigObjConfigsSlice),
|
||||
reflect.TypeOf(&types.UlimitsConfig{}): mergeUlimitsConfig,
|
||||
reflect.TypeOf(&types.ServiceNetworkConfig{}): mergeServiceNetworkConfig,
|
||||
},
|
||||
}
|
||||
for name, overrideService := range overrideServices {
|
||||
|
@ -201,6 +203,28 @@ func mergeLoggingConfig(dst, src reflect.Value) error {
|
|||
return nil
|
||||
}
|
||||
|
||||
//nolint: unparam
|
||||
func mergeUlimitsConfig(dst, src reflect.Value) error {
|
||||
if src.Interface() != reflect.Zero(reflect.TypeOf(src.Interface())).Interface() {
|
||||
dst.Elem().Set(src.Elem())
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
//nolint: unparam
|
||||
func mergeServiceNetworkConfig(dst, src reflect.Value) error {
|
||||
if src.Interface() != reflect.Zero(reflect.TypeOf(src.Interface())).Interface() {
|
||||
dst.Elem().FieldByName("Aliases").Set(src.Elem().FieldByName("Aliases"))
|
||||
if ipv4 := src.Elem().FieldByName("Ipv4Address").Interface().(string); ipv4 != "" {
|
||||
dst.Elem().FieldByName("Ipv4Address").SetString(ipv4)
|
||||
}
|
||||
if ipv6 := src.Elem().FieldByName("Ipv6Address").Interface().(string); ipv6 != "" {
|
||||
dst.Elem().FieldByName("Ipv6Address").SetString(ipv6)
|
||||
}
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
func getLoggingDriver(v reflect.Value) string {
|
||||
return v.FieldByName("Driver").String()
|
||||
}
|
||||
|
|
|
@ -1,9 +1,11 @@
|
|||
package loader
|
||||
|
||||
import (
|
||||
"reflect"
|
||||
"testing"
|
||||
|
||||
"github.com/docker/cli/cli/compose/types"
|
||||
"github.com/imdario/mergo"
|
||||
"gotest.tools/assert"
|
||||
)
|
||||
|
||||
|
@ -1014,3 +1016,94 @@ func TestLoadMultipleNetworks(t *testing.T) {
|
|||
Configs: map[string]types.ConfigObjConfig{},
|
||||
}, config)
|
||||
}
|
||||
|
||||
func TestMergeUlimitsConfig(t *testing.T) {
|
||||
specials := &specials{
|
||||
m: map[reflect.Type]func(dst, src reflect.Value) error{
|
||||
reflect.TypeOf(&types.UlimitsConfig{}): mergeUlimitsConfig,
|
||||
},
|
||||
}
|
||||
base := map[string]*types.UlimitsConfig{
|
||||
"override-single": &types.UlimitsConfig{Single: 100},
|
||||
"override-single-with-soft-hard": &types.UlimitsConfig{Single: 200},
|
||||
"override-soft-hard": &types.UlimitsConfig{Soft: 300, Hard: 301},
|
||||
"override-soft-hard-with-single": &types.UlimitsConfig{Soft: 400, Hard: 401},
|
||||
"dont-override": &types.UlimitsConfig{Single: 500},
|
||||
}
|
||||
override := map[string]*types.UlimitsConfig{
|
||||
"override-single": &types.UlimitsConfig{Single: 110},
|
||||
"override-single-with-soft-hard": &types.UlimitsConfig{Soft: 210, Hard: 211},
|
||||
"override-soft-hard": &types.UlimitsConfig{Soft: 310, Hard: 311},
|
||||
"override-soft-hard-with-single": &types.UlimitsConfig{Single: 410},
|
||||
"add": &types.UlimitsConfig{Single: 610},
|
||||
}
|
||||
err := mergo.Merge(&base, &override, mergo.WithOverride, mergo.WithTransformers(specials))
|
||||
assert.NilError(t, err)
|
||||
assert.DeepEqual(
|
||||
t,
|
||||
base,
|
||||
map[string]*types.UlimitsConfig{
|
||||
"override-single": &types.UlimitsConfig{Single: 110},
|
||||
"override-single-with-soft-hard": &types.UlimitsConfig{Soft: 210, Hard: 211},
|
||||
"override-soft-hard": &types.UlimitsConfig{Soft: 310, Hard: 311},
|
||||
"override-soft-hard-with-single": &types.UlimitsConfig{Single: 410},
|
||||
"dont-override": &types.UlimitsConfig{Single: 500},
|
||||
"add": &types.UlimitsConfig{Single: 610},
|
||||
},
|
||||
)
|
||||
}
|
||||
|
||||
func TestMergeServiceNetworkConfig(t *testing.T) {
|
||||
specials := &specials{
|
||||
m: map[reflect.Type]func(dst, src reflect.Value) error{
|
||||
reflect.TypeOf(&types.ServiceNetworkConfig{}): mergeServiceNetworkConfig,
|
||||
},
|
||||
}
|
||||
base := map[string]*types.ServiceNetworkConfig{
|
||||
"override-aliases": &types.ServiceNetworkConfig{
|
||||
Aliases: []string{"100", "101"},
|
||||
Ipv4Address: "127.0.0.1",
|
||||
Ipv6Address: "0:0:0:0:0:0:0:1",
|
||||
},
|
||||
"dont-override": &types.ServiceNetworkConfig{
|
||||
Aliases: []string{"200", "201"},
|
||||
Ipv4Address: "127.0.0.2",
|
||||
Ipv6Address: "0:0:0:0:0:0:0:2",
|
||||
},
|
||||
}
|
||||
override := map[string]*types.ServiceNetworkConfig{
|
||||
"override-aliases": &types.ServiceNetworkConfig{
|
||||
Aliases: []string{"110", "111"},
|
||||
Ipv4Address: "127.0.1.1",
|
||||
Ipv6Address: "0:0:0:0:0:0:1:1",
|
||||
},
|
||||
"add": &types.ServiceNetworkConfig{
|
||||
Aliases: []string{"310", "311"},
|
||||
Ipv4Address: "127.0.3.1",
|
||||
Ipv6Address: "0:0:0:0:0:0:3:1",
|
||||
},
|
||||
}
|
||||
err := mergo.Merge(&base, &override, mergo.WithOverride, mergo.WithTransformers(specials))
|
||||
assert.NilError(t, err)
|
||||
assert.DeepEqual(
|
||||
t,
|
||||
base,
|
||||
map[string]*types.ServiceNetworkConfig{
|
||||
"override-aliases": &types.ServiceNetworkConfig{
|
||||
Aliases: []string{"110", "111"},
|
||||
Ipv4Address: "127.0.1.1",
|
||||
Ipv6Address: "0:0:0:0:0:0:1:1",
|
||||
},
|
||||
"dont-override": &types.ServiceNetworkConfig{
|
||||
Aliases: []string{"200", "201"},
|
||||
Ipv4Address: "127.0.0.2",
|
||||
Ipv6Address: "0:0:0:0:0:0:0:2",
|
||||
},
|
||||
"add": &types.ServiceNetworkConfig{
|
||||
Aliases: []string{"310", "311"},
|
||||
Ipv4Address: "127.0.3.1",
|
||||
Ipv6Address: "0:0:0:0:0:0:3:1",
|
||||
},
|
||||
},
|
||||
)
|
||||
}
|
||||
|
|
|
@ -34,7 +34,7 @@ github.com/gorilla/mux 00bdffe0f3c77e27d2cf6f5c7023
|
|||
github.com/grpc-ecosystem/grpc-gateway 1a03ca3bad1e1ebadaedd3abb76bc58d4ac8143b
|
||||
github.com/grpc-ecosystem/grpc-opentracing 8e809c8a86450a29b90dcc9efbf062d0fe6d9746
|
||||
github.com/hashicorp/golang-lru 7f827b33c0f158ec5dfbba01bb0b14a4541fd81d # v0.5.3
|
||||
github.com/imdario/mergo 7c29201646fa3de8506f701213473dd407f19646 # v0.3.7
|
||||
github.com/imdario/mergo 1afb36080aec31e0d1528973ebe6721b191b0369 # v0.3.8
|
||||
github.com/inconshreveable/mousetrap 76626ae9c91c4f2a10f34cad8ce83ea42c93bb75 # v1.0.0
|
||||
github.com/jaguilar/vt100 ad4c4a5743050fb7f88ce968dca9422f72a0e3f2 git://github.com/tonistiigi/vt100.git
|
||||
github.com/json-iterator/go 0ff49de124c6f76f8494e194af75bde0f1a49a29 # 1.1.6
|
||||
|
|
|
@ -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
|
||||
|
|
Loading…
Reference in New Issue