[Gradle] Fix eager task realization due to attributes querying

Gradle 8.3+ starts triggering JVM eager tasks creating via eagerly
configured attributes that we copy over from the Gradle JVM plugin for
Kotlin compilation. The fix is to migrate to '.attributeProvider()' API
to configure the attribute.

^KT-60664 In Progress
This commit is contained in:
Yahor Berdnikau
2023-12-21 22:18:33 +01:00
committed by Space Team
parent 2da6946ac2
commit dbd77fc785
58 changed files with 563 additions and 222 deletions
@@ -5,7 +5,6 @@
package org.jetbrains.kotlin.gradle package org.jetbrains.kotlin.gradle
import org.gradle.api.logging.configuration.WarningMode
import org.gradle.util.GradleVersion import org.gradle.util.GradleVersion
import org.jetbrains.kotlin.gradle.testbase.* import org.jetbrains.kotlin.gradle.testbase.*
import org.junit.jupiter.api.DisplayName import org.junit.jupiter.api.DisplayName
@@ -27,7 +26,8 @@ class ConfigurationAvoidanceIT : KGPBaseTest() {
@JvmGradlePluginTests @JvmGradlePluginTests
@GradleTestVersions( @GradleTestVersions(
additionalVersions = [TestVersions.Gradle.G_7_3] additionalVersions = [TestVersions.Gradle.G_7_3],
maxVersion = TestVersions.Gradle.G_8_3
) )
@DisplayName("KGP/Jvm does not eagerly configure any tasks") @DisplayName("KGP/Jvm does not eagerly configure any tasks")
@GradleTest @GradleTest
@@ -648,7 +648,7 @@ class KotlinGradleIT : KGPBaseTest() {
subProject("projB").buildGradle.appendText("\nkotlin.target.attributes.attribute(targetAttribute, \"bar\")") subProject("projB").buildGradle.appendText("\nkotlin.target.attributes.attribute(targetAttribute, \"bar\")")
buildAndFail(":projB:compileKotlin") { buildAndFail(":projB:compileKotlin") {
when { when {
gradleVersion < GradleVersion.version("6.8.4") -> { gradleVersion <= GradleVersion.version(TestVersions.Gradle.G_6_8) -> {
assertOutputContains( assertOutputContains(
"No matching variant of project :projA was found. The consumer was configured to find an API of a library " + "No matching variant of project :projA was found. The consumer was configured to find an API of a library " +
"compatible with Java 8, preferably in the form of class files, " + "compatible with Java 8, preferably in the form of class files, " +
@@ -659,14 +659,19 @@ class KotlinGradleIT : KGPBaseTest() {
) )
} }
else -> { else -> {
assertOutputContains( // Attributes may come in random order
"No matching variant of project :projA was found. The consumer was configured to find a library for use during compile-time, " + val attributeMatchingString = output.lineSequence().find {
"compatible with Java 8, preferably in the form of class files, " + it.trimStart().startsWith(
"preferably optimized for standard JVMs, and its dependencies declared externally, " + "> No matching variant of project :projA was found. " +
"as well as attribute 'org.jetbrains.kotlin.platform.type' with value 'jvm', " + "The consumer was configured to find a library for use during compile-time, " +
"attribute 'com.example.compilation' with value 'foo', " + "compatible with Java 8, preferably in the form of class files, " +
"attribute 'com.example.target' with value 'bar' but:" "preferably optimized for standard JVMs, and its dependencies declared externally, "
) )
}
assertNotNull(attributeMatchingString, "Expected variant mismatch string is not found")
assertTrue(attributeMatchingString.contains("attribute 'com.example.compilation' with value 'foo'"))
assertTrue(attributeMatchingString.contains("attribute 'com.example.target' with value 'bar'"))
assertTrue(attributeMatchingString.contains("attribute 'org.jetbrains.kotlin.platform.type' with value 'jvm'"))
} }
} }
} }
@@ -681,7 +686,7 @@ class KotlinGradleIT : KGPBaseTest() {
) )
buildAndFail(":projB:compileKotlin") { buildAndFail(":projB:compileKotlin") {
when { when {
gradleVersion < GradleVersion.version("6.8.4") -> { gradleVersion <= GradleVersion.version(TestVersions.Gradle.G_6_8) -> {
assertOutputContains( assertOutputContains(
"No matching variant of project :projA was found. The consumer was configured to find an API of a library " + "No matching variant of project :projA was found. The consumer was configured to find an API of a library " +
"compatible with Java 8, preferably in the form of class files, and its dependencies declared externally, " + "compatible with Java 8, preferably in the form of class files, and its dependencies declared externally, " +
@@ -691,14 +696,19 @@ class KotlinGradleIT : KGPBaseTest() {
) )
} }
else -> { else -> {
assertOutputContains( // Attributes may come in random order
"No matching variant of project :projA was found. The consumer was configured to find a library for use during compile-time, " + val attributeMatchingString = output.lineSequence().find {
"compatible with Java 8, preferably in the form of class files, preferably optimized for standard JVMs, " + it.contains(
"and its dependencies declared externally, " + "No matching variant of project :projA was found. " +
"as well as attribute 'org.jetbrains.kotlin.platform.type' with value 'jvm', " + "The consumer was configured to find a library for use during compile-time, " +
"attribute 'com.example.compilation' with value 'bar', " + "compatible with Java 8, preferably in the form of class files, " +
"attribute 'com.example.target' with value 'foo' but:" "preferably optimized for standard JVMs, and its dependencies declared externally, "
) )
}
assertNotNull(attributeMatchingString, "Expected variant mismatch string is not found")
assertTrue(attributeMatchingString.contains("attribute 'com.example.compilation' with value 'bar'"))
assertTrue(attributeMatchingString.contains("attribute 'com.example.target' with value 'foo'"))
assertTrue(attributeMatchingString.contains("attribute 'org.jetbrains.kotlin.platform.type' with value 'jvm'"))
} }
} }
} }
@@ -52,8 +52,14 @@ fun KotlinMultiplatformExtension.androidTargetPrototype(): PrototypeAndroidTarge
In this example we hardcoded AGP version 7.4.0-beta02 as demo In this example we hardcoded AGP version 7.4.0-beta02 as demo
*/ */
apiElements.configure { _, configuration -> apiElements.configure { _, configuration ->
configuration.attributes.attribute(TARGET_JVM_ENVIRONMENT_ATTRIBUTE, project.objects.named(TargetJvmEnvironment.ANDROID)) configuration.attributes.attributeProvider(
configuration.attributes.attribute(AgpVersionAttr.ATTRIBUTE, project.objects.named("7.4.0-beta02")) /* For demo */ TARGET_JVM_ENVIRONMENT_ATTRIBUTE,
project.provider { project.objects.named(TargetJvmEnvironment.ANDROID) }
)
configuration.attributes.attributeProvider(
AgpVersionAttr.ATTRIBUTE,
project.provider { project.objects.named("7.4.0-beta02") } /* For demo */
)
} }
/* /*
@@ -61,8 +67,14 @@ fun KotlinMultiplatformExtension.androidTargetPrototype(): PrototypeAndroidTarge
In this example we hardcoded AGP version 7.4.0-beta02 as demo In this example we hardcoded AGP version 7.4.0-beta02 as demo
*/ */
runtimeElements.configure { _, configuration -> runtimeElements.configure { _, configuration ->
configuration.attributes.attribute(TARGET_JVM_ENVIRONMENT_ATTRIBUTE, project.objects.named(TargetJvmEnvironment.ANDROID)) configuration.attributes.attributeProvider(
configuration.attributes.attribute(AgpVersionAttr.ATTRIBUTE, project.objects.named("7.4.0-beta02")) /* For demo */ TARGET_JVM_ENVIRONMENT_ATTRIBUTE,
project.provider { project.objects.named(TargetJvmEnvironment.ANDROID) }
)
configuration.attributes.attributeProvider(
AgpVersionAttr.ATTRIBUTE,
project.provider { project.objects.named("7.4.0-beta02") } /* For demo */
)
} }
/* /*
@@ -70,8 +82,16 @@ fun KotlinMultiplatformExtension.androidTargetPrototype(): PrototypeAndroidTarge
In this example we hardcoded AGP version 7.4.0-beta02 as demo In this example we hardcoded AGP version 7.4.0-beta02 as demo
*/ */
sourcesElements.configure { _, configuration -> sourcesElements.configure { _, configuration ->
configuration.attributes.attribute(TARGET_JVM_ENVIRONMENT_ATTRIBUTE, project.objects.named(TargetJvmEnvironment.ANDROID)) configuration.attributes.attributeProvider(
configuration.attributes.attribute(AgpVersionAttr.ATTRIBUTE, project.objects.named("7.4.0-beta02")) /* For demo */ TARGET_JVM_ENVIRONMENT_ATTRIBUTE,
project.provider { project.objects.named(TargetJvmEnvironment.ANDROID) }
)
configuration.attributes.attributeProvider(
AgpVersionAttr.ATTRIBUTE,
project.provider {
project.objects.named("7.4.0-beta02") /* For demo */
}
)
} }
/* /*
@@ -80,14 +100,30 @@ fun KotlinMultiplatformExtension.androidTargetPrototype(): PrototypeAndroidTarge
*/ */
apiElementsPublished.configure { _, configuration -> apiElementsPublished.configure { _, configuration ->
/* TODO w/ Google: Find a way to deprecate this attribute */ /* TODO w/ Google: Find a way to deprecate this attribute */
configuration.attributes.attribute(KotlinPlatformType.attribute, KotlinPlatformType.androidJvm) configuration.attributes.attributeProvider(
configuration.attributes.attribute(TARGET_JVM_ENVIRONMENT_ATTRIBUTE, project.objects.named(TargetJvmEnvironment.ANDROID)) KotlinPlatformType.attribute,
project.provider { KotlinPlatformType.androidJvm }
)
configuration.attributes.attributeProvider(
TARGET_JVM_ENVIRONMENT_ATTRIBUTE,
project.provider {
project.objects.named(TargetJvmEnvironment.ANDROID)
}
)
} }
runtimeElementsPublished.configure { _, configuration -> runtimeElementsPublished.configure { _, configuration ->
/* TODO w/ Google: Find a way to deprecate this attribute */ /* TODO w/ Google: Find a way to deprecate this attribute */
configuration.attributes.attribute(KotlinPlatformType.attribute, KotlinPlatformType.androidJvm) configuration.attributes.attributeProvider(
configuration.attributes.attribute(TARGET_JVM_ENVIRONMENT_ATTRIBUTE, project.objects.named(TargetJvmEnvironment.ANDROID)) KotlinPlatformType.attribute,
project.provider { KotlinPlatformType.androidJvm }
)
configuration.attributes.attributeProvider(
TARGET_JVM_ENVIRONMENT_ATTRIBUTE,
project.provider {
project.objects.named(TargetJvmEnvironment.ANDROID)
}
)
} }
configureIdeImport { configureIdeImport {
@@ -165,7 +201,10 @@ fun KotlinMultiplatformExtension.androidTargetPrototype(): PrototypeAndroidTarge
artifactType: CLASSES_JAR artifactType: CLASSES_JAR
*/ */
androidTarget.apiElementsConfiguration.outgoing.variants.create("classes").let { variant -> androidTarget.apiElementsConfiguration.outgoing.variants.create("classes").let { variant ->
variant.attributes.attribute(AndroidArtifacts.ARTIFACT_TYPE, AndroidArtifacts.ArtifactType.CLASSES_JAR.type) variant.attributes.attributeProvider(
AndroidArtifacts.ARTIFACT_TYPE,
project.provider { AndroidArtifacts.ArtifactType.CLASSES_JAR.type }
)
variant.artifact(mainCompilation.output.classesDirs.singleFile) { variant.artifact(mainCompilation.output.classesDirs.singleFile) {
it.builtBy(mainCompilation.output.classesDirs) it.builtBy(mainCompilation.output.classesDirs)
} }
@@ -178,7 +217,10 @@ fun KotlinMultiplatformExtension.androidTargetPrototype(): PrototypeAndroidTarge
artifactType: CLASSES_JAR artifactType: CLASSES_JAR
*/ */
androidTarget.runtimeElementsConfiguration.outgoing.variants.create("classes").let { variant -> androidTarget.runtimeElementsConfiguration.outgoing.variants.create("classes").let { variant ->
variant.attributes.attribute(AndroidArtifacts.ARTIFACT_TYPE, AndroidArtifacts.ArtifactType.CLASSES_JAR.type) variant.attributes.attributeProvider(
AndroidArtifacts.ARTIFACT_TYPE,
project.provider { AndroidArtifacts.ArtifactType.CLASSES_JAR.type }
)
variant.artifact(mainCompilation.output.classesDirs.singleFile) { variant.artifact(mainCompilation.output.classesDirs.singleFile) {
it.builtBy(mainCompilation.output.classesDirs) it.builtBy(mainCompilation.output.classesDirs)
} }
@@ -41,14 +41,26 @@ internal fun PrototypeAndroidTarget.createAndroidCompilation(name: String): Prot
configure { compilation -> configure { compilation ->
/* Setup attributes for the compile dependencies */ /* Setup attributes for the compile dependencies */
compilation.configurations.compileDependencyConfiguration.apply { compilation.configurations.compileDependencyConfiguration.apply {
attributes.attribute(ARTIFACT_TYPE, AndroidArtifacts.ArtifactType.CLASSES_JAR.type) attributes.attributeProvider(
attributes.attribute(TARGET_JVM_ENVIRONMENT_ATTRIBUTE, project.objects.named(TargetJvmEnvironment.ANDROID)) ARTIFACT_TYPE,
project.provider { AndroidArtifacts.ArtifactType.CLASSES_JAR.type }
)
attributes.attributeProvider(
TARGET_JVM_ENVIRONMENT_ATTRIBUTE,
project.provider { project.objects.named(TargetJvmEnvironment.ANDROID) }
)
} }
/* Setup attributes for the runtime dependencies */ /* Setup attributes for the runtime dependencies */
compilation.configurations.runtimeDependencyConfiguration?.apply { compilation.configurations.runtimeDependencyConfiguration?.apply {
attributes.attribute(ARTIFACT_TYPE, AndroidArtifacts.ArtifactType.CLASSES_JAR.type) attributes.attributeProvider(
attributes.attribute(TARGET_JVM_ENVIRONMENT_ATTRIBUTE, project.objects.named(TargetJvmEnvironment.ANDROID)) ARTIFACT_TYPE,
project.provider { AndroidArtifacts.ArtifactType.CLASSES_JAR.type }
)
attributes.attributeProvider(
TARGET_JVM_ENVIRONMENT_ATTRIBUTE,
project.provider { project.objects.named(TargetJvmEnvironment.ANDROID) }
)
} }
} }
} }
@@ -20,22 +20,23 @@ import org.jetbrains.kotlin.gradle.plugin.usageByName
import org.jetbrains.kotlin.gradle.utils.createResolvable import org.jetbrains.kotlin.gradle.utils.createResolvable
import org.jetbrains.kotlin.gradle.utils.findResolvable import org.jetbrains.kotlin.gradle.utils.findResolvable
import org.jetbrains.kotlin.gradle.utils.named import org.jetbrains.kotlin.gradle.utils.named
import org.jetbrains.kotlin.gradle.utils.setAttribute
private const val KOTLIN_KLIB_COMMONIZER_EMBEDDABLE = "kotlin-klib-commonizer-embeddable" private const val KOTLIN_KLIB_COMMONIZER_EMBEDDABLE = "kotlin-klib-commonizer-embeddable"
internal fun GradleCliCommonizer(commonizerToolRunner: KotlinNativeCommonizerToolRunner): CliCommonizer { internal fun GradleCliCommonizer(commonizerToolRunner: KotlinNativeCommonizerToolRunner): CliCommonizer {
return CliCommonizer(CliCommonizer.Executor { arguments -> return CliCommonizer { arguments ->
commonizerToolRunner.run(arguments) commonizerToolRunner.run(arguments)
}) }
} }
internal fun Project.maybeCreateCommonizerClasspathConfiguration(): Configuration { internal fun Project.maybeCreateCommonizerClasspathConfiguration(): Configuration {
return configurations.findResolvable(KLIB_COMMONIZER_CLASSPATH_CONFIGURATION_NAME) return configurations.findResolvable(KLIB_COMMONIZER_CLASSPATH_CONFIGURATION_NAME)
?: project.configurations.createResolvable(KLIB_COMMONIZER_CLASSPATH_CONFIGURATION_NAME) ?: project.configurations.createResolvable(KLIB_COMMONIZER_CLASSPATH_CONFIGURATION_NAME)
.run { .run {
attributes.attribute(Category.CATEGORY_ATTRIBUTE, objects.named(Category.LIBRARY)) attributes.setAttribute(Category.CATEGORY_ATTRIBUTE, objects.named(Category.LIBRARY))
attributes.attribute(LibraryElements.LIBRARY_ELEMENTS_ATTRIBUTE, objects.named(LibraryElements.JAR)) attributes.setAttribute(LibraryElements.LIBRARY_ELEMENTS_ATTRIBUTE, objects.named(LibraryElements.JAR))
attributes.attribute(Usage.USAGE_ATTRIBUTE, usageByName(Usage.JAVA_RUNTIME)) attributes.setAttribute(Usage.USAGE_ATTRIBUTE, usageByName(Usage.JAVA_RUNTIME))
defaultDependencies { dependencies -> defaultDependencies { dependencies ->
dependencies.add( dependencies.add(
project.dependencies.create("$KOTLIN_MODULE_GROUP:$KOTLIN_KLIB_COMMONIZER_EMBEDDABLE:${getKotlinPluginVersion()}") project.dependencies.create("$KOTLIN_MODULE_GROUP:$KOTLIN_KLIB_COMMONIZER_EMBEDDABLE:${getKotlinPluginVersion()}")
@@ -22,6 +22,7 @@ import org.jetbrains.kotlin.gradle.targets.metadata.isCompatibilityMetadataVaria
import org.jetbrains.kotlin.gradle.targets.metadata.isKotlinGranularMetadataEnabled import org.jetbrains.kotlin.gradle.targets.metadata.isKotlinGranularMetadataEnabled
import org.jetbrains.kotlin.gradle.tasks.registerTask import org.jetbrains.kotlin.gradle.tasks.registerTask
import org.jetbrains.kotlin.gradle.utils.createConsumable import org.jetbrains.kotlin.gradle.utils.createConsumable
import org.jetbrains.kotlin.gradle.utils.setAttribute
internal val KotlinLegacyCompatibilityMetadataArtifact = KotlinTargetArtifact { target, _, _ -> internal val KotlinLegacyCompatibilityMetadataArtifact = KotlinTargetArtifact { target, _, _ ->
if (target !is KotlinMetadataTarget) return@KotlinTargetArtifact if (target !is KotlinMetadataTarget) return@KotlinTargetArtifact
@@ -39,8 +40,8 @@ internal val KotlinLegacyCompatibilityMetadataArtifact = KotlinTargetArtifact {
target.project.configurations.createConsumable(COMMON_MAIN_ELEMENTS_CONFIGURATION_NAME).apply { target.project.configurations.createConsumable(COMMON_MAIN_ELEMENTS_CONFIGURATION_NAME).apply {
usesPlatformOf(target) usesPlatformOf(target)
attributes.attribute(Usage.USAGE_ATTRIBUTE, KotlinUsages.producerApiUsage(target)) attributes.setAttribute(Usage.USAGE_ATTRIBUTE, KotlinUsages.producerApiUsage(target))
attributes.attribute(Category.CATEGORY_ATTRIBUTE, target.project.categoryByName(Category.LIBRARY)) attributes.setAttribute(Category.CATEGORY_ATTRIBUTE, target.project.categoryByName(Category.LIBRARY))
val commonMainApiConfiguration = target.project.configurations.sourceSetDependencyConfigurationByScope( val commonMainApiConfiguration = target.project.configurations.sourceSetDependencyConfigurationByScope(
target.project.kotlinExtension.sourceSets.getByName(KotlinSourceSet.COMMON_MAIN_SOURCE_SET_NAME), target.project.kotlinExtension.sourceSets.getByName(KotlinSourceSet.COMMON_MAIN_SOURCE_SET_NAME),
@@ -15,12 +15,13 @@ import org.jetbrains.kotlin.gradle.targets.metadata.createGenerateProjectStructu
import org.jetbrains.kotlin.gradle.targets.metadata.isCompatibilityMetadataVariantEnabled import org.jetbrains.kotlin.gradle.targets.metadata.isCompatibilityMetadataVariantEnabled
import org.jetbrains.kotlin.gradle.targets.metadata.isKotlinGranularMetadataEnabled import org.jetbrains.kotlin.gradle.targets.metadata.isKotlinGranularMetadataEnabled
import org.jetbrains.kotlin.gradle.targets.native.internal.includeCommonizedCInteropMetadata import org.jetbrains.kotlin.gradle.targets.native.internal.includeCommonizedCInteropMetadata
import org.jetbrains.kotlin.gradle.utils.setAttribute
internal val KotlinMetadataArtifact = KotlinTargetArtifact { target, apiElements, _ -> internal val KotlinMetadataArtifact = KotlinTargetArtifact { target, apiElements, _ ->
if (target !is KotlinMetadataTarget || !target.project.isKotlinGranularMetadataEnabled) return@KotlinTargetArtifact if (target !is KotlinMetadataTarget || !target.project.isKotlinGranularMetadataEnabled) return@KotlinTargetArtifact
apiElements.attributes.attribute(Usage.USAGE_ATTRIBUTE, target.project.usageByName(KotlinUsages.KOTLIN_METADATA)) apiElements.attributes.setAttribute(Usage.USAGE_ATTRIBUTE, target.project.usageByName(KotlinUsages.KOTLIN_METADATA))
apiElements.attributes.attribute(Category.CATEGORY_ATTRIBUTE, target.project.categoryByName(Category.LIBRARY)) apiElements.attributes.setAttribute(Category.CATEGORY_ATTRIBUTE, target.project.categoryByName(Category.LIBRARY))
val metadataJarTask = target.createArtifactsTask { jar -> val metadataJarTask = target.createArtifactsTask { jar ->
jar.description = "Assembles a jar archive containing the metadata for all Kotlin source sets." jar.description = "Assembles a jar archive containing the metadata for all Kotlin source sets."
@@ -21,8 +21,9 @@ import org.jetbrains.kotlin.gradle.targets.metadata.findMetadataCompilation
import org.jetbrains.kotlin.gradle.targets.metadata.isKotlinGranularMetadataEnabled import org.jetbrains.kotlin.gradle.targets.metadata.isKotlinGranularMetadataEnabled
import org.jetbrains.kotlin.gradle.targets.native.internal.includeCommonizedCInteropMetadata import org.jetbrains.kotlin.gradle.targets.native.internal.includeCommonizedCInteropMetadata
import org.jetbrains.kotlin.gradle.tasks.locateOrRegisterTask import org.jetbrains.kotlin.gradle.tasks.locateOrRegisterTask
import org.jetbrains.kotlin.gradle.utils.copyAttributes import org.jetbrains.kotlin.gradle.utils.copyAttributesTo
import org.jetbrains.kotlin.gradle.utils.createConsumable import org.jetbrains.kotlin.gradle.utils.createConsumable
import org.jetbrains.kotlin.gradle.utils.setAttribute
import org.jetbrains.kotlin.util.capitalizeDecapitalize.toLowerCaseAsciiOnly import org.jetbrains.kotlin.util.capitalizeDecapitalize.toLowerCaseAsciiOnly
internal val KotlinNativeHostSpecificMetadataArtifact = KotlinTargetArtifact { target, apiElements, _ -> internal val KotlinNativeHostSpecificMetadataArtifact = KotlinTargetArtifact { target, apiElements, _ ->
@@ -34,8 +35,14 @@ internal val KotlinNativeHostSpecificMetadataArtifact = KotlinTargetArtifact { t
configuration.extendsFrom(*apiElements.extendsFrom.toTypedArray()) configuration.extendsFrom(*apiElements.extendsFrom.toTypedArray())
target.project.launchInStage(AfterFinaliseDsl) { target.project.launchInStage(AfterFinaliseDsl) {
copyAttributes(from = apiElements.attributes, to = configuration.attributes) apiElements.copyAttributesTo(
configuration.attributes.attribute(Usage.USAGE_ATTRIBUTE, target.project.usageByName(KotlinUsages.KOTLIN_METADATA)) target.project,
dest = configuration.attributes
)
configuration.setAttribute(
Usage.USAGE_ATTRIBUTE,
target.project.usageByName(KotlinUsages.KOTLIN_METADATA)
)
} }
} }
@@ -21,6 +21,7 @@ import org.jetbrains.kotlin.gradle.plugin.mpp.KotlinNativeTarget
import org.jetbrains.kotlin.gradle.plugin.mpp.enabledOnCurrentHost import org.jetbrains.kotlin.gradle.plugin.mpp.enabledOnCurrentHost
import org.jetbrains.kotlin.gradle.tasks.dependsOn import org.jetbrains.kotlin.gradle.tasks.dependsOn
import org.jetbrains.kotlin.gradle.tasks.registerTask import org.jetbrains.kotlin.gradle.tasks.registerTask
import org.jetbrains.kotlin.gradle.utils.setAttribute
import java.io.File import java.io.File
internal val KotlinNativeKlibArtifact = KotlinTargetArtifact { target, apiElements, _ -> internal val KotlinNativeKlibArtifact = KotlinTargetArtifact { target, apiElements, _ ->
@@ -31,7 +32,7 @@ internal val KotlinNativeKlibArtifact = KotlinTargetArtifact { target, apiElemen
it.description = "Assembles outputs for target '${target.name}'." it.description = "Assembles outputs for target '${target.name}'."
} }
apiElements.outgoing.attributes.attribute(target.project.artifactTypeAttribute, NativeArtifactFormat.KLIB) apiElements.outgoing.attributes.setAttribute(target.project.artifactTypeAttribute, NativeArtifactFormat.KLIB)
target.compilations.getByName(MAIN_COMPILATION_NAME).let { mainCompilation -> target.compilations.getByName(MAIN_COMPILATION_NAME).let { mainCompilation ->
artifactsTask.dependsOn(mainCompilation.compileTaskProvider) artifactsTask.dependsOn(mainCompilation.compileTaskProvider)
@@ -67,7 +68,7 @@ internal fun createKlibArtifact(
} }
compilation.project.extensions.getByType(DefaultArtifactPublicationSet::class.java).addCandidate(klibArtifact) compilation.project.extensions.getByType(DefaultArtifactPublicationSet::class.java).addCandidate(klibArtifact)
artifacts.add(klibArtifact) artifacts.add(klibArtifact)
attributes.attribute(compilation.project.artifactTypeAttribute, NativeArtifactFormat.KLIB) attributes.setAttribute(compilation.project.artifactTypeAttribute, NativeArtifactFormat.KLIB)
} }
} }
@@ -15,6 +15,7 @@ import org.jetbrains.kotlin.gradle.plugin.KotlinGradlePluginExtensionPoint
import org.jetbrains.kotlin.gradle.plugin.KotlinTarget import org.jetbrains.kotlin.gradle.plugin.KotlinTarget
import org.jetbrains.kotlin.gradle.plugin.internal.artifactTypeAttribute import org.jetbrains.kotlin.gradle.plugin.internal.artifactTypeAttribute
import org.jetbrains.kotlin.gradle.tasks.registerTask import org.jetbrains.kotlin.gradle.tasks.registerTask
import org.jetbrains.kotlin.gradle.utils.setAttribute
import org.jetbrains.kotlin.util.capitalizeDecapitalize.toLowerCaseAsciiOnly import org.jetbrains.kotlin.util.capitalizeDecapitalize.toLowerCaseAsciiOnly
internal fun interface KotlinTargetArtifact { internal fun interface KotlinTargetArtifact {
@@ -52,8 +53,8 @@ internal fun KotlinTarget.createPublishArtifact(
elementsConfiguration.filterNotNull().forEach { configuration -> elementsConfiguration.filterNotNull().forEach { configuration ->
configuration.outgoing.artifacts.add(artifact) configuration.outgoing.artifacts.add(artifact)
configuration.outgoing.attributes.attribute(project.artifactTypeAttribute, artifactType) configuration.outgoing.attributes.setAttribute(project.artifactTypeAttribute, artifactType)
} }
return artifact return artifact
} }
@@ -151,7 +151,7 @@ class Kapt3GradleSubplugin @Inject internal constructor(private val registry: To
project.configurations.findResolvable(configurationName)?.let { return it } project.configurations.findResolvable(configurationName)?.let { return it }
val aptConfiguration = project.configurations.createResolvable(configurationName).apply { val aptConfiguration = project.configurations.createResolvable(configurationName).apply {
attributes.attribute(Usage.USAGE_ATTRIBUTE, project.objects.named(Usage::class.java, Usage.JAVA_RUNTIME)) attributes.setAttribute(Usage.USAGE_ATTRIBUTE, project.objects.named(Usage.JAVA_RUNTIME))
} }
if (aptConfiguration.name != MAIN_KAPT_CONFIGURATION_NAME) { if (aptConfiguration.name != MAIN_KAPT_CONFIGURATION_NAME) {
@@ -34,6 +34,7 @@ import org.jetbrains.kotlin.gradle.tasks.locateTask
import org.jetbrains.kotlin.gradle.tasks.registerTask import org.jetbrains.kotlin.gradle.tasks.registerTask
import org.jetbrains.kotlin.gradle.utils.whenEvaluated import org.jetbrains.kotlin.gradle.utils.whenEvaluated
import org.jetbrains.kotlin.gradle.utils.archivePathCompatible import org.jetbrains.kotlin.gradle.utils.archivePathCompatible
import org.jetbrains.kotlin.gradle.utils.setAttribute
const val PLUGIN_CLASSPATH_CONFIGURATION_NAME = "kotlinCompilerPluginClasspath" const val PLUGIN_CLASSPATH_CONFIGURATION_NAME = "kotlinCompilerPluginClasspath"
const val NATIVE_COMPILER_PLUGIN_CLASSPATH_CONFIGURATION_NAME = "kotlinNativeCompilerPluginClasspath" const val NATIVE_COMPILER_PLUGIN_CLASSPATH_CONFIGURATION_NAME = "kotlinNativeCompilerPluginClasspath"
@@ -270,14 +271,14 @@ internal abstract class AbstractKotlinPlugin(
// platform-specific modules // platform-specific modules
if (kotlinTarget.platformType != KotlinPlatformType.common) { if (kotlinTarget.platformType != KotlinPlatformType.common) {
project.configurations.getByName(kotlinTarget.apiElementsConfigurationName).run { project.configurations.getByName(kotlinTarget.apiElementsConfigurationName).run {
attributes.attribute(Usage.USAGE_ATTRIBUTE, KotlinUsages.producerApiUsage(kotlinTarget)) attributes.setAttribute(Usage.USAGE_ATTRIBUTE, KotlinUsages.producerApiUsage(kotlinTarget))
attributes.attribute(Category.CATEGORY_ATTRIBUTE, project.categoryByName(Category.LIBRARY)) attributes.setAttribute(Category.CATEGORY_ATTRIBUTE, project.categoryByName(Category.LIBRARY))
usesPlatformOf(kotlinTarget) usesPlatformOf(kotlinTarget)
} }
project.configurations.getByName(kotlinTarget.runtimeElementsConfigurationName).run { project.configurations.getByName(kotlinTarget.runtimeElementsConfigurationName).run {
attributes.attribute(Usage.USAGE_ATTRIBUTE, KotlinUsages.producerRuntimeUsage(kotlinTarget)) attributes.setAttribute(Usage.USAGE_ATTRIBUTE, KotlinUsages.producerRuntimeUsage(kotlinTarget))
attributes.attribute(Category.CATEGORY_ATTRIBUTE, project.categoryByName(Category.LIBRARY)) attributes.setAttribute(Category.CATEGORY_ATTRIBUTE, project.categoryByName(Category.LIBRARY))
usesPlatformOf(kotlinTarget) usesPlatformOf(kotlinTarget)
} }
} }
@@ -181,6 +181,11 @@ abstract class DefaultKotlinBasePlugin : KotlinBasePlugin {
SourceSetCompatibilityHelper.SourceSetCompatibilityHelperVariantFactory::class, SourceSetCompatibilityHelper.SourceSetCompatibilityHelperVariantFactory::class,
DefaultSourceSetCompatibilityHelperVariantFactory() DefaultSourceSetCompatibilityHelperVariantFactory()
) )
factories.putIfAbsent(
AttributesConfigurationHelper.AttributeConfigurationHelperVariantFactory::class,
DefaultAttributeConfigurationHelperVariantFactory()
)
} }
protected fun setupAttributeMatchingStrategy( protected fun setupAttributeMatchingStrategy(
@@ -9,6 +9,9 @@ import org.gradle.api.Named
import org.gradle.api.Project import org.gradle.api.Project
import org.gradle.api.artifacts.Configuration import org.gradle.api.artifacts.Configuration
import org.gradle.api.attributes.* import org.gradle.api.attributes.*
import org.gradle.api.attributes.java.TargetJvmEnvironment
import org.gradle.util.GradleVersion
import org.jetbrains.kotlin.gradle.plugin.PropertiesProvider.Companion.kotlinPropertiesProvider
import org.jetbrains.kotlin.gradle.plugin.mpp.* import org.jetbrains.kotlin.gradle.plugin.mpp.*
import org.jetbrains.kotlin.gradle.plugin.mpp.compilationImpl.runKotlinCompilationSideEffects import org.jetbrains.kotlin.gradle.plugin.mpp.compilationImpl.runKotlinCompilationSideEffects
import org.jetbrains.kotlin.gradle.targets.js.KotlinJsCompilerAttribute import org.jetbrains.kotlin.gradle.targets.js.KotlinJsCompilerAttribute
@@ -53,7 +56,7 @@ internal inline fun <reified T : Named> Project.attributeValueByName(attributeVa
objects.named(T::class.java, attributeValueName) 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.setAttribute(KotlinPlatformType.attribute, target.platformType)
when (target.platformType) { when (target.platformType) {
KotlinPlatformType.jvm -> setJavaTargetEnvironmentAttributeIfSupported(target.project, "standard-jvm") KotlinPlatformType.jvm -> setJavaTargetEnvironmentAttributeIfSupported(target.project, "standard-jvm")
@@ -72,33 +75,31 @@ fun Configuration.usesPlatformOf(target: KotlinTarget): Configuration {
else -> setJavaTargetEnvironmentAttributeIfSupported(target.project, "non-jvm") else -> setJavaTargetEnvironmentAttributeIfSupported(target.project, "non-jvm")
} }
val publishJsCompilerAttribute = PropertiesProvider(target.project).publishJsCompilerAttribute val publishJsCompilerAttribute = target.project.kotlinPropertiesProvider.publishJsCompilerAttribute
if (publishJsCompilerAttribute && target is KotlinJsIrTarget) { if (publishJsCompilerAttribute && target is KotlinJsIrTarget) {
if (target.platformType == KotlinPlatformType.js) { if (target.platformType == KotlinPlatformType.js) {
attributes.attribute(KotlinJsCompilerAttribute.jsCompilerAttribute, KotlinJsCompilerAttribute.ir) attributes.setAttribute(KotlinJsCompilerAttribute.jsCompilerAttribute, KotlinJsCompilerAttribute.ir)
} else { } else {
attributes.attribute(KotlinWasmTargetAttribute.wasmTargetAttribute, target.wasmTargetType!!.toAttribute()) attributes.setAttributeProvider<KotlinWasmTargetAttribute>(
target.project,
KotlinWasmTargetAttribute.wasmTargetAttribute,
) { target.wasmTargetType!!.toAttribute() }
} }
} }
// TODO: Provide an universal way to copy attributes from the target.
if (target is KotlinNativeTarget) { if (target is KotlinNativeTarget) {
attributes.attribute(KotlinNativeTarget.konanTargetAttribute, target.konanTarget.name) attributes.setAttribute(KotlinNativeTarget.konanTargetAttribute, target.konanTarget.name)
} }
return this return this
} }
private fun Configuration.setJavaTargetEnvironmentAttributeIfSupported(project: Project, value: String) { private fun Configuration.setJavaTargetEnvironmentAttributeIfSupported(project: Project, value: String) {
if (isGradleVersionAtLeast(7, 0)) { if (GradleVersion.current() >= GradleVersion.version("7.0")) {
@Suppress("UNCHECKED_CAST") attributes.setAttribute(
val attributeClass = Class.forName("org.gradle.api.attributes.java.TargetJvmEnvironment") as Class<out Named> TargetJvmEnvironment.TARGET_JVM_ENVIRONMENT_ATTRIBUTE,
project.objects.named(value)
@Suppress("UNCHECKED_CAST") )
val attributeKey = attributeClass.getField("TARGET_JVM_ENVIRONMENT_ATTRIBUTE").get(null) as Attribute<Named>
val attributeValue = project.objects.named(attributeClass, value)
attributes.attribute(attributeKey, attributeValue)
} }
} }
@@ -9,7 +9,6 @@ package org.jetbrains.kotlin.gradle.plugin.ide.dependencyResolvers
import org.gradle.api.Project import org.gradle.api.Project
import org.gradle.api.artifacts.DependencySubstitutions import org.gradle.api.artifacts.DependencySubstitutions
import org.gradle.api.artifacts.ProjectDependency
import org.gradle.api.artifacts.component.ModuleComponentSelector import org.gradle.api.artifacts.component.ModuleComponentSelector
import org.gradle.api.artifacts.component.ProjectComponentIdentifier import org.gradle.api.artifacts.component.ProjectComponentIdentifier
import org.gradle.api.attributes.Category import org.gradle.api.attributes.Category
@@ -23,6 +22,7 @@ import org.jetbrains.kotlin.gradle.plugin.KotlinPlatformType
import org.jetbrains.kotlin.gradle.plugin.ide.IdeDependencyResolver import org.jetbrains.kotlin.gradle.plugin.ide.IdeDependencyResolver
import org.jetbrains.kotlin.gradle.plugin.usageByName import org.jetbrains.kotlin.gradle.plugin.usageByName
import org.jetbrains.kotlin.gradle.utils.named import org.jetbrains.kotlin.gradle.utils.named
import org.jetbrains.kotlin.gradle.utils.setAttribute
/** /**
* Resolves dependencies of jvm and Android source sets from the perspective jvm * Resolves dependencies of jvm and Android source sets from the perspective jvm
@@ -32,10 +32,10 @@ internal fun IdeJvmAndAndroidPlatformBinaryDependencyResolver(project: Project):
binaryType = IdeaKotlinBinaryDependency.KOTLIN_COMPILE_BINARY_TYPE, binaryType = IdeaKotlinBinaryDependency.KOTLIN_COMPILE_BINARY_TYPE,
artifactResolutionStrategy = IdeBinaryDependencyResolver.ArtifactResolutionStrategy.PlatformLikeSourceSet( artifactResolutionStrategy = IdeBinaryDependencyResolver.ArtifactResolutionStrategy.PlatformLikeSourceSet(
setupPlatformResolutionAttributes = { setupPlatformResolutionAttributes = {
attributes.attribute(Usage.USAGE_ATTRIBUTE, project.usageByName(Usage.JAVA_API)) attributes.setAttribute(Usage.USAGE_ATTRIBUTE, project.usageByName(Usage.JAVA_API))
attributes.attribute(Category.CATEGORY_ATTRIBUTE, project.objects.named(Category.LIBRARY)) attributes.setAttribute(Category.CATEGORY_ATTRIBUTE, project.objects.named(Category.LIBRARY))
attributes.attribute(KotlinPlatformType.attribute, KotlinPlatformType.jvm) attributes.setAttribute(KotlinPlatformType.attribute, KotlinPlatformType.jvm)
attributes.attribute( attributes.setAttribute(
TargetJvmEnvironment.TARGET_JVM_ENVIRONMENT_ATTRIBUTE, TargetJvmEnvironment.TARGET_JVM_ENVIRONMENT_ATTRIBUTE,
project.objects.named(TargetJvmEnvironment.STANDARD_JVM) project.objects.named(TargetJvmEnvironment.STANDARD_JVM)
) )
@@ -8,7 +8,6 @@ package org.jetbrains.kotlin.gradle.plugin.ide.dependencyResolvers
import org.gradle.api.Project import org.gradle.api.Project
import org.gradle.api.artifacts.component.ProjectComponentIdentifier import org.gradle.api.artifacts.component.ProjectComponentIdentifier
import org.gradle.api.attributes.Attribute import org.gradle.api.attributes.Attribute
import org.jetbrains.kotlin.gradle.dsl.kotlinExtension
import org.jetbrains.kotlin.gradle.dsl.multiplatformExtensionOrNull import org.jetbrains.kotlin.gradle.dsl.multiplatformExtensionOrNull
import org.jetbrains.kotlin.gradle.idea.tcs.IdeaKotlinBinaryDependency import org.jetbrains.kotlin.gradle.idea.tcs.IdeaKotlinBinaryDependency
import org.jetbrains.kotlin.gradle.idea.tcs.IdeaKotlinDependency import org.jetbrains.kotlin.gradle.idea.tcs.IdeaKotlinDependency
@@ -28,7 +27,8 @@ import org.jetbrains.kotlin.gradle.plugin.sources.DefaultKotlinSourceSet
import org.jetbrains.kotlin.gradle.plugin.sources.android.AndroidVariantType import org.jetbrains.kotlin.gradle.plugin.sources.android.AndroidVariantType
import org.jetbrains.kotlin.gradle.plugin.sources.android.type import org.jetbrains.kotlin.gradle.plugin.sources.android.type
import org.jetbrains.kotlin.gradle.plugin.sources.internal import org.jetbrains.kotlin.gradle.plugin.sources.internal
import org.jetbrains.kotlin.gradle.utils.copyAttributes import org.jetbrains.kotlin.gradle.utils.setAttribute
import org.jetbrains.kotlin.gradle.utils.setAttributeProvider
import org.jetbrains.kotlin.gradle.utils.toMap import org.jetbrains.kotlin.gradle.utils.toMap
/** /**
@@ -112,7 +112,10 @@ internal object IdeJvmAndAndroidSourceDependencyResolver : IdeDependencyResolver
.map { attributes -> attributes.toMap().toList().toSet() } .map { attributes -> attributes.toMap().toList().toSet() }
.reduceOrNull { acc, next -> acc intersect next } .reduceOrNull { acc, next -> acc intersect next }
.orEmpty() .orEmpty()
.forEach { (key, value) -> @Suppress("UNCHECKED_CAST") attribute(key as Attribute<Any>, value as Any) } .forEach { (key, value) ->
@Suppress("UNCHECKED_CAST")
setAttributeProvider(sourceSet.project, key as Attribute<Any>) { value as Any }
}
}, },
componentFilter = { id -> id is ProjectComponentIdentifier } componentFilter = { id -> id is ProjectComponentIdentifier }
) )
@@ -0,0 +1,55 @@
/*
* 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.internal
import org.gradle.api.Project
import org.gradle.api.attributes.Attribute
import org.gradle.api.attributes.HasAttributes
import org.gradle.api.provider.ProviderFactory
import org.jetbrains.kotlin.gradle.plugin.VariantImplementationFactories
import org.jetbrains.kotlin.gradle.plugin.variantImplementationFactory
/**
* Gradle 7.4 introduced a way of configuring attribute values using a [org.gradle.api.provider.Provider].
* In Gradle 8.3+ using a non-Provider value caused eager task realization (see KT-60664).
*/
internal interface AttributesConfigurationHelper {
fun <T : Any> setAttribute(
attributesContainer: HasAttributes,
key: Attribute<T>,
value: () -> T
)
interface AttributeConfigurationHelperVariantFactory : VariantImplementationFactories.VariantImplementationFactory {
fun getInstance(providerFactory: ProviderFactory): AttributesConfigurationHelper
}
}
internal class DefaultAttributesConfigurationHelper(
private val providerFactory: ProviderFactory
) : AttributesConfigurationHelper {
override fun <T : Any> setAttribute(
attributesContainer: HasAttributes,
key: Attribute<T>,
value: () -> T
) {
attributesContainer.attributes.attributeProvider(
key,
providerFactory.provider { value() }
)
}
}
internal class DefaultAttributeConfigurationHelperVariantFactory :
AttributesConfigurationHelper.AttributeConfigurationHelperVariantFactory {
override fun getInstance(
providerFactory: ProviderFactory
): AttributesConfigurationHelper = DefaultAttributesConfigurationHelper(providerFactory)
}
internal val Project.attributesConfigurationHelper
get() = variantImplementationFactory<AttributesConfigurationHelper.AttributeConfigurationHelperVariantFactory>()
.getInstance(providers)
@@ -50,11 +50,11 @@ class HierarchyAttributeContainer(
override fun isEmpty(): Boolean = lazyAttributesMap.isEmpty() && override fun isEmpty(): Boolean = lazyAttributesMap.isEmpty() &&
attributesMap.isEmpty() && attributesMap.isEmpty() &&
(parent?.keySet().orEmpty().filter(filterParentAttributes).isEmpty()) (parent?.keySet().orEmpty().toSet().none(filterParentAttributes))
override fun keySet(): Set<Attribute<*>> = lazyAttributesMap.keys + override fun keySet(): Set<Attribute<*>> = lazyAttributesMap.keys +
attributesMap.keys + attributesMap.keys +
parent?.keySet().orEmpty().filter(filterParentAttributes) parent?.keySet().orEmpty().toSet().filter(filterParentAttributes)
override fun <T : Any> attribute(key: Attribute<T>, value: T): AttributeContainer { override fun <T : Any> attribute(key: Attribute<T>, value: T): AttributeContainer {
val checkedValue = requireNotNull(value as Any?) { "null values for attributes are not supported" } val checkedValue = requireNotNull(value as Any?) { "null values for attributes are not supported" }
@@ -208,13 +208,11 @@ class DefaultKotlinUsageContext(
*/ */
val result = project.configurations.detachedResolvable().attributes val result = project.configurations.detachedResolvable().attributes
// Capture type parameter T: configurationAttributes.copyAttributesTo(
fun <T> copyAttribute(attribute: Attribute<T>, from: AttributeContainer, to: AttributeContainer) { project,
to.attribute<T>(attribute, from.getAttribute(attribute)!!) dest = result,
} keys = filterOutNonPublishableAttributes(configurationAttributes.keySet())
)
filterOutNonPublishableAttributes(configurationAttributes.keySet())
.forEach { copyAttribute(it, configurationAttributes, result) }
return result return result
} }
@@ -16,7 +16,7 @@ import org.gradle.api.internal.project.ProjectInternal
import org.jetbrains.kotlin.gradle.plugin.KotlinPluginLifecycle import org.jetbrains.kotlin.gradle.plugin.KotlinPluginLifecycle
import org.jetbrains.kotlin.gradle.plugin.KotlinTargetComponent import org.jetbrains.kotlin.gradle.plugin.KotlinTargetComponent
import org.jetbrains.kotlin.gradle.plugin.launchInStage import org.jetbrains.kotlin.gradle.plugin.launchInStage
import org.jetbrains.kotlin.gradle.utils.copyAttributes import org.jetbrains.kotlin.gradle.utils.copyAttributesTo
import org.jetbrains.kotlin.gradle.utils.createDependencyScope import org.jetbrains.kotlin.gradle.utils.createDependencyScope
import org.jetbrains.kotlin.gradle.utils.findDependencyScope import org.jetbrains.kotlin.gradle.utils.findDependencyScope
import org.jetbrains.kotlin.tooling.core.UnsafeApi import org.jetbrains.kotlin.tooling.core.UnsafeApi
@@ -39,7 +39,14 @@ internal fun KotlinTargetSoftwareComponent(
publishedConfiguration.isVisible = false publishedConfiguration.isVisible = false
publishedConfiguration.extendsFrom(project.configurations.getByName(kotlinUsageContext.dependencyConfigurationName)) publishedConfiguration.extendsFrom(project.configurations.getByName(kotlinUsageContext.dependencyConfigurationName))
publishedConfiguration.artifacts.addAll(kotlinUsageContext.artifacts) publishedConfiguration.artifacts.addAll(kotlinUsageContext.artifacts)
copyAttributes(from = kotlinUsageContext.attributes, to = publishedConfiguration.attributes) // KT-64789: workaround for missing 'org.gradle.libraryelements' attribute on the kotlinUsageContext returned keys Set
// So far I don't know the reason why it appears only on the second call to `keySet()`
// Test failing without it - KotlinAndroidMppIT#testMppAndroidLibFlavorsPublication
kotlinUsageContext.attributes.keySet()
kotlinUsageContext.copyAttributesTo(
project,
dest = publishedConfiguration
)
} }
adhocVariant.addVariantsFromConfiguration(configuration) { configurationVariantDetails -> adhocVariant.addVariantsFromConfiguration(configuration) { configurationVariantDetails ->
@@ -168,12 +168,12 @@ internal fun Configuration.configureSourcesPublicationAttributes(target: KotlinT
// to be either JAVA_RUNTIME (for jvm) or KOTLIN_RUNTIME (for other targets) // 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 // 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. // so consistency with Java Gradle Plugin seemed most desirable choice.
attributes.attribute(Usage.USAGE_ATTRIBUTE, KotlinUsages.producerRuntimeUsage(target)) attributes.setAttribute(Usage.USAGE_ATTRIBUTE, KotlinUsages.producerRuntimeUsage(target))
attributes.attribute(Category.CATEGORY_ATTRIBUTE, project.attributeValueByName(Category.DOCUMENTATION)) attributes.setAttribute(Category.CATEGORY_ATTRIBUTE, project.attributeValueByName(Category.DOCUMENTATION))
attributes.attribute(DocsType.DOCS_TYPE_ATTRIBUTE, project.attributeValueByName(DocsType.SOURCES)) attributes.setAttribute(DocsType.DOCS_TYPE_ATTRIBUTE, project.attributeValueByName(DocsType.SOURCES))
// Bundling attribute is about component dependencies, external means that they are provided as separate components // 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 // 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 // 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)) attributes.setAttribute(Bundling.BUNDLING_ATTRIBUTE, project.attributeValueByName(Bundling.EXTERNAL))
usesPlatformOf(target) usesPlatformOf(target)
} }
@@ -11,7 +11,7 @@ import org.jetbrains.kotlin.gradle.plugin.KotlinPluginLifecycle.Stage.AfterEvalu
import org.jetbrains.kotlin.gradle.plugin.KotlinProjectSetupCoroutine import org.jetbrains.kotlin.gradle.plugin.KotlinProjectSetupCoroutine
import org.jetbrains.kotlin.gradle.plugin.await import org.jetbrains.kotlin.gradle.plugin.await
import org.jetbrains.kotlin.gradle.targets.js.ir.KotlinJsIrCompilation import org.jetbrains.kotlin.gradle.targets.js.ir.KotlinJsIrCompilation
import org.jetbrains.kotlin.gradle.utils.copyAttributes import org.jetbrains.kotlin.gradle.utils.copyAttributesTo
import org.jetbrains.kotlin.gradle.utils.forAllTargets import org.jetbrains.kotlin.gradle.utils.forAllTargets
@@ -25,22 +25,31 @@ internal val UserDefinedAttributesSetupAction = KotlinProjectSetupCoroutine {
kotlinExtension.forAllTargets { target -> kotlinExtension.forAllTargets { target ->
target.internal.kotlinComponents.flatMap { it.internal.usages }.forEach { usage -> target.internal.kotlinComponents.flatMap { it.internal.usages }.forEach { usage ->
val dependencyConfiguration = target.project.configurations.findByName(usage.dependencyConfigurationName) ?: return@forEach val dependencyConfiguration = target.project.configurations.findByName(usage.dependencyConfigurationName) ?: return@forEach
copyAttributes(usage.compilation.attributes, dependencyConfiguration.attributes) usage.compilation.copyAttributesTo(
this@KotlinProjectSetupCoroutine,
dest = dependencyConfiguration.attributes
)
} }
target.compilations.all { compilation -> target.compilations.all { compilation ->
val compilationAttributes = compilation.attributes
compilation.allOwnedConfigurationsNames compilation.allOwnedConfigurationsNames
.mapNotNull { configurationName -> project.configurations.findByName(configurationName) } .mapNotNull { configurationName -> project.configurations.findByName(configurationName) }
.forEach { configuration -> copyAttributes(compilationAttributes, configuration.attributes) } .forEach { configuration ->
compilation.copyAttributesTo(
this@KotlinProjectSetupCoroutine,
dest = configuration
)
}
} }
// Copy to host-specific metadata elements configurations // Copy to host-specific metadata elements configurations
if (target is KotlinNativeTarget) { if (target is KotlinNativeTarget) {
val hostSpecificMetadataElements = project.configurations.findByName(target.hostSpecificMetadataElementsConfigurationName) val hostSpecificMetadataElements = project.configurations.findByName(target.hostSpecificMetadataElementsConfigurationName)
if (hostSpecificMetadataElements != null) { if (hostSpecificMetadataElements != null) {
copyAttributes(from = target.attributes, to = hostSpecificMetadataElements.attributes) target.copyAttributesTo(
this@KotlinProjectSetupCoroutine,
dest = hostSpecificMetadataElements
)
} }
} }
} }
@@ -138,7 +138,7 @@ private fun KotlinCompilationDependencyConfigurationsContainer(
val compileOnlyConfiguration = target.project.configurations val compileOnlyConfiguration = target.project.configurations
.maybeCreateDependencyScope(compileOnlyConfigurationName).apply { .maybeCreateDependencyScope(compileOnlyConfigurationName).apply {
setupAsLocalTargetSpecificConfigurationIfSupported(target) setupAsLocalTargetSpecificConfigurationIfSupported(target)
attributes.attribute(Category.CATEGORY_ATTRIBUTE, target.project.categoryByName(Category.LIBRARY)) attributes.setAttribute(Category.CATEGORY_ATTRIBUTE, target.project.categoryByName(Category.LIBRARY))
isVisible = false isVisible = false
description = "Compile only dependencies for $compilationCoordinates." description = "Compile only dependencies for $compilationCoordinates."
} }
@@ -153,9 +153,9 @@ private fun KotlinCompilationDependencyConfigurationsContainer(
extendsFrom(compileOnlyConfiguration, implementationConfiguration) extendsFrom(compileOnlyConfiguration, implementationConfiguration)
usesPlatformOf(target) usesPlatformOf(target)
isVisible = false isVisible = false
attributes.attribute(Usage.USAGE_ATTRIBUTE, KotlinUsages.consumerApiUsage(target)) attributes.setAttribute(Usage.USAGE_ATTRIBUTE, KotlinUsages.consumerApiUsage(target))
if (target.platformType != KotlinPlatformType.androidJvm) { if (target.platformType != KotlinPlatformType.androidJvm) {
attributes.attribute(Category.CATEGORY_ATTRIBUTE, target.project.categoryByName(Category.LIBRARY)) attributes.setAttribute(Category.CATEGORY_ATTRIBUTE, target.project.categoryByName(Category.LIBRARY))
} }
description = "Compile classpath for $compilationCoordinates." description = "Compile classpath for $compilationCoordinates."
} }
@@ -166,9 +166,9 @@ private fun KotlinCompilationDependencyConfigurationsContainer(
deprecatedRuntimeConfiguration?.let { extendsFrom(it) } deprecatedRuntimeConfiguration?.let { extendsFrom(it) }
usesPlatformOf(target) usesPlatformOf(target)
isVisible = false isVisible = false
attributes.attribute(Usage.USAGE_ATTRIBUTE, KotlinUsages.consumerRuntimeUsage(target)) attributes.setAttribute(Usage.USAGE_ATTRIBUTE, KotlinUsages.consumerRuntimeUsage(target))
if (target.platformType != KotlinPlatformType.androidJvm) { if (target.platformType != KotlinPlatformType.androidJvm) {
attributes.attribute(Category.CATEGORY_ATTRIBUTE, target.project.categoryByName(Category.LIBRARY)) attributes.setAttribute(Category.CATEGORY_ATTRIBUTE, target.project.categoryByName(Category.LIBRARY))
} }
description = "Runtime classpath of $compilationCoordinates." description = "Runtime classpath of $compilationCoordinates."
} else null } else null
@@ -178,10 +178,11 @@ private fun KotlinCompilationDependencyConfigurationsContainer(
isVisible = false isVisible = false
description = "Host-specific Metadata dependencies for $compilationCoordinates" description = "Host-specific Metadata dependencies for $compilationCoordinates"
extendsFrom(compileDependencyConfiguration) extendsFrom(compileDependencyConfiguration)
copyAttributes(from = compileDependencyConfiguration.attributes, to = attributes) compileDependencyConfiguration.copyAttributesTo(
attributes { target.project,
it.attribute(Usage.USAGE_ATTRIBUTE, target.project.usageByName(KotlinUsages.KOTLIN_METADATA)) dest = this
} )
setAttribute(Usage.USAGE_ATTRIBUTE, target.project.usageByName(KotlinUsages.KOTLIN_METADATA))
} else null } else null
val pluginConfiguration = target.project.configurations.maybeCreateResolvable(pluginConfigurationName).apply { val pluginConfiguration = target.project.configurations.maybeCreateResolvable(pluginConfigurationName).apply {
@@ -128,14 +128,14 @@ fun <T : DecoratedExternalKotlinTarget> KotlinMultiplatformExtension.createExter
private fun ExternalKotlinTargetImpl.setupApiElements(configuration: Configuration) { private fun ExternalKotlinTargetImpl.setupApiElements(configuration: Configuration) {
configuration.usesPlatformOf(this) configuration.usesPlatformOf(this)
configuration.attributes.attribute(Usage.USAGE_ATTRIBUTE, KotlinUsages.producerApiUsage(this)) configuration.attributes.setAttribute(Usage.USAGE_ATTRIBUTE, KotlinUsages.producerApiUsage(this))
configuration.attributes.attribute(Category.CATEGORY_ATTRIBUTE, project.objects.named(Category.LIBRARY)) configuration.attributes.setAttribute(Category.CATEGORY_ATTRIBUTE, project.objects.named(Category.LIBRARY))
} }
private fun ExternalKotlinTargetImpl.setupRuntimeElements(configuration: Configuration) { private fun ExternalKotlinTargetImpl.setupRuntimeElements(configuration: Configuration) {
configuration.usesPlatformOf(this) configuration.usesPlatformOf(this)
configuration.attributes.attribute(Usage.USAGE_ATTRIBUTE, KotlinUsages.producerRuntimeUsage(this)) configuration.attributes.setAttribute(Usage.USAGE_ATTRIBUTE, KotlinUsages.producerRuntimeUsage(this))
configuration.attributes.attribute(Category.CATEGORY_ATTRIBUTE, project.objects.named(Category.LIBRARY)) configuration.attributes.setAttribute(Category.CATEGORY_ATTRIBUTE, project.objects.named(Category.LIBRARY))
} }
private fun ExternalKotlinTargetImpl.setupSourcesElements(configuration: Configuration) { private fun ExternalKotlinTargetImpl.setupSourcesElements(configuration: Configuration) {
@@ -60,7 +60,10 @@ internal val InternalKotlinSourceSet.resolvableMetadataConfiguration: Configurat
/* Ensure consistent dependency resolution result within the whole module */ /* Ensure consistent dependency resolution result within the whole module */
configuration.shouldResolveConsistentlyWith(allCompileMetadataConfiguration) configuration.shouldResolveConsistentlyWith(allCompileMetadataConfiguration)
copyAttributes(allCompileMetadataConfiguration.attributes, configuration.attributes) allCompileMetadataConfiguration.copyAttributesTo(
project,
dest = configuration
)
configureMetadataDependenciesConfigurations(configuration) configureMetadataDependenciesConfigurations(configuration)
@@ -96,8 +99,8 @@ private val Project.allCompileMetadataConfiguration
get(): Configuration = configurations.findResolvable("allSourceSetsCompileDependenciesMetadata") get(): Configuration = configurations.findResolvable("allSourceSetsCompileDependenciesMetadata")
?: configurations.createResolvable("allSourceSetsCompileDependenciesMetadata").also { configuration -> ?: configurations.createResolvable("allSourceSetsCompileDependenciesMetadata").also { configuration ->
configuration.usesPlatformOf(multiplatformExtension.metadata()) configuration.usesPlatformOf(multiplatformExtension.metadata())
configuration.attributes.attribute(Usage.USAGE_ATTRIBUTE, project.usageByName(KotlinUsages.KOTLIN_METADATA)) configuration.attributes.setAttribute(Usage.USAGE_ATTRIBUTE, project.usageByName(KotlinUsages.KOTLIN_METADATA))
configuration.attributes.attribute(Category.CATEGORY_ATTRIBUTE, project.categoryByName(Category.LIBRARY)) configuration.attributes.setAttribute(Category.CATEGORY_ATTRIBUTE, project.categoryByName(Category.LIBRARY))
kotlinExtension.sourceSets.all { sourceSet -> kotlinExtension.sourceSets.all { sourceSet ->
configuration.extendsFrom(configurations.getByName(sourceSet.apiConfigurationName)) configuration.extendsFrom(configurations.getByName(sourceSet.apiConfigurationName))
@@ -21,6 +21,7 @@ import org.jetbrains.kotlin.gradle.targets.metadata.isKotlinGranularMetadataEnab
import org.jetbrains.kotlin.gradle.utils.createResolvable import org.jetbrains.kotlin.gradle.utils.createResolvable
import org.jetbrains.kotlin.gradle.utils.maybeCreateDependencyScope import org.jetbrains.kotlin.gradle.utils.maybeCreateDependencyScope
import org.jetbrains.kotlin.gradle.utils.maybeCreateResolvable import org.jetbrains.kotlin.gradle.utils.maybeCreateResolvable
import org.jetbrains.kotlin.gradle.utils.setAttribute
import java.io.File import java.io.File
internal abstract class KotlinSourceSetFactory<T : KotlinSourceSet> internal constructor( internal abstract class KotlinSourceSetFactory<T : KotlinSourceSet> internal constructor(
@@ -98,9 +99,9 @@ internal class DefaultKotlinSourceSetFactory(
dependencyConfigurationWithMetadata.forEach { (configurationName, metadataName) -> dependencyConfigurationWithMetadata.forEach { (configurationName, metadataName) ->
project.configurations.maybeCreateResolvable(metadataName).apply { project.configurations.maybeCreateResolvable(metadataName).apply {
attributes.attribute(KotlinPlatformType.attribute, KotlinPlatformType.common) attributes.setAttribute(KotlinPlatformType.attribute, KotlinPlatformType.common)
attributes.attribute(Usage.USAGE_ATTRIBUTE, project.usageByName(KotlinUsages.KOTLIN_API)) attributes.setAttribute(Usage.USAGE_ATTRIBUTE, project.usageByName(KotlinUsages.KOTLIN_API))
attributes.attribute(Category.CATEGORY_ATTRIBUTE, project.categoryByName(Category.LIBRARY)) attributes.setAttribute(Category.CATEGORY_ATTRIBUTE, project.categoryByName(Category.LIBRARY))
isVisible = false isVisible = false
if (configurationName != null) { if (configurationName != null) {
@@ -108,7 +109,7 @@ internal class DefaultKotlinSourceSetFactory(
} }
if (project.isKotlinGranularMetadataEnabled) { if (project.isKotlinGranularMetadataEnabled) {
attributes.attribute(Usage.USAGE_ATTRIBUTE, project.usageByName(KotlinUsages.KOTLIN_METADATA)) attributes.setAttribute(Usage.USAGE_ATTRIBUTE, project.usageByName(KotlinUsages.KOTLIN_METADATA))
} }
} }
} }
@@ -33,6 +33,7 @@ import org.jetbrains.kotlin.gradle.scripting.ScriptingExtension
import org.jetbrains.kotlin.gradle.tasks.KotlinCompile import org.jetbrains.kotlin.gradle.tasks.KotlinCompile
import org.jetbrains.kotlin.gradle.utils.maybeCreateDependencyScope import org.jetbrains.kotlin.gradle.utils.maybeCreateDependencyScope
import org.jetbrains.kotlin.gradle.utils.maybeCreateResolvable import org.jetbrains.kotlin.gradle.utils.maybeCreateResolvable
import org.jetbrains.kotlin.gradle.utils.setAttribute
import org.jetbrains.kotlin.util.capitalizeDecapitalize.capitalizeAsciiOnly import org.jetbrains.kotlin.util.capitalizeDecapitalize.capitalizeAsciiOnly
private const val SCRIPTING_LOG_PREFIX = "kotlin scripting plugin:" private const val SCRIPTING_LOG_PREFIX = "kotlin scripting plugin:"
@@ -113,7 +114,7 @@ private fun configureDiscoveryTransformation(
discoveryResultsConfigurationName: String discoveryResultsConfigurationName: String
) { ) {
project.configurations.maybeCreateResolvable(discoveryResultsConfigurationName).apply { project.configurations.maybeCreateResolvable(discoveryResultsConfigurationName).apply {
attributes.attribute(artifactType, scriptFilesExtensions) attributes.setAttribute(artifactType, scriptFilesExtensions)
extendsFrom(discoveryConfiguration) extendsFrom(discoveryConfiguration)
} }
val classLoadersCachingService = ClassLoadersCachingBuildService.registerIfAbsent(project) val classLoadersCachingService = ClassLoadersCachingBuildService.registerIfAbsent(project)
@@ -161,14 +162,14 @@ private fun DependencyHandler.registerDiscoverScriptExtensionsTransform(
parameters.compilerClasspath.from(compilerClasspath) parameters.compilerClasspath.from(compilerClasspath)
} }
registerTransform(DiscoverScriptExtensionsTransformAction::class.java) { transformSpec -> registerTransform(DiscoverScriptExtensionsTransformAction::class.java) { transformSpec ->
transformSpec.from.attribute(artifactType, "jar") transformSpec.from.setAttribute(artifactType, "jar")
transformSpec.to.attribute(artifactType, scriptFilesExtensions) transformSpec.to.setAttribute(artifactType, scriptFilesExtensions)
transformSpec.configureCommonParameters() transformSpec.configureCommonParameters()
} }
registerTransform(DiscoverScriptExtensionsTransformAction::class.java) { transformSpec -> registerTransform(DiscoverScriptExtensionsTransformAction::class.java) { transformSpec ->
transformSpec.from.attribute(artifactType, "classes") transformSpec.from.setAttribute(artifactType, "classes")
transformSpec.to.attribute(artifactType, scriptFilesExtensions) transformSpec.to.setAttribute(artifactType, scriptFilesExtensions)
transformSpec.configureCommonParameters() transformSpec.configureCommonParameters()
} }
} }
@@ -17,6 +17,7 @@ import org.jetbrains.kotlin.gradle.plugin.mpp.isSourcesPublishableFuture
import org.jetbrains.kotlin.gradle.targets.js.ir.KotlinJsIrTarget import org.jetbrains.kotlin.gradle.targets.js.ir.KotlinJsIrTarget
import org.jetbrains.kotlin.gradle.utils.maybeCreateConsumable import org.jetbrains.kotlin.gradle.utils.maybeCreateConsumable
import org.jetbrains.kotlin.gradle.utils.maybeCreateDependencyScope import org.jetbrains.kotlin.gradle.utils.maybeCreateDependencyScope
import org.jetbrains.kotlin.gradle.utils.setAttribute
internal val CreateTargetConfigurationsSideEffect = KotlinTargetSideEffect { target -> internal val CreateTargetConfigurationsSideEffect = KotlinTargetSideEffect { target ->
val project = target.project val project = target.project
@@ -36,8 +37,8 @@ internal val CreateTargetConfigurationsSideEffect = KotlinTargetSideEffect { tar
configurations.maybeCreateConsumable(target.apiElementsConfigurationName).apply { configurations.maybeCreateConsumable(target.apiElementsConfigurationName).apply {
description = "API elements for main." description = "API elements for main."
isVisible = false isVisible = false
attributes.attribute(Usage.USAGE_ATTRIBUTE, KotlinUsages.producerApiUsage(target)) attributes.setAttribute(Usage.USAGE_ATTRIBUTE, KotlinUsages.producerApiUsage(target))
attributes.attribute(Category.CATEGORY_ATTRIBUTE, project.categoryByName(Category.LIBRARY)) attributes.setAttribute(Category.CATEGORY_ATTRIBUTE, project.categoryByName(Category.LIBRARY))
extendsFrom(configurations.maybeCreateDependencyScope(mainCompilation.apiConfigurationName)) extendsFrom(configurations.maybeCreateDependencyScope(mainCompilation.apiConfigurationName))
if (mainCompilation is KotlinCompilationToRunnableFiles) { if (mainCompilation is KotlinCompilationToRunnableFiles) {
val runtimeConfiguration = mainCompilation.internal.configurations.deprecatedRuntimeConfiguration val runtimeConfiguration = mainCompilation.internal.configurations.deprecatedRuntimeConfiguration
@@ -50,8 +51,8 @@ internal val CreateTargetConfigurationsSideEffect = KotlinTargetSideEffect { tar
configurations.maybeCreateConsumable(target.runtimeElementsConfigurationName).apply { configurations.maybeCreateConsumable(target.runtimeElementsConfigurationName).apply {
description = "Elements of runtime for main." description = "Elements of runtime for main."
isVisible = false isVisible = false
attributes.attribute(Usage.USAGE_ATTRIBUTE, KotlinUsages.producerRuntimeUsage(target)) attributes.setAttribute(Usage.USAGE_ATTRIBUTE, KotlinUsages.producerRuntimeUsage(target))
attributes.attribute(Category.CATEGORY_ATTRIBUTE, project.categoryByName(Category.LIBRARY)) attributes.setAttribute(Category.CATEGORY_ATTRIBUTE, project.categoryByName(Category.LIBRARY))
val runtimeConfiguration = mainCompilation.internal.configurations.deprecatedRuntimeConfiguration val runtimeConfiguration = mainCompilation.internal.configurations.deprecatedRuntimeConfiguration
extendsFrom(implementationConfiguration) extendsFrom(implementationConfiguration)
if (runtimeOnlyConfiguration != null) if (runtimeOnlyConfiguration != null)
@@ -94,8 +95,8 @@ internal val CreateTargetConfigurationsSideEffect = KotlinTargetSideEffect { tar
).apply { ).apply {
description = "Common Fake API elements for main." description = "Common Fake API elements for main."
isVisible = false isVisible = false
attributes.attribute<Usage>(Usage.USAGE_ATTRIBUTE, KotlinUsages.producerApiUsage(target)) attributes.setAttribute(Usage.USAGE_ATTRIBUTE, KotlinUsages.producerApiUsage(target))
attributes.attribute(KotlinPlatformType.attribute, KotlinPlatformType.common) attributes.setAttribute(KotlinPlatformType.attribute, KotlinPlatformType.common)
} }
} }
} }
@@ -335,7 +335,10 @@ internal class AndroidProjectHandler(
val buildTypeAttrValue = project.objects.named<BuildTypeAttr>(variant.buildType.name) val buildTypeAttrValue = project.objects.named<BuildTypeAttr>(variant.buildType.name)
listOf(compilation.compileDependencyConfigurationName, compilation.runtimeDependencyConfigurationName).forEach { listOf(compilation.compileDependencyConfigurationName, compilation.runtimeDependencyConfigurationName).forEach {
project.configurations.findByName(it)?.attributes?.attribute(Attribute.of(BuildTypeAttr::class.java), buildTypeAttrValue) project.configurations.findByName(it)?.attributes?.setAttribute(
Attribute.of(BuildTypeAttr::class.java),
buildTypeAttrValue
)
} }
// TODO this code depends on the convention that is present in the Android plugin as there's no public API // TODO this code depends on the convention that is present in the Android plugin as there's no public API
@@ -355,7 +358,7 @@ internal class AndroidProjectHandler(
listOf(apiElementsConfigurationName, runtimeElementsConfigurationName).forEach { outputConfigurationName -> listOf(apiElementsConfigurationName, runtimeElementsConfigurationName).forEach { outputConfigurationName ->
project.configurations.findByName(outputConfigurationName)?.let { configuration -> project.configurations.findByName(outputConfigurationName)?.let { configuration ->
configuration.usesPlatformOf(compilation.target) configuration.usesPlatformOf(compilation.target)
configuration.attributes.attribute(Category.CATEGORY_ATTRIBUTE, project.categoryByName(Category.LIBRARY)) configuration.attributes.setAttribute(Category.CATEGORY_ATTRIBUTE, project.categoryByName(Category.LIBRARY))
} }
} }
} }
@@ -15,6 +15,7 @@ import org.jetbrains.kotlin.gradle.dsl.HasConfigurableCompilerOptions
import org.jetbrains.kotlin.gradle.dsl.KotlinJvmCompilerOptions import org.jetbrains.kotlin.gradle.dsl.KotlinJvmCompilerOptions
import org.jetbrains.kotlin.gradle.dsl.KotlinJvmCompilerOptionsDefault import org.jetbrains.kotlin.gradle.dsl.KotlinJvmCompilerOptionsDefault
import org.jetbrains.kotlin.gradle.plugin.* import org.jetbrains.kotlin.gradle.plugin.*
import org.jetbrains.kotlin.gradle.plugin.internal.attributesConfigurationHelper
import org.jetbrains.kotlin.gradle.tasks.DefaultKotlinJavaToolchain import org.jetbrains.kotlin.gradle.tasks.DefaultKotlinJavaToolchain
import org.jetbrains.kotlin.gradle.utils.* import org.jetbrains.kotlin.gradle.utils.*
import org.jetbrains.kotlin.gradle.utils.dashSeparatedName import org.jetbrains.kotlin.gradle.utils.dashSeparatedName
@@ -299,7 +300,7 @@ abstract class KotlinAndroidTarget @Inject constructor(
description = "Source files of Android ${variantName}." description = "Source files of Android ${variantName}."
isVisible = false isVisible = false
copyAttributes(apiElementsConfiguration.attributes, attributes) apiElementsConfiguration.copyAttributesTo(project, dest = this)
configureSourcesPublicationAttributes(this@KotlinAndroidTarget) configureSourcesPublicationAttributes(this@KotlinAndroidTarget)
} }
} }
@@ -135,9 +135,9 @@ class KotlinCompilationNpmResolver(
val all = project.configurations.createResolvable(compilation.npmAggregatedConfigurationName) val all = project.configurations.createResolvable(compilation.npmAggregatedConfigurationName)
all.usesPlatformOf(target) all.usesPlatformOf(target)
all.attributes.attribute(Usage.USAGE_ATTRIBUTE, KotlinUsages.consumerRuntimeUsage(target)) all.attributes.setAttribute(Usage.USAGE_ATTRIBUTE, KotlinUsages.consumerRuntimeUsage(target))
all.attributes.attribute(Category.CATEGORY_ATTRIBUTE, project.categoryByName(Category.LIBRARY)) all.attributes.setAttribute(Category.CATEGORY_ATTRIBUTE, project.categoryByName(Category.LIBRARY))
all.attributes.attribute(publicPackageJsonAttribute, PUBLIC_PACKAGE_JSON_ATTR_VALUE) all.attributes.setAttribute(publicPackageJsonAttribute, PUBLIC_PACKAGE_JSON_ATTR_VALUE)
all.isVisible = false all.isVisible = false
all.description = "NPM configuration for $compilation." all.description = "NPM configuration for $compilation."
@@ -163,9 +163,9 @@ class KotlinCompilationNpmResolver(
val all = project.configurations.createConsumable(compilation.publicPackageJsonConfigurationName) val all = project.configurations.createConsumable(compilation.publicPackageJsonConfigurationName)
all.usesPlatformOf(target) all.usesPlatformOf(target)
all.attributes.attribute(Usage.USAGE_ATTRIBUTE, KotlinUsages.consumerRuntimeUsage(target)) all.attributes.setAttribute(Usage.USAGE_ATTRIBUTE, KotlinUsages.consumerRuntimeUsage(target))
all.attributes.attribute(Category.CATEGORY_ATTRIBUTE, project.categoryByName(Category.LIBRARY)) all.attributes.setAttribute(Category.CATEGORY_ATTRIBUTE, project.categoryByName(Category.LIBRARY))
all.attributes.attribute(publicPackageJsonAttribute, PUBLIC_PACKAGE_JSON_ATTR_VALUE) all.attributes.setAttribute(publicPackageJsonAttribute, PUBLIC_PACKAGE_JSON_ATTR_VALUE)
all.isVisible = false all.isVisible = false
return all return all
@@ -324,7 +324,7 @@ abstract class KotlinJvmTarget @Inject constructor(
).mapNotNull { ).mapNotNull {
project.configurations.findByName(it) project.configurations.findByName(it)
}.forEach { configuration -> }.forEach { configuration ->
copyAttributes(attributes, configuration.attributes) copyAttributesTo(project, dest = configuration)
} }
} }
@@ -14,6 +14,7 @@ import org.jetbrains.kotlin.gradle.plugin.mpp.KotlinUsages
import org.jetbrains.kotlin.gradle.plugin.usesPlatformOf import org.jetbrains.kotlin.gradle.plugin.usesPlatformOf
import org.jetbrains.kotlin.gradle.targets.KotlinTargetSideEffect import org.jetbrains.kotlin.gradle.targets.KotlinTargetSideEffect
import org.jetbrains.kotlin.gradle.utils.maybeCreateResolvable import org.jetbrains.kotlin.gradle.utils.maybeCreateResolvable
import org.jetbrains.kotlin.gradle.utils.setAttribute
internal val ConfigureFrameworkExportSideEffect = KotlinTargetSideEffect<KotlinNativeTarget> { target -> internal val ConfigureFrameworkExportSideEffect = KotlinTargetSideEffect<KotlinNativeTarget> { target ->
val project = target.project val project = target.project
@@ -23,9 +24,9 @@ internal val ConfigureFrameworkExportSideEffect = KotlinTargetSideEffect<KotlinN
isVisible = false isVisible = false
isTransitive = false isTransitive = false
usesPlatformOf(target) usesPlatformOf(target)
attributes.attribute(Usage.USAGE_ATTRIBUTE, KotlinUsages.consumerApiUsage(target)) attributes.setAttribute(Usage.USAGE_ATTRIBUTE, KotlinUsages.consumerApiUsage(target))
attributes.attribute(Category.CATEGORY_ATTRIBUTE, project.categoryByName(Category.LIBRARY)) attributes.setAttribute(Category.CATEGORY_ATTRIBUTE, project.categoryByName(Category.LIBRARY))
description = "Dependenceis to be exported in framework ${framework.name} for target ${target.targetName}" description = "Dependencies to be exported in framework ${framework.name} for target ${target.targetName}"
} }
} }
} }
@@ -24,6 +24,7 @@ import org.jetbrains.kotlin.gradle.targets.native.KotlinNativeSimulatorTestRunFa
import org.jetbrains.kotlin.gradle.utils.dashSeparatedName import org.jetbrains.kotlin.gradle.utils.dashSeparatedName
import org.jetbrains.kotlin.gradle.utils.klibModuleName import org.jetbrains.kotlin.gradle.utils.klibModuleName
import org.jetbrains.kotlin.gradle.utils.newInstance import org.jetbrains.kotlin.gradle.utils.newInstance
import org.jetbrains.kotlin.gradle.utils.setAttribute
import org.jetbrains.kotlin.konan.target.HostManager import org.jetbrains.kotlin.konan.target.HostManager
import org.jetbrains.kotlin.konan.target.KonanTarget import org.jetbrains.kotlin.konan.target.KonanTarget
import org.jetbrains.kotlin.util.capitalizeDecapitalize.toLowerCaseAsciiOnly import org.jetbrains.kotlin.util.capitalizeDecapitalize.toLowerCaseAsciiOnly
@@ -40,7 +41,7 @@ abstract class KotlinNativeTarget @Inject constructor(
) { ) {
init { init {
attributes.attribute(konanTargetAttribute, konanTarget.name) attributes.setAttribute(konanTargetAttribute, konanTarget.name)
} }
private val hostSpecificMetadataJarTaskName get() = disambiguateName("MetadataJar") private val hostSpecificMetadataJarTaskName get() = disambiguateName("MetadataJar")
@@ -19,6 +19,7 @@ import org.gradle.api.tasks.AbstractExecTask
import org.gradle.api.tasks.TaskProvider import org.gradle.api.tasks.TaskProvider
import org.jetbrains.kotlin.gradle.ExperimentalKotlinGradlePluginApi import org.jetbrains.kotlin.gradle.ExperimentalKotlinGradlePluginApi
import org.jetbrains.kotlin.gradle.tasks.KotlinNativeLink import org.jetbrains.kotlin.gradle.tasks.KotlinNativeLink
import org.jetbrains.kotlin.gradle.utils.attributeOf
import org.jetbrains.kotlin.gradle.utils.lowerCamelCaseName import org.jetbrains.kotlin.gradle.utils.lowerCamelCaseName
import org.jetbrains.kotlin.gradle.utils.maybeCreateResolvable import org.jetbrains.kotlin.gradle.utils.maybeCreateResolvable
import org.jetbrains.kotlin.konan.target.KonanTarget import org.jetbrains.kotlin.konan.target.KonanTarget
@@ -321,9 +322,8 @@ class Framework(
} }
companion object { companion object {
val frameworkTargets: Attribute<Set<*>> = Attribute.of( val frameworkTargets: Attribute<Set<String>> = attributeOf<Set<String>>(
"org.jetbrains.kotlin.native.framework.targets", "org.jetbrains.kotlin.native.framework.targets"
Set::class.java
) )
} }
} }
@@ -45,7 +45,7 @@ internal fun Project.createFrameworkArtifact(binaryFramework: Framework, linkTas
?: configurations.createConsumable(binaryFramework.binaryFrameworkConfigurationName).also { ?: configurations.createConsumable(binaryFramework.binaryFrameworkConfigurationName).also {
it.applyBinaryFrameworkGroupAttributes(project, binaryFramework.frameworkGroupDescription, listOf(binaryFramework.target)) it.applyBinaryFrameworkGroupAttributes(project, binaryFramework.frameworkGroupDescription, listOf(binaryFramework.target))
project.launchInStage(KotlinPluginLifecycle.Stage.FinaliseDsl) { project.launchInStage(KotlinPluginLifecycle.Stage.FinaliseDsl) {
copyAttributes(binaryFramework.attributes, it.attributes) binaryFramework.copyAttributesTo(project, dest = it)
} }
} }
@@ -78,11 +78,13 @@ private fun Configuration.applyBinaryFrameworkGroupAttributes(
targets: List<KotlinNativeTarget>, targets: List<KotlinNativeTarget>,
) { ) {
with(attributes) { with(attributes) {
attribute(KotlinPlatformType.attribute, KotlinPlatformType.native) setAttribute(KotlinPlatformType.attribute, KotlinPlatformType.native)
attribute(project.artifactTypeAttribute, KotlinNativeTargetConfigurator.NativeArtifactFormat.FRAMEWORK) setAttribute(project.artifactTypeAttribute, KotlinNativeTargetConfigurator.NativeArtifactFormat.FRAMEWORK)
attribute(KotlinNativeTarget.kotlinNativeBuildTypeAttribute, frameworkDescription.buildType.name) setAttribute(KotlinNativeTarget.kotlinNativeBuildTypeAttribute, frameworkDescription.buildType.name)
attribute(KotlinNativeTarget.kotlinNativeFrameworkNameAttribute, frameworkDescription.frameworkName) setAttribute(KotlinNativeTarget.kotlinNativeFrameworkNameAttribute, frameworkDescription.frameworkName)
attribute(Framework.frameworkTargets, targets.map { it.konanTarget.name }.toSet()) setAttributeProvider(project, Framework.frameworkTargets) {
targets.map { it.konanTarget.name }.toSet()
}
} }
} }
@@ -18,6 +18,7 @@ import org.gradle.api.tasks.PathSensitivity
import org.gradle.work.DisableCachingByDefault import org.gradle.work.DisableCachingByDefault
import org.jetbrains.kotlin.gradle.targets.native.internal.CInteropCommonizerArtifactTypeAttribute.KLIB import org.jetbrains.kotlin.gradle.targets.native.internal.CInteropCommonizerArtifactTypeAttribute.KLIB
import org.jetbrains.kotlin.gradle.targets.native.internal.CInteropCommonizerArtifactTypeAttribute.KLIB_COLLECTION_DIR import org.jetbrains.kotlin.gradle.targets.native.internal.CInteropCommonizerArtifactTypeAttribute.KLIB_COLLECTION_DIR
import org.jetbrains.kotlin.gradle.utils.setAttribute
/** /**
* Commonized CInterop artifacts can come in two shapes: * Commonized CInterop artifacts can come in two shapes:
@@ -52,16 +53,16 @@ internal object CInteropCommonizerArtifactTypeAttribute {
*/ */
fun setupTransform(project: Project) { fun setupTransform(project: Project) {
project.dependencies.artifactTypes.maybeCreate(KLIB_COLLECTION_DIR).also { artifactType -> project.dependencies.artifactTypes.maybeCreate(KLIB_COLLECTION_DIR).also { artifactType ->
artifactType.attributes.attribute(attribute, KLIB_COLLECTION_DIR) artifactType.attributes.setAttribute(attribute, KLIB_COLLECTION_DIR)
} }
project.dependencies.artifactTypes.maybeCreate(KLIB).also { artifactType -> project.dependencies.artifactTypes.maybeCreate(KLIB).also { artifactType ->
artifactType.attributes.attribute(attribute, KLIB) artifactType.attributes.setAttribute(attribute, KLIB)
} }
project.dependencies.registerTransform(KlibCollectionDirTransform::class.java) { transform -> project.dependencies.registerTransform(KlibCollectionDirTransform::class.java) { transform ->
transform.from.attribute(attribute, KLIB_COLLECTION_DIR) transform.from.setAttribute(attribute, KLIB_COLLECTION_DIR)
transform.to.attribute(attribute, KLIB) transform.to.setAttribute(attribute, KLIB)
} }
} }
@@ -21,8 +21,10 @@ import org.jetbrains.kotlin.gradle.plugin.mpp.resolvableMetadataConfiguration
import org.jetbrains.kotlin.gradle.plugin.sources.internal import org.jetbrains.kotlin.gradle.plugin.sources.internal
import org.jetbrains.kotlin.gradle.targets.metadata.awaitMetadataCompilationsCreated import org.jetbrains.kotlin.gradle.targets.metadata.awaitMetadataCompilationsCreated
import org.jetbrains.kotlin.gradle.targets.metadata.findMetadataCompilation import org.jetbrains.kotlin.gradle.targets.metadata.findMetadataCompilation
import org.jetbrains.kotlin.gradle.utils.*
import org.jetbrains.kotlin.gradle.utils.createConsumable import org.jetbrains.kotlin.gradle.utils.createConsumable
import org.jetbrains.kotlin.gradle.utils.createResolvable import org.jetbrains.kotlin.gradle.utils.createResolvable
import org.jetbrains.kotlin.gradle.utils.setAttribute
import org.jetbrains.kotlin.tooling.core.UnsafeApi import org.jetbrains.kotlin.tooling.core.UnsafeApi
/* Elements configuration */ /* Elements configuration */
@@ -113,7 +115,10 @@ internal suspend fun Project.locateOrCreateCommonizedCInteropDependencyConfigura
* If artifacts are added using [CInteropCommonizerArtifactTypeAttribute.KLIB_COLLECTION_DIR] then a transformation * If artifacts are added using [CInteropCommonizerArtifactTypeAttribute.KLIB_COLLECTION_DIR] then a transformation
* has to happen that will resolve the exact list of klibs. * has to happen that will resolve the exact list of klibs.
*/ */
configuration.attributes.attribute(CInteropCommonizerArtifactTypeAttribute.attribute, CInteropCommonizerArtifactTypeAttribute.KLIB) configuration.attributes.setAttribute(
CInteropCommonizerArtifactTypeAttribute.attribute,
CInteropCommonizerArtifactTypeAttribute.KLIB
)
description = "Commonized CInterop dependencies for $sourceSet with targets: '$commonizerTarget'." description = "Commonized CInterop dependencies for $sourceSet with targets: '$commonizerTarget'."
} }
@@ -124,7 +129,7 @@ private fun Project.setupBasicCommonizedCInteropConfigurationAttributes(
configuration: Configuration, configuration: Configuration,
commonizerTarget: SharedCommonizerTarget, commonizerTarget: SharedCommonizerTarget,
) { ) {
configuration.attributes.attribute(CommonizerTargetAttribute.attribute, commonizerTarget.identityString) configuration.attributes.setAttribute(CommonizerTargetAttribute.attribute, commonizerTarget.identityString)
configuration.attributes.attribute(Usage.USAGE_ATTRIBUTE, objects.named(Usage::class.java, KotlinUsages.KOTLIN_COMMONIZED_CINTEROP)) configuration.attributes.setAttribute(Usage.USAGE_ATTRIBUTE, objects.named(KotlinUsages.KOTLIN_COMMONIZED_CINTEROP))
configuration.attributes.attribute(Category.CATEGORY_ATTRIBUTE, project.categoryByName(Category.LIBRARY)) configuration.attributes.setAttribute(Category.CATEGORY_ATTRIBUTE, project.categoryByName(Category.LIBRARY))
} }
@@ -22,7 +22,6 @@ import org.jetbrains.kotlin.gradle.targets.KotlinTargetSideEffect
import org.jetbrains.kotlin.gradle.targets.native.internal.CInteropKlibLibraryElements.cinteropKlibLibraryElements import org.jetbrains.kotlin.gradle.targets.native.internal.CInteropKlibLibraryElements.cinteropKlibLibraryElements
import org.jetbrains.kotlin.gradle.tasks.CInteropProcess import org.jetbrains.kotlin.gradle.tasks.CInteropProcess
import org.jetbrains.kotlin.gradle.utils.* import org.jetbrains.kotlin.gradle.utils.*
import org.jetbrains.kotlin.gradle.utils.copyAttributes
import org.jetbrains.kotlin.gradle.utils.createConsumable import org.jetbrains.kotlin.gradle.utils.createConsumable
import org.jetbrains.kotlin.gradle.utils.findConsumable import org.jetbrains.kotlin.gradle.utils.findConsumable
@@ -57,10 +56,10 @@ internal fun Project.locateOrCreateCInteropDependencyConfiguration(
/* Deferring attributes to wait for compilation.attributes to be configured by user*/ /* Deferring attributes to wait for compilation.attributes to be configured by user*/
launchInStage(AfterFinaliseDsl) { launchInStage(AfterFinaliseDsl) {
usesPlatformOf(compilation.target) usesPlatformOf(compilation.target)
copyAttributes(compilation.attributes, attributes) compilation.copyAttributesTo(project, dest = attributes)
attributes.attribute(LibraryElements.LIBRARY_ELEMENTS_ATTRIBUTE, cinteropKlibLibraryElements()) attributes.setAttribute(LibraryElements.LIBRARY_ELEMENTS_ATTRIBUTE, cinteropKlibLibraryElements())
attributes.attribute(Usage.USAGE_ATTRIBUTE, objects.named(Usage::class.java, KotlinUsages.KOTLIN_CINTEROP)) attributes.setAttribute(Usage.USAGE_ATTRIBUTE, objects.named(KotlinUsages.KOTLIN_CINTEROP))
attributes.attribute(Category.CATEGORY_ATTRIBUTE, project.categoryByName(Category.LIBRARY)) attributes.setAttribute(Category.CATEGORY_ATTRIBUTE, project.categoryByName(Category.LIBRARY))
description = "CInterop dependencies for compilation '${compilation.name}')." description = "CInterop dependencies for compilation '${compilation.name}')."
} }
} }
@@ -81,11 +80,11 @@ internal fun Project.locateOrCreateCInteropApiElementsConfiguration(target: Kotl
/* Deferring attributes to wait for target.attributes to be configured by user */ /* Deferring attributes to wait for target.attributes to be configured by user */
launchInStage(AfterFinaliseDsl) { launchInStage(AfterFinaliseDsl) {
usesPlatformOf(target) usesPlatformOf(target)
copyAttributes(target.attributes, attributes) target.copyAttributesTo(project, dest = attributes)
attributes.attribute(LibraryElements.LIBRARY_ELEMENTS_ATTRIBUTE, cinteropKlibLibraryElements()) attributes.setAttribute(LibraryElements.LIBRARY_ELEMENTS_ATTRIBUTE, cinteropKlibLibraryElements())
attributes.attribute(Usage.USAGE_ATTRIBUTE, objects.named(Usage::class.java, KotlinUsages.KOTLIN_CINTEROP)) attributes.setAttribute(Usage.USAGE_ATTRIBUTE, objects.named(KotlinUsages.KOTLIN_CINTEROP))
attributes.attribute(Category.CATEGORY_ATTRIBUTE, project.categoryByName(Category.LIBRARY)) attributes.setAttribute(Category.CATEGORY_ATTRIBUTE, project.categoryByName(Category.LIBRARY))
attributes.attribute(artifactTypeAttribute, NativeArtifactFormat.KLIB) attributes.setAttribute(artifactTypeAttribute, NativeArtifactFormat.KLIB)
/* Expose api dependencies */ /* Expose api dependencies */
target.compilations.findByName(MAIN_COMPILATION_NAME)?.let { compilation -> target.compilations.findByName(MAIN_COMPILATION_NAME)?.let { compilation ->
@@ -194,8 +194,8 @@ constructor(
val apiConfiguration = project.configurations.getByName(compilation.apiConfigurationName) val apiConfiguration = project.configurations.getByName(compilation.apiConfigurationName)
dependencies.addAll(apiConfiguration.allDependencies) dependencies.addAll(apiConfiguration.allDependencies)
usesPlatformOf(compilation.target) usesPlatformOf(compilation.target)
attributes.attribute(Usage.USAGE_ATTRIBUTE, KotlinUsages.consumerApiUsage(compilation.target)) attributes.setAttribute(Usage.USAGE_ATTRIBUTE, KotlinUsages.consumerApiUsage(compilation.target))
attributes.attribute(Category.CATEGORY_ATTRIBUTE, project.categoryByName(Category.LIBRARY)) attributes.setAttribute(Category.CATEGORY_ATTRIBUTE, project.categoryByName(Category.LIBRARY))
}.filterKlibsPassedToCompiler() }.filterKlibsPassedToCompiler()
@get:Optional @get:Optional
@@ -15,6 +15,8 @@ import org.jetbrains.kotlin.gradle.plugin.mpp.KotlinUsages
import org.jetbrains.kotlin.gradle.plugin.mpp.NativeBuildType import org.jetbrains.kotlin.gradle.plugin.mpp.NativeBuildType
import org.jetbrains.kotlin.gradle.utils.lowerCamelCaseName import org.jetbrains.kotlin.gradle.utils.lowerCamelCaseName
import org.jetbrains.kotlin.gradle.utils.maybeCreateResolvable import org.jetbrains.kotlin.gradle.utils.maybeCreateResolvable
import org.jetbrains.kotlin.gradle.utils.named
import org.jetbrains.kotlin.gradle.utils.setAttribute
import org.jetbrains.kotlin.konan.target.KonanTarget import org.jetbrains.kotlin.konan.target.KonanTarget
import org.jetbrains.kotlin.konan.target.presetName import org.jetbrains.kotlin.konan.target.presetName
@@ -76,9 +78,9 @@ internal fun Project.registerLibsDependencies(target: KonanTarget, artifactName:
configurations.maybeCreateResolvable(librariesConfigurationName).apply { configurations.maybeCreateResolvable(librariesConfigurationName).apply {
isVisible = false isVisible = false
isTransitive = true isTransitive = true
attributes.attribute(KotlinPlatformType.attribute, KotlinPlatformType.native) attributes.setAttribute(KotlinPlatformType.attribute, KotlinPlatformType.native)
attributes.attribute(KotlinNativeTarget.konanTargetAttribute, target.name) attributes.setAttribute(KotlinNativeTarget.konanTargetAttribute, target.name)
attributes.attribute(Usage.USAGE_ATTRIBUTE, project.objects.named(Usage::class.java, KotlinUsages.KOTLIN_API)) attributes.setAttribute(Usage.USAGE_ATTRIBUTE, project.objects.named(KotlinUsages.KOTLIN_API))
} }
deps.forEach { dependencies.add(librariesConfigurationName, it) } deps.forEach { dependencies.add(librariesConfigurationName, it) }
return librariesConfigurationName return librariesConfigurationName
@@ -89,9 +91,9 @@ internal fun Project.registerExportDependencies(target: KonanTarget, artifactNam
configurations.maybeCreateResolvable(exportConfigurationName).apply { configurations.maybeCreateResolvable(exportConfigurationName).apply {
isVisible = false isVisible = false
isTransitive = false isTransitive = false
attributes.attribute(KotlinPlatformType.attribute, KotlinPlatformType.native) attributes.setAttribute(KotlinPlatformType.attribute, KotlinPlatformType.native)
attributes.attribute(KotlinNativeTarget.konanTargetAttribute, target.name) attributes.setAttribute(KotlinNativeTarget.konanTargetAttribute, target.name)
attributes.attribute(Usage.USAGE_ATTRIBUTE, project.objects.named(Usage::class.java, KotlinUsages.KOTLIN_API)) attributes.setAttribute(Usage.USAGE_ATTRIBUTE, project.objects.named(KotlinUsages.KOTLIN_API))
} }
deps.forEach { dependencies.add(exportConfigurationName, it) } deps.forEach { dependencies.add(exportConfigurationName, it) }
return exportConfigurationName return exportConfigurationName
@@ -26,7 +26,6 @@ import org.jetbrains.kotlin.gradle.internal.kapt.incremental.StructureTransformL
import org.jetbrains.kotlin.gradle.plugin.* import org.jetbrains.kotlin.gradle.plugin.*
import org.jetbrains.kotlin.gradle.tasks.toCompilerPluginOptions import org.jetbrains.kotlin.gradle.tasks.toCompilerPluginOptions
import org.jetbrains.kotlin.gradle.utils.* import org.jetbrains.kotlin.gradle.utils.*
import org.jetbrains.kotlin.gradle.utils.createDependencyScope
import org.jetbrains.kotlin.gradle.utils.detachedResolvable import org.jetbrains.kotlin.gradle.utils.detachedResolvable
import org.jetbrains.kotlin.gradle.utils.listProperty import org.jetbrains.kotlin.gradle.utils.listProperty
import java.io.File import java.io.File
@@ -101,7 +100,7 @@ internal open class KaptConfig<TASK : KaptTask>(
// the attributes that are potentially needed to resolve dependencies on MPP modules, and the classpath configuration does. // the attributes that are potentially needed to resolve dependencies on MPP modules, and the classpath configuration does.
classStructureConfiguration.dependencies.add(project.dependencies.create(project.files(project.provider { taskProvider.get().classpath }))) classStructureConfiguration.dependencies.add(project.dependencies.create(project.files(project.provider { taskProvider.get().classpath })))
classStructureConfiguration.incoming.artifactView { viewConfig -> classStructureConfiguration.incoming.artifactView { viewConfig ->
viewConfig.attributes.attribute(artifactType, CLASS_STRUCTURE_ARTIFACT_TYPE) viewConfig.attributes.setAttribute(artifactType, CLASS_STRUCTURE_ARTIFACT_TYPE)
}.files }.files
} else null } else null
} }
@@ -114,13 +113,13 @@ internal open class KaptConfig<TASK : KaptTask>(
else else
StructureTransformLegacyAction::class.java StructureTransformLegacyAction::class.java
project.dependencies.registerTransform(transformActionClass) { transformSpec -> project.dependencies.registerTransform(transformActionClass) { transformSpec ->
transformSpec.from.attribute(artifactType, "jar") transformSpec.from.setAttribute(artifactType, "jar")
transformSpec.to.attribute(artifactType, CLASS_STRUCTURE_ARTIFACT_TYPE) transformSpec.to.setAttribute(artifactType, CLASS_STRUCTURE_ARTIFACT_TYPE)
} }
project.dependencies.registerTransform(transformActionClass) { transformSpec -> project.dependencies.registerTransform(transformActionClass) { transformSpec ->
transformSpec.from.attribute(artifactType, "directory") transformSpec.from.setAttribute(artifactType, "directory")
transformSpec.to.attribute(artifactType, CLASS_STRUCTURE_ARTIFACT_TYPE) transformSpec.to.setAttribute(artifactType, CLASS_STRUCTURE_ARTIFACT_TYPE)
} }
project.extensions.extraProperties["KaptStructureTransformAdded"] = true project.extensions.extraProperties["KaptStructureTransformAdded"] = true
@@ -32,6 +32,7 @@ import org.jetbrains.kotlin.gradle.tasks.DefaultKotlinJavaToolchain
import org.jetbrains.kotlin.gradle.tasks.KotlinCompile import org.jetbrains.kotlin.gradle.tasks.KotlinCompile
import org.jetbrains.kotlin.gradle.utils.detachedResolvable import org.jetbrains.kotlin.gradle.utils.detachedResolvable
import org.jetbrains.kotlin.gradle.utils.providerWithLazyConvention import org.jetbrains.kotlin.gradle.utils.providerWithLazyConvention
import org.jetbrains.kotlin.gradle.utils.setAttribute
internal typealias KotlinCompileConfig = BaseKotlinCompileConfig<KotlinCompile> internal typealias KotlinCompileConfig = BaseKotlinCompileConfig<KotlinCompile>
@@ -71,7 +72,7 @@ internal open class BaseKotlinCompileConfig<TASK : KotlinCompile> : AbstractKotl
task.classpathSnapshotProperties.useClasspathSnapshot.value(useClasspathSnapshot).disallowChanges() task.classpathSnapshotProperties.useClasspathSnapshot.value(useClasspathSnapshot).disallowChanges()
if (useClasspathSnapshot) { if (useClasspathSnapshot) {
val classpathEntrySnapshotFiles = classpathConfiguration!!.incoming.artifactView { val classpathEntrySnapshotFiles = classpathConfiguration!!.incoming.artifactView {
it.attributes.attribute(ARTIFACT_TYPE_ATTRIBUTE, CLASSPATH_ENTRY_SNAPSHOT_ARTIFACT_TYPE) it.attributes.setAttribute(ARTIFACT_TYPE_ATTRIBUTE, CLASSPATH_ENTRY_SNAPSHOT_ARTIFACT_TYPE)
}.files }.files
task.classpathSnapshotProperties.classpathSnapshot.from(classpathEntrySnapshotFiles).disallowChanges() task.classpathSnapshotProperties.classpathSnapshot.from(classpathEntrySnapshotFiles).disallowChanges()
task.classpathSnapshotProperties.classpathSnapshotDir.value(getClasspathSnapshotDir(task)).disallowChanges() task.classpathSnapshotProperties.classpathSnapshotDir.value(getClasspathSnapshotDir(task)).disallowChanges()
@@ -185,14 +186,14 @@ internal open class BaseKotlinCompileConfig<TASK : KotlinCompile> : AbstractKotl
val kgpVersion = project.getKotlinPluginVersion() val kgpVersion = project.getKotlinPluginVersion()
val suppressVersionInconsistencyChecks = project.kotlinPropertiesProvider.suppressBuildToolsApiVersionConsistencyChecks val suppressVersionInconsistencyChecks = project.kotlinPropertiesProvider.suppressBuildToolsApiVersionConsistencyChecks
project.dependencies.registerTransform(BuildToolsApiClasspathEntrySnapshotTransform::class.java) { project.dependencies.registerTransform(BuildToolsApiClasspathEntrySnapshotTransform::class.java) {
it.from.attribute(ARTIFACT_TYPE_ATTRIBUTE, JAR_ARTIFACT_TYPE) it.from.setAttribute(ARTIFACT_TYPE_ATTRIBUTE, JAR_ARTIFACT_TYPE)
it.to.attribute(ARTIFACT_TYPE_ATTRIBUTE, CLASSPATH_ENTRY_SNAPSHOT_ARTIFACT_TYPE) it.to.setAttribute(ARTIFACT_TYPE_ATTRIBUTE, CLASSPATH_ENTRY_SNAPSHOT_ARTIFACT_TYPE)
it.configureCommonParameters(kgpVersion, classLoadersCachingService, classpath, jvmToolchain, runKotlinCompilerViaBuildToolsApi, suppressVersionInconsistencyChecks) it.configureCommonParameters(kgpVersion, classLoadersCachingService, classpath, jvmToolchain, runKotlinCompilerViaBuildToolsApi, suppressVersionInconsistencyChecks)
it.setupTransformActionToolingDiagnostics(project) it.setupTransformActionToolingDiagnostics(project)
} }
project.dependencies.registerTransform(BuildToolsApiClasspathEntrySnapshotTransform::class.java) { project.dependencies.registerTransform(BuildToolsApiClasspathEntrySnapshotTransform::class.java) {
it.from.attribute(ARTIFACT_TYPE_ATTRIBUTE, DIRECTORY_ARTIFACT_TYPE) it.from.setAttribute(ARTIFACT_TYPE_ATTRIBUTE, DIRECTORY_ARTIFACT_TYPE)
it.to.attribute(ARTIFACT_TYPE_ATTRIBUTE, CLASSPATH_ENTRY_SNAPSHOT_ARTIFACT_TYPE) it.to.setAttribute(ARTIFACT_TYPE_ATTRIBUTE, CLASSPATH_ENTRY_SNAPSHOT_ARTIFACT_TYPE)
it.configureCommonParameters(kgpVersion, classLoadersCachingService, classpath, jvmToolchain, runKotlinCompilerViaBuildToolsApi, suppressVersionInconsistencyChecks) it.configureCommonParameters(kgpVersion, classLoadersCachingService, classpath, jvmToolchain, runKotlinCompilerViaBuildToolsApi, suppressVersionInconsistencyChecks)
it.setupTransformActionToolingDiagnostics(project) it.setupTransformActionToolingDiagnostics(project)
} }
@@ -5,8 +5,11 @@
package org.jetbrains.kotlin.gradle.utils package org.jetbrains.kotlin.gradle.utils
import org.gradle.api.Project
import org.gradle.api.attributes.Attribute import org.gradle.api.attributes.Attribute
import org.gradle.api.attributes.AttributeContainer import org.gradle.api.attributes.AttributeContainer
import org.gradle.api.attributes.HasAttributes
import org.jetbrains.kotlin.gradle.plugin.internal.attributesConfigurationHelper
/** /**
* KGP's internal analog of [org.gradle.api.internal.attributes.AttributeContainerInternal.asMap] * KGP's internal analog of [org.gradle.api.internal.attributes.AttributeContainerInternal.asMap]
@@ -21,15 +24,47 @@ internal fun AttributeContainer.toMap(): Map<Attribute<*>, Any?> {
return result return result
} }
internal fun <T : Any> HasAttributes.setAttributeProvider(
project: Project,
key: Attribute<T>,
value: () -> T
) {
project.attributesConfigurationHelper.setAttribute(this, key, value)
}
internal fun copyAttributes(from: AttributeContainer, to: AttributeContainer, keys: Iterable<Attribute<*>> = from.keySet()) { /**
// capture type argument T * Should only be used to configure simple attributes values!
fun <T : Any> copyOneAttribute(from: AttributeContainer, to: AttributeContainer, key: Attribute<T>) { *
val value = checkNotNull(from.getAttribute(key)) * When in doubt, prefer lazy method overload.
to.attribute(key, value) */
} internal fun <T : Any> HasAttributes.setAttribute(
for (key in keys) { key: Attribute<T>,
copyOneAttribute(from, to, key) value: T
) {
attributes.attribute(key, value)
}
internal fun <T : Any> HasAttributes.copyAttributeTo(
project: Project,
dest: HasAttributes,
key: Attribute<T>,
) {
dest.setAttributeProvider(project, key) {
attributes.getAttribute(key)
?: throw IllegalStateException("Failed to copy attribute. Source container is missing $key (named ${key.name}).")
} }
} }
internal fun HasAttributes.copyAttributesTo(
project: Project,
dest: HasAttributes,
keys: Iterable<Attribute<*>> = attributes.keySet(),
) {
for (key in keys) {
copyAttributeTo(project, dest, key)
}
}
internal inline fun <reified T> attributeOf(
name: String
): Attribute<T> = Attribute.of(name, T::class.java)
@@ -34,13 +34,13 @@ internal fun Configuration.addGradlePluginMetadataAttributes(
project: Project project: Project
) { ) {
attributes { attributes {
it.attribute(Category.CATEGORY_ATTRIBUTE, project.objects.named(Category.LIBRARY)) it.setAttribute(Category.CATEGORY_ATTRIBUTE, project.objects.named(Category.LIBRARY))
it.attribute(Usage.USAGE_ATTRIBUTE, project.objects.named(Usage.JAVA_RUNTIME)) it.setAttribute(Usage.USAGE_ATTRIBUTE, project.objects.named(Usage.JAVA_RUNTIME))
it.attribute(LibraryElements.LIBRARY_ELEMENTS_ATTRIBUTE, project.objects.named(LibraryElements.JAR)) it.setAttribute(LibraryElements.LIBRARY_ELEMENTS_ATTRIBUTE, project.objects.named(LibraryElements.JAR))
if (GradleVersion.current() >= GradleVersion.version("7.0")) { if (GradleVersion.current() >= GradleVersion.version("7.0")) {
it.attribute( it.setAttribute(
GradlePluginApiVersion.GRADLE_PLUGIN_API_VERSION_ATTRIBUTE, GradlePluginApiVersion.GRADLE_PLUGIN_API_VERSION_ATTRIBUTE,
project.objects.named(GradlePluginApiVersion::class.java, GradleVersion.current().version) project.objects.named(GradleVersion.current().version)
) )
} }
} }
@@ -21,7 +21,7 @@ class BinaryFrameworksCustomAttributesTest {
val project = buildProjectWithMPP { val project = buildProjectWithMPP {
kotlin { kotlin {
iosArm64("ios") { iosArm64("ios") {
attributes.attribute(disambiguationAttribute1, "someValue") attributes.attributeProvider(disambiguationAttribute1, provider { "someValue" })
binaries { binaries {
framework("main") framework("main")
framework("custom") { framework("custom") {
@@ -29,7 +29,7 @@ class BinaryFrameworksCustomAttributesTest {
linkerOpts = mutableListOf("-L.") linkerOpts = mutableListOf("-L.")
freeCompilerArgs = mutableListOf("-Xtime") freeCompilerArgs = mutableListOf("-Xtime")
isStatic = true isStatic = true
attributes.attribute(disambiguationAttribute2, "someValue2") attributes.attributeProvider(disambiguationAttribute2, provider { "someValue2" })
} }
} }
} }
@@ -33,13 +33,13 @@ class KT56143CinteropConfigurationAttributes {
private val project = buildProjectWithMPP { private val project = buildProjectWithMPP {
kotlin { kotlin {
linuxX64("variantA") { linuxX64("variantA") {
attributes.attribute(targetAttribute, "a") attributes.attributeProvider(targetAttribute, provider { "a" })
compilations.main.attributes.attribute(compilationAttribute, "compilation:a") compilations.main.attributes.attributeProvider(compilationAttribute, provider { "compilation:a" })
} }
linuxX64("variantB") { linuxX64("variantB") {
attributes.attribute(targetAttribute, "b") attributes.attributeProvider(targetAttribute, provider { "b" })
compilations.main.attributes.attribute(compilationAttribute, "compilation:b") compilations.main.attributes.attributeProvider(compilationAttribute, provider { "compilation:b" })
} }
} }
} }
@@ -34,7 +34,10 @@ class CInteropCommonizerArtifactTypeAttributeTest {
/* Create consumable elements configuration */ /* Create consumable elements configuration */
project.configurations.createConsumable("testElements").also { configuration -> project.configurations.createConsumable("testElements").also { configuration ->
configuration.attributes.attribute(Usage.USAGE_ATTRIBUTE, project.objects.named("test")) configuration.attributes.attributeProvider(
Usage.USAGE_ATTRIBUTE,
project.provider { project.objects.named("test") }
)
/* Add klibCollectionDir as artifact */ /* Add klibCollectionDir as artifact */
configuration.outgoing.artifact(klibCollectionDir) { artifact -> configuration.outgoing.artifact(klibCollectionDir) { artifact ->
@@ -45,9 +48,13 @@ class CInteropCommonizerArtifactTypeAttributeTest {
/* Create resolvable configuration */ /* Create resolvable configuration */
val resolvable = project.configurations.createResolvable("testDependencies").also { configuration -> val resolvable = project.configurations.createResolvable("testDependencies").also { configuration ->
configuration.attributes.attribute(Usage.USAGE_ATTRIBUTE, project.objects.named("test")) configuration.attributes.attributeProvider(
configuration.attributes.attribute( Usage.USAGE_ATTRIBUTE,
CInteropCommonizerArtifactTypeAttribute.attribute, CInteropCommonizerArtifactTypeAttribute.KLIB project.provider { project.objects.named("test") }
)
configuration.attributes.attributeProvider(
CInteropCommonizerArtifactTypeAttribute.attribute,
project.provider { CInteropCommonizerArtifactTypeAttribute.KLIB }
) )
} }
@@ -180,12 +180,12 @@ class ExternalKotlinTargetApiTests {
defaults() defaults()
sourcesElements.configure { target, configuration -> sourcesElements.configure { target, configuration ->
assertEquals(target.sourcesElementsConfiguration, configuration) assertEquals(target.sourcesElementsConfiguration, configuration)
configuration.attributes.attribute(testAttribute, "sourcesElements") configuration.attributes.attributeProvider(testAttribute, provider { "sourcesElements" })
} }
sourcesElementsPublished.configure { target, configuration -> sourcesElementsPublished.configure { target, configuration ->
assertEquals(target.sourcesElementsPublishedConfiguration, configuration) assertEquals(target.sourcesElementsPublishedConfiguration, configuration)
configuration.attributes.attribute(testAttribute, "sourcesElements-published") configuration.attributes.attributeProvider(testAttribute, provider { "sourcesElements-published" })
} }
} }
target.createCompilation<FakeCompilation> { defaults(kotlin) } target.createCompilation<FakeCompilation> { defaults(kotlin) }
@@ -306,7 +306,7 @@ class ExternalKotlinTargetApiTests {
val target = kotlin.createExternalKotlinTarget<FakeTarget> { defaults() } val target = kotlin.createExternalKotlinTarget<FakeTarget> { defaults() }
target.createCompilation<FakeCompilation> { defaults(kotlin) } target.createCompilation<FakeCompilation> { defaults(kotlin) }
target.attributes.attribute(userAttribute, "foo") target.attributes.attributeProvider(userAttribute, target.project.provider { "foo" })
project.evaluate() project.evaluate()
@@ -23,8 +23,14 @@ class IdeaKotlinBinaryAttributesFactoryTest {
val dummyConfiguration = project.configurations.create("dummy") val dummyConfiguration = project.configurations.create("dummy")
val container = dummyConfiguration.attributes val container = dummyConfiguration.attributes
container.attribute(Usage.USAGE_ATTRIBUTE, project.objects.named(Usage.JAVA_API)) container.attributeProvider(
container.attribute(Category.CATEGORY_ATTRIBUTE, project.objects.named(Category.DOCUMENTATION)) Usage.USAGE_ATTRIBUTE,
project.provider { project.objects.named(Usage.JAVA_API) }
)
container.attributeProvider(
Category.CATEGORY_ATTRIBUTE,
project.provider { project.objects.named(Category.DOCUMENTATION) }
)
assertEquals( assertEquals(
mapOf( mapOf(
@@ -10,7 +10,6 @@ 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.file.SourceDirectorySet import org.gradle.api.file.SourceDirectorySet
import org.gradle.api.model.ObjectFactory
import org.gradle.tooling.provider.model.ToolingModelBuilderRegistry import org.gradle.tooling.provider.model.ToolingModelBuilderRegistry
import org.jetbrains.kotlin.gradle.plugin.internal.* import org.jetbrains.kotlin.gradle.plugin.internal.*
import org.jetbrains.kotlin.gradle.plugin.internal.BasePluginConfigurationG70 import org.jetbrains.kotlin.gradle.plugin.internal.BasePluginConfigurationG70
@@ -155,4 +154,5 @@ private fun Project.registerVariantImplementations() {
factories[UnameExecutor.UnameExecutorVariantFactory::class] = factories[UnameExecutor.UnameExecutorVariantFactory::class] =
UnameExecutorG70.UnameExecutorVariantFactoryG70() UnameExecutorG70.UnameExecutorVariantFactoryG70()
factories[ConfigurationCacheStartParameterAccessor.Factory::class] = ConfigurationCacheStartParameterAccessorG70.Factory() factories[ConfigurationCacheStartParameterAccessor.Factory::class] = ConfigurationCacheStartParameterAccessorG70.Factory()
factories[AttributesConfigurationHelper.AttributeConfigurationHelperVariantFactory::class] = AttributeConfigurationHelperVariantFactoryG70()
} }
@@ -0,0 +1,26 @@
/*
* 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.internal
import org.gradle.api.attributes.Attribute
import org.gradle.api.attributes.HasAttributes
import org.gradle.api.provider.ProviderFactory
internal class AttributesConfigurationHelperG70 : AttributesConfigurationHelper {
override fun <T : Any> setAttribute(
attributesContainer: HasAttributes,
key: Attribute<T>,
value: () -> T
) {
attributesContainer.attributes.attribute(key, value())
}
}
internal class AttributeConfigurationHelperVariantFactoryG70 : AttributesConfigurationHelper.AttributeConfigurationHelperVariantFactory {
override fun getInstance(
providerFactory: ProviderFactory
): AttributesConfigurationHelper = AttributesConfigurationHelperG70()
}
@@ -10,7 +10,6 @@ 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.file.SourceDirectorySet import org.gradle.api.file.SourceDirectorySet
import org.gradle.api.model.ObjectFactory
import org.gradle.tooling.provider.model.ToolingModelBuilderRegistry import org.gradle.tooling.provider.model.ToolingModelBuilderRegistry
import org.jetbrains.kotlin.gradle.plugin.internal.* import org.jetbrains.kotlin.gradle.plugin.internal.*
import org.jetbrains.kotlin.gradle.plugin.internal.ConfigurationTimePropertiesAccessorG71 import org.jetbrains.kotlin.gradle.plugin.internal.ConfigurationTimePropertiesAccessorG71
@@ -156,4 +155,5 @@ private fun Project.registerVariantImplementations() {
factories[UnameExecutor.UnameExecutorVariantFactory::class] = factories[UnameExecutor.UnameExecutorVariantFactory::class] =
UnameExecutorG71.UnameExecutorVariantFactoryG71() UnameExecutorG71.UnameExecutorVariantFactoryG71()
factories[ConfigurationCacheStartParameterAccessor.Factory::class] = ConfigurationCacheStartParameterAccessorG71.Factory() factories[ConfigurationCacheStartParameterAccessor.Factory::class] = ConfigurationCacheStartParameterAccessorG71.Factory()
factories[AttributesConfigurationHelper.AttributeConfigurationHelperVariantFactory::class] = AttributeConfigurationHelperVariantFactoryG71()
} }
@@ -0,0 +1,26 @@
/*
* 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.internal
import org.gradle.api.attributes.Attribute
import org.gradle.api.attributes.HasAttributes
import org.gradle.api.provider.ProviderFactory
internal class AttributesConfigurationHelperG71 : AttributesConfigurationHelper {
override fun <T : Any> setAttribute(
attributesContainer: HasAttributes,
key: Attribute<T>,
value: () -> T
) {
attributesContainer.attributes.attribute(key, value())
}
}
internal class AttributeConfigurationHelperVariantFactoryG71 : AttributesConfigurationHelper.AttributeConfigurationHelperVariantFactory {
override fun getInstance(
providerFactory: ProviderFactory
): AttributesConfigurationHelper = AttributesConfigurationHelperG71()
}
@@ -145,4 +145,6 @@ private fun Project.registerVariantImplementations() {
factories[UnameExecutor.UnameExecutorVariantFactory::class] = factories[UnameExecutor.UnameExecutorVariantFactory::class] =
UnameExecutorG74.UnameExecutorVariantFactoryG74() UnameExecutorG74.UnameExecutorVariantFactoryG74()
factories[ConfigurationCacheStartParameterAccessor.Factory::class] = ConfigurationCacheStartParameterAccessorG74.Factory() factories[ConfigurationCacheStartParameterAccessor.Factory::class] = ConfigurationCacheStartParameterAccessorG74.Factory()
factories[AttributesConfigurationHelper.AttributeConfigurationHelperVariantFactory::class] =
AttributeConfigurationHelperVariantFactoryG74()
} }
@@ -0,0 +1,35 @@
/*
* Copyright 2010-2024 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.internal
import org.gradle.api.attributes.Attribute
import org.gradle.api.attributes.AttributeContainer
import org.gradle.api.attributes.HasAttributes
import org.gradle.api.provider.ProviderFactory
/**
* While Gradle 7.4 already has [AttributeContainer.attributeProvider] method available,
* Gradle itself has a bug in mixed attributes (eager + provider) case leading to the false-positive
* deprecation message:
* ```
* Consumable configurations with identical capabilities within a project must have unique attributes, ...
* ```
*/
internal class AttributesConfigurationHelperG74 : AttributesConfigurationHelper {
override fun <T : Any> setAttribute(
attributesContainer: HasAttributes,
key: Attribute<T>,
value: () -> T
) {
attributesContainer.attributes.attribute(key, value())
}
}
internal class AttributeConfigurationHelperVariantFactoryG74 : AttributesConfigurationHelper.AttributeConfigurationHelperVariantFactory {
override fun getInstance(
providerFactory: ProviderFactory
): AttributesConfigurationHelper = AttributesConfigurationHelperG74()
}
@@ -162,4 +162,5 @@ private fun Project.registerVariantImplementations() {
factories[ConfigurationCacheStartParameterAccessor.Factory::class] = ConfigurationCacheStartParameterAccessorG6.Factory() factories[ConfigurationCacheStartParameterAccessor.Factory::class] = ConfigurationCacheStartParameterAccessorG6.Factory()
factories[SourceSetCompatibilityHelper.SourceSetCompatibilityHelperVariantFactory::class] = factories[SourceSetCompatibilityHelper.SourceSetCompatibilityHelperVariantFactory::class] =
SourceSetCompatibilityHelperG6VariantFactory() SourceSetCompatibilityHelperG6VariantFactory()
factories[AttributesConfigurationHelper.AttributeConfigurationHelperVariantFactory::class] = AttributeConfigurationHelperVariantFactoryG6()
} }
@@ -0,0 +1,26 @@
/*
* 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.internal
import org.gradle.api.attributes.Attribute
import org.gradle.api.attributes.HasAttributes
import org.gradle.api.provider.ProviderFactory
internal class AttributesConfigurationHelperG6 : AttributesConfigurationHelper {
override fun <T : Any> setAttribute(
attributesContainer: HasAttributes,
key: Attribute<T>,
value: () -> T
) {
attributesContainer.attributes.attribute(key, value())
}
}
internal class AttributeConfigurationHelperVariantFactoryG6 : AttributesConfigurationHelper.AttributeConfigurationHelperVariantFactory {
override fun getInstance(
providerFactory: ProviderFactory
): AttributesConfigurationHelper = AttributesConfigurationHelperG6()
}