Fix comment commands, comments reads multiple words, fix user as author, and implemented a function to list comments
This commit is contained in:
@@ -22,5 +22,7 @@ func init() {
|
|||||||
issuesCmd.RootCmd.AddCommand(issuesCmd.CreateCmd)
|
issuesCmd.RootCmd.AddCommand(issuesCmd.CreateCmd)
|
||||||
issuesCmd.RootCmd.AddCommand(issuesCmd.DeleteCmd)
|
issuesCmd.RootCmd.AddCommand(issuesCmd.DeleteCmd)
|
||||||
issuesCmd.RootCmd.AddCommand(issuesCmd.UpdateCmd)
|
issuesCmd.RootCmd.AddCommand(issuesCmd.UpdateCmd)
|
||||||
|
issuesCmd.RootCmd.AddCommand(issuesCmd.CommentCmd)
|
||||||
|
issuesCmd.RootCmd.AddCommand(issuesCmd.CommentsCmd)
|
||||||
issuesCmd.RootCmd.AddCommand(surveyCmd.StatusCmd)
|
issuesCmd.RootCmd.AddCommand(surveyCmd.StatusCmd)
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -2,6 +2,8 @@ package issuesCmd
|
|||||||
|
|
||||||
import (
|
import (
|
||||||
"fmt"
|
"fmt"
|
||||||
|
"os"
|
||||||
|
"os/user"
|
||||||
"strings"
|
"strings"
|
||||||
|
|
||||||
"github.com/spf13/cobra"
|
"github.com/spf13/cobra"
|
||||||
@@ -13,19 +15,17 @@ var commentFlags struct {
|
|||||||
author string
|
author string
|
||||||
}
|
}
|
||||||
|
|
||||||
const commentCmdExample = `pm comment ISSUE-1 "Fix the login bug"
|
const commentCmdExample = `pm comment ISSUE-1 Fix the login bug
|
||||||
pm comment ISSUE-1 "LGTM" --author "alice"
|
pm comment ISSUE-1 LGTM --author alice
|
||||||
pm comment ISSUE-1 -m "Needs review"`
|
pm comment ISSUE-1 -m "Needs review"`
|
||||||
|
|
||||||
// CommentCmd represents the comment command,
|
|
||||||
// which allows users to add a comment on an existing issue by its ID.
|
|
||||||
var CommentCmd = &cobra.Command{
|
var CommentCmd = &cobra.Command{
|
||||||
Use: "comment [issue ID] [message]",
|
Use: "comment [issue ID] [message...]",
|
||||||
Short: "Add a comment on an issue",
|
Short: "Add a comment on an issue",
|
||||||
Long: `Add a comment on an issue by ID. Message can be passed as an argument or via --message.`,
|
Long: `Add a comment on an issue by ID. All arguments after the issue ID form the message (no quotes needed), or use --message.`,
|
||||||
Example: commentCmdExample,
|
Example: commentCmdExample,
|
||||||
|
|
||||||
Args: cobra.RangeArgs(1, 2),
|
Args: cobra.RangeArgs(1, 100), // issue ID + up to 99 words for the message
|
||||||
RunE: runCommentCmd,
|
RunE: runCommentCmd,
|
||||||
ValidArgsFunction: completeIssues,
|
ValidArgsFunction: completeIssues,
|
||||||
}
|
}
|
||||||
@@ -35,13 +35,13 @@ var CommentCmd = &cobra.Command{
|
|||||||
func runCommentCmd(cmd *cobra.Command, args []string) error {
|
func runCommentCmd(cmd *cobra.Command, args []string) error {
|
||||||
issueID := args[0]
|
issueID := args[0]
|
||||||
var text string
|
var text string
|
||||||
if len(args) >= 2 {
|
if len(args) > 1 {
|
||||||
text = args[1]
|
text = strings.Join(args[1:], " ")
|
||||||
} else {
|
} else {
|
||||||
text = commentFlags.message
|
text = commentFlags.message
|
||||||
}
|
}
|
||||||
if strings.TrimSpace(text) == "" {
|
if strings.TrimSpace(text) == "" {
|
||||||
return fmt.Errorf("comment text cannot be empty (use --message or pass as argument)")
|
return fmt.Errorf("comment text cannot be empty (use --message or pass words after the issue ID)")
|
||||||
}
|
}
|
||||||
|
|
||||||
app := AppFromContext(cmd.Context())
|
app := AppFromContext(cmd.Context())
|
||||||
@@ -57,7 +57,7 @@ func runCommentCmd(cmd *cobra.Command, args []string) error {
|
|||||||
|
|
||||||
author := commentFlags.author
|
author := commentFlags.author
|
||||||
if author == "" {
|
if author == "" {
|
||||||
author = "cli"
|
author = defaultCommentAuthor()
|
||||||
}
|
}
|
||||||
|
|
||||||
comment, err := app.Issues.AddIssueComment(cmd.Context(), issue.ID, author, text)
|
comment, err := app.Issues.AddIssueComment(cmd.Context(), issue.ID, author, text)
|
||||||
@@ -70,7 +70,21 @@ func runCommentCmd(cmd *cobra.Command, args []string) error {
|
|||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func init() {
|
|
||||||
CommentCmd.Flags().StringVarP(&commentFlags.message, "message", "m", "", "Comment text (alternative to positional argument)")
|
func defaultCommentAuthor() string {
|
||||||
CommentCmd.Flags().StringVarP(&commentFlags.author, "author", "a", "cli", "Author name for the comment")
|
if u, err := user.Current(); err == nil && u.Username != "" {
|
||||||
|
return u.Username
|
||||||
|
}
|
||||||
|
if s := os.Getenv("USER"); s != "" {
|
||||||
|
return s
|
||||||
|
}
|
||||||
|
if s := os.Getenv("USERNAME"); s != "" {
|
||||||
|
return s
|
||||||
|
}
|
||||||
|
return "user"
|
||||||
|
}
|
||||||
|
|
||||||
|
func init() {
|
||||||
|
CommentCmd.Flags().StringVarP(&commentFlags.message, "message", "m", "", "Comment text (alternative to positional arguments)")
|
||||||
|
CommentCmd.Flags().StringVarP(&commentFlags.author, "author", "a", "", "Author name (default: current OS user)")
|
||||||
}
|
}
|
||||||
|
|||||||
50
internal/commands/issues/comments_list.go
Normal file
50
internal/commands/issues/comments_list.go
Normal file
@@ -0,0 +1,50 @@
|
|||||||
|
package issuesCmd
|
||||||
|
|
||||||
|
import (
|
||||||
|
"fmt"
|
||||||
|
|
||||||
|
"github.com/spf13/cobra"
|
||||||
|
)
|
||||||
|
|
||||||
|
// CommentsCmd represents the command to list comments on an issue.
|
||||||
|
var CommentsCmd = &cobra.Command{
|
||||||
|
Use: "comments [issue ID]",
|
||||||
|
Short: "List comments on an issue",
|
||||||
|
Long: `List all comments on an issue by ID.`,
|
||||||
|
|
||||||
|
Args: cobra.ExactArgs(1),
|
||||||
|
RunE: runCommentsCmd,
|
||||||
|
ValidArgsFunction: completeIssues,
|
||||||
|
}
|
||||||
|
|
||||||
|
// runCommentsCmd executes the comments command logic.
|
||||||
|
func runCommentsCmd(cmd *cobra.Command, args []string) error {
|
||||||
|
issueID := args[0]
|
||||||
|
|
||||||
|
app := AppFromContext(cmd.Context())
|
||||||
|
|
||||||
|
issue, err := app.Issues.GetIssue(cmd.Context(), issueID)
|
||||||
|
if err != nil {
|
||||||
|
return fmt.Errorf("error fetching issue: %w", err)
|
||||||
|
}
|
||||||
|
if issue == nil {
|
||||||
|
return fmt.Errorf("issue with ID %s not found", issueID)
|
||||||
|
}
|
||||||
|
|
||||||
|
comments, err := app.Issues.GetIssueComments(cmd.Context(), issue.ID)
|
||||||
|
if err != nil {
|
||||||
|
return fmt.Errorf("error fetching comments: %w", err)
|
||||||
|
}
|
||||||
|
|
||||||
|
cmd.Printf("Comments on %s (%s):\n\n", issueID, issue.Title)
|
||||||
|
if len(comments) == 0 {
|
||||||
|
cmd.Println(" No comments yet.")
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
for _, c := range comments {
|
||||||
|
if c != nil {
|
||||||
|
cmd.Printf(" %s @ %s:\n %s\n\n", c.Author, c.CreatedAt.Format("2006-01-02 15:04"), c.Text)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return nil
|
||||||
|
}
|
||||||
@@ -150,5 +150,7 @@ func init() {
|
|||||||
issuesCmd.RootCmd.AddCommand(issuesCmd.CreateCmd)
|
issuesCmd.RootCmd.AddCommand(issuesCmd.CreateCmd)
|
||||||
issuesCmd.RootCmd.AddCommand(issuesCmd.DeleteCmd)
|
issuesCmd.RootCmd.AddCommand(issuesCmd.DeleteCmd)
|
||||||
issuesCmd.RootCmd.AddCommand(issuesCmd.UpdateCmd)
|
issuesCmd.RootCmd.AddCommand(issuesCmd.UpdateCmd)
|
||||||
|
issuesCmd.RootCmd.AddCommand(issuesCmd.CommentCmd)
|
||||||
|
issuesCmd.RootCmd.AddCommand(issuesCmd.CommentsCmd)
|
||||||
issuesCmd.RootCmd.AddCommand(surveyCmd.StatusCmd)
|
issuesCmd.RootCmd.AddCommand(surveyCmd.StatusCmd)
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -28,6 +28,8 @@ var baseSuggestions = []prompt.Suggest{
|
|||||||
{Text: "update", Description: "Update an existing issue by ID"},
|
{Text: "update", Description: "Update an existing issue by ID"},
|
||||||
{Text: "describe", Description: "Get issue details by ID"},
|
{Text: "describe", Description: "Get issue details by ID"},
|
||||||
{Text: "list", Description: "List all issues"},
|
{Text: "list", Description: "List all issues"},
|
||||||
|
{Text: "comment", Description: "Add a comment on an issue by ID"},
|
||||||
|
{Text: "comments", Description: "List comments on an issue by ID"},
|
||||||
}
|
}
|
||||||
|
|
||||||
// createFlags is a list of prompt suggestions for the create command flags.
|
// createFlags is a list of prompt suggestions for the create command flags.
|
||||||
@@ -63,6 +65,13 @@ var deleteFlags = []prompt.Suggest{
|
|||||||
{Text: "--interactive", Description: "Select issues to delete interactively"},
|
{Text: "--interactive", Description: "Select issues to delete interactively"},
|
||||||
}
|
}
|
||||||
|
|
||||||
|
var commentFlags = []prompt.Suggest{
|
||||||
|
{Text: "--message", Description: "Comment text (alternative to positional args)"},
|
||||||
|
{Text: "-m", Description: "Comment text (short)"},
|
||||||
|
{Text: "--author", Description: "Author name for the comment"},
|
||||||
|
{Text: "-a", Description: "Author name (short)"},
|
||||||
|
}
|
||||||
|
|
||||||
// statusValues is a list of prompt suggestions for status types
|
// statusValues is a list of prompt suggestions for status types
|
||||||
var statusValues = []prompt.Suggest{
|
var statusValues = []prompt.Suggest{
|
||||||
{Text: "open", Description: "Open status"},
|
{Text: "open", Description: "Open status"},
|
||||||
@@ -98,20 +107,24 @@ var isIDCommand = map[string]bool{
|
|||||||
"close": true,
|
"close": true,
|
||||||
"update": true,
|
"update": true,
|
||||||
"edit": true,
|
"edit": true,
|
||||||
|
"comment": true,
|
||||||
|
"comments": true,
|
||||||
}
|
}
|
||||||
|
|
||||||
var commandFlags = map[string][]prompt.Suggest{
|
var commandFlags = map[string][]prompt.Suggest{
|
||||||
"create": createFlags,
|
"create": createFlags,
|
||||||
"add": createFlags,
|
"add": createFlags,
|
||||||
"update": updateFlags,
|
"update": updateFlags,
|
||||||
"edit": updateFlags,
|
"edit": updateFlags,
|
||||||
"list": listFlags,
|
"list": listFlags,
|
||||||
"ls": listFlags,
|
"ls": listFlags,
|
||||||
"search": listFlags,
|
"search": listFlags,
|
||||||
"delete": deleteFlags,
|
"delete": deleteFlags,
|
||||||
"del": deleteFlags,
|
"del": deleteFlags,
|
||||||
"rm": deleteFlags,
|
"rm": deleteFlags,
|
||||||
"remove": deleteFlags,
|
"remove": deleteFlags,
|
||||||
|
"comment": commentFlags,
|
||||||
|
"comments": nil, // no flags, just issue ID
|
||||||
}
|
}
|
||||||
|
|
||||||
// commandSuggestions returns a list of prompt suggestions based on the current input words.
|
// commandSuggestions returns a list of prompt suggestions based on the current input words.
|
||||||
|
|||||||
Reference in New Issue
Block a user