From 81b4031a352045fb1bdc97be773f3a3f2a6f3c0b Mon Sep 17 00:00:00 2001 From: Sergey Igushkin Date: Thu, 11 Oct 2018 19:01:23 +0300 Subject: [PATCH] Remove internal Gradle API usage for stale output cleanup BuildOutputCleanupRegistry tracks the all of the outputs that belong to the Gradle build, so when Gradle runs in an unknown state (e.g. without any history), it can detect stale outputs in the output directories and delete them. Since this is an internal API, its usage is removed. Instead, another way to tell Gradle that a set of directories belongs to the build is to add them to the `delete` task targets. --- .../kotlin/gradle/NewMultiplatformIT.kt | 31 +++++++++++++++++++ .../gradle/plugin/KotlinPluginWrapper.kt | 4 +-- .../gradle/plugin/KotlinTargetConfigurator.kt | 12 +++---- .../plugin/mpp/KotlinMultiplatformPlugin.kt | 10 +++--- .../gradle/plugin/mpp/kotlinTargetPresets.kt | 15 ++------- 5 files changed, 45 insertions(+), 27 deletions(-) diff --git a/libraries/tools/kotlin-gradle-plugin-integration-tests/src/test/kotlin/org/jetbrains/kotlin/gradle/NewMultiplatformIT.kt b/libraries/tools/kotlin-gradle-plugin-integration-tests/src/test/kotlin/org/jetbrains/kotlin/gradle/NewMultiplatformIT.kt index 31cfe6b5918..c37f45266e0 100644 --- a/libraries/tools/kotlin-gradle-plugin-integration-tests/src/test/kotlin/org/jetbrains/kotlin/gradle/NewMultiplatformIT.kt +++ b/libraries/tools/kotlin-gradle-plugin-integration-tests/src/test/kotlin/org/jetbrains/kotlin/gradle/NewMultiplatformIT.kt @@ -920,4 +920,35 @@ class NewMultiplatformIT : BaseGradleIT() { assertTrue(fileInWorkingDir("$pathPrefix/kotlin.js").length() < 500 * 1000, "Looks like kotlin.js file was not minified by DCE") } } + + + @Test + fun testStaleOutputCleanup() = with(Project("new-mpp-lib-with-tests", gradleVersion)) { + setupWorkingDir() + // Check that output directories of Kotlin compilations are registered for Gradle stale outputs cleanup. + // One way to check that is to run a Gradle build with no Gradle history (no .gradle directory) and see that the compilation + // output directories are cleaned up, even those outside the project's buildDir + + gradleBuildScript().appendText( + "\n" + """ + kotlin.targets.js.compilations.main.output.classesDirs.from("foo") // should affect Gradle's behavior wrt stale output cleanup + task('foo') { + outputs.dir("foo") + doFirst { + println 'hello' + file("foo/2.txt").text = System.currentTimeMillis() + } + } + """.trimIndent() + ) + + val staleFilePath = "foo/1.txt" + projectDir.resolve(staleFilePath).run { parentFile.mkdirs(); createNewFile() } + + build("foo") { + assertSuccessful() + assertNoSuchFile(staleFilePath) + assertFileExists("foo/2.txt") + } + } } diff --git a/libraries/tools/kotlin-gradle-plugin/src/main/kotlin/org/jetbrains/kotlin/gradle/plugin/KotlinPluginWrapper.kt b/libraries/tools/kotlin-gradle-plugin/src/main/kotlin/org/jetbrains/kotlin/gradle/plugin/KotlinPluginWrapper.kt index 18852a68bd1..b1566af02c2 100644 --- a/libraries/tools/kotlin-gradle-plugin/src/main/kotlin/org/jetbrains/kotlin/gradle/plugin/KotlinPluginWrapper.kt +++ b/libraries/tools/kotlin-gradle-plugin/src/main/kotlin/org/jetbrains/kotlin/gradle/plugin/KotlinPluginWrapper.kt @@ -22,7 +22,6 @@ import org.gradle.api.internal.FeaturePreviews import org.gradle.api.internal.file.FileResolver import org.gradle.api.logging.Logger import org.gradle.api.logging.Logging -import org.gradle.internal.cleanup.BuildOutputCleanupRegistry import org.gradle.internal.reflect.Instantiator import org.gradle.tooling.provider.model.ToolingModelBuilderRegistry import org.jetbrains.kotlin.gradle.dsl.* @@ -134,12 +133,11 @@ open class Kotlin2JsPluginWrapper @Inject constructor( open class KotlinMultiplatformPluginWrapper @Inject constructor( fileResolver: FileResolver, private val instantiator: Instantiator, - private val buildOutputCleanupRegistry: BuildOutputCleanupRegistry, private val featurePreviews: FeaturePreviews ): KotlinBasePluginWrapper(fileResolver) { override fun getPlugin(project: Project, kotlinGradleBuildServices: KotlinGradleBuildServices): Plugin = KotlinMultiplatformPlugin( - buildOutputCleanupRegistry, fileResolver, + fileResolver, instantiator, kotlinPluginVersion, featurePreviews ) diff --git a/libraries/tools/kotlin-gradle-plugin/src/main/kotlin/org/jetbrains/kotlin/gradle/plugin/KotlinTargetConfigurator.kt b/libraries/tools/kotlin-gradle-plugin/src/main/kotlin/org/jetbrains/kotlin/gradle/plugin/KotlinTargetConfigurator.kt index 4b04781ae4c..a1d4db5d78d 100644 --- a/libraries/tools/kotlin-gradle-plugin/src/main/kotlin/org/jetbrains/kotlin/gradle/plugin/KotlinTargetConfigurator.kt +++ b/libraries/tools/kotlin-gradle-plugin/src/main/kotlin/org/jetbrains/kotlin/gradle/plugin/KotlinTargetConfigurator.kt @@ -44,7 +44,6 @@ import java.util.* import java.util.concurrent.Callable abstract class AbstractKotlinTargetConfigurator( - private val buildOutputCleanupRegistry: BuildOutputCleanupRegistry, protected val createDefaultSourceSets: Boolean, protected val createTestCompilation: Boolean ) { @@ -62,12 +61,17 @@ abstract class AbstractKotlinTargetConfigurator abstract fun configureArchivesAndComponent(target: KotlinTargetType) + private fun Project.registerOutputsForStaleOutputCleanup(kotlinCompilation: KotlinCompilation) { + val cleanTask = tasks.getByName(LifecycleBasePlugin.CLEAN_TASK_NAME) as Delete + cleanTask.delete(kotlinCompilation.output.allOutputs) + } + protected fun configureCompilations(platformTarget: KotlinTargetType) { val project = platformTarget.project val main = platformTarget.compilations.create(KotlinCompilation.MAIN_COMPILATION_NAME) platformTarget.compilations.all { - buildOutputCleanupRegistry.registerOutputs(it.output) + project.registerOutputsForStaleOutputCleanup(it) it.compileDependencyFiles = project.configurations.maybeCreate(it.compileDependencyConfigurationName) if (it is KotlinCompilationToRunnableFiles) { it.runtimeDependencyFiles = project.configurations.maybeCreate(it.runtimeDependencyConfigurationName) @@ -324,11 +328,9 @@ internal val KotlinCompilationToRunnableFiles.deprecatedRuntimeConfigurationName get() = disambiguateName("runtime") open class KotlinTargetConfigurator( - buildOutputCleanupRegistry: BuildOutputCleanupRegistry, createDefaultSourceSets: Boolean, createTestCompilation: Boolean ) : AbstractKotlinTargetConfigurator>( - buildOutputCleanupRegistry, createDefaultSourceSets, createTestCompilation ) { @@ -378,10 +380,8 @@ open class KotlinTargetConfigurator( open class KotlinNativeTargetConfigurator( - buildOutputCleanupRegistry: BuildOutputCleanupRegistry, private val kotlinPluginVersion: String ) : AbstractKotlinTargetConfigurator( - buildOutputCleanupRegistry, createDefaultSourceSets = true, createTestCompilation = true ) { diff --git a/libraries/tools/kotlin-gradle-plugin/src/main/kotlin/org/jetbrains/kotlin/gradle/plugin/mpp/KotlinMultiplatformPlugin.kt b/libraries/tools/kotlin-gradle-plugin/src/main/kotlin/org/jetbrains/kotlin/gradle/plugin/mpp/KotlinMultiplatformPlugin.kt index 85b92dcf2bc..7f7c7c251f7 100644 --- a/libraries/tools/kotlin-gradle-plugin/src/main/kotlin/org/jetbrains/kotlin/gradle/plugin/mpp/KotlinMultiplatformPlugin.kt +++ b/libraries/tools/kotlin-gradle-plugin/src/main/kotlin/org/jetbrains/kotlin/gradle/plugin/mpp/KotlinMultiplatformPlugin.kt @@ -19,7 +19,6 @@ import org.gradle.api.publish.PublishingExtension import org.gradle.api.publish.maven.MavenPublication import org.gradle.api.publish.maven.internal.publication.MavenPublicationInternal import org.gradle.api.publish.maven.tasks.AbstractPublishToMaven -import org.gradle.internal.cleanup.BuildOutputCleanupRegistry import org.gradle.internal.reflect.Instantiator import org.gradle.jvm.tasks.Jar import org.gradle.util.ConfigureUtil @@ -34,7 +33,6 @@ internal val Project.multiplatformExtension get(): KotlinMultiplatformExtension? project.extensions.findByName("kotlin") as? KotlinMultiplatformExtension class KotlinMultiplatformPlugin( - private val buildOutputCleanupRegistry: BuildOutputCleanupRegistry, private val fileResolver: FileResolver, private val instantiator: Instantiator, private val kotlinPluginVersion: String, @@ -87,19 +85,19 @@ class KotlinMultiplatformPlugin( // set up metadata publishing targetsFromPreset.fromPreset( - KotlinMetadataTargetPreset(project, instantiator, fileResolver, buildOutputCleanupRegistry, kotlinPluginVersion), + KotlinMetadataTargetPreset(project, instantiator, fileResolver, kotlinPluginVersion), METADATA_TARGET_NAME ) } fun setupDefaultPresets(project: Project) { with((project.kotlinExtension as KotlinMultiplatformExtension).presets) { - add(KotlinJvmTargetPreset(project, instantiator, fileResolver, buildOutputCleanupRegistry, kotlinPluginVersion)) - add(KotlinJsTargetPreset(project, instantiator, fileResolver, buildOutputCleanupRegistry, kotlinPluginVersion)) + add(KotlinJvmTargetPreset(project, instantiator, fileResolver, kotlinPluginVersion)) + add(KotlinJsTargetPreset(project, instantiator, fileResolver, kotlinPluginVersion)) add(KotlinAndroidTargetPreset(project, kotlinPluginVersion)) add(KotlinJvmWithJavaTargetPreset(project, kotlinPluginVersion)) HostManager().targets.forEach { _, target -> - add(KotlinNativeTargetPreset(target.presetName, project, target, buildOutputCleanupRegistry, kotlinPluginVersion)) + add(KotlinNativeTargetPreset(target.presetName, project, target, kotlinPluginVersion)) } } } diff --git a/libraries/tools/kotlin-gradle-plugin/src/main/kotlin/org/jetbrains/kotlin/gradle/plugin/mpp/kotlinTargetPresets.kt b/libraries/tools/kotlin-gradle-plugin/src/main/kotlin/org/jetbrains/kotlin/gradle/plugin/mpp/kotlinTargetPresets.kt index ea0756c2ceb..f403549219f 100644 --- a/libraries/tools/kotlin-gradle-plugin/src/main/kotlin/org/jetbrains/kotlin/gradle/plugin/mpp/kotlinTargetPresets.kt +++ b/libraries/tools/kotlin-gradle-plugin/src/main/kotlin/org/jetbrains/kotlin/gradle/plugin/mpp/kotlinTargetPresets.kt @@ -11,7 +11,6 @@ import org.gradle.api.artifacts.repositories.IvyArtifactRepository import org.gradle.api.artifacts.repositories.IvyPatternRepositoryLayout import org.gradle.api.internal.file.FileResolver import org.gradle.api.plugins.JavaPlugin -import org.gradle.internal.cleanup.BuildOutputCleanupRegistry import org.gradle.internal.reflect.Instantiator import org.jetbrains.kotlin.compilerRunner.KotlinNativeProjectProperty import org.jetbrains.kotlin.compilerRunner.hasProperty @@ -33,12 +32,11 @@ abstract class KotlinOnlyTargetPreset( protected val project: Project, private val instantiator: Instantiator, private val fileResolver: FileResolver, - protected val buildOutputCleanupRegistry: BuildOutputCleanupRegistry, protected val kotlinPluginVersion: String ) : KotlinTargetPreset> { protected open fun createKotlinTargetConfigurator(): KotlinTargetConfigurator = - KotlinTargetConfigurator(buildOutputCleanupRegistry, createDefaultSourceSets = true, createTestCompilation = true) + KotlinTargetConfigurator(createDefaultSourceSets = true, createTestCompilation = true) override fun createTarget(name: String): KotlinOnlyTarget { val result = KotlinOnlyTarget(project, platformType).apply { @@ -67,13 +65,11 @@ class KotlinMetadataTargetPreset( project: Project, instantiator: Instantiator, fileResolver: FileResolver, - buildOutputCleanupRegistry: BuildOutputCleanupRegistry, kotlinPluginVersion: String ) : KotlinOnlyTargetPreset( project, instantiator, fileResolver, - buildOutputCleanupRegistry, kotlinPluginVersion ) { override fun getName(): String = PRESET_NAME @@ -99,7 +95,7 @@ class KotlinMetadataTargetPreset( } override fun createKotlinTargetConfigurator(): KotlinTargetConfigurator = - KotlinTargetConfigurator(buildOutputCleanupRegistry, createDefaultSourceSets = false, createTestCompilation = false) + KotlinTargetConfigurator(createDefaultSourceSets = false, createTestCompilation = false) override fun createTarget(name: String): KotlinOnlyTarget = super.createTarget(name).apply { @@ -120,13 +116,11 @@ class KotlinJvmTargetPreset( project: Project, instantiator: Instantiator, fileResolver: FileResolver, - buildOutputCleanupRegistry: BuildOutputCleanupRegistry, kotlinPluginVersion: String ) : KotlinOnlyTargetPreset( project, instantiator, fileResolver, - buildOutputCleanupRegistry, kotlinPluginVersion ) { override fun getName(): String = PRESET_NAME @@ -149,13 +143,11 @@ class KotlinJsTargetPreset( project: Project, instantiator: Instantiator, fileResolver: FileResolver, - buildOutputCleanupRegistry: BuildOutputCleanupRegistry, kotlinPluginVersion: String ) : KotlinOnlyTargetPreset( project, instantiator, fileResolver, - buildOutputCleanupRegistry, kotlinPluginVersion ) { override fun getName(): String = PRESET_NAME @@ -248,7 +240,6 @@ class KotlinNativeTargetPreset( private val name: String, val project: Project, val konanTarget: KonanTarget, - private val buildOutputCleanupRegistry: BuildOutputCleanupRegistry, private val kotlinPluginVersion: String ) : KotlinTargetPreset { @@ -317,7 +308,7 @@ class KotlinNativeTargetPreset( compilations = project.container(compilationFactory.itemClass, compilationFactory) } - KotlinNativeTargetConfigurator(buildOutputCleanupRegistry, kotlinPluginVersion).configureTarget(result) + KotlinNativeTargetConfigurator(kotlinPluginVersion).configureTarget(result) // Allow IDE to resolve the libraries provided by the compiler by adding them into dependencies. result.compilations.all { compilation ->