diff --git a/cmd/evalute_sequence_command.go b/cmd/evalute_sequence_command.go index 45625207..9ee0d294 100644 --- a/cmd/evalute_sequence_command.go +++ b/cmd/evalute_sequence_command.go @@ -63,7 +63,6 @@ func evaluateSequence(cmd *cobra.Command, args []string) error { printer := yqlib.NewPrinter(out, outputToJSON, unwrapScalar, colorsEnabled, indent, !noDocSeparators) streamEvaluator := yqlib.NewStreamEvaluator() - allAtOnceEvaluator := yqlib.NewAllAtOnceEvaluator() switch len(args) { case 0: @@ -75,7 +74,7 @@ func evaluateSequence(cmd *cobra.Command, args []string) error { } case 1: if nullInput { - err = allAtOnceEvaluator.EvaluateFiles(args[0], []string{}, printer) + err = streamEvaluator.EvaluateNew(args[0], printer) } else { err = streamEvaluator.EvaluateFiles("", []string{args[0]}, printer) } diff --git a/pkg/yqlib/doc/Assign.md b/pkg/yqlib/doc/Assign.md index 11524986..f902e029 100644 --- a/pkg/yqlib/doc/Assign.md +++ b/pkg/yqlib/doc/Assign.md @@ -5,6 +5,18 @@ Which will assign the LHS node values to the RHS node values. The RHS expression ### relative form: `|=` This will do a similar thing to the plain form, however, the RHS expression is run against _the LHS nodes_. This is useful for updating values based on old values, e.g. increment. +## Create yaml file +Running +```bash +yq eval --null-input '(.a.b = "cat") | (.x = "frog")' +``` +will output +```yaml +a: + b: cat +x: frog +``` + ## Update node to be the child value Given a sample.yml file of: ```yaml diff --git a/pkg/yqlib/operator_assign.go b/pkg/yqlib/operator_assign.go index 5a6f3b58..82c7db04 100644 --- a/pkg/yqlib/operator_assign.go +++ b/pkg/yqlib/operator_assign.go @@ -36,6 +36,11 @@ func AssignUpdateOperator(d *dataTreeNavigator, matchingNodes *list.List, pathNo candidate.UpdateFrom(first.Value.(*CandidateNode)) } } + // // if there was nothing given, perhaps we are creating a new yaml doc + // if matchingNodes.Len() == 0 { + // log.Debug("started with nothing, returning LHS, %v", lhs.Len()) + // return lhs, nil + // } return matchingNodes, nil } diff --git a/pkg/yqlib/operator_assign_test.go b/pkg/yqlib/operator_assign_test.go index cf5fa788..def448bb 100644 --- a/pkg/yqlib/operator_assign_test.go +++ b/pkg/yqlib/operator_assign_test.go @@ -5,6 +5,13 @@ import ( ) var assignOperatorScenarios = []expressionScenario{ + { + description: "Create yaml file", + expression: `(.a.b = "cat") | (.x = "frog")`, + expected: []string{ + "D0, P[], ()::a:\n b: cat\nx: frog\n", + }, + }, { description: "Update node to be the child value", document: `{a: {b: {g: foof}}}`, diff --git a/pkg/yqlib/operators_test.go b/pkg/yqlib/operators_test.go index 083ce930..610c8873 100644 --- a/pkg/yqlib/operators_test.go +++ b/pkg/yqlib/operators_test.go @@ -11,6 +11,7 @@ import ( "testing" "github.com/mikefarah/yq/v4/test" + yaml "gopkg.in/yaml.v3" ) type expressionScenario struct { @@ -40,6 +41,15 @@ func testScenario(t *testing.T, s *expressionScenario) { t.Error(err, s.document) return } + } else { + candidateNode := &CandidateNode{ + Document: 0, + Filename: "", + Node: &yaml.Node{Tag: "!!null"}, + FileIndex: 0, + } + inputs.PushBack(candidateNode) + } results, err = treeNavigator.GetMatchingNodes(inputs, node) @@ -152,20 +162,20 @@ func documentScenarios(t *testing.T, title string, scenarios []expressionScenari var output bytes.Buffer var err error printer := NewPrinter(bufio.NewWriter(&output), false, true, false, 2, true) + streamEvaluator := NewStreamEvaluator() if s.document != "" { node, err := treeCreator.ParsePath(s.expression) if err != nil { t.Error(err) } - streamEvaluator := NewStreamEvaluator() err = streamEvaluator.Evaluate("sample.yaml", strings.NewReader(formattedDoc), node, printer) + if err != nil { t.Error(err) } } else { - allAtOnceEvaluator := NewAllAtOnceEvaluator() - err = allAtOnceEvaluator.EvaluateFiles(s.expression, []string{}, printer) + err = streamEvaluator.EvaluateNew(s.expression, printer) if err != nil { t.Error(err) } diff --git a/pkg/yqlib/stream_evaluator.go b/pkg/yqlib/stream_evaluator.go index d4c22f19..b2fdb9e1 100644 --- a/pkg/yqlib/stream_evaluator.go +++ b/pkg/yqlib/stream_evaluator.go @@ -11,6 +11,7 @@ import ( type StreamEvaluator interface { Evaluate(filename string, reader io.Reader, node *PathTreeNode, printer Printer) error EvaluateFiles(expression string, filenames []string, printer Printer) error + EvaluateNew(expression string, printer Printer) error } type streamEvaluator struct { @@ -23,6 +24,27 @@ func NewStreamEvaluator() StreamEvaluator { return &streamEvaluator{treeNavigator: NewDataTreeNavigator(), treeCreator: NewPathTreeCreator()} } +func (s *streamEvaluator) EvaluateNew(expression string, printer Printer) error { + node, err := treeCreator.ParsePath(expression) + if err != nil { + return err + } + candidateNode := &CandidateNode{ + Document: 0, + Filename: "", + Node: &yaml.Node{Tag: "!!null"}, + FileIndex: 0, + } + inputList := list.New() + inputList.PushBack(candidateNode) + + matches, errorParsing := treeNavigator.GetMatchingNodes(inputList, node) + if errorParsing != nil { + return errorParsing + } + return printer.PrintResults(matches) +} + func (s *streamEvaluator) EvaluateFiles(expression string, filenames []string, printer Printer) error { node, err := treeCreator.ParsePath(expression)