Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
@@ -0,0 +1,54 @@
// Copyright 2024 Amazon.com, Inc. or its affiliates. All Rights Reserved.
// SPDX-License-Identifier: Apache-2.0

package software.aws.toolkits.gradle.intellij

import java.io.File

/**
* Gateway 2026.1 product-info.json has moduleV2/productModuleV2 layout entries without
* "classPath". intellij-plugin-structure declares ProductModuleV2.classPath as non-null
* Kotlin parameter, so Jackson throws NPE during deserialization.
*
* Bug exists on master: https://github.com/JetBrains/intellij-plugin-verifier
* (intellij-plugin-structure/structure-intellij/.../ProductInfo.kt)
*
* Patches cached product-info.json to add empty classPath arrays where missing.
*/
object ProductInfoPatcher {
private val MISSING_CLASSPATH = Regex(
"""(?s)"kind"\s*:\s*"(moduleV2|productModuleV2)"\s*\}"""
)

fun patchGatewayProductInfo(gradleUserHome: File) {
val caches = gradleUserHome.resolve("caches")
if (!caches.isDirectory) return

caches.listFiles()
?.filter { it.isDirectory && it.name.matches(Regex("\\d+\\.\\d+")) }
?.forEach { versionDir ->
val transformsDir = versionDir.resolve("transforms")
if (!transformsDir.isDirectory) return@forEach
transformsDir.listFiles()?.forEach inner@{ transformDir ->
val transformed = transformDir.resolve("transformed")
if (!transformed.isDirectory) return@inner
transformed.listFiles()
?.filter { it.name.startsWith("JetBrainsGateway") }
?.forEach { gatewayDir ->
patchFile(gatewayDir.resolve("product-info.json"))
}
}
}
}

private fun patchFile(productInfo: File) {
if (!productInfo.isFile) return
val content = productInfo.readText()
val patched = MISSING_CLASSPATH.replace(content) {
"\"kind\": \"${it.groupValues[1]}\",\n \"classPath\": []\n }"
}
if (patched != content) {
productInfo.writeText(patched)
}
}
}
11 changes: 11 additions & 0 deletions buildSrc/src/main/kotlin/toolkit-intellij-subplugin.gradle.kts
Original file line number Diff line number Diff line change
Expand Up @@ -110,6 +110,17 @@ dependencies {
create(type, version, useInstaller = false)
} else {
create(IntelliJPlatformType.Gateway, version)

// Gateway 2026.1 product-info.json has layout entries without "classPath".
// intellij-plugin-structure crashes on these (ProductModuleV2.classPath is non-null).
// Bug exists on master: https://github.com/JetBrains/intellij-plugin-verifier
// Force-resolve IDE, patch product-info.json, then let bundledPlugins proceed.
afterEvaluate {
configurations.findByName("intellijPlatformDependency")?.resolve()
software.aws.toolkits.gradle.intellij.ProductInfoPatcher.patchGatewayProductInfo(
gradle.gradleUserHomeDir
)
}
}

bundledPlugins(toolkitIntelliJ.productProfile().map { it.bundledPlugins })
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,9 @@
<incompatible-with>com.intellij.modules.python</incompatible-with>
<incompatible-with>com.intellij.java</incompatible-with>

<xi:include href="/META-INF/module-core.xml" />
<xi:include href="/META-INF/module-core.xml">
<xi:fallback/>
</xi:include>

<extensions defaultExtensionNs="com.intellij">
<applicationService serviceInterface="software.aws.toolkit.jetbrains.core.credentials.ToolkitConnectionManager"
Expand Down
2 changes: 1 addition & 1 deletion settings.gradle.kts
Original file line number Diff line number Diff line change
Expand Up @@ -170,7 +170,7 @@ file("plugins").listFiles()?.forEach root@ {
if (it.name == "jetbrains-gateway") {
when (providers.gradleProperty("ideProfileName").get()) {
// buildSrc is evaluated after settings so we can't key off of IdeVersions.kt
"2025.1", "2025.2", "2026.1" -> {
"2025.1", "2025.2" -> {
return@forEach
}
}
Expand Down
Loading