Files
LazyPM/internal/commands/issues/update.go
Robin Olsen d900a5fcd3 Merge pull request #75 from LazyBachelor/LPM-140
LPM-140 The Sprinting Update
Adds sprint support across the web UI (board + issue detail), TUI kanban, CLI/REPL, and the Beads-backed storage layer.

Changes:

Introduces sprint entities in storage and exposes sprint operations via IssueService.
Updates web board to support backlog vs. sprint columns, sprint selection, and sprint creation routes.
Updates TUI kanban to show backlog + sprint columns and adds sprint selection/creation actions.
2026-03-23 19:26:04 +01:00

115 lines
3.3 KiB
Go

package issues
import (
"fmt"
"github.com/LazyBachelor/LazyPM/internal/models"
"github.com/LazyBachelor/LazyPM/internal/utils/shellcomp"
"github.com/spf13/cobra"
"github.com/spf13/pflag"
)
var updateFlags Flags
var UpdateCmd = &cobra.Command{
Use: "update [id]",
Short: "Update an existing issue",
Long: `Update an existing issue by its ID with the specified details.`,
Example: `pm update pm-001 --title "New title" -d "Description" -s in_progress --type task -p 3`,
RunE: runUpdateCmd,
Aliases: []string{"edit"},
Args: cobra.ExactArgs(1),
ValidArgsFunction: completeIssues,
}
func runUpdateCmd(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 getting issue: %w", err)
}
if issue == nil {
return fmt.Errorf("issue with ID %s not found", issueID)
}
updates, err := getUpdateValues(cmd)
if err != nil {
return fmt.Errorf("error getting update values: %w", err)
}
err = app.Issues.UpdateIssue(cmd.Context(), issueID, updates, "test_actor")
if err != nil {
return fmt.Errorf("error updating issue: %w", err)
}
updatedIssue, err := app.Issues.GetIssue(cmd.Context(), issueID)
if err != nil {
return fmt.Errorf("error getting updated issue: %w", err)
}
cmd.Printf("Updated issue to:\n%s", models.IssueString(*updatedIssue))
updateFlags = Flags{}
cmd.Flags().VisitAll(func(f *pflag.Flag) {
f.Changed = false
_ = f.Value.Set(f.DefValue)
})
return nil
}
func init() {
UpdateCmd.Flags().StringVar(&updateFlags.title, "title", "", "New issue title")
UpdateCmd.Flags().StringVarP(&updateFlags.description, "desc", "d", "", "New issue description")
UpdateCmd.Flags().StringVarP(&updateFlags.status, "status", "s", "", "New issue status(open, closed, in_progress)")
UpdateCmd.Flags().StringVarP(&updateFlags.issueType, "type", "t", "", "New issue type(bug, feature, task)")
UpdateCmd.Flags().IntVarP(&updateFlags.priority, "priority", "p", 0, "New issue priority(0-4)")
UpdateCmd.Flags().StringVarP(&updateFlags.assignee, "assignee", "a", "", "New issue assignee")
UpdateCmd.RegisterFlagCompletionFunc("type", shellcomp.CompletionFunc(typeOptions))
UpdateCmd.RegisterFlagCompletionFunc("status", shellcomp.CompletionFunc(statusOptions))
UpdateCmd.RegisterFlagCompletionFunc("priority", shellcomp.CompletionFunc(priorityRange))
}
func getUpdateValues(cmd *cobra.Command) (map[string]interface{}, error) {
updates := make(map[string]interface{})
if cmd.Flags().Changed("title") {
if updateFlags.title == "" {
return updates, fmt.Errorf("issue title cannot be empty")
}
updates["title"] = updateFlags.title
}
if cmd.Flags().Changed("desc") {
updates["description"] = updateFlags.description
}
if cmd.Flags().Changed("status") {
updates["status"] = updateFlags.status
}
if cmd.Flags().Changed("type") {
updates["issue_type"] = updateFlags.issueType
}
if cmd.Flags().Changed("priority") {
updates["priority"] = updateFlags.priority
}
if cmd.Flags().Changed("assignee") {
updates["assignee"] = updateFlags.assignee
}
if len(updates) == 0 {
return updates, fmt.Errorf("no updates specified")
}
return updates, nil
}