[Gradle] Implement IdeFriendSourceDependencyResolver & IdeVisibleMultiplatformSourceDependencyResolver

KT-55112
This commit is contained in:
Sebastian Sellmair
2022-11-23 15:01:10 +01:00
committed by Space Team
parent 30002e29d1
commit d935e41862
6 changed files with 214 additions and 0 deletions
@@ -22,9 +22,23 @@ fun ideSourceDependency(type: IdeaKotlinSourceDependency.Type, project: Project,
return IdeaKotlinSourceDependencyMatcher(type, project.path, sourceSetName)
}
fun ideSourceDependency(type: IdeaKotlinSourceDependency.Type, path: String): IdeaKotlinDependencyMatcher {
val segments = path.split(":")
val projectPath = segments.dropLast(1).joinToString(":")
val sourceSetName = segments.last()
return IdeaKotlinSourceDependencyMatcher(type, projectPath, sourceSetName)
}
fun regularSourceDependency(path: String) = ideSourceDependency(IdeaKotlinSourceDependency.Type.Regular, path)
fun friendSourceDependency(path: String) = ideSourceDependency(IdeaKotlinSourceDependency.Type.Friend, path)
fun dependsOnDependency(project: Project, sourceSetName: String) =
ideSourceDependency(IdeaKotlinSourceDependency.Type.DependsOn, project, sourceSetName)
fun dependsOnDependency(path: String) = ideSourceDependency(IdeaKotlinSourceDependency.Type.DependsOn, path)
fun binaryCoordinates(regex: Regex): IdeaKotlinDependencyMatcher {
return IdeaBinaryCoordinatesMatcher(regex)
}
@@ -20,6 +20,20 @@ fun IdeMultiplatformImport(extension: KotlinMultiplatformExtension): IdeMultipla
level = IdeMultiplatformImport.DependencyResolutionLevel.Default
)
registerDependencyResolver(
resolver = IdeFriendSourceDependencyResolver,
constraint = IdeMultiplatformImport.SourceSetConstraint.unconstrained,
phase = IdeMultiplatformImport.DependencyResolutionPhase.SourceDependencyResolution,
level = IdeMultiplatformImport.DependencyResolutionLevel.Default
)
registerDependencyResolver(
resolver = IdeVisibleMultiplatformSourceDependencyResolver,
constraint = IdeMultiplatformImport.SourceSetConstraint.unconstrained,
phase = IdeMultiplatformImport.DependencyResolutionPhase.SourceDependencyResolution,
level = IdeMultiplatformImport.DependencyResolutionLevel.Default
)
registerDependencyResolver(
resolver = IdeTransformedMetadataDependencyResolver,
constraint = IdeMultiplatformImport.SourceSetConstraint.isMetadata,
@@ -0,0 +1,33 @@
/*
* 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.ide.dependencyResolvers
import org.jetbrains.kotlin.gradle.idea.tcs.IdeaKotlinDependency
import org.jetbrains.kotlin.gradle.idea.tcs.IdeaKotlinSourceCoordinates
import org.jetbrains.kotlin.gradle.idea.tcs.IdeaKotlinSourceDependency
import org.jetbrains.kotlin.gradle.plugin.KotlinSourceSet
import org.jetbrains.kotlin.gradle.plugin.ide.IdeDependencyResolver
import org.jetbrains.kotlin.gradle.plugin.mpp.pm20.util.currentBuildId
import org.jetbrains.kotlin.gradle.plugin.sources.getVisibleSourceSetsFromAssociateCompilations
import org.jetbrains.kotlin.gradle.plugin.sources.project
import org.jetbrains.kotlin.tooling.core.mutableExtrasOf
object IdeFriendSourceDependencyResolver : IdeDependencyResolver {
override fun resolve(sourceSet: KotlinSourceSet): Set<IdeaKotlinDependency> {
return getVisibleSourceSetsFromAssociateCompilations(sourceSet).map { friendSourceSet ->
IdeaKotlinSourceDependency(
type = IdeaKotlinSourceDependency.Type.Friend,
extras = mutableExtrasOf(),
coordinates = IdeaKotlinSourceCoordinates(
buildId = friendSourceSet.project.currentBuildId().toString(),
projectPath = friendSourceSet.project.path,
projectName = friendSourceSet.project.name,
sourceSetName = friendSourceSet.name
)
)
}.toSet()
}
}
@@ -0,0 +1,47 @@
/*
* 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.ide.dependencyResolvers
import org.jetbrains.kotlin.gradle.idea.tcs.IdeaKotlinDependency
import org.jetbrains.kotlin.gradle.idea.tcs.IdeaKotlinSourceCoordinates
import org.jetbrains.kotlin.gradle.idea.tcs.IdeaKotlinSourceDependency
import org.jetbrains.kotlin.gradle.plugin.KotlinSourceSet
import org.jetbrains.kotlin.gradle.plugin.ide.IdeDependencyResolver
import org.jetbrains.kotlin.gradle.plugin.mpp.MetadataDependencyResolution
import org.jetbrains.kotlin.gradle.plugin.mpp.pm20.util.currentBuildId
import org.jetbrains.kotlin.gradle.plugin.sources.DefaultKotlinSourceSet
import org.jetbrains.kotlin.gradle.plugin.sources.KotlinDependencyScope.*
import org.jetbrains.kotlin.tooling.core.mutableExtrasOf
object IdeVisibleMultiplatformSourceDependencyResolver : IdeDependencyResolver {
override fun resolve(sourceSet: KotlinSourceSet): Set<IdeaKotlinDependency> {
if (sourceSet !is DefaultKotlinSourceSet) return emptySet()
return sourceSet.dependencyTransformations[API_SCOPE]?.metadataDependencyResolutions?.toList().orEmpty()
.plus(sourceSet.dependencyTransformations[IMPLEMENTATION_SCOPE]?.metadataDependencyResolutions?.toList().orEmpty())
.plus(sourceSet.dependencyTransformations[COMPILE_ONLY_SCOPE]?.metadataDependencyResolutions?.toList().orEmpty())
.filterIsInstance<MetadataDependencyResolution.ChooseVisibleSourceSets>()
.flatMap { resolution -> resolveSourceDependencies(resolution) }
.toSet()
}
private fun resolveSourceDependencies(
resolution: MetadataDependencyResolution.ChooseVisibleSourceSets
): Iterable<IdeaKotlinDependency> {
val project = resolution.projectDependency ?: return emptyList()
return resolution.allVisibleSourceSetNames.map { visibleSourceSetName ->
IdeaKotlinSourceDependency(
type = IdeaKotlinSourceDependency.Type.Regular,
extras = mutableExtrasOf(),
coordinates = IdeaKotlinSourceCoordinates(
buildId = project.currentBuildId().toString(),
projectPath = project.path,
projectName = project.name,
sourceSetName = visibleSourceSetName
)
)
}
}
}
@@ -0,0 +1,103 @@
/*
* 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.
*/
@file:Suppress("FunctionName")
package org.jetbrains.kotlin.gradle.ide
import org.jetbrains.kotlin.gradle.applyMultiplatformPlugin
import org.jetbrains.kotlin.gradle.buildProject
import org.jetbrains.kotlin.gradle.dsl.multiplatformExtension
import org.jetbrains.kotlin.gradle.enableDefaultStdlibDependency
import org.jetbrains.kotlin.gradle.idea.tcs.IdeaKotlinSourceDependency
import org.jetbrains.kotlin.gradle.idea.testFixtures.tcs.assertMatches
import org.jetbrains.kotlin.gradle.idea.testFixtures.tcs.dependsOnDependency
import org.jetbrains.kotlin.gradle.idea.testFixtures.tcs.friendSourceDependency
import org.jetbrains.kotlin.gradle.idea.testFixtures.tcs.regularSourceDependency
import org.jetbrains.kotlin.gradle.plugin.ide.kotlinIdeMultiplatformImport
import kotlin.test.Test
class IdeResolveSourceDependenciesTest {
@Test
fun `test - multiplatform to multiplatform - sample 0`() {
val root = buildProject()
val producer = buildProject({ withParent(root).withName("producer") }) {
enableDefaultStdlibDependency(false)
applyMultiplatformPlugin()
multiplatformExtension.apply {
targetHierarchy.default()
linuxX64()
linuxArm64()
jvm()
}
}
val consumer = buildProject({ withParent(root).withName("consumer") }) {
enableDefaultStdlibDependency(false)
applyMultiplatformPlugin()
multiplatformExtension.apply {
targetHierarchy.default()
linuxX64()
linuxArm64()
jvm()
sourceSets.getByName("commonMain").dependencies {
implementation(project(":producer"))
}
}
}
root.evaluate()
producer.evaluate()
consumer.evaluate()
fun resolveConsumerSourceSet(sourceSetName: String) = consumer.kotlinIdeMultiplatformImport
.resolveDependencies(consumer.multiplatformExtension.sourceSets.getByName(sourceSetName))
.filterIsInstance<IdeaKotlinSourceDependency>()
resolveConsumerSourceSet("commonMain").assertMatches(
regularSourceDependency(":producer:commonMain")
)
resolveConsumerSourceSet("nativeMain").assertMatches(
regularSourceDependency(":producer:commonMain"),
regularSourceDependency(":producer:nativeMain"),
regularSourceDependency(":producer:linuxMain"),
dependsOnDependency(":consumer:commonMain"),
)
resolveConsumerSourceSet("nativeTest").assertMatches(
regularSourceDependency(":producer:commonMain"),
regularSourceDependency(":producer:nativeMain"),
regularSourceDependency(":producer:linuxMain"),
friendSourceDependency(":consumer:commonMain"),
friendSourceDependency(":consumer:nativeMain"),
friendSourceDependency(":consumer:linuxMain"),
dependsOnDependency(":consumer:commonTest"),
)
resolveConsumerSourceSet("linuxMain").assertMatches(
regularSourceDependency(":producer:commonMain"),
regularSourceDependency(":producer:nativeMain"),
regularSourceDependency(":producer:linuxMain"),
dependsOnDependency(":consumer:commonMain"),
dependsOnDependency(":consumer:nativeMain"),
)
resolveConsumerSourceSet("linuxTest").assertMatches(
regularSourceDependency(":producer:commonMain"),
regularSourceDependency(":producer:nativeMain"),
regularSourceDependency(":producer:linuxMain"),
friendSourceDependency(":consumer:commonMain"),
friendSourceDependency(":consumer:nativeMain"),
friendSourceDependency(":consumer:linuxMain"),
dependsOnDependency(":consumer:commonTest"),
dependsOnDependency(":consumer:nativeTest"),
)
}
}
@@ -5,8 +5,11 @@
package org.jetbrains.kotlin.gradle.ide
import org.jetbrains.kotlin.gradle.idea.tcs.IdeaKotlinSourceDependency
import org.jetbrains.kotlin.gradle.idea.testFixtures.tcs.ideSourceDependency
import org.jetbrains.kotlin.gradle.plugin.KotlinSourceSet
import org.jetbrains.kotlin.gradle.plugin.sources.internal
import org.jetbrains.kotlin.gradle.plugin.sources.project
fun dependsOnDependency(sourceSet: KotlinSourceSet) =
org.jetbrains.kotlin.gradle.idea.testFixtures.tcs.dependsOnDependency(sourceSet.internal.project, sourceSet.name)