[MPP] KGP dependency resolution: JVM stdlib for JVM+Android source sets
KTIJ-24701
This commit is contained in:
committed by
Space Team
parent
0c33e89c02
commit
7dd438cb9e
+6
-1
@@ -7,6 +7,7 @@ package org.jetbrains.kotlin.gradle.plugin.ide.dependencyResolvers
|
||||
|
||||
import org.gradle.api.artifacts.ArtifactView
|
||||
import org.gradle.api.artifacts.Configuration
|
||||
import org.gradle.api.artifacts.DependencySubstitutions
|
||||
import org.gradle.api.artifacts.component.*
|
||||
import org.gradle.api.attributes.AttributeContainer
|
||||
import org.gradle.api.logging.Logger
|
||||
@@ -75,7 +76,8 @@ class IdeBinaryDependencyResolver(
|
||||
data class PlatformLikeSourceSet(
|
||||
internal val setupPlatformResolutionAttributes: AttributeContainer.(sourceSet: KotlinSourceSet) -> Unit,
|
||||
internal val setupArtifactViewAttributes: AttributeContainer.(sourceSet: KotlinSourceSet) -> Unit = {},
|
||||
internal val componentFilter: ((ComponentIdentifier) -> Boolean)? = null
|
||||
internal val componentFilter: ((ComponentIdentifier) -> Boolean)? = null,
|
||||
internal val dependencySubstitution: ((DependencySubstitutions) -> Unit)? = null,
|
||||
) : ArtifactResolutionStrategy()
|
||||
}
|
||||
|
||||
@@ -194,6 +196,9 @@ class IdeBinaryDependencyResolver(
|
||||
platformLikeCompileDependenciesConfiguration.attributes.setupPlatformResolutionAttributes(sourceSet)
|
||||
platformLikeCompileDependenciesConfiguration.dependencies.addAll(sourceSet.resolvableMetadataConfiguration.allDependencies)
|
||||
|
||||
if (dependencySubstitution != null)
|
||||
platformLikeCompileDependenciesConfiguration.resolutionStrategy.dependencySubstitution(dependencySubstitution)
|
||||
|
||||
return platformLikeCompileDependenciesConfiguration.incoming.artifactView { view ->
|
||||
view.isLenient = true
|
||||
view.attributes.setupArtifactViewAttributes(sourceSet)
|
||||
|
||||
+23
-1
@@ -8,11 +8,16 @@
|
||||
package org.jetbrains.kotlin.gradle.plugin.ide.dependencyResolvers
|
||||
|
||||
import org.gradle.api.Project
|
||||
import org.gradle.api.artifacts.DependencySubstitutions
|
||||
import org.gradle.api.artifacts.component.ModuleComponentSelector
|
||||
import org.gradle.api.artifacts.component.ProjectComponentIdentifier
|
||||
import org.gradle.api.attributes.Category
|
||||
import org.gradle.api.attributes.Usage
|
||||
import org.gradle.api.attributes.java.TargetJvmEnvironment
|
||||
import org.jetbrains.kotlin.gradle.idea.tcs.IdeaKotlinBinaryDependency
|
||||
import org.jetbrains.kotlin.gradle.internal.KOTLIN_ANDROID_JVM_STDLIB_MODULE_NAME
|
||||
import org.jetbrains.kotlin.gradle.internal.KOTLIN_MODULE_GROUP
|
||||
import org.jetbrains.kotlin.gradle.internal.KOTLIN_STDLIB_COMMON_MODULE_NAME
|
||||
import org.jetbrains.kotlin.gradle.plugin.KotlinPlatformType
|
||||
import org.jetbrains.kotlin.gradle.plugin.ide.IdeDependencyResolver
|
||||
import org.jetbrains.kotlin.gradle.plugin.usageByName
|
||||
@@ -39,6 +44,23 @@ internal fun IdeJvmAndAndroidPlatformBinaryDependencyResolver(project: Project):
|
||||
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 }
|
||||
componentFilter = { identifier -> identifier !is ProjectComponentIdentifier },
|
||||
dependencySubstitution = ::substituteStdlibCommonWithAndroidJvm,
|
||||
)
|
||||
)
|
||||
|
||||
/**
|
||||
* This is a replacement for propagation of stdlib-jvm in non-KGP-based IDE import for JVM+Android source sets.
|
||||
* It's possible to resolve regular dependencies of the source set with platform attributes to get the correct JVM variants.
|
||||
* But stdlib is a special case, kotlin-stdlib-common is not a common variant for the JVM stdlib w.r.t. publication.
|
||||
* Substituting kotlin-stdlib-common with the Android-JVM stdlib in requests workarounds the issue.
|
||||
*/
|
||||
internal fun substituteStdlibCommonWithAndroidJvm(dependencySubstitutions: DependencySubstitutions) {
|
||||
dependencySubstitutions.all { dependency ->
|
||||
val requested = dependency.requested
|
||||
if (requested is ModuleComponentSelector
|
||||
&& requested.group == KOTLIN_MODULE_GROUP
|
||||
&& requested.module == KOTLIN_STDLIB_COMMON_MODULE_NAME
|
||||
) dependency.useTarget("$KOTLIN_MODULE_GROUP:$KOTLIN_ANDROID_JVM_STDLIB_MODULE_NAME:${requested.version}")
|
||||
}
|
||||
}
|
||||
|
||||
+58
-6
@@ -10,7 +10,9 @@ package org.jetbrains.kotlin.gradle.dependencyResolutionTests.tcs
|
||||
import org.gradle.api.Project
|
||||
import org.jetbrains.kotlin.gradle.dependencyResolutionTests.mavenCentralCacheRedirector
|
||||
import org.jetbrains.kotlin.gradle.dsl.multiplatformExtension
|
||||
import org.jetbrains.kotlin.gradle.idea.tcs.IdeaKotlinResolvedBinaryDependency
|
||||
import org.jetbrains.kotlin.gradle.idea.testFixtures.tcs.*
|
||||
import org.jetbrains.kotlin.gradle.plugin.getKotlinPluginVersion
|
||||
import org.jetbrains.kotlin.gradle.plugin.ide.dependencyResolvers.IdeJvmAndAndroidPlatformBinaryDependencyResolver
|
||||
import org.jetbrains.kotlin.gradle.plugin.ide.kotlinIdeMultiplatformImport
|
||||
import org.jetbrains.kotlin.gradle.util.*
|
||||
@@ -25,13 +27,14 @@ class IdeJvmAndAndroidDependencyResolutionTest {
|
||||
assumeAndroidSdkAvailable()
|
||||
}
|
||||
|
||||
private fun Project.configureAndroidAndMultiplatform() {
|
||||
enableDefaultStdlibDependency(false)
|
||||
private fun Project.configureAndroidAndMultiplatform(enableDefaultStdlib: Boolean = false) {
|
||||
enableDefaultStdlibDependency(enableDefaultStdlib)
|
||||
enableDependencyVerification(false)
|
||||
setMultiplatformAndroidSourceSetLayoutVersion(2)
|
||||
applyMultiplatformPlugin()
|
||||
plugins.apply("com.android.library")
|
||||
androidExtension.compileSdkVersion(33)
|
||||
if (enableDefaultStdlib) repositories.mavenLocal()
|
||||
repositories.mavenCentralCacheRedirector()
|
||||
|
||||
project.multiplatformExtension.targetHierarchy.custom {
|
||||
@@ -48,9 +51,14 @@ class IdeJvmAndAndroidDependencyResolutionTest {
|
||||
|
||||
}
|
||||
|
||||
private fun Project.assertBinaryDependencies(sourceSetName: String, notation: Any) {
|
||||
project.kotlinIdeMultiplatformImport.resolveDependencies(sourceSetName).filterIsInstance<IdeaKotlinResolvedBinaryDependency>()
|
||||
.assertMatches(notation)
|
||||
}
|
||||
|
||||
@Test
|
||||
fun `test - MVIKotlin - on jvmAndAndroidMain`() {
|
||||
val project = buildProject { configureAndroidAndMultiplatform() }
|
||||
val project = buildProject { configureAndroidAndMultiplatform(enableDefaultStdlib = false) }
|
||||
val kotlin = project.multiplatformExtension
|
||||
kotlin.sourceSets.getByName("commonMain").dependencies {
|
||||
implementation("com.arkivanov.mvikotlin:mvikotlin:3.0.2")
|
||||
@@ -62,12 +70,10 @@ class IdeJvmAndAndroidDependencyResolutionTest {
|
||||
binaryCoordinates("com.arkivanov.mvikotlin:mvikotlin-jvm:3.0.2"),
|
||||
binaryCoordinates("com.arkivanov.essenty:lifecycle-jvm:0.4.2"),
|
||||
binaryCoordinates("com.arkivanov.essenty:instance-keeper-jvm:0.4.2"),
|
||||
binaryCoordinates("org.jetbrains.kotlin:kotlin-stdlib-jdk8:1.7.10"),
|
||||
binaryCoordinates("org.jetbrains.kotlin:kotlin-stdlib-jdk8:1.7.10"), // transitive
|
||||
binaryCoordinates("org.jetbrains.kotlin:kotlin-stdlib-jdk7:1.7.10"),
|
||||
binaryCoordinates("org.jetbrains.kotlin:kotlin-stdlib:1.7.10"),
|
||||
binaryCoordinates("org.jetbrains:annotations:13.0"),
|
||||
/* This resolver cannot differentiate between non-hmpp metadata libraries and platform libraries. This is OK */
|
||||
binaryCoordinates("org.jetbrains.kotlin:kotlin-stdlib-common:1.7.10")
|
||||
)
|
||||
|
||||
IdeJvmAndAndroidPlatformBinaryDependencyResolver(project).resolve(kotlin.sourceSets.getByName("jvmAndAndroidMain"))
|
||||
@@ -105,4 +111,50 @@ class IdeJvmAndAndroidDependencyResolutionTest {
|
||||
regularSourceDependency(":producer/jvmAndAndroidMain"),
|
||||
)
|
||||
}
|
||||
|
||||
@Test
|
||||
fun `test - default stdlib with no other dependencies`() {
|
||||
val project = buildProject { configureAndroidAndMultiplatform(enableDefaultStdlib = true) }
|
||||
project.evaluate()
|
||||
|
||||
val stdlibVersion = project.getKotlinPluginVersion()
|
||||
val stdlibDependencies = listOf(
|
||||
binaryCoordinates("org.jetbrains.kotlin:kotlin-stdlib:${stdlibVersion}"),
|
||||
binaryCoordinates("org.jetbrains.kotlin:kotlin-stdlib-jdk7:${stdlibVersion}"),
|
||||
binaryCoordinates("org.jetbrains.kotlin:kotlin-stdlib-jdk8:${stdlibVersion}"),
|
||||
binaryCoordinates("org.jetbrains:annotations:13.0"),
|
||||
)
|
||||
|
||||
project.assertBinaryDependencies("commonMain", stdlibDependencies)
|
||||
project.assertBinaryDependencies("jvmAndAndroidMain", stdlibDependencies)
|
||||
project.assertBinaryDependencies("commonTest", stdlibDependencies)
|
||||
project.assertBinaryDependencies("jvmAndAndroidTest", stdlibDependencies)
|
||||
}
|
||||
|
||||
@Test
|
||||
fun `test - MVIKotlin - binary dependencies - with stdlib enabled by default`() {
|
||||
val project = buildProject { configureAndroidAndMultiplatform(enableDefaultStdlib = true) }
|
||||
val kotlin = project.multiplatformExtension
|
||||
kotlin.sourceSets.getByName("commonMain").dependencies {
|
||||
implementation("com.arkivanov.mvikotlin:mvikotlin:3.0.2")
|
||||
}
|
||||
|
||||
project.evaluate()
|
||||
|
||||
val kgpVersion = project.getKotlinPluginVersion()
|
||||
val jvmAndAndroidDependencies = listOf(
|
||||
binaryCoordinates("com.arkivanov.mvikotlin:mvikotlin-jvm:3.0.2"),
|
||||
binaryCoordinates("com.arkivanov.essenty:lifecycle-jvm:0.4.2"),
|
||||
binaryCoordinates("com.arkivanov.essenty:instance-keeper-jvm:0.4.2"),
|
||||
binaryCoordinates("org.jetbrains.kotlin:kotlin-stdlib-jdk8:$kgpVersion"), // uplifted to plugin version
|
||||
binaryCoordinates("org.jetbrains.kotlin:kotlin-stdlib-jdk7:$kgpVersion"),
|
||||
binaryCoordinates("org.jetbrains.kotlin:kotlin-stdlib:$kgpVersion"),
|
||||
binaryCoordinates("org.jetbrains:annotations:13.0"),
|
||||
)
|
||||
|
||||
project.assertBinaryDependencies("commonMain", jvmAndAndroidDependencies)
|
||||
project.assertBinaryDependencies("jvmAndAndroidMain", jvmAndAndroidDependencies)
|
||||
project.assertBinaryDependencies("commonTest", jvmAndAndroidDependencies)
|
||||
project.assertBinaryDependencies("jvmAndAndroidTest", jvmAndAndroidDependencies)
|
||||
}
|
||||
}
|
||||
|
||||
+8
-6
@@ -13,6 +13,7 @@ import org.jetbrains.kotlin.gradle.idea.tcs.IdeaKotlinBinaryDependency
|
||||
import org.jetbrains.kotlin.gradle.idea.testFixtures.tcs.assertMatches
|
||||
import org.jetbrains.kotlin.gradle.idea.testFixtures.tcs.binaryCoordinates
|
||||
import org.jetbrains.kotlin.gradle.plugin.KotlinSourceSet
|
||||
import org.jetbrains.kotlin.gradle.plugin.getKotlinPluginVersion
|
||||
import org.jetbrains.kotlin.gradle.plugin.ide.dependencyResolvers.IdeTransformedMetadataDependencyResolver
|
||||
import org.jetbrains.kotlin.gradle.plugin.ide.kotlinIdeMultiplatformImport
|
||||
import org.jetbrains.kotlin.gradle.util.*
|
||||
@@ -98,19 +99,20 @@ class IdeTransformedMetadataDependencyResolverTest {
|
||||
fun KotlinSourceSet.binaryDependencies() =
|
||||
project.kotlinIdeMultiplatformImport.resolveDependencies(this).filterIsInstance<IdeaKotlinBinaryDependency>()
|
||||
|
||||
val kgpVersion = project.getKotlinPluginVersion()
|
||||
commonMain.binaryDependencies().assertMatches(
|
||||
binaryCoordinates("com.squareup.okio:okio-jvm:3.2.0"),
|
||||
binaryCoordinates("org.jetbrains.kotlin:kotlin-stdlib-jdk8:1.6.20"),
|
||||
binaryCoordinates("org.jetbrains.kotlin:kotlin-stdlib-jdk7:1.6.20"),
|
||||
binaryCoordinates("org.jetbrains.kotlin:kotlin-stdlib:1.6.20"),
|
||||
binaryCoordinates("org.jetbrains.kotlin:kotlin-stdlib-jdk8:$kgpVersion"),
|
||||
binaryCoordinates("org.jetbrains.kotlin:kotlin-stdlib-jdk7:$kgpVersion"),
|
||||
binaryCoordinates("org.jetbrains.kotlin:kotlin-stdlib:$kgpVersion"),
|
||||
binaryCoordinates("org.jetbrains:annotations:13.0"),
|
||||
)
|
||||
|
||||
commonTest.binaryDependencies().assertMatches(
|
||||
binaryCoordinates("com.squareup.okio:okio-jvm:3.2.0"),
|
||||
binaryCoordinates("org.jetbrains.kotlin:kotlin-stdlib-jdk8:1.6.20"),
|
||||
binaryCoordinates("org.jetbrains.kotlin:kotlin-stdlib-jdk7:1.6.20"),
|
||||
binaryCoordinates("org.jetbrains.kotlin:kotlin-stdlib:1.6.20"),
|
||||
binaryCoordinates("org.jetbrains.kotlin:kotlin-stdlib-jdk8:$kgpVersion"),
|
||||
binaryCoordinates("org.jetbrains.kotlin:kotlin-stdlib-jdk7:$kgpVersion"),
|
||||
binaryCoordinates("org.jetbrains.kotlin:kotlin-stdlib:$kgpVersion"),
|
||||
binaryCoordinates("org.jetbrains:annotations:13.0"),
|
||||
)
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user