diff --git a/loader/merge.go b/loader/merge.go index bf10cf779..ce7c1dcf2 100644 --- a/loader/merge.go +++ b/loader/merge.go @@ -119,6 +119,9 @@ func _merge(baseService *types.ServiceConfig, overrideService *types.ServiceConf if overrideService.Command != nil { baseService.Command = overrideService.Command } + if overrideService.HealthCheck != nil { + baseService.HealthCheck.Test = overrideService.HealthCheck.Test + } if overrideService.Entrypoint != nil { baseService.Entrypoint = overrideService.Entrypoint } @@ -127,9 +130,26 @@ func _merge(baseService *types.ServiceConfig, overrideService *types.ServiceConf } else { baseService.Environment = overrideService.Environment } + baseService.Expose = unique(baseService.Expose) return baseService, nil } +func unique(slice []string) []string { + if slice == nil { + return nil + } + uniqMap := make(map[string]struct{}) + for _, v := range slice { + uniqMap[v] = struct{}{} + } + + uniqSlice := make([]string, 0, len(uniqMap)) + for v := range uniqMap { + uniqSlice = append(uniqSlice, v) + } + return uniqSlice +} + func toServiceSecretConfigsMap(s interface{}) (map[interface{}]interface{}, error) { secrets, ok := s.([]types.ServiceSecretConfig) if !ok { @@ -299,7 +319,7 @@ func mergeLoggingConfig(dst, src reflect.Value) error { return nil } -//nolint: unparam +// nolint: unparam func mergeUlimitsConfig(dst, src reflect.Value) error { if src.Interface() != reflect.Zero(reflect.TypeOf(src.Interface())).Interface() { dst.Elem().Set(src.Elem()) @@ -307,7 +327,7 @@ func mergeUlimitsConfig(dst, src reflect.Value) error { return nil } -//nolint: unparam +// 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")) diff --git a/loader/merge_test.go b/loader/merge_test.go index 329b08485..b74113bc0 100644 --- a/loader/merge_test.go +++ b/loader/merge_test.go @@ -1223,6 +1223,36 @@ func TestMergeCommands(t *testing.T) { assert.DeepEqual(t, merged.Services[0].Command, types.ShellCommand{"/bin/ash", "-c", "echo 'world'"}) } +func TestMergeHealthCheck(t *testing.T) { + configDetails := types.ConfigDetails{ + ConfigFiles: []types.ConfigFile{ + {Filename: "base.yml", Config: map[string]interface{}{ + "services": map[string]interface{}{ + "foo": map[string]interface{}{ + "image": "alpine", + "healthcheck": map[string]interface{}{ + "test": []interface{}{"CMD", "original"}, + }, + }, + }, + }}, + {Filename: "override.yml", Config: map[string]interface{}{ + "services": map[string]interface{}{ + "foo": map[string]interface{}{ + "image": "alpine", + "healthcheck": map[string]interface{}{ + "test": []interface{}{"CMD", "override"}, + }, + }, + }, + }}, + }, + } + merged, err := loadTestProject(configDetails) + assert.NilError(t, err) + assert.DeepEqual(t, merged.Services[0].HealthCheck.Test, types.HealthCheckTest{"CMD", "override"}) +} + func TestMergeEnvironments(t *testing.T) { configDetails := types.ConfigDetails{ ConfigFiles: []types.ConfigFile{