Created
August 23, 2015 08:41
-
-
Save Piasy/4d658ebcf9b9a6af29ad to your computer and use it in GitHub Desktop.
Android Gradle build script that create jacocoReport task for all sub projects, with some customization
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
/** | |
* List of modules that don't require Jacoco | |
*/ | |
def ignoredByJacoco = [ | |
'presentation' | |
] | |
/** | |
* module class dirs | |
* */ | |
def moduleClassDirs = [ | |
'common' : 'build/classes', | |
'common-android': 'build/intermediates/classes/debug', | |
'model' : 'build/intermediates/classes/debug', | |
'presentation' : 'build/intermediates/classes/debug' | |
] | |
/** | |
* module jacoco exec | |
* */ | |
def moduleJacocoExec = [ | |
'common' : 'build/jacoco/test.exec', | |
'common-android': 'build/jacoco/testDebugUnitTest.exec', | |
'model' : 'build/jacoco/testDebugUnitTest.exec', | |
'presentation' : 'build/jacoco/testDebugUnitTest.exec' | |
] | |
/** | |
* module excludes | |
* */ | |
def moduleExcludes = [ | |
'common' : [ | |
'**/R*.class', | |
'**/BuildConfig*' | |
], | |
'common-android': [ | |
'**/R*.class', | |
'**/BuildConfig*' | |
], | |
'model' : [ | |
'**/R*.class', | |
'**/BuildConfig*' | |
], | |
'presentation' : [ | |
'**/R*.class', | |
'**/BuildConfig*' | |
] | |
] | |
/** | |
* Apply additional build steps to sub-projects | |
*/ | |
subprojects { prj -> | |
// Apply Jacoco only if the project is not in the ignore list | |
if (!ignoredByJacoco.contains(prj.name)) { | |
apply plugin: 'jacoco' | |
jacoco { | |
version rootProject.ext.jacocoVersion | |
} | |
task jacocoReport(type: JacocoReport, dependsOn: 'test') { | |
group = 'Reporting' | |
description = 'Generate Jacoco coverage reports after running tests.' | |
reports { | |
xml.enabled = true | |
html.enabled = true | |
} | |
classDirectories = fileTree( | |
dir: moduleClassDirs[prj.name], | |
excludes: moduleExcludes[prj.name] | |
) | |
sourceDirectories = files('src/main/java') | |
executionData = files(moduleJacocoExec[prj.name]) | |
doFirst { | |
renameClasses(prj.name + File.separator + moduleClassDirs[prj.name]) | |
} | |
} | |
} | |
} | |
apply plugin: 'jacoco' | |
jacoco { | |
toolVersion rootProject.ext.jacocoVersion | |
} | |
/** | |
* Root task that generates an aggregated Jacoco test coverage report for all sub-projects | |
*/ | |
task jacocoFullReport(type: JacocoReport, group: 'Coverage reports') { | |
group = 'Reporting' | |
description = 'Generates an aggregate report from all subprojects' | |
// Get list of projects which should be included in the report | |
def projects = new ArrayList() | |
subprojects.each { prj -> | |
if (!ignoredByJacoco.contains(prj.name)) { | |
projects.add(prj) | |
} | |
} | |
//noinspection GrUnresolvedAccess | |
dependsOn(projects.jacocoReport) | |
additionalSourceDirs = generateSourceFiles(projects) | |
sourceDirectories = generateSourceFiles(projects) | |
classDirectories = generateClassDirs(projects, moduleClassDirs, moduleExcludes) | |
executionData = files(projects.jacocoReport.executionData) | |
reports { | |
html { | |
enabled true | |
destination 'build/reports/jacoco/full' | |
} | |
xml { | |
enabled true | |
destination 'build/reports/jacoco/full/jacocoFullReport.xml' | |
} | |
} | |
doFirst { | |
//noinspection GroovyAssignabilityCheck | |
executionData = files(executionData.findAll { it.exists() }) | |
} | |
} | |
/** | |
* Generate a FileCollection of all projects source files | |
*/ | |
FileCollection generateSourceFiles(Collection projects) { | |
def dirs = [] | |
projects.each { prj -> | |
dirs.add("${prj.name}/src/main/java") | |
} | |
return files(dirs) | |
} | |
/** | |
* Generate a FileCollection of all projects class files | |
*/ | |
FileCollection generateClassDirs(Collection projects, moduleClassDirs, moduleExcludes) { | |
def tree = fileTree('directory does not exists') // I know it's ugly :) | |
projects.each { prj -> | |
//noinspection GrReassignedInClosureLocalVar | |
tree += fileTree( | |
dir: "${prj.name}/${moduleClassDirs[prj.name]}", | |
excludes: moduleExcludes[prj.name] | |
) | |
} | |
return tree | |
} | |
List<File> listDirRecursive(File rootPath) { | |
List<File> result = new ArrayList<>() | |
List<File> children = rootPath.listFiles() | |
children.each { file -> | |
if (file.isFile()) { | |
result.add(file) | |
} else if (file.isDirectory()) { | |
result.addAll(listDirRecursive(file)) | |
} | |
} | |
return result | |
} | |
void renameClasses(String rootPath) { | |
List<File> classes = listDirRecursive(file(rootPath)) | |
classes.each { file -> | |
if (file.name.contains('$$')) { | |
file.renameTo(file.path.replace('$$', '$')) | |
} | |
} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment