mirror of
https://github.com/mikefarah/yq.git
synced 2026-07-06 13:25:42 +00:00
Fixed processing of block labels
This commit is contained in:
parent
6270c29f54
commit
5f3dcb1ccf
@ -151,7 +151,15 @@ func (he *hclEncoder) encodeNode(body *hclwrite.Body, node *CandidateNode) error
|
|||||||
|
|
||||||
// Check if value is a mapping without FlowStyle -> render as block
|
// Check if value is a mapping without FlowStyle -> render as block
|
||||||
if valueNode.Kind == MappingNode && valueNode.Style != FlowStyle {
|
if valueNode.Kind == MappingNode && valueNode.Style != FlowStyle {
|
||||||
// Render as block: key { ... }
|
// Try to extract block labels from a single-entry mapping chain
|
||||||
|
if labels, bodyNode, ok := extractBlockLabels(valueNode); ok {
|
||||||
|
block := body.AppendNewBlock(key, labels)
|
||||||
|
if err := he.encodeNodeAttributes(block.Body(), bodyNode); err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
// No labels detected, render as unlabeled block
|
||||||
block := body.AppendNewBlock(key, nil)
|
block := body.AppendNewBlock(key, nil)
|
||||||
if err := he.encodeNodeAttributes(block.Body(), valueNode); err != nil {
|
if err := he.encodeNodeAttributes(block.Body(), valueNode); err != nil {
|
||||||
return err
|
return err
|
||||||
@ -282,6 +290,30 @@ func (he *hclEncoder) encodeNodeAttributes(body *hclwrite.Body, node *CandidateN
|
|||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// extractBlockLabels detects a chain of single-entry mappings that encode block labels.
|
||||||
|
// It returns the collected labels and the final mapping to be used as the block body.
|
||||||
|
// Pattern: {label1: {label2: { ... {bodyMap} }}}
|
||||||
|
func extractBlockLabels(node *CandidateNode) ([]string, *CandidateNode, bool) {
|
||||||
|
var labels []string
|
||||||
|
current := node
|
||||||
|
for current != nil && current.Kind == MappingNode && len(current.Content) == 2 {
|
||||||
|
keyNode := current.Content[0]
|
||||||
|
valNode := current.Content[1]
|
||||||
|
if valNode.Kind != MappingNode {
|
||||||
|
break
|
||||||
|
}
|
||||||
|
labels = append(labels, keyNode.Value)
|
||||||
|
// If the child is itself a single mapping entry with a mapping value, keep descending.
|
||||||
|
if len(valNode.Content) == 2 && valNode.Content[1].Kind == MappingNode {
|
||||||
|
current = valNode
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
// Otherwise, we have reached the body mapping.
|
||||||
|
return labels, valNode, true
|
||||||
|
}
|
||||||
|
return nil, nil, false
|
||||||
|
}
|
||||||
|
|
||||||
// nodeToCtyValue converts a CandidateNode directly to cty.Value, preserving order
|
// nodeToCtyValue converts a CandidateNode directly to cty.Value, preserving order
|
||||||
func nodeToCtyValue(node *CandidateNode) (cty.Value, error) {
|
func nodeToCtyValue(node *CandidateNode) (cty.Value, error) {
|
||||||
switch node.Kind {
|
switch node.Kind {
|
||||||
|
|||||||
@ -139,6 +139,12 @@ var hclFormatScenarios = []formatScenario{
|
|||||||
expected: "resource:\n aws_instance:\n example:\n ami: \"ami-12345\"\n",
|
expected: "resource:\n aws_instance:\n example:\n ami: \"ami-12345\"\n",
|
||||||
scenarioType: "decode",
|
scenarioType: "decode",
|
||||||
},
|
},
|
||||||
|
{
|
||||||
|
description: "block with labels roundtrip",
|
||||||
|
input: `resource "aws_instance" "example" { ami = "ami-12345" }`,
|
||||||
|
expected: "resource \"aws_instance\" \"example\" {\n ami = \"ami-12345\"\n}\n",
|
||||||
|
scenarioType: "roundtrip",
|
||||||
|
},
|
||||||
{
|
{
|
||||||
description: "roundtrip simple attribute",
|
description: "roundtrip simple attribute",
|
||||||
input: `io_mode = "async"`,
|
input: `io_mode = "async"`,
|
||||||
|
|||||||
Loading…
Reference in New Issue
Block a user