Skip to content

Commit e58d90c

Browse files
authored
Merge pull request #1 from tstromberg/main
Show percentages for each section
2 parents 8c11cca + 4709e7a commit e58d90c

3 files changed

Lines changed: 60 additions & 36 deletions

File tree

cmd/prcost/main.go

Lines changed: 12 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -255,8 +255,9 @@ func printHumanReadable(breakdown *cost.Breakdown, prURL string) {
255255
formatCurrency(breakdown.Author.GitHubContextCost), formatTimeUnit(breakdown.Author.GitHubContextHours))
256256
}
257257
fmt.Println(" ────────────")
258-
fmt.Printf(" Subtotal %12s %s\n",
259-
formatCurrency(breakdown.Author.TotalCost), formatTimeUnit(breakdown.Author.TotalHours))
258+
pct := (breakdown.Author.TotalCost / breakdown.TotalCost) * 100
259+
fmt.Printf(" Subtotal %12s %s (%.1f%%)\n",
260+
formatCurrency(breakdown.Author.TotalCost), formatTimeUnit(breakdown.Author.TotalHours), pct)
260261
fmt.Println()
261262
}
262263

@@ -291,8 +292,9 @@ func printHumanReadable(breakdown *cost.Breakdown, prURL string) {
291292
}
292293
}
293294
fmt.Println(" ────────────")
294-
fmt.Printf(" Subtotal %12s %s\n",
295-
formatCurrency(totalParticipantCost), formatTimeUnit(totalParticipantHours))
295+
pct := (totalParticipantCost / breakdown.TotalCost) * 100
296+
fmt.Printf(" Subtotal %12s %s (%.1f%%)\n",
297+
formatCurrency(totalParticipantCost), formatTimeUnit(totalParticipantHours), pct)
296298
fmt.Println()
297299
}
298300

