[Gradle] Introduce SourceSetDependenciesResolution dsl for tests
It allows to mock published via gradle libraries to verify dependency resolution correctness.
This commit is contained in:
committed by
Space Team
parent
46abf63796
commit
c027ba642f
+69
@@ -0,0 +1,69 @@
|
|||||||
|
/*
|
||||||
|
* Copyright 2010-2024 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.dependencyResolutionTests
|
||||||
|
|
||||||
|
import org.jetbrains.kotlin.gradle.dsl.KotlinMultiplatformExtension
|
||||||
|
import org.jetbrains.kotlin.gradle.plugin.KotlinTarget
|
||||||
|
import java.io.File
|
||||||
|
|
||||||
|
fun KotlinMultiplatformExtension.publishAsMockedLibrary(repoDir: File, name: String, version: String) {
|
||||||
|
val moduleRootDir = repoDir.resolve("test/$name/$version")
|
||||||
|
moduleRootDir.mkdirs()
|
||||||
|
val moduleFile = moduleRootDir.resolve("$name-$version.module")
|
||||||
|
moduleFile.writeText(publishedMockedGradleMetadata(name, version))
|
||||||
|
val pomFile = moduleFile.parentFile.resolve("$name-$version.pom")
|
||||||
|
pomFile.writeText(
|
||||||
|
"""
|
||||||
|
<?xml version="1.0" encoding="UTF-8"?>
|
||||||
|
<project xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 https://maven.apache.org/xsd/maven-4.0.0.xsd"
|
||||||
|
xmlns="http://maven.apache.org/POM/4.0.0"
|
||||||
|
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
|
||||||
|
<modelVersion>4.0.0</modelVersion>
|
||||||
|
<groupId>test</groupId>
|
||||||
|
<artifactId>$name</artifactId>
|
||||||
|
<version>$version</version>
|
||||||
|
</project>
|
||||||
|
""".trimIndent()
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
|
private fun KotlinMultiplatformExtension.publishedMockedGradleMetadata(name: String, version: String): String {
|
||||||
|
val variants = targets.joinToString(",") { it.variantJson() + "\n" }
|
||||||
|
return """
|
||||||
|
{
|
||||||
|
"formatVersion": "1.1",
|
||||||
|
"component": {
|
||||||
|
"group": "test",
|
||||||
|
"module": "$name",
|
||||||
|
"version": "$version",
|
||||||
|
"attributes": {
|
||||||
|
"org.gradle.status": "release"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"variants": [
|
||||||
|
$variants
|
||||||
|
]
|
||||||
|
}
|
||||||
|
""".trimIndent()
|
||||||
|
}
|
||||||
|
|
||||||
|
private fun KotlinTarget.variantJson(): String {
|
||||||
|
val apiElements = project.configurations.getByName(apiElementsConfigurationName)
|
||||||
|
val attributesString = apiElements
|
||||||
|
.attributes
|
||||||
|
.keySet()
|
||||||
|
.map { it to apiElements.attributes.getAttribute(it) }
|
||||||
|
.joinToString(",\n") { "\"${it.first.name}\": \"${it.second}\"" }
|
||||||
|
|
||||||
|
return """
|
||||||
|
{
|
||||||
|
"name": "$name",
|
||||||
|
"attributes": {
|
||||||
|
$attributesString
|
||||||
|
}
|
||||||
|
}
|
||||||
|
""".trimIndent()
|
||||||
|
}
|
||||||
+87
@@ -0,0 +1,87 @@
|
|||||||
|
/*
|
||||||
|
* Copyright 2010-2024 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.dependencyResolutionTests
|
||||||
|
|
||||||
|
import org.gradle.api.Project
|
||||||
|
import org.gradle.kotlin.dsl.maven
|
||||||
|
import org.jetbrains.kotlin.gradle.dsl.kotlinExtension
|
||||||
|
import org.jetbrains.kotlin.gradle.dsl.multiplatformExtension
|
||||||
|
import org.jetbrains.kotlin.gradle.dsl.platformTargets
|
||||||
|
import org.jetbrains.kotlin.gradle.plugin.mpp.resolvableMetadataConfiguration
|
||||||
|
import org.jetbrains.kotlin.gradle.plugin.sources.internal
|
||||||
|
import org.jetbrains.kotlin.gradle.util.*
|
||||||
|
import org.jetbrains.kotlin.test.KotlinTestUtils
|
||||||
|
import org.junit.Rule
|
||||||
|
import org.junit.rules.TemporaryFolder
|
||||||
|
|
||||||
|
abstract class SourceSetDependenciesResolution {
|
||||||
|
@get:Rule
|
||||||
|
val tempFolder = TemporaryFolder()
|
||||||
|
|
||||||
|
class SourceSetDependenciesDsl(
|
||||||
|
private val project: Project
|
||||||
|
) {
|
||||||
|
val declaredDependencies = mutableSetOf<Pair<String, String>>() // list of name + versions
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Declares an API dependency to test:[name]:[version] for [sourceSetName] source set
|
||||||
|
*/
|
||||||
|
fun api(sourceSetName: String, name: String, version: String) {
|
||||||
|
declaredDependencies.add(name to version)
|
||||||
|
project.kotlinExtension.sourceSets.getByName(sourceSetName).dependencies { api("test:$name:$version") }
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
fun assertSourceSetDependenciesResolution(expectedFilePath: String, configure: SourceSetDependenciesDsl.(Project) -> Unit) {
|
||||||
|
val repoRoot = tempFolder.newFolder()
|
||||||
|
val project = buildProject {
|
||||||
|
enableDefaultStdlibDependency(false)
|
||||||
|
enableDependencyVerification(false)
|
||||||
|
applyMultiplatformPlugin()
|
||||||
|
|
||||||
|
repositories.maven(repoRoot)
|
||||||
|
}
|
||||||
|
|
||||||
|
val dsl = SourceSetDependenciesDsl(project)
|
||||||
|
dsl.configure(project)
|
||||||
|
|
||||||
|
dsl.declaredDependencies.forEach { project.multiplatformExtension.publishAsMockedLibrary(repoRoot, it.first, it.second) }
|
||||||
|
|
||||||
|
project.evaluate()
|
||||||
|
|
||||||
|
val actualResult = project.resolveAllSourceSetDependencies()
|
||||||
|
val expectedFile = resourcesRoot.resolve("dependenciesResolution").resolve(expectedFilePath)
|
||||||
|
KotlinTestUtils.assertEqualsToFile(expectedFile, actualResult)
|
||||||
|
}
|
||||||
|
|
||||||
|
private fun Project.resolveAllSourceSetDependencies(): String {
|
||||||
|
val allSourceSets = multiplatformExtension.sourceSets.toSet()
|
||||||
|
|
||||||
|
val platformSpecificSourceSets = multiplatformExtension
|
||||||
|
.targets
|
||||||
|
.platformTargets
|
||||||
|
.flatMap { it.compilations }
|
||||||
|
.associate { it.defaultSourceSet to configurations.getByName(it.compileDependencyConfigurationName) }
|
||||||
|
|
||||||
|
val commonSourceSetsWithoutMetadataCompilation = allSourceSets
|
||||||
|
.minus(platformSpecificSourceSets.keys)
|
||||||
|
.associateWith { it.internal.resolvableMetadataConfiguration }
|
||||||
|
|
||||||
|
val actual = (platformSpecificSourceSets + commonSourceSetsWithoutMetadataCompilation).mapValues { (_, configuration) ->
|
||||||
|
val resolutionResult = configuration.incoming.resolutionResult
|
||||||
|
val rootComponent = resolutionResult.root
|
||||||
|
val dependencies = resolutionResult.allComponents
|
||||||
|
.minus(rootComponent)
|
||||||
|
.map { it.id.displayName }
|
||||||
|
.sorted()
|
||||||
|
dependencies.joinToString("\n") { " $it" }
|
||||||
|
}.entries.sortedBy { (sourceSet, _) -> sourceSet.name }.joinToString("\n") {
|
||||||
|
it.key.name + "\n" + it.value
|
||||||
|
}
|
||||||
|
|
||||||
|
return actual
|
||||||
|
}
|
||||||
|
}
|
||||||
Reference in New Issue
Block a user