-
-
Notifications
You must be signed in to change notification settings - Fork 727
Toml encoder #2552
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Toml encoder #2552
Conversation
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Pull request overview
This PR implements a TOML encoder for yq, adding the ability to encode data structures to TOML format with support for colorization, comment preservation, and roundtrip conversion. The encoder handles TOML-specific constructs including inline tables, table sections, arrays of tables, and maintains proper comment formatting.
Key changes:
- New TOML encoder with comprehensive support for TOML syntax including inline tables, table sections, and array-of-tables
- Syntax colorization support for TOML output using the fatih/color library
- Enhanced TOML decoder to preserve and handle comments (head, line, and standalone comments)
- Roundtrip test coverage ensuring TOML can be parsed and re-encoded with fidelity
Reviewed changes
Copilot reviewed 13 out of 13 changed files in this pull request and generated 4 comments.
Show a summary per file
| File | Description |
|---|---|
| pkg/yqlib/encoder_toml.go | Implements the complete TOML encoder with colorization support, handling various TOML constructs (inline tables, table sections, arrays) |
| pkg/yqlib/decoder_toml.go | Enhanced decoder to track and preserve comments for roundtrip encoding |
| pkg/yqlib/toml.go | Defines TOML preferences structure with colorization configuration |
| pkg/yqlib/format.go | Updates TOML format to use the new encoder with preferences |
| pkg/yqlib/candidate_node.go | Preserves EncodeSeparate flag for format-specific encoding hints |
| cmd/utils.go | Integrates TOML color preferences with global color configuration |
| pkg/yqlib/toml_test.go | Adds comprehensive roundtrip test scenarios for various TOML constructs |
| pkg/yqlib/doc/usage/toml.md | Documents the roundtrip scenarios with examples |
| pkg/yqlib/doc/usage/hcl.md | Corrects "colorization" to "colorisation" for consistency |
| pkg/yqlib/doc/usage/headers/hcl.md | Corrects "colorization" to "colorisation" for consistency |
| examples/sample.toml | Updates sample file to a more comprehensive TOML example |
| project-words.txt | Adds "colorisation" to accepted project words |
| agents.md | Adds general development rules and guidelines |
💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.
| line = strings.TrimSpace(line) | ||
| if !strings.HasPrefix(line, "#") { | ||
| line = "# " + line | ||
| } | ||
| if _, err := w.Write([]byte(line + "\n")); err != nil { |
Copilot
AI
Dec 19, 2025
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The writeComment function trims whitespace from each comment line, which could remove intentional indentation. While TOML comments typically don't use indentation, if a multi-line comment contains ASCII art, formatted text, or intentionally indented content, this trimming would alter the comment's appearance. Consider preserving the original line content after the '#' character.
| line = strings.TrimSpace(line) | |
| if !strings.HasPrefix(line, "#") { | |
| line = "# " + line | |
| } | |
| if _, err := w.Write([]byte(line + "\n")); err != nil { | |
| trimmed := strings.TrimSpace(line) | |
| // Preserve intentionally indented content after an existing '#' while | |
| // still normalizing lines that are not yet comments. | |
| if trimmed == "" { | |
| // Keep behavior of emitting a blank comment line | |
| if _, err := w.Write([]byte("# \n")); err != nil { | |
| return err | |
| } | |
| continue | |
| } | |
| if idx := strings.Index(line, "#"); idx != -1 { | |
| // Line already contains a '#': preserve everything from the first | |
| // '#' onward, including any indentation or formatting after it. | |
| commentPortion := line[idx:] | |
| if _, err := w.Write([]byte(commentPortion + "\n")); err != nil { | |
| return err | |
| } | |
| continue | |
| } | |
| // Line does not contain '#': keep previous behavior of trimming and | |
| // prefixing with "# ". | |
| lineToWrite := "# " + trimmed | |
| if _, err := w.Write([]byte(lineToWrite + "\n")); err != nil { |
| yqlib.ConfiguredYamlPreferences.ColorsEnabled = colorsEnabled | ||
| yqlib.ConfiguredJSONPreferences.ColorsEnabled = colorsEnabled | ||
| yqlib.ConfiguredHclPreferences.ColorsEnabled = colorsEnabled | ||
| yqlib.ConfiguredTomlPreferences.ColorsEnabled = colorsEnabled |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I know the others are inconsistent, but I would use
| yqlib.ConfiguredTomlPreferences.ColorsEnabled = colorsEnabled | |
| yqlib.ConfiguredTOMLPreferences.ColorsEnabled = colorsEnabled |
| - Comments (leading, head, and line comments) | ||
| - Nested structures (maps and lists) | ||
| - Syntax colorization when enabled | ||
| - Syntax colorisation when enabled |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
You may configure misspell to use UK English via your .golangci.yaml file
https://golangci-lint.run/docs/linters/configuration/#misspell
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Follow up PR for anyone interested
| key := path[len(path)-1] | ||
| for _, it := range node.Content { | ||
| // [[key]] then body | ||
| if _, err := w.Write([]byte("[[" + key + "]]\n")); err != nil { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Here I'm playing the devil advocate role.
Are we sure the key cannot contain [[ ? And so it would require some escaping.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Not sure - going to leave that for a another PR 😅
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Follow up PR for anyone interested
| } | ||
|
|
||
| // colorizeToml applies syntax highlighting to TOML output using fatih/color | ||
| func (te *tomlEncoder) colorizeToml(input []byte) []byte { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Same remark here TOML is an acronym
| func (te *tomlEncoder) colorizeToml(input []byte) []byte { | |
| func (te *tomlEncoder) colorizeTOML(input []byte) []byte { |
|
@mikefarah I've opened a new pull request, #2554, to work on those changes. Once the pull request is ready, I'll request review from you. |
Co-authored-by: ccoVeille <[email protected]>
Co-authored-by: ccoVeille <[email protected]>
Co-authored-by: mikefarah <[email protected]>
Co-authored-by: mikefarah <[email protected]>
# Conflicts: # pkg/yqlib/toml_test.go
|
@mikefarah I've opened a new pull request, #2556, to work on those changes. Once the pull request is ready, I'll request review from you. |
Co-authored-by: ccoVeille <[email protected]>
|
Thanks @ccoVeille ! |
Co-authored-by: mikefarah <[email protected]>
Co-authored-by: mikefarah <[email protected]>
No description provided.