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-sam-with-receiver",
":kotlin-android-extensions",
":kotlin-android-extensions-runtime",
":kotlin-parcelize-compiler",
":kotlin-build-common",
":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) {
project.setupWorkingDir()
@@ -198,17 +198,13 @@ class Kapt3GradleSubplugin @Inject internal constructor(private val registry: To
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.temporaryKaptDirectory(name: String, doMkDirs: Boolean = true): File {
val dir = File(project.buildDir, "tmp/kapt3/$name/$sourceSetName")
if (doMkDirs) {
dir.mkdirs()
}
return dir
}
private fun Kapt3SubpluginContext.temporaryKaptDirectory(
name: String
) = project.buildDir.resolve("tmp/kapt3/$name/$sourceSetName")
internal inner class Kapt3SubpluginContext(
val project: Project,
@@ -328,8 +324,6 @@ class Kapt3GradleSubplugin @Inject internal constructor(private val registry: To
pluginOptions += SubpluginOption("processors", annotationProcessors)
}
kotlinSourcesOutputDir.mkdirs()
val apOptions = getAPOptions().get()
pluginOptions += CompositeSubpluginOption(
@@ -476,7 +470,7 @@ class Kapt3GradleSubplugin @Inject internal constructor(private val registry: To
kaptTask.kotlinCompileTask = kotlinCompilation.compileKotlinTaskProvider.get() as KotlinCompile
kaptTask.stubsDir = getKaptStubsDir()
kaptTask.stubsDir.set(getKaptStubsDir())
kaptTask.destinationDir = sourcesOutputDir
kaptTask.kotlinSourcesDestinationDir = kotlinSourcesOutputDir
@@ -486,7 +480,7 @@ class Kapt3GradleSubplugin @Inject internal constructor(private val registry: To
kaptTask.isIncremental = project.isIncrementalKapt()
if (kaptTask.isIncremental) {
kaptTask.incAptCache = getKaptIncrementalAnnotationProcessingCache()
kaptTask.incAptCache.set(getKaptIncrementalAnnotationProcessingCache())
kaptTask.localState.register(kaptTask.incAptCache)
kaptTask.classpathStructure = classStructureIfIncremental!!.incoming.artifactView { viewConfig ->
@@ -496,7 +490,10 @@ class Kapt3GradleSubplugin @Inject internal constructor(private val registry: To
if (kaptTask is KaptWithKotlincTask) {
kaptTask.pluginOptions.addPluginArgument(
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 ->
kaptTask.kotlinCompileTask = kotlinCompile.get()
kaptTask.stubsDir = getKaptStubsDir()
kaptTask.stubsDir.set(getKaptStubsDir())
kaptTask.setDestinationDir { getKaptIncrementalDataDir() }
kaptTask.mapClasspath { kaptTask.kotlinCompileTask.classpath }
kaptTask.generatedSourcesDirs = listOf(sourcesOutputDir, kotlinSourcesOutputDir)
@@ -17,7 +17,9 @@
package org.jetbrains.kotlin.gradle.internal
import org.gradle.api.artifacts.Configuration
import org.gradle.api.file.DirectoryProperty
import org.gradle.api.file.FileCollection
import org.gradle.api.model.ObjectFactory
import org.gradle.api.tasks.*
import org.jetbrains.kotlin.cli.common.arguments.K2JVMCompilerArguments
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.destinationAsFile
import java.io.File
import javax.inject.Inject
@CacheableTask
open class KaptGenerateStubsTask : KotlinCompile() {
open class KaptGenerateStubsTask @Inject constructor(
objectFactory: ObjectFactory
) : KotlinCompile() {
override val sourceRootsContainer = FilteringSourceRootsContainer(emptyList(), { isSourceRootAllowed(it) })
override val kotlinOptions: KotlinJvmOptions = KotlinJvmOptionsImpl()
@@ -42,7 +47,7 @@ open class KaptGenerateStubsTask : KotlinCompile() {
internal lateinit var kotlinCompileTask: KotlinCompile
@get:OutputDirectory
lateinit var stubsDir: File
val stubsDir: DirectoryProperty = objectFactory.directoryProperty()
@get:Internal
lateinit var generatedSourcesDirs: List<File>
@@ -82,7 +87,7 @@ open class KaptGenerateStubsTask : KotlinCompile() {
private fun isSourceRootAllowed(source: File): Boolean =
!destinationDir.isParentOf(source) &&
!stubsDir.isParentOf(source) &&
!stubsDir.asFile.get().isParentOf(source) &&
generatedSourcesDirs.none { it.isParentOf(source) }
private val compileKotlinArgumentsContributor by project.provider {
@@ -1,8 +1,10 @@
package org.jetbrains.kotlin.gradle.internal
import org.gradle.api.file.ConfigurableFileCollection
import org.gradle.api.file.DirectoryProperty
import org.gradle.api.file.FileCollection
import org.gradle.api.internal.ConventionTask
import org.gradle.api.model.ObjectFactory
import org.gradle.api.provider.ListProperty
import org.gradle.api.tasks.*
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 java.io.File
import java.util.jar.JarFile
import javax.inject.Inject
@CacheableTask
abstract class KaptTask : ConventionTask(), TaskWithLocalState {
abstract class KaptTask @Inject constructor(
objectFactory: ObjectFactory
): ConventionTask(), TaskWithLocalState {
init {
cacheOnlyIfEnabledForKotlin()
@@ -30,14 +35,16 @@ abstract class KaptTask : ConventionTask(), TaskWithLocalState {
outputs.cacheIf(reason) { useBuildCache }
}
override fun localStateDirectories(): FileCollection = objects.fileCollection().from(incAptCache)
override fun localStateDirectories(): FileCollection = objects
.fileCollection()
.from({ incAptCache.orNull })
@get:Internal
@field:Transient
internal lateinit var kotlinCompileTask: KotlinCompile
@get:Internal
internal lateinit var stubsDir: File
internal val stubsDir: DirectoryProperty = objectFactory.directoryProperty()
@get:Internal
internal val objects = project.objects
@@ -67,7 +74,7 @@ abstract class KaptTask : ConventionTask(), TaskWithLocalState {
* annotations are specified during task configuration.
*/
@get:Internal
var incAptCache: File? = null
val incAptCache: DirectoryProperty = objectFactory.directoryProperty()
@get:OutputDirectory
internal lateinit var classesDir: File
@@ -121,23 +128,17 @@ abstract class KaptTask : ConventionTask(), TaskWithLocalState {
@get:InputFiles
@get:PathSensitive(PathSensitivity.RELATIVE)
val source: Collection<File>
get() {
val result = HashSet<File>()
for (root in javaSourceRoots) {
root.walk().filterTo(result) { it.isJavaFile() }
}
return result
val source: FileCollection = objectFactory
.fileCollection()
.from(
{ kotlinCompileTask.sourceRootsContainer.sourceRoots },
stubsDir
)
.asFileTree
.matching {
it.include("**/*.java")
}
// 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)
.filter(::isRootAllowed)
@get:Internal
override val metrics: BuildMetricsReporter =
@@ -145,8 +146,8 @@ abstract class KaptTask : ConventionTask(), TaskWithLocalState {
private fun isRootAllowed(file: File): Boolean =
file.exists() &&
!isAncestor(destinationDir, file) &&
!isAncestor(classesDir, file)
!isAncestor(destinationDir, file) &&
!isAncestor(classesDir, file)
//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 {
@@ -224,7 +225,7 @@ abstract class KaptTask : ConventionTask(), TaskWithLocalState {
}
private fun findClasspathChanges(inputs: IncrementalTaskInputs): KaptIncrementalChanges {
val incAptCacheDir = incAptCache!!
val incAptCacheDir = incAptCache.asFile.get()
incAptCacheDir.mkdirs()
val allDataFiles = classpathStructure!!.files
@@ -8,6 +8,7 @@ package org.jetbrains.kotlin.gradle.internal
import com.intellij.openapi.util.SystemInfo
import org.gradle.api.GradleException
import org.gradle.api.file.FileCollection
import org.gradle.api.model.ObjectFactory
import org.gradle.api.tasks.Classpath
import org.gradle.api.tasks.InputFiles
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.toSortedPathsArray
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
internal val pluginOptions = CompilerPluginOptions()
@@ -107,7 +111,7 @@ abstract class KaptWithKotlincTask : KaptTask(), CompilerArgumentAwareWithInput<
compilerRunner.runJvmCompilerAsync(
sourcesToCompile = emptyList(),
commonSources = emptyList(),
javaSourceRoots = javaSourceRoots,
javaSourceRoots = source.files,
javaPackagePrefix = javaPackagePrefix,
args = args,
environment = environment
@@ -6,6 +6,8 @@
package org.jetbrains.kotlin.gradle.internal
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.tasks.*
import org.gradle.api.tasks.incremental.IncrementalTaskInputs
@@ -27,7 +29,10 @@ import java.net.URL
import java.net.URLClassLoader
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:Classpath
@Suppress("unused")
@@ -98,16 +103,16 @@ abstract class KaptWithoutKotlincTask @Inject constructor(private val workerExec
val optionsForWorker = KaptOptionsForWorker(
projectDir,
compileClasspath,
javaSourceRoots.toList(),
source.files.toList(),
changedFiles,
compiledSources,
incAptCache,
incAptCache.orNull?.asFile,
classpathChanges.toList(),
destinationDir,
classesDir,
stubsDir,
stubsDir.asFile.get(),
kaptClasspath.files.toList(),
annotationProcessorFqNames,