mirror of
https://github.com/mikefarah/yq.git
synced 2024-11-13 22:38:04 +00:00
Introduced 'format' to encapsulate encoding and decoding formats together
This commit is contained in:
parent
8f6d642012
commit
447bf28cd8
@ -76,7 +76,7 @@ func evaluateAll(cmd *cobra.Command, args []string) (cmdError error) {
|
|||||||
}()
|
}()
|
||||||
}
|
}
|
||||||
|
|
||||||
format, err := yqlib.OutputFormatFromString(outputFormat)
|
format, err := yqlib.FormatFromString(outputFormat)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
@ -90,7 +90,7 @@ func evaluateSequence(cmd *cobra.Command, args []string) (cmdError error) {
|
|||||||
}()
|
}()
|
||||||
}
|
}
|
||||||
|
|
||||||
format, err := yqlib.OutputFormatFromString(outputFormat)
|
format, err := yqlib.FormatFromString(outputFormat)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
16
cmd/root.go
16
cmd/root.go
@ -98,12 +98,22 @@ yq -P -oy sample.json
|
|||||||
}
|
}
|
||||||
|
|
||||||
rootCmd.PersistentFlags().StringVarP(&outputFormat, "output-format", "o", "auto", fmt.Sprintf("[auto|a|%v] output format type.", yqlib.GetAvailableOutputFormatString()))
|
rootCmd.PersistentFlags().StringVarP(&outputFormat, "output-format", "o", "auto", fmt.Sprintf("[auto|a|%v] output format type.", yqlib.GetAvailableOutputFormatString()))
|
||||||
|
var outputCompletions = []string{"auto"}
|
||||||
|
for _, formats := range yqlib.GetAvailableOutputFormats() {
|
||||||
|
outputCompletions = append(outputCompletions, formats.FormalName)
|
||||||
|
}
|
||||||
|
|
||||||
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(outputCompletions, cobra.ShellCompDirectiveNoFileComp)); err != nil {
|
||||||
panic(err)
|
panic(err)
|
||||||
}
|
}
|
||||||
rootCmd.PersistentFlags().StringVarP(&inputFormat, "input-format", "p", "auto", "[auto|a|yaml|y|props|p|xml|x|tsv|t|csv|c|toml] parse format for input. Note that json is a subset of yaml.")
|
rootCmd.PersistentFlags().StringVarP(&inputFormat, "input-format", "p", "auto", fmt.Sprintf("[auto|a|%v] parse format for input.", yqlib.GetAvailableInputFormatString()))
|
||||||
if err = rootCmd.RegisterFlagCompletionFunc("input-format", cobra.FixedCompletions([]string{"auto", "yaml", "props", "xml", "tsv", "csv", "toml"}, cobra.ShellCompDirectiveNoFileComp)); err != nil {
|
|
||||||
|
var inputCompletions = []string{"auto"}
|
||||||
|
for _, formats := range yqlib.GetAvailableInputFormats() {
|
||||||
|
inputCompletions = append(inputCompletions, formats.FormalName)
|
||||||
|
}
|
||||||
|
|
||||||
|
if err = rootCmd.RegisterFlagCompletionFunc("input-format", cobra.FixedCompletions(inputCompletions, cobra.ShellCompDirectiveNoFileComp)); err != nil {
|
||||||
panic(err)
|
panic(err)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
63
cmd/utils.go
63
cmd/utils.go
@ -64,9 +64,9 @@ func initCommand(cmd *cobra.Command, args []string) (string, []string, error) {
|
|||||||
}
|
}
|
||||||
if inputFormat == "" || inputFormat == "auto" || inputFormat == "a" {
|
if inputFormat == "" || inputFormat == "auto" || inputFormat == "a" {
|
||||||
|
|
||||||
inputFormat = yqlib.FormatFromFilename(inputFilename)
|
inputFormat = yqlib.FormatStringFromFilename(inputFilename)
|
||||||
|
|
||||||
_, err := yqlib.InputFormatFromString(inputFormat)
|
_, err := yqlib.FormatFromString(inputFormat)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
// unknown file type, default to yaml
|
// unknown file type, default to yaml
|
||||||
yqlib.GetLogger().Debug("Unknown file format extension '%v', defaulting to yaml", inputFormat)
|
yqlib.GetLogger().Debug("Unknown file format extension '%v', defaulting to yaml", inputFormat)
|
||||||
@ -86,14 +86,14 @@ func initCommand(cmd *cobra.Command, args []string) (string, []string, error) {
|
|||||||
// before this was introduced, `yq -pcsv things.csv`
|
// before this was introduced, `yq -pcsv things.csv`
|
||||||
// would produce *yaml* output.
|
// would produce *yaml* output.
|
||||||
//
|
//
|
||||||
outputFormat = yqlib.FormatFromFilename(inputFilename)
|
outputFormat = yqlib.FormatStringFromFilename(inputFilename)
|
||||||
if inputFilename != "-" {
|
if inputFilename != "-" {
|
||||||
yqlib.GetLogger().Warning("yq default output is now 'auto' (based on the filename extension). Normally yq would output '%v', but for backwards compatibility 'yaml' has been set. Please use -oy to specify yaml, or drop the -p flag.", outputFormat)
|
yqlib.GetLogger().Warning("yq default output is now 'auto' (based on the filename extension). Normally yq would output '%v', but for backwards compatibility 'yaml' has been set. Please use -oy to specify yaml, or drop the -p flag.", outputFormat)
|
||||||
}
|
}
|
||||||
outputFormat = "yaml"
|
outputFormat = "yaml"
|
||||||
}
|
}
|
||||||
|
|
||||||
outputFormatType, err := yqlib.OutputFormatFromString(outputFormat)
|
outputFormatType, err := yqlib.FormatFromString(outputFormat)
|
||||||
|
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return "", nil, err
|
return "", nil, err
|
||||||
@ -101,8 +101,8 @@ func initCommand(cmd *cobra.Command, args []string) (string, []string, error) {
|
|||||||
yqlib.GetLogger().Debug("Using input format %v", inputFormat)
|
yqlib.GetLogger().Debug("Using input format %v", inputFormat)
|
||||||
yqlib.GetLogger().Debug("Using output format %v", outputFormat)
|
yqlib.GetLogger().Debug("Using output format %v", outputFormat)
|
||||||
|
|
||||||
if outputFormatType == yqlib.YamlOutputFormat ||
|
if outputFormatType == yqlib.YamlFormat ||
|
||||||
outputFormatType == yqlib.PropsOutputFormat {
|
outputFormatType == yqlib.PropertiesFormat {
|
||||||
unwrapScalar = true
|
unwrapScalar = true
|
||||||
}
|
}
|
||||||
if unwrapScalarFlag.IsExplicitlySet() {
|
if unwrapScalarFlag.IsExplicitlySet() {
|
||||||
@ -113,42 +113,20 @@ func initCommand(cmd *cobra.Command, args []string) (string, []string, error) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
func configureDecoder(evaluateTogether bool) (yqlib.Decoder, error) {
|
func configureDecoder(evaluateTogether bool) (yqlib.Decoder, error) {
|
||||||
yqlibInputFormat, err := yqlib.InputFormatFromString(inputFormat)
|
format, err := yqlib.FormatFromString(inputFormat)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
yqlibDecoder, err := createDecoder(yqlibInputFormat, evaluateTogether)
|
yqlib.ConfiguredYamlPreferences.EvaluateTogether = evaluateTogether
|
||||||
|
|
||||||
|
yqlibDecoder := format.DecoderFactory()
|
||||||
if yqlibDecoder == nil {
|
if yqlibDecoder == nil {
|
||||||
return nil, fmt.Errorf("no support for %s input format", inputFormat)
|
return nil, fmt.Errorf("no support for %s input format", inputFormat)
|
||||||
}
|
}
|
||||||
return yqlibDecoder, err
|
return yqlibDecoder, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func createDecoder(format yqlib.InputFormat, evaluateTogether bool) (yqlib.Decoder, error) {
|
func configurePrinterWriter(format *yqlib.Format, out io.Writer) (yqlib.PrinterWriter, error) {
|
||||||
switch format {
|
|
||||||
case yqlib.LuaInputFormat:
|
|
||||||
return yqlib.NewLuaDecoder(yqlib.ConfiguredLuaPreferences), nil
|
|
||||||
case yqlib.XMLInputFormat:
|
|
||||||
return yqlib.NewXMLDecoder(yqlib.ConfiguredXMLPreferences), nil
|
|
||||||
case yqlib.PropertiesInputFormat:
|
|
||||||
return yqlib.NewPropertiesDecoder(), nil
|
|
||||||
case yqlib.JsonInputFormat:
|
|
||||||
return yqlib.NewJSONDecoder(), nil
|
|
||||||
case yqlib.CSVObjectInputFormat:
|
|
||||||
return yqlib.NewCSVObjectDecoder(yqlib.ConfiguredCsvPreferences), nil
|
|
||||||
case yqlib.TSVObjectInputFormat:
|
|
||||||
return yqlib.NewCSVObjectDecoder(yqlib.ConfiguredTsvPreferences), nil
|
|
||||||
case yqlib.TomlInputFormat:
|
|
||||||
return yqlib.NewTomlDecoder(), nil
|
|
||||||
case yqlib.YamlInputFormat:
|
|
||||||
prefs := yqlib.ConfiguredYamlPreferences
|
|
||||||
prefs.EvaluateTogether = evaluateTogether
|
|
||||||
return yqlib.NewYamlDecoder(prefs), nil
|
|
||||||
}
|
|
||||||
return nil, fmt.Errorf("invalid decoder: %v", format)
|
|
||||||
}
|
|
||||||
|
|
||||||
func configurePrinterWriter(format *yqlib.PrinterOutputFormat, out io.Writer) (yqlib.PrinterWriter, error) {
|
|
||||||
|
|
||||||
var printerWriter yqlib.PrinterWriter
|
var printerWriter yqlib.PrinterWriter
|
||||||
|
|
||||||
@ -166,18 +144,10 @@ func configurePrinterWriter(format *yqlib.PrinterOutputFormat, out io.Writer) (y
|
|||||||
}
|
}
|
||||||
|
|
||||||
func configureEncoder() (yqlib.Encoder, error) {
|
func configureEncoder() (yqlib.Encoder, error) {
|
||||||
yqlibOutputFormat, err := yqlib.OutputFormatFromString(outputFormat)
|
yqlibOutputFormat, err := yqlib.FormatFromString(outputFormat)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
yqlibEncoder, err := createEncoder(yqlibOutputFormat)
|
|
||||||
if yqlibEncoder == nil {
|
|
||||||
return nil, fmt.Errorf("no support for %s output format", outputFormat)
|
|
||||||
}
|
|
||||||
return yqlibEncoder, err
|
|
||||||
}
|
|
||||||
|
|
||||||
func createEncoder(format *yqlib.PrinterOutputFormat) (yqlib.Encoder, error) {
|
|
||||||
yqlib.ConfiguredXMLPreferences.Indent = indent
|
yqlib.ConfiguredXMLPreferences.Indent = indent
|
||||||
yqlib.ConfiguredYamlPreferences.Indent = indent
|
yqlib.ConfiguredYamlPreferences.Indent = indent
|
||||||
yqlib.ConfiguredJSONPreferences.Indent = indent
|
yqlib.ConfiguredJSONPreferences.Indent = indent
|
||||||
@ -191,11 +161,12 @@ func createEncoder(format *yqlib.PrinterOutputFormat) (yqlib.Encoder, error) {
|
|||||||
|
|
||||||
yqlib.ConfiguredYamlPreferences.PrintDocSeparators = !noDocSeparators
|
yqlib.ConfiguredYamlPreferences.PrintDocSeparators = !noDocSeparators
|
||||||
|
|
||||||
encoder := format.EncoderFactory()
|
encoder := yqlibOutputFormat.EncoderFactory()
|
||||||
|
|
||||||
if encoder == nil {
|
if encoder == nil {
|
||||||
return nil, fmt.Errorf("invalid encoder: %v", format)
|
return nil, fmt.Errorf("no support for %s output format", outputFormat)
|
||||||
}
|
}
|
||||||
return encoder, nil
|
return encoder, err
|
||||||
}
|
}
|
||||||
|
|
||||||
// this is a hack to enable backwards compatibility with githubactions (which pipe /dev/null into everything)
|
// this is a hack to enable backwards compatibility with githubactions (which pipe /dev/null into everything)
|
||||||
|
@ -1,66 +1,10 @@
|
|||||||
package yqlib
|
package yqlib
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"fmt"
|
|
||||||
"io"
|
"io"
|
||||||
"strings"
|
|
||||||
)
|
|
||||||
|
|
||||||
type InputFormat uint
|
|
||||||
|
|
||||||
const (
|
|
||||||
YamlInputFormat = 1 << iota
|
|
||||||
XMLInputFormat
|
|
||||||
PropertiesInputFormat
|
|
||||||
Base64InputFormat
|
|
||||||
JsonInputFormat
|
|
||||||
CSVObjectInputFormat
|
|
||||||
TSVObjectInputFormat
|
|
||||||
TomlInputFormat
|
|
||||||
UriInputFormat
|
|
||||||
LuaInputFormat
|
|
||||||
)
|
)
|
||||||
|
|
||||||
type Decoder interface {
|
type Decoder interface {
|
||||||
Init(reader io.Reader) error
|
Init(reader io.Reader) error
|
||||||
Decode() (*CandidateNode, error)
|
Decode() (*CandidateNode, error)
|
||||||
}
|
}
|
||||||
|
|
||||||
func InputFormatFromString(format string) (InputFormat, error) {
|
|
||||||
switch format {
|
|
||||||
case "yaml", "yml", "y":
|
|
||||||
return YamlInputFormat, nil
|
|
||||||
case "xml", "x":
|
|
||||||
return XMLInputFormat, nil
|
|
||||||
case "properties", "props", "p":
|
|
||||||
return PropertiesInputFormat, nil
|
|
||||||
case "json", "ndjson", "j":
|
|
||||||
return JsonInputFormat, nil
|
|
||||||
case "csv", "c":
|
|
||||||
return CSVObjectInputFormat, nil
|
|
||||||
case "tsv", "t":
|
|
||||||
return TSVObjectInputFormat, nil
|
|
||||||
case "toml":
|
|
||||||
return TomlInputFormat, nil
|
|
||||||
case "lua", "l":
|
|
||||||
return LuaInputFormat, nil
|
|
||||||
default:
|
|
||||||
return 0, fmt.Errorf("unknown format '%v' please use [yaml|json|props|csv|tsv|xml|toml]", format)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
func FormatFromFilename(filename string) string {
|
|
||||||
|
|
||||||
if filename != "" {
|
|
||||||
GetLogger().Debugf("checking file extension '%s' for auto format detection", filename)
|
|
||||||
nPos := strings.LastIndex(filename, ".")
|
|
||||||
if nPos > -1 {
|
|
||||||
format := filename[nPos+1:]
|
|
||||||
GetLogger().Debugf("detected format '%s'", format)
|
|
||||||
return format
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
GetLogger().Debugf("using default inputFormat 'yaml'")
|
|
||||||
return "yaml"
|
|
||||||
}
|
|
||||||
|
180
pkg/yqlib/format.go
Normal file
180
pkg/yqlib/format.go
Normal file
@ -0,0 +1,180 @@
|
|||||||
|
package yqlib
|
||||||
|
|
||||||
|
import (
|
||||||
|
"fmt"
|
||||||
|
"strings"
|
||||||
|
)
|
||||||
|
|
||||||
|
type EncoderFactoryFunction func() Encoder
|
||||||
|
type DecoderFactoryFunction func() Decoder
|
||||||
|
|
||||||
|
type Format struct {
|
||||||
|
FormalName string
|
||||||
|
Names []string
|
||||||
|
EncoderFactory EncoderFactoryFunction
|
||||||
|
DecoderFactory DecoderFactoryFunction
|
||||||
|
}
|
||||||
|
|
||||||
|
var YamlFormat = &Format{"yaml", []string{"y", "yml"},
|
||||||
|
func() Encoder { return NewYamlEncoder(ConfiguredYamlPreferences) },
|
||||||
|
func() Decoder { return NewYamlDecoder(ConfiguredYamlPreferences) },
|
||||||
|
}
|
||||||
|
|
||||||
|
var JSONFormat = &Format{"json", []string{"j"},
|
||||||
|
func() Encoder { return NewJSONEncoder(ConfiguredJSONPreferences) },
|
||||||
|
func() Decoder { return NewJSONDecoder() },
|
||||||
|
}
|
||||||
|
|
||||||
|
var PropertiesFormat = &Format{"props", []string{"p", "properties"},
|
||||||
|
func() Encoder { return NewPropertiesEncoder(ConfiguredPropertiesPreferences) },
|
||||||
|
func() Decoder { return NewPropertiesDecoder() },
|
||||||
|
}
|
||||||
|
|
||||||
|
var CSVFormat = &Format{"csv", []string{"c"},
|
||||||
|
func() Encoder { return NewCsvEncoder(ConfiguredCsvPreferences) },
|
||||||
|
func() Decoder { return NewCSVObjectDecoder(ConfiguredCsvPreferences) },
|
||||||
|
}
|
||||||
|
|
||||||
|
var TSVFormat = &Format{"tsv", []string{"t"},
|
||||||
|
func() Encoder { return NewCsvEncoder(ConfiguredTsvPreferences) },
|
||||||
|
func() Decoder { return NewCSVObjectDecoder(ConfiguredTsvPreferences) },
|
||||||
|
}
|
||||||
|
|
||||||
|
var XMLFormat = &Format{"xml", []string{"x"},
|
||||||
|
func() Encoder { return NewXMLEncoder(ConfiguredXMLPreferences) },
|
||||||
|
func() Decoder { return NewXMLDecoder(ConfiguredXMLPreferences) },
|
||||||
|
}
|
||||||
|
|
||||||
|
var Base64Format = &Format{"base64", []string{},
|
||||||
|
func() Encoder { return NewBase64Encoder() },
|
||||||
|
func() Decoder { return NewBase64Decoder() },
|
||||||
|
}
|
||||||
|
|
||||||
|
var UriFormat = &Format{"uri", []string{},
|
||||||
|
func() Encoder { return NewUriEncoder() },
|
||||||
|
func() Decoder { return NewUriDecoder() },
|
||||||
|
}
|
||||||
|
|
||||||
|
var ShFormat = &Format{"", nil,
|
||||||
|
func() Encoder { return NewShEncoder() },
|
||||||
|
nil,
|
||||||
|
}
|
||||||
|
|
||||||
|
var TomlFormat = &Format{"toml", []string{},
|
||||||
|
func() Encoder { return NewTomlEncoder() },
|
||||||
|
func() Decoder { return NewTomlDecoder() },
|
||||||
|
}
|
||||||
|
|
||||||
|
var ShellVariablesFormat = &Format{"shell", []string{"s", "sh"},
|
||||||
|
func() Encoder { return NewShellVariablesEncoder() },
|
||||||
|
nil,
|
||||||
|
}
|
||||||
|
|
||||||
|
var LuaFormat = &Format{"lua", []string{"l"},
|
||||||
|
func() Encoder { return NewLuaEncoder(ConfiguredLuaPreferences) },
|
||||||
|
func() Decoder { return NewLuaDecoder(ConfiguredLuaPreferences) },
|
||||||
|
}
|
||||||
|
|
||||||
|
var Formats = []*Format{
|
||||||
|
YamlFormat,
|
||||||
|
JSONFormat,
|
||||||
|
PropertiesFormat,
|
||||||
|
CSVFormat,
|
||||||
|
TSVFormat,
|
||||||
|
XMLFormat,
|
||||||
|
Base64Format,
|
||||||
|
UriFormat,
|
||||||
|
ShFormat,
|
||||||
|
TomlFormat,
|
||||||
|
ShellVariablesFormat,
|
||||||
|
LuaFormat,
|
||||||
|
}
|
||||||
|
|
||||||
|
func (f *Format) MatchesName(name string) bool {
|
||||||
|
if f.FormalName == name {
|
||||||
|
return true
|
||||||
|
}
|
||||||
|
for _, n := range f.Names {
|
||||||
|
if n == name {
|
||||||
|
return true
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return false
|
||||||
|
}
|
||||||
|
|
||||||
|
func (f *Format) GetConfiguredEncoder() Encoder {
|
||||||
|
return f.EncoderFactory()
|
||||||
|
}
|
||||||
|
|
||||||
|
func FormatStringFromFilename(filename string) string {
|
||||||
|
|
||||||
|
if filename != "" {
|
||||||
|
GetLogger().Debugf("checking file extension '%s' for auto format detection", filename)
|
||||||
|
nPos := strings.LastIndex(filename, ".")
|
||||||
|
if nPos > -1 {
|
||||||
|
format := filename[nPos+1:]
|
||||||
|
GetLogger().Debugf("detected format '%s'", format)
|
||||||
|
return format
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
GetLogger().Debugf("using default inputFormat 'yaml'")
|
||||||
|
return "yaml"
|
||||||
|
}
|
||||||
|
|
||||||
|
func FormatFromString(format string) (*Format, 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 GetAvailableOutputFormats() []*Format {
|
||||||
|
var formats = []*Format{}
|
||||||
|
for _, printerFormat := range Formats {
|
||||||
|
if printerFormat.EncoderFactory != nil {
|
||||||
|
formats = append(formats, printerFormat)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return formats
|
||||||
|
}
|
||||||
|
|
||||||
|
func GetAvailableOutputFormatString() string {
|
||||||
|
var formats = []string{}
|
||||||
|
for _, printerFormat := range GetAvailableOutputFormats() {
|
||||||
|
|
||||||
|
if printerFormat.FormalName != "" {
|
||||||
|
formats = append(formats, printerFormat.FormalName)
|
||||||
|
}
|
||||||
|
if len(printerFormat.Names) >= 1 {
|
||||||
|
formats = append(formats, printerFormat.Names[0])
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return strings.Join(formats, "|")
|
||||||
|
}
|
||||||
|
|
||||||
|
func GetAvailableInputFormats() []*Format {
|
||||||
|
var formats = []*Format{}
|
||||||
|
for _, printerFormat := range Formats {
|
||||||
|
if printerFormat.DecoderFactory != nil {
|
||||||
|
formats = append(formats, printerFormat)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return formats
|
||||||
|
}
|
||||||
|
|
||||||
|
func GetAvailableInputFormatString() string {
|
||||||
|
var formats = []string{}
|
||||||
|
for _, printerFormat := range GetAvailableInputFormats() {
|
||||||
|
|
||||||
|
if printerFormat.FormalName != "" {
|
||||||
|
formats = append(formats, printerFormat.FormalName)
|
||||||
|
}
|
||||||
|
if len(printerFormat.Names) >= 1 {
|
||||||
|
formats = append(formats, printerFormat.Names[0])
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return strings.Join(formats, "|")
|
||||||
|
}
|
@ -57,35 +57,35 @@ var participleYqRules = []*participleYqRule{
|
|||||||
|
|
||||||
{"ArrayToMap", "array_?to_?map", expressionOpToken(`(.[] | select(. != null) ) as $i ireduce({}; .[$i | key] = $i)`), 0},
|
{"ArrayToMap", "array_?to_?map", expressionOpToken(`(.[] | select(. != null) ) as $i ireduce({}; .[$i | key] = $i)`), 0},
|
||||||
|
|
||||||
{"YamlEncodeWithIndent", `to_?yaml\([0-9]+\)`, encodeParseIndent(YamlOutputFormat), 0},
|
{"YamlEncodeWithIndent", `to_?yaml\([0-9]+\)`, encodeParseIndent(YamlFormat), 0},
|
||||||
{"XMLEncodeWithIndent", `to_?xml\([0-9]+\)`, encodeParseIndent(XMLOutputFormat), 0},
|
{"XMLEncodeWithIndent", `to_?xml\([0-9]+\)`, encodeParseIndent(XMLFormat), 0},
|
||||||
{"JSONEncodeWithIndent", `to_?json\([0-9]+\)`, encodeParseIndent(JSONOutputFormat), 0},
|
{"JSONEncodeWithIndent", `to_?json\([0-9]+\)`, encodeParseIndent(JSONFormat), 0},
|
||||||
|
|
||||||
{"YamlDecode", `from_?yaml|@yamld|from_?json|@jsond`, decodeOp(YamlInputFormat), 0},
|
{"YamlDecode", `from_?yaml|@yamld|from_?json|@jsond`, decodeOp(YamlFormat), 0},
|
||||||
{"YamlEncode", `to_?yaml|@yaml`, encodeWithIndent(YamlOutputFormat, 2), 0},
|
{"YamlEncode", `to_?yaml|@yaml`, encodeWithIndent(YamlFormat, 2), 0},
|
||||||
|
|
||||||
{"JSONEncode", `to_?json`, encodeWithIndent(JSONOutputFormat, 2), 0},
|
{"JSONEncode", `to_?json`, encodeWithIndent(JSONFormat, 2), 0},
|
||||||
{"JSONEncodeNoIndent", `@json`, encodeWithIndent(JSONOutputFormat, 0), 0},
|
{"JSONEncodeNoIndent", `@json`, encodeWithIndent(JSONFormat, 0), 0},
|
||||||
|
|
||||||
{"PropertiesDecode", `from_?props|@propsd`, decodeOp(PropertiesInputFormat), 0},
|
{"PropertiesDecode", `from_?props|@propsd`, decodeOp(PropertiesFormat), 0},
|
||||||
{"PropsEncode", `to_?props|@props`, encodeWithIndent(PropsOutputFormat, 2), 0},
|
{"PropsEncode", `to_?props|@props`, encodeWithIndent(PropertiesFormat, 2), 0},
|
||||||
|
|
||||||
{"XmlDecode", `from_?xml|@xmld`, decodeOp(XMLInputFormat), 0},
|
{"XmlDecode", `from_?xml|@xmld`, decodeOp(XMLFormat), 0},
|
||||||
{"XMLEncode", `to_?xml`, encodeWithIndent(XMLOutputFormat, 2), 0},
|
{"XMLEncode", `to_?xml`, encodeWithIndent(XMLFormat, 2), 0},
|
||||||
{"XMLEncodeNoIndent", `@xml`, encodeWithIndent(XMLOutputFormat, 0), 0},
|
{"XMLEncodeNoIndent", `@xml`, encodeWithIndent(XMLFormat, 0), 0},
|
||||||
|
|
||||||
{"CSVDecode", `from_?csv|@csvd`, decodeOp(CSVObjectInputFormat), 0},
|
{"CSVDecode", `from_?csv|@csvd`, decodeOp(CSVFormat), 0},
|
||||||
{"CSVEncode", `to_?csv|@csv`, encodeWithIndent(CSVOutputFormat, 0), 0},
|
{"CSVEncode", `to_?csv|@csv`, encodeWithIndent(CSVFormat, 0), 0},
|
||||||
|
|
||||||
{"TSVDecode", `from_?tsv|@tsvd`, decodeOp(TSVObjectInputFormat), 0},
|
{"TSVDecode", `from_?tsv|@tsvd`, decodeOp(TSVFormat), 0},
|
||||||
{"TSVEncode", `to_?tsv|@tsv`, encodeWithIndent(TSVOutputFormat, 0), 0},
|
{"TSVEncode", `to_?tsv|@tsv`, encodeWithIndent(TSVFormat, 0), 0},
|
||||||
|
|
||||||
{"Base64d", `@base64d`, decodeOp(Base64InputFormat), 0},
|
{"Base64d", `@base64d`, decodeOp(Base64Format), 0},
|
||||||
{"Base64", `@base64`, encodeWithIndent(Base64OutputFormat, 0), 0},
|
{"Base64", `@base64`, encodeWithIndent(Base64Format, 0), 0},
|
||||||
|
|
||||||
{"Urid", `@urid`, decodeOp(UriInputFormat), 0},
|
{"Urid", `@urid`, decodeOp(UriFormat), 0},
|
||||||
{"Uri", `@uri`, encodeWithIndent(UriOutputFormat, 0), 0},
|
{"Uri", `@uri`, encodeWithIndent(UriFormat, 0), 0},
|
||||||
{"SH", `@sh`, encodeWithIndent(ShOutputFormat, 0), 0},
|
{"SH", `@sh`, encodeWithIndent(ShFormat, 0), 0},
|
||||||
|
|
||||||
{"LoadXML", `load_?xml|xml_?load`, loadOp(NewXMLDecoder(ConfiguredXMLPreferences), false), 0},
|
{"LoadXML", `load_?xml|xml_?load`, loadOp(NewXMLDecoder(ConfiguredXMLPreferences), false), 0},
|
||||||
|
|
||||||
@ -496,7 +496,7 @@ func numberValue() yqAction {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
func encodeParseIndent(outputFormat *PrinterOutputFormat) yqAction {
|
func encodeParseIndent(outputFormat *Format) 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,13 +510,13 @@ func encodeParseIndent(outputFormat *PrinterOutputFormat) yqAction {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
func encodeWithIndent(outputFormat *PrinterOutputFormat, indent int) yqAction {
|
func encodeWithIndent(outputFormat *Format, 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)
|
||||||
}
|
}
|
||||||
|
|
||||||
func decodeOp(inputFormat InputFormat) yqAction {
|
func decodeOp(format *Format) yqAction {
|
||||||
prefs := decoderPreferences{format: inputFormat}
|
prefs := decoderPreferences{format: format}
|
||||||
return opTokenWithPrefs(decodeOpType, nil, prefs)
|
return opTokenWithPrefs(decodeOpType, nil, prefs)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -9,21 +9,21 @@ import (
|
|||||||
"strings"
|
"strings"
|
||||||
)
|
)
|
||||||
|
|
||||||
func configureEncoder(format *PrinterOutputFormat, indent int) Encoder {
|
func configureEncoder(format *Format, indent int) Encoder {
|
||||||
|
|
||||||
switch format {
|
switch format {
|
||||||
case JSONOutputFormat:
|
case JSONFormat:
|
||||||
prefs := ConfiguredJSONPreferences.Copy()
|
prefs := ConfiguredJSONPreferences.Copy()
|
||||||
prefs.Indent = indent
|
prefs.Indent = indent
|
||||||
prefs.ColorsEnabled = false
|
prefs.ColorsEnabled = false
|
||||||
prefs.UnwrapScalar = false
|
prefs.UnwrapScalar = false
|
||||||
return NewJSONEncoder(prefs)
|
return NewJSONEncoder(prefs)
|
||||||
case YamlOutputFormat:
|
case YamlFormat:
|
||||||
var prefs = ConfiguredYamlPreferences.Copy()
|
var prefs = ConfiguredYamlPreferences.Copy()
|
||||||
prefs.Indent = indent
|
prefs.Indent = indent
|
||||||
prefs.ColorsEnabled = false
|
prefs.ColorsEnabled = false
|
||||||
return NewYamlEncoder(prefs)
|
return NewYamlEncoder(prefs)
|
||||||
case XMLOutputFormat:
|
case XMLFormat:
|
||||||
var xmlPrefs = ConfiguredXMLPreferences.Copy()
|
var xmlPrefs = ConfiguredXMLPreferences.Copy()
|
||||||
xmlPrefs.Indent = indent
|
xmlPrefs.Indent = indent
|
||||||
return NewXMLEncoder(xmlPrefs)
|
return NewXMLEncoder(xmlPrefs)
|
||||||
@ -46,7 +46,7 @@ func encodeToString(candidate *CandidateNode, prefs encoderPreferences) (string,
|
|||||||
}
|
}
|
||||||
|
|
||||||
type encoderPreferences struct {
|
type encoderPreferences struct {
|
||||||
format *PrinterOutputFormat
|
format *Format
|
||||||
indent int
|
indent int
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -81,9 +81,9 @@ func encodeOperator(_ *dataTreeNavigator, context Context, expressionNode *Expre
|
|||||||
}
|
}
|
||||||
|
|
||||||
// dont print a newline when printing json on a single line.
|
// dont print a newline when printing json on a single line.
|
||||||
if (preferences.format == JSONOutputFormat && preferences.indent == 0) ||
|
if (preferences.format == JSONFormat && preferences.indent == 0) ||
|
||||||
preferences.format == CSVOutputFormat ||
|
preferences.format == CSVFormat ||
|
||||||
preferences.format == TSVOutputFormat {
|
preferences.format == TSVFormat {
|
||||||
stringValue = chomper.ReplaceAllString(stringValue, "")
|
stringValue = chomper.ReplaceAllString(stringValue, "")
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -93,30 +93,7 @@ func encodeOperator(_ *dataTreeNavigator, context Context, expressionNode *Expre
|
|||||||
}
|
}
|
||||||
|
|
||||||
type decoderPreferences struct {
|
type decoderPreferences struct {
|
||||||
format InputFormat
|
format *Format
|
||||||
}
|
|
||||||
|
|
||||||
func createDecoder(format InputFormat) Decoder {
|
|
||||||
var decoder Decoder
|
|
||||||
switch format {
|
|
||||||
case JsonInputFormat:
|
|
||||||
decoder = NewJSONDecoder()
|
|
||||||
case YamlInputFormat:
|
|
||||||
decoder = NewYamlDecoder(ConfiguredYamlPreferences)
|
|
||||||
case XMLInputFormat:
|
|
||||||
decoder = NewXMLDecoder(ConfiguredXMLPreferences)
|
|
||||||
case Base64InputFormat:
|
|
||||||
decoder = NewBase64Decoder()
|
|
||||||
case PropertiesInputFormat:
|
|
||||||
decoder = NewPropertiesDecoder()
|
|
||||||
case CSVObjectInputFormat:
|
|
||||||
decoder = NewCSVObjectDecoder(ConfiguredCsvPreferences)
|
|
||||||
case TSVObjectInputFormat:
|
|
||||||
decoder = NewCSVObjectDecoder(ConfiguredTsvPreferences)
|
|
||||||
case UriInputFormat:
|
|
||||||
decoder = NewUriDecoder()
|
|
||||||
}
|
|
||||||
return decoder
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/* takes a string and decodes it back into an object */
|
/* takes a string and decodes it back into an object */
|
||||||
@ -124,7 +101,7 @@ func decodeOperator(_ *dataTreeNavigator, context Context, expressionNode *Expre
|
|||||||
|
|
||||||
preferences := expressionNode.Operation.Preferences.(decoderPreferences)
|
preferences := expressionNode.Operation.Preferences.(decoderPreferences)
|
||||||
|
|
||||||
decoder := createDecoder(preferences.format)
|
decoder := preferences.format.DecoderFactory()
|
||||||
if decoder == nil {
|
if decoder == nil {
|
||||||
return Context{}, errors.New("no support for input format")
|
return Context{}, errors.New("no support for input format")
|
||||||
}
|
}
|
||||||
|
@ -110,14 +110,14 @@ func testScenario(t *testing.T, s *expressionScenario) {
|
|||||||
|
|
||||||
if s.requiresFormat != "" {
|
if s.requiresFormat != "" {
|
||||||
format := s.requiresFormat
|
format := s.requiresFormat
|
||||||
inputFormat, err := InputFormatFromString(format)
|
inputFormat, err := FormatFromString(format)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
t.Error(err)
|
t.Error(err)
|
||||||
}
|
}
|
||||||
if decoder := createDecoder(inputFormat); decoder == nil {
|
if decoder := inputFormat.DecoderFactory(); decoder == nil {
|
||||||
t.Skipf("no support for %s input format", format)
|
t.Skipf("no support for %s input format", format)
|
||||||
}
|
}
|
||||||
outputFormat, err := OutputFormatFromString(format)
|
outputFormat, err := FormatFromString(format)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
t.Error(err)
|
t.Error(err)
|
||||||
}
|
}
|
||||||
|
@ -7,7 +7,6 @@ import (
|
|||||||
"fmt"
|
"fmt"
|
||||||
"io"
|
"io"
|
||||||
"regexp"
|
"regexp"
|
||||||
"strings"
|
|
||||||
)
|
)
|
||||||
|
|
||||||
type Printer interface {
|
type Printer interface {
|
||||||
@ -18,84 +17,6 @@ type Printer interface {
|
|||||||
SetNulSepOutput(nulSepOutput bool)
|
SetNulSepOutput(nulSepOutput bool)
|
||||||
}
|
}
|
||||||
|
|
||||||
type EncoderFactoryFunction func() Encoder
|
|
||||||
|
|
||||||
type PrinterOutputFormat struct {
|
|
||||||
FormalName string
|
|
||||||
Names []string
|
|
||||||
EncoderFactory EncoderFactoryFunction
|
|
||||||
}
|
|
||||||
|
|
||||||
var YamlOutputFormat = &PrinterOutputFormat{"yaml", []string{"y", "yml"}, func() Encoder { return NewYamlEncoder(ConfiguredYamlPreferences) }}
|
|
||||||
var JSONOutputFormat = &PrinterOutputFormat{"json", []string{"j"}, func() Encoder { return NewJSONEncoder(ConfiguredJSONPreferences) }}
|
|
||||||
var PropsOutputFormat = &PrinterOutputFormat{"props", []string{"p", "properties"}, func() Encoder { return NewPropertiesEncoder(ConfiguredPropertiesPreferences) }}
|
|
||||||
var CSVOutputFormat = &PrinterOutputFormat{"csv", []string{"c"}, func() Encoder { return NewCsvEncoder(ConfiguredCsvPreferences) }}
|
|
||||||
var TSVOutputFormat = &PrinterOutputFormat{"tsv", []string{"t"}, func() Encoder { return NewCsvEncoder(ConfiguredTsvPreferences) }}
|
|
||||||
var XMLOutputFormat = &PrinterOutputFormat{"xml", []string{"x"}, func() Encoder { return NewXMLEncoder(ConfiguredXMLPreferences) }}
|
|
||||||
|
|
||||||
var Base64OutputFormat = &PrinterOutputFormat{"base64", []string{}, func() Encoder { return NewBase64Encoder() }}
|
|
||||||
var UriOutputFormat = &PrinterOutputFormat{"uri", []string{}, func() Encoder { return NewUriEncoder() }}
|
|
||||||
var ShOutputFormat = &PrinterOutputFormat{"", nil, func() Encoder { return NewShEncoder() }}
|
|
||||||
|
|
||||||
var TomlOutputFormat = &PrinterOutputFormat{"toml", []string{}, func() Encoder { return NewTomlEncoder() }}
|
|
||||||
var ShellVariablesOutputFormat = &PrinterOutputFormat{"shell", []string{"s", "sh"}, func() Encoder { return NewShellVariablesEncoder() }}
|
|
||||||
|
|
||||||
var LuaOutputFormat = &PrinterOutputFormat{"lua", []string{"l"}, func() Encoder { return NewLuaEncoder(ConfiguredLuaPreferences) }}
|
|
||||||
|
|
||||||
var Formats = []*PrinterOutputFormat{
|
|
||||||
YamlOutputFormat,
|
|
||||||
JSONOutputFormat,
|
|
||||||
PropsOutputFormat,
|
|
||||||
CSVOutputFormat,
|
|
||||||
TSVOutputFormat,
|
|
||||||
XMLOutputFormat,
|
|
||||||
Base64OutputFormat,
|
|
||||||
UriOutputFormat,
|
|
||||||
ShOutputFormat,
|
|
||||||
TomlOutputFormat,
|
|
||||||
ShellVariablesOutputFormat,
|
|
||||||
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 (f *PrinterOutputFormat) GetConfiguredEncoder() Encoder {
|
|
||||||
return f.EncoderFactory()
|
|
||||||
}
|
|
||||||
|
|
||||||
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 {
|
||||||
encoder Encoder
|
encoder Encoder
|
||||||
printerWriter PrinterWriter
|
printerWriter PrinterWriter
|
||||||
|
@ -33,13 +33,13 @@ type multiPrintWriter struct {
|
|||||||
index int
|
index int
|
||||||
}
|
}
|
||||||
|
|
||||||
func NewMultiPrinterWriter(expression *ExpressionNode, format *PrinterOutputFormat) PrinterWriter {
|
func NewMultiPrinterWriter(expression *ExpressionNode, format *Format) PrinterWriter {
|
||||||
extension := "yml"
|
extension := "yml"
|
||||||
|
|
||||||
switch format {
|
switch format {
|
||||||
case JSONOutputFormat:
|
case JSONFormat:
|
||||||
extension = "json"
|
extension = "json"
|
||||||
case PropsOutputFormat:
|
case PropertiesFormat:
|
||||||
extension = "properties"
|
extension = "properties"
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user