Skip to content

Commit 0a6ec0b

Browse files
committed
Make the plugin delete non-instrumented classes from the output directory
1 parent e11b331 commit 0a6ec0b

File tree

5 files changed

+91
-12
lines changed

5 files changed

+91
-12
lines changed

build.gradle

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -49,6 +49,7 @@ targetCompatibility = '1.6'
4949

5050
dependencies {
5151
compileOnly "org.scoverage:scalac-scoverage-plugin_2.12:1.3.1"
52+
compile group: 'commons-io', name: 'commons-io', version: '2.6'
5253
testCompile 'junit:junit:4.12'
5354
testCompile 'org.hamcrest:hamcrest-library:1.3'
5455
}

src/functionalTest/java/org.scoverage/ScalaSingleModuleTest.java

Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -79,6 +79,24 @@ public void checkScoverageFails() throws Exception {
7979
assertCoverage(0.0);
8080
}
8181

82+
@Test
83+
public void reportScoverageWithExcludedClasses() throws Exception {
84+
85+
AssertableBuildResult result = run("clean", ScoveragePlugin.getREPORT_NAME(),
86+
"-PexcludedFile=.*");
87+
88+
result.assertTaskSucceeded(ScoveragePlugin.getCOMPILE_NAME());
89+
result.assertTaskSucceeded(ScoveragePlugin.getREPORT_NAME());
90+
result.assertTaskDoesntExist(ScoveragePlugin.getCHECK_NAME());
91+
result.assertTaskDoesntExist(ScoveragePlugin.getAGGREGATE_NAME());
92+
93+
Assert.assertTrue(resolve(reportDir(), "index.html").exists());
94+
Assert.assertFalse(resolve(reportDir(), "src/main/scala/org/hello/World.scala.html").exists());
95+
assertCoverage(100.0); // coverage is 100 since no classes are covered
96+
97+
Assert.assertFalse(resolve(buildDir(), "classes/scala/scoverage/org/hello/World.class").exists());
98+
}
99+
82100
private void assertReportFilesExist() {
83101

84102
Assert.assertTrue(resolve(reportDir(), "index.html").exists());

src/functionalTest/java/org.scoverage/ScoverageFunctionalTest.java

Lines changed: 11 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -49,14 +49,24 @@ protected File projectDir() {
4949
return new File("src/functionalTest/resources/projects/" + projectName);
5050
}
5151

52+
protected File buildDir() {
53+
54+
return buildDir(projectDir());
55+
}
56+
57+
protected File buildDir(File projectDir) {
58+
59+
return projectDir.toPath().resolve("build").toFile();
60+
}
61+
5262
protected File reportDir() {
5363

5464
return reportDir(projectDir());
5565
}
5666

5767
protected File reportDir(File projectDir) {
5868

59-
return projectDir.toPath().resolve("build").resolve(ScoveragePlugin.getDEFAULT_REPORT_DIR()).toFile();
69+
return buildDir(projectDir).toPath().resolve(ScoveragePlugin.getDEFAULT_REPORT_DIR()).toFile();
6070
}
6171

6272
protected AssertableBuildResult run(String... arguments) {

src/functionalTest/resources/projects/scala-single-module/build.gradle

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -26,4 +26,10 @@ test {
2626

2727
checkScoverage {
2828
minimumRate = 0.5
29+
}
30+
31+
if (hasProperty("excludedFile")) {
32+
scoverage {
33+
excludedFiles = [excludedFile]
34+
}
2935
}

src/main/groovy/org/scoverage/ScoveragePlugin.groovy

Lines changed: 55 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -1,12 +1,16 @@
11
package org.scoverage
22

3+
import org.apache.commons.io.FileUtils
34
import org.gradle.api.Plugin
45
import org.gradle.api.Project
56
import org.gradle.api.invocation.Gradle
67
import org.gradle.api.plugins.PluginAware
78
import org.gradle.api.tasks.SourceSet
89
import org.gradle.api.tasks.bundling.Jar
9-
import org.gradle.util.GFileUtils
10+
11+
import java.nio.file.Files
12+
13+
import static groovy.io.FileType.FILES
1014

1115
class ScoveragePlugin implements Plugin<PluginAware> {
1216

@@ -82,18 +86,19 @@ class ScoveragePlugin implements Plugin<PluginAware> {
8286

8387
ScoverageRunner scoverageRunner = new ScoverageRunner(project.configurations.scoverage)
8488

89+
def originalSourceSet = project.sourceSets.getByName(SourceSet.MAIN_SOURCE_SET_NAME)
8590
def instrumentedSourceSet = project.sourceSets.create('scoverage') {
86-
def original = project.sourceSets.getByName(SourceSet.MAIN_SOURCE_SET_NAME)
8791

88-
resources.source(original.resources)
89-
scala.source(original.java)
90-
scala.source(original.scala)
92+
resources.source(originalSourceSet.resources)
93+
scala.source(originalSourceSet.java)
94+
scala.source(originalSourceSet.scala)
9195

92-
compileClasspath += original.compileClasspath + project.configurations.scoverage
93-
runtimeClasspath = it.output + project.configurations.scoverage + original.runtimeClasspath
96+
compileClasspath += originalSourceSet.compileClasspath + project.configurations.scoverage
97+
runtimeClasspath = it.output + project.configurations.scoverage + originalSourceSet.runtimeClasspath
9498
}
9599

96100
def compileTask = project.tasks[instrumentedSourceSet.getCompileTaskName("scala")]
101+
compileTask.mustRunAfter(originalSourceSet.getCompileTaskName("scala"))
97102
project.test.mustRunAfter(compileTask)
98103

99104
def scoverageJar = project.tasks.create('jarScoverage', Jar.class) {
@@ -127,7 +132,6 @@ class ScoveragePlugin implements Plugin<PluginAware> {
127132

128133
project.gradle.taskGraph.whenReady { graph ->
129134
if (graph.hasTask(reportTask)) {
130-
131135
project.test.configure {
132136
project.logger.debug("Adding instrumented classes to '${path}' classpath")
133137

@@ -164,6 +168,10 @@ class ScoveragePlugin implements Plugin<PluginAware> {
164168
}
165169

166170
compileTask.configure {
171+
doFirst {
172+
destinationDir.deleteDir()
173+
}
174+
167175
File pluginFile = project.configurations[CONFIGURATION_NAME].find {
168176
it.name.startsWith("scalac-scoverage-plugin")
169177
}
@@ -184,13 +192,49 @@ class ScoveragePlugin implements Plugin<PluginAware> {
184192
if (extension.highlighting.get()) {
185193
parameters.add('-Yrangepos')
186194
}
187-
doFirst {
188-
GFileUtils.deleteDirectory(destinationDir)
189-
}
190195
scalaCompileOptions.additionalParameters = parameters
191196
// the compile task creates a store of measured statements
192197
outputs.file(new File(extension.dataDir.get(), 'scoverage.coverage.xml'))
198+
199+
doLast {
200+
def originalCompileTaskName = project.sourceSets.getByName(SourceSet.MAIN_SOURCE_SET_NAME)
201+
.getCompileTaskName("scala")
202+
def originalDestinationDir = project.tasks[originalCompileTaskName].destinationDir
203+
204+
def findFiles = { File dir, Closure<Boolean> condition = null ->
205+
def files = []
206+
207+
if (dir.exists()) {
208+
dir.eachFileRecurse(FILES) { f ->
209+
if (condition == null || condition(f)) {
210+
def relativePath = dir.relativePath(f)
211+
files << relativePath
212+
}
213+
}
214+
}
215+
216+
return files
217+
}
218+
219+
def isSameFile = { String relativePath ->
220+
def fileA = new File(originalDestinationDir, relativePath)
221+
def fileB = new File(destinationDir, relativePath)
222+
return FileUtils.contentEquals(fileA, fileB)
223+
}
224+
225+
def originalClasses = findFiles(originalDestinationDir)
226+
def identicalInstrumentedClasses = findFiles(destinationDir, { f ->
227+
def relativePath = destinationDir.relativePath(f)
228+
return originalClasses.contains(relativePath) && isSameFile(relativePath)
229+
})
230+
231+
identicalInstrumentedClasses.each { f ->
232+
Files.deleteIfExists(destinationDir.toPath().resolve(f))
233+
}
234+
}
193235
}
194236
}
195237
}
238+
239+
196240
}

0 commit comments

Comments
 (0)