HMPP resolution fixes
While we already had the associateWith relationship that established additional visibility between such source sets as fooMain and fooTest, this relationship was not used properly when requested dependencies were built for source set visibility inference in HMPP. Instead, an old workaround was used that just added dependencies of commonMain to commonTest. Fix this by using the associateWith relationship in the preparation logic of source sets visibiltiy. ALso, make the artifact view used in source sets visibility inference lenient, so that a host-specific module that has not yet been published won't lead to fail in source sets visibility and will instead be ingored.
This commit is contained in:
+47
-5
@@ -58,9 +58,42 @@ class HierarchicalMppIT : BaseGradleIT() {
|
||||
}
|
||||
|
||||
@Test
|
||||
fun testDependenciesInTests() {
|
||||
fun testNoSourceSetsVisibleIfNoVariantMatched() {
|
||||
publishThirdPartyLib(withGranularMetadata = true)
|
||||
|
||||
Project("my-lib-foo", gradleVersion, "hierarchical-mpp-published-modules").run {
|
||||
setupWorkingDir()
|
||||
gradleBuildScript().modify(::transformBuildScriptWithPluginsDsl)
|
||||
|
||||
// --- Move the dependency from jvmAndJsMain to commonMain, where there's a linuxX64 target missing in the lib
|
||||
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 thirdPartyLibApiVisibility = reports.filter { report ->
|
||||
report.groupAndModule.startsWith("com.example.thirdparty:third-party-lib") && report.scope == "api"
|
||||
}
|
||||
val jvmJsSourceSets = setOf("jvmMain", "jsMain", "jvmTest", "jsTest", "jvmAndJsMain", "jvmAndJsTest")
|
||||
thirdPartyLibApiVisibility.forEach {
|
||||
if (it.sourceSetName in jvmJsSourceSets)
|
||||
assertTrue("$it") { it.allVisibleSourceSets == setOf("commonMain") }
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@Test
|
||||
fun testDependenciesInTests() {
|
||||
publishThirdPartyLib(withGranularMetadata = true) {
|
||||
projectDir.resolve("src/jvmMain").copyRecursively(projectDir.resolve("src/linuxX64Main"))
|
||||
gradleBuildScript().appendText("\nkotlin.linuxX64()")
|
||||
}
|
||||
|
||||
Project("my-lib-foo", gradleVersion, "hierarchical-mpp-published-modules").run {
|
||||
setupWorkingDir()
|
||||
gradleBuildScript().modify(::transformBuildScriptWithPluginsDsl)
|
||||
@@ -68,12 +101,18 @@ class HierarchicalMppIT : BaseGradleIT() {
|
||||
testDependencyTransformations { reports ->
|
||||
val testApiTransformationReports =
|
||||
reports.filter { report ->
|
||||
report.groupAndModule.startsWith("com.example.thirdparty") &&
|
||||
report.sourceSetName.let { it == "commonTest" || it == "jvmAndJsTest" }
|
||||
report.groupAndModule.startsWith("com.example.thirdparty:third-party-lib") &&
|
||||
report.sourceSetName.let { it == "commonTest" || it == "jvmAndJsTest" } &&
|
||||
report.scope == "api"
|
||||
}
|
||||
|
||||
testApiTransformationReports.forEach {
|
||||
assertTrue("$it") { it.isExcluded } // should not be visible in test source sets
|
||||
if (it.sourceSetName == "commonTest")
|
||||
assertTrue("$it") { it.isExcluded } // should not be visible in commonTest
|
||||
else {
|
||||
assertTrue("$it") { it.allVisibleSourceSets == setOf("commonMain") }
|
||||
assertTrue("$it") { it.newVisibleSourceSets == emptySet<String>() }
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -187,12 +226,15 @@ class HierarchicalMppIT : BaseGradleIT() {
|
||||
projectName: String = "third-party-lib",
|
||||
directoryPrefix: String = "hierarchical-mpp-published-modules",
|
||||
withGranularMetadata: Boolean,
|
||||
jsCompilerType: KotlinJsCompilerType = KotlinJsCompilerType.LEGACY
|
||||
jsCompilerType: KotlinJsCompilerType = KotlinJsCompilerType.LEGACY,
|
||||
beforePublishing: Project.() -> Unit = { }
|
||||
): Project =
|
||||
Project(projectName, gradleVersion, directoryPrefix).apply {
|
||||
setupWorkingDir()
|
||||
gradleBuildScript().modify(::transformBuildScriptWithPluginsDsl)
|
||||
|
||||
beforePublishing()
|
||||
|
||||
if (withGranularMetadata) {
|
||||
projectDir.resolve("gradle.properties").appendText("kotlin.mpp.enableGranularSourceSetsMetadata=true")
|
||||
}
|
||||
|
||||
+1
-1
@@ -62,7 +62,7 @@ val KOTLIN_JS_DSL_NAME = "kotlin2js"
|
||||
val KOTLIN_OPTIONS_DSL_NAME = "kotlinOptions"
|
||||
|
||||
abstract class KotlinCompilationProcessor<out T : AbstractCompile>(
|
||||
open val kotlinCompilation: AbstractKotlinCompilation<*>
|
||||
open val kotlinCompilation: KotlinCompilation<*>
|
||||
) {
|
||||
abstract val kotlinTask: TaskProvider<out T>
|
||||
abstract fun run()
|
||||
|
||||
+1
@@ -146,6 +146,7 @@ internal class ResolvedMppVariantsProvider private constructor(private val proje
|
||||
return artifactsConfiguration.incoming.artifactView { view ->
|
||||
view.componentFilter { it in mppComponentIds }
|
||||
view.attributes { attrs -> attrs.attribute(Usage.USAGE_ATTRIBUTE, project.usageByName(KotlinUsages.KOTLIN_METADATA)) }
|
||||
view.lenient(true)
|
||||
}.artifacts.associateBy { it.id.componentIdentifier }
|
||||
}
|
||||
|
||||
|
||||
+6
-6
@@ -71,7 +71,7 @@ internal class SourceSetVisibilityProvider(
|
||||
|
||||
val firstConfigurationByVariant = mutableMapOf<String, Configuration>()
|
||||
|
||||
val visiblePlatformVariantNames: Set<String> =
|
||||
val visiblePlatformVariantNames: Set<String?> =
|
||||
compilations
|
||||
.filter { it.target.platformType != KotlinPlatformType.common }
|
||||
.flatMapTo(mutableSetOf()) { compilation ->
|
||||
@@ -79,10 +79,10 @@ internal class SourceSetVisibilityProvider(
|
||||
// that we have in the compilations:
|
||||
dependencyScopes.mapNotNull { scope -> project.resolvableConfigurationFromCompilationByScope(compilation, scope) }
|
||||
}
|
||||
.mapNotNullTo(mutableSetOf()) { configuration ->
|
||||
.mapTo(mutableSetOf()) { configuration ->
|
||||
val resolvedVariant = resolvedVariantsProvider.getResolvedVariantName(mppModuleIdentifier, configuration)
|
||||
?.let { platformVariantName(it) }
|
||||
?: return@mapNotNullTo null
|
||||
?: return@mapTo null
|
||||
|
||||
firstConfigurationByVariant.putIfAbsent(resolvedVariant, configuration)
|
||||
resolvedVariant
|
||||
@@ -121,11 +121,11 @@ internal class SourceSetVisibilityProvider(
|
||||
.keys.first()
|
||||
}
|
||||
|
||||
someVariantByHostSpecificSourceSet.mapValues { (_, variantName) ->
|
||||
someVariantByHostSpecificSourceSet.entries.mapNotNull { (sourceSetName, variantName) ->
|
||||
val configuration = firstConfigurationByVariant.getValue(variantName)
|
||||
resolvedVariantsProvider.getMetadataArtifactByRootModule(mppModuleIdentifier, configuration)
|
||||
?: error("Couldn't resolve metadata artifact for $mppModuleIdentifier in $configuration")
|
||||
}
|
||||
?.let { sourceSetName to it }
|
||||
}.toMap()
|
||||
}
|
||||
|
||||
return SourceSetVisibilityResult(
|
||||
|
||||
+1
-4
@@ -51,12 +51,9 @@ class KotlinMetadataTargetConfigurator(kotlinPluginVersion: String) :
|
||||
internal fun transformGranularMetadataTaskName(sourceSetName: String) =
|
||||
lowerCamelCaseName("transform", sourceSetName, "DependenciesMetadata")
|
||||
|
||||
// TODO generalize once a general production-test and other kinds of inter-compilation visibility are supported
|
||||
// Currently, this is a temporary ad-hoc mechanism for exposing the commonMain dependencies to the test source sets
|
||||
internal fun dependsOnWithInterCompilationDependencies(project: Project, sourceSet: KotlinSourceSet): Set<KotlinSourceSet> =
|
||||
sourceSet.dependsOn.toMutableSet().apply {
|
||||
if (sourceSet.name == KotlinSourceSet.COMMON_TEST_SOURCE_SET_NAME)
|
||||
add(project.kotlinExtension.sourceSets.getByName(KotlinSourceSet.COMMON_MAIN_SOURCE_SET_NAME))
|
||||
addAll(getVisibleSourceSetsFromAssociateCompilations(project, sourceSet))
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
+7
-6
@@ -21,6 +21,7 @@ import org.gradle.api.Task
|
||||
import org.gradle.api.UnknownTaskException
|
||||
import org.gradle.api.tasks.TaskCollection
|
||||
import org.gradle.api.tasks.TaskProvider
|
||||
import org.jetbrains.kotlin.gradle.plugin.KotlinCompilation
|
||||
import org.jetbrains.kotlin.gradle.plugin.PropertiesProvider
|
||||
import org.jetbrains.kotlin.gradle.plugin.mapKotlinTaskProperties
|
||||
import org.jetbrains.kotlin.gradle.plugin.mpp.AbstractKotlinCompilation
|
||||
@@ -83,7 +84,7 @@ internal open class KotlinTasksProvider(val targetName: String) {
|
||||
open fun registerKotlinJVMTask(
|
||||
project: Project,
|
||||
name: String,
|
||||
compilation: AbstractKotlinCompilation<*>,
|
||||
compilation: KotlinCompilation<*>,
|
||||
configureAction: (KotlinCompile) -> (Unit)
|
||||
): TaskProvider<out KotlinCompile> {
|
||||
val properties = PropertiesProvider(project)
|
||||
@@ -98,7 +99,7 @@ internal open class KotlinTasksProvider(val targetName: String) {
|
||||
fun registerKotlinJSTask(
|
||||
project: Project,
|
||||
name: String,
|
||||
compilation: AbstractKotlinCompilation<*>,
|
||||
compilation: KotlinCompilation<*>,
|
||||
configureAction: (Kotlin2JsCompile) -> Unit
|
||||
): TaskProvider<out Kotlin2JsCompile> {
|
||||
val properties = PropertiesProvider(project)
|
||||
@@ -113,7 +114,7 @@ internal open class KotlinTasksProvider(val targetName: String) {
|
||||
fun registerKotlinJsIrTask(
|
||||
project: Project,
|
||||
name: String,
|
||||
compilation: AbstractKotlinCompilation<*>,
|
||||
compilation: KotlinCompilation<*>,
|
||||
configureAction: (KotlinJsIrLink) -> Unit
|
||||
): TaskProvider<out KotlinJsIrLink> {
|
||||
val properties = PropertiesProvider(project)
|
||||
@@ -128,7 +129,7 @@ internal open class KotlinTasksProvider(val targetName: String) {
|
||||
fun registerKotlinCommonTask(
|
||||
project: Project,
|
||||
name: String,
|
||||
compilation: AbstractKotlinCompilation<*>,
|
||||
compilation: KotlinCompilation<*>,
|
||||
configureAction: (KotlinCompileCommon) -> (Unit)
|
||||
): TaskProvider<out KotlinCompileCommon> {
|
||||
val properties = PropertiesProvider(project)
|
||||
@@ -144,7 +145,7 @@ internal open class KotlinTasksProvider(val targetName: String) {
|
||||
kotlinTaskHolder: TaskProvider<out AbstractKotlinCompile<*>>,
|
||||
project: Project,
|
||||
propertiesProvider: PropertiesProvider,
|
||||
compilation: AbstractKotlinCompilation<*>
|
||||
compilation: KotlinCompilation<*>
|
||||
) {
|
||||
project.runOnceAfterEvaluated("apply properties and language settings to ${kotlinTaskHolder.name}", kotlinTaskHolder) {
|
||||
propertiesProvider.mapKotlinTaskProperties(kotlinTaskHolder.get())
|
||||
@@ -165,7 +166,7 @@ internal class AndroidTasksProvider(targetName: String) : KotlinTasksProvider(ta
|
||||
kotlinTaskHolder: TaskProvider<out AbstractKotlinCompile<*>>,
|
||||
project: Project,
|
||||
propertiesProvider: PropertiesProvider,
|
||||
compilation: AbstractKotlinCompilation<*>
|
||||
compilation: KotlinCompilation<*>
|
||||
) {
|
||||
super.configure(kotlinTaskHolder, project, propertiesProvider, compilation)
|
||||
kotlinTaskHolder.configure {
|
||||
|
||||
Reference in New Issue
Block a user