[Gradle] HierarchicalNativeDistributionCommonizerTask: Implement project global caching

- Implement NativeDistributionCommonizationCache which will act similar
to the 'SuccessMarker' used in the non hierarchical commonization task.

- Implement 'kotlin.mpp.enableNativeDistributionCommonizationCache'
Gradle property to disable project global caching. The cache is
turned on by default.
This commit is contained in:
sebastian.sellmair
2021-04-07 16:54:05 +02:00
parent 50d0439af3
commit 9ac7b61094
4 changed files with 78 additions and 3 deletions
@@ -19,9 +19,24 @@ class CommonizerIT : BaseGradleIT() {
@Test
fun `test commonizeNativeDistributionWithIosLinuxWindows`() {
with(Project("commonizeNativeDistributionWithIosLinuxWindows")) {
build(":p1:commonize") {
build(":p1:commonize", "-Pkotlin.mpp.enableNativeDistributionCommonizationCache=false") {
assertTasksExecuted(":p1:commonizeNativeDistribution")
assertContains(DISABLED_NATIVE_TARGETS_REPORTER_WARNING_PREFIX)
assertContains("Kotlin KLIB commonizer:")
assertSuccessful()
}
build(":p1:commonize", "--rerun-tasks", "-Pkotlin.mpp.enableNativeDistributionCommonizationCache=true") {
assertTasksExecuted(":p1:commonizeNativeDistribution")
assertContains("Native Distribution Commonization: Cache hit")
assertNotContains("Kotlin KLIB commonizer:")
assertSuccessful()
}
build(":p1:commonize", "--rerun-tasks", "-Pkotlin.mpp.enableNativeDistributionCommonizationCache=false") {
assertTasksExecuted(":p1:commonizeNativeDistribution")
assertContains("Native Distribution Commonization: Cache disabled")
assertContains("Kotlin KLIB commonizer:")
assertSuccessful()
}
}
@@ -230,6 +230,9 @@ internal class PropertiesProvider private constructor(private val project: Proje
val enableHierarchicalCommonization: Boolean
get() = booleanProperty("kotlin.mpp.enableHierarchicalCommonization") ?: true
val enableNativeDistributionCommonizationCache: Boolean
get() = booleanProperty("kotlin.mpp.enableNativeDistributionCommonizationCache") ?: true
/**
* Dependencies caching strategy for all targets that support caches.
*/
@@ -81,8 +81,8 @@ internal open class HierarchicalNativeDistributionCommonizerTask : DefaultTask()
@TaskAction
protected fun run() {
for (target in rootCommonizerTargets) {
getRootOutputDirectory(target).deleteRecursively()
commonizerRunner.run(getCommandLineArguments(target))
NativeDistributionCommonizationCache(commonizerRunner, getRootOutputDirectory(target))
.runIfNecessary(getCommandLineArguments(target))
}
}
@@ -111,3 +111,4 @@ private val String.base64
get() = base64Encoder.encodeToString(toByteArray(StandardCharsets.UTF_8))
private val base64Encoder = Base64.getEncoder().withoutPadding()
@@ -0,0 +1,56 @@
/*
* Copyright 2010-2021 JetBrains s.r.o. and Kotlin Programming Language contributors.
* Use of this source code is governed by the Apache 2.0 license that can be found in the license/LICENSE.txt file.
*/
package org.jetbrains.kotlin.gradle.targets.native.internal
import org.gradle.api.Project
import org.jetbrains.kotlin.compilerRunner.KotlinToolRunner
import org.jetbrains.kotlin.gradle.plugin.PropertiesProvider
import java.io.File
internal val Project.isNativeDistributionCommonizationCacheEnabled: Boolean
get() = PropertiesProvider(this).enableNativeDistributionCommonizationCache
internal class NativeDistributionCommonizationCache(
private val runner: KotlinToolRunner,
private val outputDirectory: File
) {
private val successMarker = outputDirectory.resolve(".commonized")
fun runIfNecessary(args: List<String>) {
if (!isCached(args)) {
run(args)
}
}
private fun isCached(args: List<String>): Boolean {
if (!runner.project.isNativeDistributionCommonizationCacheEnabled) {
runner.project.logger.info("Native Distribution Commonization: Cache disabled")
return false
}
if (successMarker.exists() && successMarker.isFile) {
if (successMarker.readText() == successMarkerText(args)) {
runner.project.logger.info("Native Distribution Commonization: Cache hit for ${outputDirectory.path}")
return true
} else {
runner.project.logger.info("Native Distribution Commonization: Cache miss. Different args")
successMarker.delete()
}
}
return false
}
private fun run(args: List<String>) {
outputDirectory.deleteRecursively()
runner.run(args)
successMarker.writeText(successMarkerText(args))
}
private fun successMarkerText(args: List<String>): String {
return args.joinToString("\n")
}
}