def excludes = [ // dependency injection graph '**/*Module.*', '**/*Module*.*', // Framework entry points '**/*Activity*', '**/*Fragment*', '**/*Application*', // We would like to exclude android widgets as well but our naming is inconsistent // Proof of concept '**/*Login2*', // Generated '**/*JsonAdapter*', '**/*Item.*', '**/*$Holder.*', '**/*ViewHolder.*', '**/*View.*', '**/*BottomSheet.*' ] def initializeReport(report, projects, classExcludes) { projects.each { project -> project.apply plugin: 'jacoco' } report.executionData { fileTree(rootProject.rootDir.absolutePath).include( "**/build/outputs/unit_test_code_coverage/**/*.exec", "**/build/outputs/code_coverage/**/coverage.ec" ) } 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/gplayDebug") androidSourceDirs.add("${project.buildDir}/generated/source/kapt/gplayDebug") 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/debug") androidSourceDirs.add("${project.buildDir}/generated/source/kapt/debug") 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 theCodeCoverageReport(type: JacocoReport) { outputs.upToDateWhen { false } rootProject.apply plugin: 'jacoco' tasks.withType(Test) { jacoco.includeNoLocationClasses = true } def projects = collectProjects { ['vector','matrix-sdk-android'].contains(it.name) } dependsOn { [':vector:testGplayDebugUnitTest'] + [':vector:connectedGplayDebugAndroidTest'] + [':matrix-sdk-android:testDebugUnitTest'] + [':matrix-sdk-android:connectedDebugAndroidTest'] } initializeReport(it, projects, excludes) }