Adding magic to detect leading seperators

This commit is contained in:
Mike Farah 2021-07-14 20:48:16 +10:00
parent 5c0a5bd9d3
commit d74bb8e28d
8 changed files with 124 additions and 6 deletions

View File

@ -1 +1,2 @@
---
{"a":{"b":1}}

View File

@ -0,0 +1,2 @@
---
a: test

View File

@ -48,13 +48,19 @@ func (e *allAtOnceEvaluator) EvaluateCandidateNodes(expression string, inputCand
func (e *allAtOnceEvaluator) EvaluateFiles(expression string, filenames []string, printer Printer) error {
fileIndex := 0
firstFileLeadingSeperator := false
var allDocuments *list.List = list.New()
for _, filename := range filenames {
reader, err := readStream(filename)
reader, leadingSeperator, err := readStream(filename)
if err != nil {
return err
}
if fileIndex == 0 && leadingSeperator {
firstFileLeadingSeperator = leadingSeperator
}
fileDocuments, err := readDocuments(reader, filename, fileIndex)
if err != nil {
return err
@ -66,5 +72,6 @@ func (e *allAtOnceEvaluator) EvaluateFiles(expression string, filenames []string
if err != nil {
return err
}
printer.SetPrintLeadingSeperator(firstFileLeadingSeperator)
return printer.PrintResults(matches)
}

View File

@ -11,6 +11,7 @@ import (
type Printer interface {
PrintResults(matchingNodes *list.List) error
PrintedAnything() bool
SetPrintLeadingSeperator(bool)
}
type resultsPrinter struct {
@ -40,6 +41,13 @@ func NewPrinter(writer io.Writer, outputToJSON bool, unwrapScalar bool, colorsEn
}
}
func (p *resultsPrinter) SetPrintLeadingSeperator(printLeadingSeperator bool) {
if printLeadingSeperator {
p.firstTimePrinting = false
p.previousFileIndex = -1
}
}
func (p *resultsPrinter) PrintedAnything() bool {
return p.printedMatches
}

View File

@ -17,12 +17,36 @@ a: apple
a: coconut
`
var leadingSeperatorSample = `---
a: good doc
`
func nodeToList(candidate *CandidateNode) *list.List {
elMap := list.New()
elMap.PushBack(candidate)
return elMap
}
func TestPrinterWithLeadingSeperator(t *testing.T) {
var output bytes.Buffer
var writer = bufio.NewWriter(&output)
printer := NewPrinter(writer, false, true, false, 2, true)
inputs, err := readDocuments(strings.NewReader(leadingSeperatorSample), "sample.yml", 0)
if err != nil {
panic(err)
}
printer.SetPrintLeadingSeperator(true)
err = printer.PrintResults(inputs)
if err != nil {
panic(err)
}
writer.Flush()
test.AssertResult(t, leadingSeperatorSample, output.String())
}
func TestPrinterMultipleDocsInSequence(t *testing.T) {
var output bytes.Buffer
var writer = bufio.NewWriter(&output)

View File

@ -55,8 +55,11 @@ func (s *streamEvaluator) EvaluateFiles(expression string, filenames []string, p
return err
}
for _, filename := range filenames {
reader, err := readStream(filename)
for index, filename := range filenames {
reader, leadingSeperator, err := readStream(filename)
if index == 0 && leadingSeperator {
printer.SetPrintLeadingSeperator(leadingSeperator)
}
if err != nil {
return err
}

View File

@ -9,13 +9,28 @@ import (
yaml "gopkg.in/yaml.v3"
)
func readStream(filename string) (io.Reader, error) {
func readStream(filename string) (io.Reader, bool, error) {
if filename == "-" {
return bufio.NewReader(os.Stdin), nil
reader := bufio.NewReader(os.Stdin)
seperatorBytes, err := reader.Peek(3)
return reader, string(seperatorBytes) == "---", err
} else {
// ignore CWE-22 gosec issue - that's more targetted for http based apps that run in a public directory,
// and ensuring that it's not possible to give a path to a file outside thar directory.
return os.Open(filename) // #nosec
reader, err := os.Open(filename)
if err != nil {
return nil, false, err
}
seperatorBytes := make([]byte, 3)
_, err = reader.Read(seperatorBytes)
if err != nil {
return nil, false, err
}
_, err = reader.Seek(0, 0)
return reader, string(seperatorBytes) == "---", err
}
}

View File

@ -55,6 +55,64 @@ if [[ $? != 1 ]]; then
exit 1
fi
# Test leading seperator logic
expected=$(cat examples/leading-seperator.yaml)
X=$(cat examples/leading-seperator.yaml | ./yq e '.' -)
if [[ $X != $expected ]]; then
echo "Pipe into e"
echo "Expected $expected but was $X"
exit 1
fi
X=$(./yq e '.' examples/leading-seperator.yaml)
expected=$(cat examples/leading-seperator.yaml)
if [[ $X != $expected ]]; then
echo "read given file e"
echo "Expected $expected but was $X"
exit 1
fi
X=$(cat examples/leading-seperator.yaml | ./yq ea '.' -)
if [[ $X != $expected ]]; then
echo "Pipe into e"
echo "Expected $expected but was $X"
exit 1
fi
X=$(./yq ea '.' examples/leading-seperator.yaml)
expected=$(cat examples/leading-seperator.yaml)
if [[ $X != $expected ]]; then
echo "read given file e"
echo "Expected $expected but was $X"
exit 1
fi
# multidoc
read -r -d '' expected << EOM
---
a: test
---
version: 3
application: MyApp
EOM
X=$(./yq e '.' examples/leading-seperator.yaml examples/order.yaml)
if [[ $X != $expected ]]; then
echo "Multidoc with leading seperator"
echo "Expected $expected but was $X"
exit 1
fi
X=$(./yq ea '.' examples/leading-seperator.yaml examples/order.yaml)
if [[ $X != $expected ]]; then
echo "Multidoc with leading seperator"
echo "Expected $expected but was $X"
exit 1
fi
echo "--success"
set -e