diff --git a/app-nia-catalog/dependencies/releaseRuntimeClasspath.txt b/app-nia-catalog/dependencies/releaseRuntimeClasspath.txt index ea1e0801c..ba6dce52a 100644 --- a/app-nia-catalog/dependencies/releaseRuntimeClasspath.txt +++ b/app-nia-catalog/dependencies/releaseRuntimeClasspath.txt @@ -126,10 +126,10 @@ io.coil-kt:coil-compose:2.7.0 io.coil-kt:coil:2.7.0 jakarta.inject:jakarta.inject-api:2.0.1 javax.inject:javax.inject:1 -org.jetbrains.kotlin:kotlin-stdlib-common:2.2.21 +org.jetbrains.kotlin:kotlin-stdlib-common:2.3.0 org.jetbrains.kotlin:kotlin-stdlib-jdk7:1.9.0 org.jetbrains.kotlin:kotlin-stdlib-jdk8:1.9.0 -org.jetbrains.kotlin:kotlin-stdlib:2.2.21 +org.jetbrains.kotlin:kotlin-stdlib:2.3.0 org.jetbrains.kotlinx:kotlinx-coroutines-android:1.9.0 org.jetbrains.kotlinx:kotlinx-coroutines-bom:1.9.0 org.jetbrains.kotlinx:kotlinx-coroutines-core-jvm:1.9.0 diff --git a/app/dependencies/prodReleaseRuntimeClasspath.txt b/app/dependencies/prodReleaseRuntimeClasspath.txt index 7bea0cb3e..e34425a60 100644 --- a/app/dependencies/prodReleaseRuntimeClasspath.txt +++ b/app/dependencies/prodReleaseRuntimeClasspath.txt @@ -235,10 +235,10 @@ io.coil-kt:coil:2.7.0 jakarta.inject:jakarta.inject-api:2.0.1 javax.inject:javax.inject:1 org.checkerframework:checker-qual:3.12.0 -org.jetbrains.kotlin:kotlin-stdlib-common:2.2.21 +org.jetbrains.kotlin:kotlin-stdlib-common:2.3.0 org.jetbrains.kotlin:kotlin-stdlib-jdk7:1.9.0 org.jetbrains.kotlin:kotlin-stdlib-jdk8:1.9.0 -org.jetbrains.kotlin:kotlin-stdlib:2.2.21 +org.jetbrains.kotlin:kotlin-stdlib:2.3.0 org.jetbrains.kotlinx:kotlinx-coroutines-android:1.10.1 org.jetbrains.kotlinx:kotlinx-coroutines-bom:1.10.1 org.jetbrains.kotlinx:kotlinx-coroutines-core-jvm:1.10.1 diff --git a/build-logic/convention/build.gradle.kts b/build-logic/convention/build.gradle.kts index 8000fbadf..5faf257c1 100644 --- a/build-logic/convention/build.gradle.kts +++ b/build-logic/convention/build.gradle.kts @@ -37,7 +37,7 @@ kotlin { } dependencies { - compileOnly(libs.android.gradleApiPlugin) + compileOnly(libs.android.gradlePlugin) compileOnly(libs.android.tools.common) compileOnly(libs.compose.gradlePlugin) compileOnly(libs.firebase.crashlytics.gradlePlugin) diff --git a/build-logic/convention/src/main/kotlin/AndroidApplicationConventionPlugin.kt b/build-logic/convention/src/main/kotlin/AndroidApplicationConventionPlugin.kt index 9ae9888db..8c45a056c 100644 --- a/build-logic/convention/src/main/kotlin/AndroidApplicationConventionPlugin.kt +++ b/build-logic/convention/src/main/kotlin/AndroidApplicationConventionPlugin.kt @@ -29,14 +29,12 @@ class AndroidApplicationConventionPlugin : Plugin { override fun apply(target: Project) { with(target) { apply(plugin = "com.android.application") - apply(plugin = "org.jetbrains.kotlin.android") apply(plugin = "nowinandroid.android.lint") apply(plugin = "com.dropbox.dependency-guard") extensions.configure { configureKotlinAndroid(this) defaultConfig.targetSdk = 36 - @Suppress("UnstableApiUsage") testOptions.animationsDisabled = true configureGradleManagedDevices(this) } diff --git a/build-logic/convention/src/main/kotlin/AndroidApplicationJacocoConventionPlugin.kt b/build-logic/convention/src/main/kotlin/AndroidApplicationJacocoConventionPlugin.kt index b0eece41d..326d03f4f 100644 --- a/build-logic/convention/src/main/kotlin/AndroidApplicationJacocoConventionPlugin.kt +++ b/build-logic/convention/src/main/kotlin/AndroidApplicationJacocoConventionPlugin.kt @@ -21,20 +21,16 @@ import org.gradle.api.Plugin import org.gradle.api.Project import org.gradle.kotlin.dsl.apply import org.gradle.kotlin.dsl.getByType +import org.gradle.testing.jacoco.plugins.JacocoPlugin class AndroidApplicationJacocoConventionPlugin : Plugin { override fun apply(target: Project) { with(target) { - apply(plugin = "jacoco") - - val androidExtension = extensions.getByType() - - androidExtension.buildTypes.configureEach { - enableAndroidTestCoverage = true - enableUnitTestCoverage = true - } - - configureJacoco(extensions.getByType()) + apply() + configureJacoco( + commonExtension = extensions.getByType(), + androidComponentsExtension = extensions.getByType(), + ) } } } diff --git a/build-logic/convention/src/main/kotlin/AndroidLibraryConventionPlugin.kt b/build-logic/convention/src/main/kotlin/AndroidLibraryConventionPlugin.kt index a3f6e0a2e..ee47e823a 100644 --- a/build-logic/convention/src/main/kotlin/AndroidLibraryConventionPlugin.kt +++ b/build-logic/convention/src/main/kotlin/AndroidLibraryConventionPlugin.kt @@ -32,14 +32,12 @@ class AndroidLibraryConventionPlugin : Plugin { override fun apply(target: Project) { with(target) { apply(plugin = "com.android.library") - apply(plugin = "org.jetbrains.kotlin.android") apply(plugin = "nowinandroid.android.lint") extensions.configure { configureKotlinAndroid(this) testOptions.targetSdk = 36 lint.targetSdk = 36 - defaultConfig.targetSdk = 36 defaultConfig.testInstrumentationRunner = "androidx.test.runner.AndroidJUnitRunner" testOptions.animationsDisabled = true configureFlavors(this) @@ -57,6 +55,7 @@ class AndroidLibraryConventionPlugin : Plugin { dependencies { "androidTestImplementation"(libs.findLibrary("kotlin.test").get()) "testImplementation"(libs.findLibrary("kotlin.test").get()) + "testImplementation"(libs.findLibrary("junit").get()) "implementation"(libs.findLibrary("androidx.tracing.ktx").get()) } diff --git a/build-logic/convention/src/main/kotlin/AndroidLibraryJacocoConventionPlugin.kt b/build-logic/convention/src/main/kotlin/AndroidLibraryJacocoConventionPlugin.kt index d249e4cbf..2fd97d456 100644 --- a/build-logic/convention/src/main/kotlin/AndroidLibraryJacocoConventionPlugin.kt +++ b/build-logic/convention/src/main/kotlin/AndroidLibraryJacocoConventionPlugin.kt @@ -21,20 +21,16 @@ import org.gradle.api.Plugin import org.gradle.api.Project import org.gradle.kotlin.dsl.apply import org.gradle.kotlin.dsl.getByType +import org.gradle.testing.jacoco.plugins.JacocoPlugin class AndroidLibraryJacocoConventionPlugin : Plugin { override fun apply(target: Project) { with(target) { - apply(plugin = "jacoco") - - val androidExtension = extensions.getByType() - - androidExtension.buildTypes.configureEach { - enableAndroidTestCoverage = true - enableUnitTestCoverage = true - } - - configureJacoco(extensions.getByType()) + apply() + configureJacoco( + commonExtension = extensions.getByType(), + androidComponentsExtension = extensions.getByType(), + ) } } } diff --git a/build-logic/convention/src/main/kotlin/AndroidTestConventionPlugin.kt b/build-logic/convention/src/main/kotlin/AndroidTestConventionPlugin.kt index 9fd446eac..8a2f0b5a4 100644 --- a/build-logic/convention/src/main/kotlin/AndroidTestConventionPlugin.kt +++ b/build-logic/convention/src/main/kotlin/AndroidTestConventionPlugin.kt @@ -26,7 +26,6 @@ class AndroidTestConventionPlugin : Plugin { override fun apply(target: Project) { with(target) { apply(plugin = "com.android.test") - apply(plugin = "org.jetbrains.kotlin.android") extensions.configure { configureKotlinAndroid(this) diff --git a/build-logic/convention/src/main/kotlin/HiltConventionPlugin.kt b/build-logic/convention/src/main/kotlin/HiltConventionPlugin.kt index 5a90ff98f..82bf9f60c 100644 --- a/build-logic/convention/src/main/kotlin/HiltConventionPlugin.kt +++ b/build-logic/convention/src/main/kotlin/HiltConventionPlugin.kt @@ -28,6 +28,7 @@ class HiltConventionPlugin : Plugin { dependencies { "ksp"(libs.findLibrary("hilt.compiler").get()) + "ksp"(libs.findLibrary("kotlin.metadata").get()) } // Add support for Jvm Module, base on org.jetbrains.kotlin.jvm diff --git a/build-logic/convention/src/main/kotlin/com/google/samples/apps/nowinandroid/AndroidCompose.kt b/build-logic/convention/src/main/kotlin/com/google/samples/apps/nowinandroid/AndroidCompose.kt index 709a711c2..ca2a6c99b 100644 --- a/build-logic/convention/src/main/kotlin/com/google/samples/apps/nowinandroid/AndroidCompose.kt +++ b/build-logic/convention/src/main/kotlin/com/google/samples/apps/nowinandroid/AndroidCompose.kt @@ -27,10 +27,10 @@ import org.jetbrains.kotlin.compose.compiler.gradle.ComposeCompilerGradlePluginE * Configure Compose-specific options */ internal fun Project.configureAndroidCompose( - commonExtension: CommonExtension<*, *, *, *, *, *>, + commonExtension: CommonExtension, ) { commonExtension.apply { - buildFeatures { + buildFeatures.apply { compose = true } @@ -46,6 +46,7 @@ internal fun Project.configureAndroidCompose( extensions.configure { fun Provider.onlyIfTrue() = flatMap { provider { it.takeIf(String::toBoolean) } } fun Provider<*>.relativeToRootProject(dir: String) = map { + @Suppress("UnstableApiUsage") isolated.rootProject.projectDirectory .dir("build") .dir(projectDir.toRelativeString(rootDir)) @@ -59,6 +60,7 @@ internal fun Project.configureAndroidCompose( .relativeToRootProject("compose-reports") .let(reportsDestination::set) + @Suppress("UnstableApiUsage") stabilityConfigurationFiles .add(isolated.rootProject.projectDirectory.file("compose_compiler_config.conf")) } diff --git a/build-logic/convention/src/main/kotlin/com/google/samples/apps/nowinandroid/GradleManagedDevices.kt b/build-logic/convention/src/main/kotlin/com/google/samples/apps/nowinandroid/GradleManagedDevices.kt index f67e9093d..992a3f91e 100644 --- a/build-logic/convention/src/main/kotlin/com/google/samples/apps/nowinandroid/GradleManagedDevices.kt +++ b/build-logic/convention/src/main/kotlin/com/google/samples/apps/nowinandroid/GradleManagedDevices.kt @@ -25,7 +25,7 @@ import org.gradle.kotlin.dsl.invoke * Configure project for Gradle managed devices */ internal fun configureGradleManagedDevices( - commonExtension: CommonExtension<*, *, *, *, *, *>, + commonExtension: CommonExtension, ) { val pixel4 = DeviceConfig("Pixel 4", 30, "aosp-atd") val pixel6 = DeviceConfig("Pixel 6", 31, "aosp") @@ -34,9 +34,11 @@ internal fun configureGradleManagedDevices( val allDevices = listOf(pixel4, pixel6, pixelC) val ciDevices = listOf(pixel4, pixelC) - commonExtension.testOptions { + + commonExtension.testOptions.apply { + @Suppress("UnstableApiUsage") managedDevices { - devices { + allDevices { allDevices.forEach { deviceConfig -> maybeCreate(deviceConfig.taskName, ManagedVirtualDevice::class.java).apply { device = deviceConfig.device @@ -48,7 +50,7 @@ internal fun configureGradleManagedDevices( groups { maybeCreate("ci").apply { ciDevices.forEach { deviceConfig -> - targetDevices.add(devices[deviceConfig.taskName]) + targetDevices.add(localDevices[deviceConfig.taskName]) } } } diff --git a/build-logic/convention/src/main/kotlin/com/google/samples/apps/nowinandroid/Jacoco.kt b/build-logic/convention/src/main/kotlin/com/google/samples/apps/nowinandroid/Jacoco.kt index ed1ea4254..8d16c428e 100644 --- a/build-logic/convention/src/main/kotlin/com/google/samples/apps/nowinandroid/Jacoco.kt +++ b/build-logic/convention/src/main/kotlin/com/google/samples/apps/nowinandroid/Jacoco.kt @@ -17,9 +17,12 @@ package com.google.samples.apps.nowinandroid import com.android.build.api.artifact.ScopedArtifact +import com.android.build.api.dsl.BuildType +import com.android.build.api.dsl.CommonExtension import com.android.build.api.variant.AndroidComponentsExtension import com.android.build.api.variant.ScopedArtifacts import com.android.build.api.variant.SourceDirectories +import org.gradle.api.NamedDomainObjectContainer import org.gradle.api.Project import org.gradle.api.file.Directory import org.gradle.api.file.RegularFile @@ -59,8 +62,15 @@ private fun String.capitalize() = replaceFirstChar { * tests on CI using a different Github Action or an external device farm. */ internal fun Project.configureJacoco( + commonExtension: CommonExtension, androidComponentsExtension: AndroidComponentsExtension<*, *, *>, ) { + // Configure only the debug build, otherwise it will force the debuggable flag on release buildTypes as well + commonExtension.buildTypes.named("debug") { + enableAndroidTestCoverage = true + enableUnitTestCoverage = true + } + configure { toolVersion = libs.findVersion("jacoco").get().toString() } diff --git a/build-logic/convention/src/main/kotlin/com/google/samples/apps/nowinandroid/KotlinAndroid.kt b/build-logic/convention/src/main/kotlin/com/google/samples/apps/nowinandroid/KotlinAndroid.kt index 588ab88f3..37b1ba99b 100644 --- a/build-logic/convention/src/main/kotlin/com/google/samples/apps/nowinandroid/KotlinAndroid.kt +++ b/build-logic/convention/src/main/kotlin/com/google/samples/apps/nowinandroid/KotlinAndroid.kt @@ -27,22 +27,21 @@ import org.jetbrains.kotlin.gradle.dsl.JvmTarget import org.jetbrains.kotlin.gradle.dsl.KotlinAndroidProjectExtension import org.jetbrains.kotlin.gradle.dsl.KotlinBaseExtension import org.jetbrains.kotlin.gradle.dsl.KotlinJvmProjectExtension -import org.jetbrains.kotlin.gradle.dsl.KotlinVersion /** * Configure base Kotlin with Android options */ internal fun Project.configureKotlinAndroid( - commonExtension: CommonExtension<*, *, *, *, *, *>, + commonExtension: CommonExtension, ) { commonExtension.apply { compileSdk = 36 - defaultConfig { + defaultConfig.apply { minSdk = 23 } - compileOptions { + compileOptions.apply { // Up to Java 11 APIs are available through desugaring // https://developer.android.com/studio/write/java11-minimal-support-table sourceCompatibility = JavaVersion.VERSION_11 @@ -86,9 +85,6 @@ private inline fun Project.configureKotlin() = is KotlinJvmProjectExtension -> compilerOptions else -> TODO("Unsupported project extension $this ${T::class}") }.apply { - // TODO: move remove languageVersion and coreLibrariesVersion after upgrading to AGP 9.0 - languageVersion.set(KotlinVersion.KOTLIN_2_2) - coreLibrariesVersion = "2.2.21" jvmTarget = JvmTarget.JVM_11 allWarningsAsErrors = warningsAsErrors freeCompilerArgs.add( diff --git a/build-logic/convention/src/main/kotlin/com/google/samples/apps/nowinandroid/NiaFlavor.kt b/build-logic/convention/src/main/kotlin/com/google/samples/apps/nowinandroid/NiaFlavor.kt index e6409cd04..96ca6073d 100644 --- a/build-logic/convention/src/main/kotlin/com/google/samples/apps/nowinandroid/NiaFlavor.kt +++ b/build-logic/convention/src/main/kotlin/com/google/samples/apps/nowinandroid/NiaFlavor.kt @@ -4,6 +4,7 @@ import com.android.build.api.dsl.ApplicationExtension import com.android.build.api.dsl.ApplicationProductFlavor import com.android.build.api.dsl.CommonExtension import com.android.build.api.dsl.ProductFlavor +import org.gradle.kotlin.dsl.invoke @Suppress("EnumEntryName") enum class FlavorDimension { @@ -20,7 +21,7 @@ enum class NiaFlavor(val dimension: FlavorDimension, val applicationIdSuffix: St } fun configureFlavors( - commonExtension: CommonExtension<*, *, *, *, *, *>, + commonExtension: CommonExtension, flavorConfigurationBlock: ProductFlavor.(flavor: NiaFlavor) -> Unit = {}, ) { commonExtension.apply { @@ -33,7 +34,7 @@ fun configureFlavors( register(niaFlavor.name) { dimension = niaFlavor.dimension.name flavorConfigurationBlock(this, niaFlavor) - if (this@apply is ApplicationExtension && this is ApplicationProductFlavor) { + if (commonExtension is ApplicationExtension && this is ApplicationProductFlavor) { if (niaFlavor.applicationIdSuffix != null) { applicationIdSuffix = niaFlavor.applicationIdSuffix } diff --git a/gradle.properties b/gradle.properties index 2e9d9fc30..32a00e430 100644 --- a/gradle.properties +++ b/gradle.properties @@ -63,3 +63,8 @@ roborazzi.test.verify=true # Prevent uninstall app after instrumented tests # https://issuetracker.google.com/issues/295039976 android.injected.androidTest.leaveApksInstalledAfterRun=true + +# Blockers: +# - https://github.com/google/dagger/issues/4944 +# - https://github.com/google/dagger/issues/4979 +android.newDsl=false diff --git a/gradle/libs.versions.toml b/gradle/libs.versions.toml index b4bbd187e..791686973 100644 --- a/gradle/libs.versions.toml +++ b/gradle/libs.versions.toml @@ -2,8 +2,8 @@ accompanist = "0.37.0" androidDesugarJdkLibs = "2.1.4" # AGP and tools should be updated together -androidGradlePlugin = "8.13.1" -androidTools = "31.13.1" +androidGradlePlugin = "9.0.0" +androidTools = "32.0.0" androidxActivity = "1.9.3" androidxAppCompat = "1.7.0" androidxBrowser = "1.8.0" @@ -20,7 +20,7 @@ androidxHiltLifecycleViewModelCompose = "1.3.0-alpha02" androidxLifecycle = "2.10.0" androidxLintGradle = "1.0.0-alpha03" androidxLifecycleViewModelNavigation3 = "2.10.0" -androidxMacroBenchmark = "1.4.1" +androidxMacroBenchmark = "1.5.0-alpha01" androidxMetrics = "1.0.0-beta01" androidxNavigation = "2.8.5" androidxNavigation3 = "1.0.0" @@ -57,7 +57,7 @@ protobufPlugin = "0.9.5" retrofit = "2.11.0" retrofitKotlinxSerializationJson = "1.0.0" robolectric = "4.16" -roborazzi = "1.51.0" +roborazzi = "1.56.0" room = "2.8.3" truth = "1.4.4" turbine = "1.2.0" @@ -134,6 +134,8 @@ hilt-core = { group = "com.google.dagger", name = "hilt-core", version.ref = "hi hilt-ext-compiler = { group = "androidx.hilt", name = "hilt-compiler", version.ref = "hiltExt" } hilt-ext-work = { group = "androidx.hilt", name = "hilt-work", version.ref = "hiltExt" } javax-inject = { module = "javax.inject:javax.inject", version = "1" } +junit = { module = "junit:junit", version.ref = "junit4" } +kotlin-metadata = { module = "org.jetbrains.kotlin:kotlin-metadata-jvm", version.ref = "kotlin" } kotlin-stdlib = { group = "org.jetbrains.kotlin", name = "kotlin-stdlib-jdk8", version.ref = "kotlin" } kotlin-test = { group = "org.jetbrains.kotlin", name = "kotlin-test", version.ref = "kotlin" } kotlinx-coroutines-core = { group = "org.jetbrains.kotlinx", name = "kotlinx-coroutines-core", version.ref = "kotlinxCoroutines" } @@ -160,7 +162,7 @@ truth = { group = "com.google.truth", name = "truth", version.ref = "truth" } turbine = { group = "app.cash.turbine", name = "turbine", version.ref = "turbine" } # Dependencies of the included build-logic -android-gradleApiPlugin = { group = "com.android.tools.build", name = "gradle-api", version.ref = "androidGradlePlugin" } +android-gradlePlugin = { group = "com.android.tools.build", name = "gradle-api", version.ref = "androidGradlePlugin" } android-tools-common = { group = "com.android.tools", name = "common", version.ref = "androidTools" } compose-gradlePlugin = { module = "org.jetbrains.kotlin:compose-compiler-gradle-plugin", version.ref = "kotlin" } firebase-crashlytics-gradlePlugin = { group = "com.google.firebase", name = "firebase-crashlytics-gradle", version.ref = "firebaseCrashlyticsPlugin" }