outputStatsTable outputs metrics in a human-readable table format nolint:funlen // stats display has many sections by nature
(m *metrics.Metrics, groupBy string)
| 105 | // |
| 106 | //nolint:funlen // stats display has many sections by nature |
| 107 | func outputStatsTable(m *metrics.Metrics, groupBy string) error { |
| 108 | r := getRenderer() |
| 109 | |
| 110 | fmt.Println(formatLabel("TASK STATISTICS", r)) |
| 111 | fmt.Println(strings.Repeat("=", 50)) |
| 112 | fmt.Println() |
| 113 | |
| 114 | // Overall stats |
| 115 | tw := NewTableWriter() |
| 116 | tw.AddRow([]string{"Total Tasks:", fmt.Sprintf("%d", m.TotalTasks)}, []string{"Total Tasks:", fmt.Sprintf("%d", m.TotalTasks)}) |
| 117 | tw.AddRow([]string{"Blocked Tasks:", fmt.Sprintf("%d", m.BlockedTasksCount)}, []string{"Blocked Tasks:", fmt.Sprintf("%d", m.BlockedTasksCount)}) |
| 118 | tw.AddRow([]string{"Critical Path Length:", fmt.Sprintf("%d", m.CriticalPathLength)}, []string{"Critical Path Length:", fmt.Sprintf("%d", m.CriticalPathLength)}) |
| 119 | tw.AddRow([]string{"Max Dependency Depth:", fmt.Sprintf("%d", m.MaxDependencyDepth)}, []string{"Max Dependency Depth:", fmt.Sprintf("%d", m.MaxDependencyDepth)}) |
| 120 | tw.AddRow([]string{"Avg Dependencies/Task:", fmt.Sprintf("%.2f", m.AvgDependenciesPerTask)}, []string{"Avg Dependencies/Task:", fmt.Sprintf("%.2f", m.AvgDependenciesPerTask)}) |
| 121 | tw.Flush(os.Stdout) |
| 122 | fmt.Println() |
| 123 | |
| 124 | // Tasks by status |
| 125 | fmt.Println(formatLabel("BY STATUS:", r)) |
| 126 | printStatsBreakdownByStatus(m, r) |
| 127 | fmt.Println() |
| 128 | |
| 129 | // Tasks by priority |
| 130 | fmt.Println(formatLabel("BY PRIORITY:", r)) |
| 131 | printStatsBreakdownByPriority(m, r) |
| 132 | fmt.Println() |
| 133 | |
| 134 | // Tasks by effort |
| 135 | fmt.Println(formatLabel("BY EFFORT:", r)) |
| 136 | printStatsBreakdownByEffort(m, r) |
| 137 | |
| 138 | // Tasks by phase (shown when --group-by phase or when phases exist) |
| 139 | if groupBy == "phase" || len(m.TasksByPhase) > 0 { |
| 140 | fmt.Println() |
| 141 | fmt.Println(formatLabel("BY PHASE:", r)) |
| 142 | printStatsBreakdownByPhase(m) |
| 143 | } |
| 144 | |
| 145 | return nil |
| 146 | } |
| 147 | |
| 148 | func printStatsBreakdownByStatus(m *metrics.Metrics, r *lipgloss.Renderer) { |
| 149 | if len(m.TasksByStatus) == 0 { |