[Gradle] ExternalKotlinTargetComponent: Implement 'usages' as 'KotlinUsageContext'
... to support multiplatform publication components as re-writing pom dependencies and project structure metadata KT-60159
This commit is contained in:
committed by
Space Team
parent
93f8e21e9e
commit
3d593f0ee9
+13
-78
@@ -8,24 +8,17 @@ import org.gradle.api.Action
|
|||||||
import org.gradle.api.DomainObjectSet
|
import org.gradle.api.DomainObjectSet
|
||||||
import org.gradle.api.Project
|
import org.gradle.api.Project
|
||||||
import org.gradle.api.artifacts.ConfigurablePublishArtifact
|
import org.gradle.api.artifacts.ConfigurablePublishArtifact
|
||||||
import org.gradle.api.attributes.*
|
import org.gradle.api.attributes.AttributeContainer
|
||||||
import org.gradle.api.component.ComponentWithCoordinates
|
|
||||||
import org.gradle.api.component.ComponentWithVariants
|
|
||||||
import org.gradle.api.component.SoftwareComponent
|
|
||||||
import org.gradle.api.component.SoftwareComponentFactory
|
|
||||||
import org.gradle.api.internal.component.SoftwareComponentInternal
|
|
||||||
import org.gradle.api.internal.component.UsageContext
|
|
||||||
import org.gradle.api.internal.project.ProjectInternal
|
|
||||||
import org.gradle.api.publish.maven.MavenPublication
|
import org.gradle.api.publish.maven.MavenPublication
|
||||||
|
import org.jetbrains.kotlin.gradle.DeprecatedTargetPresetApi
|
||||||
import org.jetbrains.kotlin.gradle.InternalKotlinGradlePluginApi
|
import org.jetbrains.kotlin.gradle.InternalKotlinGradlePluginApi
|
||||||
import org.jetbrains.kotlin.gradle.PRESETS_API_IS_DEPRECATED_MESSAGE
|
import org.jetbrains.kotlin.gradle.PRESETS_API_IS_DEPRECATED_MESSAGE
|
||||||
import org.jetbrains.kotlin.gradle.DeprecatedTargetPresetApi
|
|
||||||
import org.jetbrains.kotlin.gradle.dsl.KotlinMultiplatformExtension
|
import org.jetbrains.kotlin.gradle.dsl.KotlinMultiplatformExtension
|
||||||
import org.jetbrains.kotlin.gradle.dsl.kotlinExtension
|
import org.jetbrains.kotlin.gradle.dsl.kotlinExtension
|
||||||
import org.jetbrains.kotlin.gradle.plugin.*
|
import org.jetbrains.kotlin.gradle.plugin.*
|
||||||
import org.jetbrains.kotlin.gradle.plugin.mpp.KotlinUsageContext.MavenScope.*
|
import org.jetbrains.kotlin.gradle.plugin.mpp.KotlinUsageContext.MavenScope.COMPILE
|
||||||
import org.jetbrains.kotlin.gradle.utils.dashSeparatedName
|
import org.jetbrains.kotlin.gradle.plugin.mpp.KotlinUsageContext.MavenScope.RUNTIME
|
||||||
import org.jetbrains.kotlin.gradle.utils.lowerCamelCaseName
|
import org.jetbrains.kotlin.gradle.utils.*
|
||||||
import org.jetbrains.kotlin.tooling.core.MutableExtras
|
import org.jetbrains.kotlin.tooling.core.MutableExtras
|
||||||
import org.jetbrains.kotlin.tooling.core.mutableExtrasOf
|
import org.jetbrains.kotlin.tooling.core.mutableExtrasOf
|
||||||
import org.jetbrains.kotlin.util.capitalizeDecapitalize.toLowerCaseAsciiOnly
|
import org.jetbrains.kotlin.util.capitalizeDecapitalize.toLowerCaseAsciiOnly
|
||||||
@@ -34,7 +27,7 @@ import org.jetbrains.kotlin.utils.addIfNotNull
|
|||||||
internal const val PRIMARY_SINGLE_COMPONENT_NAME = "kotlin"
|
internal const val PRIMARY_SINGLE_COMPONENT_NAME = "kotlin"
|
||||||
|
|
||||||
abstract class AbstractKotlinTarget(
|
abstract class AbstractKotlinTarget(
|
||||||
final override val project: Project
|
final override val project: Project,
|
||||||
) : InternalKotlinTarget {
|
) : InternalKotlinTarget {
|
||||||
|
|
||||||
final override val extras: MutableExtras = mutableExtrasOf()
|
final override val extras: MutableExtras = mutableExtrasOf()
|
||||||
@@ -96,8 +89,13 @@ abstract class AbstractKotlinTarget(
|
|||||||
setOf(result)
|
setOf(result)
|
||||||
}
|
}
|
||||||
|
|
||||||
override val components: Set<SoftwareComponent> by lazy {
|
|
||||||
project.buildAdhocComponentsFromKotlinVariants(kotlinComponents)
|
/**
|
||||||
|
* Returns, potentially not configured (e.g. without some usages), Gradle SoftwareComponent's for this target
|
||||||
|
* For final version of components use [awaitComponents]
|
||||||
|
*/
|
||||||
|
override val components: Set<KotlinTargetSoftwareComponent> by lazy {
|
||||||
|
kotlinComponents.map { kotlinComponent -> KotlinTargetSoftwareComponent(this, kotlinComponent) }.toSet()
|
||||||
}
|
}
|
||||||
|
|
||||||
protected open fun createKotlinVariant(
|
protected open fun createKotlinVariant(
|
||||||
@@ -190,69 +188,6 @@ abstract class AbstractKotlinTarget(
|
|||||||
internal set
|
internal set
|
||||||
}
|
}
|
||||||
|
|
||||||
private val publishedConfigurationNameSuffix = "-published"
|
|
||||||
|
|
||||||
internal fun publishedConfigurationName(originalVariantName: String) = originalVariantName + publishedConfigurationNameSuffix
|
|
||||||
internal fun originalVariantNameFromPublished(publishedConfigurationName: String): String? =
|
|
||||||
publishedConfigurationName.takeIf { it.endsWith(publishedConfigurationNameSuffix) }?.removeSuffix(publishedConfigurationNameSuffix)
|
|
||||||
|
|
||||||
internal fun KotlinTarget.disambiguateName(simpleName: String) =
|
internal fun KotlinTarget.disambiguateName(simpleName: String) =
|
||||||
lowerCamelCaseName(targetName, simpleName)
|
lowerCamelCaseName(targetName, simpleName)
|
||||||
|
|
||||||
internal fun javaApiUsageForMavenScoping() = "java-api-jars"
|
|
||||||
|
|
||||||
internal fun Project.buildAdhocComponentsFromKotlinVariants(kotlinVariants: Set<KotlinTargetComponent>): Set<SoftwareComponent> {
|
|
||||||
val softwareComponentFactoryClass = SoftwareComponentFactory::class.java
|
|
||||||
// TODO replace internal API access with injection (not possible until we have this class on the compile classpath)
|
|
||||||
val softwareComponentFactory = (project as ProjectInternal).services.get(softwareComponentFactoryClass)
|
|
||||||
|
|
||||||
return kotlinVariants.map { kotlinVariant ->
|
|
||||||
val adhocVariant = softwareComponentFactory.adhoc(kotlinVariant.name)
|
|
||||||
|
|
||||||
project.launchInStage(KotlinPluginLifecycle.Stage.AfterFinaliseCompilations) {
|
|
||||||
(kotlinVariant as SoftwareComponentInternal).usages.filterIsInstance<KotlinUsageContext>().forEach { kotlinUsageContext ->
|
|
||||||
val publishedConfigurationName = publishedConfigurationName(kotlinUsageContext.name)
|
|
||||||
val configuration = project.configurations.findByName(publishedConfigurationName)
|
|
||||||
?: project.configurations.create(publishedConfigurationName).also { configuration ->
|
|
||||||
configuration.isCanBeConsumed = false
|
|
||||||
configuration.isCanBeResolved = false
|
|
||||||
configuration.extendsFrom(project.configurations.getByName(kotlinUsageContext.dependencyConfigurationName))
|
|
||||||
configuration.artifacts.addAll(kotlinUsageContext.artifacts)
|
|
||||||
|
|
||||||
val attributes = kotlinUsageContext.attributes
|
|
||||||
attributes.keySet().forEach {
|
|
||||||
// capture type parameter T
|
|
||||||
fun <T> copyAttribute(key: Attribute<T>, from: AttributeContainer, to: AttributeContainer) {
|
|
||||||
to.attribute(key, from.getAttribute(key)!!)
|
|
||||||
}
|
|
||||||
copyAttribute(it, attributes, configuration.attributes)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
adhocVariant.addVariantsFromConfiguration(configuration) { configurationVariantDetails ->
|
|
||||||
val mavenScope = kotlinUsageContext.mavenScope
|
|
||||||
if (mavenScope != null) {
|
|
||||||
val mavenScopeString = when (mavenScope) {
|
|
||||||
COMPILE -> "compile"
|
|
||||||
RUNTIME -> "runtime"
|
|
||||||
}
|
|
||||||
configurationVariantDetails.mapToMavenScope(mavenScopeString)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
adhocVariant as SoftwareComponent
|
|
||||||
|
|
||||||
object : ComponentWithVariants, ComponentWithCoordinates, SoftwareComponentInternal {
|
|
||||||
override fun getCoordinates() =
|
|
||||||
(kotlinVariant as? ComponentWithCoordinates)?.coordinates ?: error("kotlinVariant is not ComponentWithCoordinates")
|
|
||||||
|
|
||||||
override fun getVariants(): Set<SoftwareComponent> =
|
|
||||||
(kotlinVariant as? KotlinVariantWithMetadataVariant)?.variants.orEmpty()
|
|
||||||
|
|
||||||
override fun getName(): String = adhocVariant.name
|
|
||||||
override fun getUsages(): MutableSet<out UsageContext> = (adhocVariant as SoftwareComponentInternal).usages
|
|
||||||
}
|
|
||||||
}.toSet()
|
|
||||||
}
|
|
||||||
|
|||||||
+5
@@ -6,6 +6,8 @@
|
|||||||
package org.jetbrains.kotlin.gradle.plugin.mpp
|
package org.jetbrains.kotlin.gradle.plugin.mpp
|
||||||
|
|
||||||
import org.gradle.api.publish.maven.MavenPublication
|
import org.gradle.api.publish.maven.MavenPublication
|
||||||
|
import org.jetbrains.kotlin.gradle.InternalKotlinGradlePluginApi
|
||||||
|
import org.jetbrains.kotlin.gradle.plugin.KotlinPluginLifecycle
|
||||||
import org.jetbrains.kotlin.gradle.plugin.KotlinTarget
|
import org.jetbrains.kotlin.gradle.plugin.KotlinTarget
|
||||||
import org.jetbrains.kotlin.gradle.plugin.KotlinTargetComponent
|
import org.jetbrains.kotlin.gradle.plugin.KotlinTargetComponent
|
||||||
import org.jetbrains.kotlin.tooling.core.HasMutableExtras
|
import org.jetbrains.kotlin.tooling.core.HasMutableExtras
|
||||||
@@ -13,6 +15,9 @@ import org.jetbrains.kotlin.tooling.core.HasMutableExtras
|
|||||||
internal interface InternalKotlinTarget : KotlinTarget, HasMutableExtras {
|
internal interface InternalKotlinTarget : KotlinTarget, HasMutableExtras {
|
||||||
var isSourcesPublishable: Boolean
|
var isSourcesPublishable: Boolean
|
||||||
val kotlinComponents: Set<KotlinTargetComponent>
|
val kotlinComponents: Set<KotlinTargetComponent>
|
||||||
|
|
||||||
|
@InternalKotlinGradlePluginApi
|
||||||
|
override val components: Set<KotlinTargetSoftwareComponent>
|
||||||
fun onPublicationCreated(publication: MavenPublication)
|
fun onPublicationCreated(publication: MavenPublication)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
+21
@@ -0,0 +1,21 @@
|
|||||||
|
/*
|
||||||
|
* Copyright 2010-2023 JetBrains s.r.o. and Kotlin Programming Language contributors.
|
||||||
|
* Use of this source code is governed by the Apache 2.0 license that can be found in the license/LICENSE.txt file.
|
||||||
|
*/
|
||||||
|
|
||||||
|
package org.jetbrains.kotlin.gradle.plugin.mpp
|
||||||
|
|
||||||
|
import org.gradle.api.internal.component.SoftwareComponentInternal
|
||||||
|
import org.jetbrains.kotlin.gradle.InternalKotlinGradlePluginApi
|
||||||
|
import org.jetbrains.kotlin.gradle.plugin.KotlinTargetComponent
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Enforced 'internal' common supertype for all [KotlinTargetComponent] implementations.
|
||||||
|
*/
|
||||||
|
@InternalKotlinGradlePluginApi
|
||||||
|
abstract class InternalKotlinTargetComponent : KotlinTargetComponent, SoftwareComponentInternal {
|
||||||
|
abstract override fun getUsages(): Set<KotlinUsageContext>
|
||||||
|
}
|
||||||
|
|
||||||
|
internal val KotlinTargetComponent.internal: InternalKotlinTargetComponent
|
||||||
|
get() = this as InternalKotlinTargetComponent
|
||||||
+20
@@ -0,0 +1,20 @@
|
|||||||
|
/*
|
||||||
|
* Copyright 2010-2023 JetBrains s.r.o. and Kotlin Programming Language contributors.
|
||||||
|
* Use of this source code is governed by the Apache 2.0 license that can be found in the license/LICENSE.txt file.
|
||||||
|
*/
|
||||||
|
|
||||||
|
package org.jetbrains.kotlin.gradle.plugin.mpp
|
||||||
|
|
||||||
|
import org.gradle.api.component.ComponentWithCoordinates
|
||||||
|
import org.gradle.api.component.ComponentWithVariants
|
||||||
|
import org.gradle.api.internal.component.SoftwareComponentInternal
|
||||||
|
import org.jetbrains.kotlin.gradle.InternalKotlinGradlePluginApi
|
||||||
|
import org.jetbrains.kotlin.gradle.plugin.mpp.external.ExternalKotlinTargetSoftwareComponent
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Common supertype for
|
||||||
|
* - [KotlinTargetSoftwareComponentImpl]: internal targets
|
||||||
|
* - [ExternalKotlinTargetSoftwareComponent]: external targets
|
||||||
|
*/
|
||||||
|
@InternalKotlinGradlePluginApi
|
||||||
|
abstract class KotlinTargetSoftwareComponent : ComponentWithVariants, ComponentWithCoordinates, SoftwareComponentInternal
|
||||||
+86
@@ -0,0 +1,86 @@
|
|||||||
|
/*
|
||||||
|
* Copyright 2010-2023 JetBrains s.r.o. and Kotlin Programming Language contributors.
|
||||||
|
* Use of this source code is governed by the Apache 2.0 license that can be found in the license/LICENSE.txt file.
|
||||||
|
*/
|
||||||
|
|
||||||
|
package org.jetbrains.kotlin.gradle.plugin.mpp
|
||||||
|
|
||||||
|
import org.gradle.api.Project
|
||||||
|
import org.gradle.api.component.AdhocComponentWithVariants
|
||||||
|
import org.gradle.api.component.ComponentWithCoordinates
|
||||||
|
import org.gradle.api.component.SoftwareComponent
|
||||||
|
import org.gradle.api.component.SoftwareComponentFactory
|
||||||
|
import org.gradle.api.internal.component.SoftwareComponentInternal
|
||||||
|
import org.gradle.api.internal.component.UsageContext
|
||||||
|
import org.gradle.api.internal.project.ProjectInternal
|
||||||
|
import org.jetbrains.kotlin.gradle.plugin.KotlinPluginLifecycle
|
||||||
|
import org.jetbrains.kotlin.gradle.plugin.KotlinTargetComponent
|
||||||
|
import org.jetbrains.kotlin.gradle.plugin.launchInStage
|
||||||
|
import org.jetbrains.kotlin.gradle.plugin.mpp.pm20.util.copyAttributes
|
||||||
|
import org.jetbrains.kotlin.tooling.core.UnsafeApi
|
||||||
|
|
||||||
|
internal fun KotlinTargetSoftwareComponent(
|
||||||
|
target: AbstractKotlinTarget,
|
||||||
|
kotlinComponent: KotlinTargetComponent,
|
||||||
|
): KotlinTargetSoftwareComponent {
|
||||||
|
val softwareComponentFactory = (target.project as ProjectInternal).services.get(SoftwareComponentFactory::class.java)
|
||||||
|
val adhocVariant = softwareComponentFactory.adhoc(kotlinComponent.name)
|
||||||
|
|
||||||
|
/* Launch configuration */
|
||||||
|
target.project.launchInStage(KotlinPluginLifecycle.Stage.AfterFinaliseCompilations) {
|
||||||
|
kotlinComponent.internal.usages.forEach { kotlinUsageContext ->
|
||||||
|
/* Explicitly typing 'Project' to avoid smart cast from 'target.project as ProjectInternal' */
|
||||||
|
val project: Project = target.project
|
||||||
|
val publishedConfigurationName = publishedConfigurationName(kotlinUsageContext.name)
|
||||||
|
val configuration = project.configurations.findByName(publishedConfigurationName)
|
||||||
|
?: project.configurations.create(publishedConfigurationName).also { publishedConfiguration ->
|
||||||
|
publishedConfiguration.isCanBeConsumed = false
|
||||||
|
publishedConfiguration.isCanBeResolved = false
|
||||||
|
publishedConfiguration.extendsFrom(project.configurations.getByName(kotlinUsageContext.dependencyConfigurationName))
|
||||||
|
publishedConfiguration.artifacts.addAll(kotlinUsageContext.artifacts)
|
||||||
|
copyAttributes(from = kotlinUsageContext.attributes, to = publishedConfiguration.attributes)
|
||||||
|
}
|
||||||
|
|
||||||
|
adhocVariant.addVariantsFromConfiguration(configuration) { configurationVariantDetails ->
|
||||||
|
val mavenScope = kotlinUsageContext.mavenScope
|
||||||
|
if (mavenScope != null) {
|
||||||
|
val mavenScopeString = when (mavenScope) {
|
||||||
|
KotlinUsageContext.MavenScope.COMPILE -> "compile"
|
||||||
|
KotlinUsageContext.MavenScope.RUNTIME -> "runtime"
|
||||||
|
}
|
||||||
|
configurationVariantDetails.mapToMavenScope(mavenScopeString)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@OptIn(UnsafeApi::class)
|
||||||
|
return KotlinTargetSoftwareComponentImpl(adhocVariant, kotlinComponent)
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/* Smaller Utils functions */
|
||||||
|
|
||||||
|
private val publishedConfigurationNameSuffix = "-published"
|
||||||
|
|
||||||
|
internal fun originalVariantNameFromPublished(publishedConfigurationName: String): String? =
|
||||||
|
publishedConfigurationName.takeIf { it.endsWith(publishedConfigurationNameSuffix) }?.removeSuffix(publishedConfigurationNameSuffix)
|
||||||
|
|
||||||
|
internal fun publishedConfigurationName(originalVariantName: String) = originalVariantName + publishedConfigurationNameSuffix
|
||||||
|
|
||||||
|
/* KotlinTargetSoftwareComponent Implementation */
|
||||||
|
|
||||||
|
internal class KotlinTargetSoftwareComponentImpl @UnsafeApi constructor(
|
||||||
|
private val adhocComponent: AdhocComponentWithVariants,
|
||||||
|
private val kotlinComponent: KotlinTargetComponent,
|
||||||
|
) : KotlinTargetSoftwareComponent() {
|
||||||
|
|
||||||
|
override fun getCoordinates() =
|
||||||
|
(kotlinComponent as? ComponentWithCoordinates)?.coordinates ?: error("kotlinComponent is not ComponentWithCoordinates")
|
||||||
|
|
||||||
|
override fun getVariants(): Set<SoftwareComponent> =
|
||||||
|
(kotlinComponent as? KotlinVariantWithMetadataVariant)?.variants.orEmpty()
|
||||||
|
|
||||||
|
override fun getName(): String = adhocComponent.name
|
||||||
|
override fun getUsages(): MutableSet<out UsageContext> = (adhocComponent as SoftwareComponentInternal).usages
|
||||||
|
}
|
||||||
+26
-6
@@ -10,16 +10,17 @@ import org.gradle.api.artifacts.PublishArtifact
|
|||||||
import org.gradle.api.component.ComponentWithCoordinates
|
import org.gradle.api.component.ComponentWithCoordinates
|
||||||
import org.gradle.api.publish.maven.MavenPublication
|
import org.gradle.api.publish.maven.MavenPublication
|
||||||
import org.jetbrains.kotlin.gradle.dsl.KotlinMultiplatformExtension
|
import org.jetbrains.kotlin.gradle.dsl.KotlinMultiplatformExtension
|
||||||
import org.jetbrains.kotlin.gradle.plugin.KotlinTarget
|
import org.jetbrains.kotlin.gradle.plugin.KotlinCompilation
|
||||||
import org.jetbrains.kotlin.gradle.plugin.mpp.KotlinTargetComponentWithPublication
|
import org.jetbrains.kotlin.gradle.plugin.mpp.*
|
||||||
|
import org.jetbrains.kotlin.gradle.plugin.mpp.KotlinUsageContext.MavenScope.COMPILE
|
||||||
|
import org.jetbrains.kotlin.gradle.plugin.mpp.KotlinUsageContext.MavenScope.RUNTIME
|
||||||
import org.jetbrains.kotlin.gradle.plugin.mpp.external.ExternalKotlinTargetComponent.TargetProvider
|
import org.jetbrains.kotlin.gradle.plugin.mpp.external.ExternalKotlinTargetComponent.TargetProvider
|
||||||
import org.jetbrains.kotlin.gradle.plugin.mpp.getCoordinatesFromPublicationDelegateAndProject
|
|
||||||
import org.jetbrains.kotlin.gradle.utils.dashSeparatedName
|
import org.jetbrains.kotlin.gradle.utils.dashSeparatedName
|
||||||
import org.jetbrains.kotlin.util.capitalizeDecapitalize.toLowerCaseAsciiOnly
|
import org.jetbrains.kotlin.util.capitalizeDecapitalize.toLowerCaseAsciiOnly
|
||||||
|
|
||||||
internal class ExternalKotlinTargetComponent(
|
internal class ExternalKotlinTargetComponent(
|
||||||
val targetProvider: TargetProvider
|
val targetProvider: TargetProvider,
|
||||||
) : KotlinTargetComponentWithPublication, ComponentWithCoordinates {
|
) : InternalKotlinTargetComponent(), KotlinTargetComponentWithPublication, ComponentWithCoordinates {
|
||||||
|
|
||||||
/*
|
/*
|
||||||
Target creation requires this component. We will provide the target once it is required
|
Target creation requires this component. We will provide the target once it is required
|
||||||
@@ -37,7 +38,7 @@ internal class ExternalKotlinTargetComponent(
|
|||||||
/* Required for getting correct coordinates */
|
/* Required for getting correct coordinates */
|
||||||
override var publicationDelegate: MavenPublication? = null
|
override var publicationDelegate: MavenPublication? = null
|
||||||
|
|
||||||
override val target: KotlinTarget by lazy { targetProvider() }
|
override val target: DecoratedExternalKotlinTarget by lazy { targetProvider() }
|
||||||
|
|
||||||
override val publishable: Boolean
|
override val publishable: Boolean
|
||||||
get() = target.publishable
|
get() = target.publishable
|
||||||
@@ -60,4 +61,23 @@ internal class ExternalKotlinTargetComponent(
|
|||||||
|
|
||||||
override fun getCoordinates(): ModuleVersionIdentifier =
|
override fun getCoordinates(): ModuleVersionIdentifier =
|
||||||
getCoordinatesFromPublicationDelegateAndProject(publicationDelegate, target.project, null)
|
getCoordinatesFromPublicationDelegateAndProject(publicationDelegate, target.project, null)
|
||||||
|
|
||||||
|
private val _usages: Set<DefaultKotlinUsageContext> by lazy {
|
||||||
|
val compilation = target.compilations.findByName(KotlinCompilation.MAIN_COMPILATION_NAME)
|
||||||
|
?: error("Missing conventional '${KotlinCompilation.MAIN_COMPILATION_NAME}' compilation in '$target'")
|
||||||
|
|
||||||
|
setOf(
|
||||||
|
DefaultKotlinUsageContext(compilation, COMPILE, target.apiElementsPublishedConfiguration.name),
|
||||||
|
DefaultKotlinUsageContext(compilation, RUNTIME, target.runtimeElementsPublishedConfiguration.name),
|
||||||
|
DefaultKotlinUsageContext(
|
||||||
|
compilation = compilation,
|
||||||
|
mavenScope = null,
|
||||||
|
dependencyConfigurationName = target.sourcesElementsPublishedConfiguration.name,
|
||||||
|
includeIntoProjectStructureMetadata = false,
|
||||||
|
publishOnlyIf = { target.isSourcesPublishable }
|
||||||
|
)
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
|
override fun getUsages(): Set<KotlinUsageContext> = _usages.filter { it.publishOnlyIf.predicate() }.toSet()
|
||||||
}
|
}
|
||||||
|
|||||||
+7
-5
@@ -1,13 +1,11 @@
|
|||||||
/*
|
/*
|
||||||
* Copyright 2010-2022 JetBrains s.r.o. and Kotlin Programming Language contributors.
|
* Copyright 2010-2023 JetBrains s.r.o. and Kotlin Programming Language contributors.
|
||||||
* Use of this source code is governed by the Apache 2.0 license that can be found in the license/LICENSE.txt file.
|
* Use of this source code is governed by the Apache 2.0 license that can be found in the license/LICENSE.txt file.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
package org.jetbrains.kotlin.gradle.plugin.mpp.external
|
package org.jetbrains.kotlin.gradle.plugin.mpp.external
|
||||||
|
|
||||||
import org.gradle.api.artifacts.ModuleVersionIdentifier
|
import org.gradle.api.artifacts.ModuleVersionIdentifier
|
||||||
import org.gradle.api.component.ComponentWithCoordinates
|
|
||||||
import org.gradle.api.component.ComponentWithVariants
|
|
||||||
import org.gradle.api.component.SoftwareComponent
|
import org.gradle.api.component.SoftwareComponent
|
||||||
import org.gradle.api.component.SoftwareComponentFactory
|
import org.gradle.api.component.SoftwareComponentFactory
|
||||||
import org.gradle.api.internal.component.SoftwareComponentInternal
|
import org.gradle.api.internal.component.SoftwareComponentInternal
|
||||||
@@ -15,8 +13,11 @@ import org.gradle.api.internal.component.UsageContext
|
|||||||
import org.gradle.api.internal.project.ProjectInternal
|
import org.gradle.api.internal.project.ProjectInternal
|
||||||
import org.jetbrains.kotlin.gradle.dsl.KotlinMultiplatformExtension
|
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.plugin.launch
|
||||||
|
import org.jetbrains.kotlin.gradle.plugin.mpp.KotlinTargetSoftwareComponent
|
||||||
import org.jetbrains.kotlin.tooling.core.UnsafeApi
|
import org.jetbrains.kotlin.tooling.core.UnsafeApi
|
||||||
|
|
||||||
|
|
||||||
internal fun ExternalKotlinTargetSoftwareComponent(
|
internal fun ExternalKotlinTargetSoftwareComponent(
|
||||||
target: ExternalKotlinTargetImpl,
|
target: ExternalKotlinTargetImpl,
|
||||||
): ExternalKotlinTargetSoftwareComponent {
|
): ExternalKotlinTargetSoftwareComponent {
|
||||||
@@ -39,7 +40,7 @@ internal fun ExternalKotlinTargetSoftwareComponent(
|
|||||||
return ExternalKotlinTargetSoftwareComponent(
|
return ExternalKotlinTargetSoftwareComponent(
|
||||||
target.project.multiplatformExtension,
|
target.project.multiplatformExtension,
|
||||||
adhocSoftwareComponent as SoftwareComponentInternal,
|
adhocSoftwareComponent as SoftwareComponentInternal,
|
||||||
target.kotlinTargetComponent
|
target.kotlinTargetComponent,
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -47,7 +48,8 @@ internal class ExternalKotlinTargetSoftwareComponent @UnsafeApi constructor(
|
|||||||
private val multiplatformExtension: KotlinMultiplatformExtension,
|
private val multiplatformExtension: KotlinMultiplatformExtension,
|
||||||
private val adhocSoftwareComponent: SoftwareComponentInternal,
|
private val adhocSoftwareComponent: SoftwareComponentInternal,
|
||||||
private val kotlinTargetComponent: ExternalKotlinTargetComponent,
|
private val kotlinTargetComponent: ExternalKotlinTargetComponent,
|
||||||
) : ComponentWithCoordinates, ComponentWithVariants, SoftwareComponentInternal {
|
) : KotlinTargetSoftwareComponent() {
|
||||||
|
|
||||||
override fun getName(): String = adhocSoftwareComponent.name
|
override fun getName(): String = adhocSoftwareComponent.name
|
||||||
override fun getUsages(): Set<UsageContext> = adhocSoftwareComponent.usages
|
override fun getUsages(): Set<UsageContext> = adhocSoftwareComponent.usages
|
||||||
override fun getVariants(): Set<SoftwareComponent> = multiplatformExtension.metadata().components
|
override fun getVariants(): Set<SoftwareComponent> = multiplatformExtension.metadata().components
|
||||||
|
|||||||
+2
-2
@@ -59,7 +59,7 @@ private interface KotlinTargetComponentWithCoordinatesAndPublication :
|
|||||||
open class KotlinVariant(
|
open class KotlinVariant(
|
||||||
val producingCompilation: KotlinCompilation<*>,
|
val producingCompilation: KotlinCompilation<*>,
|
||||||
private val usages: Set<DefaultKotlinUsageContext>
|
private val usages: Set<DefaultKotlinUsageContext>
|
||||||
) : KotlinTargetComponentWithPublication, SoftwareComponentInternal {
|
) : InternalKotlinTargetComponent(), KotlinTargetComponentWithPublication {
|
||||||
var componentName: String? = null
|
var componentName: String? = null
|
||||||
|
|
||||||
var artifactTargetName: String = target.targetName
|
var artifactTargetName: String = target.targetName
|
||||||
@@ -112,7 +112,7 @@ 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>
|
||||||
) : KotlinTargetComponentWithCoordinatesAndPublication, SoftwareComponentInternal {
|
) : InternalKotlinTargetComponent(), KotlinTargetComponentWithCoordinatesAndPublication {
|
||||||
|
|
||||||
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()
|
||||||
|
|
||||||
|
|||||||
+8
-13
@@ -12,7 +12,6 @@ import org.gradle.api.attributes.Category
|
|||||||
import org.gradle.api.attributes.Category.CATEGORY_ATTRIBUTE
|
import org.gradle.api.attributes.Category.CATEGORY_ATTRIBUTE
|
||||||
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.component.SoftwareComponentInternal
|
|
||||||
import org.gradle.api.plugins.BasePlugin
|
import org.gradle.api.plugins.BasePlugin
|
||||||
import org.gradle.api.tasks.TaskProvider
|
import org.gradle.api.tasks.TaskProvider
|
||||||
import org.gradle.api.tasks.bundling.Jar
|
import org.gradle.api.tasks.bundling.Jar
|
||||||
@@ -189,7 +188,7 @@ class KotlinMetadataTargetConfigurator :
|
|||||||
|
|
||||||
private fun createMetadataCompilationsForCommonSourceSets(
|
private fun createMetadataCompilationsForCommonSourceSets(
|
||||||
target: KotlinMetadataTarget,
|
target: KotlinMetadataTarget,
|
||||||
allMetadataJar: TaskProvider<out Jar>
|
allMetadataJar: TaskProvider<out Jar>,
|
||||||
) = target.project.launchInStage(KotlinPluginLifecycle.Stage.AfterFinaliseDsl) {
|
) = target.project.launchInStage(KotlinPluginLifecycle.Stage.AfterFinaliseDsl) {
|
||||||
withRestrictedStages(KotlinPluginLifecycle.Stage.upTo(KotlinPluginLifecycle.Stage.FinaliseCompilations)) {
|
withRestrictedStages(KotlinPluginLifecycle.Stage.upTo(KotlinPluginLifecycle.Stage.FinaliseCompilations)) {
|
||||||
// Do this after all targets are configured by the user build script
|
// Do this after all targets are configured by the user build script
|
||||||
@@ -255,7 +254,7 @@ class KotlinMetadataTargetConfigurator :
|
|||||||
}
|
}
|
||||||
|
|
||||||
private fun exportDependenciesForPublishing(
|
private fun exportDependenciesForPublishing(
|
||||||
compilation: KotlinCompilation<*>
|
compilation: KotlinCompilation<*>,
|
||||||
) {
|
) {
|
||||||
val sourceSet = compilation.defaultSourceSet
|
val sourceSet = compilation.defaultSourceSet
|
||||||
val isSharedNativeCompilation = compilation is KotlinSharedNativeCompilation
|
val isSharedNativeCompilation = compilation is KotlinSharedNativeCompilation
|
||||||
@@ -295,7 +294,7 @@ class KotlinMetadataTargetConfigurator :
|
|||||||
target: KotlinMetadataTarget,
|
target: KotlinMetadataTarget,
|
||||||
sourceSet: KotlinSourceSet,
|
sourceSet: KotlinSourceSet,
|
||||||
allMetadataJar: TaskProvider<out Jar>,
|
allMetadataJar: TaskProvider<out Jar>,
|
||||||
isHostSpecific: Boolean
|
isHostSpecific: Boolean,
|
||||||
): KotlinCompilation<*> {
|
): KotlinCompilation<*> {
|
||||||
val project = target.project
|
val project = target.project
|
||||||
|
|
||||||
@@ -392,7 +391,7 @@ class KotlinMetadataTargetConfigurator :
|
|||||||
}
|
}
|
||||||
|
|
||||||
internal class NativeSharedCompilationProcessor(
|
internal class NativeSharedCompilationProcessor(
|
||||||
private val compilation: KotlinSharedNativeCompilation
|
private val compilation: KotlinSharedNativeCompilation,
|
||||||
) : KotlinCompilationProcessor<KotlinNativeCompile>(KotlinCompilationInfo(compilation)) {
|
) : KotlinCompilationProcessor<KotlinNativeCompile>(KotlinCompilationInfo(compilation)) {
|
||||||
|
|
||||||
override val kotlinTask: TaskProvider<out KotlinNativeCompile> =
|
override val kotlinTask: TaskProvider<out KotlinNativeCompile> =
|
||||||
@@ -472,18 +471,14 @@ internal suspend fun getCommonSourceSetsForMetadataCompilation(project: Project)
|
|||||||
internal suspend fun getPublishedPlatformCompilations(project: Project): Map<KotlinUsageContext, KotlinCompilation<*>> {
|
internal suspend fun getPublishedPlatformCompilations(project: Project): Map<KotlinUsageContext, KotlinCompilation<*>> {
|
||||||
val result = mutableMapOf<KotlinUsageContext, KotlinCompilation<*>>()
|
val result = mutableMapOf<KotlinUsageContext, KotlinCompilation<*>>()
|
||||||
|
|
||||||
project.multiplatformExtension.awaitTargets().withType(AbstractKotlinTarget::class.java).forEach { target ->
|
project.multiplatformExtension.awaitTargets().withType(InternalKotlinTarget::class.java).forEach { target ->
|
||||||
if (target.platformType == KotlinPlatformType.common)
|
if (target.platformType == KotlinPlatformType.common)
|
||||||
return@forEach
|
return@forEach
|
||||||
|
|
||||||
target.kotlinComponents
|
target.kotlinComponents
|
||||||
.filterIsInstance<SoftwareComponentInternal>()
|
.flatMap { component -> component.internal.usages }
|
||||||
.forEach { component ->
|
.filter { it.includeIntoProjectStructureMetadata }
|
||||||
component.usages
|
.forEach { usage -> result[usage] = usage.compilation }
|
||||||
.filterIsInstance<KotlinUsageContext>()
|
|
||||||
.filter { it.includeIntoProjectStructureMetadata }
|
|
||||||
.forEach { usage -> result[usage] = usage.compilation }
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
return result
|
return result
|
||||||
|
|||||||
+20
@@ -0,0 +1,20 @@
|
|||||||
|
/*
|
||||||
|
* Copyright 2010-2023 JetBrains s.r.o. and Kotlin Programming Language contributors.
|
||||||
|
* Use of this source code is governed by the Apache 2.0 license that can be found in the license/LICENSE.txt file.
|
||||||
|
*/
|
||||||
|
|
||||||
|
@file:Suppress("FunctionName")
|
||||||
|
|
||||||
|
package org.jetbrains.kotlin.gradle.unitTests
|
||||||
|
|
||||||
|
import org.jetbrains.kotlin.gradle.plugin.KotlinTargetComponent
|
||||||
|
import org.jetbrains.kotlin.gradle.plugin.mpp.InternalKotlinTargetComponent
|
||||||
|
import org.jetbrains.kotlin.gradle.util.assertAllImplementationsAlsoImplement
|
||||||
|
import kotlin.test.Test
|
||||||
|
|
||||||
|
class InternalKotlinTargetComponentTest {
|
||||||
|
@Test
|
||||||
|
fun `test - all implementations of KotlinTargetComponent - implement InternalKotlinTargetComponent`() {
|
||||||
|
assertAllImplementationsAlsoImplement(KotlinTargetComponent::class, InternalKotlinTargetComponent::class)
|
||||||
|
}
|
||||||
|
}
|
||||||
+3
-1
@@ -124,7 +124,7 @@ class MppPublicationTest {
|
|||||||
|
|
||||||
for ((targetName, sourceElements) in sourcesElements) {
|
for ((targetName, sourceElements) in sourcesElements) {
|
||||||
assertTrue(
|
assertTrue(
|
||||||
message = "Sources Elements of target $targetName doesn't have 'userAttribute'"
|
message = "$sourceElements of target $targetName doesn't have 'userAttribute'"
|
||||||
) { sourceElements.attributes.toMapOfStrings().containsKey("userAttribute") }
|
) { sourceElements.attributes.toMapOfStrings().containsKey("userAttribute") }
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -143,6 +143,7 @@ class MppPublicationTest {
|
|||||||
@Test
|
@Test
|
||||||
fun `sourcesJar task should be available during configuration time`() {
|
fun `sourcesJar task should be available during configuration time`() {
|
||||||
kotlin.linuxX64("linux")
|
kotlin.linuxX64("linux")
|
||||||
|
project.evaluate()
|
||||||
|
|
||||||
val sourcesJars = listOf(
|
val sourcesJars = listOf(
|
||||||
"sourcesJar", // sources of common source sets i.e. root module
|
"sourcesJar", // sources of common source sets i.e. root module
|
||||||
@@ -187,6 +188,7 @@ class MppPublicationTest {
|
|||||||
fun `test that sourcesJar tasks still exist even if sources should not be published`() {
|
fun `test that sourcesJar tasks still exist even if sources should not be published`() {
|
||||||
kotlin.linuxX64("linux")
|
kotlin.linuxX64("linux")
|
||||||
kotlin.withSourcesJar(publish = false)
|
kotlin.withSourcesJar(publish = false)
|
||||||
|
project.evaluate()
|
||||||
|
|
||||||
val sourcesJars = listOf(
|
val sourcesJars = listOf(
|
||||||
"sourcesJar", // sources of common source sets i.e. root module
|
"sourcesJar", // sources of common source sets i.e. root module
|
||||||
|
|||||||
+3
-3
@@ -190,7 +190,7 @@ class ProjectCompilerOptionsTests {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
assertEquals(true, project.kotlinJvmTask("compileFakeKotlinFake").compilerOptions.javaParameters.get())
|
assertEquals(true, project.kotlinJvmTask("compileKotlinFake").compilerOptions.javaParameters.get())
|
||||||
assertEquals(true, project.kotlinJvmTask("compileTestKotlinFake").compilerOptions.javaParameters.get())
|
assertEquals(true, project.kotlinJvmTask("compileTestKotlinFake").compilerOptions.javaParameters.get())
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -199,7 +199,7 @@ class ProjectCompilerOptionsTests {
|
|||||||
val project = buildProjectWithMPP()
|
val project = buildProjectWithMPP()
|
||||||
project.runLifecycleAwareTest {
|
project.runLifecycleAwareTest {
|
||||||
tasks.withType<KotlinJvmCompileTask>().configureEach {
|
tasks.withType<KotlinJvmCompileTask>().configureEach {
|
||||||
if (it.name == "compileFakeKotlinFake") {
|
if (it.name == "compileKotlinFake") {
|
||||||
it.compilerOptions.javaParameters.set(false)
|
it.compilerOptions.javaParameters.set(false)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -215,7 +215,7 @@ class ProjectCompilerOptionsTests {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
assertEquals(false, project.kotlinJvmTask("compileFakeKotlinFake").compilerOptions.javaParameters.get())
|
assertEquals(false, project.kotlinJvmTask("compileKotlinFake").compilerOptions.javaParameters.get())
|
||||||
assertEquals(true, project.kotlinJvmTask("compileTestKotlinFake").compilerOptions.javaParameters.get())
|
assertEquals(true, project.kotlinJvmTask("compileTestKotlinFake").compilerOptions.javaParameters.get())
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
+3
-1
@@ -8,6 +8,7 @@ package org.jetbrains.kotlin.gradle.util
|
|||||||
import org.gradle.api.NamedDomainObjectContainer
|
import org.gradle.api.NamedDomainObjectContainer
|
||||||
import org.jetbrains.kotlin.gradle.dsl.*
|
import org.jetbrains.kotlin.gradle.dsl.*
|
||||||
import org.jetbrains.kotlin.gradle.plugin.HasCompilerOptions
|
import org.jetbrains.kotlin.gradle.plugin.HasCompilerOptions
|
||||||
|
import org.jetbrains.kotlin.gradle.plugin.KotlinCompilation
|
||||||
import org.jetbrains.kotlin.gradle.plugin.KotlinPlatformType
|
import org.jetbrains.kotlin.gradle.plugin.KotlinPlatformType
|
||||||
import org.jetbrains.kotlin.gradle.plugin.mpp.external.*
|
import org.jetbrains.kotlin.gradle.plugin.mpp.external.*
|
||||||
import org.jetbrains.kotlin.gradle.plugin.mpp.external.ExternalKotlinCompilationDescriptor.CompilationFactory
|
import org.jetbrains.kotlin.gradle.plugin.mpp.external.ExternalKotlinCompilationDescriptor.CompilationFactory
|
||||||
@@ -18,6 +19,7 @@ class FakeCompilation(delegate: Delegate) : DecoratedExternalKotlinCompilation(d
|
|||||||
override val compilerOptions: HasCompilerOptions<KotlinJvmCompilerOptions>
|
override val compilerOptions: HasCompilerOptions<KotlinJvmCompilerOptions>
|
||||||
get() = super.compilerOptions as HasCompilerOptions<KotlinJvmCompilerOptions>
|
get() = super.compilerOptions as HasCompilerOptions<KotlinJvmCompilerOptions>
|
||||||
}
|
}
|
||||||
|
|
||||||
class FakeTarget(delegate: Delegate) : DecoratedExternalKotlinTarget(delegate) {
|
class FakeTarget(delegate: Delegate) : DecoratedExternalKotlinTarget(delegate) {
|
||||||
|
|
||||||
@Suppress("UNCHECKED_CAST")
|
@Suppress("UNCHECKED_CAST")
|
||||||
@@ -40,7 +42,7 @@ fun ExternalKotlinTargetDescriptorBuilder<FakeTarget>.defaults() {
|
|||||||
|
|
||||||
fun ExternalKotlinCompilationDescriptorBuilder<FakeCompilation>.defaults(
|
fun ExternalKotlinCompilationDescriptorBuilder<FakeCompilation>.defaults(
|
||||||
kotlin: KotlinMultiplatformExtension,
|
kotlin: KotlinMultiplatformExtension,
|
||||||
name: String = "fake"
|
name: String = KotlinCompilation.MAIN_COMPILATION_NAME,
|
||||||
) {
|
) {
|
||||||
compilationName = name
|
compilationName = name
|
||||||
compilationFactory = CompilationFactory(::FakeCompilation)
|
compilationFactory = CompilationFactory(::FakeCompilation)
|
||||||
|
|||||||
Reference in New Issue
Block a user