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