@@ -343,8 +345,9 @@ func printDelayCosts(breakdown *cost.Breakdown, formatCurrency func(float64) str
343345
mergeDelayCost := breakdown.DelayCostDetail.DeliveryDelayCost + breakdown.DelayCostDetail.CoordinationCost
344346
mergeDelayHours := breakdown.DelayCostDetail.DeliveryDelayHours + breakdown.DelayCostDetail.CoordinationHours
345347
fmt.Println(" ────────────")
346-
fmt.Printf(" Subtotal %12s %s\n",
347-
formatCurrency(mergeDelayCost), formatTimeUnit(mergeDelayHours))
348+
pct := (mergeDelayCost / breakdown.TotalCost) * 100
349+
fmt.Printf(" Subtotal %12s %s (%.1f%%)\n",
350+
formatCurrency(mergeDelayCost), formatTimeUnit(mergeDelayHours), pct)
348351
fmt.Println()
349352

350353
// Future Costs
@@ -401,8 +404,9 @@ func printFutureCosts(breakdown *cost.Breakdown, formatCurrency func(float64) st
401404
breakdown.DelayCostDetail.FutureMergeHours +
402405
breakdown.DelayCostDetail.FutureContextHours
403406
fmt.Println(" ────────────")
404-
fmt.Printf(" Subtotal %12s %s\n",
405-
formatCurrency(futureCost), formatTimeUnit(futureHours))
407+
pct := (futureCost / breakdown.TotalCost) * 100
408+
fmt.Printf(" Subtotal %12s %s (%.1f%%)\n",
409+
formatCurrency(futureCost), formatTimeUnit(futureHours), pct)
406410
fmt.Println()
407411
}
408412

cmd/prcost/repository.go

Lines changed: 24 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -263,8 +263,9 @@ func printExtrapolatedResults(title string, days int, ext *cost.ExtrapolatedBrea
263263
fmt.Printf(" GitHub Context Switching %12s %s\n",
264264
formatWithCommas(avgAuthorGitHubContextCost), formatTimeUnit(avgAuthorGitHubContextHours))
265265
fmt.Println(" ────────────")
266-
fmt.Printf(" Subtotal %12s %s\n",
267-
formatWithCommas(avgAuthorTotalCost), formatTimeUnit(avgAuthorTotalHours))
266+
pct := (avgAuthorTotalCost / avgTotalCost) * 100
267+
fmt.Printf(" Subtotal %12s %s (%.1f%%)\n",
268+
formatWithCommas(avgAuthorTotalCost), formatTimeUnit(avgAuthorTotalHours), pct)
268269
fmt.Println()
269270

270271
// Participants section (if any participants)
@@ -282,8 +283,9 @@ func printExtrapolatedResults(title string, days int, ext *cost.ExtrapolatedBrea
282283
fmt.Printf(" Context Switching %12s %s\n",
283284
formatWithCommas(avgParticipantContextCost), formatTimeUnit(avgParticipantContextHours))
284285
fmt.Println(" ────────────")
285-
fmt.Printf(" Subtotal %12s %s\n",
286-
formatWithCommas(avgParticipantTotalCost), formatTimeUnit(avgParticipantTotalHours))
286+
pct := (avgParticipantTotalCost / avgTotalCost) * 100
287+
fmt.Printf(" Subtotal %12s %s (%.1f%%)\n",
288+
formatWithCommas(avgParticipantTotalCost), formatTimeUnit(avgParticipantTotalHours), pct)
287289
fmt.Println()
288290
}
289291

@@ -297,8 +299,9 @@ func printExtrapolatedResults(title string, days int, ext *cost.ExtrapolatedBrea
297299
avgMergeDelayCost := avgDeliveryDelayCost + avgCoordinationCost
298300
avgMergeDelayHours := avgDeliveryDelayHours + avgCoordinationHours
299301
fmt.Println(" ────────────")
300-
fmt.Printf(" Subtotal %12s %s\n",
301-
formatWithCommas(avgMergeDelayCost), formatTimeUnit(avgMergeDelayHours))
302+
pct = (avgMergeDelayCost / avgTotalCost) * 100
303+
fmt.Printf(" Subtotal %12s %s (%.1f%%)\n",
304+
formatWithCommas(avgMergeDelayCost), formatTimeUnit(avgMergeDelayHours), pct)
302305
fmt.Println()
303306

304307
// Future Costs section
@@ -337,8 +340,9 @@ func printExtrapolatedResults(title string, days int, ext *cost.ExtrapolatedBrea
337340
avgFutureCost := avgCodeChurnCost + avgFutureReviewCost + avgFutureMergeCost + avgFutureContextCost
338341
avgFutureHours := avgCodeChurnHours + avgFutureReviewHours + avgFutureMergeHours + avgFutureContextHours
339342
fmt.Println(" ────────────")
340-
fmt.Printf(" Subtotal %12s %s\n",
341-
formatWithCommas(avgFutureCost), formatTimeUnit(avgFutureHours))
343+
pct = (avgFutureCost / avgTotalCost) * 100
344+
fmt.Printf(" Subtotal %12s %s (%.1f%%)\n",
345+
formatWithCommas(avgFutureCost), formatTimeUnit(avgFutureHours), pct)
342346
fmt.Println()
343347
}
344348

@@ -368,8 +372,9 @@ func printExtrapolatedResults(title string, days int, ext *cost.ExtrapolatedBrea
368372
fmt.Printf(" GitHub Context Switching %12s %s\n",
369373
formatWithCommas(ext.AuthorGitHubContextCost), formatTimeUnit(ext.AuthorGitHubContextHours))
370374
fmt.Println(" ────────────")
371-
fmt.Printf(" Subtotal %12s %s\n",
372-
formatWithCommas(ext.AuthorTotalCost), formatTimeUnit(ext.AuthorTotalHours))
375+
pct = (ext.AuthorTotalCost / ext.TotalCost) * 100
376+
fmt.Printf(" Subtotal %12s %s (%.1f%%)\n",
377+
formatWithCommas(ext.AuthorTotalCost), formatTimeUnit(ext.AuthorTotalHours), pct)
373378
fmt.Println()
374379

375380
// Participants section (extrapolated, if any participants)
@@ -387,8 +392,9 @@ func printExtrapolatedResults(title string, days int, ext *cost.ExtrapolatedBrea
387392
fmt.Printf(" Context Switching %12s %s\n",
388393
formatWithCommas(ext.ParticipantContextCost), formatTimeUnit(ext.ParticipantContextHours))
389394
fmt.Println(" ────────────")
390-
fmt.Printf(" Subtotal %12s %s\n",
391-
formatWithCommas(ext.ParticipantTotalCost), formatTimeUnit(ext.ParticipantTotalHours))
395+
pct = (ext.ParticipantTotalCost / ext.TotalCost) * 100
396+
fmt.Printf(" Subtotal %12s %s (%.1f%%)\n",
397+
formatWithCommas(ext.ParticipantTotalCost), formatTimeUnit(ext.ParticipantTotalHours), pct)
392398
fmt.Println()
393399
}
394400

@@ -402,8 +408,9 @@ func printExtrapolatedResults(title string, days int, ext *cost.ExtrapolatedBrea
402408
extMergeDelayCost := ext.DeliveryDelayCost + ext.CoordinationCost
403409
extMergeDelayHours := ext.DeliveryDelayHours + ext.CoordinationHours
404410
fmt.Println(" ────────────")
405-
fmt.Printf(" Subtotal %12s %s\n",
406-
formatWithCommas(extMergeDelayCost), formatTimeUnit(extMergeDelayHours))
411+
pct = (extMergeDelayCost / ext.TotalCost) * 100
412+
fmt.Printf(" Subtotal %12s %s (%.1f%%)\n",
413+
formatWithCommas(extMergeDelayCost), formatTimeUnit(extMergeDelayHours), pct)
407414
fmt.Println()
408415

409416
// Future Costs section (extrapolated)
@@ -435,8 +442,9 @@ func printExtrapolatedResults(title string, days int, ext *cost.ExtrapolatedBrea
435442
extFutureCost := ext.CodeChurnCost + ext.FutureReviewCost + ext.FutureMergeCost + ext.FutureContextCost
436443
extFutureHours := ext.CodeChurnHours + ext.FutureReviewHours + ext.FutureMergeHours + ext.FutureContextHours
437444
fmt.Println(" ────────────")
438-
fmt.Printf(" Subtotal %12s %s\n",
439-
formatWithCommas(extFutureCost), formatTimeUnit(extFutureHours))
445+
pct = (extFutureCost / ext.TotalCost) * 100
446+
fmt.Printf(" Subtotal %12s %s (%.1f%%)\n",
447+
formatWithCommas(extFutureCost), formatTimeUnit(extFutureHours), pct)
440448
fmt.Println()
441449
}
442450

internal/server/static/index.html

Lines changed: 24 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -1078,7 +1078,8 @@ <h3>Why calculate PR costs?</h3>
10781078
output += ` GitHub Context Switching ${formatCurrency(b.author.github_context_cost).padStart(12)} ${formatTimeUnit(b.author.github_context_hours)}\n`;
10791079
}
10801080
output += ' ────────────\n';
1081-
output += ` Subtotal ${formatCurrency(b.author.total_cost).padStart(12)} ${formatTimeUnit(b.author.total_hours)}\n\n`;
1081+
let pct = (b.author.total_cost / b.total_cost) * 100;
1082+
output += ` Subtotal ${formatCurrency(b.author.total_cost).padStart(12)} ${formatTimeUnit(b.author.total_hours)} (${pct.toFixed(1)}%)\n\n`;
10821083

10831084
// Participants
10841085
if (b.participants && b.participants.length > 0) {
@@ -1097,7 +1098,8 @@ <h3>Why calculate PR costs?</h3>
10971098
output += ` Context Switching ${formatCurrency(p.github_context_cost).padStart(12)} ${formatTimeUnit(p.github_context_hours)}\n`;
10981099
});
10991100
output += ' ────────────\n';
1100-
output += ` Subtotal ${formatCurrency(totalParticipantCost).padStart(12)} ${formatTimeUnit(totalParticipantHours)}\n\n`;
1101+
pct = (totalParticipantCost / b.total_cost) * 100;
1102+
output += ` Subtotal ${formatCurrency(totalParticipantCost).padStart(12)} ${formatTimeUnit(totalParticipantHours)} (${pct.toFixed(1)}%)\n\n`;
11011103
}
11021104

11031105
// Delay and Future Costs - only show if there are any delay costs
@@ -1111,7 +1113,8 @@ <h3>Why calculate PR costs?</h3>
11111113
const mergeDelayCost = b.delay_cost_detail.delivery_delay_cost + b.delay_cost_detail.coordination_cost;
11121114
const mergeDelayHours = b.delay_cost_detail.delivery_delay_hours + b.delay_cost_detail.coordination_hours;
11131115
output += ' ────────────\n';
1114-
output += ` Subtotal ${formatCurrency(mergeDelayCost).padStart(12)} ${formatTimeUnit(mergeDelayHours)}\n\n`;
1116+
pct = (mergeDelayCost / b.total_cost) * 100;
1117+
output += ` Subtotal ${formatCurrency(mergeDelayCost).padStart(12)} ${formatTimeUnit(mergeDelayHours)} (${pct.toFixed(1)}%)\n\n`;
11151118

11161119
// Future Costs
11171120
const hasFuture = b.delay_cost_detail.rework_percentage > 0 ||
@@ -1141,7 +1144,8 @@ <h3>Why calculate PR costs?</h3>
11411144
const futureHours = b.delay_cost_detail.code_churn_hours + b.delay_cost_detail.future_review_hours +
11421145
b.delay_cost_detail.future_merge_hours + b.delay_cost_detail.future_context_hours;
11431146
output += ' ────────────\n';
1144-
output += ` Subtotal ${formatCurrency(futureCost).padStart(12)} ${formatTimeUnit(futureHours)}\n\n`;
1147+
pct = (futureCost / b.total_cost) * 100;
1148+
output += ` Subtotal ${formatCurrency(futureCost).padStart(12)} ${formatTimeUnit(futureHours)} (${pct.toFixed(1)}%)\n\n`;
11451149
}
11461150
}
11471151

