Skip to content

Commit

Permalink
Refactoring JSON encoder prefs
Browse files Browse the repository at this point in the history
  • Loading branch information
mikefarah committed Feb 24, 2024
1 parent 7a01e21 commit 55f6a3a
Show file tree
Hide file tree
Showing 9 changed files with 76 additions and 21 deletions.
5 changes: 4 additions & 1 deletion cmd/utils.go
Original file line number Diff line number Diff line change
Expand Up @@ -180,17 +180,20 @@ func configureEncoder() (yqlib.Encoder, error) {
func createEncoder(format *yqlib.PrinterOutputFormat) (yqlib.Encoder, error) {
yqlib.ConfiguredXMLPreferences.Indent = indent
yqlib.ConfiguredYamlPreferences.Indent = indent
yqlib.ConfiguredJsonPreferences.Indent = indent

yqlib.ConfiguredYamlPreferences.UnwrapScalar = unwrapScalar
yqlib.ConfiguredPropertiesPreferences.UnwrapScalar = unwrapScalar
yqlib.ConfiguredJsonPreferences.UnwrapScalar = unwrapScalar

yqlib.ConfiguredYamlPreferences.ColorsEnabled = colorsEnabled
yqlib.ConfiguredJsonPreferences.ColorsEnabled = colorsEnabled

yqlib.ConfiguredYamlPreferences.PrintDocSeparators = !noDocSeparators

switch format {
case yqlib.JSONOutputFormat:
return yqlib.NewJSONEncoder(indent, colorsEnabled, unwrapScalar), nil
return yqlib.NewJSONEncoder(yqlib.ConfiguredJsonPreferences), nil
case yqlib.PropsOutputFormat:
return yqlib.NewPropertiesEncoder(yqlib.ConfiguredPropertiesPreferences), nil
case yqlib.CSVOutputFormat:
Expand Down
15 changes: 7 additions & 8 deletions pkg/yqlib/encoder_json.go
Original file line number Diff line number Diff line change
Expand Up @@ -10,19 +10,18 @@ import (
)

type jsonEncoder struct {
prefs JsonPreferences
indentString string
colorise bool
UnwrapScalar bool
}

func NewJSONEncoder(indent int, colorise bool, unwrapScalar bool) Encoder {
func NewJSONEncoder(prefs JsonPreferences) Encoder {
var indentString = ""

for index := 0; index < indent; index++ {
for index := 0; index < prefs.Indent; index++ {
indentString = indentString + " "
}

return &jsonEncoder{indentString, colorise, unwrapScalar}
return &jsonEncoder{prefs, indentString}
}

func (je *jsonEncoder) CanHandleAliases() bool {
Expand All @@ -41,13 +40,13 @@ func (je *jsonEncoder) Encode(writer io.Writer, node *CandidateNode) error {
log.Debugf("I need to encode %v", NodeToString(node))
log.Debugf("kids %v", len(node.Content))

if node.Kind == ScalarNode && je.UnwrapScalar {
if node.Kind == ScalarNode && je.prefs.UnwrapScalar {
return writeString(writer, node.Value+"\n")
}

destination := writer
tempBuffer := bytes.NewBuffer(nil)
if je.colorise {
if je.prefs.ColorsEnabled {
destination = tempBuffer
}

Expand All @@ -59,7 +58,7 @@ func (je *jsonEncoder) Encode(writer io.Writer, node *CandidateNode) error {
if err != nil {
return err
}
if je.colorise {
if je.prefs.ColorsEnabled {
return colorizeAndPrint(tempBuffer.Bytes(), writer)
}
return nil
Expand Down
5 changes: 4 additions & 1 deletion pkg/yqlib/encoder_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,10 @@ func yamlToJSON(t *testing.T, sampleYaml string, indent int) string {
var output bytes.Buffer
writer := bufio.NewWriter(&output)

var jsonEncoder = NewJSONEncoder(indent, false, false)
prefs := ConfiguredJsonPreferences.Copy()
prefs.Indent = indent
prefs.UnwrapScalar = false
var jsonEncoder = NewJSONEncoder(prefs)
inputs, err := readDocuments(strings.NewReader(sampleYaml), "sample.yml", 0, NewYamlDecoder(ConfiguredYamlPreferences))
if err != nil {
panic(err)
Expand Down
2 changes: 1 addition & 1 deletion pkg/yqlib/formatting_expressions_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -71,7 +71,7 @@ func documentExpressionScenario(_ *testing.T, w *bufio.Writer, i interface{}) {
encoder := NewYamlEncoder(ConfiguredYamlPreferences)

if s.scenarioType == "shebang-json" {
encoder = NewJSONEncoder(2, false, false)
encoder = NewJSONEncoder(ConfiguredJsonPreferences)
}

writeOrPanic(w, fmt.Sprintf("```yaml\n%v```\n\n", mustProcessFormatScenario(s, NewYamlDecoder(ConfiguredYamlPreferences), encoder)))
Expand Down
25 changes: 25 additions & 0 deletions pkg/yqlib/json.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@
package yqlib

type JsonPreferences struct {
Indent int
ColorsEnabled bool
UnwrapScalar bool
}

func NewDefaultJsonPreferences() JsonPreferences {
return JsonPreferences{
Indent: 2,
ColorsEnabled: true,
UnwrapScalar: true,
}
}

func (p *JsonPreferences) Copy() JsonPreferences {
return JsonPreferences{
Indent: p.Indent,
ColorsEnabled: p.ColorsEnabled,
UnwrapScalar: p.UnwrapScalar,
}
}

var ConfiguredJsonPreferences = NewDefaultJsonPreferences()
30 changes: 23 additions & 7 deletions pkg/yqlib/json_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -85,27 +85,31 @@ var jsonScenarios = []formatScenario{
skipDoc: true,
input: "[]",
scenarioType: "roundtrip-ndjson",
indent: 0,
expected: "[]\n",
},
{
description: "array has scalar",
skipDoc: true,
input: "[3]",
scenarioType: "roundtrip-ndjson",
indent: 0,
expected: "[3]\n",
},
{
description: "array has object",
skipDoc: true,
input: `[{"x": 3}]`,
scenarioType: "roundtrip-ndjson",
indent: 0,
expected: "[{\"x\":3}]\n",
},
{
description: "array null",
skipDoc: true,
input: "[null]",
scenarioType: "roundtrip-ndjson",
indent: 0,
expected: "[null]\n",
},
{
Expand All @@ -114,6 +118,7 @@ var jsonScenarios = []formatScenario{
input: "[{}]",
expression: `[.. | type]`,
scenarioType: "roundtrip-ndjson",
indent: 0,
expected: "[\"!!seq\",\"!!map\"]\n",
},
{
Expand Down Expand Up @@ -220,6 +225,7 @@ var jsonScenarios = []formatScenario{
input: sampleNdJson,
expected: expectedRoundTripSampleNdJson,
scenarioType: "roundtrip-ndjson",
indent: 0,
},
{
description: "Roundtrip multi-document JSON",
Expand Down Expand Up @@ -322,8 +328,11 @@ func documentRoundtripNdJsonScenario(w *bufio.Writer, s formatScenario, indent i
}

writeOrPanic(w, "will output\n")
prefs := ConfiguredJsonPreferences.Copy()
prefs.Indent = indent
prefs.UnwrapScalar = false

writeOrPanic(w, fmt.Sprintf("```yaml\n%v```\n\n", mustProcessFormatScenario(s, NewJSONDecoder(), NewJSONEncoder(indent, false, false))))
writeOrPanic(w, fmt.Sprintf("```yaml\n%v```\n\n", mustProcessFormatScenario(s, NewJSONDecoder(), NewJSONEncoder(prefs))))
}

func documentDecodeNdJsonScenario(w *bufio.Writer, s formatScenario) {
Expand Down Expand Up @@ -377,19 +386,23 @@ func decodeJSON(t *testing.T, jsonString string) *CandidateNode {
}

func testJSONScenario(t *testing.T, s formatScenario) {
prefs := ConfiguredJsonPreferences.Copy()
prefs.Indent = s.indent
prefs.UnwrapScalar = false
switch s.scenarioType {
case "encode":
test.AssertResultWithContext(t, s.expected, mustProcessFormatScenario(s, NewYamlDecoder(ConfiguredYamlPreferences), NewJSONEncoder(s.indent, false, false)), s.description)
test.AssertResultWithContext(t, s.expected, mustProcessFormatScenario(s, NewYamlDecoder(ConfiguredYamlPreferences), NewJSONEncoder(prefs)), s.description)
case "decode":
test.AssertResultWithContext(t, s.expected, mustProcessFormatScenario(s, NewJSONDecoder(), NewJSONEncoder(s.indent, false, false)), s.description)
test.AssertResultWithContext(t, s.expected, mustProcessFormatScenario(s, NewJSONDecoder(), NewJSONEncoder(prefs)), s.description)
case "decode-ndjson":
test.AssertResultWithContext(t, s.expected, mustProcessFormatScenario(s, NewJSONDecoder(), NewYamlEncoder(ConfiguredYamlPreferences)), s.description)
case "roundtrip-ndjson":
test.AssertResultWithContext(t, s.expected, mustProcessFormatScenario(s, NewJSONDecoder(), NewJSONEncoder(0, false, false)), s.description)
test.AssertResultWithContext(t, s.expected, mustProcessFormatScenario(s, NewJSONDecoder(), NewJSONEncoder(prefs)), s.description)
case "roundtrip-multi":
test.AssertResultWithContext(t, s.expected, mustProcessFormatScenario(s, NewJSONDecoder(), NewJSONEncoder(2, false, false)), s.description)
prefs.Indent = 2
test.AssertResultWithContext(t, s.expected, mustProcessFormatScenario(s, NewJSONDecoder(), NewJSONEncoder(prefs)), s.description)
case "decode-error":
result, err := processFormatScenario(s, NewJSONDecoder(), NewJSONEncoder(2, false, false))
result, err := processFormatScenario(s, NewJSONDecoder(), NewJSONEncoder(prefs))
if err == nil {
t.Errorf("Expected error '%v' but it worked: %v", s.expectedError, result)
} else {
Expand Down Expand Up @@ -475,8 +488,11 @@ func documentJSONEncodeScenario(w *bufio.Writer, s formatScenario) {
writeOrPanic(w, fmt.Sprintf("```bash\nyq -o=json -I=%v '%v' sample.yml\n```\n", s.indent, expression))
}
writeOrPanic(w, "will output\n")
prefs := ConfiguredJsonPreferences.Copy()
prefs.Indent = s.indent
prefs.UnwrapScalar = false

writeOrPanic(w, fmt.Sprintf("```json\n%v```\n\n", mustProcessFormatScenario(s, NewYamlDecoder(ConfiguredYamlPreferences), NewJSONEncoder(s.indent, false, false))))
writeOrPanic(w, fmt.Sprintf("```json\n%v```\n\n", mustProcessFormatScenario(s, NewYamlDecoder(ConfiguredYamlPreferences), NewJSONEncoder(prefs))))
}

func TestJSONScenarios(t *testing.T) {
Expand Down
6 changes: 5 additions & 1 deletion pkg/yqlib/operator_encoder_decoder.go
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,11 @@ func configureEncoder(format *PrinterOutputFormat, indent int) Encoder {

switch format {
case JSONOutputFormat:
return NewJSONEncoder(indent, false, false)
prefs := ConfiguredJsonPreferences.Copy()
prefs.Indent = indent
prefs.ColorsEnabled = false
prefs.UnwrapScalar = false
return NewJSONEncoder(prefs)
case PropsOutputFormat:
return NewPropertiesEncoder(ConfiguredPropertiesPreferences)
case CSVOutputFormat:
Expand Down
1 change: 1 addition & 0 deletions pkg/yqlib/operators_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -34,6 +34,7 @@ type expressionScenario struct {
func TestMain(m *testing.M) {
logging.SetLevel(logging.ERROR, "")
ConfiguredYamlPreferences.ColorsEnabled = false
ConfiguredJsonPreferences.ColorsEnabled = false
Now = func() time.Time {
return time.Date(2021, time.May, 19, 1, 2, 3, 4, time.UTC)
}
Expand Down
8 changes: 6 additions & 2 deletions pkg/yqlib/printer_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -314,7 +314,9 @@ func TestPrinterMultipleDocsJson(t *testing.T) {
var writer = bufio.NewWriter(&output)
// note printDocSeparators is true, it should still not print document separators
// when outputting JSON.
encoder := NewJSONEncoder(0, false, false)
prefs := ConfiguredJsonPreferences.Copy()
prefs.Indent = 0
encoder := NewJSONEncoder(prefs)
if encoder == nil {
t.Skipf("no support for %s output format", "json")
}
Expand Down Expand Up @@ -366,7 +368,9 @@ func TestPrinterNulSeparatorWithJson(t *testing.T) {
var writer = bufio.NewWriter(&output)
// note printDocSeparators is true, it should still not print document separators
// when outputting JSON.
encoder := NewJSONEncoder(0, false, false)
prefs := ConfiguredJsonPreferences.Copy()
prefs.Indent = 0
encoder := NewJSONEncoder(prefs)
if encoder == nil {
t.Skipf("no support for %s output format", "json")
}
Expand Down

0 comments on commit 55f6a3a

Please sign in to comment.