From d431159fd44fb438e876dfa697971603c35f4261 Mon Sep 17 00:00:00 2001 From: Jan Dubois Date: Tue, 10 Dec 2024 21:37:43 -0800 Subject: [PATCH] Use yq string evaluator instead of stream evaluator This allows us to pass the YAML content in memory instead of having to write it to a file. This commit also switches to "eval-all" mode, so multiple documents are all loaded together, allowing merge operations between them. This is in preparation of multi-file template assembly. Signed-off-by: Jan Dubois --- pkg/yqutil/yqutil.go | 28 +++------------------------- pkg/yqutil/yqutil_test.go | 25 +++++++++++++++++++++++++ 2 files changed, 28 insertions(+), 25 deletions(-) diff --git a/pkg/yqutil/yqutil.go b/pkg/yqutil/yqutil.go index 2bae00b4f7c..cd0f0ddd99b 100644 --- a/pkg/yqutil/yqutil.go +++ b/pkg/yqutil/yqutil.go @@ -6,7 +6,6 @@ import ( "errors" "fmt" "io" - "os" "strings" "github.com/google/yamlfmt" @@ -37,7 +36,7 @@ func ValidateContent(content []byte) error { return err } -// EvaluateExpression evaluates the yq expression, and returns the modified yaml. +// EvaluateExpression evaluates the yq expression and returns the modified yaml. func EvaluateExpression(expression string, content []byte) ([]byte, error) { if expression == "" { return content, nil @@ -56,21 +55,6 @@ func EvaluateExpression(expression string, content []byte) ([]byte, error) { if err != nil { return nil, err } - tmpYAMLFile, err := os.CreateTemp("", "lima-yq-*.yaml") - if err != nil { - return nil, err - } - tmpYAMLPath := tmpYAMLFile.Name() - defer os.RemoveAll(tmpYAMLPath) - _, err = tmpYAMLFile.Write(contentModified) - if err != nil { - tmpYAMLFile.Close() - return nil, err - } - if err = tmpYAMLFile.Close(); err != nil { - return nil, err - } - memory := logging.NewMemoryBackend(0) backend := logging.AddModuleLevel(memory) logging.SetBackend(backend) @@ -80,13 +64,8 @@ func EvaluateExpression(expression string, content []byte) ([]byte, error) { encoderPrefs.Indent = 2 encoderPrefs.ColorsEnabled = false encoder := yqlib.NewYamlEncoder(encoderPrefs) - out := new(bytes.Buffer) - printer := yqlib.NewPrinter(encoder, yqlib.NewSinglePrinterWriter(out)) decoder := yqlib.NewYamlDecoder(yqlib.ConfiguredYamlPreferences) - - streamEvaluator := yqlib.NewStreamEvaluator() - files := []string{tmpYAMLPath} - err = streamEvaluator.EvaluateFiles(expression, files, printer, decoder) + out, err := yqlib.NewStringEvaluator().EvaluateAll(expression, string(contentModified), encoder, decoder) if err != nil { logger := logrus.StandardLogger() for node := memory.Head(); node != nil; node = node.Next() { @@ -110,8 +89,7 @@ func EvaluateExpression(expression string, content []byte) ([]byte, error) { } return nil, err } - - return formatter.Format(out.Bytes()) + return formatter.Format([]byte(out)) } func Join(yqExprs []string) string { diff --git a/pkg/yqutil/yqutil_test.go b/pkg/yqutil/yqutil_test.go index 89df0f24d9f..fb9b17a8ae4 100644 --- a/pkg/yqutil/yqutil_test.go +++ b/pkg/yqutil/yqutil_test.go @@ -1,6 +1,7 @@ package yqutil import ( + "strings" "testing" "gotest.tools/v3/assert" @@ -95,3 +96,27 @@ func TestEvaluateExpressionError(t *testing.T) { _, err := EvaluateExpression(expression, []byte("")) assert.ErrorContains(t, err, "invalid input text") } + +func TestEvaluateMergeExpression(t *testing.T) { + expression := `select(di == 0) * select(di == 1)` + content := ` +yolo: true +foo: + bar: 1 + baz: 2 +--- +foo: + bar: 3 + fomo: false +` + expected := ` +yolo: true +foo: + bar: 3 + baz: 2 + fomo: false +` + out, err := EvaluateExpression(expression, []byte(strings.TrimSpace(content))) + assert.NilError(t, err) + assert.Equal(t, strings.TrimSpace(expected), strings.TrimSpace(string(out))) +}