Skip to content

Commit 9a4e5d3

Browse files
committed
Execute tests in parallel and bump deps
1 parent 57591dd commit 9a4e5d3

15 files changed

Lines changed: 160 additions & 66 deletions

File tree

build.gradle.kts

Lines changed: 47 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,7 @@
33
*
44
* https://mcdev.io/
55
*
6-
* Copyright (C) 2025 minecraft-dev
6+
* Copyright (C) 2026 minecraft-dev
77
*
88
* This program is free software: you can redistribute it and/or modify
99
* it under the terms of the GNU Lesser General Public License as published
@@ -19,11 +19,14 @@
1919
*/
2020

2121
import io.sentry.android.gradle.extensions.SentryPluginExtension
22+
import java.util.concurrent.atomic.AtomicInteger
23+
import kotlin.concurrent.atomics.AtomicInt
2224
import org.gradle.kotlin.dsl.configure
2325
import org.jetbrains.changelog.Changelog
2426
import org.jetbrains.gradle.ext.settings
2527
import org.jetbrains.gradle.ext.taskTriggers
2628
import org.jetbrains.intellij.platform.gradle.TestFrameworkType
29+
import org.jetbrains.intellij.platform.gradle.tasks.CleanSandboxTask
2730
import org.jetbrains.intellij.platform.gradle.tasks.PrepareSandboxTask
2831

