@@ -3,10 +3,14 @@ package scoverage
33import sbt .Keys ._
44import sbt ._
55import 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
1014
1115import java .time .Instant
1216
@@ -15,6 +19,8 @@ object ScoverageSbtPlugin extends AutoPlugin {
1519 val orgScoverage = " org.scoverage"
1620 val scalacRuntimeArtifact = " scalac-scoverage-runtime"
1721 val scalacPluginArtifact = " scalac-scoverage-plugin"
22+ val scalacDomainArtifact = " scalac-scoverage-domain"
23+ val scalacReporterArtifact = " scalac-scoverage-reporter"
1824 val defaultScoverageVersion = BuildInfo .scoverageVersion
1925 val autoImport = ScoverageKeys
2026 lazy val ScoveragePluginConfig = config(" scoveragePlugin" ).hide
@@ -65,10 +71,21 @@ object ScoverageSbtPlugin extends AutoPlugin {
6571 coverageDataDir := crossTarget.value
6672 ) ++ coverageSettings ++ scalacSettings
6773
74+ private def isScala2 (scalaVersion : String ) =
75+ CrossVersion
76+ .partialVersion(scalaVersion)
77+ .collect { case (2 , _) =>
78+ true
79+ }
80+ .getOrElse(false )
81+
6882 private lazy val coverageSettings = Seq (
6983 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)) {
7186 Seq (
87+ orgScoverage %% scalacDomainArtifact % coverageScalacPluginVersion.value,
88+ orgScoverage %% scalacReporterArtifact % coverageScalacPluginVersion.value,
7289 // We only add for "compile" because of macros. This setting could be optimed to just "test" if the handling
7390 // of macro coverage was improved.
7491 orgScoverage %% (scalacRuntime(
@@ -84,22 +101,40 @@ object ScoverageSbtPlugin extends AutoPlugin {
84101 )
85102
86103 private lazy val scalacSettings = Seq (
104+ // TODO check will need to go here for scala 3
87105 Compile / compile / scalacOptions ++= {
88106 val updateReport = update.value
89- if (coverageEnabled.value) {
107+ if (coverageEnabled.value && isScala2(scalaVersion.value) ) {
90108 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()
100127 }
128+
129+ if (pluginPaths.size != 2 )
130+ throw new Exception (
131+ s " Fatal: Not finding either $scalacDomainArtifact or $scalacPluginArtifact in libraryDependencies. "
132+ )
133+
101134 Seq (
102- Some (s " -Xplugin: ${pluginPath.getAbsolutePath}" ),
135+ Some (
136+ s " -Xplugin: ${pluginPaths.mkString(" :" )}"
137+ ),
103138 Some (
104139 s " -P:scoverage:dataDir: ${coverageDataDir.value.getAbsolutePath}/scoverage-data "
105140 ),
@@ -116,6 +151,15 @@ object ScoverageSbtPlugin extends AutoPlugin {
116151 // rangepos is broken in some releases of scala so option to turn it off
117152 if (coverageHighlighting.value) Some (" -Yrangepos" ) else None
118153 ).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+ )
119163 } else {
120164 Nil
121165 }
@@ -335,13 +379,13 @@ object ScoverageSbtPlugin extends AutoPlugin {
335379 ): Option [Coverage ] = {
336380
337381 val dataDir = crossTarget / " /scoverage-data"
338- val coverageFile = Serializer .coverageFile(dataDir)
382+ val coverageFile = Deserializer .coverageFile(dataDir)
339383
340384 log.info(s " Reading scoverage instrumentation [ $coverageFile] " )
341385
342386 if (coverageFile.exists) {
343387
344- val coverage = Serializer .deserialize(
388+ val coverage = Deserializer .deserialize(
345389 coverageFile,
346390 sourceRoot
347391 )
0 commit comments