Skip to content

Commit 70de9bc

Browse files
authored
Merge pull request #200 from hossain-khan/feature/51-use-initial-time-in-reports-and-csv
[ADDED] #51 Initial response time in the CSV and HTML report
2 parents 1087fb6 + 7730a10 commit 70de9bc

File tree

6 files changed

+42
-15
lines changed

6 files changed

+42
-15
lines changed

src/main/kotlin/dev/hossain/githubstats/PrAuthorStatsService.kt

+12-10
Original file line numberDiff line numberDiff line change
@@ -30,12 +30,12 @@ class PrAuthorStatsService constructor(
3030
*
3131
* For example, assume 'Bob' is a contributor on a specific repo called 'Awesome Json Library'.
3232
* This will be generated PR reviews for all the PRs 'Bob' has created and will be grouped by
33-
* all the PR authors like 'Sally', 'Mike', 'Jim' and so on.
33+
* all the PR reviewers like 'Sally', 'Mike', 'Jim' and so on.
3434
*
3535
* ```
36-
* Sally -> 78 PRs reviewed; Average Review Time: 2 hours 8 min
37-
* Mike -> 42 PRs reviewed; Average Review Time: 8 hours 32 min
38-
* Jim -> 13 PRs reviewed; Average Review Time: 14 hours 21 min
36+
* Sally -> 78 PRs reviewed for Bob; Average Review Time: 2 hours 8 min
37+
* Mike -> 42 PRs reviewed for Bob; Average Review Time: 8 hours 32 min
38+
* Jim -> 13 PRs reviewed for Bob; Average Review Time: 14 hours 21 min
3939
* ```
4040
*/
4141
suspend fun authorStats(
@@ -73,7 +73,7 @@ class PrAuthorStatsService constructor(
7373
)
7474
} catch (e: Exception) {
7575
val error = errorProcessor.getDetailedError(e)
76-
println("Error getting PR#${pr.number}. Got: ${error.message}")
76+
Log.w("Error getting PR#${pr.number}. Got: ${error.message}")
7777
StatsResult.Failure(error)
7878
}
7979
}
@@ -88,18 +88,20 @@ class PrAuthorStatsService constructor(
8888
val userReviews = mutableMapOf<UserId, List<ReviewStats>>()
8989
prStatsList.filter { it.prApprovalTime.isNotEmpty() }
9090
.forEach { stats: PrStats ->
91-
stats.prApprovalTime.forEach { (user, time) ->
91+
stats.prApprovalTime.forEach { (userId, time) ->
9292
val reviewStats = ReviewStats(
93+
reviewerUserId = userId,
9394
pullRequest = stats.pullRequest,
9495
reviewCompletion = time,
95-
prComments = stats.comments[user] ?: noComments(user),
96+
initialResponseTime = stats.initialResponseTime[userId] ?: time,
97+
prComments = stats.comments[userId] ?: noComments(userId),
9698
prReadyOn = stats.prReadyOn,
9799
prMergedOn = stats.prMergedOn
98100
)
99-
if (userReviews.containsKey(user)) {
100-
userReviews[user] = userReviews[user]!!.plus(reviewStats)
101+
if (userReviews.containsKey(userId)) {
102+
userReviews[userId] = userReviews[userId]!!.plus(reviewStats)
101103
} else {
102-
userReviews[user] = listOf(reviewStats)
104+
userReviews[userId] = listOf(reviewStats)
103105
}
104106
}
105107
}

src/main/kotlin/dev/hossain/githubstats/PrReviewerStatsService.kt

+4-1
Original file line numberDiff line numberDiff line change
@@ -78,9 +78,12 @@ class PrReviewerStatsService constructor(
7878
it.prApprovalTime.containsKey(prReviewerUserId)
7979
}
8080
.map { stats ->
81+
val prApprovalTime = stats.prApprovalTime[prReviewerUserId]!!
8182
ReviewStats(
83+
reviewerUserId = prReviewerUserId,
8284
pullRequest = stats.pullRequest,
83-
reviewCompletion = stats.prApprovalTime[prReviewerUserId]!!,
85+
reviewCompletion = prApprovalTime,
86+
initialResponseTime = stats.initialResponseTime[prReviewerUserId] ?: prApprovalTime,
8487
prComments = stats.comments[prReviewerUserId] ?: noComments(prReviewerUserId),
8588
prReadyOn = stats.prReadyOn,
8689
prMergedOn = stats.prMergedOn

src/main/kotlin/dev/hossain/githubstats/ReviewStats.kt

+11-1
Original file line numberDiff line numberDiff line change
@@ -50,7 +50,11 @@ data class PrStats(
5050
/**
5151
* PR review stats for a specific author.
5252
*/
53-
data class ReviewStats(
53+
data class ReviewStats constructor(
54+
/**
55+
* User who has reviewer the PR.
56+
*/
57+
val reviewerUserId: UserId,
5458
/**
5559
* The PR information including PR number and URL.
5660
*/
@@ -61,6 +65,12 @@ data class ReviewStats(
6165
*/
6266
val reviewCompletion: Duration,
6367

68+
/**
69+
* The initial response time indicates the time it took for reviewer to first respond to PR
70+
* by either commenting, reviewing or approving the PR.
71+
*/
72+
val initialResponseTime: Duration,
73+
6474
/**
6575
* Contains PR issue comment and review comment count by a specific user.
6676
*/

src/main/kotlin/dev/hossain/githubstats/formatter/CsvFormatter.kt

+11-1
Original file line numberDiff line numberDiff line change
@@ -4,9 +4,11 @@ import com.github.doyaaaaaken.kotlincsv.dsl.csvWriter
44
import dev.hossain.ascii.Art
55
import dev.hossain.githubstats.AuthorReviewStats
66
import dev.hossain.githubstats.PrStats
7+
import dev.hossain.githubstats.ReviewStats
78
import dev.hossain.githubstats.ReviewerReviewStats
89
import dev.hossain.githubstats.util.FileUtil
910
import dev.hossain.githubstats.util.LocalProperties
11+
import dev.hossain.time.toWorkingHour
1012
import org.koin.core.component.KoinComponent
1113
import org.koin.core.component.inject
1214
import kotlin.time.DurationUnit
@@ -50,6 +52,7 @@ class CsvFormatter : StatsFormatter, KoinComponent {
5052
"Reviewer",
5153
"PR Number",
5254
"Review time (mins)",
55+
"Initial Response time (mins)",
5356
"Code Review Comments",
5457
"PR Issue Comments",
5558
"PR Review Comments",
@@ -65,6 +68,7 @@ class CsvFormatter : StatsFormatter, KoinComponent {
6568
stat.reviewerId, /* "Reviewer" */
6669
"PR ${reviewStats.pullRequest.number}", /* "PR Number" */
6770
"${reviewStats.reviewCompletion.toInt(DurationUnit.MINUTES)}", /* "Review time (mins)" */
71+
"${reviewStats.initialResponseTime.toInt(DurationUnit.MINUTES)}", /* "Initial Response time (mins)" */
6872
"${reviewStats.prComments.codeReviewComment}", /* "Code Review Comments" */
6973
"${reviewStats.prComments.issueComment}", /* "PR Issue Comments" */
7074
"${reviewStats.prComments.prReviewComment}", /* "PR Review Comments" */
@@ -126,7 +130,10 @@ class CsvFormatter : StatsFormatter, KoinComponent {
126130
listOf(
127131
"PR#",
128132
"Review Time",
133+
"Review Time (working days)",
129134
"Review Time (mins)",
135+
"Initial Response Time (working days)",
136+
"Initial Response Time (mins)",
130137
"Code Review Comments",
131138
"PR Issue Comments",
132139
"PR Review Comments",
@@ -138,11 +145,14 @@ class CsvFormatter : StatsFormatter, KoinComponent {
138145
"PR URL"
139146
)
140147
)
141-
stats.reviewedPrStats.forEach { reviewStats ->
148+
stats.reviewedPrStats.forEach { reviewStats: ReviewStats ->
142149
writeRow(
143150
reviewStats.pullRequest.number,
144151
reviewStats.reviewCompletion,
152+
reviewStats.reviewCompletion.toWorkingHour(),
145153
reviewStats.reviewCompletion.toInt(DurationUnit.MINUTES),
154+
reviewStats.initialResponseTime.toWorkingHour(),
155+
reviewStats.initialResponseTime.toInt(DurationUnit.MINUTES),
146156
reviewStats.prComments.codeReviewComment,
147157
reviewStats.prComments.issueComment,
148158
reviewStats.prComments.prReviewComment,

src/main/kotlin/dev/hossain/githubstats/formatter/HtmlChartFormatter.kt

+3-1
Original file line numberDiff line numberDiff line change
@@ -93,7 +93,7 @@ class HtmlChartFormatter : StatsFormatter, KoinComponent {
9393
"[" +
9494
"'Reviewed For different PR Authors', " +
9595
"'Total PRs Reviewed by ${stats.reviewerId} since ${appConfig.get().dateLimitAfter}', " +
96-
"'Total Code Review Comments', " +
96+
"'Total Source Code Review Comments', " +
9797
"'Total PR Issue Comments', " +
9898
"'Total PR Review Comments', " +
9999
"'Total All Comments Made'" +
@@ -136,13 +136,15 @@ class HtmlChartFormatter : StatsFormatter, KoinComponent {
136136
"" +
137137
"[" +
138138
"'PR#', " +
139+
"'Initial Response Time (mins)'," +
139140
"'Review Time (mins)'" +
140141
"]"
141142
).plus(
142143
stats.reviewedPrStats.map { reviewStats ->
143144
"" +
144145
"[" +
145146
"'PR# ${reviewStats.pullRequest.number}', " +
147+
"${reviewStats.initialResponseTime.toInt(DurationUnit.MINUTES)}," +
146148
"${reviewStats.reviewCompletion.toInt(DurationUnit.MINUTES)}" +
147149
"]"
148150
}

src/main/kotlin/dev/hossain/githubstats/repository/PullRequestStatsRepoImpl.kt

+1-1
Original file line numberDiff line numberDiff line change
@@ -198,7 +198,7 @@ class PullRequestStatsRepoImpl(
198198
endInstant = firstReviewedEvent.submitted_at.toInstant(),
199199
timeZoneId = userTimeZone.get(prReviewerUserId)
200200
)
201-
Log.i(" -- First Responded[${firstReviewedEvent.state.name.lowercase()}] in `$reviewTimeInWorkingHours` by `$prReviewerUserId`.")
201+
Log.d(" -- First Responded[${firstReviewedEvent.state.name.lowercase()}] in `$reviewTimeInWorkingHours` by `$prReviewerUserId`.")
202202
Log.v(
203203
" -- 🔍👀 Initial response event: $firstReviewedEvent. PR available on ${prAvailableForReviewOn.format()} " +
204204
"and event on ${firstReviewedEvent.submitted_at.toInstant().format()}"

0 commit comments

Comments
 (0)