Skip to content

Commit a59770f

Browse files
passsyvanniktech
authored andcommitted
Don't add jacoco tasks for ignored build variants (#69)
1 parent b35ed5c commit a59770f

File tree

2 files changed

+122
-55
lines changed

2 files changed

+122
-55
lines changed

src/main/groovy/com/vanniktech/android/junit/jacoco/Generation.groovy

Lines changed: 58 additions & 51 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,6 @@
11
package com.vanniktech.android.junit.jacoco
22

3+
import com.android.build.gradle.api.BaseVariant
34
import org.gradle.api.Plugin
45
import org.gradle.api.Project
56
import org.gradle.testing.jacoco.tasks.JacocoReport
@@ -28,9 +29,10 @@ class Generation implements Plugin<Project> {
2829
}
2930
}
3031

31-
protected static boolean addJacoco(final Project subProject, final JunitJacocoExtension extension) {
32+
protected static boolean addJacoco(final Project subProject,
33+
final JunitJacocoExtension extension) {
3234
if (!shouldIgnore(subProject, extension)) {
33-
if (isAndroidProject(subProject)) {
35+
if (isAndroidApplication(subProject) || isAndroidLibrary(subProject)) {
3436
addJacocoAndroid(subProject, extension)
3537
return true
3638
} else if (isJavaProject(subProject)) {
@@ -84,65 +86,68 @@ class Generation implements Plugin<Project> {
8486
toolVersion extension.jacocoVersion
8587
}
8688

87-
subProject.android.testOptions.unitTests.all {
89+
subProject.android.testOptions?.unitTests?.all {
8890
it.jacoco.includeNoLocationClasses = extension.includeNoLocationClasses
8991
}
9092

91-
final def buildTypes = subProject.android.buildTypes.collect { type -> type.name }
92-
final def productFlavors = subProject.android.productFlavors.collect { flavor -> flavor.name }
93+
Collection<BaseVariant> variants = []
94+
if (isAndroidApplication(subProject)) {
95+
variants = subProject.android.applicationVariants
96+
} else if (isAndroidLibrary(subProject)) {
97+
variants = subProject.android.libraryVariants
98+
}
9399

94-
// When no product flavors defined, use empty
95-
if (!productFlavors) productFlavors.add('')
100+
variants.all { variant ->
96101

97-
productFlavors.each { productFlavorName ->
98-
buildTypes.each { buildTypeName ->
102+
def productFlavorName = variant.getFlavorName()
103+
def buildTypeName = variant.getBuildType().name
99104

100-
def sourceName, sourcePath
101-
if (!productFlavorName) {
102-
sourceName = sourcePath = "${buildTypeName}"
103-
} else {
104-
sourceName = "${productFlavorName}${buildTypeName.capitalize()}"
105-
sourcePath = "${productFlavorName}/${buildTypeName}"
106-
}
107-
final def testTaskName = "test${sourceName.capitalize()}UnitTest"
108-
final def taskName = "jacocoTestReport${sourceName.capitalize()}"
109-
110-
subProject.task(taskName, type: JacocoReport, dependsOn: testTaskName) {
111-
group = 'Reporting'
112-
description = "Generate Jacoco coverage reports after running ${sourceName} tests."
113-
114-
reports {
115-
xml {
116-
enabled = true
117-
destination "${subProject.buildDir}/reports/jacoco/${sourceName}/jacoco.xml"
118-
}
119-
html {
120-
enabled = true
121-
destination "${subProject.buildDir}/reports/jacoco/${sourceName}"
122-
}
123-
}
105+
def sourceName, sourcePath
106+
if (!productFlavorName) {
107+
sourceName = sourcePath = "${buildTypeName}"
108+
} else {
109+
sourceName = "${productFlavorName}${buildTypeName.capitalize()}"
110+
sourcePath = "${productFlavorName}/${buildTypeName}"
111+
}
124112

125-
classDirectories = subProject.fileTree(
126-
dir: "${subProject.buildDir}/intermediates/classes/${sourcePath}",
127-
excludes: getExcludes(extension)
128-
)
113+
final def testTaskName = "test${sourceName.capitalize()}UnitTest"
114+
final def taskName = "jacocoTestReport${sourceName.capitalize()}"
129115

130-
final def coverageSourceDirs = [
131-
"src/main/java",
132-
"src/$buildTypeName/java"
133-
]
116+
subProject.task(taskName, type: JacocoReport, dependsOn: testTaskName) {
117+
group = 'Reporting'
118+
description = "Generate Jacoco coverage reports after running ${sourceName} tests."
134119

135-
if (productFlavorName) {
136-
coverageSourceDirs.add("src/$productFlavorName/java")
120+
reports {
121+
xml {
122+
enabled = true
123+
destination "${subProject.buildDir}/reports/jacoco/${sourceName}/jacoco.xml"
124+
}
125+
html {
126+
enabled = true
127+
destination "${subProject.buildDir}/reports/jacoco/${sourceName}"
137128
}
129+
}
138130

139-
additionalSourceDirs = subProject.files(coverageSourceDirs)
140-
sourceDirectories = subProject.files(coverageSourceDirs)
141-
executionData = subProject.files("${subProject.buildDir}/jacoco/${testTaskName}.exec")
131+
classDirectories = subProject.fileTree(
132+
dir: "${subProject.buildDir}/intermediates/classes/${sourcePath}",
133+
excludes: getExcludes(extension)
134+
)
135+
136+
final def coverageSourceDirs = [
137+
"src/main/java",
138+
"src/$buildTypeName/java"
139+
]
140+
141+
if (productFlavorName) {
142+
coverageSourceDirs.add("src/$productFlavorName/java")
142143
}
143144

144-
subProject.check.dependsOn "${taskName}"
145+
additionalSourceDirs = subProject.files(coverageSourceDirs)
146+
sourceDirectories = subProject.files(coverageSourceDirs)
147+
executionData = subProject.files("${subProject.buildDir}/jacoco/${testTaskName}.exec")
145148
}
149+
150+
subProject.check.dependsOn "${taskName}"
146151
}
147152
}
148153

@@ -169,10 +174,12 @@ class Generation implements Plugin<Project> {
169174
] : extension.excludes
170175
}
171176

172-
protected static boolean isAndroidProject(final Project project) {
173-
final boolean isAndroidLibrary = project.plugins.hasPlugin('com.android.library')
174-
final boolean isAndroidApp = project.plugins.hasPlugin('com.android.application')
175-
return isAndroidLibrary || isAndroidApp
177+
protected static boolean isAndroidLibrary(final Project project) {
178+
return project.plugins.hasPlugin('com.android.library')
179+
}
180+
181+
protected static boolean isAndroidApplication(final Project project) {
182+
return project.plugins.hasPlugin('com.android.application')
176183
}
177184

178185
protected static boolean isJavaProject(final Project project) {

src/test/groovy/com/vanniktech/android/junit/jacoco/ProjectHelper.groovy

Lines changed: 64 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,10 @@
11
package com.vanniktech.android.junit.jacoco
22

3+
import com.android.build.gradle.AppExtension
4+
import com.android.build.gradle.LibraryExtension
5+
import com.android.build.gradle.api.BaseVariant
6+
import com.android.builder.model.BuildType
7+
import groovy.mock.interceptor.MockFor
38
import org.gradle.api.Project
49
import org.gradle.testfixtures.ProjectBuilder
510

@@ -21,9 +26,45 @@ final class ProjectHelper {
2126
break
2227
case ProjectType.ANDROID_APPLICATION:
2328
project = ProjectBuilder.builder().withName('android app').build()
29+
def androidMock = new MockFor(AppExtension)
30+
def buildTypesMock = ["debug", "release"].collect { bt ->
31+
def type = new MockFor(BuildType)
32+
type.metaClass.getName = { bt }
33+
type
34+
}
35+
androidMock.metaClass.getBuildTypes = { buildTypesMock }
36+
def appVariants = buildTypesMock.collect { bt ->
37+
def variant = new MockFor(BaseVariant)
38+
variant.metaClass.getFlavorName = { null }
39+
variant.metaClass.getBuildType = { bt }
40+
variant
41+
}
42+
androidMock.metaClass.getApplicationVariants = { appVariants }
43+
androidMock.metaClass.testOptions = null
44+
project.metaClass.android = androidMock
45+
// mock .all{ } function from android gradle lib with standard groovy .each{ }
46+
project.android.applicationVariants.metaClass.all = { delegate.each(it) }
2447
break
2548
case ProjectType.ANDROID_LIBRARY:
2649
project = ProjectBuilder.builder().withName('android library').build()
50+
def androidMock = new MockFor(LibraryExtension)
51+
def buildTypesMock = ["debug", "release"].collect { bt ->
52+
def type = new MockFor(BuildType)
53+
type.metaClass.getName = { bt }
54+
type
55+
}
56+
androidMock.metaClass.getBuildTypes = { buildTypesMock }
57+
def appVariants = buildTypesMock.collect { bt ->
58+
def variant = new MockFor(BaseVariant)
59+
variant.metaClass.getFlavorName = { null }
60+
variant.metaClass.getBuildType = { bt }
61+
variant
62+
}
63+
androidMock.metaClass.getLibraryVariants = { appVariants }
64+
androidMock.metaClass.testOptions = null
65+
project.metaClass.android = androidMock
66+
// mock .all{ } function from android gradle lib with standard groovy .each{ }
67+
project.android.libraryVariants.metaClass.all = { delegate.each(it) }
2768
break
2869
}
2970

@@ -41,12 +82,31 @@ final class ProjectHelper {
4182
blue: [applicationId: 'com.example.blue']
4283
]
4384

44-
project.android.productFlavors {
45-
customFlavors.each { name, config ->
46-
"$name" {
47-
applicationId config.applicationId
85+
def variants = customFlavors.collect { flavorName, config ->
86+
project.android.buildTypes.collect { buildType ->
87+
def variant = new MockFor(BaseVariant)
88+
variant.metaClass.getBuildType = {
89+
def type = new MockFor(BuildType)
90+
type.metaClass.getName = { buildType.name }
91+
type
4892
}
93+
variant.metaClass.getFlavorName = { flavorName }
94+
variant.metaClass.getApplicationId = { config.applicationId }
95+
variant
4996
}
97+
}.flatten()
98+
99+
switch (projectType) {
100+
case ProjectType.ANDROID_APPLICATION:
101+
project.android.metaClass.applicationVariants = variants
102+
// mock .all{ } function from android gradle lib with standard groovy .each{ }
103+
project.android.applicationVariants.metaClass.all = { delegate.each(it) }
104+
break
105+
case ProjectType.ANDROID_LIBRARY:
106+
project.android.metaClass.libraryVariants = variants
107+
// mock .all{ } function from android gradle lib with standard groovy .each{ }
108+
project.android.libraryVariants.metaClass.all = { delegate.each(it) }
109+
break
50110
}
51111

52112
return this

0 commit comments

Comments
 (0)