package cmd import ( "fmt" "os" "git.franklin.lab/steve.cliff/pcli/model" "git.franklin.lab/steve.cliff/pcli/output" "github.com/spf13/cobra" ) var statusCmd = &cobra.Command{ Use: "status", Short: "Show status summary of boards and their lists", Long: "Displays a summary of boards, their lists, and the number of cards in each list.\nUse --project to filter by project name.", RunE: func(cmd *cobra.Command, args []string) error { projectName, _ := cmd.Flags().GetString("project") // Get all boards boards, err := getClient().ListBoards(getContext()) if err != nil { return fmt.Errorf("failed to list boards: %w", err) } // Filter boards by project if --project flag is provided if projectName != "" { projectID, err := resolveProjectNameToID(projectName) if err != nil { return err } filtered := boards[:0] for _, board := range boards { if board.ProjectID == projectID { filtered = append(filtered, board) } } boards = filtered } // Build status summary with error collection summary := model.StatusSummary{ TotalBoards: len(boards), Boards: make([]model.BoardSummary, 0, len(boards)), } var boardErrors []string successfulBoards := 0 // For each board, get details and aggregate card counts for _, board := range boards { boardDetail, err := getClient().GetBoard(getContext(), board.ID) if err != nil { boardErrors = append(boardErrors, fmt.Sprintf("Board %s (%s): %v", board.Name, board.ID, err)) continue } // Initialize list summaries with zero counts listCounts := make(map[string]*model.ListSummary) listOrder := make([]string, 0, len(boardDetail.Lists)) for _, list := range boardDetail.Lists { listName := "" if list.Name != nil { listName = *list.Name } listCounts[list.ID] = &model.ListSummary{ ID: list.ID, Name: listName, OpenCards: 0, ClosedCards: 0, } listOrder = append(listOrder, list.ID) } // Count cards per list for _, card := range boardDetail.Cards { if listSummary, exists := listCounts[card.ListID]; exists { if card.IsClosed { listSummary.ClosedCards++ } else { listSummary.OpenCards++ } } } // Build list summaries in original order listSummaries := make([]model.ListSummary, 0, len(listOrder)) for _, id := range listOrder { listSummaries = append(listSummaries, *listCounts[id]) } // Add board summary boardSummary := model.BoardSummary{ ID: board.ID, Name: board.Name, Lists: listSummaries, } summary.Boards = append(summary.Boards, boardSummary) successfulBoards++ } // Update total boards to reflect successful loads summary.TotalBoards = successfulBoards // If we have errors but some successful boards, add error info to output if len(boardErrors) > 0 && successfulBoards > 0 { fmt.Fprintf(os.Stderr, "Warning: %d board(s) failed to load:\n", len(boardErrors)) for _, errMsg := range boardErrors { fmt.Fprintf(os.Stderr, " - %s\n", errMsg) } fmt.Fprintf(os.Stderr, "\nShowing %d successful board(s):\n\n", successfulBoards) } else if len(boardErrors) > 0 && successfulBoards == 0 { return fmt.Errorf("failed to load any boards: %s", boardErrors[0]) } // Output the summary return output.Print(summary, getFormat(), os.Stdout) }, } func init() { rootCmd.AddCommand(statusCmd) statusCmd.Flags().String("project", "", "Filter status by project name") }