mirror of
https://github.com/vitorpamplona/amethyst.git
synced 2026-08-08 23:54:39 +00:00
build: aggregate Kover coverage for SonarQube import
- Apply Kover (Apache-2.0, build-time only) to the KMP/JVM modules and aggregate at the root - include amethyst playDebug in the aggregated Kover coverage
This commit is contained in:
+19
@@ -278,6 +278,25 @@ call does not guarantee lint finishes first):
|
|||||||
The reports persist under each module's `build/reports/`, so re-run lint only
|
The reports persist under each module's `build/reports/`, so re-run lint only
|
||||||
when you want fresh lint data in the next scan.
|
when you want fresh lint data in the next scan.
|
||||||
|
|
||||||
|
### 5. Optional: include test coverage
|
||||||
|
|
||||||
|
Coverage comes from [Kover](https://github.com/Kotlin/kotlinx-kover). The root
|
||||||
|
`koverXmlReportCoverage` task runs the unit-test suites of the covered modules
|
||||||
|
(`quartz`, `commons`, `quic`, `nestsClient`, `geode`, `cli`, `relayBench`,
|
||||||
|
`desktopApp`, and `amethyst`'s `fdroidDebug` variant) and merges the result
|
||||||
|
into `build/reports/kover/reportCoverage.xml`, which the scanner imports
|
||||||
|
automatically when it exists. Same recipe as lint — generate first, scan
|
||||||
|
second:
|
||||||
|
|
||||||
|
```bash
|
||||||
|
./gradlew koverXmlReportCoverage
|
||||||
|
./gradlew sonar
|
||||||
|
```
|
||||||
|
|
||||||
|
For a human-readable version of the same data, run
|
||||||
|
`./gradlew koverHtmlReportCoverage` and open
|
||||||
|
`build/reports/kover/htmlCoverage/index.html`.
|
||||||
|
|
||||||
Every `sonar.*` entry in `local.properties` is forwarded to the scanner, so any
|
Every `sonar.*` entry in `local.properties` is forwarded to the scanner, so any
|
||||||
[analysis parameter](https://docs.sonarsource.com/sonarqube-server/latest/analyzing-source-code/analysis-parameters/)
|
[analysis parameter](https://docs.sonarsource.com/sonarqube-server/latest/analyzing-source-code/analysis-parameters/)
|
||||||
can be set there. `sonar.projectKey` / `sonar.projectName` default to the root
|
can be set there. `sonar.projectKey` / `sonar.projectName` default to the root
|
||||||
|
|||||||
@@ -6,6 +6,7 @@ plugins {
|
|||||||
alias(libs.plugins.jetbrainsComposeCompiler)
|
alias(libs.plugins.jetbrainsComposeCompiler)
|
||||||
alias(libs.plugins.serialization)
|
alias(libs.plugins.serialization)
|
||||||
alias(libs.plugins.googleKsp)
|
alias(libs.plugins.googleKsp)
|
||||||
|
alias(libs.plugins.kotlinxKover)
|
||||||
}
|
}
|
||||||
|
|
||||||
fun getCurrentBranch(workingDir: java.io.File): String =
|
fun getCurrentBranch(workingDir: java.io.File): String =
|
||||||
|
|||||||
@@ -45,6 +45,50 @@ plugins {
|
|||||||
alias(libs.plugins.androidKotlinMultiplatformLibrary) apply false
|
alias(libs.plugins.androidKotlinMultiplatformLibrary) apply false
|
||||||
alias(libs.plugins.serialization)
|
alias(libs.plugins.serialization)
|
||||||
alias(libs.plugins.googleKsp) apply false
|
alias(libs.plugins.googleKsp) apply false
|
||||||
|
alias(libs.plugins.kotlinxKover)
|
||||||
|
}
|
||||||
|
|
||||||
|
// Aggregated code coverage: `./gradlew koverXmlReportCoverage` runs the unit
|
||||||
|
// test suites of the modules below and merges their coverage into
|
||||||
|
// build/reports/kover/reportCoverage.xml (JaCoCo-compatible XML, importable by
|
||||||
|
// SonarQube — see BUILDING.md). `koverHtmlReportCoverage` renders the same
|
||||||
|
// data for humans. A named variant is used instead of Kover's default total
|
||||||
|
// report because the total for an Android project unconditionally merges
|
||||||
|
// EVERY build variant — compiling all release/benchmark variants of
|
||||||
|
// :amethyst just to measure unit tests. The "coverage" variant below picks
|
||||||
|
// one representative compilation per project: the `jvm` target for KMP/JVM
|
||||||
|
// modules and `playDebug` for :amethyst — play is the primary flavor and the
|
||||||
|
// larger code surface (both `add`s are optional so the one block fits every
|
||||||
|
// project). :nappletHost stays out — it has no tests.
|
||||||
|
dependencies {
|
||||||
|
kover(project(":amethyst"))
|
||||||
|
kover(project(":quartz"))
|
||||||
|
kover(project(":commons"))
|
||||||
|
kover(project(":quic"))
|
||||||
|
kover(project(":nestsClient"))
|
||||||
|
kover(project(":geode"))
|
||||||
|
kover(project(":cli"))
|
||||||
|
kover(project(":relayBench"))
|
||||||
|
kover(project(":desktopApp"))
|
||||||
|
}
|
||||||
|
|
||||||
|
kover {
|
||||||
|
currentProject {
|
||||||
|
createVariant("coverage") {}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
subprojects {
|
||||||
|
plugins.withId("org.jetbrains.kotlinx.kover") {
|
||||||
|
configure<kotlinx.kover.gradle.plugin.dsl.KoverProjectExtension> {
|
||||||
|
currentProject {
|
||||||
|
createVariant("coverage") {
|
||||||
|
add("jvm", optional = true)
|
||||||
|
add("playDebug", optional = true)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// Shared app version for all subprojects — read from gradle/libs.versions.toml.
|
// Shared app version for all subprojects — read from gradle/libs.versions.toml.
|
||||||
@@ -120,6 +164,15 @@ if (sonarEnabled) {
|
|||||||
.filter { it.startsWith("sonar.") }
|
.filter { it.startsWith("sonar.") }
|
||||||
.forEach { System.setProperty(it, sonarProperties.getProperty(it)) }
|
.forEach { System.setProperty(it, sonarProperties.getProperty(it)) }
|
||||||
|
|
||||||
|
// Import Kover's aggregated coverage (run `./gradlew koverXmlReportCoverage`
|
||||||
|
// first) unless the operator pointed the scanner somewhere else.
|
||||||
|
if (System.getProperty("sonar.coverage.jacoco.xmlReportPaths") == null) {
|
||||||
|
System.setProperty(
|
||||||
|
"sonar.coverage.jacoco.xmlReportPaths",
|
||||||
|
layout.buildDirectory.file("reports/kover/reportCoverage.xml").get().asFile.absolutePath,
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
// The scanner's sonarResolver task reads AGP's generated-res-values provider
|
// The scanner's sonarResolver task reads AGP's generated-res-values provider
|
||||||
// but doesn't depend on the task that produces it — wire it up in every
|
// but doesn't depend on the task that produces it — wire it up in every
|
||||||
// module that has both (today only :amethyst enables resValues, but the
|
// module that has both (today only :amethyst enables resValues, but the
|
||||||
|
|||||||
@@ -3,6 +3,7 @@ import org.jetbrains.kotlin.gradle.dsl.JvmTarget
|
|||||||
plugins {
|
plugins {
|
||||||
alias(libs.plugins.jetbrainsKotlinJvm)
|
alias(libs.plugins.jetbrainsKotlinJvm)
|
||||||
application
|
application
|
||||||
|
alias(libs.plugins.kotlinxKover)
|
||||||
}
|
}
|
||||||
|
|
||||||
kotlin {
|
kotlin {
|
||||||
|
|||||||
@@ -25,6 +25,7 @@ plugins {
|
|||||||
alias(libs.plugins.jetbrainsComposeCompiler)
|
alias(libs.plugins.jetbrainsComposeCompiler)
|
||||||
alias(libs.plugins.composeMultiplatform)
|
alias(libs.plugins.composeMultiplatform)
|
||||||
alias(libs.plugins.serialization)
|
alias(libs.plugins.serialization)
|
||||||
|
alias(libs.plugins.kotlinxKover)
|
||||||
}
|
}
|
||||||
|
|
||||||
kotlin {
|
kotlin {
|
||||||
|
|||||||
@@ -6,6 +6,7 @@ plugins {
|
|||||||
alias(libs.plugins.jetbrainsKotlinJvm)
|
alias(libs.plugins.jetbrainsKotlinJvm)
|
||||||
alias(libs.plugins.composeMultiplatform)
|
alias(libs.plugins.composeMultiplatform)
|
||||||
alias(libs.plugins.jetbrainsComposeCompiler)
|
alias(libs.plugins.jetbrainsComposeCompiler)
|
||||||
|
alias(libs.plugins.kotlinxKover)
|
||||||
}
|
}
|
||||||
|
|
||||||
// RPM rejects dashes in version strings — replace with tilde (~) which RPM uses
|
// RPM rejects dashes in version strings — replace with tilde (~) which RPM uses
|
||||||
|
|||||||
@@ -5,6 +5,7 @@ plugins {
|
|||||||
alias(libs.plugins.serialization)
|
alias(libs.plugins.serialization)
|
||||||
application
|
application
|
||||||
`java-test-fixtures`
|
`java-test-fixtures`
|
||||||
|
alias(libs.plugins.kotlinxKover)
|
||||||
}
|
}
|
||||||
|
|
||||||
application {
|
application {
|
||||||
|
|||||||
@@ -35,6 +35,7 @@ kmpTorResource = "409.5.0"
|
|||||||
junit = "4.13.2"
|
junit = "4.13.2"
|
||||||
kchesslib = "1.0.5"
|
kchesslib = "1.0.5"
|
||||||
kotlin = "2.4.0"
|
kotlin = "2.4.0"
|
||||||
|
kover = "0.9.8"
|
||||||
kotlinxCollectionsImmutable = "0.5.0"
|
kotlinxCollectionsImmutable = "0.5.0"
|
||||||
kotlinxCoroutinesCore = "1.11.0"
|
kotlinxCoroutinesCore = "1.11.0"
|
||||||
kotlinxSerialization = "1.11.0"
|
kotlinxSerialization = "1.11.0"
|
||||||
@@ -246,6 +247,7 @@ jetbrainsKotlinJvm = { id = "org.jetbrains.kotlin.jvm", version.ref = "kotlin" }
|
|||||||
jetbrainsComposeCompiler = { id = "org.jetbrains.kotlin.plugin.compose", version.ref = "kotlin" }
|
jetbrainsComposeCompiler = { id = "org.jetbrains.kotlin.plugin.compose", version.ref = "kotlin" }
|
||||||
serialization = { id = 'org.jetbrains.kotlin.plugin.serialization', version.ref = 'kotlin' }
|
serialization = { id = 'org.jetbrains.kotlin.plugin.serialization', version.ref = 'kotlin' }
|
||||||
kotlinMultiplatform = { id = "org.jetbrains.kotlin.multiplatform", version.ref = "kotlin" }
|
kotlinMultiplatform = { id = "org.jetbrains.kotlin.multiplatform", version.ref = "kotlin" }
|
||||||
|
kotlinxKover = { id = "org.jetbrains.kotlinx.kover", version.ref = "kover" }
|
||||||
androidKotlinMultiplatformLibrary = { id = "com.android.kotlin.multiplatform.library", version.ref = "agp" }
|
androidKotlinMultiplatformLibrary = { id = "com.android.kotlin.multiplatform.library", version.ref = "agp" }
|
||||||
vanniktech-mavenPublish = { id = "com.vanniktech.maven.publish", version.ref = "mavenPublish" }
|
vanniktech-mavenPublish = { id = "com.vanniktech.maven.publish", version.ref = "mavenPublish" }
|
||||||
composeMultiplatform = { id = "org.jetbrains.compose", version.ref = "composeMultiplatform" }
|
composeMultiplatform = { id = "org.jetbrains.compose", version.ref = "composeMultiplatform" }
|
||||||
|
|||||||
@@ -5,6 +5,7 @@ plugins {
|
|||||||
alias(libs.plugins.kotlinMultiplatform)
|
alias(libs.plugins.kotlinMultiplatform)
|
||||||
alias(libs.plugins.androidKotlinMultiplatformLibrary)
|
alias(libs.plugins.androidKotlinMultiplatformLibrary)
|
||||||
alias(libs.plugins.serialization)
|
alias(libs.plugins.serialization)
|
||||||
|
alias(libs.plugins.kotlinxKover)
|
||||||
}
|
}
|
||||||
|
|
||||||
kotlin {
|
kotlin {
|
||||||
|
|||||||
@@ -9,6 +9,7 @@ plugins {
|
|||||||
alias(libs.plugins.androidKotlinMultiplatformLibrary)
|
alias(libs.plugins.androidKotlinMultiplatformLibrary)
|
||||||
alias(libs.plugins.serialization)
|
alias(libs.plugins.serialization)
|
||||||
alias(libs.plugins.vanniktech.mavenPublish)
|
alias(libs.plugins.vanniktech.mavenPublish)
|
||||||
|
alias(libs.plugins.kotlinxKover)
|
||||||
}
|
}
|
||||||
|
|
||||||
kotlin {
|
kotlin {
|
||||||
|
|||||||
@@ -23,6 +23,7 @@ import org.jetbrains.kotlin.gradle.dsl.JvmTarget
|
|||||||
plugins {
|
plugins {
|
||||||
alias(libs.plugins.kotlinMultiplatform)
|
alias(libs.plugins.kotlinMultiplatform)
|
||||||
alias(libs.plugins.androidKotlinMultiplatformLibrary)
|
alias(libs.plugins.androidKotlinMultiplatformLibrary)
|
||||||
|
alias(libs.plugins.kotlinxKover)
|
||||||
}
|
}
|
||||||
|
|
||||||
kotlin {
|
kotlin {
|
||||||
|
|||||||
@@ -3,6 +3,7 @@ import org.jetbrains.kotlin.gradle.dsl.JvmTarget
|
|||||||
plugins {
|
plugins {
|
||||||
alias(libs.plugins.jetbrainsKotlinJvm)
|
alias(libs.plugins.jetbrainsKotlinJvm)
|
||||||
application
|
application
|
||||||
|
alias(libs.plugins.kotlinxKover)
|
||||||
}
|
}
|
||||||
|
|
||||||
application {
|
application {
|
||||||
|
|||||||
Reference in New Issue
Block a user