From 2a238fa1bf23b8b0da2e883e52663414023ea55d Mon Sep 17 00:00:00 2001 From: Danil Nikolaev Date: Sat, 24 Jan 2026 14:58:04 +0300 Subject: [PATCH] Refactor: Upgrade Gradle and streamline build logic This commit upgrades the project's build system and refactors the build logic for better maintainability and alignment with modern practices. The Gradle version has been updated from 8.14.2 to 9.3.0, and the Android Gradle Plugin (AGP) has been upgraded to version 9.0.0. This required migrating the build logic to use the new `com.android.build.api.dsl` interfaces instead of the deprecated `com.android.build.gradle` ones. Key changes: - Upgraded Gradle to `9.3.0`. - Upgraded Android Gradle Plugin to `9.0.0`. - Updated various dependencies including Kotlin, Compose BOM, Chucker, and serialization. - Removed the explicit `kotlin-android` plugin application, as it's now handled by AGP. - Migrated build convention plugins to use the new AGP DSL APIs. - Commented out the custom APK naming logic in `app/build.gradle.kts`. - Added new `gradle.properties` flags for build configuration. - Corrected the namespace in `core/model` from `datastore` to `model`. --- app/build.gradle.kts | 22 ++++++++--------- .../AndroidApplicationConventionPlugin.kt | 8 ++++--- .../AndroidLibraryComposeConventionPlugin.kt | 2 +- .../kotlin/AndroidLibraryConventionPlugin.kt | 4 +--- .../kotlin/AndroidTestConventionPlugin.kt | 4 +--- .../kotlin/dev/meloda/fast/AndroidCompose.kt | 6 ++--- .../kotlin/dev/meloda/fast/KotlinAndroid.kt | 24 +++++++++++-------- build.gradle.kts | 2 +- core/domain/build.gradle.kts | 1 + core/model/build.gradle.kts | 4 ++-- gradle.properties | 10 ++++++++ gradle/libs.versions.toml | 13 +++++----- gradle/wrapper/gradle-wrapper.properties | 2 +- settings.gradle.kts | 1 - 14 files changed, 57 insertions(+), 46 deletions(-) diff --git a/app/build.gradle.kts b/app/build.gradle.kts index f97e537e..66330db5 100644 --- a/app/build.gradle.kts +++ b/app/build.gradle.kts @@ -59,17 +59,17 @@ android { } } - applicationVariants.all { - outputs.all { - val date = System.currentTimeMillis() / 1000 - val buildType = buildType.name - val appVersion = versionName - val appVersionCode = versionCode - - val newApkName = "app-$buildType-v$appVersion($appVersionCode)-$date.apk" - (this as? BaseVariantOutputImpl)?.outputFileName = newApkName - } - } +// applicationVariants.all { +// outputs.all { +// val date = System.currentTimeMillis() / 1000 +// val buildType = buildType.name +// val appVersion = versionName +// val appVersionCode = versionCode +// +// val newApkName = "app-$buildType-v$appVersion($appVersionCode)-$date.apk" +// (this as? BaseVariantOutputImpl)?.outputFileName = newApkName +// } +// } packaging { resources { diff --git a/build-logic/convention/src/main/kotlin/AndroidApplicationConventionPlugin.kt b/build-logic/convention/src/main/kotlin/AndroidApplicationConventionPlugin.kt index b321cd68..618bb8c8 100644 --- a/build-logic/convention/src/main/kotlin/AndroidApplicationConventionPlugin.kt +++ b/build-logic/convention/src/main/kotlin/AndroidApplicationConventionPlugin.kt @@ -1,6 +1,5 @@ import com.android.build.api.dsl.ApplicationExtension import dev.meloda.fast.configureKotlinAndroid -import dev.meloda.fast.libs import org.gradle.api.Plugin import org.gradle.api.Project import org.gradle.kotlin.dsl.configure @@ -10,12 +9,15 @@ class AndroidApplicationConventionPlugin : Plugin { with(target) { with(pluginManager) { apply("com.android.application") - apply("org.jetbrains.kotlin.android") } extensions.configure { configureKotlinAndroid(this) - defaultConfig.targetSdk = 36 + defaultConfig { + targetSdk = 36 + compileSdk = 36 + minSdk = 23 + } } } } diff --git a/build-logic/convention/src/main/kotlin/AndroidLibraryComposeConventionPlugin.kt b/build-logic/convention/src/main/kotlin/AndroidLibraryComposeConventionPlugin.kt index b637c54b..8004e599 100644 --- a/build-logic/convention/src/main/kotlin/AndroidLibraryComposeConventionPlugin.kt +++ b/build-logic/convention/src/main/kotlin/AndroidLibraryComposeConventionPlugin.kt @@ -1,4 +1,4 @@ -import com.android.build.gradle.LibraryExtension +import com.android.build.api.dsl.LibraryExtension import dev.meloda.fast.configureAndroidCompose import org.gradle.api.Plugin import org.gradle.api.Project diff --git a/build-logic/convention/src/main/kotlin/AndroidLibraryConventionPlugin.kt b/build-logic/convention/src/main/kotlin/AndroidLibraryConventionPlugin.kt index 74c136a5..7b080bca 100644 --- a/build-logic/convention/src/main/kotlin/AndroidLibraryConventionPlugin.kt +++ b/build-logic/convention/src/main/kotlin/AndroidLibraryConventionPlugin.kt @@ -1,5 +1,5 @@ +import com.android.build.api.dsl.LibraryExtension import com.android.build.api.variant.LibraryAndroidComponentsExtension -import com.android.build.gradle.LibraryExtension import dev.meloda.fast.configureKotlinAndroid import dev.meloda.fast.disableUnnecessaryAndroidTests import org.gradle.api.Plugin @@ -13,7 +13,6 @@ class AndroidLibraryConventionPlugin : Plugin { with(target) { with(pluginManager) { apply("com.android.library") - apply("org.jetbrains.kotlin.android") apply("org.jetbrains.kotlin.plugin.parcelize") apply("org.jetbrains.kotlin.plugin.serialization") } @@ -21,7 +20,6 @@ class AndroidLibraryConventionPlugin : Plugin { extensions.configure { configureKotlinAndroid(this) androidResources.enable = false - defaultConfig.targetSdk = 36 defaultConfig.testInstrumentationRunner = "androidx.test.runner.AndroidJUnitRunner" } extensions.configure { diff --git a/build-logic/convention/src/main/kotlin/AndroidTestConventionPlugin.kt b/build-logic/convention/src/main/kotlin/AndroidTestConventionPlugin.kt index 5a76d6fb..22c0a9cc 100644 --- a/build-logic/convention/src/main/kotlin/AndroidTestConventionPlugin.kt +++ b/build-logic/convention/src/main/kotlin/AndroidTestConventionPlugin.kt @@ -1,6 +1,5 @@ -import com.android.build.gradle.TestExtension +import com.android.build.api.dsl.TestExtension import dev.meloda.fast.configureKotlinAndroid -import dev.meloda.fast.libs import org.gradle.api.Plugin import org.gradle.api.Project import org.gradle.kotlin.dsl.configure @@ -10,7 +9,6 @@ class AndroidTestConventionPlugin : Plugin { with(target) { with(pluginManager) { apply("com.android.test") - apply("org.jetbrains.kotlin.android") } extensions.configure { diff --git a/build-logic/convention/src/main/kotlin/dev/meloda/fast/AndroidCompose.kt b/build-logic/convention/src/main/kotlin/dev/meloda/fast/AndroidCompose.kt index 204fee29..86cb2e45 100644 --- a/build-logic/convention/src/main/kotlin/dev/meloda/fast/AndroidCompose.kt +++ b/build-logic/convention/src/main/kotlin/dev/meloda/fast/AndroidCompose.kt @@ -5,12 +5,10 @@ import org.gradle.api.Project import org.gradle.kotlin.dsl.dependencies internal fun Project.configureAndroidCompose( - commonExtension: CommonExtension<*, *, *, *, *, *>, + commonExtension: CommonExtension, ) { commonExtension.apply { - buildFeatures { - compose = true - } + buildFeatures.compose = true dependencies { val bom = libs.findLibrary("compose-bom").get() diff --git a/build-logic/convention/src/main/kotlin/dev/meloda/fast/KotlinAndroid.kt b/build-logic/convention/src/main/kotlin/dev/meloda/fast/KotlinAndroid.kt index c94adb81..5664cb9e 100644 --- a/build-logic/convention/src/main/kotlin/dev/meloda/fast/KotlinAndroid.kt +++ b/build-logic/convention/src/main/kotlin/dev/meloda/fast/KotlinAndroid.kt @@ -1,6 +1,9 @@ package dev.meloda.fast +import com.android.build.api.dsl.ApplicationExtension import com.android.build.api.dsl.CommonExtension +import com.android.build.api.dsl.CompileOptions +import com.android.build.api.dsl.LibraryExtension import org.gradle.api.JavaVersion import org.gradle.api.Project import org.gradle.api.plugins.JavaPluginExtension @@ -13,24 +16,25 @@ import org.jetbrains.kotlin.gradle.dsl.KotlinBaseExtension import org.jetbrains.kotlin.gradle.dsl.KotlinJvmProjectExtension internal fun Project.configureKotlinAndroid( - commonExtension: CommonExtension<*, *, *, *, *, *>, + commonExtension: CommonExtension, ) { + when (commonExtension) { + is ApplicationExtension -> commonExtension.compileOptions(buildCompileOptions()) + is LibraryExtension -> commonExtension.compileOptions(buildCompileOptions()) + } + commonExtension.apply { compileSdk = 36 - - defaultConfig { - minSdk = 23 - } - - compileOptions { - sourceCompatibility = JavaVersion.VERSION_21 - targetCompatibility = JavaVersion.VERSION_21 - } } configureKotlin() } +private fun buildCompileOptions(): CompileOptions.() -> Unit = { + sourceCompatibility = JavaVersion.VERSION_21 + targetCompatibility = JavaVersion.VERSION_21 +} + internal fun Project.configureKotlinJvm() { extensions.configure { sourceCompatibility = JavaVersion.VERSION_21 diff --git a/build.gradle.kts b/build.gradle.kts index 2ed91045..7489e407 100644 --- a/build.gradle.kts +++ b/build.gradle.kts @@ -1,7 +1,6 @@ plugins { alias(libs.plugins.android.application) apply false alias(libs.plugins.android.library) apply false - alias(libs.plugins.kotlin.android) apply false alias(libs.plugins.kotlin.parcelize) apply false alias(libs.plugins.kotlin.serialization) apply false alias(libs.plugins.kotlin.jvm) apply false @@ -9,4 +8,5 @@ plugins { alias(libs.plugins.room) apply false alias(libs.plugins.ksp) apply false alias(libs.plugins.module.graph) apply true + alias(libs.plugins.versions) apply true } diff --git a/core/domain/build.gradle.kts b/core/domain/build.gradle.kts index 5bc03e91..085e6f24 100644 --- a/core/domain/build.gradle.kts +++ b/core/domain/build.gradle.kts @@ -18,5 +18,6 @@ dependencies { implementation(libs.bundles.nanokt) + implementation(platform(libs.compose.bom)) implementation(libs.compose.ui) } diff --git a/core/model/build.gradle.kts b/core/model/build.gradle.kts index 3c8a9297..84448281 100644 --- a/core/model/build.gradle.kts +++ b/core/model/build.gradle.kts @@ -4,7 +4,7 @@ plugins { } android { - namespace = "dev.meloda.fast.datastore" + namespace = "dev.meloda.fast.model" } dependencies { @@ -12,7 +12,7 @@ dependencies { ksp(libs.moshi.kotlin.codegen) implementation(platform(libs.compose.bom)) - implementation(libs.bundles.compose) + implementation(libs.compose.ui) implementation(libs.room.ktx) implementation(libs.room.runtime) diff --git a/gradle.properties b/gradle.properties index 930aeb27..d17a3995 100644 --- a/gradle.properties +++ b/gradle.properties @@ -7,3 +7,13 @@ kotlin.code.style=official org.gradle.unsafe.configuration-cache=true android.nonTransitiveRClass=true android.nonFinalResIds=true + +#android.defaults.buildfeatures.resvalues=true +#android.sdk.defaultTargetSdkToCompileSdkIfUnset=false +#android.enableAppCompileTimeRClass=false +#android.usesSdkInManifest.disallowed=false +#android.uniquePackageNames=false +#android.dependency.useConstraints=true +#android.r8.strictFullModeForKeepRules=false +#android.r8.optimizedResourceShrinking=false +#android.newDsl=false diff --git a/gradle/libs.versions.toml b/gradle/libs.versions.toml index 94c68a36..fa86a2cd 100644 --- a/gradle/libs.versions.toml +++ b/gradle/libs.versions.toml @@ -1,20 +1,21 @@ [versions] -agp = "8.13.2" +agp = "9.0.0" retrofit = "3.0.0" eithernet = "2.0.0" haze = "1.7.1" kotlin = "2.3.0" -ksp = "2.3.3" +ksp = "2.3.4" moduleGraph = "2.9.0" +versions = "0.53.0" -compose-bom = "2025.12.00" +compose-bom = "2026.01.00" koin = "4.1.1" accompanist = "0.37.3" coil = "2.7.0" coroutines = "1.10.2" junit = "4.13.2" -chucker = "4.2.0" +chucker = "4.3.0" guava = "33.5.0-jre" lifecycle = "2.10.0" core-ktx = "1.17.0" @@ -25,7 +26,7 @@ room = "2.8.4" preference-ktx = "1.2.1" nanokt = "1.3.0" androidx-navigation = "2.9.6" -serialization = "1.9.0" +serialization = "1.10.0" [libraries] accompanist-permissions = { module = "com.google.accompanist:accompanist-permissions", version.ref = "accompanist" } @@ -109,13 +110,13 @@ nanokt = [ android-application = { id = "com.android.application", version.ref = "agp" } android-library = { id = "com.android.library", version.ref = "agp" } compose = { id = "org.jetbrains.kotlin.plugin.compose", version.ref = "kotlin" } -kotlin-android = { id = "org.jetbrains.kotlin.android", version.ref = "kotlin" } kotlin-parcelize = { id = "org.jetbrains.kotlin.plugin.parcelize", version.ref = "kotlin" } kotlin-serialization = { id = "org.jetbrains.kotlin.plugin.serialization", version.ref = "kotlin" } kotlin-jvm = { id = "org.jetbrains.kotlin.jvm", version.ref = "kotlin" } room = { id = "androidx.room", version.ref = "room" } ksp = { id = "com.google.devtools.ksp", version.ref = "ksp" } module-graph = { id = "com.jraska.module.graph.assertion", version.ref = "moduleGraph" } +versions = { id = "com.github.ben-manes.versions", version.ref = "versions" } #project plugins fast-android-application = { id = "fast.android.application", version = "unspecified" } diff --git a/gradle/wrapper/gradle-wrapper.properties b/gradle/wrapper/gradle-wrapper.properties index ff23a68d..19a6bdeb 100644 --- a/gradle/wrapper/gradle-wrapper.properties +++ b/gradle/wrapper/gradle-wrapper.properties @@ -1,6 +1,6 @@ distributionBase=GRADLE_USER_HOME distributionPath=wrapper/dists -distributionUrl=https\://services.gradle.org/distributions/gradle-8.14.2-bin.zip +distributionUrl=https\://services.gradle.org/distributions/gradle-9.3.0-bin.zip networkTimeout=10000 validateDistributionUrl=true zipStoreBase=GRADLE_USER_HOME diff --git a/settings.gradle.kts b/settings.gradle.kts index b6782c43..571ece6c 100644 --- a/settings.gradle.kts +++ b/settings.gradle.kts @@ -22,7 +22,6 @@ dependencyResolutionManagement { .orElse(providers.environmentVariable("NEXUS_MAVEN_URL")) .orNull - repositories { if (!nexusMavenUrl.isNullOrBlank()) { maven(url = uri(nexusMavenUrl))