Scripts/convention/src/main/kotlin/io/gitlab/jfronny/scripts/CommitType.kt

51 lines
2.3 KiB
Kotlin

package io.gitlab.jfronny.scripts
enum class CommitType {
FIX, FEAT, BREAKING;
companion object {
private val conventionalPattern = Regex("^(\\w+)(\\(([\\w\\-.,\\s:]+)\\)?)?(!?)[\\s?]*:(.+)")
private val footerPattern = Regex("^(BREAKING[ -]CHANGE|[^ ]+)(((: )|( #))(.+))")
fun from(commitMessage: String, warn: (String) -> Unit): CommitType {
val lines = commitMessage.trim().split("\\r?\\n")
val headerMatch = conventionalPattern.matchEntire(extractHeader(lines[0]))
if (headerMatch == null) {
warn("Could not parse commit, guessing type is FEAT: $commitMessage")
return FEAT
}
if (headerMatch.groupValues[3] == "!") return BREAKING
for (s in lines.drop(1).filterNot { it.isBlank() }) {
val footerMatch = footerPattern.matchEntire(s)
if (footerMatch != null) {
val type = footerMatch.groupValues[1].lowercase()
if (type == "breaking change" || type == "breaking-change") return BREAKING
}
}
return when (headerMatch.groupValues[1].lowercase()) {
"fix", "build", "chore", "ci", "docs", "style", "refactor", "perf", "test" -> FIX
"feat" -> FEAT
"breaking change", "breaking" -> BREAKING
else -> {
warn("Unrecognized commit type: ${headerMatch.groupValues[1]}, guessing FEAT")
FEAT
}
}
}
private val revertPattern = Regex("^Revert \"(.+)\"", RegexOption.IGNORE_CASE)
private val reapplyPattern = Regex("^Reapply \"(.+)\"", RegexOption.IGNORE_CASE)
private tailrec fun extractHeader(headerLine: String): String {
if (headerLine.startsWith("Revert ")) {
val revertMatch = revertPattern.matchEntire(headerLine)
if (revertMatch != null) return extractHeader(revertMatch.groupValues[1])
}
if (headerLine.startsWith("Reapply ")) {
val reapplyMatch = reapplyPattern.matchEntire(headerLine)
if (reapplyMatch != null) return extractHeader(reapplyMatch.groupValues[1])
}
return headerLine
}
}
}