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

View File

@ -11,6 +11,7 @@ import (
type Printer interface { type Printer interface {
PrintResults(matchingNodes *list.List) error PrintResults(matchingNodes *list.List) error
PrintedAnything() bool PrintedAnything() bool
SetPrintLeadingSeperator(bool)
} }
type resultsPrinter struct { 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 { func (p *resultsPrinter) PrintedAnything() bool {
return p.printedMatches return p.printedMatches
} }

View File

@ -17,12 +17,36 @@ a: apple
a: coconut a: coconut
` `
var leadingSeperatorSample = `---
a: good doc
`
func nodeToList(candidate *CandidateNode) *list.List { func nodeToList(candidate *CandidateNode) *list.List {
elMap := list.New() elMap := list.New()
elMap.PushBack(candidate) elMap.PushBack(candidate)
return elMap 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) { func TestPrinterMultipleDocsInSequence(t *testing.T) {
var output bytes.Buffer var output bytes.Buffer
var writer = bufio.NewWriter(&output) var writer = bufio.NewWriter(&output)

View File

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

View File

@ -9,13 +9,28 @@ import (
yaml "gopkg.in/yaml.v3" yaml "gopkg.in/yaml.v3"
) )
func readStream(filename string) (io.Reader, error) { func readStream(filename string) (io.Reader, bool, error) {
if filename == "-" { if filename == "-" {
return bufio.NewReader(os.Stdin), nil reader := bufio.NewReader(os.Stdin)
seperatorBytes, err := reader.Peek(3)
return reader, string(seperatorBytes) == "---", err
} else { } else {
// ignore CWE-22 gosec issue - that's more targetted for http based apps that run in a public directory, // 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. // 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 exit 1
fi 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" echo "--success"
set -e set -e