diff --git a/build.gradle b/build.gradle index 0a41ac3625..42d2abe2ce 100644 --- a/build.gradle +++ b/build.gradle @@ -105,6 +105,16 @@ task clean(type: Delete) { delete rootProject.buildDir } +def launchTask = getGradle() + .getStartParameter() + .getTaskRequests() + .toString() + .toLowerCase() + +if (launchTask.contains("codeCoverageReport".toLowerCase())) { + apply from: 'coverage.gradle' +} + apply plugin: 'org.sonarqube' // To run a sonar analysis: diff --git a/coverage.gradle b/coverage.gradle new file mode 100644 index 0000000000..098c67c26f --- /dev/null +++ b/coverage.gradle @@ -0,0 +1,97 @@ +def excludes = [ + // DI graph + '**/*Module.*', + '**/*Module*.*', + + // Android composables + '**/*Screen*', + '**/components/*', + '**/*Compose*.*', + + // Android framework + '**/*Activity*', + '**/*AndroidService*', + '**/*Application*', + + // Generated + '**/*serializer*', + '**/*Serializer*', + "**/*request/*Companion*.*", + '**/*QueriesImpl*', + '**/*Db*', + '**/Select*', + + // Tmp until serializationx can ignore generated + '**/Api*', +] + +def initializeReport(report, projects, classExcludes) { + projects.each { project -> project.apply plugin: 'jacoco' } + report.executionData { fileTree(rootProject.rootDir.absolutePath).include("**/build/jacoco/*.exec") } + + report.reports { + xml.enabled true + html.enabled true + csv.enabled false + } + + gradle.projectsEvaluated { + def androidSourceDirs = [] + def androidClassDirs = [] + + projects.each { project -> + switch (project) { + case { project.plugins.hasPlugin("com.android.application") }: + androidClassDirs.add("${project.buildDir}/tmp/kotlin-classes/debug") + androidSourceDirs.add("${project.projectDir}/src/main/kotlin") + androidSourceDirs.add("${project.projectDir}/src/main/java") + break + case { project.plugins.hasPlugin("com.android.library") }: + androidClassDirs.add("${project.buildDir}/tmp/kotlin-classes/release") + androidSourceDirs.add("${project.projectDir}/src/main/kotlin") + androidSourceDirs.add("${project.projectDir}/src/main/java") + break + default: + report.sourceSets project.sourceSets.main + } + } + + report.sourceDirectories.setFrom(report.sourceDirectories + files(androidSourceDirs)) + def classFiles = androidClassDirs.collect { files(it).files }.flatten() + report.classDirectories.setFrom(files((report.classDirectories.files + classFiles).collect { + fileTree(dir: it, excludes: classExcludes) + })) + } +} + +def collectProjects(predicate) { + return subprojects.findAll { it.buildFile.isFile() && predicate(it) } +} + +//task unitCodeCoverageReport(type: JacocoReport) { +// outputs.upToDateWhen { false } +// rootProject.apply plugin: 'jacoco' +// def excludedProjects = [ +// 'olm-stub', +// 'test-harness' +// ] +// def projects = collectProjects { !excludedProjects.contains(it.name) } +// dependsOn { ["app:assembleDebug"] + projects*.test } +// initializeReport(it, projects, excludes) +//} +// +//task harnessCodeCoverageReport(type: JacocoReport) { +// outputs.upToDateWhen { false } +// rootProject.apply plugin: 'jacoco' +// def projects = collectProjects { true } +// dependsOn { ["app:assembleDebug", project(":test-harness").test] } +// initializeReport(it, projects, excludes) +//} + +task allCodeCoverageReport(type: JacocoReport) { + outputs.upToDateWhen { false } + rootProject.apply plugin: 'jacoco' + def projects = collectProjects { true } + dependsOn { projects*.test } + initializeReport(it, projects, excludes) +} diff --git a/dependencies_groups.gradle b/dependencies_groups.gradle index 7de8100469..4c976faa7c 100644 --- a/dependencies_groups.gradle +++ b/dependencies_groups.gradle @@ -150,6 +150,7 @@ ext.groups = [ 'org.ec4j.core', 'org.glassfish.jaxb', 'org.hamcrest', + 'org.jacoco', 'org.jetbrains', 'org.jetbrains.intellij.deps', 'org.jetbrains.kotlin',