@@ -2,6 +2,7 @@ package scoverage
2
2
3
3
import sbt .Keys ._
4
4
import sbt ._
5
+ import scoverage .ScoverageKeys ._
5
6
import scoverage .report .{CoverageAggregator , CoberturaXmlWriter , ScoverageHtmlWriter , ScoverageXmlWriter }
6
7
7
8
object ScoverageSbtPlugin extends AutoPlugin {
@@ -40,7 +41,8 @@ object ScoverageSbtPlugin extends AutoPlugin {
40
41
coverageOutputHTML := true ,
41
42
coverageOutputCobertura := true ,
42
43
coverageOutputDebug := false ,
43
- coverageCleanSubprojectFiles := true
44
+ coverageCleanSubprojectFiles := true ,
45
+ coverageOutputTeamCity := false
44
46
)
45
47
46
48
/**
@@ -72,6 +74,7 @@ object ScoverageSbtPlugin extends AutoPlugin {
72
74
coverageOutputXML.value,
73
75
coverageOutputHTML.value,
74
76
coverageOutputDebug.value,
77
+ coverageOutputTeamCity.value,
75
78
log)
76
79
77
80
checkCoverage(cov, log, coverageMinimum.value, coverageFailOnMinimum.value)
@@ -94,6 +97,7 @@ object ScoverageSbtPlugin extends AutoPlugin {
94
97
coverageOutputXML.value,
95
98
coverageOutputHTML.value,
96
99
coverageOutputDebug.value,
100
+ coverageOutputTeamCity.value,
97
101
log)
98
102
val cfmt = cov.statementCoverageFormatted
99
103
log.info(s " Aggregation complete. Coverage was [ $cfmt] " )
@@ -145,6 +149,7 @@ object ScoverageSbtPlugin extends AutoPlugin {
145
149
coverageOutputXML : Boolean ,
146
150
coverageOutputHTML : Boolean ,
147
151
coverageDebug : Boolean ,
152
+ coverageOutputTeamCity : Boolean ,
148
153
log : Logger ): Unit = {
149
154
log.info(s " Generating scoverage reports... " )
150
155
@@ -170,10 +175,38 @@ object ScoverageSbtPlugin extends AutoPlugin {
170
175
log.info(s " Written HTML coverage report [ ${reportDir.getAbsolutePath}/index.html] " )
171
176
new ScoverageHtmlWriter (compileSourceDirectories, reportDir).write(coverage)
172
177
}
178
+ if (coverageOutputTeamCity) {
179
+ log.info(" Writing coverage report to teamcity" )
180
+ reportToTeamcity(coverage, coverageOutputHTML, reportDir, crossTarget, log)
181
+ }
173
182
183
+ log.info(s " Statement coverage.: ${coverage.statementCoverageFormatted}% " )
184
+ log.info(s " Branch coverage....: ${coverage.branchCoverageFormatted}% " )
174
185
log.info(" Coverage reports completed" )
175
186
}
176
187
188
+ private def reportToTeamcity (coverage : Coverage ,
189
+ createCoverageZip : Boolean ,
190
+ reportDir : File ,
191
+ crossTarget : File ,
192
+ log : Logger ) {
193
+
194
+
195
+ def statsKeyValue (key : String , value : Int ): String =
196
+ s " ##teamcity[buildStatisticValue key=' ${key}' value=' ${value}'] "
197
+
198
+ // Log statement coverage as per: https://devnet.jetbrains.com/message/5467985
199
+ log.info(statsKeyValue(" CodeCoverageAbsSCovered" , coverage.invokedStatementCount))
200
+ log.info(statsKeyValue(" CodeCoverageAbsSTotal" , coverage.statementCount))
201
+
202
+ // Log branch coverage as a custom metrics (in percent)
203
+ log.info(statsKeyValue(" CodeCoverageBranch" , " %.0f" .format(coverage.branchCoveragePercent).toInt))
204
+
205
+ // Create the coverage report for teamcity (HTML files)
206
+ if (createCoverageZip)
207
+ IO .zip(Path .allSubpaths(reportDir), crossTarget / " coverage.zip" )
208
+ }
209
+
177
210
private def loadCoverage (crossTarget : File , log : Logger ): Option [Coverage ] = {
178
211
179
212
val dataDir = crossTarget / " /scoverage-data"
0 commit comments