[Gradle] Mark tasks that not compatible with configuration cache

Gradle 7.4 offers new API that allow to exclude task configuration
from being stored in Configuration Cache.

GCC should be supported in further releases.
* KotlinNativeCompile -- KT-43293
* GenerateProjectStructureMetadata
 and TransformKotlinGranularMetadata -- KT-49933

cherry-picked from 7bdde5f4c025f2f55c0038a8d58e0ea78a0ff151

^KT-51946 Verification Pending
This commit is contained in:
Anton Lakotka
2022-04-13 13:33:11 +02:00
committed by Space
parent 399bd750c1
commit d2c6489de9
10 changed files with 115 additions and 1 deletions
@@ -717,6 +717,42 @@ class HierarchicalMppIT : KGPBaseTest() {
}
}
@GradleTest
@GradleTestVersions(minVersion = TestVersions.Gradle.G_7_4, maxVersion = TestVersions.Gradle.G_7_4)
@DisplayName("KT-51946: Temporarily mark HMPP tasks as notCompatibleWithConfigurationCache for Gradle 7.4")
fun testHmppTasksAreNotIncludedInGradleConfigurationCache(gradleVersion: GradleVersion, @TempDir tempDir: Path) {
with(project("hmppGradleConfigurationCache", gradleVersion = gradleVersion, localRepoDir = tempDir)) {
val options = buildOptions.copy(configurationCache = true, configurationCacheProblems = BaseGradleIT.ConfigurationCacheProblems.FAIL)
build(":lib:publish") {
assertTasksExecuted(":lib:publish")
}
build("clean", "assemble", buildOptions = options) {
assertTasksExecuted(
":generateProjectStructureMetadata",
":transformCommonMainDependenciesMetadata"
)
assertOutputContains(
"""Task `:generateProjectStructureMetadata` of type `.+`: invocation of 'Task\.project' at execution time is unsupported"""
.toRegex()
)
assertOutputContains(
"""Task `:transformCommonMainDependenciesMetadata` of type `.+`: invocation of 'Task.project' at execution time is unsupported"""
.toRegex()
)
}
build("clean", "assemble", buildOptions = options) {
assertOutputContains("Configuration cache entry discarded")
assertTasksExecuted(
":generateProjectStructureMetadata",
":transformCommonMainDependenciesMetadata"
)
}
}
}
private fun TestProject.testDependencyTransformations(
subproject: String? = null,
check: BuildResult.(reports: Iterable<DependencyTransformationReport>) -> Unit
@@ -0,0 +1,24 @@
plugins {
kotlin("multiplatform")
}
allprojects {
repositories {
mavenLocal()
mavenCentral()
maven("<localRepo>")
}
}
kotlin {
jvm()
linuxX64()
sourceSets {
val commonMain by getting {
dependencies {
implementation("test:lib:1.0")
}
}
}
}
@@ -0,0 +1,18 @@
plugins {
kotlin("multiplatform")
`maven-publish`
}
kotlin {
jvm()
linuxX64()
}
group = "test"
version = "1.0"
publishing {
repositories {
maven("<localRepo>")
}
}
@@ -0,0 +1,3 @@
package com.example
fun commonMainLib() = "commonMainLib"
@@ -0,0 +1,2 @@
rootProject.name = "hmppGradleConfigurationCache"
include("lib")
@@ -0,0 +1,3 @@
package com.example
fun commonMainApp() = commonMainLib() + "commonMainApp"
@@ -10,9 +10,15 @@ import org.gradle.api.tasks.Internal
import org.gradle.api.tasks.Nested
import org.gradle.api.tasks.OutputFile
import org.gradle.api.tasks.TaskAction
import org.jetbrains.kotlin.gradle.utils.notCompatibleWithConfigurationCache
import java.io.File
open class GenerateProjectStructureMetadata : DefaultTask() {
init {
notCompatibleWithConfigurationCache("Task $name does not support Gradle Configuration Cache. Check KT-49933 for more info")
}
@get:Internal
internal lateinit var lazyKotlinProjectStructureMetadata: Lazy<KotlinProjectStructureMetadata>
@@ -18,6 +18,7 @@ import org.jetbrains.kotlin.gradle.targets.metadata.KotlinMetadataTargetConfigur
import org.jetbrains.kotlin.gradle.targets.metadata.ResolvedMetadataFilesProvider
import org.jetbrains.kotlin.gradle.targets.metadata.dependsOnClosureWithInterCompilationDependencies
import org.jetbrains.kotlin.gradle.utils.getValue
import org.jetbrains.kotlin.gradle.utils.notCompatibleWithConfigurationCache
import java.io.File
import javax.inject.Inject
@@ -28,6 +29,10 @@ open class TransformKotlinGranularMetadata
val kotlinSourceSet: KotlinSourceSet
) : DefaultTask() {
init {
notCompatibleWithConfigurationCache("Task $name does not support Gradle Configuration Cache. Check KT-49933 for more info")
}
@get:OutputDirectory
val outputsDir: File by project.provider {
project.buildDir.resolve("kotlinSourceSetMetadata/${kotlinSourceSet.name}")
@@ -313,6 +313,10 @@ constructor(
) : AbstractKotlinNativeCompile<KotlinCommonOptions, KotlinNativeCompilationData<*>, StubK2NativeCompilerArguments>(objectFactory),
KotlinCompile<KotlinCommonOptions> {
init {
notCompatibleWithConfigurationCache("Task $name does not support Gradle Configuration Cache. Check KT-43293 for more info")
}
@get:Input
override val outputKind = LIBRARY
@@ -6,6 +6,7 @@
package org.jetbrains.kotlin.gradle.utils
import org.gradle.api.Project
import org.gradle.api.Task
import org.gradle.api.invocation.Gradle
internal fun isConfigurationCacheAvailable(gradle: Gradle) =
@@ -25,4 +26,16 @@ internal fun Project.getSystemProperty(key: String): String? {
}
internal fun unavailableValueError(propertyName: String): Nothing =
error("'$propertyName' should be available at configuration time but unavailable on configuration cache reuse")
error("'$propertyName' should be available at configuration time but unavailable on configuration cache reuse")
fun Task.notCompatibleWithConfigurationCache(reason: String) {
if (!isGradleVersionAtLeast(7, 4)) return
try {
val taskClass = Task::class.java
val method = taskClass.getMethod("notCompatibleWithConfigurationCache", String::class.java)
method.invoke(this, reason)
} catch (e: ReflectiveOperationException) {
logger.warn("Can't mark task $this as notCompatibleWithConfigurationCache due to reflection issue", e)
}
}