[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:
Sebastian Sellmair
2023-08-03 12:10:23 +02:00
committed by Space Team
parent 93f8e21e9e
commit 3d593f0ee9
13 changed files with 217 additions and 109 deletions
@@ -8,24 +8,17 @@ import org.gradle.api.Action
import org.gradle.api.DomainObjectSet
import org.gradle.api.Project
import org.gradle.api.artifacts.ConfigurablePublishArtifact
import org.gradle.api.attributes.*
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.attributes.AttributeContainer
import org.gradle.api.publish.maven.MavenPublication
import org.jetbrains.kotlin.gradle.DeprecatedTargetPresetApi
import org.jetbrains.kotlin.gradle.InternalKotlinGradlePluginApi
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.kotlinExtension
import org.jetbrains.kotlin.gradle.plugin.*
import org.jetbrains.kotlin.gradle.plugin.mpp.KotlinUsageContext.MavenScope.*
import org.jetbrains.kotlin.gradle.utils.dashSeparatedName
import org.jetbrains.kotlin.gradle.utils.lowerCamelCaseName
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.utils.*
import org.jetbrains.kotlin.tooling.core.MutableExtras
import org.jetbrains.kotlin.tooling.core.mutableExtrasOf
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"
abstract class AbstractKotlinTarget(
final override val project: Project
final override val project: Project,
) : InternalKotlinTarget {
final override val extras: MutableExtras = mutableExtrasOf()
@@ -96,8 +89,13 @@ abstract class AbstractKotlinTarget(
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(
@@ -190,69 +188,6 @@ abstract class AbstractKotlinTarget(
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) =
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()
}
@@ -6,6 +6,8 @@
package org.jetbrains.kotlin.gradle.plugin.mpp
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.KotlinTargetComponent
import org.jetbrains.kotlin.tooling.core.HasMutableExtras
@@ -13,6 +15,9 @@ import org.jetbrains.kotlin.tooling.core.HasMutableExtras
internal interface InternalKotlinTarget : KotlinTarget, HasMutableExtras {
var isSourcesPublishable: Boolean
val kotlinComponents: Set<KotlinTargetComponent>
@InternalKotlinGradlePluginApi
override val components: Set<KotlinTargetSoftwareComponent>
fun onPublicationCreated(publication: MavenPublication)
}
@@ -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
@@ -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
@@ -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
}
@@ -10,16 +10,17 @@ import org.gradle.api.artifacts.PublishArtifact
import org.gradle.api.component.ComponentWithCoordinates
import org.gradle.api.publish.maven.MavenPublication
import org.jetbrains.kotlin.gradle.dsl.KotlinMultiplatformExtension
import org.jetbrains.kotlin.gradle.plugin.KotlinTarget
import org.jetbrains.kotlin.gradle.plugin.mpp.KotlinTargetComponentWithPublication
import org.jetbrains.kotlin.gradle.plugin.KotlinCompilation
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.getCoordinatesFromPublicationDelegateAndProject
import org.jetbrains.kotlin.gradle.utils.dashSeparatedName
import org.jetbrains.kotlin.util.capitalizeDecapitalize.toLowerCaseAsciiOnly
internal class ExternalKotlinTargetComponent(
val targetProvider: TargetProvider
) : KotlinTargetComponentWithPublication, ComponentWithCoordinates {
val targetProvider: TargetProvider,
) : InternalKotlinTargetComponent(), KotlinTargetComponentWithPublication, ComponentWithCoordinates {
/*
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 */
override var publicationDelegate: MavenPublication? = null
override val target: KotlinTarget by lazy { targetProvider() }
override val target: DecoratedExternalKotlinTarget by lazy { targetProvider() }
override val publishable: Boolean
get() = target.publishable
@@ -60,4 +61,23 @@ internal class ExternalKotlinTargetComponent(
override fun getCoordinates(): ModuleVersionIdentifier =
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()
}
@@ -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.
*/
package org.jetbrains.kotlin.gradle.plugin.mpp.external
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.SoftwareComponentFactory
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.jetbrains.kotlin.gradle.dsl.KotlinMultiplatformExtension
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
internal fun ExternalKotlinTargetSoftwareComponent(
target: ExternalKotlinTargetImpl,
): ExternalKotlinTargetSoftwareComponent {
@@ -39,7 +40,7 @@ internal fun ExternalKotlinTargetSoftwareComponent(
return ExternalKotlinTargetSoftwareComponent(
target.project.multiplatformExtension,
adhocSoftwareComponent as SoftwareComponentInternal,
target.kotlinTargetComponent
target.kotlinTargetComponent,
)
}
@@ -47,7 +48,8 @@ internal class ExternalKotlinTargetSoftwareComponent @UnsafeApi constructor(
private val multiplatformExtension: KotlinMultiplatformExtension,
private val adhocSoftwareComponent: SoftwareComponentInternal,
private val kotlinTargetComponent: ExternalKotlinTargetComponent,
) : ComponentWithCoordinates, ComponentWithVariants, SoftwareComponentInternal {
) : KotlinTargetSoftwareComponent() {
override fun getName(): String = adhocSoftwareComponent.name
override fun getUsages(): Set<UsageContext> = adhocSoftwareComponent.usages
override fun getVariants(): Set<SoftwareComponent> = multiplatformExtension.metadata().components
@@ -59,7 +59,7 @@ private interface KotlinTargetComponentWithCoordinatesAndPublication :
open class KotlinVariant(
val producingCompilation: KotlinCompilation<*>,
private val usages: Set<DefaultKotlinUsageContext>
) : KotlinTargetComponentWithPublication, SoftwareComponentInternal {
) : InternalKotlinTargetComponent(), KotlinTargetComponentWithPublication {
var componentName: String? = null
var artifactTargetName: String = target.targetName
@@ -112,7 +112,7 @@ class JointAndroidKotlinTargetComponent(
override val target: KotlinAndroidTarget,
private val nestedVariants: Set<KotlinVariant>,
val flavorNames: List<String>
) : KotlinTargetComponentWithCoordinatesAndPublication, SoftwareComponentInternal {
) : InternalKotlinTargetComponent(), KotlinTargetComponentWithCoordinatesAndPublication {
override fun getUsages(): Set<KotlinUsageContext> = nestedVariants.filter { it.publishable }.flatMap { it.usages }.toSet()
@@ -12,7 +12,6 @@ import org.gradle.api.attributes.Category
import org.gradle.api.attributes.Category.CATEGORY_ATTRIBUTE
import org.gradle.api.attributes.Usage.USAGE_ATTRIBUTE
import org.gradle.api.file.FileCollection
import org.gradle.api.internal.component.SoftwareComponentInternal
import org.gradle.api.plugins.BasePlugin
import org.gradle.api.tasks.TaskProvider
import org.gradle.api.tasks.bundling.Jar
@@ -189,7 +188,7 @@ class KotlinMetadataTargetConfigurator :
private fun createMetadataCompilationsForCommonSourceSets(
target: KotlinMetadataTarget,
allMetadataJar: TaskProvider<out Jar>
allMetadataJar: TaskProvider<out Jar>,
) = target.project.launchInStage(KotlinPluginLifecycle.Stage.AfterFinaliseDsl) {
withRestrictedStages(KotlinPluginLifecycle.Stage.upTo(KotlinPluginLifecycle.Stage.FinaliseCompilations)) {
// Do this after all targets are configured by the user build script
@@ -255,7 +254,7 @@ class KotlinMetadataTargetConfigurator :
}
private fun exportDependenciesForPublishing(
compilation: KotlinCompilation<*>
compilation: KotlinCompilation<*>,
) {
val sourceSet = compilation.defaultSourceSet
val isSharedNativeCompilation = compilation is KotlinSharedNativeCompilation
@@ -295,7 +294,7 @@ class KotlinMetadataTargetConfigurator :
target: KotlinMetadataTarget,
sourceSet: KotlinSourceSet,
allMetadataJar: TaskProvider<out Jar>,
isHostSpecific: Boolean
isHostSpecific: Boolean,
): KotlinCompilation<*> {
val project = target.project
@@ -392,7 +391,7 @@ class KotlinMetadataTargetConfigurator :
}
internal class NativeSharedCompilationProcessor(
private val compilation: KotlinSharedNativeCompilation
private val compilation: KotlinSharedNativeCompilation,
) : KotlinCompilationProcessor<KotlinNativeCompile>(KotlinCompilationInfo(compilation)) {
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<*>> {
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)
return@forEach
target.kotlinComponents
.filterIsInstance<SoftwareComponentInternal>()
.forEach { component ->
component.usages
.filterIsInstance<KotlinUsageContext>()
.filter { it.includeIntoProjectStructureMetadata }
.forEach { usage -> result[usage] = usage.compilation }
}
.flatMap { component -> component.internal.usages }
.filter { it.includeIntoProjectStructureMetadata }
.forEach { usage -> result[usage] = usage.compilation }
}
return result
@@ -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)
}
}
@@ -124,7 +124,7 @@ class MppPublicationTest {
for ((targetName, sourceElements) in sourcesElements) {
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") }
}
}
@@ -143,6 +143,7 @@ class MppPublicationTest {
@Test
fun `sourcesJar task should be available during configuration time`() {
kotlin.linuxX64("linux")
project.evaluate()
val sourcesJars = listOf(
"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`() {
kotlin.linuxX64("linux")
kotlin.withSourcesJar(publish = false)
project.evaluate()
val sourcesJars = listOf(
"sourcesJar", // sources of common source sets i.e. root module
@@ -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())
}
@@ -199,7 +199,7 @@ class ProjectCompilerOptionsTests {
val project = buildProjectWithMPP()
project.runLifecycleAwareTest {
tasks.withType<KotlinJvmCompileTask>().configureEach {
if (it.name == "compileFakeKotlinFake") {
if (it.name == "compileKotlinFake") {
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())
}
@@ -8,6 +8,7 @@ package org.jetbrains.kotlin.gradle.util
import org.gradle.api.NamedDomainObjectContainer
import org.jetbrains.kotlin.gradle.dsl.*
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.mpp.external.*
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>
get() = super.compilerOptions as HasCompilerOptions<KotlinJvmCompilerOptions>
}
class FakeTarget(delegate: Delegate) : DecoratedExternalKotlinTarget(delegate) {
@Suppress("UNCHECKED_CAST")
@@ -40,7 +42,7 @@ fun ExternalKotlinTargetDescriptorBuilder<FakeTarget>.defaults() {
fun ExternalKotlinCompilationDescriptorBuilder<FakeCompilation>.defaults(
kotlin: KotlinMultiplatformExtension,
name: String = "fake"
name: String = KotlinCompilation.MAIN_COMPILATION_NAME,
) {
compilationName = name
compilationFactory = CompilationFactory(::FakeCompilation)