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
123 changes: 118 additions & 5 deletions mpp-idea/build.gradle.kts
Original file line number Diff line number Diff line change
Expand Up @@ -2,10 +2,10 @@ import org.jetbrains.intellij.platform.gradle.TestFrameworkType

plugins {
id("java")
kotlin("jvm") version "2.2.0"
id("org.jetbrains.intellij.platform") version "2.10.2"
kotlin("plugin.compose") version "2.2.0"
kotlin("plugin.serialization") version "2.2.0"
kotlin("jvm")
id("org.jetbrains.intellij.platform")
kotlin("plugin.compose")
kotlin("plugin.serialization")
}

group = "cc.unitmesh.devins"
Expand All @@ -26,14 +26,80 @@ kotlin {

repositories {
mavenCentral()
google()
// Required for mpp-ui's webview dependencies (jogamp)
maven("https://jogamp.org/deployment/maven")
maven("https://oss.sonatype.org/content/repositories/snapshots/")
maven("https://packages.jetbrains.team/maven/p/ij/intellij-dependencies/")

intellijPlatform {
defaultRepositories()
}
google()
}

dependencies {
// Depend on mpp-ui and mpp-core JVM targets for shared UI components and ConfigManager
// For KMP projects, we need to depend on the JVM target specifically
// IMPORTANT: Exclude ALL transitive dependencies that conflict with IntelliJ's bundled libraries
implementation("cc.unitmesh.devins:mpp-ui-jvm") {
// Exclude all Compose dependencies - IntelliJ provides its own via bundledModules
exclude(group = "org.jetbrains.compose")
exclude(group = "org.jetbrains.compose.runtime")
exclude(group = "org.jetbrains.compose.foundation")
exclude(group = "org.jetbrains.compose.material3")
exclude(group = "org.jetbrains.compose.material")
exclude(group = "org.jetbrains.compose.ui")
exclude(group = "org.jetbrains.compose.desktop")
exclude(group = "org.jetbrains.compose.components")
exclude(group = "org.jetbrains.compose.animation")
exclude(group = "org.jetbrains.skiko")
// Exclude kotlinx libraries - IntelliJ provides its own
exclude(group = "org.jetbrains.kotlinx", module = "kotlinx-coroutines-core")
exclude(group = "org.jetbrains.kotlinx", module = "kotlinx-coroutines-core-jvm")
exclude(group = "org.jetbrains.kotlinx", module = "kotlinx-coroutines-swing")
exclude(group = "org.jetbrains.kotlinx", module = "kotlinx-serialization-json")
exclude(group = "org.jetbrains.kotlinx", module = "kotlinx-serialization-json-jvm")
exclude(group = "org.jetbrains.kotlinx", module = "kotlinx-serialization-json-io")
exclude(group = "org.jetbrains.kotlinx", module = "kotlinx-serialization-json-io-jvm")
exclude(group = "org.jetbrains.kotlinx", module = "kotlinx-serialization-core")
exclude(group = "org.jetbrains.kotlinx", module = "kotlinx-serialization-core-jvm")
exclude(group = "org.jetbrains.kotlinx", module = "kotlinx-io-core")
exclude(group = "org.jetbrains.kotlinx", module = "kotlinx-io-core-jvm")
// Exclude webview/KCEF - not needed in IntelliJ and causes issues
exclude(group = "io.github.kevinnzou")
exclude(group = "dev.datlag")
// Exclude other UI libraries that may conflict
exclude(group = "com.mohamedrejeb.richeditor")
exclude(group = "cafe.adriel.bonsai")
exclude(group = "com.mikepenz")
exclude(group = "org.jetbrains.jediterm")
exclude(group = "org.jetbrains.pty4j")
exclude(group = "io.github.vinceglb")
// Exclude SQLDelight - not needed in IntelliJ plugin
exclude(group = "app.cash.sqldelight")
}
implementation("cc.unitmesh.devins:mpp-core-jvm") {
// Exclude Compose dependencies from mpp-core as well
exclude(group = "org.jetbrains.compose")
exclude(group = "org.jetbrains.compose.runtime")
exclude(group = "org.jetbrains.compose.foundation")
exclude(group = "org.jetbrains.compose.material3")
exclude(group = "org.jetbrains.compose.material")
exclude(group = "org.jetbrains.compose.ui")
exclude(group = "org.jetbrains.skiko")
// Exclude kotlinx libraries - IntelliJ provides its own
exclude(group = "org.jetbrains.kotlinx", module = "kotlinx-coroutines-core")
exclude(group = "org.jetbrains.kotlinx", module = "kotlinx-coroutines-core-jvm")
exclude(group = "org.jetbrains.kotlinx", module = "kotlinx-serialization-json")
exclude(group = "org.jetbrains.kotlinx", module = "kotlinx-serialization-json-jvm")
exclude(group = "org.jetbrains.kotlinx", module = "kotlinx-serialization-json-io")
exclude(group = "org.jetbrains.kotlinx", module = "kotlinx-serialization-json-io-jvm")
exclude(group = "org.jetbrains.kotlinx", module = "kotlinx-serialization-core")
exclude(group = "org.jetbrains.kotlinx", module = "kotlinx-serialization-core-jvm")
exclude(group = "org.jetbrains.kotlinx", module = "kotlinx-io-core")
exclude(group = "org.jetbrains.kotlinx", module = "kotlinx-io-core-jvm")
}

// Use platform-provided kotlinx libraries to avoid classloader conflicts
compileOnly("org.jetbrains.kotlinx:kotlinx-serialization-json:1.7.3")
compileOnly("org.jetbrains.kotlinx:kotlinx-coroutines-core:1.10.1")
Expand Down Expand Up @@ -85,4 +151,51 @@ tasks {
test {
useJUnitPlatform()
}

// Task to verify no conflicting dependencies are included
register("verifyNoDuplicateDependencies") {
group = "verification"
description = "Verifies that no Compose/Kotlinx dependencies are included that would conflict with IntelliJ's bundled versions"

doLast {
val forbiddenPatterns = listOf(
"org.jetbrains.compose",
"org.jetbrains.skiko",
"kotlinx-coroutines-core",
"kotlinx-coroutines-swing",
"kotlinx-serialization-json",
"kotlinx-serialization-core"
)

val runtimeClasspath = configurations.getByName("runtimeClasspath")
val violations = mutableListOf<String>()

runtimeClasspath.resolvedConfiguration.resolvedArtifacts.forEach { artifact ->
val id = artifact.moduleVersion.id
val fullName = "${id.group}:${id.name}:${id.version}"
forbiddenPatterns.forEach { pattern ->
if (fullName.contains(pattern)) {
violations.add(fullName)
}
}
}

if (violations.isNotEmpty()) {
throw GradleException("""
|DEPENDENCY CONFLICT DETECTED!
|The following dependencies will conflict with IntelliJ's bundled libraries:
|${violations.joinToString("\n") { " - $it" }}
|
|These dependencies must be excluded from mpp-ui and mpp-core.
""".trimMargin())
} else {
println("✓ No conflicting dependencies found in runtime classpath")
}
}
}

// Run verification before build
named("build") {
dependsOn("verifyNoDuplicateDependencies")
}
Comment on lines +156 to +200
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

⚠️ Potential issue | 🟠 Major

Pattern matching logic in verification task has overlapping patterns causing false positives.

The forbiddenPatterns list uses string .contains() matching, which can produce false positives. For example:

  • Pattern "kotlinx-coroutines-core" will match "kotlinx-coroutines-core-jvm" ✓ (intended)
  • But also inadvertently matches "kotlinx-coroutines-swing" if it contains "kotlinx-coroutines-core" as a substring (potential issue)

Additionally, the forbidden pattern list (lines 161–168) overlaps semantically without explicit boundary checks.

Apply this diff to improve pattern matching robustness:

-            val forbiddenPatterns = listOf(
-                "org.jetbrains.compose",
-                "org.jetbrains.skiko",
-                "kotlinx-coroutines-core",
-                "kotlinx-coroutines-swing",
-                "kotlinx-serialization-json",
-                "kotlinx-serialization-core"
-            )
-
-            val runtimeClasspath = configurations.getByName("runtimeClasspath")
-            val violations = mutableListOf<String>()
-
-            runtimeClasspath.resolvedConfiguration.resolvedArtifacts.forEach { artifact ->
-                val id = artifact.moduleVersion.id
-                val fullName = "${id.group}:${id.name}:${id.version}"
-                forbiddenPatterns.forEach { pattern ->
-                    if (fullName.contains(pattern)) {
-                        violations.add(fullName)
-                    }
-                }
-            }
+            val forbiddenGroups = setOf(
+                "org.jetbrains.compose",
+                "org.jetbrains.skiko",
+                "io.github.kevinnzou",
+                "dev.datlag"
+            )
+            val forbiddenModulePatterns = setOf(
+                "kotlinx-coroutines-core",
+                "kotlinx-coroutines-swing",
+                "kotlinx-serialization-json",
+                "kotlinx-serialization-core",
+                "kotlinx-io-core"
+            )
+
+            val runtimeClasspath = configurations.getByName("runtimeClasspath")
+            val violations = mutableListOf<String>()
+
+            runtimeClasspath.resolvedConfiguration.resolvedArtifacts.forEach { artifact ->
+                val id = artifact.moduleVersion.id
+                val fullName = "${id.group}:${id.name}:${id.version}"
+                
+                // Check if group is in forbidden list
+                if (forbiddenGroups.contains(id.group)) {
+                    violations.add(fullName)
+                } else if (forbiddenModulePatterns.any { id.name == it || id.name.startsWith(it + "-") }) {
+                    // Check specific module names with proper boundary checking
+                    violations.add(fullName)
+                }
+            }

}
20 changes: 16 additions & 4 deletions mpp-idea/settings.gradle.kts
Original file line number Diff line number Diff line change
@@ -1,16 +1,28 @@
rootProject.name = "mpp-idea"

enableFeaturePreview("TYPESAFE_PROJECT_ACCESSORS")

pluginManagement {
repositories {
google()
mavenCentral()
gradlePluginPortal()
}

plugins {
kotlin("jvm") version "2.1.20"
kotlin("plugin.compose") version "2.1.20"
kotlin("plugin.serialization") version "2.1.20"
id("org.jetbrains.intellij.platform") version "2.10.2"
}
}

dependencyResolutionManagement {
repositories {
google()
mavenCentral()
// Include mpp-ui from parent project for shared UI components and ConfigManager
// For KMP projects, we substitute the JVM target artifacts
includeBuild("..") {
dependencySubstitution {
substitute(module("cc.unitmesh.devins:mpp-ui-jvm")).using(project(":mpp-ui"))
substitute(module("cc.unitmesh.devins:mpp-core-jvm")).using(project(":mpp-core"))
}
}

This file was deleted.

This file was deleted.

This file was deleted.

Loading
Loading