[Gradle][KMP] IdeJvmAndAndroidPlatformDependencyResolver: Do not filter ProjectDependencies

as this will result in losing transitive dependencies from said
project dependency.

KT-59020 is now fixed by detecting this case
before creating the 'IdeaKotlinUnresolvedBinaryDependency'

Caused by: KT-59020
^KT-62029 Verification Pending
This commit is contained in:
Sebastian Sellmair
2023-10-03 09:00:36 +02:00
committed by Space Team
parent 7e52aa7b00
commit 750ae2c850
4 changed files with 58 additions and 10 deletions
@@ -121,18 +121,33 @@ class IdeBinaryDependencyResolver @JvmOverloads constructor(
val unresolvedDependencies = artifacts.failures
.onEach { reason -> sourceSet.project.logger.info("Failed to resolve platform dependency on ${sourceSet.name}", reason) }
.map { reason ->
.mapNotNull { reason ->
val selector = (reason as? ModuleVersionResolveException)?.selector
val selector = (reason as? ModuleVersionResolveException)?.selector as? ModuleComponentSelector
/* Can't figure out the dependency here :( */
?: return@map IdeaKotlinUnresolvedBinaryDependency(
coordinates = null, cause = reason.message?.takeIf { it.isNotBlank() }, extras = mutableExtrasOf()
/* We failed to resolve a library module (e.g., from a remote repository) */
if (selector is ModuleComponentSelector)
return@mapNotNull IdeaKotlinUnresolvedBinaryDependency(
coordinates = IdeaKotlinBinaryCoordinates(selector.group, selector.module, selector.version, null),
cause = reason.message?.takeIf { it.isNotBlank() },
extras = mutableExtrasOf()
)
/*
We failed to resolve the same project as the SourceSet was declared to in a
'PlatformLikeSourceSet' mode: We ignore this error:
https://youtrack.jetbrains.com/issue/KT-59020/
It seems like 'detachedConfiguration' causes an issue resolving to its project.
*/
if (selector is ProjectComponentSelector &&
selector.projectPath == sourceSet.project.path &&
artifactResolutionStrategy is ArtifactResolutionStrategy.PlatformLikeSourceSet
) {
return@mapNotNull null
}
/* Can't figure out the dependency here :( */
IdeaKotlinUnresolvedBinaryDependency(
coordinates = IdeaKotlinBinaryCoordinates(selector.group, selector.module, selector.version, null),
cause = reason.message?.takeIf { it.isNotBlank() },
extras = mutableExtrasOf()
coordinates = null, cause = reason.message?.takeIf { it.isNotBlank() }, extras = mutableExtrasOf()
)
}.toSet()
@@ -45,8 +45,7 @@ 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 }, // paranoia: Only dependencyFilter should be OK
dependencyFilter = { dependency -> dependency !is ProjectDependency },
componentFilter = { identifier -> identifier !is ProjectComponentIdentifier },
dependencySubstitution = ::substituteStdlibCommonWithAndroidJvm,
)
)
@@ -56,10 +56,16 @@ internal object IdeJvmAndAndroidSourceDependencyResolver : IdeDependencyResolver
if (sourceSet !is DefaultKotlinSourceSet) return emptySet()
return sourceSet.resolveMetadata<MetadataDependencyResolution>()
/**
* Only care about project dependencies as this resolver tries to provide source dependencies
*/
.filter { metadataDependencyResolution -> metadataDependencyResolution.projectDependency(sourceSet.project) != null }
/**
* See [IdeVisibleMultiplatformSourceDependencyResolver] on why this could happen
*/
.filter { metadataDependencyResolution -> metadataDependencyResolution.projectDependency(sourceSet.project) != sourceSet.project }
.flatMap { metadataDependencyResolution ->
when (metadataDependencyResolution) {
@@ -198,6 +198,34 @@ class IdeJvmAndAndroidDependencyResolutionTest {
)
}
@Test
fun `test - KT-62029 - transitive dependencies form project dependency`() {
val root = buildProject { enableDefaultStdlibDependency(false) }
val producer = buildProject({ withName("producer").withParent(root) }) { configureAndroidAndMultiplatform() }
val consumer = buildProject({ withName("consumer").withParent(root) }) { configureAndroidAndMultiplatform() }
producer.multiplatformExtension.sourceSets.commonMain.dependencies {
api("org.jetbrains.kotlinx:kotlinx-coroutines-core:1.7.2")
}
consumer.multiplatformExtension.sourceSets.commonMain.dependencies {
implementation(producer)
}
root.evaluate()
producer.evaluate()
consumer.evaluate()
consumer.kotlinIdeMultiplatformImport.resolveDependencies("commonMain").assertMatches(
regularSourceDependency(":producer/commonMain"),
regularSourceDependency(":producer/jvmAndAndroidMain"),
binaryCoordinates(Regex(".*stdlib.*")),
binaryCoordinates(Regex("org.jetbrains:annotations.*")),
binaryCoordinates("org.jetbrains.kotlinx:kotlinx-coroutines-core-jvm:1.7.2")
)
}
@Test
fun `test - default stdlib with no other dependencies`() {
val project = buildProject { configureAndroidAndMultiplatform(enableDefaultStdlib = true) }