Conversation
Add `atl confluence comment list|add|edit` commands for managing footer comments on Confluence pages via the v2 API. - list: view all footer comments on a page - add: create a comment (supports --reply-to for threaded replies) - edit: update an existing comment by ID - All commands support --json output and --body-file input - Add OAuth scopes: read:comment:confluence, write:comment:confluence
Summary of ChangesHello, I'm Gemini Code Assist1! I'm currently reviewing this pull request and will post my feedback shortly. In the meantime, here's a summary to help you and other reviewers quickly get up to speed! This pull request significantly enhances the Confluence CLI capabilities by introducing a comprehensive set of commands for managing page comments. Users can now programmatically list, add, and modify footer comments on Confluence pages, streamlining content collaboration workflows directly from the command line. This feature leverages the Confluence v2 API and integrates seamlessly into the existing CLI structure, providing a powerful new tool for Confluence administrators and power users. Highlights
Using Gemini Code AssistThe full guide for Gemini Code Assist can be found on our documentation page, here are some quick tips. Invoking Gemini You can request assistance from Gemini at any point by creating a comment using either
Customization To customize Gemini Code Assist for GitHub experience, repository maintainers can create a configuration file and/or provide a custom code review style guide (such as PEP-8 for Python) by creating and adding files to a Limitations & Feedback Gemini Code Assist may make mistakes. Please leave feedback on any instances where its feedback is incorrect or counter productive. You can react with 👍 and 👎 on @gemini-code-assist comments. If you're interested in giving your feedback about your experience with Gemini Code Assist for GitHub and other Google products, sign up here. Footnotes
|
There was a problem hiding this comment.
Code Review
This pull request adds commands for managing Confluence page comments. The implementation is solid, adding new API service methods and corresponding CLI commands for list, add, and edit. My review focuses on improving code reuse, robustness, and fixing a bug in the HTML stripping logic. I've suggested refactoring some duplicated anonymous structs in the API layer, improving how shared output structs are handled between commands, making the timestamp formatting more robust, and replacing a buggy HTML stripping function with a more reliable regex-based approach.
| func stripHTML(s string) string { | ||
| // Simple tag stripping for display purposes | ||
| result := s | ||
| for { | ||
| start := strings.Index(result, "<") | ||
| if start == -1 { | ||
| break | ||
| } | ||
| end := strings.Index(result[start:], ">") | ||
| if end == -1 { | ||
| break | ||
| } | ||
| result = result[:start] + result[start+end+1:] | ||
| } | ||
| return strings.TrimSpace(result) | ||
| } |
There was a problem hiding this comment.
This stripHTML implementation has a bug. It can incorrectly strip content if the text contains \u003c characters, for example 1 \u003c 2. A much safer and more robust approach is to use a regular expression to remove tags. For example: regexp.MustCompile("\u003c[^\u003e]*\u003e").ReplaceAllString(s, ""). This will correctly strip tags without affecting content.
| // CreateFooterCommentRequest represents a request to create a footer comment. | ||
| type CreateFooterCommentRequest struct { | ||
| PageID string `json:"pageId"` | ||
| ParentCommentID string `json:"parentCommentId,omitempty"` | ||
| Body struct { | ||
| Representation string `json:"representation"` | ||
| Value string `json:"value"` | ||
| } `json:"body"` | ||
| } | ||
|
|
||
| // UpdateFooterCommentRequest represents a request to update a footer comment. | ||
| type UpdateFooterCommentRequest struct { | ||
| Version struct { | ||
| Number int `json:"number"` | ||
| } `json:"version"` | ||
| Body struct { | ||
| Representation string `json:"representation"` | ||
| Value string `json:"value"` | ||
| } `json:"body"` | ||
| } |
There was a problem hiding this comment.
The CreateFooterCommentRequest and UpdateFooterCommentRequest structs use anonymous structs for Body and Version. This leads to code duplication for the Body struct. To improve maintainability and clarity, consider extracting these into named types. For example, a CommentRequestBody could be defined and reused, and a CommentUpdateVersion could be defined for the update request.
| // AddCommentOutput represents the result of adding a comment. | ||
| type AddCommentOutput struct { | ||
| PageID string `json:"page_id"` | ||
| CommentID string `json:"comment_id"` | ||
| Action string `json:"action"` | ||
| } |
There was a problem hiding this comment.
The AddCommentOutput struct is defined here but is also used by the edit command. To better reflect its shared nature and improve code organization, consider moving this struct to a more central location (e.g., internal/cmd/confluence/comment/comment.go) and renaming it to something more generic like CommentActionOutput.
| func formatTime(t string) string { | ||
| if len(t) >= 19 { | ||
| return t[:10] + " " + t[11:19] | ||
| } | ||
| return t | ||
| } |
There was a problem hiding this comment.
The formatTime function uses string slicing, which is brittle. It assumes the timestamp string will always have a specific length and format. A more robust method would be to parse the string using time.Parse(time.RFC3339, t) and then format the resulting time.Time object. This would correctly handle any valid ISO 8601 timestamp from the API.
Merging this branch will decrease overall coverage
Coverage by fileChanged files (no unit tests)
Please note that the "Total", "Covered", and "Missed" counts above refer to code statements instead of lines of code. The value in brackets refers to the test coverage of that file in the old version of the code. |
Summary
atl confluence comment list|add|editcommands for managing footer comments on Confluence pages via the v2 APIlist— view all footer comments on a page (with--jsonsupport)add— create a comment (supports--reply-tofor threaded replies,--body-filefor file input)edit— update an existing comment by ID (auto-fetches current version)read:comment:confluence,write:comment:confluencedeletecommand — Confluence does not allow normal users to delete comments via APITest plan
atl confluence comment list <page-id>returns comments (tested against live Confluence)atl confluence comment add <page-id> --body "<p>text</p>"creates a commentatl confluence comment add <page-id> --body "<p>reply</p>" --reply-to <id>creates a threaded replyatl confluence comment edit --id <id> --body "<p>updated</p>"updates a comment--jsonoutput works on all commands--body-filereads from file correctlyatl auth logout && atl auth login) to pick up new OAuth scopes