[Gradle] Implement IDEA sync detection via ValueSource for Gradle 7.5+

#KT-53374 Fixed
This commit is contained in:
Alexander Likhachev
2022-08-04 23:43:46 +02:00
committed by Space
parent b5491177c9
commit 7cc42d3fe9
9 changed files with 162 additions and 21 deletions
@@ -6,20 +6,11 @@
package org.jetbrains.kotlin.gradle.internal
import org.gradle.api.Project
import org.jetbrains.kotlin.gradle.utils.getSystemProperty
import org.jetbrains.kotlin.gradle.plugin.internal.IdeaSyncDetector
import org.jetbrains.kotlin.gradle.plugin.variantImplementationFactory
internal val Project.isInIdeaSync: Boolean
get() {
// "idea.sync.active" was introduced in 2019.1
if (getSystemProperty("idea.sync.active")?.toBoolean() == true) return true
// before 2019.1 there is "idea.active" that was true only on sync,
// but since 2019.1 "idea.active" present in task execution too.
// So let's check Idea version
val majorIdeaVersion = getSystemProperty("idea.version")
?.split(".")
?.getOrNull(0)
val isBeforeIdea2019 = majorIdeaVersion == null || majorIdeaVersion.toInt() < 2019
return isBeforeIdea2019 && getSystemProperty("idea.active")?.toBoolean() == true
}
internal val Project.isInIdeaSync
get() = gradle
.variantImplementationFactory<IdeaSyncDetector.IdeaSyncDetectorVariantFactory>()
.getInstance(this)
.isInIdeaSync
@@ -204,6 +204,11 @@ abstract class KotlinBasePluginWrapper : DefaultKotlinBasePlugin() {
BasePluginConfiguration.BasePluginConfigurationVariantFactory::class,
DefaultBasePluginConfigurationVariantFactory()
)
factories.putIfAbsent(
IdeaSyncDetector.IdeaSyncDetectorVariantFactory::class,
DefaultIdeaSyncDetectorVariantFactory()
)
}
internal open fun createTestRegistry(project: Project) = KotlinTestsRegistry(project)
@@ -0,0 +1,71 @@
/*
* Copyright 2010-2022 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.plugin.internal
import org.gradle.api.Project
import org.gradle.api.provider.Property
import org.gradle.api.provider.ProviderFactory
import org.gradle.api.provider.ValueSource
import org.gradle.api.provider.ValueSourceParameters
import org.jetbrains.kotlin.gradle.plugin.VariantImplementationFactories
import java.io.Serializable
internal abstract class IdeaPropertiesEvaluator {
protected abstract fun readSystemPropertyValue(key: String): String?
internal fun isInIdeaSync(): Boolean {
// "idea.sync.active" was introduced in 2019.1
if (readSystemPropertyValue("idea.sync.active")?.toBoolean() == true) return true
// before 2019.1 there is "idea.active" that was true only on sync,
// but since 2019.1 "idea.active" present in task execution too.
// So let's check Idea version
val majorIdeaVersion = readSystemPropertyValue("idea.version")
?.split(".")
?.getOrNull(0)
val isBeforeIdea2019 = majorIdeaVersion == null || majorIdeaVersion.toInt() < 2019
return isBeforeIdea2019 && readSystemPropertyValue("idea.active")?.toBoolean() == true
}
}
internal interface IdeaSyncDetector {
val isInIdeaSync: Boolean
fun createIdeaPropertiesEvaluator(): IdeaPropertiesEvaluator
interface IdeaSyncDetectorVariantFactory : VariantImplementationFactories.VariantImplementationFactory {
fun getInstance(project: Project): IdeaSyncDetector
}
}
internal class DefaultIdeaSyncDetectorVariantFactory : IdeaSyncDetector.IdeaSyncDetectorVariantFactory {
override fun getInstance(project: Project): IdeaSyncDetector = DefaultIdeaSyncDetector(project.providers)
}
internal abstract class IdeaPropertiesValueSource : ValueSource<Boolean, IdeaPropertiesValueSource.Parameters> {
interface Parameters : ValueSourceParameters {
val propertiesEvaluator: Property<IdeaPropertiesEvaluator>
}
override fun obtain(): Boolean {
return parameters.propertiesEvaluator.get().isInIdeaSync()
}
}
internal class DefaultIdeaSyncDetector(
providerFactory: ProviderFactory
) : IdeaSyncDetector {
override val isInIdeaSync: Boolean = providerFactory.of(IdeaPropertiesValueSource::class.java) {
it.parameters.propertiesEvaluator.set(createIdeaPropertiesEvaluator())
}.get()
override fun createIdeaPropertiesEvaluator(): IdeaPropertiesEvaluator = object : IdeaPropertiesEvaluator(), Serializable {
// since Gradle 7.5 we shouldn't declare system property read
// and also now we can read system properties inside ValueSource without configuration cache invalidation
override fun readSystemPropertyValue(key: String) = System.getProperty(key)
}
}
@@ -12,9 +12,8 @@ import org.gradle.api.Project
import org.gradle.api.file.SourceDirectorySet
import org.gradle.api.model.ObjectFactory
import org.gradle.tooling.provider.model.ToolingModelBuilderRegistry
import org.jetbrains.kotlin.gradle.plugin.internal.BasePluginConfiguration
import org.jetbrains.kotlin.gradle.plugin.internal.*
import org.jetbrains.kotlin.gradle.plugin.internal.BasePluginConfigurationG70
import org.jetbrains.kotlin.gradle.plugin.internal.JavaSourceSetsAccessor
import org.jetbrains.kotlin.gradle.plugin.internal.JavaSourceSetsAccessorG70
import javax.inject.Inject
@@ -142,4 +141,6 @@ private fun Project.registerVariantImplementations() {
JavaSourceSetsAccessorG70.JavaSourceSetAccessorVariantFactoryG70()
factories[BasePluginConfiguration.BasePluginConfigurationVariantFactory::class] =
BasePluginConfigurationG70.BasePluginConfigurationVariantFactoryG70()
factories[IdeaSyncDetector.IdeaSyncDetectorVariantFactory::class] =
IdeaSyncDetectorG70.IdeaSyncDetectorVariantFactoryG70()
}
@@ -0,0 +1,22 @@
/*
* Copyright 2010-2022 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.plugin.internal
import org.gradle.api.Project
import org.gradle.api.provider.ProviderFactory
internal class IdeaSyncDetectorG70(private val providerFactory: ProviderFactory) : IdeaSyncDetector {
override val isInIdeaSync = createIdeaPropertiesEvaluator().isInIdeaSync()
override fun createIdeaPropertiesEvaluator() = object : IdeaPropertiesEvaluator() {
// we should declare system property read for Gradle < 7.4
override fun readSystemPropertyValue(key: String) = providerFactory.systemProperty(key).forUseAtConfigurationTime().orNull
}
internal class IdeaSyncDetectorVariantFactoryG70 : IdeaSyncDetector.IdeaSyncDetectorVariantFactory {
override fun getInstance(project: Project): IdeaSyncDetector = IdeaSyncDetectorG70(project.providers)
}
}
@@ -12,6 +12,8 @@ import org.gradle.api.Project
import org.gradle.api.file.SourceDirectorySet
import org.gradle.api.model.ObjectFactory
import org.gradle.tooling.provider.model.ToolingModelBuilderRegistry
import org.jetbrains.kotlin.gradle.plugin.internal.IdeaSyncDetector
import org.jetbrains.kotlin.gradle.plugin.internal.IdeaSyncDetectorG71
import javax.inject.Inject
private const val PLUGIN_VARIANT_NAME = "gradle71"
@@ -137,5 +139,8 @@ open class KotlinPlatformCommonPlugin : KotlinPlatformPluginBase("common") {
}
}
@Suppress("unused")
private fun Project.registerVariantImplementations() {}
private fun Project.registerVariantImplementations() {
val factories = VariantImplementationFactories.get(gradle)
factories[IdeaSyncDetector.IdeaSyncDetectorVariantFactory::class] =
IdeaSyncDetectorG71.IdeaSyncDetectorVariantFactoryG71()
}
@@ -0,0 +1,22 @@
/*
* Copyright 2010-2022 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.plugin.internal
import org.gradle.api.Project
import org.gradle.api.provider.ProviderFactory
internal class IdeaSyncDetectorG71(private val providerFactory: ProviderFactory) : IdeaSyncDetector {
override val isInIdeaSync = createIdeaPropertiesEvaluator().isInIdeaSync()
override fun createIdeaPropertiesEvaluator() = object : IdeaPropertiesEvaluator() {
// we should declare system property read for Gradle < 7.4
override fun readSystemPropertyValue(key: String) = providerFactory.systemProperty(key).forUseAtConfigurationTime().orNull
}
internal class IdeaSyncDetectorVariantFactoryG71 : IdeaSyncDetector.IdeaSyncDetectorVariantFactory {
override fun getInstance(project: Project): IdeaSyncDetector = IdeaSyncDetectorG71(project.providers)
}
}
@@ -144,7 +144,9 @@ private fun Project.registerVariantImplementations() {
factories[MavenPluginConfigurator.MavenPluginConfiguratorVariantFactory::class] =
MavenPluginConfiguratorG6.Gradle6MavenPluginConfiguratorVariantFactory()
factories[JavaSourceSetsAccessor.JavaSourceSetsAccessorVariantFactory::class] =
JavaSourceSetsAccessorG6.JavaSourceSetAccessorVariantFactoryG70()
JavaSourceSetsAccessorG6.JavaSourceSetAccessorVariantFactoryG6()
factories[BasePluginConfiguration.BasePluginConfigurationVariantFactory::class] =
BasePluginConfigurationG6.BasePluginConfigurationVariantFactoryG6()
factories[IdeaSyncDetector.IdeaSyncDetectorVariantFactory::class] =
IdeaSyncDetectorG6.IdeaSyncDetectorVariantFactoryG6()
}
@@ -0,0 +1,22 @@
/*
* Copyright 2010-2022 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.plugin.internal
import org.gradle.api.Project
import org.gradle.api.provider.ProviderFactory
internal class IdeaSyncDetectorG6(private val providerFactory: ProviderFactory) : IdeaSyncDetector {
override val isInIdeaSync = createIdeaPropertiesEvaluator().isInIdeaSync()
override fun createIdeaPropertiesEvaluator() = object : IdeaPropertiesEvaluator() {
// we should declare system property read for Gradle < 7.4
override fun readSystemPropertyValue(key: String) = providerFactory.systemProperty(key).forUseAtConfigurationTime().orNull
}
internal class IdeaSyncDetectorVariantFactoryG6 : IdeaSyncDetector.IdeaSyncDetectorVariantFactory {
override fun getInstance(project: Project): IdeaSyncDetector = IdeaSyncDetectorG6(project.providers)
}
}