Skip to content

Commit

Permalink
merge
Browse files Browse the repository at this point in the history
  • Loading branch information
kellerza committed Jul 14, 2021
1 parent 929abda commit e09dfaa
Show file tree
Hide file tree
Showing 2 changed files with 130 additions and 16 deletions.
55 changes: 39 additions & 16 deletions utils/env.go
Original file line number Diff line number Diff line change
Expand Up @@ -13,27 +13,50 @@ func ConvertEnvs(m map[string]string) []string {
return s
}

// mergeStringMaps merges map m1 into m2 and return a resulting map as a new map
// maps that are passed for merging will not be changed
func MergeStringMaps(m1, m2 map[string]string) map[string]string {
if m1 == nil {
return m2
}
if m2 == nil {
return m1
}
// make a copy of a map
m := make(map[string]string)
for k, v := range m1 {
m[k] = v
// merge all dictionaries and return a new dictionary
// recursively if matching keys are both dictionaries
func MergeDicts(dicts ...map[string]interface{}) map[string]interface{} {
res := make(map[string]interface{})
for _, m := range dicts {
if m == nil {
continue
}
for k, v := range m {

if v0, ok := res[k]; ok {
// Recursive merging if res[k] exists (and both are dicts)
t0, ok0 := v0.(map[string]interface{})
t1, ok1 := v.(map[string]interface{})
if ok0 && ok1 {
res[k] = MergeDicts(t0, t1)
continue
}
}
res[k] = v
}
}
return res
}

for k, v := range m2 {
m[k] = v
// merge all string maps and return a new map
// maps that are passed for merging will not be changed
func MergeStringMaps(maps ...map[string]string) map[string]string {
res := make(map[string]string)
for _, m := range maps {
if m == nil {
continue
}
for k, v := range m {
res[k] = v
}
}
if len(res) == 0 {
return nil
}
return m
return res
}

// does a slice contain a string
func StringInSlice(slice []string, val string) (int, bool) {
for i, item := range slice {
if item == val {
Expand Down
91 changes: 91 additions & 0 deletions utils/env_test.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,91 @@
package utils

import (
"fmt"
"testing"
)

func TestMergeDicts(t *testing.T) {
MergeDicts(nil, nil)
d1 := map[string]interface{}{
"t": "1",
}
d2 := map[string]interface{}{
"t": "2",
"t2": "1",
}
expect := func(m1, m2 map[string]interface{}, v ...string) {
d := MergeDicts(m1, m2)
for i := 0; i < len(v)/2; i++ {
if fmt.Sprintf("%v", d[v[i*2]]) != v[i*2+1] {
t.Errorf("err %v, expected %s", d, v)
}
}
}
expect(nil, d1, "t", "1")
expect(d1, d1, "t", "1")
expect(d1, nil, "t", "1")
expect(d2, d1, "t", "1", "t2", "1")
expect(d1, d2, "t", "2", "t2", "1")
expect(nil, d2, "t", "2", "t2", "1")
}

func TestMergeDictsRecursive(t *testing.T) {
d0 := map[string]interface{}{
"a": "1",
}
d1 := map[string]interface{}{
"a": "11",
"b": "2",
}
r0 := map[string]interface{}{
"r": d0,
"r1": "1",
}
r1 := map[string]interface{}{
"r": d1,
"r2": "2",
}
r3 := map[string]interface{}{
"r": "00",
"r2": "0",
}

expect := func(m1, m2 map[string]interface{}, v string) {
d := MergeDicts(m1, m2)
if fmt.Sprintf("%v", d) != v {
t.Errorf("err %v, expected %s", d, v)
}
}
// all simple vars... second overwrites
expect(d1, d0, "map[a:1 b:2]")
expect(d0, d1, "map[a:11 b:2]")

// r are both dicts... recursive on r... same inner result as the previous
expect(r1, r0, "map[r:map[a:1 b:2] r1:1 r2:2]")
expect(r0, r1, "map[r:map[a:11 b:2] r1:1 r2:2]")

// one is NOT a dict... second overwrites
expect(r1, r3, "map[r:00 r2:0]")
expect(r3, r1, "map[r:map[a:11 b:2] r2:2]")
}

func TestMergeStringMaps(t *testing.T) {
d0 := map[string]string{
"a": "1",
}
d1 := map[string]string{
"a": "11",
"b": "2",
}

expect := func(m1, m2 map[string]string, v string) {
d := MergeStringMaps(m1, m2)
if fmt.Sprintf("%v", d) != v {
t.Errorf("err %v, expected %s", d, v)
}
}
// all simple vars... second overwrites
expect(d1, d0, "map[a:1 b:2]")
expect(d0, d1, "map[a:11 b:2]")
}

0 comments on commit e09dfaa

Please sign in to comment.