Publish MPP -metadata artifact in the root module, drop separate module
Until now, there was a separate module foo-metadata that contained the Kotlin metadata artifacts. The reasons for this were only historical, namely the platform modules used to depend on the metadata module and expect it to bring the common sources to the IDE. Now we don't really need the -metadata module, and it's now more harm from it than good, as users never need to specify it as a dependency. We fix this by removing the -metadata module from the default publishing layout and putting the -metadata artifact(-s) directly to the root module.
This commit is contained in:
+13
-5
@@ -253,7 +253,7 @@ class HierarchicalMppIT : BaseGradleIT() {
|
||||
|
||||
ZipFile(
|
||||
project.projectDir.parentFile.resolve(
|
||||
"repo/com/example/foo/my-lib-foo-metadata/1.0/my-lib-foo-metadata-1.0-all.jar"
|
||||
"repo/com/example/foo/my-lib-foo/1.0/my-lib-foo-1.0-all.jar"
|
||||
)
|
||||
).use { publishedMetadataJar ->
|
||||
publishedMetadataJar.checkAllEntryNamesArePresent(
|
||||
@@ -291,7 +291,7 @@ class HierarchicalMppIT : BaseGradleIT() {
|
||||
|
||||
ZipFile(
|
||||
project.projectDir.parentFile.resolve(
|
||||
"repo/com/example/bar/my-lib-bar-metadata/1.0/my-lib-bar-metadata-1.0-all.jar"
|
||||
"repo/com/example/bar/my-lib-bar/1.0/my-lib-bar-1.0-all.jar"
|
||||
)
|
||||
).use { publishedMetadataJar ->
|
||||
publishedMetadataJar.checkAllEntryNamesArePresent(
|
||||
@@ -420,14 +420,21 @@ class HierarchicalMppIT : BaseGradleIT() {
|
||||
val compilerArgsLine = taskOutput.lines().single { "Kotlin compiler args:" in it }
|
||||
val classpathItems = compilerArgsLine.substringAfter("-classpath").substringBefore(" -").split(File.pathSeparator)
|
||||
|
||||
val actualClasspath = classpathItems.joinToString("\n")
|
||||
|
||||
shouldInclude.forEach { (module, sourceSet) ->
|
||||
assertTrue("expected module '$module' source set '$sourceSet' on the classpath of task $taskPath") {
|
||||
assertTrue(
|
||||
"expected module '$module' source set '$sourceSet' on the classpath of task $taskPath. Actual classpath:\n$actualClasspath"
|
||||
) {
|
||||
classpathItems.any { module in it && it.contains(sourceSet, ignoreCase = true) }
|
||||
}
|
||||
}
|
||||
|
||||
shouldNotInclude.forEach { (module, sourceSet) ->
|
||||
assertTrue("not expected module '$module' source set '$sourceSet' on the compile classpath of task $taskPath") {
|
||||
assertTrue(
|
||||
"not expected module '$module' source set '$sourceSet' on the compile classpath of task $taskPath. " +
|
||||
"Actual classpath:\n$actualClasspath"
|
||||
) {
|
||||
classpathItems.none { module in it && it.contains(sourceSet, ignoreCase = true) }
|
||||
}
|
||||
}
|
||||
@@ -469,7 +476,8 @@ class HierarchicalMppIT : BaseGradleIT() {
|
||||
}.toSet()
|
||||
},
|
||||
hostSpecificSourceSets = emptySet(),
|
||||
sourceSetBinaryLayout = sourceSetModuleDependencies.mapValues { SourceSetMetadataLayout.KLIB }
|
||||
sourceSetBinaryLayout = sourceSetModuleDependencies.mapValues { SourceSetMetadataLayout.KLIB },
|
||||
isPublishedAsRoot = true
|
||||
)
|
||||
}
|
||||
|
||||
|
||||
+5
-5
@@ -93,10 +93,10 @@ class KlibBasedMppIT : BaseGradleIT() {
|
||||
checkTaskCompileClasspath(
|
||||
"compile${hostSpecificSourceSet.capitalize()}KotlinMetadata",
|
||||
listOf(
|
||||
"published-producer-metadata-$hostSpecificSourceSet.klib",
|
||||
"published-producer-metadata-commonMain.klib",
|
||||
"published-dependency-metadata-$hostSpecificSourceSet.klib",
|
||||
"published-dependency-metadata-commonMain.klib"
|
||||
"published-producer-$hostSpecificSourceSet.klib",
|
||||
"published-producer-commonMain.klib",
|
||||
"published-dependency-$hostSpecificSourceSet.klib",
|
||||
"published-dependency-commonMain.klib"
|
||||
)
|
||||
)
|
||||
}
|
||||
@@ -209,7 +209,7 @@ class KlibBasedMppIT : BaseGradleIT() {
|
||||
// Check that the metadata JAR doesn't contain the host-specific source set entries, but contains the shared-Native source set
|
||||
// that can be built on every host:
|
||||
|
||||
ZipFile(groupDir.resolve("$dependencyModuleName-metadata/1.0/$dependencyModuleName-metadata-1.0-all.jar")).use { metadataJar ->
|
||||
ZipFile(groupDir.resolve("$dependencyModuleName/1.0/$dependencyModuleName-1.0-all.jar")).use { metadataJar ->
|
||||
assertTrue { metadataJar.entries().asSequence().none { it.name.startsWith(hostSpecificSourceSet) } }
|
||||
assertTrue { metadataJar.entries().asSequence().any { it.name.startsWith("linuxMain") } }
|
||||
}
|
||||
|
||||
+4
-5
@@ -105,7 +105,7 @@ class NewMultiplatformIT : BaseGradleIT() {
|
||||
val jvmJarName = "sample-lib-jvm6/1.0/sample-lib-jvm6-1.0.jar"
|
||||
val jsExtension = "jar"
|
||||
val jsJarName = "sample-lib-nodejs/1.0/sample-lib-nodejs-1.0.$jsExtension"
|
||||
val metadataJarName = "sample-lib-metadata/1.0/sample-lib-metadata-1.0.jar"
|
||||
val metadataJarName = "sample-lib/1.0/sample-lib-1.0.jar"
|
||||
val wasmKlibName = "sample-lib-wasm32/1.0/sample-lib-wasm32-1.0.klib"
|
||||
val nativeKlibName = "sample-lib-$nativeHostTargetName/1.0/sample-lib-$nativeHostTargetName-1.0.klib"
|
||||
|
||||
@@ -116,7 +116,7 @@ class NewMultiplatformIT : BaseGradleIT() {
|
||||
val gradleMetadata = groupDir.resolve("sample-lib/1.0/sample-lib-1.0.module").readText()
|
||||
assertFalse(gradleMetadata.contains(ProjectLocalConfigurations.ATTRIBUTE.name))
|
||||
|
||||
listOf(jvmJarName, jsJarName, metadataJarName, wasmKlibName, nativeKlibName).forEach {
|
||||
listOf(jvmJarName, jsJarName, wasmKlibName, nativeKlibName).forEach {
|
||||
val pom = groupDir.resolve(it.replaceAfterLast('.', "pom"))
|
||||
Assert.assertTrue(
|
||||
"$pom should contain a name section.",
|
||||
@@ -325,7 +325,7 @@ class NewMultiplatformIT : BaseGradleIT() {
|
||||
val groupDir = projectDir.resolve("repo/com/example")
|
||||
val jsExtension = if (jsCompilerType == LEGACY) "jar" else "klib"
|
||||
val jsJarName = "sample-lib-nodejs/1.0/sample-lib-nodejs-1.0.$jsExtension"
|
||||
val metadataJarName = "sample-lib-metadata/1.0/sample-lib-metadata-1.0.jar"
|
||||
val metadataJarName = "sample-lib/1.0/sample-lib-1.0.jar"
|
||||
|
||||
listOf(jsJarName, metadataJarName, "sample-lib/1.0/sample-lib-1.0.module").forEach {
|
||||
Assert.assertTrue("$it should exist", groupDir.resolve(it).exists())
|
||||
@@ -334,7 +334,7 @@ class NewMultiplatformIT : BaseGradleIT() {
|
||||
val gradleMetadata = groupDir.resolve("sample-lib/1.0/sample-lib-1.0.module").readText()
|
||||
assertFalse(gradleMetadata.contains(ProjectLocalConfigurations.ATTRIBUTE.name))
|
||||
|
||||
listOf(jsJarName, metadataJarName).forEach {
|
||||
jsJarName.let {
|
||||
val pom = groupDir.resolve(it.replaceAfterLast('.', "pom"))
|
||||
Assert.assertTrue(
|
||||
"$pom should contain a name section.",
|
||||
@@ -998,7 +998,6 @@ class NewMultiplatformIT : BaseGradleIT() {
|
||||
with(Project("sample-old-style-app", gradleVersion, "new-mpp-lib-and-app")) {
|
||||
setupWorkingDir()
|
||||
gradleBuildScript().appendText("\nallprojects { repositories { maven { url '${repoDir.toURI()}' } } }")
|
||||
gradleBuildScript("app-common").modify { it.replace("com.example:sample-lib:", "com.example:sample-lib-metadata:") }
|
||||
gradleBuildScript("app-jvm").modify { it.replace("com.example:sample-lib:", "com.example:sample-lib-jvm6:") }
|
||||
gradleBuildScript("app-js").modify { it.replace("com.example:sample-lib:", "com.example:sample-lib-nodejs:") }
|
||||
|
||||
|
||||
+1
-1
@@ -246,7 +246,7 @@ internal class GranularMetadataTransformation(
|
||||
SourceSetVisibilityProvider(project).getVisibleSourceSets(
|
||||
kotlinSourceSet,
|
||||
sourceSetRequestedScopes,
|
||||
parent, module,
|
||||
if (projectStructureMetadata.isPublishedAsRoot) module else parent, module,
|
||||
projectStructureMetadata,
|
||||
resolvedToProject
|
||||
)
|
||||
|
||||
+3
-1
@@ -65,7 +65,9 @@ open class KotlinMetadataTarget @Inject constructor(project: Project) :
|
||||
}
|
||||
|
||||
val component =
|
||||
createKotlinVariant(targetName, compilations.getByName(KotlinCompilation.MAIN_COMPILATION_NAME), usageContexts)
|
||||
createKotlinVariant(targetName, compilations.getByName(KotlinCompilation.MAIN_COMPILATION_NAME), usageContexts).apply {
|
||||
publishable = false // this component is not published on its own, its variants are included in the 'root' module
|
||||
}
|
||||
|
||||
val sourcesJarTask =
|
||||
sourcesJarTask(project, lazy { project.kotlinExtension.sourceSets.toSet() }, null, targetName.toLowerCase())
|
||||
|
||||
+4
-1
@@ -195,10 +195,13 @@ class KotlinMultiplatformPlugin(
|
||||
project.extensions.configure(PublishingExtension::class.java) { publishing ->
|
||||
|
||||
// The root publication that references the platform specific publications as its variants:
|
||||
val rootPublication = publishing.publications.create("kotlinMultiplatform", MavenPublication::class.java).apply {
|
||||
publishing.publications.create("kotlinMultiplatform", MavenPublication::class.java).apply {
|
||||
from(kotlinSoftwareComponent)
|
||||
(this as MavenPublicationInternal).publishWithOriginalFileName()
|
||||
kotlinSoftwareComponent.publicationDelegate = this@apply
|
||||
|
||||
project.multiplatformExtension.metadata {}.kotlinComponents.filterIsInstance<KotlinTargetComponentWithPublication>()
|
||||
.single().publicationDelegate = this@apply
|
||||
}
|
||||
|
||||
// Enforce the order of creating the publications, since the metadata publication is used in the other publications:
|
||||
|
||||
+14
-2
@@ -68,8 +68,11 @@ data class KotlinProjectStructureMetadata(
|
||||
@Input
|
||||
val hostSpecificSourceSets: Set<String>,
|
||||
|
||||
@get:Input
|
||||
val isPublishedAsRoot: Boolean,
|
||||
|
||||
@Input
|
||||
val formatVersion: String = FORMAT_VERSION_0_3
|
||||
val formatVersion: String = FORMAT_VERSION_0_3_1
|
||||
) {
|
||||
@Suppress("UNUSED") // Gradle input
|
||||
@get:Input
|
||||
@@ -84,6 +87,9 @@ data class KotlinProjectStructureMetadata(
|
||||
|
||||
// + 'hostSpecific' flag for source sets
|
||||
internal const val FORMAT_VERSION_0_3 = "0.3"
|
||||
|
||||
// + 'isPublishedInRootModule' top-level flag
|
||||
internal const val FORMAT_VERSION_0_3_1 = "0.3.1"
|
||||
}
|
||||
}
|
||||
|
||||
@@ -122,7 +128,8 @@ internal fun buildKotlinProjectStructureMetadata(project: Project): KotlinProjec
|
||||
hostSpecificSourceSets = getHostSpecificSourceSets(project).map { it.name }.toSet(),
|
||||
sourceSetBinaryLayout = sourceSetsWithMetadataCompilations.keys.associate { sourceSet ->
|
||||
sourceSet.name to SourceSetMetadataLayout.chooseForProducingProject(project)
|
||||
}
|
||||
},
|
||||
isPublishedAsRoot = true
|
||||
)
|
||||
}
|
||||
|
||||
@@ -137,6 +144,8 @@ internal fun <Serializer> KotlinProjectStructureMetadata.serialize(
|
||||
node(ROOT_NODE_NAME) {
|
||||
value(FORMAT_VERSION_NODE_NAME, formatVersion)
|
||||
|
||||
value(PUBLISHED_AS_ROOT_NAME, isPublishedAsRoot.toString())
|
||||
|
||||
multiNodes(VARIANTS_NODE_NAME) {
|
||||
sourceSetNamesByVariantName.forEach { (variantName, sourceSets) ->
|
||||
multiNodesItem(VARIANT_NODE_NAME) {
|
||||
@@ -232,6 +241,7 @@ internal fun <ParsingContext> parseKotlinSourceSetMetadata(
|
||||
val formatVersion = checkNotNull(projectStructureNode.valueNamed(FORMAT_VERSION_NODE_NAME))
|
||||
val variantsNode = projectStructureNode.multiObjects(VARIANTS_NODE_NAME)
|
||||
|
||||
val isPublishedAsRoot = projectStructureNode.valueNamed(PUBLISHED_AS_ROOT_NAME)?.toBoolean() ?: false
|
||||
val sourceSetsByVariant = mutableMapOf<String, Set<String>>()
|
||||
|
||||
variantsNode.forEach { variantNode ->
|
||||
@@ -274,11 +284,13 @@ internal fun <ParsingContext> parseKotlinSourceSetMetadata(
|
||||
sourceSetBinaryLayout,
|
||||
sourceSetModuleDependencies,
|
||||
hostSpecificSourceSets,
|
||||
isPublishedAsRoot,
|
||||
formatVersion
|
||||
)
|
||||
}
|
||||
|
||||
private const val ROOT_NODE_NAME = "projectStructure"
|
||||
private const val PUBLISHED_AS_ROOT_NAME = "isPublishedAsRoot"
|
||||
private const val FORMAT_VERSION_NODE_NAME = "formatVersion"
|
||||
private const val VARIANTS_NODE_NAME = "variants"
|
||||
private const val VARIANT_NODE_NAME = "variant"
|
||||
|
||||
+5
-2
@@ -26,10 +26,13 @@ abstract class KotlinSoftwareComponent(
|
||||
protected val kotlinTargets: Iterable<KotlinTarget>
|
||||
) : SoftwareComponentInternal, ComponentWithVariants {
|
||||
|
||||
override fun getUsages(): Set<UsageContext> = emptySet()
|
||||
private val metadataTarget: KotlinMetadataTarget
|
||||
get() = kotlinTargets.filterIsInstance<KotlinMetadataTarget>().single()
|
||||
|
||||
override fun getUsages(): Set<UsageContext> = (metadataTarget.components.single() as SoftwareComponentInternal).usages
|
||||
|
||||
override fun getVariants(): Set<SoftwareComponent> =
|
||||
kotlinTargets.flatMap { it.components }.toSet()
|
||||
kotlinTargets.minus(metadataTarget).flatMap { it.components }.toSet()
|
||||
|
||||
override fun getName(): String = name
|
||||
|
||||
|
||||
+1
-2
@@ -37,8 +37,7 @@ internal class SourceSetVisibilityProvider(
|
||||
* Determine which source sets of the [resolvedRootMppDependency] are visible in the [visibleFrom] source set.
|
||||
*
|
||||
* This requires resolving dependencies of the compilations which [visibleFrom] takes part in, in order to find which variants the
|
||||
* [resolvedRootMppDependency] got resolved to for those compilations. The [resolvedRootMppDependency] should therefore be the dependency
|
||||
* on the 'root' module of the MPP (such as 'com.example:lib-foo', not 'com.example:lib-foo-metadata').
|
||||
* [resolvedRootMppDependency] got resolved to for those compilations.
|
||||
*
|
||||
* Once the variants are known, they are checked against the [dependencyProjectStructureMetadata], and the
|
||||
* source sets of the dependency are determined that are compiled for all those variants and thus should be visible here.
|
||||
|
||||
+8
-13
@@ -125,19 +125,14 @@ abstract class AbstractKotlinTarget(
|
||||
|
||||
adhocVariant as SoftwareComponent
|
||||
|
||||
if (kotlinVariant is KotlinVariantWithMetadataVariant) {
|
||||
object : ComponentWithVariants, ComponentWithCoordinates, SoftwareComponentInternal {
|
||||
override fun getCoordinates() = kotlinVariant.coordinates
|
||||
override fun getVariants(): Set<out SoftwareComponent> = kotlinVariant.variants
|
||||
override fun getName(): String = adhocVariant.name
|
||||
override fun getUsages(): MutableSet<out UsageContext> = (adhocVariant as SoftwareComponentInternal).usages
|
||||
}
|
||||
} else {
|
||||
object : ComponentWithCoordinates, SoftwareComponentInternal {
|
||||
override fun getCoordinates() = (kotlinVariant as? ComponentWithCoordinates)?.coordinates
|
||||
override fun getName(): String = adhocVariant.name
|
||||
override fun getUsages(): MutableSet<out UsageContext> = (adhocVariant as SoftwareComponentInternal).usages
|
||||
}
|
||||
object : ComponentWithVariants, ComponentWithCoordinates, SoftwareComponentInternal {
|
||||
override fun getCoordinates() = (kotlinVariant as? ComponentWithCoordinates)?.coordinates
|
||||
|
||||
override fun getVariants(): Set<out SoftwareComponent> =
|
||||
(kotlinVariant as? KotlinVariantWithMetadataVariant)?.variants.orEmpty()
|
||||
|
||||
override fun getName(): String = adhocVariant.name
|
||||
override fun getUsages(): MutableSet<out UsageContext> = (adhocVariant as SoftwareComponentInternal).usages
|
||||
}
|
||||
}.toSet()
|
||||
}
|
||||
|
||||
+2
-3
@@ -69,8 +69,7 @@ open class KotlinVariant(
|
||||
|
||||
override fun getName(): String = componentName ?: producingCompilation.target.targetName
|
||||
|
||||
override val publishable: Boolean
|
||||
get() = target.publishable
|
||||
override var publishable: Boolean = target.publishable
|
||||
|
||||
override var sourcesArtifacts: Set<PublishArtifact> = emptySet()
|
||||
internal set
|
||||
@@ -102,7 +101,7 @@ class JointAndroidKotlinTargetComponent(
|
||||
private val nestedVariants: Set<KotlinVariant>,
|
||||
val flavorNames: List<String>,
|
||||
override val sourcesArtifacts: Set<PublishArtifact>
|
||||
) : KotlinTargetComponentWithCoordinatesAndPublication, SoftwareComponentInternal {
|
||||
) : KotlinTargetComponentWithCoordinatesAndPublication, SoftwareComponentInternal {
|
||||
|
||||
override fun getUsages(): Set<KotlinUsageContext> = nestedVariants.flatMap { it.usages }.toSet()
|
||||
|
||||
|
||||
-2
@@ -143,8 +143,6 @@ class KotlinMetadataTargetConfigurator(kotlinPluginVersion: String) :
|
||||
allMetadataJar.description = "Assembles a jar archive containing the metadata for all Kotlin source sets."
|
||||
allMetadataJar.group = BasePlugin.BUILD_GROUP
|
||||
|
||||
allMetadataJar.archiveAppendix.set(target.name.toLowerCase())
|
||||
|
||||
if (target.project.isCompatibilityMetadataVariantEnabled) {
|
||||
allMetadataJar.archiveClassifier.set("all")
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user