-
Notifications
You must be signed in to change notification settings - Fork 0
feat: add Confluence page comment commands #40
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
Changes from all commits
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,110 @@ | ||
| package comment | ||
|
|
||
| import ( | ||
| "context" | ||
| "fmt" | ||
|
|
||
| "github.com/spf13/cobra" | ||
|
|
||
| "github.com/enthus-appdev/atl-cli/internal/api" | ||
| "github.com/enthus-appdev/atl-cli/internal/iostreams" | ||
| "github.com/enthus-appdev/atl-cli/internal/output" | ||
| ) | ||
|
|
||
| // AddOptions holds the options for the add command. | ||
| type AddOptions struct { | ||
| IO *iostreams.IOStreams | ||
| PageID string | ||
| Body string | ||
| BodyFile string | ||
| ReplyTo string | ||
| JSON bool | ||
| } | ||
|
|
||
| // NewCmdAdd creates the add command. | ||
| func NewCmdAdd(ios *iostreams.IOStreams) *cobra.Command { | ||
| opts := &AddOptions{ | ||
| IO: ios, | ||
| } | ||
|
|
||
| cmd := &cobra.Command{ | ||
| Use: "add <page-id>", | ||
| Short: "Add a comment to a page", | ||
| Long: `Add a new footer comment to a Confluence page. | ||
|
|
||
| The body must be HTML (Confluence storage format). | ||
| Use --reply-to to create a threaded reply to an existing comment.`, | ||
| Example: ` # Add a comment | ||
| atl confluence comment add 1234567 --body "<p>This looks good!</p>" | ||
|
|
||
| # Add a comment from a file | ||
| atl confluence comment add 1234567 --body-file comment.html | ||
|
|
||
| # Reply to an existing comment | ||
| atl confluence comment add 1234567 --body "<p>I agree</p>" --reply-to 9876543 | ||
|
|
||
| # Output as JSON | ||
| atl confluence comment add 1234567 --body "<p>Comment</p>" --json`, | ||
| Args: cobra.ExactArgs(1), | ||
| RunE: func(cmd *cobra.Command, args []string) error { | ||
| opts.PageID = args[0] | ||
|
|
||
| if err := resolveBody(&opts.Body, opts.BodyFile); err != nil { | ||
| return err | ||
| } | ||
| if opts.Body == "" { | ||
| return fmt.Errorf("--body or --body-file is required") | ||
| } | ||
|
|
||
| return runAdd(opts) | ||
| }, | ||
| } | ||
|
|
||
| cmd.Flags().StringVarP(&opts.Body, "body", "b", "", "Comment body in HTML (required)") | ||
| cmd.Flags().StringVar(&opts.BodyFile, "body-file", "", "Read comment body from file") | ||
| cmd.Flags().StringVar(&opts.ReplyTo, "reply-to", "", "Comment ID to reply to (creates threaded reply)") | ||
| cmd.Flags().BoolVarP(&opts.JSON, "json", "j", false, "Output as JSON") | ||
|
|
||
| return cmd | ||
| } | ||
|
|
||
| // 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"` | ||
| } | ||
|
Comment on lines
+71
to
+76
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. The |
||
|
|
||
| func runAdd(opts *AddOptions) error { | ||
| client, err := api.NewClientFromConfig() | ||
| if err != nil { | ||
| return err | ||
| } | ||
|
|
||
| ctx := context.Background() | ||
| confluence := api.NewConfluenceService(client) | ||
|
|
||
| comment, err := confluence.CreateFooterComment(ctx, opts.PageID, opts.Body, opts.ReplyTo) | ||
| if err != nil { | ||
| return fmt.Errorf("failed to add comment: %w", err) | ||
| } | ||
|
|
||
| addOutput := &AddCommentOutput{ | ||
| PageID: opts.PageID, | ||
| CommentID: comment.ID, | ||
| Action: "added", | ||
| } | ||
|
|
||
| if opts.JSON { | ||
| return output.JSON(opts.IO.Out, addOutput) | ||
| } | ||
|
|
||
| action := "Added comment to" | ||
| if opts.ReplyTo != "" { | ||
| action = fmt.Sprintf("Replied to comment %s on", opts.ReplyTo) | ||
| } | ||
| fmt.Fprintf(opts.IO.Out, "%s page %s\n", action, opts.PageID) | ||
| fmt.Fprintf(opts.IO.Out, "Comment ID: %s\n", addOutput.CommentID) | ||
|
|
||
| return nil | ||
| } | ||
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,38 @@ | ||
| package comment | ||
|
|
||
| import ( | ||
| "github.com/spf13/cobra" | ||
|
|
||
| "github.com/enthus-appdev/atl-cli/internal/iostreams" | ||
| ) | ||
|
|
||
| // NewCmdComment creates the comment command group. | ||
| func NewCmdComment(ios *iostreams.IOStreams) *cobra.Command { | ||
| cmd := &cobra.Command{ | ||
| Use: "comment", | ||
| Short: "Manage comments on Confluence pages", | ||
| Long: `Add, edit, or view footer comments on Confluence pages. | ||
|
|
||
| Use subcommands to manage comments: | ||
| list - View comments on a page | ||
| add - Add a new comment | ||
| edit - Edit an existing comment`, | ||
| Example: ` # List comments on a page | ||
| atl confluence comment list 1234567 | ||
|
|
||
| # Add a comment | ||
| atl confluence comment add 1234567 --body "<p>This looks good!</p>" | ||
|
|
||
| # Reply to an existing comment | ||
| atl confluence comment add 1234567 --body "<p>I agree</p>" --reply-to 9876543 | ||
|
|
||
| # Edit a comment | ||
| atl confluence comment edit --id 9876543 --body "<p>Updated text</p>"`, | ||
| } | ||
|
|
||
| cmd.AddCommand(NewCmdList(ios)) | ||
| cmd.AddCommand(NewCmdAdd(ios)) | ||
| cmd.AddCommand(NewCmdEdit(ios)) | ||
|
|
||
| return cmd | ||
| } |
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
CreateFooterCommentRequestandUpdateFooterCommentRequeststructs use anonymous structs forBodyandVersion. This leads to code duplication for theBodystruct. To improve maintainability and clarity, consider extracting these into named types. For example, aCommentRequestBodycould be defined and reused, and aCommentUpdateVersioncould be defined for the update request.