@@ -35,6 +35,11 @@ object ScoverageSbtPlugin extends AutoPlugin {
3535 coverageExcludedPackages := " " ,
3636 coverageExcludedFiles := " " ,
3737 coverageMinimum := 0 , // default is no minimum
38+ coverageMinimumBranchTotal := 0 ,
39+ coverageMinimumStmtPerPackage := 0 ,
40+ coverageMinimumBranchPerPackage := 0 ,
41+ coverageMinimumStmtPerFile := 0 ,
42+ coverageMinimumBranchPerFile := 0 ,
3843 coverageFailOnMinimum := false ,
3944 coverageHighlighting := true ,
4045 coverageOutputXML := true ,
@@ -156,7 +161,7 @@ object ScoverageSbtPlugin extends AutoPlugin {
156161 checkCoverage(
157162 cov,
158163 log,
159- coverageMinimum .value,
164+ coverageMinima .value,
160165 coverageFailOnMinimum.value
161166 )
162167 case None => log.warn(" No coverage data, skipping reports" )
@@ -190,7 +195,7 @@ object ScoverageSbtPlugin extends AutoPlugin {
190195 checkCoverage(
191196 cov,
192197 log,
193- coverageMinimum .value,
198+ coverageMinima .value,
194199 coverageFailOnMinimum.value
195200 )
196201 case None =>
@@ -329,29 +334,72 @@ object ScoverageSbtPlugin extends AutoPlugin {
329334 private def checkCoverage (
330335 coverage : Coverage ,
331336 log : Logger ,
332- min : Double ,
337+ min : CoverageMinima ,
333338 failOnMin : Boolean
334339 ): Unit = {
340+ val ok : Boolean = checkCoverage(coverage, " Total" , log, min.total) &&
341+ coverage.packages.forall(x =>
342+ checkCoverage(x, s " Package: ${x.name}" , log, min.perPackage)
343+ ) &&
344+ coverage.files.forall(x =>
345+ checkCoverage(x, s " File: ${x.filename}" , log, min.perFile)
346+ )
335347
336- val cper = coverage.statementCoveragePercent
337- val cfmt = coverage.statementCoverageFormatted
348+ if ( ! ok && failOnMin)
349+ throw new RuntimeException ( " Coverage minimum was not reached " )
338350
351+ log.info(
352+ s " All done. Coverage was [ ${coverage.statementCoverageFormatted}%] "
353+ )
354+ }
355+
356+ private def checkCoverage (
357+ metrics : CoverageMetrics ,
358+ metric : String ,
359+ log : Logger ,
360+ min : CoverageMinimum
361+ ): Boolean = {
362+ checkCoverage(
363+ s " Branch: $metric" ,
364+ log,
365+ min.branch,
366+ metrics.branchCoveragePercent
367+ ) &&
368+ checkCoverage(
369+ s " Stmt: $metric" ,
370+ log,
371+ min.statement,
372+ metrics.statementCoveragePercent
373+ )
374+ }
375+
376+ private def checkCoverage (
377+ metric : String ,
378+ log : Logger ,
379+ min : Double ,
380+ cper : Double
381+ ): Boolean = {
339382 // check for default minimum
340- if (min > 0 ) {
383+ if (min <= 0 ) {
384+ true
385+ } else {
341386 def is100 (d : Double ) = Math .abs(100 - d) <= 0.00001
342387
343388 if (is100(min) && is100(cper)) {
344- log.info(s " 100% Coverage ! " )
345- } else if (min > cper) {
346- log.error(s " Coverage is below minimum [ $cfmt% < $min%] " )
347- if (failOnMin)
348- throw new RuntimeException (" Coverage minimum was not reached" )
389+ log.debug(s " 100% Coverage: $metric" )
390+ true
349391 } else {
350- log.info(s " Coverage is above minimum [ $cfmt% > $min%] " )
392+ val ok : Boolean = min <= cper
393+ val minfmt = scoverage.DoubleFormat .twoFractionDigits(min)
394+ val cfmt = scoverage.DoubleFormat .twoFractionDigits(cper)
395+ if (ok) {
396+ log.debug(s " Coverage is above minimum [ $cfmt% > $minfmt%]: $metric" )
397+ } else {
398+ log.error(s " Coverage is below minimum [ $cfmt% < $minfmt%]: $metric" )
399+ }
400+ ok
351401 }
352402 }
353-
354- log.info(s " All done. Coverage was [ $cfmt%] " )
355403 }
356404
357405 private def sourceEncoding (scalacOptions : Seq [String ]): Option [String ] = {
0 commit comments