diff --git a/app/k9mail/build.gradle b/app/k9mail/build.gradle
index 9f6fa38a2..e86cbf52b 100644
--- a/app/k9mail/build.gradle
+++ b/app/k9mail/build.gradle
@@ -1,5 +1,5 @@
plugins {
- id("thunderbird.app.android.default")
+ id("thunderbird.app.android")
}
if (rootProject.testCoverage) {
diff --git a/build-plugin/README.md b/build-plugin/README.md
new file mode 100644
index 000000000..9df6be12a
--- /dev/null
+++ b/build-plugin/README.md
@@ -0,0 +1,70 @@
+# Build plugins
+
+The `build-plugin` folder defines Gradle build plugins, used as single source of truth for the project configuration.
+This helps to avoid duplicated build script setups and provides a central location for all common build logic.
+
+## Background
+
+We use Gradle's
+[sharing build logic in a multi-repo setup](https://docs.gradle.org/current/samples/sample_publishing_convention_plugins.html)
+to create common configuration. It allows usage of `xyz.gradle.kts` files, that are then automatically converted to
+Gradle Plugins.
+
+The `build-plugin` is used as included build in the root `settings.gradle.kts` and provides all
+included `xyz.gradle.kts` as plugins under their `xyz` name to the whole project.
+
+The plugins should try to accomplish single responsibility and leave one-off configuration to the module's `build.gradle.kts`.
+
+## Convention plugins
+
+- `thunderbird.app.android` - Configures common options for Android apps
+- `thunderbird.app.android.compose` - Configures common options for Jetpack Compose, based
+ on `thunderbird.app.android`
+- `thunderbird.library.android` - Configures common options for Android libraries
+- `thunderbird.library.android.compose` - Configures common options for Jetpack Compose, based
+ on `thunderbird.library.android`
+- `thunderbird.library.jvm` - Configures common options for JVM libraries
+
+## Supportive plugins
+
+- `thunderbird.quality.detekt` - [Detekt - Static code analysis for Kotlin ](https://detekt.dev/)
+ - Use `./gradlew detekt` to check for any issue and `./gradlew detektBaseline` in case you can't fix the reported
+ issue.
+- `thunderbird.quality.spotless` - [Spotless - Code formatter](https://github.com/diffplug/spotless)
+ with [Ktlint - Kotlin linter and formatter](https://pinterest.github.io/ktlint/)
+ - Use `./gradlew spotlessCheck` to check for any issue and `./gradlew spotlessApply` to format your code
+
+## Add new build plugin
+
+Create a `thunderbird.xyz.gradle.kts` file, while `xyz` describes the new plugin.
+
+If you need to access dependencies that are not yet defined in `build-plugin/build.gradle.kts` you have to:
+
+1. Add the dependency to the version catalog `gradle/libs.versions.toml`
+2. Then add it to `build-plugin/build.gradle.kts`.
+ 1. In case of a plugin dependency use `implementation(plugin(libs.plugins.YOUR_PLUGIN_DEPENDENCY))`.
+ 1. Otherwise `implementation(libs.YOUR_DEPENDENCY))`.
+
+When done, add the plugin to `build-plugin/src/main/kotlin/ThunderbirdPlugins.kt`
+
+Then apply the plugin to any subproject it should be used with:
+
+```
+plugins {
+ id(ThunderbirdPlugins.xyz)
+}
+```
+
+If the plugin is meant for the root `build.gradle.kts`, you can't use `ThunderbirdPlugins`, as it's not available to
+the `plugins` block. Instead use:
+
+```
+plugins {
+ id("thunderbird.xyz")
+}
+```
+
+## Acknowledgments
+
+- [Herding Elephants | Square Corner Blog](https://developer.squareup.com/blog/herding-elephants/)
+- [Idiomatic Gradle: How do I idiomatically structure a large build with Gradle](https://github.com/jjohannes/idiomatic-gradle#idiomatic-build-logic-structure)
diff --git a/build-plugin/src/main/kotlin/ThunderbirdPlugins.kt b/build-plugin/src/main/kotlin/ThunderbirdPlugins.kt
index b304084de..3a4e97e93 100644
--- a/build-plugin/src/main/kotlin/ThunderbirdPlugins.kt
+++ b/build-plugin/src/main/kotlin/ThunderbirdPlugins.kt
@@ -1,6 +1,7 @@
object ThunderbirdPlugins {
object App {
+ const val android = "thunderbird.app.android"
const val androidCompose = "thunderbird.app.android.compose"
}
object Library {
diff --git a/build-plugin/src/main/kotlin/thunderbird.app.android.compose.gradle.kts b/build-plugin/src/main/kotlin/thunderbird.app.android.compose.gradle.kts
index 82d514aa0..49256ffa6 100644
--- a/build-plugin/src/main/kotlin/thunderbird.app.android.compose.gradle.kts
+++ b/build-plugin/src/main/kotlin/thunderbird.app.android.compose.gradle.kts
@@ -1,5 +1,5 @@
plugins {
- id("thunderbird.app.android.default")
+ id("thunderbird.app.android")
}
android {
diff --git a/build-plugin/src/main/kotlin/thunderbird.app.android.default.gradle.kts b/build-plugin/src/main/kotlin/thunderbird.app.android.gradle.kts
similarity index 100%
rename from build-plugin/src/main/kotlin/thunderbird.app.android.default.gradle.kts
rename to build-plugin/src/main/kotlin/thunderbird.app.android.gradle.kts
diff --git a/config/detekt/baseline.xml b/config/detekt/baseline.xml
index 28c0c24b1..501c5f10a 100644
--- a/config/detekt/baseline.xml
+++ b/config/detekt/baseline.xml
@@ -30,6 +30,7 @@
CyclomaticComplexMethod:K9NotificationStrategy.kt$K9NotificationStrategy$override fun shouldNotifyForMessage( account: Account, localFolder: LocalFolder, message: LocalMessage, isOldMessage: Boolean, ): Boolean
CyclomaticComplexMethod:MessageList.kt$MessageList$private fun decodeExtrasToLaunchData(intent: Intent): LaunchData
CyclomaticComplexMethod:MessageList.kt$MessageList$private fun onCustomKeyDown(event: KeyEvent): Boolean
+ CyclomaticComplexMethod:MessageListAdapter.kt$MessageListAdapter$private fun bindMessageViewHolder(holder: MessageViewHolder, messageListItem: MessageListItem)
CyclomaticComplexMethod:MessageListFragment.kt$MessageListFragment$override fun onOptionsItemSelected(item: MenuItem): Boolean
CyclomaticComplexMethod:MessagePartDatabaseHelpers.kt$MessagePartEntry$override fun equals(other: Any?): Boolean
CyclomaticComplexMethod:MessagePartDatabaseHelpers.kt$MessagePartEntry$override fun hashCode(): Int
@@ -139,6 +140,7 @@
LongMethod:MessageList.kt$MessageList$private fun decodeExtrasToLaunchData(intent: Intent): LaunchData
LongMethod:MessageList.kt$MessageList$private fun onCustomKeyDown(event: KeyEvent): Boolean
LongMethod:MessageList.kt$MessageList$public override fun onCreate(savedInstanceState: Bundle?)
+ LongMethod:MessageListAdapter.kt$MessageListAdapter$private fun bindMessageViewHolder(holder: MessageViewHolder, messageListItem: MessageListItem)
LongMethod:MessageListRepositoryTest.kt$MessageListRepositoryTest$@Test fun `getThread() should use flag values from the cache`()
LongMethod:MessageTest.kt$MessageTest$@Test fun toBodyPart()
LongMethod:MessageTest.kt$MessageTest$@Test fun writeTo_withNestedMessage()
@@ -448,6 +450,7 @@
MagicNumber:StorageMigrations.kt$StorageMigrations$17
MagicNumber:StorageMigrations.kt$StorageMigrations$18
MagicNumber:StorageMigrations.kt$StorageMigrations$19
+ MagicNumber:StorageMigrations.kt$StorageMigrations$20
MagicNumber:StorageMigrations.kt$StorageMigrations$3
MagicNumber:StorageMigrations.kt$StorageMigrations$4
MagicNumber:StorageMigrations.kt$StorageMigrations$5