@@ -1204,7 +1208,8 @@ <h3>Why calculate PR costs?</h3>
12041208
output += ` GitHub Activity ${formatCurrency(avgAuthorGitHubCost).padStart(12)} ${formatTimeUnit(avgAuthorGitHubHours)}\n`;
12051209
output += ` GitHub Context Switching ${formatCurrency(avgAuthorGitHubContextCost).padStart(12)} ${formatTimeUnit(avgAuthorGitHubContextHours)}\n`;
12061210
output += ' ────────────\n';
1207-
output += ` Subtotal ${formatCurrency(avgAuthorTotalCost).padStart(12)} ${formatTimeUnit(avgAuthorTotalHours)}\n\n`;
1211+
let pct = (avgAuthorTotalCost / avgTotalCost) * 100;
1212+
output += ` Subtotal ${formatCurrency(avgAuthorTotalCost).padStart(12)} ${formatTimeUnit(avgAuthorTotalHours)} (${pct.toFixed(1)}%)\n\n`;
12081213

12091214
// Participants
12101215
if (e.participant_total_cost > 0) {
@@ -1213,7 +1218,8 @@ <h3>Why calculate PR costs?</h3>
12131218
output += ` Review Activity ${formatCurrency(avgParticipantGitHubCost).padStart(12)} ${formatTimeUnit(avgParticipantGitHubHours)}\n`;
12141219
output += ` Context Switching ${formatCurrency(avgParticipantContextCost).padStart(12)} ${formatTimeUnit(avgParticipantContextHours)}\n`;
12151220
output += ' ────────────\n';
1216-
output += ` Subtotal ${formatCurrency(avgParticipantTotalCost).padStart(12)} ${formatTimeUnit(avgParticipantTotalHours)}\n\n`;
1221+
pct = (avgParticipantTotalCost / avgTotalCost) * 100;
1222+
output += ` Subtotal ${formatCurrency(avgParticipantTotalCost).padStart(12)} ${formatTimeUnit(avgParticipantTotalHours)} (${pct.toFixed(1)}%)\n\n`;
12171223
}
12181224

