[Gradle, MPP] Publish sources as gradle variants
Now when MPP library is published it will contain "sourcesElements" variant for each target and one for common code. Sources variants are published under gradle attributes that were borrowed from Java Gradle Plugin for consistency reasons. This makes it compatible with JVM tooling that rely on these attributes. ^KT-36943 Verification Pending
This commit is contained in:
+1
@@ -34,6 +34,7 @@ interface KotlinTarget : Named, HasAttributes {
|
|||||||
val defaultConfigurationName: String
|
val defaultConfigurationName: String
|
||||||
val apiElementsConfigurationName: String
|
val apiElementsConfigurationName: String
|
||||||
val runtimeElementsConfigurationName: String
|
val runtimeElementsConfigurationName: String
|
||||||
|
val sourcesElementsConfigurationName: String
|
||||||
|
|
||||||
val publishable: Boolean
|
val publishable: Boolean
|
||||||
|
|
||||||
|
|||||||
+6
@@ -13,5 +13,11 @@ interface KotlinTargetComponent : SoftwareComponent {
|
|||||||
val publishable: Boolean
|
val publishable: Boolean
|
||||||
val publishableOnCurrentHost: Boolean
|
val publishableOnCurrentHost: Boolean
|
||||||
val defaultArtifactId: String
|
val defaultArtifactId: String
|
||||||
|
|
||||||
|
@Deprecated(
|
||||||
|
message = "Sources artifacts are now published as separate variant " +
|
||||||
|
"use target.sourcesElementsConfigurationName to obtain necessary information",
|
||||||
|
replaceWith = ReplaceWith("target.sourcesElementsConfigurationName")
|
||||||
|
)
|
||||||
val sourcesArtifacts: Set<PublishArtifact>
|
val sourcesArtifacts: Set<PublishArtifact>
|
||||||
}
|
}
|
||||||
+12
-3
@@ -13,9 +13,7 @@ import org.gradle.api.artifacts.Configuration
|
|||||||
import org.gradle.api.artifacts.Dependency
|
import org.gradle.api.artifacts.Dependency
|
||||||
import org.gradle.api.artifacts.PublishArtifact
|
import org.gradle.api.artifacts.PublishArtifact
|
||||||
import org.gradle.api.artifacts.type.ArtifactTypeDefinition
|
import org.gradle.api.artifacts.type.ArtifactTypeDefinition
|
||||||
import org.gradle.api.attributes.Attribute
|
import org.gradle.api.attributes.*
|
||||||
import org.gradle.api.attributes.Category
|
|
||||||
import org.gradle.api.attributes.Usage
|
|
||||||
import org.gradle.api.attributes.Usage.USAGE_ATTRIBUTE
|
import org.gradle.api.attributes.Usage.USAGE_ATTRIBUTE
|
||||||
import org.gradle.api.file.FileCollection
|
import org.gradle.api.file.FileCollection
|
||||||
import org.gradle.api.internal.artifacts.ArtifactAttributes
|
import org.gradle.api.internal.artifacts.ArtifactAttributes
|
||||||
@@ -200,6 +198,14 @@ abstract class AbstractKotlinTargetConfigurator<KotlinTargetType : KotlinTarget>
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
configurations.maybeCreate(target.sourcesElementsConfigurationName).apply {
|
||||||
|
description = "Source files of main compilation of ${target.name}."
|
||||||
|
isVisible = false
|
||||||
|
isCanBeResolved = false
|
||||||
|
isCanBeConsumed = true
|
||||||
|
configureSourcesPublicationAttributes(target)
|
||||||
|
}
|
||||||
|
|
||||||
if (createTestCompilation) {
|
if (createTestCompilation) {
|
||||||
val testCompilation = target.compilations.getByName(KotlinCompilation.TEST_COMPILATION_NAME)
|
val testCompilation = target.compilations.getByName(KotlinCompilation.TEST_COMPILATION_NAME)
|
||||||
val compileTestsConfiguration = testCompilation.internal.configurations.deprecatedCompileConfiguration
|
val compileTestsConfiguration = testCompilation.internal.configurations.deprecatedCompileConfiguration
|
||||||
@@ -390,6 +396,9 @@ internal fun Project.usageByName(usageName: String): Usage =
|
|||||||
internal fun Project.categoryByName(categoryName: String): Category =
|
internal fun Project.categoryByName(categoryName: String): Category =
|
||||||
objects.named(Category::class.java, categoryName)
|
objects.named(Category::class.java, categoryName)
|
||||||
|
|
||||||
|
internal inline fun <reified T: Named> Project.attributeValueByName(attributeValueName: String): T =
|
||||||
|
objects.named(T::class.java, attributeValueName)
|
||||||
|
|
||||||
fun Configuration.usesPlatformOf(target: KotlinTarget): Configuration {
|
fun Configuration.usesPlatformOf(target: KotlinTarget): Configuration {
|
||||||
attributes.attribute(KotlinPlatformType.attribute, target.platformType)
|
attributes.attribute(KotlinPlatformType.attribute, target.platformType)
|
||||||
|
|
||||||
|
|||||||
+25
-23
@@ -50,6 +50,9 @@ abstract class AbstractKotlinTarget(
|
|||||||
override val runtimeElementsConfigurationName: String
|
override val runtimeElementsConfigurationName: String
|
||||||
get() = disambiguateName("runtimeElements")
|
get() = disambiguateName("runtimeElements")
|
||||||
|
|
||||||
|
override val sourcesElementsConfigurationName: String
|
||||||
|
get() = disambiguateName("sourcesElements")
|
||||||
|
|
||||||
override val artifactsTaskName: String
|
override val artifactsTaskName: String
|
||||||
get() = disambiguateName("jar")
|
get() = disambiguateName("jar")
|
||||||
|
|
||||||
@@ -61,18 +64,24 @@ abstract class AbstractKotlinTarget(
|
|||||||
@InternalKotlinGradlePluginApi
|
@InternalKotlinGradlePluginApi
|
||||||
override val kotlinComponents: Set<KotlinTargetComponent> by lazy {
|
override val kotlinComponents: Set<KotlinTargetComponent> by lazy {
|
||||||
val mainCompilation = compilations.getByName(KotlinCompilation.MAIN_COMPILATION_NAME)
|
val mainCompilation = compilations.getByName(KotlinCompilation.MAIN_COMPILATION_NAME)
|
||||||
val usageContexts = createUsageContexts(mainCompilation)
|
val usageContexts = createUsageContexts(mainCompilation).toMutableSet()
|
||||||
|
|
||||||
val componentName =
|
val componentName =
|
||||||
if (project.kotlinExtension is KotlinMultiplatformExtension)
|
if (project.kotlinExtension is KotlinMultiplatformExtension)
|
||||||
targetName
|
targetName
|
||||||
else PRIMARY_SINGLE_COMPONENT_NAME
|
else PRIMARY_SINGLE_COMPONENT_NAME
|
||||||
|
|
||||||
val result = createKotlinVariant(componentName, mainCompilation, usageContexts)
|
val sourcesArtifact = configureSourcesJarArtifact(mainCompilation, componentName, dashSeparatedName(targetName.toLowerCase()))
|
||||||
|
if (sourcesArtifact != null) {
|
||||||
|
usageContexts += DefaultKotlinUsageContext(
|
||||||
|
compilation = mainCompilation,
|
||||||
|
dependencyConfigurationName = sourcesElementsConfigurationName,
|
||||||
|
includeIntoProjectStructureMetadata = false,
|
||||||
|
includeDependenciesToMavenPublication = false,
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
result.sourcesArtifacts = setOf(
|
val result = createKotlinVariant(componentName, mainCompilation, usageContexts)
|
||||||
sourcesJarArtifact(mainCompilation, componentName, dashSeparatedName(targetName.toLowerCase()))
|
|
||||||
)
|
|
||||||
|
|
||||||
setOf(result)
|
setOf(result)
|
||||||
}
|
}
|
||||||
@@ -117,28 +126,21 @@ abstract class AbstractKotlinTarget(
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
protected fun sourcesJarArtifact(
|
protected fun configureSourcesJarArtifact(
|
||||||
producingCompilation: KotlinCompilation<*>,
|
producingCompilation: KotlinCompilation<*>,
|
||||||
componentName: String,
|
componentName: String,
|
||||||
artifactNameAppendix: String,
|
artifactNameAppendix: String,
|
||||||
classifierPrefix: String? = null
|
classifierPrefix: String? = null,
|
||||||
): PublishArtifact {
|
sourcesElementsConfigurationName: String = this.sourcesElementsConfigurationName,
|
||||||
val sourcesJarTask = sourcesJarTask(producingCompilation, componentName, artifactNameAppendix)
|
): PublishArtifact? {
|
||||||
val sourceArtifactConfigurationName = producingCompilation.disambiguateName("sourceArtifacts")
|
// If sourcesElements configuration not found, don't create artifact.
|
||||||
|
// This can happen in pure JVM plugin where source publication is delegated to Java Gradle Plugin
|
||||||
|
project.configurations.findByName(sourcesElementsConfigurationName) ?: return null
|
||||||
|
|
||||||
return with(producingCompilation.target.project) {
|
val sourcesJarTask = sourcesJarTask(producingCompilation, componentName, artifactNameAppendix)
|
||||||
(configurations.findByName(sourceArtifactConfigurationName) ?: run {
|
val artifact = project.artifacts.add(sourcesElementsConfigurationName, sourcesJarTask) as ConfigurablePublishArtifact
|
||||||
val configuration = configurations.create(sourceArtifactConfigurationName) {
|
artifact.classifier = dashSeparatedName(classifierPrefix, "sources")
|
||||||
it.isCanBeResolved = false
|
return artifact
|
||||||
it.isCanBeConsumed = false
|
|
||||||
}
|
|
||||||
artifacts.add(sourceArtifactConfigurationName, sourcesJarTask)
|
|
||||||
configuration
|
|
||||||
}).artifacts.single().apply {
|
|
||||||
this as ConfigurablePublishArtifact
|
|
||||||
classifier = dashSeparatedName(classifierPrefix, "sources")
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@Suppress("UNCHECKED_CAST")
|
@Suppress("UNCHECKED_CAST")
|
||||||
|
|||||||
+18
-12
@@ -7,9 +7,7 @@ package org.jetbrains.kotlin.gradle.plugin.mpp
|
|||||||
|
|
||||||
import org.gradle.api.Project
|
import org.gradle.api.Project
|
||||||
import org.gradle.api.artifacts.*
|
import org.gradle.api.artifacts.*
|
||||||
import org.gradle.api.attributes.Attribute
|
import org.gradle.api.attributes.*
|
||||||
import org.gradle.api.attributes.AttributeContainer
|
|
||||||
import org.gradle.api.attributes.Usage
|
|
||||||
import org.gradle.api.capabilities.Capability
|
import org.gradle.api.capabilities.Capability
|
||||||
import org.gradle.api.component.ComponentWithCoordinates
|
import org.gradle.api.component.ComponentWithCoordinates
|
||||||
import org.gradle.api.component.ComponentWithVariants
|
import org.gradle.api.component.ComponentWithVariants
|
||||||
@@ -19,12 +17,12 @@ import org.gradle.api.internal.component.UsageContext
|
|||||||
import org.gradle.api.provider.SetProperty
|
import org.gradle.api.provider.SetProperty
|
||||||
import org.gradle.api.publish.maven.MavenPublication
|
import org.gradle.api.publish.maven.MavenPublication
|
||||||
import org.jetbrains.kotlin.gradle.dsl.multiplatformExtension
|
import org.jetbrains.kotlin.gradle.dsl.multiplatformExtension
|
||||||
import org.jetbrains.kotlin.gradle.plugin.KotlinCompilation
|
import org.jetbrains.kotlin.gradle.plugin.*
|
||||||
import org.jetbrains.kotlin.gradle.plugin.KotlinCompilation.Companion.MAIN_COMPILATION_NAME
|
import org.jetbrains.kotlin.gradle.plugin.KotlinCompilation.Companion.MAIN_COMPILATION_NAME
|
||||||
import org.jetbrains.kotlin.gradle.plugin.KotlinTarget
|
|
||||||
import org.jetbrains.kotlin.gradle.plugin.ProjectLocalConfigurations
|
|
||||||
import org.jetbrains.kotlin.gradle.plugin.usageByName
|
|
||||||
import org.jetbrains.kotlin.gradle.targets.metadata.*
|
import org.jetbrains.kotlin.gradle.targets.metadata.*
|
||||||
|
import org.jetbrains.kotlin.gradle.targets.metadata.COMMON_MAIN_ELEMENTS_CONFIGURATION_NAME
|
||||||
|
import org.jetbrains.kotlin.gradle.targets.metadata.isCompatibilityMetadataVariantEnabled
|
||||||
|
import org.jetbrains.kotlin.gradle.targets.metadata.isKotlinGranularMetadataEnabled
|
||||||
import org.jetbrains.kotlin.gradle.utils.setProperty
|
import org.jetbrains.kotlin.gradle.utils.setProperty
|
||||||
|
|
||||||
abstract class KotlinSoftwareComponent(
|
abstract class KotlinSoftwareComponent(
|
||||||
@@ -35,6 +33,8 @@ abstract class KotlinSoftwareComponent(
|
|||||||
|
|
||||||
override fun getName(): String = name
|
override fun getName(): String = name
|
||||||
|
|
||||||
|
private val metadataTarget get() = project.multiplatformExtension.metadata()
|
||||||
|
|
||||||
override fun getVariants(): Set<SoftwareComponent> = kotlinTargets
|
override fun getVariants(): Set<SoftwareComponent> = kotlinTargets
|
||||||
.filter { target -> target !is KotlinMetadataTarget }
|
.filter { target -> target !is KotlinMetadataTarget }
|
||||||
.flatMap { target ->
|
.flatMap { target ->
|
||||||
@@ -47,8 +47,6 @@ abstract class KotlinSoftwareComponent(
|
|||||||
}.toSet()
|
}.toSet()
|
||||||
|
|
||||||
private val _usages: Set<UsageContext> by lazy {
|
private val _usages: Set<UsageContext> by lazy {
|
||||||
val metadataTarget = project.multiplatformExtension.metadata()
|
|
||||||
|
|
||||||
if (!project.isKotlinGranularMetadataEnabled) {
|
if (!project.isKotlinGranularMetadataEnabled) {
|
||||||
val metadataCompilation = metadataTarget.compilations.getByName(MAIN_COMPILATION_NAME)
|
val metadataCompilation = metadataTarget.compilations.getByName(MAIN_COMPILATION_NAME)
|
||||||
return@lazy metadataTarget.createUsageContexts(metadataCompilation)
|
return@lazy metadataTarget.createUsageContexts(metadataCompilation)
|
||||||
@@ -80,6 +78,14 @@ abstract class KotlinSoftwareComponent(
|
|||||||
)
|
)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
configureSourcesJarArtifact()
|
||||||
|
this += DefaultKotlinUsageContext(
|
||||||
|
compilation = metadataTarget.compilations.getByName(MAIN_COMPILATION_NAME),
|
||||||
|
dependencyConfigurationName = metadataTarget.sourcesElementsConfigurationName,
|
||||||
|
includeIntoProjectStructureMetadata = false,
|
||||||
|
includeDependenciesToMavenPublication = false
|
||||||
|
)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -87,7 +93,7 @@ abstract class KotlinSoftwareComponent(
|
|||||||
return _usages
|
return _usages
|
||||||
}
|
}
|
||||||
|
|
||||||
val sourcesArtifacts: Set<PublishArtifact> by lazy {
|
private fun configureSourcesJarArtifact(): PublishArtifact {
|
||||||
fun allPublishableCommonSourceSets() = getCommonSourceSetsForMetadataCompilation(project) +
|
fun allPublishableCommonSourceSets() = getCommonSourceSetsForMetadataCompilation(project) +
|
||||||
getHostSpecificMainSharedSourceSets(project)
|
getHostSpecificMainSharedSourceSets(project)
|
||||||
|
|
||||||
@@ -98,10 +104,10 @@ abstract class KotlinSoftwareComponent(
|
|||||||
lazy { allPublishableCommonSourceSets().associate { it.name to it.kotlin } },
|
lazy { allPublishableCommonSourceSets().associate { it.name to it.kotlin } },
|
||||||
name.toLowerCase()
|
name.toLowerCase()
|
||||||
)
|
)
|
||||||
val sourcesJarArtifact = project.artifacts.add(Dependency.ARCHIVES_CONFIGURATION, sourcesJarTask) { sourcesJarArtifact ->
|
|
||||||
|
return project.artifacts.add(metadataTarget.sourcesElementsConfigurationName, sourcesJarTask) { sourcesJarArtifact ->
|
||||||
sourcesJarArtifact.classifier = "sources"
|
sourcesJarArtifact.classifier = "sources"
|
||||||
}
|
}
|
||||||
setOf(sourcesJarArtifact)
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// This property is declared in the parent type to allow the usages to reference it without forcing the subtypes to load,
|
// This property is declared in the parent type to allow the usages to reference it without forcing the subtypes to load,
|
||||||
|
|||||||
+2
@@ -61,6 +61,8 @@ object KotlinUsages {
|
|||||||
|
|
||||||
internal fun producerRuntimeUsage(project: Project, platformType: KotlinPlatformType) = project.usageByName(
|
internal fun producerRuntimeUsage(project: Project, platformType: KotlinPlatformType) = project.usageByName(
|
||||||
when (platformType) {
|
when (platformType) {
|
||||||
|
// This attribute is deprecated in Gradle and additionally to Usage attribute
|
||||||
|
// it implicitly adds `org.gradle.libraryelements=jar`
|
||||||
in jvmPlatformTypes -> "java-runtime-jars"
|
in jvmPlatformTypes -> "java-runtime-jars"
|
||||||
else -> KOTLIN_RUNTIME
|
else -> KOTLIN_RUNTIME
|
||||||
}
|
}
|
||||||
|
|||||||
+23
-7
@@ -6,6 +6,11 @@
|
|||||||
package org.jetbrains.kotlin.gradle.plugin.mpp
|
package org.jetbrains.kotlin.gradle.plugin.mpp
|
||||||
|
|
||||||
import org.gradle.api.Project
|
import org.gradle.api.Project
|
||||||
|
import org.gradle.api.artifacts.Configuration
|
||||||
|
import org.gradle.api.attributes.Bundling
|
||||||
|
import org.gradle.api.attributes.Category
|
||||||
|
import org.gradle.api.attributes.DocsType
|
||||||
|
import org.gradle.api.attributes.Usage
|
||||||
import org.gradle.api.provider.Provider
|
import org.gradle.api.provider.Provider
|
||||||
import org.gradle.api.publish.PublicationContainer
|
import org.gradle.api.publish.PublicationContainer
|
||||||
import org.gradle.api.publish.PublishingExtension
|
import org.gradle.api.publish.PublishingExtension
|
||||||
@@ -14,7 +19,7 @@ import org.gradle.api.publish.maven.MavenPublication
|
|||||||
import org.gradle.api.publish.maven.internal.publication.MavenPublicationInternal
|
import org.gradle.api.publish.maven.internal.publication.MavenPublicationInternal
|
||||||
import org.jetbrains.kotlin.gradle.dsl.kotlinExtension
|
import org.jetbrains.kotlin.gradle.dsl.kotlinExtension
|
||||||
import org.jetbrains.kotlin.gradle.dsl.multiplatformExtension
|
import org.jetbrains.kotlin.gradle.dsl.multiplatformExtension
|
||||||
import org.jetbrains.kotlin.gradle.plugin.KotlinSourceSet
|
import org.jetbrains.kotlin.gradle.plugin.*
|
||||||
import org.jetbrains.kotlin.gradle.plugin.PropertiesProvider
|
import org.jetbrains.kotlin.gradle.plugin.PropertiesProvider
|
||||||
import org.jetbrains.kotlin.gradle.plugin.sources.KotlinDependencyScope
|
import org.jetbrains.kotlin.gradle.plugin.sources.KotlinDependencyScope
|
||||||
import org.jetbrains.kotlin.gradle.plugin.sources.sourceSetDependencyConfigurationByScope
|
import org.jetbrains.kotlin.gradle.plugin.sources.sourceSetDependencyConfigurationByScope
|
||||||
@@ -41,9 +46,6 @@ private fun createRootPublication(project: Project, publishing: PublishingExtens
|
|||||||
from(kotlinSoftwareComponent)
|
from(kotlinSoftwareComponent)
|
||||||
(this as MavenPublicationInternal).publishWithOriginalFileName()
|
(this as MavenPublicationInternal).publishWithOriginalFileName()
|
||||||
kotlinSoftwareComponent.publicationDelegate = this@apply
|
kotlinSoftwareComponent.publicationDelegate = this@apply
|
||||||
kotlinSoftwareComponent.sourcesArtifacts.forEach { sourceArtifact ->
|
|
||||||
artifact(sourceArtifact)
|
|
||||||
}
|
|
||||||
|
|
||||||
addKotlinToolingMetadataArtifactIfNeeded(project)
|
addKotlinToolingMetadataArtifactIfNeeded(project)
|
||||||
}
|
}
|
||||||
@@ -82,9 +84,6 @@ private fun InternalKotlinTarget.createMavenPublications(publications: Publicati
|
|||||||
// do this in whenEvaluated since older Gradle versions seem to check the files in the variant eagerly:
|
// do this in whenEvaluated since older Gradle versions seem to check the files in the variant eagerly:
|
||||||
project.whenEvaluated {
|
project.whenEvaluated {
|
||||||
from(gradleComponent)
|
from(gradleComponent)
|
||||||
kotlinComponent.sourcesArtifacts.forEach { sourceArtifact ->
|
|
||||||
artifact(sourceArtifact)
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
(this as MavenPublicationInternal).publishWithOriginalFileName()
|
(this as MavenPublicationInternal).publishWithOriginalFileName()
|
||||||
artifactId = kotlinComponent.defaultArtifactId
|
artifactId = kotlinComponent.defaultArtifactId
|
||||||
@@ -144,3 +143,20 @@ private fun dependenciesForPomRewriting(target: InternalKotlinTarget): Provider<
|
|||||||
commonMainDependencies.map { ModuleCoordinates(it.group, it.name, it.version) }.toSet()
|
commonMainDependencies.map { ModuleCoordinates(it.group, it.name, it.version) }.toSet()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
internal fun Configuration.configureSourcesPublicationAttributes(target: KotlinTarget) {
|
||||||
|
val project = target.project
|
||||||
|
|
||||||
|
// In order to be consistent with Java Gradle Plugin, set usage attribute for sources variant
|
||||||
|
// to be either JAVA_RUNTIME (for jvm) or KOTLIN_RUNTIME (for other targets)
|
||||||
|
// the latter isn't a strong requirement since there is no tooling that consume kotlin sources through gradle variants at the moment
|
||||||
|
// so consistency with Java Gradle Plugin seemed most desirable choice.
|
||||||
|
attributes.attribute(Usage.USAGE_ATTRIBUTE, KotlinUsages.producerRuntimeUsage(target))
|
||||||
|
attributes.attribute(Category.CATEGORY_ATTRIBUTE, project.attributeValueByName(Category.DOCUMENTATION))
|
||||||
|
attributes.attribute(DocsType.DOCS_TYPE_ATTRIBUTE, project.attributeValueByName(DocsType.SOURCES))
|
||||||
|
// Bundling attribute is about component dependencies, external means that they are provided as separate components
|
||||||
|
// source variants doesn't have any dependencies (at least at the moment) so there is not much sense to use this attribute
|
||||||
|
// however for Java Gradle Plugin compatibility and in order to prevent weird Variant Resolution errors we include this attribute
|
||||||
|
attributes.attribute(Bundling.BUNDLING_ATTRIBUTE, project.attributeValueByName(Bundling.EXTERNAL))
|
||||||
|
usesPlatformOf(target)
|
||||||
|
}
|
||||||
+18
-4
@@ -74,8 +74,16 @@ open class KotlinVariant(
|
|||||||
override val publishableOnCurrentHost: Boolean
|
override val publishableOnCurrentHost: Boolean
|
||||||
get() = publishable && target.publishable
|
get() = publishable && target.publishable
|
||||||
|
|
||||||
override var sourcesArtifacts: Set<PublishArtifact> = emptySet()
|
@Deprecated(
|
||||||
internal set
|
message = "Sources artifacts are now published as separate variant " +
|
||||||
|
"use target.sourcesElementsConfigurationName to obtain necessary information",
|
||||||
|
replaceWith = ReplaceWith("target.sourcesElementsConfigurationName") )
|
||||||
|
override val sourcesArtifacts: Set<PublishArtifact> get() = target
|
||||||
|
.project
|
||||||
|
.configurations
|
||||||
|
.findByName(target.sourcesElementsConfigurationName)
|
||||||
|
?.artifacts
|
||||||
|
?: emptySet()
|
||||||
|
|
||||||
internal var defaultArtifactIdSuffix: String? = null
|
internal var defaultArtifactIdSuffix: String? = null
|
||||||
|
|
||||||
@@ -102,8 +110,7 @@ class KotlinVariantWithMetadataVariant(
|
|||||||
class JointAndroidKotlinTargetComponent(
|
class JointAndroidKotlinTargetComponent(
|
||||||
override val target: KotlinAndroidTarget,
|
override val target: KotlinAndroidTarget,
|
||||||
private val nestedVariants: Set<KotlinVariant>,
|
private val nestedVariants: Set<KotlinVariant>,
|
||||||
val flavorNames: List<String>,
|
val flavorNames: List<String>
|
||||||
override val sourcesArtifacts: Set<PublishArtifact>
|
|
||||||
) : KotlinTargetComponentWithCoordinatesAndPublication, SoftwareComponentInternal {
|
) : KotlinTargetComponentWithCoordinatesAndPublication, SoftwareComponentInternal {
|
||||||
|
|
||||||
override fun getUsages(): Set<KotlinUsageContext> = nestedVariants.filter { it.publishable }.flatMap { it.usages }.toSet()
|
override fun getUsages(): Set<KotlinUsageContext> = nestedVariants.filter { it.publishable }.flatMap { it.usages }.toSet()
|
||||||
@@ -124,4 +131,11 @@ class JointAndroidKotlinTargetComponent(
|
|||||||
)
|
)
|
||||||
|
|
||||||
override var publicationDelegate: MavenPublication? = null
|
override var publicationDelegate: MavenPublication? = null
|
||||||
|
|
||||||
|
@Deprecated(
|
||||||
|
message = "Sources artifacts are now published as separate variant " +
|
||||||
|
"use target.sourcesElementsConfigurationName to obtain necessary information",
|
||||||
|
replaceWith = ReplaceWith("target.sourcesElementsConfigurationName")
|
||||||
|
)
|
||||||
|
override val sourcesArtifacts: Set<PublishArtifact> = emptySet()
|
||||||
}
|
}
|
||||||
|
|||||||
+77
-36
@@ -11,9 +11,10 @@ import org.gradle.api.InvalidUserDataException
|
|||||||
import org.gradle.api.Named
|
import org.gradle.api.Named
|
||||||
import org.gradle.api.NamedDomainObjectContainer
|
import org.gradle.api.NamedDomainObjectContainer
|
||||||
import org.gradle.api.Project
|
import org.gradle.api.Project
|
||||||
import org.gradle.api.attributes.Attribute
|
import org.gradle.api.artifacts.Configuration
|
||||||
import org.gradle.api.attributes.Usage.JAVA_RUNTIME_JARS
|
import org.gradle.api.attributes.*
|
||||||
import org.jetbrains.kotlin.gradle.plugin.*
|
import org.jetbrains.kotlin.gradle.plugin.*
|
||||||
|
import org.jetbrains.kotlin.gradle.plugin.mpp.pm20.util.copyAttributes
|
||||||
import org.jetbrains.kotlin.gradle.utils.dashSeparatedName
|
import org.jetbrains.kotlin.gradle.utils.dashSeparatedName
|
||||||
import org.jetbrains.kotlin.gradle.utils.forAllAndroidVariants
|
import org.jetbrains.kotlin.gradle.utils.forAllAndroidVariants
|
||||||
import org.jetbrains.kotlin.gradle.utils.lowerCamelCaseName
|
import org.jetbrains.kotlin.gradle.utils.lowerCamelCaseName
|
||||||
@@ -120,33 +121,18 @@ abstract class KotlinAndroidTarget @Inject constructor(
|
|||||||
val androidVariantName = getVariantName(androidVariant)
|
val androidVariantName = getVariantName(androidVariant)
|
||||||
val compilation = compilations.getByName(androidVariantName)
|
val compilation = compilations.getByName(androidVariantName)
|
||||||
|
|
||||||
val flavorNames = getFlavorNames(androidVariant)
|
val usageContexts = createAndroidUsageContexts(
|
||||||
val buildTypeName = getBuildTypeName(androidVariant)
|
variant = androidVariant,
|
||||||
|
compilation = compilation,
|
||||||
val artifactClassifier = buildTypeName.takeIf { it != "release" && publishLibraryVariantsGroupedByFlavor }
|
isSingleBuildType = publishableVariants.filter(::isVariantPublished).map(::getBuildTypeName).distinct().size == 1,
|
||||||
|
)
|
||||||
|
|
||||||
createKotlinVariant(
|
createKotlinVariant(
|
||||||
lowerCamelCaseName(compilation.target.name, *flavorGroupNameParts.toTypedArray()),
|
lowerCamelCaseName(compilation.target.name, *flavorGroupNameParts.toTypedArray()),
|
||||||
compilation,
|
compilation,
|
||||||
createAndroidUsageContexts(
|
usageContexts,
|
||||||
androidVariant,
|
|
||||||
compilation,
|
|
||||||
artifactClassifier,
|
|
||||||
publishableVariants.filter(::isVariantPublished).map(::getBuildTypeName).distinct().size == 1
|
|
||||||
)
|
|
||||||
).apply {
|
).apply {
|
||||||
publishable = isVariantPublished(androidVariant)
|
publishable = isVariantPublished(androidVariant)
|
||||||
sourcesArtifacts = setOf(
|
|
||||||
sourcesJarArtifact(
|
|
||||||
compilation, compilation.disambiguateName(""),
|
|
||||||
dashSeparatedName(
|
|
||||||
compilation.target.name.toLowerCase(),
|
|
||||||
*flavorNames.map { it.toLowerCase() }.toTypedArray(),
|
|
||||||
buildTypeName.takeIf { it != "release" }?.toLowerCase()
|
|
||||||
),
|
|
||||||
classifierPrefix = artifactClassifier
|
|
||||||
)
|
|
||||||
)
|
|
||||||
|
|
||||||
if (!publishLibraryVariantsGroupedByFlavor) {
|
if (!publishLibraryVariantsGroupedByFlavor) {
|
||||||
defaultArtifactIdSuffix =
|
defaultArtifactIdSuffix =
|
||||||
@@ -163,7 +149,6 @@ abstract class KotlinAndroidTarget @Inject constructor(
|
|||||||
target = this@KotlinAndroidTarget,
|
target = this@KotlinAndroidTarget,
|
||||||
nestedVariants = nestedVariants,
|
nestedVariants = nestedVariants,
|
||||||
flavorNames = flavorGroupNameParts,
|
flavorNames = flavorGroupNameParts,
|
||||||
sourcesArtifacts = nestedVariants.filter { it.publishable }.flatMap { it.sourcesArtifacts }.toSet()
|
|
||||||
)
|
)
|
||||||
} else {
|
} else {
|
||||||
nestedVariants.single()
|
nestedVariants.single()
|
||||||
@@ -174,9 +159,12 @@ abstract class KotlinAndroidTarget @Inject constructor(
|
|||||||
private fun AndroidProjectHandler.createAndroidUsageContexts(
|
private fun AndroidProjectHandler.createAndroidUsageContexts(
|
||||||
variant: BaseVariant,
|
variant: BaseVariant,
|
||||||
compilation: KotlinCompilation<*>,
|
compilation: KotlinCompilation<*>,
|
||||||
artifactClassifier: String?,
|
isSingleBuildType: Boolean,
|
||||||
isSingleBuildType: Boolean
|
|
||||||
): Set<DefaultKotlinUsageContext> {
|
): Set<DefaultKotlinUsageContext> {
|
||||||
|
val flavorNames = getFlavorNames(variant)
|
||||||
|
val buildTypeName = getBuildTypeName(variant)
|
||||||
|
val artifactClassifier = buildTypeName.takeIf { it != "release" && publishLibraryVariantsGroupedByFlavor }
|
||||||
|
|
||||||
val variantName = getVariantName(variant)
|
val variantName = getVariantName(variant)
|
||||||
val outputTaskOrProvider = getLibraryOutputTask(variant) ?: return emptySet()
|
val outputTaskOrProvider = getLibraryOutputTask(variant) ?: return emptySet()
|
||||||
val artifact = run {
|
val artifact = run {
|
||||||
@@ -193,9 +181,46 @@ abstract class KotlinAndroidTarget @Inject constructor(
|
|||||||
val apiElementsConfigurationName = lowerCamelCaseName(variantName, "apiElements")
|
val apiElementsConfigurationName = lowerCamelCaseName(variantName, "apiElements")
|
||||||
val runtimeElementsConfigurationName = lowerCamelCaseName(variantName, "runtimeElements")
|
val runtimeElementsConfigurationName = lowerCamelCaseName(variantName, "runtimeElements")
|
||||||
|
|
||||||
|
val sourcesElementsConfigurationName = lowerCamelCaseName(variantName, "sourcesElements")
|
||||||
|
val sourcesElementsConfiguration = createSourcesElementsIfNeeded(
|
||||||
|
variantName,
|
||||||
|
apiElementsConfigurationName,
|
||||||
|
sourcesElementsConfigurationName
|
||||||
|
)
|
||||||
|
configureSourcesJarArtifact(
|
||||||
|
compilation,
|
||||||
|
compilation.disambiguateName(""),
|
||||||
|
dashSeparatedName(
|
||||||
|
compilation.target.name.toLowerCase(),
|
||||||
|
*flavorNames.map { it.toLowerCase() }.toTypedArray(),
|
||||||
|
buildTypeName.takeIf { it != "release" }?.toLowerCase()
|
||||||
|
),
|
||||||
|
classifierPrefix = artifactClassifier,
|
||||||
|
sourcesElementsConfigurationName = sourcesElementsConfigurationName
|
||||||
|
)
|
||||||
|
|
||||||
|
fun AttributeContainer.filterOutAndroidVariantAttributes(): AttributeContainer =
|
||||||
|
HierarchyAttributeContainer(this) {
|
||||||
|
val valueString = run {
|
||||||
|
val value = getAttribute(it)
|
||||||
|
(value as? Named)?.name ?: value.toString()
|
||||||
|
}
|
||||||
|
filterOutAndroidVariantAttribute(it) &&
|
||||||
|
filterOutAndroidBuildTypeAttribute(it, valueString, isSingleBuildType) &&
|
||||||
|
filterOutAndroidAgpVersionAttribute(it)
|
||||||
|
}
|
||||||
|
|
||||||
|
val sourcesUsageContext = DefaultKotlinUsageContext(
|
||||||
|
compilation = compilation,
|
||||||
|
dependencyConfigurationName = sourcesElementsConfigurationName,
|
||||||
|
overrideConfigurationAttributes = sourcesElementsConfiguration.attributes.filterOutAndroidVariantAttributes(),
|
||||||
|
includeDependenciesToMavenPublication = false,
|
||||||
|
includeIntoProjectStructureMetadata = false
|
||||||
|
)
|
||||||
|
|
||||||
return listOf(
|
return listOf(
|
||||||
apiElementsConfigurationName to KotlinUsageContext.UsageScope.COMPILE,
|
apiElementsConfigurationName to KotlinUsageContext.UsageScope.COMPILE,
|
||||||
runtimeElementsConfigurationName to KotlinUsageContext.UsageScope.RUNTIME
|
runtimeElementsConfigurationName to KotlinUsageContext.UsageScope.RUNTIME,
|
||||||
).mapTo(mutableSetOf()) { (dependencyConfigurationName, mavenScope) ->
|
).mapTo(mutableSetOf()) { (dependencyConfigurationName, mavenScope) ->
|
||||||
val configuration = project.configurations.getByName(dependencyConfigurationName)
|
val configuration = project.configurations.getByName(dependencyConfigurationName)
|
||||||
DefaultKotlinUsageContext(
|
DefaultKotlinUsageContext(
|
||||||
@@ -203,16 +228,32 @@ abstract class KotlinAndroidTarget @Inject constructor(
|
|||||||
mavenScope,
|
mavenScope,
|
||||||
dependencyConfigurationName,
|
dependencyConfigurationName,
|
||||||
overrideConfigurationArtifacts = project.setProperty { listOf(artifact) },
|
overrideConfigurationArtifacts = project.setProperty { listOf(artifact) },
|
||||||
overrideConfigurationAttributes = HierarchyAttributeContainer(configuration.attributes) {
|
overrideConfigurationAttributes = configuration.attributes.filterOutAndroidVariantAttributes()
|
||||||
val valueString = run {
|
|
||||||
val value = configuration.attributes.getAttribute(it)
|
|
||||||
(value as? Named)?.name ?: value.toString()
|
|
||||||
}
|
|
||||||
filterOutAndroidVariantAttribute(it) &&
|
|
||||||
filterOutAndroidBuildTypeAttribute(it, valueString, isSingleBuildType) &&
|
|
||||||
filterOutAndroidAgpVersionAttribute(it)
|
|
||||||
}
|
|
||||||
)
|
)
|
||||||
|
} + sourcesUsageContext
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* TODO: Ask Google about providing such configuration where they could set their attributes and control them.
|
||||||
|
* Just like as they do with apiElements or runtimeElements
|
||||||
|
*/
|
||||||
|
private fun createSourcesElementsIfNeeded(
|
||||||
|
variantName: String,
|
||||||
|
apiElementsConfigurationName: String,
|
||||||
|
sourcesElementsConfigurationName: String
|
||||||
|
): Configuration {
|
||||||
|
val existingConfiguration = project.configurations.findByName(sourcesElementsConfigurationName)
|
||||||
|
if (existingConfiguration != null) return existingConfiguration
|
||||||
|
|
||||||
|
val apiElementsConfiguration = project.configurations.getByName(apiElementsConfigurationName)
|
||||||
|
return project.configurations.create(sourcesElementsConfigurationName).apply {
|
||||||
|
description = "Source files of Android ${variantName}."
|
||||||
|
isVisible = false
|
||||||
|
isCanBeResolved = false
|
||||||
|
isCanBeConsumed = true
|
||||||
|
|
||||||
|
copyAttributes(apiElementsConfiguration.attributes, attributes)
|
||||||
|
configureSourcesPublicationAttributes(this@KotlinAndroidTarget)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
+12
-6
@@ -71,20 +71,26 @@ constructor(
|
|||||||
super.kotlinComponents
|
super.kotlinComponents
|
||||||
else {
|
else {
|
||||||
val mainCompilation = compilations.getByName(MAIN_COMPILATION_NAME)
|
val mainCompilation = compilations.getByName(MAIN_COMPILATION_NAME)
|
||||||
val usageContexts = createUsageContexts(mainCompilation) +
|
val usageContexts = createUsageContexts(mainCompilation).toMutableSet()
|
||||||
irTarget!!.createUsageContexts(irTarget!!.compilations.getByName(MAIN_COMPILATION_NAME))
|
|
||||||
|
usageContexts += irTarget!!.createUsageContexts(irTarget!!.compilations.getByName(MAIN_COMPILATION_NAME))
|
||||||
|
|
||||||
val componentName =
|
val componentName =
|
||||||
if (project.kotlinExtension is KotlinMultiplatformExtension)
|
if (project.kotlinExtension is KotlinMultiplatformExtension)
|
||||||
irTarget?.let { targetName.removeJsCompilerSuffix(LEGACY) } ?: targetName
|
irTarget?.let { targetName.removeJsCompilerSuffix(LEGACY) } ?: targetName
|
||||||
else PRIMARY_SINGLE_COMPONENT_NAME
|
else PRIMARY_SINGLE_COMPONENT_NAME
|
||||||
|
|
||||||
val result = createKotlinVariant(componentName, mainCompilation, usageContexts)
|
configureSourcesJarArtifact(mainCompilation, componentName, dashSeparatedName(targetName.toLowerCase()))
|
||||||
|
usageContexts += DefaultKotlinUsageContext(
|
||||||
result.sourcesArtifacts = setOf(
|
compilation = mainCompilation,
|
||||||
sourcesJarArtifact(mainCompilation, componentName, dashSeparatedName(targetName.toLowerCase()))
|
usageScope = KotlinUsageContext.UsageScope.RUNTIME,
|
||||||
|
dependencyConfigurationName = sourcesElementsConfigurationName,
|
||||||
|
includeIntoProjectStructureMetadata = false,
|
||||||
|
includeDependenciesToMavenPublication = false,
|
||||||
)
|
)
|
||||||
|
|
||||||
|
val result = createKotlinVariant(componentName, mainCompilation, usageContexts)
|
||||||
|
|
||||||
setOf(result)
|
setOf(result)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
+9
-4
@@ -101,11 +101,16 @@ abstract class KotlinNativeTarget @Inject constructor(
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
val result = createKotlinVariant(targetName, mainCompilation, mutableUsageContexts)
|
configureSourcesJarArtifact(mainCompilation, targetName, dashSeparatedName(targetName.toLowerCase()))
|
||||||
|
val sourcesUsage = DefaultKotlinUsageContext(
|
||||||
result.sourcesArtifacts = setOf(
|
compilation = mainCompilation,
|
||||||
sourcesJarArtifact(mainCompilation, targetName, dashSeparatedName(targetName.toLowerCase()))
|
dependencyConfigurationName = sourcesElementsConfigurationName,
|
||||||
|
includeIntoProjectStructureMetadata = false,
|
||||||
|
includeDependenciesToMavenPublication = false,
|
||||||
)
|
)
|
||||||
|
mutableUsageContexts += sourcesUsage
|
||||||
|
|
||||||
|
val result = createKotlinVariant(targetName, mainCompilation, mutableUsageContexts)
|
||||||
|
|
||||||
setOf(result)
|
setOf(result)
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user