From 727991aee4c8e3389fbcc0ae5551b1bc13e0fbda Mon Sep 17 00:00:00 2001 From: Tyler Wong Date: Tue, 18 Jun 2024 19:02:25 -0700 Subject: [PATCH 1/3] Add Support for Specifying Annotations that Break Compatibility --- build.gradle.kts | 1 + .../gradle/metalava/extension/MetalavaExtension.kt | 8 ++++++++ .../tylerbwong/gradle/metalava/task/BaseMetalavaTask.kt | 4 ++++ .../metalava/task/MetalavaCheckCompatibilityTask.kt | 7 ++++++- .../gradle/metalava/task/MetalavaGenerateSignatureTask.kt | 7 ++++++- samples/kotlin-dsl-compose/build.gradle.kts | 1 + 6 files changed, 26 insertions(+), 2 deletions(-) diff --git a/build.gradle.kts b/build.gradle.kts index a5e5219..e11343a 100644 --- a/build.gradle.kts +++ b/build.gradle.kts @@ -14,6 +14,7 @@ buildscript { allprojects { repositories { + mavenLocal() google() mavenCentral() } diff --git a/plugin/src/main/kotlin/me/tylerbwong/gradle/metalava/extension/MetalavaExtension.kt b/plugin/src/main/kotlin/me/tylerbwong/gradle/metalava/extension/MetalavaExtension.kt index 0ed79f2..5a45af3 100644 --- a/plugin/src/main/kotlin/me/tylerbwong/gradle/metalava/extension/MetalavaExtension.kt +++ b/plugin/src/main/kotlin/me/tylerbwong/gradle/metalava/extension/MetalavaExtension.kt @@ -61,6 +61,14 @@ open class MetalavaExtension @Inject constructor( */ val hiddenAnnotations: SetProperty = objectFactory.setProperty() + /** + * A comma separated list of fully qualified annotation names. + * + * Treat elements annotated with the passed in annotations as important for API compatibility. + * (e.g. @Composable) + */ + val apiCompatAnnotations: SetProperty = objectFactory.setProperty() + /** * Whether the signature file being read should be interpreted as having encoded its types using * Kotlin style types: a suffix of "?" for nullable types, no suffix for non nullable types, and diff --git a/plugin/src/main/kotlin/me/tylerbwong/gradle/metalava/task/BaseMetalavaTask.kt b/plugin/src/main/kotlin/me/tylerbwong/gradle/metalava/task/BaseMetalavaTask.kt index e83a9d0..c294c04 100644 --- a/plugin/src/main/kotlin/me/tylerbwong/gradle/metalava/task/BaseMetalavaTask.kt +++ b/plugin/src/main/kotlin/me/tylerbwong/gradle/metalava/task/BaseMetalavaTask.kt @@ -38,6 +38,10 @@ internal abstract class BaseMetalavaTask( @get:Input val hiddenAnnotations: SetProperty = objectFactory.setProperty() + @get:Optional + @get:Input + val apiCompatAnnotations: SetProperty = objectFactory.setProperty() + @get:Optional @get:Input val arguments: SetProperty = objectFactory.setProperty() diff --git a/plugin/src/main/kotlin/me/tylerbwong/gradle/metalava/task/MetalavaCheckCompatibilityTask.kt b/plugin/src/main/kotlin/me/tylerbwong/gradle/metalava/task/MetalavaCheckCompatibilityTask.kt index aae0926..d7fbd60 100644 --- a/plugin/src/main/kotlin/me/tylerbwong/gradle/metalava/task/MetalavaCheckCompatibilityTask.kt +++ b/plugin/src/main/kotlin/me/tylerbwong/gradle/metalava/task/MetalavaCheckCompatibilityTask.kt @@ -45,6 +45,10 @@ internal abstract class MetalavaCheckCompatibilityTask @Inject constructor( metalavaGenerateSignatureInternal(filenameOverride = tempFilename.get(), awaitWork = true) val hidePackages = hiddenPackages.get().flatMap { listOf("--hide-package", it) } val hideAnnotations = hiddenAnnotations.get().flatMap { listOf("--hide-annotation", it) } + val apiCompatAnnotations = listOf( + "--api-compat-annotations", + apiCompatAnnotations.get().joinToString(), + ) val args: List = listOf( "--format=${format.get()}", @@ -53,7 +57,7 @@ internal abstract class MetalavaCheckCompatibilityTask @Inject constructor( "--check-compatibility:${apiType.get()}:released", filename.get(), ) + reportWarningsAsErrors.get().flag("--warnings-as-errors") + reportLintsAsErrors.get() - .flag("--lints-as-errors") + hidePackages + hideAnnotations + arguments.get() + .flag("--lints-as-errors") + hidePackages + hideAnnotations + apiCompatAnnotations + arguments.get() executeMetalavaWork(args) } @@ -94,6 +98,7 @@ internal abstract class MetalavaCheckCompatibilityTask @Inject constructor( javaSourceLevel.set(extension.javaSourceLevel) hiddenPackages.set(extension.hiddenPackages) hiddenAnnotations.set(extension.hiddenAnnotations) + apiCompatAnnotations.set(extension.apiCompatAnnotations) apiType.set(extension.apiType) inputKotlinNulls.set(extension.inputKotlinNulls) reportWarningsAsErrors.set(extension.reportWarningsAsErrors) diff --git a/plugin/src/main/kotlin/me/tylerbwong/gradle/metalava/task/MetalavaGenerateSignatureTask.kt b/plugin/src/main/kotlin/me/tylerbwong/gradle/metalava/task/MetalavaGenerateSignatureTask.kt index 12057da..234777a 100644 --- a/plugin/src/main/kotlin/me/tylerbwong/gradle/metalava/task/MetalavaGenerateSignatureTask.kt +++ b/plugin/src/main/kotlin/me/tylerbwong/gradle/metalava/task/MetalavaGenerateSignatureTask.kt @@ -82,6 +82,10 @@ internal abstract class MetalavaGenerateSignatureTask @Inject constructor( .joinToString(File.pathSeparator) val hidePackages = hiddenPackages.get().flatMap { listOf("--hide-package", it) } val hideAnnotations = hiddenAnnotations.get().flatMap { listOf("--hide-annotation", it) } + val apiCompatAnnotations = listOf( + "--api-compat-annotations", + apiCompatAnnotations.get().joinToString(), + ) val keepFilename = keepFilename.orNull val keepFileFlags = if (!keepFilename.isNullOrEmpty()) { listOf("--proguard", keepFilename) @@ -95,7 +99,7 @@ internal abstract class MetalavaGenerateSignatureTask @Inject constructor( "--java-source", "${javaSourceLevel.get()}", "--classpath", fullClasspath, "--source-path", sourcePaths, - ) + hidePackages + hideAnnotations + keepFileFlags + arguments.get() + ) + hidePackages + hideAnnotations + apiCompatAnnotations + keepFileFlags + arguments.get() executeMetalavaWork(args, awaitWork) } @@ -131,6 +135,7 @@ internal abstract class MetalavaGenerateSignatureTask @Inject constructor( javaSourceLevel.set(extension.javaSourceLevel) hiddenPackages.set(extension.hiddenPackages) hiddenAnnotations.set(extension.hiddenAnnotations) + apiCompatAnnotations.set(extension.apiCompatAnnotations) keepFilename.set(extension.keepFilename) arguments.set(extension.arguments) } diff --git a/samples/kotlin-dsl-compose/build.gradle.kts b/samples/kotlin-dsl-compose/build.gradle.kts index a743735..68fd45c 100644 --- a/samples/kotlin-dsl-compose/build.gradle.kts +++ b/samples/kotlin-dsl-compose/build.gradle.kts @@ -15,6 +15,7 @@ android { metalava { filename.set("api/$name-api.txt") + apiCompatAnnotations.set(listOf("androidx.compose.runtime.Composable")) } dependencies { From 2017779382979146f3a2f43ff02d4e2661f579bc Mon Sep 17 00:00:00 2001 From: Tyler Wong Date: Tue, 18 Jun 2024 19:03:42 -0700 Subject: [PATCH 2/3] Remove mavenLocal --- build.gradle.kts | 1 - .../tylerbwong/gradle/metalava/extension/MetalavaExtension.kt | 2 +- 2 files changed, 1 insertion(+), 2 deletions(-) diff --git a/build.gradle.kts b/build.gradle.kts index e11343a..a5e5219 100644 --- a/build.gradle.kts +++ b/build.gradle.kts @@ -14,7 +14,6 @@ buildscript { allprojects { repositories { - mavenLocal() google() mavenCentral() } diff --git a/plugin/src/main/kotlin/me/tylerbwong/gradle/metalava/extension/MetalavaExtension.kt b/plugin/src/main/kotlin/me/tylerbwong/gradle/metalava/extension/MetalavaExtension.kt index 5a45af3..7411623 100644 --- a/plugin/src/main/kotlin/me/tylerbwong/gradle/metalava/extension/MetalavaExtension.kt +++ b/plugin/src/main/kotlin/me/tylerbwong/gradle/metalava/extension/MetalavaExtension.kt @@ -17,7 +17,7 @@ open class MetalavaExtension @Inject constructor( /** * The version of Metalava to use. */ - val version: Property = objectFactory.property().also { it.set("1.0.0-alpha10") } + val version: Property = objectFactory.property().also { it.set("1.0.0-alpha11") } /** * A custom Metalava JAR location path to use instead of the embedded dependency. From 8384201aef5338c024b48f05d5f9bb4c93c6e2a0 Mon Sep 17 00:00:00 2001 From: Tyler Wong Date: Thu, 11 Jul 2024 17:22:48 -0700 Subject: [PATCH 3/3] Adhere to finalized api --- README.md | 2 +- .../gradle/metalava/task/MetalavaCheckCompatibilityTask.kt | 5 +---- .../gradle/metalava/task/MetalavaGenerateSignatureTask.kt | 5 +---- 3 files changed, 3 insertions(+), 9 deletions(-) diff --git a/README.md b/README.md index a7d2048..f270fe8 100644 --- a/README.md +++ b/README.md @@ -1,7 +1,7 @@ # metalava-gradle [![Build](https://github.com/tylerbwong/metalava-gradle/actions/workflows/build.yml/badge.svg)](https://github.com/tylerbwong/metalava-gradle/actions/workflows/build.yml) [![Gradle Plugin Portal](https://img.shields.io/maven-metadata/v/https/plugins.gradle.org/m2/me/tylerbwong/gradle/metalava/me.tylerbwong.gradle.metalava.gradle.plugin/maven-metadata.xml.svg?colorB=007ec6&label=Gradle%20Plugin%20Portal)](https://plugins.gradle.org/plugin/me.tylerbwong.gradle.metalava) -[![Metalava](https://img.shields.io/badge/Metalava-1.0.0--alpha10-orange)](https://maven.google.com/web/index.html#com.android.tools.metalava:metalava:1.0.0-alpha10) +[![Metalava](https://img.shields.io/badge/Metalava-1.0.0--alpha11-orange)](https://maven.google.com/web/index.html#com.android.tools.metalava:metalava:1.0.0-alpha11) A Gradle plugin for [Metalava](https://android.googlesource.com/platform/tools/metalava/), AOSP's tool for API metadata extraction and compatibility tracking. diff --git a/plugin/src/main/kotlin/me/tylerbwong/gradle/metalava/task/MetalavaCheckCompatibilityTask.kt b/plugin/src/main/kotlin/me/tylerbwong/gradle/metalava/task/MetalavaCheckCompatibilityTask.kt index 865668a..0b724c0 100644 --- a/plugin/src/main/kotlin/me/tylerbwong/gradle/metalava/task/MetalavaCheckCompatibilityTask.kt +++ b/plugin/src/main/kotlin/me/tylerbwong/gradle/metalava/task/MetalavaCheckCompatibilityTask.kt @@ -45,10 +45,7 @@ internal abstract class MetalavaCheckCompatibilityTask @Inject constructor( metalavaGenerateSignatureInternal(filenameOverride = tempFilename.get(), awaitWork = true) val hidePackages = hiddenPackages.get().flatMap { listOf("--hide-package", it) } val hideAnnotations = hiddenAnnotations.get().flatMap { listOf("--hide-annotation", it) } - val apiCompatAnnotations = listOf( - "--api-compat-annotations", - apiCompatAnnotations.get().joinToString(), - ) + val apiCompatAnnotations = apiCompatAnnotations.get().flatMap { listOf("--api-compat-annotation", it) } val args: List = listOf( "--format=${format.get()}", diff --git a/plugin/src/main/kotlin/me/tylerbwong/gradle/metalava/task/MetalavaGenerateSignatureTask.kt b/plugin/src/main/kotlin/me/tylerbwong/gradle/metalava/task/MetalavaGenerateSignatureTask.kt index 9126f54..5bb36fc 100644 --- a/plugin/src/main/kotlin/me/tylerbwong/gradle/metalava/task/MetalavaGenerateSignatureTask.kt +++ b/plugin/src/main/kotlin/me/tylerbwong/gradle/metalava/task/MetalavaGenerateSignatureTask.kt @@ -82,10 +82,7 @@ internal abstract class MetalavaGenerateSignatureTask @Inject constructor( .joinToString(File.pathSeparator) val hidePackages = hiddenPackages.get().flatMap { listOf("--hide-package", it) } val hideAnnotations = hiddenAnnotations.get().flatMap { listOf("--hide-annotation", it) } - val apiCompatAnnotations = listOf( - "--api-compat-annotations", - apiCompatAnnotations.get().joinToString(), - ) + val apiCompatAnnotations = apiCompatAnnotations.get().flatMap { listOf("--api-compat-annotation", it) } val keepFilename = keepFilename.orNull val keepFileFlags = if (!keepFilename.isNullOrEmpty()) { listOf("--proguard", keepFilename)