Demonstrator for Support adding 'remote' variants to SoftwareComponents, so variants are published to separate coordinates and are linked via GMM relative URLs.
Written using Gradle 9.1.0
Run gradle publishAllPublicationsToBuildDirRepository. Gradle will publish 3 separate, but linked, libraries to build/build-dir-maven.
import org.gradle.api.internal.component.SoftwareComponentInternal
import org.gradle.api.internal.component.UsageContext
import org.gradle.api.publish.internal.component.DefaultAdhocSoftwareComponent
import org.gradle.kotlin.dsl.support.serviceOf
plugins {
base
`maven-publish`
}
group = "a.b.c.group"
version = "1.2.3"
publishing {
repositories {
maven(layout.buildDirectory.dir("build-dir-maven")) {
name = "BuildDir"
}
}
}
val generateTextFile by tasks.registering {
val output = temporaryDir.resolve("outgoing.txt")
outputs.file(output)
doLast {
output.writeText("demo outgoing txt")
}
}
val generateJsonFile by tasks.registering {
val output = temporaryDir.resolve("outgoing.json")
outputs.file(output)
doLast {
output.writeText("demo outgoing json")
}
}
val baseOutgoingVariant = configurations.consumable("baseOutgoingVariant").get().apply {
attributes {
attribute(Usage.USAGE_ATTRIBUTE, objects.named("demo-lib"))
}
}
val textOutgoingVariant = configurations.consumable("textOutgoingVariant").get().apply {
attributes {
attribute(Usage.USAGE_ATTRIBUTE, objects.named("demo-lib"))
attribute(Category.CATEGORY_ATTRIBUTE, objects.named("text"))
}
outgoing {
capability("a.b.c.group:demo-lib-text:1.2.3")
artifact(generateTextFile) {
type = "text"
}
}
}
val jsonOutgoingVariant = configurations.consumable("jsonOutgoingVariant").get().apply {
attributes {
attribute(Usage.USAGE_ATTRIBUTE, objects.named("demo-lib"))
attribute(Category.CATEGORY_ATTRIBUTE, objects.named("json"))
}
outgoing {
capability("a.b.c.group:demo-lib-json:1.2.3")
artifact(generateJsonFile) {
type = "json"
}
}
}
val softwareComponentFactory = serviceOf<SoftwareComponentFactory>()
val adhocComponent: SoftwareComponentWithVariants =
SoftwareComponentWithVariants(softwareComponentFactory.adhoc("myAdhocComponent") as DefaultAdhocSoftwareComponent)
class SoftwareComponentWithVariants(
private val baseComponent: DefaultAdhocSoftwareComponent
) : SoftwareComponentInternal, ComponentWithVariants, AdhocComponentWithVariants by baseComponent {
val childVariants: MutableSet<SoftwareComponentVariant> = mutableSetOf()
override fun getUsages(): Set<UsageContext> = baseComponent.usages
override fun getName(): String = baseComponent.name
/** @returns the 'children' published at different coords, linked via `relative-at` url */
override fun getVariants(): Set<SoftwareComponent> =
childVariants
}
class SoftwareComponentVariant(
private val baseComponent: DefaultAdhocSoftwareComponent,
private val gav: String,
) : SoftwareComponentInternal, PublishableComponent, AdhocComponentWithVariants by baseComponent {
override fun getUsages(): Set<UsageContext> =
baseComponent.usages
override fun getName(): String = baseComponent.name
private val coords = object : ModuleVersionIdentifier {
private val _group = gav.substringBefore(':')
private val _name = gav.substringAfter(':').substringBefore(':')
private val _version = gav.substringAfterLast(':')
override fun getVersion(): String = _version
override fun getGroup(): String = _group
override fun getName(): String = _name
override fun getModule(): ModuleIdentifier {
return object : ModuleIdentifier {
override fun getGroup(): String = _group
override fun getName(): String = _name
}
}
}
override fun getCoordinates(): ModuleVersionIdentifier = coords
}
components.add(adhocComponent)
adhocComponent.addVariantsFromConfiguration(baseOutgoingVariant) {
mapToMavenScope("runtime")
}
val textComponentVariant: SoftwareComponentVariant =
SoftwareComponentVariant(
softwareComponentFactory.adhoc("textComponentVariant") as DefaultAdhocSoftwareComponent,
"a.b.c.group:demo-lib-text:1.2.3"
)
textComponentVariant.addVariantsFromConfiguration(textOutgoingVariant) {
mapToMavenScope("runtime")
}
adhocComponent.childVariants.add(textComponentVariant)
val jsonComponentVariant: SoftwareComponentVariant =
SoftwareComponentVariant(
softwareComponentFactory.adhoc("jsonComponentVariant") as DefaultAdhocSoftwareComponent,
"a.b.c.group:demo-lib-json:1.2.3"
)
jsonComponentVariant.addVariantsFromConfiguration(jsonOutgoingVariant) {
mapToMavenScope("runtime")
}
adhocComponent.childVariants.add(jsonComponentVariant)
publishing {
publications {
create<MavenPublication>("maven") {
from(adhocComponent)
}
create<MavenPublication>("mavenText") {
from(textComponentVariant)
artifactId = "demo-lib-text"
}
create<MavenPublication>("mavenJson") {
from(jsonComponentVariant)
artifactId = "demo-lib-json"
}
}
}