[Gradle] Always declare system property reads for compile tasks

When Kotlin plugin is applied in buildSrc or included build that defines Gradle plugins it can cause Gradle to report undeclared system property reads at configuration time. Declaring all system properties reads through Gradle providers to cover all these cases.
#KT-45910 Fixed
This commit is contained in:
Alexander Likhachev
2021-04-10 18:20:31 +03:00
parent 47407c4445
commit 9e78e43c49
8 changed files with 108 additions and 35 deletions
@@ -77,6 +77,17 @@ class ConfigurationCacheIT : AbstractConfigurationCacheIT() {
)
}
@Test
fun testInstantExecutionWithIncludedBuildPlugin() =
with(Project("instantExecutionWithIncludedBuildPlugin", gradleVersionRequirement = GradleVersionRequired.AtLeast("6.8"))) {
setupWorkingDir()
testConfigurationCacheOf(
"build", executedTaskNames = listOf(
":compileKotlin",
)
)
}
@Test
fun testInstantExecutionForJs() = with(Project("instantExecutionToJs")) {
testConfigurationCacheOf("assemble", executedTaskNames = asList(":compileKotlin2Js"))
@@ -0,0 +1,20 @@
buildscript {
repositories {
mavenLocal()
mavenCentral()
}
dependencies {
classpath "org.jetbrains.kotlin:kotlin-gradle-plugin:$kotlin_version"
}
}
plugins {
id("foo-plugin")
}
apply plugin: 'kotlin'
repositories {
mavenLocal()
mavenCentral()
}
@@ -0,0 +1,27 @@
buildscript {
repositories {
mavenLocal()
mavenCentral()
}
dependencies {
classpath "org.jetbrains.kotlin:kotlin-gradle-plugin:$kotlin_version"
}
}
plugins {
id 'java-gradle-plugin'
}
apply plugin: 'kotlin'
repositories {
mavenLocal()
mavenCentral()
}
gradlePlugin {
plugins.register("foo-plugin") {
id = "foo-plugin"
implementationClass = "FooPlugin"
}
}
@@ -0,0 +1,7 @@
import org.gradle.api.Plugin
import org.gradle.api.Project
class FooPlugin : Plugin<Project> {
override fun apply(project: Project) {
}
}
@@ -5,7 +5,6 @@
package org.jetbrains.kotlin.compilerRunner
import org.gradle.api.Project
import org.gradle.api.invocation.Gradle
import org.gradle.api.provider.MapProperty
import org.gradle.api.provider.Provider
@@ -22,22 +21,25 @@ internal abstract class CompilerSystemPropertiesService : BuildService<CompilerS
private val properties by lazy { parameters.properties.get().mapValues { it.value.orNull }.toMutableMap() }
fun startIntercept() {
if (!parameters.properties.isPresent) return
if (parameters.properties.get().isEmpty()) return
CompilerSystemProperties.systemPropertyGetter = {
if (it in properties) properties[it] else System.getProperty(it)
}
CompilerSystemProperties.systemPropertySetter = setter@{ key, value ->
if (key !in properties) {
return@setter System.setProperty(key, value)
}
val oldValue = properties[key]
if (oldValue == value) return@setter oldValue
properties[key] = value
System.setProperty(key, value)
oldValue
}
CompilerSystemProperties.systemPropertyCleaner = {
CompilerSystemProperties.systemPropertyCleaner = cleaner@{
if (it !in properties) {
return@cleaner System.clearProperty(it)
}
val oldValue = properties[it]
properties.remove(it)
System.clearProperty(it)
oldValue
}
}
@@ -49,22 +51,19 @@ internal abstract class CompilerSystemPropertiesService : BuildService<CompilerS
}
companion object {
private val Project.isBuildSrc get() = name == ":buildSrc"
fun registerIfAbsent(gradle: Gradle): Provider<CompilerSystemPropertiesService> =
gradle.sharedServices.registerIfAbsent(
"${CompilerSystemPropertiesService::class.java.canonicalName}_${CompilerSystemPropertiesService::class.java.classLoader.hashCode()}",
CompilerSystemPropertiesService::class.java
) { service ->
val rootProject = gradle.rootProject
if (rootProject.isBuildSrc && isConfigurationCacheAvailable(gradle)) {
service.parameters.properties.set(
CompilerSystemProperties.values()
.associate {
it.property to rootProject.providers.systemProperty(it.property).forUseAtConfigurationTime()
}.toMap()
)
}
fun registerIfAbsent(gradle: Gradle): Provider<CompilerSystemPropertiesService> = gradle.sharedServices.registerIfAbsent(
"${CompilerSystemPropertiesService::class.java.canonicalName}_${CompilerSystemPropertiesService::class.java.classLoader.hashCode()}",
CompilerSystemPropertiesService::class.java
) { service ->
if (isConfigurationCacheAvailable(gradle)) {
service.parameters.properties.set(
CompilerSystemProperties.values()
.filterNot { it.alwaysDirectAccess }
.associate {
it.property to gradle.rootProject.providers.systemProperty(it.property).forUseAtConfigurationTime()
}.toMap()
)
}
}
}
}