Repository: knative/client (go)

Issue:
Error when multiple filter with the same name are given for kn trigger
In `kn trigger --filter type=bla --filter type=blub`, "blub" will silently win. As this is very likely not the user's intent, an error should be thrown instead.

Same btw for "kn service create --env". The check could be part of a unified list-option handling.

Pull request description:
Retrurn error if exist duplicate key in filter option
Fixes #569

## Proposed Changes

*Return error if user set duplicate key in `--filter` option. For example, `kn trigger create --filter type=bla --filter type=blub test`.


Patch:
diff --git a/pkg/kn/commands/trigger/update_flags.go b/pkg/kn/commands/trigger/update_flags.go
index e3246540..e18317b6 100644
--- a/pkg/kn/commands/trigger/update_flags.go
+++ b/pkg/kn/commands/trigger/update_flags.go
@@ -54,6 +54,9 @@ func (f *TriggerUpdateFlags) GetFilters() (map[string]string, error) {
 		if len(parts) < 2 || parts[0] == "" || parts[1] == "" {
 			return nil, fmt.Errorf("invalid filter %s", f.Filters)
 		} else {
+			if _, ok := filters[parts[0]]; ok {
+				return nil, fmt.Errorf("duplicate key '%s' in filters %s", parts[0], f.Filters)
+			}
 			filters[parts[0]] = parts[1]
 		}
 	}
@@ -72,6 +75,9 @@ func (f *TriggerUpdateFlags) GetUpdateFilters() (map[string]string, []string, er
 			if len(parts) < 2 || parts[0] == "" || parts[1] == "" {
 				return nil, nil, fmt.Errorf("invalid filter %s", f.Filters)
 			}
+			if _, ok := filters[parts[0]]; ok {
+				return nil, nil, fmt.Errorf("duplicate key '%s' in filters %s", parts[0], f.Filters)
+			}
 			filters[parts[0]] = parts[1]
 		}
 	}


Test patch:
diff --git a/pkg/kn/commands/trigger/update_flags_test.go b/pkg/kn/commands/trigger/update_flags_test.go
index d383d815..b52d9322 100644
--- a/pkg/kn/commands/trigger/update_flags_test.go
+++ b/pkg/kn/commands/trigger/update_flags_test.go
@@ -59,6 +59,14 @@ func TestGetFilters(t *testing.T) {
 		_, err = createFlag.GetFilters()
 		assert.ErrorContains(t, err, "invalid filter")
 	})
+
+	t.Run("get duplicate filters", func(t *testing.T) {
+		createFlag := TriggerUpdateFlags{
+			Filters: filterArray{"type=foo", "type=bar"},
+		}
+		_, err := createFlag.GetFilters()
+		assert.ErrorContains(t, err, "duplicate key")
+	})
 }
 
 func TestGetUpdateFilters(t *testing.T) {
@@ -101,4 +109,12 @@ func TestGetUpdateFilters(t *testing.T) {
 		assert.DeepEqual(t, wantedRemoved, removed)
 		assert.DeepEqual(t, wantedUpdated, updated)
 	})
+
+	t.Run("update duplicate filters", func(t *testing.T) {
+		createFlag := TriggerUpdateFlags{
+			Filters: filterArray{"type=foo", "type=bar"},
+		}
+		_, _, err := createFlag.GetUpdateFilters()
+		assert.ErrorContains(t, err, "duplicate key")
+	})
 }