From 0cff8c234a1fe79de651e527ccd2dbde8078ffc2 Mon Sep 17 00:00:00 2001 From: Mike Farah Date: Sun, 7 Dec 2025 10:04:47 +1100 Subject: [PATCH] maps and strings --- pkg/yqlib/decoder_hcl.go | 36 ++++++++++++++++++++++++++++++++++-- pkg/yqlib/encoder_yaml.go | 1 - pkg/yqlib/hcl_test.go | 4 ++-- 3 files changed, 36 insertions(+), 5 deletions(-) diff --git a/pkg/yqlib/decoder_hcl.go b/pkg/yqlib/decoder_hcl.go index 6542ebc5..fa6d3010 100644 --- a/pkg/yqlib/decoder_hcl.go +++ b/pkg/yqlib/decoder_hcl.go @@ -122,7 +122,7 @@ func convertHclExprToNode(expr hclsyntax.Expression, src []byte) *CandidateNode // check if bf represents an exact integer if intVal, acc := bf.Int(nil); acc == big.Exact { s := intVal.String() - return createScalarNode(int64(intVal.Int64()), s) + return createScalarNode(intVal.Int64(), s) } s := bf.Text('g', -1) return createScalarNode(0.0, s) @@ -152,6 +152,38 @@ func convertHclExprToNode(expr hclsyntax.Expression, src []byte) *CandidateNode s := v.GoString() return createStringScalarNode(s) } + case *hclsyntax.TupleConsExpr: + // parse tuple/list into YAML sequence + seq := &CandidateNode{Kind: SequenceNode} + for _, exprVal := range e.Exprs { + child := convertHclExprToNode(exprVal, src) + seq.AddChild(child) + } + return seq + case *hclsyntax.ObjectConsExpr: + // parse object into YAML mapping + m := &CandidateNode{Kind: MappingNode} + for _, item := range e.Items { + // evaluate key expression to get the key string + keyVal, keyDiags := item.KeyExpr.Value(nil) + if keyDiags != nil && keyDiags.HasErrors() { + // fallback: try to extract key from source + r := item.KeyExpr.Range() + start := r.Start.Byte + end := r.End.Byte + if start > 0 && end >= start && end <= len(src) { + keyNode := createStringScalarNode(strings.TrimSpace(string(src[start-1 : end]))) + valNode := convertHclExprToNode(item.ValueExpr, src) + m.AddKeyValueChild(keyNode, valNode) + } + continue + } + keyStr := keyVal.AsString() + keyNode := createStringScalarNode(keyStr) + valNode := convertHclExprToNode(item.ValueExpr, src) + m.AddKeyValueChild(keyNode, valNode) + } + return m case *hclsyntax.TemplateExpr: // join parts; if single literal, return that string var parts []string @@ -206,7 +238,7 @@ func convertCtyValueToNode(v cty.Value) *CandidateNode { } if intVal, acc := bf.Int(nil); acc == big.Exact { s := intVal.String() - return createScalarNode(int64(intVal.Int64()), s) + return createScalarNode(intVal.Int64(), s) } s := bf.Text('g', -1) return createScalarNode(0.0, s) diff --git a/pkg/yqlib/encoder_yaml.go b/pkg/yqlib/encoder_yaml.go index 607361d3..afae87b0 100644 --- a/pkg/yqlib/encoder_yaml.go +++ b/pkg/yqlib/encoder_yaml.go @@ -5,7 +5,6 @@ import ( "bytes" "errors" "io" - "strings" "github.com/fatih/color" diff --git a/pkg/yqlib/hcl_test.go b/pkg/yqlib/hcl_test.go index 882a2d11..35db2f4c 100644 --- a/pkg/yqlib/hcl_test.go +++ b/pkg/yqlib/hcl_test.go @@ -34,13 +34,13 @@ var hclFormatScenarios = []formatScenario{ { description: "list of strings", input: `tags = ["a", "b"]`, - expected: "tags: ' [\"a\", \"b\"]'\n", + expected: "tags:\n - a\n - b\n", scenarioType: "decode", }, { description: "object/map attribute", input: `obj = { a = 1, b = "two" }`, - expected: "obj: ' { a = 1, b = \"two\" }'\n", + expected: "obj:\n a: 1\n b: two\n", scenarioType: "decode", }, {