mirror of
https://github.com/mikefarah/yq.git
synced 2025-01-31 03:35:56 +00:00
wip refactoring printer
This commit is contained in:
parent
9c6d84d184
commit
d105efbcf1
@ -1,8 +1,4 @@
|
|||||||
# above_cat
|
#hi
|
||||||
cat: # inline_cat
|
---
|
||||||
# above_array
|
# hi
|
||||||
array: # inline_array
|
- - fish
|
||||||
- 3 # inline_3
|
|
||||||
# above_4
|
|
||||||
- 4 # inline_4
|
|
||||||
# below_cat
|
|
@ -1,2 +1,14 @@
|
|||||||
<?xml version="1.0" encoding="UTF-8"?>
|
<!-- before cat -->
|
||||||
<cat legs="4">BiBi</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 -->
|
@ -1,17 +1,21 @@
|
|||||||
package yqlib
|
package yqlib
|
||||||
|
|
||||||
import (
|
import (
|
||||||
|
"bufio"
|
||||||
"bytes"
|
"bytes"
|
||||||
"encoding/json"
|
"encoding/json"
|
||||||
"errors"
|
"errors"
|
||||||
"fmt"
|
"fmt"
|
||||||
"io"
|
"io"
|
||||||
|
"strings"
|
||||||
|
|
||||||
yaml "gopkg.in/yaml.v3"
|
yaml "gopkg.in/yaml.v3"
|
||||||
)
|
)
|
||||||
|
|
||||||
type Encoder interface {
|
type Encoder interface {
|
||||||
Encode(node *yaml.Node) error
|
Encode(node *yaml.Node) error
|
||||||
|
PrintDocumentSeparator() error
|
||||||
|
PrintLeadingContent(content string) error
|
||||||
}
|
}
|
||||||
|
|
||||||
type yamlEncoder struct {
|
type yamlEncoder struct {
|
||||||
@ -19,17 +23,67 @@ type yamlEncoder struct {
|
|||||||
indent int
|
indent int
|
||||||
colorise bool
|
colorise bool
|
||||||
firstDoc 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 {
|
if indent < 0 {
|
||||||
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 {
|
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
|
destination := ye.destination
|
||||||
tempBuffer := bytes.NewBuffer(nil)
|
tempBuffer := bytes.NewBuffer(nil)
|
||||||
if ye.colorise {
|
if ye.colorise {
|
||||||
@ -88,6 +142,14 @@ func NewJsonEncoder(destination io.Writer, indent int) Encoder {
|
|||||||
return &jsonEncoder{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 {
|
func (je *jsonEncoder) Encode(node *yaml.Node) error {
|
||||||
var dataBucket orderedMap
|
var dataBucket orderedMap
|
||||||
// firstly, convert all map keys to strings
|
// firstly, convert all map keys to strings
|
||||||
|
@ -18,6 +18,14 @@ func NewCsvEncoder(destination io.Writer, separator rune) Encoder {
|
|||||||
return &csvEncoder{csvWriter}
|
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 {
|
func (e *csvEncoder) encodeRow(contents []*yaml.Node) error {
|
||||||
stringValues := make([]string, len(contents))
|
stringValues := make([]string, len(contents))
|
||||||
|
|
||||||
|
@ -1,8 +1,11 @@
|
|||||||
package yqlib
|
package yqlib
|
||||||
|
|
||||||
import (
|
import (
|
||||||
|
"bufio"
|
||||||
|
"errors"
|
||||||
"fmt"
|
"fmt"
|
||||||
"io"
|
"io"
|
||||||
|
"strings"
|
||||||
|
|
||||||
"github.com/magiconair/properties"
|
"github.com/magiconair/properties"
|
||||||
yaml "gopkg.in/yaml.v3"
|
yaml "gopkg.in/yaml.v3"
|
||||||
@ -16,6 +19,43 @@ func NewPropertiesEncoder(destination io.Writer) Encoder {
|
|||||||
return &propertiesEncoder{destination}
|
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 {
|
func (pe *propertiesEncoder) Encode(node *yaml.Node) error {
|
||||||
mapKeysToStrings(node)
|
mapKeysToStrings(node)
|
||||||
p := properties.NewProperties()
|
p := properties.NewProperties()
|
||||||
|
@ -25,6 +25,15 @@ func NewXmlEncoder(writer io.Writer, indent int, attributePrefix string, content
|
|||||||
encoder.Indent("", indentString)
|
encoder.Indent("", indentString)
|
||||||
return &xmlEncoder{encoder, attributePrefix, contentName}
|
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 {
|
func (e *xmlEncoder) Encode(node *yaml.Node) error {
|
||||||
switch node.Kind {
|
switch node.Kind {
|
||||||
case yaml.MappingNode:
|
case yaml.MappingNode:
|
||||||
|
@ -86,7 +86,8 @@ func getCommentsOperator(d *dataTreeNavigator, context Context, expressionNode *
|
|||||||
var chompRegexp = regexp.MustCompile(`\n$`)
|
var chompRegexp = regexp.MustCompile(`\n$`)
|
||||||
var output bytes.Buffer
|
var output bytes.Buffer
|
||||||
var writer = bufio.NewWriter(&output)
|
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
|
return Context{}, err
|
||||||
}
|
}
|
||||||
if err := writer.Flush(); err != nil {
|
if err := writer.Flush(); err != nil {
|
||||||
|
@ -49,6 +49,7 @@ func OutputFormatFromString(format string) (PrinterOutputFormat, error) {
|
|||||||
|
|
||||||
type resultsPrinter struct {
|
type resultsPrinter struct {
|
||||||
outputFormat PrinterOutputFormat
|
outputFormat PrinterOutputFormat
|
||||||
|
encoder Encoder
|
||||||
unwrapScalar bool
|
unwrapScalar bool
|
||||||
colorsEnabled bool
|
colorsEnabled bool
|
||||||
indent int
|
indent int
|
||||||
@ -91,27 +92,22 @@ func (p *resultsPrinter) printNode(node *yaml.Node, writer io.Writer) error {
|
|||||||
p.printedMatches = p.printedMatches || (node.Tag != "!!null" &&
|
p.printedMatches = p.printedMatches || (node.Tag != "!!null" &&
|
||||||
(node.Tag != "!!bool" || node.Value != "false"))
|
(node.Tag != "!!bool" || node.Value != "false"))
|
||||||
|
|
||||||
var encoder Encoder
|
// switch p.outputFormat {
|
||||||
if node.Kind == yaml.ScalarNode && p.unwrapScalar && p.outputFormat == YamlOutputFormat {
|
// case JsonOutputFormat:
|
||||||
return writeString(writer, node.Value+"\n")
|
// 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 {
|
return p.encoder.Encode(node)
|
||||||
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)
|
|
||||||
}
|
}
|
||||||
|
|
||||||
func (p *resultsPrinter) PrintResults(matchingNodes *list.List) error {
|
func (p *resultsPrinter) PrintResults(matchingNodes *list.List) error {
|
||||||
@ -152,14 +148,14 @@ func (p *resultsPrinter) PrintResults(matchingNodes *list.List) error {
|
|||||||
commentsStartWithSepExp := regexp.MustCompile(`^\$yqDocSeperator\$`)
|
commentsStartWithSepExp := regexp.MustCompile(`^\$yqDocSeperator\$`)
|
||||||
commentStartsWithSeparator := commentsStartWithSepExp.MatchString(mappedDoc.LeadingContent)
|
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")
|
log.Debug("-- writing doc sep")
|
||||||
if err := writeString(writer, "---\n"); err != nil {
|
if err := p.encoder.PrintDocumentSeparator(); err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if err := processLeadingContent(mappedDoc, writer, p.printDocSeparators, p.outputFormat); err != nil {
|
if err := p.encoder.PrintLeadingContent(mappedDoc.LeadingContent); err != nil {
|
||||||
return err
|
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 {
|
if p.appendixReader != nil && p.outputFormat == YamlOutputFormat {
|
||||||
writer, err := p.printerWriter.GetWriter(nil)
|
writer, err := p.printerWriter.GetWriter(nil)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
|
@ -38,43 +38,6 @@ func writeString(writer io.Writer, txt string) error {
|
|||||||
return errorWriting
|
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) {
|
func processReadStream(reader *bufio.Reader) (io.Reader, string, error) {
|
||||||
var commentLineRegEx = regexp.MustCompile(`^\s*#`)
|
var commentLineRegEx = regexp.MustCompile(`^\s*#`)
|
||||||
var sb strings.Builder
|
var sb strings.Builder
|
||||||
|
Loading…
Reference in New Issue
Block a user