Skip to content

Commit

Permalink
Added application flavor and applied convention plugin to all module (#…
Browse files Browse the repository at this point in the history
…2102)

* Refactor - renamed datastore module to database module

* Refactor - Added application flavor

- Moved files to respective module
- Applied convention plugins in all module
- Removed unnecessary dependencies from all module
- Added few modules like :core:ui, :core:testing, :core:domain
  • Loading branch information
niyajali authored May 25, 2024
1 parent d9cd3b1 commit 8112ffc
Show file tree
Hide file tree
Showing 390 changed files with 807 additions and 586 deletions.
12 changes: 12 additions & 0 deletions build-logic/convention/build.gradle.kts
Original file line number Diff line number Diff line change
Expand Up @@ -46,6 +46,10 @@ gradlePlugin {
id = "mifos.android.application"
implementationClass = "AndroidApplicationConventionPlugin"
}
register("androidApplicationJacoco") {
id = "mifos.android.application.jacoco"
implementationClass = "AndroidApplicationJacocoConventionPlugin"
}
register("androidHilt") {
id = "mifos.android.hilt"
implementationClass = "AndroidHiltConventionPlugin"
Expand All @@ -66,6 +70,10 @@ gradlePlugin {
id = "mifos.android.test"
implementationClass = "AndroidTestConventionPlugin"
}
register("androidLibraryJacoco") {
id = "mifos.android.library.jacoco"
implementationClass = "AndroidLibraryJacocoConventionPlugin"
}
register("androidRoom") {
id = "mifos.android.room"
implementationClass = "AndroidRoomConventionPlugin"
Expand All @@ -74,6 +82,10 @@ gradlePlugin {
id = "mifos.android.application.firebase"
implementationClass = "AndroidApplicationFirebaseConventionPlugin"
}
register("androidFlavors") {
id = "mifos.android.application.flavors"
implementationClass = "AndroidApplicationFlavorsConventionPlugin"
}
register("androidLint") {
id = "mifos.android.lint"
implementationClass = "AndroidLintConventionPlugin"
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@ import org.gradle.api.Project
import org.gradle.kotlin.dsl.configure
import org.gradle.kotlin.dsl.getByType
import org.mifos.configureBadgingTasks
import org.mifos.configureGradleManagedDevices
import org.mifos.configureKotlinAndroid
import org.mifos.configurePrintApksTask

Expand All @@ -23,6 +24,7 @@ class AndroidApplicationConventionPlugin : Plugin<Project> {
defaultConfig.targetSdk = 34
@Suppress("UnstableApiUsage")
testOptions.animationsDisabled = true
configureGradleManagedDevices(this)
}
extensions.configure<ApplicationAndroidComponentsExtension> {
configurePrintApksTask(this)
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
import com.android.build.api.dsl.ApplicationExtension
import org.gradle.api.Plugin
import org.gradle.api.Project
import org.gradle.kotlin.dsl.configure
import org.mifos.configureFlavors

class AndroidApplicationFlavorsConventionPlugin : Plugin<Project> {
override fun apply(target: Project) {
with(target) {
extensions.configure<ApplicationExtension> {
configureFlavors(this)
}
}
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
import com.android.build.api.variant.ApplicationAndroidComponentsExtension
import com.android.build.gradle.internal.dsl.BaseAppModuleExtension
import org.gradle.api.Plugin
import org.gradle.api.Project
import org.gradle.kotlin.dsl.getByType
import org.mifos.configureJacoco

class AndroidApplicationJacocoConventionPlugin : Plugin<Project> {
override fun apply(target: Project) {
with(target) {
pluginManager.apply("jacoco")
val androidExtension = extensions.getByType<BaseAppModuleExtension>()

androidExtension.buildTypes.configureEach {
enableAndroidTestCoverage = true
enableUnitTestCoverage = true
}

configureJacoco(extensions.getByType<ApplicationAndroidComponentsExtension>())
}
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@ 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.configureGradleManagedDevices
import org.mifos.libs

class AndroidFeatureConventionPlugin : Plugin<Project> {
Expand All @@ -15,25 +16,24 @@ class AndroidFeatureConventionPlugin : Plugin<Project> {
extensions.configure<LibraryExtension> {
defaultConfig {
// set custom test runner
testInstrumentationRunner = "androidx.test.runner.AndroidJUnitRunner"
testInstrumentationRunner = "com.mifos.core.testing.MifosTestRunner"
}
testOptions.animationsDisabled = true
configureGradleManagedDevices(this)
}

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

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()
)
add("androidTestImplementation", libs.findLibrary("androidx.lifecycle.runtimeTesting").get())
}
}
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -7,13 +7,13 @@ class AndroidHiltConventionPlugin : Plugin<Project> {
override fun apply(target: Project) {
with(target) {
with(pluginManager) {
apply("com.google.devtools.ksp")
apply("org.jetbrains.kotlin.kapt")
apply("dagger.hilt.android.plugin")
}

dependencies {
"implementation"(libs.findLibrary("hilt.android").get())
"ksp"(libs.findLibrary("hilt.compiler").get())
"kapt"(libs.findLibrary("hilt.compiler").get())
}
}
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,8 @@ 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.configureFlavors
import org.mifos.configureGradleManagedDevices
import org.mifos.configureKotlinAndroid
import org.mifos.configurePrintApksTask
import org.mifos.disableUnnecessaryAndroidTests
Expand All @@ -23,6 +25,8 @@ class AndroidLibraryConventionPlugin : Plugin<Project> {
configureKotlinAndroid(this)
defaultConfig.targetSdk = 34
testOptions.animationsDisabled = true
configureFlavors(this)
configureGradleManagedDevices(this)
// The resource prefix is derived from the module name,
// so resources inside ":core:module1" must be prefixed with "core_module1_"
resourcePrefix =
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
import com.android.build.api.dsl.LibraryExtension
import com.android.build.api.variant.LibraryAndroidComponentsExtension
import org.gradle.api.Plugin
import org.gradle.api.Project
import org.gradle.kotlin.dsl.getByType
import org.mifos.configureJacoco

class AndroidLibraryJacocoConventionPlugin : Plugin<Project> {
override fun apply(target: Project) {
with(target) {
pluginManager.apply("jacoco")
val androidExtension = extensions.getByType<LibraryExtension>()

androidExtension.buildTypes.configureEach {
enableAndroidTestCoverage = true
enableUnitTestCoverage = true
}

configureJacoco(extensions.getByType<LibraryAndroidComponentsExtension>())
}
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@ 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.configureGradleManagedDevices
import org.mifos.configureKotlinAndroid

class AndroidTestConventionPlugin : Plugin<Project> {
Expand All @@ -14,6 +15,7 @@ class AndroidTestConventionPlugin : Plugin<Project> {

extensions.configure<TestExtension> {
configureKotlinAndroid(this)
configureGradleManagedDevices(this)
defaultConfig.targetSdk = 34
}
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -45,6 +45,7 @@ internal fun Project.configureAndroidCompose(
kotlinOptions {
freeCompilerArgs += buildComposeMetricsParameters()
freeCompilerArgs += stabilityConfiguration()
freeCompilerArgs += strongSkippingConfiguration()
}
}
}
Expand Down Expand Up @@ -79,3 +80,8 @@ private fun Project.stabilityConfiguration() = listOf(
"-P",
"plugin:androidx.compose.compiler.plugins.kotlin:stabilityConfigurationPath=${project.rootDir.absolutePath}/compose_compiler_config.conf",
)

private fun Project.strongSkippingConfiguration() = listOf(
"-P",
"plugin:androidx.compose.compiler.plugins.kotlin:experimentalStrongSkipping=true",
)
Original file line number Diff line number Diff line change
@@ -0,0 +1,54 @@
package org.mifos

import com.android.build.api.dsl.CommonExtension
import com.android.build.api.dsl.ManagedVirtualDevice
import org.gradle.kotlin.dsl.get
import org.gradle.kotlin.dsl.invoke

/**
* Configure project for Gradle managed devices
*/
internal fun configureGradleManagedDevices(
commonExtension: CommonExtension<*, *, *, *, *>,
) {
val pixel4 = DeviceConfig("Pixel 4", 30, "aosp-atd")
val pixel6 = DeviceConfig("Pixel 6", 31, "aosp")
val pixelC = DeviceConfig("Pixel C", 30, "aosp-atd")

val allDevices = listOf(pixel4, pixel6, pixelC)
val ciDevices = listOf(pixel4, pixelC)

commonExtension.testOptions {
managedDevices {
devices {
allDevices.forEach { deviceConfig ->
maybeCreate(deviceConfig.taskName, ManagedVirtualDevice::class.java).apply {
device = deviceConfig.device
apiLevel = deviceConfig.apiLevel
systemImageSource = deviceConfig.systemImageSource
}
}
}
groups {
maybeCreate("ci").apply {
ciDevices.forEach { deviceConfig ->
targetDevices.add(devices[deviceConfig.taskName])
}
}
}
}
}
}

private data class DeviceConfig(
val device: String,
val apiLevel: Int,
val systemImageSource: String,
) {
val taskName = buildString {
append(device.lowercase().replace(" ", ""))
append("api")
append(apiLevel.toString())
append(systemImageSource.replace("-", ""))
}
}
112 changes: 112 additions & 0 deletions build-logic/convention/src/main/kotlin/org/mifos/Jacoco.kt
Original file line number Diff line number Diff line change
@@ -0,0 +1,112 @@
package org.mifos

import com.android.build.api.artifact.ScopedArtifact
import com.android.build.api.variant.AndroidComponentsExtension
import com.android.build.api.variant.ScopedArtifacts
import org.gradle.api.Project
import org.gradle.api.file.Directory
import org.gradle.api.file.RegularFile
import org.gradle.api.provider.ListProperty
import org.gradle.api.tasks.testing.Test
import org.gradle.kotlin.dsl.configure
import org.gradle.kotlin.dsl.register
import org.gradle.kotlin.dsl.withType
import org.gradle.testing.jacoco.plugins.JacocoPluginExtension
import org.gradle.testing.jacoco.plugins.JacocoTaskExtension
import org.gradle.testing.jacoco.tasks.JacocoReport
import java.util.Locale

private val coverageExclusions = listOf(
// Android
"**/R.class",
"**/R\$*.class",
"**/BuildConfig.*",
"**/Manifest*.*",
"**/*_Hilt*.class",
"**/Hilt_*.class",
)

private fun String.capitalize() = replaceFirstChar {
if (it.isLowerCase()) it.titlecase(Locale.getDefault()) else it.toString()
}

/**
* Creates a new task that generates a combined coverage report with data from local and
* instrumented tests.
*
* `create{variant}CombinedCoverageReport`
*
* Note that coverage data must exist before running the task. This allows us to run device
* tests on CI using a different Github Action or an external device farm.
*/
internal fun Project.configureJacoco(
androidComponentsExtension: AndroidComponentsExtension<*, *, *>,
) {
configure<JacocoPluginExtension> {
toolVersion = libs.findVersion("jacoco").get().toString()
}

androidComponentsExtension.onVariants { variant ->
val myObjFactory = project.objects
val buildDir = layout.buildDirectory.get().asFile
val allJars: ListProperty<RegularFile> = myObjFactory.listProperty(RegularFile::class.java)
val allDirectories: ListProperty<Directory> =
myObjFactory.listProperty(Directory::class.java)
val reportTask =
tasks.register(
"create${variant.name.capitalize()}CombinedCoverageReport",
JacocoReport::class
) {

classDirectories.setFrom(
allJars,
allDirectories.map { dirs ->
dirs.map { dir ->
myObjFactory.fileTree().setDir(dir).exclude(coverageExclusions)
}
}
)
reports {
xml.required.set(true)
html.required.set(true)
}

// TODO: This is missing files in src/debug/, src/prod, src/demo, src/demoDebug...
sourceDirectories.setFrom(
files(
"$projectDir/src/main/java",
"$projectDir/src/main/kotlin"
)
)

executionData.setFrom(
project.fileTree("$buildDir/outputs/unit_test_code_coverage/${variant.name}UnitTest")
.matching { include("**/*.exec") },

project.fileTree("$buildDir/outputs/code_coverage/${variant.name}AndroidTest")
.matching { include("**/*.ec") }
)
}


variant.artifacts.forScope(ScopedArtifacts.Scope.PROJECT)
.use(reportTask)
.toGet(
ScopedArtifact.CLASSES,
{ _ -> allJars },
{ _ -> allDirectories },
)
}

tasks.withType<Test>().configureEach {
configure<JacocoTaskExtension> {
// Required for JaCoCo + Robolectric
// https://github.com/robolectric/robolectric/issues/2230
isIncludeNoLocationClasses = true

// Required for JDK 11 with the above
// https://github.com/gradle/gradle/issues/5184#issuecomment-391982009
excludes = listOf("jdk.internal.*")
}
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
package org.mifos

/**
* This is shared between :app and :benchmarks module to provide configurations type safety.
*/
enum class MifosBuildType(val applicationIdSuffix: String? = null) {
DEBUG(".debug"),
RELEASE,
}
Loading

0 comments on commit 8112ffc

Please sign in to comment.