Fix metadata transformation for non-published dependencies, KT-32225
Fix dependencies that are added in non-published source sets, which were omitted from the requested dependencies since their configurations were not added to the extendsFrom set of the merged configurations. Also, don't resolve both merged configurations (compile and runtime) in GranularMetadataTransformation, as the IDE can anyway import only the compile-scoped dependencies from api & implementation. Issue #KT-32225 Fixed
This commit is contained in:
+72
@@ -10,6 +10,7 @@ import org.jetbrains.kotlin.gradle.internals.parseKotlinSourceSetMetadataFromXml
|
||||
import org.jetbrains.kotlin.gradle.plugin.mpp.KotlinProjectStructureMetadata
|
||||
import org.jetbrains.kotlin.gradle.plugin.mpp.ModuleDependencyIdentifier
|
||||
import org.jetbrains.kotlin.gradle.plugin.sources.DefaultKotlinSourceSet
|
||||
import org.jetbrains.kotlin.gradle.util.checkedReplace
|
||||
import org.jetbrains.kotlin.gradle.util.modify
|
||||
import java.io.File
|
||||
import java.util.zip.ZipFile
|
||||
@@ -52,6 +53,77 @@ class HierarchicalMppIT : BaseGradleIT() {
|
||||
}
|
||||
}
|
||||
|
||||
@Test
|
||||
fun testDependenciesInTests() {
|
||||
publishThirdPartyLib(withGranularMetadata = true)
|
||||
|
||||
Project("my-lib-foo", gradleVersion, "hierarchical-mpp-published-modules").run {
|
||||
setupWorkingDir()
|
||||
gradleBuildScript().modify(::transformBuildScriptWithPluginsDsl)
|
||||
|
||||
testDependencyTransformations { reports ->
|
||||
val testApiTransformationReports =
|
||||
reports.filter { report ->
|
||||
report.groupAndModule.startsWith("com.example.thirdparty") &&
|
||||
report.sourceSetName.let { it == "commonTest" || it == "jvmAndJsTest" }
|
||||
}
|
||||
|
||||
testApiTransformationReports.forEach {
|
||||
assertTrue("$it") { it.isExcluded } // should not be visible in test source sets
|
||||
}
|
||||
}
|
||||
|
||||
// --- Move the dependency from jvmAndJsMain to commonMain, expect that it is now propagated to commonTest:
|
||||
gradleBuildScript().modify {
|
||||
it.checkedReplace("api(\"com.example.thirdparty:third-party-lib:1.0\")", "//") + "\n" + """
|
||||
dependencies {
|
||||
"commonMainApi"("com.example.thirdparty:third-party-lib:1.0")
|
||||
}
|
||||
""".trimIndent()
|
||||
}
|
||||
|
||||
testDependencyTransformations { reports ->
|
||||
val testApiTransformationReports =
|
||||
reports.filter { report ->
|
||||
report.groupAndModule.startsWith("com.example.thirdparty") &&
|
||||
report.sourceSetName.let { it == "commonTest" || it == "jvmAndJsTest" } &&
|
||||
report.scope == "api"
|
||||
}
|
||||
|
||||
testApiTransformationReports.forEach {
|
||||
assertEquals(setOf("commonMain"), it.allVisibleSourceSets, "$it")
|
||||
assertEquals(emptySet(), it.newVisibleSourceSets, "$it")
|
||||
}
|
||||
}
|
||||
|
||||
// --- Remove the dependency from commonMain, add it to commonTest to check that it is correctly picked from a non-published
|
||||
// source set:
|
||||
gradleBuildScript().modify {
|
||||
it.checkedReplace("\"commonMainApi\"(\"com.example.thirdparty:third-party-lib:1.0\")", "//") + "\n" + """
|
||||
dependencies {
|
||||
"commonTestApi"("com.example.thirdparty:third-party-lib:1.0")
|
||||
}
|
||||
""".trimIndent()
|
||||
}
|
||||
|
||||
testDependencyTransformations { reports ->
|
||||
reports.single {
|
||||
it.sourceSetName == "commonTest" && it.scope == "api" && it.groupAndModule.startsWith("com.example.thirdparty")
|
||||
}.let {
|
||||
assertEquals(setOf("commonMain"), it.allVisibleSourceSets)
|
||||
assertEquals(setOf("commonMain"), it.newVisibleSourceSets)
|
||||
}
|
||||
|
||||
reports.single {
|
||||
it.sourceSetName == "jvmAndJsTest" && it.scope == "api" && it.groupAndModule.startsWith("com.example.thirdparty")
|
||||
}.let {
|
||||
assertEquals(setOf("commonMain"), it.allVisibleSourceSets)
|
||||
assertEquals(emptySet(), it.newVisibleSourceSets)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@Test
|
||||
fun testProjectDependencies() {
|
||||
publishThirdPartyLib(withGranularMetadata = false)
|
||||
|
||||
+21
-5
@@ -82,7 +82,7 @@ internal class GranularMetadataTransformation(
|
||||
/** A list of scopes that the dependencies from [kotlinSourceSet] are treated as requested dependencies. */
|
||||
val sourceSetRequestedScopes: List<KotlinDependencyScope>,
|
||||
/** A configuration that holds the dependencies of the appropriate scope for all Kotlin source sets in the project */
|
||||
val allSourceSetsConfigurations: Iterable<Configuration>
|
||||
val allSourceSetsConfiguration: Configuration,
|
||||
val parentTransformations: Lazy<Iterable<GranularMetadataTransformation>>
|
||||
) {
|
||||
val metadataDependencyResolutions: Iterable<MetadataDependencyResolution> by lazy { doTransform() }
|
||||
@@ -134,8 +134,24 @@ internal class GranularMetadataTransformation(
|
||||
ownDependencies + parentDependencies
|
||||
}
|
||||
|
||||
private val resolvedConfigurations: Iterable<LenientConfiguration> by lazy {
|
||||
allSourceSetsConfigurations.map { it.resolvedConfiguration.lenientConfiguration }
|
||||
private val resolvedConfiguration: LenientConfiguration by lazy {
|
||||
/** If [kotlinSourceSet] is not a published source set, its dependencies are not included in [allSourceSetsConfiguration].
|
||||
* In that case, to resolve the dependencies of the source set in a way that is consistent with the published source sets,
|
||||
* we need to create a new configuration with the dependencies from both [allSourceSetsConfiguration] and the
|
||||
* input configuration(s) of the source set. */
|
||||
var modifiedConfiguration: Configuration? = null
|
||||
|
||||
val originalDependencies = allSourceSetsConfiguration.allDependencies
|
||||
|
||||
requestedDependencies.forEach { dependency ->
|
||||
if (dependency !in originalDependencies) {
|
||||
modifiedConfiguration = (modifiedConfiguration ?: allSourceSetsConfiguration.copyRecursive()).apply {
|
||||
dependencies.add(dependency)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
(modifiedConfiguration ?: allSourceSetsConfiguration).resolvedConfiguration.lenientConfiguration
|
||||
}
|
||||
|
||||
private fun doTransform(): Iterable<MetadataDependencyResolution> {
|
||||
@@ -146,7 +162,7 @@ internal class GranularMetadataTransformation(
|
||||
|
||||
val allRequestedDependencies = requestedDependencies
|
||||
|
||||
val allModuleDependencies = resolvedConfigurations.flatMap { it.allModuleDependencies }
|
||||
val allModuleDependencies = resolvedConfiguration.allModuleDependencies
|
||||
|
||||
val knownProjectDependencies = collectProjectDependencies(
|
||||
allRequestedDependencies.filterIsInstance<ProjectDependency>(),
|
||||
@@ -157,7 +173,7 @@ internal class GranularMetadataTransformation(
|
||||
val requestedModules: Set<ModuleId> = allRequestedDependencies.mapTo(mutableSetOf()) { it.moduleId }
|
||||
|
||||
addAll(
|
||||
resolvedConfigurations.flatMap { it.firstLevelModuleDependencies }
|
||||
resolvedConfiguration.firstLevelModuleDependencies
|
||||
.filter { it.moduleId in requestedModules }
|
||||
.map { ResolvedDependencyWithParent(it, null) }
|
||||
)
|
||||
|
||||
+1
-1
@@ -71,7 +71,7 @@ open class TransformKotlinGranularMetadata
|
||||
project,
|
||||
kotlinSourceSet,
|
||||
listOf(API_SCOPE, IMPLEMENTATION_SCOPE),
|
||||
listOf(project.configurations.getByName(ALL_COMPILE_METADATA_CONFIGURATION_NAME)),
|
||||
project.configurations.getByName(ALL_COMPILE_METADATA_CONFIGURATION_NAME),
|
||||
lazy {
|
||||
KotlinMetadataTargetConfigurator.dependsOnWithInterCompilationDependencies(project, kotlinSourceSet).map {
|
||||
project.tasks.withType(TransformKotlinGranularMetadata::class.java)
|
||||
|
||||
Reference in New Issue
Block a user