Skip to content

Commit cb7a8e3

Browse files
Migrate to IntelliJ Platform Gradle Plugin 2 (#2194)
Closes sourcegraph/cody-issues#240 Fixes https://linear.app/sourcegraph/issue/CODY-3713/upgrade-to-intellij-gradle-2x-plugin-to-debug-in-splitmode ## Test plan 1. Full QA 2. Green CI 3. runIde (and other gradle tasks) working --------- Co-authored-by: Piotr Kukielka <pkukielka@virtuslab.com>
1 parent 7118ffa commit cb7a8e3

21 files changed

+131
-116
lines changed

.gitignore

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -24,6 +24,7 @@ idea-sandbox/
2424

2525
# IntelliJ
2626
/out/
27+
.intellijPlatform
2728

2829
# mpeltonen/sbt-idea plugin
2930
.idea_modules/

CONTRIBUTING.md

Lines changed: 1 addition & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -72,7 +72,7 @@ run `sdk use java 17-zulu`. Confirm that you have Java 17 installed with `java -
7272
| Run the plugin locally with fresh build of Cody | `./gradlew -PforceAgentBuild=true :runIde` |
7373
| Run the plugin locally with fresh build of a local clone of Cody (CODY_DIR needs to be an absolute path) | `CODY_DIR=<path_to_cody> ./gradlew -PforceAgentBuild=true :runIde` |
7474
| Run the plugin locally with fresh build of Code Search assets | `./gradlew -PforceCodeSearchBuild=true :runIde` |
75-
| Run the plugin locally with different IntelliJ version | `./gradlew -PplatformVersion=2023.1 :runIde` |
75+
| Run the plugin locally with different IntelliJ version | `./gradlew -PplatformRuntimeVersion=2024.2.0.2 :customRunIde` |
7676
| Build Code Search assets (separate terminal) | `pnpm build` |
7777
| Continuously re-build Code Search assets (separate terminal) | `pnpm watch` |
7878
| Code Search "Find with Sourcegraph" window | `pnpm standalone && open http://localhost:3000/` |
@@ -97,9 +97,6 @@ Few tips and tricks regarding versioning of the tooling:
9797
- Use `node` version `18` (newer versions causes hard to diagnose errors with `ERR_INVALID_THIS`).
9898
- If you changed `pnpm` or `node` version after running gradle you need to kill gradle daemon with `./gradlew --stop`.
9999
Otherwise you won't see effects of your changes.
100-
- Running `./gradlew -PplatformRuntimeVersion=X.Y :runIde` for the first time might fail due to missing IntelliJ
101-
installation. You
102-
can fix it by running `./gradlew -PplatformVersion=X.Y :runIde` once - even if compilation fails it fixes your caches.
103100
- IF you get error 134 while building different things with jetbrains its because java process doesn't have enough
104101
memory to build so you might need to get into your activity monitor to close other processes.
105102

build.gradle.kts

Lines changed: 103 additions & 87 deletions
Original file line numberDiff line numberDiff line change
@@ -12,11 +12,14 @@ import java.util.EnumSet
1212
import java.util.jar.JarFile
1313
import java.util.zip.ZipFile
1414
import org.jetbrains.changelog.markdownToHTML
15-
import org.jetbrains.intellij.or
16-
import org.jetbrains.intellij.tasks.RunPluginVerifierTask.FailureLevel
15+
import org.jetbrains.intellij.platform.gradle.IntelliJPlatformType
16+
import org.jetbrains.intellij.platform.gradle.TestFrameworkType
17+
import org.jetbrains.intellij.platform.gradle.tasks.VerifyPluginTask.FailureLevel
18+
import org.jetbrains.kotlin.gradle.dsl.JvmTarget
1719
import org.jetbrains.kotlin.gradle.tasks.KotlinCompile
20+
import org.jetbrains.kotlin.gradle.tasks.KotlinJvmCompile
1821

19-
fun properties(key: String) = project.findProperty(key).toString()
22+
fun properties(key: String) = project.findProperty(key)?.toString()
2023

2124
val isForceBuild = properties("forceBuild") == "true"
2225
val isForceAgentBuild =
@@ -53,42 +56,84 @@ plugins {
5356
id("java")
5457
id("jvm-test-suite")
5558
id("org.jetbrains.kotlin.jvm") version "2.0.20"
56-
id("org.jetbrains.intellij") version "1.17.4"
59+
id("org.jetbrains.intellij.platform") version "2.0.1"
5760
id("org.jetbrains.changelog") version "2.2.1"
5861
id("com.diffplug.spotless") version "6.25.0"
5962
}
6063

6164
val platformVersion: String by project
65+
val platformType: String by project
6266
val javaVersion: String by project
6367

64-
group = properties("pluginGroup")
68+
group = properties("pluginGroup")!!
6569

66-
version = properties("pluginVersion")
70+
version = properties("pluginVersion")!!
6771

6872
repositories {
6973
maven { url = uri("https://www.jetbrains.com/intellij-repository/releases") }
7074
mavenCentral()
75+
gradlePluginPortal()
76+
intellijPlatform {
77+
defaultRepositories()
78+
jetbrainsRuntime()
79+
}
7180
}
7281

73-
intellij {
74-
pluginName.set(properties("pluginName"))
75-
version.set(platformVersion)
76-
type.set(properties("platformType"))
82+
intellijPlatform {
83+
pluginConfiguration {
84+
name = properties("pluginName")
85+
version = properties("pluginVersion")
86+
ideaVersion {
87+
sinceBuild = properties("pluginSinceBuild")
88+
untilBuild = properties("pluginUntilBuild")
89+
}
90+
// Extract the <!-- Plugin description --> section from README.md and provide for the plugin's
91+
// manifest
92+
description =
93+
projectDir
94+
.resolve("README.md")
95+
.readText()
96+
.lines()
97+
.run {
98+
val start = "<!-- Plugin description -->"
99+
val end = "<!-- Plugin description end -->"
77100

78-
// Plugin Dependencies. Uses `platformPlugins` property from the gradle.properties file.
79-
plugins.set(properties("platformPlugins").split(',').map(String::trim).filter(String::isNotEmpty))
101+
if (!containsAll(listOf(start, end))) {
102+
throw GradleException(
103+
"Plugin description section not found in README.md:\n$start ... $end")
104+
}
105+
subList(indexOf(start) + 1, indexOf(end))
106+
}
107+
.joinToString("\n")
108+
.run { markdownToHTML(this) }
109+
}
80110

81-
updateSinceUntilBuild.set(false)
111+
pluginVerification {
112+
ides { ides(versionsToValidate) }
113+
failureLevel = EnumSet.complementOf(skippedFailureLevels)
114+
}
82115
}
83116

84117
dependencies {
85-
// ActionUpdateThread.jar contains copy of the
86-
// com.intellij.openapi.actionSystem.ActionUpdateThread class
87-
compileOnly(files("libs/ActionUpdateThread.jar"))
118+
intellijPlatform {
119+
jetbrainsRuntime()
120+
create(platformType, platformVersion)
121+
bundledPlugins(
122+
properties("platformPlugins")
123+
.orEmpty()
124+
.split(',')
125+
.map(String::trim)
126+
.filter(String::isNotEmpty))
127+
instrumentationTools()
128+
pluginVerifier()
129+
testFramework(TestFrameworkType.Platform)
130+
}
131+
88132
implementation("org.commonmark:commonmark:0.22.0")
89133
implementation("org.commonmark:commonmark-ext-gfm-tables:0.22.0")
90134
implementation("org.eclipse.lsp4j:org.eclipse.lsp4j.jsonrpc:0.23.1")
91135
implementation("io.github.java-diff-utils:java-diff-utils:4.12")
136+
testImplementation("net.java.dev.jna:jna:5.10.0")
92137
testImplementation("org.awaitility:awaitility-kotlin:4.2.1")
93138
testImplementation("org.mockito:mockito-core:5.12.0")
94139
testImplementation("org.junit.jupiter:junit-jupiter:5.10.2")
@@ -118,10 +163,18 @@ spotless {
118163
}
119164

120165
java {
121-
toolchain { languageVersion.set(JavaLanguageVersion.of(properties("javaVersion").toInt())) }
166+
toolchain {
167+
languageVersion.set(JavaLanguageVersion.of(javaVersion.toInt()))
168+
vendor = JvmVendorSpec.JETBRAINS
169+
}
122170
}
123171

124-
tasks.named("classpathIndexCleanup") { dependsOn("compileIntegrationTestKotlin") }
172+
kotlin {
173+
jvmToolchain {
174+
languageVersion.set(JavaLanguageVersion.of(javaVersion.toInt()))
175+
vendor = JvmVendorSpec.JETBRAINS
176+
}
177+
}
125178

126179
fun download(url: String, output: File) {
127180
if (output.exists()) {
@@ -205,6 +258,22 @@ fun Test.sharedIntegrationTestConfig(buildCodyDir: File, mode: String) {
205258

206259
include("**/AllSuites.class")
207260

261+
jvmArgs(
262+
"-Djava.system.class.loader=com.intellij.util.lang.PathClassLoader",
263+
"--add-opens=java.desktop/java.awt.event=ALL-UNNAMED",
264+
"--add-opens=java.desktop/sun.font=ALL-UNNAMED",
265+
"--add-opens=java.desktop/java.awt=ALL-UNNAMED",
266+
"--add-opens=java.desktop/sun.awt=ALL-UNNAMED",
267+
"--add-opens=java.base/java.lang=ALL-UNNAMED",
268+
"--add-opens=java.base/java.util=ALL-UNNAMED",
269+
"--add-opens=java.desktop/javax.swing=ALL-UNNAMED",
270+
"--add-opens=java.desktop/sun.swing=ALL-UNNAMED",
271+
"--add-opens=java.desktop/javax.swing.plaf.basic=ALL-UNNAMED",
272+
"--add-opens=java.desktop/java.awt.peer=ALL-UNNAMED",
273+
"--add-opens=java.desktop/javax.swing.text.html=ALL-UNNAMED",
274+
"--add-exports=java.base/jdk.internal.vm=ALL-UNNAMED",
275+
"--add-exports=java.desktop/sun.font=ALL-UNNAMED")
276+
208277
val resourcesDir = project.file("src/integrationTest/resources")
209278
systemProperties(
210279
"cody-agent.trace-path" to
@@ -215,7 +284,7 @@ fun Test.sharedIntegrationTestConfig(buildCodyDir: File, mode: String) {
215284
(project.property("cody.autocomplete.enableFormatting") as String? ?: "true"),
216285
"cody.integration.testing" to "true",
217286
"cody.ignore.policy.timeout" to 1500, // Increased to 1500ms as CI tends to be slower
218-
"idea.test.execution.policy" to "com.sourcegraph.cody.test.NonEdtIdeaTestExecutionPolicy",
287+
"idea.test.execution.policy" to "com.sourcegraph.cody.NonEdtIdeaTestExecutionPolicy",
219288
"test.resources.dir" to resourcesDir.absolutePath)
220289

221290
environment(
@@ -287,8 +356,8 @@ tasks {
287356
}
288357

289358
fun downloadNodeBinaries(): File {
290-
val nodeCommit = properties("nodeBinaries.commit")
291-
val nodeVersion = properties("nodeBinaries.version")
359+
val nodeCommit = properties("nodeBinaries.commit")!!
360+
val nodeVersion = properties("nodeBinaries.version")!!
292361
val url = "https://github.com/sourcegraph/node-binaries/archive/$nodeCommit.zip"
293362
val zipFile = githubArchiveCache.resolve("$nodeCommit.zip")
294363
download(url, zipFile)
@@ -425,37 +494,12 @@ tasks {
425494
processResources { dependsOn(":buildCodeSearch") }
426495

427496
// Set the JVM compatibility versions
428-
properties("javaVersion").let {
497+
javaVersion.let {
429498
withType<JavaCompile> {
430499
sourceCompatibility = it
431500
targetCompatibility = it
432501
}
433-
withType<KotlinCompile> { kotlinOptions.jvmTarget = it }
434-
}
435-
436-
patchPluginXml {
437-
version.set(properties("pluginVersion"))
438-
439-
// Extract the <!-- Plugin description --> section from README.md and provide for the plugin's
440-
// manifest
441-
pluginDescription.set(
442-
projectDir
443-
.resolve("README.md")
444-
.readText()
445-
.lines()
446-
.run {
447-
val start = "<!-- Plugin description -->"
448-
val end = "<!-- Plugin description end -->"
449-
450-
if (!containsAll(listOf(start, end))) {
451-
throw GradleException(
452-
"Plugin description section not found in README.md:\n$start ... $end")
453-
}
454-
subList(indexOf(start) + 1, indexOf(end))
455-
}
456-
.joinToString("\n")
457-
.run { markdownToHTML(this) },
458-
)
502+
withType<KotlinJvmCompile> { compilerOptions.jvmTarget.set(JvmTarget.JVM_17) }
459503
}
460504

461505
buildPlugin {
@@ -488,46 +532,19 @@ tasks {
488532
}
489533
}
490534

491-
patchPluginXml {
492-
sinceBuild = properties("pluginSinceBuild")
493-
untilBuild = properties("pluginUntilBuild")
494-
}
535+
val customRunIde by
536+
intellijPlatformTesting.runIde.registering {
537+
version.set(properties("platformRuntimeVersion"))
538+
val myType = IntelliJPlatformType.fromCode(properties("platformRuntimeType") ?: "IC")
539+
type.set(myType)
540+
plugins { plugins(properties("platformRuntimePlugins").orEmpty()) }
541+
}
495542

496543
runIde {
497544
dependsOn(project.tasks.getByPath("buildCody"))
498545
jvmArgs("-Djdk.module.illegalAccess.silent=true")
499546

500547
agentProperties.forEach { (key, value) -> systemProperty(key, value) }
501-
502-
val platformRuntimeVersion = project.findProperty("platformRuntimeVersion")
503-
val platformRuntimeType = project.findProperty("platformRuntimeType")
504-
if (platformRuntimeVersion != null || platformRuntimeType != null) {
505-
val ideaInstallDir =
506-
getIdeaInstallDir(
507-
platformRuntimeVersion.or(project.property("platformVersion")).toString(),
508-
platformRuntimeType.or(project.property("platformType")).toString())
509-
?: throw GradleException(
510-
"Could not find IntelliJ install for version: $platformRuntimeVersion")
511-
ideDir.set(ideaInstallDir)
512-
}
513-
// TODO: we need to wait to switch to Platform Gradle Plugin 2.0.0 to be able to have separate
514-
// runtime plugins
515-
// https://github.com/JetBrains/intellij-platform-gradle-plugin/issues/1489
516-
// val platformRuntimePlugins = project.findProperty("platformRuntimePlugins")
517-
}
518-
519-
runPluginVerifier {
520-
ideVersions.set(versionsToValidate)
521-
failureLevel.set(EnumSet.complementOf(skippedFailureLevels))
522-
}
523-
524-
// Configure UI tests plugin
525-
// Read more: https://github.com/JetBrains/intellij-ui-test-robot
526-
runIdeForUiTests {
527-
systemProperty("robot-server.port", "8082")
528-
systemProperty("ide.mac.message.dialogs.as.sheets", "false")
529-
systemProperty("jb.privacy.policy.text", "<!--999.999-->")
530-
systemProperty("jb.consents.confirmation.enabled", "false")
531548
}
532549

533550
signPlugin {
@@ -544,7 +561,7 @@ tasks {
544561
// Specify pre-release label to publish the plugin in a custom Release Channel automatically.
545562
// Read more:
546563
// https://plugins.jetbrains.com/docs/intellij/deployment.html#specifying-a-release-channel
547-
val channel = properties("pluginVersion").split('-').getOrElse(1) { "default" }
564+
val channel = properties("pluginVersion")!!.split('-').getOrElse(1) { "default" }
548565
channels.set(listOf(channel))
549566

550567
if (channel == "default") {
@@ -565,8 +582,8 @@ tasks {
565582
sourceSets {
566583
create("integrationTest") {
567584
kotlin.srcDir("src/integrationTest/kotlin")
568-
compileClasspath += main.get().output
569-
runtimeClasspath += main.get().output
585+
compileClasspath += main.get().output + configurations.testCompileClasspath.get()
586+
runtimeClasspath += compileClasspath + configurations.testRuntimeClasspath.get()
570587
}
571588
}
572589

@@ -600,12 +617,11 @@ tasks {
600617
withType<Test> {
601618
systemProperty(
602619
"idea.test.src.dir", "${layout.buildDirectory.asFile.get()}/resources/integrationTest")
620+
systemProperty("idea.force.use.core.classloader", "true")
603621
}
604622

605623
withType<KotlinCompile> { dependsOn("copyProtocol") }
606624

607-
named("classpathIndexCleanup") { dependsOn("processIntegrationTestResources") }
608-
609625
named("check") { dependsOn("integrationTest") }
610626

611627
test {

gradle.properties

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -13,7 +13,7 @@ platformType=IC
1313
platformVersion=2023.2
1414
# Plugin Dependencies -> https://plugins.jetbrains.com/docs/intellij/plugin-dependencies.html
1515
# Example: platformPlugins = com.intellij.java, com.jetbrains.php:203.4449.22
16-
platformPlugins=Git4Idea,PerforceDirectPlugin,java
16+
platformPlugins=Git4Idea,PerforceDirectPlugin,com.intellij.java
1717
javaVersion=17
1818
# Opt-out flag for bundling Kotlin standard library.
1919
# See https://plugins.jetbrains.com/docs/intellij/kotlin.html#kotlin-standard-library for details.

gradle/wrapper/gradle-wrapper.jar

130 Bytes
Binary file not shown.

gradle/wrapper/gradle-wrapper.properties

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
distributionBase=GRADLE_USER_HOME
22
distributionPath=wrapper/dists
3-
distributionUrl=https\://services.gradle.org/distributions/gradle-8.8-bin.zip
3+
distributionUrl=https\://services.gradle.org/distributions/gradle-8.10-all.zip
44
networkTimeout=10000
55
validateDistributionUrl=true
66
zipStoreBase=GRADLE_USER_HOME

gradlew

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -15,6 +15,8 @@
1515
# See the License for the specific language governing permissions and
1616
# limitations under the License.
1717
#
18+
# SPDX-License-Identifier: Apache-2.0
19+
#
1820

1921
##############################################################################
2022
#
@@ -84,7 +86,8 @@ done
8486
# shellcheck disable=SC2034
8587
APP_BASE_NAME=${0##*/}
8688
# Discard cd standard output in case $CDPATH is set (https://github.com/gradle/gradle/issues/25036)
87-
APP_HOME=$( cd "${APP_HOME:-./}" > /dev/null && pwd -P ) || exit
89+
APP_HOME=$( cd -P "${APP_HOME:-./}" > /dev/null && printf '%s
90+
' "$PWD" ) || exit
8891

8992
# Use the maximum available, or set MAX_FD != -1 to use that value.
9093
MAX_FD=maximum

gradlew.bat

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -13,6 +13,8 @@
1313
@rem See the License for the specific language governing permissions and
1414
@rem limitations under the License.
1515
@rem
16+
@rem SPDX-License-Identifier: Apache-2.0
17+
@rem
1618

1719
@if "%DEBUG%"=="" @echo off
1820
@rem ##########################################################################

src/main/kotlin/com/sourcegraph/cody/test/NonEdtIdeaTestExecutionPolicy.kt renamed to src/integrationTest/kotlin/com/sourcegraph/cody/NonEdtIdeaTestExecutionPolicy.kt

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
package com.sourcegraph.cody.test
1+
package com.sourcegraph.cody
22

33
import com.intellij.testFramework.fixtures.IdeaTestExecutionPolicy
44

0 commit comments

Comments
 (0)