@@ -6,89 +6,140 @@ import org.gradle.testing.jacoco.tasks.JacocoReport
6
6
7
7
class Generation implements Plugin<Project > {
8
8
@Override
9
- void apply (final Project project ) {
10
- project . extensions. create(' junitJacoco' , JunitJacocoExtension )
9
+ void apply (final Project rootProject ) {
10
+ rootProject . extensions. create(' junitJacoco' , JunitJacocoExtension )
11
11
12
- project. subprojects { subProject ->
13
- subProject. plugins. apply(' jacoco' )
12
+ rootProject. subprojects { subProject ->
13
+ afterEvaluate {
14
+ final def extension = rootProject. junitJacoco
14
15
15
- subProject. jacoco {
16
- toolVersion project. junitJacoco. jacocoVersion
16
+ addJacoco(subProject, extension)
17
17
}
18
+ }
19
+ }
20
+
21
+ protected static boolean addJacoco (final Project subProject , final JunitJacocoExtension extension ) {
22
+ if (! shouldIgnore(subProject, extension)) {
23
+ if (isAndroidProject(subProject)) {
24
+ addJacocoAndroid(subProject, extension)
25
+ return true
26
+ } else if (isJavaProject(subProject)) {
27
+ addJacocoJava(subProject, extension)
28
+ return true
29
+ }
30
+ }
31
+
32
+ return false
33
+ }
34
+
35
+ private static void addJacocoJava (final Project subProject , final extension ) {
36
+ subProject. plugins. apply(' jacoco' )
37
+
38
+ subProject. jacoco {
39
+ toolVersion extension. jacocoVersion
40
+ }
41
+
42
+ subProject. jacocoTestReport {
43
+ dependsOn ' test'
44
+
45
+ group = ' Reporting'
46
+ description = ' Generate Jacoco coverage reports.'
47
+
48
+ reports {
49
+ xml. enabled = true
50
+ html. enabled = true
51
+ }
52
+
53
+ classDirectories = subProject. fileTree(
54
+ dir : ' build/classes/main/' ,
55
+ excludes : getExcludes()
56
+ )
57
+
58
+ final def coverageSourceDirs = [
59
+ ' src/main/java' ,
60
+ ]
61
+
62
+ additionalSourceDirs = subProject. files(coverageSourceDirs)
63
+ sourceDirectories = subProject. files(coverageSourceDirs)
64
+ executionData = subProject. files(" ${ subProject.buildDir} /jacoco/test.exec" )
65
+ }
66
+
67
+ subProject. check. dependsOn ' jacocoTestReport'
68
+ }
69
+
70
+ private static void addJacocoAndroid (final Project subProject , final extension ) {
71
+ subProject. plugins. apply(' jacoco' )
72
+
73
+ subProject. jacoco {
74
+ toolVersion extension. jacocoVersion
75
+ }
76
+
77
+ final def buildTypes = subProject. android. buildTypes. collect { type -> type. name }
78
+
79
+ buildTypes. each { buildTypeName ->
80
+ final def taskName = " jacocoTestReport${ buildTypeName.capitalize()} "
81
+ final def testTaskName = " test${ buildTypeName.capitalize()} UnitTest"
18
82
19
- subProject. task(' jacocoReport ' , type : JacocoReport , dependsOn : ' testDebugUnitTest ' ) {
83
+ subProject. task(taskName , type : JacocoReport , dependsOn : testTaskName ) {
20
84
group = ' Reporting'
21
- description = ' Generate Jacoco coverage reports after running tests.'
85
+ description = " Generate Jacoco coverage reports after running ${ buildTypeName } tests."
22
86
23
87
reports {
24
88
xml {
25
89
enabled = true
26
- destination " ${ subProject.buildDir} /reports/jacoco/jacoco.xml"
90
+ destination " ${ subProject.buildDir} /reports/jacoco/${ buildTypeName } / jacoco.xml"
27
91
}
28
92
html {
29
93
enabled = true
30
- destination " ${ subProject.buildDir} /reports/jacoco"
94
+ destination " ${ subProject.buildDir} /reports/jacoco/ ${ buildTypeName } "
31
95
}
32
96
}
33
97
34
- classDirectories = fileTree(
35
- dir : ' build/intermediates/classes/debug' ,
36
- excludes : [' **/R.class' ,
37
- ' **/R$*.class' ,
38
- ' **/*$$*' ,
39
- ' **/*$ViewInjector*.*' ,
40
- ' **/*$ViewBinder*.*' ,
41
- ' **/BuildConfig.*' ,
42
- ' **/Manifest*.*' ,
43
- ' **/*$Lambda$*.*' , // Jacoco can not handle several "$" in class name.
44
- ' **/*Dagger*.*' , // Dagger auto-generated code.
45
- ' **/*MembersInjector*.*' , // Dagger auto-generated code.
46
- ' **/*_Provide*Factory*.*' // Dagger auto-generated code.
47
- ]
98
+ classDirectories = subProject. fileTree(
99
+ dir : " build/intermediates/classes/${ buildTypeName} " ,
100
+ excludes : getExcludes()
48
101
)
49
102
50
- sourceDirectories = files(' src/main/java' )
51
- executionData = files(' build/jacoco/testDebugUnitTest.exec' )
103
+ final def coverageSourceDirs = [
104
+ ' src/main/java' ,
105
+ " src/$buildTypeName /java"
106
+ ]
52
107
53
- doFirst {
54
- files(' build/intermediates/classes/debug' ). getFiles(). each { file ->
55
- if (file. name. contains(' $$' )) {
56
- file. renameTo(file. path. replace(' $$' , ' $' ))
57
- }
58
- }
59
- }
108
+ additionalSourceDirs = subProject. files(coverageSourceDirs)
109
+ sourceDirectories = subProject. files(coverageSourceDirs)
110
+ executionData = subProject. files(" ${ subProject.buildDir} /jacoco/${ testTaskName} .exec" )
60
111
}
61
- }
62
112
63
- project. plugins. apply(' jacoco' )
64
-
65
- project. jacoco {
66
- toolVersion project. junitJacoco. jacocoVersion
113
+ subProject. check. dependsOn " ${ taskName} "
67
114
}
115
+ }
68
116
69
- project. task(' jacocoFullReport' , type : JacocoReport , group : ' Coverage reports' ) {
70
- group = ' Reporting'
71
- description = ' Generate Jacoco coverage reports aggregated from all subprojects.'
72
- dependsOn(project. subprojects. jacocoReport)
117
+ private static ArrayList<String > getExcludes () {
118
+ [' **/R.class' ,
119
+ ' **/R$*.class' ,
120
+ ' **/*$$*' ,
121
+ ' **/*$ViewInjector*.*' ,
122
+ ' **/*$ViewBinder*.*' ,
123
+ ' **/BuildConfig.*' ,
124
+ ' **/Manifest*.*' ,
125
+ ' **/*$Lambda$*.*' , // Jacoco can not handle several "$" in class name.
126
+ ' **/*Dagger*.*' , // Dagger auto-generated code.
127
+ ' **/*MembersInjector*.*' , // Dagger auto-generated code.
128
+ ' **/*_Provide*Factory*.*' // Dagger auto-generated code.
129
+ ]
130
+ }
73
131
74
- executionData = project. files(project. subprojects. jacocoReport. executionData)
75
- classDirectories = project. files(project. subprojects. jacocoReport. classDirectories)
76
- sourceDirectories = project. files(project. subprojects. jacocoReport. sourceDirectories)
132
+ protected static boolean isAndroidProject (final Project project ) {
133
+ final boolean isAndroidLibrary = project. plugins. hasPlugin(' com.android.library' )
134
+ final boolean isAndroidApp = project. plugins. hasPlugin(' com.android.application' )
135
+ return isAndroidLibrary || isAndroidApp
136
+ }
77
137
78
- reports {
79
- xml {
80
- enabled = true
81
- destination " ${ project.buildDir} /reports/jacoco/full/jacoco.xml"
82
- }
83
- html {
84
- enabled = true
85
- destination " ${ project.buildDir} /reports/jacoco/full"
86
- }
87
- }
138
+ protected static boolean isJavaProject (final Project project ) {
139
+ return project. plugins. hasPlugin(' org.gradle.java' )
140
+ }
88
141
89
- doFirst {
90
- executionData = project. files(executionData. findAll { it. exists() })
91
- }
92
- }
142
+ private static boolean shouldIgnore (final Project project , final JunitJacocoExtension extension ) {
143
+ return extension. ignoreProjects?. contains(project. name)
93
144
}
94
145
}
0 commit comments