fix: incomplete environment values merging (#378)

Fixes #377

Ref https://github.com/imdario/mergo/pull/81
This commit is contained in:
KUOKA Yusuke 2018-10-03 22:39:37 +09:00 committed by GitHub
parent 770c3daa5f
commit b0f9062e08
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
5 changed files with 68 additions and 13 deletions

43
Gopkg.lock generated
View File

@ -2,59 +2,78 @@
[[projects]] [[projects]]
digest = "1:d9141c149f722217d35834972878499a4781fe5ae46a152e8ac843ff15efc80f"
name = "github.com/Masterminds/semver" name = "github.com/Masterminds/semver"
packages = ["."] packages = ["."]
pruneopts = "UT"
revision = "8d82589cda2d7b5b9167396841975c4535c9bec6" revision = "8d82589cda2d7b5b9167396841975c4535c9bec6"
version = "v1.4.1" version = "v1.4.1"
[[projects]] [[projects]]
digest = "1:46a054a232ea2b7f0a35398d682b433d26ba9975fce9197b1784824402059f5b"
name = "github.com/Masterminds/sprig" name = "github.com/Masterminds/sprig"
packages = ["."] packages = ["."]
pruneopts = "UT"
revision = "6b2a58267f6a8b1dc8e2eb5519b984008fa85e8c" revision = "6b2a58267f6a8b1dc8e2eb5519b984008fa85e8c"
version = "v2.15.0" version = "v2.15.0"
[[projects]] [[projects]]
digest = "1:8f5416c7f59da8600725ae1ff00a99af1da8b04c211ae6f3c8f8bcab0164f650"
name = "github.com/aokoli/goutils" name = "github.com/aokoli/goutils"
packages = ["."] packages = ["."]
pruneopts = "UT"
revision = "3391d3790d23d03408670993e957e8f408993c34" revision = "3391d3790d23d03408670993e957e8f408993c34"
version = "v1.0.1" version = "v1.0.1"
[[projects]] [[projects]]
digest = "1:8f8811f9be822914c3a25c6a071e93beb4c805d7b026cbf298bc577bc1cc945b"
name = "github.com/google/uuid" name = "github.com/google/uuid"
packages = ["."] packages = ["."]
pruneopts = "UT"
revision = "064e2069ce9c359c118179501254f67d7d37ba24" revision = "064e2069ce9c359c118179501254f67d7d37ba24"
version = "0.2" version = "0.2"
[[projects]] [[projects]]
digest = "1:6b1e7618931d0ed9a17fec1c1d84271907aa61172c50b8272327f6cd4fafb650"
name = "github.com/huandu/xstrings" name = "github.com/huandu/xstrings"
packages = ["."] packages = ["."]
pruneopts = "UT"
revision = "2bf18b218c51864a87384c06996e40ff9dcff8e1" revision = "2bf18b218c51864a87384c06996e40ff9dcff8e1"
version = "v1.0.0" version = "v1.0.0"
[[projects]] [[projects]]
digest = "1:8eb1de8112c9924d59bf1d3e5c26f5eaa2bfc2a5fcbb92dc1c2e4546d695f277"
name = "github.com/imdario/mergo" name = "github.com/imdario/mergo"
packages = ["."] packages = ["."]
revision = "9d5f1277e9a8ed20c3684bda8fde67c05628518c" pruneopts = "UT"
version = "v0.3.4" revision = "9f23e2d6bd2a77f959b2bf6acdbefd708a83a4a4"
version = "v0.3.6"
[[projects]] [[projects]]
digest = "1:55d0f7127962b0657acfd69650634057b3a08958226feee1b64a379666bb915e"
name = "github.com/urfave/cli" name = "github.com/urfave/cli"
packages = ["."] packages = ["."]
pruneopts = "UT"
revision = "6011f165dc288c72abd8acd7722f837c5c64198d" revision = "6011f165dc288c72abd8acd7722f837c5c64198d"
[[projects]] [[projects]]
digest = "1:3c1a69cdae3501bf75e76d0d86dc6f2b0a7421bc205c0cb7b96b19eed464a34d"
name = "go.uber.org/atomic" name = "go.uber.org/atomic"
packages = ["."] packages = ["."]
pruneopts = "UT"
revision = "1ea20fb1cbb1cc08cbd0d913a96dead89aa18289" revision = "1ea20fb1cbb1cc08cbd0d913a96dead89aa18289"
version = "v1.3.2" version = "v1.3.2"
[[projects]] [[projects]]
digest = "1:60bf2a5e347af463c42ed31a493d817f8a72f102543060ed992754e689805d1a"
name = "go.uber.org/multierr" name = "go.uber.org/multierr"
packages = ["."] packages = ["."]
pruneopts = "UT"
revision = "3c4937480c32f4c13a875a1829af76c98ca3d40a" revision = "3c4937480c32f4c13a875a1829af76c98ca3d40a"
version = "v1.1.0" version = "v1.1.0"
[[projects]] [[projects]]
digest = "1:9580b1b079114140ade8cec957685344d14f00119e0241f6b369633cb346eeb3"
name = "go.uber.org/zap" name = "go.uber.org/zap"
packages = [ packages = [
".", ".",
@ -62,29 +81,41 @@
"internal/bufferpool", "internal/bufferpool",
"internal/color", "internal/color",
"internal/exit", "internal/exit",
"zapcore" "zapcore",
] ]
pruneopts = "UT"
revision = "eeedf312bc6c57391d84767a4cd413f02a917974" revision = "eeedf312bc6c57391d84767a4cd413f02a917974"
version = "v1.8.0" version = "v1.8.0"
[[projects]] [[projects]]
branch = "master" branch = "master"
digest = "1:7b1c378a71f617ec07229a1fcbb90b6a5344295823e1d732398f50fd9ae4bbec"
name = "golang.org/x/crypto" name = "golang.org/x/crypto"
packages = [ packages = [
"pbkdf2", "pbkdf2",
"scrypt" "scrypt",
] ]
pruneopts = "UT"
revision = "b2aa35443fbc700ab74c586ae79b81c171851023" revision = "b2aa35443fbc700ab74c586ae79b81c171851023"
[[projects]] [[projects]]
branch = "v2"
digest = "1:342378ac4dcb378a5448dd723f0784ae519383532f5e70ade24132c4c8693202"
name = "gopkg.in/yaml.v2" name = "gopkg.in/yaml.v2"
packages = ["."] packages = ["."]
pruneopts = "UT"
revision = "5420a8b6744d3b0345ab293f6fcba19c978f1183" revision = "5420a8b6744d3b0345ab293f6fcba19c978f1183"
version = "v2.2.1"
[solve-meta] [solve-meta]
analyzer-name = "dep" analyzer-name = "dep"
analyzer-version = 1 analyzer-version = 1
inputs-digest = "b1f000751afc0a44973307c69b6a4b8e8c1b807fd9881a13f370c30fcbcab7a2" input-imports = [
"github.com/Masterminds/sprig",
"github.com/imdario/mergo",
"github.com/urfave/cli",
"go.uber.org/zap",
"go.uber.org/zap/zapcore",
"gopkg.in/yaml.v2",
]
solver-name = "gps-cdcl" solver-name = "gps-cdcl"
solver-version = 1 solver-version = 1

View File

@ -12,4 +12,4 @@
[[constraint]] [[constraint]]
name = "github.com/imdario/mergo" name = "github.com/imdario/mergo"
version = "0.3.4" version = "0.3.6"

View File

@ -27,7 +27,7 @@ It is ready for production use. [It is used in several projects by Docker, Googl
### Latest release ### Latest release
[Release v0.3.4](https://github.com/imdario/mergo/releases/tag/v0.3.4). [Release v0.3.6](https://github.com/imdario/mergo/releases/tag/v0.3.6).
### Important note ### Important note

View File

@ -9,6 +9,7 @@
package mergo package mergo
import ( import (
"fmt"
"reflect" "reflect"
) )
@ -103,7 +104,15 @@ func deepMerge(dst, src reflect.Value, visited map[uintptr]*visit, depth int, co
case reflect.Ptr: case reflect.Ptr:
fallthrough fallthrough
case reflect.Map: case reflect.Map:
if err = deepMerge(dstElement, srcElement, visited, depth+1, config); err != nil { srcMapElm := srcElement
dstMapElm := dstElement
if srcMapElm.CanInterface() {
srcMapElm = reflect.ValueOf(srcMapElm.Interface())
if dstMapElm.IsValid() {
dstMapElm = reflect.ValueOf(dstMapElm.Interface())
}
}
if err = deepMerge(dstMapElm, srcMapElm, visited, depth+1, config); err != nil {
return return
} }
case reflect.Slice: case reflect.Slice:
@ -116,7 +125,14 @@ func deepMerge(dst, src reflect.Value, visited map[uintptr]*visit, depth int, co
dstSlice = reflect.ValueOf(dstElement.Interface()) dstSlice = reflect.ValueOf(dstElement.Interface())
} }
if !isEmptyValue(src) && (overwrite || isEmptyValue(dst)) && !config.AppendSlice {
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())
}
dstSlice = reflect.AppendSlice(dstSlice, srcSlice) dstSlice = reflect.AppendSlice(dstSlice, srcSlice)
}
dst.SetMapIndex(key, dstSlice) dst.SetMapIndex(key, dstSlice)
} }
} }
@ -124,7 +140,7 @@ func deepMerge(dst, src reflect.Value, visited map[uintptr]*visit, depth int, co
continue continue
} }
if srcElement.IsValid() && (overwrite || (!dstElement.IsValid() || isEmptyValue(dst))) { if srcElement.IsValid() && (overwrite || (!dstElement.IsValid() || isEmptyValue(dstElement))) {
if dst.IsNil() { if dst.IsNil() {
dst.Set(reflect.MakeMap(dst.Type())) dst.Set(reflect.MakeMap(dst.Type()))
} }
@ -137,7 +153,10 @@ func deepMerge(dst, src reflect.Value, visited map[uintptr]*visit, depth int, co
} }
if !isEmptyValue(src) && (overwrite || isEmptyValue(dst)) && !config.AppendSlice { if !isEmptyValue(src) && (overwrite || isEmptyValue(dst)) && !config.AppendSlice {
dst.Set(src) dst.Set(src)
} else { } else if config.AppendSlice {
if src.Type() != dst.Type() {
return fmt.Errorf("cannot append two slice with different type (%s, %s)", src.Type(), dst.Type())
}
dst.Set(reflect.AppendSlice(dst, src)) dst.Set(reflect.AppendSlice(dst, src))
} }
case reflect.Ptr: case reflect.Ptr:

View File

@ -45,7 +45,12 @@ func isEmptyValue(v reflect.Value) bool {
return v.Uint() == 0 return v.Uint() == 0
case reflect.Float32, reflect.Float64: case reflect.Float32, reflect.Float64:
return v.Float() == 0 return v.Float() == 0
case reflect.Interface, reflect.Ptr, reflect.Func: case reflect.Interface, reflect.Ptr:
if v.IsNil() {
return true
}
return isEmptyValue(v.Elem())
case reflect.Func:
return v.IsNil() return v.IsNil()
case reflect.Invalid: case reflect.Invalid:
return true return true