add descriptive comment to variour commands

move completions to its own class
This commit is contained in:
Robin Olsen
2026-02-07 12:15:09 +01:00
parent 9baedea9b5
commit 6bf8b76aab
5 changed files with 82 additions and 52 deletions

View File

@@ -7,8 +7,10 @@ import (
"github.com/LazyBachelor/LazyPM/pkg/cli/commands" "github.com/LazyBachelor/LazyPM/pkg/cli/commands"
) )
// CLIConfig is an alias for service.Config, which contains all the necessary
type CLIConfig = service.Config type CLIConfig = service.Config
// Run initializes the services and executes the CLI commands.
func Run(ctx context.Context, config CLIConfig) error { func Run(ctx context.Context, config CLIConfig) error {
svc, cleanup, err := service.NewServices(ctx, config) svc, cleanup, err := service.NewServices(ctx, config)
if err != nil { if err != nil {
@@ -26,6 +28,7 @@ func Run(ctx context.Context, config CLIConfig) error {
return nil return nil
} }
// RunWithArgs initializes the services and executes the CLI commands with the provided arguments.
func RunWithArgs(ctx context.Context, config CLIConfig, args []string) error { func RunWithArgs(ctx context.Context, config CLIConfig, args []string) error {
svc, cleanup, err := service.NewServices(ctx, config) svc, cleanup, err := service.NewServices(ctx, config)
if err != nil { if err != nil {

View File

@@ -0,0 +1,42 @@
package commands
import (
"context"
"strings"
"github.com/LazyBachelor/LazyPM/internal/models"
"github.com/spf13/cobra"
)
// completeIssues provides shell completion for issue IDs and titles.
func completeIssues(cmd *cobra.Command, args []string, toComplete string) ([]string, cobra.ShellCompDirective) {
issues, _ := GetIssueCompletions(cmd.Context(), toComplete)
var ids []string
for _, issue := range issues {
ids = append(ids, issue.ID)
}
return ids, cobra.ShellCompDirectiveNoFileComp
}
// GetIssueCompletions fetches issues matching the toComplete string for shell completion.
func GetIssueCompletions(ctx context.Context, toComplete string) ([]models.Issue, cobra.ShellCompDirective) {
if svc == nil {
return nil, cobra.ShellCompDirectiveNoFileComp
}
issues, err := svc.Beads.AllIssues(ctx)
if err != nil {
return nil, cobra.ShellCompDirectiveNoFileComp
}
var completions []models.Issue
for _, issue := range issues {
if strings.HasPrefix(issue.ID, toComplete) {
completions = append(completions, issue)
} else if strings.HasPrefix(issue.Title, toComplete) {
completions = append(completions, issue)
}
}
return completions, cobra.ShellCompDirectiveNoFileComp
}

View File

@@ -9,6 +9,7 @@ import (
"github.com/spf13/cobra" "github.com/spf13/cobra"
) )
// Variables to hold flag values for the create command.
var ( var (
createDescription string createDescription string
createStatus string createStatus string
@@ -21,6 +22,7 @@ const (
pm create Fix bug --desc "Bug description" --status in_progress --type bug --priority 5` pm create Fix bug --desc "Bug description" --status in_progress --type bug --priority 5`
) )
// createCmd represents the create command, which allows users to create a new issue with specified details.
var createCmd = &cobra.Command{ var createCmd = &cobra.Command{
Use: "create [title]", Use: "create [title]",
Short: "Create a new issue", Short: "Create a new issue",
@@ -32,6 +34,7 @@ var createCmd = &cobra.Command{
RunE: runCreateCmd, RunE: runCreateCmd,
} }
// runCreateCmd executes the create command logic,
func runCreateCmd(cmd *cobra.Command, args []string) error { func runCreateCmd(cmd *cobra.Command, args []string) error {
createTitle := strings.Join(args, " ") createTitle := strings.Join(args, " ")
@@ -47,11 +50,13 @@ func runCreateCmd(cmd *cobra.Command, args []string) error {
Priority: createPriority, Priority: createPriority,
} }
// Create the issue using the service layer.
err := svc.Beads.CreateIssue(cmd.Context(), issue, "test_actor") err := svc.Beads.CreateIssue(cmd.Context(), issue, "test_actor")
if err != nil { if err != nil {
return fmt.Errorf("error creating issue: %w", err) return fmt.Errorf("error creating issue: %w", err)
} }
// Build the output string with the created issue details.
str := fmt.Sprintf("Created issue with ID: %s\n", issue.ID) str := fmt.Sprintf("Created issue with ID: %s\n", issue.ID)
if issue.Title != "" { if issue.Title != "" {
@@ -74,11 +79,12 @@ func runCreateCmd(cmd *cobra.Command, args []string) error {
str += fmt.Sprintf("Priority: %d\n", issue.Priority) str += fmt.Sprintf("Priority: %d\n", issue.Priority)
} }
fmt.Print(str) cmd.Print(str)
return nil return nil
} }
// init function to set up the create command and its flags.
func init() { func init() {
createCmd.Flags().StringVarP(&createDescription, "desc", "d", "", "Issue description") createCmd.Flags().StringVarP(&createDescription, "desc", "d", "", "Issue description")
createCmd.Flags().StringVarP(&createStatus, "status", "s", "open", "Issue status(open, closed, in_progress)") createCmd.Flags().StringVarP(&createStatus, "status", "s", "open", "Issue status(open, closed, in_progress)")

View File

@@ -7,6 +7,7 @@ import (
"github.com/spf13/cobra" "github.com/spf13/cobra"
) )
// Variables for get-issues command flags.
var ( var (
titleFlag string titleFlag string
descriptionFlag string descriptionFlag string
@@ -23,18 +24,21 @@ pm ls --title "New feature" --desc "feature description"
pm ls -p 1 -l 10` pm ls -p 1 -l 10`
) )
// getIssuesCmd represents the get issues command.
var getIssuesCmd = &cobra.Command{ var getIssuesCmd = &cobra.Command{
Use: "ls [search query]", Use: "ls [search query]",
Short: "List all issues", Short: "List all issues",
Long: `List all issues in the project management system.`, Long: `List all issues in the project management system.`,
Aliases: []string{"list", "search"},
Example: lsExamples, Example: lsExamples,
Aliases: []string{"list", "search"},
Args: cobra.MinimumNArgs(0), Args: cobra.MinimumNArgs(0),
RunE: runGetIssuesCmd, RunE: runGetIssuesCmd,
} }
// runGetIssuesCmd executes the get issues command logic,
// which retrieves and displays a list of issues based on the provided search query and filters.
func runGetIssuesCmd(cmd *cobra.Command, args []string) error { func runGetIssuesCmd(cmd *cobra.Command, args []string) error {
queryArg := strings.Join(args, " ") queryArg := strings.Join(args, " ")
filter := models.IssueFilter{ filter := models.IssueFilter{
@@ -43,6 +47,8 @@ func runGetIssuesCmd(cmd *cobra.Command, args []string) error {
Limit: limit, Limit: limit,
} }
// Only set filter fields if the corresponding flags
// were explicitly provided by the user.
if cmd.Flags().Changed("status") { if cmd.Flags().Changed("status") {
s := models.Status(statusFlag) s := models.Status(statusFlag)
filter.Status = &s filter.Status = &s
@@ -55,18 +61,20 @@ func runGetIssuesCmd(cmd *cobra.Command, args []string) error {
filter.Priority = &priorityFlag filter.Priority = &priorityFlag
} }
// Fetch issues based on the search query and filters.
issuesPtr, err := svc.Beads.SearchIssues(cmd.Context(), queryArg, filter) issuesPtr, err := svc.Beads.SearchIssues(cmd.Context(), queryArg, filter)
if err != nil { if err != nil {
return err return err
} }
// Convert the returned issue pointers to issue values and print them.
issues := models.IssuesPtrToIssues(issuesPtr) issues := models.IssuesPtrToIssues(issuesPtr)
models.PrintIssues(issues) models.PrintIssues(issues)
return nil return nil
} }
// init function to set up the get issues command and its flags.
func init() { func init() {
getIssuesCmd.Flags().StringVar(&titleFlag, "title", "", "Filter issues by title") getIssuesCmd.Flags().StringVar(&titleFlag, "title", "", "Filter issues by title")
getIssuesCmd.Flags().StringVarP(&descriptionFlag, "desc", "d", "", "Filter issues by description") getIssuesCmd.Flags().StringVarP(&descriptionFlag, "desc", "d", "", "Filter issues by description")

View File

@@ -1,76 +1,47 @@
package commands package commands
import ( import (
"context"
"strings"
"github.com/LazyBachelor/LazyPM/internal/models" "github.com/LazyBachelor/LazyPM/internal/models"
"github.com/spf13/cobra" "github.com/spf13/cobra"
) )
// getIssueCmd represents the get issue command.
var getIssueCmd = &cobra.Command{ var getIssueCmd = &cobra.Command{
Use: "describe [issue ID]", Use: "describe [issue ID]",
Short: "Get issue details", Short: "Get issue details",
Long: `Get issue details by ID`, Long: `Get issue details by ID`,
Aliases: []string{"get", "read"},
Args: cobra.ExactArgs(1),
RunE: runGetCmd,
ValidArgsFunction: completeIssues, ValidArgsFunction: completeIssues,
Aliases: []string{"get", "read"},
Args: cobra.ExactArgs(1),
RunE: runGetCmd,
} }
// runGetCmd executes the get issue command logic,
// which retrieves and displays issue details by its ID.
func runGetCmd(cmd *cobra.Command, args []string) error { func runGetCmd(cmd *cobra.Command, args []string) error {
issueID := args[0] issueID := args[0]
issue, err := svc.Beads.GetIssue(cmd.Context(), issueID) // Fetch the issue details using the service layer.
issuePtr, err := svc.Beads.GetIssue(cmd.Context(), issueID)
if err != nil { if err != nil {
return err return err
} }
if issue == nil { // If the issue is not found, inform the user.
cmd.Printf("Issue with ID '%s' not found\n", issueID) if issuePtr == nil {
cmd.Printf("Issue with ID %s not found\n", issueID)
return nil return nil
} }
cmd.Printf("Title: %s\n", issue.Title) // Display the issue details to the user.
cmd.Printf("Description: %s\n", issue.Description) cmd.Println(models.IssueString(*issuePtr))
cmd.Printf("Status: %s\n", issue.Status)
cmd.Printf("Type: %s\n", issue.IssueType)
cmd.Printf("Priority: %d\n", issue.Priority)
return nil return nil
} }
// init function to set up the get issue command.
func init() { func init() {
rootCmd.AddCommand(getIssueCmd) rootCmd.AddCommand(getIssueCmd)
} }
func completeIssues(cmd *cobra.Command, args []string, toComplete string) ([]string, cobra.ShellCompDirective) {
issues, _ := GetIssueCompletions(cmd.Context(), toComplete)
var ids []string
for _, issue := range issues {
ids = append(ids, issue.ID)
}
return ids, cobra.ShellCompDirectiveNoFileComp
}
func GetIssueCompletions(ctx context.Context, toComplete string) ([]models.Issue, cobra.ShellCompDirective) {
if svc == nil {
return nil, cobra.ShellCompDirectiveNoFileComp
}
issues, err := svc.Beads.AllIssues(ctx)
if err != nil {
return nil, cobra.ShellCompDirectiveNoFileComp
}
var completions []models.Issue
for _, issue := range issues {
if strings.HasPrefix(issue.ID, toComplete) {
completions = append(completions, issue)
} else if strings.HasPrefix(issue.Title, toComplete) {
completions = append(completions, issue)
}
}
return completions, cobra.ShellCompDirectiveNoFileComp
}