def excludes = [ ] def initializeReport(report, projects, classExcludes) { projects.each { project -> project.apply plugin: 'jacoco' } report.executionData { fileTree(rootProject.rootDir.absolutePath).include("**/build/jacoco/*.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/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 allCodeCoverageReport(type: JacocoReport) { outputs.upToDateWhen { false } rootProject.apply plugin: 'jacoco' // to limit projects in a specific report, add // def excludedProjects = [ ... ] // def projects = collectProjects { !excludedProjects.contains(it.name) } def projects = collectProjects { true } dependsOn { projects*.test } initializeReport(it, projects, excludes) }