All Downloads are FREE. Search and download functionalities are using the official Maven repository.

com.bugsnag.android.gradle.BugsnagUploadProguardTask.groovy Maven / Gradle / Ivy

There is a newer version: 8.1.0
Show newest version
package com.bugsnag.android.gradle

import org.apache.http.entity.mime.HttpMultipartMode
import org.apache.http.entity.mime.MultipartEntity
import org.apache.http.entity.mime.content.FileBody
import org.gradle.api.GradleException
import org.gradle.api.Project
import org.gradle.api.tasks.TaskAction

import java.nio.charset.Charset
import java.nio.file.Paths

/**
 Task to upload ProGuard mapping files to Bugsnag.

 Reads meta-data tags from the project's AndroidManifest.xml to extract a
 build UUID (injected by BugsnagManifestTask) and a Bugsnag API Key:

 https://developer.android.com/guide/topics/manifest/manifest-intro.html
 https://developer.android.com/guide/topics/manifest/meta-data-element.html

 This task must be called after ProGuard mapping files are generated, so
 it is usually safe to have this be the absolute last task executed during
 a build.
 */
class BugsnagUploadProguardTask extends BugsnagMultiPartUploadTask {

    String partName

    BugsnagUploadProguardTask() {
        super()
        this.description = "Uploads the mapping file to Bugsnag"
    }

    @TaskAction
    void upload() {
        File mappingFile = findMappingFile()
        project.logger.info("Using mapping file: $mappingFile")

        // If we haven't enabled proguard for this variant, or the proguard
        // configuration includes -dontobfuscate, the mapping file
        // will not exist (but we also won't need it).
        if (!mappingFile || !mappingFile.exists()) {
            project.logger.warn("Mapping file not found: ${mappingFile}")
            if (project.bugsnag.failOnUploadError) {
                throw new GradleException("Mapping file not found: ${mappingFile}")
            } else {
                return
            }
        } else if (mappingFile.length() == 0) { // proguard's -dontobfuscate generates an empty mapping file
            return
        }

        // Read the API key and Build ID etc..
        super.readManifestFile()
        project.logger.info("Attempting to upload mapping file: ${mappingFile}")

        // Construct a basic request
        Charset charset = Charset.forName("UTF-8")
        MultipartEntity mpEntity = new MultipartEntity(HttpMultipartMode.BROWSER_COMPATIBLE, null, charset)
        mpEntity.addPart(partName, new FileBody(mappingFile))

        // Send the request
        super.uploadMultipartEntity(mpEntity)
    }

    private File findMappingFile() {
        if (BugsnagPlugin.hasDexguardPlugin(project) && BugsnagPlugin.hasMultipleOutputs(project)) {
            File mappingFile = findDexguardMappingFile(project)

            if (mappingFile && mappingFile.exists()) {
                return mappingFile
            } else {
                project.logger.warn("Could not find DexGuard mapping file at: $mappingFile -" +
                    " falling back to AGP mapping file value")
            }
        }
        // use AGP supplied value by default, or as fallback
        variant.mappingFile
    }

    /**
     * Retrieves the location of a DexGuard mapping file for the given variantOutput. The expected location for this
     * is: build/outputs/mapping///
     *
     * variant.mappingFile cannot currently be overridden using the AGP DSL on a per-variantOutput basis, which
     * necessitates this workaround. https://issuetracker.google.com/issues/78921539
     */
    File findDexguardMappingFile(Project project) {
        String buildDir = project.buildDir.toString()
        String outputDir = variantOutput.dirName

        if (variantOutput.dirName.endsWith("dpi" + File.separator)) {
            outputDir = new File(variantOutput.dirName).parent

            if (outputDir == null) { // if only density splits enabled
                outputDir = ""
            }
        }
        Paths.get(buildDir, "outputs", "mapping", variant.dirName, outputDir, "mapping.txt").toFile()
    }

}




© 2015 - 2025 Weber Informatics LLC | Privacy Policy