[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:
@@ -16,10 +16,10 @@
|
||||
|
||||
package org.jetbrains.kotlin.cli.common
|
||||
|
||||
import com.intellij.util.LineSeparator
|
||||
import java.util.*
|
||||
|
||||
enum class CompilerSystemProperties(val property: String) {
|
||||
/**
|
||||
* @param alwaysDirectAccess Gradle has a list of properties that can be read without declaring, see https://github.com/gradle/gradle/blob/f191a61cec61afe308f2b45184cb303d32706a6f/subprojects/configuration-cache/src/main/kotlin/org/gradle/configurationcache/SystemPropertyAccessListener.kt#L32
|
||||
*/
|
||||
enum class CompilerSystemProperties(val property: String, val alwaysDirectAccess: Boolean = false) {
|
||||
COMPILE_DAEMON_ENABLED_PROPERTY("kotlin.daemon.enabled"),
|
||||
COMPILE_DAEMON_JVM_OPTIONS_PROPERTY("kotlin.daemon.jvm.options"),
|
||||
COMPILE_DAEMON_OPTIONS_PROPERTY("kotlin.daemon.options"),
|
||||
@@ -36,24 +36,31 @@ enum class CompilerSystemProperties(val property: String) {
|
||||
KOTLIN_COMPILER_ENVIRONMENT_KEEPALIVE_PROPERTY("kotlin.environment.keepalive"),
|
||||
COMPILE_DAEMON_CUSTOM_RUN_FILES_PATH_FOR_TESTS("kotlin.daemon.custom.run.files.path.for.tests"),
|
||||
KOTLIN_COLORS_ENABLED_PROPERTY("kotlin.colors.enabled"),
|
||||
OS_NAME("os.name"),
|
||||
OS_NAME("os.name", alwaysDirectAccess = true),
|
||||
TMP_DIR("java.io.tmpdir"),
|
||||
USER_HOME("user.home"),
|
||||
JAVA_VERSION("java.specification.version"),
|
||||
JAVA_HOME("java.home"),
|
||||
JAVA_CLASS_PATH("java.class.path"),
|
||||
USER_HOME("user.home", alwaysDirectAccess = true),
|
||||
JAVA_VERSION("java.specification.version", alwaysDirectAccess = true),
|
||||
JAVA_HOME("java.home", alwaysDirectAccess = true),
|
||||
JAVA_CLASS_PATH("java.class.path", alwaysDirectAccess = true),
|
||||
;
|
||||
|
||||
var value
|
||||
get() = (systemPropertyGetter ?: System::getProperty)(property)
|
||||
private fun <T> getProperFunction(custom: T?, default: T): T {
|
||||
if (alwaysDirectAccess) return default
|
||||
return custom ?: default
|
||||
}
|
||||
|
||||
var value: String?
|
||||
get() {
|
||||
return getProperFunction(systemPropertyGetter, System::getProperty)(property)
|
||||
}
|
||||
set(value) {
|
||||
(systemPropertySetter ?: System::setProperty)(property, value!!)
|
||||
getProperFunction(systemPropertySetter, System::setProperty)(property, value!!)
|
||||
}
|
||||
|
||||
val safeValue
|
||||
get() = value ?: error("No value for $property system property")
|
||||
|
||||
fun clear(): String? = (systemPropertyCleaner ?: System::clearProperty)(property)
|
||||
fun clear(): String? = getProperFunction(systemPropertyCleaner, System::clearProperty)(property)
|
||||
|
||||
companion object {
|
||||
var systemPropertyGetter: ((String) -> String?)? = null
|
||||
|
||||
+11
@@ -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"))
|
||||
|
||||
+20
@@ -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()
|
||||
}
|
||||
+27
@@ -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"
|
||||
}
|
||||
}
|
||||
+7
@@ -0,0 +1,7 @@
|
||||
import org.gradle.api.Plugin
|
||||
import org.gradle.api.Project
|
||||
|
||||
class FooPlugin : Plugin<Project> {
|
||||
override fun apply(project: Project) {
|
||||
}
|
||||
}
|
||||
+1
@@ -0,0 +1 @@
|
||||
includeBuild("includedBuild")
|
||||
+1
@@ -0,0 +1 @@
|
||||
fun hello() = "Hello"
|
||||
+21
-22
@@ -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()
|
||||
)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user