12191225
// Delay Costs
@@ -1224,7 +1230,8 @@ <h3>Why calculate PR costs?</h3>
12241230
const avgMergeDelayCost = avgDeliveryDelayCost + avgCoordinationCost;
12251231
const avgMergeDelayHours = avgDeliveryDelayHours + avgCoordinationHours;
12261232
output += ' ────────────\n';
1227-
output += ` Subtotal ${formatCurrency(avgMergeDelayCost).padStart(12)} ${formatTimeUnit(avgMergeDelayHours)}\n\n`;
1233+
pct = (avgMergeDelayCost / avgTotalCost) * 100;
1234+
output += ` Subtotal ${formatCurrency(avgMergeDelayCost).padStart(12)} ${formatTimeUnit(avgMergeDelayHours)} (${pct.toFixed(1)}%)\n\n`;
12281235

12291236
// Future Costs
12301237
const hasFuture = e.code_churn_cost > 0.01 || e.future_review_cost > 0.01 || e.future_merge_cost > 0.01 || e.future_context_cost > 0.01;
@@ -1246,7 +1253,8 @@ <h3>Why calculate PR costs?</h3>
12461253
const avgFutureCost = avgCodeChurnCost + avgFutureReviewCost + avgFutureMergeCost + avgFutureContextCost;
12471254
const avgFutureHours = avgCodeChurnHours + avgFutureReviewHours + avgFutureMergeHours + avgFutureContextHours;
12481255
output += ' ────────────\n';
1249-
output += ` Subtotal ${formatCurrency(avgFutureCost).padStart(12)} ${formatTimeUnit(avgFutureHours)}\n\n`;
1256+
pct = (avgFutureCost / avgTotalCost) * 100;
1257+
output += ` Subtotal ${formatCurrency(avgFutureCost).padStart(12)} ${formatTimeUnit(avgFutureHours)} (${pct.toFixed(1)}%)\n\n`;
12501258
}
12511259

