Migrated from Groovy to Kotlin DSL and upgrade AGP version (#6322)
Some checks are pending
Android CI / Run tests and generate APK (push) Waiting to run

* chore: migrate groovy build files to Kotlin DSL and upgrade AGP

chore: use version catalog to manage dependencies

chore: move plugins to version catalog

remove deprecated way of enabling build-config and redundant code

chore: setup triplet-play plugin configuration

refactor: move dependency block and tasks to the end of build file

refactor: move dependency block and mark redundant dependencies

* cleanup: remove redundant dependencies from build file

* cleanup: remove git utils file as the functions moved to build file

---------

Co-authored-by: Nicolas Raoul <nicolas.raoul@gmail.com>
This commit is contained in:
Rohit Verma 2025-05-28 17:13:13 +05:30 committed by GitHub
parent c49c85e68b
commit ed1485ca22
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
10 changed files with 685 additions and 502 deletions

View file

@ -1,431 +0,0 @@
plugins {
id 'com.github.triplet.play' version '2.7.2' apply false
}
apply from: '../gitutils.gradle'
apply plugin: 'com.android.application'
apply plugin: 'kotlin-android'
apply plugin: 'kotlin-kapt'
apply plugin: 'kotlin-parcelize'
apply from: "$rootDir/jacoco.gradle"
def isRunningOnTravisAndIsNotPRBuild = System.getenv("CI") == "true" && file('../play.p12').exists()
if (isRunningOnTravisAndIsNotPRBuild) {
apply plugin: 'com.github.triplet.play'
}
dependencies {
// Utils
implementation 'in.yuvi:http.fluent:1.3'
implementation 'com.google.code.gson:gson:2.8.5'
implementation ("com.squareup.okhttp3:okhttp:$OKHTTP_VERSION!!"){
// Forcing dependency versions using force = true on a first-level dependency has been deprecated.
// Ref: https://docs.gradle.org/7.5/userguide/upgrading_version_5.html#forced_dependencies
//force = true //API 19 support
}
implementation 'com.squareup.retrofit2:retrofit:2.8.1'
implementation "com.squareup.retrofit2:converter-gson:2.8.1"
implementation "com.squareup.retrofit2:adapter-rxjava2:2.8.1"
implementation 'com.squareup.okio:okio:2.2.2'
implementation 'io.reactivex.rxjava2:rxandroid:2.1.0'
implementation 'io.reactivex.rxjava2:rxjava:2.2.3'
implementation 'com.jakewharton.rxbinding2:rxbinding:2.1.1'
implementation 'com.jakewharton.rxbinding3:rxbinding-appcompat:3.0.0'
implementation 'com.jakewharton.rxbinding2:rxbinding-support-v4:2.1.1'
implementation 'com.jakewharton.rxbinding2:rxbinding-appcompat-v7:2.1.1'
implementation 'com.jakewharton.rxbinding2:rxbinding-design:2.1.1'
implementation 'com.facebook.fresco:fresco:1.13.0'
implementation 'org.apache.commons:commons-lang3:3.8.1'
// UI
implementation 'fr.avianey.com.viewpagerindicator:library:2.4.1.1@aar'
implementation 'com.github.chrisbanes:PhotoView:2.0.0'
implementation 'com.github.pedrovgs:renderers:3.3.3'
implementation "org.maplibre.gl:android-sdk:$MAPLIBRE_VERSION"
implementation 'org.maplibre.gl:android-plugin-scalebar-v9:1.0.0'
implementation 'com.jakewharton.timber:timber:4.7.1'
implementation 'com.github.deano2390:MaterialShowcaseView:1.2.0'
implementation "com.google.android.material:material:1.12.0"
implementation 'com.karumi:dexter:5.0.0'
implementation 'androidx.lifecycle:lifecycle-extensions:2.2.0'
implementation 'androidx.compose.ui:ui-tooling-preview'
androidTestImplementation 'androidx.compose.ui:ui-test-junit4'
// Jetpack Compose
def composeBom = platform('androidx.compose:compose-bom:2024.11.00')
implementation "androidx.activity:activity-compose:1.9.3"
implementation "androidx.lifecycle:lifecycle-runtime-ktx:2.8.4"
implementation (composeBom)
implementation "androidx.compose.runtime:runtime"
implementation "androidx.compose.ui:ui"
implementation "androidx.compose.ui:ui-viewbinding"
implementation "androidx.compose.ui:ui-graphics"
implementation "androidx.compose.ui:ui-tooling"
implementation "androidx.compose.foundation:foundation"
implementation "androidx.compose.foundation:foundation-layout"
implementation "androidx.compose.material3:material3"
androidTestImplementation(composeBom)
implementation "com.hannesdorfmann:adapterdelegates4-kotlin-dsl-viewbinding:$ADAPTER_DELEGATES_VERSION"
implementation "com.hannesdorfmann:adapterdelegates4-pagination:$ADAPTER_DELEGATES_VERSION"
implementation "androidx.paging:paging-runtime-ktx:$PAGING_VERSION"
testImplementation "androidx.paging:paging-common-ktx:$PAGING_VERSION"
implementation "androidx.paging:paging-rxjava2-ktx:$PAGING_VERSION"
implementation "androidx.recyclerview:recyclerview:1.2.0-alpha02"
implementation "com.squareup.okhttp3:okhttp-ws:$OKHTTP_VERSION"
// Logging
implementation 'ch.acra:acra-dialog:5.8.4'
implementation 'ch.acra:acra-mail:5.8.4'
implementation 'org.slf4j:slf4j-api:1.7.25'
api('com.github.tony19:logback-android-classic:1.1.1-6') {
exclude group: 'com.google.android', module: 'android'
}
implementation "com.squareup.okhttp3:logging-interceptor:$OKHTTP_VERSION"
// Dependency injector
implementation "com.google.dagger:dagger-android:$DAGGER_VERSION"
implementation "com.google.dagger:dagger-android-support:$DAGGER_VERSION"
debugImplementation 'androidx.compose.ui:ui-tooling'
debugImplementation 'androidx.compose.ui:ui-test-manifest'
kapt "com.google.dagger:dagger-android-processor:$DAGGER_VERSION"
kapt "com.google.dagger:dagger-compiler:$DAGGER_VERSION"
annotationProcessor "com.google.dagger:dagger-android-processor:$DAGGER_VERSION"
implementation "org.jetbrains.kotlin:kotlin-reflect:$KOTLIN_VERSION"
//Mocking
testImplementation 'com.nhaarman.mockitokotlin2:mockito-kotlin:2.2.0'
testImplementation 'org.mockito:mockito-inline:5.2.0'
testImplementation 'org.mockito:mockito-core:5.6.0'
testImplementation "org.powermock:powermock-module-junit4:2.0.9"
testImplementation "org.powermock:powermock-api-mockito2:2.0.9"
testImplementation("io.mockk:mockk:1.13.5")
// Unit testing
testImplementation 'junit:junit:4.13.2'
testImplementation 'org.robolectric:robolectric:4.11.1'
testImplementation 'androidx.test:core:1.5.0'
testImplementation "androidx.test:runner:1.5.2"
testImplementation 'androidx.test.ext:junit:1.1.5'
testImplementation "androidx.test:rules:1.5.0"
testImplementation "com.squareup.okhttp3:mockwebserver:$OKHTTP_VERSION"
testImplementation "com.jraska.livedata:testing-ktx:1.2.0"
testImplementation "androidx.arch.core:core-testing:2.2.0"
testImplementation "org.junit.jupiter:junit-jupiter-api:5.10.0"
testRuntimeOnly "org.junit.jupiter:junit-jupiter-engine:5.10.0"
testImplementation 'com.facebook.soloader:soloader:0.10.5'
testImplementation "org.jetbrains.kotlinx:kotlinx-coroutines-test:1.7.3"
debugImplementation("androidx.fragment:fragment-testing-manifest:1.6.2")
androidTestImplementation("androidx.fragment:fragment-testing:1.6.2")
testImplementation "commons-io:commons-io:2.6"
// Android testing
androidTestImplementation 'androidx.test.espresso:espresso-core:3.5.0-alpha04'
androidTestImplementation 'androidx.test.espresso:espresso-intents:3.4.0'
androidTestImplementation 'androidx.test.espresso:espresso-contrib:3.5.0-alpha04'
androidTestImplementation 'androidx.test:runner:1.4.0'
androidTestImplementation 'androidx.test:rules:1.4.1-alpha04'
androidTestImplementation 'androidx.test:core:1.4.0'
androidTestImplementation 'androidx.test.ext:junit:1.1.3'
androidTestImplementation 'androidx.annotation:annotation:1.3.0'
androidTestImplementation 'com.squareup.okhttp3:mockwebserver:4.8.0'
androidTestImplementation "androidx.test.uiautomator:uiautomator:2.2.0"
androidTestUtil 'androidx.test:orchestrator:1.4.1'
// Debugging
debugImplementation "com.squareup.leakcanary:leakcanary-android:$LEAK_CANARY_VERSION"
// Support libraries
implementation "com.google.android.material:material:1.1.0-alpha04"
implementation "androidx.browser:browser:1.3.0"
implementation "androidx.cardview:cardview:1.0.0"
implementation 'androidx.constraintlayout:constraintlayout:1.1.3'
implementation 'androidx.exifinterface:exifinterface:1.3.7'
implementation "androidx.core:core-ktx:$CORE_KTX_VERSION"
implementation 'com.simplecityapps:recyclerview-fastscroll:2.0.1'
//swipe_layout
implementation 'com.daimajia.swipelayout:library:1.2.0@aar'
//Room
implementation "androidx.room:room-runtime:$ROOM_VERSION"
implementation "androidx.room:room-ktx:$ROOM_VERSION"
implementation "androidx.room:room-rxjava2:$ROOM_VERSION"
kapt "androidx.room:room-compiler:$ROOM_VERSION"
// For Kotlin use kapt instead of annotationProcessor
testImplementation "androidx.arch.core:core-testing:2.1.0"
// Pref
// Java language implementation
implementation "androidx.preference:preference:$PREFERENCE_VERSION"
// Kotlin
implementation "androidx.preference:preference-ktx:$PREFERENCE_VERSION"
//Android Media
implementation 'com.github.juanitobananas:AndroidMediaUtil:v1.0-1'
implementation "androidx.multidex:multidex:$MULTIDEX_VERSION"
def work_version = "2.8.1"
// Kotlin + coroutines
implementation "androidx.work:work-runtime-ktx:$work_version"
implementation("androidx.work:work-runtime:$work_version")
testImplementation "androidx.work:work-testing:$work_version"
//Glide
implementation 'com.github.bumptech.glide:glide:4.16.0'
annotationProcessor 'com.github.bumptech.glide:compiler:4.16.0'
kaptTest "androidx.databinding:databinding-compiler:8.0.2"
kaptAndroidTest "androidx.databinding:databinding-compiler:8.0.2"
implementation("io.github.coordinates2country:coordinates2country-android:1.8") { exclude group: 'com.google.android', module: 'android' }
//OSMDroid
implementation ("org.osmdroid:osmdroid-android:$OSMDROID_VERSION")
constraints {
implementation("org.jetbrains.kotlin:kotlin-stdlib-jdk7:1.8.0") {
because("kotlin-stdlib-jdk7 is now a part of kotlin-stdlib")
}
implementation("org.jetbrains.kotlin:kotlin-stdlib-jdk8:1.8.0") {
because("kotlin-stdlib-jdk8 is now a part of kotlin-stdlib")
}
}
}
task disableAnimations(type: Exec) {
def adb = "$System.env.ANDROID_HOME/platform-tools/adb"
commandLine "$adb", 'shell', 'settings', 'put', 'global', 'window_animation_scale', '0'
commandLine "$adb", 'shell', 'settings', 'put', 'global', 'transition_animation_scale', '0'
commandLine "$adb", 'shell', 'settings', 'put', 'global', 'animator_duration_scale', '0'
}
project.gradle.taskGraph.whenReady {
connectedBetaDebugAndroidTest.dependsOn disableAnimations
connectedProdDebugAndroidTest.dependsOn disableAnimations
}
android {
compileSdkVersion 34
defaultConfig {
//applicationId 'fr.free.nrw.commons'
versionCode 1051
versionName '5.4.0'
setProperty("archivesBaseName", "app-commons-v$versionName-" + getBranchName())
minSdkVersion 21
targetSdkVersion 34
testInstrumentationRunner "androidx.test.runner.AndroidJUnitRunner"
testInstrumentationRunnerArguments clearPackageData: 'true'
multiDexEnabled true
testInstrumentationRunner "androidx.test.runner.AndroidJUnitRunner"
vectorDrawables.useSupportLibrary = true
}
packagingOptions {
jniLibs {
excludes += ['META-INF/androidx.*']
}
resources {
excludes += ['META-INF/androidx.*', 'META-INF/proguard/androidx-annotations.pro', '/META-INF/LICENSE.md', '/META-INF/LICENSE-notice.md']
}
}
testOptions {
animationsDisabled true
unitTests {
returnDefaultValues = true
includeAndroidResources = true
}
unitTests.all {
jvmArgs '-noverify'
}
}
sourceSets {
// use kotlin only in tests (for now)
test.java.srcDirs += 'src/test/kotlin'
// use main assets and resources in test
test.assets.srcDirs += 'src/main/assets'
test.resources.srcDirs += 'src/main/resoures'
}
signingConfigs {
release
}
buildTypes {
release {
minifyEnabled true
proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.txt'
testProguardFile 'test-proguard-rules.txt'
signingConfig signingConfigs.debug
if (isRunningOnTravisAndIsNotPRBuild) {
signingConfig signingConfigs.release
}
}
debug {
minifyEnabled false
proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.txt'
testProguardFile 'test-proguard-rules.txt'
versionNameSuffix "-debug-" + getBranchName()
enableUnitTestCoverage true
enableAndroidTestCoverage true
}
}
if (isRunningOnTravisAndIsNotPRBuild) {
// configure keystore based on env vars in Travis for automated alpha builds
signingConfigs.release.storeFile = file("../nr-commons.keystore")
signingConfigs.release.storePassword = System.getenv("keystore_password")
signingConfigs.release.keyAlias = System.getenv("key_alias")
signingConfigs.release.keyPassword = System.getenv("key_password")
}
configurations.all {
resolutionStrategy.force 'androidx.annotation:annotation:1.1.0'
resolutionStrategy.force 'com.jakewharton.timber:timber:4.7.1'
resolutionStrategy.force 'androidx.fragment:fragment:1.3.6'
exclude module: 'okhttp-ws'
}
flavorDimensions 'tier'
productFlavors {
prod {
applicationId 'fr.free.nrw.commons'
buildConfigField "String", "WIKIMEDIA_API_POTD", "\"https://commons.wikimedia.org/w/api.php?action=featuredfeed&feed=potd&feedformat=rss&language=en\""
buildConfigField "String", "WIKIMEDIA_API_HOST", "\"https://commons.wikimedia.org/w/api.php\""
buildConfigField "String", "WIKIDATA_API_HOST", "\"https://www.wikidata.org/w/api.php\""
buildConfigField "String", "WIKIDATA_URL", "\"https://www.wikidata.org\""
buildConfigField "String", "WIKIMEDIA_FORGE_API_HOST", "\"https://tools.wmflabs.org/\""
buildConfigField "String", "WIKIMEDIA_CAMPAIGNS_URL", "\"https://raw.githubusercontent.com/commons-app/campaigns/master/campaigns.json\""
buildConfigField "String", "IMAGE_URL_BASE", "\"https://upload.wikimedia.org/wikipedia/commons\""
buildConfigField "String", "HOME_URL", "\"https://commons.wikimedia.org/wiki/\""
buildConfigField "String", "COMMONS_URL", "\"https://commons.wikimedia.org\""
buildConfigField "String", "WIKIDATA_URL", "\"https://www.wikidata.org\""
buildConfigField "String", "MOBILE_HOME_URL", "\"https://commons.m.wikimedia.org/wiki/\""
buildConfigField "String", "MOBILE_META_URL", "\"https://meta.m.wikimedia.org/wiki/\""
buildConfigField "String", "SIGNUP_LANDING_URL", "\"https://commons.m.wikimedia.org/w/index.php?title=Special:CreateAccount&returnto=Main+Page&returntoquery=welcome%3Dyes\""
buildConfigField "String", "SIGNUP_SUCCESS_REDIRECTION_URL", "\"https://commons.m.wikimedia.org/w/index.php?title=Main_Page&welcome=yes\""
buildConfigField "String", "FORGOT_PASSWORD_URL", "\"https://commons.wikimedia.org/wiki/Special:PasswordReset\""
buildConfigField "String", "PRIVACY_POLICY_URL", "\"https://commons-app.github.io/privacy-policy\""
buildConfigField "String", "FILE_USAGES_BASE_URL", "\"https://commons.wikimedia.org/w/api.php?action=query&format=json&formatversion=2\""
buildConfigField "String", "ACCOUNT_TYPE", "\"fr.free.nrw.commons\""
buildConfigField "String", "CONTRIBUTION_AUTHORITY", "\"fr.free.nrw.commons.contributions.contentprovider\""
buildConfigField "String", "MODIFICATION_AUTHORITY", "\"fr.free.nrw.commons.modifications.contentprovider\""
buildConfigField "String", "CATEGORY_AUTHORITY", "\"fr.free.nrw.commons.categories.contentprovider\""
buildConfigField "String", "RECENT_SEARCH_AUTHORITY", "\"fr.free.nrw.commons.explore.recentsearches.contentprovider\""
buildConfigField "String", "RECENT_LANGUAGE_AUTHORITY", "\"fr.free.nrw.commons.recentlanguages.contentprovider\""
buildConfigField "String", "BOOKMARK_AUTHORITY", "\"fr.free.nrw.commons.bookmarks.contentprovider\""
buildConfigField "String", "BOOKMARK_LOCATIONS_AUTHORITY", "\"fr.free.nrw.commons.bookmarks.locations.contentprovider\""
buildConfigField "String", "BOOKMARK_ITEMS_AUTHORITY", "\"fr.free.nrw.commons.bookmarks.items.contentprovider\""
buildConfigField "String", "COMMIT_SHA", "\"" + getBuildVersion().toString() + "\""
buildConfigField "String", "TEST_USERNAME", "\"" + getTestUserName() + "\""
buildConfigField "String", "TEST_PASSWORD", "\"" + getTestPassword() + "\""
buildConfigField "String", "DEPICTS_PROPERTY", "\"P180\""
buildConfigField "String", "CREATOR_PROPERTY", "\"P170\""
dimension 'tier'
}
beta {
applicationId 'fr.free.nrw.commons.beta'
// What values do we need to hit the BETA versions of the site / api ?
buildConfigField "String", "WIKIMEDIA_API_POTD", "\"https://commons.wikimedia.org/w/api.php?action=featuredfeed&feed=potd&feedformat=rss&language=en\""
buildConfigField "String", "WIKIMEDIA_API_HOST", "\"https://commons.wikimedia.beta.wmflabs.org/w/api.php\""
buildConfigField "String", "WIKIDATA_API_HOST", "\"https://www.wikidata.org/w/api.php\""
buildConfigField "String", "WIKIDATA_URL", "\"https://www.wikidata.org\""
buildConfigField "String", "WIKIMEDIA_FORGE_API_HOST", "\"https://tools.wmflabs.org/\""
buildConfigField "String", "WIKIMEDIA_CAMPAIGNS_URL", "\"https://raw.githubusercontent.com/commons-app/campaigns/master/campaigns_beta_active.json\""
buildConfigField "String", "IMAGE_URL_BASE", "\"https://upload.beta.wmflabs.org/wikipedia/commons\""
buildConfigField "String", "HOME_URL", "\"https://commons.wikimedia.beta.wmflabs.org/wiki/\""
buildConfigField "String", "COMMONS_URL", "\"https://commons.wikimedia.beta.wmflabs.org\""
buildConfigField "String", "WIKIDATA_URL", "\"https://www.wikidata.org\""
buildConfigField "String", "MOBILE_HOME_URL", "\"https://commons.m.wikimedia.beta.wmflabs.org/wiki/\""
buildConfigField "String", "MOBILE_META_URL", "\"https://meta.m.wikimedia.beta.wmflabs.org/wiki/\""
buildConfigField "String", "SIGNUP_LANDING_URL", "\"https://commons.m.wikimedia.beta.wmflabs.org/w/index.php?title=Special:CreateAccount&returnto=Main+Page&returntoquery=welcome%3Dyes\""
buildConfigField "String", "SIGNUP_SUCCESS_REDIRECTION_URL", "\"https://commons.m.wikimedia.beta.wmflabs.org/w/index.php?title=Main_Page&welcome=yes\""
buildConfigField "String", "FORGOT_PASSWORD_URL", "\"https://commons.wikimedia.beta.wmflabs.org/wiki/Special:PasswordReset\""
buildConfigField "String", "PRIVACY_POLICY_URL", "\"https://commons-app.github.io/privacy-policy\""
buildConfigField "String", "FILE_USAGES_BASE_URL", "\"https://commons.wikimedia.org/w/api.php?action=query&format=json&formatversion=2\""
buildConfigField "String", "ACCOUNT_TYPE", "\"fr.free.nrw.commons.beta\""
buildConfigField "String", "CONTRIBUTION_AUTHORITY", "\"fr.free.nrw.commons.beta.contributions.contentprovider\""
buildConfigField "String", "MODIFICATION_AUTHORITY", "\"fr.free.nrw.commons.beta.modifications.contentprovider\""
buildConfigField "String", "CATEGORY_AUTHORITY", "\"fr.free.nrw.commons.beta.categories.contentprovider\""
buildConfigField "String", "RECENT_SEARCH_AUTHORITY", "\"fr.free.nrw.commons.beta.explore.recentsearches.contentprovider\""
buildConfigField "String", "RECENT_LANGUAGE_AUTHORITY", "\"fr.free.nrw.commons.beta.recentlanguages.contentprovider\""
buildConfigField "String", "BOOKMARK_AUTHORITY", "\"fr.free.nrw.commons.beta.bookmarks.contentprovider\""
buildConfigField "String", "BOOKMARK_LOCATIONS_AUTHORITY", "\"fr.free.nrw.commons.beta.bookmarks.locations.contentprovider\""
buildConfigField "String", "BOOKMARK_ITEMS_AUTHORITY", "\"fr.free.nrw.commons.beta.bookmarks.items.contentprovider\""
buildConfigField "String", "COMMIT_SHA", "\"" + getBuildVersion().toString() + "\""
buildConfigField "String", "TEST_USERNAME", "\"" + getTestUserName() + "\""
buildConfigField "String", "TEST_PASSWORD", "\"" + getTestPassword() + "\""
buildConfigField "String", "DEPICTS_PROPERTY", "\"P245962\""
buildConfigField "String", "CREATOR_PROPERTY", "\"P253075\""
dimension 'tier'
}
}
compileOptions {
sourceCompatibility JavaVersion.VERSION_17
targetCompatibility JavaVersion.VERSION_17
}
kotlinOptions {
jvmTarget = "17"
}
buildToolsVersion buildToolsVersion
buildFeatures {
viewBinding true
compose true
}
composeOptions {
kotlinCompilerExtensionVersion '1.5.8'
}
namespace 'fr.free.nrw.commons'
lint {
abortOnError false
disable 'MissingTranslation', 'ExtraTranslation'
}
}
String getTestUserName() {
def propFile = rootProject.file("./local.properties")
def properties = new Properties()
properties.load(new FileInputStream(propFile))
return properties['TEST_USER_NAME']
}
String getTestPassword() {
def propFile = rootProject.file("./local.properties")
def properties = new Properties()
properties.load(new FileInputStream(propFile))
return properties['TEST_USER_PASSWORD']
}
if (isRunningOnTravisAndIsNotPRBuild) {
play {
track = "alpha"
userFraction = 1
serviceAccountEmail = System.getenv("SERVICE_ACCOUNT_NAME")
serviceAccountCredentials = file("../play.p12")
resolutionStrategy = "auto"
outputProcessor { // this: ApkVariantOutput
versionNameOverride = "$versionNameOverride.$versionCode"
}
}
}

445
app/build.gradle.kts Normal file
View file

@ -0,0 +1,445 @@
import java.util.Properties
import java.io.ByteArrayOutputStream
plugins {
alias(libs.plugins.android.application)
alias(libs.plugins.jetbrains.kotlin.android)
alias(libs.plugins.kotlin.kapt)
alias(libs.plugins.kotlin.parcelize)
}
apply(from = "$rootDir/jacoco.gradle")
val isRunningOnTravisAndIsNotPRBuild = System.getenv("CI") == "true" && file("../play.p12").exists()
if (isRunningOnTravisAndIsNotPRBuild) {
apply(plugin = "com.github.triplet.play")
}
android {
namespace = "fr.free.nrw.commons"
compileSdk = 34
defaultConfig {
applicationId = "fr.free.nrw.commons"
minSdk = 21
targetSdk = 34
versionCode = 1043
versionName = "5.1.2"
setProperty("archivesBaseName", "app-commons-v$versionName-" + getBranchName())
testInstrumentationRunner = "androidx.test.runner.AndroidJUnitRunner"
testInstrumentationRunnerArguments["clearPackageData"] = "true"
multiDexEnabled = true
vectorDrawables {
useSupportLibrary = true
}
}
sourceSets {
getByName("test") {
// Use kotlin only in tests (for now)
java.srcDirs("src/test/kotlin")
// Use main assets and resources in test
assets.srcDirs("src/main/assets")
resources.srcDirs("src/main/resources")
}
}
signingConfigs {
create("release") {
// Configure keystore based on env vars in Travis for automated alpha builds
if(isRunningOnTravisAndIsNotPRBuild) {
storeFile = file("../nr-commons.keystore")
storePassword = System.getenv("keystore_password")
keyAlias = System.getenv("key_alias")
keyPassword = System.getenv("key_password")
}
}
}
buildTypes {
release {
isMinifyEnabled = true
proguardFiles(getDefaultProguardFile("proguard-android.txt"), "proguard-rules.txt")
testProguardFile("test-proguard-rules.txt")
signingConfig = signingConfigs.getByName("debug")
if (isRunningOnTravisAndIsNotPRBuild) {
signingConfig = signingConfigs.getByName("release")
}
}
debug {
isMinifyEnabled = false
proguardFiles(getDefaultProguardFile("proguard-android.txt"), "proguard-rules.txt")
testProguardFile("test-proguard-rules.txt")
versionNameSuffix = "-debug-" + getBranchName()
enableUnitTestCoverage = true
enableAndroidTestCoverage = true
}
}
configurations.all {
resolutionStrategy {
force("androidx.annotation:annotation:1.1.0")
force("com.jakewharton.timber:timber:4.7.1")
force("androidx.fragment:fragment:1.3.6")
}
exclude(module = "okhttp-ws")
}
flavorDimensions += "tier"
productFlavors {
create("prod") {
dimension = "tier"
applicationId = "fr.free.nrw.commons"
buildConfigField("String", "WIKIMEDIA_API_POTD", "\"https://commons.wikimedia.org/w/api.php?action=featuredfeed&feed=potd&feedformat=rss&language=en\"")
buildConfigField("String", "WIKIMEDIA_API_HOST", "\"https://commons.wikimedia.org/w/api.php\"")
buildConfigField("String", "WIKIDATA_API_HOST", "\"https://www.wikidata.org/w/api.php\"")
buildConfigField("String", "WIKIDATA_URL", "\"https://www.wikidata.org\"")
buildConfigField("String", "WIKIMEDIA_FORGE_API_HOST", "\"https://tools.wmflabs.org/\"")
buildConfigField("String", "WIKIMEDIA_CAMPAIGNS_URL", "\"https://raw.githubusercontent.com/commons-app/campaigns/master/campaigns.json\"")
buildConfigField("String", "IMAGE_URL_BASE", "\"https://upload.wikimedia.org/wikipedia/commons\"")
buildConfigField("String", "HOME_URL", "\"https://commons.wikimedia.org/wiki/\"")
buildConfigField("String", "COMMONS_URL", "\"https://commons.wikimedia.org\"")
buildConfigField("String", "WIKIDATA_URL", "\"https://www.wikidata.org\"")
buildConfigField("String", "MOBILE_HOME_URL", "\"https://commons.m.wikimedia.org/wiki/\"")
buildConfigField("String", "MOBILE_META_URL", "\"https://meta.m.wikimedia.org/wiki/\"")
buildConfigField("String", "SIGNUP_LANDING_URL", "\"https://commons.m.wikimedia.org/w/index.php?title=Special:CreateAccount&returnto=Main+Page&returntoquery=welcome%3Dyes\"")
buildConfigField("String", "SIGNUP_SUCCESS_REDIRECTION_URL", "\"https://commons.m.wikimedia.org/w/index.php?title=Main_Page&welcome=yes\"")
buildConfigField("String", "FORGOT_PASSWORD_URL", "\"https://commons.wikimedia.org/wiki/Special:PasswordReset\"")
buildConfigField("String", "PRIVACY_POLICY_URL", "\"https://github.com/commons-app/commons-app-documentation/blob/master/android/Privacy-policy.md\"")
buildConfigField("String", "FILE_USAGES_BASE_URL", "\"https://commons.wikimedia.org/w/api.php?action=query&format=json&formatversion=2\"")
buildConfigField("String", "ACCOUNT_TYPE", "\"fr.free.nrw.commons\"")
buildConfigField("String", "CONTRIBUTION_AUTHORITY", "\"fr.free.nrw.commons.contributions.contentprovider\"")
buildConfigField("String", "MODIFICATION_AUTHORITY", "\"fr.free.nrw.commons.modifications.contentprovider\"")
buildConfigField("String", "CATEGORY_AUTHORITY", "\"fr.free.nrw.commons.categories.contentprovider\"")
buildConfigField("String", "RECENT_SEARCH_AUTHORITY", "\"fr.free.nrw.commons.explore.recentsearches.contentprovider\"")
buildConfigField("String", "RECENT_LANGUAGE_AUTHORITY", "\"fr.free.nrw.commons.recentlanguages.contentprovider\"")
buildConfigField("String", "BOOKMARK_AUTHORITY", "\"fr.free.nrw.commons.bookmarks.contentprovider\"")
buildConfigField("String", "BOOKMARK_LOCATIONS_AUTHORITY", "\"fr.free.nrw.commons.bookmarks.locations.contentprovider\"")
buildConfigField("String", "BOOKMARK_ITEMS_AUTHORITY", "\"fr.free.nrw.commons.bookmarks.items.contentprovider\"")
buildConfigField("String", "COMMIT_SHA", "\"" + getBuildVersion().toString() + "\"")
buildConfigField("String", "TEST_USERNAME", "\"" + getTestUserName() + "\"")
buildConfigField("String", "TEST_PASSWORD", "\"" + getTestPassword() + "\"")
buildConfigField("String", "DEPICTS_PROPERTY", "\"P180\"")
buildConfigField("String", "CREATOR_PROPERTY", "\"P170\"")
}
create("beta") {
dimension = "tier"
applicationId = "fr.free.nrw.commons.beta"
// What values do we need to hit the BETA versions of the site / api ?
buildConfigField("String", "WIKIMEDIA_API_POTD", "\"https://commons.wikimedia.org/w/api.php?action=featuredfeed&feed=potd&feedformat=rss&language=en\"")
buildConfigField("String", "WIKIMEDIA_API_HOST", "\"https://commons.wikimedia.beta.wmflabs.org/w/api.php\"")
buildConfigField("String", "WIKIDATA_API_HOST", "\"https://www.wikidata.org/w/api.php\"")
buildConfigField("String", "WIKIDATA_URL", "\"https://www.wikidata.org\"")
buildConfigField("String", "WIKIMEDIA_FORGE_API_HOST", "\"https://tools.wmflabs.org/\"")
buildConfigField("String", "WIKIMEDIA_CAMPAIGNS_URL", "\"https://raw.githubusercontent.com/commons-app/campaigns/master/campaigns_beta_active.json\"")
buildConfigField("String", "IMAGE_URL_BASE", "\"https://upload.beta.wmflabs.org/wikipedia/commons\"")
buildConfigField("String", "HOME_URL", "\"https://commons.wikimedia.beta.wmflabs.org/wiki/\"")
buildConfigField("String", "COMMONS_URL", "\"https://commons.wikimedia.beta.wmflabs.org\"")
buildConfigField("String", "WIKIDATA_URL", "\"https://www.wikidata.org\"")
buildConfigField("String", "MOBILE_HOME_URL", "\"https://commons.m.wikimedia.beta.wmflabs.org/wiki/\"")
buildConfigField("String", "MOBILE_META_URL", "\"https://meta.m.wikimedia.beta.wmflabs.org/wiki/\"")
buildConfigField("String", "SIGNUP_LANDING_URL", "\"https://commons.m.wikimedia.beta.wmflabs.org/w/index.php?title=Special:CreateAccount&returnto=Main+Page&returntoquery=welcome%3Dyes\"")
buildConfigField("String", "SIGNUP_SUCCESS_REDIRECTION_URL", "\"https://commons.m.wikimedia.beta.wmflabs.org/w/index.php?title=Main_Page&welcome=yes\"")
buildConfigField("String", "FORGOT_PASSWORD_URL", "\"https://commons.wikimedia.beta.wmflabs.org/wiki/Special:PasswordReset\"")
buildConfigField("String", "PRIVACY_POLICY_URL", "\"https://github.com/commons-app/commons-app-documentation/blob/master/android/Privacy-policy.md\"")
buildConfigField("String", "FILE_USAGES_BASE_URL", "\"https://commons.wikimedia.org/w/api.php?action=query&format=json&formatversion=2\"")
buildConfigField("String", "ACCOUNT_TYPE", "\"fr.free.nrw.commons.beta\"")
buildConfigField("String", "CONTRIBUTION_AUTHORITY", "\"fr.free.nrw.commons.beta.contributions.contentprovider\"")
buildConfigField("String", "MODIFICATION_AUTHORITY", "\"fr.free.nrw.commons.beta.modifications.contentprovider\"")
buildConfigField("String", "CATEGORY_AUTHORITY", "\"fr.free.nrw.commons.beta.categories.contentprovider\"")
buildConfigField("String", "RECENT_SEARCH_AUTHORITY", "\"fr.free.nrw.commons.beta.explore.recentsearches.contentprovider\"")
buildConfigField("String", "RECENT_LANGUAGE_AUTHORITY", "\"fr.free.nrw.commons.beta.recentlanguages.contentprovider\"")
buildConfigField("String", "BOOKMARK_AUTHORITY", "\"fr.free.nrw.commons.beta.bookmarks.contentprovider\"")
buildConfigField("String", "BOOKMARK_LOCATIONS_AUTHORITY", "\"fr.free.nrw.commons.beta.bookmarks.locations.contentprovider\"")
buildConfigField("String", "BOOKMARK_ITEMS_AUTHORITY", "\"fr.free.nrw.commons.beta.bookmarks.items.contentprovider\"")
buildConfigField("String", "COMMIT_SHA", "\"" + getBuildVersion().toString() + "\"")
buildConfigField("String", "TEST_USERNAME", "\"" + getTestUserName() + "\"")
buildConfigField("String", "TEST_PASSWORD", "\"" + getTestPassword() + "\"")
buildConfigField("String", "DEPICTS_PROPERTY", "\"P245962\"")
buildConfigField("String", "CREATOR_PROPERTY", "\"P253075\"")
}
}
compileOptions {
sourceCompatibility = JavaVersion.VERSION_17
targetCompatibility = JavaVersion.VERSION_17
}
kotlinOptions {
jvmTarget = "17"
}
buildFeatures {
buildConfig = true
viewBinding = true
compose = true
}
buildToolsVersion = buildToolsVersion
composeOptions {
kotlinCompilerExtensionVersion = "1.5.8"
}
packaging {
jniLibs {
excludes += listOf("META-INF/androidx.*")
}
resources {
excludes += listOf(
"META-INF/androidx.*",
"META-INF/proguard/androidx-annotations.pro",
"/META-INF/LICENSE.md",
"/META-INF/LICENSE-notice.md"
)
}
}
testOptions {
animationsDisabled = true
unitTests {
isReturnDefaultValues = true
isIncludeAndroidResources = true
}
unitTests.all {
it.jvmArgs("-noverify")
}
}
lint {
abortOnError = false
disable += listOf("MissingTranslation", "ExtraTranslation")
}
}
dependencies {
// Utils
implementation(libs.gson)
implementation(libs.okhttp)
implementation(libs.retrofit)
implementation(libs.retrofit.converter.gson)
implementation(libs.retrofit.adapter.rxjava)
implementation(libs.rxandroid)
implementation(libs.rxjava)
implementation(libs.rxbinding)
implementation(libs.rxbinding.appcompat)
implementation(libs.facebook.fresco)
implementation(libs.apache.commons.lang3)
// UI
implementation("${libs.viewpagerindicator.library.get()}@aar")
implementation(libs.photoview)
implementation(libs.android.sdk)
implementation(libs.android.plugin.scalebar)
implementation(libs.timber)
implementation(libs.android.material)
implementation(libs.dexter)
// Jetpack Compose
implementation(libs.androidx.core.ktx)
implementation(libs.androidx.lifecycle.runtime.ktx)
implementation(libs.androidx.activity.compose)
implementation(platform(libs.androidx.compose.bom))
implementation(libs.androidx.compose.runtime)
implementation(libs.androidx.ui)
implementation(libs.androidx.ui.graphics)
implementation(libs.androidx.ui.tooling.preview)
implementation(libs.androidx.ui.viewbinding)
implementation(libs.androidx.material3)
implementation(libs.androidx.foundation)
implementation(libs.androidx.foundation.layout)
androidTestImplementation(platform(libs.androidx.compose.bom))
androidTestImplementation(libs.androidx.ui.test.junit4)
debugImplementation(libs.androidx.ui.tooling)
debugImplementation(libs.androidx.ui.test.manifest)
implementation(libs.adapterdelegates4.kotlin.dsl.viewbinding)
implementation(libs.adapterdelegates4.pagination)
implementation(libs.androidx.paging.runtime.ktx)
testImplementation(libs.androidx.paging.common.ktx)
implementation(libs.androidx.paging.rxjava2.ktx)
implementation(libs.androidx.recyclerview)
// Logging
implementation(libs.acra.dialog)
implementation(libs.acra.mail)
implementation(libs.slf4j.api)
implementation(libs.logback.android.classic) {
exclude(group = "com.google.android", module = "android")
}
implementation(libs.logging.interceptor)
// Dependency injector
implementation(libs.dagger.android)
implementation(libs.dagger.android.support)
kapt(libs.dagger.android.processor)
kapt(libs.dagger.compiler)
annotationProcessor(libs.dagger.android.processor)
implementation(libs.kotlin.reflect)
//Mocking
testImplementation(libs.mockito.kotlin)
testImplementation(libs.mockito.core)
testImplementation(libs.powermock.module.junit)
testImplementation(libs.powermock.api.mockito)
testImplementation(libs.mockk)
// Unit testing
testImplementation(libs.junit)
testImplementation(libs.robolectric)
testImplementation(libs.androidx.test.core)
testImplementation(libs.androidx.runner)
testImplementation(libs.androidx.test.ext.junit)
testImplementation(libs.androidx.test.rules)
testImplementation(libs.mockwebserver)
testImplementation(libs.livedata.testing.ktx)
testImplementation(libs.androidx.core.testing)
testImplementation(libs.junit.jupiter.api)
testRuntimeOnly(libs.junit.jupiter.engine)
testImplementation(libs.soloader)
testImplementation(libs.kotlinx.coroutines.test)
debugImplementation(libs.androidx.fragment.testing)
testImplementation(libs.commons.io)
// Android testing
androidTestImplementation(libs.androidx.espresso.core)
androidTestImplementation(libs.androidx.espresso.intents)
androidTestImplementation(libs.androidx.espresso.contrib)
androidTestImplementation(libs.androidx.runner)
androidTestImplementation(libs.androidx.test.rules)
androidTestImplementation(libs.androidx.test.core)
androidTestImplementation(libs.androidx.test.ext.junit)
androidTestImplementation(libs.androidx.annotation)
androidTestImplementation(libs.mockwebserver)
androidTestImplementation(libs.androidx.uiautomator)
// Debugging
debugImplementation(libs.leakcanary.android)
// Support libraries
implementation(libs.androidx.browser)
implementation(libs.androidx.cardview)
implementation(libs.androidx.constraintlayout)
implementation(libs.androidx.exifinterface)
implementation(libs.recyclerview.fastscroll)
//swipe_layout
implementation(libs.swipelayout.library)
//Room
implementation(libs.androidx.room.runtime)
implementation(libs.androidx.room.ktx)
implementation(libs.androidx.room.rxjava)
kapt(libs.androidx.room.compiler)
// Preferences
implementation(libs.androidx.preference)
implementation(libs.androidx.preference.ktx)
//Android Media
implementation(libs.juanitobananas.androidDmediaUtil)
implementation(libs.androidx.multidex)
// Kotlin + coroutines
implementation(libs.androidx.work.runtime.ktx)
implementation(libs.androidx.work.runtime)
testImplementation(libs.androidx.work.testing)
//Glide
implementation(libs.glide)
annotationProcessor(libs.glide.compiler)
kaptTest(libs.androidx.databinding.compiler)
kaptAndroidTest(libs.androidx.databinding.compiler)
implementation(libs.coordinates2country.android) {
exclude(group = "com.google.android", module = "android")
}
//OSMDroid
implementation(libs.osmdroid.android)
constraints {
implementation(libs.kotlin.stdlib.jdk7) {
because("kotlin-stdlib-jdk7 is now a part of kotlin-stdlib")
}
implementation(libs.kotlin.stdlib.jdk8) {
because("kotlin-stdlib-jdk8 is now a part of kotlin-stdlib")
}
}
}
tasks.register<Exec>("disableAnimations") {
val adb = "${System.getenv("ANDROID_HOME")}/platform-tools/adb"
commandLine(adb, "shell", "settings", "put", "global", "window_animation_scale", "0")
commandLine(adb, "shell", "settings", "put", "global", "transition_animation_scale", "0")
commandLine(adb, "shell", "settings", "put", "global", "animator_duration_scale", "0")
}
project.gradle.taskGraph.whenReady {
val connectedBetaDebugAndroidTest = tasks.named("connectedBetaDebugAndroidTest")
val connectedProdDebugAndroidTest = tasks.named("connectedProdDebugAndroidTest")
connectedBetaDebugAndroidTest.configure {
dependsOn("disableAnimations")
}
connectedProdDebugAndroidTest.configure {
dependsOn("disableAnimations")
}
}
fun getTestUserName(): String? {
val propFile = rootProject.file("./local.properties")
val properties = Properties()
propFile.inputStream().use { properties.load(it) }
return properties.getProperty("TEST_USER_NAME")
}
fun getTestPassword(): String? {
val propFile = rootProject.file("./local.properties")
val properties = Properties()
propFile.inputStream().use { properties.load(it) }
return properties.getProperty("TEST_USER_PASSWORD")
}
if (isRunningOnTravisAndIsNotPRBuild) {
configure<com.github.triplet.gradle.play.PlayPublisherExtension> {
track = "alpha"
userFraction = 1.0
serviceAccountEmail = System.getenv("SERVICE_ACCOUNT_NAME")
serviceAccountCredentials = file("../play.p12")
resolutionStrategy = "auto"
outputProcessor { // this: ApkVariantOutput
versionNameOverride = "$versionNameOverride.$versionCode"
}
}
}
fun getBuildVersion(): String? {
return try {
val stdout = ByteArrayOutputStream()
exec {
commandLine("git", "rev-parse", "--short", "HEAD")
standardOutput = stdout
}
stdout.toString().trim()
} catch (e: Exception) {
null
}
}
fun getBranchName(): String? {
return try {
val stdout = ByteArrayOutputStream()
exec {
commandLine("git", "rev-parse", "--abbrev-ref", "HEAD")
standardOutput = stdout
}
stdout.toString().trim()
} catch (e: Exception) {
null
}
}