2021-10-30 02:04:05 +00:00
|
|
|
package cmd
|
|
|
|
|
|
|
|
import (
|
|
|
|
"fmt"
|
|
|
|
"io"
|
|
|
|
"os"
|
|
|
|
|
|
|
|
"github.com/mikefarah/yq/v4/pkg/yqlib"
|
|
|
|
"github.com/spf13/cobra"
|
2022-02-06 21:46:43 +00:00
|
|
|
"gopkg.in/op/go-logging.v1"
|
2021-10-30 02:04:05 +00:00
|
|
|
)
|
|
|
|
|
|
|
|
func initCommand(cmd *cobra.Command, args []string) (firstFileIndex int, err error) {
|
|
|
|
cmd.SilenceUsage = true
|
|
|
|
|
|
|
|
fileInfo, _ := os.Stdout.Stat()
|
|
|
|
|
|
|
|
if forceColor || (!forceNoColor && (fileInfo.Mode()&os.ModeCharDevice) != 0) {
|
|
|
|
colorsEnabled = true
|
|
|
|
}
|
|
|
|
|
|
|
|
firstFileIndex = -1
|
|
|
|
if !nullInput && len(args) == 1 {
|
|
|
|
firstFileIndex = 0
|
|
|
|
} else if len(args) > 1 {
|
|
|
|
firstFileIndex = 1
|
|
|
|
}
|
|
|
|
|
2021-11-25 09:24:51 +00:00
|
|
|
// backwards compatibility
|
2021-10-30 02:04:05 +00:00
|
|
|
if outputToJSON {
|
|
|
|
outputFormat = "json"
|
|
|
|
}
|
|
|
|
|
|
|
|
if writeInplace && (firstFileIndex == -1) {
|
|
|
|
return 0, fmt.Errorf("write inplace flag only applicable when giving an expression and at least one file")
|
|
|
|
}
|
|
|
|
|
|
|
|
if writeInplace && splitFileExp != "" {
|
|
|
|
return 0, fmt.Errorf("write inplace cannot be used with split file")
|
|
|
|
}
|
|
|
|
|
|
|
|
if nullInput && len(args) > 1 {
|
|
|
|
return 0, fmt.Errorf("cannot pass files in when using null-input flag")
|
|
|
|
}
|
|
|
|
|
|
|
|
return firstFileIndex, nil
|
|
|
|
}
|
|
|
|
|
2021-12-21 04:02:07 +00:00
|
|
|
func configureDecoder() (yqlib.Decoder, error) {
|
|
|
|
yqlibInputFormat, err := yqlib.InputFormatFromString(inputFormat)
|
|
|
|
if err != nil {
|
|
|
|
return nil, err
|
|
|
|
}
|
|
|
|
switch yqlibInputFormat {
|
2022-02-07 00:55:55 +00:00
|
|
|
case yqlib.XMLInputFormat:
|
|
|
|
return yqlib.NewXMLDecoder(xmlAttributePrefix, xmlContentName), nil
|
2021-12-21 04:02:07 +00:00
|
|
|
}
|
|
|
|
return yqlib.NewYamlDecoder(), nil
|
|
|
|
}
|
|
|
|
|
2022-01-26 22:29:41 +00:00
|
|
|
func configurePrinterWriter(format yqlib.PrinterOutputFormat, out io.Writer) (yqlib.PrinterWriter, error) {
|
2021-10-30 02:04:05 +00:00
|
|
|
|
|
|
|
var printerWriter yqlib.PrinterWriter
|
|
|
|
|
|
|
|
if splitFileExp != "" {
|
|
|
|
colorsEnabled = forceColor
|
2022-02-01 03:47:51 +00:00
|
|
|
splitExp, err := yqlib.ExpressionParser.ParseExpression(splitFileExp)
|
2021-10-30 02:04:05 +00:00
|
|
|
if err != nil {
|
2022-01-26 22:29:41 +00:00
|
|
|
return nil, fmt.Errorf("bad split document expression: %w", err)
|
2021-10-30 02:04:05 +00:00
|
|
|
}
|
|
|
|
printerWriter = yqlib.NewMultiPrinterWriter(splitExp, format)
|
|
|
|
} else {
|
|
|
|
printerWriter = yqlib.NewSinglePrinterWriter(out)
|
|
|
|
}
|
2022-01-26 22:29:41 +00:00
|
|
|
return printerWriter, nil
|
2021-10-30 02:04:05 +00:00
|
|
|
}
|
2022-01-15 00:57:59 +00:00
|
|
|
|
|
|
|
func configureEncoder(format yqlib.PrinterOutputFormat) yqlib.Encoder {
|
|
|
|
switch format {
|
2022-02-07 00:55:55 +00:00
|
|
|
case yqlib.JSONOutputFormat:
|
|
|
|
return yqlib.NewJONEncoder(indent)
|
2022-01-15 00:57:59 +00:00
|
|
|
case yqlib.PropsOutputFormat:
|
|
|
|
return yqlib.NewPropertiesEncoder()
|
2022-02-07 00:55:55 +00:00
|
|
|
case yqlib.CSVOutputFormat:
|
2022-01-15 00:57:59 +00:00
|
|
|
return yqlib.NewCsvEncoder(',')
|
2022-02-07 00:55:55 +00:00
|
|
|
case yqlib.TSVOutputFormat:
|
2022-01-15 00:57:59 +00:00
|
|
|
return yqlib.NewCsvEncoder('\t')
|
|
|
|
case yqlib.YamlOutputFormat:
|
|
|
|
return yqlib.NewYamlEncoder(indent, colorsEnabled, !noDocSeparators, unwrapScalar)
|
2022-02-07 00:55:55 +00:00
|
|
|
case yqlib.XMLOutputFormat:
|
|
|
|
return yqlib.NewXMLEncoder(indent, xmlAttributePrefix, xmlContentName)
|
2022-01-15 00:57:59 +00:00
|
|
|
}
|
|
|
|
panic("invalid encoder")
|
|
|
|
}
|
2022-01-27 04:54:26 +00:00
|
|
|
|
|
|
|
// this is a hack to enable backwards compatibility with githubactions (which pipe /dev/null into everything)
|
|
|
|
// and being able to call yq with the filename as a single parameter
|
|
|
|
//
|
|
|
|
// without this - yq detects there is stdin (thanks githubactions),
|
|
|
|
// then tries to parse the filename as an expression
|
|
|
|
func maybeFile(str string) bool {
|
2022-02-06 21:46:43 +00:00
|
|
|
yqlib.GetLogger().Debugf("checking '%v' is a file", str)
|
2022-02-06 21:04:26 +00:00
|
|
|
stat, err := os.Stat(str) // #nosec
|
2022-02-06 21:46:43 +00:00
|
|
|
result := err == nil && !stat.IsDir()
|
|
|
|
if yqlib.GetLogger().IsEnabledFor(logging.DEBUG) {
|
|
|
|
if err != nil {
|
|
|
|
yqlib.GetLogger().Debugf("error: %v", err)
|
|
|
|
} else {
|
|
|
|
yqlib.GetLogger().Debugf("error: %v, dir: %v", err, stat.IsDir())
|
|
|
|
}
|
|
|
|
yqlib.GetLogger().Debugf("result: %v", result)
|
|
|
|
}
|
|
|
|
return result
|
|
|
|
}
|
|
|
|
|
2022-02-06 22:27:52 +00:00
|
|
|
func processStdInArgs(pipingStdin bool, args []string) []string {
|
2022-02-06 21:46:43 +00:00
|
|
|
if !pipingStdin {
|
|
|
|
return args
|
|
|
|
}
|
|
|
|
|
|
|
|
for _, arg := range args {
|
|
|
|
if arg == "-" {
|
|
|
|
return args
|
|
|
|
}
|
|
|
|
}
|
|
|
|
yqlib.GetLogger().Debugf("missing '-', adding it to the end")
|
|
|
|
|
|
|
|
// we're piping from stdin, but there's no '-' arg
|
|
|
|
// lets add one to the end
|
|
|
|
return append(args, "-")
|
2022-01-27 04:54:26 +00:00
|
|
|
}
|
2022-02-06 22:27:52 +00:00
|
|
|
|
|
|
|
func processArgs(pipingStdin bool, originalArgs []string) (string, []string) {
|
|
|
|
args := processStdInArgs(pipingStdin, originalArgs)
|
|
|
|
yqlib.GetLogger().Debugf("processed args: %v", args)
|
|
|
|
expression := forceExpression
|
|
|
|
if expression == "" && len(args) > 0 && args[0] != "-" && !maybeFile(args[0]) {
|
|
|
|
yqlib.GetLogger().Debug("assuming expression is '%v'", args[0])
|
|
|
|
expression = args[0]
|
|
|
|
args = args[1:]
|
|
|
|
}
|
|
|
|
return expression, args
|
|
|
|
}
|