Fix MPP publishing with metadata on Gradle 5.2 (KT-29758)
In publishing, use attribute containers of detached configuration instead of HierarchyAttributeContainer, which is rejected by Gradle for not being an AttributeContainerInternal. Using attributes of a detached configuration is a small and conservative fix; we may need to either not filter the attributes, which will lead to [ProjectLocalConfigurations.ATTRIBUTE] being published in the Gradle module metadata, which will potentially complicate our attributes schema migration, or create proper, non-detached configurations for publishing that are separated from the configurations used for project-to-project dependencies. Issue #KT-29758 Fixed
This commit is contained in:
+7
@@ -20,6 +20,13 @@ import org.gradle.api.attributes.AttributeContainer
|
|||||||
import java.util.*
|
import java.util.*
|
||||||
|
|
||||||
// TODO better implementation: attribute invariants (no attrs with same name and different types allowed), thread safety?
|
// TODO better implementation: attribute invariants (no attrs with same name and different types allowed), thread safety?
|
||||||
|
/** An attribute container that delegates attributes lookup to the [parent] when the key matches [filterParentAttributes] and is missing
|
||||||
|
* in this container.
|
||||||
|
*
|
||||||
|
* This container should never be passed to any Gradle API, as Gradle assumes all [AttributeContainer] instances to
|
||||||
|
* implement AttributeContainerInternal.
|
||||||
|
* TODO expose Kotlin-specific API to the users, convert the user attributes to Gradle attributes internally
|
||||||
|
*/
|
||||||
class HierarchyAttributeContainer(
|
class HierarchyAttributeContainer(
|
||||||
val parent: AttributeContainer?,
|
val parent: AttributeContainer?,
|
||||||
val filterParentAttributes: (Attribute<*>) -> Boolean = { true }
|
val filterParentAttributes: (Attribute<*>) -> Boolean = { true }
|
||||||
|
|||||||
+23
-2
@@ -7,6 +7,7 @@ package org.jetbrains.kotlin.gradle.plugin.mpp
|
|||||||
|
|
||||||
import org.gradle.api.Project
|
import org.gradle.api.Project
|
||||||
import org.gradle.api.artifacts.*
|
import org.gradle.api.artifacts.*
|
||||||
|
import org.gradle.api.attributes.Attribute
|
||||||
import org.gradle.api.attributes.AttributeContainer
|
import org.gradle.api.attributes.AttributeContainer
|
||||||
import org.gradle.api.attributes.Usage
|
import org.gradle.api.attributes.Usage
|
||||||
import org.gradle.api.capabilities.Capability
|
import org.gradle.api.capabilities.Capability
|
||||||
@@ -85,8 +86,28 @@ class DefaultKotlinUsageContext(
|
|||||||
// TODO Gradle Java plugin does that in a different way; check whether we can improve this
|
// TODO Gradle Java plugin does that in a different way; check whether we can improve this
|
||||||
configuration.artifacts
|
configuration.artifacts
|
||||||
|
|
||||||
override fun getAttributes(): AttributeContainer =
|
override fun getAttributes(): AttributeContainer {
|
||||||
HierarchyAttributeContainer(configuration.outgoing.attributes) { it != ProjectLocalConfigurations.ATTRIBUTE }
|
val configurationAttributes = configuration.attributes
|
||||||
|
|
||||||
|
/** TODO Using attributes of a detached configuration is a small and 'conservative' fix for KT-29758, [HierarchyAttributeContainer]
|
||||||
|
* being rejected by Gradle 5.2+; we may need to either not filter the attributes, which will lead to
|
||||||
|
* [ProjectLocalConfigurations.ATTRIBUTE] being published in the Gradle module metadata, which will potentially complicate our
|
||||||
|
* attributes schema migration, or create proper, non-detached configurations for publishing that are separated from the
|
||||||
|
* configurations used for project-to-project dependencies
|
||||||
|
*/
|
||||||
|
val result = project.configurations.detachedConfiguration().attributes
|
||||||
|
|
||||||
|
// Capture type parameter T:
|
||||||
|
fun <T> copyAttribute(attribute: Attribute<T>, from: AttributeContainer, to: AttributeContainer) {
|
||||||
|
to.attribute<T>(attribute, from.getAttribute(attribute)!!)
|
||||||
|
}
|
||||||
|
|
||||||
|
configurationAttributes.keySet()
|
||||||
|
.filter { it != ProjectLocalConfigurations.ATTRIBUTE }
|
||||||
|
.forEach { copyAttribute(it, configurationAttributes, result) }
|
||||||
|
|
||||||
|
return result
|
||||||
|
}
|
||||||
|
|
||||||
override fun getCapabilities(): Set<Capability> = emptySet()
|
override fun getCapabilities(): Set<Capability> = emptySet()
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user