23
23
24
24
import org .apache .maven .plugin .AbstractMojo ;
25
25
import org .apache .maven .plugin .MojoFailureException ;
26
+ import org .apache .maven .plugin .logging .Log ;
26
27
import org .apache .maven .plugins .annotations .Execute ;
27
28
import org .apache .maven .plugins .annotations .LifecyclePhase ;
28
29
import org .apache .maven .plugins .annotations .Mojo ;
33
34
import scala .jdk .javaapi .CollectionConverters ;
34
35
35
36
import scoverage .domain .Coverage ;
37
+ import scoverage .domain .CoverageMetrics ;
38
+ import scoverage .domain .DoubleFormat ;
39
+ import scoverage .domain .MeasuredFile ;
40
+ import scoverage .domain .MeasuredPackage ;
36
41
import scoverage .reporter .IOUtils ;
37
42
import scoverage .serialize .Serializer ;
38
43
@@ -70,7 +75,7 @@ public class SCoverageCheckMojo
70
75
private File dataDirectory ;
71
76
72
77
/**
73
- * Required minimum coverage.
78
+ * Required minimum total statement coverage.
74
79
* <br>
75
80
* <br>
76
81
* See <a href="https://github.com/scoverage/sbt-scoverage#minimum-coverage">https://github.com/scoverage/sbt-scoverage#minimum-coverage</a> for additional documentation.
@@ -81,6 +86,56 @@ public class SCoverageCheckMojo
81
86
@ Parameter ( property = "scoverage.minimumCoverage" , defaultValue = "0" )
82
87
private Double minimumCoverage ;
83
88
89
+ /**
90
+ * Required minimum total branch coverage.
91
+ * <br>
92
+ * <br>
93
+ * See <a href="https://github.com/scoverage/sbt-scoverage#minimum-coverage">https://github.com/scoverage/sbt-scoverage#minimum-coverage</a> for additional documentation.
94
+ * <br>
95
+ */
96
+ @ Parameter ( property = "scoverage.minimumCoverageBranchTotal" , defaultValue = "0" )
97
+ private Double minimumCoverageBranchTotal ;
98
+
99
+ /**
100
+ * Required minimum per-package statement coverage.
101
+ * <br>
102
+ * <br>
103
+ * See <a href="https://github.com/scoverage/sbt-scoverage#minimum-coverage">https://github.com/scoverage/sbt-scoverage#minimum-coverage</a> for additional documentation.
104
+ * <br>
105
+ */
106
+ @ Parameter ( property = "scoverage.minimumCoverageStmtPerPackage" , defaultValue = "0" )
107
+ private Double minimumCoverageStmtPerPackage ;
108
+
109
+ /**
110
+ * Required minimum per-package branch coverage.
111
+ * <br>
112
+ * <br>
113
+ * See <a href="https://github.com/scoverage/sbt-scoverage#minimum-coverage">https://github.com/scoverage/sbt-scoverage#minimum-coverage</a> for additional documentation.
114
+ * <br>
115
+ */
116
+ @ Parameter ( property = "scoverage.minimumCoverageBranchPerPackage" , defaultValue = "0" )
117
+ private Double minimumCoverageBranchPerPackage ;
118
+
119
+ /**
120
+ * Required minimum per-file statement coverage.
121
+ * <br>
122
+ * <br>
123
+ * See <a href="https://github.com/scoverage/sbt-scoverage#minimum-coverage">https://github.com/scoverage/sbt-scoverage#minimum-coverage</a> for additional documentation.
124
+ * <br>
125
+ */
126
+ @ Parameter ( property = "scoverage.minimumCoverageStmtPerFile" , defaultValue = "0" )
127
+ private Double minimumCoverageStmtPerFile ;
128
+
129
+ /**
130
+ * Required minimum per-file branch coverage.
131
+ * <br>
132
+ * <br>
133
+ * See <a href="https://github.com/scoverage/sbt-scoverage#minimum-coverage">https://github.com/scoverage/sbt-scoverage#minimum-coverage</a> for additional documentation.
134
+ * <br>
135
+ */
136
+ @ Parameter ( property = "scoverage.minimumCoverageBranchPerFile" , defaultValue = "0" )
137
+ private Double minimumCoverageBranchPerFile ;
138
+
84
139
/**
85
140
* Fail the build if minimum coverage was not reached.
86
141
* <br>
@@ -172,27 +227,23 @@ public void execute() throws MojoFailureException
172
227
getLog ().info ( String .format ( "Branch coverage....: %s%%" , coverage .branchCoverageFormatted () ) );
173
228
getLog ().debug ( String .format ( "invokedBranchesCount:%d / branchCount:%d, invokedStatementCount:%d / statementCount:%d" ,
174
229
invokedBranchesCount , branchCount , invokedStatementCount , statementCount ) );
175
- if ( minimumCoverage > 0.0 )
230
+
231
+ boolean ok = checkCoverage ( getLog (), "Total" , coverage ,
232
+ minimumCoverage , minimumCoverageBranchTotal );
233
+ for ( MeasuredPackage pkgCoverage : CollectionConverters .asJava ( coverage .packages () ) )
176
234
{
177
- String minimumCoverageFormatted = scoverage .domain .DoubleFormat .twoFractionDigits ( minimumCoverage );
178
- if ( is100 ( minimumCoverage ) && is100 ( coverage .statementCoveragePercent () ) )
179
- {
180
- getLog ().info ( "100% Coverage !" );
181
- }
182
- else if ( coverage .statementCoveragePercent () < minimumCoverage )
183
- {
184
- getLog ().error ( String .format ( "Coverage is below minimum [%s%% < %s%%]" ,
185
- coverage .statementCoverageFormatted (), minimumCoverageFormatted ) );
186
- if ( failOnMinimumCoverage )
187
- {
188
- throw new MojoFailureException ( "Coverage minimum was not reached" );
189
- }
190
- }
191
- else
192
- {
193
- getLog ().info ( String .format ( "Coverage is above minimum [%s%% >= %s%%]" ,
194
- coverage .statementCoverageFormatted (), minimumCoverageFormatted ) );
195
- }
235
+ ok &= checkCoverage ( getLog (), "Package:" + pkgCoverage .name (), pkgCoverage ,
236
+ minimumCoverageStmtPerPackage , minimumCoverageBranchPerPackage );
237
+ }
238
+ for ( MeasuredFile fileCoverage : CollectionConverters .asJava ( coverage .files () ) )
239
+ {
240
+ ok &= checkCoverage ( getLog (), "File:" + fileCoverage .filename (), fileCoverage ,
241
+ minimumCoverageStmtPerFile , minimumCoverageBranchPerFile );
242
+ }
243
+
244
+ if ( !ok && failOnMinimumCoverage )
245
+ {
246
+ throw new MojoFailureException ( "Coverage minimum was not reached" );
196
247
}
197
248
198
249
long te = System .currentTimeMillis ();
@@ -201,9 +252,47 @@ else if ( coverage.statementCoveragePercent() < minimumCoverage )
201
252
202
253
// Private utility methods
203
254
204
- private boolean is100 ( Double d )
255
+ private static boolean is100 ( Double d )
205
256
{
206
257
return Math .abs ( 100 - d ) <= 0.00001d ;
207
258
}
208
259
209
- }
260
+ private static boolean checkCoverage ( Log logger , String metric , CoverageMetrics metrics ,
261
+ double minimumStmt , double minimimBranch )
262
+ {
263
+ return
264
+ checkCoverage ( logger , "Statement:" + metric , minimumStmt , metrics .statementCoveragePercent () ) &&
265
+ checkCoverage ( logger , "Branch:" + metric , minimimBranch , metrics .branchCoveragePercent () );
266
+ }
267
+
268
+ private static boolean checkCoverage ( Log logger , String metric , double minimum , double actual )
269
+ {
270
+ if ( minimum <= 0 )
271
+ {
272
+ return true ;
273
+ }
274
+
275
+ if ( is100 ( minimum ) && is100 ( actual ) )
276
+ {
277
+ logger .debug ( String .format ( "Coverage is 100%: %s!" , metric ));
278
+ return true ;
279
+ }
280
+
281
+ String minimumFormatted = DoubleFormat .twoFractionDigits ( minimum );
282
+ String actualFormatted = DoubleFormat .twoFractionDigits ( actual );
283
+ boolean ok = minimum <= actual ;
284
+
285
+ if ( ok )
286
+ {
287
+ logger .debug ( String .format ( "Coverage is above minimum [%s%% >= %s%%]: %s" ,
288
+ actualFormatted , minimumFormatted , metric ) );
289
+ }
290
+ else
291
+ {
292
+ logger .error ( String .format ( "Coverage is below minimum [%s%% < %s%%]: %s" ,
293
+ actualFormatted , minimumFormatted , metric ) );
294
+ }
295
+
296
+ return ok ;
297
+ }
298
+ }
0 commit comments