Skip to content

Commit 56f2732

Browse files
committed
Add Scala 3 support
1 parent 5d41789 commit 56f2732

File tree

13 files changed

+220
-26
lines changed

13 files changed

+220
-26
lines changed

README.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -69,7 +69,7 @@ This can be set as project property.
6969

7070
##### Scala version configuration
7171

72-
Plugin supports Scala 2.12.x and 2.13.x versions by automatically loading and configuring matching `scalac-scoverage-plugin` Scalac SCoverage Plugin artifact. For this to work Scala version has to be set. It can be done by defining `scalaVersion` plugin configuration parameter or `scala.version` project property. Without this setting, coverage will not be calculated.
72+
Plugin supports Scala 2.12.8+, 2.13.0+ and 3.2.0+ versions by automatically loading and configuring matching `scalac-scoverage-plugin` Scalac SCoverage Plugin artifact. For this to work Scala version has to be set. It can be done by defining `scalaVersion` plugin configuration parameter or `scala.version` project property. Without this setting, coverage will not be calculated.
7373

7474
```xml
7575
<project>

src/it/integration_tests_parent/pom.xml

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -26,12 +26,13 @@
2626
<scala.compat.version>2.13</scala.compat.version>
2727
<scala.minor.version>12</scala.minor.version>
2828
<scala.version>${scala.compat.version}.${scala.minor.version}</scala.version>
29+
<scala.library.artifact.id>scala-library</scala.library.artifact.id>
2930
</properties>
3031

3132
<dependencies>
3233
<dependency>
3334
<groupId>org.scala-lang</groupId>
34-
<artifactId>scala-library</artifactId>
35+
<artifactId>${scala.library.artifact.id}</artifactId>
3536
<version>${scala.version}</version>
3637
</dependency>
3738

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
invoker.goals=clean verify site -e -ntp
Lines changed: 46 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,46 @@
1+
<?xml version="1.0" encoding="UTF-8"?>
2+
3+
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
4+
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/maven-v4_0_0.xsd">
5+
<modelVersion>4.0.0</modelVersion>
6+
7+
<parent>
8+
<groupId>it.scoverage-maven-plugin</groupId>
9+
<artifactId>integration_tests_parent</artifactId>
10+
<version>1.0-SNAPSHOT</version>
11+
<relativePath>../integration_tests_parent/pom.xml</relativePath>
12+
</parent>
13+
14+
<artifactId>test_ScalaMavenPlugin_Scala32Plus_ScalaTest</artifactId>
15+
<version>1.0-SNAPSHOT</version>
16+
<packaging>jar</packaging>
17+
<name>Test Scoverage Report using scala-maven-plugin, Scala 3.2+ and ScalaTest</name>
18+
<description>Test Scoverage Report using scala-maven-plugin, Scala 3.2+ and ScalaTest</description>
19+
20+
<properties>
21+
<scala.compat.version>3</scala.compat.version>
22+
<scala.version>3.3.1</scala.version>
23+
<scala.library.artifact.id>scala3-library_3</scala.library.artifact.id>
24+
</properties>
25+
26+
<build>
27+
<plugins>
28+
<plugin>
29+
<groupId>org.apache.maven.plugins</groupId>
30+
<artifactId>maven-compiler-plugin</artifactId>
31+
</plugin>
32+
<plugin>
33+
<groupId>net.alchim31.maven</groupId>
34+
<artifactId>scala-maven-plugin</artifactId>
35+
</plugin>
36+
<plugin>
37+
<groupId>org.scalatest</groupId>
38+
<artifactId>scalatest-maven-plugin</artifactId>
39+
</plugin>
40+
<plugin>
41+
<groupId>@project.groupId@</groupId>
42+
<artifactId>@project.artifactId@</artifactId>
43+
</plugin>
44+
</plugins>
45+
</build>
46+
</project>
Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,6 @@
1+
package service
2+
3+
object HelloServiceScala {
4+
def hello = { "Hello" }
5+
6+
}
Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,12 @@
1+
package service
2+
3+
import org.scalatest.wordspec.AnyWordSpec
4+
5+
class HelloServiceScalaTest extends AnyWordSpec {
6+
7+
"HelloService" should {
8+
"say hello" in {
9+
assert(HelloServiceScala.hello == "Hello")
10+
}
11+
}
12+
}
Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,19 @@
1+
try {
2+
3+
def logFile = new File(basedir, "build.log")
4+
def lines = logFile.readLines()
5+
assert lines.contains("[INFO] Statement coverage.: 100.00%")
6+
assert lines.contains("[INFO] Branch coverage....: 100.00%")
7+
8+
def scoverageFile = new File(basedir, "target/scoverage.xml")
9+
assert scoverageFile.exists()
10+
11+
def reportFile = new File(basedir, "target/site/scoverage/index.html")
12+
assert reportFile.exists()
13+
14+
return true
15+
16+
} catch (Throwable e) {
17+
e.printStackTrace()
18+
return false
19+
}
Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
invoker.goals=clean verify site -e -ntp
Lines changed: 54 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,54 @@
1+
<?xml version="1.0" encoding="UTF-8"?>
2+
3+
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
4+
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/maven-v4_0_0.xsd">
5+
<modelVersion>4.0.0</modelVersion>
6+
7+
<parent>
8+
<groupId>it.scoverage-maven-plugin</groupId>
9+
<artifactId>integration_tests_parent</artifactId>
10+
<version>1.0-SNAPSHOT</version>
11+
<relativePath>../integration_tests_parent/pom.xml</relativePath>
12+
</parent>
13+
14+
<artifactId>test_ScalaMavenPlugin_Scala32Plus_ScalaTest_ScalaVersion_Not_Set</artifactId>
15+
<version>1.0-SNAPSHOT</version>
16+
<packaging>jar</packaging>
17+
<name>Test Scoverage Report using scala-maven-plugin, Scala 3.2+ and ScalaTest when scala.version is not set</name>
18+
<description>Test Scoverage Report using scala-maven-plugin, Scala 3.2+ and ScalaTest when scala.version is not set</description>
19+
20+
<properties>
21+
<scala.compat.version>3</scala.compat.version>
22+
<scala.version/>
23+
<scala.library.artifact.id>scala3-library_3</scala.library.artifact.id>
24+
</properties>
25+
26+
<dependencies>
27+
<dependency>
28+
<groupId>org.scala-lang</groupId>
29+
<artifactId>${scala.library.artifact.id}</artifactId>
30+
<version>3.3.1</version>
31+
</dependency>
32+
</dependencies>
33+
34+
<build>
35+
<plugins>
36+
<plugin>
37+
<groupId>org.apache.maven.plugins</groupId>
38+
<artifactId>maven-compiler-plugin</artifactId>
39+
</plugin>
40+
<plugin>
41+
<groupId>net.alchim31.maven</groupId>
42+
<artifactId>scala-maven-plugin</artifactId>
43+
</plugin>
44+
<plugin>
45+
<groupId>org.scalatest</groupId>
46+
<artifactId>scalatest-maven-plugin</artifactId>
47+
</plugin>
48+
<plugin>
49+
<groupId>@project.groupId@</groupId>
50+
<artifactId>@project.artifactId@</artifactId>
51+
</plugin>
52+
</plugins>
53+
</build>
54+
</project>
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,6 @@
1+
package service
2+
3+
object HelloServiceScala {
4+
def hello = { "Hello" }
5+
6+
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,12 @@
1+
package service
2+
3+
import org.scalatest.wordspec.AnyWordSpec
4+
5+
class HelloServiceScalaTest extends AnyWordSpec {
6+
7+
"HelloService" should {
8+
"say hello" in {
9+
assert(HelloServiceScala.hello == "Hello")
10+
}
11+
}
12+
}
Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,19 @@
1+
try {
2+
3+
def logFile = new File(basedir, "build.log")
4+
def lines = logFile.readLines()
5+
assert lines.contains("[INFO] Statement coverage.: 100.00%")
6+
assert lines.contains("[INFO] Branch coverage....: 100.00%")
7+
8+
def scoverageFile = new File(basedir, "target/scoverage.xml")
9+
assert scoverageFile.exists()
10+
11+
def reportFile = new File(basedir, "target/site/scoverage/index.html")
12+
assert reportFile.exists()
13+
14+
return true
15+
16+
} catch (Throwable e) {
17+
e.printStackTrace()
18+
return false
19+
}

src/main/java/org/scoverage/plugin/SCoveragePreCompileMojo.java

Lines changed: 41 additions & 24 deletions
Original file line numberDiff line numberDiff line change
@@ -24,9 +24,7 @@
2424
import java.io.OutputStreamWriter;
2525
import java.util.*;
2626
import java.util.stream.Collectors;
27-
import java.util.stream.Stream;
2827

29-
import edu.emory.mathcs.backport.java.util.Arrays;
3028
import org.apache.maven.artifact.Artifact;
3129
import org.apache.maven.artifact.factory.ArtifactFactory;
3230
import org.apache.maven.artifact.repository.ArtifactRepository;
@@ -228,6 +226,7 @@ public void execute() throws MojoExecutionException
228226

229227
String scalaBinaryVersion = null;
230228
String resolvedScalaVersion = resolveScalaVersion();
229+
boolean scala2 = true;
231230
if ( resolvedScalaVersion != null )
232231
{
233232
if ( "2.12".equals( resolvedScalaVersion ) || resolvedScalaVersion.startsWith( "2.12." ) )
@@ -238,9 +237,14 @@ else if ( "2.13".equals( resolvedScalaVersion ) || resolvedScalaVersion.startsWi
238237
{
239238
scalaBinaryVersion = "2.13";
240239
}
240+
else if ( resolvedScalaVersion.compareTo("3.2.") > 0 ) // Scala 3 is supported from 3.2.0
241+
{
242+
scalaBinaryVersion = "3";
243+
scala2 = false;
244+
}
241245
else
242246
{
243-
getLog().warn( String.format( "Skipping SCoverage execution - unsupported Scala version \"%s\"",
247+
getLog().warn( String.format( "Skipping SCoverage execution - unsupported Scala version \"%s\". Supported Scala versions are 2.12.8+, 2.13.0+ and 3.2.0+ .",
244248
resolvedScalaVersion ) );
245249
return;
246250
}
@@ -278,16 +282,18 @@ else if ( "2.13".equals( resolvedScalaVersion ) || resolvedScalaVersion.startsWi
278282

279283
try
280284
{
281-
List<Artifact> pluginArtifacts = getScalaScoveragePluginArtifacts( resolvedScalaVersion, scalaBinaryVersion );
282-
Artifact runtimeArtifact = getScalaScoverageRuntimeArtifact( scalaBinaryVersion );
283-
284-
addScoverageDependenciesToClasspath( runtimeArtifact );
285+
List<Artifact> pluginArtifacts = getScalaScoveragePluginArtifacts( resolvedScalaVersion, scalaBinaryVersion, scala2 );
286+
if ( scala2 ) // Scala 3 doesn't need scalac-scoverage-runtime
287+
{
288+
Artifact runtimeArtifact = getScalaScoverageRuntimeArtifact( scalaBinaryVersion );
289+
addScoverageDependenciesToClasspath( runtimeArtifact );
290+
}
285291

286-
String arg = DATA_DIR_OPTION + dataDirectory.getAbsolutePath();
292+
String arg = ( scala2 ? SCALA2_DATA_DIR_OPTION : SCALA3_COVERAGE_OUT_OPTION ) + dataDirectory.getAbsolutePath();
287293
String _scalacOptions = quoteArgument( arg );
288294
String addScalacArgs = arg;
289295

290-
arg = SOURCE_ROOT_OPTION + project.getBasedir().getAbsolutePath();
296+
arg = scala2 ? ( SOURCE_ROOT_OPTION + project.getBasedir().getAbsolutePath() ) : "";
291297
_scalacOptions = _scalacOptions + SPACE + quoteArgument( arg );
292298
addScalacArgs = addScalacArgs + PIPE + arg;
293299

@@ -305,17 +311,19 @@ else if ( "2.13".equals( resolvedScalaVersion ) || resolvedScalaVersion.startsWi
305311
addScalacArgs = addScalacArgs + PIPE + arg;
306312
}
307313

308-
if ( highlighting )
314+
if ( highlighting && scala2 )
309315
{
310316
_scalacOptions = _scalacOptions + SPACE + "-Yrangepos";
311317
addScalacArgs = addScalacArgs + PIPE + "-Yrangepos";
312318
}
313319

314-
String _scalacPlugins = pluginArtifacts.stream()
315-
.map(x -> String.format("%s:%s:%s", x.getGroupId(), x.getArtifactId(),x.getVersion())).collect(Collectors.joining(" "));
320+
String _scalacPlugins = scala2 ? pluginArtifacts.stream()
321+
.map(x -> String.format("%s:%s:%s", x.getGroupId(), x.getArtifactId(), x.getVersion())).collect(Collectors.joining(" ")) : "";
316322

317-
arg = PLUGIN_OPTION + pluginArtifacts.stream().map(x -> x.getFile().getAbsolutePath()).collect(Collectors.joining(String.valueOf(java.io.File.pathSeparatorChar)));
318-
addScalacArgs = addScalacArgs + PIPE + arg;
323+
if ( scala2 ) {
324+
arg = PLUGIN_OPTION + pluginArtifacts.stream().map(x -> x.getFile().getAbsolutePath()).collect(Collectors.joining(String.valueOf(java.io.File.pathSeparatorChar)));
325+
addScalacArgs = addScalacArgs + PIPE + arg;
326+
}
319327

320328
Properties projectProperties = project.getProperties();
321329

@@ -358,9 +366,11 @@ else if ( "2.13".equals( resolvedScalaVersion ) || resolvedScalaVersion.startsWi
358366
// Private utility methods
359367

360368
private static final String SCALA_LIBRARY_GROUP_ID = "org.scala-lang";
361-
private static final String SCALA_LIBRARY_ARTIFACT_ID = "scala-library";
369+
private static final String SCALA2_LIBRARY_ARTIFACT_ID = "scala-library";
370+
private static final String SCALA3_LIBRARY_ARTIFACT_ID = "scala3-library_3";
362371

363-
private static final String DATA_DIR_OPTION = "-P:scoverage:dataDir:";
372+
private static final String SCALA2_DATA_DIR_OPTION = "-P:scoverage:dataDir:";
373+
private static final String SCALA3_COVERAGE_OUT_OPTION = "-coverage-out:";
364374
private static final String SOURCE_ROOT_OPTION = "-P:scoverage:sourceRoot:";
365375
private static final String EXCLUDED_PACKAGES_OPTION = "-P:scoverage:excludedPackages:";
366376
private static final String EXCLUDED_FILES_OPTION = "-P:scoverage:excludedFiles:";
@@ -378,15 +388,19 @@ private String quoteArgument( String arg )
378388
private String resolveScalaVersion()
379389
{
380390
String result = scalaVersion;
381-
if ( result == null )
391+
if ( result == null || result.isEmpty() )
382392
{
383393
// check project direct dependencies (transitive dependencies cannot be checked in this Maven lifecycle phase)
384394
@SuppressWarnings( "unchecked" )
385395
List<Dependency> dependencies = project.getDependencies();
386396
for ( Dependency dependency: dependencies )
387397
{
388398
if ( SCALA_LIBRARY_GROUP_ID.equals( dependency.getGroupId() )
389-
&& SCALA_LIBRARY_ARTIFACT_ID.equals( dependency.getArtifactId() ) )
399+
&& (
400+
SCALA2_LIBRARY_ARTIFACT_ID.equals( dependency.getArtifactId() ) ||
401+
SCALA3_LIBRARY_ARTIFACT_ID.equals( dependency.getArtifactId() )
402+
)
403+
)
390404
{
391405
result = dependency.getVersion();
392406
break;
@@ -428,22 +442,25 @@ private ArtifactVersion getScalacPluginVersion() {
428442
}
429443
}
430444

431-
private List<Artifact> getScalaScoveragePluginArtifacts(String resolvedScalaVersion, String scalaMainVersion )
445+
private List<Artifact> getScalaScoveragePluginArtifacts( String resolvedScalaVersion, String scalaBinaryVersion, boolean scala2 )
432446
throws ArtifactNotFoundException, ArtifactResolutionException
433447
{
434448
String resolvedScalacPluginVersion = getScalacPluginVersion().toString();
435449
List<Artifact> resolvedArtifacts = new ArrayList<>();
436-
resolvedArtifacts.add(getResolvedArtifact("org.scoverage", "scalac-scoverage-plugin_" + resolvedScalaVersion, resolvedScalacPluginVersion));
437-
resolvedArtifacts.add(getResolvedArtifact("org.scoverage", "scalac-scoverage-domain_" + scalaMainVersion, resolvedScalacPluginVersion));
438-
resolvedArtifacts.add(getResolvedArtifact("org.scoverage", "scalac-scoverage-serializer_" + scalaMainVersion, resolvedScalacPluginVersion));
450+
if ( scala2 ) // Scala 3 doesn't need scalac-scoverage-plugin
451+
{
452+
resolvedArtifacts.add(getResolvedArtifact("org.scoverage", "scalac-scoverage-plugin_" + resolvedScalaVersion, resolvedScalacPluginVersion));
453+
}
454+
resolvedArtifacts.add(getResolvedArtifact("org.scoverage", "scalac-scoverage-domain_" + scalaBinaryVersion, resolvedScalacPluginVersion));
455+
resolvedArtifacts.add(getResolvedArtifact("org.scoverage", "scalac-scoverage-serializer_" + scalaBinaryVersion, resolvedScalacPluginVersion));
439456
return resolvedArtifacts;
440457
}
441458

442-
private Artifact getScalaScoverageRuntimeArtifact( String scalaMainVersion )
459+
private Artifact getScalaScoverageRuntimeArtifact( String scalaBinaryVersion )
443460
throws ArtifactNotFoundException, ArtifactResolutionException
444461
{
445462
return getResolvedArtifact(
446-
"org.scoverage", "scalac-scoverage-runtime_" + scalaMainVersion,
463+
"org.scoverage", "scalac-scoverage-runtime_" + scalaBinaryVersion,
447464
getScalacPluginVersion().toString() );
448465
}
449466

0 commit comments

Comments
 (0)