From 587af7f722c49ca2446aba57b441207ce4743282 Mon Sep 17 00:00:00 2001 From: Mike Farah Date: Fri, 22 Oct 2021 15:21:01 +1100 Subject: [PATCH] Fixed newline handling in encoder/decoder --- pkg/yqlib/doc/Encoder and Decoder.md | 2 ++ pkg/yqlib/operator_encoder_decoder.go | 6 ++++-- pkg/yqlib/operator_encoder_decoder_test.go | 11 ++++++++++- 3 files changed, 16 insertions(+), 3 deletions(-) diff --git a/pkg/yqlib/doc/Encoder and Decoder.md b/pkg/yqlib/doc/Encoder and Decoder.md index 3cc179cc..ae7bca4a 100644 --- a/pkg/yqlib/doc/Encoder and Decoder.md +++ b/pkg/yqlib/doc/Encoder and Decoder.md @@ -1,5 +1,6 @@ Encode operators will take the piped in object structure and encode it as a string in the desired format. The decode operators do the opposite, they take a formatted string and decode it into the relevant object structure. +These operators are useful to process yaml documents that have stringified embeded yaml/json/props in them. ## Encode value as yaml string Given a sample.yml file of: ```yaml @@ -98,6 +99,7 @@ Given a sample.yml file of: a: | foo: bar baz: dog + ``` then ```bash diff --git a/pkg/yqlib/operator_encoder_decoder.go b/pkg/yqlib/operator_encoder_decoder.go index 629d0e45..7accc51b 100644 --- a/pkg/yqlib/operator_encoder_decoder.go +++ b/pkg/yqlib/operator_encoder_decoder.go @@ -28,6 +28,7 @@ func encodeOperator(d *dataTreeNavigator, context Context, expressionNode *Expre var results = list.New() hasOnlyOneNewLine := regexp.MustCompile("[^\n].*\n$") + endWithNewLine := regexp.MustCompile(".*\n$") chomper := regexp.MustCompile("\n+$") for el := context.MatchingNodes.Front(); el != nil; el = el.Next() { @@ -44,8 +45,9 @@ func encodeOperator(d *dataTreeNavigator, context Context, expressionNode *Expre if originalList != nil && originalList.Len() > 0 && hasOnlyOneNewLine.MatchString(stringValue) { original := originalList.Front().Value.(*CandidateNode) - if unwrapDoc(original.Node).Style == yaml.SingleQuotedStyle || - unwrapDoc(original.Node).Style == yaml.DoubleQuotedStyle { + originalNode := unwrapDoc(original.Node) + // original block did not have a new line at the end, get rid of this one too + if !endWithNewLine.MatchString(originalNode.Value) { stringValue = chomper.ReplaceAllString(stringValue, "") } } diff --git a/pkg/yqlib/operator_encoder_decoder_test.go b/pkg/yqlib/operator_encoder_decoder_test.go index 55bcbaad..85ff0f8d 100644 --- a/pkg/yqlib/operator_encoder_decoder_test.go +++ b/pkg/yqlib/operator_encoder_decoder_test.go @@ -53,12 +53,21 @@ var encoderDecoderOperatorScenarios = []expressionScenario{ { description: "Update a multiline encoded yaml string", dontFormatInputForDoc: true, - document: "a: |\n foo: bar\n baz: dog", + document: "a: |\n foo: bar\n baz: dog\n", expression: `.a |= (from_yaml | .foo = "cat" | to_yaml)`, expected: []string{ "D0, P[], (doc)::a: |\n foo: cat\n baz: dog\n", }, }, + { + skipDoc: true, + dontFormatInputForDoc: true, + document: "a: |-\n foo: bar\n baz: dog\n", + expression: `.a |= (from_yaml | .foo = "cat" | to_yaml)`, + expected: []string{ + "D0, P[], (doc)::a: |-\n foo: cat\n baz: dog\n", + }, + }, { description: "Update a single line encoded yaml string", dontFormatInputForDoc: true,