@@ -3,10 +3,13 @@ package conventions
33import org.gradle.api.Plugin
44import org.gradle.api.Project
55import org.gradle.api.artifacts.VersionCatalogsExtension
6+ import org.gradle.configurationcache.extensions.capitalized
67import org.gradle.kotlin.dsl.extra
78import org.gradle.kotlin.dsl.getByType
9+ import org.gradle.kotlin.dsl.register
810import org.gradle.kotlin.dsl.withType
911import org.gradle.testing.jacoco.plugins.JacocoPlugin
12+ import org.gradle.testing.jacoco.tasks.JacocoReport
1013import ytemplate.android.jacoco.extractTestCoverage
1114import ytemplate.android.jacoco.jacoco
1215
@@ -45,7 +48,7 @@ class ProjectJacocoConventionPlugin : Plugin<Project> {
4548 group = " Reporting"
4649 description = " Generate test coverage reports on the debug build"
4750 subprojects {
48- val subproject= this
51+ val subproject = this
4952 subproject.plugins.withType<JacocoPlugin >().configureEach {
5053 if (tasks.findByName(" createDemoDebugJacocoReport" ) != null ) {
5154 val moduleTask = tasks.findByName(" createDemoDebugJacocoReport" )
@@ -54,10 +57,11 @@ class ProjectJacocoConventionPlugin : Plugin<Project> {
5457 }
5558 }
5659 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 >>()
60+ logger.lifecycle(" Making Overall coverage report" )
61+ addReportMergingTask()
62+ val metrics = mutableMapOf<String , Map <String , Double >>()
63+ val moduleLimits = mutableMapOf<String , Map <String , Double >>()
64+ val failures = mutableMapOf<String , List <String >>()
6165
6266 if (! extra.has(" limits" )) {
6367 setProjectTestCoverageLimits()
@@ -67,27 +71,28 @@ class ProjectJacocoConventionPlugin : Plugin<Project> {
6771 val reportDir = jacoco.reportsDirectory.asFile.get()
6872 val report =
6973 file(" $reportDir /createDemoDebugJacocoReport/createDemoDebugJacocoReport.xml" )
70- if (report.exists()) {
74+ if (report.exists()) {
7175 logger.lifecycle(" Checking coverage results:$report " )
7276 metrics[project.name] = report.extractTestCoverage()
73- moduleLimits[project.name] = project.extra[" limits" ] as Map <String , Double >
77+ moduleLimits[project.name] =
78+ project.extra[" limits" ] as Map <String , Double >
7479 }
7580 }
7681 }
7782 metrics.forEach { (key, metricsMap) ->
78- val extractedMetricsMap = mutableMapOf<String ,Double >()
79- if (metricsMap.isNotEmpty()) {
83+ val extractedMetricsMap = mutableMapOf<String , Double >()
84+ if (metricsMap.isNotEmpty()) {
8085 val failureMap = metricsMap.filter { item ->
8186 item.value < moduleLimits[key]!! [item.key]!!
8287 }.map { item ->
8388 extractedMetricsMap[item.key] = item.value
8489 " -${item.key} coverage is: ${item.value} %, minimum is ${moduleLimits[item.key]} %"
8590 }
86- if (failureMap.isNotEmpty()){
91+ if (failureMap.isNotEmpty()) {
8792 failures[key] = failureMap
8893 }
8994 }
90- moduleLimits[key]= extractedMetricsMap
95+ moduleLimits[key] = extractedMetricsMap
9196 }
9297
9398
@@ -100,22 +105,52 @@ class ProjectJacocoConventionPlugin : Plugin<Project> {
100105 logger.quiet(" ===========================================" )
101106 }
102107
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} " )
108+ if (metrics.isNotEmpty()) {
109+ logger.quiet(" ======Code coverage success=========" )
110+ metrics.forEach { entry ->
111+ logger.quiet(" ======Module: ${entry.key} =========" )
112+ entry.value.forEach {
113+ logger.quiet(" - ${it.key} coverage: ${it.value} " )
114+ }
109115 }
116+ logger.quiet(" ===========================================" )
110117 }
111- logger.quiet(" ===========================================" )
112- }
113-
114118 }
115119
116120 }
117121
118122
119123 }
120124 }
125+
126+ private fun Project.addReportMergingTask () {
127+ tasks.register<JacocoReport >(" MergeHTMLJacocoReports" ) {
128+ group = " Reporting"
129+ description = " Merge all generated JacocoReport"
130+ logger.quiet(" ======Merging HTML Reports=========" )
131+ val javaClasses : MutableCollection <String > = mutableListOf ()
132+ val kotlinClasses : MutableCollection <String > = mutableListOf ()
133+ val sourceDir : MutableCollection <String > = mutableListOf ()
134+ val coverageFiles : MutableCollection <String > = mutableListOf ()
135+ subprojects.forEach { subProject ->
136+ javaClasses.add(" ${subProject.buildDir} /intermediates/javac/demoDebug/classes" )
137+ kotlinClasses.add(" ${subProject.buildDir} /tmp/kotlin-classes/demoDebug" )
138+ sourceDir.add( " ${subProject.projectDir} /src/main/java" )
139+ sourceDir.add( " ${subProject.projectDir} /src/main/kotlin" )
140+ sourceDir.add( " ${subProject.projectDir} /src/demoDebug/java" )
141+ coverageFiles.add(" ${subProject.buildDir} /outputs/unit_test_code_coverage/demoDebugUnitTest/testDemoDebugUnitTest.exec" )
142+ coverageFiles.add(" ${subProject.buildDir} /outputs/code_coverage/demoDebugAndroidTest/connected/coverage.ec" )
143+ }
144+ classDirectories.setFrom(files(javaClasses, kotlinClasses))
145+ additionalClassDirs.setFrom(files(sourceDir))
146+ sourceDirectories.setFrom(files(sourceDir))
147+ executionData.setFrom(files(coverageFiles))
148+ reports {
149+ xml.required.set(true )
150+ html.required.set(true )
151+ }
152+ }
153+
154+ }
155+
121156}
0 commit comments