22
22
23
23
import org .apache .maven .plugin .AbstractMojo ;
24
24
import org .apache .maven .plugin .MojoFailureException ;
25
+ import org .apache .maven .plugin .logging .Log ;
25
26
import org .apache .maven .plugins .annotations .Execute ;
26
27
import org .apache .maven .plugins .annotations .LifecyclePhase ;
27
28
import org .apache .maven .plugins .annotations .Mojo ;
28
29
import org .apache .maven .plugins .annotations .Parameter ;
29
30
import org .apache .maven .project .MavenProject ;
30
31
31
32
import scala .Predef$ ;
33
+ import scala .collection .JavaConversions ;
32
34
33
35
import scoverage .Coverage ;
34
36
import scoverage .IOUtils ;
@@ -68,7 +70,7 @@ public class SCoverageCheckMojo
68
70
private File dataDirectory ;
69
71
70
72
/**
71
- * Required minimum coverage.
73
+ * Required minimum total statement coverage.
72
74
* <br>
73
75
* <br>
74
76
* See <a href="https://github.com/scoverage/sbt-scoverage#minimum-coverage">https://github.com/scoverage/sbt-scoverage#minimum-coverage</a> for additional documentation.
@@ -79,6 +81,56 @@ public class SCoverageCheckMojo
79
81
@ Parameter ( property = "scoverage.minimumCoverage" , defaultValue = "0" )
80
82
private Double minimumCoverage ;
81
83
84
+ /**
85
+ * Required minimum total branch coverage.
86
+ * <br>
87
+ * <br>
88
+ * See <a href="https://github.com/scoverage/sbt-scoverage#minimum-coverage">https://github.com/scoverage/sbt-scoverage#minimum-coverage</a> for additional documentation.
89
+ * <br>
90
+ */
91
+ @ Parameter ( property = "scoverage.minimumCoverage.BranchTotal" , defaultValue = "0" )
92
+ private Double minimumCoverageBranchTotal ;
93
+
94
+ /**
95
+ * Required minimum per-package statement coverage.
96
+ * <br>
97
+ * <br>
98
+ * See <a href="https://github.com/scoverage/sbt-scoverage#minimum-coverage">https://github.com/scoverage/sbt-scoverage#minimum-coverage</a> for additional documentation.
99
+ * <br>
100
+ */
101
+ @ Parameter ( property = "scoverage.minimumCoverage.StmtPerPackage" , defaultValue = "0" )
102
+ private Double minimumCoverageStmtPerPackage ;
103
+
104
+ /**
105
+ * Required minimum per-package branch coverage.
106
+ * <br>
107
+ * <br>
108
+ * See <a href="https://github.com/scoverage/sbt-scoverage#minimum-coverage">https://github.com/scoverage/sbt-scoverage#minimum-coverage</a> for additional documentation.
109
+ * <br>
110
+ */
111
+ @ Parameter ( property = "scoverage.minimumCoverage.BranchPerPackage" , defaultValue = "0" )
112
+ private Double minimumCoverageBranchPerPackage ;
113
+
114
+ /**
115
+ * Required minimum per-file statement coverage.
116
+ * <br>
117
+ * <br>
118
+ * See <a href="https://github.com/scoverage/sbt-scoverage#minimum-coverage">https://github.com/scoverage/sbt-scoverage#minimum-coverage</a> for additional documentation.
119
+ * <br>
120
+ */
121
+ @ Parameter ( property = "scoverage.minimumCoverage.StmtPerFile" , defaultValue = "0" )
122
+ private Double minimumCoverageStmtPerFile ;
123
+
124
+ /**
125
+ * Required minimum per-file branch coverage.
126
+ * <br>
127
+ * <br>
128
+ * See <a href="https://github.com/scoverage/sbt-scoverage#minimum-coverage">https://github.com/scoverage/sbt-scoverage#minimum-coverage</a> for additional documentation.
129
+ * <br>
130
+ */
131
+ @ Parameter ( property = "scoverage.minimumCoverage.BranchPerFile" , defaultValue = "0" )
132
+ private Double minimumCoverageBranchPerFile ;
133
+
82
134
/**
83
135
* Fail the build if minimum coverage was not reached.
84
136
* <br>
@@ -160,27 +212,23 @@ public void execute() throws MojoFailureException
160
212
getLog ().info ( String .format ( "Branch coverage....: %s%%" , coverage .branchCoverageFormatted () ) );
161
213
getLog ().debug ( String .format ( "invokedBranchesCount:%d / branchCount:%d, invokedStatementCount:%d / statementCount:%d" ,
162
214
invokedBranchesCount , branchCount , invokedStatementCount , statementCount ) );
163
- if ( minimumCoverage > 0.0 )
215
+
216
+ boolean ok = checkCoverage ( getLog (), "Total" , coverage ,
217
+ minimumCoverage , minimumCoverageBranchTotal );
218
+ for ( scoverage .MeasuredPackage pkgCoverage : JavaConversions .asJavaIterable ( coverage .packages () ) )
164
219
{
165
- String minimumCoverageFormatted = scoverage .DoubleFormat .twoFractionDigits ( minimumCoverage );
166
- if ( is100 ( minimumCoverage ) && is100 ( coverage .statementCoveragePercent () ) )
167
- {
168
- getLog ().info ( "100% Coverage !" );
169
- }
170
- else if ( coverage .statementCoveragePercent () < minimumCoverage )
171
- {
172
- getLog ().error ( String .format ( "Coverage is below minimum [%s%% < %s%%]" ,
173
- coverage .statementCoverageFormatted (), minimumCoverageFormatted ) );
174
- if ( failOnMinimumCoverage )
175
- {
176
- throw new MojoFailureException ( "Coverage minimum was not reached" );
177
- }
178
- }
179
- else
180
- {
181
- getLog ().info ( String .format ( "Coverage is above minimum [%s%% >= %s%%]" ,
182
- coverage .statementCoverageFormatted (), minimumCoverageFormatted ) );
183
- }
220
+ ok &= checkCoverage ( getLog (), "Package:" + pkgCoverage .name (), pkgCoverage ,
221
+ minimumCoverageStmtPerPackage , minimumCoverageBranchPerPackage );
222
+ }
223
+ for ( scoverage .MeasuredFile fileCoverage : JavaConversions .asJavaIterable ( coverage .files () ) )
224
+ {
225
+ ok &= checkCoverage ( getLog (), "File:" + fileCoverage .filename (), fileCoverage ,
226
+ minimumCoverageStmtPerFile , minimumCoverageBranchPerFile );
227
+ }
228
+
229
+ if ( !ok && failOnMinimumCoverage )
230
+ {
231
+ throw new MojoFailureException ( "Coverage minimum was not reached" );
184
232
}
185
233
186
234
long te = System .currentTimeMillis ();
@@ -189,9 +237,47 @@ else if ( coverage.statementCoveragePercent() < minimumCoverage )
189
237
190
238
// Private utility methods
191
239
192
- private boolean is100 ( Double d )
240
+ private static boolean is100 ( Double d )
193
241
{
194
242
return Math .abs ( 100 - d ) <= 0.00001d ;
195
243
}
196
244
197
- }
245
+ private static boolean checkCoverage ( Log logger , String metric , scoverage .CoverageMetrics metrics ,
246
+ double minimumStmt , double minimimBranch )
247
+ {
248
+ return
249
+ checkCoverage ( logger , "Statement:" + metric , minimumStmt , metrics .statementCoveragePercent () ) &&
250
+ checkCoverage ( logger , "Branch:" + metric , minimimBranch , metrics .branchCoveragePercent () );
251
+ }
252
+
253
+ private static boolean checkCoverage ( Log logger , String metric , double minimum , double actual )
254
+ {
255
+ if ( minimum <= 0 )
256
+ {
257
+ return true ;
258
+ }
259
+
260
+ if ( is100 ( minimum ) && is100 ( actual ) )
261
+ {
262
+ logger .debug ( String .format ( "Coverage is 100%: %s!" , metric ));
263
+ return true ;
264
+ }
265
+
266
+ String minimumFormatted = scoverage .DoubleFormat .twoFractionDigits ( minimum );
267
+ String actualFormatted = scoverage .DoubleFormat .twoFractionDigits ( actual );
268
+ boolean ok = minimum <= actual ;
269
+
270
+ if ( ok )
271
+ {
272
+ logger .debug ( String .format ( "Coverage is above minimum [%s%% >= %s%%]: %s" ,
273
+ actualFormatted , minimumFormatted , metric ) );
274
+ }
275
+ else
276
+ {
277
+ logger .error ( String .format ( "Coverage is below minimum [%s%% < %s%%]: %s" ,
278
+ actualFormatted , minimumFormatted , metric ) );
279
+ }
280
+
281
+ return ok ;
282
+ }
283
+ }
0 commit comments