import io.gitlab.arturbosch.detekt.Detekt import org.jetbrains.kotlin.gradle.dsl.JvmTarget plugins { alias(libs.plugins.android.app) alias(libs.plugins.kotlin.ksp) alias(libs.plugins.kotlin.parcelize) alias(libs.plugins.kotlin.serialization) alias(libs.plugins.compose.compiler) alias(libs.plugins.androidx.room) alias(libs.plugins.detekt) alias(libs.plugins.android.junit5) } detekt { buildUponDefaultConfig = true ignoreFailures = true config.setFrom(files("$rootDir/detekt.yaml")) parallel = true } kotlin { compilerOptions { jvmTarget = JvmTarget.JVM_11 optIn.add("kotlin.RequiresOptIn") } } android { namespace = "org.jellyfin.mobile" compileSdk = libs.versions.android.compileSdk.get().toInt() defaultConfig { minSdk = libs.versions.android.minSdk.get().toInt() targetSdk = libs.versions.android.targetSdk.get().toInt() versionName = project.getVersionName() versionCode = getVersionCode(versionName!!) testInstrumentationRunner = "androidx.test.runner.AndroidJUnitRunner" vectorDrawables.useSupportLibrary = true } signingConfigs { val keystoreFile = getProperty("keystore.file") val keystorePassword = getProperty("keystore.password") val signingKeyAlias = getProperty("signing.key.alias") val signingKeyPassword = getProperty("signing.key.password") if (keystoreFile != null && keystorePassword != null && signingKeyAlias != null && signingKeyPassword != null) { create("release") { storeFile = file(keystoreFile) storePassword = keystorePassword keyAlias = signingKeyAlias keyPassword = signingKeyPassword } } } dependenciesInfo { includeInBundle = false includeInApk = false } buildTypes { getByName("release") { isMinifyEnabled = true isShrinkResources = true proguardFiles(getDefaultProguardFile("proguard-android-optimize.txt"), "proguard-rules.pro") signingConfig = signingConfigs.findByName("release") } getByName("debug") { applicationIdSuffix = ".debug" isDebuggable = true } } flavorDimensions += "variant" productFlavors { register("libre") { dimension = "variant" buildConfigField("boolean", "IS_PROPRIETARY", "false") } register("proprietary") { dimension = "variant" buildConfigField("boolean", "IS_PROPRIETARY", "true") isDefault = true } } bundle { language { enableSplit = false } } androidResources { generateLocaleConfig = true } buildFeatures { buildConfig = true viewBinding = true compose = true } compileOptions { sourceCompatibility = JavaVersion.VERSION_11 targetCompatibility = JavaVersion.VERSION_11 isCoreLibraryDesugaringEnabled = true } lint { lintConfig = file("$rootDir/android-lint.xml") abortOnError = false sarifReport = true checkDependencies = true } room { schemaDirectory("$projectDir/schemas") } } base.archivesName.set("jellyfin-android-v${project.getVersionName()}") dependencies { val proprietaryImplementation by configurations // Kotlin implementation(libs.bundles.coroutines) implementation(libs.kotlin.serialization.json) // Core implementation(libs.bundles.koin) implementation(libs.androidx.core) implementation(libs.androidx.core.splashscreen) implementation(libs.androidx.appcompat) implementation(libs.androidx.activity) implementation(libs.androidx.fragment) implementation(libs.androidx.documentfile) implementation(libs.androidx.work.runtime) coreLibraryDesugaring(libs.androiddesugarlibs) // Lifecycle implementation(libs.bundles.androidx.lifecycle) // UI implementation(libs.google.material) implementation(libs.androidx.constraintlayout) implementation(libs.androidx.webkit) implementation(libs.modernandroidpreferences) // Jetpack Compose implementation(libs.bundles.compose) // Network val sdkVersion = findProperty("sdk.version")?.toString() implementation(libs.jellyfin.sdk) { // Change version if desired when (sdkVersion) { "local" -> version { strictly(JellyfinSdk.LOCAL) } "snapshot" -> version { strictly(JellyfinSdk.SNAPSHOT) } "unstable-snapshot" -> version { strictly(JellyfinSdk.SNAPSHOT_UNSTABLE) } } } implementation(libs.bundles.coil) // Media implementation(libs.androidx.media) implementation(libs.androidx.mediarouter) implementation(libs.bundles.androidx.media3) proprietaryImplementation(libs.androidx.media3.cast) proprietaryImplementation(libs.bundles.playservices) implementation(libs.libass.media) // Room implementation(libs.bundles.androidx.room) ksp(libs.androidx.room.compiler) // Monitoring implementation(libs.slf4j.timber) implementation(libs.timber) // Testing testImplementation(libs.junit.api) testRuntimeOnly(libs.junit.engine) testImplementation(libs.bundles.kotest) testImplementation(libs.mockk) androidTestImplementation(libs.bundles.androidx.test) // Formatting rules for detekt detektPlugins(libs.detekt.formatting) } tasks { withType { reports { sarif.required.set(true) } } // Testing withType { useJUnit() testLogging { events( org.gradle.api.tasks.testing.logging.TestLogEvent.FAILED, org.gradle.api.tasks.testing.logging.TestLogEvent.STANDARD_ERROR, org.gradle.api.tasks.testing.logging.TestLogEvent.SKIPPED ) exceptionFormat = org.gradle.api.tasks.testing.logging.TestExceptionFormat.FULL showExceptions = true showCauses = true showStackTraces = true } } register("versionTxt") { doLast { val path = layout.buildDirectory.file("version.txt").get().asFile val versionString = "v${android.defaultConfig.versionName}=${android.defaultConfig.versionCode}" println("Writing [$versionString] to $path") path.writeText("$versionString\n") } } }