diff --git a/buildlogic/convention/build.gradle.kts b/buildlogic/convention/build.gradle.kts new file mode 100644 index 0000000..56d0b49 --- /dev/null +++ b/buildlogic/convention/build.gradle.kts @@ -0,0 +1,39 @@ +plugins { + `kotlin-dsl` +} + +group = "dev.carlosmartino.plugins.buildlogic" + +dependencies { + implementation(libs.plugins.kotlinMultiplatform.toDep()) + implementation(libs.plugins.kotlinSerialization.toDep()) + implementation(libs.plugins.androidApplication.toDep()) + implementation(libs.plugins.androidLibrary.toDep()) + implementation(libs.plugins.composeCompiler.toDep()) + implementation(libs.plugins.composeMultiplatform.toDep()) +} + +fun Provider.toDep() = + map { + "${it.pluginId}:${it.pluginId}.gradle.plugin:${it.version}" + } + +tasks { + validatePlugins { + enableStricterValidation = true + failOnWarning = true + } +} + +gradlePlugin { + plugins { + register("kotlinMultiplatform") { + id = "dev.carlosmartino.plugins.kotlinMultiplatform" + implementationClass = "KotlinMultiplatformConventionPlugin" + } + register("composeMultiplatform") { + id = "dev.carlosmartino.plugins.composeMultiplatform" + implementationClass = "ComposeMultiplatformConventionPlugin" + } + } +} diff --git a/buildlogic/convention/src/main/kotlin/ComposeMultiplatformConventionPlugin.kt b/buildlogic/convention/src/main/kotlin/ComposeMultiplatformConventionPlugin.kt new file mode 100644 index 0000000..49bc7b0 --- /dev/null +++ b/buildlogic/convention/src/main/kotlin/ComposeMultiplatformConventionPlugin.kt @@ -0,0 +1,36 @@ +import dev.carlosmartino.plugins.libs +import org.gradle.api.Plugin +import org.gradle.api.Project +import org.gradle.kotlin.dsl.configure +import org.gradle.kotlin.dsl.getByType +import org.jetbrains.compose.ComposeExtension +import org.jetbrains.kotlin.gradle.dsl.KotlinMultiplatformExtension + +class ComposeMultiplatformConventionPlugin : Plugin { + override fun apply(target: Project) = + with(target) { + with(pluginManager) { + apply(libs.findPlugin("compose.plugin").get().get().pluginId) + apply(libs.findPlugin("compose.multiplatform").get().get().pluginId) + } + + val composeDeps = extensions.getByType().dependencies + + extensions.configure { + sourceSets.apply { + commonMain { + dependencies { + implementation(composeDeps.runtime) + implementation(composeDeps.foundation) + implementation(composeDeps.material3) + implementation(composeDeps.ui) + implementation(composeDeps.uiUtil) + implementation(composeDeps.animation) + implementation(composeDeps.animationGraphics) + implementation(composeDeps.components.resources) + } + } + } + } + } +} diff --git a/buildlogic/convention/src/main/kotlin/KotlinMultiplatformConventionPlugin.kt b/buildlogic/convention/src/main/kotlin/KotlinMultiplatformConventionPlugin.kt new file mode 100644 index 0000000..911053d --- /dev/null +++ b/buildlogic/convention/src/main/kotlin/KotlinMultiplatformConventionPlugin.kt @@ -0,0 +1,40 @@ +import com.android.build.api.dsl.LibraryExtension +import dev.carlosmartino.plugins.configureKotlinAndroid +import dev.carlosmartino.plugins.configureKotlinMultiplatform +import dev.carlosmartino.plugins.libs +import org.gradle.api.Plugin +import org.gradle.api.Project +import org.gradle.kotlin.dsl.configure +import org.jetbrains.kotlin.gradle.dsl.KotlinMultiplatformExtension + +class KotlinMultiplatformConventionPlugin : Plugin { + override fun apply(target: Project) = + with(target) { + with(pluginManager) { + apply( + libs + .findPlugin("android.library") + .get() + .get() + .pluginId, + ) + apply( + libs + .findPlugin("kotlin.multiplatform") + .get() + .get() + .pluginId, + ) + apply( + libs + .findPlugin("kotlin.serialization") + .get() + .get() + .pluginId, + ) + } + + extensions.configure(::configureKotlinMultiplatform) + extensions.configure(::configureKotlinAndroid) + } +} diff --git a/buildlogic/convention/src/main/kotlin/dev/carlosmartino/plugins/KotlinAndroid.kt b/buildlogic/convention/src/main/kotlin/dev/carlosmartino/plugins/KotlinAndroid.kt new file mode 100644 index 0000000..cd118f5 --- /dev/null +++ b/buildlogic/convention/src/main/kotlin/dev/carlosmartino/plugins/KotlinAndroid.kt @@ -0,0 +1,39 @@ +package dev.carlosmartino.plugins + +import com.android.build.api.dsl.LibraryExtension +import org.gradle.api.JavaVersion +import org.gradle.api.Project +import org.gradle.kotlin.dsl.get + +internal fun Project.configureKotlinAndroid( + extension: LibraryExtension, +) = extension.apply { + val moduleName = path.split(":").drop(2).joinToString(".") + namespace = if (moduleName.isNotEmpty()) "dev.carlosmartino.platform.$moduleName" else "dev.carlosmartino.platform" + + compileSdk = libs + .findVersion("android.compileSdk") + .get() + .requiredVersion + .toInt() + defaultConfig { + minSdk = libs + .findVersion("android.minSdk") + .get() + .requiredVersion + .toInt() + consumerProguardFiles("consumer-proguard-rules.pro") + } + + sourceSets["main"].resources.srcDirs("src/commonMain/composeResources") + + compileOptions { + sourceCompatibility = JavaVersion.VERSION_17 + targetCompatibility = JavaVersion.VERSION_17 + } + packaging { + resources { + excludes += "/META-INF/{AL2.0,LGPL2.1}" + } + } +} diff --git a/buildlogic/convention/src/main/kotlin/dev/carlosmartino/plugins/KotlinMultiplatform.kt b/buildlogic/convention/src/main/kotlin/dev/carlosmartino/plugins/KotlinMultiplatform.kt new file mode 100644 index 0000000..ba71da1 --- /dev/null +++ b/buildlogic/convention/src/main/kotlin/dev/carlosmartino/plugins/KotlinMultiplatform.kt @@ -0,0 +1,39 @@ +package dev.carlosmartino.plugins + +import org.gradle.api.Project +import org.jetbrains.kotlin.gradle.ExperimentalWasmDsl +import org.jetbrains.kotlin.gradle.dsl.JvmTarget +import org.jetbrains.kotlin.gradle.dsl.KotlinMultiplatformExtension + +@OptIn(ExperimentalWasmDsl::class) +internal fun Project.configureKotlinMultiplatform( + extension: KotlinMultiplatformExtension, +) = extension.apply { + applyDefaultHierarchyTemplate() + + jvmToolchain(17) + + androidTarget { + compilerOptions { + jvmTarget.set(JvmTarget.JVM_17) + } + } + + listOf(iosArm64(), iosSimulatorArm64()) + + sourceSets.apply { + commonMain { + dependencies { + implementation(libs.findLibrary("kotlinx.coroutines.core").get()) + api(libs.findLibrary("koin.core").get()) + } + + androidMain { + dependencies { + implementation(libs.findLibrary("koin.android").get()) + implementation(libs.findLibrary("kotlinx.coroutines.android").get()) + } + } + } + } +} diff --git a/buildlogic/convention/src/main/kotlin/dev/carlosmartino/plugins/ProjectExtensions.kt b/buildlogic/convention/src/main/kotlin/dev/carlosmartino/plugins/ProjectExtensions.kt new file mode 100644 index 0000000..2ee7183 --- /dev/null +++ b/buildlogic/convention/src/main/kotlin/dev/carlosmartino/plugins/ProjectExtensions.kt @@ -0,0 +1,9 @@ +package dev.carlosmartino.plugins + +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/buildlogic/gradle.properties b/buildlogic/gradle.properties new file mode 100644 index 0000000..1c9073e --- /dev/null +++ b/buildlogic/gradle.properties @@ -0,0 +1,4 @@ +# Gradle properties are not passed to included builds https://github.com/gradle/gradle/issues/2534 +org.gradle.parallel=true +org.gradle.caching=true +org.gradle.configureondemand=true diff --git a/buildlogic/settings.gradle.kts b/buildlogic/settings.gradle.kts new file mode 100644 index 0000000..8eedcd9 --- /dev/null +++ b/buildlogic/settings.gradle.kts @@ -0,0 +1,14 @@ +dependencyResolutionManagement { + repositories { + google() + mavenCentral() + } + versionCatalogs { + create("libs") { + from(files("../gradle/libs.versions.toml")) + } + } +} + +rootProject.name = "buildlogic" +include(":convention") diff --git a/gradle/libs.versions.toml b/gradle/libs.versions.toml index a4c8e6b..e1b2c0c 100644 --- a/gradle/libs.versions.toml +++ b/gradle/libs.versions.toml @@ -1,17 +1,17 @@ [versions] -agp = "8.10.1" +agp = "8.13.0" android-compileSdk = "36" android-minSdk = "24" android-targetSdk = "36" -androidx-activity = "1.10.1" +androidx-activity = "1.11.0" androidx-appcompat = "1.7.1" androidx-core = "1.17.0" androidx-espresso = "3.7.0" -androidx-lifecycle = "2.9.3" +androidx-lifecycle = "2.9.4" androidx-testExt = "1.3.0" -composeMultiplatform = "1.8.2" +compose-multiplatform = "1.9.0" junit = "4.13.2" -kotlin = "2.2.10" +kotlin = "2.2.20" [libraries] kotlin-test = { module = "org.jetbrains.kotlin:kotlin-test", version.ref = "kotlin" } @@ -29,11 +29,11 @@ androidx-lifecycle-runtimeCompose = { module = "org.jetbrains.androidx.lifecycle androidApplication = { id = "com.android.application", version.ref = "agp" } androidLibrary = { id = "com.android.library", version.ref = "agp" } androidMultiplatform = { id = "com.android.kotlin.multiplatform.library", version.ref = "agp" } -composeMultiplatform = { id = "org.jetbrains.compose", version.ref = "composeMultiplatform" } +composeMultiplatform = { id = "org.jetbrains.compose", version.ref = "compose-multiplatform" } composeCompiler = { id = "org.jetbrains.kotlin.plugin.compose", version.ref = "kotlin" } kotlinMultiplatform = { id = "org.jetbrains.kotlin.multiplatform", version.ref = "kotlin" } kotlinAndroid = { id = "org.jetbrains.kotlin.android", version.ref = "kotlin" } kotlinSerialization = { id = "org.jetbrains.kotlin.plugin.serialization", version.ref = "kotlin" } - -composeMultiplatformKit = { id = "dev.carlosmartino.plugins.composeMultiplatform", version = "unspecified" } -kotlinMultiplatformKit = { id = "dev.carlosmartino.plugins.kotlinMultiplatform", version = "unspecified" } \ No newline at end of file +# Buildlogic defined plugins -> buildlogic/convention/build.gradle.kts +composeKit = { id = "dev.carlosmartino.plugins.composeMultiplatform", version = "unspecified" } +kotlinKit = { id = "dev.carlosmartino.plugins.kotlinMultiplatform", version = "unspecified" } \ No newline at end of file diff --git a/settings.gradle.kts b/settings.gradle.kts index 962482b..ea85b4e 100644 --- a/settings.gradle.kts +++ b/settings.gradle.kts @@ -2,6 +2,7 @@ rootProject.name = "Template" enableFeaturePreview("TYPESAFE_PROJECT_ACCESSORS") pluginManagement { + includeBuild("buildlogic") repositories { google { mavenContent {