Create SubpluginOptions from processor config, fix tests
diff --git a/gradle-plugin/src/main/kotlin/com/google/devtools/ksp/gradle/KspConfigurations.kt b/gradle-plugin/src/main/kotlin/com/google/devtools/ksp/gradle/KspConfigurations.kt
index a4508e8..5423a53 100644
--- a/gradle-plugin/src/main/kotlin/com/google/devtools/ksp/gradle/KspConfigurations.kt
+++ b/gradle-plugin/src/main/kotlin/com/google/devtools/ksp/gradle/KspConfigurations.kt
@@ -115,6 +115,8 @@
* that don't belong to any compilation, like user-defined intermediate source sets (e.g. iosMain).
* These do not currently have their own ksp configuration.
* 2) all* can return sets belonging to other [KotlinCompilation]s
+ *
+ * See test: SourceSetConfigurationsTest.configurationsForMultiplatformApp_doesNotCrossCompilationBoundaries
*/
fun find(compilation: KotlinCompilation<*>): Set<Configuration> {
val kotlinConfigurations = compilation.kotlinSourceSets.mapNotNull { kotlinConfigurations[it] }
diff --git a/gradle-plugin/src/main/kotlin/com/google/devtools/ksp/gradle/KspSubplugin.kt b/gradle-plugin/src/main/kotlin/com/google/devtools/ksp/gradle/KspSubplugin.kt
index f547623..78ac68d 100644
--- a/gradle-plugin/src/main/kotlin/com/google/devtools/ksp/gradle/KspSubplugin.kt
+++ b/gradle-plugin/src/main/kotlin/com/google/devtools/ksp/gradle/KspSubplugin.kt
@@ -104,7 +104,7 @@
private fun getSubpluginOptions(
project: Project,
kspExtension: KspExtension,
- nonEmptyKspConfigurations: List<Configuration>,
+ classpath: Configuration,
sourceSetName: String,
isIncremental: Boolean,
): List<SubpluginOption> {
@@ -121,7 +121,7 @@
project.findProperty("ksp.incremental.log")?.toString() ?: "false"
)
options += SubpluginOption("projectBaseDir", project.project.projectDir.canonicalPath)
- options += FilesSubpluginOption("apclasspath", nonEmptyKspConfigurations.flatten())
+ options += FilesSubpluginOption("apclasspath", classpath.toList())
kspExtension.apOptions.forEach {
options += SubpluginOption("apoption", "${it.key}=${it.value}")
@@ -186,12 +186,18 @@
val kotlinCompileTask = kotlinCompileProvider.get()
fun configureAsKspTask(kspTask: KspTask, isIncremental: Boolean) {
+ // depends on the processor; if the processor changes, it needs to be reprocessed.
+ val processorClasspath = project.configurations.maybeCreate("${kspTaskName}ProcessorClasspath")
+ .extendsFrom(*nonEmptyKspConfigurations.toTypedArray())
+ kspTask.processorClasspath.from(processorClasspath)
+ kspTask.dependsOn(processorClasspath.buildDependencies)
+
kspTask.options.addAll(
kspTask.project.provider {
getSubpluginOptions(
project,
kspExtension,
- nonEmptyKspConfigurations,
+ processorClasspath,
sourceSetName,
isIncremental
)
@@ -202,11 +208,6 @@
kspTask.apOptions.value(kspExtension.arguments).disallowChanges()
kspTask.kspCacheDir.fileValue(getKspCachesDir(project, sourceSetName)).disallowChanges()
- // depends on the processor; if the processor changes, it needs to be reprocessed.
- val processorClasspath = project.configurations.maybeCreate("${kspTaskName}ProcessorClasspath")
- .extendsFrom(*nonEmptyKspConfigurations.toTypedArray())
- kspTask.processorClasspath.from(processorClasspath)
- kspTask.dependsOn(processorClasspath.buildDependencies)
if (kspExtension.blockOtherCompilerPlugins) {
// FIXME: ask upstream to provide an API to make this not implementation-dependent.
diff --git a/gradle-plugin/src/test/kotlin/com/google/devtools/ksp/gradle/GradleCompilationTest.kt b/gradle-plugin/src/test/kotlin/com/google/devtools/ksp/gradle/GradleCompilationTest.kt
index 70b5924..3535133 100644
--- a/gradle-plugin/src/test/kotlin/com/google/devtools/ksp/gradle/GradleCompilationTest.kt
+++ b/gradle-plugin/src/test/kotlin/com/google/devtools/ksp/gradle/GradleCompilationTest.kt
@@ -111,7 +111,7 @@
testRule.runner()
.withDebug(true)
- .withArguments("app:assemble")
+ .withArguments("app:assemble", "--stacktrace")
.forwardOutput()
.build()
}
diff --git a/gradle-plugin/src/test/kotlin/com/google/devtools/ksp/gradle/SourceSetConfigurationsTest.kt b/gradle-plugin/src/test/kotlin/com/google/devtools/ksp/gradle/SourceSetConfigurationsTest.kt
index 02aded2..b754930 100644
--- a/gradle-plugin/src/test/kotlin/com/google/devtools/ksp/gradle/SourceSetConfigurationsTest.kt
+++ b/gradle-plugin/src/test/kotlin/com/google/devtools/ksp/gradle/SourceSetConfigurationsTest.kt
@@ -47,8 +47,9 @@
val result = testRule.runner()
.withArguments(":app:dependencies")
.build()
+ val configurations = result.output.lines().map { it.split(' ').first() }
- assertThat(result.output.lines()).containsAtLeast("ksp", "kspTest")
+ assertThat(configurations).containsAtLeast("ksp", "kspTest")
}
@Test
@@ -58,8 +59,9 @@
val result = testRule.runner()
.withArguments(":app:dependencies")
.build()
+ val configurations = result.output.lines().map { it.split(' ').first() }
- assertThat(result.output.lines()).containsAtLeast(
+ assertThat(configurations).containsAtLeast(
"ksp",
"kspAndroidTest",
"kspAndroidTestDebug",
@@ -87,8 +89,9 @@
val result = testRule.runner()
.withArguments(":app:dependencies")
.build()
+ val configurations = result.output.lines().map { it.split(' ').first() }
- assertThat(result.output.lines()).containsAtLeast(
+ assertThat(configurations).containsAtLeast(
// jvm target:
"kspJvm",
"kspJvmTest",
@@ -115,6 +118,42 @@
}
@Test
+ fun configurationsForMultiplatformApp_doesNotCrossCompilationBoundaries() {
+ // Adding a ksp dependency on jvmParent should not leak into jvmChild compilation,
+ // even if the source sets depend on each other. This works because we use
+ // KotlinCompilation.kotlinSourceSets instead of KotlinCompilation.allKotlinSourceSets
+ testRule.setupAppAsMultiplatformApp("""
+ kotlin {
+ jvm("jvmParent") { }
+ jvm("jvmChild") { }
+ }
+ """.trimIndent())
+ testRule.appModule.addMultiplatformSource("commonMain", "Foo.kt", "class Foo")
+ testRule.appModule.buildFileAdditions.add("""
+ kotlin {
+ sourceSets {
+ this["jvmChildMain"].dependsOn(this["jvmParentMain"])
+ }
+ }
+ dependencies {
+ add("kspJvmParent", "androidx.room:room-compiler:2.3.0")
+ }
+ tasks.register("checkConfigurations") {
+ doLast {
+ // child has no dependencies, so task is not created.
+ val parent = tasks.findByName("kspKotlinJvmParent")
+ val child = tasks.findByName("kspKotlinJvmChild")
+ require(parent != null)
+ require(child == null)
+ }
+ }
+ """.trimIndent())
+ testRule.runner()
+ .withArguments(":app:checkConfigurations")
+ .build()
+ }
+
+ @Test
fun registerJavaSourcesToAndroid() {
testRule.setupAppAsAndroidApp()
testRule.appModule.dependencies.addAll(
@@ -236,10 +275,11 @@
.build()
// kaptClasspath_* seem to be intermediate configurations that never run.
- val kaptConfigurations = result.output.lines().filter {
+ val configurations = result.output.lines().map { it.split(' ').first() }
+ val kaptConfigurations = configurations.filter {
it.startsWith("kapt") && !it.startsWith("kaptClasspath_")
}
- val kspConfigurations = result.output.lines().filter {
+ val kspConfigurations = configurations.filter {
it.startsWith("ksp")
}
assertThat(kspConfigurations).containsExactlyElementsIn(