From 6e4fd7ac5ccb120cd24d1383330841c44395dc2b Mon Sep 17 00:00:00 2001 From: Zac Sweers Date: Fri, 17 Jul 2020 01:01:09 -0400 Subject: [PATCH 01/17] Opportunistic add .iml files to gitignore --- .gitignore | 2 ++ 1 file changed, 2 insertions(+) diff --git a/.gitignore b/.gitignore index 59587dab73..42c3c96602 100644 --- a/.gitignore +++ b/.gitignore @@ -12,3 +12,5 @@ local.properties maze_output/ package-lock.json .cxx + +*.iml From 5c27b2b5cd055cf9b34c33800a07ac6f53f25592 Mon Sep 17 00:00:00 2001 From: Zac Sweers Date: Fri, 17 Jul 2020 01:17:16 -0400 Subject: [PATCH 02/17] Allow specifying separate manifest output paths and simplify uuid --- .../AndroidManifestParser.kt | 10 ++++++++-- .../BugsnagManifestUuidTask.kt | 9 +++++---- 2 files changed, 13 insertions(+), 6 deletions(-) diff --git a/src/main/kotlin/com.bugsnag.android.gradle/AndroidManifestParser.kt b/src/main/kotlin/com.bugsnag.android.gradle/AndroidManifestParser.kt index 09e48b697d..dc1dabc8eb 100644 --- a/src/main/kotlin/com.bugsnag.android.gradle/AndroidManifestParser.kt +++ b/src/main/kotlin/com.bugsnag.android.gradle/AndroidManifestParser.kt @@ -11,6 +11,7 @@ import java.io.File import java.io.FileWriter import java.io.IOException import java.io.PrintWriter +import java.util.UUID import javax.xml.parsers.ParserConfigurationException class AndroidManifestParser { @@ -56,7 +57,12 @@ class AndroidManifestParser { } @Throws(ParserConfigurationException::class, SAXException::class, IOException::class) - fun writeBuildUuid(manifestPath: File, buildUuid: String) { + fun writeBuildUuid( + manifestPath: File, + outputPath: File = manifestPath, + // Uniquely identify the build so that we can identify the proguard file. + buildUuid: String = UUID.randomUUID().toString() + ) { val root = XmlParser().parse(manifestPath) val application = (root[TAG_APPLICATION] as NodeList)[0] as Node val metadataTags = findMetadataTags(application) @@ -70,7 +76,7 @@ class AndroidManifestParser { )) // Write the manifest file - FileWriter(manifestPath).use { + FileWriter(outputPath).use { val printer = XmlNodePrinter(PrintWriter(it)) printer.isPreserveWhitespace = true printer.print(root) diff --git a/src/main/kotlin/com.bugsnag.android.gradle/BugsnagManifestUuidTask.kt b/src/main/kotlin/com.bugsnag.android.gradle/BugsnagManifestUuidTask.kt index 9a422f8323..dd03d4586a 100644 --- a/src/main/kotlin/com.bugsnag.android.gradle/BugsnagManifestUuidTask.kt +++ b/src/main/kotlin/com.bugsnag.android.gradle/BugsnagManifestUuidTask.kt @@ -10,6 +10,7 @@ import org.gradle.api.file.DirectoryProperty import org.gradle.api.logging.Logger import org.gradle.api.provider.Property import org.gradle.api.provider.Provider +import org.gradle.api.tasks.Internal import org.gradle.api.tasks.TaskAction import java.io.File import java.nio.file.Paths @@ -25,7 +26,7 @@ import java.util.UUID * This task must be called after "process${variantName}Manifest", since it * requires that an AndroidManifest.xml exists in `build/intermediates`. */ -open class BugsnagManifestUuidTask : DefaultTask() { +abstract class BugsnagManifestUuidTask : DefaultTask() { init { group = BugsnagPlugin.GROUP_NAME @@ -34,6 +35,8 @@ open class BugsnagManifestUuidTask : DefaultTask() { lateinit var variantOutput: ApkVariantOutput lateinit var variant: ApkVariant + + @get:Internal val manifestInfoProvider: Property = project.objects.property(AndroidManifestInfo::class.java) @TaskAction @@ -43,13 +46,11 @@ open class BugsnagManifestUuidTask : DefaultTask() { project.logger.warn("Failed to find manifest at $manifestPath for $variantOutput") } - // Uniquely identify the build so that we can identify the proguard file. - val buildUUID = UUID.randomUUID().toString() project.logger.lifecycle("Updating manifest with build UUID: $manifestPath") // read the manifest information and store it for subsequent tasks val manifestParser = AndroidManifestParser() - manifestParser.writeBuildUuid(manifestPath!!, buildUUID) + manifestParser.writeBuildUuid(manifestPath!!) manifestInfoProvider.set(manifestParser.readManifest(manifestPath, logger)) } From 2a78b7a49c2e94b06c8fef26f8e02b38554bc5b4 Mon Sep 17 00:00:00 2001 From: Zac Sweers Date: Fri, 17 Jul 2020 01:17:25 -0400 Subject: [PATCH 03/17] Port BugsnagManifestuuidTaskV2 --- .../BugsnagManifestuuidTaskV2.kt | 51 +++++++++++++++++++ 1 file changed, 51 insertions(+) create mode 100644 src/main/kotlin/com.bugsnag.android.gradle/BugsnagManifestuuidTaskV2.kt diff --git a/src/main/kotlin/com.bugsnag.android.gradle/BugsnagManifestuuidTaskV2.kt b/src/main/kotlin/com.bugsnag.android.gradle/BugsnagManifestuuidTaskV2.kt new file mode 100644 index 0000000000..0ea9973bbe --- /dev/null +++ b/src/main/kotlin/com.bugsnag.android.gradle/BugsnagManifestuuidTaskV2.kt @@ -0,0 +1,51 @@ +package com.bugsnag.android.gradle + +import org.gradle.api.internal.classpath.ManifestUtil + +import com.android.Version +import org.gradle.api.DefaultTask +import org.gradle.api.file.RegularFileProperty +import org.gradle.api.tasks.InputFile +import org.gradle.api.tasks.OutputFile +import org.gradle.api.tasks.PathSensitive +import org.gradle.api.tasks.PathSensitivity +import org.gradle.api.tasks.TaskAction +import org.gradle.util.VersionNumber + +/** +An AGP 4.1-compatible version of {@link BugsnagManifestTask}. + */ +abstract class BugsnagManifestuuidTaskV2 : DefaultTask() { + + internal companion object { + val MIN_AGP_VERSION: VersionNumber = VersionNumber.parse("4.1.0-alpha04") + + fun isApplicable(): Boolean { + return try { + VersionNumber.parse(Version.ANDROID_GRADLE_PLUGIN_VERSION) >= MIN_AGP_VERSION + } catch (ignored: Throwable) { + // Not on a new enough AGP version, return false + false + } + } + } + + // NONE because we only care about its contents, not location. + @get:PathSensitive(PathSensitivity.NONE) + @get:InputFile + abstract val mergedManifest: RegularFileProperty + + @get:OutputFile + abstract val updatedManifest: RegularFileProperty + + init { + group = BugsnagPlugin.GROUP_NAME + description = "Adds a unique build UUID to AndroidManifest to link proguard mappings to crash reports" + } + + @TaskAction + fun updateManifest() { + val manifestParser = AndroidManifestParser() + manifestParser.writeBuildUuid(mergedManifest.asFile.get(), updatedManifest.asFile.get()) + } +} From c9baf769491be216836c7b7dc601f9ea647fa43e Mon Sep 17 00:00:00 2001 From: Zac Sweers Date: Fri, 17 Jul 2020 01:17:54 -0400 Subject: [PATCH 04/17] Nix import --- .../kotlin/com.bugsnag.android.gradle/BugsnagManifestUuidTask.kt | 1 - 1 file changed, 1 deletion(-) diff --git a/src/main/kotlin/com.bugsnag.android.gradle/BugsnagManifestUuidTask.kt b/src/main/kotlin/com.bugsnag.android.gradle/BugsnagManifestUuidTask.kt index dd03d4586a..218a843035 100644 --- a/src/main/kotlin/com.bugsnag.android.gradle/BugsnagManifestUuidTask.kt +++ b/src/main/kotlin/com.bugsnag.android.gradle/BugsnagManifestUuidTask.kt @@ -14,7 +14,6 @@ import org.gradle.api.tasks.Internal import org.gradle.api.tasks.TaskAction import java.io.File import java.nio.file.Paths -import java.util.UUID /** * Task to add a unique build UUID to AndroidManifest.xml during the build From 89962a045355ac8691e1081ee93c58c0dd79bdf6 Mon Sep 17 00:00:00 2001 From: Zac Sweers Date: Fri, 17 Jul 2020 01:21:12 -0400 Subject: [PATCH 05/17] Extract base class for reuse --- .../BugsnagManifestUuidTask.kt | 20 ++++++++++--------- 1 file changed, 11 insertions(+), 9 deletions(-) diff --git a/src/main/kotlin/com.bugsnag.android.gradle/BugsnagManifestUuidTask.kt b/src/main/kotlin/com.bugsnag.android.gradle/BugsnagManifestUuidTask.kt index 218a843035..e3bb5cbc74 100644 --- a/src/main/kotlin/com.bugsnag.android.gradle/BugsnagManifestUuidTask.kt +++ b/src/main/kotlin/com.bugsnag.android.gradle/BugsnagManifestUuidTask.kt @@ -15,6 +15,16 @@ import org.gradle.api.tasks.TaskAction import java.io.File import java.nio.file.Paths +abstract class BaseBugsnagManifestUuidTask : DefaultTask() { + init { + group = BugsnagPlugin.GROUP_NAME + description = "Adds a unique build UUID to AndroidManifest to link proguard mappings to crash reports" + } + + @get:Internal + val manifestInfoProvider: Property = project.objects.property(AndroidManifestInfo::class.java) +} + /** * Task to add a unique build UUID to AndroidManifest.xml during the build * process. This is used by Bugsnag to identify which proguard mapping file @@ -25,19 +35,11 @@ import java.nio.file.Paths * This task must be called after "process${variantName}Manifest", since it * requires that an AndroidManifest.xml exists in `build/intermediates`. */ -abstract class BugsnagManifestUuidTask : DefaultTask() { - - init { - group = BugsnagPlugin.GROUP_NAME - description = "Adds a unique build UUID to AndroidManifest to link proguard mappings to crash reports" - } +abstract class BugsnagManifestUuidTask : BaseBugsnagManifestUuidTask() { lateinit var variantOutput: ApkVariantOutput lateinit var variant: ApkVariant - @get:Internal - val manifestInfoProvider: Property = project.objects.property(AndroidManifestInfo::class.java) - @TaskAction fun updateManifest() { val manifestPath = getManifestPaths(project, variant, variantOutput) From 1814b4f0dc5f91926562faca71d61cbc72531057 Mon Sep 17 00:00:00 2001 From: Zac Sweers Date: Fri, 17 Jul 2020 01:22:12 -0400 Subject: [PATCH 06/17] Use shared base --- ...anifestuuidTaskV2.kt => BugsnagManifestUuidTaskV2.kt} | 9 ++++----- 1 file changed, 4 insertions(+), 5 deletions(-) rename src/main/kotlin/com.bugsnag.android.gradle/{BugsnagManifestuuidTaskV2.kt => BugsnagManifestUuidTaskV2.kt} (84%) diff --git a/src/main/kotlin/com.bugsnag.android.gradle/BugsnagManifestuuidTaskV2.kt b/src/main/kotlin/com.bugsnag.android.gradle/BugsnagManifestUuidTaskV2.kt similarity index 84% rename from src/main/kotlin/com.bugsnag.android.gradle/BugsnagManifestuuidTaskV2.kt rename to src/main/kotlin/com.bugsnag.android.gradle/BugsnagManifestUuidTaskV2.kt index 0ea9973bbe..99c9b9fe2f 100644 --- a/src/main/kotlin/com.bugsnag.android.gradle/BugsnagManifestuuidTaskV2.kt +++ b/src/main/kotlin/com.bugsnag.android.gradle/BugsnagManifestUuidTaskV2.kt @@ -1,9 +1,6 @@ package com.bugsnag.android.gradle -import org.gradle.api.internal.classpath.ManifestUtil - import com.android.Version -import org.gradle.api.DefaultTask import org.gradle.api.file.RegularFileProperty import org.gradle.api.tasks.InputFile import org.gradle.api.tasks.OutputFile @@ -13,9 +10,9 @@ import org.gradle.api.tasks.TaskAction import org.gradle.util.VersionNumber /** -An AGP 4.1-compatible version of {@link BugsnagManifestTask}. + * An AGP-4-compatible implementation of [BugsnagManifestUuidTask]. */ -abstract class BugsnagManifestuuidTaskV2 : DefaultTask() { +abstract class BugsnagManifestUuidTaskV2 : BaseBugsnagManifestUuidTask() { internal companion object { val MIN_AGP_VERSION: VersionNumber = VersionNumber.parse("4.1.0-alpha04") @@ -46,6 +43,8 @@ abstract class BugsnagManifestuuidTaskV2 : DefaultTask() { @TaskAction fun updateManifest() { val manifestParser = AndroidManifestParser() + val output = updatedManifest.asFile.get() manifestParser.writeBuildUuid(mergedManifest.asFile.get(), updatedManifest.asFile.get()) + manifestInfoProvider.set(manifestParser.readManifest(output, logger)) } } From 801a677275c3b4cacef2a7933fde636f5d3879af Mon Sep 17 00:00:00 2001 From: Zac Sweers Date: Fri, 17 Jul 2020 01:29:28 -0400 Subject: [PATCH 07/17] Wire for AGP 4.1 --- build.gradle | 4 +- .../BugsnagPlugin.kt | 43 ++++++++++++++----- 2 files changed, 34 insertions(+), 13 deletions(-) diff --git a/build.gradle b/build.gradle index 3960eecad7..b2f85c82b5 100644 --- a/build.gradle +++ b/build.gradle @@ -5,7 +5,7 @@ buildscript { } dependencies { - classpath "com.android.tools.build:gradle:4.0.0" // compile against 4.0.0, but maintain compat to 3.4.0 + classpath "com.android.tools.build:gradle:4.1.0-beta04" // compile against 4.0.0, but maintain compat to 3.4.0 classpath "org.jetbrains.kotlin:kotlin-gradle-plugin:1.3.72" classpath "io.gitlab.arturbosch.detekt:detekt-gradle-plugin:1.9.1" } @@ -42,7 +42,7 @@ repositories { // Build dependencies dependencies { - compileOnly "com.android.tools.build:gradle:4.0.0" + compileOnly "com.android.tools.build:gradle:4.1.0-beta04" compile "org.apache.httpcomponents:httpclient:4.5.2" compile "org.apache.httpcomponents:httpmime:4.5.2" compile "org.jetbrains.kotlin:kotlin-stdlib-jdk8:1.3.72" diff --git a/src/main/kotlin/com.bugsnag.android.gradle/BugsnagPlugin.kt b/src/main/kotlin/com.bugsnag.android.gradle/BugsnagPlugin.kt index ff7336df7c..fb5d00cbe3 100644 --- a/src/main/kotlin/com.bugsnag.android.gradle/BugsnagPlugin.kt +++ b/src/main/kotlin/com.bugsnag.android.gradle/BugsnagPlugin.kt @@ -1,10 +1,12 @@ package com.bugsnag.android.gradle +import com.android.build.api.artifact.ArtifactType import com.android.build.gradle.AppExtension import com.android.build.gradle.AppPlugin import com.android.build.gradle.api.ApkVariant import com.android.build.gradle.api.ApkVariantOutput import com.android.build.gradle.api.ApplicationVariant +import com.android.build.gradle.internal.dsl.BaseAppModuleExtension import com.android.build.gradle.tasks.ExternalNativeBuildTask import org.gradle.api.DomainObjectSet import org.gradle.api.Plugin @@ -109,18 +111,37 @@ class BugsnagPlugin : Plugin { } } - private fun registerManifestUuidTask(project: Project, - variant: ApkVariant, - output: ApkVariantOutput): TaskProvider { + private fun registerManifestUuidTask( + project: Project, + variant: ApkVariant, + output: ApkVariantOutput + ): TaskProvider { val taskName = "processBugsnag${taskNameForOutput(output)}Manifest" - return project.tasks.register(taskName, BugsnagManifestUuidTask::class.java) { - it.variantOutput = output - it.variant = variant - val processManifest = output.processManifestProvider.getOrNull() - - if (processManifest != null) { - processManifest.finalizedBy(it) - it.dependsOn(processManifest) + return if (BugsnagManifestUuidTaskV2.isApplicable()) { + val manifestUpdater = project.tasks.register(taskName, BugsnagManifestUuidTaskV2::class.java) + val android = project.extensions.getByType(BaseAppModuleExtension::class.java) + android.onVariants.withName(variant.name) { + onProperties { + artifacts + .use(manifestUpdater) + .wiredWithFiles( + BugsnagManifestUuidTaskV2::mergedManifest, + BugsnagManifestUuidTaskV2::updatedManifest + ) + .toTransform(ArtifactType.MERGED_MANIFEST) + } + } + return manifestUpdater + } else { + project.tasks.register(taskName, BugsnagManifestUuidTask::class.java) { + it.variantOutput = output + it.variant = variant + val processManifest = output.processManifestProvider.orNull + + if (processManifest != null) { + processManifest.finalizedBy(it) + it.dependsOn(processManifest) + } } } } From e40508ea5a7fcab2071abb74c8851ee9ac57d75c Mon Sep 17 00:00:00 2001 From: Zac Sweers Date: Fri, 17 Jul 2020 01:56:13 -0400 Subject: [PATCH 08/17] Clean up wiring for manifest info output --- build.gradle | 4 + .../AndroidManifestInfo.kt | 74 ++++++++++++++++++- .../AndroidManifestInfoReceiver.kt | 18 +++++ .../BugsnagManifestUuidTask.kt | 14 ++-- .../BugsnagManifestUuidTaskV2.kt | 4 +- .../BugsnagPlugin.kt | 17 +++-- .../BugsnagReleasesTask.kt | 6 +- .../BugsnagUploadNdkTask.kt | 7 +- .../BugsnagUploadProguardTask.kt | 6 +- 9 files changed, 121 insertions(+), 29 deletions(-) create mode 100644 src/main/kotlin/com.bugsnag.android.gradle/AndroidManifestInfoReceiver.kt diff --git a/build.gradle b/build.gradle index b2f85c82b5..f6ac71c71a 100644 --- a/build.gradle +++ b/build.gradle @@ -47,6 +47,10 @@ dependencies { compile "org.apache.httpcomponents:httpmime:4.5.2" compile "org.jetbrains.kotlin:kotlin-stdlib-jdk8:1.3.72" + // For serialization of shared data + implementation "com.squareup.okio:okio:2.7.0" + implementation "com.squareup.moshi:moshi:1.9.3" + testCompile "com.android.tools.build:gradle:4.0.0" testCompile "junit:junit:4.12" testCompile "org.mockito:mockito-core:2.28.2" diff --git a/src/main/kotlin/com.bugsnag.android.gradle/AndroidManifestInfo.kt b/src/main/kotlin/com.bugsnag.android.gradle/AndroidManifestInfo.kt index ec921a0326..1029793304 100644 --- a/src/main/kotlin/com.bugsnag.android.gradle/AndroidManifestInfo.kt +++ b/src/main/kotlin/com.bugsnag.android.gradle/AndroidManifestInfo.kt @@ -1,8 +1,80 @@ package com.bugsnag.android.gradle +import com.squareup.moshi.JsonAdapter +import com.squareup.moshi.JsonReader +import com.squareup.moshi.JsonReader.Token.NULL +import com.squareup.moshi.JsonWriter +import okio.buffer +import okio.sink +import okio.source +import java.io.File + data class AndroidManifestInfo( var apiKey: String, var versionCode: String, var buildUUID: String, var versionName: String -) +) { + internal fun write(file: File) { + file.sink().buffer().use { + ADAPTER.toJson(it, this) + } + } + + internal companion object { + private val OPTIONS = JsonReader.Options.of( + "apiKey", + "versionCode", + "buildUUID", + "versionName" + ) + + private val ADAPTER = object : JsonAdapter() { + override fun fromJson(reader: JsonReader): AndroidManifestInfo? { + if (reader.peek() == NULL) { + return reader.nextNull() + } + lateinit var apiKey: String + lateinit var versionCode: String + lateinit var buildUUID: String + lateinit var versionName: String + reader.beginObject() + while (reader.hasNext()) { + when (reader.selectName(OPTIONS)) { + 0 -> apiKey = reader.nextString() + 1 -> versionCode = reader.nextString() + 2 -> buildUUID = reader.nextString() + 3 -> versionName = reader.nextString() + -1 -> reader.skipValue() + } + } + reader.endObject() + return AndroidManifestInfo(apiKey, versionCode, buildUUID, versionName) + } + + override fun toJson(writer: JsonWriter, value: AndroidManifestInfo?) { + if (value == null) { + writer.nullValue() + return + } + writer.beginObject() + .name("apiKey") + .value(value.apiKey) + .name("versionCode") + .value(value.versionCode) + .name("buildUUID") + .value(value.buildUUID) + .name("versionName") + .value(value.versionName) + .endObject() + } + + } + + fun read(file: File): AndroidManifestInfo { + return file.source().buffer().use { + ADAPTER.fromJson(it) ?: error("Failed to parse manifest info.") + } + } + } +} diff --git a/src/main/kotlin/com.bugsnag.android.gradle/AndroidManifestInfoReceiver.kt b/src/main/kotlin/com.bugsnag.android.gradle/AndroidManifestInfoReceiver.kt new file mode 100644 index 0000000000..47d2e6ef68 --- /dev/null +++ b/src/main/kotlin/com.bugsnag.android.gradle/AndroidManifestInfoReceiver.kt @@ -0,0 +1,18 @@ +package com.bugsnag.android.gradle + +import org.gradle.api.file.RegularFileProperty +import org.gradle.api.tasks.InputFile +import org.gradle.api.tasks.PathSensitive +import org.gradle.api.tasks.PathSensitivity.NONE + +interface AndroidManifestInfoReceiver { + + @get:PathSensitive(NONE) + @get:InputFile + val manifestInfoFile: RegularFileProperty + +} + +internal fun AndroidManifestInfoReceiver.parseManifestInfo(): AndroidManifestInfo { + return AndroidManifestInfo.read(manifestInfoFile.asFile.get()) +} diff --git a/src/main/kotlin/com.bugsnag.android.gradle/BugsnagManifestUuidTask.kt b/src/main/kotlin/com.bugsnag.android.gradle/BugsnagManifestUuidTask.kt index e3bb5cbc74..8ebbb144c7 100644 --- a/src/main/kotlin/com.bugsnag.android.gradle/BugsnagManifestUuidTask.kt +++ b/src/main/kotlin/com.bugsnag.android.gradle/BugsnagManifestUuidTask.kt @@ -7,10 +7,10 @@ import org.gradle.api.DefaultTask import org.gradle.api.Project import org.gradle.api.file.Directory import org.gradle.api.file.DirectoryProperty +import org.gradle.api.file.RegularFileProperty import org.gradle.api.logging.Logger -import org.gradle.api.provider.Property import org.gradle.api.provider.Provider -import org.gradle.api.tasks.Internal +import org.gradle.api.tasks.OutputFile import org.gradle.api.tasks.TaskAction import java.io.File import java.nio.file.Paths @@ -21,8 +21,12 @@ abstract class BaseBugsnagManifestUuidTask : DefaultTask() { description = "Adds a unique build UUID to AndroidManifest to link proguard mappings to crash reports" } - @get:Internal - val manifestInfoProvider: Property = project.objects.property(AndroidManifestInfo::class.java) + @get:OutputFile + abstract val manifestInfoProvider: RegularFileProperty + + fun writeManifestInfo(info: AndroidManifestInfo) { + info.write(manifestInfoProvider.get().asFile) + } } /** @@ -52,7 +56,7 @@ abstract class BugsnagManifestUuidTask : BaseBugsnagManifestUuidTask() { // read the manifest information and store it for subsequent tasks val manifestParser = AndroidManifestParser() manifestParser.writeBuildUuid(manifestPath!!) - manifestInfoProvider.set(manifestParser.readManifest(manifestPath, logger)) + writeManifestInfo(manifestParser.readManifest(manifestPath, logger)) } /** diff --git a/src/main/kotlin/com.bugsnag.android.gradle/BugsnagManifestUuidTaskV2.kt b/src/main/kotlin/com.bugsnag.android.gradle/BugsnagManifestUuidTaskV2.kt index 99c9b9fe2f..420e9c3d2c 100644 --- a/src/main/kotlin/com.bugsnag.android.gradle/BugsnagManifestUuidTaskV2.kt +++ b/src/main/kotlin/com.bugsnag.android.gradle/BugsnagManifestUuidTaskV2.kt @@ -15,7 +15,7 @@ import org.gradle.util.VersionNumber abstract class BugsnagManifestUuidTaskV2 : BaseBugsnagManifestUuidTask() { internal companion object { - val MIN_AGP_VERSION: VersionNumber = VersionNumber.parse("4.1.0-alpha04") + private val MIN_AGP_VERSION: VersionNumber = VersionNumber.parse("4.1.0-alpha04") fun isApplicable(): Boolean { return try { @@ -45,6 +45,6 @@ abstract class BugsnagManifestUuidTaskV2 : BaseBugsnagManifestUuidTask() { val manifestParser = AndroidManifestParser() val output = updatedManifest.asFile.get() manifestParser.writeBuildUuid(mergedManifest.asFile.get(), updatedManifest.asFile.get()) - manifestInfoProvider.set(manifestParser.readManifest(output, logger)) + writeManifestInfo(manifestParser.readManifest(output, logger)) } } diff --git a/src/main/kotlin/com.bugsnag.android.gradle/BugsnagPlugin.kt b/src/main/kotlin/com.bugsnag.android.gradle/BugsnagPlugin.kt index fb5d00cbe3..d8bf563393 100644 --- a/src/main/kotlin/com.bugsnag.android.gradle/BugsnagPlugin.kt +++ b/src/main/kotlin/com.bugsnag.android.gradle/BugsnagPlugin.kt @@ -12,6 +12,8 @@ import org.gradle.api.DomainObjectSet import org.gradle.api.Plugin import org.gradle.api.Project import org.gradle.api.Task +import org.gradle.api.file.RegularFile +import org.gradle.api.provider.Provider import org.gradle.api.tasks.TaskProvider /** @@ -86,7 +88,7 @@ class BugsnagPlugin : Plugin { val ndkEnabled = isNdkProject(bugsnag, project.extensions.getByType(AppExtension::class.java)) // register bugsnag tasks - val manifestUuidTask = registerManifestUuidTask(project, variant, output) + val manifestInfoFile = registerManifestUuidTask(project, variant, output) val proguardTask = when { jvmMinificationEnabled -> registerProguardUploadTask(project, variant, output, bugsnag) else -> null @@ -103,10 +105,9 @@ class BugsnagPlugin : Plugin { findAssembleBundleTasks(project, variant, output).forEach { // give all tasks a manifest info provider to prevent reading // the manifest more than once - val manifestInfoProvider = manifestUuidTask.get().manifestInfoProvider - proguardTask?.get()?.manifestInfoProvider = manifestInfoProvider - symbolFileTask?.get()?.manifestInfoProvider = manifestInfoProvider - releasesTask.get().manifestInfoProvider = manifestInfoProvider + proguardTask?.get()?.manifestInfoFile?.set(manifestInfoFile) + symbolFileTask?.get()?.manifestInfoFile?.set(manifestInfoFile) + releasesTask.get().manifestInfoFile.set(manifestInfoFile) } } } @@ -115,7 +116,7 @@ class BugsnagPlugin : Plugin { project: Project, variant: ApkVariant, output: ApkVariantOutput - ): TaskProvider { + ): Provider { val taskName = "processBugsnag${taskNameForOutput(output)}Manifest" return if (BugsnagManifestUuidTaskV2.isApplicable()) { val manifestUpdater = project.tasks.register(taskName, BugsnagManifestUuidTaskV2::class.java) @@ -131,7 +132,7 @@ class BugsnagPlugin : Plugin { .toTransform(ArtifactType.MERGED_MANIFEST) } } - return manifestUpdater + return manifestUpdater.flatMap(BaseBugsnagManifestUuidTask::manifestInfoProvider) } else { project.tasks.register(taskName, BugsnagManifestUuidTask::class.java) { it.variantOutput = output @@ -142,7 +143,7 @@ class BugsnagPlugin : Plugin { processManifest.finalizedBy(it) it.dependsOn(processManifest) } - } + }.flatMap(BaseBugsnagManifestUuidTask::manifestInfoProvider) } } diff --git a/src/main/kotlin/com.bugsnag.android.gradle/BugsnagReleasesTask.kt b/src/main/kotlin/com.bugsnag.android.gradle/BugsnagReleasesTask.kt index 0fdf265bf1..50ef3616b6 100644 --- a/src/main/kotlin/com.bugsnag.android.gradle/BugsnagReleasesTask.kt +++ b/src/main/kotlin/com.bugsnag.android.gradle/BugsnagReleasesTask.kt @@ -4,7 +4,6 @@ import com.android.build.gradle.api.ApkVariant import com.android.build.gradle.api.ApkVariantOutput import org.gradle.api.DefaultTask import org.gradle.api.logging.LogLevel -import org.gradle.api.provider.Property import org.gradle.api.tasks.TaskAction import org.gradle.process.internal.ExecException import org.json.simple.JSONObject @@ -17,7 +16,7 @@ import java.net.HttpURLConnection import java.net.URL import java.nio.charset.Charset -open class BugsnagReleasesTask : DefaultTask() { +abstract class BugsnagReleasesTask : DefaultTask(), AndroidManifestInfoReceiver { init { group = BugsnagPlugin.GROUP_NAME @@ -26,11 +25,10 @@ open class BugsnagReleasesTask : DefaultTask() { lateinit var variantOutput: ApkVariantOutput lateinit var variant: ApkVariant - lateinit var manifestInfoProvider: Property @TaskAction fun fetchReleaseInfo() { - val manifestInfo = manifestInfoProvider.get() + val manifestInfo = parseManifestInfo() val logger = project.logger val bugsnag = project.extensions.getByType(BugsnagPluginExtension::class.java) val payload = generateJsonPayload(manifestInfo, bugsnag) diff --git a/src/main/kotlin/com.bugsnag.android.gradle/BugsnagUploadNdkTask.kt b/src/main/kotlin/com.bugsnag.android.gradle/BugsnagUploadNdkTask.kt index ec793f4b03..5089e9ce77 100644 --- a/src/main/kotlin/com.bugsnag.android.gradle/BugsnagUploadNdkTask.kt +++ b/src/main/kotlin/com.bugsnag.android.gradle/BugsnagUploadNdkTask.kt @@ -11,11 +11,9 @@ import org.apache.http.entity.mime.content.StringBody import org.apache.tools.ant.taskdefs.condition.Os import org.gradle.api.DefaultTask import org.gradle.api.Project -import org.gradle.api.provider.Property import org.gradle.api.tasks.TaskAction import java.io.File import java.io.FileOutputStream -import java.io.IOException import java.io.InputStream import java.io.Reader import java.util.zip.GZIPOutputStream @@ -33,7 +31,7 @@ import java.util.zip.GZIPOutputStream * it is usually safe to have this be the absolute last task executed during * a build. */ -open class BugsnagUploadNdkTask : DefaultTask() { +abstract class BugsnagUploadNdkTask : DefaultTask(), AndroidManifestInfoReceiver { init { group = BugsnagPlugin.GROUP_NAME @@ -47,7 +45,6 @@ open class BugsnagUploadNdkTask : DefaultTask() { var sharedObjectPath: String? = null lateinit var variantOutput: ApkVariantOutput lateinit var variant: ApkVariant - lateinit var manifestInfoProvider: Property @TaskAction fun upload() { @@ -187,7 +184,7 @@ open class BugsnagUploadNdkTask : DefaultTask() { val request = BugsnagMultiPartUploadRequest() request.variant = variant request.variantOutput = variantOutput - request.uploadMultipartEntity(project, mpEntity, manifestInfoProvider.get()) + request.uploadMultipartEntity(project, mpEntity, parseManifestInfo()) } /** diff --git a/src/main/kotlin/com.bugsnag.android.gradle/BugsnagUploadProguardTask.kt b/src/main/kotlin/com.bugsnag.android.gradle/BugsnagUploadProguardTask.kt index 723243e486..ea12662f52 100644 --- a/src/main/kotlin/com.bugsnag.android.gradle/BugsnagUploadProguardTask.kt +++ b/src/main/kotlin/com.bugsnag.android.gradle/BugsnagUploadProguardTask.kt @@ -9,7 +9,6 @@ import org.apache.http.entity.mime.content.FileBody import org.gradle.api.DefaultTask import org.gradle.api.GradleException import org.gradle.api.Project -import org.gradle.api.provider.Property import org.gradle.api.tasks.TaskAction import java.io.File import java.nio.charset.Charset @@ -28,7 +27,7 @@ import java.nio.file.Paths * it is usually safe to have this be the absolute last task executed during * a build. */ -open class BugsnagUploadProguardTask : DefaultTask() { +abstract class BugsnagUploadProguardTask : DefaultTask(), AndroidManifestInfoReceiver { init { group = BugsnagPlugin.GROUP_NAME @@ -37,7 +36,6 @@ open class BugsnagUploadProguardTask : DefaultTask() { lateinit var variantOutput: ApkVariantOutput lateinit var variant: ApkVariant - lateinit var manifestInfoProvider: Property @TaskAction fun upload() { @@ -72,7 +70,7 @@ open class BugsnagUploadProguardTask : DefaultTask() { val request = BugsnagMultiPartUploadRequest() request.variant = variant request.variantOutput = variantOutput - request.uploadMultipartEntity(project, mpEntity, manifestInfoProvider.get()) + request.uploadMultipartEntity(project, mpEntity, parseManifestInfo()) } private fun findMappingFile(project: Project): File? { From e87b2c415b1b91a04130916411a0f885ee561cd1 Mon Sep 17 00:00:00 2001 From: Zac Sweers Date: Fri, 17 Jul 2020 02:06:49 -0400 Subject: [PATCH 09/17] Compute uuid every build, not just on manifest changes --- .../com.bugsnag.android.gradle/AndroidManifestParser.kt | 2 +- .../com.bugsnag.android.gradle/BugsnagManifestUuidTask.kt | 7 ++++++- .../BugsnagManifestUuidTaskV2.kt | 6 +++++- .../kotlin/com.bugsnag.android.gradle/BugsnagPlugin.kt | 7 ++++++- 4 files changed, 18 insertions(+), 4 deletions(-) diff --git a/src/main/kotlin/com.bugsnag.android.gradle/AndroidManifestParser.kt b/src/main/kotlin/com.bugsnag.android.gradle/AndroidManifestParser.kt index dc1dabc8eb..201671f018 100644 --- a/src/main/kotlin/com.bugsnag.android.gradle/AndroidManifestParser.kt +++ b/src/main/kotlin/com.bugsnag.android.gradle/AndroidManifestParser.kt @@ -61,7 +61,7 @@ class AndroidManifestParser { manifestPath: File, outputPath: File = manifestPath, // Uniquely identify the build so that we can identify the proguard file. - buildUuid: String = UUID.randomUUID().toString() + buildUuid: String ) { val root = XmlParser().parse(manifestPath) val application = (root[TAG_APPLICATION] as NodeList)[0] as Node diff --git a/src/main/kotlin/com.bugsnag.android.gradle/BugsnagManifestUuidTask.kt b/src/main/kotlin/com.bugsnag.android.gradle/BugsnagManifestUuidTask.kt index 8ebbb144c7..eaece494d3 100644 --- a/src/main/kotlin/com.bugsnag.android.gradle/BugsnagManifestUuidTask.kt +++ b/src/main/kotlin/com.bugsnag.android.gradle/BugsnagManifestUuidTask.kt @@ -9,7 +9,9 @@ import org.gradle.api.file.Directory import org.gradle.api.file.DirectoryProperty import org.gradle.api.file.RegularFileProperty import org.gradle.api.logging.Logger +import org.gradle.api.provider.Property import org.gradle.api.provider.Provider +import org.gradle.api.tasks.Input import org.gradle.api.tasks.OutputFile import org.gradle.api.tasks.TaskAction import java.io.File @@ -21,6 +23,9 @@ abstract class BaseBugsnagManifestUuidTask : DefaultTask() { description = "Adds a unique build UUID to AndroidManifest to link proguard mappings to crash reports" } + @get:Input + abstract val buildUuid: Property + @get:OutputFile abstract val manifestInfoProvider: RegularFileProperty @@ -55,7 +60,7 @@ abstract class BugsnagManifestUuidTask : BaseBugsnagManifestUuidTask() { // read the manifest information and store it for subsequent tasks val manifestParser = AndroidManifestParser() - manifestParser.writeBuildUuid(manifestPath!!) + manifestParser.writeBuildUuid(manifestPath!!, buildUuid = buildUuid.get()) writeManifestInfo(manifestParser.readManifest(manifestPath, logger)) } diff --git a/src/main/kotlin/com.bugsnag.android.gradle/BugsnagManifestUuidTaskV2.kt b/src/main/kotlin/com.bugsnag.android.gradle/BugsnagManifestUuidTaskV2.kt index 420e9c3d2c..4862779fa8 100644 --- a/src/main/kotlin/com.bugsnag.android.gradle/BugsnagManifestUuidTaskV2.kt +++ b/src/main/kotlin/com.bugsnag.android.gradle/BugsnagManifestUuidTaskV2.kt @@ -44,7 +44,11 @@ abstract class BugsnagManifestUuidTaskV2 : BaseBugsnagManifestUuidTask() { fun updateManifest() { val manifestParser = AndroidManifestParser() val output = updatedManifest.asFile.get() - manifestParser.writeBuildUuid(mergedManifest.asFile.get(), updatedManifest.asFile.get()) + manifestParser.writeBuildUuid( + mergedManifest.asFile.get(), + updatedManifest.asFile.get(), + buildUuid = buildUuid.get() + ) writeManifestInfo(manifestParser.readManifest(output, logger)) } } diff --git a/src/main/kotlin/com.bugsnag.android.gradle/BugsnagPlugin.kt b/src/main/kotlin/com.bugsnag.android.gradle/BugsnagPlugin.kt index d8bf563393..39684b716f 100644 --- a/src/main/kotlin/com.bugsnag.android.gradle/BugsnagPlugin.kt +++ b/src/main/kotlin/com.bugsnag.android.gradle/BugsnagPlugin.kt @@ -15,6 +15,7 @@ import org.gradle.api.Task import org.gradle.api.file.RegularFile import org.gradle.api.provider.Provider import org.gradle.api.tasks.TaskProvider +import java.util.UUID /** * Gradle plugin to automatically upload ProGuard mapping files to Bugsnag. @@ -118,8 +119,11 @@ class BugsnagPlugin : Plugin { output: ApkVariantOutput ): Provider { val taskName = "processBugsnag${taskNameForOutput(output)}Manifest" + val buildUuidProvider = project.provider { UUID.randomUUID().toString() } return if (BugsnagManifestUuidTaskV2.isApplicable()) { - val manifestUpdater = project.tasks.register(taskName, BugsnagManifestUuidTaskV2::class.java) + val manifestUpdater = project.tasks.register(taskName, BugsnagManifestUuidTaskV2::class.java) { + it.buildUuid.set(buildUuidProvider) + } val android = project.extensions.getByType(BaseAppModuleExtension::class.java) android.onVariants.withName(variant.name) { onProperties { @@ -135,6 +139,7 @@ class BugsnagPlugin : Plugin { return manifestUpdater.flatMap(BaseBugsnagManifestUuidTask::manifestInfoProvider) } else { project.tasks.register(taskName, BugsnagManifestUuidTask::class.java) { + it.buildUuid.set(buildUuidProvider) it.variantOutput = output it.variant = variant val processManifest = output.processManifestProvider.orNull From f67efa2865941088ad6cf569ce7e93d90713b2c8 Mon Sep 17 00:00:00 2001 From: Zac Sweers Date: Fri, 17 Jul 2020 02:07:23 -0400 Subject: [PATCH 10/17] Use more obvious naming --- .../BugsnagManifestUuidTaskV2.kt | 10 +++++----- .../kotlin/com.bugsnag.android.gradle/BugsnagPlugin.kt | 4 ++-- 2 files changed, 7 insertions(+), 7 deletions(-) diff --git a/src/main/kotlin/com.bugsnag.android.gradle/BugsnagManifestUuidTaskV2.kt b/src/main/kotlin/com.bugsnag.android.gradle/BugsnagManifestUuidTaskV2.kt index 4862779fa8..581d3b6089 100644 --- a/src/main/kotlin/com.bugsnag.android.gradle/BugsnagManifestUuidTaskV2.kt +++ b/src/main/kotlin/com.bugsnag.android.gradle/BugsnagManifestUuidTaskV2.kt @@ -30,10 +30,10 @@ abstract class BugsnagManifestUuidTaskV2 : BaseBugsnagManifestUuidTask() { // NONE because we only care about its contents, not location. @get:PathSensitive(PathSensitivity.NONE) @get:InputFile - abstract val mergedManifest: RegularFileProperty + abstract val inputManifest: RegularFileProperty @get:OutputFile - abstract val updatedManifest: RegularFileProperty + abstract val outputManifest: RegularFileProperty init { group = BugsnagPlugin.GROUP_NAME @@ -43,10 +43,10 @@ abstract class BugsnagManifestUuidTaskV2 : BaseBugsnagManifestUuidTask() { @TaskAction fun updateManifest() { val manifestParser = AndroidManifestParser() - val output = updatedManifest.asFile.get() + val output = outputManifest.asFile.get() manifestParser.writeBuildUuid( - mergedManifest.asFile.get(), - updatedManifest.asFile.get(), + inputManifest.asFile.get(), + outputManifest.asFile.get(), buildUuid = buildUuid.get() ) writeManifestInfo(manifestParser.readManifest(output, logger)) diff --git a/src/main/kotlin/com.bugsnag.android.gradle/BugsnagPlugin.kt b/src/main/kotlin/com.bugsnag.android.gradle/BugsnagPlugin.kt index 39684b716f..6fc9ebd108 100644 --- a/src/main/kotlin/com.bugsnag.android.gradle/BugsnagPlugin.kt +++ b/src/main/kotlin/com.bugsnag.android.gradle/BugsnagPlugin.kt @@ -130,8 +130,8 @@ class BugsnagPlugin : Plugin { artifacts .use(manifestUpdater) .wiredWithFiles( - BugsnagManifestUuidTaskV2::mergedManifest, - BugsnagManifestUuidTaskV2::updatedManifest + BugsnagManifestUuidTaskV2::inputManifest, + BugsnagManifestUuidTaskV2::outputManifest ) .toTransform(ArtifactType.MERGED_MANIFEST) } From a04ddf1dc02e1c192f81dc8c2175cb3290b56b5a Mon Sep 17 00:00:00 2001 From: Zac Sweers Date: Fri, 17 Jul 2020 02:17:01 -0400 Subject: [PATCH 11/17] Fix detekt issues --- .../kotlin/com.bugsnag.android.gradle/AndroidManifestInfo.kt | 1 + .../kotlin/com.bugsnag.android.gradle/BugsnagUploadNdkTask.kt | 4 +++- 2 files changed, 4 insertions(+), 1 deletion(-) diff --git a/src/main/kotlin/com.bugsnag.android.gradle/AndroidManifestInfo.kt b/src/main/kotlin/com.bugsnag.android.gradle/AndroidManifestInfo.kt index 1029793304..e73320887d 100644 --- a/src/main/kotlin/com.bugsnag.android.gradle/AndroidManifestInfo.kt +++ b/src/main/kotlin/com.bugsnag.android.gradle/AndroidManifestInfo.kt @@ -29,6 +29,7 @@ data class AndroidManifestInfo( "versionName" ) + @Suppress("MagicNumber") // They are indices into the OPTIONS field above private val ADAPTER = object : JsonAdapter() { override fun fromJson(reader: JsonReader): AndroidManifestInfo? { if (reader.peek() == NULL) { diff --git a/src/main/kotlin/com.bugsnag.android.gradle/BugsnagUploadNdkTask.kt b/src/main/kotlin/com.bugsnag.android.gradle/BugsnagUploadNdkTask.kt index 5089e9ce77..930b047c6b 100644 --- a/src/main/kotlin/com.bugsnag.android.gradle/BugsnagUploadNdkTask.kt +++ b/src/main/kotlin/com.bugsnag.android.gradle/BugsnagUploadNdkTask.kt @@ -197,7 +197,9 @@ abstract class BugsnagUploadNdkTask : DefaultTask(), AndroidManifestInfoReceiver val override = getObjDumpOverride(arch) val objDumpFile: File objDumpFile = override?.let { File(it) } ?: findObjDump(project, arch) - check((objDumpFile.exists() && objDumpFile.canExecute())) { "Failed to find executable objdump at $objDumpFile" } + check((objDumpFile.exists() && objDumpFile.canExecute())) { + "Failed to find executable objdump at $objDumpFile" + } return objDumpFile } catch (ex: Throwable) { project.logger.error("Error attempting to calculate objdump location: " + ex.message) From d8cdeb3a44930c3c64a60cac00d485d1ba3bf953 Mon Sep 17 00:00:00 2001 From: Zac Sweers Date: Mon, 20 Jul 2020 01:00:46 -0400 Subject: [PATCH 12/17] Try not using managed properties --- .../AndroidManifestInfoReceiver.kt | 7 ------- .../BugsnagManifestUuidTask.kt | 10 ++++++---- .../BugsnagManifestUuidTaskV2.kt | 8 +++++--- .../BugsnagReleasesTask.kt | 14 +++++++++++++- .../BugsnagUploadNdkTask.kt | 14 +++++++++++++- .../BugsnagUploadProguardTask.kt | 14 +++++++++++++- 6 files changed, 50 insertions(+), 17 deletions(-) diff --git a/src/main/kotlin/com.bugsnag.android.gradle/AndroidManifestInfoReceiver.kt b/src/main/kotlin/com.bugsnag.android.gradle/AndroidManifestInfoReceiver.kt index 47d2e6ef68..c1375cf08c 100644 --- a/src/main/kotlin/com.bugsnag.android.gradle/AndroidManifestInfoReceiver.kt +++ b/src/main/kotlin/com.bugsnag.android.gradle/AndroidManifestInfoReceiver.kt @@ -1,16 +1,9 @@ package com.bugsnag.android.gradle import org.gradle.api.file.RegularFileProperty -import org.gradle.api.tasks.InputFile -import org.gradle.api.tasks.PathSensitive -import org.gradle.api.tasks.PathSensitivity.NONE interface AndroidManifestInfoReceiver { - - @get:PathSensitive(NONE) - @get:InputFile val manifestInfoFile: RegularFileProperty - } internal fun AndroidManifestInfoReceiver.parseManifestInfo(): AndroidManifestInfo { diff --git a/src/main/kotlin/com.bugsnag.android.gradle/BugsnagManifestUuidTask.kt b/src/main/kotlin/com.bugsnag.android.gradle/BugsnagManifestUuidTask.kt index eaece494d3..1ee473fc6a 100644 --- a/src/main/kotlin/com.bugsnag.android.gradle/BugsnagManifestUuidTask.kt +++ b/src/main/kotlin/com.bugsnag.android.gradle/BugsnagManifestUuidTask.kt @@ -9,6 +9,7 @@ import org.gradle.api.file.Directory import org.gradle.api.file.DirectoryProperty import org.gradle.api.file.RegularFileProperty import org.gradle.api.logging.Logger +import org.gradle.api.model.ObjectFactory import org.gradle.api.provider.Property import org.gradle.api.provider.Provider import org.gradle.api.tasks.Input @@ -16,18 +17,19 @@ import org.gradle.api.tasks.OutputFile import org.gradle.api.tasks.TaskAction import java.io.File import java.nio.file.Paths +import javax.inject.Inject -abstract class BaseBugsnagManifestUuidTask : DefaultTask() { +abstract class BaseBugsnagManifestUuidTask(objects: ObjectFactory) : DefaultTask() { init { group = BugsnagPlugin.GROUP_NAME description = "Adds a unique build UUID to AndroidManifest to link proguard mappings to crash reports" } @get:Input - abstract val buildUuid: Property + val buildUuid: Property = objects.property(String::class.java) @get:OutputFile - abstract val manifestInfoProvider: RegularFileProperty + val manifestInfoProvider: RegularFileProperty = objects.fileProperty() fun writeManifestInfo(info: AndroidManifestInfo) { info.write(manifestInfoProvider.get().asFile) @@ -44,7 +46,7 @@ abstract class BaseBugsnagManifestUuidTask : DefaultTask() { * This task must be called after "process${variantName}Manifest", since it * requires that an AndroidManifest.xml exists in `build/intermediates`. */ -abstract class BugsnagManifestUuidTask : BaseBugsnagManifestUuidTask() { +open class BugsnagManifestUuidTask @Inject constructor(objects: ObjectFactory) : BaseBugsnagManifestUuidTask(objects) { lateinit var variantOutput: ApkVariantOutput lateinit var variant: ApkVariant diff --git a/src/main/kotlin/com.bugsnag.android.gradle/BugsnagManifestUuidTaskV2.kt b/src/main/kotlin/com.bugsnag.android.gradle/BugsnagManifestUuidTaskV2.kt index 581d3b6089..4321542405 100644 --- a/src/main/kotlin/com.bugsnag.android.gradle/BugsnagManifestUuidTaskV2.kt +++ b/src/main/kotlin/com.bugsnag.android.gradle/BugsnagManifestUuidTaskV2.kt @@ -2,17 +2,19 @@ package com.bugsnag.android.gradle import com.android.Version import org.gradle.api.file.RegularFileProperty +import org.gradle.api.model.ObjectFactory import org.gradle.api.tasks.InputFile import org.gradle.api.tasks.OutputFile import org.gradle.api.tasks.PathSensitive import org.gradle.api.tasks.PathSensitivity import org.gradle.api.tasks.TaskAction import org.gradle.util.VersionNumber +import javax.inject.Inject /** * An AGP-4-compatible implementation of [BugsnagManifestUuidTask]. */ -abstract class BugsnagManifestUuidTaskV2 : BaseBugsnagManifestUuidTask() { +open class BugsnagManifestUuidTaskV2 @Inject constructor(objects: ObjectFactory) : BaseBugsnagManifestUuidTask(objects) { internal companion object { private val MIN_AGP_VERSION: VersionNumber = VersionNumber.parse("4.1.0-alpha04") @@ -30,10 +32,10 @@ abstract class BugsnagManifestUuidTaskV2 : BaseBugsnagManifestUuidTask() { // NONE because we only care about its contents, not location. @get:PathSensitive(PathSensitivity.NONE) @get:InputFile - abstract val inputManifest: RegularFileProperty + val inputManifest: RegularFileProperty = objects.fileProperty() @get:OutputFile - abstract val outputManifest: RegularFileProperty + val outputManifest: RegularFileProperty = objects.fileProperty() init { group = BugsnagPlugin.GROUP_NAME diff --git a/src/main/kotlin/com.bugsnag.android.gradle/BugsnagReleasesTask.kt b/src/main/kotlin/com.bugsnag.android.gradle/BugsnagReleasesTask.kt index 50ef3616b6..bede25e74d 100644 --- a/src/main/kotlin/com.bugsnag.android.gradle/BugsnagReleasesTask.kt +++ b/src/main/kotlin/com.bugsnag.android.gradle/BugsnagReleasesTask.kt @@ -3,7 +3,12 @@ package com.bugsnag.android.gradle import com.android.build.gradle.api.ApkVariant import com.android.build.gradle.api.ApkVariantOutput import org.gradle.api.DefaultTask +import org.gradle.api.file.RegularFileProperty import org.gradle.api.logging.LogLevel +import org.gradle.api.model.ObjectFactory +import org.gradle.api.tasks.InputFile +import org.gradle.api.tasks.PathSensitive +import org.gradle.api.tasks.PathSensitivity.NONE import org.gradle.api.tasks.TaskAction import org.gradle.process.internal.ExecException import org.json.simple.JSONObject @@ -15,8 +20,11 @@ import java.io.OutputStream import java.net.HttpURLConnection import java.net.URL import java.nio.charset.Charset +import javax.inject.Inject -abstract class BugsnagReleasesTask : DefaultTask(), AndroidManifestInfoReceiver { +open class BugsnagReleasesTask @Inject constructor( + objects: ObjectFactory +) : DefaultTask(), AndroidManifestInfoReceiver { init { group = BugsnagPlugin.GROUP_NAME @@ -26,6 +34,10 @@ abstract class BugsnagReleasesTask : DefaultTask(), AndroidManifestInfoReceiver lateinit var variantOutput: ApkVariantOutput lateinit var variant: ApkVariant + @get:PathSensitive(NONE) + @get:InputFile + override val manifestInfoFile: RegularFileProperty = objects.fileProperty() + @TaskAction fun fetchReleaseInfo() { val manifestInfo = parseManifestInfo() diff --git a/src/main/kotlin/com.bugsnag.android.gradle/BugsnagUploadNdkTask.kt b/src/main/kotlin/com.bugsnag.android.gradle/BugsnagUploadNdkTask.kt index 930b047c6b..9910fd3ab3 100644 --- a/src/main/kotlin/com.bugsnag.android.gradle/BugsnagUploadNdkTask.kt +++ b/src/main/kotlin/com.bugsnag.android.gradle/BugsnagUploadNdkTask.kt @@ -11,12 +11,18 @@ import org.apache.http.entity.mime.content.StringBody import org.apache.tools.ant.taskdefs.condition.Os import org.gradle.api.DefaultTask import org.gradle.api.Project +import org.gradle.api.file.RegularFileProperty +import org.gradle.api.model.ObjectFactory +import org.gradle.api.tasks.InputFile +import org.gradle.api.tasks.PathSensitive +import org.gradle.api.tasks.PathSensitivity.NONE import org.gradle.api.tasks.TaskAction import java.io.File import java.io.FileOutputStream import java.io.InputStream import java.io.Reader import java.util.zip.GZIPOutputStream +import javax.inject.Inject /** * Task to upload shared object mapping files to Bugsnag. @@ -31,7 +37,9 @@ import java.util.zip.GZIPOutputStream * it is usually safe to have this be the absolute last task executed during * a build. */ -abstract class BugsnagUploadNdkTask : DefaultTask(), AndroidManifestInfoReceiver { +open class BugsnagUploadNdkTask @Inject constructor( + objects: ObjectFactory +) : DefaultTask(), AndroidManifestInfoReceiver { init { group = BugsnagPlugin.GROUP_NAME @@ -46,6 +54,10 @@ abstract class BugsnagUploadNdkTask : DefaultTask(), AndroidManifestInfoReceiver lateinit var variantOutput: ApkVariantOutput lateinit var variant: ApkVariant + @get:PathSensitive(NONE) + @get:InputFile + override val manifestInfoFile: RegularFileProperty = objects.fileProperty() + @TaskAction fun upload() { symbolPath = findSymbolPath(variantOutput) diff --git a/src/main/kotlin/com.bugsnag.android.gradle/BugsnagUploadProguardTask.kt b/src/main/kotlin/com.bugsnag.android.gradle/BugsnagUploadProguardTask.kt index ea12662f52..cd5d065ce1 100644 --- a/src/main/kotlin/com.bugsnag.android.gradle/BugsnagUploadProguardTask.kt +++ b/src/main/kotlin/com.bugsnag.android.gradle/BugsnagUploadProguardTask.kt @@ -9,10 +9,16 @@ import org.apache.http.entity.mime.content.FileBody import org.gradle.api.DefaultTask import org.gradle.api.GradleException import org.gradle.api.Project +import org.gradle.api.file.RegularFileProperty +import org.gradle.api.model.ObjectFactory +import org.gradle.api.tasks.InputFile +import org.gradle.api.tasks.PathSensitive +import org.gradle.api.tasks.PathSensitivity.NONE import org.gradle.api.tasks.TaskAction import java.io.File import java.nio.charset.Charset import java.nio.file.Paths +import javax.inject.Inject /** * Task to upload ProGuard mapping files to Bugsnag. @@ -27,7 +33,9 @@ import java.nio.file.Paths * it is usually safe to have this be the absolute last task executed during * a build. */ -abstract class BugsnagUploadProguardTask : DefaultTask(), AndroidManifestInfoReceiver { +open class BugsnagUploadProguardTask @Inject constructor( + objects: ObjectFactory +) : DefaultTask(), AndroidManifestInfoReceiver { init { group = BugsnagPlugin.GROUP_NAME @@ -37,6 +45,10 @@ abstract class BugsnagUploadProguardTask : DefaultTask(), AndroidManifestInfoRec lateinit var variantOutput: ApkVariantOutput lateinit var variant: ApkVariant + @get:PathSensitive(NONE) + @get:InputFile + override val manifestInfoFile: RegularFileProperty = objects.fileProperty() + @TaskAction fun upload() { val mappingFile = findMappingFile(project) From 3165bf3a673d1df8c8e1ec4919ff54404b2c0c76 Mon Sep 17 00:00:00 2001 From: Zac Sweers Date: Mon, 20 Jul 2020 01:02:18 -0400 Subject: [PATCH 13/17] Update comment Co-authored-by: Mike Nakhimovich --- build.gradle | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/build.gradle b/build.gradle index f6ac71c71a..c6475d3c03 100644 --- a/build.gradle +++ b/build.gradle @@ -5,7 +5,7 @@ buildscript { } dependencies { - classpath "com.android.tools.build:gradle:4.1.0-beta04" // compile against 4.0.0, but maintain compat to 3.4.0 + classpath "com.android.tools.build:gradle:4.1.0-beta04" // compile against 4.1.0-beta04, but maintain compat to 3.4.0 classpath "org.jetbrains.kotlin:kotlin-gradle-plugin:1.3.72" classpath "io.gitlab.arturbosch.detekt:detekt-gradle-plugin:1.9.1" } From f4f892bcf0f389809e53073acc4eb21b05bff9a8 Mon Sep 17 00:00:00 2001 From: Zac Sweers Date: Mon, 20 Jul 2020 01:34:45 -0400 Subject: [PATCH 14/17] Fix line length issue --- .../com.bugsnag.android.gradle/BugsnagManifestUuidTaskV2.kt | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/src/main/kotlin/com.bugsnag.android.gradle/BugsnagManifestUuidTaskV2.kt b/src/main/kotlin/com.bugsnag.android.gradle/BugsnagManifestUuidTaskV2.kt index 4321542405..a349b948c4 100644 --- a/src/main/kotlin/com.bugsnag.android.gradle/BugsnagManifestUuidTaskV2.kt +++ b/src/main/kotlin/com.bugsnag.android.gradle/BugsnagManifestUuidTaskV2.kt @@ -14,7 +14,9 @@ import javax.inject.Inject /** * An AGP-4-compatible implementation of [BugsnagManifestUuidTask]. */ -open class BugsnagManifestUuidTaskV2 @Inject constructor(objects: ObjectFactory) : BaseBugsnagManifestUuidTask(objects) { +open class BugsnagManifestUuidTaskV2 @Inject constructor( + objects: ObjectFactory +) : BaseBugsnagManifestUuidTask(objects) { internal companion object { private val MIN_AGP_VERSION: VersionNumber = VersionNumber.parse("4.1.0-alpha04") From 6de8a1a0395d22280d4d4fb5e5c552423bd5ef5a Mon Sep 17 00:00:00 2001 From: Zac Sweers Date: Mon, 20 Jul 2020 01:40:28 -0400 Subject: [PATCH 15/17] Fix missing outputfile configuration --- src/main/kotlin/com.bugsnag.android.gradle/BugsnagPlugin.kt | 3 +++ 1 file changed, 3 insertions(+) diff --git a/src/main/kotlin/com.bugsnag.android.gradle/BugsnagPlugin.kt b/src/main/kotlin/com.bugsnag.android.gradle/BugsnagPlugin.kt index 6fc9ebd108..ccb615723e 100644 --- a/src/main/kotlin/com.bugsnag.android.gradle/BugsnagPlugin.kt +++ b/src/main/kotlin/com.bugsnag.android.gradle/BugsnagPlugin.kt @@ -120,9 +120,11 @@ class BugsnagPlugin : Plugin { ): Provider { val taskName = "processBugsnag${taskNameForOutput(output)}Manifest" val buildUuidProvider = project.provider { UUID.randomUUID().toString() } + val manifestInfoOutputFile = project.layout.buildDirectory.file("intermediates/bugsnag/manifestInfoFor${taskNameForOutput(output)}.json") return if (BugsnagManifestUuidTaskV2.isApplicable()) { val manifestUpdater = project.tasks.register(taskName, BugsnagManifestUuidTaskV2::class.java) { it.buildUuid.set(buildUuidProvider) + it.manifestInfoProvider.set(manifestInfoOutputFile) } val android = project.extensions.getByType(BaseAppModuleExtension::class.java) android.onVariants.withName(variant.name) { @@ -142,6 +144,7 @@ class BugsnagPlugin : Plugin { it.buildUuid.set(buildUuidProvider) it.variantOutput = output it.variant = variant + it.manifestInfoProvider.set(manifestInfoOutputFile) val processManifest = output.processManifestProvider.orNull if (processManifest != null) { From 82008927fc1155a1d301f7a4c0a192f7dfefdc08 Mon Sep 17 00:00:00 2001 From: fractalwrench Date: Mon, 20 Jul 2020 10:21:08 +0100 Subject: [PATCH 16/17] style: fix ci check --- src/main/kotlin/com.bugsnag.android.gradle/BugsnagPlugin.kt | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/src/main/kotlin/com.bugsnag.android.gradle/BugsnagPlugin.kt b/src/main/kotlin/com.bugsnag.android.gradle/BugsnagPlugin.kt index ccb615723e..01c7204c76 100644 --- a/src/main/kotlin/com.bugsnag.android.gradle/BugsnagPlugin.kt +++ b/src/main/kotlin/com.bugsnag.android.gradle/BugsnagPlugin.kt @@ -120,7 +120,8 @@ class BugsnagPlugin : Plugin { ): Provider { val taskName = "processBugsnag${taskNameForOutput(output)}Manifest" val buildUuidProvider = project.provider { UUID.randomUUID().toString() } - val manifestInfoOutputFile = project.layout.buildDirectory.file("intermediates/bugsnag/manifestInfoFor${taskNameForOutput(output)}.json") + val path = "intermediates/bugsnag/manifestInfoFor${taskNameForOutput(output)}.json" + val manifestInfoOutputFile = project.layout.buildDirectory.file(path) return if (BugsnagManifestUuidTaskV2.isApplicable()) { val manifestUpdater = project.tasks.register(taskName, BugsnagManifestUuidTaskV2::class.java) { it.buildUuid.set(buildUuidProvider) From 19c78539992e1e9fd31b5c782a5015a8107a247a Mon Sep 17 00:00:00 2001 From: fractalwrench Date: Mon, 20 Jul 2020 10:23:25 +0100 Subject: [PATCH 17/17] docs: add changelog entry --- CHANGELOG.md | 3 +++ 1 file changed, 3 insertions(+) diff --git a/CHANGELOG.md b/CHANGELOG.md index a1fc5dee57..fad7fbbf08 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,5 +1,8 @@ ## 5.0.0 (TBD) +Support for manifest processing in AGP 4.1.0-alpha04 and above +[#234](https://github.com/bugsnag/bugsnag-android-gradle-plugin/pull/234) + Alter bugsnag tasks to support the Incremental Build API [#230](https://github.com/bugsnag/bugsnag-android-gradle-plugin/pull/230)