首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >通过regex匹配总结git提交的Kotlin程序

通过regex匹配总结git提交的Kotlin程序
EN

Code Review用户
提问于 2018-07-16 23:31:35
回答 1查看 159关注 0票数 2

我在努力学习科特林。我来自Java的一些背景。作为一个学习练习,我编写了这个简单的程序来总结作者电子邮件在git存储库列表中出现的字符串。

我很好奇我是否在用一种习惯的Kotlin方式来对待事物。扩展函数是很棒的,但我怀疑这是我不应该过度使用的东西。

我计划让它成为一个命令行应用程序,并可能使用递归从源目录获取git存储库,而不显式地提供它们。不过,在我走得太远之前,我想看看如何改进我所拥有的一切。

任何反馈都是非常感谢的!

代码语言:javascript
复制
import java.io.File
import java.time.OffsetDateTime
import java.time.format.DateTimeFormatter
import java.util.concurrent.TimeUnit
import java.util.regex.Pattern
import kotlin.concurrent.thread

data class CommitSummary(
        var author: String,
        var regexString: String,
        var count: Int)

data class Commit(
        var commit: String = "",
        var author: String = "",
        var date: OffsetDateTime? = null,
        var message: String = "")

fun main(args: Array<String>) {

    val cmd = "git log --all --branches=* --remotes=*"
    val matchStr = "d'{0,1}oh" //case-insensitive
    val gitDir = "C:\\dev\\git\\"

    arrayListOf("repo-1", "repo-2")
            .forEach { repo ->
                thread {
                    val log = cmd.run(File(gitDir + repo), createTempFile())
                    val commits = log.parseGitLog()
                    val summaries = commits.summarizeGitMessages(matchStr)
                    summaries.forEach { author, summary ->
                        println(String.format("repo: %s, author: %s, %s count: %s", repo, author, summary.regexString, summary.count))
                    }
                }
            }
}

fun File.parseGitLog(): ArrayList<Commit> {
    return this.readLines().fold(arrayListOf()) { accumulated, current ->

        val startingWord = current.split("\\s".toRegex())[0]

        when (startingWord) {
            "commit" -> accumulated.add(Commit(current.split("\\s".toRegex())[1]))
            "Author:" -> accumulated.last().author = current.substring(current.indexOf("<") + 1, current.indexOf(">"))
            "Date:" -> accumulated.last().date = current.split("Date:")[1].trim().parseGitDateString()
            else -> accumulated.last().message += current.trim()
        }

        return@fold accumulated
    }
}

fun ArrayList<Commit>.summarizeGitMessages(regexString: String): MutableMap<String, CommitSummary> {
    val pattern = Pattern.compile(regexString, Pattern.MULTILINE or Pattern.CASE_INSENSITIVE)

    return this.fold(mutableMapOf()) { acc, commit ->
        val summary: CommitSummary = acc.getOrPut(commit.author) { CommitSummary(commit.author, regexString, 0) }
        val match = pattern.matcher(commit.message)
        while (match.find()) {
            summary.count = summary.count.plus(1)
        }
        return@fold acc
    }
}

// string extensions
fun String.run(workingDir: File, targetFile: File = File("C:\\dev\\tmpFile")): File {

    if (targetFile.exists()) {
        targetFile.delete()
    }

    ProcessBuilder(*split(" ").toTypedArray())
            .directory(workingDir)
            .redirectOutput(ProcessBuilder.Redirect.appendTo(targetFile))
            .redirectError(ProcessBuilder.Redirect.INHERIT)
            .start()
            .waitFor(60, TimeUnit.MINUTES)

    return targetFile
}

fun String.parseGitDateString(format: DateTimeFormatter = DateTimeFormatter.ofPattern("EEE MMM d HH:mm:ss yyyy Z")): OffsetDateTime {
    return OffsetDateTime.parse(this, format)
}
EN

回答 1

Code Review用户

发布于 2018-07-17 06:56:12

我从来没有使用过Kotlin,所以我不能给出一个全面的回顾或评论,特别是具体的成语。

我对这一行有点困扰,因为null对象看起来非常像Kotlin范式通常试图避免的Java习惯。

代码语言:javascript
复制
var date: OffsetDateTime? = null,

在我看来,Commit是一种在构造时应该知道其值的东西,所以请考虑使用数据类构造函数

我对这句话也有点紧张:

代码语言:javascript
复制
val gitDir = "C:\\dev\\git\\"

File(gitDir + repo)

我知道您将参数化您想要使用的存储库列表。当你这么做的时候,它是值得思考的事情,如跨平台的可用性。我不能给出具体的建议,但通常最好是使用某种文件系统库,而不是将这样的字符串拼接在一起。

代码语言:javascript
复制
// string extensions
fun String.run(workingDir: File, targetFile: File = File("C:\\dev\\tmpFile")): File 

类扩展是一种非常酷的功能,但它也让人觉得使用这种能力是一种危险的做法。根据经验,您将不会有一个对该类的任何实例运行都没有意义和合法的类方法,同样,在添加对类的大多数版本没有意义的扩展时也要小心。因为matchStr.run(...)没有任何意义,所以我怀疑会像这样扩展String。我想说的是,要么为可运行的字符串拥有一个特定的类,要么只有一个函数将该字符串作为参数运行。

票数 1
EN
页面原文内容由Code Review提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://codereview.stackexchange.com/questions/199638

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档