diff --git a/pkg/yqlib/doc/Style.md b/pkg/yqlib/doc/Style.md index 50cfb9d3..a5094629 100644 --- a/pkg/yqlib/doc/Style.md +++ b/pkg/yqlib/doc/Style.md @@ -145,7 +145,7 @@ will output {a: cat, b: 5, c: 3.2, e: true} ``` -## Pretty print +## Reset style - or pretty print Set empty (default) quote style, note the usage of `...` to match keys too. Note that there is a `--prettyPrint/-P` short flag for this. Given a sample.yml file of: @@ -167,6 +167,22 @@ c: 3.2 e: true ``` +## Set style relatively with assign-update +Given a sample.yml file of: +```yaml +a: single +b: double +``` +then +```bash +yq eval '.[] style |= .' sample.yml +``` +will output +```yaml +a: 'single' +b: "double" +``` + ## Read style Given a sample.yml file of: ```yaml diff --git a/pkg/yqlib/operator_style.go b/pkg/yqlib/operator_style.go index b2ace2fd..1b359cdb 100644 --- a/pkg/yqlib/operator_style.go +++ b/pkg/yqlib/operator_style.go @@ -4,39 +4,46 @@ import ( "container/list" "fmt" - "gopkg.in/yaml.v3" + yaml "gopkg.in/yaml.v3" ) +func parseStyle(customStyle string) (yaml.Style, error) { + if customStyle == "tagged" { + return yaml.TaggedStyle, nil + } else if customStyle == "double" { + return yaml.DoubleQuotedStyle, nil + } else if customStyle == "single" { + return yaml.SingleQuotedStyle, nil + } else if customStyle == "literal" { + return yaml.LiteralStyle, nil + } else if customStyle == "folded" { + return yaml.FoldedStyle, nil + } else if customStyle == "flow" { + return yaml.FlowStyle, nil + } else if customStyle != "" { + return 0, fmt.Errorf("Unknown style %v", customStyle) + } + return 0, nil +} + func AssignStyleOperator(d *dataTreeNavigator, matchingNodes *list.List, pathNode *PathTreeNode) (*list.List, error) { log.Debugf("AssignStyleOperator: %v") - - rhs, err := d.GetMatchingNodes(matchingNodes, pathNode.Rhs) - if err != nil { - return nil, err - } - customStyle := "" - - if rhs.Front() != nil { - customStyle = rhs.Front().Value.(*CandidateNode).Node.Value - } - var style yaml.Style - if customStyle == "tagged" { - style = yaml.TaggedStyle - } else if customStyle == "double" { - style = yaml.DoubleQuotedStyle - } else if customStyle == "single" { - style = yaml.SingleQuotedStyle - } else if customStyle == "literal" { - style = yaml.LiteralStyle - } else if customStyle == "folded" { - style = yaml.FoldedStyle - } else if customStyle == "flow" { - style = yaml.FlowStyle - } else if customStyle != "" { - return nil, fmt.Errorf("Unknown style %v", customStyle) + if !pathNode.Operation.UpdateAssign { + rhs, err := d.GetMatchingNodes(matchingNodes, pathNode.Rhs) + if err != nil { + return nil, err + } + + if rhs.Front() != nil { + style, err = parseStyle(rhs.Front().Value.(*CandidateNode).Node.Value) + if err != nil { + return nil, err + } + } } + lhs, err := d.GetMatchingNodes(matchingNodes, pathNode.Lhs) if err != nil { @@ -46,6 +53,20 @@ func AssignStyleOperator(d *dataTreeNavigator, matchingNodes *list.List, pathNod for el := lhs.Front(); el != nil; el = el.Next() { candidate := el.Value.(*CandidateNode) log.Debugf("Setting style of : %v", candidate.GetKey()) + if pathNode.Operation.UpdateAssign { + rhs, err := d.GetMatchingNodes(nodeToMap(candidate), pathNode.Rhs) + if err != nil { + return nil, err + } + + if rhs.Front() != nil { + style, err = parseStyle(rhs.Front().Value.(*CandidateNode).Node.Value) + if err != nil { + return nil, err + } + } + } + candidate.Node.Style = style } diff --git a/pkg/yqlib/operator_style_test.go b/pkg/yqlib/operator_style_test.go index d8ca575a..fa777f26 100644 --- a/pkg/yqlib/operator_style_test.go +++ b/pkg/yqlib/operator_style_test.go @@ -86,7 +86,7 @@ e: >- }, }, { - description: "Pretty print", + description: "Reset style - or pretty print", subdescription: "Set empty (default) quote style, note the usage of `...` to match keys too. Note that there is a `--prettyPrint/-P` short flag for this.", document: `{a: cat, "b": 5, 'c': 3.2, "e": true}`, expression: `... style=""`, @@ -94,6 +94,14 @@ e: >- "D0, P[], (!!map)::a: cat\nb: 5\nc: 3.2\ne: true\n", }, }, + { + description: "Set style relatively with assign-update", + document: `{a: single, b: double}`, + expression: `.[] style |= .`, + expected: []string{ + "D0, P[], (doc)::{a: 'single', b: \"double\"}\n", + }, + }, { skipDoc: true, document: `{a: cat, b: double}`, diff --git a/pkg/yqlib/operator_tag.go b/pkg/yqlib/operator_tag.go index 3a4037ec..3ca2ede6 100644 --- a/pkg/yqlib/operator_tag.go +++ b/pkg/yqlib/operator_tag.go @@ -3,7 +3,7 @@ package yqlib import ( "container/list" - "gopkg.in/yaml.v3" + yaml "gopkg.in/yaml.v3" ) func AssignTagOperator(d *dataTreeNavigator, matchingNodes *list.List, pathNode *PathTreeNode) (*list.List, error) { @@ -26,6 +26,8 @@ func AssignTagOperator(d *dataTreeNavigator, matchingNodes *list.List, pathNode return nil, err } + // FAIL HERE + for el := lhs.Front(); el != nil; el = el.Next() { candidate := el.Value.(*CandidateNode) log.Debugf("Setting tag of : %v", candidate.GetKey())