[Gradle, Kapt] Don't immediately check if kaptClasspath dependencies are empty

Now sub-plugins are applied to compilation before users `afterEvaluate`
closure execution, which could lead to unexpected by the user state.
For example, when a user adds dependencies to 'kaptClasspath' in
'afterEvaluate'.

This fix removes check in Kapt plugin if dependencies are present on
'kaptClasspath' and moves it into KaptTask.onlyIf spec. So the task
will still have SKIPPED state if there are no AP provided.

^KT-63366 Fixed
This commit is contained in:
Yahor Berdnikau
2023-11-13 17:52:43 +01:00
committed by Space Team
parent 80cccce8d0
commit 59f544cb7c
5 changed files with 62 additions and 15 deletions
@@ -155,6 +155,33 @@ open class Kapt3IT : Kapt3BaseIT() {
project("kaptSkipped".withPrefix, gradleVersion, enableKotlinDaemonMemoryLimitInMb = 2048) {
build("build") {
assertTasksSkipped(":kaptGenerateStubsKotlin", ":kaptKotlin")
assertOutputContains("No annotation processors provided. Skip KAPT processing.")
}
}
}
@DisplayName("KT-63366: Adding kapt AP dependency in afterEvaluate for custom SourceSet")
@GradleTest
fun testKaptCustomSourceSetDependencyAfterEvaluate(gradleVersion: GradleVersion) {
project("simple".withPrefix, gradleVersion) {
buildGradle.appendText(
//language=groovy
"""
|
|sourceSets.create("custom")
|
|afterEvaluate {
| configurations.getByName("kaptCustom").dependencies.add(
| dependencies.create("org.jetbrains.kotlin:annotation-processor-example")
| )
|}
""".trimMargin()
)
build(":kaptCustomKotlin", forceOutput = true) {
assertTasksExecuted(":kaptCustomKotlin")
assertOutputDoesNotContain("No annotation processors provided. Skip KAPT processing.")
assertOutputContains("Annotation processors: example.ExampleAnnotationProcessor, example.KotlinFilerGeneratingProcessor")
}
}
}
@@ -179,11 +179,16 @@ class UpToDateIT : KGPBaseTest() {
override fun initProject(project: TestProject) = with(project) {
buildGradle.appendText(
"\n" + """
apply plugin: 'kotlin-kapt'
plugins.apply("org.jetbrains.kotlin.plugin.allopen")
allOpen { annotation("allopen.Foo"); annotation("allopen.Bar") }
""".trimIndent()
"""
|
|apply plugin: 'kotlin-kapt'
|plugins.apply("org.jetbrains.kotlin.plugin.allopen")
|allOpen { annotation("allopen.Foo"); annotation("allopen.Bar") }
|
|dependencies {
| kapt 'org.jetbrains.kotlin:annotation-processor-example'
|}
""".trimMargin()
)
}
@@ -225,6 +225,10 @@ open class Kapt3AndroidIT : Kapt3BaseIT() {
android.applicationVariants.all {
it.javaCompileOptions.annotationProcessorOptions.compilerArgumentProviders.add(nested)
}
dependencies {
kapt 'org.jetbrains.kotlin:annotation-processor-example'
}
""".trimIndent()
)
@@ -277,13 +277,16 @@ class Kapt3GradleSubplugin @Inject internal constructor(private val registry: To
val kaptExtension = project.extensions.getByType(KaptExtension::class.java)
val nonEmptyKaptConfigurations = kaptConfigurations.filter { it.allDependencies.isNotEmpty() }
val javaCompileOrNull = findJavaTaskForKotlinCompilation(kotlinCompilation)
val context = Kapt3SubpluginContext(
project, javaCompileOrNull,
androidVariantData, sourceSetName, kotlinCompilation, kaptExtension, nonEmptyKaptConfigurations
project,
javaCompileOrNull,
androidVariantData,
sourceSetName,
kotlinCompilation,
kaptExtension,
kaptConfigurations,
)
val kaptGenerateStubsTaskProvider: TaskProvider<KaptGenerateStubsTask> = context.createKaptGenerateStubsTask()
@@ -369,6 +372,7 @@ class Kapt3GradleSubplugin @Inject internal constructor(private val registry: To
.setExtendsFrom(kaptClasspathConfigurations).also {
it.isVisible = false
it.isCanBeConsumed = false
it.isCanBeResolved = true
}
taskConfigAction.configureTaskProvider { taskProvider ->
taskProvider.dependsOn(generateStubsTask)
@@ -5,6 +5,7 @@
package org.jetbrains.kotlin.gradle.internal
import org.gradle.api.Task
import org.gradle.api.file.ConfigurableFileCollection
import org.gradle.api.file.FileCollection
import org.gradle.api.model.ObjectFactory
@@ -12,6 +13,7 @@ import org.gradle.api.provider.ListProperty
import org.gradle.api.provider.MapProperty
import org.gradle.api.provider.Property
import org.gradle.api.provider.ProviderFactory
import org.gradle.api.specs.Spec
import org.gradle.api.tasks.CacheableTask
import org.gradle.api.tasks.Input
import org.gradle.api.tasks.Internal
@@ -64,6 +66,17 @@ abstract class KaptWithoutKotlincTask @Inject constructor(
@get:Input
val kaptProcessJvmArgs: ListProperty<String> = objectFactory.listPropertyWithConvention(emptyList())
init {
// Skip annotation processing if no annotation processors were provided.
onlyIf { task ->
with(task as KaptWithoutKotlincTask) {
val isRunTask = !(annotationProcessorFqNames.get().isEmpty() && kaptClasspath.isEmpty())
if (!isRunTask) task.logger.info("No annotation processors provided. Skip KAPT processing.")
isRunTask
}
}
}
private fun getAnnotationProcessorOptions(): Map<String, String> {
val result = mutableMapOf<String, String>()
kaptPluginOptions.toSingleCompilerPluginOptions().subpluginOptionsByPluginId[Kapt3GradleSubplugin.KAPT_SUBPLUGIN_ID]?.forEach {
@@ -133,12 +146,6 @@ abstract class KaptWithoutKotlincTask @Inject constructor(
disableClassloaderCacheForProcessors
)
// Skip annotation processing if no annotation processors were provided.
if (annotationProcessorFqNames.get().isEmpty() && kaptClasspath.isEmpty()) {
logger.info("No annotation processors provided. Skip KAPT processing.")
return
}
val kaptClasspath = kaptJars
val isolationMode = getWorkerIsolationMode()
logger.info("Using workers $isolationMode isolation mode to run kapt")