Skip to content

Commit 89171f3

Browse files
committed
Adding coverageExclude task.
1 parent 12aac64 commit 89171f3

File tree

2 files changed

+53
-11
lines changed

2 files changed

+53
-11
lines changed

src/main/scala/scoverage/ScoverageKeys.scala

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,7 @@ object ScoverageKeys {
88
"controls whether code instrumentation is enabled or not"
99
)
1010
lazy val coverageReport = taskKey[Unit]("run report generation")
11+
lazy val coverageExclude = taskKey[Unit]("exclude/remove files and packages from coverage file (after the fact)")
1112
lazy val coverageAggregate = taskKey[Unit]("aggregate reports from subprojects")
1213
lazy val coverageExcludedPackages = settingKey[String]("regex for excluded packages")
1314
lazy val coverageExcludedFiles = settingKey[String]("regex for excluded file paths")

src/main/scala/scoverage/ScoverageSbtPlugin.scala

Lines changed: 52 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -13,6 +13,8 @@ import scoverage.reporter.ScoverageXmlWriter
1313
import scoverage.serialize.Serializer
1414

1515
import java.time.Instant
16+
import scala.tools.nsc.reporters.NoReporter
17+
import scala.tools.nsc
1618

1719
object ScoverageSbtPlugin extends AutoPlugin {
1820

@@ -66,6 +68,7 @@ object ScoverageSbtPlugin extends AutoPlugin {
6668
override def projectSettings: Seq[Setting[_]] = Seq(
6769
ivyConfigurations += ScoveragePluginConfig,
6870
coverageReport := coverageReport0.value,
71+
coverageExclude := coverageExclude0.value,
6972
coverageAggregate := coverageAggregate0.value,
7073
coverageAggregate / aggregate := false,
7174
coverageDataDir := crossTarget.value
@@ -192,11 +195,45 @@ object ScoverageSbtPlugin extends AutoPlugin {
192195
sjsClassifier getOrElse ""
193196
}
194197

198+
private lazy val coverageExclude0 = Def.task {
199+
implicit val log = streams.value.log
200+
201+
val dataDir = coverageDataDir.value / "scoverage-data"
202+
val coverageFile = Serializer.coverageFile(dataDir)
203+
204+
if (!coverageFile.exists) {
205+
log.warn(s"No coverage data found. [$coverageFile] does not exits. Run >sbt coverage test< first.")
206+
} else {
207+
log.info(s"Reading scoverage instrumentation [$coverageFile] ...")
208+
val sourceRoot = coverageSourceRoot.value.getAbsoluteFile()
209+
val coverage = Serializer.deserialize(coverageFile, sourceRoot)
210+
211+
val filter = new RegexCoverageFilter(
212+
coverageExcludedPackages.value.split(";"),
213+
coverageExcludedFiles.value.split(";"),
214+
ScoverageOptions.default().excludedSymbols,
215+
new nsc.reporters.ConsoleReporter(new nsc.Settings())
216+
)
217+
218+
val statements = coverage.statements
219+
log.info(s"Filtering [${statements.size}] statements ...")
220+
val statementsToBeExcluded = statements.filter(
221+
s => !filter.isClassIncluded(s.location.fullClassName) || !filter.isFileIncluded(s.location.sourcePath) || !filter.isSymbolIncluded(s.symbolName)
222+
)
223+
224+
log.info(s"Statements to be excluded [${statementsToBeExcluded.size}] ...")
225+
statementsToBeExcluded.foreach(s => coverage.remove(s.id))
226+
227+
log.info(s"(Re)Writing scoverage instrumentation [$coverageFile] ...")
228+
Serializer.serialize(coverage, coverageFile, sourceRoot)
229+
}
230+
}
231+
195232
private lazy val coverageReport0 = Def.task {
196233
val target = coverageDataDir.value
197234
implicit val log = streams.value.log
198235

199-
log.info(s"Waiting for measurement data to sync...")
236+
log.info(s"Waiting for measurement data to sync ...")
200237
Thread.sleep(
201238
1000
202239
) // have noticed some delay in writing on windows, hacky but works
@@ -222,14 +259,17 @@ object ScoverageSbtPlugin extends AutoPlugin {
222259

223260
CoverageMinimum.all.value
224261
.checkCoverage(cov, coverageFailOnMinimum.value)
225-
case None => log.warn("No coverage data, skipping reports")
262+
263+
case None =>
264+
log.warn(s"No coverage data found in [$target]. Run >sbt coverage test< first.")
226265
}
227266
}
228267

229268
private lazy val coverageAggregate0 = Def.task {
269+
val target = coverageDataDir.value
230270
implicit val log = streams.value.log
231-
log.info(s"Aggregating coverage from subprojects...")
232271

272+
log.info(s"Aggregating coverage from subprojects ...")
233273
val dataDirs = coverageDataDir.?.all(aggregateFilter).value
234274
.collect {
235275
case Some(file) if (file / Constants.DataDir).isDirectory =>
@@ -239,7 +279,7 @@ object ScoverageSbtPlugin extends AutoPlugin {
239279
CoverageAggregator.aggregate(dataDirs, coverageSourceRoot.value) match {
240280
case Some(cov) =>
241281
writeReports(
242-
coverageDataDir.value,
282+
target,
243283
sourceDirectories.all(aggregateFilter).value.flatten,
244284
cov,
245285
coverageOutputCobertura.value,
@@ -255,8 +295,9 @@ object ScoverageSbtPlugin extends AutoPlugin {
255295

256296
CoverageMinimum.all.value
257297
.checkCoverage(cov, coverageFailOnMinimum.value)
298+
258299
case None =>
259-
log.info("No subproject data to aggregate, skipping reports")
300+
log.warn(s"No coverage data found to aggregate in [$target]. Run >sbt coverage test< first.")
260301
}
261302
}
262303

@@ -272,7 +313,7 @@ object ScoverageSbtPlugin extends AutoPlugin {
272313
coverageSourceEncoding: Option[String],
273314
log: Logger
274315
): Unit = {
275-
log.info(s"Generating scoverage reports...")
316+
log.info(s"Generating scoverage reports ...")
276317

277318
val coberturaDir = crossTarget / "coverage-report"
278319
val reportDir = crossTarget / "scoverage-report"
@@ -337,8 +378,8 @@ object ScoverageSbtPlugin extends AutoPlugin {
337378
log.info("Written coverage report to TeamCity")
338379
}
339380

340-
log.info(s"Statement coverage.: ${coverage.statementCoverageFormatted}%")
341-
log.info(s"Branch coverage....: ${coverage.branchCoverageFormatted}%")
381+
log.info(s"Statement coverage: ${coverage.statementCoverageFormatted}%")
382+
log.info(s"Branch coverage: ${coverage.branchCoverageFormatted}%")
342383
log.info("Coverage reports completed")
343384
}
344385

@@ -386,10 +427,10 @@ object ScoverageSbtPlugin extends AutoPlugin {
386427
sourceRoot: File
387428
): Option[Coverage] = {
388429

389-
val dataDir = crossTarget / "/scoverage-data"
430+
val dataDir = crossTarget / "scoverage-data"
390431
val coverageFile = Serializer.coverageFile(dataDir)
391432

392-
log.info(s"Reading scoverage instrumentation [$coverageFile]")
433+
log.info(s"Reading scoverage instrumentation [$coverageFile] ...")
393434

394435
if (coverageFile.exists) {
395436

@@ -398,7 +439,7 @@ object ScoverageSbtPlugin extends AutoPlugin {
398439
sourceRoot
399440
)
400441

401-
log.info(s"Reading scoverage measurements...")
442+
log.info(s"Reading scoverage measurements ...")
402443
val measurementFiles = IOUtils.findMeasurementFiles(dataDir)
403444
val measurements = IOUtils.invoked(measurementFiles)
404445
coverage.apply(measurements)

0 commit comments

Comments
 (0)