wip refactoring printer

This commit is contained in:
Mike Farah 2021-12-22 12:22:29 +11:00
parent 9c6d84d184
commit d105efbcf1
9 changed files with 165 additions and 77 deletions

View File

@ -1,8 +1,4 @@
# above_cat
cat: # inline_cat
# above_array
array: # inline_array
- 3 # inline_3
# above_4
- 4 # inline_4
# below_cat
#hi
---
# hi
- - fish

View File

@ -1,2 +1,14 @@
<?xml version="1.0" encoding="UTF-8"?>
<cat legs="4">BiBi</cat>
<!-- before cat -->
<cat>
<!-- in cat before -->
<x>3<!-- multi
line comment
for x --></x>
<y>
<!-- in y before -->
<d><!-- in d before -->4<!-- in d after --></d>
<!-- in y after -->
</y>
<!-- in_cat_after -->
</cat>
<!-- after cat -->

View File

@ -1,35 +1,89 @@
package yqlib
import (
"bufio"
"bytes"
"encoding/json"
"errors"
"fmt"
"io"
"strings"
yaml "gopkg.in/yaml.v3"
)
type Encoder interface {
Encode(node *yaml.Node) error
PrintDocumentSeparator() error
PrintLeadingContent(content string) error
}
type yamlEncoder struct {
destination io.Writer
indent int
colorise bool
firstDoc bool
destination io.Writer
indent int
colorise bool
firstDoc bool
printDocSeparators bool
}
func NewYamlEncoder(destination io.Writer, indent int, colorise bool) Encoder {
func NewYamlEncoder(destination io.Writer, indent int, colorise bool, printDocSeparators bool) Encoder {
if indent < 0 {
indent = 0
}
return &yamlEncoder{destination, indent, colorise, true}
return &yamlEncoder{destination, indent, colorise, true, printDocSeparators}
}
func (ye *yamlEncoder) PrintDocumentSeparator() error {
if ye.printDocSeparators {
if err := writeString(ye.destination, "---\n"); err != nil {
return err
}
}
return nil
}
func (ye *yamlEncoder) PrintLeadingContent(content string) error {
log.Debug("headcommentwas %v", content)
log.Debug("finished headcomment")
reader := bufio.NewReader(strings.NewReader(content))
for {
readline, errReading := reader.ReadString('\n')
if errReading != nil && !errors.Is(errReading, io.EOF) {
return errReading
}
if strings.Contains(readline, "$yqDocSeperator$") {
if err := ye.PrintDocumentSeparator(); err != nil {
return err
}
} else {
if err := writeString(ye.destination, readline); err != nil {
return err
}
}
if errors.Is(errReading, io.EOF) {
if readline != "" {
// the last comment we read didn't have a new line, put one in
if err := writeString(ye.destination, "\n"); err != nil {
return err
}
}
break
}
}
return nil
}
func (ye *yamlEncoder) Encode(node *yaml.Node) error {
if node.Kind == yaml.ScalarNode && ye.unwrapScalar {
return writeString(ye.destination, node.Value+"\n")
}
destination := ye.destination
tempBuffer := bytes.NewBuffer(nil)
if ye.colorise {
@ -88,6 +142,14 @@ func NewJsonEncoder(destination io.Writer, indent int) Encoder {
return &jsonEncoder{encoder}
}
func (je *jsonEncoder) PrintDocumentSeparator() error {
return nil
}
func (je *jsonEncoder) PrintLeadingContent(content string) error {
return nil
}
func (je *jsonEncoder) Encode(node *yaml.Node) error {
var dataBucket orderedMap
// firstly, convert all map keys to strings

View File

@ -18,6 +18,14 @@ func NewCsvEncoder(destination io.Writer, separator rune) Encoder {
return &csvEncoder{csvWriter}
}
func (e *csvEncoder) PrintDocumentSeparator() error {
return nil
}
func (e *csvEncoder) PrintLeadingContent(content string) error {
return nil
}
func (e *csvEncoder) encodeRow(contents []*yaml.Node) error {
stringValues := make([]string, len(contents))

View File

@ -1,8 +1,11 @@
package yqlib
import (
"bufio"
"errors"
"fmt"
"io"
"strings"
"github.com/magiconair/properties"
yaml "gopkg.in/yaml.v3"
@ -16,6 +19,43 @@ func NewPropertiesEncoder(destination io.Writer) Encoder {
return &propertiesEncoder{destination}
}
func (e *propertiesEncoder) PrintDocumentSeparator() error {
return nil
}
func (e *propertiesEncoder) PrintLeadingContent(content string) error {
reader := bufio.NewReader(strings.NewReader(content))
for {
readline, errReading := reader.ReadString('\n')
if errReading != nil && !errors.Is(errReading, io.EOF) {
return errReading
}
if strings.Contains(readline, "$yqDocSeperator$") {
if err := e.PrintDocumentSeparator(); err != nil {
return err
}
} else {
if err := writeString(e.destination, readline); err != nil {
return err
}
}
if errors.Is(errReading, io.EOF) {
if readline != "" {
// the last comment we read didn't have a new line, put one in
if err := writeString(e.destination, "\n"); err != nil {
return err
}
}
break
}
}
return nil
}
func (pe *propertiesEncoder) Encode(node *yaml.Node) error {
mapKeysToStrings(node)
p := properties.NewProperties()

View File

@ -25,6 +25,15 @@ func NewXmlEncoder(writer io.Writer, indent int, attributePrefix string, content
encoder.Indent("", indentString)
return &xmlEncoder{encoder, attributePrefix, contentName}
}
func (e *xmlEncoder) PrintDocumentSeparator() error {
return nil
}
func (e *xmlEncoder) PrintLeadingContent(content string) error {
return nil
}
func (e *xmlEncoder) Encode(node *yaml.Node) error {
switch node.Kind {
case yaml.MappingNode:

View File

@ -86,7 +86,8 @@ func getCommentsOperator(d *dataTreeNavigator, context Context, expressionNode *
var chompRegexp = regexp.MustCompile(`\n$`)
var output bytes.Buffer
var writer = bufio.NewWriter(&output)
if err := processLeadingContent(candidate, writer, false, YamlOutputFormat); err != nil {
var encoder = NewYamlEncoder(writer, 2, false, true)
if err := encoder.PrintLeadingContent(candidate.LeadingContent); err != nil {
return Context{}, err
}
if err := writer.Flush(); err != nil {

View File

@ -49,6 +49,7 @@ func OutputFormatFromString(format string) (PrinterOutputFormat, error) {
type resultsPrinter struct {
outputFormat PrinterOutputFormat
encoder Encoder
unwrapScalar bool
colorsEnabled bool
indent int
@ -91,27 +92,22 @@ func (p *resultsPrinter) printNode(node *yaml.Node, writer io.Writer) error {
p.printedMatches = p.printedMatches || (node.Tag != "!!null" &&
(node.Tag != "!!bool" || node.Value != "false"))
var encoder Encoder
if node.Kind == yaml.ScalarNode && p.unwrapScalar && p.outputFormat == YamlOutputFormat {
return writeString(writer, node.Value+"\n")
}
// switch p.outputFormat {
// case JsonOutputFormat:
// encoder = NewJsonEncoder(writer, p.indent)
// case PropsOutputFormat:
// encoder = NewPropertiesEncoder(writer)
// case CsvOutputFormat:
// encoder = NewCsvEncoder(writer, ',')
// case TsvOutputFormat:
// encoder = NewCsvEncoder(writer, '\t')
// case YamlOutputFormat:
// encoder = NewYamlEncoder(writer, p.indent, p.colorsEnabled)
// case XmlOutputFormat:
// encoder = NewXmlEncoder(writer, p.indent, XmlPreferences.AttributePrefix, XmlPreferences.ContentName)
// }
switch p.outputFormat {
case JsonOutputFormat:
encoder = NewJsonEncoder(writer, p.indent)
case PropsOutputFormat:
encoder = NewPropertiesEncoder(writer)
case CsvOutputFormat:
encoder = NewCsvEncoder(writer, ',')
case TsvOutputFormat:
encoder = NewCsvEncoder(writer, '\t')
case YamlOutputFormat:
encoder = NewYamlEncoder(writer, p.indent, p.colorsEnabled)
case XmlOutputFormat:
encoder = NewXmlEncoder(writer, p.indent, XmlPreferences.AttributePrefix, XmlPreferences.ContentName)
}
return encoder.Encode(node)
return p.encoder.Encode(node)
}
func (p *resultsPrinter) PrintResults(matchingNodes *list.List) error {
@ -152,14 +148,14 @@ func (p *resultsPrinter) PrintResults(matchingNodes *list.List) error {
commentsStartWithSepExp := regexp.MustCompile(`^\$yqDocSeperator\$`)
commentStartsWithSeparator := commentsStartWithSepExp.MatchString(mappedDoc.LeadingContent)
if (p.previousDocIndex != mappedDoc.Document || p.previousFileIndex != mappedDoc.FileIndex) && p.printDocSeparators && !commentStartsWithSeparator {
if (p.previousDocIndex != mappedDoc.Document || p.previousFileIndex != mappedDoc.FileIndex) && !commentStartsWithSeparator {
log.Debug("-- writing doc sep")
if err := writeString(writer, "---\n"); err != nil {
if err := p.encoder.PrintDocumentSeparator(); err != nil {
return err
}
}
if err := processLeadingContent(mappedDoc, writer, p.printDocSeparators, p.outputFormat); err != nil {
if err := p.encoder.PrintLeadingContent(mappedDoc.LeadingContent); err != nil {
return err
}
@ -173,6 +169,7 @@ func (p *resultsPrinter) PrintResults(matchingNodes *list.List) error {
}
}
// what happens if I remove output format check?
if p.appendixReader != nil && p.outputFormat == YamlOutputFormat {
writer, err := p.printerWriter.GetWriter(nil)
if err != nil {

View File

@ -38,43 +38,6 @@ func writeString(writer io.Writer, txt string) error {
return errorWriting
}
func processLeadingContent(mappedDoc *CandidateNode, writer io.Writer, printDocSeparators bool, outputFormat PrinterOutputFormat) error {
log.Debug("headcommentwas %v", mappedDoc.LeadingContent)
log.Debug("finished headcomment")
reader := bufio.NewReader(strings.NewReader(mappedDoc.LeadingContent))
for {
readline, errReading := reader.ReadString('\n')
if errReading != nil && !errors.Is(errReading, io.EOF) {
return errReading
}
if strings.Contains(readline, "$yqDocSeperator$") {
if printDocSeparators {
if err := writeString(writer, "---\n"); err != nil {
return err
}
}
} else if outputFormat == YamlOutputFormat {
if err := writeString(writer, readline); err != nil {
return err
}
}
if errors.Is(errReading, io.EOF) {
if readline != "" {
// the last comment we read didn't have a new line, put one in
if err := writeString(writer, "\n"); err != nil {
return err
}
}
break
}
}
return nil
}
func processReadStream(reader *bufio.Reader) (io.Reader, string, error) {
var commentLineRegEx = regexp.MustCompile(`^\s*#`)
var sb strings.Builder