Skip to content

Commit

Permalink
Added JaCoCo reports filtering
Browse files Browse the repository at this point in the history
Fixes #220
  • Loading branch information
shanshin committed Aug 27, 2022
1 parent cd1f9dd commit 3275f59
Show file tree
Hide file tree
Showing 4 changed files with 38 additions and 8 deletions.
Expand Up @@ -9,7 +9,7 @@ internal class ReportsFilteringTests : BaseGradleScriptTest() {

@Test
fun testExclude() {
val build = diverseBuild(languages = ALL_LANGUAGES)
val build = diverseBuild(languages = ALL_LANGUAGES, engines = ALL_ENGINES)
build.addKoverRootProject {
sourcesFrom("simple")

Expand All @@ -32,7 +32,7 @@ internal class ReportsFilteringTests : BaseGradleScriptTest() {

@Test
fun testExcludeInclude() {
val build = diverseBuild(languages = ALL_LANGUAGES)
val build = diverseBuild(languages = ALL_LANGUAGES, engines = ALL_ENGINES)
build.addKoverRootProject {
sourcesFrom("simple")

Expand Down
Expand Up @@ -43,7 +43,7 @@ internal object EngineManager {
if (details.variant.vendor == CoverageEngineVendor.INTELLIJ) {
task.intellijReport(exec, projectFiles, classFilter, xmlFile, htmlDir, details.classpath)
} else {
task.jacocoReport(projectFiles, xmlFile, htmlDir, details.classpath)
task.jacocoReport(projectFiles, classFilter, xmlFile, htmlDir, details.classpath)
}
}

Expand All @@ -58,7 +58,7 @@ internal object EngineManager {
return if (details.variant.vendor == CoverageEngineVendor.INTELLIJ) {
task.intellijVerification(exec, projectFiles, classFilter, rules, details.classpath)
} else {
task.jacocoVerification(projectFiles, rules, details.classpath)
task.jacocoVerification(projectFiles, classFilter, rules, details.classpath)
}
}

Expand Down
6 changes: 6 additions & 0 deletions src/main/kotlin/kotlinx/kover/engines/commons/Reports.kt
Expand Up @@ -5,6 +5,7 @@
package kotlinx.kover.engines.commons

import kotlinx.kover.api.*
import java.io.File
import java.math.BigDecimal


Expand All @@ -26,6 +27,11 @@ internal class ReportVerificationBound(

private val regexMetacharactersSet = "<([{\\^-=$!|]})+.>".toSet()

internal fun String.wildcardsToClassFileRegex(): String {
val filenameWithWildcards = "*" + File.separatorChar + this.replace('.', File.separatorChar) + ".class"
return filenameWithWildcards.wildcardsToRegex()
}

/**
* Replaces characters `*` or `.` to `.*` and `.` regexp characters.
*/
Expand Down
32 changes: 28 additions & 4 deletions src/main/kotlin/kotlinx/kover/engines/jacoco/JacocoReports.kt
Expand Up @@ -6,8 +6,9 @@ package kotlinx.kover.engines.jacoco

import groovy.lang.*
import kotlinx.kover.api.*
import kotlinx.kover.engines.commons.ReportVerificationRule
import kotlinx.kover.engines.commons.*
import kotlinx.kover.engines.commons.ONE_HUNDRED
import kotlinx.kover.engines.commons.ReportVerificationRule
import kotlinx.kover.tasks.*
import org.gradle.api.*
import org.gradle.api.file.*
Expand All @@ -18,11 +19,12 @@ import java.util.*

internal fun Task.jacocoReport(
projectFiles: Map<String, ProjectFiles>,
filters: KoverClassFilter,
xmlFile: File?,
htmlDir: File?,
classpath: FileCollection
) {
callJacocoAntReportTask(projectFiles, classpath) {
callJacocoAntReportTask(projectFiles, filters, classpath) {
if (xmlFile != null) {
xmlFile.parentFile.mkdirs()
invokeMethod("xml", mapOf("destfile" to xmlFile))
Expand All @@ -37,10 +39,11 @@ internal fun Task.jacocoReport(

internal fun Task.jacocoVerification(
projectFiles: Map<String, ProjectFiles>,
filters: KoverClassFilter,
rules: List<ReportVerificationRule>,
classpath: FileCollection
): String? {
callJacocoAntReportTask(projectFiles, classpath) {
callJacocoAntReportTask(projectFiles, filters, classpath) {
invokeWithBody("check", mapOf("failonviolation" to "false", "violationsproperty" to "jacocoErrors")) {
rules.forEach {
val entityType = when(it.target) {
Expand Down Expand Up @@ -97,6 +100,7 @@ internal fun Task.jacocoVerification(

private fun Task.callJacocoAntReportTask(
projectFiles: Map<String, ProjectFiles>,
filters: KoverClassFilter,
classpath: FileCollection,
block: GroovyObject.() -> Unit
) {
Expand All @@ -119,6 +123,26 @@ private fun Task.callJacocoAntReportTask(
outputs += pf.value.outputs
}


val filteredOutput = if (filters.excludes.isNotEmpty() || filters.includes.isNotEmpty()) {
val excludeRegexes = filters.excludes.map { Regex(it.wildcardsToClassFileRegex()) }
val includeRegexes = filters.includes.map { Regex(it.wildcardsToClassFileRegex()) }
val trees = outputs.map {
project.fileTree(it).filter { file ->
// the `canonicalPath` is used because a `File.separatorChar` was used to construct the class-file regex
val path = file.canonicalPath
// if the inclusion rules are declared, then the file must fit at least one of them
(includeRegexes.isEmpty() || includeRegexes.any { regex -> path.matches(regex) })
// if the exclusion rules are declared, then the file should not fit any of them
&& excludeRegexes.none { regex -> path.matches(regex) }
}
}
project.files(trees)
} else {
project.files(outputs)
}


builder.invokeWithBody("jacocoReport") {
invokeWithBody("executiondata") {
project.files(binaries).addToAntBuilder(this, "resources")
Expand All @@ -128,7 +152,7 @@ private fun Task.callJacocoAntReportTask(
project.files(sources).addToAntBuilder(this, "resources")
}
invokeWithBody("classfiles") {
project.files(outputs).addToAntBuilder(this, "resources")
filteredOutput.addToAntBuilder(this, "resources")
}
}
block()
Expand Down

0 comments on commit 3275f59

Please sign in to comment.