diff --git a/libraries/tools/kotlin-gradle-plugin-integration-tests/src/test/kotlin/org/jetbrains/kotlin/gradle/KotlinGradlePluginIT.kt b/libraries/tools/kotlin-gradle-plugin-integration-tests/src/test/kotlin/org/jetbrains/kotlin/gradle/KotlinGradlePluginIT.kt index b61b2db6586..adf024b9013 100644 --- a/libraries/tools/kotlin-gradle-plugin-integration-tests/src/test/kotlin/org/jetbrains/kotlin/gradle/KotlinGradlePluginIT.kt +++ b/libraries/tools/kotlin-gradle-plugin-integration-tests/src/test/kotlin/org/jetbrains/kotlin/gradle/KotlinGradlePluginIT.kt @@ -415,6 +415,42 @@ class KotlinGradleIT: BaseGradleIT() { } } + @Test + fun testChangeDestinationDir() { + val project = Project("kotlinProject", "3.3") + project.setupWorkingDir() + + val fileToRemove = File(project.projectDir, "src/main/kotlin/removeMe.kt") + fileToRemove.writeText("val x = 1") + val classFilePath = "build/classes/main/RemoveMeKt.class" + + project.build("build") { + assertSuccessful() + assertFileExists(classFilePath) + } + + // Check that after the change the build succeeds and no stale classes remain in the java classes dir + File(project.projectDir, "build.gradle").modify { + "$it\n\ncompileKotlin.destinationDir = file(\"\${project.buildDir}/compileKotlin\")" + } + fileToRemove.delete() + + project.build("build") { + assertSuccessful() + assertNoSuchFile(classFilePath) + // Check that the fallback to non-incremental copying was chosen + assertContains("Non-incremental copying files") + } + + // Check that the classes are copied incrementally under normal conditions + fileToRemove.writeText("val x = 1") + project.build("build") { + assertSuccessful() + assertFileExists(classFilePath) + assertNotContains("Non-incremental copying files") + } + } + @Test fun testDowngradeTo106() { val project = Project("kotlinProject", GRADLE_VERSION) diff --git a/libraries/tools/kotlin-gradle-plugin/src/main/kotlin/org/jetbrains/kotlin/gradle/tasks/SyncOutputTask.kt b/libraries/tools/kotlin-gradle-plugin/src/main/kotlin/org/jetbrains/kotlin/gradle/tasks/SyncOutputTask.kt index cb6235f0644..c6031615618 100644 --- a/libraries/tools/kotlin-gradle-plugin/src/main/kotlin/org/jetbrains/kotlin/gradle/tasks/SyncOutputTask.kt +++ b/libraries/tools/kotlin-gradle-plugin/src/main/kotlin/org/jetbrains/kotlin/gradle/tasks/SyncOutputTask.kt @@ -17,12 +17,13 @@ package org.jetbrains.kotlin.gradle.tasks import org.gradle.api.DefaultTask +import org.gradle.api.tasks.Input import org.gradle.api.tasks.InputFiles import org.gradle.api.tasks.OutputDirectory import org.gradle.api.tasks.TaskAction import org.gradle.api.tasks.incremental.IncrementalTaskInputs import org.gradle.api.tasks.incremental.InputFileDetails -import org.jetbrains.kotlin.com.intellij.openapi.util.io.FileUtil.* +import org.jetbrains.kotlin.com.intellij.openapi.util.io.FileUtil.isAncestor import org.jetbrains.kotlin.gradle.plugin.kotlinDebug import java.io.File import java.io.ObjectInputStream @@ -59,6 +60,8 @@ internal open class SyncOutputTask : DefaultTask() { @get:InputFiles var kaptClassesDir: File by Delegates.notNull() + // Marked as input to make Gradle fall back to non-incremental build when it changes. + @get:Input private val classesDirs: List get() = listOf(kotlinOutputDir, kaptClassesDir).filter(File::exists)