diff --git a/build-logic/convention/build.gradle.kts b/build-logic/convention/build.gradle.kts new file mode 100644 index 0000000..dc20cca --- /dev/null +++ b/build-logic/convention/build.gradle.kts @@ -0,0 +1,59 @@ +import org.jetbrains.kotlin.gradle.dsl.JvmTarget + +plugins { + `kotlin-dsl` +} + +group = "com.peto.droidmorning.buildlogic" + +val javaVersion = JavaVersion.toVersion(libs.versions.java.get()) + +java { + sourceCompatibility = javaVersion + targetCompatibility = javaVersion +} + +kotlin { + compilerOptions { + jvmTarget = JvmTarget.fromTarget(libs.versions.java.get()) + } +} + +dependencies { + compileOnly(libs.android.gradle.plugin) + compileOnly(libs.kotlin.gradle.plugin) + compileOnly(libs.compose.gradle.plugin) +} + +gradlePlugin { + plugins { + register("kmpPrimitive") { + id = "droidmorning.kmp" + implementationClass = "com.peto.droidmorning.KotlinMultiPlatformPlugin" + } + register("kmpAndroid") { + id = "droidmorning.kmp.android" + implementationClass = "com.peto.droidmorning.KotlinMultiPlatformAndroidPlugin" + } + register("kmpIos") { + id = "droidmorning.kmp.ios" + implementationClass = "com.peto.droidmorning.KotlinMultiPlatformiOSPlugin" + } + register("androidLibrary") { + id = "droidmorning.android.library" + implementationClass = "com.peto.droidmorning.AndroidLibraryConventionPlugin" + } + register("kotlinMultiplatform") { + id = "droidmorning.kotlin.multiplatform" + implementationClass = "com.peto.droidmorning.KotlinMultiplatformConventionPlugin" + } + register("composeMultiplatform") { + id = "droidmorning.compose.multiplatform" + implementationClass = "com.peto.droidmorning.ComposeMultiplatformConventionPlugin" + } + register("droidmorningFeature") { + id = "droidmorning.feature" + implementationClass = "com.peto.droidmorning.DroidMorningFeaturePlugin" + } + } +} diff --git a/build-logic/convention/src/main/kotlin/com/peto/droidmorning/AndroidLibraryConventionPlugin.kt b/build-logic/convention/src/main/kotlin/com/peto/droidmorning/AndroidLibraryConventionPlugin.kt new file mode 100644 index 0000000..bf3c3d4 --- /dev/null +++ b/build-logic/convention/src/main/kotlin/com/peto/droidmorning/AndroidLibraryConventionPlugin.kt @@ -0,0 +1,37 @@ +package com.peto.droidmorning + +import com.android.build.gradle.LibraryExtension +import com.peto.droidmorning.extentions.javaVersion +import com.peto.droidmorning.extentions.libs +import com.peto.droidmorning.extentions.plugin +import com.peto.droidmorning.extentions.version +import org.gradle.api.Plugin +import org.gradle.api.Project +import org.gradle.kotlin.dsl.configure + +class AndroidLibraryConventionPlugin : Plugin { + override fun apply(target: Project) { + with(target) { + with(pluginManager) { + apply(libs.plugin("android-library").pluginId) + } + + extensions.configure { + compileSdk = libs.version("compileSdk").toInt() + + defaultConfig { + minSdk = libs.version("minSdk").toInt() + } + + compileOptions { + sourceCompatibility = libs.javaVersion("java") + targetCompatibility = libs.javaVersion("java") + } + + buildFeatures { + buildConfig = true + } + } + } + } +} diff --git a/build-logic/convention/src/main/kotlin/com/peto/droidmorning/ComposeMultiplatformConventionPlugin.kt b/build-logic/convention/src/main/kotlin/com/peto/droidmorning/ComposeMultiplatformConventionPlugin.kt new file mode 100644 index 0000000..54b8ecd --- /dev/null +++ b/build-logic/convention/src/main/kotlin/com/peto/droidmorning/ComposeMultiplatformConventionPlugin.kt @@ -0,0 +1,18 @@ +package com.peto.droidmorning + +import com.peto.droidmorning.extentions.composeMultiplatformDependencies +import com.peto.droidmorning.extentions.libs +import com.peto.droidmorning.extentions.plugin +import org.gradle.api.Plugin +import org.gradle.api.Project + +class ComposeMultiplatformConventionPlugin : Plugin { + override fun apply(target: Project) = with(target) { + with(pluginManager) { + apply(libs.plugin("compose-multiplatform").pluginId) + apply(libs.plugin("kotlin-compose").pluginId) + } + + composeMultiplatformDependencies() + } +} diff --git a/build-logic/convention/src/main/kotlin/com/peto/droidmorning/DroidMorningFeaturePlugin.kt b/build-logic/convention/src/main/kotlin/com/peto/droidmorning/DroidMorningFeaturePlugin.kt new file mode 100644 index 0000000..c509129 --- /dev/null +++ b/build-logic/convention/src/main/kotlin/com/peto/droidmorning/DroidMorningFeaturePlugin.kt @@ -0,0 +1,53 @@ +package com.peto.droidmorning + +import com.peto.droidmorning.extentions.bundle +import com.peto.droidmorning.extentions.composeMultiplatformDependencies +import com.peto.droidmorning.extentions.library +import com.peto.droidmorning.extentions.libs +import com.peto.droidmorning.extentions.plugin +import org.gradle.api.Plugin +import org.gradle.api.Project +import org.gradle.kotlin.dsl.apply +import org.gradle.kotlin.dsl.configure +import org.jetbrains.kotlin.gradle.dsl.KotlinMultiplatformExtension + +class DroidMorningFeaturePlugin : Plugin { + override fun apply(target: Project) = with(target) { + with(pluginManager) { + apply(libs.plugin("android-library").pluginId) + apply(libs.plugin("kotlin-serialization").pluginId) + } + + apply() + apply() + apply() + + apply() + + extensions.configure { + sourceSets.apply { + commonMain { + dependencies { + implementation(libs.library("androidx-navigation-compose")) + implementation(libs.library("androidx-lifecycle-viewmodel-compose")) + implementation(libs.library("androidx-lifecycle-runtime-compose")) + + implementation(libs.bundle("koin")) + + implementation(libs.library("kotlinx-coroutines-core")) + implementation(libs.library("kotlinx-serialization-json")) + implementation(libs.library("kotlinx-collections-immutable")) + implementation(libs.library("napier")) + } + } + commonTest { + dependencies { + implementation(libs.library("kotlin-test")) + implementation(libs.library("koin-test")) + implementation(libs.library("kotlinx-coroutines-test")) + } + } + } + } + } +} diff --git a/build-logic/convention/src/main/kotlin/com/peto/droidmorning/KotlinMultiPlatformAndroidPlugin.kt b/build-logic/convention/src/main/kotlin/com/peto/droidmorning/KotlinMultiPlatformAndroidPlugin.kt new file mode 100644 index 0000000..a271d2c --- /dev/null +++ b/build-logic/convention/src/main/kotlin/com/peto/droidmorning/KotlinMultiPlatformAndroidPlugin.kt @@ -0,0 +1,53 @@ +package com.peto.droidmorning + +import com.peto.droidmorning.extentions.androidExtension +import com.peto.droidmorning.extentions.javaVersion +import com.peto.droidmorning.extentions.jvmTarget +import com.peto.droidmorning.extentions.libs +import com.peto.droidmorning.extentions.version +import org.gradle.api.Plugin +import org.gradle.api.Project +import org.gradle.kotlin.dsl.configure +import org.jetbrains.kotlin.gradle.dsl.KotlinMultiplatformExtension + +class KotlinMultiPlatformAndroidPlugin : Plugin { + override fun apply(target: Project): Unit = with(target) { + androidExtension.apply { + compileSdk = libs.version("compileSdk").toInt() + + extensions.configure { + androidTarget { + compilerOptions.jvmTarget.set(libs.jvmTarget("java")) + } + } + + defaultConfig { + minSdk = libs.version("minSdk").toInt() + } + + compileOptions { + sourceCompatibility = libs.javaVersion("java") + targetCompatibility = libs.javaVersion("java") + } + + packaging { + resources { + excludes += "/META-INF/{AL2.0,LGPL2.1}" + } + } + + sourceSets { + getByName("main") { + assets.srcDirs("src/androidMain/assets") + java.srcDirs("src/androidMain/kotlin") + res.srcDirs("src/androidMain/res") + } + getByName("test") { + assets.srcDirs("src/androidUnitTest/assets") + java.srcDirs("src/androidUnitTest/kotlin") + res.srcDirs("src/androidUnitTest/res") + } + } + } + } +} diff --git a/build-logic/convention/src/main/kotlin/com/peto/droidmorning/KotlinMultiPlatformPlugin.kt b/build-logic/convention/src/main/kotlin/com/peto/droidmorning/KotlinMultiPlatformPlugin.kt new file mode 100644 index 0000000..32d3ff3 --- /dev/null +++ b/build-logic/convention/src/main/kotlin/com/peto/droidmorning/KotlinMultiPlatformPlugin.kt @@ -0,0 +1,33 @@ +package com.peto.droidmorning + +import com.peto.droidmorning.extentions.jvmTarget +import com.peto.droidmorning.extentions.libs +import org.gradle.api.Plugin +import org.gradle.api.Project +import org.gradle.kotlin.dsl.configure +import org.gradle.kotlin.dsl.withType +import org.jetbrains.kotlin.gradle.dsl.KotlinMultiplatformExtension +import org.jetbrains.kotlin.gradle.tasks.KotlinCompile +import org.jetbrains.kotlin.gradle.tasks.KotlinNativeLink + +class KotlinMultiPlatformPlugin : Plugin { + override fun apply(target: Project) = with(target) { + extensions.configure { + compilerOptions { + freeCompilerArgs.add("-Xexpect-actual-classes") + } + + applyDefaultHierarchyTemplate() + } + + tasks.withType().configureEach { + compilerOptions { + jvmTarget.set(libs.jvmTarget("java")) + } + } + + tasks.withType().configureEach { + notCompatibleWithConfigurationCache("Configuration cache not supported for a system property read at configuration time") + } + } +} diff --git a/build-logic/convention/src/main/kotlin/com/peto/droidmorning/KotlinMultiPlatformiOSPlugin.kt b/build-logic/convention/src/main/kotlin/com/peto/droidmorning/KotlinMultiPlatformiOSPlugin.kt new file mode 100644 index 0000000..4925d23 --- /dev/null +++ b/build-logic/convention/src/main/kotlin/com/peto/droidmorning/KotlinMultiPlatformiOSPlugin.kt @@ -0,0 +1,29 @@ +package com.peto.droidmorning + +import org.gradle.api.Plugin +import org.gradle.api.Project +import org.gradle.kotlin.dsl.configure +import org.gradle.kotlin.dsl.get +import org.gradle.kotlin.dsl.withType +import org.jetbrains.kotlin.gradle.dsl.KotlinMultiplatformExtension +import org.jetbrains.kotlin.gradle.plugin.mpp.KotlinNativeTarget + +class KotlinMultiPlatformiOSPlugin : Plugin { + override fun apply(target: Project) = with(target) { + extensions.configure { + iosArm64() + iosX64() + iosSimulatorArm64() + + targets.withType { + compilations["main"].compilerOptions.configure { + freeCompilerArgs.add("-Xexport-kdoc") + } + binaries.framework { + baseName = project.name + isStatic = true + } + } + } + } +} diff --git a/build-logic/convention/src/main/kotlin/com/peto/droidmorning/KotlinMultiplatformConventionPlugin.kt b/build-logic/convention/src/main/kotlin/com/peto/droidmorning/KotlinMultiplatformConventionPlugin.kt new file mode 100644 index 0000000..b38f1e5 --- /dev/null +++ b/build-logic/convention/src/main/kotlin/com/peto/droidmorning/KotlinMultiplatformConventionPlugin.kt @@ -0,0 +1,17 @@ +package com.peto.droidmorning + +import org.gradle.api.Plugin +import org.gradle.api.Project +import org.gradle.kotlin.dsl.apply + +class KotlinMultiplatformConventionPlugin : Plugin { + override fun apply(target: Project) = with(target) { + with(pluginManager) { + apply("org.jetbrains.kotlin.multiplatform") + } + + apply() + apply() + apply() + } +} diff --git a/build-logic/convention/src/main/kotlin/com/peto/droidmorning/extentions/ProjectExtensions.kt b/build-logic/convention/src/main/kotlin/com/peto/droidmorning/extentions/ProjectExtensions.kt new file mode 100644 index 0000000..a11adea --- /dev/null +++ b/build-logic/convention/src/main/kotlin/com/peto/droidmorning/extentions/ProjectExtensions.kt @@ -0,0 +1,35 @@ +package com.peto.droidmorning.extentions + +import com.android.build.api.dsl.ApplicationExtension +import com.android.build.api.dsl.CommonExtension +import com.android.build.api.dsl.LibraryExtension +import org.gradle.api.Project +import org.gradle.api.artifacts.VersionCatalog +import org.gradle.api.artifacts.VersionCatalogsExtension +import org.gradle.kotlin.dsl.configure +import org.gradle.kotlin.dsl.getByType +import org.jetbrains.kotlin.gradle.dsl.KotlinMultiplatformExtension + +internal val Project.libs: VersionCatalog + get() = extensions.getByType().named("libs") + +internal val Project.androidExtension: CommonExtension<*, *, *, *, *, *> + get() = extensions.findByType(LibraryExtension::class.java) + ?: extensions.findByType(ApplicationExtension::class.java) + ?: error("Could not find Library or Application extension from this project") + +internal fun Project.composeMultiplatformDependencies() { + extensions.configure { + sourceSets.apply { + commonMain { + dependencies { + implementation(libs.bundle("compose-multiplatform")) + } + } + } + } + + configurations.findByName("debugImplementation")?.let { cfg -> + dependencies.add(cfg.name, libs.library("compose-ui-tooling")) + } +} diff --git a/build-logic/convention/src/main/kotlin/com/peto/droidmorning/extentions/VersionCatalogExtensions.kt b/build-logic/convention/src/main/kotlin/com/peto/droidmorning/extentions/VersionCatalogExtensions.kt new file mode 100644 index 0000000..45ba9ee --- /dev/null +++ b/build-logic/convention/src/main/kotlin/com/peto/droidmorning/extentions/VersionCatalogExtensions.kt @@ -0,0 +1,32 @@ +package com.peto.droidmorning.extentions + +import org.gradle.api.JavaVersion +import org.gradle.api.artifacts.ExternalModuleDependencyBundle +import org.gradle.api.artifacts.MinimalExternalModuleDependency +import org.gradle.api.artifacts.VersionCatalog +import org.gradle.plugin.use.PluginDependency +import org.jetbrains.kotlin.gradle.dsl.JvmTarget + +internal fun VersionCatalog.version(name: String): String { + return findVersion(name).get().requiredVersion +} + +internal fun VersionCatalog.library(name: String): MinimalExternalModuleDependency { + return findLibrary(name).get().get() +} + +internal fun VersionCatalog.plugin(name: String): PluginDependency { + return findPlugin(name).get().get() +} + +internal fun VersionCatalog.bundle(name: String): ExternalModuleDependencyBundle { + return findBundle(name).get().get() +} + +internal fun VersionCatalog.javaVersion(name: String): JavaVersion { + return JavaVersion.toVersion(version(name)) +} + +internal fun VersionCatalog.jvmTarget(name: String): JvmTarget { + return JvmTarget.fromTarget(version(name)) +} diff --git a/build-logic/settings.gradle.kts b/build-logic/settings.gradle.kts new file mode 100644 index 0000000..2bbf977 --- /dev/null +++ b/build-logic/settings.gradle.kts @@ -0,0 +1,16 @@ +dependencyResolutionManagement { + repositories { + google() + mavenCentral() + gradlePluginPortal() + } + versionCatalogs { + create("libs") { + from(files("../gradle/libs.versions.toml")) + } + } +} + +rootProject.name = "build-logic" + +include(":convention") diff --git a/gradle.properties b/gradle.properties index b7762d3..bf52f7e 100644 --- a/gradle.properties +++ b/gradle.properties @@ -3,9 +3,10 @@ kotlin.code.style=official kotlin.daemon.jvmargs=-Xmx3072M #Gradle -org.gradle.jvmargs=-Xmx4096M -Dfile.encoding=UTF-8 +org.gradle.jvmargs=-Xmx8g -XX:MaxMetaspaceSize=2g -XX:+HeapDumpOnOutOfMemoryError -Dfile.encoding=UTF-8 org.gradle.configuration-cache=true org.gradle.caching=true +org.gradle.parallel=true #Android android.nonTransitiveRClass=true diff --git a/gradle/libs.versions.toml b/gradle/libs.versions.toml index e2b5a0d..0bc1533 100644 --- a/gradle/libs.versions.toml +++ b/gradle/libs.versions.toml @@ -64,7 +64,7 @@ androidx-espresso = "3.7.0" # Gradle Plugins android-gradle-plugin = { group = "com.android.tools.build", name = "gradle", version.ref = "agp" } kotlin-gradle-plugin = { group = "org.jetbrains.kotlin", name = "kotlin-gradle-plugin", version.ref = "kotlin" } -compose-gradle-plugin = { module = "org.jetbrains.kotlin:compose-compiler-gradle-plugin", version.ref = "kotlin" } +compose-gradle-plugin = { group = "org.jetbrains.compose", name = "compose-gradle-plugin", version.ref = "compose-multiplatform" } # AndroidX androidx-core-ktx = { module = "androidx.core:core-ktx", version.ref = "androidx-core-ktx" } @@ -226,3 +226,12 @@ buildkonfig = { id = "com.codingfeline.buildkonfig", version.ref = "buildkonfig" # Ktlint ktlint = { id = "org.jlleitschuh.gradle.ktlint", version.ref = "ktlint" } + +# DroidMorning Convention Plugins +droidmorning-kmp = { id = "droidmorning.kmp" } +droidmorning-kmp-android = { id = "droidmorning.kmp.android" } +droidmorning-kmp-ios = { id = "droidmorning.kmp.ios" } +droidmorning-android-library = { id = "droidmorning.android.library" } +droidmorning-kotlin-multiplatform = { id = "droidmorning.kotlin.multiplatform" } +droidmorning-compose-multiplatform = { id = "droidmorning.compose.multiplatform" } +droidmorning-feature = { id = "droidmorning.feature" } diff --git a/settings.gradle.kts b/settings.gradle.kts index 23f4b35..1522ace 100644 --- a/settings.gradle.kts +++ b/settings.gradle.kts @@ -2,6 +2,7 @@ rootProject.name = "DroidMorning" enableFeaturePreview("TYPESAFE_PROJECT_ACCESSORS") pluginManagement { + includeBuild("build-logic") repositories { google { mavenContent {