[Gradle] Implement initial MppCompositeBuildIT
^KT-52172 Verification Pending
This commit is contained in:
committed by
Space Team
parent
d12fbcf574
commit
7f14255be8
+6
@@ -11,3 +11,9 @@ interface IdeaKotlinDependencyMatcher {
|
|||||||
val description: String
|
val description: String
|
||||||
fun matches(dependency: IdeaKotlinDependency): Boolean
|
fun matches(dependency: IdeaKotlinDependency): Boolean
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fun IdeaKotlinDependencyMatcher(description: String, matches: (dependency: IdeaKotlinDependency) -> Boolean) =
|
||||||
|
object : IdeaKotlinDependencyMatcher {
|
||||||
|
override val description: String = description
|
||||||
|
override fun matches(dependency: IdeaKotlinDependency): Boolean = matches(dependency)
|
||||||
|
}
|
||||||
+2
@@ -12,6 +12,7 @@ import java.io.File
|
|||||||
|
|
||||||
internal class IdeaKotlinProjectArtifactDependencyMatcher(
|
internal class IdeaKotlinProjectArtifactDependencyMatcher(
|
||||||
val type: IdeaKotlinSourceDependency.Type,
|
val type: IdeaKotlinSourceDependency.Type,
|
||||||
|
val buildId: String,
|
||||||
val projectPath: String,
|
val projectPath: String,
|
||||||
val artifactFilePath: FilePathRegex
|
val artifactFilePath: FilePathRegex
|
||||||
) : IdeaKotlinDependencyMatcher {
|
) : IdeaKotlinDependencyMatcher {
|
||||||
@@ -21,6 +22,7 @@ internal class IdeaKotlinProjectArtifactDependencyMatcher(
|
|||||||
override fun matches(dependency: IdeaKotlinDependency): Boolean {
|
override fun matches(dependency: IdeaKotlinDependency): Boolean {
|
||||||
if (dependency !is IdeaKotlinProjectArtifactDependency) return false
|
if (dependency !is IdeaKotlinProjectArtifactDependency) return false
|
||||||
return dependency.type == type &&
|
return dependency.type == type &&
|
||||||
|
dependency.coordinates.project.buildId == buildId &&
|
||||||
dependency.coordinates.project.projectPath == projectPath &&
|
dependency.coordinates.project.projectPath == projectPath &&
|
||||||
artifactFilePath.matches(dependency.coordinates.artifactFile)
|
artifactFilePath.matches(dependency.coordinates.artifactFile)
|
||||||
|
|
||||||
|
|||||||
+2
@@ -10,6 +10,7 @@ import org.jetbrains.kotlin.gradle.idea.tcs.IdeaKotlinSourceDependency
|
|||||||
|
|
||||||
internal class IdeaKotlinSourceDependencyMatcher(
|
internal class IdeaKotlinSourceDependencyMatcher(
|
||||||
val type: IdeaKotlinSourceDependency.Type,
|
val type: IdeaKotlinSourceDependency.Type,
|
||||||
|
val buildId: String,
|
||||||
val projectPath: String,
|
val projectPath: String,
|
||||||
val sourceSetName: String
|
val sourceSetName: String
|
||||||
) : IdeaKotlinDependencyMatcher {
|
) : IdeaKotlinDependencyMatcher {
|
||||||
@@ -19,6 +20,7 @@ internal class IdeaKotlinSourceDependencyMatcher(
|
|||||||
override fun matches(dependency: IdeaKotlinDependency): Boolean {
|
override fun matches(dependency: IdeaKotlinDependency): Boolean {
|
||||||
if (dependency !is IdeaKotlinSourceDependency) return false
|
if (dependency !is IdeaKotlinSourceDependency) return false
|
||||||
return dependency.type == type &&
|
return dependency.type == type &&
|
||||||
|
dependency.coordinates.buildId == buildId &&
|
||||||
dependency.coordinates.projectPath == projectPath &&
|
dependency.coordinates.projectPath == projectPath &&
|
||||||
dependency.coordinates.sourceSetName == sourceSetName
|
dependency.coordinates.sourceSetName == sourceSetName
|
||||||
}
|
}
|
||||||
|
|||||||
+27
-10
@@ -7,6 +7,9 @@ package org.jetbrains.kotlin.gradle.idea.testFixtures.tcs
|
|||||||
|
|
||||||
import org.gradle.api.Project
|
import org.gradle.api.Project
|
||||||
import org.jetbrains.kotlin.gradle.idea.tcs.IdeaKotlinBinaryCoordinates
|
import org.jetbrains.kotlin.gradle.idea.tcs.IdeaKotlinBinaryCoordinates
|
||||||
|
import org.gradle.api.artifacts.component.BuildIdentifier
|
||||||
|
import org.gradle.api.internal.project.ProjectInternal
|
||||||
|
import org.gradle.internal.build.BuildState
|
||||||
import org.jetbrains.kotlin.gradle.idea.tcs.IdeaKotlinDependency
|
import org.jetbrains.kotlin.gradle.idea.tcs.IdeaKotlinDependency
|
||||||
import org.jetbrains.kotlin.gradle.idea.tcs.IdeaKotlinSourceDependency
|
import org.jetbrains.kotlin.gradle.idea.tcs.IdeaKotlinSourceDependency
|
||||||
|
|
||||||
@@ -22,14 +25,16 @@ fun buildIdeaKotlinDependencyMatchers(notation: Any?): List<IdeaKotlinDependency
|
|||||||
}
|
}
|
||||||
|
|
||||||
fun ideSourceDependency(type: IdeaKotlinSourceDependency.Type, project: Project, sourceSetName: String): IdeaKotlinDependencyMatcher {
|
fun ideSourceDependency(type: IdeaKotlinSourceDependency.Type, project: Project, sourceSetName: String): IdeaKotlinDependencyMatcher {
|
||||||
return IdeaKotlinSourceDependencyMatcher(type, project.path, sourceSetName)
|
return IdeaKotlinSourceDependencyMatcher(type, project.currentBuildId().name, project.path, sourceSetName)
|
||||||
}
|
}
|
||||||
|
|
||||||
fun ideSourceDependency(type: IdeaKotlinSourceDependency.Type, path: String): IdeaKotlinDependencyMatcher {
|
fun ideSourceDependency(type: IdeaKotlinSourceDependency.Type, path: String): IdeaKotlinDependencyMatcher {
|
||||||
val segments = path.split("/")
|
val segments = path.split("/")
|
||||||
val projectPath = segments.dropLast(1).joinToString("/")
|
val buildAndProjectPath = segments.dropLast(1).joinToString(":").split("::", limit = 2)
|
||||||
|
val buildId = if (buildAndProjectPath.size == 2) buildAndProjectPath.first() else ":"
|
||||||
|
val projectPath = if (buildAndProjectPath.size == 2) ":" + buildAndProjectPath.last() else buildAndProjectPath.last()
|
||||||
val sourceSetName = segments.last()
|
val sourceSetName = segments.last()
|
||||||
return IdeaKotlinSourceDependencyMatcher(type, projectPath, sourceSetName)
|
return IdeaKotlinSourceDependencyMatcher(type, buildId, projectPath, sourceSetName)
|
||||||
}
|
}
|
||||||
|
|
||||||
fun regularSourceDependency(path: String) = ideSourceDependency(IdeaKotlinSourceDependency.Type.Regular, path)
|
fun regularSourceDependency(path: String) = ideSourceDependency(IdeaKotlinSourceDependency.Type.Regular, path)
|
||||||
@@ -42,12 +47,20 @@ fun dependsOnDependency(project: Project, sourceSetName: String) =
|
|||||||
fun dependsOnDependency(path: String) = ideSourceDependency(IdeaKotlinSourceDependency.Type.DependsOn, path)
|
fun dependsOnDependency(path: String) = ideSourceDependency(IdeaKotlinSourceDependency.Type.DependsOn, path)
|
||||||
|
|
||||||
fun projectArtifactDependency(
|
fun projectArtifactDependency(
|
||||||
type: IdeaKotlinSourceDependency.Type = IdeaKotlinSourceDependency.Type.Regular, projectPath: String, artifactFilePath: FilePathRegex
|
type: IdeaKotlinSourceDependency.Type = IdeaKotlinSourceDependency.Type.Regular,
|
||||||
): IdeaKotlinDependencyMatcher = IdeaKotlinProjectArtifactDependencyMatcher(
|
buildIdAndProjectPath: String, artifactFilePath: FilePathRegex
|
||||||
type = type,
|
): IdeaKotlinDependencyMatcher {
|
||||||
projectPath = projectPath,
|
val slicedProjectPath = buildIdAndProjectPath.split("::", limit = 2)
|
||||||
artifactFilePath = artifactFilePath
|
val buildId = if (slicedProjectPath.size == 2) slicedProjectPath.first() else ":"
|
||||||
)
|
val projectPath = if (slicedProjectPath.size == 2) ":" + slicedProjectPath.last() else slicedProjectPath.last()
|
||||||
|
|
||||||
|
return IdeaKotlinProjectArtifactDependencyMatcher(
|
||||||
|
type = type,
|
||||||
|
buildId = buildId,
|
||||||
|
projectPath = projectPath,
|
||||||
|
artifactFilePath = artifactFilePath
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
fun binaryCoordinates(regex: Regex): IdeaKotlinDependencyMatcher {
|
fun binaryCoordinates(regex: Regex): IdeaKotlinDependencyMatcher {
|
||||||
return IdeaBinaryCoordinatesMatcher(regex)
|
return IdeaBinaryCoordinatesMatcher(regex)
|
||||||
@@ -60,4 +73,8 @@ fun binaryCoordinates(literal: String): IdeaKotlinDependencyMatcher {
|
|||||||
fun anyDependency(): IdeaKotlinDependencyMatcher = object : IdeaKotlinDependencyMatcher {
|
fun anyDependency(): IdeaKotlinDependencyMatcher = object : IdeaKotlinDependencyMatcher {
|
||||||
override val description: String get() = "any"
|
override val description: String get() = "any"
|
||||||
override fun matches(dependency: IdeaKotlinDependency): Boolean = true
|
override fun matches(dependency: IdeaKotlinDependency): Boolean = true
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* Duplicated: Aks Gradle for public API? */
|
||||||
|
private fun Project.currentBuildId(): BuildIdentifier =
|
||||||
|
(project as ProjectInternal).services.get(BuildState::class.java).buildIdentifier
|
||||||
+1
-53
@@ -5,13 +5,9 @@
|
|||||||
|
|
||||||
package org.jetbrains.kotlin.gradle
|
package org.jetbrains.kotlin.gradle
|
||||||
|
|
||||||
import org.gradle.testkit.runner.BuildResult
|
|
||||||
import org.gradle.util.GradleVersion
|
import org.gradle.util.GradleVersion
|
||||||
import org.jetbrains.kotlin.commonizer.CommonizerTarget
|
import org.jetbrains.kotlin.commonizer.CommonizerTarget
|
||||||
import org.jetbrains.kotlin.commonizer.identityString
|
import org.jetbrains.kotlin.commonizer.identityString
|
||||||
import org.jetbrains.kotlin.gradle.idea.proto.tcs.IdeaKotlinDependency
|
|
||||||
import org.jetbrains.kotlin.gradle.idea.serialize.IdeaKotlinSerializationContext
|
|
||||||
import org.jetbrains.kotlin.gradle.idea.serialize.IdeaKotlinSerializationLogger
|
|
||||||
import org.jetbrains.kotlin.gradle.idea.tcs.IdeaKotlinDependency
|
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.CLASSPATH_BINARY_TYPE
|
||||||
import org.jetbrains.kotlin.gradle.idea.tcs.IdeaKotlinResolvedBinaryDependency
|
import org.jetbrains.kotlin.gradle.idea.tcs.IdeaKotlinResolvedBinaryDependency
|
||||||
@@ -21,11 +17,10 @@ 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.klibExtra
|
||||||
import org.jetbrains.kotlin.gradle.idea.testFixtures.tcs.assertMatches
|
import org.jetbrains.kotlin.gradle.idea.testFixtures.tcs.assertMatches
|
||||||
import org.jetbrains.kotlin.gradle.idea.testFixtures.tcs.binaryCoordinates
|
import org.jetbrains.kotlin.gradle.idea.testFixtures.tcs.binaryCoordinates
|
||||||
import org.jetbrains.kotlin.gradle.plugin.ide.kotlinExtrasSerialization
|
|
||||||
import org.jetbrains.kotlin.gradle.testbase.*
|
import org.jetbrains.kotlin.gradle.testbase.*
|
||||||
|
import org.jetbrains.kotlin.gradle.util.resolveIdeDependencies
|
||||||
import org.jetbrains.kotlin.konan.target.KonanTarget.*
|
import org.jetbrains.kotlin.konan.target.KonanTarget.*
|
||||||
import org.junit.jupiter.api.DisplayName
|
import org.junit.jupiter.api.DisplayName
|
||||||
import java.io.File
|
|
||||||
import kotlin.test.assertEquals
|
import kotlin.test.assertEquals
|
||||||
import kotlin.test.fail
|
import kotlin.test.fail
|
||||||
|
|
||||||
@@ -91,50 +86,3 @@ class MppIdeDependencyResolutionIT : KGPBaseTest() {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Test Utils / Test Infrastructure Implementation */
|
|
||||||
|
|
||||||
private fun TestProject.resolveIdeDependencies(
|
|
||||||
subproject: String? = null,
|
|
||||||
assertions: BuildResult.(dependencies: IdeaKotlinDependenciesContainer) -> Unit
|
|
||||||
) {
|
|
||||||
build("${subproject.orEmpty()}:resolveIdeDependencies") {
|
|
||||||
val subprojectPathPrefix = subproject?.removePrefix(":")?.replace(":", "/")?.plus("/") ?: ""
|
|
||||||
val output = projectPath.resolve("${subprojectPathPrefix}build/ide/dependencies/proto").toFile()
|
|
||||||
if (!output.isDirectory) fail("Missing output directory: $output")
|
|
||||||
|
|
||||||
val dependenciesBySourceSetName = output.listFiles().orEmpty().associate { sourceSetDirectory ->
|
|
||||||
if (!sourceSetDirectory.isDirectory) fail("Expected $sourceSetDirectory to be directory")
|
|
||||||
val serializedDependencyFiles = sourceSetDirectory.listFiles().orEmpty()
|
|
||||||
val deserializedDependencies = serializedDependencyFiles.map { dependencyFile ->
|
|
||||||
deserializeIdeaKotlinDependencyOrFail(dependencyFile)
|
|
||||||
}
|
|
||||||
|
|
||||||
sourceSetDirectory.name to deserializedDependencies.toSet()
|
|
||||||
}
|
|
||||||
|
|
||||||
assertions(IdeaKotlinDependenciesContainer(dependenciesBySourceSetName))
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
private fun deserializeIdeaKotlinDependencyOrFail(file: File): IdeaKotlinDependency {
|
|
||||||
return GradleIntegrationTestIdeaKotlinSerializationContext.IdeaKotlinDependency(file.readBytes())
|
|
||||||
?: fail("Failed to deserialize dependency. $file")
|
|
||||||
}
|
|
||||||
|
|
||||||
private object GradleIntegrationTestIdeaKotlinSerializationContext : IdeaKotlinSerializationContext {
|
|
||||||
override val extrasSerializationExtension = kotlinExtrasSerialization
|
|
||||||
override val logger: IdeaKotlinSerializationLogger = object : IdeaKotlinSerializationLogger {
|
|
||||||
override fun report(severity: IdeaKotlinSerializationLogger.Severity, message: String, cause: Throwable?) {
|
|
||||||
println("$severity: $message")
|
|
||||||
if (cause != null) println(cause.stackTraceToString())
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
private class IdeaKotlinDependenciesContainer(
|
|
||||||
private val dependencies: Map<String, Set<IdeaKotlinDependency>>
|
|
||||||
) {
|
|
||||||
operator fun get(sourceSetName: String) = dependencies[sourceSetName]
|
|
||||||
?: fail("SourceSet with name $sourceSetName not found. Found: ${dependencies.keys}")
|
|
||||||
}
|
|
||||||
|
|||||||
+83
@@ -0,0 +1,83 @@
|
|||||||
|
/*
|
||||||
|
* 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.mpp
|
||||||
|
|
||||||
|
import org.gradle.util.GradleVersion
|
||||||
|
import org.jetbrains.kotlin.gradle.idea.tcs.IdeaKotlinSourceDependency.Type.Regular
|
||||||
|
import org.jetbrains.kotlin.gradle.idea.testFixtures.tcs.*
|
||||||
|
import org.jetbrains.kotlin.gradle.testbase.*
|
||||||
|
import org.jetbrains.kotlin.gradle.util.kotilnNativeDistributionDependencies
|
||||||
|
import org.jetbrains.kotlin.gradle.util.kotlinStdlibDependencies
|
||||||
|
import org.jetbrains.kotlin.gradle.util.replaceText
|
||||||
|
import org.jetbrains.kotlin.gradle.util.resolveIdeDependencies
|
||||||
|
import org.junit.jupiter.api.DisplayName
|
||||||
|
import kotlin.io.path.absolutePathString
|
||||||
|
|
||||||
|
@MppGradlePluginTests
|
||||||
|
@DisplayName("Tests for multiplatform with composite builds")
|
||||||
|
class MppCompositeBuildIT : KGPBaseTest() {
|
||||||
|
@GradleTest
|
||||||
|
fun `test - simple composite build - ide dependencies`(gradleVersion: GradleVersion) {
|
||||||
|
val producer = project("mpp-composite-build/simple/producerBuild", gradleVersion)
|
||||||
|
|
||||||
|
project("mpp-composite-build/simple/consumerBuild", gradleVersion) {
|
||||||
|
settingsGradleKts.toFile().replaceText("<producer_path>", producer.projectPath.absolutePathString())
|
||||||
|
resolveIdeDependencies(":consumerA") { dependencies ->
|
||||||
|
dependencies["commonMain"].assertMatches(
|
||||||
|
regularSourceDependency("producerBuild::producerA/commonMain"),
|
||||||
|
kotlinStdlibDependencies
|
||||||
|
)
|
||||||
|
|
||||||
|
dependencies["nativeMain"].assertMatches(
|
||||||
|
dependsOnDependency(":consumerA/commonMain"),
|
||||||
|
regularSourceDependency("producerBuild::producerA/commonMain"),
|
||||||
|
regularSourceDependency("producerBuild::producerA/nativeMain"),
|
||||||
|
regularSourceDependency("producerBuild::producerA/linuxMain"),
|
||||||
|
kotilnNativeDistributionDependencies
|
||||||
|
)
|
||||||
|
|
||||||
|
dependencies["linuxMain"].assertMatches(
|
||||||
|
dependencies["nativeMain"],
|
||||||
|
dependsOnDependency(":consumerA/nativeMain"),
|
||||||
|
)
|
||||||
|
|
||||||
|
dependencies["linuxX64Main"].assertMatches(
|
||||||
|
dependsOnDependency(":consumerA/commonMain"),
|
||||||
|
dependsOnDependency(":consumerA/nativeMain"),
|
||||||
|
dependsOnDependency(":consumerA/linuxMain"),
|
||||||
|
projectArtifactDependency(Regular, "producerBuild::producerA", FilePathRegex(".*/linuxX64/main/klib/producerA.klib")),
|
||||||
|
kotilnNativeDistributionDependencies
|
||||||
|
)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@GradleTest
|
||||||
|
fun `test - simple composite build - assemble`(gradleVersion: GradleVersion) {
|
||||||
|
val producer = project("mpp-composite-build/simple/producerBuild", gradleVersion)
|
||||||
|
|
||||||
|
project("mpp-composite-build/simple/consumerBuild", gradleVersion) {
|
||||||
|
settingsGradleKts.toFile().replaceText("<producer_path>", producer.projectPath.absolutePathString())
|
||||||
|
build("cleanNativeDistributionCommonization")
|
||||||
|
|
||||||
|
build("assemble") {
|
||||||
|
assertTasksExecuted(":consumerA:compileCommonMainKotlinMetadata")
|
||||||
|
assertTasksExecuted(":consumerA:compileNativeMainKotlinMetadata")
|
||||||
|
assertTasksExecuted(":consumerA:compileNativeMainKotlinMetadata")
|
||||||
|
assertTasksExecuted(":consumerA:compileKotlinLinuxX64")
|
||||||
|
assertTasksExecuted(":consumerA:compileKotlinJvm")
|
||||||
|
}
|
||||||
|
|
||||||
|
build("assemble") {
|
||||||
|
assertTasksUpToDate(":consumerA:compileCommonMainKotlinMetadata")
|
||||||
|
assertTasksUpToDate(":consumerA:compileNativeMainKotlinMetadata")
|
||||||
|
assertTasksUpToDate(":consumerA:compileNativeMainKotlinMetadata")
|
||||||
|
assertTasksUpToDate(":consumerA:compileKotlinLinuxX64")
|
||||||
|
assertTasksUpToDate(":consumerA:compileKotlinJvm")
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
+17
@@ -0,0 +1,17 @@
|
|||||||
|
/*
|
||||||
|
* 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.util
|
||||||
|
|
||||||
|
import org.jetbrains.kotlin.gradle.idea.tcs.IdeaKotlinResolvedBinaryDependency
|
||||||
|
import org.jetbrains.kotlin.gradle.idea.tcs.extras.isNativeDistribution
|
||||||
|
import org.jetbrains.kotlin.gradle.idea.testFixtures.tcs.IdeaKotlinDependencyMatcher
|
||||||
|
import org.jetbrains.kotlin.gradle.idea.testFixtures.tcs.binaryCoordinates
|
||||||
|
|
||||||
|
val kotlinStdlibDependencies = binaryCoordinates(Regex(".*kotlin-stdlib.*"))
|
||||||
|
|
||||||
|
val kotilnNativeDistributionDependencies = IdeaKotlinDependencyMatcher("native distribution") { dependency ->
|
||||||
|
dependency is IdeaKotlinResolvedBinaryDependency && dependency.isNativeDistribution
|
||||||
|
}
|
||||||
+8
@@ -97,3 +97,11 @@ private fun normalizeTail(prefixEnd: Int, path: String, separator: Boolean): Str
|
|||||||
|
|
||||||
return result.toString()
|
return result.toString()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fun File.replaceText(oldValue: String, newValue: String) {
|
||||||
|
writeText(readText().replace(oldValue, newValue))
|
||||||
|
}
|
||||||
|
|
||||||
|
fun File.replaceText(regex: Regex, replacement: String) {
|
||||||
|
writeText(readText().replace(regex, replacement))
|
||||||
|
}
|
||||||
|
|||||||
+65
@@ -0,0 +1,65 @@
|
|||||||
|
/*
|
||||||
|
* 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.util
|
||||||
|
|
||||||
|
import org.gradle.testkit.runner.BuildResult
|
||||||
|
import org.jetbrains.kotlin.gradle.idea.proto.tcs.IdeaKotlinDependency
|
||||||
|
import org.jetbrains.kotlin.gradle.idea.serialize.IdeaKotlinSerializationContext
|
||||||
|
import org.jetbrains.kotlin.gradle.idea.serialize.IdeaKotlinSerializationLogger
|
||||||
|
import org.jetbrains.kotlin.gradle.idea.tcs.IdeaKotlinDependency
|
||||||
|
import org.jetbrains.kotlin.gradle.plugin.ide.kotlinExtrasSerialization
|
||||||
|
import org.jetbrains.kotlin.gradle.testbase.TestProject
|
||||||
|
import org.jetbrains.kotlin.gradle.testbase.build
|
||||||
|
import java.io.File
|
||||||
|
import kotlin.test.fail
|
||||||
|
|
||||||
|
|
||||||
|
/* Test Utils / Test Infrastructure Implementation */
|
||||||
|
|
||||||
|
internal fun TestProject.resolveIdeDependencies(
|
||||||
|
subproject: String? = null,
|
||||||
|
assertions: BuildResult.(dependencies: IdeaKotlinDependenciesContainer) -> Unit
|
||||||
|
) {
|
||||||
|
build("${subproject.orEmpty()}:resolveIdeDependencies") {
|
||||||
|
val subprojectPathPrefix = subproject?.removePrefix(":")?.replace(":", "/")?.plus("/") ?: ""
|
||||||
|
val output = projectPath.resolve("${subprojectPathPrefix}build/ide/dependencies/proto").toFile()
|
||||||
|
if (!output.isDirectory) fail("Missing output directory: $output")
|
||||||
|
|
||||||
|
val dependenciesBySourceSetName = output.listFiles().orEmpty().associate { sourceSetDirectory ->
|
||||||
|
if (!sourceSetDirectory.isDirectory) fail("Expected $sourceSetDirectory to be directory")
|
||||||
|
val serializedDependencyFiles = sourceSetDirectory.listFiles().orEmpty()
|
||||||
|
val deserializedDependencies = serializedDependencyFiles.map { dependencyFile ->
|
||||||
|
deserializeIdeaKotlinDependencyOrFail(dependencyFile)
|
||||||
|
}
|
||||||
|
|
||||||
|
sourceSetDirectory.name to deserializedDependencies.toSet()
|
||||||
|
}
|
||||||
|
|
||||||
|
assertions(IdeaKotlinDependenciesContainer(dependenciesBySourceSetName))
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private fun deserializeIdeaKotlinDependencyOrFail(file: File): IdeaKotlinDependency {
|
||||||
|
return GradleIntegrationTestIdeaKotlinSerializationContext.IdeaKotlinDependency(file.readBytes())
|
||||||
|
?: fail("Failed to deserialize dependency. $file")
|
||||||
|
}
|
||||||
|
|
||||||
|
private object GradleIntegrationTestIdeaKotlinSerializationContext : IdeaKotlinSerializationContext {
|
||||||
|
override val extrasSerializationExtension = kotlinExtrasSerialization
|
||||||
|
override val logger: IdeaKotlinSerializationLogger = object : IdeaKotlinSerializationLogger {
|
||||||
|
override fun report(severity: IdeaKotlinSerializationLogger.Severity, message: String, cause: Throwable?) {
|
||||||
|
println("$severity: $message")
|
||||||
|
if (cause != null) println(cause.stackTraceToString())
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
class IdeaKotlinDependenciesContainer(
|
||||||
|
private val dependencies: Map<String, Set<IdeaKotlinDependency>>
|
||||||
|
) {
|
||||||
|
operator fun get(sourceSetName: String) = dependencies[sourceSetName]
|
||||||
|
?: fail("SourceSet with name $sourceSetName not found. Found: ${dependencies.keys}")
|
||||||
|
}
|
||||||
+16
@@ -0,0 +1,16 @@
|
|||||||
|
@file:Suppress("OPT_IN_USAGE")
|
||||||
|
|
||||||
|
plugins {
|
||||||
|
kotlin("multiplatform")
|
||||||
|
}
|
||||||
|
|
||||||
|
kotlin {
|
||||||
|
targetHierarchy.default()
|
||||||
|
jvm()
|
||||||
|
linuxX64()
|
||||||
|
linuxArm64()
|
||||||
|
|
||||||
|
sourceSets.commonMain.get().dependencies {
|
||||||
|
implementation("org.jetbrains.sample:producerA:1.0.0-SNAPSHOT")
|
||||||
|
}
|
||||||
|
}
|
||||||
+5
@@ -0,0 +1,5 @@
|
|||||||
|
object ConsumerACommon {
|
||||||
|
init {
|
||||||
|
ProducerACommon
|
||||||
|
}
|
||||||
|
}
|
||||||
+7
@@ -0,0 +1,7 @@
|
|||||||
|
object ConsumerALinuxX64 {
|
||||||
|
init {
|
||||||
|
ProducerACommon
|
||||||
|
ProducerANative
|
||||||
|
ProducerALinuxX64
|
||||||
|
}
|
||||||
|
}
|
||||||
+5
@@ -0,0 +1,5 @@
|
|||||||
|
object ConsumerANative {
|
||||||
|
init {
|
||||||
|
ProducerANative
|
||||||
|
}
|
||||||
|
}
|
||||||
+14
@@ -0,0 +1,14 @@
|
|||||||
|
dependencyResolutionManagement {
|
||||||
|
repositories {
|
||||||
|
mavenLocal()
|
||||||
|
mavenCentral()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
include(":consumerA")
|
||||||
|
|
||||||
|
includeBuild("<producer_path>") {
|
||||||
|
dependencySubstitution {
|
||||||
|
substitute(module("org.jetbrains.sample:producerA")).using(project(":producerA"))
|
||||||
|
}
|
||||||
|
}
|
||||||
+17
@@ -0,0 +1,17 @@
|
|||||||
|
@file:Suppress("OPT_IN_USAGE")
|
||||||
|
|
||||||
|
plugins {
|
||||||
|
kotlin("multiplatform")
|
||||||
|
`maven-publish`
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
group = "org.jetbrains.sample"
|
||||||
|
version = "1.0.0-SNAPSHOT"
|
||||||
|
|
||||||
|
kotlin {
|
||||||
|
targetHierarchy.default()
|
||||||
|
jvm()
|
||||||
|
linuxX64()
|
||||||
|
linuxArm64()
|
||||||
|
}
|
||||||
+1
@@ -0,0 +1 @@
|
|||||||
|
object ProducerACommon
|
||||||
+1
@@ -0,0 +1 @@
|
|||||||
|
object ProducerALinuxX64
|
||||||
+1
@@ -0,0 +1 @@
|
|||||||
|
object ProducerANative
|
||||||
+8
@@ -0,0 +1,8 @@
|
|||||||
|
dependencyResolutionManagement {
|
||||||
|
repositories {
|
||||||
|
mavenLocal()
|
||||||
|
mavenCentral()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
include(":producerA")
|
||||||
+2
-2
@@ -171,8 +171,8 @@ class IdeSourceDependencyResolutionTest {
|
|||||||
consumer.resolveDependencies("jvmAndAndroidMain").assertMatches(
|
consumer.resolveDependencies("jvmAndAndroidMain").assertMatches(
|
||||||
regularSourceDependency(":producer/commonMain"),
|
regularSourceDependency(":producer/commonMain"),
|
||||||
regularSourceDependency(":producer/jvmAndAndroidMain"),
|
regularSourceDependency(":producer/jvmAndAndroidMain"),
|
||||||
projectArtifactDependency(Regular, ":producer", FilePathRegex(".*/producer/build/libs/producer-jvm.jar")),
|
dependsOnDependency(":consumer/commonMain"),
|
||||||
dependsOnDependency(":consumer/commonMain")
|
projectArtifactDependency(Regular, ":producer", FilePathRegex(".*/build/libs/producer-jvm.jar"))
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
-3
@@ -5,11 +5,8 @@
|
|||||||
|
|
||||||
package org.jetbrains.kotlin.gradle.ide
|
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.KotlinSourceSet
|
||||||
import org.jetbrains.kotlin.gradle.plugin.sources.internal
|
import org.jetbrains.kotlin.gradle.plugin.sources.internal
|
||||||
import org.jetbrains.kotlin.gradle.plugin.sources.project
|
|
||||||
|
|
||||||
fun dependsOnDependency(sourceSet: KotlinSourceSet) =
|
fun dependsOnDependency(sourceSet: KotlinSourceSet) =
|
||||||
org.jetbrains.kotlin.gradle.idea.testFixtures.tcs.dependsOnDependency(sourceSet.internal.project, sourceSet.name)
|
org.jetbrains.kotlin.gradle.idea.testFixtures.tcs.dependsOnDependency(sourceSet.internal.project, sourceSet.name)
|
||||||
Reference in New Issue
Block a user