Skip to content

Commit 6caad28

Browse files
authored
Merge pull request #32 from yml-org/feature/CM-1233-JacocoReport
Feature/cm 1233 jacoco report
2 parents 82b5361 + 32765c9 commit 6caad28

File tree

2 files changed

+48
-84
lines changed

2 files changed

+48
-84
lines changed

build-logic/src/main/java/conventions/ProjectJacocoConventionPlugin.kt

Lines changed: 43 additions & 83 deletions
Original file line numberDiff line numberDiff line change
@@ -3,10 +3,14 @@ package conventions
33
import org.gradle.api.Plugin
44
import org.gradle.api.Project
55
import org.gradle.api.artifacts.VersionCatalogsExtension
6+
import org.gradle.api.file.FileTree
7+
import org.gradle.configurationcache.extensions.capitalized
68
import org.gradle.kotlin.dsl.extra
79
import org.gradle.kotlin.dsl.getByType
10+
import org.gradle.kotlin.dsl.register
811
import org.gradle.kotlin.dsl.withType
912
import org.gradle.testing.jacoco.plugins.JacocoPlugin
13+
import org.gradle.testing.jacoco.tasks.JacocoReport
1014
import ytemplate.android.jacoco.extractTestCoverage
1115
import ytemplate.android.jacoco.jacoco
1216

