mirror of
https://github.com/mikefarah/yq.git
synced 2024-12-19 20:19:04 +00:00
Adding a EvaluateAll function to StringEvaluator #1966
This commit is contained in:
parent
93ed666000
commit
b4463e29e8
@ -4,19 +4,16 @@ import (
|
||||
"bufio"
|
||||
"bytes"
|
||||
"container/list"
|
||||
"errors"
|
||||
"fmt"
|
||||
"io"
|
||||
"strings"
|
||||
)
|
||||
|
||||
type StringEvaluator interface {
|
||||
Evaluate(expression string, input string, encoder Encoder, decoder Decoder) (string, error)
|
||||
EvaluateAll(expression string, input string, encoder Encoder, decoder Decoder) (string, error)
|
||||
}
|
||||
|
||||
type stringEvaluator struct {
|
||||
treeNavigator DataTreeNavigator
|
||||
fileIndex int
|
||||
}
|
||||
|
||||
func NewStringEvaluator() StringEvaluator {
|
||||
@ -25,6 +22,29 @@ func NewStringEvaluator() StringEvaluator {
|
||||
}
|
||||
}
|
||||
|
||||
func (s *stringEvaluator) EvaluateAll(expression string, input string, encoder Encoder, decoder Decoder) (string, error) {
|
||||
reader := bufio.NewReader(strings.NewReader(input))
|
||||
var documents *list.List
|
||||
var results *list.List
|
||||
var err error
|
||||
|
||||
if documents, err = ReadDocuments(reader, decoder); err != nil {
|
||||
return "", err
|
||||
}
|
||||
|
||||
evaluator := NewAllAtOnceEvaluator()
|
||||
if results, err = evaluator.EvaluateCandidateNodes(expression, documents); err != nil {
|
||||
return "", err
|
||||
}
|
||||
|
||||
out := new(bytes.Buffer)
|
||||
printer := NewPrinter(encoder, NewSinglePrinterWriter(out))
|
||||
if err := printer.PrintResults(results); err != nil {
|
||||
return "", err
|
||||
}
|
||||
return out.String(), nil
|
||||
}
|
||||
|
||||
func (s *stringEvaluator) Evaluate(expression string, input string, encoder Encoder, decoder Decoder) (string, error) {
|
||||
|
||||
// Use bytes.Buffer for output of string
|
||||
@ -38,36 +58,9 @@ func (s *stringEvaluator) Evaluate(expression string, input string, encoder Enco
|
||||
}
|
||||
|
||||
reader := bufio.NewReader(strings.NewReader(input))
|
||||
|
||||
var currentIndex uint
|
||||
err = decoder.Init(reader)
|
||||
if err != nil {
|
||||
evaluator := NewStreamEvaluator()
|
||||
if _, err := evaluator.Evaluate("", reader, node, printer, decoder); err != nil {
|
||||
return "", err
|
||||
}
|
||||
for {
|
||||
candidateNode, errorReading := decoder.Decode()
|
||||
|
||||
if errors.Is(errorReading, io.EOF) {
|
||||
s.fileIndex = s.fileIndex + 1
|
||||
return out.String(), nil
|
||||
} else if errorReading != nil {
|
||||
return "", fmt.Errorf("bad input '%v': %w", input, errorReading)
|
||||
}
|
||||
candidateNode.document = currentIndex
|
||||
candidateNode.fileIndex = s.fileIndex
|
||||
|
||||
inputList := list.New()
|
||||
inputList.PushBack(candidateNode)
|
||||
|
||||
result, errorParsing := s.treeNavigator.GetMatchingNodes(Context{MatchingNodes: inputList}, node)
|
||||
if errorParsing != nil {
|
||||
return "", errorParsing
|
||||
}
|
||||
err = printer.PrintResults(result.MatchingNodes)
|
||||
|
||||
if err != nil {
|
||||
return "", err
|
||||
}
|
||||
currentIndex = currentIndex + 1
|
||||
}
|
||||
return out.String(), nil
|
||||
}
|
||||
|
@ -6,6 +6,20 @@ import (
|
||||
"github.com/mikefarah/yq/v4/test"
|
||||
)
|
||||
|
||||
func TestStringEvaluator_MultipleDocumentMerge(t *testing.T) {
|
||||
yamlString := "a: Hello\n---\na: Goodbye\n"
|
||||
expected_output := "a: Goodbye\n"
|
||||
|
||||
encoder := NewYamlEncoder(ConfiguredYamlPreferences)
|
||||
decoder := NewYamlDecoder(ConfiguredYamlPreferences)
|
||||
result, err := NewStringEvaluator().EvaluateAll("select(di==0) * select(di==1)", yamlString, encoder, decoder)
|
||||
if err != nil {
|
||||
t.Error(err)
|
||||
} else {
|
||||
test.AssertResult(t, expected_output, result)
|
||||
}
|
||||
}
|
||||
|
||||
func TestStringEvaluator_Evaluate_Nominal(t *testing.T) {
|
||||
expected_output := `` +
|
||||
`yq` + "\n" +
|
||||
@ -24,7 +38,7 @@ func TestStringEvaluator_Evaluate_Nominal(t *testing.T) {
|
||||
result, err := NewStringEvaluator().Evaluate(expression, input, encoder, decoder)
|
||||
if err != nil {
|
||||
t.Error(err)
|
||||
} else {
|
||||
test.AssertResult(t, expected_output, result)
|
||||
}
|
||||
|
||||
test.AssertResult(t, expected_output, result)
|
||||
}
|
||||
|
@ -31,6 +31,10 @@ func writeString(writer io.Writer, txt string) error {
|
||||
return errorWriting
|
||||
}
|
||||
|
||||
func ReadDocuments(reader io.Reader, decoder Decoder) (*list.List, error) {
|
||||
return readDocuments(reader, "", 0, decoder)
|
||||
}
|
||||
|
||||
func readDocuments(reader io.Reader, filename string, fileIndex int, decoder Decoder) (*list.List, error) {
|
||||
err := decoder.Init(reader)
|
||||
if err != nil {
|
||||
|
Loading…
Reference in New Issue
Block a user