From 6ded6a38ebef5a12614e4306bfc007e6daa3cdc1 Mon Sep 17 00:00:00 2001 From: Tom Wright Date: Wed, 28 Sep 2022 10:44:32 +0100 Subject: [PATCH 1/2] Improve the way that selector comparisons are detected --- node_test.go | 12 ++++++------ selector.go | 36 ++++++++++++++++++++++++++++++++++-- selector_test.go | 5 +++++ 3 files changed, 45 insertions(+), 8 deletions(-) diff --git a/node_test.go b/node_test.go index 010d82dc..96a787db 100644 --- a/node_test.go +++ b/node_test.go @@ -138,8 +138,8 @@ func TestParseSelector(t *testing.T) { } }) t.Run("InvalidDynamicComparison", func(t *testing.T) { - _, err := dasel.ParseSelector(".(x<=>2)") - exp := &dasel.UnknownComparisonOperatorErr{Operator: "<=>"} + _, err := dasel.ParseSelector(".(x@2)") + exp := &dasel.UnknownComparisonOperatorErr{Operator: ""} if err == nil || err.Error() != exp.Error() { t.Errorf("expected error %v, got %v", exp, err) } @@ -152,15 +152,15 @@ func TestParseSelector(t *testing.T) { } }) t.Run("UnknownComparisonOperator", func(t *testing.T) { - _, err := dasel.ParseSelector(".(a<=>b)") - exp := "unknown comparison operator: <=>" + _, err := dasel.ParseSelector(".(a@b)") + exp := "unknown comparison operator: " if err == nil || err.Error() != exp { t.Errorf("expected error %v, got %v", exp, err) } }) t.Run("UnknownSearchComparisonOperator", func(t *testing.T) { - _, err := dasel.ParseSelector(".(?:a<=>b)") - exp := "unknown comparison operator: <=>" + _, err := dasel.ParseSelector(".(?:a@b)") + exp := "unknown comparison operator: " if err == nil || err.Error() != exp { t.Errorf("expected error %v, got %v", exp, err) } diff --git a/selector.go b/selector.go index 986f4513..55ee2897 100644 --- a/selector.go +++ b/selector.go @@ -2,6 +2,7 @@ package dasel import ( "errors" + "strings" ) // ErrDynamicSelectorBracketMismatch is returned when the number of opening brackets doesn't equal that @@ -85,6 +86,33 @@ type DynamicSelectorParts struct { Value string } +var comparisons = []string{ + "=", + "!=", + "<", + "<=", + ">", + ">=", +} + +func isBuildingComparison(comparison string) bool { + for _, c := range comparisons { + if strings.HasPrefix(c, comparison) { + return true + } + } + return false +} + +func isValidComparison(comparison string) bool { + for _, c := range comparisons { + if comparison == c { + return true + } + } + return false +} + // FindDynamicSelectorParts extracts the parts from the dynamic selector given. func FindDynamicSelectorParts(selector string) DynamicSelectorParts { i := 0 @@ -110,8 +138,12 @@ func FindDynamicSelectorParts(selector string) DynamicSelectorParts { parts.Value += string(v) } - // Matches a comparison character - case i == 0 && (v == '<' || v == '>' || v == '=' || v == '!'): + // Matches a comparison operator + case i == 0 && isValidComparison(parts.Comparison+string(v)): + parts.Comparison += string(v) + + // Is building a comparison character + case i == 0 && isBuildingComparison(parts.Comparison+string(v)): parts.Comparison += string(v) // Add to key or value based on comparison existence diff --git a/selector_test.go b/selector_test.go index a4816ef5..5b628824 100644 --- a/selector_test.go +++ b/selector_test.go @@ -92,6 +92,11 @@ func TestFindDynamicSelectorParts(t *testing.T) { Comparison: "=", Value: "b", })) + t.Run("EqualWithEqualsInValue", testFindDynamicSelectorParts("a=b=c", dasel.DynamicSelectorParts{ + Key: "a", + Comparison: "=", + Value: "b=c", + })) t.Run("NotEqual", testFindDynamicSelectorParts("a!=b", dasel.DynamicSelectorParts{ Key: "a", Comparison: "!=", From 6285df7e5e28e2d050cfeff4d3b25f9a7c50f5b0 Mon Sep 17 00:00:00 2001 From: Tom Wright Date: Wed, 28 Sep 2022 10:51:08 +0100 Subject: [PATCH 2/2] Add a test --- internal/command/root_select_test.go | 15 +++++++++++++++ 1 file changed, 15 insertions(+) diff --git a/internal/command/root_select_test.go b/internal/command/root_select_test.go index bb74e656..900fcf98 100644 --- a/internal/command/root_select_test.go +++ b/internal/command/root_select_test.go @@ -650,6 +650,21 @@ spec: t.Run("NullInput", selectTest(`null`, "yaml", `.`, newline("{}"), nil)) t.Run("EmptyDocument", selectTest(`---`, "yaml", `.`, newline("{}"), nil)) t.Run("BlankInput", selectTest(``, "yaml", `.`, newline("{}"), nil)) + + // https://github.com/TomWright/dasel/discussions/244 + t.Run("DynamicSelectorContainingEqualsInValue", selectTest(` +options: + k3s: + extraArgs: + - arg: --no-deploy=traefik + nodeFilters: + - server:* + - arg: --kube-apiserver-arg=feature-gates=HPAContainerMetrics=true + nodeFilters: + - server:* +`, "yaml", `.options.k3s.extraArgs.(arg=--no-deploy=traefik)`, newline(`arg: --no-deploy=traefik +nodeFilters: +- server:*`), nil)) } func TestRootCmd_Select_TOML(t *testing.T) {