Support basic publishing with maven-publish in the PM20 plugin

This commit is contained in:
Sergey Igushkin
2021-02-16 12:07:09 +03:00
parent 0bf408e147
commit ec3fa2610e
12 changed files with 241 additions and 36 deletions
@@ -14,7 +14,7 @@ import org.jetbrains.kotlin.gradle.plugin.HasKotlinDependencies
import org.jetbrains.kotlin.gradle.plugin.KotlinDependencyHandler import org.jetbrains.kotlin.gradle.plugin.KotlinDependencyHandler
import org.jetbrains.kotlin.gradle.plugin.PropertiesProvider import org.jetbrains.kotlin.gradle.plugin.PropertiesProvider
import org.jetbrains.kotlin.gradle.plugin.mpp.pm20.KotlinGradleModule import org.jetbrains.kotlin.gradle.plugin.mpp.pm20.KotlinGradleModule
import org.jetbrains.kotlin.gradle.plugin.mpp.pm20.util.LazyCapability import org.jetbrains.kotlin.gradle.plugin.mpp.pm20.util.CalculatedCapability
import org.jetbrains.kotlin.gradle.targets.js.npm.NpmDependency import org.jetbrains.kotlin.gradle.targets.js.npm.NpmDependency
import org.jetbrains.kotlin.gradle.targets.js.npm.directoryNpmDependency import org.jetbrains.kotlin.gradle.targets.js.npm.directoryNpmDependency
import org.jetbrains.kotlin.gradle.targets.js.npm.moduleName import org.jetbrains.kotlin.gradle.targets.js.npm.moduleName
@@ -76,7 +76,9 @@ class DefaultKotlinDependencyHandler(
val dependency = when (dependencyNotation) { val dependency = when (dependencyNotation) {
is KotlinGradleModule -> project.dependencies.create(dependencyNotation.project).apply { is KotlinGradleModule -> project.dependencies.create(dependencyNotation.project).apply {
(this as ModuleDependency).capabilities { (this as ModuleDependency).capabilities {
it.requireCapability(LazyCapability.fromModule(dependencyNotation)) if (dependencyNotation.moduleClassifier != null) {
it.requireCapability(CalculatedCapability.fromModule(dependencyNotation))
}
} }
} }
else -> dependencyNotation else -> dependencyNotation
@@ -267,8 +267,13 @@ class GradleModuleVariantResolver(val project: Project) : ModuleVariantResolver
// TODO maybe improve this behavior? Currently it contradicts dependency resolution in that it may return a chosen variant for an // TODO maybe improve this behavior? Currently it contradicts dependency resolution in that it may return a chosen variant for an
// unrequested dependency. This workaround is needed for synthetic modules which were not produced from module metadata, so maybe // unrequested dependency. This workaround is needed for synthetic modules which were not produced from module metadata, so maybe
// those modules should be marked somehow // those modules should be marked somehow
dependencyModule.variants.singleOrNull() if (dependencyModule is ExternalSyntheticKotlinModule) {
?.let { return VariantResolution.fromMatchingVariants(requestingVariant, dependencyModule, listOf(it)) } return VariantResolution.fromMatchingVariants(
requestingVariant,
dependencyModule,
listOf(dependencyModule.variants.single())
)
}
val module = requestingVariant.containingModule val module = requestingVariant.containingModule
@@ -198,6 +198,7 @@ internal fun buildProjectStructureMetadata(module: KotlinGradleModule): KotlinPr
module.fragments.associate { it.name to it.directRefinesDependencies.map { it.name }.toSet() } module.fragments.associate { it.name to it.directRefinesDependencies.map { it.name }.toSet() }
// FIXME: support native implementation-as-api-dependencies // FIXME: support native implementation-as-api-dependencies
// FIXME: support dependencies on auxiliary modules
val fragmentDependencies = val fragmentDependencies =
module.fragments.associate { fragment -> module.fragments.associate { fragment ->
fragment.name to fragment.declaredModuleDependencies.map { fragment.name to fragment.declaredModuleDependencies.map {
@@ -15,13 +15,12 @@ import org.jetbrains.kotlin.gradle.dsl.KotlinMultiplatformExtension
import org.jetbrains.kotlin.gradle.dsl.multiplatformExtension import org.jetbrains.kotlin.gradle.dsl.multiplatformExtension
import org.jetbrains.kotlin.gradle.dsl.multiplatformExtensionOrNull import org.jetbrains.kotlin.gradle.dsl.multiplatformExtensionOrNull
import org.jetbrains.kotlin.gradle.dsl.topLevelExtension import org.jetbrains.kotlin.gradle.dsl.topLevelExtension
import org.jetbrains.kotlin.gradle.plugin.mpp.pm20.KotlinPm20ProjectExtension import org.jetbrains.kotlin.gradle.plugin.mpp.pm20.*
import org.jetbrains.kotlin.gradle.plugin.mpp.pm20.currentBuildId import org.jetbrains.kotlin.gradle.plugin.mpp.pm20.util.CalculatedCapability
import org.jetbrains.kotlin.gradle.utils.getValue import org.jetbrains.kotlin.gradle.utils.getValue
import org.jetbrains.kotlin.project.model.KotlinModuleIdentifier import org.jetbrains.kotlin.project.model.KotlinModuleIdentifier
import org.jetbrains.kotlin.project.model.LocalModuleIdentifier import org.jetbrains.kotlin.project.model.LocalModuleIdentifier
import org.jetbrains.kotlin.project.model.MavenModuleIdentifier import org.jetbrains.kotlin.project.model.MavenModuleIdentifier
import java.lang.IllegalArgumentException
internal object ModuleIds { internal object ModuleIds {
fun fromDependency(dependency: Dependency) = when (dependency) { fun fromDependency(dependency: Dependency) = when (dependency) {
@@ -77,7 +76,8 @@ internal object ModuleIds {
is LocalModuleIdentifier -> { is LocalModuleIdentifier -> {
check(moduleIdentifier.buildId == thisProject.currentBuildId().name) check(moduleIdentifier.buildId == thisProject.currentBuildId().name)
val dependencyProject = thisProject.project(moduleIdentifier.projectId) val dependencyProject = thisProject.project(moduleIdentifier.projectId)
val getRootPublication: () -> MavenPublication? = when (val topLevelExtension = dependencyProject.topLevelExtension) { val topLevelExtension = dependencyProject.topLevelExtension
val getRootPublication: () -> MavenPublication? = when (topLevelExtension) {
is KotlinMultiplatformExtension -> { is KotlinMultiplatformExtension -> {
{ topLevelExtension.rootSoftwareComponent.publicationDelegate } { topLevelExtension.rootSoftwareComponent.publicationDelegate }
} }
@@ -86,7 +86,19 @@ internal object ModuleIds {
} }
else -> error("unexpected top-level extension $topLevelExtension") else -> error("unexpected top-level extension $topLevelExtension")
} }
val coordinatesProvider = MultiplatformRootPublicationCoordinatesProvider(dependencyProject, getRootPublication) val capabilities = when (topLevelExtension) {
is KotlinMultiplatformExtension -> emptyList()
is KotlinPm20ProjectExtension -> listOfNotNull(CalculatedCapability.capabilityStringFromModule(
topLevelExtension.modules.single { it.moduleIdentifier == moduleIdentifier }
))
else -> error("unexpected top-level extension $topLevelExtension")
}
val coordinatesProvider = MavenPublicationCoordinatesProvider(
dependencyProject,
getRootPublication,
defaultModuleSuffix = null,
capabilities = capabilities
)
return ChangingModuleDependencyIdentifier({ coordinatesProvider.group }, { coordinatesProvider.name }) return ChangingModuleDependencyIdentifier({ coordinatesProvider.group }, { coordinatesProvider.name })
} }
is MavenModuleIdentifier -> { is MavenModuleIdentifier -> {
@@ -104,9 +116,11 @@ interface PublishedModuleCoordinatesProvider {
val capabilities: Iterable<String> val capabilities: Iterable<String>
} }
class MultiplatformRootPublicationCoordinatesProvider( open class MavenPublicationCoordinatesProvider(
project: Project, project: Project,
val getPublication: () -> MavenPublication? val getPublication: () -> MavenPublication?,
defaultModuleSuffix: String?,
override val capabilities: Iterable<String> = emptyList()
) : PublishedModuleCoordinatesProvider { ) : PublishedModuleCoordinatesProvider {
override val group: String by project.provider { override val group: String by project.provider {
@@ -114,13 +128,10 @@ class MultiplatformRootPublicationCoordinatesProvider(
} }
override val name: String by project.provider { override val name: String by project.provider {
getPublication()?.artifactId ?: project.group.toString() getPublication()?.artifactId ?: project.name.plus(defaultModuleSuffix?.let { "-$it" }.orEmpty())
} }
override val version: String by project.provider { override val version: String by project.provider {
getPublication()?.artifactId ?: project.version.toString() getPublication()?.version ?: project.version.toString()
} }
override val capabilities: Iterable<String>
get() = emptyList()
} }
@@ -6,7 +6,9 @@
package org.jetbrains.kotlin.gradle.plugin.mpp.pm20 package org.jetbrains.kotlin.gradle.plugin.mpp.pm20
import org.gradle.api.* import org.gradle.api.*
import org.gradle.api.component.SoftwareComponentFactory
import org.gradle.api.plugins.JavaBasePlugin 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.MavenPublication
import org.gradle.util.GradleVersion import org.gradle.util.GradleVersion
import org.jetbrains.kotlin.gradle.dsl.KotlinTopLevelExtension import org.jetbrains.kotlin.gradle.dsl.KotlinTopLevelExtension
@@ -14,8 +16,11 @@ import org.jetbrains.kotlin.gradle.dsl.pm20Extension
import org.jetbrains.kotlin.gradle.internal.customizeKotlinDependencies import org.jetbrains.kotlin.gradle.internal.customizeKotlinDependencies
import org.jetbrains.kotlin.gradle.utils.checkGradleCompatibility import org.jetbrains.kotlin.gradle.utils.checkGradleCompatibility
import org.jetbrains.kotlin.project.model.KotlinModuleIdentifier import org.jetbrains.kotlin.project.model.KotlinModuleIdentifier
import javax.inject.Inject
abstract class KotlinPm20GradlePlugin : Plugin<Project> { abstract class KotlinPm20GradlePlugin @Inject constructor(
@Inject private val softwareComponentFactory: SoftwareComponentFactory
) : Plugin<Project> {
override fun apply(project: Project) { override fun apply(project: Project) {
checkGradleCompatibility("the Kotlin Multiplatform plugin", GradleVersion.version("6.1")) checkGradleCompatibility("the Kotlin Multiplatform plugin", GradleVersion.version("6.1"))
@@ -25,6 +30,8 @@ abstract class KotlinPm20GradlePlugin : Plugin<Project> {
createDefaultModules(project) createDefaultModules(project)
customizeKotlinDependencies(project) customizeKotlinDependencies(project)
registerDefaultVariantFactories(project) registerDefaultVariantFactories(project)
setupFragmentsMetadata(project)
setupPublication(project)
} }
private fun registerDefaultVariantFactories(project: Project) { private fun registerDefaultVariantFactories(project: Project) {
@@ -42,17 +49,54 @@ abstract class KotlinPm20GradlePlugin : Plugin<Project> {
modules.create(KotlinGradleModule.TEST_MODULE_NAME) modules.create(KotlinGradleModule.TEST_MODULE_NAME)
main { makePublic() } main { makePublic() }
} }
setupFragmentsMetadata(project)
} }
private fun setupFragmentsMetadata(project: Project) { private fun setupFragmentsMetadata(project: Project) {
project.pm20Extension.modules.all { module -> project.pm20Extension.modules.all { module ->
configureMetadataResolutionAndBuild(module) configureMetadataResolutionAndBuild(module)
module.ifMadePublic { configureMetadataExposure(module) } configureMetadataExposure(module)
}
}
private fun setupPublication(project: Project) {
project.pm20Extension.modules.all { module ->
setupPublicationForModule(module)
}
}
private fun setupPublicationForModule(module: KotlinGradleModule) {
val project = module.project
val metadataElements = project.configurations.getByName(metadataElementsConfigurationName(module))
val componentName = rootPublicationComponentName(module)
val rootSoftwareComponent = softwareComponentFactory.adhoc(componentName).also {
project.components.add(it)
it.addVariantsFromConfiguration(metadataElements) { }
}
module.ifMadePublic {
val metadataDependencyConfiguration = resolvableMetadataConfiguration(module)
project.pluginManager.withPlugin("maven-publish") {
project.extensions.getByType(PublishingExtension::class.java).publications.create(
componentName,
MavenPublication::class.java
) { publication ->
publication.from(rootSoftwareComponent)
publication.versionMapping { versionMapping ->
versionMapping.allVariants {
it.fromResolutionOf(metadataDependencyConfiguration)
}
}
}
}
} }
} }
} }
fun rootPublicationComponentName(module: KotlinGradleModule) =
module.disambiguateName("root")
open class KotlinPm20ProjectExtension(project: Project) : KotlinTopLevelExtension(project) { open class KotlinPm20ProjectExtension(project: Project) : KotlinTopLevelExtension(project) {
val modules: NamedDomainObjectContainer<KotlinGradleModule> by lazy { val modules: NamedDomainObjectContainer<KotlinGradleModule> by lazy {
project.objects.domainObjectContainer( project.objects.domainObjectContainer(
@@ -42,6 +42,7 @@ open class KotlinGradleModule(
private var setPublicHandlers: MutableList<() -> Unit> = mutableListOf() private var setPublicHandlers: MutableList<() -> Unit> = mutableListOf()
fun ifMadePublic(action: () -> Unit) { fun ifMadePublic(action: () -> Unit) {
// FIXME reentrancy?
if (isPublic) action() else setPublicHandlers.add(action) if (isPublic) action() else setPublicHandlers.add(action)
} }
@@ -20,7 +20,7 @@ import org.jetbrains.kotlin.gradle.utils.lowerCamelCaseName
import org.jetbrains.kotlin.project.model.refinesClosure import org.jetbrains.kotlin.project.model.refinesClosure
open class KotlinJvmVariant(containingModule: KotlinGradleModule, fragmentName: String) : open class KotlinJvmVariant(containingModule: KotlinGradleModule, fragmentName: String) :
KotlinGradleVariantWithRuntimeDependencies(containingModule, fragmentName) { KotlinGradlePublishedVariantWithRuntime(containingModule, fragmentName) {
override val platformType: KotlinPlatformType override val platformType: KotlinPlatformType
get() = KotlinPlatformType.jvm get() = KotlinPlatformType.jvm
@@ -6,12 +6,20 @@
package org.jetbrains.kotlin.gradle.plugin.mpp.pm20 package org.jetbrains.kotlin.gradle.plugin.mpp.pm20
import org.gradle.api.artifacts.Configuration import org.gradle.api.artifacts.Configuration
import org.gradle.api.artifacts.ModuleDependency
import org.gradle.api.attributes.Usage import org.gradle.api.attributes.Usage
import org.gradle.api.component.AdhocComponentWithVariants
import org.gradle.api.component.SoftwareComponentFactory
import org.gradle.api.internal.project.ProjectInternal
import org.gradle.api.publish.PublishingExtension
import org.gradle.api.publish.maven.MavenPublication
import org.jetbrains.kotlin.gradle.plugin.KotlinPlatformType import org.jetbrains.kotlin.gradle.plugin.KotlinPlatformType
import org.jetbrains.kotlin.gradle.plugin.mpp.KotlinUsages import org.jetbrains.kotlin.gradle.plugin.mpp.KotlinUsages
import org.jetbrains.kotlin.gradle.plugin.mpp.pm20.util.LazyCapability import org.jetbrains.kotlin.gradle.plugin.mpp.pm20.util.CalculatedCapability
import org.jetbrains.kotlin.gradle.plugin.mpp.publishedConfigurationName
import org.jetbrains.kotlin.gradle.plugin.mpp.sourcesJarTask import org.jetbrains.kotlin.gradle.plugin.mpp.sourcesJarTask
import org.jetbrains.kotlin.gradle.utils.addExtendsFromRelation import org.jetbrains.kotlin.gradle.utils.addExtendsFromRelation
import org.jetbrains.kotlin.gradle.utils.dashSeparatedName
import org.jetbrains.kotlin.project.model.refinesClosure import org.jetbrains.kotlin.project.model.refinesClosure
abstract class AbstractKotlinGradleVariantFactory<T : KotlinGradleVariant>( abstract class AbstractKotlinGradleVariantFactory<T : KotlinGradleVariant>(
@@ -79,7 +87,7 @@ abstract class AbstractKotlinGradleVariantFactory<T : KotlinGradleVariant>(
} }
} }
abstract class AbstractKotlinGradleVariantWithRuntimeDependenciesFactory<T : KotlinGradleVariantWithRuntimeDependencies>(module: KotlinGradleModule) : abstract class AbstractKotlinGradleVariantWithRuntimeFactory<T : KotlinGradleVariantWithRuntime>(module: KotlinGradleModule) :
AbstractKotlinGradleVariantFactory<T>(module) { AbstractKotlinGradleVariantFactory<T>(module) {
open fun configureRuntimeResolvableConfiguration(fragment: T, configuration: Configuration) { open fun configureRuntimeResolvableConfiguration(fragment: T, configuration: Configuration) {
@@ -98,7 +106,7 @@ abstract class AbstractKotlinGradleVariantWithRuntimeDependenciesFactory<T : Kot
fragment.runtimeDependencyFiles = project.configurations.create(fragment.runtimeDependencyConfigurationName).apply { fragment.runtimeDependencyFiles = project.configurations.create(fragment.runtimeDependencyConfigurationName).apply {
isCanBeConsumed = false isCanBeConsumed = false
isCanBeResolved = true isCanBeResolved = true
configureCompileResolvableConfiguration(fragment, this@apply) configureRuntimeResolvableConfiguration(fragment, this@apply)
project.addExtendsFromRelation(name, fragment.transitiveApiConfigurationName) project.addExtendsFromRelation(name, fragment.transitiveApiConfigurationName)
project.addExtendsFromRelation(name, fragment.transitiveImplementationConfigurationName) project.addExtendsFromRelation(name, fragment.transitiveImplementationConfigurationName)
} }
@@ -122,6 +130,82 @@ abstract class AbstractKotlinGradleVariantWithRuntimeDependenciesFactory<T : Kot
} }
} }
abstract class AbstractKotlinGradleRuntimePublishedVariantFactory<T : KotlinGradlePublishedVariantWithRuntime>(module: KotlinGradleModule) :
AbstractKotlinGradleVariantWithRuntimeFactory<T>(module) {
override fun create(name: String): T {
val result = super.create(name)
configureVariantPublishing(result)
return result
}
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("compile")
}
module.ifMadePublic {
project.pluginManager.withPlugin("maven-publish") {
project.extensions.getByType(PublishingExtension::class.java).apply {
publications.create(platformComponentName, MavenPublication::class.java).apply {
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) { }
}
}
open fun platformComponentName(variant: T) = variant.disambiguateName("")
}
internal fun setModuleCapability(configuration: Configuration, module: KotlinGradleModule) { internal fun setModuleCapability(configuration: Configuration, module: KotlinGradleModule) {
configuration.outgoing.capability(LazyCapability.fromModule(module)) if (module.moduleClassifier != null) {
configuration.outgoing.capability(CalculatedCapability.fromModule(module))
}
} }
@@ -7,13 +7,18 @@ package org.jetbrains.kotlin.gradle.plugin.mpp.pm20
import org.gradle.api.file.ConfigurableFileCollection import org.gradle.api.file.ConfigurableFileCollection
import org.gradle.api.file.FileCollection import org.gradle.api.file.FileCollection
import org.gradle.api.publish.maven.MavenPublication
import org.gradle.api.tasks.TaskProvider import org.gradle.api.tasks.TaskProvider
import org.gradle.api.tasks.bundling.AbstractArchiveTask import org.gradle.api.tasks.bundling.AbstractArchiveTask
import org.jetbrains.kotlin.gradle.plugin.KotlinCompilationOutput import org.jetbrains.kotlin.gradle.plugin.KotlinCompilationOutput
import org.jetbrains.kotlin.gradle.plugin.KotlinPlatformType import org.jetbrains.kotlin.gradle.plugin.KotlinPlatformType
import org.jetbrains.kotlin.gradle.plugin.mpp.DefaultKotlinCompilationOutput import org.jetbrains.kotlin.gradle.plugin.mpp.DefaultKotlinCompilationOutput
import org.jetbrains.kotlin.gradle.plugin.mpp.MavenPublicationCoordinatesProvider
import org.jetbrains.kotlin.gradle.plugin.mpp.PublishedModuleCoordinatesProvider
import org.jetbrains.kotlin.gradle.plugin.mpp.pm20.util.CalculatedCapability
import org.jetbrains.kotlin.gradle.plugin.mpp.publishedConfigurationName import org.jetbrains.kotlin.gradle.plugin.mpp.publishedConfigurationName
import org.jetbrains.kotlin.gradle.tasks.withType import org.jetbrains.kotlin.gradle.tasks.withType
import org.jetbrains.kotlin.gradle.utils.dashSeparatedName
import org.jetbrains.kotlin.project.model.KotlinAttributeKey import org.jetbrains.kotlin.project.model.KotlinAttributeKey
import org.jetbrains.kotlin.project.model.KotlinModuleVariant import org.jetbrains.kotlin.project.model.KotlinModuleVariant
import org.jetbrains.kotlin.project.model.KotlinPlatformTypeAttribute import org.jetbrains.kotlin.project.model.KotlinPlatformTypeAttribute
@@ -49,19 +54,47 @@ abstract class KotlinGradleVariant(
val apiElementsConfigurationName: String val apiElementsConfigurationName: String
get() = disambiguateName("apiElements") get() = disambiguateName("apiElements")
open val gradleVariantNames: Set<String> abstract val gradleVariantNames: Set<String>
get() = listOf(apiElementsConfigurationName, publishedConfigurationName(apiElementsConfigurationName)).toSet()
override fun toString(): String = "variant $fragmentName in $containingModule" override fun toString(): String = "variant $fragmentName in $containingModule"
} }
interface SingleMavenPublicationHolder {
fun assignMavenPublication(publication: MavenPublication)
val defaultPublishedModuleSuffix: String?
val publishedMavenModuleCoordinates: PublishedModuleCoordinatesProvider
}
class DefaultSingleMavenPublicationHolder(
private var module: KotlinGradleModule,
override val defaultPublishedModuleSuffix: String?
) : SingleMavenPublicationHolder {
private val project get() = module.project
private var assignedMavenPublication: MavenPublication? = null
override fun assignMavenPublication(publication: MavenPublication) {
if (assignedMavenPublication != null)
error("already assigned publication $publication")
assignedMavenPublication = publication
}
override val publishedMavenModuleCoordinates: PublishedModuleCoordinatesProvider =
MavenPublicationCoordinatesProvider(
project,
{ assignedMavenPublication },
defaultPublishedModuleSuffix,
capabilities = listOfNotNull(CalculatedCapability.capabilityStringFromModule(module))
)
}
private fun kotlinPlatformTypeAttributeFromPlatform(platformType: KotlinPlatformType) = platformType.name private fun kotlinPlatformTypeAttributeFromPlatform(platformType: KotlinPlatformType) = platformType.name
// TODO: rewrite with the artifacts API // TODO: rewrite with the artifacts API
internal val KotlinGradleVariant.defaultSourceArtifactTaskName: String internal val KotlinGradleVariant.defaultSourceArtifactTaskName: String
get() = disambiguateName("sourcesJar") get() = disambiguateName("sourcesJar")
abstract class KotlinGradleVariantWithRuntimeDependencies( abstract class KotlinGradleVariantWithRuntime(
containingModule: KotlinGradleModule, containingModule: KotlinGradleModule,
fragmentName: String fragmentName: String
) : KotlinGradleVariant(containingModule, fragmentName) { ) : KotlinGradleVariant(containingModule, fragmentName) {
@@ -78,8 +111,21 @@ abstract class KotlinGradleVariantWithRuntimeDependencies(
// TODO generalize exposing outputs: what if a variant has more than one such configurations or none? // TODO generalize exposing outputs: what if a variant has more than one such configurations or none?
val runtimeElementsConfigurationName: String val runtimeElementsConfigurationName: String
get() = disambiguateName("runtimeElements") get() = disambiguateName("runtimeElements")
}
private fun defaultModuleSuffix(module: KotlinGradleModule, variantName: String): String =
dashSeparatedName(variantName, module.moduleClassifier)
abstract class KotlinGradlePublishedVariantWithRuntime(containingModule: KotlinGradleModule, fragmentName: String) :
KotlinGradleVariantWithRuntime(containingModule, fragmentName),
SingleMavenPublicationHolder by DefaultSingleMavenPublicationHolder(
containingModule,
defaultModuleSuffix(containingModule, fragmentName)
) {
override val gradleVariantNames: Set<String> override val gradleVariantNames: Set<String>
get() = super.gradleVariantNames + get() =
listOf(runtimeElementsConfigurationName, publishedConfigurationName(runtimeElementsConfigurationName)) listOf(apiElementsConfigurationName, runtimeElementsConfigurationName).flatMapTo(mutableSetOf()) {
listOf(it, publishedConfigurationName(it))
}
} }
@@ -42,11 +42,14 @@ internal fun configureMetadataResolutionAndBuild(module: KotlinGradleModule) {
internal fun configureMetadataExposure(module: KotlinGradleModule) { internal fun configureMetadataExposure(module: KotlinGradleModule) {
val project = module.project val project = module.project
project.configurations.create(module.disambiguateName("metadataElements")).apply { project.configurations.create(metadataElementsConfigurationName(module)).apply {
isCanBeConsumed = true module.ifMadePublic {
isCanBeConsumed = true
}
isCanBeResolved = false isCanBeResolved = false
project.artifacts.add(name, project.tasks.named(metadataJarName(module))) project.artifacts.add(name, project.tasks.named(metadataJarName(module)))
attributes.attribute(Usage.USAGE_ATTRIBUTE, project.usageByName(KotlinUsages.KOTLIN_METADATA)) attributes.attribute(Usage.USAGE_ATTRIBUTE, project.usageByName(KotlinUsages.KOTLIN_METADATA))
attributes.attribute(KotlinPlatformType.attribute, KotlinPlatformType.common)
module.fragments.all { fragment -> module.fragments.all { fragment ->
// FIXME: native api-implementation // FIXME: native api-implementation
project.addExtendsFromRelation(name, fragment.apiConfigurationName) project.addExtendsFromRelation(name, fragment.apiConfigurationName)
@@ -55,6 +58,9 @@ internal fun configureMetadataExposure(module: KotlinGradleModule) {
} }
} }
fun metadataElementsConfigurationName(module: KotlinGradleModule) =
module.disambiguateName("metadataElements")
private fun generateAndExportProjectStructureMetadata( private fun generateAndExportProjectStructureMetadata(
module: KotlinGradleModule module: KotlinGradleModule
) { ) {
@@ -123,7 +129,7 @@ private fun configureMetadataJarTask(
} }
} }
private fun metadataJarName(module: KotlinGradleModule) = internal fun metadataJarName(module: KotlinGradleModule) =
lowerCamelCaseName(module.moduleClassifier, "metadataJar") lowerCamelCaseName(module.moduleClassifier, "metadataJar")
private fun createMetadataCompilation( private fun createMetadataCompilation(
@@ -18,7 +18,7 @@ import org.jetbrains.kotlin.project.model.utils.variantsContainingFragment
import java.util.concurrent.Callable import java.util.concurrent.Callable
open class KotlinJvmVariantFactory(module: KotlinGradleModule) : open class KotlinJvmVariantFactory(module: KotlinGradleModule) :
AbstractKotlinGradleVariantWithRuntimeDependenciesFactory<KotlinJvmVariant>(module) { AbstractKotlinGradleRuntimePublishedVariantFactory<KotlinJvmVariant>(module) {
override fun instantiateFragment(name: String) = KotlinJvmVariant(module, name) override fun instantiateFragment(name: String) = KotlinJvmVariant(module, name)
// FIXME expose the JAR with the artifacts API // FIXME expose the JAR with the artifacts API
@@ -9,7 +9,7 @@ import org.gradle.api.capabilities.Capability
import org.gradle.api.provider.Provider import org.gradle.api.provider.Provider
import org.jetbrains.kotlin.gradle.plugin.mpp.pm20.KotlinGradleModule import org.jetbrains.kotlin.gradle.plugin.mpp.pm20.KotlinGradleModule
internal class LazyCapability( internal class CalculatedCapability(
val groupProvider: Provider<String>, val groupProvider: Provider<String>,
val nameValue: String, val nameValue: String,
val versionProvider: Provider<String>, val versionProvider: Provider<String>,
@@ -22,14 +22,19 @@ internal class LazyCapability(
override fun getVersion(): String? = versionProvider.get() override fun getVersion(): String? = versionProvider.get()
companion object { companion object {
fun fromModule(module: KotlinGradleModule): LazyCapability { fun fromModule(module: KotlinGradleModule): CalculatedCapability {
val project = module.project val project = module.project
return LazyCapability( return CalculatedCapability(
project.provider { project.group.toString() }, project.provider { project.group.toString() },
project.name, project.name,
project.provider { project.version.toString() }, project.provider { project.version.toString() },
module.moduleClassifier module.moduleClassifier
) )
} }
fun capabilityStringFromModule(module: KotlinGradleModule): String? =
if (module.moduleClassifier != null) fromModule(module).notation() else null
} }
fun notation(): String = "$group:$name:$version"
} }