Fix kapt creates output directories on configuration phase.

Gradle will create such directories itself. Also it should fix build
cache issue with kapt tasks - build cache was disabled
 due to the 'overlapping outputs'.

 ^KT-45532 Fixed
This commit is contained in:
Yahor Berdnikau
2021-03-18 17:41:46 +01:00
committed by TeamCityServer
parent 5abc45e6ff
commit d46ad6c0ad
7 changed files with 72 additions and 46 deletions
+1
View File
@@ -28,6 +28,7 @@ val kotlinGradlePluginAndItsRequired = arrayOf(
":kotlin-noarg", ":kotlin-noarg",
":kotlin-sam-with-receiver", ":kotlin-sam-with-receiver",
":kotlin-android-extensions", ":kotlin-android-extensions",
":kotlin-android-extensions-runtime",
":kotlin-parcelize-compiler", ":kotlin-parcelize-compiler",
":kotlin-build-common", ":kotlin-build-common",
":kotlin-compiler-embeddable", ":kotlin-compiler-embeddable",
@@ -273,6 +273,19 @@ abstract class Kapt3AndroidIT : Kapt3BaseIT() {
} }
} }
// KT-45532
@Test
open fun kaptTasksShouldNotCreateOutputsOnConfigurationPhase() {
Project(
"android-dagger",
directoryPrefix = "kapt2"
).build("--dry-run", "assembleDebug") {
assertSuccessful()
assertNoSuchFile("app/build/tmp")
assertNoSuchFile("app/build/generated")
}
}
private fun setupDataBinding(project: Project) { private fun setupDataBinding(project: Project) {
project.setupWorkingDir() project.setupWorkingDir()
@@ -198,17 +198,13 @@ class Kapt3GradleSubplugin @Inject internal constructor(private val registry: To
private fun Kapt3SubpluginContext.getKaptStubsDir() = temporaryKaptDirectory("stubs") private fun Kapt3SubpluginContext.getKaptStubsDir() = temporaryKaptDirectory("stubs")
private fun Kapt3SubpluginContext.getKaptIncrementalDataDir() = temporaryKaptDirectory("incrementalData", doMkDirs = false) private fun Kapt3SubpluginContext.getKaptIncrementalDataDir() = temporaryKaptDirectory("incrementalData")
private fun Kapt3SubpluginContext.getKaptIncrementalAnnotationProcessingCache() = temporaryKaptDirectory("incApCache") private fun Kapt3SubpluginContext.getKaptIncrementalAnnotationProcessingCache() = temporaryKaptDirectory("incApCache")
private fun Kapt3SubpluginContext.temporaryKaptDirectory(name: String, doMkDirs: Boolean = true): File { private fun Kapt3SubpluginContext.temporaryKaptDirectory(
val dir = File(project.buildDir, "tmp/kapt3/$name/$sourceSetName") name: String
if (doMkDirs) { ) = project.buildDir.resolve("tmp/kapt3/$name/$sourceSetName")
dir.mkdirs()
}
return dir
}
internal inner class Kapt3SubpluginContext( internal inner class Kapt3SubpluginContext(
val project: Project, val project: Project,
@@ -328,8 +324,6 @@ class Kapt3GradleSubplugin @Inject internal constructor(private val registry: To
pluginOptions += SubpluginOption("processors", annotationProcessors) pluginOptions += SubpluginOption("processors", annotationProcessors)
} }
kotlinSourcesOutputDir.mkdirs()
val apOptions = getAPOptions().get() val apOptions = getAPOptions().get()
pluginOptions += CompositeSubpluginOption( pluginOptions += CompositeSubpluginOption(
@@ -476,7 +470,7 @@ class Kapt3GradleSubplugin @Inject internal constructor(private val registry: To
kaptTask.kotlinCompileTask = kotlinCompilation.compileKotlinTaskProvider.get() as KotlinCompile kaptTask.kotlinCompileTask = kotlinCompilation.compileKotlinTaskProvider.get() as KotlinCompile
kaptTask.stubsDir = getKaptStubsDir() kaptTask.stubsDir.set(getKaptStubsDir())
kaptTask.destinationDir = sourcesOutputDir kaptTask.destinationDir = sourcesOutputDir
kaptTask.kotlinSourcesDestinationDir = kotlinSourcesOutputDir kaptTask.kotlinSourcesDestinationDir = kotlinSourcesOutputDir
@@ -486,7 +480,7 @@ class Kapt3GradleSubplugin @Inject internal constructor(private val registry: To
kaptTask.isIncremental = project.isIncrementalKapt() kaptTask.isIncremental = project.isIncrementalKapt()
if (kaptTask.isIncremental) { if (kaptTask.isIncremental) {
kaptTask.incAptCache = getKaptIncrementalAnnotationProcessingCache() kaptTask.incAptCache.set(getKaptIncrementalAnnotationProcessingCache())
kaptTask.localState.register(kaptTask.incAptCache) kaptTask.localState.register(kaptTask.incAptCache)
kaptTask.classpathStructure = classStructureIfIncremental!!.incoming.artifactView { viewConfig -> kaptTask.classpathStructure = classStructureIfIncremental!!.incoming.artifactView { viewConfig ->
@@ -496,7 +490,10 @@ class Kapt3GradleSubplugin @Inject internal constructor(private val registry: To
if (kaptTask is KaptWithKotlincTask) { if (kaptTask is KaptWithKotlincTask) {
kaptTask.pluginOptions.addPluginArgument( kaptTask.pluginOptions.addPluginArgument(
getCompilerPluginId(), getCompilerPluginId(),
SubpluginOption("incrementalCache", kaptTask.incAptCache!!.absolutePath) SubpluginOption(
"incrementalCache",
lazy { kaptTask.incAptCache.asFile.get().absolutePath }
)
) )
} }
} }
@@ -612,7 +609,7 @@ class Kapt3GradleSubplugin @Inject internal constructor(private val registry: To
val kaptTaskProvider = project.registerTask<KaptGenerateStubsTask>(kaptTaskName) { kaptTask -> val kaptTaskProvider = project.registerTask<KaptGenerateStubsTask>(kaptTaskName) { kaptTask ->
kaptTask.kotlinCompileTask = kotlinCompile.get() kaptTask.kotlinCompileTask = kotlinCompile.get()
kaptTask.stubsDir = getKaptStubsDir() kaptTask.stubsDir.set(getKaptStubsDir())
kaptTask.setDestinationDir { getKaptIncrementalDataDir() } kaptTask.setDestinationDir { getKaptIncrementalDataDir() }
kaptTask.mapClasspath { kaptTask.kotlinCompileTask.classpath } kaptTask.mapClasspath { kaptTask.kotlinCompileTask.classpath }
kaptTask.generatedSourcesDirs = listOf(sourcesOutputDir, kotlinSourcesOutputDir) kaptTask.generatedSourcesDirs = listOf(sourcesOutputDir, kotlinSourcesOutputDir)
@@ -17,7 +17,9 @@
package org.jetbrains.kotlin.gradle.internal package org.jetbrains.kotlin.gradle.internal
import org.gradle.api.artifacts.Configuration import org.gradle.api.artifacts.Configuration
import org.gradle.api.file.DirectoryProperty
import org.gradle.api.file.FileCollection import org.gradle.api.file.FileCollection
import org.gradle.api.model.ObjectFactory
import org.gradle.api.tasks.* import org.gradle.api.tasks.*
import org.jetbrains.kotlin.cli.common.arguments.K2JVMCompilerArguments import org.jetbrains.kotlin.cli.common.arguments.K2JVMCompilerArguments
import org.jetbrains.kotlin.gradle.dsl.KotlinJvmOptions import org.jetbrains.kotlin.gradle.dsl.KotlinJvmOptions
@@ -30,9 +32,12 @@ import org.jetbrains.kotlin.gradle.utils.isParentOf
import org.jetbrains.kotlin.incremental.classpathAsList import org.jetbrains.kotlin.incremental.classpathAsList
import org.jetbrains.kotlin.incremental.destinationAsFile import org.jetbrains.kotlin.incremental.destinationAsFile
import java.io.File import java.io.File
import javax.inject.Inject
@CacheableTask @CacheableTask
open class KaptGenerateStubsTask : KotlinCompile() { open class KaptGenerateStubsTask @Inject constructor(
objectFactory: ObjectFactory
) : KotlinCompile() {
override val sourceRootsContainer = FilteringSourceRootsContainer(emptyList(), { isSourceRootAllowed(it) }) override val sourceRootsContainer = FilteringSourceRootsContainer(emptyList(), { isSourceRootAllowed(it) })
override val kotlinOptions: KotlinJvmOptions = KotlinJvmOptionsImpl() override val kotlinOptions: KotlinJvmOptions = KotlinJvmOptionsImpl()
@@ -42,7 +47,7 @@ open class KaptGenerateStubsTask : KotlinCompile() {
internal lateinit var kotlinCompileTask: KotlinCompile internal lateinit var kotlinCompileTask: KotlinCompile
@get:OutputDirectory @get:OutputDirectory
lateinit var stubsDir: File val stubsDir: DirectoryProperty = objectFactory.directoryProperty()
@get:Internal @get:Internal
lateinit var generatedSourcesDirs: List<File> lateinit var generatedSourcesDirs: List<File>
@@ -82,7 +87,7 @@ open class KaptGenerateStubsTask : KotlinCompile() {
private fun isSourceRootAllowed(source: File): Boolean = private fun isSourceRootAllowed(source: File): Boolean =
!destinationDir.isParentOf(source) && !destinationDir.isParentOf(source) &&
!stubsDir.isParentOf(source) && !stubsDir.asFile.get().isParentOf(source) &&
generatedSourcesDirs.none { it.isParentOf(source) } generatedSourcesDirs.none { it.isParentOf(source) }
private val compileKotlinArgumentsContributor by project.provider { private val compileKotlinArgumentsContributor by project.provider {
@@ -1,8 +1,10 @@
package org.jetbrains.kotlin.gradle.internal package org.jetbrains.kotlin.gradle.internal
import org.gradle.api.file.ConfigurableFileCollection import org.gradle.api.file.ConfigurableFileCollection
import org.gradle.api.file.DirectoryProperty
import org.gradle.api.file.FileCollection import org.gradle.api.file.FileCollection
import org.gradle.api.internal.ConventionTask import org.gradle.api.internal.ConventionTask
import org.gradle.api.model.ObjectFactory
import org.gradle.api.provider.ListProperty import org.gradle.api.provider.ListProperty
import org.gradle.api.tasks.* import org.gradle.api.tasks.*
import org.gradle.api.tasks.incremental.IncrementalTaskInputs import org.gradle.api.tasks.incremental.IncrementalTaskInputs
@@ -20,9 +22,12 @@ import org.jetbrains.kotlin.gradle.utils.getValue
import org.jetbrains.kotlin.gradle.utils.isJavaFile import org.jetbrains.kotlin.gradle.utils.isJavaFile
import java.io.File import java.io.File
import java.util.jar.JarFile import java.util.jar.JarFile
import javax.inject.Inject
@CacheableTask @CacheableTask
abstract class KaptTask : ConventionTask(), TaskWithLocalState { abstract class KaptTask @Inject constructor(
objectFactory: ObjectFactory
): ConventionTask(), TaskWithLocalState {
init { init {
cacheOnlyIfEnabledForKotlin() cacheOnlyIfEnabledForKotlin()
@@ -30,14 +35,16 @@ abstract class KaptTask : ConventionTask(), TaskWithLocalState {
outputs.cacheIf(reason) { useBuildCache } outputs.cacheIf(reason) { useBuildCache }
} }
override fun localStateDirectories(): FileCollection = objects.fileCollection().from(incAptCache) override fun localStateDirectories(): FileCollection = objects
.fileCollection()
.from({ incAptCache.orNull })
@get:Internal @get:Internal
@field:Transient @field:Transient
internal lateinit var kotlinCompileTask: KotlinCompile internal lateinit var kotlinCompileTask: KotlinCompile
@get:Internal @get:Internal
internal lateinit var stubsDir: File internal val stubsDir: DirectoryProperty = objectFactory.directoryProperty()
@get:Internal @get:Internal
internal val objects = project.objects internal val objects = project.objects
@@ -67,7 +74,7 @@ abstract class KaptTask : ConventionTask(), TaskWithLocalState {
* annotations are specified during task configuration. * annotations are specified during task configuration.
*/ */
@get:Internal @get:Internal
var incAptCache: File? = null val incAptCache: DirectoryProperty = objectFactory.directoryProperty()
@get:OutputDirectory @get:OutputDirectory
internal lateinit var classesDir: File internal lateinit var classesDir: File
@@ -121,23 +128,17 @@ abstract class KaptTask : ConventionTask(), TaskWithLocalState {
@get:InputFiles @get:InputFiles
@get:PathSensitive(PathSensitivity.RELATIVE) @get:PathSensitive(PathSensitivity.RELATIVE)
val source: Collection<File> val source: FileCollection = objectFactory
get() { .fileCollection()
val result = HashSet<File>() .from(
for (root in javaSourceRoots) { { kotlinCompileTask.sourceRootsContainer.sourceRoots },
root.walk().filterTo(result) { it.isJavaFile() } stubsDir
} )
return result .asFileTree
.matching {
it.include("**/*.java")
} }
.filter(::isRootAllowed)
// store the files before filtering, so that Gradle doesn't serialize the filtered collection for instant execution state and reuse it
private val unfilteredJavaSourceRoots by project.provider {
(kotlinCompileTask.sourceRootsContainer.sourceRoots + stubsDir)
}
@get:Internal
protected val javaSourceRoots: Set<File>
get() = unfilteredJavaSourceRoots.filterTo(HashSet(), ::isRootAllowed)
@get:Internal @get:Internal
override val metrics: BuildMetricsReporter = override val metrics: BuildMetricsReporter =
@@ -145,8 +146,8 @@ abstract class KaptTask : ConventionTask(), TaskWithLocalState {
private fun isRootAllowed(file: File): Boolean = private fun isRootAllowed(file: File): Boolean =
file.exists() && file.exists() &&
!isAncestor(destinationDir, file) && !isAncestor(destinationDir, file) &&
!isAncestor(classesDir, file) !isAncestor(classesDir, file)
//Have to avoid using FileUtil because it is required system property reading that is not allowed for configuration cache //Have to avoid using FileUtil because it is required system property reading that is not allowed for configuration cache
private fun isAncestor(dir: File, file: File): Boolean { private fun isAncestor(dir: File, file: File): Boolean {
@@ -224,7 +225,7 @@ abstract class KaptTask : ConventionTask(), TaskWithLocalState {
} }
private fun findClasspathChanges(inputs: IncrementalTaskInputs): KaptIncrementalChanges { private fun findClasspathChanges(inputs: IncrementalTaskInputs): KaptIncrementalChanges {
val incAptCacheDir = incAptCache!! val incAptCacheDir = incAptCache.asFile.get()
incAptCacheDir.mkdirs() incAptCacheDir.mkdirs()
val allDataFiles = classpathStructure!!.files val allDataFiles = classpathStructure!!.files
@@ -8,6 +8,7 @@ package org.jetbrains.kotlin.gradle.internal
import com.intellij.openapi.util.SystemInfo import com.intellij.openapi.util.SystemInfo
import org.gradle.api.GradleException import org.gradle.api.GradleException
import org.gradle.api.file.FileCollection import org.gradle.api.file.FileCollection
import org.gradle.api.model.ObjectFactory
import org.gradle.api.tasks.Classpath import org.gradle.api.tasks.Classpath
import org.gradle.api.tasks.InputFiles import org.gradle.api.tasks.InputFiles
import org.gradle.api.tasks.Internal import org.gradle.api.tasks.Internal
@@ -27,8 +28,11 @@ import org.jetbrains.kotlin.gradle.utils.getValue
import org.jetbrains.kotlin.gradle.utils.optionalProvider import org.jetbrains.kotlin.gradle.utils.optionalProvider
import org.jetbrains.kotlin.gradle.utils.toSortedPathsArray import org.jetbrains.kotlin.gradle.utils.toSortedPathsArray
import java.io.File import java.io.File
import javax.inject.Inject
abstract class KaptWithKotlincTask : KaptTask(), CompilerArgumentAwareWithInput<K2JVMCompilerArguments> { abstract class KaptWithKotlincTask @Inject constructor(
objectFactory: ObjectFactory
) : KaptTask(objectFactory), CompilerArgumentAwareWithInput<K2JVMCompilerArguments> {
@get:Internal @get:Internal
internal val pluginOptions = CompilerPluginOptions() internal val pluginOptions = CompilerPluginOptions()
@@ -107,7 +111,7 @@ abstract class KaptWithKotlincTask : KaptTask(), CompilerArgumentAwareWithInput<
compilerRunner.runJvmCompilerAsync( compilerRunner.runJvmCompilerAsync(
sourcesToCompile = emptyList(), sourcesToCompile = emptyList(),
commonSources = emptyList(), commonSources = emptyList(),
javaSourceRoots = javaSourceRoots, javaSourceRoots = source.files,
javaPackagePrefix = javaPackagePrefix, javaPackagePrefix = javaPackagePrefix,
args = args, args = args,
environment = environment environment = environment
@@ -6,6 +6,8 @@
package org.jetbrains.kotlin.gradle.internal package org.jetbrains.kotlin.gradle.internal
import org.gradle.api.file.ConfigurableFileCollection import org.gradle.api.file.ConfigurableFileCollection
import org.gradle.api.file.DirectoryProperty
import org.gradle.api.model.ObjectFactory
import org.gradle.api.provider.Property import org.gradle.api.provider.Property
import org.gradle.api.tasks.* import org.gradle.api.tasks.*
import org.gradle.api.tasks.incremental.IncrementalTaskInputs import org.gradle.api.tasks.incremental.IncrementalTaskInputs
@@ -27,7 +29,10 @@ import java.net.URL
import java.net.URLClassLoader import java.net.URLClassLoader
import javax.inject.Inject import javax.inject.Inject
abstract class KaptWithoutKotlincTask @Inject constructor(private val workerExecutor: WorkerExecutor) : KaptTask() { abstract class KaptWithoutKotlincTask @Inject constructor(
objectFactory: ObjectFactory,
private val workerExecutor: WorkerExecutor
) : KaptTask(objectFactory) {
@get:InputFiles @get:InputFiles
@get:Classpath @get:Classpath
@Suppress("unused") @Suppress("unused")
@@ -98,16 +103,16 @@ abstract class KaptWithoutKotlincTask @Inject constructor(private val workerExec
val optionsForWorker = KaptOptionsForWorker( val optionsForWorker = KaptOptionsForWorker(
projectDir, projectDir,
compileClasspath, compileClasspath,
javaSourceRoots.toList(), source.files.toList(),
changedFiles, changedFiles,
compiledSources, compiledSources,
incAptCache, incAptCache.orNull?.asFile,
classpathChanges.toList(), classpathChanges.toList(),
destinationDir, destinationDir,
classesDir, classesDir,
stubsDir, stubsDir.asFile.get(),
kaptClasspath.files.toList(), kaptClasspath.files.toList(),
annotationProcessorFqNames, annotationProcessorFqNames,