[Gradle] Move Kotlin daemon system properties read to build service

Instead of having a copy of those properties in each task move them into single build service
Related to #KT-43605
This commit is contained in:
Alexander Likhachev
2021-03-29 19:23:39 +03:00
parent 5f2095217d
commit c44d83c6ba
3 changed files with 79 additions and 38 deletions
@@ -40,25 +40,19 @@ enum class CompilerSystemProperties(val property: String) {
;
var value
get() = systemPropertyGetter(property)
get() = (systemPropertyGetter ?: System::getProperty)(property)
set(value) {
systemPropertySetter(property, value!!)
(systemPropertySetter ?: System::setProperty)(property, value!!)
}
fun clear(): String? = systemPropertyCleaner(property)
fun clear(): String? = (systemPropertyCleaner ?: System::clearProperty)(property)
companion object {
var systemPropertyGetter: (String) -> String? = {
System.getProperty(it)
}
var systemPropertyGetter: ((String) -> String?)? = null
var systemPropertySetter: (String, String) -> String? = { key, value ->
System.setProperty(key, value)
}
var systemPropertySetter: ((String, String) -> String?)? = null
var systemPropertyCleaner: (String) -> String? = { key ->
System.clearProperty(key)
}
var systemPropertyCleaner: ((String) -> String?)? = null
}
}
@@ -0,0 +1,70 @@
/*
* 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.compilerRunner
import org.gradle.api.Project
import org.gradle.api.invocation.Gradle
import org.gradle.api.provider.MapProperty
import org.gradle.api.provider.Provider
import org.gradle.api.services.BuildService
import org.gradle.api.services.BuildServiceParameters
import org.jetbrains.kotlin.cli.common.CompilerSystemProperties
import org.jetbrains.kotlin.gradle.utils.isConfigurationCacheAvailable
internal abstract class CompilerSystemPropertiesService : BuildService<CompilerSystemPropertiesService.Parameters>, AutoCloseable {
internal interface Parameters : BuildServiceParameters {
val properties: MapProperty<String, Provider<String>>
}
private val properties by lazy { parameters.properties.get().mapValues { it.value.orNull }.toMutableMap() }
fun startIntercept() {
if (!parameters.properties.isPresent) return
CompilerSystemProperties.systemPropertyGetter = {
if (it in properties) properties[it] else System.getProperty(it)
}
CompilerSystemProperties.systemPropertySetter = setter@{ key, value ->
val oldValue = properties[key]
if (oldValue == value) return@setter oldValue
properties[key] = value
System.setProperty(key, value)
oldValue
}
CompilerSystemProperties.systemPropertyCleaner = {
val oldValue = properties[it]
properties.remove(it)
System.clearProperty(it)
oldValue
}
}
override fun close() {
CompilerSystemProperties.systemPropertyGetter = null
CompilerSystemProperties.systemPropertySetter = null
CompilerSystemProperties.systemPropertyCleaner = null
}
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()
)
}
}
}
}
@@ -50,7 +50,6 @@ import org.jetbrains.kotlin.incremental.ChangedFiles
import org.jetbrains.kotlin.library.impl.isKotlinLibrary
import org.jetbrains.kotlin.utils.JsLibraryUtils
import java.io.File
import java.util.zip.ZipFile
import javax.inject.Inject
const val KOTLIN_BUILD_DIR_NAME = "kotlin"
@@ -335,24 +334,11 @@ abstract class AbstractKotlinCompile<T : CommonCompilerArguments>() : AbstractKo
internal open fun compilerRunner(): GradleCompilerRunner = GradleCompilerRunner(GradleCompileTaskProvider(this))
private val systemPropertiesService = CompilerSystemPropertiesService.registerIfAbsent(project.gradle)
@TaskAction
fun execute(inputs: IncrementalTaskInputs) {
CompilerSystemProperties.systemPropertyGetter = {
if (it in kotlinDaemonProperties) kotlinDaemonProperties[it] else System.getProperty(it)
}
CompilerSystemProperties.systemPropertySetter = setter@{ key, value ->
val oldValue = kotlinDaemonProperties[key]
if (oldValue == value) return@setter oldValue
kotlinDaemonProperties[key] = value
System.setProperty(key, value)
oldValue
}
CompilerSystemProperties.systemPropertyCleaner = {
val oldValue = kotlinDaemonProperties[it]
kotlinDaemonProperties.remove(it)
System.clearProperty(it)
oldValue
}
systemPropertiesService.get().startIntercept()
CompilerSystemProperties.KOTLIN_COMPILER_ENVIRONMENT_KEEPALIVE_PROPERTY.value = "true"
// If task throws exception, but its outputs are changed during execution,
@@ -446,15 +432,6 @@ abstract class AbstractKotlinCompile<T : CommonCompilerArguments>() : AbstractKo
val taskBuildDir = taskBuildDirectory
return taskBuildDir.walk().any { it != taskBuildDir && it.isFile }
}
@get:Internal
val kotlinDaemonProperties: MutableMap<String, String?> by lazy {
if (isGradleVersionAtLeast(6, 5)) {
CompilerSystemProperties.values()
.associate { it.property to project.providers.systemProperty(it.property).forUseAtConfigurationTime().orNull }
.toMutableMap()
} else mutableMapOf()
}
}
open class KotlinCompileArgumentsProvider<T : AbstractKotlinCompile<out CommonCompilerArguments>>(taskProvider: T) {