From a82e10e43955f5ffc8dc49a42dd125e817e39129 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Anders=20F=20Bj=C3=B6rklund?= Date: Tue, 14 Feb 2023 16:39:28 +0100 Subject: [PATCH] Allow build without json and xml support --- cmd/utils.go | 6 +++ pkg/yqlib/decoder_json.go | 2 + pkg/yqlib/decoder_xml.go | 2 + pkg/yqlib/encoder_json.go | 2 + pkg/yqlib/encoder_test.go | 2 + pkg/yqlib/encoder_xml.go | 2 + pkg/yqlib/json_test.go | 2 + pkg/yqlib/no_json.go | 11 ++++++ pkg/yqlib/no_xml.go | 11 ++++++ pkg/yqlib/operator_encoder_decoder.go | 7 ++++ pkg/yqlib/operator_encoder_decoder_test.go | 45 +++++++++++++--------- pkg/yqlib/operator_load.go | 3 ++ pkg/yqlib/operator_load_test.go | 7 ++-- pkg/yqlib/operators_test.go | 18 +++++++++ pkg/yqlib/printer_test.go | 3 ++ pkg/yqlib/xml_test.go | 2 + 16 files changed, 104 insertions(+), 21 deletions(-) create mode 100644 pkg/yqlib/no_json.go create mode 100644 pkg/yqlib/no_xml.go diff --git a/cmd/utils.go b/cmd/utils.go index 3b5e79f7..671dd86b 100644 --- a/cmd/utils.go +++ b/cmd/utils.go @@ -62,6 +62,9 @@ func configureDecoder(evaluateTogether bool) (yqlib.Decoder, error) { return nil, err } yqlibDecoder, err := createDecoder(yqlibInputFormat, evaluateTogether) + if yqlibDecoder == nil { + return nil, fmt.Errorf("no support for %s input format", inputFormat) + } return yqlibDecoder, err } @@ -108,6 +111,9 @@ func configureEncoder() (yqlib.Encoder, error) { return nil, err } yqlibEncoder, err := createEncoder(yqlibOutputFormat) + if yqlibEncoder == nil { + return nil, fmt.Errorf("no support for %s output format", outputFormat) + } return yqlibEncoder, err } diff --git a/pkg/yqlib/decoder_json.go b/pkg/yqlib/decoder_json.go index a8e1e605..35da6467 100644 --- a/pkg/yqlib/decoder_json.go +++ b/pkg/yqlib/decoder_json.go @@ -1,3 +1,5 @@ +//go:build !yq_nojson + package yqlib import ( diff --git a/pkg/yqlib/decoder_xml.go b/pkg/yqlib/decoder_xml.go index ac70e403..bfb18e12 100644 --- a/pkg/yqlib/decoder_xml.go +++ b/pkg/yqlib/decoder_xml.go @@ -1,3 +1,5 @@ +//go:build !yq_noxml + package yqlib import ( diff --git a/pkg/yqlib/encoder_json.go b/pkg/yqlib/encoder_json.go index 6039578f..53c6bd06 100644 --- a/pkg/yqlib/encoder_json.go +++ b/pkg/yqlib/encoder_json.go @@ -1,3 +1,5 @@ +//go:build !yq_nojson + package yqlib import ( diff --git a/pkg/yqlib/encoder_test.go b/pkg/yqlib/encoder_test.go index a17c51a9..cb384562 100644 --- a/pkg/yqlib/encoder_test.go +++ b/pkg/yqlib/encoder_test.go @@ -1,3 +1,5 @@ +//go:build !yq_nojson + package yqlib import ( diff --git a/pkg/yqlib/encoder_xml.go b/pkg/yqlib/encoder_xml.go index 1d2e7798..d60ede8f 100644 --- a/pkg/yqlib/encoder_xml.go +++ b/pkg/yqlib/encoder_xml.go @@ -1,3 +1,5 @@ +//go:build !yq_noxml + package yqlib import ( diff --git a/pkg/yqlib/json_test.go b/pkg/yqlib/json_test.go index ad1b6bb8..b2eddb58 100644 --- a/pkg/yqlib/json_test.go +++ b/pkg/yqlib/json_test.go @@ -1,3 +1,5 @@ +//go:build !yq_nojson + package yqlib import ( diff --git a/pkg/yqlib/no_json.go b/pkg/yqlib/no_json.go new file mode 100644 index 00000000..ae9d531a --- /dev/null +++ b/pkg/yqlib/no_json.go @@ -0,0 +1,11 @@ +//go:build yq_nojson + +package yqlib + +func NewJSONDecoder() Decoder { + return nil +} + +func NewJSONEncoder(indent int, colorise bool, unwrapScalar bool) Encoder { + return nil +} diff --git a/pkg/yqlib/no_xml.go b/pkg/yqlib/no_xml.go new file mode 100644 index 00000000..d3f96bb6 --- /dev/null +++ b/pkg/yqlib/no_xml.go @@ -0,0 +1,11 @@ +//go:build yq_noxml + +package yqlib + +func NewXMLDecoder(prefs XmlPreferences) Decoder { + return nil +} + +func NewXMLEncoder(indent int, prefs XmlPreferences) Encoder { + return nil +} diff --git a/pkg/yqlib/operator_encoder_decoder.go b/pkg/yqlib/operator_encoder_decoder.go index 718ab59b..1c9582d1 100644 --- a/pkg/yqlib/operator_encoder_decoder.go +++ b/pkg/yqlib/operator_encoder_decoder.go @@ -4,6 +4,7 @@ import ( "bufio" "bytes" "container/list" + "errors" "regexp" "strings" @@ -39,6 +40,9 @@ func encodeToString(candidate *CandidateNode, prefs encoderPreferences) (string, log.Debug("printing with indent: %v", prefs.indent) encoder := configureEncoder(prefs.format, prefs.indent) + if encoder == nil { + return "", errors.New("no support for output format") + } printer := NewPrinter(encoder, NewSinglePrinterWriter(bufio.NewWriter(&output))) err := printer.PrintResults(candidate.AsList()) @@ -127,6 +131,9 @@ func decodeOperator(d *dataTreeNavigator, context Context, expressionNode *Expre preferences := expressionNode.Operation.Preferences.(decoderPreferences) decoder := createDecoder(preferences.format) + if decoder == nil { + return Context{}, errors.New("no support for input format") + } var results = list.New() for el := context.MatchingNodes.Front(); el != nil; el = el.Next() { diff --git a/pkg/yqlib/operator_encoder_decoder_test.go b/pkg/yqlib/operator_encoder_decoder_test.go index 13448adf..00441f73 100644 --- a/pkg/yqlib/operator_encoder_decoder_test.go +++ b/pkg/yqlib/operator_encoder_decoder_test.go @@ -8,15 +8,17 @@ var prefix = "D0, P[], (doc)::a:\n cool:\n bob: dylan\n" var encoderDecoderOperatorScenarios = []expressionScenario{ { - description: "Encode value as json string", - document: `{a: {cool: "thing"}}`, - expression: `.b = (.a | to_json)`, + requiresFormat: "json", + description: "Encode value as json string", + document: `{a: {cool: "thing"}}`, + expression: `.b = (.a | to_json)`, expected: []string{ `D0, P[], (doc)::{a: {cool: "thing"}, b: "{\n \"cool\": \"thing\"\n}\n"} `, }, }, { + requiresFormat: "json", description: "Encode value as json string, on one line", subdescription: "Pass in a 0 indent to print json on a single line.", document: `{a: {cool: "thing"}}`, @@ -27,6 +29,7 @@ var encoderDecoderOperatorScenarios = []expressionScenario{ }, }, { + requiresFormat: "json", description: "Encode value as json string, on one line shorthand", subdescription: "Pass in a 0 indent to print json on a single line.", document: `{a: {cool: "thing"}}`, @@ -37,6 +40,7 @@ var encoderDecoderOperatorScenarios = []expressionScenario{ }, }, { + requiresFormat: "json", description: "Decode a json encoded string", subdescription: "Keep in mind JSON is a subset of YAML. If you want idiomatic yaml, pipe through the style operator to clear out the JSON styling.", document: `a: '{"cool":"thing"}'`, @@ -193,33 +197,37 @@ var encoderDecoderOperatorScenarios = []expressionScenario{ }, }, { - description: "Encode value as xml string", - document: `{a: {cool: {foo: "bar", +@id: hi}}}`, - expression: `.a | to_xml`, + requiresFormat: "xml", + description: "Encode value as xml string", + document: `{a: {cool: {foo: "bar", +@id: hi}}}`, + expression: `.a | to_xml`, expected: []string{ "D0, P[a], (!!str)::\n bar\n\n\n", }, }, { - description: "Encode value as xml string on a single line", - document: `{a: {cool: {foo: "bar", +@id: hi}}}`, - expression: `.a | @xml`, + requiresFormat: "xml", + description: "Encode value as xml string on a single line", + document: `{a: {cool: {foo: "bar", +@id: hi}}}`, + expression: `.a | @xml`, expected: []string{ "D0, P[a], (!!str)::bar\n\n", }, }, { - description: "Encode value as xml string with custom indentation", - document: `{a: {cool: {foo: "bar", +@id: hi}}}`, - expression: `{"cat": .a | to_xml(1)}`, + requiresFormat: "xml", + description: "Encode value as xml string with custom indentation", + document: `{a: {cool: {foo: "bar", +@id: hi}}}`, + expression: `{"cat": .a | to_xml(1)}`, expected: []string{ "D0, P[], (!!map)::cat: |\n \n bar\n \n", }, }, { - description: "Decode a xml encoded string", - document: `a: "bar"`, - expression: `.b = (.a | from_xml)`, + requiresFormat: "xml", + description: "Decode a xml encoded string", + document: `a: "bar"`, + expression: `.b = (.a | from_xml)`, expected: []string{ "D0, P[], (doc)::a: \"bar\"\nb:\n foo: bar\n", }, @@ -303,9 +311,10 @@ var encoderDecoderOperatorScenarios = []expressionScenario{ }, }, { - description: "empty xml decode", - skipDoc: true, - expression: `"" | @xmld`, + requiresFormat: "xml", + description: "empty xml decode", + skipDoc: true, + expression: `"" | @xmld`, expected: []string{ "D0, P[], (!!null)::\n", }, diff --git a/pkg/yqlib/operator_load.go b/pkg/yqlib/operator_load.go index 7d083d5b..678854f6 100644 --- a/pkg/yqlib/operator_load.go +++ b/pkg/yqlib/operator_load.go @@ -34,6 +34,9 @@ func loadString(filename string) (*CandidateNode, error) { } func loadYaml(filename string, decoder Decoder) (*CandidateNode, error) { + if decoder == nil { + return nil, fmt.Errorf("could not load %s", filename) + } file, err := os.Open(filename) // #nosec if err != nil { diff --git a/pkg/yqlib/operator_load_test.go b/pkg/yqlib/operator_load_test.go index b27e8f70..5bb30321 100644 --- a/pkg/yqlib/operator_load_test.go +++ b/pkg/yqlib/operator_load_test.go @@ -74,9 +74,10 @@ var loadScenarios = []expressionScenario{ }, }, { - description: "Load from XML", - document: "cool: things", - expression: `.more_stuff = load_xml("../../examples/small.xml")`, + requiresFormat: "xml", + description: "Load from XML", + document: "cool: things", + expression: `.more_stuff = load_xml("../../examples/small.xml")`, expected: []string{ "D0, P[], (doc)::cool: things\nmore_stuff:\n this: is some xml\n", }, diff --git a/pkg/yqlib/operators_test.go b/pkg/yqlib/operators_test.go index 79757895..c040cbed 100644 --- a/pkg/yqlib/operators_test.go +++ b/pkg/yqlib/operators_test.go @@ -28,6 +28,7 @@ type expressionScenario struct { skipDoc bool expectedError string dontFormatInputForDoc bool // dont format input doc for documentation generation + requiresFormat string } func TestMain(m *testing.M) { @@ -103,6 +104,23 @@ func testScenario(t *testing.T, s *expressionScenario) { return } + if s.requiresFormat != "" { + format := s.requiresFormat + inputFormat, err := InputFormatFromString(format) + if err != nil { + t.Error(err) + } + if decoder := createDecoder(inputFormat); decoder == nil { + t.Skipf("no support for %s input format", format) + } + outputFormat, err := OutputFormatFromString(format) + if err != nil { + t.Error(err) + } + if encoder := configureEncoder(outputFormat, 4); encoder == nil { + t.Skipf("no support for %s output format", format) + } + } if err != nil { t.Error(fmt.Errorf("%w: %v: %v", err, s.description, s.expression)) return diff --git a/pkg/yqlib/printer_test.go b/pkg/yqlib/printer_test.go index b913daca..f3be6401 100644 --- a/pkg/yqlib/printer_test.go +++ b/pkg/yqlib/printer_test.go @@ -315,6 +315,9 @@ func TestPrinterMultipleDocsJson(t *testing.T) { // note printDocSeparators is true, it should still not print document separators // when outputing JSON. encoder := NewJSONEncoder(0, false, false) + if encoder == nil { + t.Skipf("no support for %s output format", "json") + } printer := NewPrinter(encoder, NewSinglePrinterWriter(writer)) inputs, err := readDocuments(strings.NewReader(multiDocSample), "sample.yml", 0, NewYamlDecoder(ConfiguredYamlPreferences)) diff --git a/pkg/yqlib/xml_test.go b/pkg/yqlib/xml_test.go index 2e9badf4..ec9f5b67 100644 --- a/pkg/yqlib/xml_test.go +++ b/pkg/yqlib/xml_test.go @@ -1,3 +1,5 @@ +//go:build !yq_noxml + package yqlib import (