mirror of
https://github.com/mikefarah/yq.git
synced 2024-12-19 20:19:04 +00:00
Can specify indent in encode ops
This commit is contained in:
parent
587af7f722
commit
91717b3c5d
5
go.mod
5
go.mod
@ -13,13 +13,8 @@ require (
|
|||||||
)
|
)
|
||||||
|
|
||||||
require (
|
require (
|
||||||
github.com/inconshreveable/mousetrap v1.0.0 // indirect
|
|
||||||
github.com/mattn/go-colorable v0.1.8 // indirect
|
|
||||||
github.com/mattn/go-isatty v0.0.12 // indirect
|
|
||||||
github.com/spf13/pflag v1.0.5 // indirect
|
|
||||||
github.com/timtadh/data-structures v0.5.3 // indirect
|
github.com/timtadh/data-structures v0.5.3 // indirect
|
||||||
golang.org/x/sys v0.0.0-20210809222454-d867a43fc93e // indirect
|
golang.org/x/sys v0.0.0-20210809222454-d867a43fc93e // indirect
|
||||||
golang.org/x/xerrors v0.0.0-20200804184101-5ec99f83aff1 // indirect
|
|
||||||
)
|
)
|
||||||
|
|
||||||
go 1.17
|
go 1.17
|
||||||
|
@ -2,10 +2,13 @@ Encode operators will take the piped in object structure and encode it as a stri
|
|||||||
|
|
||||||
These operators are useful to process yaml documents that have stringified embeded yaml/json/props in them.
|
These operators are useful to process yaml documents that have stringified embeded yaml/json/props in them.
|
||||||
## Encode value as yaml string
|
## Encode value as yaml string
|
||||||
|
Indent defaults to 2
|
||||||
|
|
||||||
Given a sample.yml file of:
|
Given a sample.yml file of:
|
||||||
```yaml
|
```yaml
|
||||||
a:
|
a:
|
||||||
cool: thing
|
cool:
|
||||||
|
bob: dylan
|
||||||
```
|
```
|
||||||
then
|
then
|
||||||
```bash
|
```bash
|
||||||
@ -14,9 +17,34 @@ yq eval '.b = (.a | to_yaml)' sample.yml
|
|||||||
will output
|
will output
|
||||||
```yaml
|
```yaml
|
||||||
a:
|
a:
|
||||||
cool: thing
|
cool:
|
||||||
|
bob: dylan
|
||||||
b: |
|
b: |
|
||||||
cool: thing
|
cool:
|
||||||
|
bob: dylan
|
||||||
|
```
|
||||||
|
|
||||||
|
## Encode value as yaml string, with custom indentation
|
||||||
|
You can specify the indentation level as the first parameter.
|
||||||
|
|
||||||
|
Given a sample.yml file of:
|
||||||
|
```yaml
|
||||||
|
a:
|
||||||
|
cool:
|
||||||
|
bob: dylan
|
||||||
|
```
|
||||||
|
then
|
||||||
|
```bash
|
||||||
|
yq eval '.b = (.a | to_yaml(8))' sample.yml
|
||||||
|
```
|
||||||
|
will output
|
||||||
|
```yaml
|
||||||
|
a:
|
||||||
|
cool:
|
||||||
|
bob: dylan
|
||||||
|
b: |
|
||||||
|
cool:
|
||||||
|
bob: dylan
|
||||||
```
|
```
|
||||||
|
|
||||||
## Encode value as yaml string, using toyaml
|
## Encode value as yaml string, using toyaml
|
||||||
@ -59,6 +87,25 @@ b: |
|
|||||||
}
|
}
|
||||||
```
|
```
|
||||||
|
|
||||||
|
## Encode value as json string, on one line
|
||||||
|
Pass in a 0 indent to print json on a single line.
|
||||||
|
|
||||||
|
Given a sample.yml file of:
|
||||||
|
```yaml
|
||||||
|
a:
|
||||||
|
cool: thing
|
||||||
|
```
|
||||||
|
then
|
||||||
|
```bash
|
||||||
|
yq eval '.b = (.a | to_json(0))' sample.yml
|
||||||
|
```
|
||||||
|
will output
|
||||||
|
```yaml
|
||||||
|
a:
|
||||||
|
cool: thing
|
||||||
|
b: '{"cool":"thing"}'
|
||||||
|
```
|
||||||
|
|
||||||
## Encode value as props string
|
## Encode value as props string
|
||||||
Given a sample.yml file of:
|
Given a sample.yml file of:
|
||||||
```yaml
|
```yaml
|
||||||
|
@ -2,6 +2,7 @@ package yqlib
|
|||||||
|
|
||||||
import (
|
import (
|
||||||
"fmt"
|
"fmt"
|
||||||
|
"regexp"
|
||||||
"strconv"
|
"strconv"
|
||||||
"strings"
|
"strings"
|
||||||
|
|
||||||
@ -130,6 +131,24 @@ func opTokenWithPrefs(op *operationType, assignOpType *operationType, preference
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func encodeWithIndent(outputFormat PrinterOutputFormat) lex.Action {
|
||||||
|
return func(s *lex.Scanner, m *machines.Match) (interface{}, error) {
|
||||||
|
|
||||||
|
parameterParser := regexp.MustCompile(`.*\(([0-9]+)\)`)
|
||||||
|
value := string(m.Bytes)
|
||||||
|
matches := parameterParser.FindStringSubmatch(value)
|
||||||
|
|
||||||
|
var indent, errParsingInt = strconv.ParseInt(matches[1], 10, 32) // nolint
|
||||||
|
if errParsingInt != nil {
|
||||||
|
return nil, errParsingInt
|
||||||
|
}
|
||||||
|
|
||||||
|
prefs := encoderPreferences{format: outputFormat, indent: int(indent)}
|
||||||
|
op := &Operation{OperationType: encodeOpType, Value: encodeOpType.Type, StringValue: value + "i " + matches[1], Preferences: prefs}
|
||||||
|
return &token{TokenType: operationToken, Operation: op}, nil
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
func assignAllCommentsOp(updateAssign bool) lex.Action {
|
func assignAllCommentsOp(updateAssign bool) lex.Action {
|
||||||
return func(s *lex.Scanner, m *machines.Match) (interface{}, error) {
|
return func(s *lex.Scanner, m *machines.Match) (interface{}, error) {
|
||||||
log.Debug("assignAllCommentsOp %v", string(m.Bytes))
|
log.Debug("assignAllCommentsOp %v", string(m.Bytes))
|
||||||
@ -273,13 +292,19 @@ func initLexer() (*lex.Lexer, error) {
|
|||||||
lexer.Add([]byte(`:\s*`), opToken(createMapOpType))
|
lexer.Add([]byte(`:\s*`), opToken(createMapOpType))
|
||||||
lexer.Add([]byte(`length`), opToken(lengthOpType))
|
lexer.Add([]byte(`length`), opToken(lengthOpType))
|
||||||
|
|
||||||
lexer.Add([]byte(`toyaml`), opTokenWithPrefs(encodeOpType, nil, encoderPreferences{format: YamlOutputFormat}))
|
lexer.Add([]byte(`toyaml\([0-9]+\)`), encodeWithIndent(YamlOutputFormat))
|
||||||
lexer.Add([]byte(`tojson`), opTokenWithPrefs(encodeOpType, nil, encoderPreferences{format: JsonOutputFormat}))
|
lexer.Add([]byte(`to_yaml\([0-9]+\)`), encodeWithIndent(YamlOutputFormat))
|
||||||
lexer.Add([]byte(`toprops`), opTokenWithPrefs(encodeOpType, nil, encoderPreferences{format: PropsOutputFormat}))
|
|
||||||
|
|
||||||
lexer.Add([]byte(`to_yaml`), opTokenWithPrefs(encodeOpType, nil, encoderPreferences{format: YamlOutputFormat}))
|
lexer.Add([]byte(`tojson\([0-9]+\)`), encodeWithIndent(JsonOutputFormat))
|
||||||
lexer.Add([]byte(`to_json`), opTokenWithPrefs(encodeOpType, nil, encoderPreferences{format: JsonOutputFormat}))
|
lexer.Add([]byte(`to_json\([0-9]+\)`), encodeWithIndent(JsonOutputFormat))
|
||||||
lexer.Add([]byte(`to_props`), opTokenWithPrefs(encodeOpType, nil, encoderPreferences{format: PropsOutputFormat}))
|
|
||||||
|
lexer.Add([]byte(`toyaml`), opTokenWithPrefs(encodeOpType, nil, encoderPreferences{format: YamlOutputFormat, indent: 2}))
|
||||||
|
lexer.Add([]byte(`tojson`), opTokenWithPrefs(encodeOpType, nil, encoderPreferences{format: JsonOutputFormat, indent: 2}))
|
||||||
|
lexer.Add([]byte(`toprops`), opTokenWithPrefs(encodeOpType, nil, encoderPreferences{format: PropsOutputFormat, indent: 2}))
|
||||||
|
|
||||||
|
lexer.Add([]byte(`to_yaml`), opTokenWithPrefs(encodeOpType, nil, encoderPreferences{format: YamlOutputFormat, indent: 2}))
|
||||||
|
lexer.Add([]byte(`to_json`), opTokenWithPrefs(encodeOpType, nil, encoderPreferences{format: JsonOutputFormat, indent: 2}))
|
||||||
|
lexer.Add([]byte(`to_props`), opTokenWithPrefs(encodeOpType, nil, encoderPreferences{format: PropsOutputFormat, indent: 2}))
|
||||||
|
|
||||||
lexer.Add([]byte(`fromyaml`), opToken(decodeOpType))
|
lexer.Add([]byte(`fromyaml`), opToken(decodeOpType))
|
||||||
lexer.Add([]byte(`fromjson`), opToken(decodeOpType))
|
lexer.Add([]byte(`fromjson`), opToken(decodeOpType))
|
||||||
|
@ -12,13 +12,15 @@ import (
|
|||||||
|
|
||||||
func yamlToString(candidate *CandidateNode, prefs encoderPreferences) (string, error) {
|
func yamlToString(candidate *CandidateNode, prefs encoderPreferences) (string, error) {
|
||||||
var output bytes.Buffer
|
var output bytes.Buffer
|
||||||
printer := NewPrinter(bufio.NewWriter(&output), prefs.format, true, false, 2, true)
|
log.Debug("printing with indent: %v", prefs.indent)
|
||||||
|
printer := NewPrinter(bufio.NewWriter(&output), prefs.format, true, false, prefs.indent, true)
|
||||||
err := printer.PrintResults(candidate.AsList())
|
err := printer.PrintResults(candidate.AsList())
|
||||||
return output.String(), err
|
return output.String(), err
|
||||||
}
|
}
|
||||||
|
|
||||||
type encoderPreferences struct {
|
type encoderPreferences struct {
|
||||||
format PrinterOutputFormat
|
format PrinterOutputFormat
|
||||||
|
indent int
|
||||||
}
|
}
|
||||||
|
|
||||||
/* encodes object as yaml string */
|
/* encodes object as yaml string */
|
||||||
@ -52,6 +54,11 @@ func encodeOperator(d *dataTreeNavigator, context Context, expressionNode *Expre
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// dont print a new line when printing json on a single line.
|
||||||
|
if preferences.format == JsonOutputFormat && preferences.indent == 0 {
|
||||||
|
stringValue = chomper.ReplaceAllString(stringValue, "")
|
||||||
|
}
|
||||||
|
|
||||||
stringContentNode := &yaml.Node{Kind: yaml.ScalarNode, Tag: "!!str", Value: stringValue}
|
stringContentNode := &yaml.Node{Kind: yaml.ScalarNode, Tag: "!!str", Value: stringValue}
|
||||||
results.PushBack(candidate.CreateChild(nil, stringContentNode))
|
results.PushBack(candidate.CreateChild(nil, stringContentNode))
|
||||||
}
|
}
|
||||||
|
@ -4,14 +4,25 @@ import (
|
|||||||
"testing"
|
"testing"
|
||||||
)
|
)
|
||||||
|
|
||||||
|
var prefix = "D0, P[], (doc)::a:\n cool:\n bob: dylan\n"
|
||||||
|
|
||||||
var encoderDecoderOperatorScenarios = []expressionScenario{
|
var encoderDecoderOperatorScenarios = []expressionScenario{
|
||||||
{
|
{
|
||||||
description: "Encode value as yaml string",
|
description: "Encode value as yaml string",
|
||||||
document: `{a: {cool: "thing"}}`,
|
subdescription: "Indent defaults to 2",
|
||||||
expression: `.b = (.a | to_yaml)`,
|
document: "a:\n cool:\n bob: dylan",
|
||||||
|
expression: `.b = (.a | to_yaml)`,
|
||||||
expected: []string{
|
expected: []string{
|
||||||
`D0, P[], (doc)::{a: {cool: "thing"}, b: "{cool: \"thing\"}\n"}
|
prefix + "b: |\n cool:\n bob: dylan\n",
|
||||||
`,
|
},
|
||||||
|
},
|
||||||
|
{
|
||||||
|
description: "Encode value as yaml string, with custom indentation",
|
||||||
|
subdescription: "You can specify the indentation level as the first parameter.",
|
||||||
|
document: "a:\n cool:\n bob: dylan",
|
||||||
|
expression: `.b = (.a | to_yaml(8))`,
|
||||||
|
expected: []string{
|
||||||
|
prefix + "b: |\n cool:\n bob: dylan\n",
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
@ -30,6 +41,16 @@ var encoderDecoderOperatorScenarios = []expressionScenario{
|
|||||||
expression: `.b = (.a | to_json)`,
|
expression: `.b = (.a | to_json)`,
|
||||||
expected: []string{
|
expected: []string{
|
||||||
`D0, P[], (doc)::{a: {cool: "thing"}, b: "{\n \"cool\": \"thing\"\n}\n"}
|
`D0, P[], (doc)::{a: {cool: "thing"}, b: "{\n \"cool\": \"thing\"\n}\n"}
|
||||||
|
`,
|
||||||
|
},
|
||||||
|
},
|
||||||
|
{
|
||||||
|
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"}}`,
|
||||||
|
expression: `.b = (.a | to_json(0))`,
|
||||||
|
expected: []string{
|
||||||
|
`D0, P[], (doc)::{a: {cool: "thing"}, b: '{"cool":"thing"}'}
|
||||||
`,
|
`,
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
|
Loading…
Reference in New Issue
Block a user