Files
pcli/cmd/card.go
T
Steve Cliff b07572fed5 Released v1
2026-02-12 10:37:19 +00:00

358 lines
9.8 KiB
Go

package cmd
import (
"fmt"
"os"
"git.franklin.lab/steve.cliff/pcli/output"
"github.com/spf13/cobra"
)
var cardCmd = &cobra.Command{
Use: "card",
Short: "Manage cards",
Long: "Commands for managing Planka cards",
}
var cardListCmd = &cobra.Command{
Use: "list",
Short: "List cards",
RunE: func(cmd *cobra.Command, args []string) error {
boardId, _ := cmd.Flags().GetString("board")
listId, _ := cmd.Flags().GetString("list")
limit, _ := cmd.Flags().GetInt("limit")
if boardId == "" && listId == "" {
return fmt.Errorf("either --board or --list must be specified")
}
if boardId != "" && listId != "" {
return fmt.Errorf("--board and --list are mutually exclusive")
}
if boardId != "" {
cards, err := getClient().ListCardsByBoard(getContext(), boardId, limit)
if err != nil {
return err
}
return output.Print(cards, getFormat(), os.Stdout)
}
cards, err := getClient().ListCards(getContext(), listId, limit)
if err != nil {
return err
}
return output.Print(cards, getFormat(), os.Stdout)
},
}
var cardGetCmd = &cobra.Command{
Use: "get <id>",
Short: "Get a card by ID",
Args: cobra.ExactArgs(1),
RunE: func(cmd *cobra.Command, args []string) error {
card, err := getClient().GetCard(getContext(), args[0])
if err != nil {
return err
}
return output.Print(card, getFormat(), os.Stdout)
},
}
var cardCreateCmd = &cobra.Command{
Use: "create",
Short: "Create a new card",
RunE: func(cmd *cobra.Command, args []string) error {
listId, _ := cmd.Flags().GetString("list")
name, _ := cmd.Flags().GetString("name")
if listId == "" {
return fmt.Errorf("--list is required")
}
if name == "" {
return fmt.Errorf("--name is required")
}
fields := map[string]any{
"name": name,
"type": "project",
"position": float64(65536),
}
if desc, _ := cmd.Flags().GetString("description"); desc != "" {
fields["description"] = desc
}
if cardType, _ := cmd.Flags().GetString("type"); cardType != "" {
fields["type"] = cardType
}
if pos, _ := cmd.Flags().GetFloat64("position"); cmd.Flags().Changed("position") {
fields["position"] = pos
}
if dueDate, _ := cmd.Flags().GetString("due-date"); dueDate != "" {
fields["dueDate"] = dueDate
}
if dueCompleted, _ := cmd.Flags().GetBool("due-completed"); cmd.Flags().Changed("due-completed") {
fields["isDueCompleted"] = dueCompleted
}
card, err := getClient().CreateCard(getContext(), listId, fields)
if err != nil {
return err
}
return output.Print(card, getFormat(), os.Stdout)
},
}
var cardUpdateCmd = &cobra.Command{
Use: "update <id>",
Short: "Update a card",
Args: cobra.ExactArgs(1),
RunE: func(cmd *cobra.Command, args []string) error {
fields := make(map[string]any)
if name, _ := cmd.Flags().GetString("name"); name != "" {
fields["name"] = name
}
if desc, _ := cmd.Flags().GetString("description"); cmd.Flags().Changed("description") {
fields["description"] = desc
}
if cardType, _ := cmd.Flags().GetString("type"); cardType != "" {
fields["type"] = cardType
}
if pos, _ := cmd.Flags().GetFloat64("position"); cmd.Flags().Changed("position") {
fields["position"] = pos
}
if dueDate, _ := cmd.Flags().GetString("due-date"); cmd.Flags().Changed("due-date") {
fields["dueDate"] = dueDate
}
if dueCompleted, _ := cmd.Flags().GetBool("due-completed"); cmd.Flags().Changed("due-completed") {
fields["isDueCompleted"] = dueCompleted
}
if len(fields) == 0 {
return fmt.Errorf("at least one field must be specified for update")
}
card, err := getClient().UpdateCard(getContext(), args[0], fields)
if err != nil {
return err
}
return output.Print(card, getFormat(), os.Stdout)
},
}
var cardDeleteCmd = &cobra.Command{
Use: "delete <id>",
Short: "Delete a card",
Args: cobra.ExactArgs(1),
RunE: func(cmd *cobra.Command, args []string) error {
err := getClient().DeleteCard(getContext(), args[0])
if err != nil {
return err
}
return output.Print(map[string]string{"status": "deleted"}, getFormat(), os.Stdout)
},
}
var cardDuplicateCmd = &cobra.Command{
Use: "duplicate <id>",
Short: "Duplicate a card",
Args: cobra.ExactArgs(1),
RunE: func(cmd *cobra.Command, args []string) error {
name, _ := cmd.Flags().GetString("name")
if name == "" {
return fmt.Errorf("--name is required")
}
pos := float64(65536)
if cmd.Flags().Changed("position") {
pos, _ = cmd.Flags().GetFloat64("position")
}
card, err := getClient().DuplicateCard(getContext(), args[0], &name, &pos)
if err != nil {
return err
}
return output.Print(card, getFormat(), os.Stdout)
},
}
var cardMoveCmd = &cobra.Command{
Use: "move <id>",
Short: "Move a card to a different list",
Args: cobra.ExactArgs(1),
RunE: func(cmd *cobra.Command, args []string) error {
listId, _ := cmd.Flags().GetString("list")
if listId == "" {
return fmt.Errorf("--list is required")
}
fields := map[string]any{
"listId": listId,
"position": float64(65536),
}
if pos, _ := cmd.Flags().GetFloat64("position"); cmd.Flags().Changed("position") {
fields["position"] = pos
}
card, err := getClient().UpdateCard(getContext(), args[0], fields)
if err != nil {
return err
}
return output.Print(card, getFormat(), os.Stdout)
},
}
var cardAssignCmd = &cobra.Command{
Use: "assign <id>",
Short: "Assign a user to a card",
Args: cobra.ExactArgs(1),
RunE: func(cmd *cobra.Command, args []string) error {
userId, _ := cmd.Flags().GetString("user")
if userId == "" {
return fmt.Errorf("--user is required")
}
err := getClient().AddCardMember(getContext(), args[0], userId)
if err != nil {
return err
}
return output.Print(map[string]string{"status": "assigned"}, getFormat(), os.Stdout)
},
}
var cardUnassignCmd = &cobra.Command{
Use: "unassign <id>",
Short: "Unassign a user from a card",
Args: cobra.ExactArgs(1),
RunE: func(cmd *cobra.Command, args []string) error {
userId, _ := cmd.Flags().GetString("user")
if userId == "" {
return fmt.Errorf("--user is required")
}
err := getClient().RemoveCardMember(getContext(), args[0], userId)
if err != nil {
return err
}
return output.Print(map[string]string{"status": "unassigned"}, getFormat(), os.Stdout)
},
}
var cardAddLabelCmd = &cobra.Command{
Use: "add-label <id>",
Short: "Add a label to a card",
Args: cobra.ExactArgs(1),
RunE: func(cmd *cobra.Command, args []string) error {
labelId, _ := cmd.Flags().GetString("label")
if labelId == "" {
return fmt.Errorf("--label is required")
}
err := getClient().AddCardLabel(getContext(), args[0], labelId)
if err != nil {
return err
}
return output.Print(map[string]string{"status": "label added"}, getFormat(), os.Stdout)
},
}
var cardRemoveLabelCmd = &cobra.Command{
Use: "remove-label <id>",
Short: "Remove a label from a card",
Args: cobra.ExactArgs(1),
RunE: func(cmd *cobra.Command, args []string) error {
labelId, _ := cmd.Flags().GetString("label")
if labelId == "" {
return fmt.Errorf("--label is required")
}
err := getClient().RemoveCardLabel(getContext(), args[0], labelId)
if err != nil {
return err
}
return output.Print(map[string]string{"status": "label removed"}, getFormat(), os.Stdout)
},
}
var cardActionsCmd = &cobra.Command{
Use: "actions <id>",
Short: "List actions for a card",
Args: cobra.ExactArgs(1),
RunE: func(cmd *cobra.Command, args []string) error {
limit, _ := cmd.Flags().GetInt("limit")
actions, err := getClient().ListCardActions(getContext(), args[0], limit)
if err != nil {
return err
}
return output.Print(actions, getFormat(), os.Stdout)
},
}
func init() {
rootCmd.AddCommand(cardCmd)
cardCmd.AddCommand(cardListCmd)
cardCmd.AddCommand(cardGetCmd)
cardCmd.AddCommand(cardCreateCmd)
cardCmd.AddCommand(cardUpdateCmd)
cardCmd.AddCommand(cardDeleteCmd)
cardCmd.AddCommand(cardDuplicateCmd)
cardCmd.AddCommand(cardMoveCmd)
cardCmd.AddCommand(cardAssignCmd)
cardCmd.AddCommand(cardUnassignCmd)
cardCmd.AddCommand(cardAddLabelCmd)
cardCmd.AddCommand(cardRemoveLabelCmd)
cardCmd.AddCommand(cardActionsCmd)
cardListCmd.Flags().String("board", "", "Board ID to list cards from")
cardListCmd.Flags().String("list", "", "List ID to list cards from")
cardListCmd.Flags().Int("limit", 0, "Limit number of cards (0 = no limit)")
cardCreateCmd.Flags().String("list", "", "List ID (required)")
cardCreateCmd.Flags().String("name", "", "Card name (required)")
cardCreateCmd.Flags().String("description", "", "Card description")
cardCreateCmd.Flags().String("type", "", "Card type (project or story)")
cardCreateCmd.Flags().Float64("position", 0, "Card position")
cardCreateCmd.Flags().String("due-date", "", "Due date (ISO 8601 format)")
cardCreateCmd.Flags().Bool("due-completed", false, "Whether due date is completed")
cardUpdateCmd.Flags().String("name", "", "Card name")
cardUpdateCmd.Flags().String("description", "", "Card description")
cardUpdateCmd.Flags().String("type", "", "Card type (project or story)")
cardUpdateCmd.Flags().Float64("position", 0, "Card position")
cardUpdateCmd.Flags().String("due-date", "", "Due date (ISO 8601 format)")
cardUpdateCmd.Flags().Bool("due-completed", false, "Whether due date is completed")
cardDuplicateCmd.Flags().String("name", "", "Name for duplicated card")
cardDuplicateCmd.Flags().Float64("position", 0, "Position for duplicated card")
cardMoveCmd.Flags().String("list", "", "Target list ID (required)")
cardMoveCmd.Flags().Float64("position", 0, "Position in target list")
cardAssignCmd.Flags().String("user", "", "User ID (required)")
cardUnassignCmd.Flags().String("user", "", "User ID (required)")
cardAddLabelCmd.Flags().String("label", "", "Label ID (required)")
cardRemoveLabelCmd.Flags().String("label", "", "Label ID (required)")
cardActionsCmd.Flags().Int("limit", 0, "Limit number of actions (0 = no limit)")
}