[Gradle] Fine-tune Jvm and Android ide dependency resolution
The binary dependency resolver shall only run for remote artifacts. Project to project dependencies shall be handled by the IdeJvmAndAndroidSourceDependencyResolver ^KT-55475 Verification Pending
This commit is contained in:
committed by
Space Team
parent
5dd1777624
commit
9f810116d3
+5
-5
@@ -7,10 +7,7 @@ package org.jetbrains.kotlin.gradle.plugin.ide.dependencyResolvers
|
|||||||
|
|
||||||
import org.gradle.api.artifacts.ArtifactView
|
import org.gradle.api.artifacts.ArtifactView
|
||||||
import org.gradle.api.artifacts.Configuration
|
import org.gradle.api.artifacts.Configuration
|
||||||
import org.gradle.api.artifacts.component.LibraryBinaryIdentifier
|
import org.gradle.api.artifacts.component.*
|
||||||
import org.gradle.api.artifacts.component.ModuleComponentIdentifier
|
|
||||||
import org.gradle.api.artifacts.component.ModuleComponentSelector
|
|
||||||
import org.gradle.api.artifacts.component.ProjectComponentIdentifier
|
|
||||||
import org.gradle.api.attributes.AttributeContainer
|
import org.gradle.api.attributes.AttributeContainer
|
||||||
import org.gradle.api.logging.Logger
|
import org.gradle.api.logging.Logger
|
||||||
import org.gradle.api.logging.Logging
|
import org.gradle.api.logging.Logging
|
||||||
@@ -18,7 +15,6 @@ import org.gradle.internal.component.local.model.OpaqueComponentArtifactIdentifi
|
|||||||
import org.gradle.internal.resolve.ModuleVersionResolveException
|
import org.gradle.internal.resolve.ModuleVersionResolveException
|
||||||
import org.jetbrains.kotlin.gradle.ExternalKotlinTargetApi
|
import org.jetbrains.kotlin.gradle.ExternalKotlinTargetApi
|
||||||
import org.jetbrains.kotlin.gradle.idea.tcs.*
|
import org.jetbrains.kotlin.gradle.idea.tcs.*
|
||||||
import org.jetbrains.kotlin.gradle.kpm.external.ExternalVariantApi
|
|
||||||
import org.jetbrains.kotlin.gradle.plugin.KotlinCompilation
|
import org.jetbrains.kotlin.gradle.plugin.KotlinCompilation
|
||||||
import org.jetbrains.kotlin.gradle.plugin.KotlinPlatformType
|
import org.jetbrains.kotlin.gradle.plugin.KotlinPlatformType
|
||||||
import org.jetbrains.kotlin.gradle.plugin.KotlinSourceSet
|
import org.jetbrains.kotlin.gradle.plugin.KotlinSourceSet
|
||||||
@@ -76,6 +72,7 @@ class IdeBinaryDependencyResolver(
|
|||||||
data class PlatformLikeSourceSet(
|
data class PlatformLikeSourceSet(
|
||||||
internal val setupPlatformResolutionAttributes: AttributeContainer.(sourceSet: KotlinSourceSet) -> Unit,
|
internal val setupPlatformResolutionAttributes: AttributeContainer.(sourceSet: KotlinSourceSet) -> Unit,
|
||||||
internal val setupArtifactViewAttributes: AttributeContainer.(sourceSet: KotlinSourceSet) -> Unit = {},
|
internal val setupArtifactViewAttributes: AttributeContainer.(sourceSet: KotlinSourceSet) -> Unit = {},
|
||||||
|
internal val componentFilter: ((ComponentIdentifier) -> Boolean)? = null
|
||||||
) : ArtifactResolutionStrategy()
|
) : ArtifactResolutionStrategy()
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -192,6 +189,9 @@ class IdeBinaryDependencyResolver(
|
|||||||
return platformLikeCompileDependenciesConfiguration.incoming.artifactView { view ->
|
return platformLikeCompileDependenciesConfiguration.incoming.artifactView { view ->
|
||||||
view.isLenient = true
|
view.isLenient = true
|
||||||
view.attributes.setupArtifactViewAttributes(sourceSet)
|
view.attributes.setupArtifactViewAttributes(sourceSet)
|
||||||
|
if (componentFilter != null) {
|
||||||
|
view.componentFilter(componentFilter)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
+7
@@ -8,6 +8,7 @@
|
|||||||
package org.jetbrains.kotlin.gradle.plugin.ide.dependencyResolvers
|
package org.jetbrains.kotlin.gradle.plugin.ide.dependencyResolvers
|
||||||
|
|
||||||
import org.gradle.api.Project
|
import org.gradle.api.Project
|
||||||
|
import org.gradle.api.artifacts.component.ProjectComponentIdentifier
|
||||||
import org.gradle.api.attributes.Category
|
import org.gradle.api.attributes.Category
|
||||||
import org.gradle.api.attributes.Usage
|
import org.gradle.api.attributes.Usage
|
||||||
import org.gradle.api.attributes.java.TargetJvmEnvironment
|
import org.gradle.api.attributes.java.TargetJvmEnvironment
|
||||||
@@ -33,5 +34,11 @@ internal fun IdeJvmAndAndroidPlatformBinaryDependencyResolver(project: Project):
|
|||||||
project.objects.named(TargetJvmEnvironment.STANDARD_JVM)
|
project.objects.named(TargetJvmEnvironment.STANDARD_JVM)
|
||||||
)
|
)
|
||||||
},
|
},
|
||||||
|
/*
|
||||||
|
Prevent this resolver from running against project dependencies:
|
||||||
|
Otherwise we would match the -jvm.jar from the dependency project which will result in
|
||||||
|
matching the jvmMain source set as well (which is undesired)
|
||||||
|
*/
|
||||||
|
componentFilter = { identifier -> identifier !is ProjectComponentIdentifier }
|
||||||
)
|
)
|
||||||
)
|
)
|
||||||
|
|||||||
+22
-4
@@ -9,29 +9,47 @@ import org.jetbrains.kotlin.gradle.dsl.multiplatformExtensionOrNull
|
|||||||
import org.jetbrains.kotlin.gradle.idea.tcs.IdeaKotlinDependency
|
import org.jetbrains.kotlin.gradle.idea.tcs.IdeaKotlinDependency
|
||||||
import org.jetbrains.kotlin.gradle.idea.tcs.IdeaKotlinSourceDependency
|
import org.jetbrains.kotlin.gradle.idea.tcs.IdeaKotlinSourceDependency
|
||||||
import org.jetbrains.kotlin.gradle.idea.tcs.IdeaKotlinSourceDependency.Type.Regular
|
import org.jetbrains.kotlin.gradle.idea.tcs.IdeaKotlinSourceDependency.Type.Regular
|
||||||
|
import org.jetbrains.kotlin.gradle.plugin.KotlinCompilation
|
||||||
import org.jetbrains.kotlin.gradle.plugin.KotlinPlatformType
|
import org.jetbrains.kotlin.gradle.plugin.KotlinPlatformType
|
||||||
import org.jetbrains.kotlin.gradle.plugin.KotlinSourceSet
|
import org.jetbrains.kotlin.gradle.plugin.KotlinSourceSet
|
||||||
import org.jetbrains.kotlin.gradle.plugin.ide.IdeDependencyResolver
|
import org.jetbrains.kotlin.gradle.plugin.ide.IdeDependencyResolver
|
||||||
|
import org.jetbrains.kotlin.gradle.plugin.ide.IdeMultiplatformImport.SourceSetConstraint.Companion.isJvmAndAndroid
|
||||||
import org.jetbrains.kotlin.gradle.plugin.ide.IdeaKotlinSourceCoordinates
|
import org.jetbrains.kotlin.gradle.plugin.ide.IdeaKotlinSourceCoordinates
|
||||||
|
import org.jetbrains.kotlin.gradle.plugin.mpp.KotlinJvmAndroidCompilation
|
||||||
import org.jetbrains.kotlin.gradle.plugin.mpp.MetadataDependencyResolution
|
import org.jetbrains.kotlin.gradle.plugin.mpp.MetadataDependencyResolution
|
||||||
|
import org.jetbrains.kotlin.gradle.plugin.mpp.isMain
|
||||||
import org.jetbrains.kotlin.gradle.plugin.sources.DefaultKotlinSourceSet
|
import org.jetbrains.kotlin.gradle.plugin.sources.DefaultKotlinSourceSet
|
||||||
|
import org.jetbrains.kotlin.gradle.plugin.sources.android.AndroidVariantType
|
||||||
|
import org.jetbrains.kotlin.gradle.plugin.sources.android.type
|
||||||
import org.jetbrains.kotlin.gradle.plugin.sources.internal
|
import org.jetbrains.kotlin.gradle.plugin.sources.internal
|
||||||
|
|
||||||
internal object IdeJvmAndAndroidSourceDependencyResolver : IdeDependencyResolver {
|
internal object IdeJvmAndAndroidSourceDependencyResolver : IdeDependencyResolver {
|
||||||
override fun resolve(sourceSet: KotlinSourceSet): Set<IdeaKotlinDependency> {
|
override fun resolve(sourceSet: KotlinSourceSet): Set<IdeaKotlinDependency> {
|
||||||
if (!sourceSet.isJvmAndAndroid) return emptySet()
|
if (!isJvmAndAndroid(sourceSet)) return emptySet()
|
||||||
if (sourceSet !is DefaultKotlinSourceSet) return emptySet()
|
if (sourceSet !is DefaultKotlinSourceSet) return emptySet()
|
||||||
return sourceSet.resolveMetadata<MetadataDependencyResolution.ChooseVisibleSourceSets>()
|
return sourceSet.resolveMetadata<MetadataDependencyResolution.ChooseVisibleSourceSets>()
|
||||||
.flatMap { chooseVisibleSourceSets ->
|
.flatMap { chooseVisibleSourceSets ->
|
||||||
val projectDependency = chooseVisibleSourceSets.projectDependency ?: return@flatMap emptyList<IdeaKotlinDependency>()
|
val projectDependency = chooseVisibleSourceSets.projectDependency ?: return@flatMap emptyList<IdeaKotlinDependency>()
|
||||||
val kotlin = projectDependency.multiplatformExtensionOrNull ?: return@flatMap emptyList<IdeaKotlinDependency>()
|
val kotlin = projectDependency.multiplatformExtensionOrNull ?: return@flatMap emptyList<IdeaKotlinDependency>()
|
||||||
kotlin.sourceSets
|
kotlin.sourceSets
|
||||||
.filter { sourceSet -> sourceSet.isJvmAndAndroid }
|
.filter { sourceSet -> isJvmAndAndroidMain(sourceSet) }
|
||||||
.map { sourceSet -> IdeaKotlinSourceDependency(type = Regular, coordinates = IdeaKotlinSourceCoordinates(sourceSet)) }
|
.map { sourceSet -> IdeaKotlinSourceDependency(type = Regular, coordinates = IdeaKotlinSourceCoordinates(sourceSet)) }
|
||||||
}
|
}
|
||||||
.toSet()
|
.toSet()
|
||||||
}
|
}
|
||||||
|
|
||||||
private val KotlinSourceSet.isJvmAndAndroid: Boolean
|
private fun isJvmAndAndroidMain(sourceSet: KotlinSourceSet): Boolean {
|
||||||
get() = internal.compilations.map { it.platformType }.toSet() == setOf(KotlinPlatformType.androidJvm, KotlinPlatformType.jvm)
|
if (!isJvmAndAndroid(sourceSet)) return false
|
||||||
|
return sourceSet.internal.compilations.filter { it.platformType != KotlinPlatformType.common }.all { compilation ->
|
||||||
|
isJvmMain(compilation) || isAndroidMain(compilation)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private fun isJvmMain(compilation: KotlinCompilation<*>): Boolean {
|
||||||
|
return compilation.platformType == KotlinPlatformType.jvm && compilation.isMain()
|
||||||
|
}
|
||||||
|
|
||||||
|
private fun isAndroidMain(compilation: KotlinCompilation<*>): Boolean {
|
||||||
|
return compilation is KotlinJvmAndroidCompilation && compilation.androidVariant.type == AndroidVariantType.Main
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
+42
-15
@@ -7,36 +7,36 @@
|
|||||||
|
|
||||||
package org.jetbrains.kotlin.gradle.ide
|
package org.jetbrains.kotlin.gradle.ide
|
||||||
|
|
||||||
|
import org.gradle.api.Project
|
||||||
import org.jetbrains.kotlin.gradle.*
|
import org.jetbrains.kotlin.gradle.*
|
||||||
import org.jetbrains.kotlin.gradle.dsl.multiplatformExtension
|
import org.jetbrains.kotlin.gradle.dsl.multiplatformExtension
|
||||||
import org.jetbrains.kotlin.gradle.idea.testFixtures.tcs.assertMatches
|
import org.jetbrains.kotlin.gradle.idea.testFixtures.tcs.assertMatches
|
||||||
import org.jetbrains.kotlin.gradle.idea.testFixtures.tcs.binaryCoordinates
|
import org.jetbrains.kotlin.gradle.idea.testFixtures.tcs.binaryCoordinates
|
||||||
|
import org.jetbrains.kotlin.gradle.idea.testFixtures.tcs.dependsOnDependency
|
||||||
|
import org.jetbrains.kotlin.gradle.idea.testFixtures.tcs.regularSourceDependency
|
||||||
import org.jetbrains.kotlin.gradle.kpm.idea.mavenCentralCacheRedirector
|
import org.jetbrains.kotlin.gradle.kpm.idea.mavenCentralCacheRedirector
|
||||||
import org.jetbrains.kotlin.gradle.plugin.ide.dependencyResolvers.IdeJvmAndAndroidPlatformBinaryDependencyResolver
|
import org.jetbrains.kotlin.gradle.plugin.ide.dependencyResolvers.IdeJvmAndAndroidPlatformBinaryDependencyResolver
|
||||||
|
import org.jetbrains.kotlin.gradle.plugin.ide.kotlinIdeMultiplatformImport
|
||||||
import org.jetbrains.kotlin.gradle.utils.androidExtension
|
import org.jetbrains.kotlin.gradle.utils.androidExtension
|
||||||
import kotlin.test.BeforeTest
|
import kotlin.test.BeforeTest
|
||||||
import kotlin.test.Test
|
import kotlin.test.Test
|
||||||
|
|
||||||
class IdeJvmAndAndroidPlatformDependencyResolverTest {
|
class IdeJvmAndAndroidDependencyResolutionTest {
|
||||||
|
|
||||||
@BeforeTest
|
@BeforeTest
|
||||||
fun checkEnvironment() {
|
fun checkEnvironment() {
|
||||||
assumeAndroidSdkAvailable()
|
assumeAndroidSdkAvailable()
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
private fun Project.configureAndroidAndMultiplatform() {
|
||||||
fun `test - MVIKotlin - on jvmAndAndroidMain`() {
|
enableDefaultStdlibDependency(false)
|
||||||
val project = buildProject {
|
enableDependencyVerification(false)
|
||||||
enableDefaultStdlibDependency(false)
|
applyMultiplatformPlugin()
|
||||||
enableDependencyVerification(false)
|
plugins.apply("com.android.library")
|
||||||
applyMultiplatformPlugin()
|
androidExtension.compileSdkVersion(33)
|
||||||
plugins.apply("com.android.library")
|
repositories.mavenCentralCacheRedirector()
|
||||||
androidExtension.compileSdkVersion(33)
|
|
||||||
repositories.mavenCentralCacheRedirector()
|
|
||||||
}
|
|
||||||
|
|
||||||
val kotlin = project.multiplatformExtension
|
project.multiplatformExtension.targetHierarchy.custom {
|
||||||
kotlin.targetHierarchy.custom {
|
|
||||||
common {
|
common {
|
||||||
group("jvmAndAndroid") {
|
group("jvmAndAndroid") {
|
||||||
anyJvm()
|
anyJvm()
|
||||||
@@ -45,9 +45,15 @@ class IdeJvmAndAndroidPlatformDependencyResolverTest {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
kotlin.jvm()
|
project.multiplatformExtension.jvm()
|
||||||
kotlin.android()
|
project.multiplatformExtension.android()
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
fun `test - MVIKotlin - on jvmAndAndroidMain`() {
|
||||||
|
val project = buildProject { configureAndroidAndMultiplatform() }
|
||||||
|
val kotlin = project.multiplatformExtension
|
||||||
kotlin.sourceSets.getByName("commonMain").dependencies {
|
kotlin.sourceSets.getByName("commonMain").dependencies {
|
||||||
implementation("com.arkivanov.mvikotlin:mvikotlin:3.0.2")
|
implementation("com.arkivanov.mvikotlin:mvikotlin:3.0.2")
|
||||||
}
|
}
|
||||||
@@ -72,4 +78,25 @@ class IdeJvmAndAndroidPlatformDependencyResolverTest {
|
|||||||
IdeJvmAndAndroidPlatformBinaryDependencyResolver(project).resolve(kotlin.sourceSets.getByName("jvmAndAndroidTest"))
|
IdeJvmAndAndroidPlatformBinaryDependencyResolver(project).resolve(kotlin.sourceSets.getByName("jvmAndAndroidTest"))
|
||||||
.assertMatches(jvmAndAndroidDependencies)
|
.assertMatches(jvmAndAndroidDependencies)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
fun `test - project to project dependency`() {
|
||||||
|
val root = buildProject()
|
||||||
|
val producer = buildProject({ withParent(root).withName("producer") }) { configureAndroidAndMultiplatform() }
|
||||||
|
val consumer = buildProject({ withParent(root).withName("consumer") }) { configureAndroidAndMultiplatform() }
|
||||||
|
|
||||||
|
root.evaluate()
|
||||||
|
producer.evaluate()
|
||||||
|
consumer.evaluate()
|
||||||
|
|
||||||
|
consumer.multiplatformExtension.sourceSets.getByName("commonMain").dependencies {
|
||||||
|
implementation(project(":producer"))
|
||||||
|
}
|
||||||
|
|
||||||
|
consumer.kotlinIdeMultiplatformImport.resolveDependencies("jvmAndAndroidMain").assertMatches(
|
||||||
|
dependsOnDependency(":consumer/commonMain"),
|
||||||
|
regularSourceDependency(":producer/commonMain"),
|
||||||
|
regularSourceDependency(":producer/jvmAndAndroidMain"),
|
||||||
|
)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
Reference in New Issue
Block a user