Sonnet Review Bot sonnet-review-bot
  • Joined on 2026-04-24
sonnet-review-bot commented on pull request rodin/review-bot#89 2026-05-12 20:28:38 +00:00
fix(deps): replace gopkg.in/yaml.v3 with github.com/goccy/go-yaml

[NIT] The comment in TestYAMLDeeplyNestedRejection was updated from 'Each level adds 2 to the depth count (key + value mapping)' to 'Each level adds to the depth count via mapping values.' The new comment is vague — it doesn't explain the actual counting semantics with the new AST walker, making it harder to reason about whether the test correctly triggers the depth limit. Consider specifying exactly how many depth units each level of nesting adds under the new implementation.

sonnet-review-bot commented on pull request rodin/review-bot#89 2026-05-12 20:28:38 +00:00
fix(deps): replace gopkg.in/yaml.v3 with github.com/goccy/go-yaml

[MINOR] The checkYAMLDepth function uses ast.Node as a map key for cycle detection. ast.Node is an interface — map keys for interface types use the dynamic type and value for equality. For pointer types (which all the concrete ast node types appear to be), this works correctly (pointer identity). This is fine but worth a comment explaining that pointer identity is the intended comparison, not structural equality, to prevent future maintainers from being surprised.

sonnet-review-bot commented on pull request rodin/review-bot#88 2026-05-12 20:08:36 +00:00
feat(vcs): complete Phase 1 — util.go, type cleanup, interface additions (fixes #84, #85, #86)

[MINOR] There is a functional duplication between vcs.GetAllFilesInPath and gitea.Client.GetAllFilesInPath. The latter already has identical logic (though with warn-and-continue error handling instead of fail-fast). The doc comment on the vcs version explicitly calls out the difference, which is good, but over time both implementations will need to be kept in sync. Consider whether gitea.Client.GetAllFilesInPath should be refactored to delegate to vcs.GetAllFilesInPath via the vcs.FileReader interface (which gitea.Client will satisfy in Phase 2) to eliminate the duplication entirely.

sonnet-review-bot commented on pull request rodin/review-bot#88 2026-05-12 20:08:36 +00:00
feat(vcs): complete Phase 1 — util.go, type cleanup, interface additions (fixes #84, #85, #86)

[NIT] The conformance assertions under //go:build phase2 include vcs.PRReader and vcs.Reviewer which gitea.Client explicitly does NOT yet satisfy (wrong return types for GetPullRequest, GetPullRequestFiles, PostReview). The build tag correctly guards against this, but the comment block lists the gaps well. This is fine as-is — just noting that once Phase 2 lands this file should have the build tag removed rather than being left indefinitely.

sonnet-review-bot commented on pull request rodin/review-bot#88 2026-05-12 20:08:36 +00:00
feat(vcs): complete Phase 1 — util.go, type cleanup, interface additions (fixes #84, #85, #86)

[NIT] GetFileContentAtRef is a thin wrapper that does nothing but delegate to GetFileContentRef with the same arguments in the same order. The docstring says "This delegates to GetFileContentRef for the Gitea implementation" — since the method exists only to satisfy the vcs.PRReader interface, a one-liner return c.GetFileContentRef(ctx, owner, repo, path, ref) with no further ceremony would be ideal, which is already the case. No change needed, but consider whether GetFileContentRef should simply be renamed to GetFileContentAtRef to avoid the two names existing in parallel on the same type.

sonnet-review-bot commented on pull request rodin/review-bot#88 2026-05-12 19:57:18 +00:00
feat(vcs): complete Phase 1 — util.go, type cleanup, interface additions (fixes #84, #85, #86)

[MINOR] Import ordering: fmt is placed between strings and testing rather than in the stdlib block before them. goimports would reorder these. The conventions doc requires go vet ./... to pass but goimports/gofmt ordering should also be maintained. Not a compilation error but violates the canonical import grouping pattern documented in style.md.

sonnet-review-bot commented on pull request rodin/review-bot#88 2026-05-12 19:57:18 +00:00
feat(vcs): complete Phase 1 — util.go, type cleanup, interface additions (fixes #84, #85, #86)

[NIT] The walk closure captures path (the original root path) by reference for use in error messages about resource limits. This is correct and intentional, but it's subtle — path is used only in the limit-exceeded error messages, not in the traversal logic. A comment noting this would improve readability.

sonnet-review-bot commented on pull request rodin/review-bot#88 2026-05-12 19:57:18 +00:00
feat(vcs): complete Phase 1 — util.go, type cleanup, interface additions (fixes #84, #85, #86)

[MINOR] GetAllFilesInPath does not handle the case where path itself is a file rather than a directory. When ListContents returns a single-element slice containing the file itself (which is how Gitea behaves when the path is a file — see gitea.Client.ListContents which normalises the single-object response to a slice), the walk function will call GetFileContent for that entry and store it with entry.Path as the key, which works correctly. However if the API returns a 404 for the path on ListContents (e.g., a bare filename in a flat repo), the function will immediately return a 'list contents' error rather than trying to fetch the file directly, unlike gitea.Client.GetAllFilesInPath. This difference in behaviour is documented in the doc comment ('fail-fast'), but callers that previously relied on the gitea fallback (single-file fetch on 404) will silently get an error instead. Worth verifying that all call-sites only pass directory paths.

sonnet-review-bot commented on pull request rodin/review-bot#88 2026-05-12 19:57:18 +00:00
feat(vcs): complete Phase 1 — util.go, type cleanup, interface additions (fixes #84, #85, #86)

[MINOR] DismissReview returns fmt.Errorf("DismissReview: %w", errors.ErrUnsupported). Per the error-handling pattern, errors.ErrUnsupported should be wrapped with context that describes what operation was attempted and why it's unsupported, rather than restating the function name. A more idiomatic message would be fmt.Errorf("dismiss review %d on %s/%s#%d: %w", reviewID, owner, repo, number, errors.ErrUnsupported). The current form matches the anti-pattern documented in error-handling.md §9 ('Don't: Return the sentinel directly without context').

sonnet-review-bot commented on pull request rodin/review-bot#88 2026-05-12 19:57:18 +00:00
feat(vcs): complete Phase 1 — util.go, type cleanup, interface additions (fixes #84, #85, #86)

[NIT] The giteaClientAdapter.GetFileContent method has a parameter named filepath which shadows the standard library package path/filepath. Although path/filepath is not imported in this file, the name filepath for a string parameter is mildly confusing. Renaming to filePath or path would be cleaner and is consistent with how the vcs.FileReader interface parameter is described elsewhere.

sonnet-review-bot commented on pull request rodin/review-bot#88 2026-05-12 19:39:28 +00:00
feat(vcs): complete Phase 1 — util.go, type cleanup, interface additions (fixes #84, #85, #86)

[MINOR] BuildLineToPositionMap skips context lines when position == 0 (the guard if position > 0). This is correct for lines before the first hunk header, but it silently drops context lines if a diff somehow starts with a space-prefixed line before any @@ hunk. The condition also means context lines at the very beginning of the first hunk aren't counted if the hunk header somehow wasn't seen. The logic is correct for well-formed unified diffs but the guard is subtle and deserves a comment explaining why.

sonnet-review-bot commented on pull request rodin/review-bot#88 2026-05-12 19:39:28 +00:00
feat(vcs): complete Phase 1 — util.go, type cleanup, interface additions (fixes #84, #85, #86)

[MINOR] GetAllFilesInPath propagates errors from GetFileContent and recursive calls (returns nil, err) but the gitea.Client.GetAllFilesInPath in gitea/client.go logs warnings and continues instead of failing. The two implementations now have divergent error-handling semantics for the same conceptual operation. The vcs package version is stricter (fail-fast), which is the right design for a utility, but callers should be aware that a single unreachable file aborts the entire traversal. Consider documenting this difference or adding a comment explaining the fail-fast contract.

sonnet-review-bot commented on pull request rodin/review-bot#88 2026-05-12 19:39:28 +00:00
feat(vcs): complete Phase 1 — util.go, type cleanup, interface additions (fixes #84, #85, #86)

[NIT] DismissReview returns a hardcoded fmt.Errorf("DismissReview: not implemented") without wrapping any sentinel or using errors.New. This is fine as a stub but should satisfy the vcs.Reviewer interface contract note and ideally reference errors.ErrUnsupported per the pattern (fmt.Errorf("DismissReview: %w", errors.ErrUnsupported)) so callers can detect the unsupported condition programmatically.

sonnet-review-bot commented on pull request rodin/review-bot#88 2026-05-12 19:39:28 +00:00
feat(vcs): complete Phase 1 — util.go, type cleanup, interface additions (fixes #84, #85, #86)

[NIT] TestGetAllFilesInPath does not test error propagation (ListContents error and GetFileContent error cases), which are explicitly mentioned in the PR description. The description says these tests exist, but they are missing from the added test file. The PR description is inaccurate — the missing tests were promised but omitted.

sonnet-review-bot commented on pull request rodin/review-bot#88 2026-05-12 19:39:28 +00:00
feat(vcs): complete Phase 1 — util.go, type cleanup, interface additions (fixes #84, #85, #86)

[NIT] parseHunkNewStart builds a string by concatenating single characters (numStr += string(ch)), causing repeated small allocations. For a hot parsing path this is negligible, but using strconv.Atoi after extracting the substring (or using a byte-slice accumulator) would be both simpler and more idiomatic.

sonnet-review-bot commented on pull request rodin/review-bot#88 2026-05-12 19:39:28 +00:00
feat(vcs): complete Phase 1 — util.go, type cleanup, interface additions (fixes #84, #85, #86)

[MINOR] The \ No newline at end of file marker handling mentioned in the PR description is not actually implemented in BuildLineToPositionMap. Lines starting with \ are not explicitly skipped. In practice they won't be counted (they don't start with +, -, or space) so it works correctly by accident, but this should either be made explicit with a comment or an explicit strings.HasPrefix(line, "\\") continue guard for clarity and robustness.

sonnet-review-bot commented on pull request rodin/review-bot#88 2026-05-12 19:32:18 +00:00
feat(vcs): complete Phase 1 — util.go, type cleanup, interface additions (fixes #84, #85, #86)

[MINOR] The parseHunkNewStart function finds the first + in the hunk line using strings.Index(hunkLine, "+"). A unified diff hunk header is formatted as @@ -old +new @@, so the + reliably appears after the @@ preamble. However, if the function signature heading (after the trailing @@) contains a + character, this would still be correct since strings.Index finds the first occurrence and the +new_start always precedes the section heading. The bigger subtlety: for a hunk like @@ -0,0 +1 @@ (new file, single line added), idx in strings.IndexAny(rest, ", @") would find @ at some position — but only if there's a space before @@. If rest is just "1", IndexAny returns -1 and Atoi works correctly. The guard idx > 0 (strictly greater than) would miss the case where idx == 0, i.e., the + is immediately followed by a delimiter. In practice this can't happen in valid unified diffs (you always have at least one digit), but the condition should arguably be idx >= 0 to be safe. This is very unlikely to matter in practice.