Update kotlin to v0.8.0 (#2854)
* Update kotlin to v0.8.0 * Adapt our setup to `v0.8.0`'s changes * Make sure verification tasks run on `check` tasks --------- Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com> Co-authored-by: Jorge Martín <jorgem@element.io>
This commit is contained in:
parent
cd03a83797
commit
46107a9cff
4 changed files with 197 additions and 149 deletions
2
.github/workflows/nightlyReports.yml
vendored
2
.github/workflows/nightlyReports.yml
vendored
|
|
@ -33,7 +33,7 @@ jobs:
|
||||||
run: ./gradlew verifyPaparazziDebug $CI_GRADLE_ARG_PROPERTIES
|
run: ./gradlew verifyPaparazziDebug $CI_GRADLE_ARG_PROPERTIES
|
||||||
|
|
||||||
- name: 📈 Generate kover report and verify coverage
|
- name: 📈 Generate kover report and verify coverage
|
||||||
run: ./gradlew :app:koverXmlReportGplayDebug :app:koverHtmlReportGplayDebug :app:koverVerifyGplayDebug $CI_GRADLE_ARG_PROPERTIES
|
run: ./gradlew :app:koverXmlReportGplayDebug :app:koverHtmlReportGplayDebug :app:koverVerifyAll $CI_GRADLE_ARG_PROPERTIES
|
||||||
|
|
||||||
- name: ✅ Upload kover report
|
- name: ✅ Upload kover report
|
||||||
if: always()
|
if: always()
|
||||||
|
|
|
||||||
2
.github/workflows/tests.yml
vendored
2
.github/workflows/tests.yml
vendored
|
|
@ -55,7 +55,7 @@ jobs:
|
||||||
run: ./gradlew verifyPaparazziDebug $CI_GRADLE_ARG_PROPERTIES
|
run: ./gradlew verifyPaparazziDebug $CI_GRADLE_ARG_PROPERTIES
|
||||||
|
|
||||||
- name: 📈Generate kover report and verify coverage
|
- name: 📈Generate kover report and verify coverage
|
||||||
run: ./gradlew :app:koverXmlReportGplayDebug :app:koverHtmlReportGplayDebug :app:koverVerifyGplayDebug $CI_GRADLE_ARG_PROPERTIES
|
run: ./gradlew :app:koverXmlReportGplayDebug :app:koverHtmlReportGplayDebug :app:koverVerifyAll $CI_GRADLE_ARG_PROPERTIES
|
||||||
|
|
||||||
- name: 🚫 Upload kover failed coverage reports
|
- name: 🚫 Upload kover failed coverage reports
|
||||||
if: failure()
|
if: failure()
|
||||||
|
|
|
||||||
|
|
@ -57,7 +57,7 @@ autoservice = "1.1.1"
|
||||||
junit = "4.13.2"
|
junit = "4.13.2"
|
||||||
androidx-test-ext-junit = "1.1.5"
|
androidx-test-ext-junit = "1.1.5"
|
||||||
espresso-core = "3.5.1"
|
espresso-core = "3.5.1"
|
||||||
kover = "0.7.6"
|
kover = "0.8.0"
|
||||||
|
|
||||||
[libraries]
|
[libraries]
|
||||||
# Project
|
# Project
|
||||||
|
|
|
||||||
|
|
@ -16,10 +16,24 @@
|
||||||
|
|
||||||
package extension
|
package extension
|
||||||
|
|
||||||
import kotlinx.kover.gradle.plugin.dsl.KoverReportExtension
|
import kotlinx.kover.gradle.plugin.dsl.AggregationType
|
||||||
|
import kotlinx.kover.gradle.plugin.dsl.CoverageUnit
|
||||||
|
import kotlinx.kover.gradle.plugin.dsl.GroupingEntityType
|
||||||
|
import kotlinx.kover.gradle.plugin.dsl.KoverProjectExtension
|
||||||
|
import kotlinx.kover.gradle.plugin.dsl.KoverVariantCreateConfig
|
||||||
import org.gradle.api.Action
|
import org.gradle.api.Action
|
||||||
import org.gradle.api.Project
|
import org.gradle.api.Project
|
||||||
|
import org.gradle.configurationcache.extensions.capitalized
|
||||||
import org.gradle.kotlin.dsl.apply
|
import org.gradle.kotlin.dsl.apply
|
||||||
|
import org.gradle.kotlin.dsl.assign
|
||||||
|
|
||||||
|
enum class KoverVariant(val variantName: String) {
|
||||||
|
Presenters("presenters"),
|
||||||
|
States("states"),
|
||||||
|
Views("views"),
|
||||||
|
}
|
||||||
|
|
||||||
|
val koverVariants = KoverVariant.values().map { it.variantName }
|
||||||
|
|
||||||
val localAarProjects = listOf(
|
val localAarProjects = listOf(
|
||||||
":libraries:rustsdk",
|
":libraries:rustsdk",
|
||||||
|
|
@ -44,160 +58,179 @@ val excludedKoverSubProjects = listOf(
|
||||||
":libraries:di",
|
":libraries:di",
|
||||||
) + localAarProjects
|
) + localAarProjects
|
||||||
|
|
||||||
private fun Project.koverReport(action: Action<KoverReportExtension>) {
|
private fun Project.kover(action: Action<KoverProjectExtension>) {
|
||||||
(this as org.gradle.api.plugins.ExtensionAware).extensions.configure("koverReport", action)
|
(this as org.gradle.api.plugins.ExtensionAware).extensions.configure("kover", action)
|
||||||
}
|
}
|
||||||
|
|
||||||
fun Project.setupKover() {
|
fun Project.setupKover() {
|
||||||
|
// Create verify all task joining all existing verification tasks
|
||||||
|
task("koverVerifyAll") {
|
||||||
|
group = "verification"
|
||||||
|
description = "Verifies the code coverage of all subprojects."
|
||||||
|
val dependencies = listOf(":app:koverVerifyGplayDebug") + koverVariants.map { ":app:koverVerify${it.capitalized()}" }
|
||||||
|
dependsOn(dependencies)
|
||||||
|
|
||||||
|
}
|
||||||
// https://kotlin.github.io/kotlinx-kover/
|
// https://kotlin.github.io/kotlinx-kover/
|
||||||
// Run `./gradlew :app:koverHtmlReport` to get report at ./app/build/reports/kover
|
// Run `./gradlew :app:koverHtmlReport` to get report at ./app/build/reports/kover
|
||||||
// Run `./gradlew :app:koverXmlReport` to get XML report
|
// Run `./gradlew :app:koverXmlReport` to get XML report
|
||||||
koverReport {
|
kover {
|
||||||
filters {
|
reports {
|
||||||
excludes {
|
filters {
|
||||||
classes(
|
excludes {
|
||||||
// Exclude generated classes.
|
classes(
|
||||||
"*_ModuleKt",
|
// Exclude generated classes.
|
||||||
"anvil.hint.binding.io.element.*",
|
"*_ModuleKt",
|
||||||
"anvil.hint.merge.*",
|
"anvil.hint.binding.io.element.*",
|
||||||
"anvil.hint.multibinding.io.element.*",
|
"anvil.hint.merge.*",
|
||||||
"anvil.module.*",
|
"anvil.hint.multibinding.io.element.*",
|
||||||
"com.airbnb.android.showkase*",
|
"anvil.module.*",
|
||||||
"io.element.android.libraries.designsystem.showkase.*",
|
"com.airbnb.android.showkase*",
|
||||||
"io.element.android.x.di.DaggerAppComponent*",
|
"io.element.android.libraries.designsystem.showkase.*",
|
||||||
"*_Factory",
|
"io.element.android.x.di.DaggerAppComponent*",
|
||||||
"*_Factory_Impl",
|
"*_Factory",
|
||||||
"*_Factory$*",
|
"*_Factory_Impl",
|
||||||
"*_Module",
|
"*_Factory$*",
|
||||||
"*_Module$*",
|
"*_Module",
|
||||||
"*Module_Provides*",
|
"*_Module$*",
|
||||||
"Dagger*Component*",
|
"*Module_Provides*",
|
||||||
"*ComposableSingletons$*",
|
"Dagger*Component*",
|
||||||
"*_AssistedFactory_Impl*",
|
"*ComposableSingletons$*",
|
||||||
"*BuildConfig",
|
"*_AssistedFactory_Impl*",
|
||||||
// Generated by Showkase
|
"*BuildConfig",
|
||||||
"*Ioelementandroid*PreviewKt$*",
|
// Generated by Showkase
|
||||||
"*Ioelementandroid*PreviewKt",
|
"*Ioelementandroid*PreviewKt$*",
|
||||||
// Other
|
"*Ioelementandroid*PreviewKt",
|
||||||
// We do not cover Nodes (normally covered by maestro, but code coverage is not computed with maestro)
|
// Other
|
||||||
"*Node",
|
// We do not cover Nodes (normally covered by maestro, but code coverage is not computed with maestro)
|
||||||
"*Node$*",
|
"*Node",
|
||||||
"*Presenter\$present\$*",
|
"*Node$*",
|
||||||
// Forked from compose
|
"*Presenter\$present\$*",
|
||||||
"io.element.android.libraries.designsystem.theme.components.bottomsheet.*",
|
// Forked from compose
|
||||||
// Test presenter
|
"io.element.android.libraries.designsystem.theme.components.bottomsheet.*",
|
||||||
"io.element.android.features.leaveroom.fake.FakeLeaveRoomPresenter",
|
// Test presenter
|
||||||
)
|
"io.element.android.features.leaveroom.fake.FakeLeaveRoomPresenter",
|
||||||
annotatedBy(
|
)
|
||||||
"androidx.compose.ui.tooling.preview.Preview",
|
annotatedBy(
|
||||||
"io.element.android.libraries.architecture.coverage.ExcludeFromCoverage",
|
"androidx.compose.ui.tooling.preview.Preview",
|
||||||
"io.element.android.libraries.designsystem.preview.PreviewsDayNight",
|
"io.element.android.libraries.architecture.coverage.ExcludeFromCoverage",
|
||||||
"io.element.android.libraries.designsystem.preview.PreviewWithLargeHeight",
|
"io.element.android.libraries.designsystem.preview.PreviewsDayNight",
|
||||||
)
|
"io.element.android.libraries.designsystem.preview.PreviewWithLargeHeight",
|
||||||
|
)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
|
||||||
defaults {
|
total {
|
||||||
// add reports of both 'debug' and 'release' Android build variants to default reports
|
verify {
|
||||||
mergeWith("gplayDebug")
|
onCheck = true
|
||||||
|
// General rule: minimum code coverage.
|
||||||
|
rule("Global minimum code coverage.") {
|
||||||
|
groupBy = GroupingEntityType.APPLICATION
|
||||||
|
bound {
|
||||||
|
minValue = 70
|
||||||
|
// Setting a max value, so that if coverage is bigger, it means that we have to change minValue.
|
||||||
|
// For instance if we have minValue = 20 and maxValue = 30, and current code coverage is now 31.32%, update
|
||||||
|
// minValue to 25 and maxValue to 35.
|
||||||
|
maxValue = 80
|
||||||
|
coverageUnits = CoverageUnit.INSTRUCTION
|
||||||
|
aggregationForGroup = AggregationType.COVERED_PERCENTAGE
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
variant(KoverVariant.Presenters.variantName) {
|
||||||
|
verify {
|
||||||
|
onCheck = true
|
||||||
|
// Rule to ensure that coverage of Presenters is sufficient.
|
||||||
|
rule("Check code coverage of presenters") {
|
||||||
|
groupBy = GroupingEntityType.CLASS
|
||||||
|
|
||||||
verify {
|
bound {
|
||||||
onCheck = true
|
minValue = 85
|
||||||
// General rule: minimum code coverage.
|
coverageUnits = CoverageUnit.INSTRUCTION
|
||||||
rule("Global minimum code coverage.") {
|
aggregationForGroup = AggregationType.COVERED_PERCENTAGE
|
||||||
isEnabled = true
|
}
|
||||||
entity = kotlinx.kover.gradle.plugin.dsl.GroupingEntityType.APPLICATION
|
|
||||||
bound {
|
|
||||||
minValue = 70
|
|
||||||
// Setting a max value, so that if coverage is bigger, it means that we have to change minValue.
|
|
||||||
// For instance if we have minValue = 20 and maxValue = 30, and current code coverage is now 31.32%, update
|
|
||||||
// minValue to 25 and maxValue to 35.
|
|
||||||
maxValue = 80
|
|
||||||
metric = kotlinx.kover.gradle.plugin.dsl.MetricType.INSTRUCTION
|
|
||||||
aggregation = kotlinx.kover.gradle.plugin.dsl.AggregationType.COVERED_PERCENTAGE
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
// Rule to ensure that coverage of Presenters is sufficient.
|
filters {
|
||||||
rule("Check code coverage of presenters") {
|
includes {
|
||||||
isEnabled = true
|
classes(
|
||||||
entity = kotlinx.kover.gradle.plugin.dsl.GroupingEntityType.CLASS
|
"*Presenter",
|
||||||
filters {
|
)
|
||||||
includes {
|
|
||||||
classes(
|
|
||||||
"*Presenter",
|
|
||||||
)
|
|
||||||
}
|
|
||||||
excludes {
|
|
||||||
classes(
|
|
||||||
"*Fake*Presenter",
|
|
||||||
"io.element.android.appnav.loggedin.LoggedInPresenter$*",
|
|
||||||
// Some options can't be tested at the moment
|
|
||||||
"io.element.android.features.preferences.impl.developer.DeveloperSettingsPresenter$*",
|
|
||||||
"*Presenter\$present\$*",
|
|
||||||
)
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
bound {
|
excludes {
|
||||||
minValue = 85
|
classes(
|
||||||
metric = kotlinx.kover.gradle.plugin.dsl.MetricType.INSTRUCTION
|
"*Fake*Presenter",
|
||||||
aggregation = kotlinx.kover.gradle.plugin.dsl.AggregationType.COVERED_PERCENTAGE
|
"io.element.android.appnav.loggedin.LoggedInPresenter$*",
|
||||||
|
// Some options can't be tested at the moment
|
||||||
|
"io.element.android.features.preferences.impl.developer.DeveloperSettingsPresenter$*",
|
||||||
|
"*Presenter\$present\$*",
|
||||||
|
)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
// Rule to ensure that coverage of States is sufficient.
|
}
|
||||||
rule("Check code coverage of states") {
|
variant(KoverVariant.States.variantName) {
|
||||||
isEnabled = true
|
verify {
|
||||||
entity = kotlinx.kover.gradle.plugin.dsl.GroupingEntityType.CLASS
|
onCheck = true
|
||||||
filters {
|
// Rule to ensure that coverage of States is sufficient.
|
||||||
includes {
|
rule("Check code coverage of states") {
|
||||||
classes(
|
groupBy = GroupingEntityType.CLASS
|
||||||
"^*State$",
|
bound {
|
||||||
)
|
minValue = 90
|
||||||
|
coverageUnits = CoverageUnit.INSTRUCTION
|
||||||
|
aggregationForGroup = AggregationType.COVERED_PERCENTAGE
|
||||||
}
|
}
|
||||||
excludes {
|
|
||||||
classes(
|
|
||||||
"io.element.android.appnav.root.RootNavState*",
|
|
||||||
"io.element.android.libraries.matrix.api.timeline.item.event.OtherState$*",
|
|
||||||
"io.element.android.libraries.matrix.api.timeline.item.event.EventSendState$*",
|
|
||||||
"io.element.android.libraries.matrix.api.room.RoomMembershipState*",
|
|
||||||
"io.element.android.libraries.matrix.api.room.MatrixRoomMembersState*",
|
|
||||||
"io.element.android.libraries.push.impl.notifications.NotificationState*",
|
|
||||||
"io.element.android.features.messages.impl.media.local.pdf.PdfViewerState",
|
|
||||||
"io.element.android.features.messages.impl.media.local.LocalMediaViewState",
|
|
||||||
"io.element.android.features.location.impl.map.MapState*",
|
|
||||||
"io.element.android.libraries.matrix.api.timeline.item.event.LocalEventSendState*",
|
|
||||||
"io.element.android.libraries.designsystem.swipe.SwipeableActionsState*",
|
|
||||||
"io.element.android.features.messages.impl.timeline.components.ExpandableState*",
|
|
||||||
"io.element.android.features.messages.impl.timeline.model.bubble.BubbleState*",
|
|
||||||
"io.element.android.libraries.maplibre.compose.CameraPositionState*",
|
|
||||||
"io.element.android.libraries.maplibre.compose.SaveableCameraPositionState",
|
|
||||||
"io.element.android.libraries.maplibre.compose.SymbolState*",
|
|
||||||
"io.element.android.features.ftue.api.state.*",
|
|
||||||
"io.element.android.features.ftue.impl.welcome.state.*",
|
|
||||||
)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
bound {
|
|
||||||
minValue = 90
|
|
||||||
metric = kotlinx.kover.gradle.plugin.dsl.MetricType.INSTRUCTION
|
|
||||||
aggregation = kotlinx.kover.gradle.plugin.dsl.AggregationType.COVERED_PERCENTAGE
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
// Rule to ensure that coverage of Views is sufficient (deactivated for now).
|
filters {
|
||||||
rule("Check code coverage of views") {
|
includes {
|
||||||
isEnabled = true
|
classes(
|
||||||
entity = kotlinx.kover.gradle.plugin.dsl.GroupingEntityType.CLASS
|
"^*State$",
|
||||||
filters {
|
)
|
||||||
includes {
|
}
|
||||||
classes(
|
excludes {
|
||||||
"*ViewKt",
|
classes(
|
||||||
)
|
"io.element.android.appnav.root.RootNavState*",
|
||||||
|
"io.element.android.libraries.matrix.api.timeline.item.event.OtherState$*",
|
||||||
|
"io.element.android.libraries.matrix.api.timeline.item.event.EventSendState$*",
|
||||||
|
"io.element.android.libraries.matrix.api.room.RoomMembershipState*",
|
||||||
|
"io.element.android.libraries.matrix.api.room.MatrixRoomMembersState*",
|
||||||
|
"io.element.android.libraries.push.impl.notifications.NotificationState*",
|
||||||
|
"io.element.android.features.messages.impl.media.local.pdf.PdfViewerState",
|
||||||
|
"io.element.android.features.messages.impl.media.local.LocalMediaViewState",
|
||||||
|
"io.element.android.features.location.impl.map.MapState*",
|
||||||
|
"io.element.android.libraries.matrix.api.timeline.item.event.LocalEventSendState*",
|
||||||
|
"io.element.android.libraries.designsystem.swipe.SwipeableActionsState*",
|
||||||
|
"io.element.android.features.messages.impl.timeline.components.ExpandableState*",
|
||||||
|
"io.element.android.features.messages.impl.timeline.model.bubble.BubbleState*",
|
||||||
|
"io.element.android.libraries.maplibre.compose.CameraPositionState*",
|
||||||
|
"io.element.android.libraries.maplibre.compose.SaveableCameraPositionState",
|
||||||
|
"io.element.android.libraries.maplibre.compose.SymbolState*",
|
||||||
|
"io.element.android.features.ftue.api.state.*",
|
||||||
|
"io.element.android.features.ftue.impl.welcome.state.*",
|
||||||
|
)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
variant(KoverVariant.Views.variantName) {
|
||||||
|
verify {
|
||||||
|
onCheck = true
|
||||||
|
// Rule to ensure that coverage of Views is sufficient (deactivated for now).
|
||||||
|
rule("Check code coverage of views") {
|
||||||
|
groupBy = GroupingEntityType.CLASS
|
||||||
|
bound {
|
||||||
|
// TODO Update this value, for now there are too many missing tests.
|
||||||
|
minValue = 0
|
||||||
|
coverageUnits = CoverageUnit.INSTRUCTION
|
||||||
|
aggregationForGroup = AggregationType.COVERED_PERCENTAGE
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
bound {
|
}
|
||||||
// TODO Update this value, for now there are too many missing tests.
|
filters {
|
||||||
minValue = 0
|
includes {
|
||||||
metric = kotlinx.kover.gradle.plugin.dsl.MetricType.INSTRUCTION
|
classes(
|
||||||
aggregation = kotlinx.kover.gradle.plugin.dsl.AggregationType.COVERED_PERCENTAGE
|
"*ViewKt",
|
||||||
|
)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
@ -205,22 +238,37 @@ fun Project.setupKover() {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fun Project.applyKoverPluginToAllSubProjects() = rootProject.allprojects {
|
fun Project.applyKoverPluginToAllSubProjects() = rootProject.subprojects {
|
||||||
if (project.path !in localAarProjects) {
|
if (project.path !in localAarProjects) {
|
||||||
apply(plugin = "org.jetbrains.kotlinx.kover")
|
apply(plugin = "org.jetbrains.kotlinx.kover")
|
||||||
|
kover {
|
||||||
|
currentProject {
|
||||||
|
for (variant in koverVariants) {
|
||||||
|
createVariant(variant) {
|
||||||
|
defaultVariants()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fun KoverVariantCreateConfig.defaultVariants() {
|
||||||
|
addWithDependencies("gplayDebug", "debug", optional = true)
|
||||||
|
}
|
||||||
|
|
||||||
|
fun Project.koverSubprojects() = project.rootProject.subprojects
|
||||||
|
.filter {
|
||||||
|
it.project.projectDir.resolve("build.gradle.kts").exists()
|
||||||
|
}
|
||||||
|
.map { it.path }
|
||||||
|
.sorted()
|
||||||
|
.filter {
|
||||||
|
it !in excludedKoverSubProjects
|
||||||
|
}
|
||||||
|
|
||||||
fun Project.koverDependencies() {
|
fun Project.koverDependencies() {
|
||||||
project.rootProject.subprojects
|
project.koverSubprojects()
|
||||||
.filter {
|
|
||||||
it.project.projectDir.resolve("build.gradle.kts").exists()
|
|
||||||
}
|
|
||||||
.map { it.path }
|
|
||||||
.sorted()
|
|
||||||
.filter {
|
|
||||||
it !in excludedKoverSubProjects
|
|
||||||
}
|
|
||||||
.forEach {
|
.forEach {
|
||||||
// println("Add $it to kover")
|
// println("Add $it to kover")
|
||||||
dependencies.add("kover", project(it))
|
dependencies.add("kover", project(it))
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue