pachli-android/app/build.gradle.kts

212 lines
6.3 KiB
Plaintext
Raw Normal View History

refactor: Start creating core modules (#286) The existing code base is a single monolithic module. This is relatively simple to configure, but many of the tasks to compile the module and produce the final app have to run in series. This is unnecessarily slow. This change starts to split the code in to multiple modules, which are: - :core:account - AccountManager, to break a dependency cycle - :core:common - low level types or utilities used in many other modules - :core:database - database types, DAOs, and DI infrastructure - :core:network - network types, API definitions, and DI infrastructure - :core:preferences - shared preferences definitions and DI infrastructure - :core:testing - fakes and rules used across different modules Benchmarking with gradle-profiler shows a ~ 17% reduction in incremental build times after an ABI change. That will improve further as more code is moved to modules. The rough mechanics of the changes are: - Create the modules, and move existing files in to them. This causes a lot of churn in import arguments. - Convert build.gradle files to build.gradle.kts - Separate out the data required to display a tab (`TabViewData`) from the data required to configure a tab (`TabData`) to avoid circular dependencies. - Abstract the repeated build logic shared between the modules in to a set of plugins under `build-logic/`, to simplify configuration of the application and library builds. - Be explicit that some nullable types are non-null at time of use. Nullable properties in types imported from modules generally can't be smart cast to non-null. There's a detailed discussion of why this restriction exists at https://discuss.kotlinlang.org/t/what-is-the-reason-behind-smart-cast-being-impossible-to-perform-when-referenced-class-is-in-another-module/2201. The changes highlight design problems with the current code, including: - The main application code is too tightly coupled to the network types - Too many values are declared unnecessarily nullable - Dependency cycles between code that make modularisation difficult Future changes will add more modules. See #291.
2023-12-04 16:58:36 +01:00
/*
* Copyright 2023 Pachli Association
*
* This file is a part of Pachli.
*
* This program is free software; you can redistribute it and/or modify it under the terms of the
* GNU General Public License as published by the Free Software Foundation; either version 3 of the
* License, or (at your option) any later version.
*
* Pachli is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even
* the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General
* Public License for more details.
*
* You should have received a copy of the GNU General Public License along with Pachli; if not,
* see <http://www.gnu.org/licenses>.
*/
import com.android.build.gradle.internal.api.ApkVariantOutputImpl
plugins {
alias(libs.plugins.pachli.android.application)
alias(libs.plugins.pachli.android.hilt)
alias(libs.plugins.kotlin.parcelize)
alias(libs.plugins.aboutlibraries)
id("app.pachli.plugins.markdown2resource")
}
apply(from = "gitTools.gradle")
val getGitSha: groovy.lang.Closure<String> by extra
val getGitRevCount: groovy.lang.Closure<Int> by extra
android {
namespace = "app.pachli"
defaultConfig {
applicationId = "app.pachli"
versionCode = 10
versionName = "2.1.1"
refactor: Start creating core modules (#286) The existing code base is a single monolithic module. This is relatively simple to configure, but many of the tasks to compile the module and produce the final app have to run in series. This is unnecessarily slow. This change starts to split the code in to multiple modules, which are: - :core:account - AccountManager, to break a dependency cycle - :core:common - low level types or utilities used in many other modules - :core:database - database types, DAOs, and DI infrastructure - :core:network - network types, API definitions, and DI infrastructure - :core:preferences - shared preferences definitions and DI infrastructure - :core:testing - fakes and rules used across different modules Benchmarking with gradle-profiler shows a ~ 17% reduction in incremental build times after an ABI change. That will improve further as more code is moved to modules. The rough mechanics of the changes are: - Create the modules, and move existing files in to them. This causes a lot of churn in import arguments. - Convert build.gradle files to build.gradle.kts - Separate out the data required to display a tab (`TabViewData`) from the data required to configure a tab (`TabData`) to avoid circular dependencies. - Abstract the repeated build logic shared between the modules in to a set of plugins under `build-logic/`, to simplify configuration of the application and library builds. - Be explicit that some nullable types are non-null at time of use. Nullable properties in types imported from modules generally can't be smart cast to non-null. There's a detailed discussion of why this restriction exists at https://discuss.kotlinlang.org/t/what-is-the-reason-behind-smart-cast-being-impossible-to-perform-when-referenced-class-is-in-another-module/2201. The changes highlight design problems with the current code, including: - The main application code is too tightly coupled to the network types - Too many values are declared unnecessarily nullable - Dependency cycles between code that make modularisation difficult Future changes will add more modules. See #291.
2023-12-04 16:58:36 +01:00
testInstrumentationRunner = "androidx.test.runner.AndroidJUnitRunner"
testInstrumentationRunnerArguments["disableAnalytics"] = "true"
vectorDrawables.useSupportLibrary = true
}
buildTypes {
debug {
isDefault = true
}
release {
isMinifyEnabled = true
isShrinkResources = true
proguardFiles(getDefaultProguardFile("proguard-android-optimize.txt"), "proguard-rules.pro")
}
}
packaging {
resources.excludes.apply {
add("LICENSE_OFL")
add("LICENSE_UNICODE")
}
}
bundle {
language {
// bundle all languages in every apk so the dynamic language switching works
enableSplit = false
}
}
dependenciesInfo {
includeInApk = false
includeInBundle = false
}
testOptions {
unitTests {
isReturnDefaultValues = true
isIncludeAndroidResources = true
}
unitTests.all {
it.systemProperty("robolectric.logging.enabled", "true")
it.systemProperty("robolectric.lazyload", "ON")
}
}
applicationVariants.configureEach {
tasks.register("printVersionInfo${name.replaceFirstChar { it.uppercaseChar() }}") {
notCompatibleWithConfigurationCache("Should always print the version info")
doLast {
println("$versionCode $versionName")
}
}
outputs.configureEach {
this as ApkVariantOutputImpl
// Set the "orange" release versionCode to the number of commits on the
// branch, to ensure the versionCode updates on every release. Include the
// SHA of the current commit to help with troubleshooting bug reports
if (buildType.name == "release" && flavorName.startsWith("orange")) {
versionCodeOverride = getGitRevCount()
versionNameOverride = "$versionName+${getGitSha()}"
}
outputFileName = "Pachli_${versionName}_${versionCode}_${getGitSha()}_${flavorName}_${buildType.name}.apk"
}
}
}
configurations {
// JNI-only libraries don't play nicely with Robolectric
// see https://github.com/tuskyapp/Tusky/pull/3367 and
// https://github.com/google/conscrypt/issues/649
testImplementation {
exclude(group = "org.conscrypt", module = "conscrypt-android")
}
}
aboutLibraries {
configPath = "licenses"
includePlatform = false
duplicationMode = com.mikepenz.aboutlibraries.plugin.DuplicateMode.MERGE
prettyPrint = true
}
markdown2resource {
files.add(layout.projectDirectory.file("../PRIVACY.md"))
}
dependencies {
// CachedTimelineRemoteMediator needs the @Transaction annotation from Room
compileOnly(libs.bundles.room)
testCompileOnly(libs.bundles.room)
implementation(projects.core.accounts)
implementation(projects.core.common)
implementation(projects.core.database)
refactor: Break navigation dependency cycles with :core:navigation (#305) The previous code generally started an activity by having the activity provide a method in a companion object that returns the relevant intent, possibly taking additional parameters that will be included in the intent as extras. E.g., if A wants to start B, B provides the method that returns the intent that starts B. This introduces a dependency between A and B. This is worse if B also wants to start A. For example, if A is `StatusListActivity` and B is`ViewThreadActivity`. The user might click a status in `StatusListActivity` to view the thread, starting `ViewThreadActivity`. But from the thread they might click a hashtag to view the list of statuses with that hashtag. Now `StatusListActivity` and `ViewThreadActivity` have a circular dependency. Even if that doesn't happen the dependency means that any changes to B will trigger a rebuild of A, even if the changes to B are not relevant. Break this dependency by adding a `:core:navigation` module with an `app.pachli.core.navigation` package that contains `Intent` subclasses that should be used instead. The `quadrant` plugin is used to generate constants that can be used to launch activities by name instead of by class, breaking the dependency chain. The plugin uses the `Activity` names from the manifest, so when an activity is moved in the future the constant will automatically update to reflect the new package name. If the activity's intent requires specific extras those are passed via the constructor, with companion object methods to extract them from the intent. Using the intent classes from this package is enforced by a lint `IntentDetector` which will warn if any intents are created using a class literal. See #291
2023-12-07 18:36:00 +01:00
implementation(projects.core.navigation)
refactor: Start creating core modules (#286) The existing code base is a single monolithic module. This is relatively simple to configure, but many of the tasks to compile the module and produce the final app have to run in series. This is unnecessarily slow. This change starts to split the code in to multiple modules, which are: - :core:account - AccountManager, to break a dependency cycle - :core:common - low level types or utilities used in many other modules - :core:database - database types, DAOs, and DI infrastructure - :core:network - network types, API definitions, and DI infrastructure - :core:preferences - shared preferences definitions and DI infrastructure - :core:testing - fakes and rules used across different modules Benchmarking with gradle-profiler shows a ~ 17% reduction in incremental build times after an ABI change. That will improve further as more code is moved to modules. The rough mechanics of the changes are: - Create the modules, and move existing files in to them. This causes a lot of churn in import arguments. - Convert build.gradle files to build.gradle.kts - Separate out the data required to display a tab (`TabViewData`) from the data required to configure a tab (`TabData`) to avoid circular dependencies. - Abstract the repeated build logic shared between the modules in to a set of plugins under `build-logic/`, to simplify configuration of the application and library builds. - Be explicit that some nullable types are non-null at time of use. Nullable properties in types imported from modules generally can't be smart cast to non-null. There's a detailed discussion of why this restriction exists at https://discuss.kotlinlang.org/t/what-is-the-reason-behind-smart-cast-being-impossible-to-perform-when-referenced-class-is-in-another-module/2201. The changes highlight design problems with the current code, including: - The main application code is too tightly coupled to the network types - Too many values are declared unnecessarily nullable - Dependency cycles between code that make modularisation difficult Future changes will add more modules. See #291.
2023-12-04 16:58:36 +01:00
implementation(projects.core.network)
implementation(projects.core.preferences)
implementation(libs.kotlinx.coroutines.android)
implementation(libs.kotlinx.coroutines.rx3)
implementation(libs.bundles.androidx)
implementation(libs.android.material)
implementation(libs.gson)
implementation(libs.bundles.retrofit)
implementation(libs.networkresult.calladapter)
implementation(libs.bundles.okhttp)
implementation(libs.conscrypt.android)
implementation(libs.bundles.glide)
ksp(libs.glide.compiler)
implementation(libs.bundles.rxjava3)
implementation(libs.bundles.autodispose)
implementation(libs.sparkbutton)
implementation(libs.touchimageview)
implementation(libs.bundles.material.drawer)
implementation(libs.material.typeface)
implementation(libs.image.cropper)
implementation(libs.bundles.filemojicompat)
implementation(libs.bouncycastle)
implementation(libs.unified.push)
implementation(libs.bundles.xmldiff)
implementation(libs.bundles.aboutlibraries)
implementation(libs.timber)
googleImplementation(libs.app.update)
googleImplementation(libs.app.update.ktx)
implementation(libs.kotlin.result)
implementation(libs.semver)
debugImplementation(libs.leakcanary)
orangeImplementation(libs.bundles.acra)
refactor: Start creating core modules (#286) The existing code base is a single monolithic module. This is relatively simple to configure, but many of the tasks to compile the module and produce the final app have to run in series. This is unnecessarily slow. This change starts to split the code in to multiple modules, which are: - :core:account - AccountManager, to break a dependency cycle - :core:common - low level types or utilities used in many other modules - :core:database - database types, DAOs, and DI infrastructure - :core:network - network types, API definitions, and DI infrastructure - :core:preferences - shared preferences definitions and DI infrastructure - :core:testing - fakes and rules used across different modules Benchmarking with gradle-profiler shows a ~ 17% reduction in incremental build times after an ABI change. That will improve further as more code is moved to modules. The rough mechanics of the changes are: - Create the modules, and move existing files in to them. This causes a lot of churn in import arguments. - Convert build.gradle files to build.gradle.kts - Separate out the data required to display a tab (`TabViewData`) from the data required to configure a tab (`TabData`) to avoid circular dependencies. - Abstract the repeated build logic shared between the modules in to a set of plugins under `build-logic/`, to simplify configuration of the application and library builds. - Be explicit that some nullable types are non-null at time of use. Nullable properties in types imported from modules generally can't be smart cast to non-null. There's a detailed discussion of why this restriction exists at https://discuss.kotlinlang.org/t/what-is-the-reason-behind-smart-cast-being-impossible-to-perform-when-referenced-class-is-in-another-module/2201. The changes highlight design problems with the current code, including: - The main application code is too tightly coupled to the network types - Too many values are declared unnecessarily nullable - Dependency cycles between code that make modularisation difficult Future changes will add more modules. See #291.
2023-12-04 16:58:36 +01:00
testImplementation(projects.core.testing)
testImplementation(libs.androidx.test.junit)
testImplementation(libs.robolectric)
testImplementation(libs.bundles.mockito)
testImplementation(libs.androidx.core.testing)
testImplementation(libs.kotlinx.coroutines.test)
testImplementation(libs.androidx.work.testing)
testImplementation(libs.truth)
testImplementation(libs.turbine)
testImplementation(libs.androidx.test.core.ktx)
androidTestImplementation(libs.espresso.core)
androidTestImplementation(libs.androidx.room.testing)
androidTestImplementation(libs.androidx.test.junit)
androidTestImplementation(libs.androidx.test.core.ktx)
lintChecks(projects.checks)
}