feat: Add label operations to bd update command
Implements bd-au0.2, completing all P0 tasks in the command standardization epic. Changes: - Add --add-label, --remove-label, --set-labels flags to bd update - Support multiple labels via repeatable flags - Implement in both daemon and direct modes - Add comprehensive tests for all label operations The bd update command now supports: bd update <id> --add-label <label> # Add one or more labels bd update <id> --remove-label <label> # Remove one or more labels bd update <id> --set-labels <labels> # Replace all labels 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude <noreply@anthropic.com>
This commit is contained in:
@@ -279,19 +279,73 @@ func (s *Server) handleUpdate(req *Request) Response {
|
||||
|
||||
ctx := s.reqCtx(req)
|
||||
updates := updatesFromArgs(updateArgs)
|
||||
if len(updates) == 0 {
|
||||
return Response{Success: true}
|
||||
}
|
||||
actor := s.reqActor(req)
|
||||
|
||||
if err := store.UpdateIssue(ctx, updateArgs.ID, updates, s.reqActor(req)); err != nil {
|
||||
return Response{
|
||||
Success: false,
|
||||
Error: fmt.Sprintf("failed to update issue: %v", err),
|
||||
// Apply regular field updates if any
|
||||
if len(updates) > 0 {
|
||||
if err := store.UpdateIssue(ctx, updateArgs.ID, updates, actor); err != nil {
|
||||
return Response{
|
||||
Success: false,
|
||||
Error: fmt.Sprintf("failed to update issue: %v", err),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Emit mutation event for event-driven daemon
|
||||
s.emitMutation(MutationUpdate, updateArgs.ID)
|
||||
// Handle label operations
|
||||
// Set labels (replaces all existing labels)
|
||||
if len(updateArgs.SetLabels) > 0 {
|
||||
// Get current labels
|
||||
currentLabels, err := store.GetLabels(ctx, updateArgs.ID)
|
||||
if err != nil {
|
||||
return Response{
|
||||
Success: false,
|
||||
Error: fmt.Sprintf("failed to get current labels: %v", err),
|
||||
}
|
||||
}
|
||||
// Remove all current labels
|
||||
for _, label := range currentLabels {
|
||||
if err := store.RemoveLabel(ctx, updateArgs.ID, label, actor); err != nil {
|
||||
return Response{
|
||||
Success: false,
|
||||
Error: fmt.Sprintf("failed to remove label %s: %v", label, err),
|
||||
}
|
||||
}
|
||||
}
|
||||
// Add new labels
|
||||
for _, label := range updateArgs.SetLabels {
|
||||
if err := store.AddLabel(ctx, updateArgs.ID, label, actor); err != nil {
|
||||
return Response{
|
||||
Success: false,
|
||||
Error: fmt.Sprintf("failed to set label %s: %v", label, err),
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Add labels
|
||||
for _, label := range updateArgs.AddLabels {
|
||||
if err := store.AddLabel(ctx, updateArgs.ID, label, actor); err != nil {
|
||||
return Response{
|
||||
Success: false,
|
||||
Error: fmt.Sprintf("failed to add label %s: %v", label, err),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Remove labels
|
||||
for _, label := range updateArgs.RemoveLabels {
|
||||
if err := store.RemoveLabel(ctx, updateArgs.ID, label, actor); err != nil {
|
||||
return Response{
|
||||
Success: false,
|
||||
Error: fmt.Sprintf("failed to remove label %s: %v", label, err),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Emit mutation event for event-driven daemon (only if any updates or label operations were performed)
|
||||
if len(updates) > 0 || len(updateArgs.SetLabels) > 0 || len(updateArgs.AddLabels) > 0 || len(updateArgs.RemoveLabels) > 0 {
|
||||
s.emitMutation(MutationUpdate, updateArgs.ID)
|
||||
}
|
||||
|
||||
issue, err := store.GetIssue(ctx, updateArgs.ID)
|
||||
if err != nil {
|
||||
|
||||
Reference in New Issue
Block a user