[Gradle] Implement IdeTransformedMetadataDependencyResolver
KT-54825
This commit is contained in:
committed by
Space Team
parent
687ccda3e8
commit
9771e57951
@@ -0,0 +1,52 @@
|
|||||||
|
syntax = "proto3";
|
||||||
|
|
||||||
|
package org.jetbrains.kotlin.gradle.idea.proto.generated.tcs;
|
||||||
|
import "proto_extras.proto";
|
||||||
|
option java_multiple_files = true;
|
||||||
|
|
||||||
|
message IdeaKotlinDependencyProto {
|
||||||
|
oneof dependency {
|
||||||
|
IdeaKotlinSourceDependencyProto source_dependency = 1;
|
||||||
|
IdeaKotlinResolvedBinaryDependencyProto resolved_binary_dependency = 2;
|
||||||
|
IdeaKotlinUnresolvedBinaryDependencyProto unresolved_binary_dependency = 3;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
message IdeaKotlinSourceDependencyProto {
|
||||||
|
enum Type {
|
||||||
|
REGULAR = 0;
|
||||||
|
FRIEND = 1;
|
||||||
|
DEPENDS_ON = 2;
|
||||||
|
}
|
||||||
|
|
||||||
|
optional IdeaExtrasProto extras = 1;
|
||||||
|
optional Type type = 2;
|
||||||
|
optional IdeaKotlinSourceCoordinatesProto coordinates = 3;
|
||||||
|
}
|
||||||
|
|
||||||
|
message IdeaKotlinUnresolvedBinaryDependencyProto {
|
||||||
|
optional IdeaExtrasProto extras = 1;
|
||||||
|
optional IdeaKotlinBinaryCoordinatesProto coordinates = 2;
|
||||||
|
optional string cause = 3;
|
||||||
|
}
|
||||||
|
|
||||||
|
message IdeaKotlinResolvedBinaryDependencyProto {
|
||||||
|
optional IdeaExtrasProto extras = 1;
|
||||||
|
optional IdeaKotlinBinaryCoordinatesProto coordinates = 2;
|
||||||
|
optional string binary_type = 3;
|
||||||
|
optional string binary_file = 4;
|
||||||
|
}
|
||||||
|
|
||||||
|
message IdeaKotlinBinaryCoordinatesProto {
|
||||||
|
optional string group = 1;
|
||||||
|
optional string module = 2;
|
||||||
|
optional string version = 3;
|
||||||
|
optional string source_set_name = 4;
|
||||||
|
}
|
||||||
|
|
||||||
|
message IdeaKotlinSourceCoordinatesProto {
|
||||||
|
optional string build_id = 1;
|
||||||
|
optional string project_path = 2;
|
||||||
|
optional string project_name = 3;
|
||||||
|
optional string source_set_name = 4;
|
||||||
|
}
|
||||||
+1
-1
@@ -14,7 +14,7 @@ import org.gradle.api.tasks.TaskProvider
|
|||||||
import org.jetbrains.kotlin.gradle.dsl.pm20Extension
|
import org.jetbrains.kotlin.gradle.dsl.pm20Extension
|
||||||
import org.jetbrains.kotlin.gradle.tasks.locateOrRegisterTask
|
import org.jetbrains.kotlin.gradle.tasks.locateOrRegisterTask
|
||||||
import org.jetbrains.kotlin.gradle.utils.doNotTrackStateCompat
|
import org.jetbrains.kotlin.gradle.utils.doNotTrackStateCompat
|
||||||
import org.jetbrains.kotlin.kpm.idea.proto.writeTo
|
import org.jetbrains.kotlin.gradle.idea.proto.kpm.writeTo
|
||||||
import java.io.ByteArrayOutputStream
|
import java.io.ByteArrayOutputStream
|
||||||
import java.io.ObjectOutputStream
|
import java.io.ObjectOutputStream
|
||||||
|
|
||||||
|
|||||||
+1
@@ -17,6 +17,7 @@ import org.jetbrains.kotlin.gradle.plugin.mpp.pm20.GradleKpmFragment
|
|||||||
import org.jetbrains.kotlin.gradle.plugin.mpp.pm20.GradleKpmFragmentGranularMetadataResolverFactory
|
import org.jetbrains.kotlin.gradle.plugin.mpp.pm20.GradleKpmFragmentGranularMetadataResolverFactory
|
||||||
import org.jetbrains.kotlin.gradle.plugin.mpp.pm20.GradleKpmModule.Companion.moduleName
|
import org.jetbrains.kotlin.gradle.plugin.mpp.pm20.GradleKpmModule.Companion.moduleName
|
||||||
import org.jetbrains.kotlin.gradle.plugin.mpp.pm20.toKpmModuleDependency
|
import org.jetbrains.kotlin.gradle.plugin.mpp.pm20.toKpmModuleDependency
|
||||||
|
import org.jetbrains.kotlin.gradle.plugin.mpp.read
|
||||||
|
|
||||||
internal class IdeaKpmMetadataBinaryDependencyResolver(
|
internal class IdeaKpmMetadataBinaryDependencyResolver(
|
||||||
private val fragmentGranularMetadataResolverFactory: GradleKpmFragmentGranularMetadataResolverFactory
|
private val fragmentGranularMetadataResolverFactory: GradleKpmFragmentGranularMetadataResolverFactory
|
||||||
|
|||||||
+1
@@ -138,6 +138,7 @@ interface IdeMultiplatformImport {
|
|||||||
companion object {
|
companion object {
|
||||||
val unconstrained = SourceSetConstraint { true }
|
val unconstrained = SourceSetConstraint { true }
|
||||||
val isNative = SourceSetConstraint { sourceSet -> isNativeSourceSet(sourceSet) }
|
val isNative = SourceSetConstraint { sourceSet -> isNativeSourceSet(sourceSet) }
|
||||||
|
val isMetadata = SourceSetConstraint { sourceSet -> sourceSet.internal.compilations.any { it is KotlinMetadataCompilation } }
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
+8
@@ -9,6 +9,7 @@ import org.jetbrains.kotlin.gradle.dsl.KotlinMultiplatformExtension
|
|||||||
import org.jetbrains.kotlin.gradle.idea.serialize.IdeaExtrasSerializer
|
import org.jetbrains.kotlin.gradle.idea.serialize.IdeaExtrasSerializer
|
||||||
import org.jetbrains.kotlin.gradle.kpm.idea.kotlinDebugKey
|
import org.jetbrains.kotlin.gradle.kpm.idea.kotlinDebugKey
|
||||||
import org.jetbrains.kotlin.gradle.plugin.ide.dependencyResolvers.IdeDependsOnDependencyResolver
|
import org.jetbrains.kotlin.gradle.plugin.ide.dependencyResolvers.IdeDependsOnDependencyResolver
|
||||||
|
import org.jetbrains.kotlin.gradle.plugin.ide.dependencyResolvers.IdeTransformedMetadataDependencyResolver
|
||||||
|
|
||||||
fun IdeMultiplatformImport(extension: KotlinMultiplatformExtension): IdeMultiplatformImport {
|
fun IdeMultiplatformImport(extension: KotlinMultiplatformExtension): IdeMultiplatformImport {
|
||||||
return IdeMultiplatformImportImpl(extension).apply {
|
return IdeMultiplatformImportImpl(extension).apply {
|
||||||
@@ -20,6 +21,13 @@ fun IdeMultiplatformImport(extension: KotlinMultiplatformExtension): IdeMultipla
|
|||||||
level = IdeMultiplatformImport.DependencyResolutionLevel.Default
|
level = IdeMultiplatformImport.DependencyResolutionLevel.Default
|
||||||
)
|
)
|
||||||
|
|
||||||
|
registerDependencyResolver(
|
||||||
|
resolver = IdeTransformedMetadataDependencyResolver,
|
||||||
|
constraint = IdeMultiplatformImport.SourceSetConstraint.isMetadata,
|
||||||
|
phase = IdeMultiplatformImport.DependencyResolutionPhase.BinaryDependencyResolution,
|
||||||
|
level = IdeMultiplatformImport.DependencyResolutionLevel.Default
|
||||||
|
)
|
||||||
|
|
||||||
registerExtrasSerializationExtension {
|
registerExtrasSerializationExtension {
|
||||||
register(kotlinDebugKey, IdeaExtrasSerializer.javaIoSerializable())
|
register(kotlinDebugKey, IdeaExtrasSerializer.javaIoSerializable())
|
||||||
}
|
}
|
||||||
|
|||||||
+64
@@ -0,0 +1,64 @@
|
|||||||
|
/*
|
||||||
|
* 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.IdeaKotlinBinaryCoordinates
|
||||||
|
import org.jetbrains.kotlin.gradle.idea.tcs.IdeaKotlinDependency
|
||||||
|
import org.jetbrains.kotlin.gradle.idea.tcs.IdeaKotlinResolvedBinaryDependency
|
||||||
|
import org.jetbrains.kotlin.gradle.plugin.KotlinSourceSet
|
||||||
|
import org.jetbrains.kotlin.gradle.plugin.ide.IdeDependencyResolver
|
||||||
|
import org.jetbrains.kotlin.gradle.plugin.mpp.MetadataDependencyResolution.ChooseVisibleSourceSets
|
||||||
|
import org.jetbrains.kotlin.gradle.plugin.mpp.MetadataDependencyResolution.ChooseVisibleSourceSets.MetadataProvider.ArtifactMetadataProvider
|
||||||
|
import org.jetbrains.kotlin.gradle.plugin.mpp.kotlinTransformedMetadataLibraryDirectoryForIde
|
||||||
|
import org.jetbrains.kotlin.gradle.plugin.mpp.read
|
||||||
|
import org.jetbrains.kotlin.gradle.plugin.sources.DefaultKotlinSourceSet
|
||||||
|
import org.jetbrains.kotlin.gradle.plugin.sources.KotlinDependencyScope.*
|
||||||
|
import org.jetbrains.kotlin.gradle.plugin.sources.internal
|
||||||
|
import org.jetbrains.kotlin.tooling.core.mutableExtrasOf
|
||||||
|
|
||||||
|
internal object IdeTransformedMetadataDependencyResolver : 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<ChooseVisibleSourceSets>()
|
||||||
|
.flatMap { resolution -> resolve(sourceSet, resolution) }
|
||||||
|
.toSet()
|
||||||
|
}
|
||||||
|
|
||||||
|
private fun resolve(sourceSet: KotlinSourceSet, resolution: ChooseVisibleSourceSets): Iterable<IdeaKotlinDependency> {
|
||||||
|
val metadataProvider = resolution.metadataProvider as? ArtifactMetadataProvider ?: return emptySet()
|
||||||
|
|
||||||
|
return metadataProvider.read { artifactContent ->
|
||||||
|
resolution.allVisibleSourceSetNames.mapNotNull { visibleSourceSet ->
|
||||||
|
val sourceSetContent = artifactContent.findSourceSet(visibleSourceSet) ?: return@mapNotNull null
|
||||||
|
val sourceSetMetadataBinary = sourceSetContent.metadataBinary ?: return@mapNotNull null
|
||||||
|
|
||||||
|
val metadataLibraryOutputFile = sourceSet.internal.project.kotlinTransformedMetadataLibraryDirectoryForIde
|
||||||
|
.resolve(sourceSetMetadataBinary.relativeFile)
|
||||||
|
|
||||||
|
metadataLibraryOutputFile.parentFile.mkdirs()
|
||||||
|
if (!metadataLibraryOutputFile.exists()) {
|
||||||
|
sourceSetMetadataBinary.copyTo(metadataLibraryOutputFile)
|
||||||
|
if (!metadataLibraryOutputFile.exists()) return@mapNotNull null
|
||||||
|
}
|
||||||
|
|
||||||
|
IdeaKotlinResolvedBinaryDependency(
|
||||||
|
binaryType = IdeaKotlinDependency.CLASSPATH_BINARY_TYPE,
|
||||||
|
binaryFile = metadataLibraryOutputFile,
|
||||||
|
extras = mutableExtrasOf(),
|
||||||
|
coordinates = IdeaKotlinBinaryCoordinates(
|
||||||
|
group = metadataProvider.moduleDependencyIdentifier.groupId ?: "",
|
||||||
|
module = metadataProvider.moduleDependencyIdentifier.moduleId,
|
||||||
|
version = metadataProvider.moduleDependencyVersion,
|
||||||
|
sourceSetName = visibleSourceSet
|
||||||
|
)
|
||||||
|
)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
+7
-8
@@ -21,16 +21,15 @@ internal interface CompositeMetadataArtifact {
|
|||||||
* Alternatively use the [read] function instead.
|
* Alternatively use the [read] function instead.
|
||||||
*/
|
*/
|
||||||
fun open(): CompositeMetadataArtifactContent
|
fun open(): CompositeMetadataArtifactContent
|
||||||
|
|
||||||
/**
|
|
||||||
* Safe shortcut function for opening and reading the content of this artifact.
|
|
||||||
* The [CompositeMetadataArtifactContent] will be closed after the [action] executed.
|
|
||||||
*/
|
|
||||||
fun <T> read(action: (artifactContent: CompositeMetadataArtifactContent) -> T): T {
|
|
||||||
return open().use(action)
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Safe shortcut function for opening and reading the content of this artifact.
|
||||||
|
* The [CompositeMetadataArtifactContent] will be closed after the [action] executed.
|
||||||
|
*/
|
||||||
|
internal inline fun <T> CompositeMetadataArtifact.read(action: (artifactContent: CompositeMetadataArtifactContent) -> T): T {
|
||||||
|
return open().use(action)
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* This [CompositeMetadataArtifactContent] abstraction provides access into a metadata artifact published by a Multiplatform Library
|
* This [CompositeMetadataArtifactContent] abstraction provides access into a metadata artifact published by a Multiplatform Library
|
||||||
|
|||||||
+62
@@ -0,0 +1,62 @@
|
|||||||
|
/*
|
||||||
|
* 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.*
|
||||||
|
import org.jetbrains.kotlin.gradle.dsl.multiplatformExtension
|
||||||
|
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
|
||||||
|
import org.jetbrains.kotlin.gradle.plugin.ide.dependencyResolvers.IdeTransformedMetadataDependencyResolver
|
||||||
|
import org.junit.Test
|
||||||
|
|
||||||
|
class IdeTransformedMetadataDependencyResolverTest {
|
||||||
|
|
||||||
|
@Test
|
||||||
|
fun `test - MVIKotlin`() {
|
||||||
|
val project = buildProject {
|
||||||
|
enableDefaultStdlibDependency(false)
|
||||||
|
enableDependencyVerification(false)
|
||||||
|
applyMultiplatformPlugin()
|
||||||
|
repositories.mavenCentralCacheRedirector()
|
||||||
|
}
|
||||||
|
|
||||||
|
val kotlin = project.multiplatformExtension
|
||||||
|
kotlin.targetHierarchy.default()
|
||||||
|
|
||||||
|
kotlin.jvm()
|
||||||
|
kotlin.linuxX64()
|
||||||
|
kotlin.linuxArm64()
|
||||||
|
|
||||||
|
val commonMain = kotlin.sourceSets.getByName("commonMain")
|
||||||
|
val linuxMain = kotlin.sourceSets.getByName("linuxMain")
|
||||||
|
|
||||||
|
commonMain.dependencies {
|
||||||
|
implementation("com.arkivanov.mvikotlin:mvikotlin:3.0.2")
|
||||||
|
implementation("com.arkivanov.essenty:lifecycle:0.4.2")
|
||||||
|
implementation("com.arkivanov.essenty:instance-keeper:0.4.2")
|
||||||
|
}
|
||||||
|
|
||||||
|
project.evaluate()
|
||||||
|
|
||||||
|
IdeTransformedMetadataDependencyResolver.resolve(commonMain)
|
||||||
|
.assertMatches(
|
||||||
|
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")
|
||||||
|
)
|
||||||
|
|
||||||
|
IdeTransformedMetadataDependencyResolver.resolve(linuxMain)
|
||||||
|
.assertMatches(
|
||||||
|
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")
|
||||||
|
)
|
||||||
|
}
|
||||||
|
}
|
||||||
Reference in New Issue
Block a user