summaryrefslogtreecommitdiff
path: root/app/build.gradle.kts
diff options
context:
space:
mode:
Diffstat (limited to 'app/build.gradle.kts')
-rw-r--r--app/build.gradle.kts140
1 files changed, 140 insertions, 0 deletions
diff --git a/app/build.gradle.kts b/app/build.gradle.kts
new file mode 100644
index 0000000..a1d1854
--- /dev/null
+++ b/app/build.gradle.kts
@@ -0,0 +1,140 @@
+plugins {
+ id("com.android.application")
+ id("org.jetbrains.kotlin.android")
+ id("org.jetbrains.kotlin.plugin.serialization")
+ id("org.jetbrains.kotlin.plugin.compose")
+ id("com.google.devtools.ksp")
+ id("io.gitlab.arturbosch.detekt")
+ id("jacoco")
+}
+
+android {
+ namespace = "org.terst.listen"
+ compileSdk = 36
+
+ defaultConfig {
+ applicationId = "org.terst.listen"
+ // Deliberately not FeeDreader's minSdk. That value is 36 in its working tree, which
+ // would restrict the app to Android 16 and newer; 29 covers any phone in real use and
+ // is comfortably above Media3's floor of 21.
+ minSdk = 29
+ targetSdk = 36
+ versionCode = 1
+ versionName = "1.0"
+ testInstrumentationRunner = "androidx.test.runner.AndroidJUnitRunner"
+ }
+
+ buildTypes {
+ debug {
+ enableUnitTestCoverage = true
+ }
+ release {
+ isMinifyEnabled = false
+ }
+ }
+
+ buildFeatures {
+ compose = true
+ }
+
+ compileOptions {
+ sourceCompatibility = JavaVersion.VERSION_11
+ targetCompatibility = JavaVersion.VERSION_11
+ }
+
+ kotlinOptions {
+ jvmTarget = "11"
+ }
+
+ testOptions {
+ unitTests {
+ // Room's and Media3's Android stubs otherwise throw on every call from a JVM test.
+ isReturnDefaultValues = true
+ }
+ }
+}
+
+dependencies {
+ val composeBom = platform("androidx.compose:compose-bom:2026.06.01")
+ implementation(composeBom)
+ androidTestImplementation(composeBom)
+
+ implementation("androidx.core:core-ktx:1.17.0")
+ implementation("androidx.activity:activity-compose:1.11.0")
+ implementation("androidx.lifecycle:lifecycle-runtime-ktx:2.9.4")
+ implementation("androidx.lifecycle:lifecycle-viewmodel-compose:2.9.4")
+ implementation("androidx.navigation:navigation-compose:2.9.5")
+
+ implementation("androidx.compose.ui:ui")
+ implementation("androidx.compose.ui:ui-graphics")
+ implementation("androidx.compose.ui:ui-tooling-preview")
+ implementation("androidx.compose.material3:material3")
+ implementation("androidx.compose.material:material-icons-extended")
+
+ // Media3 is the whole playback stack: ExoPlayer for decode and speed control,
+ // MediaSessionService for lock-screen and Bluetooth transport, and its DownloadManager,
+ // which shares a cache with playback so a partly-downloaded episode streams the remainder
+ // instead of failing.
+ val media3 = "1.8.0"
+ implementation("androidx.media3:media3-exoplayer:$media3")
+ implementation("androidx.media3:media3-session:$media3")
+ implementation("androidx.media3:media3-ui:$media3")
+ implementation("androidx.media3:media3-datasource-okhttp:$media3")
+
+ implementation("androidx.room:room-runtime:2.8.4")
+ implementation("androidx.room:room-ktx:2.8.4")
+ ksp("androidx.room:room-compiler:2.8.4")
+
+ implementation("androidx.work:work-runtime-ktx:2.10.5")
+ implementation("androidx.datastore:datastore-preferences:1.1.7")
+
+ implementation("com.squareup.okhttp3:okhttp:4.12.0")
+ implementation("org.jetbrains.kotlinx:kotlinx-serialization-json:1.6.3")
+ implementation("org.jetbrains.kotlinx:kotlinx-coroutines-android:1.8.0")
+
+ testImplementation("junit:junit:4.13.2")
+ testImplementation("org.jetbrains.kotlinx:kotlinx-coroutines-test:1.8.0")
+ testImplementation("androidx.room:room-testing:2.8.4")
+ // The JVM has no XmlPullParser implementation; the feed parser needs a real one under test.
+ testImplementation("net.sf.kxml:kxml2:2.3.0")
+ testImplementation("xmlpull:xmlpull:1.1.3.1")
+ testImplementation("com.squareup.okhttp3:mockwebserver:4.12.0")
+
+ androidTestImplementation("androidx.test.ext:junit:1.3.0")
+ androidTestImplementation("androidx.test.espresso:espresso-core:3.7.0")
+ androidTestImplementation("androidx.compose.ui:ui-test-junit4")
+ androidTestImplementation("androidx.room:room-testing:2.8.4")
+ androidTestImplementation("org.jetbrains.kotlinx:kotlinx-coroutines-test:1.8.0")
+
+ debugImplementation("androidx.compose.ui:ui-tooling")
+ debugImplementation("androidx.compose.ui:ui-test-manifest")
+}
+
+detekt {
+ buildUponDefaultConfig = true
+ config.setFrom(files("$rootDir/config/detekt/detekt.yml"))
+ baseline = file("$rootDir/config/detekt/baseline.xml")
+}
+
+jacoco {
+ toolVersion = "0.8.12"
+}
+
+tasks.register<JacocoReport>("jacocoTestReport") {
+ dependsOn("testDebugUnitTest")
+ reports {
+ xml.required.set(true)
+ html.required.set(true)
+ }
+ // ui/** is excluded for the same reason as FeeDreader: Compose screens are impractical to
+ // unit-test for coverage and including them makes the metric meaningless.
+ val kotlinDebugTree = fileTree("${layout.buildDirectory.get()}/tmp/kotlin-classes/debug") {
+ exclude("**/ui/**", "**/R.class", "**/R$*.class", "**/BuildConfig.*", "**/*_Impl*")
+ }
+ val javaDebugTree = fileTree("${layout.buildDirectory.get()}/intermediates/javac/debug") {
+ exclude("**/ui/**", "**/R.class", "**/R$*.class", "**/BuildConfig.*", "**/*_Impl*")
+ }
+ classDirectories.setFrom(files(kotlinDebugTree, javaDebugTree))
+ sourceDirectories.setFrom(files("src/main/java"))
+ executionData.setFrom(fileTree(layout.buildDirectory) { include("**/*.exec") })
+}