Delay kapt dependencies resolution from configuration phase
Store kapt configurations instead of classpath files in the tasks Delay wrapping kapt subplugin options to task execution (when the classpath can be safely resovled) Issue #KT-18821 Fixed
This commit is contained in:
+13
@@ -324,4 +324,17 @@ open class Kapt3IT : Kapt3BaseIT() {
|
||||
assertContains("Additional warning message from AP")
|
||||
}
|
||||
}
|
||||
|
||||
@Test
|
||||
fun testKaptConfigurationLazyResolution() = with(Project("simple", GRADLE_VERSION, directoryPrefix = "kapt2")) {
|
||||
setupWorkingDir()
|
||||
File(projectDir, "build.gradle").appendText(
|
||||
"\ndependencies { kapt project.files { throw new GradleException(\"Resolved!\") } }"
|
||||
)
|
||||
// Check that the kapt configuration does not get resolved during the project evaluation:
|
||||
build("tasks") {
|
||||
assertSuccessful()
|
||||
assertNotContains("Resolved!")
|
||||
}
|
||||
}
|
||||
}
|
||||
+23
-27
@@ -80,6 +80,7 @@ class Kapt3KotlinGradleSubplugin : KotlinGradleSubplugin<KotlinCompile> {
|
||||
|
||||
val KAPT_GROUP_NAME = "org.jetbrains.kotlin"
|
||||
val KAPT_ARTIFACT_NAME = "kotlin-annotation-processing-gradle"
|
||||
val KAPT_SUBPLUGIN_ID = "org.jetbrains.kotlin.kapt3"
|
||||
|
||||
fun getKaptConfigurationName(sourceSetName: String): String {
|
||||
return if (sourceSetName != "main")
|
||||
@@ -110,14 +111,15 @@ class Kapt3KotlinGradleSubplugin : KotlinGradleSubplugin<KotlinCompile> {
|
||||
}
|
||||
|
||||
private inner class Kapt3SubpluginContext(
|
||||
val project: Project,
|
||||
val kotlinCompile: KotlinCompile,
|
||||
val javaCompile: AbstractCompile,
|
||||
val kaptVariantData: KaptVariantData<*>?,
|
||||
val sourceSetName: String,
|
||||
val javaSourceSet: SourceSet?,
|
||||
val kaptExtension: KaptExtension,
|
||||
val kaptClasspath: MutableList<File>) {
|
||||
val project: Project,
|
||||
val kotlinCompile: KotlinCompile,
|
||||
val javaCompile: AbstractCompile,
|
||||
val kaptVariantData: KaptVariantData<*>?,
|
||||
val sourceSetName: String,
|
||||
val javaSourceSet: SourceSet?,
|
||||
val kaptExtension: KaptExtension,
|
||||
val kaptClasspathConfigurations: List<Configuration>
|
||||
) {
|
||||
val sourcesOutputDir = getKaptGeneratedSourcesDir(project, sourceSetName)
|
||||
val kotlinSourcesOutputDir = getKaptGeneratedKotlinSourcesDir(project, sourceSetName)
|
||||
val classesOutputDir = getKaptGeneratedClassesDir(project, sourceSetName)
|
||||
@@ -137,23 +139,13 @@ class Kapt3KotlinGradleSubplugin : KotlinGradleSubplugin<KotlinCompile> {
|
||||
): List<SubpluginOption> {
|
||||
assert((variantData != null) xor (javaSourceSet != null))
|
||||
|
||||
val kaptClasspath = arrayListOf<File>()
|
||||
val buildDependencies = arrayListOf<TaskDependency>()
|
||||
val kaptConfigurations = arrayListOf<Configuration>()
|
||||
|
||||
fun handleSourceSet(sourceSetName: String) {
|
||||
val kaptConfiguration = project.findKaptConfiguration(sourceSetName)
|
||||
val filteredDependencies = kaptConfiguration?.dependencies?.filter {
|
||||
it.group != getGroupName() || it.name != getArtifactName()
|
||||
} ?: emptyList()
|
||||
|
||||
if (kaptConfiguration != null) {
|
||||
project.findKaptConfiguration(sourceSetName)?.let { kaptConfiguration ->
|
||||
kaptConfigurations += kaptConfiguration
|
||||
buildDependencies += kaptConfiguration.buildDependencies
|
||||
|
||||
if (filteredDependencies.isNotEmpty()) {
|
||||
kaptClasspath.addAll(kaptConfiguration.resolve())
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -175,8 +167,14 @@ class Kapt3KotlinGradleSubplugin : KotlinGradleSubplugin<KotlinCompile> {
|
||||
|
||||
val kaptExtension = project.extensions.getByType(KaptExtension::class.java)
|
||||
|
||||
val context = Kapt3SubpluginContext(project, kotlinCompile, javaCompile,
|
||||
kaptVariantData, sourceSetName, javaSourceSet, kaptExtension, kaptClasspath)
|
||||
val nonEmptyKaptConfigurations = kaptConfigurations.filter { configuration ->
|
||||
configuration.dependencies.any { it.group != getGroupName() || it.name != getArtifactName() }
|
||||
}
|
||||
|
||||
val context = Kapt3SubpluginContext(
|
||||
project, kotlinCompile, javaCompile,
|
||||
kaptVariantData, sourceSetName, javaSourceSet, kaptExtension, nonEmptyKaptConfigurations
|
||||
)
|
||||
|
||||
val kaptGenerateStubsTask = context.createKaptGenerateStubsTask()
|
||||
val kaptTask = context.createKaptKotlinTask()
|
||||
@@ -208,8 +206,6 @@ class Kapt3KotlinGradleSubplugin : KotlinGradleSubplugin<KotlinCompile> {
|
||||
pluginOptions += SubpluginOption("aptMode", aptMode)
|
||||
disableAnnotationProcessingInJavaTask()
|
||||
|
||||
kaptClasspath.forEach { pluginOptions += FilesSubpluginOption("apclasspath", listOf(it)) }
|
||||
|
||||
javaCompile.source(generatedFilesDir)
|
||||
|
||||
pluginOptions += FilesSubpluginOption("sources", listOf(generatedFilesDir))
|
||||
@@ -246,7 +242,7 @@ class Kapt3KotlinGradleSubplugin : KotlinGradleSubplugin<KotlinCompile> {
|
||||
|
||||
private fun Kapt3SubpluginContext.buildAndAddOptionsTo(task: Task, container: CompilerPluginOptions, aptMode: String) {
|
||||
val compilerPluginId = getCompilerPluginId()
|
||||
val kaptSubpluginOptions = wrapPluginOptions(buildOptions(aptMode), "configuration")
|
||||
val kaptSubpluginOptions = buildOptions(aptMode)
|
||||
task.registerSubpluginOptionsAsInputs(compilerPluginId, kaptSubpluginOptions)
|
||||
|
||||
for (option in kaptSubpluginOptions) {
|
||||
@@ -320,7 +316,7 @@ class Kapt3KotlinGradleSubplugin : KotlinGradleSubplugin<KotlinCompile> {
|
||||
registerGeneratedJavaSource(kaptTask, javaCompile)
|
||||
}
|
||||
|
||||
kaptTask.kaptClasspath = kaptClasspath
|
||||
kaptTask.kaptClasspathConfigurations = kaptClasspathConfigurations
|
||||
|
||||
buildAndAddOptionsTo(kaptTask, kaptTask.pluginOptions, aptMode = "apt")
|
||||
|
||||
@@ -344,7 +340,7 @@ class Kapt3KotlinGradleSubplugin : KotlinGradleSubplugin<KotlinCompile> {
|
||||
kaptTask.generatedSourcesDir = sourcesOutputDir
|
||||
mapKotlinTaskProperties(project, kaptTask)
|
||||
|
||||
kaptTask.kaptClasspath = kaptClasspath
|
||||
kaptTask.kaptClasspathConfigurations = kaptClasspathConfigurations
|
||||
buildAndAddOptionsTo(kaptTask, kaptTask.pluginOptions, aptMode = "stubs")
|
||||
|
||||
return kaptTask
|
||||
@@ -372,7 +368,7 @@ class Kapt3KotlinGradleSubplugin : KotlinGradleSubplugin<KotlinCompile> {
|
||||
}
|
||||
}
|
||||
|
||||
override fun getCompilerPluginId() = "org.jetbrains.kotlin.kapt3"
|
||||
override fun getCompilerPluginId() = KAPT_SUBPLUGIN_ID
|
||||
override fun getGroupName() = KAPT_GROUP_NAME
|
||||
override fun getArtifactName() = KAPT_ARTIFACT_NAME
|
||||
}
|
||||
|
||||
+13
-2
@@ -17,11 +17,14 @@
|
||||
package org.jetbrains.kotlin.gradle.internal
|
||||
|
||||
import com.intellij.openapi.util.io.FileUtil
|
||||
import org.gradle.api.artifacts.Configuration
|
||||
import org.gradle.api.file.FileCollection
|
||||
import org.gradle.api.tasks.*
|
||||
import org.gradle.api.tasks.incremental.IncrementalTaskInputs
|
||||
import org.jetbrains.kotlin.cli.common.arguments.K2JVMCompilerArguments
|
||||
import org.jetbrains.kotlin.gradle.plugin.kotlinDebug
|
||||
import org.jetbrains.kotlin.gradle.plugin.kotlinWarn
|
||||
import org.jetbrains.kotlin.gradle.tasks.CompilerPluginOptions
|
||||
import org.jetbrains.kotlin.gradle.tasks.FilteringSourceRootsContainer
|
||||
import org.jetbrains.kotlin.gradle.tasks.KotlinCompile
|
||||
import org.jetbrains.kotlin.incremental.ChangedFiles
|
||||
@@ -44,7 +47,11 @@ open class KaptGenerateStubsTask : KotlinCompile() {
|
||||
lateinit var generatedSourcesDir: File
|
||||
|
||||
@get:Classpath @get:InputFiles
|
||||
lateinit var kaptClasspath: List<File>
|
||||
val kaptClasspath: FileCollection
|
||||
get() = project.files(*kaptClasspathConfigurations.toTypedArray())
|
||||
|
||||
@get:Internal
|
||||
internal lateinit var kaptClasspathConfigurations: List<Configuration>
|
||||
|
||||
@get:Classpath @get:InputFiles @Suppress("unused")
|
||||
internal val kotlinTaskPluginClasspath get() = kotlinCompileTask.pluginClasspath
|
||||
@@ -66,8 +73,12 @@ open class KaptGenerateStubsTask : KotlinCompile() {
|
||||
|
||||
override fun setupCompilerArgs(args: K2JVMCompilerArguments, defaultsOnly: Boolean) {
|
||||
kotlinCompileTask.setupCompilerArgs(args)
|
||||
|
||||
args.pluginClasspaths = (pluginClasspath + args.pluginClasspaths!!).toSet().toTypedArray()
|
||||
args.pluginOptions = (pluginOptions.arguments + args.pluginOptions!!).toTypedArray()
|
||||
|
||||
val pluginOptionsWithKapt = pluginOptions.withWrappedKaptOptions(withApClasspath = kaptClasspath)
|
||||
args.pluginOptions = (pluginOptionsWithKapt.arguments + args.pluginOptions!!).toTypedArray()
|
||||
|
||||
args.verbose = project.hasProperty("kapt.verbose") && project.property("kapt.verbose").toString().toBoolean() == true
|
||||
args.classpathAsList = this.compileClasspath.toList()
|
||||
args.destinationAsFile = this.destinationDir
|
||||
|
||||
+10
-2
@@ -3,6 +3,7 @@ package org.jetbrains.kotlin.gradle.internal
|
||||
import com.intellij.openapi.util.io.FileUtil
|
||||
import com.intellij.openapi.util.text.StringUtil.compareVersionNumbers
|
||||
import org.gradle.api.GradleException
|
||||
import org.gradle.api.artifacts.Configuration
|
||||
import org.gradle.api.file.FileCollection
|
||||
import org.gradle.api.internal.ConventionTask
|
||||
import org.gradle.api.tasks.*
|
||||
@@ -41,7 +42,11 @@ open class KaptTask : ConventionTask(), CompilerArgumentAwareWithInput<K2JVMComp
|
||||
}
|
||||
|
||||
@get:Classpath @get:InputFiles
|
||||
lateinit var kaptClasspath: List<File>
|
||||
val kaptClasspath: FileCollection
|
||||
get() = project.files(*kaptClasspathConfigurations.toTypedArray())
|
||||
|
||||
@get:Internal
|
||||
internal lateinit var kaptClasspathConfigurations: List<Configuration>
|
||||
|
||||
@get:OutputDirectory
|
||||
internal lateinit var classesDir: File
|
||||
@@ -58,7 +63,10 @@ open class KaptTask : ConventionTask(), CompilerArgumentAwareWithInput<K2JVMComp
|
||||
kotlinCompileTask.setupCompilerArgs(args)
|
||||
|
||||
args.pluginClasspaths = (pluginClasspath + args.pluginClasspaths!!).toSet().toTypedArray()
|
||||
args.pluginOptions = (pluginOptions.arguments + args.pluginOptions!!).toTypedArray()
|
||||
|
||||
val pluginOptionsWithKapt: CompilerPluginOptions = pluginOptions.withWrappedKaptOptions(withApClasspath = kaptClasspath)
|
||||
args.pluginOptions = (pluginOptionsWithKapt.arguments + args.pluginOptions!!).toTypedArray()
|
||||
|
||||
args.verbose = project.hasProperty("kapt.verbose") && project.property("kapt.verbose").toString().toBoolean() == true
|
||||
}
|
||||
|
||||
|
||||
+22
@@ -18,7 +18,10 @@ package org.jetbrains.kotlin.gradle.internal
|
||||
|
||||
import org.jetbrains.kotlin.gradle.plugin.SubpluginOption
|
||||
import org.jetbrains.kotlin.gradle.plugin.CompositeSubpluginOption
|
||||
import org.jetbrains.kotlin.gradle.plugin.FilesSubpluginOption
|
||||
import org.jetbrains.kotlin.gradle.tasks.CompilerPluginOptions
|
||||
import java.io.ByteArrayOutputStream
|
||||
import java.io.File
|
||||
import java.io.ObjectOutputStream
|
||||
import java.util.*
|
||||
|
||||
@@ -40,6 +43,25 @@ fun encodePluginOptions(options: Map<String, List<String>>): String {
|
||||
return Base64.getEncoder().encodeToString(os.toByteArray())
|
||||
}
|
||||
|
||||
internal fun CompilerPluginOptions.withWrappedKaptOptions(withApClasspath: Iterable<File>): CompilerPluginOptions {
|
||||
val resultOptionsByPluginId: MutableMap<String, List<SubpluginOption>> =
|
||||
subpluginOptionsByPluginId.toMutableMap()
|
||||
|
||||
resultOptionsByPluginId.compute(Kapt3KotlinGradleSubplugin.KAPT_SUBPLUGIN_ID) { _, kaptOptions ->
|
||||
val kaptOptionsWithClasspath =
|
||||
kaptOptions.orEmpty() + withApClasspath.map { FilesSubpluginOption("apclasspath", listOf(it)) }
|
||||
|
||||
wrapPluginOptions(kaptOptionsWithClasspath, "configuration")
|
||||
}
|
||||
|
||||
val result = CompilerPluginOptions()
|
||||
classpath.forEach { result.addClasspathEntry(File(it)) }
|
||||
resultOptionsByPluginId.forEach { pluginId, options ->
|
||||
options.forEach { option -> result.addPluginArgument(pluginId, option) }
|
||||
}
|
||||
return result
|
||||
}
|
||||
|
||||
fun wrapPluginOptions(options: List<SubpluginOption>, newOptionName: String): List<SubpluginOption> {
|
||||
val groupedOptions = options.groupBy { it.key }.mapValues { opt -> opt.value.map { it.value } }
|
||||
val encodedOptions = encodePluginOptions(groupedOptions)
|
||||
|
||||
Reference in New Issue
Block a user