Skip to content

Commit

Permalink
Introduced 'format' to encapsulate encoding and decoding formats toge…
Browse files Browse the repository at this point in the history
…ther
  • Loading branch information
mikefarah committed Feb 24, 2024
1 parent 8f6d642 commit 447bf28
Show file tree
Hide file tree
Showing 11 changed files with 253 additions and 250 deletions.
2 changes: 1 addition & 1 deletion cmd/evaluate_all_command.go
Original file line number Diff line number Diff line change
Expand Up @@ -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 {
return err
}
Expand Down
2 changes: 1 addition & 1 deletion cmd/evaluate_sequence_command.go
Original file line number Diff line number Diff line change
Expand Up @@ -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 {
return err
}
Expand Down
16 changes: 13 additions & 3 deletions cmd/root.go
Original file line number Diff line number Diff line change
Expand Up @@ -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()))
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)
}
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.")
if err = rootCmd.RegisterFlagCompletionFunc("input-format", cobra.FixedCompletions([]string{"auto", "yaml", "props", "xml", "tsv", "csv", "toml"}, cobra.ShellCompDirectiveNoFileComp)); err != nil {
rootCmd.PersistentFlags().StringVarP(&inputFormat, "input-format", "p", "auto", fmt.Sprintf("[auto|a|%v] parse format for input.", yqlib.GetAvailableInputFormatString()))

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)
}

Expand Down
63 changes: 17 additions & 46 deletions cmd/utils.go
Original file line number Diff line number Diff line change
Expand Up @@ -64,9 +64,9 @@ func initCommand(cmd *cobra.Command, args []string) (string, []string, error) {
}
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 {
// unknown file type, default to yaml
yqlib.GetLogger().Debug("Unknown file format extension '%v', defaulting to yaml", inputFormat)
Expand All @@ -86,23 +86,23 @@ func initCommand(cmd *cobra.Command, args []string) (string, []string, error) {
// before this was introduced, `yq -pcsv things.csv`
// would produce *yaml* output.
//
outputFormat = yqlib.FormatFromFilename(inputFilename)
outputFormat = yqlib.FormatStringFromFilename(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)
}
outputFormat = "yaml"
}

outputFormatType, err := yqlib.OutputFormatFromString(outputFormat)
outputFormatType, err := yqlib.FormatFromString(outputFormat)

if err != nil {
return "", nil, err
}
yqlib.GetLogger().Debug("Using input format %v", inputFormat)
yqlib.GetLogger().Debug("Using output format %v", outputFormat)

if outputFormatType == yqlib.YamlOutputFormat ||
outputFormatType == yqlib.PropsOutputFormat {
if outputFormatType == yqlib.YamlFormat ||
outputFormatType == yqlib.PropertiesFormat {
unwrapScalar = true
}
if unwrapScalarFlag.IsExplicitlySet() {
Expand All @@ -113,42 +113,20 @@ func initCommand(cmd *cobra.Command, args []string) (string, []string, error) {
}

func configureDecoder(evaluateTogether bool) (yqlib.Decoder, error) {
yqlibInputFormat, err := yqlib.InputFormatFromString(inputFormat)
format, err := yqlib.FormatFromString(inputFormat)
if err != nil {
return nil, err
}
yqlibDecoder, err := createDecoder(yqlibInputFormat, evaluateTogether)
yqlib.ConfiguredYamlPreferences.EvaluateTogether = evaluateTogether

yqlibDecoder := format.DecoderFactory()
if yqlibDecoder == nil {
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) {
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) {
func configurePrinterWriter(format *yqlib.Format, out io.Writer) (yqlib.PrinterWriter, error) {

var printerWriter yqlib.PrinterWriter

Expand All @@ -166,18 +144,10 @@ func configurePrinterWriter(format *yqlib.PrinterOutputFormat, out io.Writer) (y
}

func configureEncoder() (yqlib.Encoder, error) {
yqlibOutputFormat, err := yqlib.OutputFormatFromString(outputFormat)
yqlibOutputFormat, err := yqlib.FormatFromString(outputFormat)
if err != nil {
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.ConfiguredYamlPreferences.Indent = indent
yqlib.ConfiguredJSONPreferences.Indent = indent
Expand All @@ -191,11 +161,12 @@ func createEncoder(format *yqlib.PrinterOutputFormat) (yqlib.Encoder, error) {

yqlib.ConfiguredYamlPreferences.PrintDocSeparators = !noDocSeparators

encoder := format.EncoderFactory()
encoder := yqlibOutputFormat.EncoderFactory()

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)
Expand Down
56 changes: 0 additions & 56 deletions pkg/yqlib/decoder.go
Original file line number Diff line number Diff line change
@@ -1,66 +1,10 @@
package yqlib

import (
"fmt"
"io"
"strings"
)

type InputFormat uint

const (
YamlInputFormat = 1 << iota
XMLInputFormat
PropertiesInputFormat
Base64InputFormat
JsonInputFormat
CSVObjectInputFormat
TSVObjectInputFormat
TomlInputFormat
UriInputFormat
LuaInputFormat
)

type Decoder interface {
Init(reader io.Reader) 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"
}
Loading

0 comments on commit 447bf28

Please sign in to comment.