mirror of
https://gitflic.ru/project/openide/openide.git
synced 2026-09-27 10:03:11 +07:00
[Kotlin] YT-issue commit handler: filter & tests
This commit adds 'fleet/plugins/kotlin' to the list of paths to exclude from the check. It also introduces tests covering filtering and message validation. GitOrigin-RevId: 3114df66be4ce73deb8a6483e4503b4f8164d135
This commit is contained in:
committed by
intellij-monorepo-bot
parent
aa66a7591a
commit
97ad13d9df
@@ -6,6 +6,7 @@
|
||||
<sourceFolder url="file://$MODULE_DIR$/src" isTestSource="false" packagePrefix="org.jetbrains.idea.devkit" />
|
||||
<sourceFolder url="file://$MODULE_DIR$/gen" isTestSource="false" generated="true" />
|
||||
<sourceFolder url="file://$MODULE_DIR$/resources" type="java-resource" />
|
||||
<sourceFolder url="file://$MODULE_DIR$/testSrc" isTestSource="true" />
|
||||
</content>
|
||||
<orderEntry type="inheritedJdk" />
|
||||
<orderEntry type="sourceFolder" forTests="false" />
|
||||
@@ -63,5 +64,6 @@
|
||||
<orderEntry type="module" module-name="intellij.platform.ide.util.netty" />
|
||||
<orderEntry type="library" name="CGLIB" level="project" />
|
||||
<orderEntry type="module" module-name="intellij.platform.bootstrap" />
|
||||
<orderEntry type="library" scope="TEST" name="JUnit4" level="project" />
|
||||
</component>
|
||||
</module>
|
||||
@@ -13,26 +13,36 @@ import com.intellij.util.PairConsumer
|
||||
import com.intellij.util.io.systemIndependentPath
|
||||
import org.jetbrains.idea.devkit.DevKitBundle
|
||||
import org.jetbrains.idea.devkit.util.PsiUtil
|
||||
import java.io.File
|
||||
import kotlin.io.path.extension
|
||||
import kotlin.io.path.isRegularFile
|
||||
|
||||
class KotlinPluginCommitMessageHandlerFactory : CheckinHandlerFactory() {
|
||||
|
||||
companion object {
|
||||
private const val kotlinPluginPath = "plugins/kotlin/"
|
||||
private val pathsToIgnore = setOf("/test/", "/testData/")
|
||||
private val fileExtensionsNotToTrack = setOf("iml", "md")
|
||||
private val commitMessageRegex = Regex(".*KTIJ-\\d+.*", RegexOption.DOT_MATCHES_ALL /* line breaks matter */)
|
||||
}
|
||||
|
||||
override fun createHandler(panel: CheckinProjectPanel, commitContext: CommitContext): CheckinHandler =
|
||||
YouTrackIssueCommitMessageHandler(panel)
|
||||
|
||||
|
||||
private class YouTrackIssueCommitMessageHandler(private val checkinPanel: CheckinProjectPanel) : CheckinHandler() {
|
||||
internal class YouTrackIssueCommitMessageHandler(private val checkinPanel: CheckinProjectPanel) : CheckinHandler() {
|
||||
|
||||
companion object {
|
||||
const val HANDLER_ENABLED_KEY = "kotlin.commit.message.validation.enabled"
|
||||
private const val HANDLER_ENABLED_KEY = "kotlin.commit.message.validation.enabled"
|
||||
private const val KOTLIN_PLUGIN_PATH = "plugins/kotlin/"
|
||||
private val pathsToIgnore = setOf("/test/", "/testData/", "/fleet/plugins/kotlin/")
|
||||
private val fileExtensionsNotToTrack = setOf("iml", "md")
|
||||
private val commitMessageRegex = Regex(".*KTIJ-\\d+.*", RegexOption.DOT_MATCHES_ALL /* line breaks matter */)
|
||||
|
||||
internal fun selectedFilesBelongToKotlinIdePlugin(files: Collection<File>): Boolean {
|
||||
return files.asSequence()
|
||||
.map { file -> file.toPath() }
|
||||
.any { path ->
|
||||
val siPath = path.systemIndependentPath
|
||||
path.extension !in fileExtensionsNotToTrack
|
||||
&& siPath.contains(KOTLIN_PLUGIN_PATH)
|
||||
&& pathsToIgnore.none { siPath.contains(it) }
|
||||
}
|
||||
}
|
||||
|
||||
internal fun commitMessageIsCorrect(message: String): Boolean = message.matches(commitMessageRegex)
|
||||
}
|
||||
|
||||
private val project = checkinPanel.project
|
||||
@@ -52,7 +62,7 @@ class KotlinPluginCommitMessageHandlerFactory : CheckinHandlerFactory() {
|
||||
|
||||
if (!messageHandlerEnabled
|
||||
|| !commitMessageShouldBeChecked()
|
||||
|| checkinPanel.commitMessage.matches(commitMessageRegex)
|
||||
|| commitMessageIsCorrect(checkinPanel.commitMessage)
|
||||
) {
|
||||
return ReturnResult.COMMIT // as is
|
||||
}
|
||||
@@ -73,18 +83,6 @@ class KotlinPluginCommitMessageHandlerFactory : CheckinHandlerFactory() {
|
||||
}
|
||||
|
||||
private fun commitMessageShouldBeChecked(): Boolean =
|
||||
PsiUtil.isIdeaProject(project) && selectedFilesBelongToKotlinIdePlugin()
|
||||
|
||||
private fun selectedFilesBelongToKotlinIdePlugin(): Boolean {
|
||||
return checkinPanel.files.asSequence()
|
||||
.map { file -> file.toPath() }
|
||||
.any { path ->
|
||||
val siPath = path.systemIndependentPath
|
||||
path.isRegularFile()
|
||||
&& path.extension !in fileExtensionsNotToTrack
|
||||
&& siPath.contains(kotlinPluginPath)
|
||||
&& pathsToIgnore.none { siPath.contains(it) }
|
||||
}
|
||||
}
|
||||
PsiUtil.isIdeaProject(project) && selectedFilesBelongToKotlinIdePlugin(checkinPanel.files)
|
||||
}
|
||||
}
|
||||
+276
@@ -0,0 +1,276 @@
|
||||
// Copyright 2000-2021 JetBrains s.r.o. and contributors. Use of this source code is governed by the Apache 2.0 license.
|
||||
package org.jetbrains.idea.devkit.commit
|
||||
|
||||
import org.jetbrains.idea.devkit.commit.KotlinPluginCommitMessageHandlerFactory.YouTrackIssueCommitMessageHandler
|
||||
import org.junit.Test
|
||||
import org.junit.experimental.runners.Enclosed
|
||||
import org.junit.runner.RunWith
|
||||
import org.junit.runners.Parameterized
|
||||
import org.junit.runners.Parameterized.Parameter
|
||||
import java.io.File
|
||||
import java.nio.file.Paths
|
||||
|
||||
@RunWith(Enclosed::class)
|
||||
class KotlinYouTrackIssueCommitMessageHandlerTest {
|
||||
|
||||
@RunWith(Parameterized::class)
|
||||
class FilesBelongToPlugin {
|
||||
companion object {
|
||||
@JvmStatic
|
||||
@Parameterized.Parameters(name = "{0}")
|
||||
fun provideTestParameters(): Iterable<List<Pair<String, String>>> {
|
||||
return listOf(
|
||||
listOf(ULTIMATE_KOTLIN_PLUGIN to "File.kt"),
|
||||
listOf(COMMUNITY_KOTLIN_PLUGIN to "File.kt"),
|
||||
|
||||
listOf(ULTIMATE_KOTLIN_PLUGIN to "File.kts"),
|
||||
listOf(COMMUNITY_KOTLIN_PLUGIN to "File.kts"),
|
||||
|
||||
listOf(ULTIMATE_KOTLIN_PLUGIN to "File.java"),
|
||||
listOf(COMMUNITY_KOTLIN_PLUGIN to "File.java"),
|
||||
|
||||
listOf(ULTIMATE_KOTLIN_PLUGIN to "File.properties"),
|
||||
listOf(COMMUNITY_KOTLIN_PLUGIN to "File.properties"),
|
||||
|
||||
listOf(ULTIMATE_KOTLIN_PLUGIN to "File.html"),
|
||||
listOf(COMMUNITY_KOTLIN_PLUGIN to "File.html"),
|
||||
|
||||
listOf(ULTIMATE_KOTLIN_PLUGIN to "File.xml"),
|
||||
listOf(COMMUNITY_KOTLIN_PLUGIN to "File.xml"),
|
||||
|
||||
listOf(
|
||||
COMMUNITY_KOTLIN_PLUGIN to "File.kt",
|
||||
"not-important-dir-A" to "whatever-file",
|
||||
"not-important-dir-B" to "whatever-file"
|
||||
),
|
||||
|
||||
listOf(
|
||||
"not-important-dir-A" to "whatever-file",
|
||||
COMMUNITY_KOTLIN_PLUGIN to "File.kt",
|
||||
"not-important-dir-B" to "whatever-file"
|
||||
),
|
||||
|
||||
listOf(
|
||||
"not-important-dir-A" to "whatever-file",
|
||||
"not-important-dir-B" to "whatever-file",
|
||||
COMMUNITY_KOTLIN_PLUGIN to "File.kt"
|
||||
)
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
@Parameter
|
||||
lateinit var files: List<Pair<String, String>>
|
||||
|
||||
@Test
|
||||
fun testThatChecksForFileSet() {
|
||||
val filesSet = files.map { fileAt(it.first, it.second) }
|
||||
assert(YouTrackIssueCommitMessageHandler.selectedFilesBelongToKotlinIdePlugin(filesSet)) {
|
||||
"The following set of files doesn't trigger the check: $filesSet"
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@RunWith(Parameterized::class)
|
||||
class FilesDoNotBelongToPlugin {
|
||||
companion object {
|
||||
@JvmStatic
|
||||
@Parameterized.Parameters(name = "{0}")
|
||||
fun provideTestParameters(): Iterable<List<Pair<String, String>>> {
|
||||
return listOf(
|
||||
// file path has no kotlin-plugin subdirectory
|
||||
listOf("not-important-dir" to "File.kt"),
|
||||
listOf(FLEET_KOTLIN_PLUGIN to "File.kt"),
|
||||
|
||||
// kotlin-plugin path contains subdirectories to exclude
|
||||
listOf("$ULTIMATE_KOTLIN_PLUGIN/test/" to "File.kt"),
|
||||
listOf("$ULTIMATE_KOTLIN_PLUGIN/testData/" to "File.kt"),
|
||||
|
||||
// file extensions to exclude
|
||||
listOf(COMMUNITY_KOTLIN_PLUGIN to "File.iml"),
|
||||
listOf(COMMUNITY_KOTLIN_PLUGIN to "File.md"),
|
||||
|
||||
// multiple files, none matches
|
||||
listOf(
|
||||
"not-important-dir" to "File.kt",
|
||||
FLEET_KOTLIN_PLUGIN to "File.kt",
|
||||
"$ULTIMATE_KOTLIN_PLUGIN/test/" to "File.kt",
|
||||
"$ULTIMATE_KOTLIN_PLUGIN/testData/" to "File.kt",
|
||||
COMMUNITY_KOTLIN_PLUGIN to "File.iml",
|
||||
COMMUNITY_KOTLIN_PLUGIN to "File.md"
|
||||
)
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
@Parameter
|
||||
lateinit var files: List<Pair<String, String>>
|
||||
|
||||
@Test
|
||||
fun testThatIgnoresFileSet() {
|
||||
val filesSet = files.map { fileAt(it.first, it.second) }
|
||||
assert(!YouTrackIssueCommitMessageHandler.selectedFilesBelongToKotlinIdePlugin(filesSet)) {
|
||||
"The following set of files triggered the check: $filesSet"
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@RunWith(Parameterized::class)
|
||||
class ValidCommitMessages {
|
||||
|
||||
companion object {
|
||||
@JvmStatic
|
||||
@Parameterized.Parameters(name = "{0}")
|
||||
fun provideTestParameters(): Iterable<String> {
|
||||
return listOf(
|
||||
"KTIJ-123",
|
||||
"(KTIJ-123)",
|
||||
"[KTIJ-123]",
|
||||
"{KTIJ-123}",
|
||||
"'KTIJ-123'",
|
||||
"`KTIJ-123`",
|
||||
"\"KTIJ-123\"",
|
||||
|
||||
"KTIJ-123 ",
|
||||
" KTIJ-123",
|
||||
" KTIJ-123 ",
|
||||
|
||||
"KTIJ-123 header",
|
||||
"Header KTIJ-123",
|
||||
"Header KTIJ-123 header",
|
||||
|
||||
"""
|
||||
Header KTIJ-123 header
|
||||
|
||||
Body-line-1
|
||||
Body-line-N
|
||||
""".trimIndent(),
|
||||
|
||||
"""
|
||||
Header KTIJ-123 header
|
||||
|
||||
Body-line-1
|
||||
Body-line-N
|
||||
|
||||
^KTIJ-123 fixed
|
||||
""".trimIndent(),
|
||||
|
||||
"""
|
||||
Header
|
||||
|
||||
Body-line-1
|
||||
Body-line-N
|
||||
|
||||
^KTIJ-123 fixed
|
||||
""".trimIndent(),
|
||||
|
||||
"""
|
||||
Header
|
||||
|
||||
Body-line-1
|
||||
Body-line-N
|
||||
|
||||
#KTIJ-123 fixed
|
||||
""".trimIndent(),
|
||||
|
||||
"""
|
||||
Header
|
||||
|
||||
Body-line-1
|
||||
Body-line-N
|
||||
|
||||
Relates to #KTIJ-123
|
||||
""".trimIndent()
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
@Parameter
|
||||
lateinit var commitMessage: String
|
||||
|
||||
@Test
|
||||
fun testThatCommitMessageIsValid() {
|
||||
assert(YouTrackIssueCommitMessageHandler.commitMessageIsCorrect(commitMessage)) {
|
||||
"The following commit message was considered invalid: $commitMessage"
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@RunWith(Parameterized::class)
|
||||
class InvalidCommitMessages {
|
||||
|
||||
companion object {
|
||||
@JvmStatic
|
||||
@Parameterized.Parameters(name = "{0}")
|
||||
fun provideTestParameters(): Iterable<String> {
|
||||
return listOf(
|
||||
"",
|
||||
"KTIJ",
|
||||
"KTIJ-",
|
||||
"KTIJ-one",
|
||||
"KT-123",
|
||||
"IDEA-123",
|
||||
"WHATEVER-123",
|
||||
"Header KTIJ",
|
||||
"Header KTIJ header",
|
||||
|
||||
"""
|
||||
Header
|
||||
|
||||
Body-line-1
|
||||
Body-line-N
|
||||
""".trimIndent(),
|
||||
|
||||
"""
|
||||
Header
|
||||
|
||||
Body-line-1
|
||||
Body-line-N
|
||||
|
||||
^IDEA-123 fixed
|
||||
""".trimIndent(),
|
||||
|
||||
"""
|
||||
Header
|
||||
|
||||
Body-line-1
|
||||
Body-line-N
|
||||
|
||||
#IDEA-123 fixed
|
||||
""".trimIndent(),
|
||||
|
||||
"""
|
||||
Header
|
||||
|
||||
Body-line-1
|
||||
Body-line-N
|
||||
|
||||
Relates to #IDEA-123
|
||||
""".trimIndent(),
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
@Parameter
|
||||
lateinit var commitMessage: String
|
||||
|
||||
@Test
|
||||
fun testThatCommitMessageIsValid() {
|
||||
assert(!YouTrackIssueCommitMessageHandler.commitMessageIsCorrect(commitMessage)) {
|
||||
"The following commit message was considered as valid: $commitMessage"
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
val tempDir: String = System.getProperty("java.io.tmpdir")
|
||||
const val ULTIMATE_KOTLIN_PLUGIN = "plugins/kotlin/package/"
|
||||
const val COMMUNITY_KOTLIN_PLUGIN = "community/plugins/kotlin/package/"
|
||||
const val FLEET_KOTLIN_PLUGIN = "fleet/plugins/kotlin/package/"
|
||||
|
||||
|
||||
private fun fileAt(dirPath: String, fileName: String): File {
|
||||
return Paths.get(tempDir, *dirPath.split("/").toTypedArray(), fileName).toFile()
|
||||
}
|
||||
Reference in New Issue
Block a user