12521260
// Average Total
@@ -1267,7 +1275,8 @@ <h3>Why calculate PR costs?</h3>
12671275
output += ` GitHub Activity ${formatCurrency(e.author_github_cost).padStart(12)} ${formatTimeUnit(e.author_github_hours)}\n`;
12681276
output += ` GitHub Context Switching ${formatCurrency(e.author_github_context_cost).padStart(12)} ${formatTimeUnit(e.author_github_context_hours)}\n`;
12691277
output += ' ────────────\n';
1270-
output += ` Subtotal ${formatCurrency(e.author_total_cost).padStart(12)} ${formatTimeUnit(e.author_total_hours)}\n\n`;
1278+
let pct = (e.author_total_cost / e.total_cost) * 100;
1279+
output += ` Subtotal ${formatCurrency(e.author_total_cost).padStart(12)} ${formatTimeUnit(e.author_total_hours)} (${pct.toFixed(1)}%)\n\n`;
12711280

12721281
// Participants
12731282
if (e.participant_total_cost > 0) {
@@ -1276,7 +1285,8 @@ <h3>Why calculate PR costs?</h3>
12761285
output += ` Review Activity ${formatCurrency(e.participant_github_cost).padStart(12)} ${formatTimeUnit(e.participant_github_hours)}\n`;
12771286
output += ` Context Switching ${formatCurrency(e.participant_context_cost).padStart(12)} ${formatTimeUnit(e.participant_context_hours)}\n`;
12781287
output += ' ────────────\n';
1279-
output += ` Subtotal ${formatCurrency(e.participant_total_cost).padStart(12)} ${formatTimeUnit(e.participant_total_hours)}\n\n`;
1288+
pct = (e.participant_total_cost / e.total_cost) * 100;
1289+
output += ` Subtotal ${formatCurrency(e.participant_total_cost).padStart(12)} ${formatTimeUnit(e.participant_total_hours)} (${pct.toFixed(1)}%)\n\n`;
12801290
}
12811291

12821292
// Delay Costs
@@ -1287,7 +1297,8 @@ <h3>Why calculate PR costs?</h3>
12871297
const mergeDelayCost = e.delivery_delay_cost + e.coordination_cost;
12881298
const mergeDelayHours = e.delivery_delay_hours + e.coordination_hours;
12891299
output += ' ────────────\n';
1290-
output += ` Subtotal ${formatCurrency(mergeDelayCost).padStart(12)} ${formatTimeUnit(mergeDelayHours)}\n\n`;
1300+
pct = (mergeDelayCost / e.total_cost) * 100;
1301+
output += ` Subtotal ${formatCurrency(mergeDelayCost).padStart(12)} ${formatTimeUnit(mergeDelayHours)} (${pct.toFixed(1)}%)\n\n`;
12911302

12921303
// Future Costs
12931304
const hasFuture = e.code_churn_cost > 0.01 || e.future_review_cost > 0.01 || e.future_merge_cost > 0.01 || e.future_context_cost > 0.01;
@@ -1309,7 +1320,8 @@ <h3>Why calculate PR costs?</h3>
13091320
const futureCost = e.code_churn_cost + e.future_review_cost + e.future_merge_cost + e.future_context_cost;
13101321
const futureHours = e.code_churn_hours + e.future_review_hours + e.future_merge_hours + e.future_context_hours;
13111322
output += ' ────────────\n';
1312-
output += ` Subtotal ${formatCurrency(futureCost).padStart(12)} ${formatTimeUnit(futureHours)}\n\n`;
1323+
pct = (futureCost / e.total_cost) * 100;
1324+
output += ` Subtotal ${formatCurrency(futureCost).padStart(12)} ${formatTimeUnit(futureHours)} (${pct.toFixed(1)}%)\n\n`;
13131325
}
13141326

13151327
// Total

0 commit comments

Comments
 (0)