def excludes = [ // DI graph '**/*Module.*', '**/*Module*.*', // Android composables '**/*Screen*', '**/components/*', '**/*Compose*.*', // Android framework '**/*Activity*', '**/*AndroidService*', '**/*Application*', // Generated '**/*serializer*', '**/*Serializer*', "**/*request/*Companion*.*", '**/*QueriesImpl*', '**/*Db*', '**/Select*', // Tmp until serializationx can ignore generated '**/Api*', '**/RoomEvent*', ] def initializeReport(report, projects, classExcludes) { projects.each { project -> project.apply plugin: 'jacoco' } report.executionData { fileTree(rootProject.rootDir.absolutePath).include("**/build/**/*.exec") } 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/debug") androidSourceDirs.add("${project.projectDir}/src/main/kotlin") break case { project.plugins.hasPlugin("com.android.library") }: androidClassDirs.add("${project.buildDir}/tmp/kotlin-classes/release") androidSourceDirs.add("${project.projectDir}/src/main/kotlin") 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 allCodeCoverageReport(type: JacocoReport) { outputs.upToDateWhen { false } rootProject.apply plugin: 'jacoco' def projects = collectProjects { !it.name.contains("stub") && !it.name.contains("-noop") } dependsOn { ["app:assembleDebug"] + projects*.test } initializeReport(it, projects, excludes) }