587 lines
18 KiB
Groovy
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")
|
|
}
|