@@ -17,105 +21,61 @@ import ytemplate.android.jacoco.jacoco
1721
*/
1822
@Suppress("UNCHECKED_CAST")
1923
class ProjectJacocoConventionPlugin : Plugin<Project> {
20-
private val project_level_limits = mutableMapOf(
21-
"instruction" to 0.0,
22-
"branch" to 0.0,
23-
"line" to 0.0,
24-
"complexity" to 0.0,
25-
"method" to 0.0,
26-
"class" to 0.0
27-
)
28-
29-
30-
fun Project.setProjectTestCoverageLimits(projectLimits: Map<String, Double>? = null) {
31-
if (projectLimits != null) {
32-
extra.set("limits", projectLimits)
33-
} else {
34-
extra.set("limits", project_level_limits)
35-
}
36-
}
37-
3824
override fun apply(target: Project) {
3925
with(target) {
4026
with(pluginManager) {
4127
apply("jacoco")
4228
}
43-
tasks.register("createMergedJacocoReport") {
29+
30+
tasks.register<JacocoReport>("createMergedJacocoReport") {
4431
val jacocoReport = this
4532
group = "Reporting"
46-
description = "Generate test coverage reports on the debug build"
47-
subprojects {
48-
val subproject=this
49-
subproject.plugins.withType<JacocoPlugin>().configureEach {
50-
if (tasks.findByName("createDemoDebugJacocoReport") != null) {
51-
val moduleTask = tasks.findByName("createDemoDebugJacocoReport")
52-
jacocoReport.dependsOn(moduleTask)
53-
}
54-
}
55-
}
56-
doLast {
57-
logger.lifecycle("Overall coverage report")
58-
val metrics = mutableMapOf<String,Map<String,Double>>()
59-
val moduleLimits = mutableMapOf<String,Map<String,Double>>()
60-
val failures = mutableMapOf<String,List<String>>()
33+
description = "create Project Jacoco Report for debug builds for all submodules with jacoco plugin"
34+
logger.quiet("======Merging HTML Reports=========")
35+
val javaClasses: MutableCollection<FileTree> = mutableListOf()
36+
val kotlinClasses: MutableCollection<FileTree> = mutableListOf()
37+
val sourceDir: MutableCollection<String> = mutableListOf()
38+
val coverageFiles: MutableCollection<String> = mutableListOf()
6139

62-
if (!extra.has("limits")) {
63-
setProjectTestCoverageLimits()
40+
subprojects {
41+
val subProject = this
42+
subProject.plugins.withType<JacocoPlugin>().configureEach {
43+
val moduleTask = tasks.findByName("createDemoDebugJacocoReport")
44+
jacocoReport.dependsOn(moduleTask)
6445
}
65-
subprojects {
66-
if (tasks.findByName("createDemoDebugJacocoReport") != null) {
67-
val reportDir = jacoco.reportsDirectory.asFile.get()
68-
val report =
69-
file("$reportDir/createDemoDebugJacocoReport/createDemoDebugJacocoReport.xml")
70-
if(report.exists()) {
71-
logger.lifecycle("Checking coverage results:$report")
72-
metrics[project.name] = report.extractTestCoverage()
73-
moduleLimits[project.name] = project.extra["limits"] as Map<String, Double>
74-
}
46+
if(subProject.plugins.findPlugin(JacocoPlugin::class.java)!=null) {
47+
val excludedFiles: MutableCollection<String> = mutableListOf()
48+
if (subProject.extra.has("excludes")) {
49+
excludedFiles.addAll(subProject.extra.get("excludes") as List<String>)
7550
}
76-
}
77-
metrics.forEach { (key, metricsMap) ->
78-
val extractedMetricsMap = mutableMapOf<String,Double>()
79-
if(metricsMap.isNotEmpty()) {
80-
val failureMap = metricsMap.filter { item ->
81-
item.value < moduleLimits[key]!![item.key]!!
82-
}.map { item ->
83-
extractedMetricsMap[item.key] = item.value
84-
"-${item.key} coverage is: ${item.value}%, minimum is ${moduleLimits[item.key]}%"
85-
}
86-
if(failureMap.isNotEmpty()){
87-
failures[key] = failureMap
51+
javaClasses.add(fileTree("${subProject.buildDir}/intermediates/javac/demoDebug/classes") {
52+
if (excludedFiles.isNotEmpty()) {
53+
exclude(excludedFiles)
8854
}
89-
}
90-
moduleLimits[key]=extractedMetricsMap
91-
}
9255

56+
}.asFileTree)
57+
kotlinClasses.add(fileTree("${subProject.buildDir}/tmp/kotlin-classes/demoDebug") {
58+
if (excludedFiles.isNotEmpty()) {
59+
exclude(excludedFiles)
60+
}
61+
}.asFileTree)
9362

94-
if (failures.isNotEmpty()) {
95-
logger.quiet("======Code coverage failures=========")
96-
failures.forEach { entry ->
97-
logger.quiet("======Module: ${entry.key}=========")
98-
entry.value.forEach { logger.quiet(it) }
99-
}
100-
logger.quiet("===========================================")
101-
}
102-
103-
if(metrics.isNotEmpty()){
104-
logger.quiet("======Code coverage success=========")
105-
metrics.forEach {entry->
106-
logger.quiet("======Module: ${entry.key}=========")
107-
entry.value.forEach {
108-
logger.quiet("- ${it.key} coverage: ${it.value}")
109-
}
63+
sourceDir.add("${subProject.projectDir}/src/main/java")
64+
sourceDir.add("${subProject.projectDir}/src/main/kotlin")
65+
sourceDir.add("${subProject.projectDir}/src/demoDebug/java")
66+
coverageFiles.add("${subProject.buildDir}/outputs/unit_test_code_coverage/demoDebugUnitTest/testDemoDebugUnitTest.exec")
67+
coverageFiles.add("${subProject.buildDir}/outputs/code_coverage/demoDebugAndroidTest/connected/coverage.ec")
11068
}
111-
logger.quiet("===========================================")
112-
}
113-
11469
}
115-
70+
classDirectories.setFrom(files(javaClasses, kotlinClasses))
71+
additionalClassDirs.setFrom(files(sourceDir))
72+
sourceDirectories.setFrom(files(sourceDir))
73+
executionData.setFrom(files(coverageFiles))
74+
reports {
75+
xml.required.set(true)
76+
html.required.set(true)
77+
}
11678
}
117-
118-
11979
}
12080
}
12181
}

build-logic/src/main/java/ytemplate/android/jacoco/Jacoco.kt

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -41,7 +41,7 @@ private val excludedFiles = mutableSetOf(
4141
"**/Dagger*Component.class",
4242
"**/Dagger*Component\$Builder.class",
4343
"**/*Module_*Factory.class",
44-
"**hilt_aggregated_deps**",
44+
"**hilt*aggregated*deps**",
4545
"**/dagger/**",
4646
"**/di/module/*",
4747
"**/*_Factory*.*",
@@ -90,6 +90,7 @@ fun Project.addExclusion(excludes: Set<String>? = null) {
9090
if (excludes != null) {
9191
excludedFiles.addAll(excludes)
9292
}
93+
extra.set("excludes",excludedFiles.toList())
9394
}
9495

9596
internal fun Project.setupJacocoPlugin() {
@@ -100,6 +101,9 @@ internal fun Project.setupJacocoPlugin() {
100101
if (!extra.has("limits")) {
101102
setModuleTestCoverageLimits()
102103
}
104+
if (!extra.has("excludes")) {
105+
addExclusion()
106+
}
103107

104108
val buildTypes = android.buildTypes.map { type -> type.name }
105109
var productFlavors = android.productFlavors.map { flavor -> flavor.name }

0 commit comments

Comments
 (0)