@@ -3,10 +3,14 @@ package scoverage
3
3
import sbt .Keys ._
4
4
import sbt ._
5
5
import sbt .plugins .JvmPlugin
6
- import scoverage .report .CoberturaXmlWriter
7
- import scoverage .report .CoverageAggregator
8
- import scoverage .report .ScoverageHtmlWriter
9
- import scoverage .report .ScoverageXmlWriter
6
+ import scoverage .reporter .CoberturaXmlWriter
7
+ import scoverage .domain .Constants
8
+ import scoverage .domain .Coverage
9
+ import scoverage .reporter .CoverageAggregator
10
+ import scoverage .reporter .IOUtils
11
+ import scoverage .reporter .ScoverageHtmlWriter
12
+ import scoverage .reporter .ScoverageXmlWriter
13
+ import scoverage .reporter .Deserializer
10
14
11
15
import java .time .Instant
12
16
@@ -15,6 +19,8 @@ object ScoverageSbtPlugin extends AutoPlugin {
15
19
val orgScoverage = " org.scoverage"
16
20
val scalacRuntimeArtifact = " scalac-scoverage-runtime"
17
21
val scalacPluginArtifact = " scalac-scoverage-plugin"
22
+ val scalacDomainArtifact = " scalac-scoverage-domain"
23
+ val scalacReporterArtifact = " scalac-scoverage-reporter"
18
24
val defaultScoverageVersion = BuildInfo .scoverageVersion
19
25
val autoImport = ScoverageKeys
20
26
lazy val ScoveragePluginConfig = config(" scoveragePlugin" ).hide
@@ -65,10 +71,21 @@ object ScoverageSbtPlugin extends AutoPlugin {
65
71
coverageDataDir := crossTarget.value
66
72
) ++ coverageSettings ++ scalacSettings
67
73
74
+ private def isScala2 (scalaVersion : String ) =
75
+ CrossVersion
76
+ .partialVersion(scalaVersion)
77
+ .collect { case (2 , _) =>
78
+ true
79
+ }
80
+ .getOrElse(false )
81
+
68
82
private lazy val coverageSettings = Seq (
69
83
libraryDependencies ++= {
70
- if (coverageEnabled.value) {
84
+ // TODO check will need to go here for Scala 3 to not add everthing
85
+ if (coverageEnabled.value && isScala2(scalaVersion.value)) {
71
86
Seq (
87
+ orgScoverage %% scalacDomainArtifact % coverageScalacPluginVersion.value,
88
+ orgScoverage %% scalacReporterArtifact % coverageScalacPluginVersion.value,
72
89
// We only add for "compile" because of macros. This setting could be optimed to just "test" if the handling
73
90
// of macro coverage was improved.
74
91
orgScoverage %% (scalacRuntime(
@@ -84,22 +101,40 @@ object ScoverageSbtPlugin extends AutoPlugin {
84
101
)
85
102
86
103
private lazy val scalacSettings = Seq (
104
+ // TODO check will need to go here for scala 3
87
105
Compile / compile / scalacOptions ++= {
88
106
val updateReport = update.value
89
- if (coverageEnabled.value) {
107
+ if (coverageEnabled.value && isScala2(scalaVersion.value) ) {
90
108
val scoverageDeps : Seq [File ] =
91
- updateReport matching configurationFilter(ScoveragePluginConfig .name)
92
- val pluginPath : File = scoverageDeps.find(
93
- _.getAbsolutePath.contains(scalacPluginArtifact)
94
- ) match {
95
- case None =>
96
- throw new Exception (
97
- s " Fatal: $scalacPluginArtifact not in libraryDependencies "
98
- )
99
- case Some (pluginPath) => pluginPath
109
+ updateReport.matching(configurationFilter(ScoveragePluginConfig .name))
110
+
111
+ // Since everything isn't contained in a single plugin jar since we
112
+ // want to share reporter/domain code between the plugin and the
113
+ // reporter which can be used for Scala3 we need to essentially put
114
+ // together the little classpath to pass in to the compiler which
115
+ // includes everything it needs for the compiler plugin phase:
116
+ // 1. the plugin jar
117
+ // 2. the domain jar
118
+ // NOTE: Even though you'd think that since plugin relies on domain
119
+ // it'd just auto include it... it doesn't.
120
+ // https://github.com/sbt/sbt/issues/2255
121
+ val pluginPaths = scoverageDeps.collect {
122
+ case path
123
+ if path.getAbsolutePath().contains(scalacPluginArtifact) || path
124
+ .getAbsolutePath()
125
+ .contains(scalacDomainArtifact) =>
126
+ path.getAbsolutePath()
100
127
}
128
+
129
+ if (pluginPaths.size != 2 )
130
+ throw new Exception (
131
+ s " Fatal: Not finding either $scalacDomainArtifact or $scalacPluginArtifact in libraryDependencies. "
132
+ )
133
+
101
134
Seq (
102
- Some (s " -Xplugin: ${pluginPath.getAbsolutePath}" ),
135
+ Some (
136
+ s " -Xplugin: ${pluginPaths.mkString(" :" )}"
137
+ ),
103
138
Some (
104
139
s " -P:scoverage:dataDir: ${coverageDataDir.value.getAbsolutePath}/scoverage-data "
105
140
),
@@ -116,6 +151,15 @@ object ScoverageSbtPlugin extends AutoPlugin {
116
151
// rangepos is broken in some releases of scala so option to turn it off
117
152
if (coverageHighlighting.value) Some (" -Yrangepos" ) else None
118
153
).flatten
154
+ } else if (
155
+ // TODO this is very temporary until support for this gets merged in.
156
+ // For now we restrict this to this exact SNAPSHOT version
157
+ coverageEnabled.value && scalaVersion.value == " 3.1.1-RC1-bin-SNAPSHOT"
158
+ ) {
159
+ Seq (
160
+ " -coverage" ,
161
+ s " ${coverageDataDir.value.getAbsolutePath()}/scoverage-data "
162
+ )
119
163
} else {
120
164
Nil
121
165
}
@@ -335,13 +379,13 @@ object ScoverageSbtPlugin extends AutoPlugin {
335
379
): Option [Coverage ] = {
336
380
337
381
val dataDir = crossTarget / " /scoverage-data"
338
- val coverageFile = Serializer .coverageFile(dataDir)
382
+ val coverageFile = Deserializer .coverageFile(dataDir)
339
383
340
384
log.info(s " Reading scoverage instrumentation [ $coverageFile] " )
341
385
342
386
if (coverageFile.exists) {
343
387
344
- val coverage = Serializer .deserialize(
388
+ val coverage = Deserializer .deserialize(
345
389
coverageFile,
346
390
sourceRoot
347
391
)
0 commit comments