Extract custom publishing dsl to buildsrc-compat

It will be used also in kotlin-test KT-61969
This commit is contained in:
Ilya Gorbunov
2023-11-23 08:19:08 +01:00
committed by Space Team
parent 38ed3216fd
commit f3240757ed
2 changed files with 200 additions and 174 deletions
+1 -174
View File
@@ -1,6 +1,4 @@
@file:Suppress("UNUSED_VARIABLE", "NAME_SHADOWING")
import org.gradle.api.internal.component.SoftwareComponentInternal
import org.gradle.api.internal.component.UsageContext
import org.gradle.jvm.tasks.Jar
import org.jetbrains.kotlin.gradle.plugin.KotlinPlatformType
import org.jetbrains.kotlin.gradle.plugin.mpp.KotlinUsages
@@ -13,6 +11,7 @@ import org.jetbrains.kotlin.gradle.tasks.AbstractKotlinCompile
import org.jetbrains.kotlin.gradle.tasks.UsesKotlinJavaToolchain
import plugins.configureDefaultPublishing
import plugins.configureKotlinPomAttributes
import plugins.publishing.*
import kotlin.io.path.copyTo
plugins {
@@ -789,11 +788,6 @@ tasks {
configureDefaultPublishing()
open class ComponentsFactoryAccess
@javax.inject.Inject
constructor(val factory: SoftwareComponentFactory)
val componentFactory = objects.newInstance<ComponentsFactoryAccess>().factory
val emptyJavadocJar by tasks.creating(org.gradle.api.tasks.bundling.Jar::class) {
archiveClassifier.set("javadoc")
@@ -906,173 +900,6 @@ publishing {
}
}
fun copyAttributes(from: AttributeContainer, to: AttributeContainer,) {
// capture type argument T
fun <T : Any> copyOneAttribute(from: AttributeContainer, to: AttributeContainer, key: Attribute<T>) {
val value = checkNotNull(from.getAttribute(key))
to.attribute(key, value)
}
for (key in from.keySet()) {
copyOneAttribute(from, to, key)
}
}
class MultiModuleMavenPublishingConfiguration() {
val modules = mutableMapOf<String, Module>()
class Module(val name: String) {
val variants = mutableMapOf<String, Variant>()
val includes = mutableSetOf<Module>()
class Variant(
val configurationName: String
) {
var name: String = configurationName
val attributesConfigurations = mutableListOf<AttributeContainer.() -> Unit>()
fun attributes(code: AttributeContainer.() -> Unit) {
attributesConfigurations += code
}
val artifactsWithConfigurations = mutableListOf<Pair<Any, ConfigurablePublishArtifact.() -> Unit>>()
fun artifact(file: Any, code: ConfigurablePublishArtifact.() -> Unit = {}) {
artifactsWithConfigurations += file to code
}
val configurationConfigurations = mutableListOf<Configuration.() -> Unit>()
fun configuration(code: Configuration.() -> Unit) {
configurationConfigurations += code
}
val variantDetailsConfigurations = mutableListOf<ConfigurationVariantDetails.() -> Unit>()
fun configureVariantDetails(code: ConfigurationVariantDetails.() -> Unit) {
variantDetailsConfigurations += code
}
}
val mavenPublicationConfigurations = mutableListOf<MavenPublication.() -> Unit>()
fun mavenPublication(code: MavenPublication.() -> Unit) {
mavenPublicationConfigurations += code
}
fun variant(fromConfigurationName: String, code: Variant.() -> Unit = {}): Variant {
val variant = variants.getOrPut(fromConfigurationName) { Variant(fromConfigurationName) }
variant.code()
return variant
}
fun include(vararg modules: Module) {
includes.addAll(modules)
}
}
fun module(name: String, code: Module.() -> Unit): Module {
val module = modules.getOrPut(name) { Module(name) }
module.code()
return module
}
}
fun configureMultiModuleMavenPublishing(code: MultiModuleMavenPublishingConfiguration.() -> Unit) {
val publishingConfiguration = MultiModuleMavenPublishingConfiguration()
publishingConfiguration.code()
val components = publishingConfiguration
.modules
.mapValues { (_, module) -> project.createModulePublication(module) }
val componentsWithExternals = publishingConfiguration
.modules
.filter { (_, module) -> module.includes.isNotEmpty() }
.mapValues { (moduleName, module) ->
val mainComponent = components[moduleName] ?: error("Component with name $moduleName wasn't created")
val externalComponents = module.includes
.map { components[it.name] ?: error("Component with name ${it.name} wasn't created") }
.toSet()
ComponentWithExternalVariants(mainComponent, externalComponents)
}
// override some components wih items from componentsWithExternals
val mergedComponents = components + componentsWithExternals
val publicationsContainer = publishing.publications
for ((componentName, component) in mergedComponents) {
publicationsContainer.create<MavenPublication>(componentName) {
from(component)
val module = publishingConfiguration.modules[componentName]!!
module.mavenPublicationConfigurations.forEach { configure -> configure() }
}
}
}
fun Project.createModulePublication(module: MultiModuleMavenPublishingConfiguration.Module): SoftwareComponent {
val component = componentFactory.adhoc(module.name)
module.variants.values.forEach { addVariant(component, it) }
val newNames = module.variants.map { it.key to it.value.name }.filter { it.first != it.second }.toMap()
return if (newNames.isNotEmpty()) {
ComponentWithRenamedVariants(newNames, component as SoftwareComponentInternal)
} else {
component
}
}
fun Project.addVariant(component: AdhocComponentWithVariants, variant: MultiModuleMavenPublishingConfiguration.Module.Variant) {
val configuration = configurations.getOrCreate(variant.configurationName)
configuration.apply {
isCanBeResolved = false
isCanBeConsumed = true
variant.attributesConfigurations.forEach { configure -> attributes.configure() }
}
for ((artifactNotation, configure) in variant.artifactsWithConfigurations) {
artifacts.add(configuration.name, artifactNotation) {
configure()
}
}
for (configure in variant.configurationConfigurations) {
configuration.apply(configure)
}
component.addVariantsFromConfiguration(configuration) {
variant.variantDetailsConfigurations.forEach { configure -> configure() }
}
}
private class RenamedVariant(val newName: String, context: UsageContext) : UsageContext by context {
override fun getName(): String = newName
}
private class ComponentWithRenamedVariants(
val newNames: Map<String, String>,
private val base: SoftwareComponentInternal
): SoftwareComponentInternal by base {
override fun getName(): String = base.name
override fun getUsages(): Set<UsageContext> {
return base.usages.map {
val newName = newNames[it.name]
if (newName != null) {
RenamedVariant(newName, it)
} else {
it
}
}.toSet()
}
}
private class ComponentWithExternalVariants(
private val mainComponent: SoftwareComponent,
private val externalComponents: Set<SoftwareComponent>
) : ComponentWithVariants, SoftwareComponentInternal {
override fun getName(): String = mainComponent.name
override fun getUsages(): Set<UsageContext> = (mainComponent as SoftwareComponentInternal).usages
override fun getVariants(): Set<SoftwareComponent> = externalComponents
}
// endregion