Skip to content

Commit

Permalink
Allow showing by author
Browse files Browse the repository at this point in the history
  • Loading branch information
AlecKazakova committed Jun 27, 2020
1 parent 6e7fbe0 commit ab48244
Showing 1 changed file with 68 additions and 11 deletions.
79 changes: 68 additions & 11 deletions src/main/kotlin/com/alecstrong/conway/main.kt
Original file line number Diff line number Diff line change
Expand Up @@ -14,17 +14,20 @@ fun main(vararg args: String) {
ConwayCli().main(args.toList())
}

internal class ConwayCli: CliktCommand(name = "conway") {
val folder by option("-D",
internal class ConwayCli : CliktCommand(name = "conway") {
val folder by option("--folders",
help = "Input directories <directory1>,<directory2>").split(",")
val author by option("--author", help = "alias to search by")
val since: String? by option("--since")

private val inFolderCommits = mutableMapOf<String, Int>()
private val allCommits = mutableMapOf<String, Int>()

private fun InputStream.forCommits(body: (email: String, changed: Int, file: String) -> Unit) {
InputStreamReader(this).useLines { sequence ->
val iterator = sequence.iterator()

if (!iterator.hasNext()) {
echo("There were no commits for the given arguments", err = true)
return
}
iterator.next() // Skip initial newline

while (iterator.hasNext()) {
Expand All @@ -48,13 +51,19 @@ internal class ConwayCli: CliktCommand(name = "conway") {
}
}

override fun run() {
val since = if (since == null) "" else "--since=\"$since\""
private fun contributionsByFolders(folders: List<String>) {
val inFolderCommits = mutableMapOf<String, Int>()
val allCommits = mutableMapOf<String, Int>()

val args = mutableListOf("git", "log", "--numstat")
if (since != null) {
args.add("--since=\"$since\"")
}
args.add("--no-merges")
args.add("--pretty=%n%ae")

Runtime.getRuntime().exec(
arrayOf("git", "log", "--numstat", since, "--no-merges",
"--pretty=%n%ae")).inputStream.forCommits { email, changed, file ->
if (folder!!.any { file.startsWith(it) }) {
Runtime.getRuntime().exec(args.toTypedArray()).inputStream.forCommits { email, changed, file ->
if (folders.any { file.startsWith(it) }) {
inFolderCommits[email] = inFolderCommits.getOrDefault(email, 0) + changed
}
allCommits[email] = allCommits.getOrDefault(email, 0) + changed
Expand Down Expand Up @@ -95,6 +104,54 @@ internal class ConwayCli: CliktCommand(name = "conway") {
}
}

private fun contributionsByAuthor(author: String) {
val folderCommits = mutableMapOf<String, Long>()

val folders = folder ?: listOf("") //default to root

val args = mutableListOf("git", "log", "--numstat", "--author", author)
if (since != null) {
args.add("--since=\"$since\"")
}
args.add("--no-merges")
args.add("--pretty=%n%ae")

echo("Finding folders with 1% or greater contributions for $author")

Runtime.getRuntime().exec(args.toTypedArray()).inputStream.forCommits { _, changed, file ->
val folder = folders.firstOrNull { file.startsWith(it) } ?: return@forCommits
val nextLevelDirectory = file.substringAfter(folder).trim('/').substringBefore('/')

folderCommits[nextLevelDirectory] = folderCommits.getOrDefault(nextLevelDirectory, 0) + changed
}

val totalChanges = folderCommits.values.sum()

folderCommits.mapNotNull { (folder, changes) ->
val percentageInFolder = changes
.toBigDecimal()
.multiply(BigDecimal.valueOf(100))
.divide(totalChanges.toBigDecimal(), 2, RoundingMode.HALF_UP)

return@mapNotNull if (percentageInFolder >= BigDecimal.valueOf(1)) {
folder to percentageInFolder
} else {
null
}
}.sortedByDescending { it.second }
.forEach { (folder, changes) ->
echo("$author writes ${changes.toPlainString()}% of their code in $folder")
}
}

override fun run() {
if (author != null) {
contributionsByAuthor(author!!)
} else if (folder != null) {
contributionsByFolders(folder!!)
}
}

private data class Contribution(
val author: String,
val percentageInFolder: BigDecimal,
Expand Down

0 comments on commit ab48244

Please sign in to comment.