[Gradle] Implement 'publishJvmEnvironmentAttribute' flag
When the flag is 'on', then publications will include The 'org.gradle.jvm.environment' Gradle attribute. We previously did not publish this attribute, as it lead to problems for 'old' consumers. We will roll out publications gradually with this feature flag. The external Android target is expected to opt into this flag as it is necessary for disambiguating Android from JVM targets when the external Android target also uses KotlinPlatformType.jvm
This commit is contained in:
committed by
Space Team
parent
89c3781c8e
commit
96b33007e5
@@ -789,6 +789,15 @@ public final class org/jetbrains/kotlin/gradle/plugin/mpp/external/ExternalKotli
|
||||
public static final fun ExternalKotlinCompilationDescriptor (Lkotlin/jvm/functions/Function1;)Lorg/jetbrains/kotlin/gradle/plugin/mpp/external/ExternalKotlinCompilationDescriptor;
|
||||
}
|
||||
|
||||
public abstract interface class org/jetbrains/kotlin/gradle/plugin/mpp/external/ExternalKotlinTargetApiUtils {
|
||||
public abstract fun enableKgpBasedDependencyResolution (Z)V
|
||||
public abstract fun publishJvmEnvironmentAttribute (Z)V
|
||||
}
|
||||
|
||||
public final class org/jetbrains/kotlin/gradle/plugin/mpp/external/ExternalKotlinTargetApiUtilsKt {
|
||||
public static final fun getExternalKotlinTargetApiUtils (Lorg/gradle/api/Project;)Lorg/jetbrains/kotlin/gradle/plugin/mpp/external/ExternalKotlinTargetApiUtils;
|
||||
}
|
||||
|
||||
public abstract interface class org/jetbrains/kotlin/gradle/plugin/mpp/external/ExternalKotlinTargetConfigurationDescriptor {
|
||||
public abstract fun getConfigure ()Lkotlin/jvm/functions/Function2;
|
||||
}
|
||||
|
||||
+5
@@ -40,6 +40,7 @@ import org.jetbrains.kotlin.gradle.plugin.PropertiesProvider.PropertyNames.KOTLI
|
||||
import org.jetbrains.kotlin.gradle.plugin.PropertiesProvider.PropertyNames.KOTLIN_MPP_HIERARCHICAL_STRUCTURE_SUPPORT
|
||||
import org.jetbrains.kotlin.gradle.plugin.PropertiesProvider.PropertyNames.KOTLIN_MPP_IMPORT_ENABLE_KGP_DEPENDENCY_RESOLUTION
|
||||
import org.jetbrains.kotlin.gradle.plugin.PropertiesProvider.PropertyNames.KOTLIN_MPP_IMPORT_ENABLE_SLOW_SOURCES_JAR_RESOLVER
|
||||
import org.jetbrains.kotlin.gradle.plugin.PropertiesProvider.PropertyNames.KOTLIN_PUBLISH_JVM_ENVIRONMENT_ATTRIBUTE
|
||||
import org.jetbrains.kotlin.gradle.plugin.PropertiesProvider.PropertyNames.KOTLIN_NATIVE_DEPENDENCY_PROPAGATION
|
||||
import org.jetbrains.kotlin.gradle.plugin.PropertiesProvider.PropertyNames.KOTLIN_NATIVE_IGNORE_DISABLED_TARGETS
|
||||
import org.jetbrains.kotlin.gradle.plugin.PropertiesProvider.PropertyNames.KOTLIN_NATIVE_SUPPRESS_EXPERIMENTAL_ARTIFACTS_DSL_WARNING
|
||||
@@ -271,6 +272,9 @@ internal class PropertiesProvider private constructor(private val project: Proje
|
||||
val ignoreHmppDeprecationWarnings: Boolean?
|
||||
get() = booleanProperty(KOTLIN_MPP_DEPRECATED_PROPERTIES_NO_WARN)
|
||||
|
||||
val publishJvmEnvironmentAttribute: Boolean
|
||||
get() = booleanProperty(KOTLIN_PUBLISH_JVM_ENVIRONMENT_ATTRIBUTE) ?: false
|
||||
|
||||
/**
|
||||
* Enables individual test task reporting for aggregated test tasks.
|
||||
*
|
||||
@@ -633,6 +637,7 @@ internal class PropertiesProvider private constructor(private val project: Proje
|
||||
const val KOTLIN_CREATE_DEFAULT_MULTIPLATFORM_PUBLICATIONS = "kotlin.internal.mpp.createDefaultMultiplatformPublications"
|
||||
const val KOTLIN_RUN_COMPILER_VIA_BUILD_TOOLS_API = "kotlin.compiler.runViaBuildToolsApi"
|
||||
const val KOTLIN_MPP_ALLOW_LEGACY_DEPENDENCIES = "kotlin.mpp.allow.legacy.dependencies"
|
||||
const val KOTLIN_PUBLISH_JVM_ENVIRONMENT_ATTRIBUTE = "kotlin.publishJvmEnvironmentAttribute"
|
||||
const val KOTLIN_EXPERIMENTAL_TRY_K2 = "kotlin.experimental.tryK2"
|
||||
const val KOTLIN_INTERNAL_VERBOSE_DIAGNOSTICS = "kotlin.internal.verboseDiagnostics"
|
||||
const val KOTLIN_SUPPRESS_GRADLE_PLUGIN_WARNINGS = "kotlin.suppressGradlePluginWarnings"
|
||||
|
||||
+13
-2
@@ -22,6 +22,7 @@ import org.jetbrains.kotlin.gradle.dsl.multiplatformExtension
|
||||
import org.jetbrains.kotlin.gradle.plugin.*
|
||||
import org.jetbrains.kotlin.gradle.plugin.KotlinCompilation.Companion.MAIN_COMPILATION_NAME
|
||||
import org.jetbrains.kotlin.gradle.plugin.KotlinPluginLifecycle.Stage.AfterFinaliseCompilations
|
||||
import org.jetbrains.kotlin.gradle.plugin.PropertiesProvider.Companion.kotlinPropertiesProvider
|
||||
import org.jetbrains.kotlin.gradle.utils.markResolvable
|
||||
import org.jetbrains.kotlin.gradle.targets.metadata.*
|
||||
import org.jetbrains.kotlin.gradle.targets.metadata.COMMON_MAIN_ELEMENTS_CONFIGURATION_NAME
|
||||
@@ -35,7 +36,7 @@ import org.jetbrains.kotlin.util.capitalizeDecapitalize.toLowerCaseAsciiOnly
|
||||
abstract class KotlinSoftwareComponent(
|
||||
private val project: Project,
|
||||
private val name: String,
|
||||
protected val kotlinTargets: Iterable<KotlinTarget>
|
||||
protected val kotlinTargets: Iterable<KotlinTarget>,
|
||||
) : SoftwareComponentInternal, ComponentWithVariants {
|
||||
|
||||
override fun getName(): String = name
|
||||
@@ -220,6 +221,8 @@ class DefaultKotlinUsageContext(
|
||||
|
||||
override fun getGlobalExcludes(): Set<ExcludeRule> = emptySet()
|
||||
|
||||
private val publishJvmEnvironmentAttribute get() = project.kotlinPropertiesProvider.publishJvmEnvironmentAttribute
|
||||
|
||||
private fun filterOutNonPublishableAttributes(attributes: Set<Attribute<*>>): Set<Attribute<*>> =
|
||||
attributes.filterTo(mutableSetOf()) {
|
||||
it != ProjectLocalConfigurations.ATTRIBUTE &&
|
||||
@@ -234,9 +237,17 @@ class DefaultKotlinUsageContext(
|
||||
* 2. If this attribute is published, but not present on all the variants in a multiplatform library, and is also
|
||||
* missing on the consumer side (like Gradle < 7.0, Kotlin 1.6.0), then there is a
|
||||
* case when Gradle fails to choose a variant in a completely reasonable setup.
|
||||
*
|
||||
* UPD: 1.9.20:
|
||||
* We should now be ready to publish the 'jvm environment' attribute.
|
||||
* It will however be rolled out as 'opt-in' first (as safety measure).
|
||||
* We expect that the 'external Android target' will opt-into publishing this attribute,
|
||||
* as it will switch to KotlinPlatformType.jvm and requires this additional attribute to disambiguate
|
||||
* Android from the JVM
|
||||
*/
|
||||
it.name != "org.gradle.jvm.environment"
|
||||
(it.name != "org.gradle.jvm.environment" || publishJvmEnvironmentAttribute)
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
internal fun Iterable<DefaultKotlinUsageContext>.publishableUsages() = this
|
||||
|
||||
+31
@@ -0,0 +1,31 @@
|
||||
/*
|
||||
* 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.Project
|
||||
import org.jetbrains.kotlin.gradle.ExternalKotlinTargetApi
|
||||
import org.jetbrains.kotlin.gradle.plugin.PropertiesProvider.PropertyNames.KOTLIN_MPP_IMPORT_ENABLE_KGP_DEPENDENCY_RESOLUTION
|
||||
import org.jetbrains.kotlin.gradle.plugin.PropertiesProvider.PropertyNames.KOTLIN_PUBLISH_JVM_ENVIRONMENT_ATTRIBUTE
|
||||
import org.jetbrains.kotlin.gradle.plugin.extraProperties
|
||||
|
||||
@ExternalKotlinTargetApi
|
||||
interface ExternalKotlinTargetApiUtils {
|
||||
fun enableKgpBasedDependencyResolution(enable: Boolean = true)
|
||||
fun publishJvmEnvironmentAttribute(publish: Boolean = true)
|
||||
}
|
||||
|
||||
@ExternalKotlinTargetApi
|
||||
val Project.externalKotlinTargetApiUtils: ExternalKotlinTargetApiUtils
|
||||
get() = object : ExternalKotlinTargetApiUtils {
|
||||
|
||||
override fun enableKgpBasedDependencyResolution(enable: Boolean) {
|
||||
project.extraProperties.set(KOTLIN_MPP_IMPORT_ENABLE_KGP_DEPENDENCY_RESOLUTION, enable.toString())
|
||||
}
|
||||
|
||||
override fun publishJvmEnvironmentAttribute(publish: Boolean) {
|
||||
project.extraProperties.set(KOTLIN_PUBLISH_JVM_ENVIRONMENT_ATTRIBUTE, publish.toString())
|
||||
}
|
||||
}
|
||||
+44
@@ -0,0 +1,44 @@
|
||||
/*
|
||||
* 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.PropertiesProvider.Companion.kotlinPropertiesProvider
|
||||
import org.jetbrains.kotlin.gradle.plugin.mpp.external.externalKotlinTargetApiUtils
|
||||
import org.jetbrains.kotlin.gradle.util.buildProjectWithMPP
|
||||
import kotlin.test.*
|
||||
|
||||
class ExternalKotlinTargetApiUtilsTest {
|
||||
@Test
|
||||
fun `test - enableKgpBasedDependencyResolution`() {
|
||||
val project = buildProjectWithMPP()
|
||||
assertNull(project.kotlinPropertiesProvider.enableKgpDependencyResolution)
|
||||
|
||||
project.externalKotlinTargetApiUtils.enableKgpBasedDependencyResolution(true)
|
||||
assertEquals(true, project.kotlinPropertiesProvider.enableKgpDependencyResolution)
|
||||
|
||||
project.externalKotlinTargetApiUtils.enableKgpBasedDependencyResolution(false)
|
||||
assertEquals(false, project.kotlinPropertiesProvider.enableKgpDependencyResolution)
|
||||
|
||||
project.externalKotlinTargetApiUtils.enableKgpBasedDependencyResolution()
|
||||
assertEquals(true, project.kotlinPropertiesProvider.enableKgpDependencyResolution)
|
||||
}
|
||||
|
||||
@Test
|
||||
fun `test - publishJvmEnvironmentAttribute`() {
|
||||
val project = buildProjectWithMPP()
|
||||
|
||||
project.externalKotlinTargetApiUtils.publishJvmEnvironmentAttribute(true)
|
||||
assertTrue(project.kotlinPropertiesProvider.publishJvmEnvironmentAttribute)
|
||||
|
||||
project.externalKotlinTargetApiUtils.publishJvmEnvironmentAttribute(false)
|
||||
assertFalse(project.kotlinPropertiesProvider.publishJvmEnvironmentAttribute)
|
||||
|
||||
project.externalKotlinTargetApiUtils.publishJvmEnvironmentAttribute()
|
||||
assertTrue(project.kotlinPropertiesProvider.publishJvmEnvironmentAttribute)
|
||||
}
|
||||
}
|
||||
+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.
|
||||
*/
|
||||
|
||||
@file:Suppress("FunctionName")
|
||||
|
||||
package org.jetbrains.kotlin.gradle.unitTests
|
||||
|
||||
import org.gradle.api.attributes.java.TargetJvmEnvironment
|
||||
import org.gradle.api.attributes.java.TargetJvmEnvironment.STANDARD_JVM
|
||||
import org.jetbrains.kotlin.gradle.dsl.multiplatformExtension
|
||||
import org.jetbrains.kotlin.gradle.plugin.KotlinTarget
|
||||
import org.jetbrains.kotlin.gradle.plugin.PropertiesProvider.Companion.kotlinPropertiesProvider
|
||||
import org.jetbrains.kotlin.gradle.plugin.PropertiesProvider.PropertyNames.KOTLIN_PUBLISH_JVM_ENVIRONMENT_ATTRIBUTE
|
||||
import org.jetbrains.kotlin.gradle.plugin.configurationResult
|
||||
import org.jetbrains.kotlin.gradle.plugin.mpp.KotlinUsageContext
|
||||
import org.jetbrains.kotlin.gradle.plugin.mpp.KotlinVariantWithMetadataVariant
|
||||
import org.jetbrains.kotlin.gradle.plugin.mpp.containsMultiplatformAttributes
|
||||
import org.jetbrains.kotlin.gradle.plugin.mpp.internal
|
||||
import org.jetbrains.kotlin.gradle.util.buildProjectWithMPP
|
||||
import org.jetbrains.kotlin.gradle.util.propertiesExtension
|
||||
import org.jetbrains.kotlin.gradle.util.runLifecycleAwareTest
|
||||
import org.jetbrains.kotlin.gradle.utils.named
|
||||
import kotlin.test.*
|
||||
|
||||
class PublishJvmEnvironmentAttributeTest {
|
||||
@Test
|
||||
fun `test - default value`() = buildProjectWithMPP().runLifecycleAwareTest {
|
||||
val kotlin = multiplatformExtension
|
||||
kotlin.jvm()
|
||||
configurationResult.await()
|
||||
assertFalse(kotlinPropertiesProvider.publishJvmEnvironmentAttribute)
|
||||
assertNoJvmEnvironmentAttribute(kotlin.jvm())
|
||||
}
|
||||
|
||||
@Test
|
||||
fun `test - publishJvmEnvironmentAttribute disabled`() = buildProjectWithMPP().runLifecycleAwareTest {
|
||||
val kotlin = multiplatformExtension
|
||||
kotlin.jvm()
|
||||
|
||||
project.propertiesExtension.set(KOTLIN_PUBLISH_JVM_ENVIRONMENT_ATTRIBUTE, "false")
|
||||
|
||||
configurationResult.await()
|
||||
assertFalse(kotlinPropertiesProvider.publishJvmEnvironmentAttribute)
|
||||
assertNoJvmEnvironmentAttribute(kotlin.jvm())
|
||||
}
|
||||
|
||||
@Test
|
||||
fun `test - publishJvmEnvironmentAttribute enabled`() = buildProjectWithMPP().runLifecycleAwareTest {
|
||||
val kotlin = multiplatformExtension
|
||||
kotlin.jvm()
|
||||
|
||||
project.propertiesExtension.set(KOTLIN_PUBLISH_JVM_ENVIRONMENT_ATTRIBUTE, "true")
|
||||
|
||||
configurationResult.await()
|
||||
assertTrue(kotlinPropertiesProvider.publishJvmEnvironmentAttribute)
|
||||
assertJvmEnvironmentAttributeEquals(kotlin.jvm(), project.objects.named<TargetJvmEnvironment>(STANDARD_JVM))
|
||||
}
|
||||
|
||||
private fun assertNoJvmEnvironmentAttribute(target: KotlinTarget) {
|
||||
target.forEachUsage { usage ->
|
||||
usage.attributes.containsMultiplatformAttributes
|
||||
assertNull(
|
||||
usage.attributes.getAttribute(TargetJvmEnvironment.TARGET_JVM_ENVIRONMENT_ATTRIBUTE),
|
||||
"Expected no jvm environment attribute to be set on usage '$usage"
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
private fun assertJvmEnvironmentAttributeEquals(target: KotlinTarget, value: TargetJvmEnvironment) {
|
||||
target.forEachUsage { usage ->
|
||||
usage.attributes.containsMultiplatformAttributes
|
||||
assertEquals(
|
||||
value, usage.attributes.getAttribute(TargetJvmEnvironment.TARGET_JVM_ENVIRONMENT_ATTRIBUTE),
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
private fun KotlinTarget.forEachUsage(action: (usage: KotlinUsageContext) -> Unit) {
|
||||
val component = internal.kotlinComponents.singleOrNull() ?: fail("Expected a single component. Found: ${components}")
|
||||
component as KotlinVariantWithMetadataVariant
|
||||
component.usages.ifEmpty { fail("Expected at least one 'usage'") }
|
||||
component.usages.forEach(action)
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user