mirror of
https://github.com/mikefarah/yq.git
synced 2024-11-12 05:38:04 +00:00
Unwrap scalar now works for JSON encoding when explicitly set #1409
This commit is contained in:
parent
fae1dbf0be
commit
1d35134310
@ -48,6 +48,55 @@ EOM
|
|||||||
assertEquals "$expected" "$X"
|
assertEquals "$expected" "$X"
|
||||||
}
|
}
|
||||||
|
|
||||||
|
testOutputYamlRawDefault() {
|
||||||
|
cat >test.yml <<EOL
|
||||||
|
a: "cat"
|
||||||
|
EOL
|
||||||
|
|
||||||
|
X=$(./yq e '.a' test.yml)
|
||||||
|
assertEquals "cat" "$X"
|
||||||
|
|
||||||
|
X=$(./yq ea '.a' test.yml)
|
||||||
|
assertEquals "cat" "$X"
|
||||||
|
}
|
||||||
|
|
||||||
|
testOutputYamlRawOff() {
|
||||||
|
cat >test.yml <<EOL
|
||||||
|
a: "cat"
|
||||||
|
EOL
|
||||||
|
|
||||||
|
X=$(./yq e -r=false '.a' test.yml)
|
||||||
|
assertEquals "\"cat\"" "$X"
|
||||||
|
|
||||||
|
X=$(./yq ea -r=false '.a' test.yml)
|
||||||
|
assertEquals "\"cat\"" "$X"
|
||||||
|
}
|
||||||
|
|
||||||
|
testOutputJsonRaw() {
|
||||||
|
cat >test.yml <<EOL
|
||||||
|
a: cat
|
||||||
|
EOL
|
||||||
|
|
||||||
|
X=$(./yq e -r --output-format=json '.a' test.yml)
|
||||||
|
assertEquals "cat" "$X"
|
||||||
|
|
||||||
|
X=$(./yq ea -r --output-format=json '.a' test.yml)
|
||||||
|
assertEquals "cat" "$X"
|
||||||
|
}
|
||||||
|
|
||||||
|
testOutputJsonDefault() {
|
||||||
|
cat >test.yml <<EOL
|
||||||
|
a: cat
|
||||||
|
EOL
|
||||||
|
|
||||||
|
X=$(./yq e --output-format=json '.a' test.yml)
|
||||||
|
assertEquals "\"cat\"" "$X"
|
||||||
|
|
||||||
|
X=$(./yq ea --output-format=json '.a' test.yml)
|
||||||
|
assertEquals "\"cat\"" "$X"
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
testOutputJsonShort() {
|
testOutputJsonShort() {
|
||||||
cat >test.yml <<EOL
|
cat >test.yml <<EOL
|
||||||
a: {b: ["cat"]}
|
a: {b: ["cat"]}
|
||||||
@ -72,11 +121,11 @@ EOM
|
|||||||
|
|
||||||
testOutputProperties() {
|
testOutputProperties() {
|
||||||
cat >test.yml <<EOL
|
cat >test.yml <<EOL
|
||||||
a: {b: {c: ["cat"]}}
|
a: {b: {c: ["cat cat"]}}
|
||||||
EOL
|
EOL
|
||||||
|
|
||||||
read -r -d '' expected << EOM
|
read -r -d '' expected << EOM
|
||||||
a.b.c.0 = cat
|
a.b.c.0 = cat cat
|
||||||
EOM
|
EOM
|
||||||
|
|
||||||
X=$(./yq e --output-format=props test.yml)
|
X=$(./yq e --output-format=props test.yml)
|
||||||
@ -86,13 +135,30 @@ EOM
|
|||||||
assertEquals "$expected" "$X"
|
assertEquals "$expected" "$X"
|
||||||
}
|
}
|
||||||
|
|
||||||
testOutputPropertiesShort() {
|
testOutputPropertiesDontUnwrap() {
|
||||||
cat >test.yml <<EOL
|
cat >test.yml <<EOL
|
||||||
a: {b: {c: ["cat"]}}
|
a: {b: {c: ["cat cat"]}}
|
||||||
EOL
|
EOL
|
||||||
|
|
||||||
read -r -d '' expected << EOM
|
read -r -d '' expected << EOM
|
||||||
a.b.c.0 = cat
|
a.b.c.0 = "cat cat"
|
||||||
|
EOM
|
||||||
|
|
||||||
|
X=$(./yq e -r=false --output-format=props test.yml)
|
||||||
|
assertEquals "$expected" "$X"
|
||||||
|
|
||||||
|
X=$(./yq ea -r=false --output-format=props test.yml)
|
||||||
|
assertEquals "$expected" "$X"
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
testOutputPropertiesShort() {
|
||||||
|
cat >test.yml <<EOL
|
||||||
|
a: {b: {c: ["cat cat"]}}
|
||||||
|
EOL
|
||||||
|
|
||||||
|
read -r -d '' expected << EOM
|
||||||
|
a.b.c.0 = cat cat
|
||||||
EOM
|
EOM
|
||||||
|
|
||||||
X=$(./yq e -o=p test.yml)
|
X=$(./yq e -o=p test.yml)
|
||||||
|
@ -1,6 +1,53 @@
|
|||||||
package cmd
|
package cmd
|
||||||
|
|
||||||
var unwrapScalar = true
|
import (
|
||||||
|
"strconv"
|
||||||
|
|
||||||
|
"github.com/spf13/pflag"
|
||||||
|
)
|
||||||
|
|
||||||
|
type boolFlag interface {
|
||||||
|
pflag.Value
|
||||||
|
IsExplicitySet() bool
|
||||||
|
IsSet() bool
|
||||||
|
}
|
||||||
|
|
||||||
|
type unwrapScalarFlagStrc struct {
|
||||||
|
explicitySet bool
|
||||||
|
value bool
|
||||||
|
}
|
||||||
|
|
||||||
|
func newFlag() boolFlag {
|
||||||
|
return &unwrapScalarFlagStrc{value: true}
|
||||||
|
}
|
||||||
|
|
||||||
|
func (f *unwrapScalarFlagStrc) IsExplicitySet() bool {
|
||||||
|
return f.explicitySet
|
||||||
|
}
|
||||||
|
|
||||||
|
func (f *unwrapScalarFlagStrc) IsSet() bool {
|
||||||
|
return f.value
|
||||||
|
}
|
||||||
|
|
||||||
|
func (f *unwrapScalarFlagStrc) String() string {
|
||||||
|
return strconv.FormatBool(f.value)
|
||||||
|
}
|
||||||
|
|
||||||
|
func (f *unwrapScalarFlagStrc) Set(value string) error {
|
||||||
|
|
||||||
|
v, err := strconv.ParseBool(value)
|
||||||
|
f.value = v
|
||||||
|
f.explicitySet = true
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
|
func (*unwrapScalarFlagStrc) Type() string {
|
||||||
|
return "bool"
|
||||||
|
}
|
||||||
|
|
||||||
|
var unwrapScalarFlag = newFlag()
|
||||||
|
|
||||||
|
var unwrapScalar = false
|
||||||
|
|
||||||
var writeInplace = false
|
var writeInplace = false
|
||||||
var outputToJSON = false
|
var outputToJSON = false
|
||||||
|
12
cmd/root.go
12
cmd/root.go
@ -60,6 +60,14 @@ yq -P sample.json
|
|||||||
"`+` please set that value explicityly with --xml-attribute-prefix.")
|
"`+` please set that value explicityly with --xml-attribute-prefix.")
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if outputFormat == "y" || outputFormat == "yaml" ||
|
||||||
|
outputFormat == "p" || outputFormat == "props" {
|
||||||
|
unwrapScalar = true
|
||||||
|
}
|
||||||
|
if unwrapScalarFlag.IsExplicitySet() {
|
||||||
|
unwrapScalar = unwrapScalarFlag.IsSet()
|
||||||
|
}
|
||||||
|
|
||||||
//copy preference form global setting
|
//copy preference form global setting
|
||||||
yqlib.ConfiguredYamlPreferences.UnwrapScalar = unwrapScalar
|
yqlib.ConfiguredYamlPreferences.UnwrapScalar = unwrapScalar
|
||||||
|
|
||||||
@ -94,7 +102,9 @@ yq -P sample.json
|
|||||||
rootCmd.PersistentFlags().IntVarP(&indent, "indent", "I", 2, "sets indent level for output")
|
rootCmd.PersistentFlags().IntVarP(&indent, "indent", "I", 2, "sets indent level for output")
|
||||||
rootCmd.Flags().BoolVarP(&version, "version", "V", false, "Print version information and quit")
|
rootCmd.Flags().BoolVarP(&version, "version", "V", false, "Print version information and quit")
|
||||||
rootCmd.PersistentFlags().BoolVarP(&writeInplace, "inplace", "i", false, "update the file inplace of first file given.")
|
rootCmd.PersistentFlags().BoolVarP(&writeInplace, "inplace", "i", false, "update the file inplace of first file given.")
|
||||||
rootCmd.PersistentFlags().BoolVarP(&unwrapScalar, "unwrapScalar", "r", true, "unwrap scalar, print the value with no quotes, colors or comments")
|
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(&prettyPrint, "prettyPrint", "P", false, "pretty print, shorthand for '... style = \"\"'")
|
rootCmd.PersistentFlags().BoolVarP(&prettyPrint, "prettyPrint", "P", false, "pretty print, shorthand for '... style = \"\"'")
|
||||||
rootCmd.PersistentFlags().BoolVarP(&exitStatus, "exit-status", "e", false, "set exit status if there are no matches or null or false is returned")
|
rootCmd.PersistentFlags().BoolVarP(&exitStatus, "exit-status", "e", false, "set exit status if there are no matches or null or false is returned")
|
||||||
|
|
||||||
|
@ -98,7 +98,7 @@ func configurePrinterWriter(format yqlib.PrinterOutputFormat, out io.Writer) (yq
|
|||||||
func configureEncoder(format yqlib.PrinterOutputFormat) yqlib.Encoder {
|
func configureEncoder(format yqlib.PrinterOutputFormat) yqlib.Encoder {
|
||||||
switch format {
|
switch format {
|
||||||
case yqlib.JSONOutputFormat:
|
case yqlib.JSONOutputFormat:
|
||||||
return yqlib.NewJSONEncoder(indent, colorsEnabled)
|
return yqlib.NewJSONEncoder(indent, colorsEnabled, unwrapScalar)
|
||||||
case yqlib.PropsOutputFormat:
|
case yqlib.PropsOutputFormat:
|
||||||
return yqlib.NewPropertiesEncoder(unwrapScalar)
|
return yqlib.NewPropertiesEncoder(unwrapScalar)
|
||||||
case yqlib.CSVOutputFormat:
|
case yqlib.CSVOutputFormat:
|
||||||
|
2
go.mod
2
go.mod
@ -13,6 +13,7 @@ require (
|
|||||||
github.com/magiconair/properties v1.8.6
|
github.com/magiconair/properties v1.8.6
|
||||||
github.com/pkg/diff v0.0.0-20210226163009-20ebb0f2a09e
|
github.com/pkg/diff v0.0.0-20210226163009-20ebb0f2a09e
|
||||||
github.com/spf13/cobra v1.6.1
|
github.com/spf13/cobra v1.6.1
|
||||||
|
github.com/spf13/pflag v1.0.5
|
||||||
golang.org/x/net v0.0.0-20220708220712-1185a9018129
|
golang.org/x/net v0.0.0-20220708220712-1185a9018129
|
||||||
gopkg.in/op/go-logging.v1 v1.0.0-20160211212156-b2cb9fa56473
|
gopkg.in/op/go-logging.v1 v1.0.0-20160211212156-b2cb9fa56473
|
||||||
gopkg.in/yaml.v3 v3.0.1
|
gopkg.in/yaml.v3 v3.0.1
|
||||||
@ -22,7 +23,6 @@ require (
|
|||||||
github.com/inconshreveable/mousetrap v1.0.1 // indirect
|
github.com/inconshreveable/mousetrap v1.0.1 // indirect
|
||||||
github.com/mattn/go-colorable v0.1.12 // indirect
|
github.com/mattn/go-colorable v0.1.12 // indirect
|
||||||
github.com/mattn/go-isatty v0.0.14 // indirect
|
github.com/mattn/go-isatty v0.0.14 // indirect
|
||||||
github.com/spf13/pflag v1.0.5 // indirect
|
|
||||||
golang.org/x/sys v0.0.0-20220712014510-0a85c31ab51e // indirect
|
golang.org/x/sys v0.0.0-20220712014510-0a85c31ab51e // indirect
|
||||||
golang.org/x/text v0.3.7 // indirect
|
golang.org/x/text v0.3.7 // indirect
|
||||||
golang.org/x/xerrors v0.0.0-20220609144429-65e65417b02f // indirect
|
golang.org/x/xerrors v0.0.0-20220609144429-65e65417b02f // indirect
|
||||||
|
@ -11,6 +11,7 @@ import (
|
|||||||
type jsonEncoder struct {
|
type jsonEncoder struct {
|
||||||
indentString string
|
indentString string
|
||||||
colorise bool
|
colorise bool
|
||||||
|
UnwrapScalar bool
|
||||||
}
|
}
|
||||||
|
|
||||||
func mapKeysToStrings(node *yaml.Node) {
|
func mapKeysToStrings(node *yaml.Node) {
|
||||||
@ -28,14 +29,14 @@ func mapKeysToStrings(node *yaml.Node) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
func NewJSONEncoder(indent int, colorise bool) Encoder {
|
func NewJSONEncoder(indent int, colorise bool, unwrapScalar bool) Encoder {
|
||||||
var indentString = ""
|
var indentString = ""
|
||||||
|
|
||||||
for index := 0; index < indent; index++ {
|
for index := 0; index < indent; index++ {
|
||||||
indentString = indentString + " "
|
indentString = indentString + " "
|
||||||
}
|
}
|
||||||
|
|
||||||
return &jsonEncoder{indentString, colorise}
|
return &jsonEncoder{indentString, colorise, unwrapScalar}
|
||||||
}
|
}
|
||||||
|
|
||||||
func (je *jsonEncoder) CanHandleAliases() bool {
|
func (je *jsonEncoder) CanHandleAliases() bool {
|
||||||
@ -52,6 +53,10 @@ func (je *jsonEncoder) PrintLeadingContent(writer io.Writer, content string) err
|
|||||||
|
|
||||||
func (je *jsonEncoder) Encode(writer io.Writer, node *yaml.Node) error {
|
func (je *jsonEncoder) Encode(writer io.Writer, node *yaml.Node) error {
|
||||||
|
|
||||||
|
if node.Kind == yaml.ScalarNode && je.UnwrapScalar {
|
||||||
|
return writeString(writer, node.Value+"\n")
|
||||||
|
}
|
||||||
|
|
||||||
destination := writer
|
destination := writer
|
||||||
tempBuffer := bytes.NewBuffer(nil)
|
tempBuffer := bytes.NewBuffer(nil)
|
||||||
if je.colorise {
|
if je.colorise {
|
||||||
|
@ -13,7 +13,7 @@ func yamlToJSON(sampleYaml string, indent int) string {
|
|||||||
var output bytes.Buffer
|
var output bytes.Buffer
|
||||||
writer := bufio.NewWriter(&output)
|
writer := bufio.NewWriter(&output)
|
||||||
|
|
||||||
var jsonEncoder = NewJSONEncoder(indent, false)
|
var jsonEncoder = NewJSONEncoder(indent, false, false)
|
||||||
inputs, err := readDocuments(strings.NewReader(sampleYaml), "sample.yml", 0, NewYamlDecoder(ConfiguredYamlPreferences))
|
inputs, err := readDocuments(strings.NewReader(sampleYaml), "sample.yml", 0, NewYamlDecoder(ConfiguredYamlPreferences))
|
||||||
if err != nil {
|
if err != nil {
|
||||||
panic(err)
|
panic(err)
|
||||||
|
@ -237,7 +237,7 @@ func documentRoundtripNdJsonScenario(w *bufio.Writer, s formatScenario, indent i
|
|||||||
|
|
||||||
writeOrPanic(w, "will output\n")
|
writeOrPanic(w, "will output\n")
|
||||||
|
|
||||||
writeOrPanic(w, fmt.Sprintf("```yaml\n%v```\n\n", mustProcessFormatScenario(s, NewJSONDecoder(), NewJSONEncoder(indent, false))))
|
writeOrPanic(w, fmt.Sprintf("```yaml\n%v```\n\n", mustProcessFormatScenario(s, NewJSONDecoder(), NewJSONEncoder(indent, false, false))))
|
||||||
}
|
}
|
||||||
|
|
||||||
func documentDecodeNdJsonScenario(w *bufio.Writer, s formatScenario) {
|
func documentDecodeNdJsonScenario(w *bufio.Writer, s formatScenario) {
|
||||||
@ -293,16 +293,16 @@ func decodeJSON(t *testing.T, jsonString string) *CandidateNode {
|
|||||||
func testJSONScenario(t *testing.T, s formatScenario) {
|
func testJSONScenario(t *testing.T, s formatScenario) {
|
||||||
switch s.scenarioType {
|
switch s.scenarioType {
|
||||||
case "encode", "decode":
|
case "encode", "decode":
|
||||||
test.AssertResultWithContext(t, s.expected, mustProcessFormatScenario(s, NewYamlDecoder(ConfiguredYamlPreferences), NewJSONEncoder(s.indent, false)), s.description)
|
test.AssertResultWithContext(t, s.expected, mustProcessFormatScenario(s, NewYamlDecoder(ConfiguredYamlPreferences), NewJSONEncoder(s.indent, false, false)), s.description)
|
||||||
case "":
|
case "":
|
||||||
var actual = resultToString(t, decodeJSON(t, s.input))
|
var actual = resultToString(t, decodeJSON(t, s.input))
|
||||||
test.AssertResultWithContext(t, s.expected, actual, s.description)
|
test.AssertResultWithContext(t, s.expected, actual, s.description)
|
||||||
case "decode-ndjson":
|
case "decode-ndjson":
|
||||||
test.AssertResultWithContext(t, s.expected, mustProcessFormatScenario(s, NewJSONDecoder(), NewYamlEncoder(2, false, ConfiguredYamlPreferences)), s.description)
|
test.AssertResultWithContext(t, s.expected, mustProcessFormatScenario(s, NewJSONDecoder(), NewYamlEncoder(2, false, ConfiguredYamlPreferences)), s.description)
|
||||||
case "roundtrip-ndjson":
|
case "roundtrip-ndjson":
|
||||||
test.AssertResultWithContext(t, s.expected, mustProcessFormatScenario(s, NewJSONDecoder(), NewJSONEncoder(0, false)), s.description)
|
test.AssertResultWithContext(t, s.expected, mustProcessFormatScenario(s, NewJSONDecoder(), NewJSONEncoder(0, false, false)), s.description)
|
||||||
case "roundtrip-multi":
|
case "roundtrip-multi":
|
||||||
test.AssertResultWithContext(t, s.expected, mustProcessFormatScenario(s, NewJSONDecoder(), NewJSONEncoder(2, false)), s.description)
|
test.AssertResultWithContext(t, s.expected, mustProcessFormatScenario(s, NewJSONDecoder(), NewJSONEncoder(2, false, false)), s.description)
|
||||||
|
|
||||||
default:
|
default:
|
||||||
panic(fmt.Sprintf("unhandled scenario type %q", s.scenarioType))
|
panic(fmt.Sprintf("unhandled scenario type %q", s.scenarioType))
|
||||||
@ -385,7 +385,7 @@ func documentJSONEncodeScenario(w *bufio.Writer, s formatScenario) {
|
|||||||
}
|
}
|
||||||
writeOrPanic(w, "will output\n")
|
writeOrPanic(w, "will output\n")
|
||||||
|
|
||||||
writeOrPanic(w, fmt.Sprintf("```json\n%v```\n\n", mustProcessFormatScenario(s, NewYamlDecoder(ConfiguredYamlPreferences), NewJSONEncoder(s.indent, false))))
|
writeOrPanic(w, fmt.Sprintf("```json\n%v```\n\n", mustProcessFormatScenario(s, NewYamlDecoder(ConfiguredYamlPreferences), NewJSONEncoder(s.indent, false, false))))
|
||||||
}
|
}
|
||||||
|
|
||||||
func TestJSONScenarios(t *testing.T) {
|
func TestJSONScenarios(t *testing.T) {
|
||||||
|
@ -13,7 +13,7 @@ import (
|
|||||||
func configureEncoder(format PrinterOutputFormat, indent int) Encoder {
|
func configureEncoder(format PrinterOutputFormat, indent int) Encoder {
|
||||||
switch format {
|
switch format {
|
||||||
case JSONOutputFormat:
|
case JSONOutputFormat:
|
||||||
return NewJSONEncoder(indent, false)
|
return NewJSONEncoder(indent, false, false)
|
||||||
case PropsOutputFormat:
|
case PropsOutputFormat:
|
||||||
return NewPropertiesEncoder(true)
|
return NewPropertiesEncoder(true)
|
||||||
case CSVOutputFormat:
|
case CSVOutputFormat:
|
||||||
|
@ -314,7 +314,7 @@ func TestPrinterMultipleDocsJson(t *testing.T) {
|
|||||||
var writer = bufio.NewWriter(&output)
|
var writer = bufio.NewWriter(&output)
|
||||||
// note printDocSeparators is true, it should still not print document separators
|
// note printDocSeparators is true, it should still not print document separators
|
||||||
// when outputing JSON.
|
// when outputing JSON.
|
||||||
printer := NewPrinter(NewJSONEncoder(0, false), NewSinglePrinterWriter(writer))
|
printer := NewPrinter(NewJSONEncoder(0, false, false), NewSinglePrinterWriter(writer))
|
||||||
|
|
||||||
inputs, err := readDocuments(strings.NewReader(multiDocSample), "sample.yml", 0, NewYamlDecoder(ConfiguredYamlPreferences))
|
inputs, err := readDocuments(strings.NewReader(multiDocSample), "sample.yml", 0, NewYamlDecoder(ConfiguredYamlPreferences))
|
||||||
if err != nil {
|
if err != nil {
|
||||||
|
Loading…
Reference in New Issue
Block a user