Skip to content

Commit

Permalink
feat: add applyPatches watcher, bump kotlin ver
Browse files Browse the repository at this point in the history
  • Loading branch information
MC-XiaoHei committed Jun 16, 2024
1 parent 1aec4fe commit 7c39c00
Show file tree
Hide file tree
Showing 5 changed files with 105 additions and 10 deletions.
2 changes: 2 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -2,3 +2,5 @@
.idea
.qodana
build
.kotlin
.run
2 changes: 1 addition & 1 deletion gradle/libs.versions.toml
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@
annotations = "24.1.0"

# plugins
kotlin = "1.9.23"
kotlin = "2.0.0"
changelog = "2.2.0"
gradleIntelliJPlugin = "1.17.2"
qodana = "2023.3.1"
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -109,15 +109,15 @@ class PluginConfigurationDialog(private val project: Project) : DialogWrapper(tr
setProperty("patches.server.path", serverPatchesInfo.path)
setProperty("patches.server.base", serverPatchesInfo.base)
val apiPatchesInfo = patchesInfo[PatchType.API]!!
apiPatchesInfo.base = serverPatchesInfo.base
apiPatchesInfo.base = modulePaths[apiPatchesInfo.module]!!
setProperty("patches.api.module", apiPatchesInfo.module)
setProperty("patches.api.path", apiPatchesInfo.path)
setProperty("patches.api.base", serverPatchesInfo.base)
setProperty("patches.api.base", apiPatchesInfo.base)
val generatedApiPatchesInfo = patchesInfo[PatchType.GENERATED_API]!!
generatedApiPatchesInfo.base = modulePaths[generatedApiPatchesInfo.module]!!
setProperty("patches.generated-api.module", generatedApiPatchesInfo.module)
setProperty("patches.generated-api.path", generatedApiPatchesInfo.path)
setProperty("patches.generated-api.base", serverPatchesInfo.base)
setProperty("patches.generated-api.base", generatedApiPatchesInfo.base)
}
configFile.outputStream().use { fileOutputStream ->
properties.store(fileOutputStream, null)
Expand Down
Original file line number Diff line number Diff line change
@@ -1,9 +1,13 @@
package cn.xor7.xiaohei.leavesknife.listeners

import cn.xor7.xiaohei.leavesknife.services.PatchType
import cn.xor7.xiaohei.leavesknife.services.leavesknifeStoreService
import cn.xor7.xiaohei.leavesknife.utils.createModuleApplyPatchesWatcher
import com.intellij.openapi.externalSystem.model.task.ExternalSystemTaskId
import com.intellij.openapi.externalSystem.model.task.ExternalSystemTaskNotificationListener
import org.jetbrains.plugins.gradle.service.task.GradleTaskManagerExtension
import org.jetbrains.plugins.gradle.settings.GradleExecutionSettings
import kotlin.concurrent.thread

class GradleTaskManager : GradleTaskManagerExtension {
override fun executeTasks(
Expand All @@ -14,11 +18,36 @@ class GradleTaskManager : GradleTaskManagerExtension {
jvmParametersSetup: String?,
listener: ExternalSystemTaskNotificationListener,
): Boolean {
taskNames.forEach {
if(it.startsWith("apply") && it.endsWith("Patches")) {
// start listen
taskNames
.filter { name -> name.startsWith("apply") && name.endsWith("Patches") }
.forEach { name ->
val store = id.findProject()?.leavesknifeStoreService ?: return@forEach
with(store) {
try {
when (name) {
"applyServerPatches" -> setOf(patchesInfo[PatchType.SERVER]!!)
"applyApiPatches" -> setOf(patchesInfo[PatchType.API]!!)
"applyGeneratedApiPatches" -> setOf(patchesInfo[PatchType.GENERATED_API]!!)
"applyPatches" -> setOf(
patchesInfo[PatchType.SERVER]!!,
patchesInfo[PatchType.API]!!,
patchesInfo[PatchType.GENERATED_API]!!
)

else -> return@forEach
}.forEach { info ->
println("Creating watcher for ${info.base}")
thread {
createModuleApplyPatchesWatcher(projectPath,info.base) {
println(it)
}
}
}
} catch (_: Exception) {
return@forEach
}
}
}
}
return super.executeTasks(id, taskNames, projectPath, settings, jvmParametersSetup, listener)
}

Expand Down
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
package cn.xor7.xiaohei.leavesknife.utils

import java.io.File
import java.nio.file.*

fun createWatchService(
Expand All @@ -10,10 +11,73 @@ fun createWatchService(
val watchService: WatchService = FileSystems.getDefault().newWatchService()
path.register(watchService, events)
var key: WatchKey
while ((watchService.take().also { key = it }) != null) {
while ((watchService.take().also { key = it }) != null && key.isValid) {
for (event: WatchEvent<*> in key.pollEvents()) {
if (onEvent(event)) return
if (!onEvent(event)) return
}
key.reset()
}
}

// 此函数使用了 Kotlin 2.0.0 中的新功能 Local variables and further scopes 但 IDEA 插件尚未更新导致报错,故添加此注解
@Suppress("SMARTCAST_IMPOSSIBLE")
fun createGitRebaseWatchService(
dotGitPath: String,
onEvent: (Int) -> Unit,
) {
createWatchService(
Path.of(dotGitPath),
StandardWatchEventKinds.ENTRY_MODIFY
) parentEvent@{
val rebaseApplyPath = "$dotGitPath/rebase-apply"
val rebaseApplyFile = File(rebaseApplyPath)
var file: File? = null
var next = 0
if (rebaseApplyFile.exists()) {
createWatchService(
Path.of(rebaseApplyPath),
StandardWatchEventKinds.ENTRY_CREATE,
StandardWatchEventKinds.ENTRY_DELETE
) childEvent@{
if (file == null) file = File("$rebaseApplyPath/next")
if (!file.exists()) return@childEvent false
val content = file.readLines().first().toInt()
if (content != next) {
next = content
onEvent(file.readLines().first().toInt())
}
return@childEvent true
}
return@parentEvent false
} else return@parentEvent true
}
}

fun createModuleApplyPatchesWatcher(
projectDir: String,
moduleBase: String,
onEvent: (Int) -> Unit,
) {
if (File(moduleBase).exists()) createModuleDotGitPathWatcher(projectDir, onEvent)
else createWatchService(
Path.of(projectDir),
StandardWatchEventKinds.ENTRY_CREATE
) parentEvent@{
if (!File(moduleBase).exists()) return@parentEvent true
createModuleDotGitPathWatcher(moduleBase, onEvent)
return@parentEvent false
}
}

private fun createModuleDotGitPathWatcher(
moduleBase: String,
onEvent: (Int) -> Unit,
) {
if (File("$moduleBase/.git").exists()) createGitRebaseWatchService("$moduleBase/.git") { onEvent(it) }
else createWatchService(Path.of(moduleBase), StandardWatchEventKinds.ENTRY_CREATE) childEvent@{
val dotGitPath = "$moduleBase/.git"
if (!File(dotGitPath).exists()) return@childEvent true
createGitRebaseWatchService(dotGitPath) { onEvent(it) }
return@childEvent false
}
}

0 comments on commit 7c39c00

Please sign in to comment.