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.
This commit is contained in:
Sergey Igushkin
2018-10-11 19:01:23 +03:00
parent a0f4d5a637
commit 81b4031a35
5 changed files with 45 additions and 27 deletions
@@ -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") 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")
}
}
} }
@@ -22,7 +22,6 @@ import org.gradle.api.internal.FeaturePreviews
import org.gradle.api.internal.file.FileResolver import org.gradle.api.internal.file.FileResolver
import org.gradle.api.logging.Logger import org.gradle.api.logging.Logger
import org.gradle.api.logging.Logging import org.gradle.api.logging.Logging
import org.gradle.internal.cleanup.BuildOutputCleanupRegistry
import org.gradle.internal.reflect.Instantiator import org.gradle.internal.reflect.Instantiator
import org.gradle.tooling.provider.model.ToolingModelBuilderRegistry import org.gradle.tooling.provider.model.ToolingModelBuilderRegistry
import org.jetbrains.kotlin.gradle.dsl.* import org.jetbrains.kotlin.gradle.dsl.*
@@ -134,12 +133,11 @@ open class Kotlin2JsPluginWrapper @Inject constructor(
open class KotlinMultiplatformPluginWrapper @Inject constructor( open class KotlinMultiplatformPluginWrapper @Inject constructor(
fileResolver: FileResolver, fileResolver: FileResolver,
private val instantiator: Instantiator, private val instantiator: Instantiator,
private val buildOutputCleanupRegistry: BuildOutputCleanupRegistry,
private val featurePreviews: FeaturePreviews private val featurePreviews: FeaturePreviews
): KotlinBasePluginWrapper(fileResolver) { ): KotlinBasePluginWrapper(fileResolver) {
override fun getPlugin(project: Project, kotlinGradleBuildServices: KotlinGradleBuildServices): Plugin<Project> = override fun getPlugin(project: Project, kotlinGradleBuildServices: KotlinGradleBuildServices): Plugin<Project> =
KotlinMultiplatformPlugin( KotlinMultiplatformPlugin(
buildOutputCleanupRegistry, fileResolver, fileResolver,
instantiator, kotlinPluginVersion, featurePreviews instantiator, kotlinPluginVersion, featurePreviews
) )
@@ -44,7 +44,6 @@ import java.util.*
import java.util.concurrent.Callable import java.util.concurrent.Callable
abstract class AbstractKotlinTargetConfigurator<KotlinTargetType : KotlinTarget>( abstract class AbstractKotlinTargetConfigurator<KotlinTargetType : KotlinTarget>(
private val buildOutputCleanupRegistry: BuildOutputCleanupRegistry,
protected val createDefaultSourceSets: Boolean, protected val createDefaultSourceSets: Boolean,
protected val createTestCompilation: Boolean protected val createTestCompilation: Boolean
) { ) {
@@ -62,12 +61,17 @@ abstract class AbstractKotlinTargetConfigurator<KotlinTargetType : KotlinTarget>
abstract fun configureArchivesAndComponent(target: KotlinTargetType) 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) { protected fun configureCompilations(platformTarget: KotlinTargetType) {
val project = platformTarget.project val project = platformTarget.project
val main = platformTarget.compilations.create(KotlinCompilation.MAIN_COMPILATION_NAME) val main = platformTarget.compilations.create(KotlinCompilation.MAIN_COMPILATION_NAME)
platformTarget.compilations.all { platformTarget.compilations.all {
buildOutputCleanupRegistry.registerOutputs(it.output) project.registerOutputsForStaleOutputCleanup(it)
it.compileDependencyFiles = project.configurations.maybeCreate(it.compileDependencyConfigurationName) it.compileDependencyFiles = project.configurations.maybeCreate(it.compileDependencyConfigurationName)
if (it is KotlinCompilationToRunnableFiles) { if (it is KotlinCompilationToRunnableFiles) {
it.runtimeDependencyFiles = project.configurations.maybeCreate(it.runtimeDependencyConfigurationName) it.runtimeDependencyFiles = project.configurations.maybeCreate(it.runtimeDependencyConfigurationName)
@@ -324,11 +328,9 @@ internal val KotlinCompilationToRunnableFiles.deprecatedRuntimeConfigurationName
get() = disambiguateName("runtime") get() = disambiguateName("runtime")
open class KotlinTargetConfigurator<KotlinCompilationType: KotlinCompilation>( open class KotlinTargetConfigurator<KotlinCompilationType: KotlinCompilation>(
buildOutputCleanupRegistry: BuildOutputCleanupRegistry,
createDefaultSourceSets: Boolean, createDefaultSourceSets: Boolean,
createTestCompilation: Boolean createTestCompilation: Boolean
) : AbstractKotlinTargetConfigurator<KotlinOnlyTarget<KotlinCompilationType>>( ) : AbstractKotlinTargetConfigurator<KotlinOnlyTarget<KotlinCompilationType>>(
buildOutputCleanupRegistry,
createDefaultSourceSets, createDefaultSourceSets,
createTestCompilation createTestCompilation
) { ) {
@@ -378,10 +380,8 @@ open class KotlinTargetConfigurator<KotlinCompilationType: KotlinCompilation>(
open class KotlinNativeTargetConfigurator( open class KotlinNativeTargetConfigurator(
buildOutputCleanupRegistry: BuildOutputCleanupRegistry,
private val kotlinPluginVersion: String private val kotlinPluginVersion: String
) : AbstractKotlinTargetConfigurator<KotlinNativeTarget>( ) : AbstractKotlinTargetConfigurator<KotlinNativeTarget>(
buildOutputCleanupRegistry,
createDefaultSourceSets = true, createDefaultSourceSets = true,
createTestCompilation = true createTestCompilation = true
) { ) {
@@ -19,7 +19,6 @@ import org.gradle.api.publish.PublishingExtension
import org.gradle.api.publish.maven.MavenPublication import org.gradle.api.publish.maven.MavenPublication
import org.gradle.api.publish.maven.internal.publication.MavenPublicationInternal import org.gradle.api.publish.maven.internal.publication.MavenPublicationInternal
import org.gradle.api.publish.maven.tasks.AbstractPublishToMaven import org.gradle.api.publish.maven.tasks.AbstractPublishToMaven
import org.gradle.internal.cleanup.BuildOutputCleanupRegistry
import org.gradle.internal.reflect.Instantiator import org.gradle.internal.reflect.Instantiator
import org.gradle.jvm.tasks.Jar import org.gradle.jvm.tasks.Jar
import org.gradle.util.ConfigureUtil import org.gradle.util.ConfigureUtil
@@ -34,7 +33,6 @@ internal val Project.multiplatformExtension get(): KotlinMultiplatformExtension?
project.extensions.findByName("kotlin") as? KotlinMultiplatformExtension project.extensions.findByName("kotlin") as? KotlinMultiplatformExtension
class KotlinMultiplatformPlugin( class KotlinMultiplatformPlugin(
private val buildOutputCleanupRegistry: BuildOutputCleanupRegistry,
private val fileResolver: FileResolver, private val fileResolver: FileResolver,
private val instantiator: Instantiator, private val instantiator: Instantiator,
private val kotlinPluginVersion: String, private val kotlinPluginVersion: String,
@@ -87,19 +85,19 @@ class KotlinMultiplatformPlugin(
// set up metadata publishing // set up metadata publishing
targetsFromPreset.fromPreset( targetsFromPreset.fromPreset(
KotlinMetadataTargetPreset(project, instantiator, fileResolver, buildOutputCleanupRegistry, kotlinPluginVersion), KotlinMetadataTargetPreset(project, instantiator, fileResolver, kotlinPluginVersion),
METADATA_TARGET_NAME METADATA_TARGET_NAME
) )
} }
fun setupDefaultPresets(project: Project) { fun setupDefaultPresets(project: Project) {
with((project.kotlinExtension as KotlinMultiplatformExtension).presets) { with((project.kotlinExtension as KotlinMultiplatformExtension).presets) {
add(KotlinJvmTargetPreset(project, instantiator, fileResolver, buildOutputCleanupRegistry, kotlinPluginVersion)) add(KotlinJvmTargetPreset(project, instantiator, fileResolver, kotlinPluginVersion))
add(KotlinJsTargetPreset(project, instantiator, fileResolver, buildOutputCleanupRegistry, kotlinPluginVersion)) add(KotlinJsTargetPreset(project, instantiator, fileResolver, kotlinPluginVersion))
add(KotlinAndroidTargetPreset(project, kotlinPluginVersion)) add(KotlinAndroidTargetPreset(project, kotlinPluginVersion))
add(KotlinJvmWithJavaTargetPreset(project, kotlinPluginVersion)) add(KotlinJvmWithJavaTargetPreset(project, kotlinPluginVersion))
HostManager().targets.forEach { _, target -> HostManager().targets.forEach { _, target ->
add(KotlinNativeTargetPreset(target.presetName, project, target, buildOutputCleanupRegistry, kotlinPluginVersion)) add(KotlinNativeTargetPreset(target.presetName, project, target, kotlinPluginVersion))
} }
} }
} }
@@ -11,7 +11,6 @@ import org.gradle.api.artifacts.repositories.IvyArtifactRepository
import org.gradle.api.artifacts.repositories.IvyPatternRepositoryLayout import org.gradle.api.artifacts.repositories.IvyPatternRepositoryLayout
import org.gradle.api.internal.file.FileResolver import org.gradle.api.internal.file.FileResolver
import org.gradle.api.plugins.JavaPlugin import org.gradle.api.plugins.JavaPlugin
import org.gradle.internal.cleanup.BuildOutputCleanupRegistry
import org.gradle.internal.reflect.Instantiator import org.gradle.internal.reflect.Instantiator
import org.jetbrains.kotlin.compilerRunner.KotlinNativeProjectProperty import org.jetbrains.kotlin.compilerRunner.KotlinNativeProjectProperty
import org.jetbrains.kotlin.compilerRunner.hasProperty import org.jetbrains.kotlin.compilerRunner.hasProperty
@@ -33,12 +32,11 @@ abstract class KotlinOnlyTargetPreset<T : KotlinCompilation>(
protected val project: Project, protected val project: Project,
private val instantiator: Instantiator, private val instantiator: Instantiator,
private val fileResolver: FileResolver, private val fileResolver: FileResolver,
protected val buildOutputCleanupRegistry: BuildOutputCleanupRegistry,
protected val kotlinPluginVersion: String protected val kotlinPluginVersion: String
) : KotlinTargetPreset<KotlinOnlyTarget<T>> { ) : KotlinTargetPreset<KotlinOnlyTarget<T>> {
protected open fun createKotlinTargetConfigurator(): KotlinTargetConfigurator<T> = protected open fun createKotlinTargetConfigurator(): KotlinTargetConfigurator<T> =
KotlinTargetConfigurator(buildOutputCleanupRegistry, createDefaultSourceSets = true, createTestCompilation = true) KotlinTargetConfigurator(createDefaultSourceSets = true, createTestCompilation = true)
override fun createTarget(name: String): KotlinOnlyTarget<T> { override fun createTarget(name: String): KotlinOnlyTarget<T> {
val result = KotlinOnlyTarget<T>(project, platformType).apply { val result = KotlinOnlyTarget<T>(project, platformType).apply {
@@ -67,13 +65,11 @@ class KotlinMetadataTargetPreset(
project: Project, project: Project,
instantiator: Instantiator, instantiator: Instantiator,
fileResolver: FileResolver, fileResolver: FileResolver,
buildOutputCleanupRegistry: BuildOutputCleanupRegistry,
kotlinPluginVersion: String kotlinPluginVersion: String
) : KotlinOnlyTargetPreset<KotlinCommonCompilation>( ) : KotlinOnlyTargetPreset<KotlinCommonCompilation>(
project, project,
instantiator, instantiator,
fileResolver, fileResolver,
buildOutputCleanupRegistry,
kotlinPluginVersion kotlinPluginVersion
) { ) {
override fun getName(): String = PRESET_NAME override fun getName(): String = PRESET_NAME
@@ -99,7 +95,7 @@ class KotlinMetadataTargetPreset(
} }
override fun createKotlinTargetConfigurator(): KotlinTargetConfigurator<KotlinCommonCompilation> = override fun createKotlinTargetConfigurator(): KotlinTargetConfigurator<KotlinCommonCompilation> =
KotlinTargetConfigurator(buildOutputCleanupRegistry, createDefaultSourceSets = false, createTestCompilation = false) KotlinTargetConfigurator(createDefaultSourceSets = false, createTestCompilation = false)
override fun createTarget(name: String): KotlinOnlyTarget<KotlinCommonCompilation> = override fun createTarget(name: String): KotlinOnlyTarget<KotlinCommonCompilation> =
super.createTarget(name).apply { super.createTarget(name).apply {
@@ -120,13 +116,11 @@ class KotlinJvmTargetPreset(
project: Project, project: Project,
instantiator: Instantiator, instantiator: Instantiator,
fileResolver: FileResolver, fileResolver: FileResolver,
buildOutputCleanupRegistry: BuildOutputCleanupRegistry,
kotlinPluginVersion: String kotlinPluginVersion: String
) : KotlinOnlyTargetPreset<KotlinJvmCompilation>( ) : KotlinOnlyTargetPreset<KotlinJvmCompilation>(
project, project,
instantiator, instantiator,
fileResolver, fileResolver,
buildOutputCleanupRegistry,
kotlinPluginVersion kotlinPluginVersion
) { ) {
override fun getName(): String = PRESET_NAME override fun getName(): String = PRESET_NAME
@@ -149,13 +143,11 @@ class KotlinJsTargetPreset(
project: Project, project: Project,
instantiator: Instantiator, instantiator: Instantiator,
fileResolver: FileResolver, fileResolver: FileResolver,
buildOutputCleanupRegistry: BuildOutputCleanupRegistry,
kotlinPluginVersion: String kotlinPluginVersion: String
) : KotlinOnlyTargetPreset<KotlinJsCompilation>( ) : KotlinOnlyTargetPreset<KotlinJsCompilation>(
project, project,
instantiator, instantiator,
fileResolver, fileResolver,
buildOutputCleanupRegistry,
kotlinPluginVersion kotlinPluginVersion
) { ) {
override fun getName(): String = PRESET_NAME override fun getName(): String = PRESET_NAME
@@ -248,7 +240,6 @@ class KotlinNativeTargetPreset(
private val name: String, private val name: String,
val project: Project, val project: Project,
val konanTarget: KonanTarget, val konanTarget: KonanTarget,
private val buildOutputCleanupRegistry: BuildOutputCleanupRegistry,
private val kotlinPluginVersion: String private val kotlinPluginVersion: String
) : KotlinTargetPreset<KotlinNativeTarget> { ) : KotlinTargetPreset<KotlinNativeTarget> {
@@ -317,7 +308,7 @@ class KotlinNativeTargetPreset(
compilations = project.container(compilationFactory.itemClass, compilationFactory) 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. // Allow IDE to resolve the libraries provided by the compiler by adding them into dependencies.
result.compilations.all { compilation -> result.compilations.all { compilation ->