Refactoring Output types

This commit is contained in:
Mike Farah 2024-02-24 14:58:11 +11:00
parent 8a538394a5
commit 571caa696a
9 changed files with 91 additions and 60 deletions

View File

@ -97,7 +97,8 @@ yq -P -oy sample.json
panic(err) panic(err)
} }
rootCmd.PersistentFlags().StringVarP(&outputFormat, "output-format", "o", "auto", "[auto|a|yaml|y|json|j|props|p|xml|x|tsv|t|csv|c] output format type.") rootCmd.PersistentFlags().StringVarP(&outputFormat, "output-format", "o", "auto", fmt.Sprintf("[auto|a|%v] output format type.", yqlib.GetAvailableOutputFormatString()))
if err = rootCmd.RegisterFlagCompletionFunc("output-format", cobra.FixedCompletions([]string{"auto", "yaml", "json", "props", "xml", "tsv", "csv"}, cobra.ShellCompDirectiveNoFileComp)); err != nil { if err = rootCmd.RegisterFlagCompletionFunc("output-format", cobra.FixedCompletions([]string{"auto", "yaml", "json", "props", "xml", "tsv", "csv"}, cobra.ShellCompDirectiveNoFileComp)); err != nil {
panic(err) panic(err)
} }

View File

@ -153,7 +153,7 @@ func createDecoder(format yqlib.InputFormat, evaluateTogether bool) (yqlib.Decod
return nil, fmt.Errorf("invalid decoder: %v", format) return nil, fmt.Errorf("invalid decoder: %v", format)
} }
func configurePrinterWriter(format yqlib.PrinterOutputFormat, out io.Writer) (yqlib.PrinterWriter, error) { func configurePrinterWriter(format *yqlib.PrinterOutputFormat, out io.Writer) (yqlib.PrinterWriter, error) {
var printerWriter yqlib.PrinterWriter var printerWriter yqlib.PrinterWriter
@ -182,7 +182,7 @@ func configureEncoder() (yqlib.Encoder, error) {
return yqlibEncoder, err return yqlibEncoder, err
} }
func createEncoder(format yqlib.PrinterOutputFormat) (yqlib.Encoder, error) { func createEncoder(format *yqlib.PrinterOutputFormat) (yqlib.Encoder, error) {
switch format { switch format {
case yqlib.JSONOutputFormat: case yqlib.JSONOutputFormat:
return yqlib.NewJSONEncoder(indent, colorsEnabled, unwrapScalar), nil return yqlib.NewJSONEncoder(indent, colorsEnabled, unwrapScalar), nil

View File

@ -416,7 +416,7 @@ func documentJSONDecodeScenario(t *testing.T, w *bufio.Writer, s formatScenario)
writeOrPanic(w, "will output\n") writeOrPanic(w, "will output\n")
var output bytes.Buffer var output bytes.Buffer
printer := NewSimpleYamlPrinter(bufio.NewWriter(&output), YamlOutputFormat, true, false, 2, true) printer := NewSimpleYamlPrinter(bufio.NewWriter(&output), true, false, 2, true)
node := decodeJSON(t, s.input) node := decodeJSON(t, s.input)

View File

@ -496,7 +496,7 @@ func numberValue() yqAction {
} }
} }
func encodeParseIndent(outputFormat PrinterOutputFormat) yqAction { func encodeParseIndent(outputFormat *PrinterOutputFormat) yqAction {
return func(rawToken lexer.Token) (*token, error) { return func(rawToken lexer.Token) (*token, error) {
value := rawToken.Value value := rawToken.Value
var indent, errParsingInt = extractNumberParameter(value) var indent, errParsingInt = extractNumberParameter(value)
@ -510,7 +510,7 @@ func encodeParseIndent(outputFormat PrinterOutputFormat) yqAction {
} }
} }
func encodeWithIndent(outputFormat PrinterOutputFormat, indent int) yqAction { func encodeWithIndent(outputFormat *PrinterOutputFormat, indent int) yqAction {
prefs := encoderPreferences{format: outputFormat, indent: indent} prefs := encoderPreferences{format: outputFormat, indent: indent}
return opTokenWithPrefs(encodeOpType, nil, prefs) return opTokenWithPrefs(encodeOpType, nil, prefs)
} }

View File

@ -9,7 +9,7 @@ import (
"strings" "strings"
) )
func configureEncoder(format PrinterOutputFormat, indent int) Encoder { func configureEncoder(format *PrinterOutputFormat, indent int) Encoder {
switch format { switch format {
case JSONOutputFormat: case JSONOutputFormat:
return NewJSONEncoder(indent, false, false) return NewJSONEncoder(indent, false, false)
@ -48,7 +48,7 @@ func encodeToString(candidate *CandidateNode, prefs encoderPreferences) (string,
} }
type encoderPreferences struct { type encoderPreferences struct {
format PrinterOutputFormat format *PrinterOutputFormat
indent int indent int
} }

View File

@ -40,7 +40,7 @@ func TestMain(m *testing.M) {
os.Exit(code) os.Exit(code)
} }
func NewSimpleYamlPrinter(writer io.Writer, _ PrinterOutputFormat, unwrapScalar bool, colorsEnabled bool, indent int, printDocSeparators bool) Printer { func NewSimpleYamlPrinter(writer io.Writer, unwrapScalar bool, colorsEnabled bool, indent int, printDocSeparators bool) Printer {
prefs := NewDefaultYamlPreferences() prefs := NewDefaultYamlPreferences()
prefs.PrintDocSeparators = printDocSeparators prefs.PrintDocSeparators = printDocSeparators
prefs.UnwrapScalar = unwrapScalar prefs.UnwrapScalar = unwrapScalar
@ -132,7 +132,7 @@ func testScenario(t *testing.T, s *expressionScenario) {
func resultToString(t *testing.T, n *CandidateNode) string { func resultToString(t *testing.T, n *CandidateNode) string {
var valueBuffer bytes.Buffer var valueBuffer bytes.Buffer
log.Debugf("printing result %v", NodeToString(n)) log.Debugf("printing result %v", NodeToString(n))
printer := NewSimpleYamlPrinter(bufio.NewWriter(&valueBuffer), YamlOutputFormat, true, false, 4, true) printer := NewSimpleYamlPrinter(bufio.NewWriter(&valueBuffer), true, false, 4, true)
err := printer.PrintResults(n.AsList()) err := printer.PrintResults(n.AsList())
if err != nil { if err != nil {
@ -182,7 +182,7 @@ func copySnippet(source string, out *os.File) error {
func formatYaml(yaml string, filename string) string { func formatYaml(yaml string, filename string) string {
var output bytes.Buffer var output bytes.Buffer
printer := NewSimpleYamlPrinter(bufio.NewWriter(&output), YamlOutputFormat, true, false, 2, true) printer := NewSimpleYamlPrinter(bufio.NewWriter(&output), true, false, 2, true)
node, err := getExpressionParser().ParseExpression(".. style= \"\"") node, err := getExpressionParser().ParseExpression(".. style= \"\"")
if err != nil { if err != nil {
@ -331,7 +331,7 @@ func documentInput(w *bufio.Writer, s expressionScenario) (string, string) {
func documentOutput(t *testing.T, w *bufio.Writer, s expressionScenario, formattedDoc string, formattedDoc2 string) { func documentOutput(t *testing.T, w *bufio.Writer, s expressionScenario, formattedDoc string, formattedDoc2 string) {
var output bytes.Buffer var output bytes.Buffer
var err error var err error
printer := NewSimpleYamlPrinter(bufio.NewWriter(&output), YamlOutputFormat, true, false, 2, true) printer := NewSimpleYamlPrinter(bufio.NewWriter(&output), true, false, 2, true)
node, err := getExpressionParser().ParseExpression(s.expression) node, err := getExpressionParser().ParseExpression(s.expression)
if err != nil { if err != nil {

View File

@ -7,6 +7,7 @@ import (
"fmt" "fmt"
"io" "io"
"regexp" "regexp"
"strings"
) )
type Printer interface { type Printer interface {
@ -17,46 +18,75 @@ type Printer interface {
SetNulSepOutput(nulSepOutput bool) SetNulSepOutput(nulSepOutput bool)
} }
type PrinterOutputFormat uint32 type PrinterOutputFormat struct {
FormalName string
Names []string
}
const ( var YamlOutputFormat = &PrinterOutputFormat{"yaml", []string{"y", "yml"}}
YamlOutputFormat = 1 << iota var JSONOutputFormat = &PrinterOutputFormat{"json", []string{"j"}}
JSONOutputFormat var PropsOutputFormat = &PrinterOutputFormat{"props", []string{"p", "properties"}}
PropsOutputFormat var CSVOutputFormat = &PrinterOutputFormat{"csv", []string{"c"}}
CSVOutputFormat var TSVOutputFormat = &PrinterOutputFormat{"tsv", []string{"t"}}
TSVOutputFormat var XMLOutputFormat = &PrinterOutputFormat{"xml", []string{"x"}}
XMLOutputFormat
Base64OutputFormat
UriOutputFormat
ShOutputFormat
TomlOutputFormat
ShellVariablesOutputFormat
LuaOutputFormat
)
func OutputFormatFromString(format string) (PrinterOutputFormat, error) { var Base64OutputFormat = &PrinterOutputFormat{}
switch format { var UriOutputFormat = &PrinterOutputFormat{}
case "yaml", "y", "yml": var ShOutputFormat = &PrinterOutputFormat{}
return YamlOutputFormat, nil
case "json", "j": var TomlOutputFormat = &PrinterOutputFormat{"toml", []string{}}
return JSONOutputFormat, nil var ShellVariablesOutputFormat = &PrinterOutputFormat{"shell", []string{"s", "sh"}}
case "props", "p", "properties":
return PropsOutputFormat, nil var LuaOutputFormat = &PrinterOutputFormat{"lua", []string{"l"}}
case "csv", "c":
return CSVOutputFormat, nil var Formats = []*PrinterOutputFormat{
case "tsv", "t": YamlOutputFormat,
return TSVOutputFormat, nil JSONOutputFormat,
case "xml", "x": PropsOutputFormat,
return XMLOutputFormat, nil CSVOutputFormat,
case "toml": TSVOutputFormat,
return TomlOutputFormat, nil XMLOutputFormat,
case "shell", "s", "sh": Base64OutputFormat,
return ShellVariablesOutputFormat, nil UriOutputFormat,
case "lua", "l": ShOutputFormat,
return LuaOutputFormat, nil TomlOutputFormat,
default: ShellVariablesOutputFormat,
return 0, fmt.Errorf("unknown format '%v' please use [yaml|json|props|csv|tsv|xml|toml|shell|lua]", format) LuaOutputFormat,
}
func (f *PrinterOutputFormat) MatchesName(name string) bool {
if f.FormalName == name {
return true
} }
for _, n := range f.Names {
if n == name {
return true
}
}
return false
}
func OutputFormatFromString(format string) (*PrinterOutputFormat, error) {
for _, printerFormat := range Formats {
if printerFormat.MatchesName(format) {
return printerFormat, nil
}
}
return nil, fmt.Errorf("unknown format '%v' please use [%v]", format, GetAvailableOutputFormatString())
}
func GetAvailableOutputFormatString() string {
var formats = []string{}
for _, printerFormat := range Formats {
if printerFormat.FormalName != "" {
formats = append(formats, printerFormat.FormalName)
}
if len(printerFormat.Names) >= 1 {
formats = append(formats, printerFormat.Names[0])
}
}
return strings.Join(formats, "|")
} }
type resultsPrinter struct { type resultsPrinter struct {

View File

@ -36,7 +36,7 @@ func nodeToList(candidate *CandidateNode) *list.List {
func TestPrinterMultipleDocsInSequenceOnly(t *testing.T) { func TestPrinterMultipleDocsInSequenceOnly(t *testing.T) {
var output bytes.Buffer var output bytes.Buffer
var writer = bufio.NewWriter(&output) var writer = bufio.NewWriter(&output)
printer := NewSimpleYamlPrinter(writer, YamlOutputFormat, true, false, 2, true) printer := NewSimpleYamlPrinter(writer, true, false, 2, true)
inputs, err := readDocuments(strings.NewReader(multiDocSample), "sample.yml", 0, NewYamlDecoder(ConfiguredYamlPreferences)) inputs, err := readDocuments(strings.NewReader(multiDocSample), "sample.yml", 0, NewYamlDecoder(ConfiguredYamlPreferences))
if err != nil { if err != nil {
@ -74,7 +74,7 @@ func TestPrinterMultipleDocsInSequenceOnly(t *testing.T) {
func TestPrinterMultipleDocsInSequenceWithLeadingContent(t *testing.T) { func TestPrinterMultipleDocsInSequenceWithLeadingContent(t *testing.T) {
var output bytes.Buffer var output bytes.Buffer
var writer = bufio.NewWriter(&output) var writer = bufio.NewWriter(&output)
printer := NewSimpleYamlPrinter(writer, YamlOutputFormat, true, false, 2, true) printer := NewSimpleYamlPrinter(writer, true, false, 2, true)
inputs, err := readDocuments(strings.NewReader(multiDocSample), "sample.yml", 0, NewYamlDecoder(ConfiguredYamlPreferences)) inputs, err := readDocuments(strings.NewReader(multiDocSample), "sample.yml", 0, NewYamlDecoder(ConfiguredYamlPreferences))
if err != nil { if err != nil {
@ -116,7 +116,7 @@ func TestPrinterMultipleDocsInSequenceWithLeadingContent(t *testing.T) {
func TestPrinterMultipleFilesInSequence(t *testing.T) { func TestPrinterMultipleFilesInSequence(t *testing.T) {
var output bytes.Buffer var output bytes.Buffer
var writer = bufio.NewWriter(&output) var writer = bufio.NewWriter(&output)
printer := NewSimpleYamlPrinter(writer, YamlOutputFormat, true, false, 2, true) printer := NewSimpleYamlPrinter(writer, true, false, 2, true)
inputs, err := readDocuments(strings.NewReader(multiDocSample), "sample.yml", 0, NewYamlDecoder(ConfiguredYamlPreferences)) inputs, err := readDocuments(strings.NewReader(multiDocSample), "sample.yml", 0, NewYamlDecoder(ConfiguredYamlPreferences))
if err != nil { if err != nil {
@ -163,7 +163,7 @@ func TestPrinterMultipleFilesInSequence(t *testing.T) {
func TestPrinterMultipleFilesInSequenceWithLeadingContent(t *testing.T) { func TestPrinterMultipleFilesInSequenceWithLeadingContent(t *testing.T) {
var output bytes.Buffer var output bytes.Buffer
var writer = bufio.NewWriter(&output) var writer = bufio.NewWriter(&output)
printer := NewSimpleYamlPrinter(writer, YamlOutputFormat, true, false, 2, true) printer := NewSimpleYamlPrinter(writer, true, false, 2, true)
inputs, err := readDocuments(strings.NewReader(multiDocSample), "sample.yml", 0, NewYamlDecoder(ConfiguredYamlPreferences)) inputs, err := readDocuments(strings.NewReader(multiDocSample), "sample.yml", 0, NewYamlDecoder(ConfiguredYamlPreferences))
if err != nil { if err != nil {
@ -213,7 +213,7 @@ func TestPrinterMultipleFilesInSequenceWithLeadingContent(t *testing.T) {
func TestPrinterMultipleDocsInSinglePrint(t *testing.T) { func TestPrinterMultipleDocsInSinglePrint(t *testing.T) {
var output bytes.Buffer var output bytes.Buffer
var writer = bufio.NewWriter(&output) var writer = bufio.NewWriter(&output)
printer := NewSimpleYamlPrinter(writer, YamlOutputFormat, true, false, 2, true) printer := NewSimpleYamlPrinter(writer, true, false, 2, true)
inputs, err := readDocuments(strings.NewReader(multiDocSample), "sample.yml", 0, NewYamlDecoder(ConfiguredYamlPreferences)) inputs, err := readDocuments(strings.NewReader(multiDocSample), "sample.yml", 0, NewYamlDecoder(ConfiguredYamlPreferences))
if err != nil { if err != nil {
@ -232,7 +232,7 @@ func TestPrinterMultipleDocsInSinglePrint(t *testing.T) {
func TestPrinterMultipleDocsInSinglePrintWithLeadingDoc(t *testing.T) { func TestPrinterMultipleDocsInSinglePrintWithLeadingDoc(t *testing.T) {
var output bytes.Buffer var output bytes.Buffer
var writer = bufio.NewWriter(&output) var writer = bufio.NewWriter(&output)
printer := NewSimpleYamlPrinter(writer, YamlOutputFormat, true, false, 2, true) printer := NewSimpleYamlPrinter(writer, true, false, 2, true)
inputs, err := readDocuments(strings.NewReader(multiDocSample), "sample.yml", 0, NewYamlDecoder(ConfiguredYamlPreferences)) inputs, err := readDocuments(strings.NewReader(multiDocSample), "sample.yml", 0, NewYamlDecoder(ConfiguredYamlPreferences))
if err != nil { if err != nil {
@ -261,7 +261,7 @@ a: coconut
func TestPrinterMultipleDocsInSinglePrintWithLeadingDocTrailing(t *testing.T) { func TestPrinterMultipleDocsInSinglePrintWithLeadingDocTrailing(t *testing.T) {
var output bytes.Buffer var output bytes.Buffer
var writer = bufio.NewWriter(&output) var writer = bufio.NewWriter(&output)
printer := NewSimpleYamlPrinter(writer, YamlOutputFormat, true, false, 2, true) printer := NewSimpleYamlPrinter(writer, true, false, 2, true)
inputs, err := readDocuments(strings.NewReader(multiDocSample), "sample.yml", 0, NewYamlDecoder(ConfiguredYamlPreferences)) inputs, err := readDocuments(strings.NewReader(multiDocSample), "sample.yml", 0, NewYamlDecoder(ConfiguredYamlPreferences))
if err != nil { if err != nil {
@ -287,7 +287,7 @@ a: coconut
func TestPrinterScalarWithLeadingCont(t *testing.T) { func TestPrinterScalarWithLeadingCont(t *testing.T) {
var output bytes.Buffer var output bytes.Buffer
var writer = bufio.NewWriter(&output) var writer = bufio.NewWriter(&output)
printer := NewSimpleYamlPrinter(writer, YamlOutputFormat, true, false, 2, true) printer := NewSimpleYamlPrinter(writer, true, false, 2, true)
node, err := getExpressionParser().ParseExpression(".a") node, err := getExpressionParser().ParseExpression(".a")
if err != nil { if err != nil {
@ -344,7 +344,7 @@ func TestPrinterMultipleDocsJson(t *testing.T) {
func TestPrinterNulSeparator(t *testing.T) { func TestPrinterNulSeparator(t *testing.T) {
var output bytes.Buffer var output bytes.Buffer
var writer = bufio.NewWriter(&output) var writer = bufio.NewWriter(&output)
printer := NewSimpleYamlPrinter(writer, YamlOutputFormat, true, false, 2, false) printer := NewSimpleYamlPrinter(writer, true, false, 2, false)
printer.SetNulSepOutput(true) printer.SetNulSepOutput(true)
node, err := getExpressionParser().ParseExpression(".a") node, err := getExpressionParser().ParseExpression(".a")
if err != nil { if err != nil {
@ -394,7 +394,7 @@ func TestPrinterNulSeparatorWithJson(t *testing.T) {
func TestPrinterRootUnwrap(t *testing.T) { func TestPrinterRootUnwrap(t *testing.T) {
var output bytes.Buffer var output bytes.Buffer
var writer = bufio.NewWriter(&output) var writer = bufio.NewWriter(&output)
printer := NewSimpleYamlPrinter(writer, YamlOutputFormat, true, false, 2, false) printer := NewSimpleYamlPrinter(writer, true, false, 2, false)
node, err := getExpressionParser().ParseExpression(".") node, err := getExpressionParser().ParseExpression(".")
if err != nil { if err != nil {
panic(err) panic(err)

View File

@ -33,7 +33,7 @@ type multiPrintWriter struct {
index int index int
} }
func NewMultiPrinterWriter(expression *ExpressionNode, format PrinterOutputFormat) PrinterWriter { func NewMultiPrinterWriter(expression *ExpressionNode, format *PrinterOutputFormat) PrinterWriter {
extension := "yml" extension := "yml"
switch format { switch format {