Skip to content

Commit d221444

Browse files
add support for com.android.fused-library (#999)
* add support for com.android.fused-library * api dump * fix tests
1 parent 90e4f9e commit d221444

File tree

11 files changed

+171
-12
lines changed

11 files changed

+171
-12
lines changed

README.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -19,6 +19,7 @@ default configuration and allows the most customization.
1919
The output of the following Gradle plugins is supported to be published with this plugin:
2020

2121
- `com.android.library`
22+
- `com.android.fused-library`
2223
- `org.jetbrains.kotlin.jvm`
2324
- `org.jetbrains.kotlin.multiplatform`
2425
- `java`

docs/what.md

Lines changed: 40 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -103,6 +103,46 @@ the specified variant instead of publishing all of them.
103103
}
104104
```
105105

106+
107+
## Android Fused Library
108+
109+
For projects using the `com.android.fused-library` plugin.
110+
111+
=== "build.gradle"
112+
113+
```groovy
114+
import com.vanniktech.maven.publish.AndroidSingleVariantLibrary
115+
116+
mavenPublishing {
117+
configure(new AndroidFusedLibrary())
118+
}
119+
```
120+
121+
=== "build.gradle.kts"
122+
123+
```kotlin
124+
import com.vanniktech.maven.publish.AndroidFusedLibrary
125+
126+
mavenPublishing {
127+
configure(AndroidFusedLibrary())
128+
}
129+
```
130+
131+
!!! warning
132+
133+
Support for Android fused libraries is considered experimental and might break
134+
with future Android Gradle plugin updates.
135+
136+
!!! warning
137+
138+
Signing is currently unsupported for Android fused libraries.
139+
140+
!!! info
141+
142+
Configuring source and javadoc publishing is currently not possible and the
143+
plugin will always publush empty jars for them.
144+
145+
106146
## Java Library
107147

108148
For projects using the `java-library` plugin.

plugin/api/plugin.api

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,11 @@
1+
public final class com/vanniktech/maven/publish/AndroidFusedLibrary : com/vanniktech/maven/publish/Platform {
2+
public fun <init> ()V
3+
public fun equals (Ljava/lang/Object;)Z
4+
public fun getJavadocJar ()Lcom/vanniktech/maven/publish/JavadocJar;
5+
public fun getSourcesJar ()Z
6+
public fun hashCode ()I
7+
}
8+
19
public final class com/vanniktech/maven/publish/AndroidMultiVariantLibrary : com/vanniktech/maven/publish/Platform {
210
public fun <init> ()V
311
public fun <init> (Z)V

plugin/src/integrationTest/kotlin/com/vanniktech/maven/publish/MavenPublishPluginPlatformTest.kt

Lines changed: 32 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -683,6 +683,38 @@ class MavenPublishPluginPlatformTest {
683683
assertThat(result).javadocJar().isSigned()
684684
}
685685

686+
@TestParameterInjectorTest
687+
fun androidFusedLibraryProject(
688+
@TestParameter(valuesProvider = AgpVersionProvider::class) agpVersion: AgpVersion,
689+
) {
690+
agpVersion.assumeSupportedJdkAndGradleVersion(gradleVersion)
691+
assume().that(agpVersion).isAtLeast(AgpVersion.AGP_ALPHA)
692+
693+
val project = androidFusedLibraryProjectSpec(agpVersion)
694+
// TODO: signing plugin currently unsupported
695+
val result = project.run(fixtures, testProjectDir, testOptions.copy(signing = TestOptions.Signing.NO_SIGNING))
696+
697+
assertThat(result).outcome().succeeded()
698+
assertThat(result).artifact("aar").exists()
699+
// TODO: signing plugin currently unsupported
700+
// assertThat(result).artifact("aar").isSigned()
701+
assertThat(result).pom().exists()
702+
// TODO: signing plugin currently unsupported
703+
// assertThat(result).pom().isSigned()
704+
assertThat(result).pom().matchesExpectedPom("aar")
705+
assertThat(result).module().exists()
706+
// TODO: signing plugin currently unsupported
707+
// assertThat(result).module().isSigned()
708+
assertThat(result).sourcesJar().exists()
709+
// TODO: signing plugin currently unsupported
710+
// assertThat(result).sourcesJar().isSigned()
711+
// TODO: actual sources jar currently unsupported
712+
// assertThat(result).sourcesJar().containsAllSourceFiles()
713+
assertThat(result).javadocJar().exists()
714+
// TODO: signing plugin currently unsupported
715+
// assertThat(result).javadocJar().isSigned()
716+
}
717+
686718
@TestParameterInjectorTest
687719
fun javaPlatformProject() {
688720
val project = javaPlatformProjectSpec()

plugin/src/integrationTest/kotlin/com/vanniktech/maven/publish/MavenPublishPluginSpecialCaseTest.kt

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -180,7 +180,7 @@ class MavenPublishPluginSpecialCaseTest {
180180
val resultSpec = project.copy(
181181
group = "com.example.test2",
182182
// the project name is used as default value for the artifact id
183-
artifactId = "default-root-project-name",
183+
artifactId = "module",
184184
version = "3.2.1",
185185
)
186186
val actualResult = result.copy(projectSpec = resultSpec)

plugin/src/integrationTest/kotlin/com/vanniktech/maven/publish/ProjectSpecRunner.kt

Lines changed: 9 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,7 @@ package com.vanniktech.maven.publish
22

33
import java.nio.file.Files
44
import java.nio.file.Path
5+
import kotlin.io.path.absolutePathString
56
import kotlin.io.path.copyTo
67
import kotlin.io.path.createDirectories
78
import kotlin.io.path.invariantSeparatorsPathString
@@ -10,15 +11,16 @@ import org.gradle.testkit.runner.GradleRunner
1011

1112
fun ProjectSpec.run(fixtures: Path, temp: Path, options: TestOptions): ProjectResult {
1213
val project = temp.resolve("project").apply { createDirectories() }
14+
val module = project.resolve("module").apply { createDirectories() }
1315
val repo = temp.resolve("repo").apply { createDirectories() }
1416

15-
writeBuildFile(project.resolve("build.gradle"), repo, options)
17+
writeBuildFile(module.resolve("build.gradle"), repo, options)
1618
writeSettingFile(project.resolve("settings.gradle"))
1719
writeGradleProperties(project.resolve("gradle.properties"), options)
18-
writeSourceFiles(fixtures, project)
20+
writeSourceFiles(fixtures, module)
1921
fixtures.resolve("test-secring.gpg").copyTo(project.resolve("test-secring.gpg"))
2022

21-
val task = ":publishAllPublicationsToTestFolderRepository"
23+
val task = ":module:publishAllPublicationsToTestFolderRepository"
2224
val arguments = mutableListOf(task, "--stacktrace")
2325
if (supportsConfigCaching()) {
2426
arguments.add("--configuration-cache")
@@ -35,7 +37,7 @@ fun ProjectSpec.run(fixtures: Path, temp: Path, options: TestOptions): ProjectRe
3537
result = result,
3638
task = task,
3739
projectSpec = this,
38-
project = project,
40+
project = module,
3941
repo = repo,
4042
)
4143
}
@@ -178,6 +180,7 @@ private fun writeSettingFile(path: Path) {
178180
179181
rootProject.name = "default-root-project-name"
180182
183+
include(":module")
181184
""".trimIndent(),
182185
)
183186
}
@@ -191,6 +194,7 @@ private fun ProjectSpec.writeGradleProperties(path: Path, options: TestOptions)
191194
appendLine("kotlin.mpp.androidSourceSetLayoutVersion1.nowarn=true")
192195
appendLine("org.jetbrains.dokka.experimental.gradle.pluginMode=V2Enabled")
193196
appendLine("org.jetbrains.dokka.experimental.gradle.pluginMode.noWarn=true")
197+
appendLine("android.experimental.fusedLibrarySupport=true")
194198
appendLine()
195199

196200
if (options.config == TestOptions.Config.PROPERTIES) {
@@ -226,7 +230,7 @@ private fun ProjectSpec.writeGradleProperties(path: Path, options: TestOptions)
226230
TestOptions.Signing.GPG_KEY -> {
227231
appendLine("signing.keyId=B89C4055")
228232
appendLine("signing.password=test")
229-
appendLine("signing.secretKeyRingFile=test-secring.gpg")
233+
appendLine("signing.secretKeyRingFile=${path.parent.absolutePathString()}/test-secring.gpg")
230234
}
231235
TestOptions.Signing.IN_MEMORY_KEY -> {
232236
appendLine(

plugin/src/integrationTest/kotlin/com/vanniktech/maven/publish/ProjectSpecs.kt

Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -13,6 +13,7 @@ val kotlinJvmPlugin = PluginSpec("org.jetbrains.kotlin.jvm")
1313
val kotlinMultiplatformPlugin = PluginSpec("org.jetbrains.kotlin.multiplatform")
1414
val kotlinAndroidPlugin = PluginSpec("org.jetbrains.kotlin.android")
1515
val androidLibraryPlugin = PluginSpec("com.android.library")
16+
val androidFusedLibraryPlugin = PluginSpec("com.android.fused-library")
1617
val gradlePluginPublishPlugin = PluginSpec("com.gradle.plugin-publish")
1718
val dokkaPlugin = PluginSpec("org.jetbrains.dokka", "1.8.10")
1819
val dokka2Plugin = PluginSpec("org.jetbrains.dokka", "2.0.0-Beta")
@@ -269,6 +270,26 @@ fun androidLibraryKotlinProjectSpec(agpVersion: AgpVersion, kotlinVersion: Kotli
269270
)
270271
}
271272

273+
fun androidFusedLibraryProjectSpec(version: AgpVersion) = ProjectSpec(
274+
plugins = listOf(
275+
androidFusedLibraryPlugin.copy(version = version.value),
276+
),
277+
group = "com.example",
278+
artifactId = "test-artifact",
279+
version = "1.0.0",
280+
properties = defaultProperties,
281+
sourceFiles = listOf(
282+
SourceFile("main", "java", "com/vanniktech/maven/publish/test/JavaTestClass.java"),
283+
),
284+
basePluginConfig = "configure(new AndroidFusedLibrary())",
285+
buildFileExtra = """
286+
androidFusedLibrary {
287+
namespace = "com.test.library"
288+
minSdk = 29
289+
}
290+
""".trimIndent(),
291+
)
292+
272293
fun javaPlatformProjectSpec() = ProjectSpec(
273294
plugins = listOf(
274295
javaPlatformPlugin,

plugin/src/main/kotlin/com/vanniktech/maven/publish/MavenPublishBaseExtension.kt

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -403,6 +403,9 @@ public abstract class MavenPublishBaseExtension @Inject constructor(
403403
val variant = project.findOptionalProperty("ANDROID_VARIANT_TO_PUBLISH") ?: "release"
404404
configure(AndroidSingleVariantLibrary(variant, sourcesJar, javadocJar))
405405
}
406+
project.plugins.hasPlugin("com.android.fused-library") -> {
407+
configure(AndroidFusedLibrary())
408+
}
406409
project.plugins.hasPlugin("com.gradle.plugin-publish") ->
407410
configure(GradlePublishPlugin())
408411
project.plugins.hasPlugin("java-gradle-plugin") ->

plugin/src/main/kotlin/com/vanniktech/maven/publish/MavenPublishPlugin.kt

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -26,6 +26,9 @@ public open class MavenPublishPlugin : Plugin<Project> {
2626
baseExtension.configureBasedOnAppliedPlugins()
2727
}
2828
}
29+
project.plugins.withId("com.android.fused-library") {
30+
baseExtension.configureBasedOnAppliedPlugins()
31+
}
2932

3033
project.afterEvaluate {
3134
// will no-op if it was already called

plugin/src/main/kotlin/com/vanniktech/maven/publish/Platform.kt

Lines changed: 49 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,7 @@ import com.android.build.api.dsl.LibraryExtension
44
import com.vanniktech.maven.publish.tasks.JavadocJar.Companion.javadocJarTask
55
import com.vanniktech.maven.publish.workaround.addTestFixturesSourcesJar
66
import com.vanniktech.maven.publish.workaround.fixTestFixturesMetadata
7+
import org.gradle.api.Incubating
78
import org.gradle.api.Project
89
import org.gradle.api.plugins.JavaPluginExtension
910
import org.gradle.api.provider.Provider
@@ -250,6 +251,42 @@ public data class AndroidMultiVariantLibrary @JvmOverloads constructor(
250251
}
251252
}
252253

254+
/**
255+
* To be used for `com.android.fused-library` projects. Applying this creates a publication for the library with
256+
* empty source and javadoc jars.
257+
*
258+
* Equivalent Gradle set up:
259+
* ```
260+
* publishing {
261+
* publications {
262+
* register<MavenPublication>("maven") {
263+
* from(components["fusedLibraryComponent"])
264+
* }
265+
* }
266+
* }
267+
* ```
268+
*/
269+
@Incubating
270+
public class AndroidFusedLibrary : Platform() {
271+
override val sourcesJar: Boolean = false
272+
override val javadocJar: JavadocJar = JavadocJar.Empty()
273+
274+
override fun configure(project: Project) {
275+
check(project.plugins.hasPlugin("com.android.fused-library")) {
276+
"Calling configure(AndroidFusedLibrary(...)) requires the com.android.fused-library plugin to be applied"
277+
}
278+
279+
project.mavenPublications {
280+
it.withJavadocJar(javadocJar, project, configureArchives = true)
281+
it.withJavaSourcesJar(sourcesJar, project, configureArchives = true)
282+
}
283+
}
284+
285+
override fun equals(other: Any?): Boolean = other is AndroidFusedLibrary
286+
287+
override fun hashCode(): Int = this::class.hashCode()
288+
}
289+
253290
/**
254291
* To be used for `org.jetbrains.kotlin.multiplatform` projects. Uses the default publications that gets created by
255292
* that plugin, including the automatically created `-sources` jars. Depending on the passed parameters for [javadocJar],
@@ -459,21 +496,31 @@ public sealed interface JavadocJar {
459496

460497
private const val PUBLICATION_NAME = "maven"
461498

462-
private fun MavenPublication.withJavaSourcesJar(enabled: Boolean, project: Project) {
499+
private fun MavenPublication.withJavaSourcesJar(enabled: Boolean, project: Project, configureArchives: Boolean = false) {
463500
if (enabled) {
464501
project.extensions.getByType(JavaPluginExtension::class.java).withSourcesJar()
465502
} else {
466503
val task = project.tasks.register("emptySourcesJar", Jar::class.java) {
467504
it.archiveClassifier.set("sources")
505+
if (configureArchives) {
506+
it.archiveBaseName.set(project.name)
507+
it.destinationDirectory.set(project.layout.buildDirectory.dir("libs"))
508+
}
468509
}
469510
artifact(task)
470511
}
471512
}
472513

473-
private fun MavenPublication.withJavadocJar(javadocJar: JavadocJar, project: Project) {
514+
private fun MavenPublication.withJavadocJar(javadocJar: JavadocJar, project: Project, configureArchives: Boolean = false) {
474515
val task = project.javadocJarTask(name, javadocJar)
475516
if (task != null) {
476517
artifact(task)
518+
519+
if (configureArchives) {
520+
task.configure {
521+
it.destinationDirectory.set(project.layout.buildDirectory.dir("libs"))
522+
}
523+
}
477524
}
478525
}
479526

0 commit comments

Comments
 (0)