diff --git a/gradle/libs.versions.toml b/gradle/libs.versions.toml index 887f8bfb..80945022 100644 --- a/gradle/libs.versions.toml +++ b/gradle/libs.versions.toml @@ -1,15 +1,15 @@ [versions] aboutLibraries = "10.8.3" -accompanist = "0.33.2-alpha" +accompanist = "0.34.0" androidDesugarJdkLibs = "2.0.4" -android-gradle-plugin = "8.2.2" +android-gradle-plugin = "8.3.2" androidxActivity = "1.8.2" androidxAnnotation = "1.7.1" androidxAppCompat = "1.6.1" -androidxBrowser = "1.7.0" -androidxComposeBom = "2024.02.01" -androidxComposeCompiler = "1.5.8" -androidxComposeMaterial3 = "1.2.0" +androidxBrowser = "1.8.0" +androidxComposeBom = "2024.04.00" +androidxComposeCompiler = "1.5.11" +androidxComposeMaterial3 = "1.2.1" androidxComposeRuntimeTracing = "1.0.0-beta01" androidxConstraint = "1.1.0-alpha13" androidxCore = "1.12.0" @@ -33,38 +33,38 @@ androidxWindowManager = "1.2.0" androidxWork = "2.9.0" apiValidator = "0.14.0" buildConfig = "3.1.0" -coil = "2.5.0" +coil = "2.6.0" colorMath = "3.2.0" dokka = "1.9.10" espressoCore = "3.5.1" -firebaseBom = "32.7.3" +firebaseBom = "32.8.1" firebaseCrashlyticsPlugin = "2.9.9" firebasePerfPlugin = "1.4.2" gmsPlugin = "4.4.1" googleMaterial = "1.11.0" gradlePublish = "1.1.0" gson = "2.10.1" -hilt = "2.50" +hilt = "2.51.1" hiltExt = "1.2.0" jacoco = "0.8.7" jdom2 = "2.0.6.1" jsoup = "1.16.1" junit = "4.13.2" junit4 = "4.13.2" -kotlin = "1.9.22" +kotlin = "1.9.23" kotlin-poet = "1.14.2" kotlin-xml-builder = "1.9.1" -kotlinx-serialization-core = "1.6.2" +kotlinx-serialization-core = "1.6.3" kotlinxCollections = "0.3.6" -kotlinxCoroutines = "1.7.3" +kotlinxCoroutines = "1.8.0" kotlinxDatetime = "0.5.0" -kotlinxSerializationJson = "1.6.2" -ksp = "1.9.22-1.0.17" +kotlinxSerializationJson = "1.6.3" +ksp = "1.9.23-1.0.20" landscapist = "2.3.1" lifecycleRuntimeKtx = "2.7.0" -lint = "31.2.2" +lint = "31.3.2" okhttp = "4.12.0" -protobuf = "3.24.4" +protobuf = "3.25.2" protobufPlugin = "0.9.4" querent = "1.0.0-alpha02" retrofit = "2.9.0" @@ -83,7 +83,7 @@ google-android-ump = "2.2.0" about-libraries-core = { group = "com.mikepenz", name = "aboutlibraries-core", version.ref = "aboutLibraries" } accompanist-testharness = { group = "com.google.accompanist", name = "accompanist-testharness", version.ref = "accompanist" } accompanist-permissions = { group = "com.google.accompanist", name = "accompanist-permissions", version.ref = "accompanist" } -android-desugarJdkLibs = { group = "com.android.tools", name = "desugar_jdk_libs", version.ref = "androidDesugarJdkLibs" } +android-desugar-jdk-libs = { group = "com.android.tools", name = "desugar_jdk_libs", version.ref = "androidDesugarJdkLibs" } androidx-activity-compose = { group = "androidx.activity", name = "activity-compose", version.ref = "androidxActivity" } androidx-appcompat = { group = "androidx.appcompat", name = "appcompat", version.ref = "androidxAppCompat" } androidx-annotation = { group = "androidx.annotation", name = "annotation", version.ref = "androidxAnnotation" } diff --git a/gradle/wrapper/gradle-wrapper.properties b/gradle/wrapper/gradle-wrapper.properties index 53f6019f..0d8dd229 100644 --- a/gradle/wrapper/gradle-wrapper.properties +++ b/gradle/wrapper/gradle-wrapper.properties @@ -1,6 +1,6 @@ #Sun Sep 03 17:17:31 EEST 2023 distributionBase=GRADLE_USER_HOME distributionPath=wrapper/dists -distributionUrl=https\://services.gradle.org/distributions/gradle-8.2-bin.zip +distributionUrl=https\://services.gradle.org/distributions/gradle-8.6-bin.zip zipStoreBase=GRADLE_USER_HOME zipStorePath=wrapper/dists diff --git a/monetisation/messaging/src/main/AndroidManifest.xml b/monetisation/messaging/src/main/AndroidManifest.xml index 92395293..11dfec02 100644 --- a/monetisation/messaging/src/main/AndroidManifest.xml +++ b/monetisation/messaging/src/main/AndroidManifest.xml @@ -22,6 +22,11 @@ android:name="dev.teogor.ceres.monetisation.admob.flag.MANUAL_ADS_SETUP" android:value="true" /> + + { apply("com.google.firebase.crashlytics") } - val libs = extensions.getByType().named("libs") dependencies { val bom = libs.findLibrary("firebase-bom").get() add("implementation", platform(bom)) diff --git a/plugin/library-convention/src/main/kotlin/AndroidLibraryConventionPlugin.kt b/plugin/library-convention/src/main/kotlin/AndroidLibraryConventionPlugin.kt index e0e1893d..b1af0301 100644 --- a/plugin/library-convention/src/main/kotlin/AndroidLibraryConventionPlugin.kt +++ b/plugin/library-convention/src/main/kotlin/AndroidLibraryConventionPlugin.kt @@ -21,6 +21,7 @@ import dev.teogor.ceres.configureGradleManagedDevices import dev.teogor.ceres.configureKotlinAndroid import dev.teogor.ceres.configurePrintApksTask import dev.teogor.ceres.disableUnnecessaryAndroidTests +import dev.teogor.ceres.libs import org.gradle.api.Plugin import org.gradle.api.Project import org.gradle.api.artifacts.VersionCatalogsExtension @@ -48,7 +49,6 @@ class AndroidLibraryConventionPlugin : Plugin { configurePrintApksTask(this) disableUnnecessaryAndroidTests(target) } - val libs = extensions.getByType().named("libs") configurations.configureEach { resolutionStrategy { val junit4 = libs.findLibrary("junit4") diff --git a/plugin/library-convention/src/main/kotlin/AndroidLintConventionPlugin.kt b/plugin/library-convention/src/main/kotlin/AndroidLintConventionPlugin.kt new file mode 100644 index 00000000..05993140 --- /dev/null +++ b/plugin/library-convention/src/main/kotlin/AndroidLintConventionPlugin.kt @@ -0,0 +1,36 @@ +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 { + override fun apply(target: Project) { + with(target) { + when { + pluginManager.hasPlugin( + "com.android.application" + ) -> configure { + lint(Lint::configure) + } + + pluginManager.hasPlugin( + "com.android.library" + ) -> configure { + lint(Lint::configure) + } + + else -> { + pluginManager.apply("com.android.lint") + configure(Lint::configure) + } + } + } + } +} + +private fun Lint.configure() { + xmlReport = true + checkDependencies = true +} diff --git a/plugin/library-convention/src/main/kotlin/AndroidRoomConventionPlugin.kt b/plugin/library-convention/src/main/kotlin/AndroidRoomConventionPlugin.kt index 47304e2a..7835eef0 100644 --- a/plugin/library-convention/src/main/kotlin/AndroidRoomConventionPlugin.kt +++ b/plugin/library-convention/src/main/kotlin/AndroidRoomConventionPlugin.kt @@ -15,6 +15,7 @@ */ import com.google.devtools.ksp.gradle.KspExtension +import dev.teogor.ceres.libs import dev.teogor.ceres.models.RoomOptionsExtension import dev.teogor.ceres.models.roomCompiler import dev.teogor.ceres.models.roomKtx @@ -54,7 +55,6 @@ class AndroidRoomConventionPlugin : Plugin { } } - val libs = extensions.getByType().named("libs") dependencies { add( dependencies = listOf( diff --git a/plugin/library-convention/src/main/kotlin/JvmLibraryConventionPlugin.kt b/plugin/library-convention/src/main/kotlin/JvmLibraryConventionPlugin.kt new file mode 100644 index 00000000..b885dfea --- /dev/null +++ b/plugin/library-convention/src/main/kotlin/JvmLibraryConventionPlugin.kt @@ -0,0 +1,15 @@ +import dev.teogor.ceres.configureKotlinJvm +import org.gradle.api.Plugin +import org.gradle.api.Project + +class JvmLibraryConventionPlugin : Plugin { + override fun apply(target: Project) { + with(target) { + with(pluginManager) { + apply("org.jetbrains.kotlin.jvm") + apply("dev.teogor.ceres.android.lint") + } + configureKotlinJvm() + } + } +} diff --git a/plugin/library-convention/src/main/kotlin/dev/teogor/ceres/AndroidBuildConfig.kt b/plugin/library-convention/src/main/kotlin/dev/teogor/ceres/AndroidBuildConfig.kt index fff71464..b6f19e0c 100644 --- a/plugin/library-convention/src/main/kotlin/dev/teogor/ceres/AndroidBuildConfig.kt +++ b/plugin/library-convention/src/main/kotlin/dev/teogor/ceres/AndroidBuildConfig.kt @@ -71,7 +71,7 @@ internal fun ConfigurationContainer.findSpecificDependency( * @param commonExtension The common extension of the Android project. */ internal fun Project.configureAndroidBuildConfig( - commonExtension: CommonExtension<*, *, *, *, *>, + commonExtension: CommonExtension<*, *, *, *, *, *>, ) { val now = Instant.now() val buildDate = now.atOffset(ZoneOffset.UTC).toLocalDate() diff --git a/plugin/library-convention/src/main/kotlin/dev/teogor/ceres/AndroidCompose.kt b/plugin/library-convention/src/main/kotlin/dev/teogor/ceres/AndroidCompose.kt index dd55c48a..113ef41c 100644 --- a/plugin/library-convention/src/main/kotlin/dev/teogor/ceres/AndroidCompose.kt +++ b/plugin/library-convention/src/main/kotlin/dev/teogor/ceres/AndroidCompose.kt @@ -31,10 +31,8 @@ import org.jetbrains.kotlin.gradle.tasks.KotlinCompile * Configure Compose-specific options */ internal fun Project.configureAndroidCompose( - commonExtension: CommonExtension<*, *, *, *, *>, + commonExtension: CommonExtension<*, *, *, *, *, *>, ) { - val libs = extensions.getByType().named("libs") - commonExtension.apply { buildFeatures { compose = true diff --git a/plugin/library-convention/src/main/kotlin/dev/teogor/ceres/CeresFlavor.kt b/plugin/library-convention/src/main/kotlin/dev/teogor/ceres/CeresFlavor.kt index 07146ad7..df765ce9 100644 --- a/plugin/library-convention/src/main/kotlin/dev/teogor/ceres/CeresFlavor.kt +++ b/plugin/library-convention/src/main/kotlin/dev/teogor/ceres/CeresFlavor.kt @@ -26,7 +26,7 @@ import dev.teogor.ceres.utils.getBooleanProperty import org.gradle.api.Project fun Project.configureFlavors( - commonExtension: CommonExtension<*, *, *, *, *>, + commonExtension: CommonExtension<*, *, *, *, *, *>, flavorConfigurationBlock: ProductFlavor.(flavor: CeresFlavor) -> Unit = {}, ) { val flavoursEnabled = getBooleanProperty( diff --git a/plugin/library-convention/src/main/kotlin/dev/teogor/ceres/GradleManagedDevices.kt b/plugin/library-convention/src/main/kotlin/dev/teogor/ceres/GradleManagedDevices.kt index 75b075b6..30dfb646 100644 --- a/plugin/library-convention/src/main/kotlin/dev/teogor/ceres/GradleManagedDevices.kt +++ b/plugin/library-convention/src/main/kotlin/dev/teogor/ceres/GradleManagedDevices.kt @@ -26,7 +26,7 @@ import org.gradle.kotlin.dsl.invoke */ @Suppress("UnstableApiUsage") internal fun configureGradleManagedDevices( - commonExtension: CommonExtension<*, *, *, *, *>, + commonExtension: CommonExtension<*, *, *, *, *, *>, ) { val pixel4 = DeviceConfig("Pixel 4", 30, "aosp-atd") val pixel6 = DeviceConfig("Pixel 6", 31, "aosp") diff --git a/plugin/library-convention/src/main/kotlin/dev/teogor/ceres/Jacoco.kt b/plugin/library-convention/src/main/kotlin/dev/teogor/ceres/Jacoco.kt index 820a4286..94a94edf 100644 --- a/plugin/library-convention/src/main/kotlin/dev/teogor/ceres/Jacoco.kt +++ b/plugin/library-convention/src/main/kotlin/dev/teogor/ceres/Jacoco.kt @@ -44,8 +44,6 @@ private fun String.capitalize() = replaceFirstChar { internal fun Project.configureJacoco( androidComponentsExtension: AndroidComponentsExtension<*, *, *>, ) { - val libs = extensions.getByType().named("libs") - configure { libs.findVersion("jacoco").let { jacoco -> if (jacoco.isPresent) { diff --git a/plugin/library-convention/src/main/kotlin/dev/teogor/ceres/KotlinAndroid.kt b/plugin/library-convention/src/main/kotlin/dev/teogor/ceres/KotlinAndroid.kt index 369106de..6b133492 100644 --- a/plugin/library-convention/src/main/kotlin/dev/teogor/ceres/KotlinAndroid.kt +++ b/plugin/library-convention/src/main/kotlin/dev/teogor/ceres/KotlinAndroid.kt @@ -17,13 +17,15 @@ package dev.teogor.ceres import com.android.build.api.dsl.CommonExtension +import dev.teogor.ceres.models.desugarJdkLibs +import dev.teogor.ceres.utils.add import dev.teogor.ceres.utils.getBooleanProperty import dev.teogor.ceres.utils.getIntProperty import org.gradle.api.JavaVersion import org.gradle.api.Project -import org.gradle.api.artifacts.VersionCatalogsExtension +import org.gradle.api.plugins.JavaPluginExtension +import org.gradle.kotlin.dsl.configure import org.gradle.kotlin.dsl.dependencies -import org.gradle.kotlin.dsl.getByType import org.gradle.kotlin.dsl.provideDelegate import org.gradle.kotlin.dsl.withType import org.jetbrains.kotlin.gradle.tasks.KotlinCompile @@ -32,9 +34,8 @@ import org.jetbrains.kotlin.gradle.tasks.KotlinCompile * Configure base Kotlin with Android options */ internal fun Project.configureKotlinAndroid( - commonExtension: CommonExtension<*, *, *, *, *>, + commonExtension: CommonExtension<*, *, *, *, *, *>, ) { - commonExtension.apply { compileSdk = getIntProperty( key = "ceres.buildfeatures.sdk.compile", @@ -53,7 +54,6 @@ internal fun Project.configureKotlinAndroid( // https://developer.android.com/studio/write/java11-minimal-support-table sourceCompatibility = JavaVersion.VERSION_11 targetCompatibility = JavaVersion.VERSION_11 - isCoreLibraryDesugaringEnabled = getBooleanProperty( key = "ceres.buildfeatures.desugaring.enabled", defaultValue = true, @@ -61,6 +61,43 @@ internal fun Project.configureKotlinAndroid( } } + configureKotlin() + + dependencies { + if (getBooleanProperty( + key = "ceres.buildfeatures.desugaring.enabled", + defaultValue = true, + ) + ) { + add( + dependencies = listOf( + desugarJdkLibs, + ), + logger = logger, + libs = libs, + ) + } + } +} + +/** + * Configure base Kotlin options for JVM (non-Android) + */ +internal fun Project.configureKotlinJvm() { + extensions.configure { + // Up to Java 11 APIs are available through desugaring + // https://developer.android.com/studio/write/java11-minimal-support-table + sourceCompatibility = JavaVersion.VERSION_11 + targetCompatibility = JavaVersion.VERSION_11 + } + + configureKotlin() +} + +/** + * Configure base Kotlin options + */ +private fun Project.configureKotlin() { // Use withType to workaround https://youtrack.jetbrains.com/issue/KT-55947 tasks.withType().configureEach { kotlinOptions { @@ -71,26 +108,9 @@ internal fun Project.configureKotlinAndroid( val warningsAsErrors: String? by project allWarningsAsErrors = warningsAsErrors.toBoolean() freeCompilerArgs = freeCompilerArgs + listOf( - "-opt-in=kotlin.RequiresOptIn", // Enable experimental coroutines APIs, including Flow "-opt-in=kotlinx.coroutines.ExperimentalCoroutinesApi", - "-opt-in=kotlinx.coroutines.FlowPreview", - ) - } - } - - val libs = extensions.getByType().named("libs") - - dependencies { - if (getBooleanProperty( - key = "ceres.buildfeatures.desugaring.enabled", - defaultValue = true, ) - ) { - val desugarJdkLibs = libs.findLibrary("android.desugarJdkLibs") - if (desugarJdkLibs.isPresent) { - add("coreLibraryDesugaring", desugarJdkLibs.get()) - } } } } diff --git a/plugin/library-convention/src/main/kotlin/dev/teogor/ceres/ProjectExtensions.kt b/plugin/library-convention/src/main/kotlin/dev/teogor/ceres/ProjectExtensions.kt new file mode 100644 index 00000000..2f4a3bfe --- /dev/null +++ b/plugin/library-convention/src/main/kotlin/dev/teogor/ceres/ProjectExtensions.kt @@ -0,0 +1,9 @@ +package dev.teogor.ceres + +import org.gradle.api.Project +import org.gradle.api.artifacts.VersionCatalog +import org.gradle.api.artifacts.VersionCatalogsExtension +import org.gradle.kotlin.dsl.getByType + +val Project.libs + get(): VersionCatalog = extensions.getByType().named("libs") diff --git a/plugin/library-convention/src/main/kotlin/dev/teogor/ceres/models/DependencyType.kt b/plugin/library-convention/src/main/kotlin/dev/teogor/ceres/models/DependencyType.kt index 1f2f384a..d27c0209 100644 --- a/plugin/library-convention/src/main/kotlin/dev/teogor/ceres/models/DependencyType.kt +++ b/plugin/library-convention/src/main/kotlin/dev/teogor/ceres/models/DependencyType.kt @@ -8,4 +8,5 @@ enum class DependencyType(val gradleNotation: String) { ANDROID_TEST_IMPLEMENTATION("androidTestImplementation"), TEST_IMPLEMENTATION("testImplementation"), COMPILE_ONLY("compileOnly"), + CORE_LIBRARY_DESUGARING("coreLibraryDesugaring"), } diff --git a/plugin/library-convention/src/main/kotlin/dev/teogor/ceres/models/LibrarySpec.kt b/plugin/library-convention/src/main/kotlin/dev/teogor/ceres/models/LibrarySpec.kt index ea0f553e..dfee5155 100644 --- a/plugin/library-convention/src/main/kotlin/dev/teogor/ceres/models/LibrarySpec.kt +++ b/plugin/library-convention/src/main/kotlin/dev/teogor/ceres/models/LibrarySpec.kt @@ -52,3 +52,10 @@ val androidxComposeBom = LibrarySpec( ), isBom = true, ) +val desugarJdkLibs = LibrarySpec( + name = "android.desugar.jdk.libs", + module = "com.android.tools:desugar_jdk_libs", + dependencyTypes = listOf( + DependencyType.CORE_LIBRARY_DESUGARING, + ), +)