From 50fc46b7ce8a03edb8b3e7f0c018b2fc3eaf6fc1 Mon Sep 17 00:00:00 2001 From: Sergejs Luhmirins Date: Tue, 25 Jun 2024 18:35:24 +0300 Subject: [PATCH 1/3] MS-475 Replace kapt with ksp --- .../kotlin/LibraryHiltConventionPlugin.kt | 27 ++++++------------- .../kotlin/LibraryProtobufConventionPlugin.kt | 19 +++++++++++++ .../kotlin/LibraryRoomConventionPlugin.kt | 6 ++--- .../src/main/kotlin/common/DependencyExt.kt | 12 ++++----- build.gradle.kts | 1 + gradle/libs.versions.toml | 6 +++-- 6 files changed, 41 insertions(+), 30 deletions(-) diff --git a/build-logic/convention/src/main/kotlin/LibraryHiltConventionPlugin.kt b/build-logic/convention/src/main/kotlin/LibraryHiltConventionPlugin.kt index b0fd2db971..106d192f84 100644 --- a/build-logic/convention/src/main/kotlin/LibraryHiltConventionPlugin.kt +++ b/build-logic/convention/src/main/kotlin/LibraryHiltConventionPlugin.kt @@ -1,29 +1,18 @@ import common.getLibs import common.implementation -import common.kapt -import common.kaptAndroidTest -import common.kaptTest +import common.ksp +import common.kspAndroidTest +import common.kspTest import org.gradle.api.Plugin import org.gradle.api.Project -import org.gradle.kotlin.dsl.configure import org.gradle.kotlin.dsl.dependencies -import org.jetbrains.kotlin.gradle.plugin.KaptExtension class LibraryHiltConventionPlugin : Plugin { override fun apply(target: Project) { with(target) { with(pluginManager) { apply("dagger.hilt.android.plugin") - // KAPT must go last to avoid build warnings. - // See: https://stackoverflow.com/questions/70550883/warning-the-following-options-were-not-recognized-by-any-processor-dagger-f - apply("org.jetbrains.kotlin.kapt") - } - - extensions.configure { - useBuildCache = true - arguments { - arg("realm.ignoreKotlinNullability", true) - } + apply("com.google.devtools.ksp") } val libs = getLibs() @@ -31,11 +20,11 @@ class LibraryHiltConventionPlugin : Plugin { implementation(libs, "hilt") implementation(libs, "hilt.work") - kapt(libs, "hilt.kapt") - kapt(libs, "hilt.compiler") + ksp(libs, "hilt.dagger.compiler") + ksp(libs, "hilt.compiler") - kaptTest(libs, "testing.hilt.kapt") - kaptAndroidTest(libs, "testing.hilt.kapt") + kspTest(libs, "testing.hilt.compiler") + kspAndroidTest(libs, "testing.hilt.compiler") } } } diff --git a/build-logic/convention/src/main/kotlin/LibraryProtobufConventionPlugin.kt b/build-logic/convention/src/main/kotlin/LibraryProtobufConventionPlugin.kt index e8a2ee101c..05814dbc70 100644 --- a/build-logic/convention/src/main/kotlin/LibraryProtobufConventionPlugin.kt +++ b/build-logic/convention/src/main/kotlin/LibraryProtobufConventionPlugin.kt @@ -1,3 +1,5 @@ +import com.android.build.api.variant.AndroidComponentsExtension +import com.google.protobuf.gradle.GenerateProtoTask import com.google.protobuf.gradle.ProtobufExtension import common.getLibs import common.implementation @@ -5,6 +7,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.jetbrains.kotlin.gradle.tasks.AbstractKotlinCompileTool class LibraryProtobufConventionPlugin : Plugin { override fun apply(target: Project) { @@ -30,6 +33,22 @@ class LibraryProtobufConventionPlugin : Plugin { dependencies { implementation(libs, "protobuf") } + + // Fox for known issue with KSP and protobuf + // https://github.com/google/ksp/issues/1590#issuecomment-1826387452 + project.extensions.getByType(AndroidComponentsExtension::class.java).onVariants { variant -> + afterEvaluate { + val variantName = variant.name.replaceFirstChar { it.uppercaseChar() } + val generateTaskName = "generate${variantName}Proto" + val kspTaskName = "ksp${variantName}Kotlin" + + val protoTask = project.tasks.getByName(generateTaskName) as GenerateProtoTask + project.tasks.getByName(kspTaskName) { + dependsOn(protoTask) + (this as AbstractKotlinCompileTool<*>).setSource(protoTask.outputBaseDir) + } + } + } } } } diff --git a/build-logic/convention/src/main/kotlin/LibraryRoomConventionPlugin.kt b/build-logic/convention/src/main/kotlin/LibraryRoomConventionPlugin.kt index 5c489cebf0..f4be13f958 100644 --- a/build-logic/convention/src/main/kotlin/LibraryRoomConventionPlugin.kt +++ b/build-logic/convention/src/main/kotlin/LibraryRoomConventionPlugin.kt @@ -2,7 +2,7 @@ import com.android.build.api.dsl.LibraryExtension import common.configureDbEncryptionBuild import common.getLibs import common.implementation -import common.kapt +import common.ksp import common.testImplementation import org.gradle.api.Plugin import org.gradle.api.Project @@ -14,7 +14,7 @@ class LibraryRoomConventionPlugin : Plugin { override fun apply(target: Project) { with(target) { with(pluginManager) { - apply("org.jetbrains.kotlin.kapt") + apply("com.google.devtools.ksp") } configureDbEncryptionBuild() @@ -43,7 +43,7 @@ class LibraryRoomConventionPlugin : Plugin { dependencies { implementation(libs, "androidX.Room.core") implementation(libs, "androidX.Room.ktx") - kapt(libs, "androidX.Room.compiler") + ksp(libs, "androidX.Room.compiler") implementation(libs, "sqlCipher.core") diff --git a/build-logic/convention/src/main/kotlin/common/DependencyExt.kt b/build-logic/convention/src/main/kotlin/common/DependencyExt.kt index 9d10bba181..640680fa15 100644 --- a/build-logic/convention/src/main/kotlin/common/DependencyExt.kt +++ b/build-logic/convention/src/main/kotlin/common/DependencyExt.kt @@ -27,14 +27,14 @@ internal fun DependencyHandlerScope.androidTestImplementation(libs: VersionCatal add("androidTestImplementation", libs.findLibrary(name).get()) } -internal fun DependencyHandlerScope.kapt(libs: VersionCatalog, name: String) { - add("kapt", libs.findLibrary(name).get()) +internal fun DependencyHandlerScope.ksp(libs: VersionCatalog, name: String) { + add("ksp", libs.findLibrary(name).get()) } -internal fun DependencyHandlerScope.kaptTest(libs: VersionCatalog, name: String) { - add("kaptTest", libs.findLibrary(name).get()) +internal fun DependencyHandlerScope.kspTest(libs: VersionCatalog, name: String) { + add("kspTest", libs.findLibrary(name).get()) } -internal fun DependencyHandlerScope.kaptAndroidTest(libs: VersionCatalog, name: String) { - add("kaptAndroidTest", libs.findLibrary(name).get()) +internal fun DependencyHandlerScope.kspAndroidTest(libs: VersionCatalog, name: String) { + add("kspAndroidTest", libs.findLibrary(name).get()) } diff --git a/build.gradle.kts b/build.gradle.kts index a089b1687f..286f61dc97 100644 --- a/build.gradle.kts +++ b/build.gradle.kts @@ -4,6 +4,7 @@ plugins { alias(libs.plugins.android.library) apply false alias(libs.plugins.android.test) apply false alias(libs.plugins.kotlin.android) apply false + alias(libs.plugins.ksp) apply false alias(libs.plugins.realm) apply false alias(libs.plugins.hilt) apply false diff --git a/gradle/libs.versions.toml b/gradle/libs.versions.toml index 5ed0073e02..0a1709853d 100644 --- a/gradle/libs.versions.toml +++ b/gradle/libs.versions.toml @@ -1,6 +1,7 @@ [versions] kotlin_version = "2.0.0" kotlin_coroutine_version = "1.8.1" +ksp_version = "2.0.0-1.0.22" android_gradlePlugin_version = "8.5.0" androidx_version = "1.5.2" @@ -210,11 +211,11 @@ secugen = { module = "com.simprints:secugenwrapper", version.ref = "secugen_vers #hilt hilt = { module = "com.google.dagger:hilt-android", version.ref = "hilt_version" } -hilt-kapt = { module = "com.google.dagger:hilt-compiler", version.ref = "hilt_version" } +hilt-dagger-compiler = { module = "com.google.dagger:hilt-compiler", version.ref = "hilt_version" } hilt-compiler = { module = "androidx.hilt:hilt-compiler", version.ref = "hilt_androidx_version" } hilt-work = { module = "androidx.hilt:hilt-work", version.ref = "hilt_androidx_version" } testing-hilt = { module = "com.google.dagger:hilt-android-testing", version.ref = "hilt_version" } -testing-hilt-kapt = { module = "com.google.dagger:hilt-android-compiler", version.ref = "hilt_version" } +testing-hilt-compiler = { module = "com.google.dagger:hilt-android-compiler", version.ref = "hilt_version" } #Datastore datastore = { module = "androidx.datastore:datastore", version.ref = "androidx_datastore_version" } @@ -277,6 +278,7 @@ android-application = { id = "com.android.application", version.ref = "android_g android-library = { id = "com.android.library", version.ref = "android_gradlePlugin_version" } android-test = { id = "com.android.test", version.ref = "android_gradlePlugin_version" } kotlin-android = { id = "org.jetbrains.kotlin.android", version.ref = "kotlin_version" } +ksp = { id = "com.google.devtools.ksp", version.ref = "ksp_version" } gms = { id = "com.google.gms.google-services", version.ref = "gsm_plugin_version" } firebase-perf = { id = "com.google.firebase.firebase-perf", version.ref = "firebase_perfPlugin_version" } firebase-crashlytics = { id = "com.google.firebase.crashlytics", version.ref = "firebase_crashlyticsPlugin_version" } From f15969c5d24b3ccb3828a218f146addb6386fcb7 Mon Sep 17 00:00:00 2001 From: Sergejs Luhmirins Date: Tue, 25 Jun 2024 18:40:45 +0300 Subject: [PATCH 2/3] MS-475 Update room config to use correct gradle plugin --- build-logic/convention/build.gradle.kts | 2 ++ .../main/kotlin/LibraryRoomConventionPlugin.kt | 17 +++++++---------- build.gradle.kts | 1 + gradle/libs.versions.toml | 2 ++ 4 files changed, 12 insertions(+), 10 deletions(-) diff --git a/build-logic/convention/build.gradle.kts b/build-logic/convention/build.gradle.kts index 1e81caf74b..87ba1b0c1d 100644 --- a/build-logic/convention/build.gradle.kts +++ b/build-logic/convention/build.gradle.kts @@ -13,6 +13,8 @@ dependencies { compileOnly(libs.plugin.firebase.perf) // Protobuf compileOnly(libs.plugin.protobuf) + // Room + compileOnly(libs.plugin.room) // Hilt compileOnly(libs.plugin.hilt) // Android X Navigation components diff --git a/build-logic/convention/src/main/kotlin/LibraryRoomConventionPlugin.kt b/build-logic/convention/src/main/kotlin/LibraryRoomConventionPlugin.kt index f4be13f958..44e0942790 100644 --- a/build-logic/convention/src/main/kotlin/LibraryRoomConventionPlugin.kt +++ b/build-logic/convention/src/main/kotlin/LibraryRoomConventionPlugin.kt @@ -8,27 +8,24 @@ import org.gradle.api.Plugin import org.gradle.api.Project import org.gradle.kotlin.dsl.configure import org.gradle.kotlin.dsl.dependencies - +import androidx.room.gradle.RoomExtension class LibraryRoomConventionPlugin : Plugin { override fun apply(target: Project) { with(target) { with(pluginManager) { + apply("androidx.room") apply("com.google.devtools.ksp") } configureDbEncryptionBuild() - extensions.configure { - defaultConfig { - javaCompileOptions { - annotationProcessorOptions { - //Required by Room to be able to export the db schemas - arguments += mapOf("room.schemaLocation" to "$projectDir/schemas") - } - } - } + extensions.configure { + //Required by Room to be able to export the db schemas + schemaDirectory("$projectDir/schemas") + } + extensions.configure { sourceSets { getByName("debug") { assets.srcDirs("$projectDir/schemas") diff --git a/build.gradle.kts b/build.gradle.kts index 286f61dc97..542577552d 100644 --- a/build.gradle.kts +++ b/build.gradle.kts @@ -10,6 +10,7 @@ plugins { alias(libs.plugins.hilt) apply false alias(libs.plugins.protobuf) apply false alias(libs.plugins.navigation.args) apply false + alias(libs.plugins.room) apply false alias(libs.plugins.gms) apply false alias(libs.plugins.firebase.crashlytics) apply false diff --git a/gradle/libs.versions.toml b/gradle/libs.versions.toml index 0a1709853d..11dc084271 100644 --- a/gradle/libs.versions.toml +++ b/gradle/libs.versions.toml @@ -271,6 +271,7 @@ plugin-firebase-distribution = { group = "com.google.firebase", name = "firebase plugin-sonar = { group = "org.sonarsource.scanner.gradle", name = "sonarqube-gradle-plugin", version.ref = "sonar_plugin_version" } plugin-jacoco = { group = "org.jacoco", name = "org.jacoco.core", version.ref = "jacoco_version" } plugin-retry = { group = "org.gradle", name = "test-retry-gradle-plugin", version.ref = "retry_version" } +plugin-room = { group = "androidx.room", name = "room-gradle-plugin", version.ref = "androidx_room_version" } [plugins] @@ -291,3 +292,4 @@ play-publisher = { id = "com.github.triplet.play", version.ref = "play_publisher retry = { id = "org.gradle.test-retry", version.ref = "retry_version" } sonar = { id = "org.sonarqube", version.ref = "sonar_plugin_version" } depsGraph = { id = "com.vanniktech.dependency.graph.generator", version.ref = "deps_graph_version" } +room = { id = "androidx.room", version.ref = "androidx_room_version" } From a6fa0e8e8416a89e00af4ca7eb626e6885e3f63b Mon Sep 17 00:00:00 2001 From: Sergejs Luhmirins Date: Tue, 25 Jun 2024 18:41:11 +0300 Subject: [PATCH 3/3] MS-475 Replace deprecated kotlin configuration --- .../src/main/kotlin/common/KotlinAndroid.kt | 35 ++++++++++--------- 1 file changed, 18 insertions(+), 17 deletions(-) diff --git a/build-logic/convention/src/main/kotlin/common/KotlinAndroid.kt b/build-logic/convention/src/main/kotlin/common/KotlinAndroid.kt index e55b1769df..e6db983452 100644 --- a/build-logic/convention/src/main/kotlin/common/KotlinAndroid.kt +++ b/build-logic/convention/src/main/kotlin/common/KotlinAndroid.kt @@ -1,9 +1,9 @@ package common import com.android.build.api.dsl.CommonExtension +import com.android.build.api.variant.AndroidComponentsExtension import org.gradle.api.Project -import org.gradle.api.plugins.ExtensionAware -import org.jetbrains.kotlin.gradle.dsl.KotlinJvmOptions +import org.jetbrains.kotlin.gradle.tasks.KotlinCompilationTask /** * Configure base Kotlin with Android options @@ -23,22 +23,23 @@ internal fun Project.configureKotlinAndroid( targetCompatibility = SdkVersions.JAVA_TARGET } - kotlinOptions { - freeCompilerArgs = freeCompilerArgs + listOf( - "-Xnew-inference", - "-opt-in=kotlin.RequiresOptIn", - // Enable experimental coroutines APIs, including Flow - "-opt-in=kotlinx.coroutines.ExperimentalCoroutinesApi", - "-opt-in=kotlinx.coroutines.FlowPreview", - "-opt-in=kotlin.Experimental", - ) - // Set JVM target to version - jvmTarget = SdkVersions.JAVA_TARGET.toString() + extensions.getByType(AndroidComponentsExtension::class.java).onVariants { variant -> + afterEvaluate { + val variantName = variant.name.replaceFirstChar { it.uppercaseChar() } + val compileTaskName = "compile${variantName}Kotlin" + + tasks.named(compileTaskName, KotlinCompilationTask::class.java) { + compilerOptions.freeCompilerArgs.addAll( + "-Xnew-inference", + "-opt-in=kotlin.RequiresOptIn", + // Enable experimental coroutines APIs, including Flow + "-opt-in=kotlinx.coroutines.ExperimentalCoroutinesApi", + "-opt-in=kotlinx.coroutines.FlowPreview", + "-opt-in=kotlin.Experimental", + ) + } + } } } } - -fun CommonExtension<*, *, *, *, *, *>.kotlinOptions(block: KotlinJvmOptions.() -> Unit) { - (this as ExtensionAware).extensions.configure("kotlinOptions", block) -}