2932
plugins {
@@ -102,8 +105,12 @@ dependencies {
102105
exclude(group = "org.slf4j")
103106
}
104107

108+
implementation(libs.jspecify)
109+
105110
intellijPlatform {
106-
intellijIdeaCommunity(libs.versions.intellij.ide, useInstaller = false)
111+
intellijIdeaCommunity(libs.versions.intellij.ide) {
112+
useInstaller = false
113+
}
107114

108115
// Bundled plugin dependencies
109116
bundledPlugin("com.intellij.java")
@@ -121,7 +128,6 @@ dependencies {
121128
bundledPlugin("org.toml.lang")
122129
bundledPlugin("org.jetbrains.plugins.yaml")
123130

124-
125131
testFramework(TestFrameworkType.JUnit5)
126132
testFramework(TestFrameworkType.Platform)
127133
testFramework(TestFrameworkType.Plugin.Java)
@@ -198,8 +204,39 @@ tasks.processResources {
198204
}
199205
}
200206

207+
// Run unit tests in paralllel. Unfortunately, to accomplish this, we also need separate sandboxes for each test fork.
208+
// All of this is still worth doing since the IntelliJ test fixtures themselves are rather slow.
209+
val testForks = 6
210+
val sandboxTestTasks = mutableListOf<TaskProvider<PrepareSandboxTask>>()
211+
repeat(testForks) {
212+
sandboxTestTasks += tasks.register<PrepareSandboxTask>("prepareTestSandboxFork$it") {
213+
sandboxSuffix.set("-fork-$it")
214+
doFirst {
215+
sandboxDirectory.get().asFile.listFiles()
216+
?.filter { f -> f.name.endsWith("-fork-$it") }
217+
?.forEach { f -> f.deleteRecursively() }
218+
}
219+
}
220+
}
221+
tasks.prepareTestSandbox {
222+
doFirst {
223+
sandboxDirectory.get().asFile.listFiles()
224+
?.filter { f -> f.name.endsWith("-test") }
225+
?.forEach { f -> f.deleteRecursively() }
226+
}
227+
}
228+
229+
val cleanTestSandboxForks by tasks.registering(Delete::class) {
230+
doFirst {
231+
tasks.prepareTestSandbox.flatMap { it.sandboxDirectory }
232+
.get().asFile.listFiles()
233+
?.filter { it.name.matches(Regex(".*-(?:fork-\\d+|test)")) }
234+
?.let { delete(it) }
235+
}
236+
}
201237
tasks.test {
202-
dependsOn(tasks.jar, testLibs)
238+
dependsOn(tasks.jar, testLibs, sandboxTestTasks)
239+
finalizedBy(cleanTestSandboxForks)
203240

204241
testLibs.resolvedConfiguration.resolvedArtifacts.forEach {
205242
systemProperty("testLibs.${it.name}", it.file.absolutePath)
@@ -211,6 +248,12 @@ tasks.test {
211248
"-Dsun.io.useCanonCaches=false",
212249
"-Dsun.io.useCanonPrefixCache=false",
213250
)
251+
252+
val sandboxDir = tasks.prepareTestSandbox.flatMap { it.sandboxDirectory }.get().asFile
253+
254+
maxParallelForks = testForks
255+
systemProperty("sandboxDir", sandboxDir.absolutePath)
256+
systemProperty("forks", testForks.toString())
214257
}
215258

216259
idea {

buildSrc/src/main/kotlin/mcdev-core.gradle.kts

Lines changed: 0 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -194,12 +194,6 @@ tasks.runIde {
194194
jvmArgs("--add-exports=java.base/jdk.internal.vm=ALL-UNNAMED")
195195
}
196196

197-
tasks.register("cleanSandbox", Delete::class) {
198-
group = "intellij"
199-
description = "Deletes the sandbox directory."
200-
delete(layout.projectDirectory.dir(".sandbox"))
201-
}
202-
203197
tasks.test {
204198
useJUnitPlatform()
205199
}

buildSrc/src/main/kotlin/mcdev-publishing.gradle.kts

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,7 @@
33
*
44
* https://mcdev.io/
55
*
6-
* Copyright (C) 2025 minecraft-dev
6+
* Copyright (C) 2026 minecraft-dev
77
*
88
* This program is free software: you can redistribute it and/or modify
99
* it under the terms of the GNU Lesser General Public License as published
@@ -26,6 +26,7 @@ import java.net.http.HttpResponse
2626
import kotlin.io.path.absolute
2727
import org.jetbrains.intellij.platform.gradle.utils.IdeServicesPluginRepositoryService
2828
import org.jetbrains.intellij.pluginRepository.PluginRepositoryFactory
29+
import org.jetbrains.intellij.pluginRepository.model.ProductFamily
2930

3031
plugins {
3132
id("org.jetbrains.intellij.platform")
@@ -63,8 +64,9 @@ tasks.publishPlugin {
6364
false -> PluginRepositoryFactory.create(host.get(), token.get())
6465
}
6566
@Suppress("DEPRECATION")
66-
val uploadBean = repositoryClient.uploader.upload(
67+
val uploadBean = repositoryClient.uploader.uploadUpdateByXmlIdAndFamily(
6768
id = pluginId,
69+
family = ProductFamily.INTELLIJ,
6870
file = path.toFile(),
6971
channel = channel.takeIf { it != "default" },
7072
notes = null,

gradle/libs.versions.toml

Lines changed: 19 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -1,25 +1,23 @@
11
[versions]
2-
kotlin = "2.2.20"
2+
kotlin = "2.3.20"
33
coroutines = "1.10.2"
4-
junit = "5.10.2"
5-
junit-platform = "1.10.2"
6-
asm = "9.6"
4+
junit = "6.0.3"
5+
asm = "9.9.1"
76
fuel = "2.3.1"
87
licenser = "0.7.5"
9-
changelog = "2.2.0"
10-
intellij-plugin = "2.6.0"
11-
intellij-plugin-repository-rest-client = "2.0.46"
8+
changelog = "2.5.0"
9+
intellij-plugin = "2.13.1"
10+
intellij-plugin-repository-rest-client = "2.0.50"
1211
intellij-ide = "2025.2"
13-
idea-ext = "1.1.10"
14-
psiPlugin = "251.175"
12+
idea-ext = "1.4.1"
1513

1614
[plugins]
1715
kotlin = { id = "org.jetbrains.kotlin.jvm", version.ref = "kotlin" }
1816
intellij-platform = { id = "org.jetbrains.intellij.platform", version.ref = "intellij-plugin" }
1917
idea-ext = { id = "org.jetbrains.gradle.plugin.idea-ext", version.ref = "idea-ext" }
2018
licenser = { id = "net.neoforged.licenser", version.ref = "licenser" }
2119
changelog = { id = "org.jetbrains.changelog", version.ref = "changelog" }
22-
sentry = "io.sentry.jvm.gradle:5.12.2"
20+
sentry = "io.sentry.jvm.gradle:6.3.0"
2321

2422
[libraries]
2523
intellij-plugin-repository-rest-client = { module = "org.jetbrains.intellij:plugin-repository-rest-client", version.ref = "intellij-plugin-repository-rest-client" }
@@ -34,7 +32,7 @@ changelog-plugin = { module = "org.jetbrains.changelog:org.jetbrains.changelog.g
3432

3533
coroutines-swing = { module = "org.jetbrains.kotlinx:kotlinx-coroutines-swing", version.ref = "coroutines" }
3634

37-
mappingIo = "net.fabricmc:mapping-io:0.2.1"
35+
mappingIo = "net.fabricmc:mapping-io:0.8.0"
3836
mixinExtras-expressions = "io.github.llamalad7:mixinextras-expressions:0.0.6"
3937
jgraphx = "com.github.vlsi.mxgraph:jgraphx:4.2.2"
4038

@@ -45,35 +43,36 @@ grammarKit = "org.jetbrains.idea:grammar-kit:1.5.1"
4543

4644
# Gradle Tooling
4745
gradleToolingExtension = { module = "com.jetbrains.intellij.gradle:gradle-tooling-extension", version = "252.23892.409" }
48-
annotations = "org.jetbrains:annotations:24.0.0"
49-
groovy = "org.codehaus.groovy:groovy:3.0.19"
46+
annotations = "org.jetbrains:annotations:26.1.0"
47+
groovy = "org.codehaus.groovy:groovy:3.0.25"
5048

5149
asm = { module = "org.ow2.asm:asm", version.ref = "asm" }
5250
asm-tree = { module = "org.ow2.asm:asm-tree", version.ref = "asm" }
5351
asm-analysis = { module = "org.ow2.asm:asm-analysis", version.ref = "asm" }
5452
asm-util = { module = "org.ow2.asm:asm-util", version.ref = "asm" }
5553

56-
gson = "com.google.code.gson:gson:2.10.1"
54+
gson = "com.google.code.gson:gson:2.13.2"
55+
jspecify = "org.jspecify:jspecify:1.0.0"
5756

5857
fuel = { module = "com.github.kittinunf.fuel:fuel", version.ref = "fuel" }
5958
fuel-coroutines = { module = "com.github.kittinunf.fuel:fuel-coroutines", version.ref = "fuel" }
6059

61-
sentry = "io.sentry:sentry:8.22.0"
60+
sentry = "io.sentry:sentry:8.37.1"
6261

6362
# Testing
6463
test-mixin = "org.spongepowered:mixin:0.8.5"
65-
test-spigotapi = "org.spigotmc:spigot-api:1.21-R0.1-SNAPSHOT"
66-
test-bungeecord = "net.md-5:bungeecord-api:1.21-R0.3"
64+
test-spigotapi = "org.spigotmc:spigot-api:1.21.11-R0.2-SNAPSHOT"
65+
test-bungeecord = "net.md-5:bungeecord-api:1.21-R0.4"
6766
test-spongeapi = "org.spongepowered:spongeapi:7.4.0"
68-
test-fabricloader = "net.fabricmc:fabric-loader:0.15.11"
67+
test-fabricloader = "net.fabricmc:fabric-loader:0.18.5"
6968
test-nbt = "com.demonwav.mcdev:all-types-nbt:1.0"
7069

7170
junit-api = { module = "org.junit.jupiter:junit-jupiter-api", version.ref = "junit" }
7271
junit-engine = { module = "org.junit.jupiter:junit-jupiter-engine", version.ref = "junit" }
7372
junit-vintage = { module = "org.junit.vintage:junit-vintage-engine", version.ref = "junit" }
74-
junit-platform-launcher = { module = "org.junit.platform:junit-platform-launcher", version.ref = "junit-platform" }
73+
junit-platform-launcher = { module = "org.junit.platform:junit-platform-launcher", version.ref = "junit" }
7574

76-
mixinExtras-common = "io.github.llamalad7:mixinextras-common:0.5.0-beta.1"
75+
mixinExtras-common = "io.github.llamalad7:mixinextras-common:0.5.3"
7776

7877
[bundles]
7978
coroutines = ["coroutines-swing"]

src/main/kotlin/platform/fabric/FabricModule.kt

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,7 @@
33
*
44
* https://mcdev.io/
55
*
6-
* Copyright (C) 2025 minecraft-dev
6+
* Copyright (C) 2026 minecraft-dev
77
*
88
* This program is free software: you can redistribute it and/or modify
99
* it under the terms of the GNU Lesser General Public License as published
@@ -136,7 +136,7 @@ class FabricModule internal constructor(facet: MinecraftFacet) : AbstractModule(
136136

137137
override fun visitMethodArg(argPosition: Int, lvIndex: Int, srcName: String?) = false
138138

139-
override fun visitMethodVar(lvtRowIndex: Int, lvIndex: Int, startOpIdx: Int, srcName: String?) = false
139+
override fun visitMethodVar(lvtRowIndex: Int, lvIndex: Int, startOpIdx: Int, endOpIdx: Int, srcName: String?) = false
140140

141141
override fun visitDstName(targetKind: MappedElementKind?, namespace: Int, name: String) {
142142
if (namespace == namedIndex && name == "net/minecraft/client/MinecraftClient") {

src/main/kotlin/platform/mcp/fabricloom/TinyUnscrambler.kt

Lines changed: 11 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,7 @@
33
*
44
* https://mcdev.io/
55
*
6-
* Copyright (C) 2025 minecraft-dev
6+
* Copyright (C) 2026 minecraft-dev
77
*
88
* This program is free software: you can redistribute it and/or modify
99
* it under the terms of the GNU Lesser General Public License as published
@@ -137,21 +137,25 @@ class TinyUnscrambler : UnscrambleSupport<TinyUnscrambler.SettingsComponent> {
137137
return true
138138
}
139139

140-
override fun visitField(srcName: String, srcDesc: String): Boolean {
141-
src = srcName
140+
override fun visitField(srcName: String?, srcDesc: String?): Boolean {
141+
if (srcName != null) {
142+
src = srcName
143+
}
142144
return true
143145
}
144146

145-
override fun visitMethod(srcName: String, srcDesc: String): Boolean {
146-
src = srcName
147+
override fun visitMethod(srcName: String?, srcDesc: String?): Boolean {
148+
if (srcName != null) {
149+
src = srcName
150+
}
147151
return true
148152
}
149153

150-
override fun visitMethodArg(argPosition: Int, lvIndex: Int, srcName: String): Boolean {
154+
override fun visitMethodArg(argPosition: Int, lvIndex: Int, srcName: String?): Boolean {
151155
return false
152156
}
153157

154-
override fun visitMethodVar(lvtRowIndex: Int, lvIndex: Int, startOpIdx: Int, srcName: String): Boolean {
158+
override fun visitMethodVar(lvtRowIndex: Int, lvIndex: Int, startOpIdx: Int, endOpIdx: Int, srcName: String?): Boolean {
155159
return false
156160
}
157161

src/main/kotlin/platform/mcp/srg/TinySrgParser.kt

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,7 @@
33
*
44
* https://mcdev.io/
55
*
6-
* Copyright (C) 2025 minecraft-dev
6+
* Copyright (C) 2026 minecraft-dev
77
*
88
* This program is free software: you can redistribute it and/or modify
99
* it under the terms of the GNU Lesser General Public License as published
@@ -136,17 +136,17 @@ object TinySrgParser : SrgParser {
136136
return true
137137
}
138138

139-
override fun visitMethod(srcName: String, srcDesc: String): Boolean {
139+
override fun visitMethod(srcName: String?, srcDesc: String?): Boolean {
140140
inter = srcName
141141
desc = srcDesc
142142
return true
143143
}
144144

145-
override fun visitMethodArg(argPosition: Int, lvIndex: Int, srcName: String): Boolean {
145+
override fun visitMethodArg(argPosition: Int, lvIndex: Int, srcName: String?): Boolean {
146146
return false
147147
}
148148

149-
override fun visitMethodVar(lvtRowIndex: Int, lvIndex: Int, startOpIdx: Int, srcName: String): Boolean {
149+
override fun visitMethodVar(lvtRowIndex: Int, lvIndex: Int, startOpIdx: Int, endOpIdx: Int, srcName: String?): Boolean {
150150
return false
151151
}
152152

src/main/kotlin/platform/mcp/vanillagradle/VanillaGradleDecompileSourceProvider.kt

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,7 @@
33
*
44
* https://mcdev.io/
55
*
6-
* Copyright (C) 2025 minecraft-dev
6+
* Copyright (C) 2026 minecraft-dev
77
*
88
* This program is free software: you can redistribute it and/or modify
99
* it under the terms of the GNU Lesser General Public License as published
@@ -68,7 +68,7 @@ class VanillaGradleDecompileSourceProvider : AttachSourcesProvider {
6868
val taskCallback = object : TaskCallback {
6969
override fun onSuccess() {
7070
val importSpec = ImportSpecBuilder(project, GradleConstants.SYSTEM_ID)
71-
.callback(
71+
.withCallback(
7272
object : ExternalProjectRefreshCallback {
7373
override fun onSuccess(externalProject: DataNode<ProjectData>?) = callback.setDone()
7474

src/main/kotlin/platform/mixin/inspection/MixinClassTypeInspection.kt

Lines changed: 4 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,7 @@
33
*
44
* https://mcdev.io/
55
*
6-
* Copyright (C) 2025 minecraft-dev
6+
* Copyright (C) 2026 minecraft-dev
77
*
88
* This program is free software: you can redistribute it and/or modify
99
* it under the terms of the GNU Lesser General Public License as published
@@ -27,6 +27,7 @@ import com.demonwav.mcdev.platform.mixin.util.mixinTargets
2727
import com.intellij.codeInspection.LocalQuickFix
2828
import com.intellij.codeInspection.LocalQuickFixOnPsiElement
2929
import com.intellij.codeInspection.ProblemsHolder
30+
import com.intellij.java.syntax.parser.JavaKeywords
3031
import com.intellij.openapi.project.Project
3132
import com.intellij.psi.JavaElementVisitor
3233
import com.intellij.psi.JavaPsiFacade
@@ -61,9 +62,9 @@ class MixinClassTypeInspection : MixinInspection() {
6162
val fixes = mutableListOf<LocalQuickFix>()
6263
if (classKeywordElement != null) {
6364
if (needsToBeClass && !needsToBeInterface) {
64-
fixes += ChangeClassTypeFix(classKeywordElement, PsiKeyword.CLASS)
65+
fixes += ChangeClassTypeFix(classKeywordElement, JavaKeywords.CLASS)
6566
} else if (needsToBeInterface && !needsToBeClass) {
66-
fixes += ChangeClassTypeFix(classKeywordElement, PsiKeyword.INTERFACE)
67+
fixes += ChangeClassTypeFix(classKeywordElement, JavaKeywords.INTERFACE)
6768
}
6869
}
6970

src/main/kotlin/platform/mixin/util/AsmUtil.kt

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,7 @@
33
*
44
* https://mcdev.io/
55
*
6-
* Copyright (C) 2025 minecraft-dev
6+
* Copyright (C) 2026 minecraft-dev
77
*
88
* This program is free software: you can redistribute it and/or modify
99
* it under the terms of the GNU Lesser General Public License as published
@@ -42,6 +42,7 @@ import com.demonwav.mcdev.util.toJavaIdentifier
4242
import com.intellij.byteCodeViewer.ByteCodeViewerManager
4343
import com.intellij.codeEditor.JavaEditorFileSwapper
4444
import com.intellij.ide.highlighter.JavaFileType
45+
import com.intellij.java.syntax.parser.JavaKeywords
4546
import com.intellij.openapi.module.Module
4647
import com.intellij.openapi.progress.ProcessCanceledException
4748
import com.intellij.openapi.project.Project
@@ -1050,7 +1051,7 @@ fun MethodNode.findBodyElements(clazz: ClassNode, project: Project, scope: Globa
10501051
if (body != null) {
10511052
val children = body.children
10521053
val superCtorIndex = children.indexOfFirst {
1053-
it is PsiMethodCallExpression && it.methodExpression.text == PsiKeyword.SUPER
1054+
it is PsiMethodCallExpression && it.methodExpression.text == JavaKeywords.SUPER
10541055
}
10551056
result += children.take(superCtorIndex + 1)
10561057
sourceMethod.containingClass?.children?.forEach { element ->

0 commit comments

Comments
 (0)