com.bugsnag.android.gradle.AndroidManifestParser.kt Maven / Gradle / Ivy
Go to download
Show more of this group Show more artifacts with this name
Show all versions of bugsnag-android-gradle-plugin Show documentation
Show all versions of bugsnag-android-gradle-plugin Show documentation
Gradle plugin to automatically upload ProGuard mapping files to Bugsnag.
package com.bugsnag.android.gradle
import groovy.util.Node
import groovy.util.NodeList
import groovy.util.XmlNodePrinter
import groovy.util.XmlParser
import groovy.xml.Namespace
import org.gradle.api.logging.Logger
import org.xml.sax.SAXException
import java.io.File
import java.io.FileWriter
import java.io.IOException
import java.io.PrintWriter
import javax.xml.parsers.ParserConfigurationException
internal class AndroidManifestParser {
private val namespace = Namespace("http://schemas.android.com/apk/res/android", "android")
fun readManifest(manifestPath: File, logger: Logger): AndroidManifestInfo {
logger.debug("Bugsnag: Reading manifest at: $manifestPath")
val root = XmlParser().parse(manifestPath)
val application = (root[TAG_APPLICATION] as NodeList)[0] as Node
val metadataTags = findMetadataTags(application)
// Get the Bugsnag API key
val apiKey = getManifestMetaData(metadataTags, TAG_API_KEY)
if (apiKey == null) {
logger.warn("Bugsnag: Could not find apiKey in '$TAG_API_KEY' " +
" tag in your AndroidManifest.xml")
}
// Get the build version
val versionCode = getVersionCode(metadataTags, root)
if (versionCode == null) {
logger.warn("Bugsnag: Could not find 'android:versionCode' value in your AndroidManifest.xml")
}
// Uniquely identify the build so that we can identify the proguard file.
val buildUUID = getManifestMetaData(metadataTags, TAG_BUILD_UUID)
if (buildUUID == null) {
logger.warn("Bugsnag: Could not find '$TAG_BUILD_UUID'" +
" tag in your AndroidManifest.xml")
}
// Get the version name
val versionName = getVersionName(metadataTags, root)
if (versionName == null) {
logger.warn("Bugsnag: Could not find 'android:versionName' value in your AndroidManifest.xml")
}
// Get the application ID
val applicationId = getApplicationId(root)
if (applicationId == null) {
logger.warn("Bugsnag: Could not find 'package' value in your AndroidManifest.xml")
}
if (apiKey == null || "" == apiKey || versionCode == null ||
buildUUID == null || versionName == null || applicationId == null) {
throw IllegalStateException(
"""Bugsnag: Missing apiKey/versionCode/buildUuid/versionName/package, required to upload to bugsnag.
|apiKey=$apiKey
|versionCode=$versionCode
|buildUUID=$buildUUID
|versionName=$versionName
|applicationId=$applicationId
|Manifest file = $manifestPath
""".trimMargin())
}
return AndroidManifestInfo(apiKey, versionCode, buildUUID, versionName, applicationId)
}
@Throws(ParserConfigurationException::class, SAXException::class, IOException::class)
fun writeBuildUuid(
manifestPath: File,
outputPath: File = manifestPath,
// Uniquely identify the build so that we can identify the proguard file.
buildUuid: String
) {
val root = XmlParser().parse(manifestPath)
val application = (root[TAG_APPLICATION] as NodeList)[0] as Node
val metadataTags = findMetadataTags(application)
// Add the new BUILD_UUID_TAG element
if (!hasBuildUuid(metadataTags)) {
application.appendNode(TAG_META_DATA, hashMapOf(
namespace.get(ATTR_NAME) to TAG_BUILD_UUID,
namespace.get(ATTR_VALUE) to buildUuid
))
}
// Write the manifest file
FileWriter(outputPath).use {
val printer = XmlNodePrinter(PrintWriter(it))
printer.isPreserveWhitespace = true
printer.print(root)
}
}
private fun findMetadataTags(application: Node): List {
return application.children()
.asSequence()
.filterIsInstance()
.filter { TAG_META_DATA == it.name() }
.toList()
}
private fun hasBuildUuid(metadataTags: List): Boolean {
return getManifestMetaData(metadataTags, TAG_BUILD_UUID) != null
}
private fun getManifestMetaData(metadataTags: List, key: String): String? {
val node = metadataTags.find {
val name = it.attribute(namespace.get(ATTR_NAME))
key == name
}
return node?.attribute(namespace.get(ATTR_VALUE)) as String?
}
private fun getVersionName(metaDataTags: List, xml: Node): String? {
val versionName = getManifestMetaData(metaDataTags, TAG_APP_VERSION)
return versionName ?: xml.attribute(namespace.get(ATTR_VERSION_NAME)) as String?
}
private fun getVersionCode(metaDataTags: List, xml: Node): String? {
val versionCode = getManifestMetaData(metaDataTags, TAG_VERSION_CODE)
return versionCode ?: xml.attribute(namespace.get(ATTR_VERSION_CODE)) as String?
}
private fun getApplicationId(xml: Node): String? {
return xml.attribute(ATTR_APPLICATION_ID) as String?
}
companion object {
private const val TAG_APPLICATION = "application"
private const val TAG_META_DATA = "meta-data"
private const val TAG_API_KEY = "com.bugsnag.android.API_KEY"
private const val TAG_BUILD_UUID = "com.bugsnag.android.BUILD_UUID"
private const val TAG_VERSION_CODE = "com.bugsnag.android.VERSION_CODE"
private const val TAG_APP_VERSION = "com.bugsnag.android.APP_VERSION"
private const val ATTR_NAME = "name"
private const val ATTR_VALUE = "value"
private const val ATTR_APPLICATION_ID = "package"
private const val ATTR_VERSION_CODE = "versionCode"
private const val ATTR_VERSION_NAME = "versionName"
}
}
© 2015 - 2025 Weber Informatics LLC | Privacy Policy