diff --git a/pom.xml b/pom.xml index 5ebd00e6..3be70b9b 100644 --- a/pom.xml +++ b/pom.xml @@ -155,6 +155,13 @@ under the License. doxia-site-renderer 1.11.1 + + + junit + junit + 4.13.1 + test + diff --git a/src/it/test_ScalaMavenPlugin_Scala212_JUnit/pom.xml b/src/it/test_ScalaMavenPlugin_Scala212_JUnit/pom.xml index f4683a3a..d981bf59 100644 --- a/src/it/test_ScalaMavenPlugin_Scala212_JUnit/pom.xml +++ b/src/it/test_ScalaMavenPlugin_Scala212_JUnit/pom.xml @@ -19,7 +19,7 @@ 2.12 - 18 + 8 @@ -39,6 +39,9 @@ @project.groupId@ @project.artifactId@ + + 2.0.0 + diff --git a/src/it/test_skip_Scala2_10/invoker.properties b/src/it/test_skip_Scala2_10/invoker.properties new file mode 100644 index 00000000..3e51a5a6 --- /dev/null +++ b/src/it/test_skip_Scala2_10/invoker.properties @@ -0,0 +1 @@ +invoker.goals=clean verify site -e -ntp \ No newline at end of file diff --git a/src/it/test_skip_Scala2_10/pom.xml b/src/it/test_skip_Scala2_10/pom.xml new file mode 100644 index 00000000..aa5fccd7 --- /dev/null +++ b/src/it/test_skip_Scala2_10/pom.xml @@ -0,0 +1,45 @@ + + + + 4.0.0 + + + it.scoverage-maven-plugin + integration_tests_parent + 1.0-SNAPSHOT + ../integration_tests_parent/pom.xml + + + test_skip_Scala2_10 + 1.0-SNAPSHOT + jar + Test Scoverage is Skipped for Scala 2.10 + Test Scoverage is Skipped for Scala 2.10 + + + 2.10 + 7 + + + + + + org.apache.maven.plugins + maven-compiler-plugin + + + net.alchim31.maven + scala-maven-plugin + + + org.scalatest + scalatest-maven-plugin + + + @project.groupId@ + @project.artifactId@ + + + + diff --git a/src/it/test_skip_Scala2_10/src/main/scala/HelloServiceScala.scala b/src/it/test_skip_Scala2_10/src/main/scala/HelloServiceScala.scala new file mode 100644 index 00000000..f946ee95 --- /dev/null +++ b/src/it/test_skip_Scala2_10/src/main/scala/HelloServiceScala.scala @@ -0,0 +1,6 @@ +package service + +object HelloServiceScala { + def hello = { "Hello" } + +} diff --git a/src/it/test_skip_Scala2_10/src/test/scala/HelloServiceScalaTest.scala b/src/it/test_skip_Scala2_10/src/test/scala/HelloServiceScalaTest.scala new file mode 100644 index 00000000..cf1636c0 --- /dev/null +++ b/src/it/test_skip_Scala2_10/src/test/scala/HelloServiceScalaTest.scala @@ -0,0 +1,12 @@ +package service + +import org.scalatest.wordspec.AnyWordSpec + +class HelloServiceScalaTest extends AnyWordSpec { + + "HelloService" should { + "say hello" in { + assert(HelloServiceScala.hello == "Hello") + } + } +} diff --git a/src/it/test_skip_Scala2_10/validate.groovy b/src/it/test_skip_Scala2_10/validate.groovy new file mode 100644 index 00000000..9b1a115e --- /dev/null +++ b/src/it/test_skip_Scala2_10/validate.groovy @@ -0,0 +1,12 @@ +try { + + def logFile = new File(basedir, "build.log") + def lines = logFile.readLines() + assert lines.contains("[WARNING] Skipping SCoverage execution - unsupported Scala version \"2.10.7\". Supported Scala versions are 2.12.8+, 2.13.0+ and 3.2.0+ .") + + return true + +} catch (Throwable e) { + e.printStackTrace() + return false +} diff --git a/src/it/test_skip_Scala2_11/invoker.properties b/src/it/test_skip_Scala2_11/invoker.properties new file mode 100644 index 00000000..3e51a5a6 --- /dev/null +++ b/src/it/test_skip_Scala2_11/invoker.properties @@ -0,0 +1 @@ +invoker.goals=clean verify site -e -ntp \ No newline at end of file diff --git a/src/it/test_skip_Scala2_11/pom.xml b/src/it/test_skip_Scala2_11/pom.xml new file mode 100644 index 00000000..a5f4ab62 --- /dev/null +++ b/src/it/test_skip_Scala2_11/pom.xml @@ -0,0 +1,45 @@ + + + + 4.0.0 + + + it.scoverage-maven-plugin + integration_tests_parent + 1.0-SNAPSHOT + ../integration_tests_parent/pom.xml + + + test_skip_Scala2_11 + 1.0-SNAPSHOT + jar + Test Scoverage is Skipped for Scala 2.11 + Test Scoverage is Skipped for Scala 2.11 + + + 2.11 + 12 + + + + + + org.apache.maven.plugins + maven-compiler-plugin + + + net.alchim31.maven + scala-maven-plugin + + + org.scalatest + scalatest-maven-plugin + + + @project.groupId@ + @project.artifactId@ + + + + diff --git a/src/it/test_skip_Scala2_11/src/main/scala/HelloServiceScala.scala b/src/it/test_skip_Scala2_11/src/main/scala/HelloServiceScala.scala new file mode 100644 index 00000000..f946ee95 --- /dev/null +++ b/src/it/test_skip_Scala2_11/src/main/scala/HelloServiceScala.scala @@ -0,0 +1,6 @@ +package service + +object HelloServiceScala { + def hello = { "Hello" } + +} diff --git a/src/it/test_skip_Scala2_11/src/test/scala/HelloServiceScalaTest.scala b/src/it/test_skip_Scala2_11/src/test/scala/HelloServiceScalaTest.scala new file mode 100644 index 00000000..cf1636c0 --- /dev/null +++ b/src/it/test_skip_Scala2_11/src/test/scala/HelloServiceScalaTest.scala @@ -0,0 +1,12 @@ +package service + +import org.scalatest.wordspec.AnyWordSpec + +class HelloServiceScalaTest extends AnyWordSpec { + + "HelloService" should { + "say hello" in { + assert(HelloServiceScala.hello == "Hello") + } + } +} diff --git a/src/it/test_skip_Scala2_11/validate.groovy b/src/it/test_skip_Scala2_11/validate.groovy new file mode 100644 index 00000000..94836baa --- /dev/null +++ b/src/it/test_skip_Scala2_11/validate.groovy @@ -0,0 +1,12 @@ +try { + + def logFile = new File(basedir, "build.log") + def lines = logFile.readLines() + assert lines.contains("[WARNING] Skipping SCoverage execution - unsupported Scala version \"2.11.12\". Supported Scala versions are 2.12.8+, 2.13.0+ and 3.2.0+ .") + + return true + +} catch (Throwable e) { + e.printStackTrace() + return false +} diff --git a/src/it/test_skip_Scala2_12_7/invoker.properties b/src/it/test_skip_Scala2_12_7/invoker.properties new file mode 100644 index 00000000..3e51a5a6 --- /dev/null +++ b/src/it/test_skip_Scala2_12_7/invoker.properties @@ -0,0 +1 @@ +invoker.goals=clean verify site -e -ntp \ No newline at end of file diff --git a/src/it/test_skip_Scala2_12_7/pom.xml b/src/it/test_skip_Scala2_12_7/pom.xml new file mode 100644 index 00000000..54e8deaa --- /dev/null +++ b/src/it/test_skip_Scala2_12_7/pom.xml @@ -0,0 +1,55 @@ + + + + 4.0.0 + + + it.scoverage-maven-plugin + integration_tests_parent + 1.0-SNAPSHOT + ../integration_tests_parent/pom.xml + + + test_skip_Scala2_12_7 + 1.0-SNAPSHOT + jar + Test Scoverage is Skipped for Scala 2.12.7 + Test Scoverage is Skipped for Scala 2.12.7 + + + 2.12 + 7 + 2.0.0 + + + + + run + + 11 + + + + + org.apache.maven.plugins + maven-compiler-plugin + + + net.alchim31.maven + scala-maven-plugin + + + org.scalatest + scalatest-maven-plugin + + + @project.groupId@ + @project.artifactId@ + + + + + + + diff --git a/src/it/test_skip_Scala2_12_7/src/main/scala/HelloServiceScala.scala b/src/it/test_skip_Scala2_12_7/src/main/scala/HelloServiceScala.scala new file mode 100644 index 00000000..f946ee95 --- /dev/null +++ b/src/it/test_skip_Scala2_12_7/src/main/scala/HelloServiceScala.scala @@ -0,0 +1,6 @@ +package service + +object HelloServiceScala { + def hello = { "Hello" } + +} diff --git a/src/it/test_skip_Scala2_12_7/src/test/scala/HelloServiceScalaTest.scala b/src/it/test_skip_Scala2_12_7/src/test/scala/HelloServiceScalaTest.scala new file mode 100644 index 00000000..cf1636c0 --- /dev/null +++ b/src/it/test_skip_Scala2_12_7/src/test/scala/HelloServiceScalaTest.scala @@ -0,0 +1,12 @@ +package service + +import org.scalatest.wordspec.AnyWordSpec + +class HelloServiceScalaTest extends AnyWordSpec { + + "HelloService" should { + "say hello" in { + assert(HelloServiceScala.hello == "Hello") + } + } +} diff --git a/src/it/test_skip_Scala2_12_7/validate.groovy b/src/it/test_skip_Scala2_12_7/validate.groovy new file mode 100644 index 00000000..594d4409 --- /dev/null +++ b/src/it/test_skip_Scala2_12_7/validate.groovy @@ -0,0 +1,12 @@ +try { + + def logFile = new File(basedir, "build.log") + def lines = logFile.readLines() + assert lines.contains("[WARNING] Skipping SCoverage execution - unsupported Scala version \"2.12.7\". Supported Scala versions are 2.12.8+, 2.13.0+ and 3.2.0+ .") + + return true + +} catch (Throwable e) { + e.printStackTrace() + return false +} diff --git a/src/it/test_skip_Scala3_1/invoker.properties b/src/it/test_skip_Scala3_1/invoker.properties new file mode 100644 index 00000000..3e51a5a6 --- /dev/null +++ b/src/it/test_skip_Scala3_1/invoker.properties @@ -0,0 +1 @@ +invoker.goals=clean verify site -e -ntp \ No newline at end of file diff --git a/src/it/test_skip_Scala3_1/pom.xml b/src/it/test_skip_Scala3_1/pom.xml new file mode 100644 index 00000000..9dba87a0 --- /dev/null +++ b/src/it/test_skip_Scala3_1/pom.xml @@ -0,0 +1,46 @@ + + + + 4.0.0 + + + it.scoverage-maven-plugin + integration_tests_parent + 1.0-SNAPSHOT + ../integration_tests_parent/pom.xml + + + test_skip_Scala3_1 + 1.0-SNAPSHOT + jar + Test Scoverage is Skipped for Scala 3.1 + Test Scoverage is Skipped for Scala 3.1 + + + 3 + 3.1.0 + scala3-library_3 + + + + + + org.apache.maven.plugins + maven-compiler-plugin + + + net.alchim31.maven + scala-maven-plugin + + + org.scalatest + scalatest-maven-plugin + + + @project.groupId@ + @project.artifactId@ + + + + diff --git a/src/it/test_skip_Scala3_1/src/main/scala/HelloServiceScala.scala b/src/it/test_skip_Scala3_1/src/main/scala/HelloServiceScala.scala new file mode 100644 index 00000000..f946ee95 --- /dev/null +++ b/src/it/test_skip_Scala3_1/src/main/scala/HelloServiceScala.scala @@ -0,0 +1,6 @@ +package service + +object HelloServiceScala { + def hello = { "Hello" } + +} diff --git a/src/it/test_skip_Scala3_1/src/test/scala/HelloServiceScalaTest.scala b/src/it/test_skip_Scala3_1/src/test/scala/HelloServiceScalaTest.scala new file mode 100644 index 00000000..cf1636c0 --- /dev/null +++ b/src/it/test_skip_Scala3_1/src/test/scala/HelloServiceScalaTest.scala @@ -0,0 +1,12 @@ +package service + +import org.scalatest.wordspec.AnyWordSpec + +class HelloServiceScalaTest extends AnyWordSpec { + + "HelloService" should { + "say hello" in { + assert(HelloServiceScala.hello == "Hello") + } + } +} diff --git a/src/it/test_skip_Scala3_1/validate.groovy b/src/it/test_skip_Scala3_1/validate.groovy new file mode 100644 index 00000000..d3cac897 --- /dev/null +++ b/src/it/test_skip_Scala3_1/validate.groovy @@ -0,0 +1,12 @@ +try { + + def logFile = new File(basedir, "build.log") + def lines = logFile.readLines() + assert lines.contains("[WARNING] Skipping SCoverage execution - unsupported Scala version \"3.1.0\". Supported Scala versions are 2.12.8+, 2.13.0+ and 3.2.0+ .") + + return true + +} catch (Throwable e) { + e.printStackTrace() + return false +} diff --git a/src/main/java/org/scoverage/plugin/SCoveragePreCompileMojo.java b/src/main/java/org/scoverage/plugin/SCoveragePreCompileMojo.java index acf25e5f..7a752d17 100644 --- a/src/main/java/org/scoverage/plugin/SCoveragePreCompileMojo.java +++ b/src/main/java/org/scoverage/plugin/SCoveragePreCompileMojo.java @@ -202,7 +202,7 @@ public void execute() throws MojoExecutionException if ( "pom".equals( project.getPackaging() ) ) { getLog().info( "Skipping SCoverage execution for project with packaging type 'pom'" ); - //for aggragetor mojo - list of submodules: List modules = project.getCollectedProjects(); + //for aggregator mojo - list of submodules: List modules = project.getCollectedProjects(); return; } @@ -224,28 +224,16 @@ public void execute() throws MojoExecutionException long ts = System.currentTimeMillis(); - String scalaBinaryVersion = null; - String resolvedScalaVersion = resolveScalaVersion(); - boolean scala2 = true; + ScalaVersion resolvedScalaVersion = resolveScalaVersion(); + if ( resolvedScalaVersion != null ) { - if ( "2.12".equals( resolvedScalaVersion ) || resolvedScalaVersion.startsWith( "2.12." ) ) - { - scalaBinaryVersion = "2.12"; - } - else if ( "2.13".equals( resolvedScalaVersion ) || resolvedScalaVersion.startsWith( "2.13." ) ) - { - scalaBinaryVersion = "2.13"; - } - else if ( resolvedScalaVersion.compareTo("3.2.") > 0 ) // Scala 3 is supported from 3.2.0 - { - scalaBinaryVersion = "3"; - scala2 = false; - } - else + boolean supportedScalaVersion = resolvedScalaVersion.isScala2() && resolvedScalaVersion.isAtLeast( "2.12.8" ) || + resolvedScalaVersion.isAtLeast( "3.2.0" ); + if (!supportedScalaVersion) { 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 ) ); + resolvedScalaVersion.full ) ); return; } } @@ -282,10 +270,12 @@ else if ( resolvedScalaVersion.compareTo("3.2.") > 0 ) // Scala 3 is supported f try { - List pluginArtifacts = getScalaScoveragePluginArtifacts( resolvedScalaVersion, scalaBinaryVersion, scala2 ); + boolean scala2 = resolvedScalaVersion.isScala2(); + + List pluginArtifacts = getScalaScoveragePluginArtifacts( resolvedScalaVersion ); if ( scala2 ) // Scala 3 doesn't need scalac-scoverage-runtime { - Artifact runtimeArtifact = getScalaScoverageRuntimeArtifact( scalaBinaryVersion ); + Artifact runtimeArtifact = getScalaScoverageRuntimeArtifact( resolvedScalaVersion ); addScoverageDependenciesToClasspath( runtimeArtifact ); } @@ -346,15 +336,7 @@ else if ( resolvedScalaVersion.compareTo("3.2.") > 0 ) // Scala 3 is supported f saveSourceRootsToFile(); } - catch ( ArtifactNotFoundException e ) - { - throw new MojoExecutionException( "SCoverage preparation failed", e ); - } - catch ( ArtifactResolutionException e ) - { - throw new MojoExecutionException( "SCoverage preparation failed", e ); - } - catch ( IOException e ) + catch (ArtifactNotFoundException | ArtifactResolutionException | IOException e ) { throw new MojoExecutionException( "SCoverage preparation failed", e ); } @@ -385,7 +367,7 @@ private String quoteArgument( String arg ) return arg.indexOf( SPACE ) >= 0 ? DOUBLE_QUOTE + arg + DOUBLE_QUOTE : arg; } - private String resolveScalaVersion() + private ScalaVersion resolveScalaVersion() { String result = scalaVersion; if ( result == null || result.isEmpty() ) @@ -407,7 +389,7 @@ private String resolveScalaVersion() } } } - return result; + return result != null ? new ScalaVersion(result) : null; } private void setProperty( Properties projectProperties, String propertyName, String newValue ) @@ -442,25 +424,25 @@ private ArtifactVersion getScalacPluginVersion() { } } - private List getScalaScoveragePluginArtifacts( String resolvedScalaVersion, String scalaBinaryVersion, boolean scala2 ) + private List getScalaScoveragePluginArtifacts( ScalaVersion resolvedScalaVersion ) throws ArtifactNotFoundException, ArtifactResolutionException { String resolvedScalacPluginVersion = getScalacPluginVersion().toString(); List resolvedArtifacts = new ArrayList<>(); - if ( scala2 ) // Scala 3 doesn't need scalac-scoverage-plugin + if ( resolvedScalaVersion.isScala2() ) // 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-plugin_" + resolvedScalaVersion.full, resolvedScalacPluginVersion)); } - resolvedArtifacts.add(getResolvedArtifact("org.scoverage", "scalac-scoverage-domain_" + scalaBinaryVersion, resolvedScalacPluginVersion)); - resolvedArtifacts.add(getResolvedArtifact("org.scoverage", "scalac-scoverage-serializer_" + scalaBinaryVersion, resolvedScalacPluginVersion)); + resolvedArtifacts.add(getResolvedArtifact("org.scoverage", "scalac-scoverage-domain_" + resolvedScalaVersion.compatible, resolvedScalacPluginVersion)); + resolvedArtifacts.add(getResolvedArtifact("org.scoverage", "scalac-scoverage-serializer_" + resolvedScalaVersion.compatible, resolvedScalacPluginVersion)); return resolvedArtifacts; } - private Artifact getScalaScoverageRuntimeArtifact( String scalaBinaryVersion ) + private Artifact getScalaScoverageRuntimeArtifact( ScalaVersion resolvedScalaVersion ) throws ArtifactNotFoundException, ArtifactResolutionException { return getResolvedArtifact( - "org.scoverage", "scalac-scoverage-runtime_" + scalaBinaryVersion, + "org.scoverage", "scalac-scoverage-runtime_" + resolvedScalaVersion.compatible, getScalacPluginVersion().toString() ); } diff --git a/src/main/java/org/scoverage/plugin/ScalaVersion.java b/src/main/java/org/scoverage/plugin/ScalaVersion.java new file mode 100644 index 00000000..f36b3d00 --- /dev/null +++ b/src/main/java/org/scoverage/plugin/ScalaVersion.java @@ -0,0 +1,59 @@ +package org.scoverage.plugin; + +import java.util.regex.Matcher; +import java.util.regex.Pattern; + +/** + * Inspired by scala-maven-plugin's VersionNumber.java + */ +public class ScalaVersion { + private static final Pattern regexp = Pattern.compile("(\\d+)\\.(\\d+)(\\.\\d+)?([-\\.].+)?"); + + public String full; + public String compatible; + public int major; + public int minor; + public int bugfix; + public String modifier; + + public ScalaVersion(String s) { + full = s; + // parse + Matcher match = regexp.matcher(s); + if (!match.find()) { + throw new IllegalArgumentException("Invalid Scala version [" + s + "]. Expected major.minor(.bugfix)(modifier)"); + } + major = Integer.parseInt(match.group(1)); + minor = Integer.parseInt(match.group(2)); + if ((match.group(3) != null) && (match.group(3).length() > 1)) { + bugfix = Integer.parseInt(match.group(3).substring(1)); + } + if ((match.group(4) != null) && (match.group(4).length() > 1)) { + modifier = match.group(4); + } + // compute compatible + compatible = + modifier != null ? full : // non-stable versions are not compatible with anything else + isScala2() ? major + "." + minor : // Scala 2.X.Y is compatible with any Scala 2.X.Z + major + ""; // Scala 3.X is compatible with any Scala 3.Y + } + + /** + * Ignores modifier, so can return `true` for any ScalaVersion with matching major, minor, bugfix. + */ + public boolean isAtLeast(ScalaVersion other) { + return major >= other.major && + (major != other.major || minor >= other.minor) && + (major != other.major || minor != other.minor || bugfix >= other.bugfix); + + } + + public boolean isAtLeast(String scalaVersion) { + return isAtLeast(new ScalaVersion(scalaVersion)); + } + + public boolean isScala2() { + return major == 2; + } + +} \ No newline at end of file diff --git a/src/test/java/org/scoverage/plugin/ScalaVersionTest.java b/src/test/java/org/scoverage/plugin/ScalaVersionTest.java new file mode 100644 index 00000000..3f01e4db --- /dev/null +++ b/src/test/java/org/scoverage/plugin/ScalaVersionTest.java @@ -0,0 +1,63 @@ +package org.scoverage.plugin; + +import org.junit.Test; + +import static org.junit.Assert.*; + +public class ScalaVersionTest { + + @Test + public void testInvalidVersion() { + try { + new ScalaVersion("whatever"); + fail("Should have thrown an exception"); + } catch (IllegalArgumentException e) { + assertEquals("Invalid Scala version [whatever]. Expected major.minor(.bugfix)(modifier)", e.getMessage()); + } + } + + @Test + public void testIsAtLeast() { + assertTrue(new ScalaVersion("2.13.12").isAtLeast("1.0")); + assertTrue(new ScalaVersion("2.12.1").isAtLeast("1.9")); + assertTrue(new ScalaVersion("2.13.10").isAtLeast("2.0")); + assertTrue(new ScalaVersion("2.13.1").isAtLeast("2.13")); + assertTrue(new ScalaVersion("2.10.0").isAtLeast("2.10.0-rc8")); + assertTrue(new ScalaVersion("2.13.1").isAtLeast("2.13.0")); + assertTrue(new ScalaVersion("2.13.12").isAtLeast("2.13.12")); + assertFalse(new ScalaVersion("3.3.1").isAtLeast("3.3.2-rc1")); + assertFalse(new ScalaVersion("2.12.10").isAtLeast("2.13")); + assertFalse(new ScalaVersion("2.13.12").isAtLeast("3.0")); + assertFalse(new ScalaVersion("2.13.12").isAtLeast("3.0.0")); + } + + @Test + public void testFull() { + assertEquals("2.12.2", new ScalaVersion("2.12.2").full); + assertEquals("2.13.12", new ScalaVersion("2.13.12").full); + assertEquals("3.0.0", new ScalaVersion("3.0.0").full); + assertEquals("3.4.0-RC1", new ScalaVersion("3.4.0-RC1").full); + } + + @Test + public void testCompatible() { + assertEquals("2.12", new ScalaVersion("2.12.2").compatible); + assertEquals("2.12", new ScalaVersion("2.12.18").compatible); + assertEquals("2.13", new ScalaVersion("2.13.0").compatible); + assertEquals("2.13", new ScalaVersion("2.13.12").compatible); + assertEquals("3", new ScalaVersion("3.0.0").compatible); + assertEquals("3", new ScalaVersion("3.3.1").compatible); + assertEquals("3", new ScalaVersion("3.4.0").compatible); + assertEquals("3.4.0-RC1", new ScalaVersion("3.4.0-RC1").compatible); + } + + @Test + public void testIsScala2() { + assertTrue(new ScalaVersion("2.12.2").isScala2()); + assertTrue(new ScalaVersion("2.13.12").isScala2()); + assertFalse(new ScalaVersion("3.0.0").isScala2()); + assertFalse(new ScalaVersion("3.4.0-RC1").isScala2()); + assertFalse(new ScalaVersion("1.0.0").isScala2()); + } + +} \ No newline at end of file