Skip to content

Commit 78d7fed

Browse files
committed
feat(openrewrite): add OpenRewrite plugin integration #319
Add support for OpenRewrite plugin by introducing a new extension module `ext-openrewrite`. This includes configuration updates, new service implementation for handling OpenRewrite file execution, and necessary dependencies.
1 parent b08ccf9 commit 78d7fed

File tree

7 files changed

+202
-3
lines changed

7 files changed

+202
-3
lines changed

build.gradle.kts

Lines changed: 31 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -663,6 +663,7 @@ project(":exts:ext-endpoints") {
663663
implementation(project(":core"))
664664
}
665665
}
666+
666667
project(":exts:ext-terminal") {
667668
dependencies {
668669
intellijPlatform {
@@ -693,6 +694,36 @@ project(":exts:ext-terminal") {
693694
}
694695
}
695696

697+
project(":exts:ext-openrewrite") {
698+
dependencies {
699+
intellijPlatform {
700+
intellijIde(prop("ideaVersion"))
701+
intellijPlugins(ideaPlugins + prop("openWritePlugin"))
702+
}
703+
704+
implementation(project(":core"))
705+
}
706+
707+
sourceSets {
708+
main {
709+
resources.srcDirs("src/$platformVersion/main/resources")
710+
}
711+
test {
712+
resources.srcDirs("src/$platformVersion/test/resources")
713+
}
714+
}
715+
kotlin {
716+
sourceSets {
717+
main {
718+
kotlin.srcDirs("src/$platformVersion/main/kotlin")
719+
}
720+
test {
721+
kotlin.srcDirs("src/$platformVersion/test/kotlin")
722+
}
723+
}
724+
}
725+
}
726+
696727
project(":exts:devins-lang") {
697728
apply {
698729
plugin("org.jetbrains.grammarkit")
Lines changed: 153 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,153 @@
1+
package cc.unitmesh.openrewrite.provider
2+
3+
import cc.unitmesh.devti.provider.RunService
4+
import com.intellij.execution.ExecutionManager
5+
import com.intellij.execution.RunManager
6+
import com.intellij.execution.configurations.ConfigurationTypeUtil
7+
import com.intellij.execution.configurations.RunConfiguration
8+
import com.intellij.execution.configurations.RunProfile
9+
import com.intellij.execution.executors.DefaultRunExecutor
10+
import com.intellij.execution.runners.ExecutionEnvironmentBuilder
11+
import com.intellij.openapi.application.runReadAction
12+
import com.intellij.openapi.project.Project
13+
import com.intellij.openapi.vfs.VirtualFile
14+
import com.intellij.psi.PsiElement
15+
import com.intellij.psi.PsiFile
16+
import com.intellij.psi.PsiManager
17+
18+
class OpenRewriteFileRunService : RunService {
19+
override fun isApplicable(project: Project, file: VirtualFile): Boolean {
20+
return file.extension == "yml" && isOpenWriteFile(project, file)
21+
}
22+
23+
private fun isOpenWriteFile(project: Project, file: VirtualFile): Boolean {
24+
try {
25+
val clazz = Class.forName("com.intellij.openRewrite.OpenRewriteFileService")
26+
val getInstanceMethod = clazz.getDeclaredMethod("getInstance")
27+
val isRecipeMethod = clazz.getDeclaredMethod("isRecipe", PsiFile::class.java)
28+
29+
val fileService = getInstanceMethod.invoke(null)
30+
val psiFile = runReadAction {
31+
PsiManager.getInstance(project).findFile(file)
32+
} ?: return false
33+
34+
isRecipeMethod.isAccessible = true
35+
36+
val result = isRecipeMethod.invoke(fileService, psiFile) as Boolean
37+
return result
38+
} catch (e: Exception) {
39+
return false
40+
}
41+
}
42+
43+
override fun runConfigurationClass(project: Project): Class<out RunProfile>? = null
44+
45+
override fun runFile(
46+
project: Project,
47+
virtualFile: VirtualFile,
48+
psiElement: PsiElement?,
49+
isFromToolAction: Boolean
50+
): String? {
51+
if (!isOpenWriteFile(project, virtualFile)) {
52+
return ""
53+
}
54+
55+
val runManager = RunManager.getInstance(project)
56+
val allSettings = runManager.allSettings
57+
58+
val workingPath = virtualFile.parent.path
59+
60+
var settings = allSettings.firstOrNull {
61+
try {
62+
val config = it.configuration
63+
val configClass = config::class.java
64+
65+
if (configClass.name == "com.intellij.openRewrite.run.OpenRewriteRunConfiguration") {
66+
val getExpandedWorkingDirectoryMethod = configClass.getMethod("getExpandedWorkingDirectory")
67+
val workingDirectory = getExpandedWorkingDirectoryMethod.invoke(config) as? String
68+
workingDirectory == workingPath
69+
} else {
70+
false
71+
}
72+
} catch (e: Exception) {
73+
false
74+
}
75+
}
76+
77+
val list = try {
78+
getRecipeDescriptors(project, virtualFile) ?: return null
79+
} catch (e: Exception) {
80+
return null
81+
}
82+
if (list.isEmpty()) return null
83+
84+
if (settings == null) {
85+
try {
86+
val configurationType = ConfigurationTypeUtil.findConfigurationType("OpenRewriteRunConfigurationType")!!
87+
settings = runManager.createConfiguration("", configurationType.configurationFactories[0])
88+
val configuration = settings.configuration
89+
90+
if (configuration.javaClass.name == "com.intellij.openRewrite.run.OpenRewriteRunConfiguration") {
91+
configureOpenRewrite(configuration, project, virtualFile, list)
92+
}
93+
94+
runManager.setUniqueNameIfNeeded(settings)
95+
runManager.setTemporaryConfiguration(settings)
96+
} catch (e: Exception) {
97+
return null
98+
}
99+
}
100+
101+
val builder = ExecutionEnvironmentBuilder.createOrNull(DefaultRunExecutor.getRunExecutorInstance(), settings)
102+
builder?.let {
103+
ExecutionManager.getInstance(project).restartRunProfile(it.build())
104+
}
105+
106+
return ""
107+
}
108+
109+
private fun configureOpenRewrite(
110+
configuration: RunConfiguration,
111+
project: Project,
112+
virtualFile: VirtualFile,
113+
list: java.util.LinkedHashMap<*, *>,
114+
) {
115+
val directoryMethod =
116+
configuration::class.java.getMethod("setWorkingDirectory", String::class.java)
117+
val projectRoot = project.basePath ?: ""
118+
directoryMethod.invoke(configuration, projectRoot)
119+
120+
val setConfigLocationMethod =
121+
configuration::class.java.getMethod("setConfigLocation", String::class.java)
122+
setConfigLocationMethod.invoke(configuration, virtualFile.path)
123+
124+
val setActiveRecipesMethod =
125+
configuration::class.java.getMethod("setActiveRecipes", String::class.java)
126+
setActiveRecipesMethod.invoke(configuration, list.keys.first())
127+
128+
val nameMethod = configuration::class.java.getMethod("setGeneratedName")
129+
nameMethod.invoke(configuration)
130+
}
131+
132+
private fun getRecipeDescriptors(project: Project, virtualFile: VirtualFile): LinkedHashMap<*, *>? {
133+
val clazz = Class.forName("com.intellij.openRewrite.recipe.OpenRewriteRecipeService")
134+
val getInstanceMethod = clazz.getDeclaredMethod("getInstance", Project::class.java)
135+
val recipeService = getInstanceMethod.invoke(null, project)
136+
val OpenRewriteType = Class.forName("com.intellij.openRewrite.recipe.OpenRewriteType").getEnumConstants()[0]
137+
138+
val method =
139+
clazz.getDeclaredMethod("getLocalDescriptors", PsiFile::class.java, OpenRewriteType::class.java)
140+
method.isAccessible = true
141+
142+
val psiFile = runReadAction {
143+
PsiManager.getInstance(project).findFile(virtualFile)
144+
} ?: return null
145+
146+
val list = runReadAction {
147+
val type = OpenRewriteType::class.java.enumConstants[0]
148+
method.invoke(recipeService, psiFile, type) as LinkedHashMap<*, *>
149+
}
150+
151+
return list
152+
}
153+
}
Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,10 @@
1+
<idea-plugin package="cc.unitmesh.openrewrite">
2+
<!--suppress PluginXmlValidity -->
3+
<dependencies>
4+
<plugin id="com.intellij.openRewrite"/>
5+
</dependencies>
6+
7+
<extensions defaultExtensionNs="cc.unitmesh">
8+
<runService implementation="cc.unitmesh.openrewrite.provider.OpenRewriteFileRunService"/>
9+
</extensions>
10+
</idea-plugin>

gradle-223.properties

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -23,4 +23,5 @@ endpointsPlugin=
2323
devContainerPlugin=
2424

2525
swaggerPlugin=com.intellij.swagger:223.7571.125
26-
vuePlugin=org.jetbrains.plugins.vue:223.7571.176
26+
vuePlugin=org.jetbrains.plugins.vue:223.7571.176
27+
openWritePlugin=

gradle-233.properties

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -23,4 +23,5 @@ devContainerPlugin=org.jetbrains.plugins.docker.gateway:233.11799.180
2323
goPlugin=org.jetbrains.plugins.go:233.11799.196
2424
endpointsPlugin=com.intellij.microservices.ui:233.11799.172
2525
swaggerPlugin=com.intellij.swagger:233.11799.188
26-
vuePlugin=org.jetbrains.plugins.vue:233.11799.172
26+
vuePlugin=org.jetbrains.plugins.vue:233.11799.172
27+
openWritePlugin=

gradle-241.properties

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -25,4 +25,6 @@ devContainerPlugin=org.jetbrains.plugins.docker.gateway:241.14494.189
2525

2626
endpointsPlugin=com.intellij.microservices.ui:241.14494.150
2727
swaggerPlugin=com.intellij.swagger:241.14494.150
28-
vuePlugin=org.jetbrains.plugins.vue:241.14494.159
28+
vuePlugin=org.jetbrains.plugins.vue:241.14494.159
29+
30+
openWritePlugin=com.intellij.openRewrite:241.14494.158

settings.gradle.kts

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -26,6 +26,7 @@ include(
2626
"exts:ext-vue",
2727
"exts:ext-dependencies",
2828
"exts:ext-container",
29+
"exts:ext-openrewrite",
2930

3031
// the Input Language support for AutoDev
3132
"exts:devins-lang"

0 commit comments

Comments
 (0)