Add publishing configurator, call it from the variant factories
This commit is contained in:
+5
-1
@@ -50,10 +50,14 @@ interface KotlinNativeVariant : KotlinGradleVariant {
|
||||
override val platformType: KotlinPlatformType
|
||||
get() = KotlinPlatformType.native
|
||||
|
||||
/** A configuration name for the metadata of the host-specific fragments which this variant includes,
|
||||
* if applies to this Native variant; null otherwise */
|
||||
val hostSpecificMetadataElementsConfigurationName: String?
|
||||
|
||||
var enableEndorsedLibraries: Boolean
|
||||
}
|
||||
|
||||
interface SingleMavenPublicationHolder {
|
||||
interface SingleMavenPublishedModuleHolder {
|
||||
fun assignMavenPublication(publication: MavenPublication)
|
||||
val defaultPublishedModuleSuffix: String?
|
||||
val publishedMavenModuleCoordinates: PublishedModuleCoordinatesProvider
|
||||
|
||||
+7
-1
@@ -19,7 +19,10 @@ open class KotlinNativeVariantInternal(
|
||||
val konanTarget: KonanTarget
|
||||
) : KotlinNativeVariant,
|
||||
KotlinGradleVariantInternal(containingModule, fragmentName),
|
||||
SingleMavenPublicationHolder by DefaultSingleMavenPublicationHolder(containingModule, fragmentName) {
|
||||
SingleMavenPublishedModuleHolder by DefaultSingleMavenPublishedModuleHolder(containingModule, fragmentName) {
|
||||
|
||||
final override val hostSpecificMetadataElementsConfigurationName: String?
|
||||
get() = disambiguateName("hostSpecificMetadataElements").takeIf { includesHostSpecificMetadata }
|
||||
|
||||
override var enableEndorsedLibraries: Boolean = false
|
||||
|
||||
@@ -33,6 +36,9 @@ open class KotlinNativeVariantInternal(
|
||||
internal val compilationData by lazy { KotlinNativeVariantCompilationData(this) }
|
||||
}
|
||||
|
||||
internal val KotlinNativeVariantInternal.includesHostSpecificMetadata: Boolean
|
||||
get() = isHostSpecificKonanTargetsSet(setOf(konanTarget))
|
||||
|
||||
// FIXME codegen
|
||||
open class KotlinLinuxX64Variant @Inject constructor(containingModule: KotlinGradleModule, fragmentName: String) :
|
||||
KotlinNativeVariantInternal(containingModule, fragmentName, KonanTarget.LINUX_X64)
|
||||
|
||||
+10
-59
@@ -49,6 +49,7 @@ open class KotlinNativeVariantFactory<T : KotlinNativeVariantInternal>(
|
||||
|
||||
override fun create(name: String): T =
|
||||
super.create(name).also { result ->
|
||||
configureHostSpecificMetadata(result)
|
||||
configureVariantPublishing(result)
|
||||
}
|
||||
|
||||
@@ -80,22 +81,10 @@ open class KotlinNativeVariantFactory<T : KotlinNativeVariantInternal>(
|
||||
}
|
||||
}
|
||||
|
||||
open fun configureVariantPublishing(variant: T) {
|
||||
val rootSoftwareComponent =
|
||||
project.components
|
||||
.withType(AdhocComponentWithVariants::class.java)
|
||||
.getByName(rootPublicationComponentName(module))
|
||||
private fun configureHostSpecificMetadata(variant: T) {
|
||||
val hostSpecificConfigurationNameIfEnabled = variant.hostSpecificMetadataElementsConfigurationName
|
||||
?: return
|
||||
|
||||
val platformModuleDependencyProvider = project.provider {
|
||||
val coordinates = variant.publishedMavenModuleCoordinates
|
||||
(project.dependencies.create("${coordinates.group}:${coordinates.name}:${coordinates.version}") as ModuleDependency).apply {
|
||||
if (module.moduleClassifier != null) {
|
||||
capabilities { it.requireCapability(CalculatedCapability.fromModule(module)) }
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
val apiElements = project.configurations.getByName(variant.apiElementsConfigurationName)
|
||||
val hostSpecificMetadataJar = project.registerTask<Jar>(variant.disambiguateName("hostSpecificMetadataJar")) { jar ->
|
||||
jar.archiveClassifier.set("metadata")
|
||||
jar.archiveAppendix.set(variant.disambiguateName(""))
|
||||
@@ -103,7 +92,7 @@ open class KotlinNativeVariantFactory<T : KotlinNativeVariantInternal>(
|
||||
.withAll { metadataCompilation ->
|
||||
val fragment = metadataCompilation.fragment
|
||||
if (metadataCompilation is KotlinNativeFragmentMetadataCompilationData) {
|
||||
jar.from(project.files(Callable {
|
||||
jar.from(project.files(project.provider {
|
||||
if (fragment in variant.refinesClosure && fragment.isNativeHostSpecific())
|
||||
project.filesWithUnpackedArchives(metadataCompilation.output.allOutputs, setOf(KLIB_FILE_EXTENSION))
|
||||
else emptyList<Any>()
|
||||
@@ -111,7 +100,8 @@ open class KotlinNativeVariantFactory<T : KotlinNativeVariantInternal>(
|
||||
}
|
||||
}
|
||||
}
|
||||
val hostSpecificMetadataElements = project.configurations.create(variant.hostSpecificMetadataConfigurationName).apply {
|
||||
val apiElements = project.configurations.getByName(variant.apiElementsConfigurationName)
|
||||
project.configurations.create(hostSpecificConfigurationNameIfEnabled).apply {
|
||||
isCanBeResolved = false
|
||||
isCanBeConsumed = false
|
||||
setPlatformAttributesAndMetadataUsage(variant)
|
||||
@@ -120,49 +110,10 @@ open class KotlinNativeVariantFactory<T : KotlinNativeVariantInternal>(
|
||||
set(project.provider { apiElements.allDependencies })
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
// FIXME inject vs internal API
|
||||
val platformComponentName = platformComponentName(variant)
|
||||
val platformComponent = (project as ProjectInternal).services
|
||||
.get(SoftwareComponentFactory::class.java)
|
||||
.adhoc(platformComponentName)
|
||||
project.components.add(platformComponent)
|
||||
platformComponent.addVariantsFromConfiguration(apiElements) {
|
||||
it.mapToMavenScope("compile")
|
||||
}
|
||||
platformComponent.addVariantsFromConfiguration(hostSpecificMetadataElements) { }
|
||||
|
||||
module.ifMadePublic {
|
||||
project.pluginManager.withPlugin("maven-publish") {
|
||||
project.extensions.getByType(PublishingExtension::class.java).apply {
|
||||
publications.create(platformComponentName, MavenPublication::class.java).apply {
|
||||
(this as DefaultMavenPublication).isAlias = true
|
||||
from(platformComponent)
|
||||
variant.assignMavenPublication(this)
|
||||
artifactId = dashSeparatedName(project.name, variant.defaultPublishedModuleSuffix)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
val publishedApiConfiguration =
|
||||
project.configurations.create(publishedConfigurationName(variant.apiElementsConfigurationName)).apply {
|
||||
isCanBeConsumed = false
|
||||
isCanBeResolved = false
|
||||
configureApiElementsConfiguration(variant, this)
|
||||
setModuleCapability(this, module)
|
||||
dependencies.addLater(platformModuleDependencyProvider)
|
||||
}
|
||||
val publishedMetadataConfiguration =
|
||||
project.configurations.create(publishedConfigurationName(variant.hostSpecificMetadataConfigurationName)).apply {
|
||||
isCanBeConsumed = false
|
||||
isCanBeResolved = false
|
||||
setPlatformAttributesAndMetadataUsage(variant)
|
||||
setModuleCapability(this, module)
|
||||
dependencies.addLater(platformModuleDependencyProvider)
|
||||
}
|
||||
rootSoftwareComponent.addVariantsFromConfiguration(publishedApiConfiguration) { }
|
||||
rootSoftwareComponent.addVariantsFromConfiguration(publishedMetadataConfiguration) { }
|
||||
open fun configureVariantPublishing(variant: T) {
|
||||
VariantPublishingConfigurator.get(project).configureNativeVariantPublication(variant)
|
||||
}
|
||||
|
||||
private fun Configuration.setPlatformAttributesAndMetadataUsage(variant: T) {
|
||||
|
||||
+6
-62
@@ -5,8 +5,12 @@
|
||||
|
||||
package org.jetbrains.kotlin.gradle.plugin.mpp.pm20
|
||||
|
||||
import jdk.internal.org.objectweb.asm.tree.VarInsnNode
|
||||
import org.gradle.api.Project
|
||||
import org.gradle.api.artifacts.Configuration
|
||||
import org.gradle.api.artifacts.ModuleDependency
|
||||
import org.gradle.api.attributes.Attribute
|
||||
import org.gradle.api.attributes.AttributeContainer
|
||||
import org.gradle.api.attributes.Usage
|
||||
import org.gradle.api.component.AdhocComponentWithVariants
|
||||
import org.gradle.api.component.SoftwareComponentFactory
|
||||
@@ -22,6 +26,7 @@ import org.jetbrains.kotlin.gradle.plugin.mpp.sourcesJarTask
|
||||
import org.jetbrains.kotlin.gradle.utils.addExtendsFromRelation
|
||||
import org.jetbrains.kotlin.gradle.utils.dashSeparatedName
|
||||
import org.jetbrains.kotlin.project.model.refinesClosure
|
||||
import javax.inject.Inject
|
||||
|
||||
abstract class AbstractKotlinGradleVariantFactory<T : KotlinGradleVariant>(
|
||||
module: KotlinGradleModule
|
||||
@@ -142,71 +147,10 @@ abstract class AbstractKotlinGradleRuntimePublishedVariantFactory<T : KotlinGrad
|
||||
}
|
||||
|
||||
open fun configureVariantPublishing(variant: T) {
|
||||
val rootSoftwareComponent =
|
||||
project.components
|
||||
.withType(AdhocComponentWithVariants::class.java)
|
||||
.getByName(rootPublicationComponentName(module))
|
||||
|
||||
val platformModuleDependencyProvider = project.provider {
|
||||
val coordinates = variant.publishedMavenModuleCoordinates
|
||||
(project.dependencies.create("${coordinates.group}:${coordinates.name}:${coordinates.version}") as ModuleDependency).apply {
|
||||
if (module.moduleClassifier != null) {
|
||||
capabilities { it.requireCapability(CalculatedCapability.fromModule(module)) }
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// FIXME inject vs internal API
|
||||
val platformComponentName = platformComponentName(variant)
|
||||
val platformComponent = (project as ProjectInternal).services
|
||||
.get(SoftwareComponentFactory::class.java)
|
||||
.adhoc(platformComponentName)
|
||||
project.components.add(platformComponent)
|
||||
platformComponent.addVariantsFromConfiguration(project.configurations.getByName(variant.apiElementsConfigurationName)) {
|
||||
it.mapToMavenScope("compile")
|
||||
}
|
||||
platformComponent.addVariantsFromConfiguration(project.configurations.getByName(variant.runtimeElementsConfigurationName)) {
|
||||
it.mapToMavenScope("runtime")
|
||||
}
|
||||
|
||||
module.ifMadePublic {
|
||||
project.pluginManager.withPlugin("maven-publish") {
|
||||
project.extensions.getByType(PublishingExtension::class.java).apply {
|
||||
publications.create(platformComponentName, MavenPublication::class.java).apply {
|
||||
(this as DefaultMavenPublication).isAlias = true
|
||||
from(platformComponent)
|
||||
variant.assignMavenPublication(this)
|
||||
artifactId = dashSeparatedName(project.name, variant.defaultPublishedModuleSuffix)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
val publishedApiConfiguration =
|
||||
project.configurations.create(publishedConfigurationName(variant.apiElementsConfigurationName)).apply {
|
||||
isCanBeConsumed = false
|
||||
isCanBeResolved = false
|
||||
configureApiElementsConfiguration(variant, this)
|
||||
setModuleCapability(this, module)
|
||||
dependencies.addLater(platformModuleDependencyProvider)
|
||||
}
|
||||
val publishedRuntimeConfiguration =
|
||||
project.configurations.create(publishedConfigurationName(variant.runtimeElementsConfigurationName)).apply {
|
||||
isCanBeConsumed = false
|
||||
isCanBeResolved = false
|
||||
configureRuntimeElementsConfiguration(variant, this)
|
||||
setModuleCapability(this, module)
|
||||
dependencies.addLater(platformModuleDependencyProvider)
|
||||
}
|
||||
listOf(publishedApiConfiguration, publishedRuntimeConfiguration).forEach {
|
||||
rootSoftwareComponent.addVariantsFromConfiguration(it) { }
|
||||
}
|
||||
VariantPublishingConfigurator.get(project).configureSingleVariantPublication(variant)
|
||||
}
|
||||
|
||||
open fun platformComponentName(variant: T) = variant.disambiguateName("")
|
||||
}
|
||||
|
||||
|
||||
internal fun setModuleCapability(configuration: Configuration, module: KotlinGradleModule) {
|
||||
if (module.moduleClassifier != null) {
|
||||
configuration.outgoing.capability(CalculatedCapability.fromModule(module))
|
||||
|
||||
+3
-3
@@ -60,10 +60,10 @@ abstract class KotlinGradleVariantInternal(
|
||||
internal val KotlinGradleVariant.compileDependencyConfiguration: Configuration
|
||||
get() = containingModule.project.configurations.getByName(compileDependencyConfigurationName)
|
||||
|
||||
class DefaultSingleMavenPublicationHolder(
|
||||
class DefaultSingleMavenPublishedModuleHolder(
|
||||
private var module: KotlinGradleModule,
|
||||
override val defaultPublishedModuleSuffix: String?
|
||||
) : SingleMavenPublicationHolder {
|
||||
) : SingleMavenPublishedModuleHolder {
|
||||
private val project get() = module.project
|
||||
|
||||
private var assignedMavenPublication: MavenPublication? = null
|
||||
@@ -114,7 +114,7 @@ private fun defaultModuleSuffix(module: KotlinGradleModule, variantName: String)
|
||||
|
||||
abstract class KotlinGradlePublishedVariantWithRuntime(containingModule: KotlinGradleModule, fragmentName: String) :
|
||||
KotlinGradleVariantWithRuntimeInternal(containingModule, fragmentName),
|
||||
SingleMavenPublicationHolder by DefaultSingleMavenPublicationHolder(
|
||||
SingleMavenPublishedModuleHolder by DefaultSingleMavenPublishedModuleHolder(
|
||||
containingModule,
|
||||
defaultModuleSuffix(containingModule, fragmentName)
|
||||
) {
|
||||
|
||||
+132
-3
@@ -5,8 +5,137 @@
|
||||
|
||||
package org.jetbrains.kotlin.gradle.plugin.mpp.pm20
|
||||
|
||||
fun <T> publishVariantWithSinglePublication(
|
||||
variant: T
|
||||
) where T : SingleMavenPublicationHolder, T : KotlinGradleVariant {
|
||||
import org.gradle.api.Project
|
||||
import org.gradle.api.artifacts.ModuleDependency
|
||||
import org.gradle.api.attributes.Attribute
|
||||
import org.gradle.api.attributes.AttributeContainer
|
||||
import org.gradle.api.component.AdhocComponentWithVariants
|
||||
import org.gradle.api.component.SoftwareComponentFactory
|
||||
import org.gradle.api.publish.PublishingExtension
|
||||
import org.gradle.api.publish.maven.MavenPublication
|
||||
import org.gradle.api.publish.maven.internal.publication.DefaultMavenPublication
|
||||
import org.jetbrains.kotlin.gradle.plugin.mpp.pm20.util.CalculatedCapability
|
||||
import org.jetbrains.kotlin.gradle.plugin.mpp.publishedConfigurationName
|
||||
import org.jetbrains.kotlin.gradle.utils.dashSeparatedName
|
||||
import javax.inject.Inject
|
||||
|
||||
fun VariantPublishingConfigurator.configureNativeVariantPublication(variant: KotlinNativeVariantInternal) {
|
||||
val publishConfigurations = listOfNotNull(
|
||||
variant.apiElementsConfigurationName,
|
||||
variant.hostSpecificMetadataElementsConfigurationName // host-specific metadata may be absent
|
||||
)
|
||||
configurePublishing(variant, variant, publishConfigurations)
|
||||
}
|
||||
|
||||
fun VariantPublishingConfigurator.configureSingleVariantPublication(variant: KotlinGradlePublishedVariantWithRuntime) {
|
||||
val publishConfigurations = listOf(variant.apiElementsConfigurationName, variant.runtimeElementsConfigurationName)
|
||||
configurePublishing(variant, variant, publishConfigurations)
|
||||
}
|
||||
|
||||
open class VariantPublishingConfigurator @Inject constructor(
|
||||
private val project: Project,
|
||||
private val softwareComponentFactory: SoftwareComponentFactory
|
||||
) {
|
||||
companion object {
|
||||
fun get(project: Project) = project.objects.newInstance(VariantPublishingConfigurator::class.java, project)
|
||||
}
|
||||
|
||||
open fun platformComponentName(variant: KotlinGradleVariant) = variant.disambiguateName("")
|
||||
|
||||
open fun inferMavenScopes(variant: KotlinGradleVariant, configurationNames: Iterable<String>): Map<String, String?> =
|
||||
configurationNames.associateWith { configurationName ->
|
||||
when {
|
||||
configurationName == variant.apiElementsConfigurationName -> "compile"
|
||||
variant is KotlinGradleVariantWithRuntime && configurationName == variant.runtimeElementsConfigurationName -> "runtime"
|
||||
else -> null
|
||||
}
|
||||
}
|
||||
|
||||
open fun configurePublishing(
|
||||
variant: KotlinGradleVariant,
|
||||
publishedModuleHolder: SingleMavenPublishedModuleHolder,
|
||||
publishConfigurations: Iterable<String>
|
||||
) {
|
||||
val componentName = platformComponentName(variant)
|
||||
val configurationsMap = inferMavenScopes(variant, publishConfigurations)
|
||||
|
||||
// FIXME: add the sources artifact of the variant to the publication!!!
|
||||
// do that following the Gradle's guidelines on publishing sources variant along library variants, if possible
|
||||
|
||||
registerPlatformModulePublication(componentName, publishedModuleHolder, configurationsMap, variant.containingModule::ifMadePublic)
|
||||
registerPlatformVariantsInRootModule(publishedModuleHolder, variant.containingModule, publishConfigurations)
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates the [AdhocComponentWithVariants] named [componentName] for the given [publishConfigurationsWithMavenScopes].
|
||||
* At the point [whenShouldRegisterPublication] creates a Maven publication named [componentName] that publishes the created component.
|
||||
* Assigns the created Maven publication to the [publishedModuleHolder].
|
||||
*/
|
||||
protected open fun registerPlatformModulePublication(
|
||||
componentName: String,
|
||||
publishedModuleHolder: SingleMavenPublishedModuleHolder,
|
||||
publishConfigurationsWithMavenScopes: Map<String, String?>,
|
||||
whenShouldRegisterPublication: (() -> Unit) -> Unit
|
||||
) {
|
||||
val platformComponent = softwareComponentFactory.adhoc(componentName)
|
||||
project.components.add(platformComponent)
|
||||
publishConfigurationsWithMavenScopes.forEach { configurationName, mavenScopeOrNull ->
|
||||
platformComponent.addVariantsFromConfiguration(project.configurations.getByName(configurationName)) { variantDetails ->
|
||||
mavenScopeOrNull?.let { variantDetails.mapToMavenScope(it) }
|
||||
}
|
||||
}
|
||||
|
||||
whenShouldRegisterPublication {
|
||||
project.pluginManager.withPlugin("maven-publish") {
|
||||
project.extensions.getByType(PublishingExtension::class.java).apply {
|
||||
publications.create(componentName, MavenPublication::class.java).apply {
|
||||
(this as DefaultMavenPublication).isAlias = true
|
||||
from(platformComponent)
|
||||
publishedModuleHolder.assignMavenPublication(this)
|
||||
artifactId = dashSeparatedName(project.name, publishedModuleHolder.defaultPublishedModuleSuffix)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
protected open fun registerPlatformVariantsInRootModule(
|
||||
publishedModuleHolder: SingleMavenPublishedModuleHolder,
|
||||
kotlinModule: KotlinGradleModule,
|
||||
configurationNames: Iterable<String>
|
||||
) {
|
||||
val platformModuleDependencyProvider = project.provider {
|
||||
val coordinates = publishedModuleHolder.publishedMavenModuleCoordinates
|
||||
(project.dependencies.create("${coordinates.group}:${coordinates.name}:${coordinates.version}") as ModuleDependency).apply {
|
||||
if (kotlinModule.moduleClassifier != null) {
|
||||
capabilities { it.requireCapability(CalculatedCapability.fromModule(kotlinModule)) }
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
val rootSoftwareComponent =
|
||||
project.components
|
||||
.withType(AdhocComponentWithVariants::class.java)
|
||||
.getByName(rootPublicationComponentName(kotlinModule))
|
||||
|
||||
configurationNames.forEach { configurationName ->
|
||||
fun <T : Any> copyAttribute(from: AttributeContainer, to: AttributeContainer, key: Attribute<T>) {
|
||||
to.attribute(key, checkNotNull(from.getAttribute(key)))
|
||||
}
|
||||
|
||||
val originalConfiguration = project.configurations.getByName(configurationName)
|
||||
project.configurations.create(publishedConfigurationName(configurationName)).apply {
|
||||
isCanBeConsumed = false
|
||||
isCanBeResolved = false
|
||||
|
||||
setModuleCapability(this, kotlinModule)
|
||||
dependencies.addLater(platformModuleDependencyProvider)
|
||||
val originalAttributes = originalConfiguration.attributes
|
||||
originalAttributes.keySet().forEach {
|
||||
copyAttribute(originalAttributes, attributes, it)
|
||||
}
|
||||
rootSoftwareComponent.addVariantsFromConfiguration(this) { }
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user