Last active
October 15, 2021 12:35
-
-
Save gmazzo/426f861660d4ae6d7ee072fa5bc21e07 to your computer and use it in GitHub Desktop.
Android Library Variant-Aware Publication (with sources)
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
import org.gradle.api.attributes.LibraryElements | |
import org.gradle.api.component.ConfigurationVariantDetails | |
import org.gradle.api.plugins.JavaPlugin.SOURCES_ELEMENTS_CONFIGURATION_NAME | |
import org.gradle.jvm.tasks.Jar | |
import java.util.Locale | |
plugins { | |
id("com.android.library") | |
`maven-publish` | |
} | |
publishing { | |
val publication = publications.create<MavenPublication>("default") | |
val componentFactory = the<SoftwareComponentFactory>() | |
val mainComponent = componentFactory.adhoc("all-multi-artifact").apply { | |
publication.from(this) | |
} | |
android.libraryVariants.all { | |
val variantName = name | |
val variantComponent = componentFactory.adhoc("$variantName-multi-artifact") | |
val sourcesJarTask = tasks.register<Jar>("${variantName}SourcesJar") { | |
group = BasePlugin.BUILD_GROUP | |
description = | |
"Assembles a jar archive containing the $variantName ${DocsType.SOURCES}." | |
from(sourceSets.map { it.kotlinDirectories + it.javaDirectories + it.resourcesDirectories }) | |
archiveAppendix.set(variantName) | |
archiveClassifier.set("sources") | |
duplicatesStrategy = DuplicatesStrategy.WARN | |
} | |
assembleProvider.configure { dependsOn(sourcesJarTask) } | |
// we transform AGP default variant-aware publication into a new variant-artifact by changing its maven coordinates | |
val variantPublication = publications.create<MavenPublication>(variantName) { | |
from(variantComponent) | |
groupId += ".$artifactId" | |
artifactId = variantName | |
(this as PublicationInternal<*>).isAlias = true | |
} | |
fun createConfiguration(type: String, mavenScope: String) = with(configurations) { | |
// the AGP default variant-aware publication (or new variant-artifact) | |
val base = getByName("${variantName}All${type}Publication") | |
// `all` artifacts have classifiers by default, we need to remove them | |
afterEvaluate { | |
base.outgoing.artifacts.configureEach { | |
(this as ConfigurablePublishArtifact).classifier = null | |
} | |
} | |
// our intermediate POM publication that will depend on the variant-artifact | |
val configuration = create("${variantName}Variant${type}Publication") { | |
isVisible = false | |
isCanBeConsumed = false | |
isCanBeResolved = false | |
// makes a dependency on the variant-artifact | |
project.dependencies.add(name, provider { | |
variantPublication.run { "$groupId:$artifactId:$version" } | |
}) | |
// clones the attributes | |
attributes.from(base.attributes, LibraryElements.LIBRARY_ELEMENTS_ATTRIBUTE) | |
} | |
val sourcesConfiguration = configurations.create( | |
"$variantName$type${SOURCES_ELEMENTS_CONFIGURATION_NAME.capitalize(Locale.ROOT)}" | |
) { | |
isVisible = false | |
isCanBeConsumed = false | |
isCanBeResolved = false | |
outgoing.artifact(sourcesJarTask) | |
attributes { | |
from(base.attributes, LibraryElements.LIBRARY_ELEMENTS_ATTRIBUTE) | |
attribute(Category.CATEGORY_ATTRIBUTE, objects.named(Category.DOCUMENTATION)) | |
attribute(DocsType.DOCS_TYPE_ATTRIBUTE, objects.named(DocsType.SOURCES)) | |
attribute(Bundling.BUNDLING_ATTRIBUTE, objects.named(Bundling.EXTERNAL)) | |
} | |
} | |
val mapAction = Action<ConfigurationVariantDetails> { | |
mapToMavenScope(mavenScope) | |
mapToOptional() | |
} | |
variantComponent.addVariantsFromConfiguration(base, mapAction) | |
variantComponent.addVariantsFromConfiguration(sourcesConfiguration, mapAction) | |
mainComponent.addVariantsFromConfiguration(configuration, mapAction) | |
} | |
createConfiguration("Api", "compile") | |
createConfiguration("Runtime", "runtime") | |
} | |
} | |
fun AttributeContainer.from(other: AttributeContainer, vararg excluding: Attribute<*>) { | |
(other.attributes.keySet() - excluding).forEach { | |
@Suppress("UNCHECKED_CAST") | |
attribute(it as Attribute<Any>, other.attributes.getAttribute(it)!!) | |
} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment