def excludes = [ // dependency injection graph '**/*Module.*', '**/*Module*.*', // Framework entry points '**/*Activity*', '**/*Fragment*', '**/*Application*', '**/*AndroidService*', // 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/**/*.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.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.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 generateCoverageReport(type: JacocoReport) { outputs.upToDateWhen { false } rootProject.apply plugin: 'jacoco' def projects = collectProjects { ['vector-app', 'vector', 'matrix-sdk-android'].contains(it.name) } initializeReport(it, projects, excludes) } task unitTestsWithCoverage(type: GradleBuild) { // the 7.1.3 android gradle plugin has a bug where enableTestCoverage generates invalid coverage startParameter.projectProperties.coverage = "false" tasks = ['testDebugUnitTest'] } task instrumentationTestsWithCoverage(type: GradleBuild) { startParameter.projectProperties.coverage = "true" startParameter.projectProperties['android.testInstrumentationRunnerArguments.notPackage'] = 'im.vector.app.ui' tasks = [':vector-app:connectedGplayKotlinCryptoDebugAndroidTest', ':vector:connectedKotlinCryptoDebugAndroidTest', 'matrix-sdk-android:connectedKotlinCryptoDebugAndroidTest'] } task instrumentationTestsRustWithCoverage(type: GradleBuild) { startParameter.projectProperties.coverage = "true" startParameter.projectProperties['android.testInstrumentationRunnerArguments.notPackage'] = 'im.vector.app.ui' tasks = [':vector-app:connectedGplayRustCryptoDebugAndroidTest', ':vector:connectedRustCryptoDebugAndroidTest', 'matrix-sdk-android:connectedRustCryptoDebugAndroidTest'] }