[KPM] Implement initial kpm/idea dependency resolution
^KT-51386 Verification Pending
This commit is contained in:
committed by
Space
parent
8b84ed4978
commit
1a5fc84080
@@ -1,5 +1,6 @@
|
||||
plugins {
|
||||
kotlin("jvm")
|
||||
`java-test-fixtures`
|
||||
}
|
||||
|
||||
object BackwardsCompatibilityTestConfiguration {
|
||||
@@ -18,9 +19,14 @@ dependencies {
|
||||
testImplementation(gradleKotlinDsl())
|
||||
testImplementation(project(":kotlin-gradle-plugin"))
|
||||
testImplementation(project(":kotlin-test:kotlin-test-junit"))
|
||||
|
||||
testImplementation("org.reflections:reflections:0.10.2") {
|
||||
because("Tests on the object graph are performed. This library will find implementations of interfaces at runtime")
|
||||
}
|
||||
|
||||
testFixturesImplementation(gradleApi())
|
||||
testFixturesImplementation(gradleKotlinDsl())
|
||||
testFixturesImplementation(project(":kotlin-test:kotlin-test-junit"))
|
||||
}
|
||||
|
||||
publish()
|
||||
@@ -39,7 +45,13 @@ run {
|
||||
val version = if (isSnapshotTest) properties["defaultSnapshotVersion"].toString()
|
||||
else BackwardsCompatibilityTestConfiguration.minimalBackwardsCompatibleVersion
|
||||
|
||||
val minimalBackwardsCompatibleVersionTestClasspath by configurations.creating
|
||||
val minimalBackwardsCompatibleVersionTestClasspath by configurations.creating {
|
||||
isCanBeResolved = true
|
||||
isCanBeConsumed = false
|
||||
attributes {
|
||||
attribute(Usage.USAGE_ATTRIBUTE, objects.named(Usage.JAVA_RUNTIME))
|
||||
}
|
||||
}
|
||||
|
||||
dependencies {
|
||||
minimalBackwardsCompatibleVersionTestClasspath("org.jetbrains.kotlin:kotlin-gradle-plugin-idea:$version")
|
||||
@@ -51,9 +63,17 @@ run {
|
||||
if (isSnapshotTest) logger.quiet("Running test against snapshot: $version")
|
||||
else logger.quiet("Running test against $version")
|
||||
|
||||
val resolvedClasspath = minimalBackwardsCompatibleVersionTestClasspath.files
|
||||
if (resolvedClasspath.none { "kotlin-gradle-plugin-idea-$version.jar" in it.path }) {
|
||||
throw IllegalStateException(buildString {
|
||||
appendLine("Bad backwardsCompatibilityClasspath: $resolvedClasspath")
|
||||
appendLine("Dependencies:${minimalBackwardsCompatibleVersionTestClasspath.allDependencies.joinToString()}")
|
||||
})
|
||||
}
|
||||
|
||||
systemProperty(
|
||||
"backwardsCompatibilityClasspath",
|
||||
minimalBackwardsCompatibleVersionTestClasspath.files.joinToString(";") { it.absolutePath }
|
||||
resolvedClasspath.joinToString(";") { it.absolutePath }
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
+131
@@ -0,0 +1,131 @@
|
||||
/*
|
||||
* 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.kpm.idea
|
||||
|
||||
import org.jetbrains.kotlin.gradle.kpm.KotlinExternalModelContainer
|
||||
import org.jetbrains.kotlin.gradle.kpm.idea.IdeaKotlinDependency.Companion.CLASSPATH_BINARY_TYPE
|
||||
import org.jetbrains.kotlin.gradle.kpm.idea.IdeaKotlinDependency.Companion.DOCUMENTATION_BINARY_TYPE
|
||||
import org.jetbrains.kotlin.gradle.kpm.idea.IdeaKotlinDependency.Companion.SOURCES_BINARY_TYPE
|
||||
import java.io.File
|
||||
import java.io.Serializable
|
||||
|
||||
sealed interface IdeaKotlinDependency : Serializable {
|
||||
val external: KotlinExternalModelContainer
|
||||
|
||||
companion object {
|
||||
const val CLASSPATH_BINARY_TYPE = "org.jetbrains.binary.type.classpath"
|
||||
const val SOURCES_BINARY_TYPE = "org.jetbrains.binary.type.sources"
|
||||
const val DOCUMENTATION_BINARY_TYPE = "org.jetbrains.binary.type.documentation"
|
||||
}
|
||||
}
|
||||
|
||||
sealed interface IdeaKotlinSourceDependency : IdeaKotlinDependency {
|
||||
val buildId: String
|
||||
val projectPath: String
|
||||
val projectName: String
|
||||
val kotlinModuleName: String
|
||||
val kotlinModuleClassifier: String?
|
||||
val kotlinFragmentName: String
|
||||
}
|
||||
|
||||
sealed interface IdeaKotlinBinaryCoordinates : Serializable {
|
||||
val group: String
|
||||
val module: String
|
||||
val version: String
|
||||
val kotlinModuleName: String?
|
||||
val kotlinFragmentName: String?
|
||||
}
|
||||
|
||||
sealed interface IdeaKotlinBinaryDependency : IdeaKotlinDependency {
|
||||
val coordinates: IdeaKotlinBinaryCoordinates?
|
||||
}
|
||||
|
||||
sealed interface IdeaKotlinUnresolvedBinaryDependency : IdeaKotlinBinaryDependency {
|
||||
val cause: String?
|
||||
}
|
||||
|
||||
sealed interface IdeaKotlinResolvedBinaryDependency : IdeaKotlinBinaryDependency {
|
||||
val binaryType: String
|
||||
val binaryFile: File
|
||||
}
|
||||
|
||||
val IdeaKotlinResolvedBinaryDependency.isSourcesType get() = binaryType == SOURCES_BINARY_TYPE
|
||||
val IdeaKotlinResolvedBinaryDependency.isDocumentationType get() = binaryType == DOCUMENTATION_BINARY_TYPE
|
||||
val IdeaKotlinResolvedBinaryDependency.isClasspathType get() = binaryType == CLASSPATH_BINARY_TYPE
|
||||
|
||||
@InternalKotlinGradlePluginApi
|
||||
data class IdeaKotlinSourceDependencyImpl(
|
||||
override val buildId: String,
|
||||
override val projectPath: String,
|
||||
override val projectName: String,
|
||||
override val kotlinModuleName: String,
|
||||
override val kotlinModuleClassifier: String?,
|
||||
override val kotlinFragmentName: String,
|
||||
override val external: KotlinExternalModelContainer = KotlinExternalModelContainer.Empty
|
||||
) : IdeaKotlinSourceDependency {
|
||||
|
||||
override fun toString(): String {
|
||||
return "project://$buildId:$projectPath:$kotlinModuleName:$kotlinFragmentName"
|
||||
}
|
||||
|
||||
@InternalKotlinGradlePluginApi
|
||||
companion object {
|
||||
private const val serialVersionUID = 0L
|
||||
}
|
||||
}
|
||||
|
||||
@InternalKotlinGradlePluginApi
|
||||
data class IdeaKotlinBinaryCoordinatesImpl(
|
||||
override val group: String,
|
||||
override val module: String,
|
||||
override val version: String,
|
||||
override val kotlinModuleName: String? = null,
|
||||
override val kotlinFragmentName: String? = null
|
||||
) : IdeaKotlinBinaryCoordinates {
|
||||
|
||||
override fun toString(): String {
|
||||
return "$group:$module:$version" +
|
||||
(if (kotlinModuleName != null) ":$kotlinModuleName" else "") +
|
||||
(if (kotlinFragmentName != null) ":$kotlinFragmentName" else "")
|
||||
}
|
||||
|
||||
companion object {
|
||||
private const val serialVersionUID = 0L
|
||||
}
|
||||
}
|
||||
|
||||
@InternalKotlinGradlePluginApi
|
||||
data class IdeaKotlinResolvedBinaryDependencyImpl(
|
||||
override val coordinates: IdeaKotlinBinaryCoordinates?,
|
||||
override val binaryType: String,
|
||||
override val binaryFile: File,
|
||||
override val external: KotlinExternalModelContainer = KotlinExternalModelContainer.Empty
|
||||
) : IdeaKotlinResolvedBinaryDependency {
|
||||
|
||||
override fun toString(): String {
|
||||
return "${binaryType.split(".").last()}://$coordinates/${binaryFile.name}"
|
||||
}
|
||||
|
||||
@InternalKotlinGradlePluginApi
|
||||
companion object {
|
||||
private const val serialVersionUID = 0L
|
||||
}
|
||||
}
|
||||
|
||||
@InternalKotlinGradlePluginApi
|
||||
data class IdeaKotlinUnresolvedBinaryDependencyImpl(
|
||||
override val cause: String?,
|
||||
override val coordinates: IdeaKotlinBinaryCoordinates?,
|
||||
override val external: KotlinExternalModelContainer = KotlinExternalModelContainer.Empty
|
||||
) : IdeaKotlinUnresolvedBinaryDependency {
|
||||
|
||||
@InternalKotlinGradlePluginApi
|
||||
companion object {
|
||||
private const val serialVersionUID = 0L
|
||||
}
|
||||
}
|
||||
+4
-2
@@ -11,8 +11,9 @@ import java.io.Serializable
|
||||
interface IdeaKotlinFragment : Serializable {
|
||||
val name: String
|
||||
val moduleIdentifier: IdeaKotlinModuleIdentifier
|
||||
val platforms: Set<IdeaKotlinPlatform>
|
||||
val languageSettings: IdeaKotlinLanguageSettings?
|
||||
val dependencies: List<IdeaKotlinFragmentDependency>
|
||||
val dependencies: List<IdeaKotlinDependency>
|
||||
val directRefinesDependencies: List<IdeaKotlinFragment>
|
||||
val sourceDirectories: List<IdeaKotlinSourceDirectory>
|
||||
val resourceDirectories: List<IdeaKotlinResourceDirectory>
|
||||
@@ -23,8 +24,9 @@ interface IdeaKotlinFragment : Serializable {
|
||||
data class IdeaKotlinFragmentImpl(
|
||||
override val name: String,
|
||||
override val moduleIdentifier: IdeaKotlinModuleIdentifier,
|
||||
override val platforms: Set<IdeaKotlinPlatform>,
|
||||
override val languageSettings: IdeaKotlinLanguageSettings?,
|
||||
override val dependencies: List<IdeaKotlinFragmentDependency>,
|
||||
override val dependencies: List<IdeaKotlinDependency>,
|
||||
override val directRefinesDependencies: List<IdeaKotlinFragment>,
|
||||
override val sourceDirectories: List<IdeaKotlinSourceDirectory>,
|
||||
override val resourceDirectories: List<IdeaKotlinResourceDirectory>,
|
||||
|
||||
-20
@@ -1,20 +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.kpm.idea
|
||||
|
||||
import java.io.Serializable
|
||||
|
||||
interface IdeaKotlinFragmentDependency : Serializable
|
||||
|
||||
@Suppress("unused")
|
||||
@InternalKotlinGradlePluginApi
|
||||
class IdeaKotlinFragmentDependencyImpl: IdeaKotlinFragmentDependency {
|
||||
|
||||
@InternalKotlinGradlePluginApi
|
||||
companion object {
|
||||
const val serialVersionUID = 0L
|
||||
}
|
||||
}
|
||||
+2
@@ -8,12 +8,14 @@ package org.jetbrains.kotlin.gradle.kpm.idea
|
||||
import java.io.Serializable
|
||||
|
||||
interface IdeaKotlinModule : Serializable {
|
||||
val name: String
|
||||
val moduleIdentifier: IdeaKotlinModuleIdentifier
|
||||
val fragments: List<IdeaKotlinFragment>
|
||||
}
|
||||
|
||||
@InternalKotlinGradlePluginApi
|
||||
data class IdeaKotlinModuleImpl(
|
||||
override val name: String,
|
||||
override val moduleIdentifier: IdeaKotlinModuleIdentifier,
|
||||
override val fragments: List<IdeaKotlinFragment>
|
||||
) : IdeaKotlinModule {
|
||||
|
||||
+100
@@ -0,0 +1,100 @@
|
||||
/*
|
||||
* 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("unused")
|
||||
|
||||
package org.jetbrains.kotlin.gradle.kpm.idea
|
||||
|
||||
import java.io.Serializable
|
||||
|
||||
sealed interface IdeaKotlinPlatform : Serializable {
|
||||
val platformType: String
|
||||
val platformDetails: IdeaKotlinPlatformDetails?
|
||||
|
||||
companion object {
|
||||
val unknown: IdeaKotlinPlatform = IdeaKotlinPlatformImpl("unknown", null)
|
||||
|
||||
const val wasmPlatformType = "wasm"
|
||||
const val nativePlatformType = "native"
|
||||
const val jvmPlatformType = "jvm"
|
||||
const val jsPlatformType = "js"
|
||||
}
|
||||
}
|
||||
|
||||
sealed interface IdeaKotlinPlatformDetails : Serializable
|
||||
|
||||
sealed interface IdeaKotlinWasmPlatformDetails : IdeaKotlinPlatformDetails
|
||||
|
||||
sealed interface IdeaKotlinNativePlatformDetails : IdeaKotlinPlatformDetails {
|
||||
val konanTarget: String
|
||||
}
|
||||
|
||||
sealed interface IdeaKotlinJvmPlatformDetails : IdeaKotlinPlatformDetails {
|
||||
val jvmTarget: String
|
||||
}
|
||||
|
||||
sealed interface IdeaKotlinJsPlatformDetails : IdeaKotlinPlatformDetails {
|
||||
val isIr: Boolean
|
||||
}
|
||||
|
||||
@InternalKotlinGradlePluginApi
|
||||
fun IdeaKotlinPlatform.Companion.wasm(): IdeaKotlinPlatform {
|
||||
return IdeaKotlinPlatformImpl(wasmPlatformType, IdeaKotlinWasmPlatformDetailsImpl)
|
||||
}
|
||||
|
||||
@InternalKotlinGradlePluginApi
|
||||
fun IdeaKotlinPlatform.Companion.native(konanTarget: String): IdeaKotlinPlatform {
|
||||
return IdeaKotlinPlatformImpl(nativePlatformType, IdeaKotlinNativePlatformDetailsImpl(konanTarget))
|
||||
}
|
||||
|
||||
@InternalKotlinGradlePluginApi
|
||||
fun IdeaKotlinPlatform.Companion.jvm(jvmTarget: String): IdeaKotlinPlatform {
|
||||
return IdeaKotlinPlatformImpl(jvmPlatformType, IdeaKotlinJvmPlatformDetailsImpl(jvmTarget))
|
||||
}
|
||||
|
||||
@InternalKotlinGradlePluginApi
|
||||
fun IdeaKotlinPlatform.Companion.js(isIr: Boolean): IdeaKotlinPlatform {
|
||||
return IdeaKotlinPlatformImpl(jsPlatformType, IdeaKotlinJsPlatformDetailsImpl(isIr))
|
||||
}
|
||||
|
||||
val IdeaKotlinPlatform.isWasm get() = platformType == IdeaKotlinPlatform.wasmPlatformType
|
||||
val IdeaKotlinPlatform.isNative get() = platformType == IdeaKotlinPlatform.nativePlatformType
|
||||
val IdeaKotlinPlatform.isJvm get() = platformType == IdeaKotlinPlatform.jvmPlatformType
|
||||
val IdeaKotlinPlatform.isJs get() = platformType == IdeaKotlinPlatform.jsPlatformType
|
||||
|
||||
val IdeaKotlinPlatform.nativeOrNull get() = (platformDetails as? IdeaKotlinNativePlatformDetails)
|
||||
val IdeaKotlinPlatform.jvmOrNull get() = (platformDetails as? IdeaKotlinJvmPlatformDetails)
|
||||
val IdeaKotlinPlatform.jsOrNull get() = (platformDetails as? IdeaKotlinJsPlatformDetails)
|
||||
|
||||
private data class IdeaKotlinPlatformImpl(
|
||||
override val platformType: String, override val platformDetails: IdeaKotlinPlatformDetails?
|
||||
) : IdeaKotlinPlatform {
|
||||
|
||||
companion object {
|
||||
const val serialVersionUID = 0L
|
||||
}
|
||||
}
|
||||
|
||||
private object IdeaKotlinWasmPlatformDetailsImpl : IdeaKotlinWasmPlatformDetails {
|
||||
private const val serialVersionUID = 0L
|
||||
}
|
||||
|
||||
private data class IdeaKotlinJvmPlatformDetailsImpl(override val jvmTarget: String) : IdeaKotlinJvmPlatformDetails {
|
||||
private companion object {
|
||||
const val serialVersionUID = 0L
|
||||
}
|
||||
}
|
||||
|
||||
private data class IdeaKotlinNativePlatformDetailsImpl(override val konanTarget: String) : IdeaKotlinNativePlatformDetails {
|
||||
private companion object {
|
||||
const val serialVersionUID = 0L
|
||||
}
|
||||
}
|
||||
|
||||
private data class IdeaKotlinJsPlatformDetailsImpl(override val isIr: Boolean) : IdeaKotlinJsPlatformDetails {
|
||||
private companion object {
|
||||
const val serialVersionUID = 0L
|
||||
}
|
||||
}
|
||||
+2
@@ -8,6 +8,7 @@ package org.jetbrains.kotlin.gradle.kpm.idea
|
||||
import java.io.Serializable
|
||||
|
||||
interface IdeaKotlinVariant : IdeaKotlinFragment, Serializable {
|
||||
val platform: IdeaKotlinPlatform
|
||||
val variantAttributes: Map<String, String>
|
||||
val compilationOutputs: IdeaKotlinCompilationOutput
|
||||
}
|
||||
@@ -15,6 +16,7 @@ interface IdeaKotlinVariant : IdeaKotlinFragment, Serializable {
|
||||
@InternalKotlinGradlePluginApi
|
||||
data class IdeaKotlinVariantImpl(
|
||||
internal val fragment: IdeaKotlinFragment,
|
||||
override val platform: IdeaKotlinPlatform,
|
||||
override val variantAttributes: Map<String, String>,
|
||||
override val compilationOutputs: IdeaKotlinCompilationOutput,
|
||||
) : IdeaKotlinVariant, IdeaKotlinFragment by fragment {
|
||||
|
||||
@@ -1,4 +1,5 @@
|
||||
import org.gradle.api.Project
|
||||
import org.gradle.api.artifacts.verification.DependencyVerificationMode
|
||||
import org.gradle.api.internal.project.ProjectInternal
|
||||
import org.gradle.configurationcache.extensions.serviceOf
|
||||
import org.gradle.testfixtures.ProjectBuilder
|
||||
@@ -20,5 +21,8 @@ fun Project.buildIdeaKotlinProjectModel(): IdeaKotlinProjectModel {
|
||||
fun createKpmProject(): Pair<ProjectInternal, KotlinPm20ProjectExtension> {
|
||||
val project = ProjectBuilder.builder().build() as ProjectInternal
|
||||
project.plugins.apply(KotlinPm20PluginWrapper::class.java)
|
||||
project.gradle.startParameter.dependencyVerificationMode = DependencyVerificationMode.OFF
|
||||
project.repositories.mavenLocal()
|
||||
project.repositories.maven { it.setUrl("https://cache-redirector.jetbrains.com/maven-central") }
|
||||
return project to project.extensions.getByType(KotlinPm20ProjectExtension::class.java)
|
||||
}
|
||||
|
||||
+2
-2
@@ -5,8 +5,8 @@
|
||||
|
||||
package org.jetbrains.kotlin.gradle.kpm
|
||||
|
||||
import deserialize
|
||||
import serialize
|
||||
import org.jetbrains.kotlin.gradle.kpm.idea.testFixtures.deserialize
|
||||
import org.jetbrains.kotlin.gradle.kpm.idea.testFixtures.serialize
|
||||
import java.io.Serializable
|
||||
import kotlin.test.Test
|
||||
import kotlin.test.assertEquals
|
||||
|
||||
+2
-5
@@ -10,23 +10,20 @@ package org.jetbrains.kotlin.gradle.kpm.idea
|
||||
import buildIdeaKotlinProjectModel
|
||||
import createKpmProject
|
||||
import createProxyInstance
|
||||
import deserialize
|
||||
import org.gradle.api.Project
|
||||
import org.gradle.api.internal.project.ProjectInternal
|
||||
import org.gradle.configurationcache.extensions.serviceOf
|
||||
import org.gradle.kotlin.dsl.create
|
||||
import org.gradle.testfixtures.ProjectBuilder
|
||||
import org.gradle.tooling.provider.model.ToolingModelBuilderRegistry
|
||||
import org.jetbrains.kotlin.gradle.kpm.KotlinExternalModelKey
|
||||
import org.jetbrains.kotlin.gradle.kpm.KotlinExternalModelSerializer.Companion.serializable
|
||||
import org.jetbrains.kotlin.gradle.kpm.external.ExternalVariantApi
|
||||
import org.jetbrains.kotlin.gradle.kpm.external.external
|
||||
import org.jetbrains.kotlin.gradle.kpm.idea.testFixtures.deserialize
|
||||
import org.jetbrains.kotlin.gradle.kpm.idea.testFixtures.serialize
|
||||
import org.jetbrains.kotlin.gradle.plugin.KotlinPm20PluginWrapper
|
||||
import org.jetbrains.kotlin.gradle.plugin.mpp.pm20.KotlinIosX64Variant
|
||||
import org.jetbrains.kotlin.gradle.plugin.mpp.pm20.KotlinLinuxX64Variant
|
||||
import org.jetbrains.kotlin.gradle.plugin.mpp.pm20.KotlinPm20ProjectExtension
|
||||
import org.jetbrains.kotlin.gradle.plugin.mpp.pm20.jvm
|
||||
import serialize
|
||||
import unwrapProxyInstance
|
||||
import java.io.File
|
||||
import java.io.Serializable
|
||||
|
||||
+75
@@ -0,0 +1,75 @@
|
||||
/*
|
||||
* 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.kpm.idea.testFixtures
|
||||
|
||||
import org.jetbrains.kotlin.gradle.kpm.idea.IdeaKotlinBinaryCoordinates
|
||||
import org.jetbrains.kotlin.gradle.kpm.idea.IdeaKotlinBinaryDependency
|
||||
import org.jetbrains.kotlin.gradle.kpm.idea.IdeaKotlinDependency
|
||||
import org.jetbrains.kotlin.gradle.kpm.idea.IdeaKotlinResolvedBinaryDependency
|
||||
import java.io.File
|
||||
|
||||
fun buildIdeaKotlinDependencyMatchers(any: Any?): List<IdeaKotlinDependencyMatcher> {
|
||||
return when (any) {
|
||||
null -> emptyList()
|
||||
is IdeaKotlinDependencyMatcher -> listOf(any)
|
||||
is String -> listOf(IdeaKotlinDependencyMatcher.Coordinates(parseIdeaKotlinBinaryCoordinates(any)))
|
||||
is Regex -> listOf(IdeaKotlinDependencyMatcher.CoordinatesRegex(any))
|
||||
is File -> listOf(IdeaKotlinDependencyMatcher.BinaryFile(any))
|
||||
is Iterable<*> -> any.flatMap { child -> buildIdeaKotlinDependencyMatchers(child) }
|
||||
else -> error("Can't build ${IdeaKotlinDependencyMatcher::class.simpleName} from $any")
|
||||
}
|
||||
}
|
||||
|
||||
interface IdeaKotlinDependencyMatcher {
|
||||
val description: String
|
||||
fun matches(dependency: IdeaKotlinDependency): Boolean
|
||||
|
||||
class Coordinates(
|
||||
private val coordinates: IdeaKotlinBinaryCoordinates
|
||||
) : IdeaKotlinDependencyMatcher {
|
||||
override val description: String = coordinates.toString()
|
||||
|
||||
override fun matches(dependency: IdeaKotlinDependency): Boolean {
|
||||
return dependency is IdeaKotlinBinaryDependency && coordinates == dependency.coordinates
|
||||
}
|
||||
}
|
||||
|
||||
class CoordinatesRegex(
|
||||
private val regex: Regex
|
||||
) : IdeaKotlinDependencyMatcher {
|
||||
override val description: String = regex.pattern
|
||||
|
||||
override fun matches(dependency: IdeaKotlinDependency): Boolean {
|
||||
return dependency is IdeaKotlinBinaryDependency && regex.matches(dependency.coordinates.toString())
|
||||
}
|
||||
}
|
||||
|
||||
class BinaryFile(
|
||||
private val binaryFile: File
|
||||
) : IdeaKotlinDependencyMatcher {
|
||||
override val description: String = binaryFile.path
|
||||
|
||||
override fun matches(dependency: IdeaKotlinDependency): Boolean {
|
||||
return dependency is IdeaKotlinResolvedBinaryDependency && dependency.binaryFile == binaryFile
|
||||
}
|
||||
}
|
||||
|
||||
class InDirectory(
|
||||
private val parentFile: File
|
||||
) : IdeaKotlinDependencyMatcher {
|
||||
constructor(parentFilePath: String) : this(File(parentFilePath))
|
||||
|
||||
override val description: String = "$parentFile/**"
|
||||
|
||||
override fun matches(dependency: IdeaKotlinDependency): Boolean {
|
||||
return dependency is IdeaKotlinResolvedBinaryDependency &&
|
||||
dependency.binaryFile.absoluteFile.normalize().canonicalPath.startsWith(
|
||||
parentFile.absoluteFile.normalize().canonicalPath
|
||||
)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
+90
@@ -0,0 +1,90 @@
|
||||
/*
|
||||
* 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.kpm.idea.testFixtures
|
||||
|
||||
import org.jetbrains.kotlin.gradle.kpm.idea.*
|
||||
import kotlin.test.fail
|
||||
|
||||
fun IdeaKotlinProjectModel.assertIsNotEmpty(): IdeaKotlinProjectModel = apply {
|
||||
if (this.modules.isEmpty()) fail("Expected at least one module in model")
|
||||
}
|
||||
|
||||
fun IdeaKotlinProjectModel.assertContainsModule(name: String): IdeaKotlinModule {
|
||||
return modules.find { it.name == name }
|
||||
?: fail("Missing module with name '$name'. Found: ${modules.map { it.name }}")
|
||||
}
|
||||
|
||||
fun IdeaKotlinModule.assertContainsFragment(name: String): IdeaKotlinFragment {
|
||||
return fragments.find { it.name == name }
|
||||
?: fail("Missing fragment with name '$name'. Found: ${fragments.map { it.name }}")
|
||||
}
|
||||
|
||||
fun IdeaKotlinFragment.assertResolvedBinaryDependencies(
|
||||
binaryType: String,
|
||||
matchers: Set<IdeaKotlinDependencyMatcher>
|
||||
): Set<IdeaKotlinResolvedBinaryDependency> {
|
||||
val resolvedBinaryDependencies = dependencies
|
||||
.mapNotNull { dependency ->
|
||||
when (dependency) {
|
||||
is IdeaKotlinResolvedBinaryDependencyImpl -> dependency
|
||||
is IdeaKotlinUnresolvedBinaryDependencyImpl -> fail("Unexpected unresolved dependency: $dependency")
|
||||
is IdeaKotlinSourceDependencyImpl -> null
|
||||
}
|
||||
}
|
||||
.filter { it.binaryType == binaryType }
|
||||
.toSet()
|
||||
|
||||
val unexpectedResolvedBinaryDependencies = resolvedBinaryDependencies
|
||||
.filter { dependency -> matchers.none { matcher -> matcher.matches(dependency) } }
|
||||
|
||||
val missingDependencies = matchers.filter { matcher ->
|
||||
resolvedBinaryDependencies.none { dependency -> matcher.matches(dependency) }
|
||||
}
|
||||
|
||||
if (unexpectedResolvedBinaryDependencies.isEmpty() && missingDependencies.isEmpty()) {
|
||||
return resolvedBinaryDependencies
|
||||
}
|
||||
|
||||
fail(
|
||||
buildString {
|
||||
if (unexpectedResolvedBinaryDependencies.isNotEmpty()) {
|
||||
appendLine("${name}: Unexpected dependencies found:")
|
||||
unexpectedResolvedBinaryDependencies.forEach { unexpectedDependency ->
|
||||
appendLine(unexpectedDependency)
|
||||
}
|
||||
|
||||
appendLine()
|
||||
appendLine("Unexpected dependency coordinates:")
|
||||
unexpectedResolvedBinaryDependencies.forEach { unexpectedDependency ->
|
||||
appendLine("\"${unexpectedDependency.coordinates}\",")
|
||||
}
|
||||
}
|
||||
|
||||
if (missingDependencies.isNotEmpty()) {
|
||||
appendLine()
|
||||
appendLine("Missing dependencies:")
|
||||
missingDependencies.forEach { missingDependency ->
|
||||
appendLine(missingDependency.description)
|
||||
}
|
||||
}
|
||||
|
||||
appendLine()
|
||||
appendLine("Resolved Dependency Coordinates:")
|
||||
resolvedBinaryDependencies.mapNotNull { it.coordinates }.forEach { coordinates ->
|
||||
appendLine("\"$coordinates\",")
|
||||
}
|
||||
}
|
||||
)
|
||||
}
|
||||
|
||||
@JvmName("assertResolvedBinaryDependenciesByAnyMatcher")
|
||||
fun IdeaKotlinFragment.assertResolvedBinaryDependencies(
|
||||
binaryType: String, matchers: Set<Any?>,
|
||||
) = assertResolvedBinaryDependencies(binaryType, matchers.flatMap { buildIdeaKotlinDependencyMatchers(it) }.toSet())
|
||||
|
||||
fun IdeaKotlinFragment.assertResolvedBinaryDependencies(
|
||||
binaryType: String, vararg matchers: Any?
|
||||
) = assertResolvedBinaryDependencies(binaryType, matchers.toSet())
|
||||
+34
@@ -0,0 +1,34 @@
|
||||
/*
|
||||
* 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.kpm.idea.testFixtures
|
||||
|
||||
import org.jetbrains.kotlin.gradle.kpm.idea.IdeaKotlinBinaryCoordinates
|
||||
import org.jetbrains.kotlin.gradle.kpm.idea.IdeaKotlinBinaryCoordinatesImpl
|
||||
import org.jetbrains.kotlin.gradle.kpm.idea.IdeaKotlinBinaryDependency
|
||||
import org.jetbrains.kotlin.gradle.kpm.idea.IdeaKotlinFragment
|
||||
|
||||
fun parseIdeaKotlinBinaryCoordinates(coordinates: String): IdeaKotlinBinaryCoordinates {
|
||||
val parts = coordinates.split(":")
|
||||
if (parts.size == 3) {
|
||||
return IdeaKotlinBinaryCoordinatesImpl(parts[0], parts[1], parts[2])
|
||||
}
|
||||
|
||||
if (parts.size == 5) {
|
||||
return IdeaKotlinBinaryCoordinatesImpl(parts[0], parts[1], parts[2], parts[3], parts[4])
|
||||
}
|
||||
|
||||
throw IllegalArgumentException("Cannot parse $coordinates into ${IdeaKotlinBinaryCoordinates::class.java.simpleName}")
|
||||
}
|
||||
|
||||
fun Iterable<IdeaKotlinBinaryCoordinates>.parsableString() =
|
||||
joinToString("," + System.lineSeparator(), "", "") { "\"$it\"" }
|
||||
|
||||
@Suppress("unused") // Debugging API
|
||||
fun IdeaKotlinFragment.parsableDependencyCoordinatesString(): String {
|
||||
return dependencies.filterIsInstance<IdeaKotlinBinaryDependency>()
|
||||
.mapNotNull { it.coordinates }.toSet()
|
||||
.parsableString()
|
||||
}
|
||||
+5
-3
@@ -1,3 +1,5 @@
|
||||
package org.jetbrains.kotlin.gradle.kpm.idea.testFixtures
|
||||
|
||||
import org.gradle.internal.io.ClassLoaderObjectInputStream
|
||||
import java.io.*
|
||||
|
||||
@@ -6,20 +8,20 @@ import java.io.*
|
||||
* Use of this source code is governed by the Apache 2.0 license that can be found in the license/LICENSE.txt file.
|
||||
*/
|
||||
|
||||
internal fun Any.serialize(): ByteArray {
|
||||
fun Any.serialize(): ByteArray {
|
||||
return ByteArrayOutputStream().use { byteArrayOutputStream ->
|
||||
ObjectOutputStream(byteArrayOutputStream).writeObject(this)
|
||||
byteArrayOutputStream.toByteArray()
|
||||
}
|
||||
}
|
||||
|
||||
internal inline fun <reified T : Serializable> ByteArray.deserialize(): T {
|
||||
inline fun <reified T : Serializable> ByteArray.deserialize(): T {
|
||||
val inputStream = ByteArrayInputStream(this)
|
||||
val objectInputStream = ObjectInputStream(inputStream)
|
||||
return objectInputStream.use { it.readObject() } as T
|
||||
}
|
||||
|
||||
internal fun ByteArray.deserialize(classLoader: ClassLoader): Any {
|
||||
fun ByteArray.deserialize(classLoader: ClassLoader): Any {
|
||||
val inputStream = ByteArrayInputStream(this)
|
||||
val objectInputStream = ClassLoaderObjectInputStream(inputStream, classLoader)
|
||||
return objectInputStream.use { it.readObject() }
|
||||
Reference in New Issue
Block a user