diff --git a/acceptance_tests/inputs-format-auto.sh b/acceptance_tests/inputs-format-auto.sh index 4732eb81..302f3025 100755 --- a/acceptance_tests/inputs-format-auto.sh +++ b/acceptance_tests/inputs-format-auto.sh @@ -15,8 +15,11 @@ testInputJson() { EOL read -r -d '' expected << EOM -mike: - things: cool +{ + "mike": { + "things": "cool" + } +} EOM X=$(./yq test.json) @@ -26,19 +29,38 @@ EOM assertEquals "$expected" "$X" } +testInputJsonOutputYaml() { + cat >test.json <test.properties <BiBi EOM X=$(./yq e test.xml) @@ -145,11 +159,8 @@ testInputXmlNamespaces() { EOL read -r -d '' expected << EOM -+p_xml: version="1.0" -map: - +@xmlns: some-namespace - +@xmlns:xsi: some-instance - +@xsi:schemaLocation: some-url + + EOM X=$(./yq e test.xml) @@ -159,25 +170,6 @@ EOM assertEquals "$expected" "$X" } -testInputXmlRoundtrip() { - cat >test.xml < - -Meow -EOL - - read -r -d '' expected << EOM - - -Meow -EOM - - X=$(./yq -o=xml test.xml) - assertEquals "$expected" "$X" - - X=$(./yq ea -o=xml test.xml) - assertEquals "$expected" "$X" -} testInputXmlStrict() { @@ -192,11 +184,11 @@ testInputXmlStrict() { EOL - X=$(./yq --xml-strict-mode test.xml -o=xml 2>&1) + X=$(./yq --xml-strict-mode test.xml 2>&1) assertEquals 1 $? assertEquals "Error: bad file 'test.xml': XML syntax error on line 7: invalid character entity &writer;" "$X" - X=$(./yq ea --xml-strict-mode test.xml -o=xml 2>&1) + X=$(./yq ea --xml-strict-mode test.xml 2>&1) assertEquals "Error: bad file 'test.xml': XML syntax error on line 7: invalid character entity &writer;" "$X" } @@ -206,9 +198,7 @@ testInputXmlGithubAction() { EOL read -r -d '' expected << EOM -cat: - +content: BiBi - +@legs: "4" +BiBi EOM X=$(cat /dev/null | ./yq e test.xml) diff --git a/acceptance_tests/inputs-format.sh b/acceptance_tests/inputs-format.sh index 2eebd501..cd48cb4a 100755 --- a/acceptance_tests/inputs-format.sh +++ b/acceptance_tests/inputs-format.sh @@ -120,7 +120,7 @@ EOM } testInputXmlNamespaces() { - cat >test.yml <test.xml < @@ -134,10 +134,10 @@ map: +@xsi:schemaLocation: some-url EOM - X=$(./yq e -p=xml test.yml) + X=$(./yq e -p=xml test.xml) assertEquals "$expected" "$X" - X=$(./yq ea -p=xml test.yml) + X=$(./yq ea -p=xml test.xml) assertEquals "$expected" "$X" } diff --git a/cmd/constant.go b/cmd/constant.go index 8b94dc2c..a8428aae 100644 --- a/cmd/constant.go +++ b/cmd/constant.go @@ -6,8 +6,9 @@ var unwrapScalar = false var writeInplace = false var outputToJSON = false -var outputFormat = "yaml" -var inputFormatDefault = "yaml" + +var outputFormat = "" + var inputFormat = "" var exitStatus = false diff --git a/cmd/evaluate_all_command.go b/cmd/evaluate_all_command.go index b56a9cc4..fff64fa5 100644 --- a/cmd/evaluate_all_command.go +++ b/cmd/evaluate_all_command.go @@ -75,12 +75,7 @@ func evaluateAll(cmd *cobra.Command, args []string) (cmdError error) { return err } - inputFilename := "" - if len(args) > 0 { - inputFilename = args[0] - } - - decoder, err := configureDecoder(true, inputFilename) + decoder, err := configureDecoder(true) if err != nil { return err } diff --git a/cmd/evalute_sequence_command.go b/cmd/evalute_sequence_command.go index bc69698f..dab803c3 100644 --- a/cmd/evalute_sequence_command.go +++ b/cmd/evalute_sequence_command.go @@ -100,12 +100,7 @@ func evaluateSequence(cmd *cobra.Command, args []string) (cmdError error) { printer := yqlib.NewPrinter(encoder, printerWriter) - inputFilename := "" - if len(args) > 0 { - inputFilename = args[0] - } - - decoder, err := configureDecoder(false, inputFilename) + decoder, err := configureDecoder(false) if err != nil { return err } diff --git a/cmd/root.go b/cmd/root.go index 76782ccb..98e52752 100644 --- a/cmd/root.go +++ b/cmd/root.go @@ -53,25 +53,6 @@ yq -P sample.json logging.SetBackend(backend) yqlib.InitExpressionParser() - outputFormatType, err := yqlib.OutputFormatFromString(outputFormat) - - if err != nil { - return err - } - - if outputFormatType == yqlib.YamlOutputFormat || - outputFormatType == yqlib.PropsOutputFormat { - unwrapScalar = true - } - if unwrapScalarFlag.IsExplicitySet() { - unwrapScalar = unwrapScalarFlag.IsSet() - } - - //copy preference form global setting - yqlib.ConfiguredYamlPreferences.UnwrapScalar = unwrapScalar - - yqlib.ConfiguredYamlPreferences.PrintDocSeparators = !noDocSeparators - return nil }, } @@ -84,8 +65,8 @@ yq -P sample.json panic(err) } - rootCmd.PersistentFlags().StringVarP(&outputFormat, "output-format", "o", "yaml", "[yaml|y|json|j|props|p|xml|x] output format type.") - rootCmd.PersistentFlags().StringVarP(&inputFormat, "input-format", "p", "", "[yaml|y|props|p|xml|x] parse format for input. Note that json is a subset of yaml.") + rootCmd.PersistentFlags().StringVarP(&outputFormat, "output-format", "o", "auto", "[auto|a|yaml|y|json|j|props|p|xml|x] output format type.") + rootCmd.PersistentFlags().StringVarP(&inputFormat, "input-format", "p", "auto", "[auto|a|yaml|y|props|p|xml|x] parse format for input. Note that json is a subset of yaml.") rootCmd.PersistentFlags().StringVar(&yqlib.ConfiguredXMLPreferences.AttributePrefix, "xml-attribute-prefix", yqlib.ConfiguredXMLPreferences.AttributePrefix, "prefix for xml attributes") rootCmd.PersistentFlags().StringVar(&yqlib.ConfiguredXMLPreferences.ContentName, "xml-content-name", yqlib.ConfiguredXMLPreferences.ContentName, "name for xml content (if no attribute name is present).") diff --git a/cmd/utils.go b/cmd/utils.go index cc20a827..c8ba95fa 100644 --- a/cmd/utils.go +++ b/cmd/utils.go @@ -53,15 +53,52 @@ func initCommand(cmd *cobra.Command, args []string) (string, []string, error) { return "", nil, fmt.Errorf("cannot pass files in when using null-input flag") } + inputFilename := "" + if len(args) > 0 { + inputFilename = args[0] + } + if inputFormat == "" || inputFormat == "auto" || inputFormat == "a" { + + inputFormat = yqlib.FormatFromFilename(inputFilename) + if outputFormat == "" || outputFormat == "auto" || outputFormat == "a" { + outputFormat = yqlib.FormatFromFilename(inputFilename) + } + } else if outputFormat == "" || outputFormat == "auto" || outputFormat == "a" { + // backwards compatibility - + // before this was introduced, `yq -pcsv things.csv` + // would produce *yaml* output. + // + outputFormat = yqlib.FormatFromFilename(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) + + if err != nil { + return "", nil, err + } + yqlib.GetLogger().Debug("Using outputformat %v", outputFormat) + + if outputFormatType == yqlib.YamlOutputFormat || + outputFormatType == yqlib.PropsOutputFormat { + unwrapScalar = true + } + if unwrapScalarFlag.IsExplicitySet() { + unwrapScalar = unwrapScalarFlag.IsSet() + } + + //copy preference form global setting + yqlib.ConfiguredYamlPreferences.UnwrapScalar = unwrapScalar + + yqlib.ConfiguredYamlPreferences.PrintDocSeparators = !noDocSeparators + return expression, args, nil } -func configureDecoder(evaluateTogether bool, inputFilename string) (yqlib.Decoder, error) { - if inputFormat == "" { - inputFormat = yqlib.InputFormatFromFilename(inputFilename, inputFormatDefault) - } else { - yqlib.GetLogger().Debugf("user specified inputFormat '%s'", inputFormat) - } +func configureDecoder(evaluateTogether bool) (yqlib.Decoder, error) { yqlibInputFormat, err := yqlib.InputFormatFromString(inputFormat) if err != nil { return nil, err diff --git a/examples/mike.xml b/examples/mike.xml index cdc6a9df..b582fff1 100644 --- a/examples/mike.xml +++ b/examples/mike.xml @@ -1,5 +1 @@ -date: "2022-11-25" -raw: - id: 1 - XML: text_outside_1text_outside_2text_outside_3 - time: 09:19:00 \ No newline at end of file +3 \ No newline at end of file diff --git a/pkg/yqlib/decoder.go b/pkg/yqlib/decoder.go index c06a5a72..9fba83d3 100644 --- a/pkg/yqlib/decoder.go +++ b/pkg/yqlib/decoder.go @@ -39,21 +39,22 @@ func InputFormatFromString(format string) (InputFormat, error) { case "tsv", "t": return TSVObjectInputFormat, nil default: - return 0, fmt.Errorf("unknown format '%v' please use [yaml|xml|props]", format) + return 0, fmt.Errorf("unknown format '%v' please use [yaml|json|props|csv|tsv|xml]", format) } } -func InputFormatFromFilename(filename string, defaultFormat string) string { +func FormatFromFilename(filename string) string { + if filename != "" { - GetLogger().Debugf("checking filename '%s' for inputFormat", filename) + GetLogger().Debugf("checking file extension '%s' for auto format detection", filename) nPos := strings.LastIndex(filename, ".") if nPos > -1 { - inputFormat := filename[nPos+1:] - GetLogger().Debugf("detected inputFormat '%s'", inputFormat) - return inputFormat + format := filename[nPos+1:] + GetLogger().Debugf("detected format '%s'", format) + return format } } - GetLogger().Debugf("using default inputFormat '%s'", defaultFormat) - return defaultFormat + GetLogger().Debugf("using default inputFormat 'yaml'") + return "yaml" } diff --git a/pkg/yqlib/operator_filter.go b/pkg/yqlib/operator_filter.go index 451b0beb..8cf28303 100644 --- a/pkg/yqlib/operator_filter.go +++ b/pkg/yqlib/operator_filter.go @@ -30,4 +30,3 @@ func filterOperator(d *dataTreeNavigator, context Context, expressionNode *Expre } return context.ChildContext(results), nil } - diff --git a/pkg/yqlib/operator_filter_test.go b/pkg/yqlib/operator_filter_test.go index 05a68161..fc050796 100644 --- a/pkg/yqlib/operator_filter_test.go +++ b/pkg/yqlib/operator_filter_test.go @@ -7,22 +7,22 @@ import ( var filterOperatorScenarios = []expressionScenario{ { description: "Filter array", - document: `[1,2,3]`, - expression: `filter(. < 3)`, + document: `[1,2,3]`, + expression: `filter(. < 3)`, expected: []string{ "D0, P[], (!!seq)::[1, 2]\n", }, }, { - skipDoc: true, - document: `[1,2,3]`, - expression: `filter(. > 1)`, + skipDoc: true, + document: `[1,2,3]`, + expression: `filter(. > 1)`, expected: []string{ "D0, P[], (!!seq)::[2, 3]\n", }, }, { - skipDoc: true, + skipDoc: true, description: "Filter array to empty", document: `[1,2,3]`, expression: `filter(. > 4)`, @@ -31,7 +31,7 @@ var filterOperatorScenarios = []expressionScenario{ }, }, { - skipDoc: true, + skipDoc: true, description: "Filter empty array", document: `[]`, expression: `filter(. > 1)`, diff --git a/pkg/yqlib/printer.go b/pkg/yqlib/printer.go index 802793a9..aca370e8 100644 --- a/pkg/yqlib/printer.go +++ b/pkg/yqlib/printer.go @@ -33,11 +33,11 @@ const ( func OutputFormatFromString(format string) (PrinterOutputFormat, error) { switch format { - case "yaml", "y": + case "yaml", "y", "yml": return YamlOutputFormat, nil case "json", "j": return JSONOutputFormat, nil - case "props", "p": + case "props", "p", "properties": return PropsOutputFormat, nil case "csv", "c": return CSVOutputFormat, nil