-
Notifications
You must be signed in to change notification settings - Fork 35
CLI refactoring #168
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
base: main
Are you sure you want to change the base?
CLI refactoring #168
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 adds support for COMMENT tokens in the go-yaml CLI tool and exports Comment struct fields in the internal libyaml package. The changes enable the CLI to emit explicit COMMENT tokens in token output mode, provide better position formatting, and support both compact and profuse node/event modes.
Key changes:
- Export Comment struct fields (Head, Line, Foot, ScanMark, TokenMark, StartMark, EndMark) from private to public
- Add COMMENT_TOKEN type and implement comment token generation in the CLI parser
- Implement compact node representation format and improve position formatting (from semicolon to slash separator)
- Add comprehensive test infrastructure with test data files
Reviewed Changes
Copilot reviewed 19 out of 20 changed files in this pull request and generated 2 comments.
Show a summary per file
| File | Description |
|---|---|
| internal/libyaml/yaml.go | Exports Comment struct fields and adds COMMENT_TOKEN type |
| internal/libyaml/scanner.go | Updates Comment field references to use exported names and adds EndMark to scanLineComment |
| internal/libyaml/parser.go | Updates Comment field references to use exported names |
| internal/libyaml/api.go | Adds GetPendingComments() and GetCommentsHead() methods for CLI access |
| cmd/go-yaml/parser.go | Implements comment token generation with processComments method |
| cmd/go-yaml/token.go | Adds CommentType field and updates field names to lowercase, implements COMMENT token formatting |
| cmd/go-yaml/node.go | Adds MapSlice type for key ordering, implements FormatNodeCompact, updates formatStyle and formatTag |
| cmd/go-yaml/main.go | Adds -N/--NODE flag support and multi-document handling |
| cmd/go-yaml/event.go | Implements implicit/explicit document markers, adds position format improvements |
| cmd/go-yaml/cli_test.go | New test infrastructure for CLI testing |
| cmd/go-yaml/testdata/*.yaml | New test data files for various CLI modes |
| GNUmakefile | Adds test-cli target and reorganizes test commands |
💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.
|
@ingydotnet I've opened a new pull request, #169, to work on those changes. Once the pull request is ready, I'll request review from you. |
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
Copilot reviewed 19 out of 20 changed files in this pull request and generated 5 comments.
💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.
| func adjustColumn(col int) int { | ||
| if col > 0 { | ||
| return col - 1 | ||
| } | ||
| return 0 | ||
| } |
Copilot
AI
Nov 3, 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.
This function lacks documentation explaining why column adjustment is necessary. Add a comment clarifying that yaml.Node uses 1-based column indexing while libyaml uses 0-based indexing, and this function converts between the two.
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.
for @ingydotnet
| startCol := adjustColumn(node.Column) | ||
| endLine := node.Line | ||
| endColumn := node.Column | ||
| endColumn := startCol | ||
| if node.Value != "" { | ||
| // For single-line values, add the length to the column | ||
| if !strings.Contains(node.Value, "\n") { | ||
| endColumn += len(node.Value) | ||
| } else { | ||
| // For multi-line values, we'd need more complex logic | ||
| // For now, just use the start position | ||
| endColumn = node.Column | ||
| endColumn = startCol + len(node.Value) | ||
| } | ||
| } |
Copilot
AI
Nov 3, 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 end column calculation uses byte length instead of rune count. For multi-byte UTF-8 characters, this will produce incorrect column positions. Use utf8.RuneCountInString(node.Value) instead of len(node.Value) to correctly handle Unicode characters.
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.
for @ingydotnet
| var buf bytes.Buffer | ||
| enc := yaml.NewEncoder(&buf) | ||
| enc.SetIndent(2) | ||
| enc.CompactSeqIndent() |
Copilot
AI
Nov 3, 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 encoder's CompactSeqIndent() method is called without checking if it exists or handling potential errors. Verify this is a valid method on yaml.Encoder. If it's a custom extension, ensure it's properly available in the imported yaml package version.
| enc.CompactSeqIndent() |
ccoVeille
left a comment
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'm doubtful.
The complexity of the code in go-yaml binary makes me think it's hard to maintain it
| // Build the CLI binary if it doesn't exist | ||
| binaryPath := "../../go-yaml" | ||
| if _, err := os.Stat(binaryPath); os.IsNotExist(err) { | ||
| t.Logf("Building go-yaml binary...") | ||
| cmd := exec.Command("go", "build", "-o", binaryPath, ".") | ||
| if output, err := cmd.CombinedOutput(); err != nil { | ||
| t.Fatalf("Failed to build go-yaml: %v\n%s", err, output) | ||
| } | ||
| } |
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.
It's not logic to build it in Go.
go run can be used
Also, code should be written in a way go test could be enough to emulate everything
The usual and idiomatic way in Go is to use os.ExecPipe and to play with it to pass data to Stdin and read result of Stdout
Using exec and string.Buffer is not the way to run and test go code. It would be of the binary launched was a blackbox binary
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.
for @SVilgelm
|
|
||
| // appendCommentTokenIfNotEmpty creates and appends a comment token if the value is not empty. | ||
| func (p *Parser) appendCommentTokenIfNotEmpty(value []byte, commentType string, comment *libyaml.Comment) { | ||
| if len(value) > 0 { |
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.
| if len(value) > 0 { | |
| if len(value) == 0 { | |
| return | |
| } |
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.
for @SVilgelm
| if tag := formatTag(n.Tag, n.Style, false); tag != "" && tag != "!!str" { | ||
| result = append(result, MapItem{Key: "tag", Value: tag}) | ||
| } | ||
| if n.Anchor != "" { | ||
| result = append(result, MapItem{Key: "anchor", Value: n.Anchor}) | ||
| } | ||
| if n.HeadComment != "" { | ||
| result = append(result, MapItem{Key: "head", Value: n.HeadComment}) | ||
| } | ||
| if n.LineComment != "" { | ||
| result = append(result, MapItem{Key: "line", Value: n.LineComment}) | ||
| } | ||
| if n.FootComment != "" { | ||
| result = append(result, MapItem{Key: "foot", Value: n.FootComment}) |
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.
!!str, tag, head, foot, …
All of them could be constants
It would avoid possible errors such as typo like "stt", "hesd"
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.
for @SVilgelm
1. Use periods instead of semicolons: 1;2 → 1/2 2. Shorten same-line ranges: 1;2-1;5 → 1/2-5 (omit repeated line number) 3. Keep full format for cross-line ranges: 1;2-3;5 → 1/2-3/5
Co-authored-by: Copilot <[email protected]>
...for consistency Co-authored-by: ingydotnet <[email protected]>
5e80bc3 to
7747504
Compare
Co-authored-by: Copilot <[email protected]>
| go test$(if $v, -v) | ||
|
|
||
| test-yts: $(GO-DEPS) $(YTS-DIR) | ||
| go test$(if $v, -v) ./yts -count=$(count) |
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.
| go test$(if $v, -v) ./yts -count=$(count) | |
| go test$(if $v, -v) ./yts/... -count=$(count) |
|
|
||
| # Test rules: | ||
| test: $(GO-DEPS) | ||
| go test$(if $v, -v) -vet=off ./... |
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 are removing the vet=off we just added 😁 also the ./...
| @RUNFAILING=1 bash -c "$$yts_pass_fail" | ||
|
|
||
| test-cli: $(GO-DEPS) cli | ||
| go test$(if $v, -v) ./cmd/go-yaml -count=$(count) |
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.
| go test$(if $v, -v) ./cmd/go-yaml -count=$(count) | |
| go test$(if $v, -v) ./cmd/go-yaml/... -count=$(count) |
| fmt: $(GOLANGCI-LINT-VERSIONED) | ||
| $< fmt ./... | ||
|
|
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.
There is no reason to remove make fmt
Heavy refactoring and feature enhancement for the
go-yamlCLI.Adds a test suite for the CLI.
Note: Claude Code was used for much of this work so. Should be interesting to review.