@@ -13,6 +13,8 @@ import scoverage.reporter.ScoverageXmlWriter
13
13
import scoverage .serialize .Serializer
14
14
15
15
import java .time .Instant
16
+ import scala .tools .nsc .reporters .NoReporter
17
+ import scala .tools .nsc
16
18
17
19
object ScoverageSbtPlugin extends AutoPlugin {
18
20
@@ -66,6 +68,7 @@ object ScoverageSbtPlugin extends AutoPlugin {
66
68
override def projectSettings : Seq [Setting [_]] = Seq (
67
69
ivyConfigurations += ScoveragePluginConfig ,
68
70
coverageReport := coverageReport0.value,
71
+ coverageExclude := coverageExclude0.value,
69
72
coverageAggregate := coverageAggregate0.value,
70
73
coverageAggregate / aggregate := false ,
71
74
coverageDataDir := crossTarget.value
@@ -192,11 +195,45 @@ object ScoverageSbtPlugin extends AutoPlugin {
192
195
sjsClassifier getOrElse " "
193
196
}
194
197
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
+
195
232
private lazy val coverageReport0 = Def .task {
196
233
val target = coverageDataDir.value
197
234
implicit val log = streams.value.log
198
235
199
- log.info(s " Waiting for measurement data to sync... " )
236
+ log.info(s " Waiting for measurement data to sync ... " )
200
237
Thread .sleep(
201
238
1000
202
239
) // have noticed some delay in writing on windows, hacky but works
@@ -222,14 +259,17 @@ object ScoverageSbtPlugin extends AutoPlugin {
222
259
223
260
CoverageMinimum .all.value
224
261
.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. " )
226
265
}
227
266
}
228
267
229
268
private lazy val coverageAggregate0 = Def .task {
269
+ val target = coverageDataDir.value
230
270
implicit val log = streams.value.log
231
- log.info(s " Aggregating coverage from subprojects... " )
232
271
272
+ log.info(s " Aggregating coverage from subprojects ... " )
233
273
val dataDirs = coverageDataDir.? .all(aggregateFilter).value
234
274
.collect {
235
275
case Some (file) if (file / Constants .DataDir ).isDirectory =>
@@ -239,7 +279,7 @@ object ScoverageSbtPlugin extends AutoPlugin {
239
279
CoverageAggregator .aggregate(dataDirs, coverageSourceRoot.value) match {
240
280
case Some (cov) =>
241
281
writeReports(
242
- coverageDataDir.value ,
282
+ target ,
243
283
sourceDirectories.all(aggregateFilter).value.flatten,
244
284
cov,
245
285
coverageOutputCobertura.value,
@@ -255,8 +295,9 @@ object ScoverageSbtPlugin extends AutoPlugin {
255
295
256
296
CoverageMinimum .all.value
257
297
.checkCoverage(cov, coverageFailOnMinimum.value)
298
+
258
299
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. " )
260
301
}
261
302
}
262
303
@@ -272,7 +313,7 @@ object ScoverageSbtPlugin extends AutoPlugin {
272
313
coverageSourceEncoding : Option [String ],
273
314
log : Logger
274
315
): Unit = {
275
- log.info(s " Generating scoverage reports... " )
316
+ log.info(s " Generating scoverage reports ... " )
276
317
277
318
val coberturaDir = crossTarget / " coverage-report"
278
319
val reportDir = crossTarget / " scoverage-report"
@@ -337,8 +378,8 @@ object ScoverageSbtPlugin extends AutoPlugin {
337
378
log.info(" Written coverage report to TeamCity" )
338
379
}
339
380
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}% " )
342
383
log.info(" Coverage reports completed" )
343
384
}
344
385
@@ -386,10 +427,10 @@ object ScoverageSbtPlugin extends AutoPlugin {
386
427
sourceRoot : File
387
428
): Option [Coverage ] = {
388
429
389
- val dataDir = crossTarget / " / scoverage-data"
430
+ val dataDir = crossTarget / " scoverage-data"
390
431
val coverageFile = Serializer .coverageFile(dataDir)
391
432
392
- log.info(s " Reading scoverage instrumentation [ $coverageFile] " )
433
+ log.info(s " Reading scoverage instrumentation [ $coverageFile] ... " )
393
434
394
435
if (coverageFile.exists) {
395
436
@@ -398,7 +439,7 @@ object ScoverageSbtPlugin extends AutoPlugin {
398
439
sourceRoot
399
440
)
400
441
401
- log.info(s " Reading scoverage measurements... " )
442
+ log.info(s " Reading scoverage measurements ... " )
402
443
val measurementFiles = IOUtils .findMeasurementFiles(dataDir)
403
444
val measurements = IOUtils .invoked(measurementFiles)
404
445
coverage.apply(measurements)
0 commit comments