Repository: knative/pkg
Pull request #1360 (2020-05-26 22:40:52)

Make UnionMaps variadic!
Thanks @dprotaso for the suggestion.

/assign @dprotaso 

knative-prow-robot: [APPROVALNOTIFIER] This PR is **APPROVED**

This pull-request has been approved by: *<a href="https://github.com/knative/pkg/pull/1360#" title="Author self-approved">vagababov</a>*

The full list of commands accepted by this bot can be found [here](https://go.k8s.io/bot-commands?repo=knative%2Fpkg).

The pull request process is described [here](https://git.k8s.io/community/contributors/guide/owners.md#the-code-review-process)

<details >
Needs approval from an approver in each of these files:

- ~~[kmeta/OWNERS](https://github.com/knative/pkg/blob/master/kmeta/OWNERS)~~ [vagababov]

Approvers can indicate their approval by writing `/approve` in a comment
Approvers can cancel approval by writing `/approve cancel` in a comment
</details>
<!-- META={"approvers":[]} -->
vagababov: /assign mattmoor
knative-prow-robot: @vagababov: The following test **failed**, say `/retest` to rerun all failed tests:

Test name | Commit | Details | Rerun command
--- | --- | --- | ---
pull-knative-pkg-unit-tests | 794c709b47df5e76ca964d9348bed3b834eff6c9 | [link](https://prow.knative.dev/view/gcs/knative-prow/pr-logs/pull/knative_pkg/1360/pull-knative-pkg-unit-tests/1265412711240437761) | `/test pull-knative-pkg-unit-tests`

[Full PR test history](https://gubernator.knative.dev/pr/knative_pkg/1360). [Your PR dashboard](https://gubernator.knative.dev/pr/vagababov).

<details>

Instructions for interacting with me using PR comments are available [here](https://git.k8s.io/community/contributors/guide/pull-requests.md).  If you have questions or suggestions related to my behavior, please file an issue against the [kubernetes/test-infra](https://github.com/kubernetes/test-infra/issues/new?title=Prow%20issue:) repository. I understand the commands that are listed [here](https://go.k8s.io/bot-commands).
</details>
<!-- test report -->
vagababov: unrelated 
/retest
tcnghia: /lgtm

Patch:
diff --git a/kmeta/map.go b/kmeta/map.go
index fc1b9b0ac..37154cd28 100644
--- a/kmeta/map.go
+++ b/kmeta/map.go
@@ -25,16 +25,18 @@ func CopyMap(a map[string]string) map[string]string {
 	return ret
 }
 
-// UnionMaps returns a map constructed from the union of `a` and `b`,
-// where value from `b` wins.
-func UnionMaps(a, b map[string]string) map[string]string {
-	out := make(map[string]string, len(a)+len(b))
-
-	for k, v := range a {
-		out[k] = v
+// UnionMaps returns a map constructed from the union of input maps.
+// where values from latter maps win.
+func UnionMaps(maps ...map[string]string) map[string]string {
+	if len(maps) == 0 {
+		return map[string]string{}
 	}
-	for k, v := range b {
-		out[k] = v
+	out := make(map[string]string, len(maps[0]))
+
+	for _, m := range maps {
+		for k, v := range m {
+			out[k] = v
+		}
 	}
 	return out
 }


Test patch:
diff --git a/kmeta/map_test.go b/kmeta/map_test.go
index 8f1926ad1..82c39e3b9 100644
--- a/kmeta/map_test.go
+++ b/kmeta/map_test.go
@@ -25,39 +25,52 @@ import (
 func TestUnion(t *testing.T) {
 	tests := []struct {
 		name string
-		in   map[string]string
-		add  map[string]string
+		in   []map[string]string
 		want map[string]string
 	}{{
-		name: "nil all",
+		name: "nothing at all",
 		want: map[string]string{},
 	}, {
 		name: "empty in",
-		in:   map[string]string{},
+		in:   []map[string]string{},
+		want: map[string]string{},
+	}, {
+		name: "nil in list",
+		in:   []map[string]string{nil},
 		want: map[string]string{},
 	}, {
-		name: "no in, only additions",
-		add:  map[string]string{"wish": "you", "were": "here"},
+		name: "empty in recursive",
+		in:   []map[string]string{{}},
+		want: map[string]string{},
+	}, {
+		name: "nil and something",
+		in:   []map[string]string{nil, {"wish": "you", "were": "here"}},
 		want: map[string]string{"wish": "you", "were": "here"},
 	}, {
-		name: "in, no add",
-		in:   map[string]string{"the-dark": "side"},
+		name: "something and nil",
+		in:   []map[string]string{{"the-dark": "side"}},
 		want: map[string]string{"the-dark": "side"},
 	}, {
-		name: "all together now",
-		in:   map[string]string{"another": "brick"},
-		add:  map[string]string{"in": "the-wall"},
+		name: "2 in",
+		in:   []map[string]string{{"another": "brick"}, {"in": "the-wall"}},
 		want: map[string]string{"in": "the-wall", "another": "brick"},
 	}, {
-		name: "merge wins",
-		in:   map[string]string{"another": "brick", "in": "the-wall-pt-I"},
-		add:  map[string]string{"in": "the-wall-pt-II"},
+		name: "2 in, latter wins",
+		in:   []map[string]string{{"another": "brick", "in": "the-wall-pt-I"}, {"in": "the-wall-pt-II"}},
 		want: map[string]string{"in": "the-wall-pt-II", "another": "brick"},
+	}, {
+		name: "3 in, latter wins",
+		in: []map[string]string{
+			{"another": "brick", "in": "the-wall-pt-I"},
+			{"in": "the-wall-pt-II"},
+			{"in": "the-wall-pt-III", "hey": "you"},
+		},
+		want: map[string]string{"in": "the-wall-pt-III", "another": "brick", "hey": "you"},
 	}}
 
 	for _, test := range tests {
 		t.Run(test.name, func(t *testing.T) {
-			got := UnionMaps(test.in, test.add)
+			got := UnionMaps(test.in...)
 			if diff := cmp.Diff(test.want, got); diff != "" {
 				t.Errorf("MakeLabels (-want, +got) = %v", diff)
 			}