yq/cmd/root.go

212 lines
11 KiB
Go
Raw Normal View History

package cmd
import (
2024-02-17 08:10:13 +00:00
"fmt"
2020-01-19 21:42:08 +00:00
"os"
2024-02-17 08:10:13 +00:00
"strings"
2020-01-19 21:42:08 +00:00
2021-12-21 05:52:54 +00:00
"github.com/mikefarah/yq/v4/pkg/yqlib"
"github.com/spf13/cobra"
logging "gopkg.in/op/go-logging.v1"
)
2024-02-17 08:10:13 +00:00
type runeValue rune
func newRuneVar(p *rune) *runeValue {
return (*runeValue)(p)
}
func (r *runeValue) String() string {
return string(*r)
}
func (r *runeValue) Set(rawVal string) error {
val := strings.ReplaceAll(rawVal, "\\n", "\n")
val = strings.ReplaceAll(val, "\\t", "\t")
val = strings.ReplaceAll(val, "\\r", "\r")
val = strings.ReplaceAll(val, "\\f", "\f")
val = strings.ReplaceAll(val, "\\v", "\v")
if len(val) != 1 {
return fmt.Errorf("[%v] is not a valid character. Must be length 1 was %v", val, len(val))
}
*r = runeValue(rune(val[0]))
return nil
}
func (r *runeValue) Type() string {
return "char"
}
func New() *cobra.Command {
var rootCmd = &cobra.Command{
Use: "yq",
Short: "yq is a lightweight and portable command-line data file processor.",
Long: `yq is a portable command-line data file processor (https://github.com/mikefarah/yq/)
See https://mikefarah.gitbook.io/yq/ for detailed documentation and examples.`,
2022-01-27 01:07:41 +00:00
Example: `
# yq tries to auto-detect the file format based off the extension, and defaults to YAML if it's unknown (or piping through STDIN)
# Use the '-p/--input-format' flag to specify a format type.
cat file.xml | yq -p xml
2022-01-27 01:07:41 +00:00
2022-01-27 06:21:10 +00:00
# read the "stuff" node from "myfile.yml"
2022-03-29 02:15:27 +00:00
yq '.stuff' < myfile.yml
2022-01-27 06:21:10 +00:00
# update myfile.yml in place
yq -i '.stuff = "foo"' myfile.yml
# print contents of sample.json as idiomatic YAML
yq -P -oy sample.json
2022-01-27 01:07:41 +00:00
`,
RunE: func(cmd *cobra.Command, args []string) error {
if version {
cmd.Print(GetVersionDisplay())
return nil
}
return evaluateSequence(cmd, args)
2020-10-27 05:45:16 +00:00
},
2022-11-10 11:07:53 +00:00
PersistentPreRunE: func(cmd *cobra.Command, args []string) error {
cmd.SetOut(cmd.OutOrStdout())
2024-02-15 22:41:33 +00:00
level := logging.WARNING
stringFormat := `[%{level}] %{color}%{time:15:04:05}%{color:reset} %{message}`
2022-02-01 03:47:51 +00:00
2024-02-15 22:41:33 +00:00
if verbose {
level = logging.DEBUG
stringFormat = `[%{level:5.5s}] %{color}%{time:15:04:05}%{color:bold} %{shortfile:-33s} %{shortfunc:-25s}%{color:reset} %{message}`
}
var format = logging.MustStringFormatter(stringFormat)
var backend = logging.AddModuleLevel(
logging.NewBackendFormatter(logging.NewLogBackend(os.Stderr, "", 0), format))
2024-02-15 22:41:33 +00:00
backend.SetLevel(level, "")
logging.SetBackend(backend)
2022-02-01 03:47:51 +00:00
yqlib.InitExpressionParser()
2022-11-10 11:07:53 +00:00
return nil
},
}
rootCmd.PersistentFlags().BoolVarP(&verbose, "verbose", "v", false, "verbose mode")
2021-07-25 08:08:33 +00:00
rootCmd.PersistentFlags().BoolVarP(&outputToJSON, "tojson", "j", false, "(deprecated) output as json. Set indent to 0 to print json in one line.")
2021-08-20 03:35:57 +00:00
err := rootCmd.PersistentFlags().MarkDeprecated("tojson", "please use -o=json instead")
2021-07-25 08:08:33 +00:00
if err != nil {
panic(err)
}
2024-02-24 03:58:11 +00:00
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)
}
2024-02-24 03:58:11 +00:00
if err = rootCmd.RegisterFlagCompletionFunc("output-format", cobra.FixedCompletions(outputCompletions, cobra.ShellCompDirectiveNoFileComp)); err != nil {
2023-12-20 07:36:57 +00:00
panic(err)
}
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 {
2023-12-20 07:36:57 +00:00
panic(err)
}
2021-12-21 04:02:07 +00:00
rootCmd.PersistentFlags().StringVar(&yqlib.ConfiguredXMLPreferences.AttributePrefix, "xml-attribute-prefix", yqlib.ConfiguredXMLPreferences.AttributePrefix, "prefix for xml attributes")
2023-12-20 07:36:57 +00:00
if err = rootCmd.RegisterFlagCompletionFunc("xml-attribute-prefix", cobra.NoFileCompletions); err != nil {
panic(err)
}
rootCmd.PersistentFlags().StringVar(&yqlib.ConfiguredXMLPreferences.ContentName, "xml-content-name", yqlib.ConfiguredXMLPreferences.ContentName, "name for xml content (if no attribute name is present).")
2023-12-20 07:36:57 +00:00
if err = rootCmd.RegisterFlagCompletionFunc("xml-content-name", cobra.NoFileCompletions); err != nil {
panic(err)
}
rootCmd.PersistentFlags().BoolVar(&yqlib.ConfiguredXMLPreferences.StrictMode, "xml-strict-mode", yqlib.ConfiguredXMLPreferences.StrictMode, "enables strict parsing of XML. See https://pkg.go.dev/encoding/xml for more details.")
rootCmd.PersistentFlags().BoolVar(&yqlib.ConfiguredXMLPreferences.KeepNamespace, "xml-keep-namespace", yqlib.ConfiguredXMLPreferences.KeepNamespace, "enables keeping namespace after parsing attributes")
rootCmd.PersistentFlags().BoolVar(&yqlib.ConfiguredXMLPreferences.UseRawToken, "xml-raw-token", yqlib.ConfiguredXMLPreferences.UseRawToken, "enables using RawToken method instead Token. Commonly disables namespace translations. See https://pkg.go.dev/encoding/xml#Decoder.RawToken for details.")
rootCmd.PersistentFlags().StringVar(&yqlib.ConfiguredXMLPreferences.ProcInstPrefix, "xml-proc-inst-prefix", yqlib.ConfiguredXMLPreferences.ProcInstPrefix, "prefix for xml processing instructions (e.g. <?xml version=\"1\"?>)")
2023-12-20 07:36:57 +00:00
if err = rootCmd.RegisterFlagCompletionFunc("xml-proc-inst-prefix", cobra.NoFileCompletions); err != nil {
panic(err)
}
rootCmd.PersistentFlags().StringVar(&yqlib.ConfiguredXMLPreferences.DirectiveName, "xml-directive-name", yqlib.ConfiguredXMLPreferences.DirectiveName, "name for xml directives (e.g. <!DOCTYPE thing cat>)")
2023-12-20 07:36:57 +00:00
if err = rootCmd.RegisterFlagCompletionFunc("xml-directive-name", cobra.NoFileCompletions); err != nil {
panic(err)
}
rootCmd.PersistentFlags().BoolVar(&yqlib.ConfiguredXMLPreferences.SkipProcInst, "xml-skip-proc-inst", yqlib.ConfiguredXMLPreferences.SkipProcInst, "skip over process instructions (e.g. <?xml version=\"1\"?>)")
rootCmd.PersistentFlags().BoolVar(&yqlib.ConfiguredXMLPreferences.SkipDirectives, "xml-skip-directives", yqlib.ConfiguredXMLPreferences.SkipDirectives, "skip over directives (e.g. <!DOCTYPE thing cat>)")
2021-12-21 04:02:07 +00:00
rootCmd.PersistentFlags().BoolVar(&yqlib.ConfiguredCsvPreferences.AutoParse, "csv-auto-parse", yqlib.ConfiguredCsvPreferences.AutoParse, "parse CSV YAML/JSON values")
2024-02-17 08:10:13 +00:00
rootCmd.PersistentFlags().Var(newRuneVar(&yqlib.ConfiguredCsvPreferences.Separator), "csv-separator", "CSV Separator character")
rootCmd.PersistentFlags().BoolVar(&yqlib.ConfiguredTsvPreferences.AutoParse, "tsv-auto-parse", yqlib.ConfiguredTsvPreferences.AutoParse, "parse TSV YAML/JSON values")
Implement basic Lua output support (#1745) * Implement basic Lua output support Ref #1700 Basic but working serialization to Lua tables. * Escape larger set of characters in Lua output Started with a minimum of replacements, this should be more complete, tho not all substitutions are strictly required in Lua. * Print simple keys unquoted in Lua output String keys that satisfy the requirements for variable names can be used as keys without quotes in tables. * Quote Lua keywords in table keys Keywords are not valid as unquoted keys, thus must be quoted * Make output of unquoted Lua table keys optional Generally safer and simpler to not do it. * Hook up settings for Lua output * Allow special characters in Lua prefix and suffix --lua-suffix='});^M' didn't work, so taking this approach instead * Panic on unhandled YAML Kind in Lua encoder * Handle YAML case varied booleans in Lua encoder * Handle special-case numbers in Lua encoder * Reject unhandled scalar Tags in Lua encoder * Add note about how Lua nil is unsuitable as table key Could add some context tracking in the future to allow rejecting nil in a table key context. * Return error instead of panic in Lua encoder * Add initial test for Lua encoder Boilerplate mostly copied from toml_test.go * Additional Lua output tests * Generate Lua encoder documentation Mostly just for the boilerplate * Convert octal for Lua output Lua doesn't have the 0oNNN syntax for octal integers, only decimal and hexadecimal, hence those can be passed trough as is while octal needs special treatment. * Implement indentation in in Lua output * Respect string Style in Lua encoder Lua has 'single', "double" and [[ long ]] strings. * Expand Lua examples * Output line comments in Lua output * Implement Lua globals output mode
2023-08-11 02:56:49 +00:00
rootCmd.PersistentFlags().StringVar(&yqlib.ConfiguredLuaPreferences.DocPrefix, "lua-prefix", yqlib.ConfiguredLuaPreferences.DocPrefix, "prefix")
2023-12-20 07:36:57 +00:00
if err = rootCmd.RegisterFlagCompletionFunc("lua-prefix", cobra.NoFileCompletions); err != nil {
panic(err)
}
Implement basic Lua output support (#1745) * Implement basic Lua output support Ref #1700 Basic but working serialization to Lua tables. * Escape larger set of characters in Lua output Started with a minimum of replacements, this should be more complete, tho not all substitutions are strictly required in Lua. * Print simple keys unquoted in Lua output String keys that satisfy the requirements for variable names can be used as keys without quotes in tables. * Quote Lua keywords in table keys Keywords are not valid as unquoted keys, thus must be quoted * Make output of unquoted Lua table keys optional Generally safer and simpler to not do it. * Hook up settings for Lua output * Allow special characters in Lua prefix and suffix --lua-suffix='});^M' didn't work, so taking this approach instead * Panic on unhandled YAML Kind in Lua encoder * Handle YAML case varied booleans in Lua encoder * Handle special-case numbers in Lua encoder * Reject unhandled scalar Tags in Lua encoder * Add note about how Lua nil is unsuitable as table key Could add some context tracking in the future to allow rejecting nil in a table key context. * Return error instead of panic in Lua encoder * Add initial test for Lua encoder Boilerplate mostly copied from toml_test.go * Additional Lua output tests * Generate Lua encoder documentation Mostly just for the boilerplate * Convert octal for Lua output Lua doesn't have the 0oNNN syntax for octal integers, only decimal and hexadecimal, hence those can be passed trough as is while octal needs special treatment. * Implement indentation in in Lua output * Respect string Style in Lua encoder Lua has 'single', "double" and [[ long ]] strings. * Expand Lua examples * Output line comments in Lua output * Implement Lua globals output mode
2023-08-11 02:56:49 +00:00
rootCmd.PersistentFlags().StringVar(&yqlib.ConfiguredLuaPreferences.DocSuffix, "lua-suffix", yqlib.ConfiguredLuaPreferences.DocSuffix, "suffix")
2023-12-20 07:36:57 +00:00
if err = rootCmd.RegisterFlagCompletionFunc("lua-suffix", cobra.NoFileCompletions); err != nil {
panic(err)
}
Implement basic Lua output support (#1745) * Implement basic Lua output support Ref #1700 Basic but working serialization to Lua tables. * Escape larger set of characters in Lua output Started with a minimum of replacements, this should be more complete, tho not all substitutions are strictly required in Lua. * Print simple keys unquoted in Lua output String keys that satisfy the requirements for variable names can be used as keys without quotes in tables. * Quote Lua keywords in table keys Keywords are not valid as unquoted keys, thus must be quoted * Make output of unquoted Lua table keys optional Generally safer and simpler to not do it. * Hook up settings for Lua output * Allow special characters in Lua prefix and suffix --lua-suffix='});^M' didn't work, so taking this approach instead * Panic on unhandled YAML Kind in Lua encoder * Handle YAML case varied booleans in Lua encoder * Handle special-case numbers in Lua encoder * Reject unhandled scalar Tags in Lua encoder * Add note about how Lua nil is unsuitable as table key Could add some context tracking in the future to allow rejecting nil in a table key context. * Return error instead of panic in Lua encoder * Add initial test for Lua encoder Boilerplate mostly copied from toml_test.go * Additional Lua output tests * Generate Lua encoder documentation Mostly just for the boilerplate * Convert octal for Lua output Lua doesn't have the 0oNNN syntax for octal integers, only decimal and hexadecimal, hence those can be passed trough as is while octal needs special treatment. * Implement indentation in in Lua output * Respect string Style in Lua encoder Lua has 'single', "double" and [[ long ]] strings. * Expand Lua examples * Output line comments in Lua output * Implement Lua globals output mode
2023-08-11 02:56:49 +00:00
rootCmd.PersistentFlags().BoolVar(&yqlib.ConfiguredLuaPreferences.UnquotedKeys, "lua-unquoted", yqlib.ConfiguredLuaPreferences.UnquotedKeys, "output unquoted string keys (e.g. {foo=\"bar\"})")
rootCmd.PersistentFlags().BoolVar(&yqlib.ConfiguredLuaPreferences.Globals, "lua-globals", yqlib.ConfiguredLuaPreferences.Globals, "output keys as top-level global variables")
rootCmd.PersistentFlags().StringVar(&yqlib.ConfiguredPropertiesPreferences.KeyValueSeparator, "properties-separator", yqlib.ConfiguredPropertiesPreferences.KeyValueSeparator, "separator to use between keys and values")
rootCmd.PersistentFlags().BoolVar(&yqlib.ConfiguredPropertiesPreferences.UseArrayBrackets, "properties-array-brackets", yqlib.ConfiguredPropertiesPreferences.UseArrayBrackets, "use [x] in array paths (e.g. for SpringBoot)")
2024-03-05 03:10:12 +00:00
rootCmd.PersistentFlags().BoolVar(&yqlib.StringInterpolationEnabled, "string-interpolation", yqlib.StringInterpolationEnabled, "Toggles strings interpolation of \\(exp)")
2021-12-21 06:07:32 +00:00
rootCmd.PersistentFlags().BoolVarP(&nullInput, "null-input", "n", false, "Don't read input, simply evaluate the expression given. Useful for creating docs from scratch.")
2020-11-13 02:35:59 +00:00
rootCmd.PersistentFlags().BoolVarP(&noDocSeparators, "no-doc", "N", false, "Don't print document separators (---)")
2020-11-06 03:37:01 +00:00
2020-02-03 05:52:12 +00:00
rootCmd.PersistentFlags().IntVarP(&indent, "indent", "I", 2, "sets indent level for output")
2023-12-20 07:36:57 +00:00
if err = rootCmd.RegisterFlagCompletionFunc("indent", cobra.NoFileCompletions); err != nil {
panic(err)
}
rootCmd.Flags().BoolVarP(&version, "version", "V", false, "Print version information and quit")
2023-09-18 23:52:36 +00:00
rootCmd.PersistentFlags().BoolVarP(&writeInplace, "inplace", "i", false, "update the file in place of first file given.")
rootCmd.PersistentFlags().VarP(unwrapScalarFlag, "unwrapScalar", "r", "unwrap scalar, print the value with no quotes, colors or comments. Defaults to true for yaml")
rootCmd.PersistentFlags().Lookup("unwrapScalar").NoOptDefVal = "true"
rootCmd.PersistentFlags().BoolVarP(&nulSepOutput, "nul-output", "0", false, "Use NUL char to separate values. If unwrap scalar is also set, fail if unwrapped scalar contains NUL char.")
2020-12-28 00:40:41 +00:00
rootCmd.PersistentFlags().BoolVarP(&prettyPrint, "prettyPrint", "P", false, "pretty print, shorthand for '... style = \"\"'")
2020-11-30 05:35:21 +00:00
rootCmd.PersistentFlags().BoolVarP(&exitStatus, "exit-status", "e", false, "set exit status if there are no matches or null or false is returned")
2020-10-27 05:45:16 +00:00
rootCmd.PersistentFlags().BoolVarP(&forceColor, "colors", "C", false, "force print with colors")
rootCmd.PersistentFlags().BoolVarP(&forceNoColor, "no-colors", "M", false, "force print with no colors")
2021-07-18 03:44:56 +00:00
rootCmd.PersistentFlags().StringVarP(&frontMatter, "front-matter", "f", "", "(extract|process) first input as yaml front-matter. Extract will pull out the yaml content, process will run the expression against the yaml content, leaving the remaining data intact")
2023-12-20 07:36:57 +00:00
if err = rootCmd.RegisterFlagCompletionFunc("front-matter", cobra.FixedCompletions([]string{"extract", "process"}, cobra.ShellCompDirectiveNoFileComp)); err != nil {
panic(err)
}
rootCmd.PersistentFlags().StringVarP(&forceExpression, "expression", "", "", "forcibly set the expression argument. Useful when yq argument detection thinks your expression is a file.")
2023-12-20 07:36:57 +00:00
if err = rootCmd.RegisterFlagCompletionFunc("expression", cobra.NoFileCompletions); err != nil {
panic(err)
}
rootCmd.PersistentFlags().BoolVarP(&yqlib.ConfiguredYamlPreferences.LeadingContentPreProcessing, "header-preprocess", "", true, "Slurp any header comments and separators before processing expression.")
2021-10-29 03:14:39 +00:00
rootCmd.PersistentFlags().StringVarP(&splitFileExp, "split-exp", "s", "", "print each result (or doc) into a file named (exp). [exp] argument must return a string. You can use $index in the expression as the result counter.")
2023-12-20 07:36:57 +00:00
if err = rootCmd.RegisterFlagCompletionFunc("split-exp", cobra.NoFileCompletions); err != nil {
panic(err)
}
rootCmd.PersistentFlags().StringVarP(&splitFileExpFile, "split-exp-file", "", "", "Use a file to specify the split-exp expression.")
2023-12-20 07:36:57 +00:00
if err = rootCmd.MarkPersistentFlagFilename("split-exp-file"); err != nil {
panic(err)
}
2021-10-29 03:14:39 +00:00
2022-03-01 00:50:09 +00:00
rootCmd.PersistentFlags().StringVarP(&expressionFile, "from-file", "", "", "Load expression from specified file.")
2023-12-20 07:36:57 +00:00
if err = rootCmd.MarkPersistentFlagFilename("from-file"); err != nil {
panic(err)
}
2022-03-01 00:50:09 +00:00
2020-11-16 01:09:57 +00:00
rootCmd.AddCommand(
createEvaluateSequenceCommand(),
createEvaluateAllCommand(),
completionCmd,
)
return rootCmd
}