Files
com.github.premnirmal.ticke…/shared/build.gradle.kts

195 lines
7.1 KiB
Kotlin

import org.jetbrains.kotlin.gradle.dsl.JvmTarget
import com.github.premnirmal.gradle.getCommitsBetween
import com.github.premnirmal.gradle.getOldGitVersionFromGit
import com.github.premnirmal.gradle.getVersionNameFromGit
plugins {
alias(libs.plugins.kotlin.multiplatform)
alias(libs.plugins.android.library)
alias(libs.plugins.kotlinx.serialization)
alias(libs.plugins.com.google.devtools.ksp)
alias(libs.plugins.androidx.room)
alias(libs.plugins.compose.multiplatform)
alias(libs.plugins.compose.compiler)
id("kotlin-parcelize")
}
room {
schemaDirectory("$projectDir/schemas")
}
repositories {
google()
mavenCentral()
maven("https://jitpack.io")
}
// Generates the "what's new" changelog from the local git history into a commonMain constant, so the
// changelog is shared by every platform (Android and iOS) instead of living only in :app's Android
// BuildConfig. CommitsProvider defaults to this constant.
val generatedChangelogDir: Provider<Directory> =
layout.buildDirectory.dir("generated/changelog/commonMain/kotlin")
val generateChangelog by tasks.registering {
val outputDir = generatedChangelogDir
outputs.dir(outputDir)
val versionName = project.getVersionNameFromGit()
val oldVersion = project.getOldGitVersionFromGit()
// git log subjects already have their newlines escaped to the literal "\n" sequence.
val changeLog = project.getCommitsBetween(old = oldVersion, new = versionName)
inputs.property("changeLog", changeLog)
doLast {
// Escape the characters that would break a Kotlin string literal. Backslashes are intentionally
// preserved so the embedded "\n" line separators survive as real newlines at runtime.
val escaped = changeLog
.replace("\"", "\\\"")
.replace("\$", "\\\$")
val pkgDir = outputDir.get().asFile.resolve("com/github/premnirmal/shared")
pkgDir.mkdirs()
pkgDir.resolve("ChangelogBuildConfig.kt").writeText(
"""
|package com.github.premnirmal.shared
|
|/**
| * Generated at build time from the local git history (see :shared `generateChangelog`).
| * Shared by every platform so Android and iOS show the same "what's new" changelog.
| */
|internal object ChangelogBuildConfig {
| const val CHANGE_LOG: String = "$escaped"
|}
|
""".trimMargin()
)
}
}
kotlin {
androidTarget {
compilerOptions {
jvmTarget.set(JvmTarget.JVM_17)
}
// kotlin-parcelize only recognises `kotlinx.parcelize.Parcelize` by default. Our shared
// models are annotated with the multiplatform `@CommonParcelize` alias, so we register it
// as an additional Parcelize annotation on the Android compilations (where the plugin runs)
// to ensure the real Parcelable implementations are generated.
compilations.configureEach {
compileTaskProvider.configure {
compilerOptions {
freeCompilerArgs.addAll(
"-P",
"plugin:org.jetbrains.kotlin.parcelize:additionalAnnotation=com.github.premnirmal.shared.CommonParcelize"
)
}
}
}
}
listOf(
iosArm64(),
iosSimulatorArm64()
).forEach { iosTarget ->
iosTarget.binaries.framework {
baseName = "Shared"
isStatic = true
// Embed Kotlin/Native debug information into the framework so Firebase Crashlytics can
// symbolicate Kotlin stack frames in iOS crash reports. Because this is a *static* framework
// the Kotlin code is linked directly into the app binary (there is no separate Shared.framework
// dynamic binary with its own auto-generated .dSYM), so the light debug info has to be added to
// the binary here. It then ends up in the app's .dSYM that the Crashlytics build phase uploads,
// turning otherwise-unsymbolicated Kotlin frames into readable function names.
// See https://kotlinlang.org/docs/native-debugging.html#debug-ios-applications
freeCompilerArgs += "-Xadd-light-debug=enable"
}
}
sourceSets {
commonMain {
kotlin.srcDir(generateChangelog)
}
commonMain.dependencies {
implementation(libs.kotlinx.serialization.json)
implementation(libs.kotlinx.coroutines.core)
implementation(libs.ktor.client.core)
implementation(libs.ktor.client.content.negotiation)
implementation(libs.ktor.serialization.kotlinx.json)
implementation(libs.xmlutil.serialization)
api(libs.room.runtime)
implementation(libs.androidx.sqlite.bundled)
implementation(libs.koin.core)
api(libs.androidx.lifecycle.viewmodel)
implementation(libs.navigation.compose)
implementation(libs.androidx.datastore.preferences.core)
implementation(libs.okio)
implementation(compose.runtime)
implementation(compose.foundation)
implementation(compose.material3)
implementation(compose.ui)
implementation(compose.components.resources)
implementation(libs.coil.compose)
implementation(libs.reorderable)
api(libs.vico.multiplatform)
}
androidMain.dependencies {
implementation(libs.ktor.client.okhttp)
implementation(libs.timber)
}
iosMain.dependencies {
implementation(libs.ktor.client.darwin)
implementation(libs.kotlinx.datetime)
implementation(libs.coil.network.ktor3)
}
commonTest.dependencies {
implementation(kotlin("test"))
implementation(libs.ktor.client.mock)
implementation(libs.kotlinx.coroutines.test)
}
}
}
// Generate the Compose Multiplatform resource accessor (`Res`) into a fixed, public package so the
// shared Compose UI (and the iOS host) can reference the bundled drawables deterministically.
compose.resources {
publicResClass = true
packageOfResClass = "com.github.premnirmal.shared.resources"
generateResClass = always
}
android {
namespace = "com.github.premnirmal.shared"
compileSdk = 36
defaultConfig {
minSdk = 26
}
compileOptions {
sourceCompatibility = JavaVersion.VERSION_17
targetCompatibility = JavaVersion.VERSION_17
}
testOptions {
unitTests.isReturnDefaultValues = true
}
}
// CMP navigation-compose is pinned to the stable 2.9.2 line (see gradle/libs.versions.toml),
// which pulls androidx.navigation:*:2.9.x for Android. Guard against any transitive bump to the
// 2.10.x pre-release line (which requires compileSdk 37 + AGP 9.x) by forcing it back to the
// Jetpack 2.8.x line that the project already uses — the CMP wrapper klib stays ABI-compatible.
configurations.matching { it.name.contains("Android") || it.name.contains("android") || it.name.startsWith("debug") || it.name.startsWith("release") }
.configureEach {
resolutionStrategy.eachDependency {
if (requested.group == "androidx.navigation" && requested.version?.startsWith("2.10") == true) {
useVersion("2.8.5")
}
}
}
// Room KSP processor for every Kotlin target that contains the shared persistence engine
// (the @Database/@Dao/@Entity declarations live in commonMain).
dependencies {
add("kspAndroid", libs.room.compiler)
add("kspIosArm64", libs.room.compiler)
add("kspIosSimulatorArm64", libs.room.compiler)
}