@@ -28,6 +28,11 @@ object ScoverageSbtPlugin extends AutoPlugin {
28
28
coverageExcludedPackages := " " ,
29
29
coverageExcludedFiles := " " ,
30
30
coverageMinimum := 0 , // default is no minimum
31
+ coverageMinimumBranchTotal := 0 ,
32
+ coverageMinimumStmtPerPackage := 0 ,
33
+ coverageMinimumBranchPerPackage := 0 ,
34
+ coverageMinimumStmtPerFile := 0 ,
35
+ coverageMinimumBranchPerFile := 0 ,
31
36
coverageFailOnMinimum := false ,
32
37
coverageHighlighting := true ,
33
38
coverageOutputXML := true ,
@@ -123,7 +128,7 @@ object ScoverageSbtPlugin extends AutoPlugin {
123
128
sourceEncoding((scalacOptions in (Compile )).value),
124
129
log)
125
130
126
- checkCoverage(cov, log, coverageMinimum .value, coverageFailOnMinimum.value)
131
+ checkCoverage(cov, log, coverageMinima .value, coverageFailOnMinimum.value)
127
132
case None => log.warn(" No coverage data, skipping reports" )
128
133
}
129
134
}
@@ -150,7 +155,7 @@ object ScoverageSbtPlugin extends AutoPlugin {
150
155
val cfmt = cov.statementCoverageFormatted
151
156
log.info(s " Aggregation complete. Coverage was [ $cfmt] " )
152
157
153
- checkCoverage(cov, log, coverageMinimum .value, coverageFailOnMinimum.value)
158
+ checkCoverage(cov, log, coverageMinima .value, coverageFailOnMinimum.value)
154
159
case None =>
155
160
log.info(" No subproject data to aggregate, skipping reports" )
156
161
}
@@ -244,28 +249,51 @@ object ScoverageSbtPlugin extends AutoPlugin {
244
249
245
250
private def checkCoverage (coverage : Coverage ,
246
251
log : Logger ,
247
- min : Double ,
252
+ min : CoverageMinima ,
248
253
failOnMin : Boolean ): Unit = {
254
+ val ok : Boolean = checkCoverage(coverage, " Total" , log, min.total) &&
255
+ coverage.packages.forall(x => checkCoverage(x, s " Package: ${x.name}" , log, min.perPackage)) &&
256
+ coverage.files.forall(x => checkCoverage(x, s " File: ${x.filename}" , log, min.perFile))
257
+
258
+ if (! ok && failOnMin)
259
+ throw new RuntimeException (" Coverage minimum was not reached" )
260
+
261
+ log.info(s " All done. Coverage was [ ${coverage.statementCoverageFormatted}%] " )
262
+ }
249
263
250
- val cper = coverage.statementCoveragePercent
251
- val cfmt = coverage.statementCoverageFormatted
264
+ private def checkCoverage (metrics : CoverageMetrics ,
265
+ metric : String ,
266
+ log : Logger ,
267
+ min : CoverageMinimum ): Boolean = {
268
+ checkCoverage(s " Branch: $metric" , log, min.branch, metrics.branchCoveragePercent) &&
269
+ checkCoverage(s " Stmt: $metric" , log, min.statement, metrics.statementCoveragePercent)
270
+ }
252
271
272
+ private def checkCoverage (metric : String ,
273
+ log : Logger ,
274
+ min : Double ,
275
+ cper : Double ): Boolean = {
253
276
// check for default minimum
254
- if (min > 0 ) {
277
+ if (min <= 0 ) {
278
+ true
279
+ } else {
255
280
def is100 (d : Double ) = Math .abs(100 - d) <= 0.00001
256
281
257
282
if (is100(min) && is100(cper)) {
258
- log.info(s " 100% Coverage ! " )
259
- } else if (min > cper) {
260
- log.error(s " Coverage is below minimum [ $cfmt% < $min%] " )
261
- if (failOnMin)
262
- throw new RuntimeException (" Coverage minimum was not reached" )
283
+ log.info(s " 100% Coverage: $metric" )
284
+ true
263
285
} else {
264
- log.info(s " Coverage is above minimum [ $cfmt% > $min%] " )
286
+ val ok : Boolean = min <= cper
287
+ val minfmt = scoverage.DoubleFormat .twoFractionDigits(min)
288
+ val cfmt = scoverage.DoubleFormat .twoFractionDigits(cper)
289
+ if (ok) {
290
+ log.info(s " Coverage is above minimum [ $cfmt% > $minfmt%]: $metric" )
291
+ } else {
292
+ log.error(s " Coverage is below minimum [ $cfmt% < $minfmt%]: $metric" )
293
+ }
294
+ ok
265
295
}
266
296
}
267
-
268
- log.info(s " All done. Coverage was [ $cfmt%] " )
269
297
}
270
298
271
299
private def sourceEncoding (scalacOptions : Seq [String ]): Option [String ] = {
0 commit comments