Skip to content

Commit 76a39fb

Browse files
jozicckipp01
authored andcommitted
Support file and package exclusions for Scala 3.4.2+
1 parent e1df4f7 commit 76a39fb

File tree

11 files changed

+126
-26
lines changed

11 files changed

+126
-26
lines changed

README.md

+3-2
Original file line numberDiff line numberDiff line change
@@ -90,8 +90,7 @@ coverageExcludedFiles := ".*\\/two\\/GoodCoverage;.*\\/three\\/.*"
9090

9191
Note: The `.scala` file extension needs to be omitted from the filename, if one is given.
9292

93-
Note: These two options only work for Scala2. Right now Scala3 does not support
94-
a way to exclude packages or files from being instrumented.
93+
Note: These two options only work for Scala2 and Scala 3.4.2+.
9594

9695
You can also mark sections of code with comments like:
9796

@@ -104,6 +103,8 @@ You can also mark sections of code with comments like:
104103
Any code between two such comments will not be instrumented or included in the
105104
coverage report.
106105

106+
Note: Comments exclusion works only for Scala2.
107+
107108
### Minimum coverage
108109

109110
Based on minimum coverage, you can fail the build with the following keys:

src/main/scala/scoverage/ScoverageSbtPlugin.scala

+49-20
Original file line numberDiff line numberDiff line change
@@ -75,18 +75,28 @@ object ScoverageSbtPlugin extends AutoPlugin {
7575
private def isScala2(scalaVersion: String) =
7676
CrossVersion
7777
.partialVersion(scalaVersion)
78-
.collect { case (2, _) =>
79-
true
78+
.exists {
79+
case (2, _) => true
80+
case _ => false
8081
}
81-
.getOrElse(false)
8282

8383
private def isScala3SupportingScoverage(scalaVersion: String) =
8484
CrossVersion
8585
.partialVersion(scalaVersion)
86-
.collect {
86+
.exists {
8787
case (3, minor) if minor >= 2 => true
88+
case _ => false
89+
}
90+
91+
private def isScala3SupportingFilePackageExclusion(scalaVersion: String) = {
92+
def patch = scalaVersion.split('.').drop(2).headOption
93+
CrossVersion
94+
.partialVersion(scalaVersion)
95+
.exists {
96+
case (3, minor) if minor >= 4 && patch.exists(_ >= "2") => true
97+
case _ => false
8898
}
89-
.getOrElse(false)
99+
}
90100

91101
private lazy val coverageSettings = Seq(
92102
libraryDependencies ++= {
@@ -114,6 +124,18 @@ object ScoverageSbtPlugin extends AutoPlugin {
114124

115125
implicit val log = streams.value.log
116126

127+
val excludedPackages =
128+
Option(coverageExcludedPackages.value.trim).filter(_.nonEmpty)
129+
val excludedFiles = Option(coverageExcludedFiles.value.trim)
130+
.filter(_.nonEmpty)
131+
.map(v =>
132+
// On windows, replace unix file separators with windows file
133+
// separators. Note that we need to replace / with \\ because
134+
// the plugin treats this string as a regular expression and
135+
// backslashes must be escaped in regular expressions.
136+
if (isWindows) v.replace("/", """\\""") else v
137+
)
138+
117139
val updateReport = update.value
118140
if (coverageEnabled.value && isScala2(scalaVersion.value)) {
119141
val scoverageDeps: Seq[File] =
@@ -156,19 +178,8 @@ object ScoverageSbtPlugin extends AutoPlugin {
156178
Some(
157179
s"-P:scoverage:sourceRoot:${coverageSourceRoot.value.getAbsolutePath}"
158180
),
159-
Option(coverageExcludedPackages.value.trim)
160-
.filter(_.nonEmpty)
161-
.map(v => s"-P:scoverage:excludedPackages:$v"),
162-
Option(coverageExcludedFiles.value.trim)
163-
.filter(_.nonEmpty)
164-
.map(v =>
165-
// On windows, replace unix file separators with windows file
166-
// separators. Note that we need to replace / with \\ because
167-
// the plugin treats this string as a regular expression and
168-
// backslashes must be escaped in regular expressions.
169-
if (isWindows) v.replace("/", """\\""") else v
170-
)
171-
.map(v => s"-P:scoverage:excludedFiles:$v"),
181+
excludedPackages.map(v => s"-P:scoverage:excludedPackages:$v"),
182+
excludedFiles.map(v => s"-P:scoverage:excludedFiles:$v"),
172183
Some("-P:scoverage:reportTestName"),
173184
// rangepos is broken in some releases of scala so option to turn it off
174185
if (coverageHighlighting.value) Some("-Yrangepos") else None
@@ -177,8 +188,26 @@ object ScoverageSbtPlugin extends AutoPlugin {
177188
coverageEnabled.value && isScala3SupportingScoverage(scalaVersion.value)
178189
) {
179190
Seq(
180-
s"-coverage-out:${coverageDataDir.value.getAbsolutePath()}/scoverage-data"
181-
)
191+
Some(
192+
s"-coverage-out:${coverageDataDir.value.getAbsolutePath()}/scoverage-data"
193+
),
194+
excludedPackages
195+
.collect {
196+
case v
197+
if isScala3SupportingFilePackageExclusion(
198+
scalaVersion.value
199+
) =>
200+
s"-coverage-exclude-classlikes:$v"
201+
},
202+
excludedFiles
203+
.collect {
204+
case v
205+
if isScala3SupportingFilePackageExclusion(
206+
scalaVersion.value
207+
) =>
208+
s"-coverage-exclude-files:$v"
209+
}
210+
).flatten
182211
} else if (coverageEnabled.value && !isScala2(scalaVersion.value)) {
183212
log.warn(
184213
"coverage in Scala 3 needs at least 3.2.x. Please update your Scala version and try again."

src/sbt-test/scoverage/scala3-coverage-excluded-files/build.sbt

+1-1
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
version := "0.1"
22

3-
scalaVersion := "3.2.0-RC1"
3+
scalaVersion := "3.4.2"
44

55
libraryDependencies += "org.scalameta" %% "munit" % "0.7.29" % Test
66

src/sbt-test/scoverage/scala3-coverage-excluded-files/test

+1-3
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,4 @@
44
> test
55
> coverageReport
66
# There should be no directory for the excluded files
7-
#-$ exists target/scala-3.2.0-RC1/scoverage-report/two
8-
# But right now there is, because Scala3 does not support excluding files
9-
$ exists target/scala-3.2.0-RC1/scoverage-report/two
7+
-$ exists target/scala-3.4.2/scoverage-report/two
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,13 @@
1+
version := "0.1"
2+
3+
scalaVersion := "3.4.2"
4+
5+
libraryDependencies += "org.scalameta" %% "munit" % "0.7.29" % Test
6+
7+
coverageExcludedPackages := "two\\..*"
8+
9+
resolvers ++= {
10+
if (sys.props.get("plugin.version").exists(_.endsWith("-SNAPSHOT")))
11+
Seq(Resolver.sonatypeRepo("snapshots"))
12+
else Seq.empty
13+
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
sbt.version=1.9.9
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,16 @@
1+
val pluginVersion = sys.props.getOrElse(
2+
"plugin.version",
3+
throw new RuntimeException(
4+
"""|The system property 'plugin.version' is not defined.
5+
|Specify this property using the scriptedLaunchOpts -D.""".stripMargin
6+
)
7+
)
8+
9+
addSbtPlugin("org.scoverage" % "sbt-scoverage" % pluginVersion)
10+
11+
resolvers ++= {
12+
if (pluginVersion.endsWith("-SNAPSHOT"))
13+
Seq(Resolver.sonatypeRepo("snapshots"))
14+
else
15+
Seq.empty
16+
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,7 @@
1+
object GoodCoverage {
2+
3+
def sum(num1: Int, num2: Int) = {
4+
if (0 == num1) num2 else if (0 == num2) num1 else num1 + num2
5+
}
6+
7+
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,9 @@
1+
package two
2+
3+
object GoodCoverage {
4+
5+
def sum(num1: Int, num2: Int) = {
6+
if (0 == num1) num2 else if (0 == num2) num1 else num1 + num2
7+
}
8+
9+
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,19 @@
1+
import munit.FunSuite
2+
3+
/** Created by tbarke001c on 7/8/14.
4+
*/
5+
class GoodCoverageSpec extends FunSuite {
6+
7+
test("GoodCoverage should sum two numbers") {
8+
assertEquals(GoodCoverage.sum(1, 2), 3)
9+
assertEquals(GoodCoverage.sum(0, 3), 3)
10+
assertEquals(GoodCoverage.sum(3, 0), 3)
11+
}
12+
13+
test("two.GoodCoverage should sum two numbers") {
14+
assertEquals(two.GoodCoverage.sum(1, 2), 3)
15+
assertEquals(two.GoodCoverage.sum(0, 3), 3)
16+
assertEquals(two.GoodCoverage.sum(3, 0), 3)
17+
}
18+
19+
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,7 @@
1+
# run scoverage using the coverage task
2+
> clean
3+
> coverage
4+
> test
5+
> coverageReport
6+
# There should be no directory for the excluded package
7+
-$ exists target/scala-3.4.2/scoverage-report/two

0 commit comments

Comments
 (0)