[Gradle] Implement IdeMultiplatformImport using new IdeaKotlinClasspath

^KT-55492 Verification Pending
This commit is contained in:
Sebastian Sellmair
2022-12-15 15:13:12 +01:00
committed by Space Team
parent 53c5444a7a
commit e32cff3b38
24 changed files with 273 additions and 214 deletions
@@ -7,7 +7,10 @@ package org.jetbrains.kotlin.gradle.idea.proto.tcs
import org.jetbrains.kotlin.gradle.idea.proto.classLoaderForBackwardsCompatibleClasses
import org.jetbrains.kotlin.gradle.idea.serialize.IdeaKotlinSerializationLogger
import org.jetbrains.kotlin.gradle.idea.tcs.*
import org.jetbrains.kotlin.gradle.idea.tcs.IdeaKotlinProjectArtifactDependency
import org.jetbrains.kotlin.gradle.idea.tcs.IdeaKotlinResolvedBinaryDependency
import org.jetbrains.kotlin.gradle.idea.tcs.IdeaKotlinSourceDependency
import org.jetbrains.kotlin.gradle.idea.tcs.IdeaKotlinUnresolvedBinaryDependency
import org.jetbrains.kotlin.gradle.idea.testFixtures.tcs.TestIdeaKotlinDependencySerializer
import org.jetbrains.kotlin.gradle.idea.testFixtures.tcs.TestIdeaKotlinInstances
import org.jetbrains.kotlin.gradle.idea.testFixtures.utils.copy
@@ -66,27 +69,6 @@ class IdeaKotlinDependencyBackwardsCompatibilityTest {
assertEquals(dependency.coordinates, deserializedCopied.coordinates)
assertEquals(dependency.extras, deserializedCopied.extras)
}
@Test
fun `test - empty classpath`() {
val classpath = TestIdeaKotlinInstances.emptyClasspath
val binary = TestIdeaKotlinDependencySerializer().serialize(classpath)
val deserialized = deserializeIdeaKotlinDependencyWithBackwardsCompatibleClasses(binary)
val copied = deserialized.copy<IdeaKotlinClasspath>()
assertEquals(classpath.toSet(), copied.toSet())
}
@Test
fun `test - simple classpath`() {
val classpath = TestIdeaKotlinInstances.simpleClasspath
val binary = TestIdeaKotlinDependencySerializer().serialize(classpath)
val deserialized = deserializeIdeaKotlinDependencyWithBackwardsCompatibleClasses(binary)
val copied = deserialized.copy<IdeaKotlinClasspath>()
assertEquals(classpath.toSet(), copied.toSet())
}
}
private fun deserializeIdeaKotlinDependencyWithBackwardsCompatibleClasses(project: ByteArray): Any {
@@ -335,6 +335,7 @@ public final class org/jetbrains/kotlin/gradle/idea/tcs/IdeaKotlinClasspath : ja
public fun add (Ljava/io/File;)Z
public synthetic fun add (Ljava/lang/Object;)Z
public fun addAll (Ljava/util/Collection;)Z
public final fun addAll (Lorg/jetbrains/kotlin/gradle/idea/tcs/IdeaKotlinClasspath;)Z
public fun clear ()V
public fun contains (Ljava/io/File;)Z
public final fun contains (Ljava/lang/Object;)Z
@@ -23,6 +23,10 @@ class IdeaKotlinClasspath private constructor(private val files: MutableSet<File
return files.add(normalise(element))
}
fun addAll(classpath: IdeaKotlinClasspath): Boolean {
return files.addAll(classpath.files)
}
override fun addAll(elements: Collection<File>): Boolean {
return files.addAll(elements.map(::normalise))
}
@@ -25,7 +25,6 @@ data class IdeaKotlinBinaryCoordinates(
}
}
@IdeaKotlinModel
data class IdeaKotlinProjectCoordinates(
val buildId: String,
val projectPath: String,
@@ -8,8 +8,8 @@ package org.jetbrains.kotlin.gradle
import org.gradle.util.GradleVersion
import org.jetbrains.kotlin.commonizer.CommonizerTarget
import org.jetbrains.kotlin.commonizer.identityString
import org.jetbrains.kotlin.gradle.idea.tcs.IdeaKotlinBinaryDependency
import org.jetbrains.kotlin.gradle.idea.tcs.IdeaKotlinDependency
import org.jetbrains.kotlin.gradle.idea.tcs.IdeaKotlinDependency.Companion.CLASSPATH_BINARY_TYPE
import org.jetbrains.kotlin.gradle.idea.tcs.IdeaKotlinResolvedBinaryDependency
import org.jetbrains.kotlin.gradle.idea.tcs.extras.isCommonized
import org.jetbrains.kotlin.gradle.idea.tcs.extras.isNativeDistribution
@@ -37,7 +37,7 @@ class MppIdeDependencyResolutionIT : KGPBaseTest() {
filterIsInstance<IdeaKotlinResolvedBinaryDependency>()
.filter { !it.isNativeStdlib }
.filter { it.isNativeDistribution }
.filter { it.binaryType == CLASSPATH_BINARY_TYPE }
.filter { it.binaryType == IdeaKotlinBinaryDependency.KOTLIN_COMPILE_BINARY_TYPE }
val nativeMainDependencies = dependencies["nativeMain"].filterNativePlatformDependencies()
val nativeTestDependencies = dependencies["nativeTest"].filterNativePlatformDependencies()
@@ -10,9 +10,7 @@ import org.gradle.api.Project
import org.gradle.api.file.FileCollection
import org.gradle.kotlin.dsl.getByType
import org.jetbrains.kotlin.gradle.android.AndroidKotlinSourceSet.Companion.android
import org.jetbrains.kotlin.gradle.idea.tcs.IdeaKotlinBinaryCoordinates
import org.jetbrains.kotlin.gradle.idea.tcs.IdeaKotlinDependency
import org.jetbrains.kotlin.gradle.idea.tcs.IdeaKotlinResolvedBinaryDependency
import org.jetbrains.kotlin.gradle.idea.tcs.*
import org.jetbrains.kotlin.gradle.plugin.KotlinSourceSet
import org.jetbrains.kotlin.gradle.plugin.ide.IdeDependencyResolver
import org.jetbrains.kotlin.tooling.core.mutableExtrasOf
@@ -25,13 +23,13 @@ internal fun Project.androidBootClasspath(): FileCollection {
internal class AndroidBootClasspathIdeDependencyResolver(private val project: Project) : IdeDependencyResolver {
override fun resolve(sourceSet: KotlinSourceSet): Set<IdeaKotlinDependency> {
if (sourceSet.android == null) return emptySet()
return project.androidBootClasspath().files.map { file ->
return setOf(
IdeaKotlinResolvedBinaryDependency(
binaryType = IdeaKotlinDependency.CLASSPATH_BINARY_TYPE,
binaryFile = file,
binaryType = IdeaKotlinBinaryDependency.KOTLIN_COMPILE_BINARY_TYPE,
classpath = IdeaKotlinClasspath(project.androidBootClasspath().files),
extras = mutableExtrasOf(),
coordinates = IdeaKotlinBinaryCoordinates("com.android", "sdk", "7.4")
)
}.toSet()
)
}
}
@@ -0,0 +1,70 @@
/*
* 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
import org.jetbrains.kotlin.gradle.idea.tcs.IdeaKotlinBinaryDependency
import org.jetbrains.kotlin.gradle.idea.tcs.IdeaKotlinDependency
import org.jetbrains.kotlin.gradle.idea.tcs.IdeaKotlinResolvedBinaryDependency
import org.jetbrains.kotlin.gradle.idea.tcs.extras.documentationClasspath
import org.jetbrains.kotlin.gradle.idea.tcs.extras.sourcesClasspath
import org.jetbrains.kotlin.gradle.plugin.KotlinSourceSet
import org.jetbrains.kotlin.gradle.plugin.ide.IdeDependencyResolver.Companion.DOCUMENTATION_BINARY_TYPE
import org.jetbrains.kotlin.gradle.plugin.ide.IdeDependencyResolver.Companion.SOURCES_BINARY_TYPE
fun interface IdeAdditionalArtifactResolver {
fun resolve(sourceSet: KotlinSourceSet, dependencies: Set<IdeaKotlinDependency>)
}
internal fun IdeDependencyResolver.withAdditionalArtifactResolver(resolver: IdeAdditionalArtifactResolver) =
IdeDependencyResolver { sourceSet ->
this@withAdditionalArtifactResolver.resolve(sourceSet).also { result ->
resolver.resolve(sourceSet, result)
}
}
internal fun IdeAdditionalArtifactResolver(resolvers: Iterable<IdeAdditionalArtifactResolver?>) =
IdeAdditionalArtifactResolver { sourceSet, dependencies ->
resolvers.forEach { resolver -> resolver?.resolve(sourceSet, dependencies) }
}
/**
* Creates an [IdeAdditionalArtifactResolver] from a given [IdeDependencyResolver]:
* Dependencies from the [IdeDependencyResolver] need to resolve sources and javadoc using
* the [SOURCES_BINARY_TYPE] or [DOCUMENTATION_BINARY_TYPE]
*/
fun IdeAdditionalArtifactResolver(resolver: IdeDependencyResolver) = IdeAdditionalArtifactResolver { sourceSet, dependencies ->
/*
Group already resolved dependencies by their coordinates (ignoring sourceSetName, since -sources.jar are not published
on a "per source set" level.)
*/
val dependenciesByCoordinates = dependencies.filterIsInstance<IdeaKotlinResolvedBinaryDependency>()
.filter { it.binaryType == IdeaKotlinBinaryDependency.KOTLIN_COMPILE_BINARY_TYPE }
.groupBy { it.coordinates?.copy(sourceSetName = null) }
/*
Use the passed resolver to resolve the -sources.jar and -javadoc jar dependencies as idea dependencies.
For each dependency, we will find the dependencies to add this artifacts by matching the coordinates.
*/
resolver.resolve(sourceSet).filterIsInstance<IdeaKotlinResolvedBinaryDependency>()
.filter { it.binaryType == SOURCES_BINARY_TYPE || it.binaryType == DOCUMENTATION_BINARY_TYPE }
.forEach forEachSourceOrDocumentationDependency@{ sourceOrDocumentationDependency ->
/* Find dependencies that match by coordinates and add the artifacts */
dependenciesByCoordinates[sourceOrDocumentationDependency.coordinates ?: return@forEachSourceOrDocumentationDependency]
.orEmpty().forEach forEachMatchedDependency@{ dependency ->
val classpath = when (sourceOrDocumentationDependency.binaryType) {
SOURCES_BINARY_TYPE -> dependency.sourcesClasspath
DOCUMENTATION_BINARY_TYPE -> dependency.documentationClasspath
else -> return@forEachMatchedDependency
}
classpath.addAll(dependency.classpath)
}
}
}
fun IdeDependencyResolver.asAdditionalArtifactResolver() = IdeAdditionalArtifactResolver(this)
@@ -26,6 +26,9 @@ fun interface IdeDependencyResolver {
}
companion object {
const val SOURCES_BINARY_TYPE = "SOURCES"
const val DOCUMENTATION_BINARY_TYPE = "DOCUMENTATION"
var IdeaKotlinDependency.resolvedBy: IdeDependencyResolver? by extrasReadWriteProperty("resolvedBy")
var IdeaKotlinDependency.gradleArtifact: ResolvedArtifactResult? by extrasReadWriteProperty("gradleArtifact")
}
@@ -15,9 +15,7 @@ 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.KotlinPlatformType.androidJvm
import org.jetbrains.kotlin.gradle.plugin.KotlinPlatformType.jvm
import org.jetbrains.kotlin.gradle.plugin.KotlinPlatformType.common
import org.jetbrains.kotlin.gradle.plugin.KotlinPlatformType.*
import org.jetbrains.kotlin.gradle.plugin.KotlinSourceSet
import org.jetbrains.kotlin.gradle.plugin.extraProperties
import org.jetbrains.kotlin.gradle.plugin.ide.IdeMultiplatformImport.DependencyResolutionLevel.Default
@@ -50,6 +48,14 @@ interface IdeMultiplatformImport {
level: DependencyResolutionLevel = Default,
)
@ExternalKotlinTargetApi
fun registerAdditionalArtifactResolver(
resolver: IdeAdditionalArtifactResolver,
constraint: SourceSetConstraint,
phase: AdditionalArtifactResolutionPhase,
level: AdditionalArtifactResolutionLevel = AdditionalArtifactResolutionLevel.Default
)
@ExternalKotlinTargetApi
fun registerDependencyTransformer(
transformer: IdeDependencyTransformer,
@@ -112,6 +118,16 @@ interface IdeMultiplatformImport {
Default, Overwrite
}
enum class AdditionalArtifactResolutionPhase {
PreAdditionalArtifactResolution,
SourcesAndJavadocArtifactResolution,
PostAdditionalArtifactResolution
}
enum class AdditionalArtifactResolutionLevel {
Default, Overwrite
}
/**
* Any [IdeDependencyResolver] has to be registered for a given transformation phase.
* The phases will be executed in the order of this enums ordinal.
@@ -10,7 +10,6 @@ import org.jetbrains.kotlin.gradle.plugin.PropertiesProvider.Companion.kotlinPro
import org.jetbrains.kotlin.gradle.plugin.ide.IdeMultiplatformImport.SourceSetConstraint
import org.jetbrains.kotlin.gradle.plugin.ide.dependencyResolvers.*
import org.jetbrains.kotlin.gradle.plugin.ide.dependencyTransformers.IdePlatformStdlibCommonDependencyFilter
import org.jetbrains.kotlin.gradle.plugin.ide.dependencyTransformers.UnusedSourcesAndDocumentationFilter
internal fun IdeMultiplatformImport(extension: KotlinProjectExtension): IdeMultiplatformImport {
return IdeMultiplatformImportImpl(extension).apply {
@@ -96,13 +95,6 @@ internal fun IdeMultiplatformImport(extension: KotlinProjectExtension): IdeMulti
level = IdeMultiplatformImport.DependencyResolutionLevel.Default
)
registerDependencyResolver(
resolver = IdeNativeStdlibSourcesResolver,
constraint = SourceSetConstraint.isNative,
phase = IdeMultiplatformImport.DependencyResolutionPhase.SourcesAndDocumentationResolution,
level = IdeMultiplatformImport.DependencyResolutionLevel.Default
)
registerDependencyResolver(
resolver = IdePlatformSourcesResolver(),
constraint = SourceSetConstraint.isSinglePlatformType,
@@ -110,19 +102,19 @@ internal fun IdeMultiplatformImport(extension: KotlinProjectExtension): IdeMulti
level = IdeMultiplatformImport.DependencyResolutionLevel.Default
)
registerDependencyResolver(
registerAdditionalArtifactResolver(
resolver = IdeMetadataSourcesResolver(),
constraint = !SourceSetConstraint.isSinglePlatformType,
phase = IdeMultiplatformImport.DependencyResolutionPhase.SourcesAndDocumentationResolution,
level = IdeMultiplatformImport.DependencyResolutionLevel.Default
phase = IdeMultiplatformImport.AdditionalArtifactResolutionPhase.SourcesAndJavadocArtifactResolution,
level = IdeMultiplatformImport.AdditionalArtifactResolutionLevel.Default
)
if (extension.project.kotlinPropertiesProvider.enableSlowIdeSourcesJarResolver) {
registerDependencyResolver(
registerAdditionalArtifactResolver(
resolver = IdeArtifactResolutionQuerySourcesAndDocumentationResolver,
constraint = SourceSetConstraint.unconstrained,
phase = IdeMultiplatformImport.DependencyResolutionPhase.SourcesAndDocumentationResolution,
level = IdeMultiplatformImport.DependencyResolutionLevel.Default
phase = IdeMultiplatformImport.AdditionalArtifactResolutionPhase.SourcesAndJavadocArtifactResolution,
level = IdeMultiplatformImport.AdditionalArtifactResolutionLevel.Default
)
}
@@ -132,12 +124,6 @@ internal fun IdeMultiplatformImport(extension: KotlinProjectExtension): IdeMulti
phase = IdeMultiplatformImport.DependencyTransformationPhase.DependencyFilteringPhase,
)
registerDependencyTransformer(
transformer = UnusedSourcesAndDocumentationFilter,
constraint = SourceSetConstraint.unconstrained,
phase = IdeMultiplatformImport.DependencyTransformationPhase.DependencyFilteringPhase
)
registerDependencyEffect(
effect = IdeDependencyLogger,
constraint = SourceSetConstraint.unconstrained
@@ -18,6 +18,7 @@ import org.jetbrains.kotlin.gradle.plugin.ide.IdeMultiplatformImport.*
import org.jetbrains.kotlin.gradle.plugin.ide.IdeMultiplatformImport.Companion.logger
import org.jetbrains.kotlin.tooling.core.Extras
import org.jetbrains.kotlin.utils.addToStdlib.measureTimeMillisWithResult
import kotlin.system.measureTimeMillis
internal class IdeMultiplatformImportImpl(
@@ -47,6 +48,7 @@ internal class IdeMultiplatformImportImpl(
}
private val registeredDependencyResolvers = mutableListOf<RegisteredDependencyResolver>()
private val registeredAdditionalArtifactResolvers = mutableListOf<RegisteredAdditionalArtifactResolver>()
private val registeredDependencyTransformers = mutableListOf<RegisteredDependencyTransformer>()
private val registeredDependencyEffects = mutableListOf<RegisteredDependencyEffect>()
private val registeredExtrasSerializationExtensions = mutableListOf<IdeaKotlinExtrasSerializationExtension>()
@@ -82,6 +84,20 @@ internal class IdeMultiplatformImportImpl(
)
}
@ExternalKotlinTargetApi
override fun registerAdditionalArtifactResolver(
resolver: IdeAdditionalArtifactResolver,
constraint: SourceSetConstraint,
phase: AdditionalArtifactResolutionPhase,
level: AdditionalArtifactResolutionLevel
) {
registeredAdditionalArtifactResolvers.add(
RegisteredAdditionalArtifactResolver(
extension.project.kotlinIdeMultiplatformImportStatistics, resolver, constraint, phase, level
)
)
}
@ExternalKotlinTargetApi
override fun registerDependencyEffect(effect: IdeDependencyEffect, constraint: SourceSetConstraint) {
registeredDependencyEffects.add(
@@ -95,9 +111,11 @@ internal class IdeMultiplatformImportImpl(
}
private fun createDependencyResolver(): IdeDependencyResolver {
return IdeDependencyResolver(DependencyResolutionPhase.values().map { phase ->
createDependencyResolver(phase)
}).withTransformer(createDependencyTransformer())
return IdeDependencyResolver(
DependencyResolutionPhase.values().map { phase -> createDependencyResolver(phase) }
)
.withAdditionalArtifactResolver(createAdditionalArtifactsResolver())
.withTransformer(createDependencyTransformer())
.withEffect(createDependencyEffect())
}
@@ -119,6 +137,25 @@ internal class IdeMultiplatformImportImpl(
emptySet()
}
private fun createAdditionalArtifactsResolver() = IdeAdditionalArtifactResolver(
AdditionalArtifactResolutionPhase.values().map { phase -> createAdditionalArtifactsResolver(phase) })
private fun createAdditionalArtifactsResolver(phase: AdditionalArtifactResolutionPhase) =
IdeAdditionalArtifactResolver resolve@{ sourceSet, dependencies ->
val applicableResolvers = registeredAdditionalArtifactResolvers
.filter { it.phase == phase }
.filter { it.constraint(sourceSet) }
.groupBy { it.level }
AdditionalArtifactResolutionLevel.values().reversed().forEach { level ->
val resolvers = applicableResolvers[level].orEmpty()
if (resolvers.isNotEmpty()) {
resolvers.forEach { resolver -> resolver.resolve(sourceSet, dependencies) }
return@resolve
}
}
}
private fun createDependencyTransformer(): IdeDependencyTransformer {
return IdeDependencyTransformer(DependencyTransformationPhase.values().map { phase ->
createDependencyTransformer(phase)
@@ -202,4 +239,18 @@ internal class IdeMultiplatformImportImpl(
}
}
}
private class RegisteredAdditionalArtifactResolver(
private val statistics: IdeMultiplatformImportStatistics,
private val resolver: IdeAdditionalArtifactResolver,
val constraint: SourceSetConstraint,
val phase: AdditionalArtifactResolutionPhase,
val level: AdditionalArtifactResolutionLevel
) : IdeAdditionalArtifactResolver {
override fun resolve(sourceSet: KotlinSourceSet, dependencies: Set<IdeaKotlinDependency>) {
runCatching { measureTimeMillis { resolver.resolve(sourceSet, dependencies) } }
.onFailure { logger.error("e: ${resolver::class.java.name} failed on ${IdeaKotlinSourceCoordinates(sourceSet)}", it) }
.onSuccess { statistics.addExecutionTime(resolver::class.java, it) }
}
}
}
@@ -7,17 +7,18 @@ package org.jetbrains.kotlin.gradle.plugin.ide.dependencyResolvers
import org.gradle.api.artifacts.Configuration
import org.gradle.api.artifacts.component.ModuleComponentIdentifier
import org.gradle.api.artifacts.result.ArtifactResolutionResult
import org.gradle.api.artifacts.result.ResolvedArtifactResult
import org.gradle.api.component.Artifact
import org.gradle.jvm.JvmLibrary
import org.gradle.language.base.artifact.SourcesArtifact
import org.gradle.language.java.artifact.JavadocArtifact
import org.jetbrains.kotlin.gradle.idea.tcs.IdeaKotlinDependency
import org.jetbrains.kotlin.gradle.idea.tcs.IdeaKotlinResolvedBinaryDependency
import org.jetbrains.kotlin.gradle.idea.tcs.extras.documentationClasspath
import org.jetbrains.kotlin.gradle.idea.tcs.extras.sourcesClasspath
import org.jetbrains.kotlin.gradle.idea.tcs.isKotlinCompileBinaryType
import org.jetbrains.kotlin.gradle.plugin.KotlinPlatformType
import org.jetbrains.kotlin.gradle.plugin.KotlinSourceSet
import org.jetbrains.kotlin.gradle.plugin.ide.IdeDependencyResolver
import org.jetbrains.kotlin.gradle.plugin.ide.IdeAdditionalArtifactResolver
import org.jetbrains.kotlin.gradle.plugin.ide.IdeaKotlinBinaryCoordinates
import org.jetbrains.kotlin.gradle.plugin.mpp.internal
import org.jetbrains.kotlin.gradle.plugin.mpp.resolvableMetadataConfiguration
@@ -32,8 +33,12 @@ import org.jetbrains.kotlin.gradle.plugin.sources.project
*
* cc Anton Lakotka, Sebastian Sellmair
*/
internal object IdeArtifactResolutionQuerySourcesAndDocumentationResolver : IdeDependencyResolver {
override fun resolve(sourceSet: KotlinSourceSet): Set<IdeaKotlinDependency> {
internal object IdeArtifactResolutionQuerySourcesAndDocumentationResolver : IdeAdditionalArtifactResolver {
override fun resolve(sourceSet: KotlinSourceSet, dependencies: Set<IdeaKotlinDependency>) {
val binaryDependencies = dependencies.filterIsInstance<IdeaKotlinResolvedBinaryDependency>()
.filter { dependency -> dependency.isKotlinCompileBinaryType }
.groupBy { dependency -> dependency.coordinates?.copy(sourceSetName = null) }
val project = sourceSet.project
val configuration = selectConfiguration(sourceSet)
val resolutionResult = project.dependencies.createArtifactResolutionQuery()
@@ -41,25 +46,29 @@ internal object IdeArtifactResolutionQuerySourcesAndDocumentationResolver : IdeD
.withArtifacts(JvmLibrary::class.java, SourcesArtifact::class.java, JavadocArtifact::class.java)
.execute()
return resolve(resolutionResult, SourcesArtifact::class.java, IdeaKotlinDependency.SOURCES_BINARY_TYPE) +
resolve(resolutionResult, JavadocArtifact::class.java, IdeaKotlinDependency.DOCUMENTATION_BINARY_TYPE)
}
val sourcesArtifacts = resolutionResult.resolvedComponents.flatMap { resolved ->
resolved.getArtifacts(SourcesArtifact::class.java).filterIsInstance<ResolvedArtifactResult>()
}
fun resolve(
resolutionResult: ArtifactResolutionResult, artifactType: Class<out Artifact>, binaryType: String
): Set<IdeaKotlinResolvedBinaryDependency> {
return resolutionResult.resolvedComponents.flatMap { resolved ->
resolved.getArtifacts(artifactType)
.filterIsInstance<ResolvedArtifactResult>()
.mapNotNull { artifact ->
val id = artifact.id.componentIdentifier as? ModuleComponentIdentifier ?: return@mapNotNull null
IdeaKotlinResolvedBinaryDependency(
coordinates = IdeaKotlinBinaryCoordinates(id),
binaryType = binaryType,
binaryFile = artifact.file
)
}
}.toSet()
sourcesArtifacts.forEach { artifact ->
val artifactId = artifact.id.componentIdentifier as? ModuleComponentIdentifier ?: return@forEach
val artifactCoordinates = IdeaKotlinBinaryCoordinates(artifactId)
binaryDependencies[artifactCoordinates]?.forEach { dependency ->
dependency.sourcesClasspath.add(artifact.file)
}
}
val javadocArtifacts = resolutionResult.resolvedComponents.flatMap { resolved ->
resolved.getArtifacts(JavadocArtifact::class.java).filterIsInstance<ResolvedArtifactResult>()
}
javadocArtifacts.forEach { artifact ->
val artifactId = artifact.id.componentIdentifier as? ModuleComponentIdentifier ?: return@forEach
val artifactCoordinates = IdeaKotlinBinaryCoordinates(artifactId)
binaryDependencies[artifactCoordinates]?.forEach { dependency ->
dependency.documentationClasspath.add(artifact.file)
}
}
}
private fun selectConfiguration(sourceSet: KotlinSourceSet): Configuration {
@@ -15,6 +15,7 @@ import org.gradle.internal.component.local.model.OpaqueComponentArtifactIdentifi
import org.gradle.internal.resolve.ModuleVersionResolveException
import org.jetbrains.kotlin.gradle.ExternalKotlinTargetApi
import org.jetbrains.kotlin.gradle.idea.tcs.*
import org.jetbrains.kotlin.gradle.idea.tcs.extras.artifactsClasspath
import org.jetbrains.kotlin.gradle.plugin.KotlinCompilation
import org.jetbrains.kotlin.gradle.plugin.KotlinPlatformType
import org.jetbrains.kotlin.gradle.plugin.KotlinSourceSet
@@ -36,7 +37,7 @@ import org.jetbrains.kotlin.tooling.core.mutableExtrasOf
@ExternalKotlinTargetApi
class IdeBinaryDependencyResolver(
private val binaryType: String = IdeaKotlinDependency.CLASSPATH_BINARY_TYPE,
private val binaryType: String = IdeaKotlinBinaryDependency.KOTLIN_COMPILE_BINARY_TYPE,
private val artifactResolutionStrategy: ArtifactResolutionStrategy = ArtifactResolutionStrategy.Compilation()
) : IdeDependencyResolver {
@@ -100,18 +101,17 @@ class IdeBinaryDependencyResolver(
is ProjectComponentIdentifier -> {
IdeaKotlinProjectArtifactDependency(
type = IdeaKotlinSourceDependency.Type.Regular,
coordinates = IdeaKotlinProjectArtifactCoordinates(
project = IdeaKotlinProjectCoordinates(componentId),
artifactFile = artifact.file
)
)
coordinates = IdeaKotlinProjectCoordinates(componentId)
).apply {
artifactsClasspath.add(artifact.file)
}
}
is ModuleComponentIdentifier -> {
IdeaKotlinResolvedBinaryDependency(
coordinates = IdeaKotlinBinaryCoordinates(componentId),
binaryType = binaryType,
binaryFile = artifact.file,
classpath = IdeaKotlinClasspath(artifact.file),
)
}
@@ -123,7 +123,7 @@ class IdeBinaryDependencyResolver(
module = componentId.libraryName,
version = null, sourceSetName = null
),
binaryFile = artifact.file
classpath = IdeaKotlinClasspath(artifact.file)
)
}
@@ -12,7 +12,7 @@ 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.IdeaKotlinDependency
import org.jetbrains.kotlin.gradle.idea.tcs.IdeaKotlinBinaryDependency
import org.jetbrains.kotlin.gradle.plugin.KotlinPlatformType
import org.jetbrains.kotlin.gradle.plugin.ide.IdeDependencyResolver
import org.jetbrains.kotlin.gradle.plugin.usageByName
@@ -23,7 +23,7 @@ import org.jetbrains.kotlin.gradle.utils.named
*/
internal fun IdeJvmAndAndroidPlatformBinaryDependencyResolver(project: Project): IdeDependencyResolver =
IdeBinaryDependencyResolver(
binaryType = IdeaKotlinDependency.CLASSPATH_BINARY_TYPE,
binaryType = IdeaKotlinBinaryDependency.KOTLIN_COMPILE_BINARY_TYPE,
artifactResolutionStrategy = IdeBinaryDependencyResolver.ArtifactResolutionStrategy.PlatformLikeSourceSet(
setupPlatformResolutionAttributes = {
attributes.attribute(Usage.USAGE_ATTRIBUTE, project.usageByName(Usage.JAVA_API))
@@ -9,14 +9,16 @@ package org.jetbrains.kotlin.gradle.plugin.ide.dependencyResolvers
import org.gradle.api.attributes.Category
import org.gradle.api.attributes.DocsType
import org.jetbrains.kotlin.gradle.idea.tcs.IdeaKotlinDependency
import org.jetbrains.kotlin.gradle.plugin.ide.IdeAdditionalArtifactResolver
import org.jetbrains.kotlin.gradle.plugin.ide.IdeDependencyResolver
import org.jetbrains.kotlin.gradle.plugin.ide.asAdditionalArtifactResolver
import org.jetbrains.kotlin.gradle.plugin.mpp.resolvableMetadataConfiguration
import org.jetbrains.kotlin.gradle.plugin.sources.internal
import org.jetbrains.kotlin.gradle.plugin.sources.project
import org.jetbrains.kotlin.gradle.utils.named
internal fun IdeMetadataSourcesResolver(): IdeBinaryDependencyResolver = IdeBinaryDependencyResolver(
binaryType = IdeaKotlinDependency.SOURCES_BINARY_TYPE,
internal fun IdeMetadataSourcesResolver(): IdeAdditionalArtifactResolver = IdeBinaryDependencyResolver(
binaryType = IdeDependencyResolver.SOURCES_BINARY_TYPE,
artifactResolutionStrategy = IdeBinaryDependencyResolver.ArtifactResolutionStrategy.ResolvableConfiguration(
configurationSelector = { it.internal.resolvableMetadataConfiguration },
setupArtifactViewAttributes = {
@@ -24,4 +26,4 @@ internal fun IdeMetadataSourcesResolver(): IdeBinaryDependencyResolver = IdeBina
attribute(DocsType.DOCS_TYPE_ATTRIBUTE, it.project.objects.named(DocsType.SOURCES))
}
)
)
).asAdditionalArtifactResolver()
@@ -9,15 +9,15 @@ import org.gradle.api.Project
import org.gradle.api.logging.Logger
import org.gradle.api.logging.Logging
import org.jetbrains.kotlin.commonizer.KonanDistribution
import org.jetbrains.kotlin.commonizer.sourcesDir
import org.jetbrains.kotlin.commonizer.stdlib
import org.jetbrains.kotlin.compilerRunner.konanHome
import org.jetbrains.kotlin.compilerRunner.konanVersion
import org.jetbrains.kotlin.gradle.idea.tcs.IdeaKotlinBinaryCoordinates
import org.jetbrains.kotlin.gradle.idea.tcs.IdeaKotlinDependency
import org.jetbrains.kotlin.gradle.idea.tcs.IdeaKotlinResolvedBinaryDependency
import org.jetbrains.kotlin.gradle.idea.tcs.*
import org.jetbrains.kotlin.gradle.idea.tcs.extras.isNativeDistribution
import org.jetbrains.kotlin.gradle.idea.tcs.extras.isNativeStdlib
import org.jetbrains.kotlin.gradle.idea.tcs.extras.klibExtra
import org.jetbrains.kotlin.gradle.idea.tcs.extras.sourcesClasspath
import org.jetbrains.kotlin.gradle.plugin.KotlinSourceSet
import org.jetbrains.kotlin.gradle.plugin.ide.IdeDependencyResolver
import org.jetbrains.kotlin.gradle.plugin.ide.KlibExtra
@@ -30,11 +30,12 @@ internal object IdeNativeStdlibDependencyResolver : IdeDependencyResolver {
private val logger: Logger = Logging.getLogger(IdeNativePlatformDependencyResolver::class.java)
override fun resolve(sourceSet: KotlinSourceSet): Set<IdeaKotlinDependency> {
val binaryFile = KonanDistribution(sourceSet.project.konanHome).stdlib
val konanDistribution = KonanDistribution(sourceSet.project.konanHome)
val stdlibFile = KonanDistribution(sourceSet.project.konanHome).stdlib
val klibExtra = try {
val kotlinLibrary = resolveSingleFileKlib(
libraryFile = File(binaryFile.absolutePath),
libraryFile = File(stdlibFile.absolutePath),
strategy = ToolingSingleFileKlibResolveStrategy
)
@@ -46,13 +47,17 @@ internal object IdeNativeStdlibDependencyResolver : IdeDependencyResolver {
return setOf(
IdeaKotlinResolvedBinaryDependency(
binaryType = IdeaKotlinDependency.CLASSPATH_BINARY_TYPE,
binaryFile = binaryFile,
binaryType = IdeaKotlinBinaryDependency.KOTLIN_COMPILE_BINARY_TYPE,
classpath = IdeaKotlinClasspath(stdlibFile),
coordinates = nativeStdlibCoordinates(sourceSet.project)
).apply {
this.isNativeDistribution = true
this.isNativeStdlib = true
this.klibExtra = klibExtra
this.sourcesClasspath += konanDistribution.sourcesDir.listFiles().orEmpty()
/* Ignore org.jetbrains.kotlinx. in this case */
.filter { file -> file.name.startsWith("kotlin") }
.ifEmpty { return emptySet() }
}
)
}
@@ -1,35 +0,0 @@
/*
* 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.commonizer.KonanDistribution
import org.jetbrains.kotlin.commonizer.sourcesDir
import org.jetbrains.kotlin.compilerRunner.konanHome
import org.jetbrains.kotlin.gradle.idea.tcs.IdeaKotlinDependency
import org.jetbrains.kotlin.gradle.idea.tcs.IdeaKotlinResolvedBinaryDependency
import org.jetbrains.kotlin.gradle.idea.tcs.extras.isNativeDistribution
import org.jetbrains.kotlin.gradle.idea.tcs.extras.isNativeStdlib
import org.jetbrains.kotlin.gradle.plugin.KotlinSourceSet
import org.jetbrains.kotlin.gradle.plugin.ide.IdeDependencyResolver
import org.jetbrains.kotlin.gradle.plugin.sources.project
internal object IdeNativeStdlibSourcesResolver : IdeDependencyResolver {
override fun resolve(sourceSet: KotlinSourceSet): Set<IdeaKotlinDependency> {
return KonanDistribution(sourceSet.project.konanHome).sourcesDir.listFiles().orEmpty()
/* Ignore org.jetbrains.kotlinx. in this case */
.filter { file -> file.name.startsWith("kotlin") }
.map { file ->
IdeaKotlinResolvedBinaryDependency(
binaryType = IdeaKotlinDependency.SOURCES_BINARY_TYPE,
binaryFile = file,
coordinates = IdeNativeStdlibDependencyResolver.nativeStdlibCoordinates(sourceSet.project)
).apply {
isNativeStdlib = true
isNativeDistribution = true
}
}.toSet()
}
}
@@ -6,6 +6,8 @@
package org.jetbrains.kotlin.gradle.plugin.ide.dependencyResolvers
import org.gradle.api.artifacts.component.ModuleComponentIdentifier
import org.jetbrains.kotlin.gradle.idea.tcs.IdeaKotlinBinaryDependency
import org.jetbrains.kotlin.gradle.idea.tcs.IdeaKotlinClasspath
import org.jetbrains.kotlin.gradle.idea.tcs.IdeaKotlinDependency
import org.jetbrains.kotlin.gradle.idea.tcs.IdeaKotlinResolvedBinaryDependency
import org.jetbrains.kotlin.gradle.plugin.KotlinSourceSet
@@ -30,8 +32,8 @@ internal object IdeOriginalMetadataDependencyResolver : IdeDependencyResolver {
return artifactsView.artifacts.mapNotNull { artifact ->
val moduleId = artifact.id.componentIdentifier as? ModuleComponentIdentifier ?: return@mapNotNull null
IdeaKotlinResolvedBinaryDependency(
binaryType = IdeaKotlinDependency.CLASSPATH_BINARY_TYPE,
binaryFile = artifact.file,
binaryType = IdeaKotlinBinaryDependency.KOTLIN_COMPILE_BINARY_TYPE,
classpath = IdeaKotlinClasspath(artifact.file),
coordinates = IdeaKotlinBinaryCoordinates(moduleId)
)
}.toSet()
@@ -9,12 +9,12 @@ package org.jetbrains.kotlin.gradle.plugin.ide.dependencyResolvers
import org.gradle.api.attributes.Category
import org.gradle.api.attributes.DocsType
import org.jetbrains.kotlin.gradle.idea.tcs.IdeaKotlinDependency
import org.jetbrains.kotlin.gradle.plugin.ide.IdeDependencyResolver
import org.jetbrains.kotlin.gradle.plugin.sources.project
import org.jetbrains.kotlin.gradle.utils.named
internal fun IdePlatformSourcesResolver(): IdeBinaryDependencyResolver = IdeBinaryDependencyResolver(
binaryType = IdeaKotlinDependency.SOURCES_BINARY_TYPE,
binaryType = IdeDependencyResolver.SOURCES_BINARY_TYPE,
artifactResolutionStrategy = IdeBinaryDependencyResolver.ArtifactResolutionStrategy.Compilation(
setupArtifactViewAttributes = {
attribute(Category.CATEGORY_ATTRIBUTE, it.project.objects.named(Category.DOCUMENTATION))
@@ -6,9 +6,7 @@
package org.jetbrains.kotlin.gradle.plugin.ide.dependencyResolvers
import org.gradle.api.artifacts.component.ProjectComponentIdentifier
import org.jetbrains.kotlin.gradle.idea.tcs.IdeaKotlinBinaryCoordinates
import org.jetbrains.kotlin.gradle.idea.tcs.IdeaKotlinDependency
import org.jetbrains.kotlin.gradle.idea.tcs.IdeaKotlinResolvedBinaryDependency
import org.jetbrains.kotlin.gradle.idea.tcs.*
import org.jetbrains.kotlin.gradle.plugin.KotlinSourceSet
import org.jetbrains.kotlin.gradle.plugin.ide.IdeDependencyResolver
import org.jetbrains.kotlin.gradle.plugin.mpp.MetadataDependencyResolution.ChooseVisibleSourceSets
@@ -42,8 +40,8 @@ internal object IdeTransformedMetadataDependencyResolver : IdeDependencyResolver
}
IdeaKotlinResolvedBinaryDependency(
binaryType = IdeaKotlinDependency.CLASSPATH_BINARY_TYPE,
binaryFile = metadataLibraryOutputFile,
binaryType = IdeaKotlinBinaryDependency.KOTLIN_COMPILE_BINARY_TYPE,
classpath = IdeaKotlinClasspath(metadataLibraryOutputFile),
extras = mutableExtrasOf(),
coordinates = IdeaKotlinBinaryCoordinates(
group = metadataProvider.moduleDependencyIdentifier.groupId ?: "",
@@ -11,7 +11,8 @@ import org.jetbrains.kotlin.commonizer.CommonizerTarget
import org.jetbrains.kotlin.commonizer.identityString
import org.jetbrains.kotlin.compilerRunner.konanVersion
import org.jetbrains.kotlin.gradle.idea.tcs.IdeaKotlinBinaryCoordinates
import org.jetbrains.kotlin.gradle.idea.tcs.IdeaKotlinDependency
import org.jetbrains.kotlin.gradle.idea.tcs.IdeaKotlinBinaryDependency
import org.jetbrains.kotlin.gradle.idea.tcs.IdeaKotlinClasspath
import org.jetbrains.kotlin.gradle.idea.tcs.IdeaKotlinResolvedBinaryDependency
import org.jetbrains.kotlin.gradle.idea.tcs.extras.isNativeDistribution
import org.jetbrains.kotlin.gradle.idea.tcs.extras.klibExtra
@@ -35,8 +36,8 @@ internal fun Project.resolveNativeDistributionLibraryForIde(
}
return IdeaKotlinResolvedBinaryDependency(
binaryType = IdeaKotlinDependency.CLASSPATH_BINARY_TYPE,
binaryFile = library,
binaryType = IdeaKotlinBinaryDependency.KOTLIN_COMPILE_BINARY_TYPE,
classpath = IdeaKotlinClasspath(library),
coordinates = IdeaKotlinBinaryCoordinates(
group = "org.jetbrains.kotlin.native",
module = resolvedLibrary.packageFqName ?: resolvedLibrary.shortName ?: resolvedLibrary.uniqueName,
@@ -1,48 +0,0 @@
/*
* 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.dependencyTransformers
import org.jetbrains.kotlin.gradle.idea.tcs.IdeaKotlinBinaryCoordinates
import org.jetbrains.kotlin.gradle.idea.tcs.IdeaKotlinDependency
import org.jetbrains.kotlin.gradle.idea.tcs.IdeaKotlinDependency.Companion.CLASSPATH_BINARY_TYPE
import org.jetbrains.kotlin.gradle.idea.tcs.IdeaKotlinDependency.Companion.DOCUMENTATION_BINARY_TYPE
import org.jetbrains.kotlin.gradle.idea.tcs.IdeaKotlinDependency.Companion.SOURCES_BINARY_TYPE
import org.jetbrains.kotlin.gradle.idea.tcs.IdeaKotlinResolvedBinaryDependency
import org.jetbrains.kotlin.gradle.plugin.KotlinSourceSet
import org.jetbrains.kotlin.gradle.plugin.ide.IdeDependencyTransformer
import org.jetbrains.kotlin.gradle.plugin.ide.dependencyResolvers.IdeArtifactResolutionQuerySourcesAndDocumentationResolver
/**
* Filters out -sources.jar and -javadoc.jar dependencies that are actually not necessary for the KotlinSourceSet:
* This counter-acts the fact that the [IdeArtifactResolutionQuerySourcesAndDocumentationResolver] is potentially "over-resolving" sources
* for multiplatform libraries.
*/
internal object UnusedSourcesAndDocumentationFilter : IdeDependencyTransformer {
override fun transform(sourceSet: KotlinSourceSet, dependencies: Set<IdeaKotlinDependency>): Set<IdeaKotlinDependency> {
val binaryDependencies = dependencies.filterIsInstance<IdeaKotlinResolvedBinaryDependency>()
val classpathBinaryCoordinates = binaryDependencies.filter { it.binaryType == CLASSPATH_BINARY_TYPE }
.mapNotNull { it.coordinates?.relevantString() }
.toSet()
val unusedDependencies = binaryDependencies.filter { it.binaryType in sourcesAndDocumentationBinaryTypes }
.filter { it.coordinates?.relevantString() !in classpathBinaryCoordinates }
.toSet()
return dependencies - unusedDependencies
}
private val sourcesAndDocumentationBinaryTypes = setOf(SOURCES_BINARY_TYPE, DOCUMENTATION_BINARY_TYPE)
/**
* This filter only works based upon group, module and version.
* We can consider the sourceSetName to be irrelevant, since we do not have -sources.jar published on a 'per source set' level.
*/
private fun IdeaKotlinBinaryCoordinates.relevantString(): String = "$group:$module:$version"
}
@@ -6,6 +6,7 @@
package org.jetbrains.kotlin.gradle.plugin.ide
import org.jetbrains.kotlin.gradle.InternalKotlinGradlePluginApi
import org.jetbrains.kotlin.gradle.idea.proto.tcs.IdeaKotlinClasspathSerializer
import org.jetbrains.kotlin.gradle.idea.serialize.IdeaKotlinBooleanExtrasSerializer
import org.jetbrains.kotlin.gradle.idea.serialize.IdeaKotlinExtrasSerializationExtension
import org.jetbrains.kotlin.gradle.idea.serialize.IdeaKotlinExtrasSerializer.Companion.javaIoSerializable
@@ -20,4 +21,7 @@ val kotlinExtrasSerialization = IdeaKotlinExtrasSerializationExtension {
register(isNativeDistributionKey, IdeaKotlinBooleanExtrasSerializer)
register(isNativeStdlibKey, IdeaKotlinBooleanExtrasSerializer)
register(isCommonizedKey, IdeaKotlinBooleanExtrasSerializer)
register(sourcesClasspathKey, IdeaKotlinClasspathSerializer)
register(documentationClasspathKey, IdeaKotlinClasspathSerializer)
register(projectArtifactsClasspathKey, IdeaKotlinClasspathSerializer)
}
@@ -13,7 +13,9 @@ import org.jetbrains.kotlin.gradle.dsl.multiplatformExtension
import org.jetbrains.kotlin.gradle.enableDefaultStdlibDependency
import org.jetbrains.kotlin.gradle.enableDependencyVerification
import org.jetbrains.kotlin.gradle.idea.tcs.IdeaKotlinResolvedBinaryDependency
import org.jetbrains.kotlin.gradle.idea.tcs.isSourcesBinaryType
import org.jetbrains.kotlin.gradle.idea.tcs.extras.documentationClasspathKey
import org.jetbrains.kotlin.gradle.idea.tcs.extras.sourcesClasspath
import org.jetbrains.kotlin.gradle.idea.tcs.extras.sourcesClasspathKey
import org.jetbrains.kotlin.gradle.idea.testFixtures.tcs.assertMatches
import org.jetbrains.kotlin.gradle.idea.testFixtures.tcs.binaryCoordinates
import org.jetbrains.kotlin.gradle.kpm.idea.mavenCentralCacheRedirector
@@ -57,36 +59,36 @@ class IdeSourcesAndDocumentationResolutionTest {
fun resolveDependencySources(sourceSet: KotlinSourceSet): List<IdeaKotlinResolvedBinaryDependency> =
project.kotlinIdeMultiplatformImport.resolveDependencies(sourceSet)
.filterIsInstance<IdeaKotlinResolvedBinaryDependency>()
.filter { it.isSourcesBinaryType }
.filter { it.sourcesClasspath.isNotEmpty() }
/* Check commonMain&commonTest */
run {
val expectedDependencies = listOf(
binaryCoordinates("com.arkivanov.mvikotlin:mvikotlin:3.0.2"),
binaryCoordinates("com.arkivanov.essenty:lifecycle:0.4.2"),
binaryCoordinates("com.arkivanov.essenty:instance-keeper:0.4.2"),
binaryCoordinates("com.arkivanov.mvikotlin:mvikotlin:3.0.2:commonMain"),
binaryCoordinates("com.arkivanov.essenty:lifecycle:0.4.2:commonMain"),
binaryCoordinates("com.arkivanov.essenty:instance-keeper:0.4.2:commonMain"),
)
val resolvedDependencies = resolveDependencySources(commonMain)
resolvedDependencies.assertMatches(expectedDependencies)
resolveDependencySources(commonTest).assertMatches(resolvedDependencies)
resolvedDependencies.assertFilesEndWith("-sources.jar")
resolvedDependencies.assertSourcesFilesEndWith("-sources.jar")
}
/* Check nativeMain&nativeTest */
run {
val expectedDependencies = listOf(
binaryCoordinates("com.arkivanov.mvikotlin:mvikotlin:3.0.2"),
binaryCoordinates("com.arkivanov.essenty:lifecycle:0.4.2"),
binaryCoordinates("com.arkivanov.essenty:instance-keeper:0.4.2"),
binaryCoordinates("com.arkivanov.mvikotlin:mvikotlin:3.0.2:commonMain"),
binaryCoordinates("com.arkivanov.mvikotlin:mvikotlin:3.0.2:jsNativeMain"),
binaryCoordinates("com.arkivanov.essenty:lifecycle:0.4.2:commonMain"),
binaryCoordinates("com.arkivanov.essenty:instance-keeper:0.4.2:commonMain"),
IdeNativeStdlibDependencyResolver.nativeStdlibCoordinates(project)
)
val resolvedDependencies = resolveDependencySources(nativeMain)
resolvedDependencies.assertMatches(expectedDependencies)
resolveDependencySources(nativeTest).assertMatches(resolvedDependencies)
resolvedDependencies.assertFilesEndWith("-sources.jar", "-sources.zip")
resolvedDependencies.assertSourcesFilesEndWith("-sources.jar", "-sources.zip")
}
/* Check linuxX64Main and linuxX64Test */
@@ -114,16 +116,25 @@ class IdeSourcesAndDocumentationResolutionTest {
val resolvedDependencies = resolveDependencySources(linuxX64Main)
resolvedDependencies.assertMatches(expectedDependencies)
resolveDependencySources(linuxX64Test).assertMatches(resolvedDependencies)
resolvedDependencies.assertFilesEndWith("-sources.jar", "-sources.zip")
resolveDependencySources(linuxX64Test).withSanitisedExtras().assertMatches(resolvedDependencies.withSanitisedExtras())
resolvedDependencies.assertSourcesFilesEndWith("-sources.jar", "-sources.zip")
}
}
}
private fun Iterable<IdeaKotlinResolvedBinaryDependency>.assertFilesEndWith(vararg suffixes: String) {
private fun Iterable<IdeaKotlinResolvedBinaryDependency>.withSanitisedExtras() = onEach { dependency ->
val keysToKeep = setOf(sourcesClasspathKey, documentationClasspathKey)
(dependency.extras.keys - keysToKeep).forEach { keyToRemove ->
dependency.extras.remove(keyToRemove)
}
}
private fun Iterable<IdeaKotlinResolvedBinaryDependency>.assertSourcesFilesEndWith(vararg suffixes: String) {
forEach { dependency ->
if (suffixes.none { suffix -> dependency.binaryFile.path.endsWith(suffix) }) {
fail("Expected binaryFile to end with one of ${suffixes.toList()}. Found: ${dependency.binaryFile}")
dependency.sourcesClasspath.forEach { sourcesFile ->
if (suffixes.none { suffix -> sourcesFile.path.endsWith(suffix) }) {
fail("Expected binaryFile to end with one of ${suffixes.toList()}. Found: ${sourcesFile}")
}
}
}
}
}