Skip to content

Commit

Permalink
feat: added build-logic and refactor plugin (#2094)
Browse files Browse the repository at this point in the history
* feat: added  build-logic and refactor plugin

* feat: added build-logic and refactor plugin

* fix: fix test and lint check fails

* fix: code clean up

* fix: remove crashlytic for sspecific flavors
  • Loading branch information
Aditya-gupta99 committed May 9, 2024
1 parent 9e8f83f commit e282602
Show file tree
Hide file tree
Showing 86 changed files with 1,761 additions and 376 deletions.
38 changes: 38 additions & 0 deletions build-logic/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,38 @@
# Convention Plugins

The `build-logic` folder defines project-specific convention plugins, used to keep a single
source of truth for common module configurations.

This approach is heavily based on
[https://developer.squareup.com/blog/herding-elephants/](https://developer.squareup.com/blog/herding-elephants/)
and
[https://github.com/jjohannes/idiomatic-gradle](https://github.com/jjohannes/idiomatic-gradle).

By setting up convention plugins in `build-logic`, we can avoid duplicated build script setup,
messy `subproject` configurations, without the pitfalls of the `buildSrc` directory.

`build-logic` is an included build, as configured in the root
[`settings.gradle.kts`](../settings.gradle.kts).

Inside `build-logic` is a `convention` module, which defines a set of plugins that all normal
modules can use to configure themselves.

`build-logic` also includes a set of `Kotlin` files used to share logic between plugins themselves,
which is most useful for configuring Android components (libraries vs applications) with shared
code.

These plugins are *additive* and *composable*, and try to only accomplish a single responsibility.
Modules can then pick and choose the configurations they need.
If there is one-off logic for a module without shared code, it's preferable to define that directly
in the module's `build.gradle`, as opposed to creating a convention plugin with module-specific
setup.

Current list of convention plugins:

- [`mifospay.android.application`](convention/src/main/kotlin/AndroidApplicationConventionPlugin.kt),
[`mifospay.android.library`](convention/src/main/kotlin/AndroidLibraryConventionPlugin.kt),
[`mifospay.android.test`](convention/src/main/kotlin/AndroidTestConventionPlugin.kt):
Configures common Android and Kotlin options.
- [`mifospay.android.application.compose`](convention/src/main/kotlin/AndroidApplicationComposeConventionPlugin.kt),
[`mifospay.android.library.compose`](convention/src/main/kotlin/AndroidLibraryComposeConventionPlugin.kt):
Configures Jetpack Compose options
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
import com.android.build.api.dsl.ApplicationExtension
import org.gradle.api.Plugin
import org.gradle.api.Project
import org.gradle.kotlin.dsl.getByType
import org.mifos.configureAndroidCompose

class AndroidApplicationComposeConventionPlugin : Plugin<Project> {
override fun apply(target: Project) {
with(target) {
pluginManager.apply("com.android.application")

val extension = extensions.getByType<ApplicationExtension>()
configureAndroidCompose(extension)
}
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,33 @@
import com.android.build.api.dsl.ApplicationExtension
import com.android.build.api.variant.ApplicationAndroidComponentsExtension
import com.android.build.gradle.BaseExtension
import org.gradle.api.Plugin
import org.gradle.api.Project
import org.gradle.kotlin.dsl.configure
import org.gradle.kotlin.dsl.getByType
import org.mifos.configureBadgingTasks
import org.mifos.configureKotlinAndroid
import org.mifos.configurePrintApksTask

class AndroidApplicationConventionPlugin : Plugin<Project> {
override fun apply(target: Project) {
with(target) {
with(pluginManager) {
apply("com.android.application")
apply("org.jetbrains.kotlin.android")
apply("mifos.android.lint")
}

extensions.configure<ApplicationExtension> {
configureKotlinAndroid(this)
defaultConfig.targetSdk = 34
@Suppress("UnstableApiUsage")
testOptions.animationsDisabled = true
}
extensions.configure<ApplicationAndroidComponentsExtension> {
configurePrintApksTask(this)
configureBadgingTasks(extensions.getByType<BaseExtension>(), this)
}
}
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,39 @@
import com.android.build.api.dsl.ApplicationExtension
import com.google.firebase.crashlytics.buildtools.gradle.CrashlyticsExtension
import org.gradle.api.Plugin
import org.gradle.api.Project
import org.gradle.kotlin.dsl.configure
import org.gradle.kotlin.dsl.dependencies
import org.mifos.libs

class AndroidApplicationFirebaseConventionPlugin : Plugin<Project> {
override fun apply(target: Project) {
with(target) {
with(pluginManager) {
apply("com.google.gms.google-services")
apply("com.google.firebase.firebase-perf")
apply("com.google.firebase.crashlytics")
}

dependencies {
val bom = libs.findLibrary("firebase-bom").get()
add("implementation", platform(bom))
"implementation"(libs.findLibrary("firebase.analytics").get())
"implementation"(libs.findLibrary("firebase.performance").get())
"implementation"(libs.findLibrary("firebase.crashlytics").get())
"implementation"(libs.findLibrary("firebase.cloud.messaging").get())
}

extensions.configure<ApplicationExtension> {
buildTypes.configureEach {
// Disable the Crashlytics mapping file upload. This feature should only be
// enabled if a Firebase backend is available and configured in
// google-services.json.
configure<CrashlyticsExtension> {
mappingFileUploadEnabled = false
}
}
}
}
}
}
40 changes: 40 additions & 0 deletions build-logic/convention/bin/main/AndroidFeatureConventionPlugin.kt
Original file line number Diff line number Diff line change
@@ -0,0 +1,40 @@
import com.android.build.gradle.LibraryExtension
import org.gradle.api.Plugin
import org.gradle.api.Project
import org.gradle.kotlin.dsl.configure
import org.gradle.kotlin.dsl.dependencies
import org.mifos.libs

class AndroidFeatureConventionPlugin : Plugin<Project> {
override fun apply(target: Project) {
with(target) {
pluginManager.apply {
apply("mifos.android.library")
apply("mifos.android.hilt")
}
extensions.configure<LibraryExtension> {
defaultConfig {
// set custom test runner
testInstrumentationRunner = "androidx.test.runner.AndroidJUnitRunner"
}
testOptions.animationsDisabled = true
}

dependencies {
add("implementation", project(":core:data"))
add("implementation", project(":core:designsystem"))
add("implementation", project(":core:common"))

add("implementation", libs.findLibrary("androidx.hilt.navigation.compose").get())
add("implementation", libs.findLibrary("androidx.lifecycle.runtimeCompose").get())
add("implementation", libs.findLibrary("androidx.lifecycle.viewModelCompose").get())
add("implementation", libs.findLibrary("androidx.tracing.ktx").get())

add(
"androidTestImplementation",
libs.findLibrary("androidx.lifecycle.runtimeTesting").get()
)
}
}
}
}
20 changes: 20 additions & 0 deletions build-logic/convention/bin/main/AndroidHiltConventionPlugin.kt
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
import org.gradle.api.Plugin
import org.gradle.api.Project
import org.gradle.kotlin.dsl.dependencies
import org.mifos.libs

class AndroidHiltConventionPlugin : Plugin<Project> {
override fun apply(target: Project) {
with(target) {
with(pluginManager) {
apply("com.google.devtools.ksp")
apply("dagger.hilt.android.plugin")
}

dependencies {
"implementation"(libs.findLibrary("hilt.android").get())
"ksp"(libs.findLibrary("hilt.compiler").get())
}
}
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
import com.android.build.gradle.LibraryExtension
import org.gradle.api.Plugin
import org.gradle.api.Project
import org.gradle.kotlin.dsl.getByType
import org.mifos.configureAndroidCompose

class AndroidLibraryComposeConventionPlugin : Plugin<Project> {
override fun apply(target: Project) {
with(target) {
pluginManager.apply("com.android.library")

val extension = extensions.getByType<LibraryExtension>()
configureAndroidCompose(extension)
}
}

}
42 changes: 42 additions & 0 deletions build-logic/convention/bin/main/AndroidLibraryConventionPlugin.kt
Original file line number Diff line number Diff line change
@@ -0,0 +1,42 @@
import com.android.build.api.variant.LibraryAndroidComponentsExtension
import com.android.build.gradle.LibraryExtension
import org.gradle.api.Plugin
import org.gradle.api.Project
import org.gradle.kotlin.dsl.configure
import org.gradle.kotlin.dsl.dependencies
import org.gradle.kotlin.dsl.kotlin
import org.mifos.configureKotlinAndroid
import org.mifos.configurePrintApksTask
import org.mifos.disableUnnecessaryAndroidTests
import org.mifos.libs

class AndroidLibraryConventionPlugin : Plugin<Project> {
override fun apply(target: Project) {
with(target) {
with(pluginManager) {
apply("com.android.library")
apply("org.jetbrains.kotlin.android")
apply("mifos.android.lint")
}

extensions.configure<LibraryExtension> {
configureKotlinAndroid(this)
defaultConfig.targetSdk = 34
testOptions.animationsDisabled = true
// The resource prefix is derived from the module name,
// so resources inside ":core:module1" must be prefixed with "core_module1_"
resourcePrefix =
path.split("""\W""".toRegex()).drop(1).distinct().joinToString(separator = "_")
.lowercase() + "_"
}
extensions.configure<LibraryAndroidComponentsExtension> {
configurePrintApksTask(this)
disableUnnecessaryAndroidTests(target)
}
dependencies {
add("testImplementation", kotlin("test"))
add("implementation", libs.findLibrary("androidx.tracing.ktx").get())
}
}
}
}
30 changes: 30 additions & 0 deletions build-logic/convention/bin/main/AndroidLintConventionPlugin.kt
Original file line number Diff line number Diff line change
@@ -0,0 +1,30 @@
import com.android.build.api.dsl.ApplicationExtension
import com.android.build.api.dsl.LibraryExtension
import com.android.build.api.dsl.Lint
import org.gradle.api.Plugin
import org.gradle.api.Project
import org.gradle.kotlin.dsl.configure

class AndroidLintConventionPlugin : Plugin<Project> {
override fun apply(target: Project) {
with(target) {
when {
pluginManager.hasPlugin("com.android.application") ->
configure<ApplicationExtension> { lint(Lint::configure) }

pluginManager.hasPlugin("com.android.library") ->
configure<LibraryExtension> { lint(Lint::configure) }

else -> {
pluginManager.apply("com.android.lint")
configure<Lint>(Lint::configure)
}
}
}
}
}

private fun Lint.configure() {
xmlReport = true
checkDependencies = true
}
29 changes: 29 additions & 0 deletions build-logic/convention/bin/main/AndroidRoomConventionPlugin.kt
Original file line number Diff line number Diff line change
@@ -0,0 +1,29 @@
import androidx.room.gradle.RoomExtension
import org.gradle.api.Plugin
import org.gradle.api.Project
import org.gradle.kotlin.dsl.configure
import org.gradle.kotlin.dsl.dependencies
import org.mifos.libs

class AndroidRoomConventionPlugin : Plugin<Project> {

override fun apply(target: Project) {
with(target) {
pluginManager.apply("androidx.room")
pluginManager.apply("com.google.devtools.ksp")

extensions.configure<RoomExtension> {
// The schemas directory contains a schema file for each version of the Room database.
// This is required to enable Room auto migrations.
// See https://developer.android.com/reference/kotlin/androidx/room/AutoMigration.
schemaDirectory("$projectDir/schemas")
}

dependencies {
add("implementation", libs.findLibrary("room.runtime").get())
add("implementation", libs.findLibrary("room.ktx").get())
add("ksp", libs.findLibrary("room.compiler").get())
}
}
}
}
21 changes: 21 additions & 0 deletions build-logic/convention/bin/main/AndroidTestConventionPlugin.kt
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
import com.android.build.gradle.TestExtension
import org.gradle.api.Plugin
import org.gradle.api.Project
import org.gradle.kotlin.dsl.configure
import org.mifos.configureKotlinAndroid

class AndroidTestConventionPlugin : Plugin<Project> {
override fun apply(target: Project) {
with(target) {
with(pluginManager) {
apply("com.android.test")
apply("org.jetbrains.kotlin.android")
}

extensions.configure<TestExtension> {
configureKotlinAndroid(this)
defaultConfig.targetSdk = 34
}
}
}
}
15 changes: 15 additions & 0 deletions build-logic/convention/bin/main/JvmLibraryConventionPlugin.kt
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
import org.gradle.api.Plugin
import org.gradle.api.Project
import org.mifos.configureKotlinJvm

class JvmLibraryConventionPlugin : Plugin<Project> {
override fun apply(target: Project) {
with(target) {
with(pluginManager) {
apply("org.jetbrains.kotlin.jvm")
apply("mifos.android.lint")
}
configureKotlinJvm()
}
}
}

0 comments on commit e282602

Please sign in to comment.