c2c-sync/app/build.gradle
2025-10-05 16:07:21 +02:00

587 lines
18 KiB
Groovy

/*
* Nextcloud - Android Client
*
* SPDX-FileCopyrightText: 2016-2024 Nextcloud GmbH and Nextcloud contributors
* SPDX-FileCopyrightText: 2024 Alper Ozturk <alper.ozturk@nextcloud.com>
* SPDX-FileCopyrightText: 2024 Tobias Kaminsky <tobias@kaminsky.me>
* SPDX-FileCopyrightText: 2024 Andy Scherzinger <info@andy-scherzinger.de>
* SPDX-FileCopyrightText: 2022 Álvaro Brey Vilas <alvaro@alvarobrey.com>
* SPDX-License-Identifier: AGPL-3.0-or-later OR GPL-2.0-only
*/
import com.github.spotbugs.snom.Confidence
import com.github.spotbugs.snom.Effort
import com.github.spotbugs.snom.SpotBugsTask
import org.gradle.internal.jvm.Jvm
buildscript {
dependencies {
classpath "com.android.tools.build:gradle:$androidPluginVersion"
classpath libs.spotbugs.gradle.plugin
classpath libs.kotlin.gradle.plugin
classpath libs.detekt.gradle.plugin
classpath libs.commons.httpclient.commons.httpclient // remove after entire switch to lib v2
classpath libs.shot
classpath "org.jacoco:org.jacoco.core:$jacoco_version"
classpath "org.jacoco:org.jacoco.report:$jacoco_version"
classpath "org.jacoco:org.jacoco.agent:$jacoco_version"
}
}
plugins {
alias(libs.plugins.kotlin.compose)
alias(libs.plugins.spotless)
alias(libs.plugins.kapt)
alias(libs.plugins.ksp) apply false
}
apply plugin: "com.android.application"
apply plugin: "kotlin-android"
apply plugin: "kotlin-parcelize"
apply plugin: "checkstyle"
apply plugin: "pmd"
apply from: "$rootProject.projectDir/jacoco.gradle"
apply plugin: "com.github.spotbugs"
apply plugin: "io.gitlab.arturbosch.detekt"
// needed to make renovate run without shot, as shot requires Android SDK
// https://github.com/pedrovgs/Shot/issues/300
if (shotTest) {
apply plugin: "shot"
}
apply plugin: "com.google.devtools.ksp"
println "Gradle uses Java ${Jvm.current()}"
configurations {
configureEach {
exclude group: "org.jetbrains", module: "annotations-java5" // via prism4j, already using annotations explicitly
}
}
configurations.configureEach {
resolutionStrategy.eachDependency {
if (requested.group == "org.checkerframework" && requested.name != "checker-compat-qual") {
useVersion(checkerVersion)
because("https://github.com/google/ExoPlayer/issues/10007")
}
if (requested.group == "commons-logging" && requested.name == "commons-logging") {
useTarget("org.slf4j:jcl-over-slf4j:1.7.4")
}
}
}
// semantic versioning for version code
def versionMajor = 3
def versionMinor = 34
def versionPatch = 0
def versionBuild = 90 // 0-50=Alpha / 51-98=RC / 90-99=stable
def ndkEnv = new HashMap<String, String>()
file("$project.rootDir/ndk.env").readLines().each() {
def (key, value) = it.tokenize("=")
ndkEnv.put(key, value)
}
def perfAnalysis = project.hasProperty("perfAnalysis")
def getConfigProperties() {
def props = new Properties()
def file = rootProject.file(".gradle/config.properties")
if (file.exists()) {
props.load(new FileInputStream(file))
}
return props
}
def configProps = getConfigProperties()
android {
// install this NDK version and Cmake to produce smaller APKs. Build will still work if not installed
ndkVersion = "${ndkEnv.get("NDK_VERSION")}"
namespace = "com.owncloud.android"
testNamespace = "${namespace}.test"
androidResources {
generateLocaleConfig = true
}
defaultConfig {
applicationId = "com.nextcloud.client"
minSdk = 27
targetSdk = 35
compileSdk = 35
buildConfigField "boolean", "CI", ciBuild.toString()
buildConfigField "boolean", "RUNTIME_PERF_ANALYSIS", perfAnalysis.toString()
javaCompileOptions {
annotationProcessorOptions {
arguments += ["room.schemaLocation": "$projectDir/schemas".toString()]
}
}
// arguments to be passed to functional tests
if (shotTest) {
testInstrumentationRunner "com.karumi.shot.ShotTestRunner"
} else {
testInstrumentationRunner "com.nextcloud.client.TestRunner"
}
testInstrumentationRunnerArgument "TEST_SERVER_URL", "${NC_TEST_SERVER_BASEURL}"
testInstrumentationRunnerArgument "TEST_SERVER_USERNAME", "${NC_TEST_SERVER_USERNAME}"
testInstrumentationRunnerArgument "TEST_SERVER_PASSWORD", "${NC_TEST_SERVER_PASSWORD}"
testInstrumentationRunnerArguments disableAnalytics: "true"
versionCode versionMajor * 10000000 + versionMinor * 10000 + versionPatch * 100 + versionBuild
if (versionBuild > 89) {
versionName "${versionMajor}.${versionMinor}.${versionPatch}"
} else if (versionBuild > 50) {
versionName "${versionMajor}.${versionMinor}.${versionPatch} RC" + (versionBuild - 50)
} else {
versionName "${versionMajor}.${versionMinor}.${versionPatch} Alpha" + (versionBuild + 1)
}
// adapt structure from Eclipse to Gradle/Android Studio expectations;
// see http://tools.android.com/tech-docs/new-build-system/user-guide#TOC-Configuring-the-Structure
flavorDimensions += "default"
buildTypes {
release {
buildConfigField "String", "NC_TEST_SERVER_DATA_STRING", "\"\""
}
debug {
testCoverageEnabled = project.hasProperty("coverage")
resConfigs "xxxhdpi"
buildConfigField "String", "NC_TEST_SERVER_DATA_STRING", "\"nc://login/user:${configProps['NC_TEST_SERVER_USERNAME']}&password:${configProps['NC_TEST_SERVER_PASSWORD']}&server:${configProps['NC_TEST_SERVER_BASEURL']}\""
}
}
buildFeatures {
buildConfig = true
}
productFlavors {
// used for f-droid
generic {
applicationId "com.nextcloud.client"
dimension "default"
}
gplay {
applicationId "com.nextcloud.client"
dimension "default"
}
huawei {
applicationId "com.nextcloud.client"
dimension "default"
}
versionDev {
applicationId "com.nextcloud.android.beta"
dimension "default"
versionCode 20220322
versionName "20220322"
}
qa {
applicationId "com.nextcloud.android.qa"
dimension "default"
versionCode 1
versionName "1"
}
}
testOptions {
unitTests.returnDefaultValues = true
animationsDisabled = true
}
}
// adapt structure from Eclipse to Gradle/Android Studio expectations;
// see http://tools.android.com/tech-docs/new-build-system/user-guide#TOC-Configuring-the-Structure
packagingOptions {
resources {
excludes += "META-INF/LICENSE*"
excludes += "META-INF/versions/9/OSGI-INF/MANIFEST*"
pickFirst "MANIFEST.MF" // workaround for duplicated manifest on some dependencies
}
}
tasks.register("checkstyle", Checkstyle) {
configFile = file("${rootProject.projectDir}/checkstyle.xml")
configProperties.checkstyleSuppressionsPath = file("${project.rootDir}/config/quality/checkstyle/suppressions.xml").absolutePath
source "src"
include "**/*.java"
exclude "**/gen/**"
classpath = files()
}
tasks.register("pmd", Pmd) {
ruleSetFiles = files("${project.rootDir}/ruleset.xml")
ignoreFailures = true // should continue checking
ruleSets = []
source "src"
include "**/*.java"
exclude "**/gen/**"
reports {
xml {
destination = layout.buildDirectory.file("reports/pmd/pmd.xml").get().asFile
}
html {
destination = layout.buildDirectory.file("reports/pmd/pmd.html").get().asFile
}
}
}
check.dependsOn "checkstyle", "spotbugsGplayDebug", "pmd", "lint", "spotlessKotlinCheck", "detekt"
buildFeatures {
dataBinding = true
viewBinding = true
aidl = true
compose = true
}
compileOptions {
sourceCompatibility JavaVersion.VERSION_17
targetCompatibility JavaVersion.VERSION_17
}
kotlinOptions {
jvmTarget = "17"
}
lint {
abortOnError = false
checkGeneratedSources = true
disable "MissingTranslation", "GradleDependency", "VectorPath", "IconMissingDensityFolder", "IconDensities", "GoogleAppIndexingWarning", "MissingDefaultResource", "InvalidPeriodicWorkRequestInterval", "StringFormatInvalid", "MissingQuantity"
htmlOutput = layout.buildDirectory.file("reports/lint/lint.html").get().asFile
htmlReport = true
}
sourceSets {
// Adds exported schema location as test app assets.
androidTest.assets.srcDirs += files("$projectDir/schemas".toString())
}
kapt {
useBuildCache = true
}
}
dependencies {
// region Nextcloud library
implementation("com.github.nextcloud:android-library:$androidLibraryVersion") {
exclude group: "org.ogce", module: "xpp3" // unused in Android and brings wrong Junit version
}
// endregion
// region Splash Screen
implementation libs.splashscreen
// endregion
// region Jetpack Compose
implementation(platform(libs.compose.bom))
implementation(libs.compose.ui)
implementation(libs.compose.ui.graphics)
implementation(libs.compose.material3)
debugImplementation(libs.compose.ui.tooling)
implementation(libs.compose.ui.tooling.preview)
// endregion
// region Media3
implementation libs.media3.ui
implementation libs.media3.session
implementation libs.media3.exoplayer
implementation libs.media3.datasource
// endregion
// region Room
implementation libs.room.runtime
ksp "androidx.room:room-compiler:$roomVersion"
androidTestImplementation libs.room.testing
// endregion
// region Espresso
androidTestImplementation libs.espresso.core
androidTestImplementation libs.espresso.contrib
androidTestImplementation libs.espresso.web
androidTestImplementation libs.espresso.accessibility
androidTestImplementation libs.espresso.intents
androidTestImplementation libs.espresso.idling.resource
// endregion
// region Glide
implementation libs.glide
ksp libs.ksp
// endregion
// region UI
implementation libs.appcompat
implementation libs.webkit
implementation libs.cardview
implementation libs.exifinterface
implementation libs.fragment.ktx
// endregion
// region Worker
implementation libs.work.runtime
implementation libs.work.runtime.ktx
// endregion
// region Lifecycle
implementation libs.lifecycle.viewmodel.ktx
implementation libs.lifecycle.service
implementation(libs.lifecycle.runtime.ktx)
// endregion
// region JUnit
androidTestImplementation libs.junit
androidTestImplementation libs.rules
androidTestImplementation libs.runner
androidTestUtil libs.orchestrator
androidTestImplementation libs.core.ktx
androidTestImplementation libs.core.testing
// endregion
// region other libraries
compileOnly libs.org.jbundle.util.osgi.wrapped.org.apache.http.client
implementation libs.commons.httpclient.commons.httpclient // remove after entire switch to lib v2
implementation libs.jackrabbit.webdav // remove after entire switch to lib v2
implementation libs.constraintlayout
implementation libs.legacy.support.v4
implementation libs.material
implementation libs.disklrucache
implementation libs.juniversalchardet // need this version for Android <7
compileOnly libs.annotations
implementation libs.commons.io
implementation libs.eventbus
implementation libs.ez.vcard
implementation libs.nnio
implementation libs.bcpkix.jdk18on
implementation libs.gson
implementation libs.sectioned.recyclerview
implementation libs.photoview
implementation libs.android.gif.drawable
implementation libs.qrcodescanner // "com.github.blikoon:QRCodeScanner:0.1.2"
implementation libs.flexbox
implementation libs.androidsvg
implementation libs.annotation
implementation libs.emoji.google
// endregion
// region AppScan, document scanner not available on FDroid (generic) due to OpenCV binaries
gplayImplementation project(":appscan")
huaweiImplementation project(":appscan")
qaImplementation project(":appscan")
// endregion
// region SpotBugs
spotbugsPlugins libs.findsecbugs.plugin
spotbugsPlugins libs.fb.contrib
// endregion
// region Dagger
implementation libs.dagger
implementation libs.dagger.android
implementation libs.dagger.android.support
kapt "com.google.dagger:dagger-compiler:$daggerVersion"
kapt "com.google.dagger:dagger-android-processor:$daggerVersion"
// endregion
// region Crypto
implementation libs.conscrypt.android
// endregion
// region Library
implementation libs.library
// endregion
// region Shimmer
implementation libs.loaderviewlibrary
// endregion
// region Markdown rendering
implementation libs.core
implementation libs.ext.strikethrough
implementation libs.ext.tables
implementation libs.ext.tasklist
implementation libs.html
implementation libs.syntax.highlight
implementation libs.prism4j
kapt "io.noties:prism4j-bundler:$prismVersion"
// endregion
// region Image cropping / rotation
implementation libs.android.image.cropper
// endregion
// region Maps
implementation libs.osmdroid.android
// endregion
// region iCal4j
implementation(libs.ical4j) {
["org.apache.commons", "commons-logging"].each {
exclude group: "$it"
}
}
// endregion
// region LeakCanary
if (perfAnalysis) {
debugImplementation "com.squareup.leakcanary:leakcanary-android:2.14"
}
// endregion
// region Local Unit Test
testImplementation libs.junit.junit
testImplementation libs.mockito.core
testImplementation libs.test.core
testImplementation libs.json
testImplementation libs.mockito.kotlin
testImplementation libs.core.testing
testImplementation "io.mockk:mockk:$mockkVersion"
testImplementation libs.mockk.android
// endregion
// region Mocking support
androidTestImplementation libs.dexopener // required to allow mocking on API 27 and older
androidTestImplementation libs.mockito.kotlin
androidTestImplementation libs.mockito.core
androidTestImplementation(libs.mockito.android)
androidTestImplementation libs.mockk.android
androidTestImplementation libs.screenshot.core
// endregion
// region UIAutomator
// UIAutomator - for cross-app UI tests, and to grant screen is turned on in Espresso tests
// androidTestImplementation "androidx.test.uiautomator:uiautomator:2.2.0"
// fix conflict in dependencies; see http://g.co/androidstudio/app-test-app-conflict for details
// androidTestImplementation "com.android.support:support-annotations:${supportLibraryVersion}"
androidTestImplementation libs.screengrab
// endregion
// region Kotlin
implementation libs.kotlin.stdlib
// endregion
// region Stateless
implementation libs.stateless4j
// endregion
// region Google Play dependencies, upon each update first test: new registration, receive push
gplayImplementation libs.firebase.messaging
gplayImplementation libs.play.services.base
gplayImplementation libs.review.ktx
// endregion
// region UI
implementation libs.ui
// endregion
// region Image loading
implementation libs.coil
// endregion
}
configurations.configureEach {
resolutionStrategy {
force "org.objenesis:objenesis:3.4"
eachDependency { details ->
if ("org.jacoco" == details.requested.group) {
details.useVersion "$jacoco_version"
}
}
}
}
// Run the compiler as a separate process
tasks.withType(JavaCompile).configureEach {
options.fork = true
// Enable Incremental Compilation
options.incremental = true
}
tasks.withType(Test).configureEach {
// Run tests in parallel
maxParallelForks = Runtime.runtime.availableProcessors().intdiv(2) ?: 1
// increased logging for tests
testLogging {
events "passed", "skipped", "failed"
}
}
android.applicationVariants.configureEach { variant ->
variant.outputs.configureEach { output -> outputFileName = "${output.baseName}-${variant.versionCode}.apk"
}
}
spotless {
kotlin {
target "**/*.kt"
ktlint()
}
}
detekt {
config.setFrom("detekt.yml")
}
if (shotTest) {
shot {
showOnlyFailingTestsInReports = ciBuild
// CI environment renders some shadows slightly different from local VMs
// Add a 0.5% tolerance to account for that
tolerance = ciBuild ? 0.1 : 0
}
}
jacoco {
toolVersion = "$jacoco_version"
}
spotbugs {
ignoreFailures = true // should continue checking
effort = Effort.MAX
reportLevel = Confidence.valueOf("MEDIUM")
}
tasks.withType(SpotBugsTask){task ->
String variantNameCap = task.name.replace("spotbugs", "")
String variantName = variantNameCap.substring(0, 1).toLowerCase() + variantNameCap.substring(1)
dependsOn "compile${variantNameCap}Sources"
classes = fileTree(layout.buildDirectory.get().asFile.toString()+"/intermediates/javac/${variantName}/compile${variantNameCap}JavaWithJavac/classes/")
excludeFilter = file("${project.rootDir}/scripts/analysis/spotbugs-filter.xml")
reports {
xml {
required = true
}
html {
required = true
outputLocation = layout.buildDirectory.file("reports/spotbugs/spotbugs.html").get().asFile
stylesheet = "fancy.xsl"
}
}
}
ksp {
arg("room.schemaLocation", "$projectDir/schemas")
}