io.sentry.android.gradle.AppConfig.kt Maven / Gradle / Ivy
The newest version!
package io.sentry.android.gradle
import com.android.build.gradle.AppExtension
import com.android.build.gradle.api.ApplicationVariant
import com.android.build.gradle.api.BaseVariant
import io.sentry.android.gradle.SentryPlugin.Companion.sep
import io.sentry.android.gradle.SentryPropertiesFileProvider.getPropertiesFilePath
import io.sentry.android.gradle.SentryTasksProvider.capitalized
import io.sentry.android.gradle.SentryTasksProvider.getLintVitalAnalyzeProvider
import io.sentry.android.gradle.SentryTasksProvider.getLintVitalReportProvider
import io.sentry.android.gradle.SentryTasksProvider.getMergeAssetsProvider
import io.sentry.android.gradle.extensions.SentryPluginExtension
import io.sentry.android.gradle.sourcecontext.OutputPaths
import io.sentry.android.gradle.sourcecontext.SourceContext
import io.sentry.android.gradle.tasks.PropertiesFileOutputTask
import io.sentry.android.gradle.tasks.SentryGenerateDebugMetaPropertiesTask
import io.sentry.android.gradle.tasks.SentryGenerateProguardUuidTask
import io.sentry.android.gradle.tasks.SentryUploadProguardMappingsTask
import io.sentry.android.gradle.tasks.configureNativeSymbolsTask
import io.sentry.android.gradle.tasks.dependencies.SentryExternalDependenciesReportTaskFactory
import io.sentry.android.gradle.telemetry.SentryTelemetryService
import io.sentry.android.gradle.util.AgpVersions
import io.sentry.android.gradle.util.AgpVersions.isAGP74
import io.sentry.android.gradle.util.GroovyCompat
import io.sentry.android.gradle.util.ReleaseInfo
import io.sentry.android.gradle.util.SentryPluginUtils.isMinificationEnabled
import io.sentry.android.gradle.util.SentryPluginUtils.isVariantAllowed
import io.sentry.android.gradle.util.SentryPluginUtils.withLogging
import io.sentry.android.gradle.util.hookWithAssembleTasks
import io.sentry.android.gradle.util.hookWithMinifyTasks
import io.sentry.android.gradle.util.hookWithPackageTasks
import io.sentry.android.gradle.util.info
import org.gradle.api.Project
import org.gradle.api.Task
import org.gradle.api.file.Directory
import org.gradle.api.provider.Provider
import org.gradle.api.tasks.TaskProvider
import org.gradle.internal.build.event.BuildEventListenerRegistryInternal
fun AppExtension.configure(
project: Project,
extension: SentryPluginExtension,
cliExecutable: Provider,
sentryOrg: String?,
sentryProject: String?,
buildEvents: BuildEventListenerRegistryInternal
) {
applicationVariants.matching {
isVariantAllowed(extension, it.name, it.flavorName, it.buildType.name)
}.configureEach { variant ->
val mergeAssetsDependants = setOf(
getMergeAssetsProvider(variant),
// lint vital tasks scan the entire "build" folder; since we're writing our
// generated stuff in there, we put explicit dependency on them to avoid
// warnings about implicit dependency
withLogging(project.logger, "lintVitalAnalyzeTask") {
getLintVitalAnalyzeProvider(project, variant.name)
},
withLogging(project.logger, "lintVitalReportTask") {
getLintVitalReportProvider(project, variant.name)
}
)
val sentryTelemetryProvider = variant.configureTelemetry(
project,
extension,
cliExecutable,
sentryOrg,
sentryProject,
buildEvents
)
// TODO: do this only once, and all other tasks should be SentryVariant.configureSomething
val sentryVariant = if (isAGP74) null else AndroidVariant70(variant)
sentryVariant?.configureNativeSymbolsTask(
project,
extension,
sentryTelemetryProvider,
cliExecutable,
sentryOrg,
sentryProject
)
val additionalSourcesProvider = project.provider {
extension.additionalSourceDirsForSourceContext.getOrElse(emptySet())
.map { project.layout.projectDirectory.dir(it) }
}
val sourceFiles = sentryVariant?.sources(
project,
additionalSourcesProvider
)
val tasksGeneratingProperties = mutableListOf>()
val sourceContextTasks = variant.configureSourceBundleTasks(
project,
extension,
sentryTelemetryProvider,
sourceFiles,
cliExecutable,
sentryOrg,
sentryProject
)
sourceContextTasks?.let { tasksGeneratingProperties.add(it.generateBundleIdTask) }
variant.configureDependenciesTask(
project,
extension,
sentryTelemetryProvider,
this,
mergeAssetsDependants
)
val generateProguardUuidTask = variant.configureProguardMappingsTasks(
project,
extension,
sentryTelemetryProvider,
cliExecutable,
sentryOrg,
sentryProject
)
generateProguardUuidTask?.let { tasksGeneratingProperties.add(it) }
variant.configureDebugMetaPropertiesTask(
project,
extension,
this,
sentryTelemetryProvider,
mergeAssetsDependants,
tasksGeneratingProperties
)
}
}
private fun ApplicationVariant.configureTelemetry(
project: Project,
extension: SentryPluginExtension,
cliExecutable: Provider,
sentryOrg: String?,
sentryProject: String?,
buildEvents: BuildEventListenerRegistryInternal
): Provider {
val variant = if (isAGP74) null else AndroidVariant70(this)
val sentryTelemetryProvider = SentryTelemetryService.register(project)
project.gradle.taskGraph.whenReady {
sentryTelemetryProvider.get().start {
SentryTelemetryService.createParameters(
project,
variant,
extension,
cliExecutable,
sentryOrg,
"Android"
)
}
buildEvents.onOperationCompletion(sentryTelemetryProvider)
}
return sentryTelemetryProvider
}
private fun ApplicationVariant.configureDebugMetaPropertiesTask(
project: Project,
extension: SentryPluginExtension,
appExtension: AppExtension,
sentryTelemetryProvider: Provider,
dependants: Set?>,
tasksGeneratingProperties: List>
) {
if (isAGP74) {
project.logger.info {
"Not configuring deprecated AppExtension for ${AgpVersions.CURRENT}, " +
"new AppComponentsExtension will be configured"
}
} else {
val variant = AndroidVariant70(this)
val taskSuffix = name.capitalized
val outputDir = project.layout.buildDirectory.dir(
"generated${sep}assets${sep}sentry${sep}debug-meta-properties${sep}$name"
)
val generateDebugMetaPropertiesTask = SentryGenerateDebugMetaPropertiesTask.register(
project,
extension,
sentryTelemetryProvider,
tasksGeneratingProperties,
outputDir,
taskSuffix
)
generateDebugMetaPropertiesTask.setupMergeAssetsDependencies(dependants)
generateDebugMetaPropertiesTask.hookWithPackageTasks(project, variant)
appExtension.sourceSets.getByName(name).assets.srcDir(
generateDebugMetaPropertiesTask.flatMap { it.output }
)
}
}
private fun ApplicationVariant.configureSourceBundleTasks(
project: Project,
extension: SentryPluginExtension,
sentryTelemetryProvider: Provider,
sourceFiles: Provider>?,
cliExecutable: Provider,
sentryOrg: String?,
sentryProject: String?
): SourceContext.SourceContextTasks? {
if (isAGP74) {
project.logger.info {
"Not configuring deprecated AppExtension for ${AgpVersions.CURRENT}, " +
"new AppComponentsExtension will be configured"
}
return null
} else if (extension.includeSourceContext.get()) {
val paths = OutputPaths(project, name)
val variant = AndroidVariant70(this)
val taskSuffix = name.capitalized
val sourceContextTasks = SourceContext.register(
project,
extension,
sentryTelemetryProvider,
variant,
paths,
sourceFiles,
cliExecutable,
sentryOrg,
sentryProject,
taskSuffix
)
if (variant.buildTypeName == "release") {
sourceContextTasks.uploadSourceBundleTask.hookWithAssembleTasks(project, variant)
}
return sourceContextTasks
} else {
return null
}
}
private fun BaseVariant.configureDependenciesTask(
project: Project,
extension: SentryPluginExtension,
sentryTelemetryProvider: Provider,
appExtension: AppExtension,
dependants: Set?>
) {
if (isAGP74) {
project.logger.info {
"Not configuring deprecated AppExtension for ${AgpVersions.CURRENT}, " +
"new AppComponentsExtension will be configured"
}
} else if (extension.includeDependenciesReport.get()) {
val outputDir = project.layout.buildDirectory.dir(
"generated${sep}assets${sep}sentry${sep}dependencies${sep}$name"
)
val reportDependenciesTask =
SentryExternalDependenciesReportTaskFactory.register(
project = project,
extension,
sentryTelemetryProvider,
configurationName = "${name}RuntimeClasspath",
attributeValueJar = "android-classes",
includeReport = extension.includeDependenciesReport,
output = outputDir,
taskSuffix = name.capitalized
)
reportDependenciesTask.setupMergeAssetsDependencies(dependants)
appExtension.sourceSets.getByName(name).assets.srcDir(
reportDependenciesTask.flatMap { it.output }
)
}
}
private fun ApplicationVariant.configureProguardMappingsTasks(
project: Project,
extension: SentryPluginExtension,
sentryTelemetryProvider: Provider,
cliExecutable: Provider,
sentryOrg: String?,
sentryProject: String?
): TaskProvider? {
if (isAGP74) {
project.logger.info {
"Not configuring deprecated AppExtension for ${AgpVersions.CURRENT}, " +
"new AppComponentsExtension will be configured"
}
return null
} else {
val variant = AndroidVariant70(this)
val sentryProps = getPropertiesFilePath(project, variant)
val dexguardEnabled = extension.dexguardEnabled.get()
val isMinifyEnabled = isMinificationEnabled(project, variant, dexguardEnabled)
val outputDir = project.layout.buildDirectory.dir(
"generated${sep}assets${sep}sentry${sep}proguard${sep}$name"
)
if (isMinifyEnabled && extension.includeProguardMapping.get()) {
val generateUuidTask =
SentryGenerateProguardUuidTask.register(
project = project,
extension,
sentryTelemetryProvider,
output = outputDir,
proguardMappingFile = SentryTasksProvider.getMappingFileProvider(
project,
variant,
dexguardEnabled
),
taskSuffix = name.capitalized
)
val versionName = versionName ?: "undefined"
val versionCode = if (versionCode == -1) {
null
} else {
versionCode
}
val releaseInfo = ReleaseInfo(applicationId, versionName, versionCode)
val uploadMappingsTask = SentryUploadProguardMappingsTask.register(
project = project,
extension,
sentryTelemetryProvider,
debug = extension.debug,
cliExecutable = cliExecutable,
generateUuidTask = generateUuidTask,
sentryProperties = sentryProps,
mappingFiles = SentryTasksProvider.getMappingFileProvider(
project,
variant,
dexguardEnabled
),
autoUploadProguardMapping = extension.autoUploadProguardMapping,
sentryOrg = sentryOrg?.let { project.provider { it } } ?: extension.org,
sentryProject = sentryProject?.let { project.provider { it } }
?: extension.projectName,
sentryAuthToken = extension.authToken,
taskSuffix = name.capitalized,
releaseInfo = releaseInfo,
sentryUrl = extension.url
)
generateUuidTask.hookWithMinifyTasks(
project,
name,
dexguardEnabled && GroovyCompat.isDexguardEnabledForVariant(project, name)
)
uploadMappingsTask.hookWithAssembleTasks(
project,
variant
)
return generateUuidTask
} else {
return null
}
}
}
private fun TaskProvider.setupMergeAssetsDependencies(
dependants: Set?>
) {
dependants.forEach {
it?.configure { task ->
task.dependsOn(this)
}
}
}
© 2015 - 2025 Weber Informatics LLC | Privacy Policy