Fallback for publishing with no Gradle metadata
The following parts of the publications are affected:
* root publication
* with Gradle metadata, it is published and references the
other publications using the `available-at` mechanism
* without metadata opt-in, it is not published
* Kotlin metadata variant
* with Gradle metadata, it is added as an additional variant to the
platform-specific publications to allow the IDE to discover it
* without metadata opt-in, it is added as a dependency to the platform-
specific modules (like in old MPP)
This commit is contained in:
+3
@@ -5,6 +5,7 @@
|
||||
|
||||
package org.jetbrains.kotlin.gradle.dsl
|
||||
|
||||
import org.gradle.api.InvalidUserCodeException
|
||||
import org.gradle.api.NamedDomainObjectCollection
|
||||
import org.jetbrains.kotlin.gradle.plugin.KotlinTarget
|
||||
import org.jetbrains.kotlin.gradle.plugin.KotlinTargetPreset
|
||||
@@ -15,4 +16,6 @@ open class KotlinMultiplatformExtension : KotlinProjectExtension() {
|
||||
|
||||
lateinit var targets: NamedDomainObjectCollection<KotlinTarget>
|
||||
internal set
|
||||
|
||||
internal var isGradleMetadataAvailable: Boolean = false
|
||||
}
|
||||
+4
-2
@@ -18,6 +18,7 @@ package org.jetbrains.kotlin.gradle.plugin
|
||||
|
||||
import org.gradle.api.Plugin
|
||||
import org.gradle.api.Project
|
||||
import org.gradle.api.internal.FeaturePreviews
|
||||
import org.gradle.api.internal.file.FileResolver
|
||||
import org.gradle.api.logging.Logger
|
||||
import org.gradle.api.logging.Logging
|
||||
@@ -132,12 +133,13 @@ open class Kotlin2JsPluginWrapper @Inject constructor(
|
||||
open class KotlinMultiplatformPluginWrapper @Inject constructor(
|
||||
fileResolver: FileResolver,
|
||||
private val instantiator: Instantiator,
|
||||
private val buildOutputCleanupRegistry: BuildOutputCleanupRegistry
|
||||
private val buildOutputCleanupRegistry: BuildOutputCleanupRegistry,
|
||||
private val featurePreviews: FeaturePreviews
|
||||
): KotlinBasePluginWrapper(fileResolver) {
|
||||
override fun getPlugin(project: Project, kotlinGradleBuildServices: KotlinGradleBuildServices): Plugin<Project> =
|
||||
KotlinMultiplatformPlugin(
|
||||
buildOutputCleanupRegistry, fileResolver,
|
||||
instantiator, kotlinPluginVersion
|
||||
instantiator, kotlinPluginVersion, featurePreviews
|
||||
)
|
||||
|
||||
override val projectExtensionClass: KClass<out KotlinMultiplatformExtension>
|
||||
|
||||
+17
-3
@@ -11,12 +11,14 @@ import org.gradle.api.Plugin
|
||||
import org.gradle.api.Project
|
||||
import org.gradle.api.attributes.Attribute
|
||||
import org.gradle.api.attributes.AttributeContainer
|
||||
import org.gradle.api.internal.FeaturePreviews
|
||||
import org.gradle.api.internal.file.FileResolver
|
||||
import org.gradle.api.internal.plugins.DslObject
|
||||
import org.gradle.api.plugins.JavaBasePlugin
|
||||
import org.gradle.api.publish.PublishingExtension
|
||||
import org.gradle.api.publish.maven.MavenPublication
|
||||
import org.gradle.api.publish.maven.internal.publication.MavenPublicationInternal
|
||||
import org.gradle.api.publish.maven.tasks.AbstractPublishToMaven
|
||||
import org.gradle.internal.cleanup.BuildOutputCleanupRegistry
|
||||
import org.gradle.internal.reflect.Instantiator
|
||||
import org.gradle.jvm.tasks.Jar
|
||||
@@ -34,7 +36,8 @@ class KotlinMultiplatformPlugin(
|
||||
private val buildOutputCleanupRegistry: BuildOutputCleanupRegistry,
|
||||
private val fileResolver: FileResolver,
|
||||
private val instantiator: Instantiator,
|
||||
private val kotlinPluginVersion: String
|
||||
private val kotlinPluginVersion: String,
|
||||
private val featurePreviews: FeaturePreviews // TODO get rid of this internal API usage once we don't need it
|
||||
) : Plugin<Project> {
|
||||
|
||||
private class TargetFromPresetExtension(val targetsContainer: NamedDomainObjectCollection<KotlinTarget>) {
|
||||
@@ -64,6 +67,11 @@ class KotlinMultiplatformPlugin(
|
||||
|
||||
presets = project.container(KotlinTargetPreset::class.java)
|
||||
addExtension("presets", presets)
|
||||
|
||||
isGradleMetadataAvailable =
|
||||
featurePreviews.activeFeatures.find { it.name == "GRADLE_METADATA" }?.let { metadataFeature ->
|
||||
featurePreviews.isFeatureEnabled(metadataFeature)
|
||||
} ?: true // the feature entry will be gone once the feature is stable
|
||||
}
|
||||
|
||||
setupDefaultPresets(project)
|
||||
@@ -98,8 +106,9 @@ class KotlinMultiplatformPlugin(
|
||||
val kotlinSoftwareComponent = KotlinSoftwareComponent(project, "kotlin", targets)
|
||||
|
||||
project.extensions.configure(PublishingExtension::class.java) { publishing ->
|
||||
// The root publication.
|
||||
publishing.publications.create("kotlinMultiplatform", MavenPublication::class.java).apply {
|
||||
|
||||
// The root publication that references the platform specific publications as its variants:
|
||||
val rootPublication = publishing.publications.create("kotlinMultiplatform", MavenPublication::class.java).apply {
|
||||
from(kotlinSoftwareComponent)
|
||||
(this as MavenPublicationInternal).publishWithOriginalFileName()
|
||||
artifactId = project.name
|
||||
@@ -107,6 +116,11 @@ class KotlinMultiplatformPlugin(
|
||||
version = project.version.toString()
|
||||
}
|
||||
|
||||
// Publish the root publication only if Gradle metadata publishing is enabled:
|
||||
project.tasks.withType(AbstractPublishToMaven::class.java).all { publishTask ->
|
||||
publishTask.onlyIf { publishTask.publication != rootPublication || project.multiplatformExtension!!.isGradleMetadataAvailable }
|
||||
}
|
||||
|
||||
// Create separate publications for all publishable targets
|
||||
targets.matching { it.publishable }.all { target ->
|
||||
val variant = target.component as KotlinVariant
|
||||
|
||||
+8
-5
@@ -6,15 +6,16 @@
|
||||
package org.jetbrains.kotlin.gradle.plugin.mpp
|
||||
|
||||
import org.gradle.api.Project
|
||||
import org.gradle.api.artifacts.*
|
||||
import org.gradle.api.artifacts.Configuration
|
||||
import org.gradle.api.artifacts.DependencyConstraint
|
||||
import org.gradle.api.artifacts.ModuleDependency
|
||||
import org.gradle.api.artifacts.PublishArtifact
|
||||
import org.gradle.api.attributes.AttributeContainer
|
||||
import org.gradle.api.attributes.Usage
|
||||
import org.gradle.api.capabilities.Capability
|
||||
import org.gradle.api.component.ComponentWithCoordinates
|
||||
import org.gradle.api.component.ComponentWithVariants
|
||||
import org.gradle.api.internal.component.SoftwareComponentInternal
|
||||
import org.gradle.api.internal.component.UsageContext
|
||||
import org.gradle.api.publish.maven.MavenPublication
|
||||
import org.jetbrains.kotlin.gradle.plugin.KotlinTarget
|
||||
import org.jetbrains.kotlin.gradle.plugin.KotlinTargetComponent
|
||||
import org.jetbrains.kotlin.gradle.plugin.usageByName
|
||||
@@ -40,11 +41,13 @@ object NativeUsage {
|
||||
}
|
||||
|
||||
internal class KotlinPlatformUsageContext(
|
||||
val project: Project,
|
||||
val kotlinTarget: KotlinTarget,
|
||||
private val usage: Usage,
|
||||
val dependencyConfigurationName: String
|
||||
val dependencyConfigurationName: String,
|
||||
private val publishWithGradleMetadata: Boolean
|
||||
) : UsageContext {
|
||||
private val project: Project get() = kotlinTarget.project
|
||||
|
||||
override fun getUsage(): Usage = usage
|
||||
|
||||
override fun getName(): String = kotlinTarget.targetName + when (dependencyConfigurationName) {
|
||||
|
||||
+34
-10
@@ -19,6 +19,8 @@ import org.gradle.api.plugins.JavaPlugin
|
||||
import org.gradle.api.publish.maven.MavenPublication
|
||||
import org.gradle.util.ConfigureUtil
|
||||
import org.gradle.util.WrapUtil
|
||||
import org.jetbrains.kotlin.gradle.dsl.KotlinMultiplatformExtension
|
||||
import org.jetbrains.kotlin.gradle.dsl.kotlinExtension
|
||||
import org.jetbrains.kotlin.gradle.plugin.*
|
||||
import org.jetbrains.kotlin.gradle.utils.isGradleVersionAtLeast
|
||||
import org.jetbrains.kotlin.gradle.utils.lowerCamelCaseName
|
||||
@@ -49,28 +51,50 @@ abstract class AbstractKotlinTarget (
|
||||
get() = true
|
||||
|
||||
override val component: KotlinTargetComponent by lazy {
|
||||
if (isGradleVersionAtLeast(4, 7))
|
||||
KotlinVariantWithCoordinates(this)
|
||||
else
|
||||
if (isGradleVersionAtLeast(4, 7)) {
|
||||
createKotlinTargetComponent()
|
||||
} else {
|
||||
KotlinVariant(this)
|
||||
}
|
||||
}
|
||||
|
||||
private fun createKotlinTargetComponent(): KotlinTargetComponent {
|
||||
val kotlinExtension = project.kotlinExtension as? KotlinMultiplatformExtension
|
||||
?: return KotlinVariantWithCoordinates(this)
|
||||
|
||||
if (targetName == KotlinMultiplatformPlugin.METADATA_TARGET_NAME)
|
||||
return KotlinVariantWithCoordinates(this)
|
||||
|
||||
val separateMetadataTarget = kotlinExtension.targets.getByName(KotlinMultiplatformPlugin.METADATA_TARGET_NAME)
|
||||
|
||||
return if (kotlinExtension.isGradleMetadataAvailable) {
|
||||
KotlinVariantWithMetadataVariant(this, separateMetadataTarget)
|
||||
} else {
|
||||
// we should only add the Kotlin metadata dependency if we publish no Gradle metadata related to Kotlin MPP;
|
||||
// with metadata, such a dependency would get invalid, since a platform module should only depend on modules for that
|
||||
// same platform, not Kotlin metadata modules
|
||||
KotlinVariantWithMetadataDependency(this, separateMetadataTarget)
|
||||
}
|
||||
}
|
||||
|
||||
override fun createUsageContexts(): Set<UsageContext> {
|
||||
val publishWithKotlinMetadata = (project.kotlinExtension as? KotlinMultiplatformExtension)?.isGradleMetadataAvailable
|
||||
?: true // In non-MPP project, these usage contexts do not get published anyway
|
||||
|
||||
// Here, `JAVA_API` and `JAVA_RUNTIME_JARS` are used intentionally as Gradle needs this for
|
||||
// ordering of the usage contexts (prioritizing the dependencies);
|
||||
// These Java usages should not be replaced with the custom Kotlin usages.
|
||||
|
||||
return listOfNotNull(
|
||||
KotlinPlatformUsageContext(
|
||||
project, this, project.usageByName(JAVA_API),
|
||||
apiElementsConfigurationName
|
||||
this, project.usageByName(JAVA_API),
|
||||
apiElementsConfigurationName, publishWithKotlinMetadata
|
||||
),
|
||||
if (compilations.getByName(KotlinCompilation.MAIN_COMPILATION_NAME) is KotlinCompilationToRunnableFiles)
|
||||
if (compilations.getByName(KotlinCompilation.MAIN_COMPILATION_NAME) is KotlinCompilationToRunnableFiles) {
|
||||
KotlinPlatformUsageContext(
|
||||
project, this, project.usageByName(JAVA_RUNTIME_JARS),
|
||||
runtimeElementsConfigurationName
|
||||
this, project.usageByName(JAVA_RUNTIME_JARS),
|
||||
runtimeElementsConfigurationName, publishWithKotlinMetadata
|
||||
)
|
||||
else null
|
||||
} else null
|
||||
).toSet()
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user