[Gradle] Add IdeMultiplatformImportAction API
This API can be used to schedule actions/setup code that is only relevant for IDE sync. ^KT-56440 Verification Pending
This commit is contained in:
committed by
Space Team
parent
dada4a60bd
commit
4c7ad7eeb5
@@ -606,6 +606,7 @@ public abstract interface class org/jetbrains/kotlin/gradle/plugin/ide/IdeMultip
|
||||
public abstract fun registerDependencyResolver (Lorg/jetbrains/kotlin/gradle/plugin/ide/IdeDependencyResolver;Lorg/jetbrains/kotlin/gradle/plugin/ide/IdeMultiplatformImport$SourceSetConstraint;Lorg/jetbrains/kotlin/gradle/plugin/ide/IdeMultiplatformImport$DependencyResolutionPhase;Lorg/jetbrains/kotlin/gradle/plugin/ide/IdeMultiplatformImport$Priority;)V
|
||||
public abstract fun registerDependencyTransformer (Lorg/jetbrains/kotlin/gradle/plugin/ide/IdeDependencyTransformer;Lorg/jetbrains/kotlin/gradle/plugin/ide/IdeMultiplatformImport$SourceSetConstraint;Lorg/jetbrains/kotlin/gradle/plugin/ide/IdeMultiplatformImport$DependencyTransformationPhase;)V
|
||||
public abstract fun registerExtrasSerializationExtension (Lorg/jetbrains/kotlin/gradle/idea/serialize/IdeaKotlinExtrasSerializationExtension;)V
|
||||
public abstract fun registerImportAction (Lorg/jetbrains/kotlin/gradle/plugin/ide/IdeMultiplatformImportAction;)V
|
||||
public abstract fun resolveDependencies (Ljava/lang/String;)Ljava/util/Set;
|
||||
public abstract fun resolveDependencies (Lorg/jetbrains/kotlin/gradle/plugin/KotlinSourceSet;)Ljava/util/Set;
|
||||
public abstract fun resolveDependenciesSerialized (Ljava/lang/String;)Ljava/util/List;
|
||||
@@ -678,6 +679,11 @@ public final class org/jetbrains/kotlin/gradle/plugin/ide/IdeMultiplatformImport
|
||||
public final fun isSinglePlatformType ()Lorg/jetbrains/kotlin/gradle/plugin/ide/IdeMultiplatformImport$SourceSetConstraint;
|
||||
}
|
||||
|
||||
public abstract interface class org/jetbrains/kotlin/gradle/plugin/ide/IdeMultiplatformImportAction {
|
||||
public static final field Companion Lorg/jetbrains/kotlin/gradle/plugin/ide/IdeMultiplatformImportAction$Companion;
|
||||
public abstract fun prepareIdeImport (Lorg/gradle/api/Project;)V
|
||||
}
|
||||
|
||||
public final class org/jetbrains/kotlin/gradle/plugin/ide/IdeMultiplatformImportKt {
|
||||
public static final fun and (Lorg/jetbrains/kotlin/gradle/plugin/ide/IdeMultiplatformImport$SourceSetConstraint;Lorg/jetbrains/kotlin/gradle/plugin/ide/IdeMultiplatformImport$SourceSetConstraint;)Lorg/jetbrains/kotlin/gradle/plugin/ide/IdeMultiplatformImport$SourceSetConstraint;
|
||||
public static final fun not (Lorg/jetbrains/kotlin/gradle/plugin/ide/IdeMultiplatformImport$SourceSetConstraint;)Lorg/jetbrains/kotlin/gradle/plugin/ide/IdeMultiplatformImport$SourceSetConstraint;
|
||||
|
||||
+16
-1
@@ -15,10 +15,15 @@ import org.jetbrains.kotlin.gradle.dsl.multiplatformExtensionOrNull
|
||||
import org.jetbrains.kotlin.gradle.idea.serialize.IdeaKotlinExtrasSerializationExtension
|
||||
import org.jetbrains.kotlin.gradle.idea.serialize.IdeaKotlinExtrasSerializationExtensionBuilder
|
||||
import org.jetbrains.kotlin.gradle.idea.tcs.IdeaKotlinDependency
|
||||
import org.jetbrains.kotlin.gradle.plugin.*
|
||||
import org.jetbrains.kotlin.gradle.plugin.KotlinPlatformType
|
||||
import org.jetbrains.kotlin.gradle.plugin.KotlinPlatformType.*
|
||||
import org.jetbrains.kotlin.gradle.plugin.KotlinProjectSetupAction
|
||||
import org.jetbrains.kotlin.gradle.plugin.KotlinSourceSet
|
||||
import org.jetbrains.kotlin.gradle.plugin.KotlinTarget
|
||||
import org.jetbrains.kotlin.gradle.plugin.ide.IdeMultiplatformImport.Priority.Companion.high
|
||||
import org.jetbrains.kotlin.gradle.plugin.ide.IdeMultiplatformImport.Priority.Companion.low
|
||||
import org.jetbrains.kotlin.gradle.plugin.ide.IdeMultiplatformImport.Priority.Companion.normal
|
||||
import org.jetbrains.kotlin.gradle.plugin.ide.IdeMultiplatformImport.Priority.Companion.veryHigh
|
||||
import org.jetbrains.kotlin.gradle.plugin.ide.IdeMultiplatformImport.SourceSetConstraint
|
||||
import org.jetbrains.kotlin.gradle.plugin.mpp.KotlinNativeCompilation
|
||||
import org.jetbrains.kotlin.gradle.plugin.sources.internal
|
||||
@@ -118,6 +123,16 @@ interface IdeMultiplatformImport {
|
||||
extension: IdeaKotlinExtrasSerializationExtension,
|
||||
)
|
||||
|
||||
/**
|
||||
* Registers a [IdeMultiplatformImportAction] which will be invoked only if an IDE/Gradle sync (import) is running.
|
||||
* This action is guaranteed to run before the Kotlin Multiplatform Model is being built.
|
||||
* There is no 'guarantee' whether this action will be running during configuration phase or as a first step
|
||||
* of model building. This is considered an implementation detail.
|
||||
* For further details please read [IdeMultiplatformImportAction]
|
||||
*/
|
||||
@ExternalKotlinTargetApi
|
||||
fun registerImportAction(action: IdeMultiplatformImportAction)
|
||||
|
||||
/**
|
||||
* Any [IdeDependencyResolver] has to be registered for a given dependency resolution phase in which it participates
|
||||
* The resolution phases will be executed in the order of their enum's ordinal.
|
||||
|
||||
+56
@@ -0,0 +1,56 @@
|
||||
/*
|
||||
* Copyright 2010-2023 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.ide
|
||||
|
||||
import org.gradle.api.Project
|
||||
import org.jetbrains.kotlin.gradle.ExternalKotlinTargetApi
|
||||
import org.jetbrains.kotlin.gradle.internal.isInIdeaSync
|
||||
import org.jetbrains.kotlin.gradle.plugin.KotlinGradlePluginExtensionPoint
|
||||
import org.jetbrains.kotlin.gradle.plugin.KotlinPluginLifecycle
|
||||
import org.jetbrains.kotlin.gradle.plugin.KotlinProjectSetupCoroutine
|
||||
import org.jetbrains.kotlin.gradle.plugin.await
|
||||
|
||||
/**
|
||||
* Registers a generic action that shall only run when a Kotlin Multiplatform project is being imported into the IDE.
|
||||
* Note: For heavy workloads, please consider using the 'prepareKotlinIdeaImport' task infrastructure.
|
||||
* (e.g. by implementing [IdeDependencyResolver.WithBuildDependencies]) instead.
|
||||
*
|
||||
* Note: The *exact* time of execution is not guaranteed and can be considered an implementation detail, however
|
||||
* it is guaranteed that the action will be executed
|
||||
* - only during Gradle import
|
||||
* - before any Kotlin Multiplatform Model will be built
|
||||
*
|
||||
*
|
||||
* Example of registering an action:
|
||||
*
|
||||
* ```kotlin
|
||||
* kotlinExtension.createExternalKotlinTarget<MyExternalTarget> {
|
||||
* configureIdeImport {
|
||||
* registerImportAction {
|
||||
* println("Running ide import") // Will be executed during Gradle sync
|
||||
* }
|
||||
*
|
||||
* registerImportAction(MyIdeImportAction) // Will be executed during Gradle sync
|
||||
* }
|
||||
* }
|
||||
* ```
|
||||
*/
|
||||
@ExternalKotlinTargetApi
|
||||
fun interface IdeMultiplatformImportAction {
|
||||
fun prepareIdeImport(project: Project)
|
||||
|
||||
companion object {
|
||||
internal val extensionPoint = KotlinGradlePluginExtensionPoint<IdeMultiplatformImportAction>()
|
||||
}
|
||||
}
|
||||
|
||||
internal val IdeMultiplatformImportActionSetupAction = KotlinProjectSetupCoroutine {
|
||||
if (!isInIdeaSync) return@KotlinProjectSetupCoroutine
|
||||
KotlinPluginLifecycle.Stage.ReadyForExecution.await()
|
||||
IdeMultiplatformImportAction.extensionPoint[this].forEach { action ->
|
||||
action.prepareIdeImport(this)
|
||||
}
|
||||
}
|
||||
+4
@@ -127,6 +127,10 @@ internal class IdeMultiplatformImportImpl(
|
||||
registeredExtrasSerializationExtensions.add(extension)
|
||||
}
|
||||
|
||||
override fun registerImportAction(action: IdeMultiplatformImportAction) {
|
||||
IdeMultiplatformImportAction.extensionPoint.register(extension.project, action)
|
||||
}
|
||||
|
||||
private fun createDependencyResolver(): IdeDependencyResolver {
|
||||
return IdeDependencyResolver(
|
||||
DependencyResolutionPhase.values().map { phase -> createDependencyResolver(phase) }
|
||||
|
||||
+4
-43
@@ -7,63 +7,23 @@ package org.jetbrains.kotlin.gradle.plugin
|
||||
|
||||
import org.gradle.api.Project
|
||||
import org.jetbrains.kotlin.gradle.artifacts.*
|
||||
import org.jetbrains.kotlin.gradle.artifacts.KotlinJsKlibArtifact
|
||||
import org.jetbrains.kotlin.gradle.artifacts.KotlinJvmJarArtifact
|
||||
import org.jetbrains.kotlin.gradle.artifacts.KotlinNativeHostSpecificMetadataArtifact
|
||||
import org.jetbrains.kotlin.gradle.artifacts.KotlinNativeKlibArtifact
|
||||
import org.jetbrains.kotlin.gradle.artifacts.KotlinTargetArtifact
|
||||
import org.jetbrains.kotlin.gradle.dsl.*
|
||||
import org.jetbrains.kotlin.gradle.dsl.AndroidMainSourceSetConventionsChecker
|
||||
import org.jetbrains.kotlin.gradle.dsl.IosSourceSetConventionChecker
|
||||
import org.jetbrains.kotlin.gradle.dsl.PlatformSourceSetConventionsChecker
|
||||
import org.jetbrains.kotlin.gradle.dsl.multiplatformExtensionOrNull
|
||||
import org.jetbrains.kotlin.gradle.internal.CustomizeKotlinDependenciesSetupAction
|
||||
import org.jetbrains.kotlin.gradle.plugin.diagnostics.KotlinToolingDiagnosticsSetupAction
|
||||
import org.jetbrains.kotlin.gradle.plugin.diagnostics.KotlinGradleProjectChecker
|
||||
import org.jetbrains.kotlin.gradle.plugin.diagnostics.checkers.AndroidPluginWithoutAndroidTargetChecker
|
||||
import org.jetbrains.kotlin.gradle.plugin.diagnostics.checkers.AndroidSourceSetLayoutV1SourceSetsNotFoundChecker
|
||||
import org.jetbrains.kotlin.gradle.plugin.diagnostics.checkers.CommonMainOrTestWithDependsOnChecker
|
||||
import org.jetbrains.kotlin.gradle.plugin.diagnostics.checkers.DeprecatedKotlinNativeTargetsChecker
|
||||
import org.jetbrains.kotlin.gradle.plugin.diagnostics.checkers.DisabledCinteropCommonizationInHmppProjectChecker
|
||||
import org.jetbrains.kotlin.gradle.plugin.diagnostics.checkers.DisabledNativeTargetsChecker
|
||||
import org.jetbrains.kotlin.gradle.plugin.diagnostics.checkers.DuplicateSourceSetChecker
|
||||
import org.jetbrains.kotlin.gradle.plugin.diagnostics.checkers.ExperimentalTryNextUsageChecker
|
||||
import org.jetbrains.kotlin.gradle.plugin.diagnostics.checkers.IncorrectNativeDependenciesChecker
|
||||
import org.jetbrains.kotlin.gradle.plugin.diagnostics.checkers.InternalGradlePropertiesUsageChecker
|
||||
import org.jetbrains.kotlin.gradle.plugin.diagnostics.checkers.JsEnvironmentChecker
|
||||
import org.jetbrains.kotlin.gradle.plugin.diagnostics.checkers.KotlinSourceSetTreeDependsOnMismatchChecker
|
||||
import org.jetbrains.kotlin.gradle.plugin.diagnostics.checkers.KotlinTargetAlreadyDeclaredChecker
|
||||
import org.jetbrains.kotlin.gradle.plugin.diagnostics.checkers.MissingNativeStdlibChecker
|
||||
import org.jetbrains.kotlin.gradle.plugin.diagnostics.checkers.NoKotlinTargetsDeclaredChecker
|
||||
import org.jetbrains.kotlin.gradle.plugin.diagnostics.checkers.PreHmppDependenciesUsageChecker
|
||||
import org.jetbrains.kotlin.gradle.plugin.diagnostics.checkers.UnusedSourceSetsChecker
|
||||
import org.jetbrains.kotlin.gradle.plugin.diagnostics.checkers.WasmSourceSetsNotFoundChecker
|
||||
import org.jetbrains.kotlin.gradle.plugin.diagnostics.KotlinToolingDiagnosticsSetupAction
|
||||
import org.jetbrains.kotlin.gradle.plugin.diagnostics.checkers.*
|
||||
import org.jetbrains.kotlin.gradle.plugin.ide.IdeMultiplatformImportActionSetupAction
|
||||
import org.jetbrains.kotlin.gradle.plugin.ide.IdeMultiplatformImportSetupAction
|
||||
import org.jetbrains.kotlin.gradle.plugin.ide.IdeResolveDependenciesTaskSetupAction
|
||||
import org.jetbrains.kotlin.gradle.plugin.mpp.*
|
||||
import org.jetbrains.kotlin.gradle.plugin.mpp.GlobalProjectStructureMetadataStorageSetupAction
|
||||
import org.jetbrains.kotlin.gradle.plugin.mpp.KotlinMultiplatformTargetPresetAction
|
||||
import org.jetbrains.kotlin.gradle.plugin.mpp.MultiplatformPublishingSetupAction
|
||||
import org.jetbrains.kotlin.gradle.plugin.mpp.SyncLanguageSettingsWithKotlinExtensionSetupAction
|
||||
import org.jetbrains.kotlin.gradle.plugin.mpp.UserDefinedAttributesSetupAction
|
||||
import org.jetbrains.kotlin.gradle.plugin.mpp.apple.AddBuildListenerForXCodeSetupAction
|
||||
import org.jetbrains.kotlin.gradle.plugin.mpp.compilationImpl.*
|
||||
import org.jetbrains.kotlin.gradle.plugin.mpp.compilationImpl.KotlinCompilationProcessorSideEffect
|
||||
import org.jetbrains.kotlin.gradle.plugin.mpp.compilationImpl.KotlinCompilationSideEffect
|
||||
import org.jetbrains.kotlin.gradle.plugin.mpp.compilationImpl.KotlinCreateResourcesTaskSideEffect
|
||||
import org.jetbrains.kotlin.gradle.plugin.mpp.compilationImpl.KotlinCreateSourcesJarTaskSideEffect
|
||||
import org.jetbrains.kotlin.gradle.plugin.mpp.internal.DeprecatedMppGradlePropertiesMigrationSetupAction
|
||||
import org.jetbrains.kotlin.gradle.plugin.sources.KotlinMultiplatformSourceSetSetupAction
|
||||
import org.jetbrains.kotlin.gradle.plugin.sources.LanguageSettingsSetupAction
|
||||
import org.jetbrains.kotlin.gradle.plugin.statistics.MultiplatformBuildStatsReportSetupAction
|
||||
import org.jetbrains.kotlin.gradle.scripting.internal.ScriptingGradleSubpluginSetupAction
|
||||
import org.jetbrains.kotlin.gradle.targets.*
|
||||
import org.jetbrains.kotlin.gradle.targets.ConfigureBuildSideEffect
|
||||
import org.jetbrains.kotlin.gradle.targets.CreateArtifactsSideEffect
|
||||
import org.jetbrains.kotlin.gradle.targets.CreateDefaultCompilationsSideEffect
|
||||
import org.jetbrains.kotlin.gradle.targets.CreateTargetConfigurationsSideEffect
|
||||
import org.jetbrains.kotlin.gradle.targets.KotlinTargetSideEffect
|
||||
import org.jetbrains.kotlin.gradle.targets.NativeForwardImplementationToApiElementsSideEffect
|
||||
import org.jetbrains.kotlin.gradle.targets.js.npm.AddNpmDependencyExtensionProjectSetupAction
|
||||
import org.jetbrains.kotlin.gradle.targets.metadata.KotlinMetadataTargetSetupAction
|
||||
import org.jetbrains.kotlin.gradle.targets.native.ConfigureFrameworkExportSideEffect
|
||||
@@ -109,6 +69,7 @@ internal fun Project.registerKotlinPluginExtensions() {
|
||||
register(project, AddBuildListenerForXCodeSetupAction)
|
||||
register(project, CreateFatFrameworksSetupAction)
|
||||
register(project, KotlinRegisterCompilationArchiveTasksExtension)
|
||||
register(project, IdeMultiplatformImportActionSetupAction)
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
+82
@@ -0,0 +1,82 @@
|
||||
/*
|
||||
* Copyright 2010-2023 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.
|
||||
*/
|
||||
|
||||
@file:Suppress("FunctionName")
|
||||
|
||||
package org.jetbrains.kotlin.gradle.unitTests
|
||||
|
||||
import org.jetbrains.kotlin.gradle.dsl.multiplatformExtension
|
||||
import org.jetbrains.kotlin.gradle.plugin.ide.IdeMultiplatformImportAction
|
||||
import org.jetbrains.kotlin.gradle.util.applyMultiplatformPlugin
|
||||
import org.jetbrains.kotlin.gradle.util.buildProject
|
||||
import org.jetbrains.kotlin.gradle.util.buildProjectWithMPP
|
||||
import java.util.concurrent.atomic.AtomicBoolean
|
||||
import kotlin.test.Test
|
||||
import kotlin.test.assertFalse
|
||||
import kotlin.test.assertTrue
|
||||
import kotlin.test.fail
|
||||
|
||||
class IdeMultiplatformImportActionTest {
|
||||
|
||||
@Test
|
||||
fun `test - action is not launched when not in idea sync`() {
|
||||
val project = buildProjectWithMPP()
|
||||
/* Register arbitrary target */
|
||||
project.multiplatformExtension.jvm()
|
||||
|
||||
IdeMultiplatformImportAction.extensionPoint.register(project) {
|
||||
fail("This action is not expected to be executed")
|
||||
}
|
||||
|
||||
project.evaluate()
|
||||
}
|
||||
|
||||
@Test
|
||||
fun `test - action is launched in idea sync`() = runInIdeSyncMode {
|
||||
System.setProperty("idea.sync.active", "true")
|
||||
|
||||
val project = buildProject {
|
||||
applyMultiplatformPlugin()
|
||||
}
|
||||
|
||||
/* Register arbitrary target */
|
||||
project.multiplatformExtension.jvm()
|
||||
|
||||
val executedAction1 = AtomicBoolean(false)
|
||||
val executedAction2 = AtomicBoolean(false)
|
||||
|
||||
IdeMultiplatformImportAction.extensionPoint.register(project) {
|
||||
assertFalse(executedAction1.getAndSet(true))
|
||||
}
|
||||
|
||||
IdeMultiplatformImportAction.extensionPoint.register(project) {
|
||||
assertFalse(executedAction2.getAndSet(true))
|
||||
}
|
||||
|
||||
project.evaluate()
|
||||
assertTrue(executedAction1.get(), "Expected action 1 to be executed")
|
||||
assertTrue(executedAction2.get(), "Expected action 2 to be executed")
|
||||
}
|
||||
|
||||
/**
|
||||
* Will swap out the System property 'idea.sync.active' to emulate IDE sync.
|
||||
* This method will enter the 'System properties monitor' to block any other thread from reading
|
||||
* System properties while this [block] is executing
|
||||
*/
|
||||
private fun runInIdeSyncMode(block: () -> Unit) = synchronized(System.getProperties()) {
|
||||
val isIdeaSyncActiveKey = "idea.sync.active"
|
||||
val previousValue = System.getProperty(isIdeaSyncActiveKey)
|
||||
try {
|
||||
System.setProperty(isIdeaSyncActiveKey, "true")
|
||||
block()
|
||||
} finally {
|
||||
if (previousValue != null) {
|
||||
System.setProperty(isIdeaSyncActiveKey, previousValue)
|
||||
} else {
|
||||
System.clearProperty(isIdeaSyncActiveKey)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user