diff --git a/Agents.md b/Agents.md index b73c8a9f..19454032 100644 --- a/Agents.md +++ b/Agents.md @@ -61,7 +61,7 @@ Both library modules target: - **Android** (`androidMain`) - **JVM** (`jvmMain`) -- **iOS** (`iosX64`, `iosArm64`, `iosSimulatorArm64`) +- **iOS** (`iosArm64`, `iosSimulatorArm64`) ## Workflow @@ -313,8 +313,8 @@ targets. The compiler reports `Unresolved reference 'SYSTEM'` during iOS publica **Workaround:** Use the `expect`/`actual` pattern. Declare an `internal expect val` in `commonMain` and provide `actual` implementations in each platform source set (`androidMain`, `jvmMain`, -`iosMain`) that return `FileSystem.SYSTEM`. The `iosMain` source set covers all three iOS targets -(`iosX64`, `iosArm64`, `iosSimulatorArm64`) via `applyDefaultHierarchyTemplate()`. +`iosMain`) that return `FileSystem.SYSTEM`. The `iosMain` source set covers all two iOS targets +(`iosArm64`, `iosSimulatorArm64`) via `applyDefaultHierarchyTemplate()`. Files involved: diff --git a/README.md b/README.md index c7f79f3d..7afd04bc 100644 --- a/README.md +++ b/README.md @@ -20,7 +20,7 @@ SharedPreferences. ### KMP Targets -Both modules target **Android**, **Desktop (JVM)**, and **iOS** (`iosX64`, `iosArm64`, +Both modules target **Android**, **Desktop (JVM)**, and **iOS** (`iosArm64`, `iosSimulatorArm64`). ## Installation diff --git a/build-logic/convention/build.gradle.kts b/build-logic/convention/build.gradle.kts new file mode 100644 index 00000000..39879de4 --- /dev/null +++ b/build-logic/convention/build.gradle.kts @@ -0,0 +1,44 @@ +plugins { + `kotlin-dsl` +} + +dependencies { + compileOnly(libs.android.gradle.plugin) + compileOnly(libs.kotlin.gradle.plugin) + implementation(libs.spotless.gradle.plugin) + compileOnly(libs.compose.gradle.plugin) + compileOnly(libs.vanniktech.maven.publish.plugin) +} + +gradlePlugin { + plugins { + register("spotless") { + id = "gd.spotless" + implementationClass = "SpotlessConventionPlugin" + } + register("kmpLibrary") { + id = "gd.kmp.library" + implementationClass = "KmpLibraryConventionPlugin" + } + register("kmpLibraryTest") { + id = "gd.kmp.library.test" + implementationClass = "KmpLibraryTestConventionPlugin" + } + register("mavenPublish") { + id = "gd.maven.publish" + implementationClass = "MavenPublishConventionPlugin" + } + register("compose") { + id = "gd.compose" + implementationClass = "ComposeConventionPlugin" + } + register("kmpSample") { + id = "gd.kmp.sample" + implementationClass = "KmpSampleConventionPlugin" + } + register("androidSampleApp") { + id = "gd.android.sample" + implementationClass = "AndroidSampleAppConventionPlugin" + } + } +} diff --git a/build-logic/convention/src/main/kotlin/AndroidSampleAppConventionPlugin.kt b/build-logic/convention/src/main/kotlin/AndroidSampleAppConventionPlugin.kt new file mode 100644 index 00000000..6d25b61d --- /dev/null +++ b/build-logic/convention/src/main/kotlin/AndroidSampleAppConventionPlugin.kt @@ -0,0 +1,39 @@ +import com.android.build.api.dsl.ApplicationExtension +import gd.buildlogic.configureAndroid +import gd.buildlogic.configureCommonKotlinCompileOptions +import org.gradle.api.Plugin +import org.gradle.api.Project +import org.gradle.kotlin.dsl.configure + +@Suppress("unused") +class AndroidSampleAppConventionPlugin : Plugin { + override fun apply(target: Project) { + with(target) { + with(pluginManager) { + apply("com.android.application") + apply("gd.compose") + apply("gd.spotless") + } + + extensions.configure { + configureAndroid(this) + + defaultConfig { + testInstrumentationRunner = "androidx.test.runner.AndroidJUnitRunner" + } + + buildFeatures { + compose = true + } + + packaging { + resources { + excludes += "/META-INF/{AL2.0,LGPL2.1}" + } + } + } + + configureCommonKotlinCompileOptions() + } + } +} diff --git a/build-logic/convention/src/main/kotlin/ComposeConventionPlugin.kt b/build-logic/convention/src/main/kotlin/ComposeConventionPlugin.kt new file mode 100644 index 00000000..a2eb8fff --- /dev/null +++ b/build-logic/convention/src/main/kotlin/ComposeConventionPlugin.kt @@ -0,0 +1,16 @@ +import gd.buildlogic.libs +import gd.buildlogic.pluginId +import org.gradle.api.Plugin +import org.gradle.api.Project + +@Suppress("unused") +class ComposeConventionPlugin : Plugin { + override fun apply(target: Project) { + with(target) { + with(pluginManager) { + apply(libs.pluginId("compose-compiler")) + apply(libs.pluginId("jetbrains-compose")) + } + } + } +} diff --git a/build-logic/convention/src/main/kotlin/KmpLibraryConventionPlugin.kt b/build-logic/convention/src/main/kotlin/KmpLibraryConventionPlugin.kt new file mode 100644 index 00000000..186fe110 --- /dev/null +++ b/build-logic/convention/src/main/kotlin/KmpLibraryConventionPlugin.kt @@ -0,0 +1,50 @@ +import com.android.build.api.dsl.KotlinMultiplatformAndroidLibraryTarget +import gd.buildlogic.AndroidConfig +import gd.buildlogic.configureCommonKotlinCompileOptions +import gd.buildlogic.configureKmpLibrary +import gd.buildlogic.libs +import gd.buildlogic.pluginId +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 + +@Suppress("unused") +class KmpLibraryConventionPlugin : Plugin { + override fun apply(target: Project) { + with(target) { + configureCommonKotlinCompileOptions() + + with(pluginManager) { + apply(libs.pluginId("kotlin-multiplatform")) + apply(libs.pluginId("android-library")) + apply("gd.spotless") + } + + extensions.configure { + configureKmpLibrary() + explicitApi() + + applyDefaultHierarchyTemplate() + + targets.withType().configureEach { + compileSdk = AndroidConfig.COMPILE_SDK + minSdk = AndroidConfig.MIN_SDK + } + + iosArm64() + iosSimulatorArm64() + + jvm() + + compilerOptions { + freeCompilerArgs.addAll( + "-opt-in=kotlinx.coroutines.ExperimentalCoroutinesApi", + "-Xexpect-actual-classes", + ) + } + } + } + } +} diff --git a/build-logic/convention/src/main/kotlin/KmpLibraryTestConventionPlugin.kt b/build-logic/convention/src/main/kotlin/KmpLibraryTestConventionPlugin.kt new file mode 100644 index 00000000..1d5fe31c --- /dev/null +++ b/build-logic/convention/src/main/kotlin/KmpLibraryTestConventionPlugin.kt @@ -0,0 +1,55 @@ +import com.android.build.api.dsl.KotlinMultiplatformAndroidLibraryTarget +import gd.buildlogic.library +import gd.buildlogic.libs +import gd.buildlogic.pluginId +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 + +class KmpLibraryTestConventionPlugin : Plugin { + override fun apply(target: Project) { + with(target) { + with(pluginManager) { + apply(libs.pluginId("kotlin-multiplatform")) + apply(libs.pluginId("android-library")) + } + extensions.configure { + applyDefaultHierarchyTemplate() + + targets.withType().configureEach { + withDeviceTestBuilder { + sourceSetTreeName = "test" + }.configure { + instrumentationRunner = "androidx.test.runner.AndroidJUnitRunner" + } + } + + jvm() + + sourceSets.apply { + commonTest.dependencies { + implementation(libs.library("kotlin-test")) + implementation(libs.library("coroutines-test")) + } + + getByName("androidDeviceTest") { + dependencies { + implementation(libs.library("kotlin-test")) + implementation(libs.library("coroutines-test")) + implementation(libs.library("datastore-preferences")) + implementation(libs.library("junit4")) + implementation(libs.library("androidx-test-junit")) + implementation(libs.library("androidx-test-espresso")) + } + } + + jvmTest.dependencies { + implementation(libs.library("junit5")) + } + } + } + } + } +} diff --git a/build-logic/convention/src/main/kotlin/KmpSampleConventionPlugin.kt b/build-logic/convention/src/main/kotlin/KmpSampleConventionPlugin.kt new file mode 100644 index 00000000..ca9f0ea8 --- /dev/null +++ b/build-logic/convention/src/main/kotlin/KmpSampleConventionPlugin.kt @@ -0,0 +1,95 @@ +import com.android.build.api.dsl.KotlinMultiplatformAndroidLibraryTarget +import gd.buildlogic.AndroidConfig +import gd.buildlogic.configureCommonKotlinCompileOptions +import gd.buildlogic.configureKmpLibrary +import gd.buildlogic.library +import gd.buildlogic.libs +import gd.buildlogic.pluginId +import org.gradle.api.Plugin +import org.gradle.api.Project +import org.gradle.api.file.DuplicatesStrategy +import org.gradle.api.tasks.testing.Test +import org.gradle.jvm.tasks.Jar +import org.gradle.kotlin.dsl.configure +import org.gradle.kotlin.dsl.withType +import org.jetbrains.compose.ComposeExtension +import org.jetbrains.compose.ComposePlugin +import org.jetbrains.compose.desktop.DesktopExtension +import org.jetbrains.compose.desktop.application.dsl.TargetFormat +import org.jetbrains.kotlin.gradle.dsl.KotlinMultiplatformExtension + +@Suppress("unused") +class KmpSampleConventionPlugin : Plugin { + override fun apply(target: Project) { + with(target) { + configureCommonKotlinCompileOptions() + + with(pluginManager) { + apply(libs.pluginId("kotlin-multiplatform")) + apply(libs.pluginId("android-library")) + apply(libs.pluginId("kotlin-serialization")) + apply("gd.compose") + apply("gd.spotless") + } + + extensions.configure { + configureKmpLibrary() + + applyDefaultHierarchyTemplate() + + targets.withType().configureEach { + compileSdk = AndroidConfig.COMPILE_SDK + minSdk = AndroidConfig.MIN_SDK + } + + jvm("desktop") + + compilerOptions { + freeCompilerArgs.add("-Xexpect-actual-classes") + } + + sourceSets.named("desktopMain") { + dependencies { + implementation(libs.library("coroutines-swing")) + @Suppress("DEPRECATION") + implementation(ComposePlugin.DesktopDependencies.currentOs) + } + } + } + + extensions.configure { + extensions.configure { + application { + buildTypes { + release { + proguard { + configurationFiles.from(project.file("proguard-rules.pro")) + } + } + } + + nativeDistributions { + modules("jdk.unsupported") + targetFormats(TargetFormat.Dmg, TargetFormat.Msi, TargetFormat.Deb) + packageVersion = "1.0.0" + } + } + } + } + + configureCommonKotlinCompileOptions() + + tasks.withType().configureEach { + useJUnitPlatform() + } + + tasks.withType().configureEach { + duplicatesStrategy = DuplicatesStrategy.EXCLUDE + + exclude("META-INF/AL2.0") + exclude("META-INF/LGPL2.1") + exclude("META-INF/MANIFEST.MF") + } + } + } +} diff --git a/build-logic/convention/src/main/kotlin/MavenPublishConventionPlugin.kt b/build-logic/convention/src/main/kotlin/MavenPublishConventionPlugin.kt new file mode 100644 index 00000000..16e1c419 --- /dev/null +++ b/build-logic/convention/src/main/kotlin/MavenPublishConventionPlugin.kt @@ -0,0 +1,14 @@ +import gd.buildlogic.configureMavenPublish +import org.gradle.api.Plugin +import org.gradle.api.Project + +@Suppress("unused") +class MavenPublishConventionPlugin : Plugin { + override fun apply(target: Project) { + with(target) { + pluginManager.apply("com.vanniktech.maven.publish") + + configureMavenPublish() + } + } +} diff --git a/build-logic/convention/src/main/kotlin/SpotlessConventionPlugin.kt b/build-logic/convention/src/main/kotlin/SpotlessConventionPlugin.kt new file mode 100644 index 00000000..4a916686 --- /dev/null +++ b/build-logic/convention/src/main/kotlin/SpotlessConventionPlugin.kt @@ -0,0 +1,33 @@ +import com.diffplug.gradle.spotless.SpotlessExtension +import gd.buildlogic.libs +import org.gradle.api.Plugin +import org.gradle.api.Project +import org.gradle.kotlin.dsl.configure + +@Suppress("unused") +class SpotlessConventionPlugin : Plugin { + override fun apply(target: Project) { + with(target) { + pluginManager.apply("com.diffplug.spotless") + + extensions.configure { + kotlin { + target("**/*.kt", "**/*.kts") + targetExclude("**/build/**/*.kt") + ktlint( + libs.findLibrary("ktlint-core").get().get().version!!, + ).editorConfigOverride( + mapOf("ktlint_standard_annotation" to "disabled"), + ) + trimTrailingWhitespace() + endWithNewline() + } + format("xml") { + target("**/*.xml") + trimTrailingWhitespace() + endWithNewline() + } + } + } + } +} diff --git a/build-logic/convention/src/main/kotlin/gd/buildlogic/AndroidConfig.kt b/build-logic/convention/src/main/kotlin/gd/buildlogic/AndroidConfig.kt new file mode 100644 index 00000000..7f39be73 --- /dev/null +++ b/build-logic/convention/src/main/kotlin/gd/buildlogic/AndroidConfig.kt @@ -0,0 +1,14 @@ +package gd.buildlogic + +import org.gradle.api.JavaVersion as GradleJavaVersion +import org.jetbrains.kotlin.gradle.dsl.JvmTarget as KotlinJvmTarget + +object AndroidConfig { + const val COMPILE_SDK = 36 + const val TARGET_SDK = 36 + const val MIN_SDK = 24 + + // https://youtrack.jetbrains.com/issue/KT-66995/JvmTarget-and-JavaVersion-compatibility-for-easier-JVM-version-setup + val JavaVersion = GradleJavaVersion.VERSION_17 + val JvmTarget = KotlinJvmTarget.JVM_17 +} diff --git a/build-logic/convention/src/main/kotlin/gd/buildlogic/KmpLibrary.kt b/build-logic/convention/src/main/kotlin/gd/buildlogic/KmpLibrary.kt new file mode 100644 index 00000000..818d4578 --- /dev/null +++ b/build-logic/convention/src/main/kotlin/gd/buildlogic/KmpLibrary.kt @@ -0,0 +1,48 @@ +package gd.buildlogic + +import com.android.build.api.dsl.CommonExtension +import org.gradle.api.Project +import org.gradle.api.tasks.testing.Test +import org.gradle.kotlin.dsl.withType +import org.jetbrains.kotlin.gradle.tasks.KotlinCompile +import org.jetbrains.kotlin.gradle.tasks.KotlinNativeCompile + +internal fun Project.configureAndroid(commonExtension: CommonExtension) { + commonExtension.apply { + compileSdk = AndroidConfig.COMPILE_SDK + + defaultConfig.apply { + minSdk = AndroidConfig.MIN_SDK + } + + compileOptions.apply { + sourceCompatibility = AndroidConfig.JavaVersion + targetCompatibility = AndroidConfig.JavaVersion + } + } +} + +internal fun Project.configureCommonKotlinCompileOptions() { + tasks.withType().configureEach { + compilerOptions { + jvmTarget.set(AndroidConfig.JvmTarget) + freeCompilerArgs.addAll( + "-opt-in=kotlinx.coroutines.ExperimentalCoroutinesApi", + "-opt-in=kotlin.time.ExperimentalTime", + ) + } + } +} + +internal fun Project.configureKmpLibrary() { + + tasks.withType(Test::class.java).configureEach { + useJUnitPlatform() + } + + tasks.withType(KotlinNativeCompile::class.java).configureEach { + compilerOptions { + optIn.add("kotlinx.cinterop.ExperimentalForeignApi") + } + } +} diff --git a/build-logic/convention/src/main/kotlin/gd/buildlogic/Libs.kt b/build-logic/convention/src/main/kotlin/gd/buildlogic/Libs.kt new file mode 100644 index 00000000..57f2b1c8 --- /dev/null +++ b/build-logic/convention/src/main/kotlin/gd/buildlogic/Libs.kt @@ -0,0 +1,20 @@ +package gd.buildlogic + +import org.gradle.api.Project +import org.gradle.api.artifacts.MinimalExternalModuleDependency +import org.gradle.api.artifacts.VersionCatalog +import org.gradle.api.artifacts.VersionCatalogsExtension +import org.gradle.api.provider.Provider +import org.gradle.kotlin.dsl.getByType + +val Project.libs: VersionCatalog + get() = extensions.getByType().named("libs") + +fun VersionCatalog.library(name: String): Provider = + findLibrary(name).get() + +fun VersionCatalog.pluginId(name: String): String = + findPlugin(name).get().get().pluginId + +fun VersionCatalog.version(name: String): String = + findVersion(name).get().requiredVersion diff --git a/build-logic/convention/src/main/kotlin/gd/buildlogic/MavenPublish.kt b/build-logic/convention/src/main/kotlin/gd/buildlogic/MavenPublish.kt new file mode 100644 index 00000000..ce46c70c --- /dev/null +++ b/build-logic/convention/src/main/kotlin/gd/buildlogic/MavenPublish.kt @@ -0,0 +1,49 @@ +package gd.buildlogic + +import com.vanniktech.maven.publish.MavenPublishBaseExtension +import org.gradle.api.Project +import org.gradle.api.publish.PublishingExtension +import org.gradle.kotlin.dsl.configure + +internal fun Project.configureMavenPublish() { + version = providers.environmentVariable("RELEASE_TAG") + .map { it.removePrefix("v") } + .getOrElse("1.0.0") + + extensions.configure { + repositories { + maven { + name = "GitHubPackages" + url = uri("https://maven.pkg.github.com/ArthurKun21/generic-datastore") + credentials { + username = System.getenv("GITHUB_ACTOR") + password = System.getenv("GITHUB_TOKEN") + } + } + } + } + + extensions.configure { + pom { + url.set("https://github.com/ArthurKun21/generic-datastore") + licenses { + license { + name.set("The Apache License, Version 2.0") + url.set("http://www.apache.org/licenses/LICENSE-2.0.txt") + } + } + developers { + developer { + id.set("ArthurKun21") + name.set("Arthur") + email.set("16458204+ArthurKun21@users.noreply.github.com") + } + } + scm { + connection.set("scm:git:git://github.com/ArthurKun21/generic-datastore.git") + developerConnection.set("scm:git:ssh://github.com/ArthurKun21/generic-datastore.git") + url.set("https://github.com/ArthurKun21/generic-datastore") + } + } + } +} diff --git a/build-logic/gradle.properties b/build-logic/gradle.properties new file mode 100644 index 00000000..1c9073eb --- /dev/null +++ b/build-logic/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/build-logic/settings.gradle.kts b/build-logic/settings.gradle.kts new file mode 100644 index 00000000..f4f70e7a --- /dev/null +++ b/build-logic/settings.gradle.kts @@ -0,0 +1,21 @@ +dependencyResolutionManagement { + repositories { + google { + content { + includeGroupByRegex("com\\.android.*") + includeGroupByRegex("com\\.google.*") + includeGroupByRegex("androidx.*") + } + } + mavenCentral() + gradlePluginPortal() + } + versionCatalogs { + create("libs") { + from(files("../gradle/libs.versions.toml")) + } + } +} + +rootProject.name = "build-logic" +include(":convention") diff --git a/build.gradle.kts b/build.gradle.kts index a03c5fc7..1463d510 100644 --- a/build.gradle.kts +++ b/build.gradle.kts @@ -1,64 +1,11 @@ -import org.jetbrains.kotlin.gradle.dsl.JvmTarget -import org.jetbrains.kotlin.gradle.tasks.KotlinCompile - plugins { alias(libs.plugins.agp) apply false alias(libs.plugins.android.library) apply false alias(libs.plugins.compose.compiler) apply false alias(libs.plugins.kotlin.multiplatform) apply false - alias(libs.plugins.spotless) apply false alias(libs.plugins.vanniktech.maven.publish) apply false alias(libs.plugins.jetbrains.compose) apply false alias(libs.plugins.kotlin.serialization) apply false alias(libs.plugins.wire) apply false + alias(libs.plugins.spotless) apply false } - -version = providers.environmentVariable("RELEASE_TAG") - .map { it.removePrefix("v") } - .getOrElse("1.0.0") - -subprojects { - version = rootProject.version - apply(plugin = "com.diffplug.spotless") - - plugins.withId("com.vanniktech.maven.publish") { - configure { - repositories { - maven { - name = "GitHubPackages" - url = uri("https://maven.pkg.github.com/ArthurKun21/generic-datastore") - credentials { - username = System.getenv("GITHUB_ACTOR") - password = System.getenv("GITHUB_TOKEN") - } - } - } - } - } - tasks.withType().configureEach { - compilerOptions { - jvmTarget.set(JvmTarget.JVM_17) - freeCompilerArgs.addAll( - "-opt-in=kotlinx.coroutines.ExperimentalCoroutinesApi", - "-opt-in=kotlin.time.ExperimentalTime", - ) - } - } - configure { - kotlin { - target("**/*.kt", "**/*.kts") - targetExclude("**/build/**/*.kt") - ktlint(libs.ktlint.core.get().version).editorConfigOverride( - mapOf("ktlint_standard_annotation" to "disabled"), - ) - trimTrailingWhitespace() - endWithNewline() - } - format("xml") { - target("**/*.xml") - trimTrailingWhitespace() - endWithNewline() - } - } -} - diff --git a/generic-datastore-compose/build.gradle.kts b/generic-datastore-compose/build.gradle.kts index 4c877141..324ad546 100644 --- a/generic-datastore-compose/build.gradle.kts +++ b/generic-datastore-compose/build.gradle.kts @@ -1,114 +1,41 @@ -import org.jetbrains.kotlin.gradle.tasks.KotlinNativeCompile - plugins { - alias(libs.plugins.kotlin.multiplatform) - alias(libs.plugins.vanniktech.maven.publish) - alias(libs.plugins.android.library) + id("gd.kmp.library") + id("gd.kmp.library.test") + id("gd.maven.publish") alias(libs.plugins.compose.compiler) } kotlin { - explicitApi() - - applyDefaultHierarchyTemplate() - - androidLibrary { + android { namespace = "io.github.arthurkun.generic.datastore.compose" - compileSdk = libs.versions.compile.sdk.get().toInt() - minSdk = libs.versions.min.sdk.get().toInt() + @Suppress("UnstableApiUsage") optimization { consumerKeepRules.file("consumer-rules.pro") } - - withDeviceTestBuilder { - sourceSetTreeName = "test" - }.configure { - instrumentationRunner = "androidx.test.runner.AndroidJUnitRunner" - } - } - - jvm { - testRuns["test"].executionTask.configure { - useJUnitPlatform() - } } - iosX64() - iosArm64() - iosSimulatorArm64() - sourceSets { commonMain.dependencies { - api(project(":generic-datastore")) // Core library dependency + api(project(":generic-datastore")) implementation(libs.compose.runtime) } - commonTest.dependencies { - implementation(libs.kotlin.test) - implementation(libs.coroutines.test) - } - androidMain.dependencies { implementation(libs.lifecycle.runtime.compose) } - - getByName("androidDeviceTest") { - dependencies { - implementation(libs.kotlin.test) - implementation(libs.coroutines.test) - implementation(libs.datastore.preferences) - implementation(libs.junit4) - implementation(libs.androidx.test.junit) - implementation(libs.androidx.test.espresso) - } - } - - named("jvmTest") { - dependencies { - implementation(libs.junit5) - } - } - } - - compilerOptions { - freeCompilerArgs.addAll( - "-opt-in=kotlinx.coroutines.ExperimentalCoroutinesApi", - "-Xexpect-actual-classes", - ) - } -} - -tasks.withType().configureEach { - compilerOptions { - optIn.add("kotlinx.cinterop.ExperimentalForeignApi") } } mavenPublishing { - coordinates("com.github.ArthurKun21", "generic-datastore-compose", version.toString()) + coordinates( + groupId = "com.github.ArthurKun21", + artifactId = "generic-datastore-compose", + version = version.toString(), + ) pom { name.set("Generic Datastore Compose Extensions") description.set("Jetpack Compose extensions for Generic Datastore Library.") - url.set("https://github.com/ArthurKun21/generic-datastore") - licenses { - license { - name.set("The Apache License, Version 2.0") - url.set("http://www.apache.org/licenses/LICENSE-2.0.txt") - } - } - developers { - developer { - id.set("ArthurKun21") - name.set("Arthur") - email.set("16458204+ArthurKun21@users.noreply.github.com") - } - } - scm { - connection.set("scm:git:git://github.com/ArthurKun21/generic-datastore.git") - developerConnection.set("scm:git:ssh://github.com/ArthurKun21/generic-datastore.git") - url.set("https://github.com/ArthurKun21/generic-datastore") - } } } diff --git a/generic-datastore/build.gradle.kts b/generic-datastore/build.gradle.kts index 4b4efcf6..e9134c64 100644 --- a/generic-datastore/build.gradle.kts +++ b/generic-datastore/build.gradle.kts @@ -1,114 +1,42 @@ -import org.jetbrains.kotlin.gradle.tasks.KotlinNativeCompile - plugins { - alias(libs.plugins.kotlin.multiplatform) - alias(libs.plugins.vanniktech.maven.publish) - alias(libs.plugins.android.library) + id("gd.kmp.library") + id("gd.kmp.library.test") + id("gd.maven.publish") alias(libs.plugins.kotlin.serialization) } kotlin { - explicitApi() - - androidLibrary { + android { namespace = "io.github.arthurkun.generic.datastore" - compileSdk = libs.versions.compile.sdk.get().toInt() - minSdk = libs.versions.min.sdk.get().toInt() withJava() + @Suppress("UnstableApiUsage") optimization { consumerKeepRules.file("consumer-rules.pro") } - - withDeviceTestBuilder { - sourceSetTreeName = "test" - }.configure { - instrumentationRunner = "androidx.test.runner.AndroidJUnitRunner" - } } - iosX64() - iosArm64() - iosSimulatorArm64() - - jvm { - testRuns["test"].executionTask.configure { - useJUnitPlatform() - } - } - - applyDefaultHierarchyTemplate() - sourceSets { commonMain.dependencies { implementation(libs.coroutines.core) api(libs.datastore.preferences.core) api(libs.datastore.core) - api(libs.kotlinx.io.core) + implementation(libs.kotlinx.io.core) implementation(libs.kotlinx.serialization.json) } - - commonTest.dependencies { - implementation(libs.kotlin.test) - implementation(libs.coroutines.test) - } - - getByName("androidDeviceTest") { - dependencies { - implementation(libs.kotlin.test) - implementation(libs.coroutines.test) - implementation(libs.datastore.preferences) - implementation(libs.junit4) - implementation(libs.androidx.test.junit) - implementation(libs.androidx.test.espresso) - } - } - named("jvmTest") { - dependencies { - implementation(libs.junit5) - } - } - } - - compilerOptions { - freeCompilerArgs.addAll( - "-opt-in=kotlinx.coroutines.ExperimentalCoroutinesApi", - "-Xexpect-actual-classes", - ) - } -} - -tasks.withType().configureEach { - compilerOptions { - optIn.add("kotlinx.cinterop.ExperimentalForeignApi") } } mavenPublishing { - coordinates("com.github.ArthurKun21", "generic-datastore", version.toString()) + coordinates( + groupId = "com.github.ArthurKun21", + artifactId = "generic-datastore", + version = version.toString(), + ) pom { name.set("Generic Datastore Library") description.set("A generic datastore library for Kotlin Multiplatform.") - url.set("https://github.com/ArthurKun21/generic-datastore") - licenses { - license { - name.set("The Apache License, Version 2.0") - url.set("http://www.apache.org/licenses/LICENSE-2.0.txt") - } - } - developers { - developer { - id.set("ArthurKun21") - name.set("Arthur") - email.set("16458204+ArthurKun21@users.noreply.github.com") - } - } - scm { - connection.set("scm:git:git://github.com/ArthurKun21/generic-datastore.git") - developerConnection.set("scm:git:ssh://github.com/ArthurKun21/generic-datastore.git") - url.set("https://github.com/ArthurKun21/generic-datastore") - } } } diff --git a/gradle/libs.versions.toml b/gradle/libs.versions.toml index a4d834da..43529682 100644 --- a/gradle/libs.versions.toml +++ b/gradle/libs.versions.toml @@ -1,8 +1,4 @@ [versions] -compile-sdk = "36" -target-sdk = "36" -min-sdk = "24" - agp = "9.1.0" kotlin = "2.3.20" @@ -80,6 +76,13 @@ wire-runtime = { module = "com.squareup.wire:wire-runtime", version.ref = "wire" ktlint-core = { module = "com.pinterest.ktlint:ktlint-cli", version.ref = "ktlint-core" } +# Gradle plugin artifacts (for build-logic convention plugins) +android-gradle-plugin = { module = "com.android.tools.build:gradle", version.ref = "agp" } +kotlin-gradle-plugin = { module = "org.jetbrains.kotlin:kotlin-gradle-plugin", version.ref = "kotlin" } +spotless-gradle-plugin = { module = "com.diffplug.spotless:spotless-plugin-gradle", version.ref = "spotless" } +compose-gradle-plugin = { module = "org.jetbrains.compose:compose-gradle-plugin", version.ref = "compose" } +vanniktech-maven-publish-plugin = { module = "com.vanniktech:gradle-maven-publish-plugin", version.ref = "vanniktechMavenPublish" } + [plugins] agp = { id = "com.android.application", version.ref = "agp" } android-library = { id = "com.android.kotlin.multiplatform.library", version.ref = "agp" } diff --git a/samples/preferenceAndroidApp/build.gradle.kts b/samples/preferenceAndroidApp/build.gradle.kts index 761d7430..fbe60e7b 100644 --- a/samples/preferenceAndroidApp/build.gradle.kts +++ b/samples/preferenceAndroidApp/build.gradle.kts @@ -1,23 +1,14 @@ plugins { - id("com.android.application") - alias(libs.plugins.compose.compiler) + id("gd.android.sample") } android { namespace = "io.github.arthurkun.generic.datastore.app" - compileSdk = libs.versions.compile.sdk.get().toInt() defaultConfig { applicationId = "io.github.arthurkun.generic.datastore.app" - minSdk = libs.versions.min.sdk.get().toInt() - targetSdk = libs.versions.target.sdk.get().toInt() versionCode = 1 versionName = "1.0" - - testInstrumentationRunner = "androidx.test.runner.AndroidJUnitRunner" - vectorDrawables { - useSupportLibrary = true - } } buildTypes { @@ -30,18 +21,6 @@ android { signingConfig = signingConfigs.getByName("debug") } } - compileOptions { - sourceCompatibility = JavaVersion.VERSION_17 - targetCompatibility = JavaVersion.VERSION_17 - } - buildFeatures { - compose = true - } - packaging { - resources { - excludes += "/META-INF/{AL2.0,LGPL2.1}" - } - } } dependencies { diff --git a/samples/preferenceComposeApp/build.gradle.kts b/samples/preferenceComposeApp/build.gradle.kts index 1dfd8b15..4e3c39af 100644 --- a/samples/preferenceComposeApp/build.gradle.kts +++ b/samples/preferenceComposeApp/build.gradle.kts @@ -1,22 +1,12 @@ -import org.gradle.jvm.tasks.Jar -import org.jetbrains.compose.desktop.application.dsl.TargetFormat - plugins { - alias(libs.plugins.kotlin.multiplatform) - alias(libs.plugins.android.library) - alias(libs.plugins.compose.compiler) - alias(libs.plugins.kotlin.serialization) - alias(libs.plugins.jetbrains.compose) + id("gd.kmp.sample") } kotlin { - androidLibrary { + android { namespace = "io.github.arthurkun.generic.datastore.compose.app" - compileSdk = libs.versions.compile.sdk.get().toInt() - minSdk = libs.versions.min.sdk.get().toInt() - - withJava() + @Suppress("UnstableApiUsage") optimization { consumerKeepRules.file("consumer-rules.pro") } @@ -32,14 +22,6 @@ kotlin { } } - jvm("desktop") { - testRuns["test"].executionTask.configure { - useJUnitPlatform() - } - } - - applyDefaultHierarchyTemplate() - sourceSets { val commonMain by getting { dependencies { @@ -58,25 +40,14 @@ kotlin { } } - val desktopMain by getting { - dependencies { - implementation(libs.coroutines.swing) - implementation(compose.desktop.currentOs) - } - } - val jvmCommon by creating { dependsOn(commonMain) } androidMain.dependsOn(jvmCommon) - desktopMain.dependsOn(jvmCommon) - } - - compilerOptions { - freeCompilerArgs.addAll( - "-Xexpect-actual-classes", - ) + named("desktopMain") { + dependsOn(jvmCommon) + } } } @@ -84,28 +55,8 @@ compose.desktop { application { mainClass = "io.github.arthurkun.generic.datastore.compose.app.MainKt" - buildTypes { - release { - proguard { - configurationFiles.from(project.file("proguard-rules.pro")) - } - } - } - nativeDistributions { - modules("jdk.unsupported") - targetFormats(TargetFormat.Dmg, TargetFormat.Msi, TargetFormat.Deb) packageName = "generic-datastore-sample" - packageVersion = "1.0.0" } } } - -tasks.withType().configureEach { - duplicatesStrategy = DuplicatesStrategy.EXCLUDE - - exclude("META-INF/AL2.0") - exclude("META-INF/LGPL2.1") - - exclude("META-INF/MANIFEST.MF") -} diff --git a/samples/protoComposeApp/build.gradle.kts b/samples/protoComposeApp/build.gradle.kts index db24e972..d10ab220 100644 --- a/samples/protoComposeApp/build.gradle.kts +++ b/samples/protoComposeApp/build.gradle.kts @@ -1,22 +1,13 @@ -import org.gradle.jvm.tasks.Jar -import org.jetbrains.compose.desktop.application.dsl.TargetFormat - plugins { - alias(libs.plugins.kotlin.multiplatform) - alias(libs.plugins.compose.compiler) - alias(libs.plugins.jetbrains.compose) + id("gd.kmp.sample") alias(libs.plugins.wire) } kotlin { - jvm("desktop") { - testRuns["test"].executionTask.configure { - useJUnitPlatform() - } + android { + namespace = "io.github.arthurkun.generic.datastore.proto.app" } - applyDefaultHierarchyTemplate() - sourceSets { val commonMain by getting { dependencies { @@ -27,19 +18,6 @@ kotlin { implementation(libs.wire.runtime) } } - - val desktopMain by getting { - dependencies { - implementation(libs.coroutines.swing) - implementation(compose.desktop.currentOs) - } - } - } - - compilerOptions { - freeCompilerArgs.addAll( - "-Xexpect-actual-classes", - ) } } @@ -56,28 +34,8 @@ compose.desktop { application { mainClass = "io.github.arthurkun.generic.datastore.proto.app.MainKt" - buildTypes { - release { - proguard { - configurationFiles.from(project.file("proguard-rules.pro")) - } - } - } - nativeDistributions { - modules("jdk.unsupported") - targetFormats(TargetFormat.Dmg, TargetFormat.Msi, TargetFormat.Deb) packageName = "generic-datastore-proto-sample" - packageVersion = "1.0.0" } } } - -tasks.withType().configureEach { - duplicatesStrategy = DuplicatesStrategy.EXCLUDE - - exclude("META-INF/AL2.0") - exclude("META-INF/LGPL2.1") - - exclude("META-INF/MANIFEST.MF") -} diff --git a/settings.gradle.kts b/settings.gradle.kts index 8ab7d37a..c7d36282 100644 --- a/settings.gradle.kts +++ b/settings.gradle.kts @@ -1,4 +1,5 @@ pluginManagement { + includeBuild("build-logic") repositories { google { content { @@ -30,9 +31,13 @@ plugins { id("org.gradle.toolchains.foojay-resolver-convention") version "1.0.0" } +val isJitPack = System.getenv("JITPACK") == "true" + rootProject.name = "GenericDataStore" -include(":samples:preferenceAndroidApp") -include(":samples:preferenceComposeApp") -include(":samples:protoComposeApp") include(":generic-datastore") include(":generic-datastore-compose") +if (!isJitPack) { + include(":samples:preferenceAndroidApp") + include(":samples:preferenceComposeApp") + include(":samples:protoComposeApp") +}