@@ -296,95 +296,111 @@ func printHumanReadable(breakdown *cost.Breakdown, prURL string) {
296296
297297 // Delay and Future Costs - only show if there are any delay costs
298298 if breakdown .DelayCost > 0 {
299- // Merge Delay Costs
300- fmt .Println (" Delay Costs" )
301- fmt .Println (" ───────────" )
302- if breakdown .DelayCostDetail .DeliveryDelayHours > 0 {
303- if breakdown .DelayCapped {
304- fmt .Printf (" Delivery %12s %s (capped)\n " ,
305- formatCurrency (breakdown .DelayCostDetail .DeliveryDelayCost ), formatTimeUnit (breakdown .DelayCostDetail .DeliveryDelayHours ))
306- } else {
307- fmt .Printf (" Delivery %12s %s\n " ,
308- formatCurrency (breakdown .DelayCostDetail .DeliveryDelayCost ), formatTimeUnit (breakdown .DelayCostDetail .DeliveryDelayHours ))
309- }
299+ printDelayCosts (breakdown , formatCurrency )
300+ }
301+
302+ // Grand Total
303+ totalHours := breakdown .Author .TotalHours + breakdown .DelayCostDetail .TotalDelayHours
304+ for _ , p := range breakdown .Participants {
305+ totalHours += p .TotalHours
306+ }
307+ fmt .Println (" ═══════════════════════════════════════════════════════════════" )
308+ fmt .Printf (" Total %12s %s\n " ,
309+ formatCurrency (breakdown .TotalCost ), formatTimeUnit (totalHours ))
310+ fmt .Println ()
311+ }
312+
313+ // printDelayCosts prints delay and future costs section.
314+ func printDelayCosts (breakdown * cost.Breakdown , formatCurrency func (float64 ) string ) {
315+ // Merge Delay Costs
316+ fmt .Println (" Delay Costs" )
317+ fmt .Println (" ───────────" )
318+
319+ if breakdown .DelayCostDetail .DeliveryDelayHours > 0 {
320+ cappedSuffix := ""
321+ if breakdown .DelayCapped {
322+ cappedSuffix = " (capped)"
310323 }
324+ fmt .Printf (" Delivery %12s %s%s\n " ,
325+ formatCurrency (breakdown .DelayCostDetail .DeliveryDelayCost ),
326+ formatTimeUnit (breakdown .DelayCostDetail .DeliveryDelayHours ),
327+ cappedSuffix )
328+ }
311329
312- if breakdown .DelayCostDetail .CoordinationHours > 0 {
313- if breakdown .DelayCapped {
314- fmt .Printf (" Coordination %12s %s (capped)\n " ,
315- formatCurrency (breakdown .DelayCostDetail .CoordinationCost ), formatTimeUnit (breakdown .DelayCostDetail .CoordinationHours ))
316- } else {
317- fmt .Printf (" Coordination %12s %s\n " ,
318- formatCurrency (breakdown .DelayCostDetail .CoordinationCost ), formatTimeUnit (breakdown .DelayCostDetail .CoordinationHours ))
319- }
330+ if breakdown .DelayCostDetail .CoordinationHours > 0 {
331+ cappedSuffix := ""
332+ if breakdown .DelayCapped {
333+ cappedSuffix = " (capped)"
320334 }
335+ fmt .Printf (" Coordination %12s %s%s\n " ,
336+ formatCurrency (breakdown .DelayCostDetail .CoordinationCost ),
337+ formatTimeUnit (breakdown .DelayCostDetail .CoordinationHours ),
338+ cappedSuffix )
339+ }
321340
322- mergeDelayCost := breakdown .DelayCostDetail .DeliveryDelayCost + breakdown .DelayCostDetail .CoordinationCost
323- mergeDelayHours := breakdown .DelayCostDetail .DeliveryDelayHours + breakdown .DelayCostDetail .CoordinationHours
324- fmt .Println (" ────────────" )
325- fmt .Printf (" Subtotal %12s %s\n " ,
326- formatCurrency (mergeDelayCost ), formatTimeUnit (mergeDelayHours ))
327- fmt .Println ()
341+ mergeDelayCost := breakdown .DelayCostDetail .DeliveryDelayCost + breakdown .DelayCostDetail .CoordinationCost
342+ mergeDelayHours := breakdown .DelayCostDetail .DeliveryDelayHours + breakdown .DelayCostDetail .CoordinationHours
343+ fmt .Println (" ────────────" )
344+ fmt .Printf (" Subtotal %12s %s\n " ,
345+ formatCurrency (mergeDelayCost ), formatTimeUnit (mergeDelayHours ))
346+ fmt .Println ()
328347
329- // Future Costs
330- hasFutureCosts := breakdown .DelayCostDetail .ReworkPercentage > 0 ||
331- breakdown .DelayCostDetail .FutureReviewCost > 0 ||
332- breakdown .DelayCostDetail .FutureMergeCost > 0 ||
333- breakdown .DelayCostDetail .FutureContextCost > 0
334-
335- if hasFutureCosts {
336- fmt .Println (" Future Costs" )
337- fmt .Println (" ────────────" )
338-
339- if breakdown .DelayCostDetail .ReworkPercentage > 0 {
340- label := fmt .Sprintf ("Code Churn (%.0f%% drift)" , breakdown .DelayCostDetail .ReworkPercentage )
341- fmt .Printf (" %-26s%12s %s\n " ,
342- label ,
343- formatCurrency (breakdown .DelayCostDetail .CodeChurnCost ),
344- formatTimeUnit (breakdown .DelayCostDetail .CodeChurnHours ))
345- }
348+ // Future Costs
349+ hasFutureCosts := breakdown .DelayCostDetail .ReworkPercentage > 0 ||
350+ breakdown .DelayCostDetail .FutureReviewCost > 0 ||
351+ breakdown .DelayCostDetail .FutureMergeCost > 0 ||
352+ breakdown .DelayCostDetail .FutureContextCost > 0
346353
347- if breakdown .DelayCostDetail .FutureReviewCost > 0 {
348- fmt .Printf (" %-26s%12s %s\n " ,
349- "Review" ,
350- formatCurrency (breakdown .DelayCostDetail .FutureReviewCost ), formatTimeUnit (breakdown .DelayCostDetail .FutureReviewHours ))
351- }
354+ if hasFutureCosts {
355+ printFutureCosts (breakdown , formatCurrency )
356+ }
357+ }
352358
353- if breakdown .DelayCostDetail .FutureMergeCost > 0 {
354- fmt .Printf (" %-26s%12s %s\n " ,
355- "Merge" ,
356- formatCurrency (breakdown .DelayCostDetail .FutureMergeCost ), formatTimeUnit (breakdown .DelayCostDetail .FutureMergeHours ))
357- }
359+ // printFutureCosts prints future costs subsection.
360+ func printFutureCosts (breakdown * cost.Breakdown , formatCurrency func (float64 ) string ) {
361+ fmt .Println (" Future Costs" )
362+ fmt .Println (" ────────────" )
363+
364+ if breakdown .DelayCostDetail .ReworkPercentage > 0 {
365+ label := fmt .Sprintf ("Code Churn (%.0f%% drift)" , breakdown .DelayCostDetail .ReworkPercentage )
366+ fmt .Printf (" %-26s%12s %s\n " ,
367+ label ,
368+ formatCurrency (breakdown .DelayCostDetail .CodeChurnCost ),
369+ formatTimeUnit (breakdown .DelayCostDetail .CodeChurnHours ))
370+ }
358371
359- if breakdown .DelayCostDetail .FutureContextCost > 0 {
360- fmt .Printf (" %-26s%12s %s\n " ,
361- "Context Switching" ,
362- formatCurrency (breakdown .DelayCostDetail .FutureContextCost ), formatTimeUnit (breakdown .DelayCostDetail .FutureContextHours ))
363- }
372+ if breakdown .DelayCostDetail .FutureReviewCost > 0 {
373+ fmt .Printf (" %-26s%12s %s\n " ,
374+ "Review" ,
375+ formatCurrency (breakdown .DelayCostDetail .FutureReviewCost ),
376+ formatTimeUnit (breakdown .DelayCostDetail .FutureReviewHours ))
377+ }
364378
365- futureCost := breakdown .DelayCostDetail .CodeChurnCost +
366- breakdown .DelayCostDetail .FutureReviewCost +
367- breakdown .DelayCostDetail .FutureMergeCost +
368- breakdown .DelayCostDetail .FutureContextCost
369- futureHours := breakdown .DelayCostDetail .CodeChurnHours +
370- breakdown .DelayCostDetail .FutureReviewHours +
371- breakdown .DelayCostDetail .FutureMergeHours +
372- breakdown .DelayCostDetail .FutureContextHours
373- fmt .Println (" ────────────" )
374- fmt .Printf (" Subtotal %12s %s\n " ,
375- formatCurrency (futureCost ), formatTimeUnit (futureHours ))
376- fmt .Println ()
377- }
379+ if breakdown .DelayCostDetail .FutureMergeCost > 0 {
380+ fmt .Printf (" %-26s%12s %s\n " ,
381+ "Merge" ,
382+ formatCurrency (breakdown .DelayCostDetail .FutureMergeCost ),
383+ formatTimeUnit (breakdown .DelayCostDetail .FutureMergeHours ))
378384 }
379385
380- // Grand Total
381- totalHours := breakdown .Author .TotalHours + breakdown .DelayCostDetail .TotalDelayHours
382- for _ , p := range breakdown .Participants {
383- totalHours += p .TotalHours
386+ if breakdown .DelayCostDetail .FutureContextCost > 0 {
387+ fmt .Printf (" %-26s%12s %s\n " ,
388+ "Context Switching" ,
389+ formatCurrency (breakdown .DelayCostDetail .FutureContextCost ),
390+ formatTimeUnit (breakdown .DelayCostDetail .FutureContextHours ))
384391 }
385- fmt .Println (" ═══════════════════════════════════════════════════════════════" )
386- fmt .Printf (" Total %12s %s\n " ,
387- formatCurrency (breakdown .TotalCost ), formatTimeUnit (totalHours ))
392+
393+ futureCost := breakdown .DelayCostDetail .CodeChurnCost +
394+ breakdown .DelayCostDetail .FutureReviewCost +
395+ breakdown .DelayCostDetail .FutureMergeCost +
396+ breakdown .DelayCostDetail .FutureContextCost
397+ futureHours := breakdown .DelayCostDetail .CodeChurnHours +
398+ breakdown .DelayCostDetail .FutureReviewHours +
399+ breakdown .DelayCostDetail .FutureMergeHours +
400+ breakdown .DelayCostDetail .FutureContextHours
401+ fmt .Println (" ────────────" )
402+ fmt .Printf (" Subtotal %12s %s\n " ,
403+ formatCurrency (futureCost ), formatTimeUnit (futureHours ))
388404 fmt .Println ()
389405}
390406
0 commit comments