Skip to content

Commit

Permalink
Add Scala 3 support
Browse files Browse the repository at this point in the history
  • Loading branch information
jozic committed Dec 17, 2023
1 parent 5d41789 commit 56f2732
Show file tree
Hide file tree
Showing 13 changed files with 220 additions and 26 deletions.
2 changes: 1 addition & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -69,7 +69,7 @@ This can be set as project property.

##### Scala version configuration

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.
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.

```xml
<project>
Expand Down
3 changes: 2 additions & 1 deletion src/it/integration_tests_parent/pom.xml
Original file line number Diff line number Diff line change
Expand Up @@ -26,12 +26,13 @@
<scala.compat.version>2.13</scala.compat.version>
<scala.minor.version>12</scala.minor.version>
<scala.version>${scala.compat.version}.${scala.minor.version}</scala.version>
<scala.library.artifact.id>scala-library</scala.library.artifact.id>
</properties>

<dependencies>
<dependency>
<groupId>org.scala-lang</groupId>
<artifactId>scala-library</artifactId>
<artifactId>${scala.library.artifact.id}</artifactId>
<version>${scala.version}</version>
</dependency>

Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
invoker.goals=clean verify site -e -ntp
46 changes: 46 additions & 0 deletions src/it/test_ScalaMavenPlugin_Scala32Plus_ScalaTest/pom.xml
Original file line number Diff line number Diff line change
@@ -0,0 +1,46 @@
<?xml version="1.0" encoding="UTF-8"?>

<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/maven-v4_0_0.xsd">
<modelVersion>4.0.0</modelVersion>

<parent>
<groupId>it.scoverage-maven-plugin</groupId>
<artifactId>integration_tests_parent</artifactId>
<version>1.0-SNAPSHOT</version>
<relativePath>../integration_tests_parent/pom.xml</relativePath>
</parent>

<artifactId>test_ScalaMavenPlugin_Scala32Plus_ScalaTest</artifactId>
<version>1.0-SNAPSHOT</version>
<packaging>jar</packaging>
<name>Test Scoverage Report using scala-maven-plugin, Scala 3.2+ and ScalaTest</name>
<description>Test Scoverage Report using scala-maven-plugin, Scala 3.2+ and ScalaTest</description>

<properties>
<scala.compat.version>3</scala.compat.version>
<scala.version>3.3.1</scala.version>
<scala.library.artifact.id>scala3-library_3</scala.library.artifact.id>
</properties>

<build>
<plugins>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-compiler-plugin</artifactId>
</plugin>
<plugin>
<groupId>net.alchim31.maven</groupId>
<artifactId>scala-maven-plugin</artifactId>
</plugin>
<plugin>
<groupId>org.scalatest</groupId>
<artifactId>scalatest-maven-plugin</artifactId>
</plugin>
<plugin>
<groupId>@project.groupId@</groupId>
<artifactId>@project.artifactId@</artifactId>
</plugin>
</plugins>
</build>
</project>
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
package service

object HelloServiceScala {
def hello = { "Hello" }

}
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
package service

import org.scalatest.wordspec.AnyWordSpec

class HelloServiceScalaTest extends AnyWordSpec {

"HelloService" should {
"say hello" in {
assert(HelloServiceScala.hello == "Hello")
}
}
}
19 changes: 19 additions & 0 deletions src/it/test_ScalaMavenPlugin_Scala32Plus_ScalaTest/validate.groovy
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
try {

def logFile = new File(basedir, "build.log")
def lines = logFile.readLines()
assert lines.contains("[INFO] Statement coverage.: 100.00%")
assert lines.contains("[INFO] Branch coverage....: 100.00%")

def scoverageFile = new File(basedir, "target/scoverage.xml")
assert scoverageFile.exists()

def reportFile = new File(basedir, "target/site/scoverage/index.html")
assert reportFile.exists()

return true

} catch (Throwable e) {
e.printStackTrace()
return false
}
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
invoker.goals=clean verify site -e -ntp
Original file line number Diff line number Diff line change
@@ -0,0 +1,54 @@
<?xml version="1.0" encoding="UTF-8"?>

<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/maven-v4_0_0.xsd">
<modelVersion>4.0.0</modelVersion>

<parent>
<groupId>it.scoverage-maven-plugin</groupId>
<artifactId>integration_tests_parent</artifactId>
<version>1.0-SNAPSHOT</version>
<relativePath>../integration_tests_parent/pom.xml</relativePath>
</parent>

<artifactId>test_ScalaMavenPlugin_Scala32Plus_ScalaTest_ScalaVersion_Not_Set</artifactId>
<version>1.0-SNAPSHOT</version>
<packaging>jar</packaging>
<name>Test Scoverage Report using scala-maven-plugin, Scala 3.2+ and ScalaTest when scala.version is not set</name>
<description>Test Scoverage Report using scala-maven-plugin, Scala 3.2+ and ScalaTest when scala.version is not set</description>

<properties>
<scala.compat.version>3</scala.compat.version>
<scala.version/>
<scala.library.artifact.id>scala3-library_3</scala.library.artifact.id>
</properties>

<dependencies>
<dependency>
<groupId>org.scala-lang</groupId>
<artifactId>${scala.library.artifact.id}</artifactId>
<version>3.3.1</version>
</dependency>
</dependencies>

<build>
<plugins>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-compiler-plugin</artifactId>
</plugin>
<plugin>
<groupId>net.alchim31.maven</groupId>
<artifactId>scala-maven-plugin</artifactId>
</plugin>
<plugin>
<groupId>org.scalatest</groupId>
<artifactId>scalatest-maven-plugin</artifactId>
</plugin>
<plugin>
<groupId>@project.groupId@</groupId>
<artifactId>@project.artifactId@</artifactId>
</plugin>
</plugins>
</build>
</project>
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
package service

object HelloServiceScala {
def hello = { "Hello" }

}
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
package service

import org.scalatest.wordspec.AnyWordSpec

class HelloServiceScalaTest extends AnyWordSpec {

"HelloService" should {
"say hello" in {
assert(HelloServiceScala.hello == "Hello")
}
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
try {

def logFile = new File(basedir, "build.log")
def lines = logFile.readLines()
assert lines.contains("[INFO] Statement coverage.: 100.00%")
assert lines.contains("[INFO] Branch coverage....: 100.00%")

def scoverageFile = new File(basedir, "target/scoverage.xml")
assert scoverageFile.exists()

def reportFile = new File(basedir, "target/site/scoverage/index.html")
assert reportFile.exists()

return true

} catch (Throwable e) {
e.printStackTrace()
return false
}
65 changes: 41 additions & 24 deletions src/main/java/org/scoverage/plugin/SCoveragePreCompileMojo.java
Original file line number Diff line number Diff line change
Expand Up @@ -24,9 +24,7 @@
import java.io.OutputStreamWriter;
import java.util.*;
import java.util.stream.Collectors;
import java.util.stream.Stream;

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

String scalaBinaryVersion = null;
String resolvedScalaVersion = resolveScalaVersion();
boolean scala2 = true;
if ( resolvedScalaVersion != null )
{
if ( "2.12".equals( resolvedScalaVersion ) || resolvedScalaVersion.startsWith( "2.12." ) )
Expand All @@ -238,9 +237,14 @@ else if ( "2.13".equals( resolvedScalaVersion ) || resolvedScalaVersion.startsWi
{
scalaBinaryVersion = "2.13";
}
else if ( resolvedScalaVersion.compareTo("3.2.") > 0 ) // Scala 3 is supported from 3.2.0
{
scalaBinaryVersion = "3";
scala2 = false;
}
else
{
getLog().warn( String.format( "Skipping SCoverage execution - unsupported Scala version \"%s\"",
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+ .",
resolvedScalaVersion ) );
return;
}
Expand Down Expand Up @@ -278,16 +282,18 @@ else if ( "2.13".equals( resolvedScalaVersion ) || resolvedScalaVersion.startsWi

try
{
List<Artifact> pluginArtifacts = getScalaScoveragePluginArtifacts( resolvedScalaVersion, scalaBinaryVersion );
Artifact runtimeArtifact = getScalaScoverageRuntimeArtifact( scalaBinaryVersion );

addScoverageDependenciesToClasspath( runtimeArtifact );
List<Artifact> pluginArtifacts = getScalaScoveragePluginArtifacts( resolvedScalaVersion, scalaBinaryVersion, scala2 );
if ( scala2 ) // Scala 3 doesn't need scalac-scoverage-runtime
{
Artifact runtimeArtifact = getScalaScoverageRuntimeArtifact( scalaBinaryVersion );
addScoverageDependenciesToClasspath( runtimeArtifact );
}

String arg = DATA_DIR_OPTION + dataDirectory.getAbsolutePath();
String arg = ( scala2 ? SCALA2_DATA_DIR_OPTION : SCALA3_COVERAGE_OUT_OPTION ) + dataDirectory.getAbsolutePath();
String _scalacOptions = quoteArgument( arg );
String addScalacArgs = arg;

arg = SOURCE_ROOT_OPTION + project.getBasedir().getAbsolutePath();
arg = scala2 ? ( SOURCE_ROOT_OPTION + project.getBasedir().getAbsolutePath() ) : "";
_scalacOptions = _scalacOptions + SPACE + quoteArgument( arg );
addScalacArgs = addScalacArgs + PIPE + arg;

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

if ( highlighting )
if ( highlighting && scala2 )
{
_scalacOptions = _scalacOptions + SPACE + "-Yrangepos";
addScalacArgs = addScalacArgs + PIPE + "-Yrangepos";
}

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

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

Properties projectProperties = project.getProperties();

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

private static final String SCALA_LIBRARY_GROUP_ID = "org.scala-lang";
private static final String SCALA_LIBRARY_ARTIFACT_ID = "scala-library";
private static final String SCALA2_LIBRARY_ARTIFACT_ID = "scala-library";
private static final String SCALA3_LIBRARY_ARTIFACT_ID = "scala3-library_3";

private static final String DATA_DIR_OPTION = "-P:scoverage:dataDir:";
private static final String SCALA2_DATA_DIR_OPTION = "-P:scoverage:dataDir:";
private static final String SCALA3_COVERAGE_OUT_OPTION = "-coverage-out:";
private static final String SOURCE_ROOT_OPTION = "-P:scoverage:sourceRoot:";
private static final String EXCLUDED_PACKAGES_OPTION = "-P:scoverage:excludedPackages:";
private static final String EXCLUDED_FILES_OPTION = "-P:scoverage:excludedFiles:";
Expand All @@ -378,15 +388,19 @@ private String quoteArgument( String arg )
private String resolveScalaVersion()
{
String result = scalaVersion;
if ( result == null )
if ( result == null || result.isEmpty() )
{
// check project direct dependencies (transitive dependencies cannot be checked in this Maven lifecycle phase)
@SuppressWarnings( "unchecked" )
List<Dependency> dependencies = project.getDependencies();
for ( Dependency dependency: dependencies )
{
if ( SCALA_LIBRARY_GROUP_ID.equals( dependency.getGroupId() )
&& SCALA_LIBRARY_ARTIFACT_ID.equals( dependency.getArtifactId() ) )
&& (
SCALA2_LIBRARY_ARTIFACT_ID.equals( dependency.getArtifactId() ) ||
SCALA3_LIBRARY_ARTIFACT_ID.equals( dependency.getArtifactId() )
)
)
{
result = dependency.getVersion();
break;
Expand Down Expand Up @@ -428,22 +442,25 @@ private ArtifactVersion getScalacPluginVersion() {
}
}

private List<Artifact> getScalaScoveragePluginArtifacts(String resolvedScalaVersion, String scalaMainVersion )
private List<Artifact> getScalaScoveragePluginArtifacts( String resolvedScalaVersion, String scalaBinaryVersion, boolean scala2 )
throws ArtifactNotFoundException, ArtifactResolutionException
{
String resolvedScalacPluginVersion = getScalacPluginVersion().toString();
List<Artifact> resolvedArtifacts = new ArrayList<>();
resolvedArtifacts.add(getResolvedArtifact("org.scoverage", "scalac-scoverage-plugin_" + resolvedScalaVersion, resolvedScalacPluginVersion));
resolvedArtifacts.add(getResolvedArtifact("org.scoverage", "scalac-scoverage-domain_" + scalaMainVersion, resolvedScalacPluginVersion));
resolvedArtifacts.add(getResolvedArtifact("org.scoverage", "scalac-scoverage-serializer_" + scalaMainVersion, resolvedScalacPluginVersion));
if ( scala2 ) // Scala 3 doesn't need scalac-scoverage-plugin
{
resolvedArtifacts.add(getResolvedArtifact("org.scoverage", "scalac-scoverage-plugin_" + resolvedScalaVersion, resolvedScalacPluginVersion));
}
resolvedArtifacts.add(getResolvedArtifact("org.scoverage", "scalac-scoverage-domain_" + scalaBinaryVersion, resolvedScalacPluginVersion));
resolvedArtifacts.add(getResolvedArtifact("org.scoverage", "scalac-scoverage-serializer_" + scalaBinaryVersion, resolvedScalacPluginVersion));
return resolvedArtifacts;
}

private Artifact getScalaScoverageRuntimeArtifact( String scalaMainVersion )
private Artifact getScalaScoverageRuntimeArtifact( String scalaBinaryVersion )
throws ArtifactNotFoundException, ArtifactResolutionException
{
return getResolvedArtifact(
"org.scoverage", "scalac-scoverage-runtime_" + scalaMainVersion,
"org.scoverage", "scalac-scoverage-runtime_" + scalaBinaryVersion,
getScalacPluginVersion().toString() );
}

Expand Down

0 comments on commit 56f2732

Please sign in to comment.