Skip to content

Commit

Permalink
Added scalar output for TOML (#1617)
Browse files Browse the repository at this point in the history
  • Loading branch information
mikefarah committed Apr 3, 2023
1 parent a389bb6 commit eba0752
Show file tree
Hide file tree
Showing 5 changed files with 88 additions and 3 deletions.
5 changes: 2 additions & 3 deletions cmd/utils.go
Expand Up @@ -75,9 +75,6 @@ func initCommand(cmd *cobra.Command, args []string) (string, []string, error) {
}
} else if isAutomaticOutputFormat() {
// automatic input worked, we can do it for output too unless specified
if inputFormat == "toml" {
return "", nil, fmt.Errorf("toml is not yet supported as an output format. Please specify another output format using the [--output-format/-o] flag")
}
if inputFormat == "json" {
yqlib.GetLogger().Warning("JSON file output is now JSON by default (instead of yaml). Use '-oy' or '--output-format=yaml' for yaml output")
}
Expand Down Expand Up @@ -196,6 +193,8 @@ func createEncoder(format yqlib.PrinterOutputFormat) (yqlib.Encoder, error) {
return yqlib.NewYamlEncoder(indent, colorsEnabled, yqlib.ConfiguredYamlPreferences), nil
case yqlib.XMLOutputFormat:
return yqlib.NewXMLEncoder(indent, yqlib.ConfiguredXMLPreferences), nil
case yqlib.TomlOutputFormat:
return yqlib.NewTomlEncoder(), nil
}
return nil, fmt.Errorf("invalid encoder: %v", format)
}
Expand Down
16 changes: 16 additions & 0 deletions pkg/yqlib/doc/usage/toml.md
Expand Up @@ -38,6 +38,22 @@ person:
address: 12 cat st
```

## Encode: Scalar
Given a sample.toml file of:
```toml
person.name = "hello"
person.address = "12 cat st"

```
then
```bash
yq '.person.name' sample.toml
```
will output
```yaml
hello
```

## Parse: inline table
Given a sample.toml file of:
```toml
Expand Down
34 changes: 34 additions & 0 deletions pkg/yqlib/encoder_toml.go
@@ -0,0 +1,34 @@
package yqlib

import (
"fmt"
"io"

yaml "gopkg.in/yaml.v3"
)

type tomlEncoder struct {
}

func NewTomlEncoder() Encoder {
return &tomlEncoder{}
}

func (te *tomlEncoder) Encode(writer io.Writer, node *yaml.Node) error {
if node.Kind == yaml.ScalarNode {
return writeString(writer, node.Value+"\n")
}
return fmt.Errorf("only scalars (e.g. strings, numbers, booleans) are supported for TOML output at the moment. Please use yaml output format (-oy) until the encoder has been fully implemented")
}

func (te *tomlEncoder) PrintDocumentSeparator(writer io.Writer) error {
return nil
}

func (te *tomlEncoder) PrintLeadingContent(writer io.Writer, content string) error {
return nil
}

func (te *tomlEncoder) CanHandleAliases() bool {
return false
}
3 changes: 3 additions & 0 deletions pkg/yqlib/printer.go
Expand Up @@ -31,6 +31,7 @@ const (
Base64OutputFormat
UriOutputFormat
ShOutputFormat
TomlOutputFormat
)

func OutputFormatFromString(format string) (PrinterOutputFormat, error) {
Expand All @@ -47,6 +48,8 @@ func OutputFormatFromString(format string) (PrinterOutputFormat, error) {
return TSVOutputFormat, nil
case "xml", "x":
return XMLOutputFormat, nil
case "toml":
return TomlOutputFormat, nil
default:
return 0, fmt.Errorf("unknown format '%v' please use [yaml|json|props|csv|tsv|xml]", format)
}
Expand Down
33 changes: 33 additions & 0 deletions pkg/yqlib/toml_test.go
Expand Up @@ -94,6 +94,13 @@ var tomlScenarios = []formatScenario{
expected: "person:\n name: hello\n address: 12 cat st\n",
scenarioType: "decode",
},
{
description: "Encode: Scalar",
input: "person.name = \"hello\"\nperson.address = \"12 cat st\"\n",
expression: ".person.name",
expected: "hello\n",
scenarioType: "roundtrip",
},
{
skipDoc: true,
input: `A.B = "hello"`,
Expand Down Expand Up @@ -188,6 +195,8 @@ func testTomlScenario(t *testing.T, s formatScenario) {
} else {
test.AssertResultComplexWithContext(t, s.expectedError, err.Error(), s.description)
}
case "roundtrip":
test.AssertResultWithContext(t, s.expected, mustProcessFormatScenario(s, NewTomlDecoder(), NewTomlEncoder()), s.description)
}
}

Expand All @@ -213,6 +222,28 @@ func documentTomlDecodeScenario(w *bufio.Writer, s formatScenario) {
writeOrPanic(w, fmt.Sprintf("```yaml\n%v```\n\n", mustProcessFormatScenario(s, NewTomlDecoder(), NewYamlEncoder(2, false, ConfiguredYamlPreferences))))
}

func documentTomlRoundtripScenario(w *bufio.Writer, s formatScenario) {
writeOrPanic(w, fmt.Sprintf("## %v\n", s.description))

if s.subdescription != "" {
writeOrPanic(w, s.subdescription)
writeOrPanic(w, "\n\n")
}

writeOrPanic(w, "Given a sample.toml file of:\n")
writeOrPanic(w, fmt.Sprintf("```toml\n%v\n```\n", s.input))

writeOrPanic(w, "then\n")
expression := s.expression
if expression == "" {
expression = "."
}
writeOrPanic(w, fmt.Sprintf("```bash\nyq '%v' sample.toml\n```\n", expression))
writeOrPanic(w, "will output\n")

writeOrPanic(w, fmt.Sprintf("```yaml\n%v```\n\n", mustProcessFormatScenario(s, NewTomlDecoder(), NewTomlEncoder())))
}

func documentTomlScenario(t *testing.T, w *bufio.Writer, i interface{}) {
s := i.(formatScenario)

Expand All @@ -222,6 +253,8 @@ func documentTomlScenario(t *testing.T, w *bufio.Writer, i interface{}) {
switch s.scenarioType {
case "", "decode":
documentTomlDecodeScenario(w, s)
case "roundtrip":
documentTomlRoundtripScenario(w, s)

default:
panic(fmt.Sprintf("unhandled scenario type %q", s.scenarioType))
Expand Down

0 comments on commit eba0752

Please sign in to comment.