Skip to content

Commit 288ca2d

Browse files
authored
Fixing comments in TOML arrays #2592 (#2595)
1 parent eb04fa8 commit 288ca2d

3 files changed

Lines changed: 108 additions & 0 deletions

File tree

pkg/yqlib/decoder_toml.go

Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -157,13 +157,30 @@ func (dec *tomlDecoder) createInlineTableMap(tomlNode *toml.Node) (*CandidateNod
157157

158158
func (dec *tomlDecoder) createArray(tomlNode *toml.Node) (*CandidateNode, error) {
159159
content := make([]*CandidateNode, 0)
160+
var pendingArrayComments []string
161+
160162
iterator := tomlNode.Children()
161163
for iterator.Next() {
162164
child := iterator.Node()
165+
166+
// Handle comments within arrays
167+
if child.Kind == toml.Comment {
168+
// Collect comments to attach to the next array element
169+
pendingArrayComments = append(pendingArrayComments, string(child.Data))
170+
continue
171+
}
172+
163173
yamlNode, err := dec.decodeNode(child)
164174
if err != nil {
165175
return nil, err
166176
}
177+
178+
// Attach any pending comments to this array element
179+
if len(pendingArrayComments) > 0 {
180+
yamlNode.HeadComment = strings.Join(pendingArrayComments, "\n")
181+
pendingArrayComments = make([]string, 0)
182+
}
183+
167184
content = append(content, yamlNode)
168185
}
169186

pkg/yqlib/encoder_toml.go

Lines changed: 75 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -222,6 +222,81 @@ func (te *tomlEncoder) writeArrayAttribute(w io.Writer, key string, seq *Candida
222222
return err
223223
}
224224

225+
// Check if any array elements have head comments - if so, use multiline format
226+
hasElementComments := false
227+
for _, it := range seq.Content {
228+
if it.HeadComment != "" {
229+
hasElementComments = true
230+
break
231+
}
232+
}
233+
234+
if hasElementComments {
235+
// Write multiline array format with comments
236+
if _, err := w.Write([]byte(key + " = [\n")); err != nil {
237+
return err
238+
}
239+
240+
for i, it := range seq.Content {
241+
// Write head comment for this element
242+
if it.HeadComment != "" {
243+
commentLines := strings.Split(it.HeadComment, "\n")
244+
for _, commentLine := range commentLines {
245+
if strings.TrimSpace(commentLine) != "" {
246+
if !strings.HasPrefix(strings.TrimSpace(commentLine), "#") {
247+
commentLine = "# " + commentLine
248+
}
249+
if _, err := w.Write([]byte(" " + commentLine + "\n")); err != nil {
250+
return err
251+
}
252+
}
253+
}
254+
}
255+
256+
// Write the element value
257+
var itemStr string
258+
switch it.Kind {
259+
case ScalarNode:
260+
itemStr = te.formatScalar(it)
261+
case SequenceNode:
262+
nested, err := te.sequenceToInlineArray(it)
263+
if err != nil {
264+
return err
265+
}
266+
itemStr = nested
267+
case MappingNode:
268+
inline, err := te.mappingToInlineTable(it)
269+
if err != nil {
270+
return err
271+
}
272+
itemStr = inline
273+
case AliasNode:
274+
return fmt.Errorf("aliases are not supported in TOML")
275+
default:
276+
return fmt.Errorf("unsupported array item kind: %v", it.Kind)
277+
}
278+
279+
// Always add trailing comma in multiline arrays
280+
itemStr += ","
281+
282+
if _, err := w.Write([]byte(" " + itemStr + "\n")); err != nil {
283+
return err
284+
}
285+
286+
// Add blank line between elements (except after the last one)
287+
if i < len(seq.Content)-1 {
288+
if _, err := w.Write([]byte("\n")); err != nil {
289+
return err
290+
}
291+
}
292+
}
293+
294+
if _, err := w.Write([]byte("]\n")); err != nil {
295+
return err
296+
}
297+
return nil
298+
}
299+
225300
// Join scalars or nested arrays recursively into TOML array syntax
226301
items := make([]string, 0, len(seq.Content))
227302
for _, it := range seq.Content {

pkg/yqlib/toml_test.go

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -271,6 +271,16 @@ var subArrays = `
271271
[[array.subarray.subsubarray]]
272272
`
273273

274+
var tomlTableWithComments = `[section]
275+
the_array = [
276+
# comment
277+
"value 1",
278+
279+
# comment
280+
"value 2",
281+
]
282+
`
283+
274284
var expectedSubArrays = `array:
275285
- subarray:
276286
- subsubarray:
@@ -598,6 +608,12 @@ var tomlScenarios = []formatScenario{
598608
expected: sampleFromWeb,
599609
scenarioType: "roundtrip",
600610
},
611+
{
612+
skipDoc: true,
613+
input: tomlTableWithComments,
614+
expected: tomlTableWithComments,
615+
scenarioType: "roundtrip",
616+
},
601617
}
602618

603619
func testTomlScenario(t *testing.T, s formatScenario) {

0 commit comments

Comments
 (0)