From 00eec21820bdc9fbf9620c8e935965884aa7e0c3 Mon Sep 17 00:00:00 2001 From: Eliezer Graber Date: Sun, 30 Jul 2023 00:53:08 -0400 Subject: [PATCH] Assorted improvements to Compose and Kotlin (#211) --- .../com/eygraber/conventions/kotlin/kgp.kt | 8 +- .../src/main/kotlin/ProjectExtensions.kt | 5 + ...ber.conventions-android-library.gradle.kts | 209 +++++++++--------- ...r.conventions-compose-jetbrains.gradle.kts | 16 +- ...ber.conventions-compose-jetpack.gradle.kts | 15 +- ...om.eygraber.conventions-compose.gradle.kts | 7 +- ...aber.conventions-kotlin-library.gradle.kts | 46 +++- .../conventions/GradleConventionsPlugin.kt | 4 +- .../GradleConventionsPluginExtension.kt | 7 +- .../compose/GradleConventionsCompose.kt | 78 ++++--- .../kotlin/GradleConventionsKotlin.kt | 5 +- detekt.yml | 2 - gradle/libs.versions.toml | 2 +- 13 files changed, 232 insertions(+), 172 deletions(-) diff --git a/conventions-kotlin/src/main/kotlin/com/eygraber/conventions/kotlin/kgp.kt b/conventions-kotlin/src/main/kotlin/com/eygraber/conventions/kotlin/kgp.kt index 98b7657..3fc4fb2 100644 --- a/conventions-kotlin/src/main/kotlin/com/eygraber/conventions/kotlin/kgp.kt +++ b/conventions-kotlin/src/main/kotlin/com/eygraber/conventions/kotlin/kgp.kt @@ -25,7 +25,7 @@ public fun Project.configureKgp( jvmDistribution: JvmVendorSpec? = null, allWarningsAsErrors: Boolean = true, explicitApiMode: ExplicitApiMode = ExplicitApiMode.Disabled, - configureJavaCompatibility: Boolean = true, + configureJavaTargetVersion: Boolean = true, useK2: Boolean = false, freeCompilerArgs: List = emptyList(), vararg optIns: KotlinOptIn @@ -36,7 +36,7 @@ public fun Project.configureKgp( jvmDistribution, allWarningsAsErrors, explicitApiMode, - configureJavaCompatibility, + configureJavaTargetVersion, useK2, freeCompilerArgs, *optIns @@ -49,12 +49,12 @@ public fun Project.configureKgp( jvmDistribution: JvmVendorSpec? = null, allWarningsAsErrors: Boolean = true, explicitApiMode: ExplicitApiMode = ExplicitApiMode.Disabled, - configureJavaCompatibility: Boolean = true, + configureJavaTargetVersion: Boolean = true, useK2: Boolean = false, freeCompilerArgs: List = emptyList(), vararg optIns: KotlinOptIn ) { - if(configureJavaCompatibility && jvmTargetVersion != null) { + if(configureJavaTargetVersion && jvmTargetVersion != null) { tasks.withType(JavaCompile::class.java) { sourceCompatibility = jvmTargetVersion.target targetCompatibility = jvmTargetVersion.target diff --git a/conventions-plugin/src/main/kotlin/ProjectExtensions.kt b/conventions-plugin/src/main/kotlin/ProjectExtensions.kt index a30caf3..074e5b2 100644 --- a/conventions-plugin/src/main/kotlin/ProjectExtensions.kt +++ b/conventions-plugin/src/main/kotlin/ProjectExtensions.kt @@ -1,6 +1,7 @@ @file:Suppress("NOTHING_TO_INLINE") import com.android.build.api.variant.LibraryAndroidComponentsExtension +import com.android.build.gradle.AppExtension import com.android.build.gradle.BaseExtension import com.android.build.gradle.LibraryExtension import com.vanniktech.maven.publish.MavenPublishBaseExtension @@ -17,6 +18,10 @@ internal inline fun Project.android(action: Action) { action.execute(extensions.getByType(BaseExtension::class.java)) } +internal inline fun Project.androidApp(action: Action) { + action.execute(extensions.getByType(AppExtension::class.java)) +} + internal inline fun Project.androidLibraryComponents(action: Action) { action.execute(extensions.getByType(LibraryAndroidComponentsExtension::class.java)) } diff --git a/conventions-plugin/src/main/kotlin/com.eygraber.conventions-android-library.gradle.kts b/conventions-plugin/src/main/kotlin/com.eygraber.conventions-android-library.gradle.kts index 981a530..c91cea3 100644 --- a/conventions-plugin/src/main/kotlin/com.eygraber.conventions-android-library.gradle.kts +++ b/conventions-plugin/src/main/kotlin/com.eygraber.conventions-android-library.gradle.kts @@ -26,152 +26,143 @@ ext.kotlin.jvmTargetVersion = kotlinDefaults.jvmTargetVersion var isAndroidPublishingConfigured = false @Suppress("LabeledExpression") -ext.awaitKotlinConfigured { isKotlinUserConfigured -> - ext.awaitAndroidConfigured { isAndroidUserConfigured -> - val isSdkVersionsConfigured = compileSdk > 0 && minSdk > 0 - if(!isSdkVersionsConfigured && !isAndroidUserConfigured) return@awaitAndroidConfigured +ext.awaitAndroidConfigured { isAndroidUserConfigured -> + val isSdkVersionsConfigured = compileSdk > 0 && minSdk > 0 + if(!isSdkVersionsConfigured && !isAndroidUserConfigured) return@awaitAndroidConfigured - if(jvmTargetVersion == null && !isKotlinUserConfigured) return@awaitAndroidConfigured - - check(compileSdk > 0) { - "android.compileSdk doesn't have a value set" - } + check(compileSdk > 0) { + "android.compileSdk doesn't have a value set" + } - check(minSdk > 0) { - "android.minSdk doesn't have a value set" - } + check(minSdk > 0) { + "android.minSdk doesn't have a value set" + } - val androidCompileSdk = compileSdk - val androidMinSdk = minSdk + val androidCompileSdk = compileSdk + val androidMinSdk = minSdk - androidLibrary { - compileSdk = androidCompileSdk + androidLibrary { + compileSdk = androidCompileSdk - val kmpManifestFilePath = "src/androidMain/AndroidManifest.xml" - if(layout.projectDirectory.file(kmpManifestFilePath).asFile.exists()) { - sourceSets.named("main") { - manifest.srcFile(kmpManifestFilePath) - } + val kmpManifestFilePath = "src/androidMain/AndroidManifest.xml" + if(layout.projectDirectory.file(kmpManifestFilePath).asFile.exists()) { + sourceSets.named("main") { + manifest.srcFile(kmpManifestFilePath) } + } - val kmpResPath = "src/androidMain/res" - if(layout.projectDirectory.file(kmpResPath).asFile.exists()) { - sourceSets.named("main") { - res.srcDir(kmpResPath) - } + val kmpResPath = "src/androidMain/res" + if(layout.projectDirectory.file(kmpResPath).asFile.exists()) { + sourceSets.named("main") { + res.srcDir(kmpResPath) } + } - val kmpResourcesPath = "src/commonMain/resources" - if(layout.projectDirectory.file(kmpResourcesPath).asFile.exists()) { - sourceSets.named("main") { - res.srcDir(kmpResourcesPath) - } + val kmpResourcesPath = "src/commonMain/resources" + if(layout.projectDirectory.file(kmpResourcesPath).asFile.exists()) { + sourceSets.named("main") { + res.srcDir(kmpResourcesPath) } + } - defaultConfig { - consumerProguardFile(project.file("consumer-rules.pro")) + defaultConfig { + consumerProguardFile(project.file("consumer-rules.pro")) - minSdk = androidMinSdk + minSdk = androidMinSdk - testInstrumentationRunner = "androidx.test.runner.AndroidJUnitRunner" - } + testInstrumentationRunner = "androidx.test.runner.AndroidJUnitRunner" + } - val jvmTargetVersion = jvmTargetVersion - if(jvmTargetVersion != null) { - compileOptions { - if(coreLibraryDesugaringDependency != null) { - isCoreLibraryDesugaringEnabled = true - } - sourceCompatibility = JavaVersion.toVersion(jvmTargetVersion) - targetCompatibility = JavaVersion.toVersion(jvmTargetVersion) - } + compileOptions { + if(coreLibraryDesugaringDependency != null) { + isCoreLibraryDesugaringEnabled = true } + } - packaging { - resources.pickFirsts += "META-INF/*" - } + packaging { + resources.pickFirsts += "META-INF/*" + } - buildTypes { - named("release") { - isMinifyEnabled = false - } - named("debug") { - isMinifyEnabled = false - } + buildTypes { + named("release") { + isMinifyEnabled = false + } + named("debug") { + isMinifyEnabled = false } + } - for((dimension, flavorsToRegister) in flavors) { - if(dimension !in flavorDimensions) flavorDimensions += dimension + for((dimension, flavorsToRegister) in flavors) { + if(dimension !in flavorDimensions) flavorDimensions += dimension - for(flavor in flavorsToRegister) { - // register throws if the name is already registered - // and this block can be called multiple times - runCatching { - productFlavors.register(flavor.name) - } + for(flavor in flavorsToRegister) { + // register throws if the name is already registered + // and this block can be called multiple times + runCatching { + productFlavors.register(flavor.name) } } + } - testOptions { - unitTests { - isIncludeAndroidResources = true - } + testOptions { + unitTests { + isIncludeAndroidResources = true } + } - if(publishEverything) { - // we can't configure this twice and awaitAndroidConfigured can be called twice (default and user config) - // since publishing doesn't depend on values from the extension we can guard against this without issue - if(!isAndroidPublishingConfigured) { - publishing { - multipleVariants { - allVariants() - withJavadocJar() - withSourcesJar() - } + if(publishEverything) { + // we can't configure this twice and awaitAndroidConfigured can be called twice (default and user config) + // since publishing doesn't depend on values from the extension we can guard against this without issue + if(!isAndroidPublishingConfigured) { + publishing { + multipleVariants { + allVariants() + withJavadocJar() + withSourcesJar() } - isAndroidPublishingConfigured = true } + isAndroidPublishingConfigured = true } + } - coreLibraryDesugaringDependency?.let { desugaringDependency -> - dependencies { - add("coreLibraryDesugaring", desugaringDependency) - } + coreLibraryDesugaringDependency?.let { desugaringDependency -> + dependencies { + add("coreLibraryDesugaring", desugaringDependency) } } + } - androidLibraryComponents { - val disabledFlavors = flavors.mapNotNull { (dimension, flavorsToRegister) -> - val disabledFlavors = flavorsToRegister.filterNot { it.enabled } - (dimension to disabledFlavors).takeIf { disabledFlavors.isNotEmpty() } - } - if(disabledFlavors.isNotEmpty()) { - val selector = selector().let { - var s = it - for((dimension, disabled) in disabledFlavors) { - for(disabledFlavor in disabled) { - s = s.withFlavor(dimension to disabledFlavor.name) - } + androidLibraryComponents { + val disabledFlavors = flavors.mapNotNull { (dimension, flavorsToRegister) -> + val disabledFlavors = flavorsToRegister.filterNot { it.enabled } + (dimension to disabledFlavors).takeIf { disabledFlavors.isNotEmpty() } + } + if(disabledFlavors.isNotEmpty()) { + val selector = selector().let { + var s = it + for((dimension, disabled) in disabledFlavors) { + for(disabledFlavor in disabled) { + s = s.withFlavor(dimension to disabledFlavor.name) } - s } + s + } - beforeVariants(selector) { variant -> - variant.enable = false - } + beforeVariants(selector) { variant -> + variant.enable = false } + } - for((optIns, dependencyPredicate) in optInsToDependencyPredicate) { - onVariants { variant -> - doOnFirstMatchingIncomingDependencyBeforeResolution( - configurationName = "${variant.name}RuntimeClasspath", - dependencyPredicate = dependencyPredicate - ) { - tasks.withType(KotlinCompilationTask::class.java).configureEach { - compilerOptions { - for(optIn in optIns) { - freeCompilerArgs.addAll("-opt-in=${optIn.value}") - } + for((optIns, dependencyPredicate) in optInsToDependencyPredicate) { + onVariants { variant -> + doOnFirstMatchingIncomingDependencyBeforeResolution( + configurationName = "${variant.name}RuntimeClasspath", + dependencyPredicate = dependencyPredicate + ) { + tasks.withType(KotlinCompilationTask::class.java).configureEach { + compilerOptions { + for(optIn in optIns) { + freeCompilerArgs.addAll("-opt-in=${optIn.value}") } } } diff --git a/conventions-plugin/src/main/kotlin/com.eygraber.conventions-compose-jetbrains.gradle.kts b/conventions-plugin/src/main/kotlin/com.eygraber.conventions-compose-jetbrains.gradle.kts index 19088df..a00a039 100644 --- a/conventions-plugin/src/main/kotlin/com.eygraber.conventions-compose-jetbrains.gradle.kts +++ b/conventions-plugin/src/main/kotlin/com.eygraber.conventions-compose-jetbrains.gradle.kts @@ -11,7 +11,7 @@ plugins { } gradleConventionsExtension.awaitComposeConfigured { - if(ignoreNonJvmTargets) { + if(applyToAndroidAndJvmOnly) { // only apply to android/jvm targets if we're in a multiplatform project plugins.withId("org.jetbrains.kotlin.multiplatform") { plugins.removeAll { @@ -36,12 +36,13 @@ gradleConventionsExtension.awaitComposeConfigured { ) } - plugins.withType { - android { - dependencies { - // jetbrains compose plugin rewrites compose dependencies for android to point to androidx - // if we want to use the compose BOM we need to rewrite the rewritten dependencies to not include a version - if(androidComposeDependencyBomVersion != null) { + // jetbrains compose plugin rewrites compose dependencies for android to point to androidx + // if we want to use the compose BOM we need to rewrite the rewritten dependencies to not include a version + // https://github.com/JetBrains/compose-multiplatform/issues/2502 + if(androidComposeDependencyBomVersion != null) { + plugins.withType { + android { + dependencies { components { all { val isCompiler = id.group.endsWith("compiler") @@ -50,7 +51,6 @@ gradleConventionsExtension.awaitComposeConfigured { val override = isCompose && !isCompiler && !isBom if(override) { - // copied from Jetbrains Compose RedirectAndroidVariants - https://shorturl.at/dioY9 listOf( "debugApiElements-published", "debugRuntimeElements-published", diff --git a/conventions-plugin/src/main/kotlin/com.eygraber.conventions-compose-jetpack.gradle.kts b/conventions-plugin/src/main/kotlin/com.eygraber.conventions-compose-jetpack.gradle.kts index b7c9f15..c8235ea 100644 --- a/conventions-plugin/src/main/kotlin/com.eygraber.conventions-compose-jetpack.gradle.kts +++ b/conventions-plugin/src/main/kotlin/com.eygraber.conventions-compose-jetpack.gradle.kts @@ -7,13 +7,18 @@ plugins { id("com.eygraber.conventions-compose") } -plugins.withType { - android { - buildFeatures.compose = true +gradleConventionsExtension.awaitComposeConfigured { + plugins.withType { + android { + buildFeatures.compose = true + + androidComposeCompilerVersionOverride?.let { versionOverride -> + @Suppress("UnstableApiUsage") + composeOptions.kotlinCompilerExtensionVersion = versionOverride + } + } } -} -gradleConventionsExtension.awaitComposeConfigured { if(enableAndroidCompilerMetrics) { val output = project.layout.buildDirectory.dir("compose_metrics").get().asFile diff --git a/conventions-plugin/src/main/kotlin/com.eygraber.conventions-compose.gradle.kts b/conventions-plugin/src/main/kotlin/com.eygraber.conventions-compose.gradle.kts index f65869e..1590faa 100644 --- a/conventions-plugin/src/main/kotlin/com.eygraber.conventions-compose.gradle.kts +++ b/conventions-plugin/src/main/kotlin/com.eygraber.conventions-compose.gradle.kts @@ -8,7 +8,7 @@ val composeDefaults = gradleConventionsDefaultsService.compose ext.compose.androidComposeCompilerVersionOverride = composeDefaults.androidComposeCompilerVersionOverride ext.compose.androidComposeDependencyBomVersion = composeDefaults.androidComposeDependencyBomVersion ext.compose.enableAndroidCompilerMetrics = composeDefaults.enableAndroidCompilerMetrics -ext.compose.ignoreNonJvmTargets = composeDefaults.ignoreNonJvmTargets +ext.compose.applyToAndroidAndJvmOnly = composeDefaults.applyToAndroidAndJvmOnly ext.compose.jetbrainsComposeCompilerOverride = composeDefaults.jetbrainsComposeCompilerOverride ext.compose.useAndroidComposeCompilerVersionForJetbrainsComposeCompilerVersion = composeDefaults.useAndroidComposeCompilerVersionForJetbrainsComposeCompilerVersion @@ -16,11 +16,6 @@ ext.compose.useAndroidComposeCompilerVersionForJetbrainsComposeCompilerVersion = ext.awaitComposeConfigured { plugins.withType { android { - androidComposeCompilerVersionOverride?.let { versionOverride -> - @Suppress("UnstableApiUsage") - composeOptions.kotlinCompilerExtensionVersion = versionOverride - } - dependencies { androidComposeDependencyBomVersion?.let { bomVersion -> implementation(platform("androidx.compose:compose-bom:$bomVersion")) diff --git a/conventions-plugin/src/main/kotlin/com.eygraber.conventions-kotlin-library.gradle.kts b/conventions-plugin/src/main/kotlin/com.eygraber.conventions-kotlin-library.gradle.kts index 70cc09f..bc223cb 100644 --- a/conventions-plugin/src/main/kotlin/com.eygraber.conventions-kotlin-library.gradle.kts +++ b/conventions-plugin/src/main/kotlin/com.eygraber.conventions-kotlin-library.gradle.kts @@ -1,3 +1,4 @@ +import com.android.build.api.dsl.CompileOptions import com.eygraber.conventions.gradleConventionsDefaultsService import com.eygraber.conventions.gradleConventionsExtension import com.eygraber.conventions.kotlin.configureKgp @@ -11,12 +12,29 @@ with(gradleConventionsExtension) { jvmDistribution = kotlinDefaults.jvmDistribution allWarningsAsErrors = kotlinDefaults.allWarningsAsErrors explicitApiMode = kotlinDefaults.explicitApiMode - configureJava = kotlinDefaults.configureJava + configureJavaTargetVersion = kotlinDefaults.configureJavaTargetVersion useK2 = kotlinDefaults.useK2 freeCompilerArgs = kotlinDefaults.freeCompilerArgs optIns = kotlinDefaults.optIns } + val highestSupportedJava: JavaVersion = when { + GradleVersion.current() < GradleVersion.version("8.3") -> JavaVersion.VERSION_17 + else -> JavaVersion.VERSION_20 + } + + val lowestSupportedJava: JavaVersion = JavaVersion.VERSION_17 + + val buildJavaVersion: JavaVersion = when { + JavaVersion.current() < lowestSupportedJava -> lowestSupportedJava + JavaVersion.current() > highestSupportedJava -> highestSupportedJava + else -> JavaVersion.current() + } + + if(JavaVersion.current() != buildJavaVersion) { + kotlin.jdkToolchainVersion = JavaLanguageVersion.of(buildJavaVersion.majorVersion.toInt()) + } + awaitKotlinConfigured { configureKgp( jvmTargetVersion = jvmTargetVersion, @@ -24,9 +42,33 @@ with(gradleConventionsExtension) { jvmDistribution = jvmDistribution, allWarningsAsErrors = allWarningsAsErrors, explicitApiMode = explicitApiMode, - configureJavaCompatibility = configureJava, + configureJavaTargetVersion = configureJavaTargetVersion, freeCompilerArgs = freeCompilerArgs.toList(), optIns = optIns.toTypedArray() ) + + fun CompileOptions.configureJvmTarget() { + val jvmTargetVersion = jvmTargetVersion + if(configureJavaTargetVersion) { + val androidJvmTargetVersion = jvmTargetVersion?.let { + JavaVersion.toVersion(it.target) + } ?: buildJavaVersion + + sourceCompatibility = androidJvmTargetVersion + targetCompatibility = androidJvmTargetVersion + } + } + + plugins.withId("com.android.application") { + androidApp { + compileOptions.configureJvmTarget() + } + } + + plugins.withId("com.android.library") { + androidLibrary { + compileOptions.configureJvmTarget() + } + } } } diff --git a/conventions-plugin/src/main/kotlin/com/eygraber/conventions/GradleConventionsPlugin.kt b/conventions-plugin/src/main/kotlin/com/eygraber/conventions/GradleConventionsPlugin.kt index b447c5f..fede8e8 100644 --- a/conventions-plugin/src/main/kotlin/com/eygraber/conventions/GradleConventionsPlugin.kt +++ b/conventions-plugin/src/main/kotlin/com/eygraber/conventions/GradleConventionsPlugin.kt @@ -46,7 +46,7 @@ abstract class GradleConventionsPlugin : Plugin { compose.androidComposeCompilerVersionOverride = androidComposeCompilerVersionOverride compose.androidComposeDependencyBomVersion = androidComposeDependencyBomVersion compose.enableAndroidCompilerMetrics = enableAndroidCompilerMetrics - compose.ignoreNonJvmTargets = ignoreNonJvmTargets + compose.applyToAndroidAndJvmOnly = applyToAndroidAndJvmOnly compose.jetbrainsComposeCompilerOverride = jetbrainsComposeCompilerOverride compose.useAndroidComposeCompilerVersionForJetbrainsComposeCompilerVersion = useAndroidComposeCompilerVersionForJetbrainsComposeCompilerVersion @@ -74,7 +74,7 @@ abstract class GradleConventionsPlugin : Plugin { kotlin.jvmDistribution = jvmDistribution kotlin.allWarningsAsErrors = allWarningsAsErrors kotlin.explicitApiMode = explicitApiMode - kotlin.configureJava = configureJava + kotlin.configureJavaTargetVersion = configureJavaTargetVersion kotlin.useK2 = useK2 kotlin.freeCompilerArgs = freeCompilerArgs kotlin.optIns = optIns diff --git a/conventions-plugin/src/main/kotlin/com/eygraber/conventions/GradleConventionsPluginExtension.kt b/conventions-plugin/src/main/kotlin/com/eygraber/conventions/GradleConventionsPluginExtension.kt index f56bb22..721c7c4 100644 --- a/conventions-plugin/src/main/kotlin/com/eygraber/conventions/GradleConventionsPluginExtension.kt +++ b/conventions-plugin/src/main/kotlin/com/eygraber/conventions/GradleConventionsPluginExtension.kt @@ -10,6 +10,7 @@ import com.eygraber.conventions.spm.GradleConventionsSpm import org.gradle.api.Action import org.gradle.api.Project import org.gradle.kotlin.dsl.create +import org.jetbrains.kotlin.gradle.dsl.JvmTarget import java.util.concurrent.CopyOnWriteArrayList internal interface GradleConventionsConfigurableListener { @@ -176,7 +177,11 @@ abstract class GradleConventionsPluginExtension { return field } - fun kotlin(action: Action) { + fun kotlin( + jvmTargetVersion: JvmTarget, + action: Action + ) { + kotlin.jvmTargetVersion = jvmTargetVersion action.execute(kotlin) isKotlinConfigured = true configureListeners.forEach { listener -> diff --git a/conventions-plugin/src/main/kotlin/com/eygraber/conventions/compose/GradleConventionsCompose.kt b/conventions-plugin/src/main/kotlin/com/eygraber/conventions/compose/GradleConventionsCompose.kt index c8268e2..9fa5be4 100644 --- a/conventions-plugin/src/main/kotlin/com/eygraber/conventions/compose/GradleConventionsCompose.kt +++ b/conventions-plugin/src/main/kotlin/com/eygraber/conventions/compose/GradleConventionsCompose.kt @@ -11,36 +11,67 @@ class GradleConventionsCompose { var androidComposeCompilerVersionOverride: String? = null var androidComposeDependencyBomVersion: String? = null var enableAndroidCompilerMetrics: Boolean = false - var ignoreNonJvmTargets: Boolean = false + var applyToAndroidAndJvmOnly: Boolean = false var jetbrainsComposeCompilerOverride: MinimalExternalModuleDependency? = null var useAndroidComposeCompilerVersionForJetbrainsComposeCompilerVersion: Boolean = false + @Suppress("ObjectPropertyNaming") + companion object { + const val JetbrainsCompilerArtifact = "org.jetbrains.compose.compiler:compiler" + const val JetpackCompilerArtifact = "androidx.compose.compiler:compiler" + } + fun android( - compilerVersion: Provider? = null, + compilerVersionOverride: Provider? = null, + compilerOverride: Provider? = null, bomVersion: Provider? = null, + bom: Provider? = null, enableAndroidCompilerMetrics: Boolean = false ) { - compilerVersion?.let { androidComposeCompilerVersionOverride = it.get() } + compilerVersionOverride?.let { androidComposeCompilerVersionOverride = it.get() } + compilerOverride?.let { + val dependency = it.get() + check(dependency.group == "androidx.compose.compiler" && dependency.name == "compiler") { + "Only the $JetpackCompilerArtifact artifact should be used as an override" + } + val version = it.get().version + requireNotNull(version) { + "Please specify a version for the $JetpackCompilerArtifact artifact" + } + androidComposeCompilerVersionOverride = version + } bomVersion?.let { androidComposeDependencyBomVersion = it.get() } + bom?.let { androidComposeDependencyBomVersion = it.get().version } this.enableAndroidCompilerMetrics = enableAndroidCompilerMetrics } - fun android( - compilerVersion: String? = null, - bomVersion: String? = null, - enableAndroidCompilerMetrics: Boolean = false + fun multiplatformWithAndroidCompiler( + androidCompilerVersion: Provider, + applyToAndroidAndJvmOnly: Boolean = false ) { - compilerVersion?.let { androidComposeCompilerVersionOverride = it } - bomVersion?.let { androidComposeDependencyBomVersion = it } - this.enableAndroidCompilerMetrics = enableAndroidCompilerMetrics + multiplatform( + compilerMavenCoordinatesOverride = "$JetpackCompilerArtifact:$androidCompilerVersion", + applyToAndroidAndJvmOnly = applyToAndroidAndJvmOnly + ) + } + + fun multiplatformWithJetbrainsCompiler( + jetbrainsCompilerVersion: Provider, + applyToAndroidAndJvmOnly: Boolean = false + ) { + multiplatform( + compilerMavenCoordinatesOverride = "$JetbrainsCompilerArtifact:$jetbrainsCompilerVersion", + applyToAndroidAndJvmOnly = applyToAndroidAndJvmOnly + ) } fun multiplatform( - compilerMavenCoordinates: String? = null, - ignoreNonJvmTargets: Boolean = false + compilerMavenCoordinatesOverride: String? = null, + compilerOverride: Provider? = null, + applyToAndroidAndJvmOnly: Boolean = false ) { - if(compilerMavenCoordinates != null) { - val coords = compilerMavenCoordinates.split(":") + if(compilerMavenCoordinatesOverride != null) { + val coords = compilerMavenCoordinatesOverride.split(":") jetbrainsComposeCompilerOverride = when(coords.size) { 3 -> DefaultMinimalDependency( DefaultModuleIdentifier.newId( @@ -61,22 +92,7 @@ class GradleConventionsCompose { else -> error("Please specify full maven coordinates for the Compose compiler you'd like to use") } } - this.ignoreNonJvmTargets = ignoreNonJvmTargets - } - - fun multiplatform( - compiler: Provider? = null, - ignoreNonJvmTargets: Boolean = false - ) { - compiler?.let { jetbrainsComposeCompilerOverride = it.get() } - this.ignoreNonJvmTargets = ignoreNonJvmTargets - } - - fun multiplatform( - compiler: MinimalExternalModuleDependency? = null, - ignoreNonJvmTargets: Boolean = false - ) { - compiler?.let { jetbrainsComposeCompilerOverride = it } - this.ignoreNonJvmTargets = ignoreNonJvmTargets + compilerOverride?.let { jetbrainsComposeCompilerOverride = it.get() } + this.applyToAndroidAndJvmOnly = applyToAndroidAndJvmOnly } } diff --git a/conventions-plugin/src/main/kotlin/com/eygraber/conventions/kotlin/GradleConventionsKotlin.kt b/conventions-plugin/src/main/kotlin/com/eygraber/conventions/kotlin/GradleConventionsKotlin.kt index b42cb6b..a32eabb 100644 --- a/conventions-plugin/src/main/kotlin/com/eygraber/conventions/kotlin/GradleConventionsKotlin.kt +++ b/conventions-plugin/src/main/kotlin/com/eygraber/conventions/kotlin/GradleConventionsKotlin.kt @@ -1,5 +1,6 @@ package com.eygraber.conventions.kotlin +import org.gradle.api.provider.Provider import org.gradle.jvm.toolchain.JavaLanguageVersion import org.gradle.jvm.toolchain.JvmVendorSpec import org.jetbrains.kotlin.gradle.dsl.ExplicitApiMode @@ -11,8 +12,10 @@ class GradleConventionsKotlin { var jvmDistribution: JvmVendorSpec? = null var allWarningsAsErrors: Boolean = true var explicitApiMode: ExplicitApiMode = ExplicitApiMode.Disabled - var configureJava: Boolean = true + var configureJavaTargetVersion: Boolean = true var useK2: Boolean = false var freeCompilerArgs: Set = emptySet() var optIns: Set = emptySet() + + fun Provider.toJvmTarget() = JvmTarget.fromTarget(get()) } diff --git a/detekt.yml b/detekt.yml index 7f9a0da..3590a63 100644 --- a/detekt.yml +++ b/detekt.yml @@ -480,8 +480,6 @@ style: active: true OptionalUnit: active: true - OptionalWhenBraces: - active: true PreferToOverPairSyntax: active: true ProtectedMemberInFinalClass: diff --git a/gradle/libs.versions.toml b/gradle/libs.versions.toml index 8afe5c7..7cf960a 100644 --- a/gradle/libs.versions.toml +++ b/gradle/libs.versions.toml @@ -5,7 +5,7 @@ android-plugin = "8.1.0" compose-jetbrains = "1.4.3" -detekt = "1.23.0" +detekt = "1.23.1" detektEygraber = "1.0.11" dokka = "1.8.20"