diff --git a/README.md b/README.md index e98fbcb5..1dc7b770 100644 --- a/README.md +++ b/README.md @@ -325,8 +325,10 @@ If you want to customize plugin's configuration parameters used by compilation s ``` -Read [SBT SCoverage Plugin documentation](https://github.com/scoverage/sbt-scoverage) for more information about [highlighting](https://github.com/scoverage/sbt-scoverage#highlighting) and [excludedPackages](https://github.com/scoverage/sbt-scoverage#exclude-classes-and-packages). +Read [SBT SCoverage Plugin documentation](https://github.com/scoverage/sbt-scoverage) for more information about +[excludedPackages and excludedFiles](https://github.com/scoverage/sbt-scoverage?tab=readme-ov-file#exclude-classes-and-packages-and-files). +File and package exclusions are supported for Scala 2 and Scala 3 since version `3.4.2`. ### Checking minimum test coverage level diff --git a/src/it/integration_tests_parent/pom.xml b/src/it/integration_tests_parent/pom.xml index 3b1c4a8c..587294da 100644 --- a/src/it/integration_tests_parent/pom.xml +++ b/src/it/integration_tests_parent/pom.xml @@ -18,7 +18,7 @@ 3.11.0 3.1.2 - 4.8.1 + 4.9.1 2.0.0 3.5.0 3.12.1 diff --git a/src/it/test_exclusion_Scala3_4_1/invoker.properties b/src/it/test_exclusion_Scala3_4_1/invoker.properties new file mode 100644 index 00000000..3e51a5a6 --- /dev/null +++ b/src/it/test_exclusion_Scala3_4_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_exclusion_Scala3_4_1/pom.xml b/src/it/test_exclusion_Scala3_4_1/pom.xml new file mode 100644 index 00000000..44457d19 --- /dev/null +++ b/src/it/test_exclusion_Scala3_4_1/pom.xml @@ -0,0 +1,51 @@ + + + + 4.0.0 + + + it.scoverage-maven-plugin + integration_tests_parent + 1.0-SNAPSHOT + ../integration_tests_parent/pom.xml + + + test_exclusion + 1.0-SNAPSHOT + jar + Test Scoverage exclusion + Test Scoverage exclusion + + + 3 + 3.4.1 + scala3-library_3 + UTF-8 + + + + + + org.apache.maven.plugins + maven-compiler-plugin + + + net.alchim31.maven + scala-maven-plugin + + + org.scalatest + scalatest-maven-plugin + + + @project.groupId@ + @project.artifactId@ + + .*package02.*;.*package05 + .*Package03HelloService.*;.*Package03ByeService + + + + + diff --git a/src/it/test_exclusion_Scala3_4_1/src/main/scala/org/package01/Package01HelloService.scala b/src/it/test_exclusion_Scala3_4_1/src/main/scala/org/package01/Package01HelloService.scala new file mode 100644 index 00000000..55ada336 --- /dev/null +++ b/src/it/test_exclusion_Scala3_4_1/src/main/scala/org/package01/Package01HelloService.scala @@ -0,0 +1,8 @@ +package org.package01 + +object Package01HelloService { + + // gonna be included in coverage report + def hello: String = "Hello from package01" + +} diff --git a/src/it/test_exclusion_Scala3_4_1/src/main/scala/org/package02/nested02/package02nested02objects.scala b/src/it/test_exclusion_Scala3_4_1/src/main/scala/org/package02/nested02/package02nested02objects.scala new file mode 100644 index 00000000..00f40ebe --- /dev/null +++ b/src/it/test_exclusion_Scala3_4_1/src/main/scala/org/package02/nested02/package02nested02objects.scala @@ -0,0 +1,14 @@ +// gonna be excluded from coverage report by package exclusion +package org.package02.nested02 + +object ImGonnaBeExcludedCauseImInPackage02Nested02 { + + def hello: String = "Hello from package02.nested02" + +} + +object SameStoryBro { + + def hello: String = "Hello from package02.nested02 again" + +} diff --git a/src/it/test_exclusion_Scala3_4_1/src/main/scala/org/package02/package02objects.scala b/src/it/test_exclusion_Scala3_4_1/src/main/scala/org/package02/package02objects.scala new file mode 100644 index 00000000..fca9d0c8 --- /dev/null +++ b/src/it/test_exclusion_Scala3_4_1/src/main/scala/org/package02/package02objects.scala @@ -0,0 +1,14 @@ +// gonna be excluded from coverage report by package exclusion +package org.package02 + +object ImGonnaBeExcludedCauseImInPackage02 { + + def hello: String = "Hello from package02" + +} + +object SameStoryBro { + + def hello: String = "Hello from package02 again" + +} diff --git a/src/it/test_exclusion_Scala3_4_1/src/main/scala/org/package03/Package03ByeService.scala b/src/it/test_exclusion_Scala3_4_1/src/main/scala/org/package03/Package03ByeService.scala new file mode 100644 index 00000000..56914ec8 --- /dev/null +++ b/src/it/test_exclusion_Scala3_4_1/src/main/scala/org/package03/Package03ByeService.scala @@ -0,0 +1,8 @@ +package org.package03 + +object Package03ByeService { + + // gonna be excluded from coverage report by file exclusion + def bye: String = "Bye from package03" + +} diff --git a/src/it/test_exclusion_Scala3_4_1/src/main/scala/org/package03/Package03HelloService1.scala b/src/it/test_exclusion_Scala3_4_1/src/main/scala/org/package03/Package03HelloService1.scala new file mode 100644 index 00000000..2d05b244 --- /dev/null +++ b/src/it/test_exclusion_Scala3_4_1/src/main/scala/org/package03/Package03HelloService1.scala @@ -0,0 +1,8 @@ +package org.package03 + +object Package03HelloService1 { + + // gonna be excluded from coverage report by file exclusion + def hello: String = "Hello from package03 service 1" + +} diff --git a/src/it/test_exclusion_Scala3_4_1/src/main/scala/org/package03/Package03HelloService2.scala b/src/it/test_exclusion_Scala3_4_1/src/main/scala/org/package03/Package03HelloService2.scala new file mode 100644 index 00000000..38c422b2 --- /dev/null +++ b/src/it/test_exclusion_Scala3_4_1/src/main/scala/org/package03/Package03HelloService2.scala @@ -0,0 +1,8 @@ +package org.package03 + +object Package03HelloService2 { + + // gonna be excluded from coverage report by file exclusion + def hello: String = "Hello from package03 service 2" + +} diff --git a/src/it/test_exclusion_Scala3_4_1/src/main/scala/org/package05/package05objects.scala b/src/it/test_exclusion_Scala3_4_1/src/main/scala/org/package05/package05objects.scala new file mode 100644 index 00000000..7b5cca13 --- /dev/null +++ b/src/it/test_exclusion_Scala3_4_1/src/main/scala/org/package05/package05objects.scala @@ -0,0 +1,14 @@ +// gonna be excluded from coverage report by package exclusion +package org.package05 + +object ImGonnaBeExcludedCauseImInPackage05 { + + def hello: String = "Hello from package05" + +} + +object SameStoryBro { + + def hello: String = "Hello from package05 again" + +} diff --git a/src/it/test_exclusion_Scala3_4_1/src/test/scala/org/package01/Package01HelloServiceTest.scala b/src/it/test_exclusion_Scala3_4_1/src/test/scala/org/package01/Package01HelloServiceTest.scala new file mode 100644 index 00000000..ebe11c6b --- /dev/null +++ b/src/it/test_exclusion_Scala3_4_1/src/test/scala/org/package01/Package01HelloServiceTest.scala @@ -0,0 +1,12 @@ +package org.package01 + +import org.scalatest.wordspec.AnyWordSpec + +class Package01HelloServiceTest extends AnyWordSpec { + + "Package01HelloService" should { + "say hello" in { + assert(Package01HelloService.hello == "Hello from package01") + } + } +} diff --git a/src/it/test_exclusion_Scala3_4_1/validate.groovy b/src/it/test_exclusion_Scala3_4_1/validate.groovy new file mode 100644 index 00000000..0e0f82ad --- /dev/null +++ b/src/it/test_exclusion_Scala3_4_1/validate.groovy @@ -0,0 +1,14 @@ +try { + + def logFile = new File(basedir, "build.log") + def lines = logFile.readLines() + assert lines.contains("[WARNING] Package exclusion is supported since Scala 3.4.2") + assert lines.contains("[WARNING] File exclusion is supported since Scala 3.4.2") + assert lines.contains("[INFO] Statement coverage.: 10.00%") + + return true + +} catch (Throwable e) { + e.printStackTrace() + return false +} diff --git a/src/it/test_exclusion_Scala3_4_2/invoker.properties b/src/it/test_exclusion_Scala3_4_2/invoker.properties new file mode 100644 index 00000000..3e51a5a6 --- /dev/null +++ b/src/it/test_exclusion_Scala3_4_2/invoker.properties @@ -0,0 +1 @@ +invoker.goals=clean verify site -e -ntp \ No newline at end of file diff --git a/src/it/test_exclusion_Scala3_4_2/pom.xml b/src/it/test_exclusion_Scala3_4_2/pom.xml new file mode 100644 index 00000000..94c2ef0a --- /dev/null +++ b/src/it/test_exclusion_Scala3_4_2/pom.xml @@ -0,0 +1,51 @@ + + + + 4.0.0 + + + it.scoverage-maven-plugin + integration_tests_parent + 1.0-SNAPSHOT + ../integration_tests_parent/pom.xml + + + test_exclusion + 1.0-SNAPSHOT + jar + Test Scoverage exclusion + Test Scoverage exclusion + + + 3 + 3.4.2 + scala3-library_3 + UTF-8 + + + + + + org.apache.maven.plugins + maven-compiler-plugin + + + net.alchim31.maven + scala-maven-plugin + + + org.scalatest + scalatest-maven-plugin + + + @project.groupId@ + @project.artifactId@ + + .*package02.*;.*package05 + .*Package03HelloService.*;.*Package03ByeService + + + + + diff --git a/src/it/test_exclusion_Scala3_4_2/src/main/scala/org/package01/Package01HelloService.scala b/src/it/test_exclusion_Scala3_4_2/src/main/scala/org/package01/Package01HelloService.scala new file mode 100644 index 00000000..55ada336 --- /dev/null +++ b/src/it/test_exclusion_Scala3_4_2/src/main/scala/org/package01/Package01HelloService.scala @@ -0,0 +1,8 @@ +package org.package01 + +object Package01HelloService { + + // gonna be included in coverage report + def hello: String = "Hello from package01" + +} diff --git a/src/it/test_exclusion_Scala3_4_2/src/main/scala/org/package02/nested02/package02nested02objects.scala b/src/it/test_exclusion_Scala3_4_2/src/main/scala/org/package02/nested02/package02nested02objects.scala new file mode 100644 index 00000000..00f40ebe --- /dev/null +++ b/src/it/test_exclusion_Scala3_4_2/src/main/scala/org/package02/nested02/package02nested02objects.scala @@ -0,0 +1,14 @@ +// gonna be excluded from coverage report by package exclusion +package org.package02.nested02 + +object ImGonnaBeExcludedCauseImInPackage02Nested02 { + + def hello: String = "Hello from package02.nested02" + +} + +object SameStoryBro { + + def hello: String = "Hello from package02.nested02 again" + +} diff --git a/src/it/test_exclusion_Scala3_4_2/src/main/scala/org/package02/package02objects.scala b/src/it/test_exclusion_Scala3_4_2/src/main/scala/org/package02/package02objects.scala new file mode 100644 index 00000000..fca9d0c8 --- /dev/null +++ b/src/it/test_exclusion_Scala3_4_2/src/main/scala/org/package02/package02objects.scala @@ -0,0 +1,14 @@ +// gonna be excluded from coverage report by package exclusion +package org.package02 + +object ImGonnaBeExcludedCauseImInPackage02 { + + def hello: String = "Hello from package02" + +} + +object SameStoryBro { + + def hello: String = "Hello from package02 again" + +} diff --git a/src/it/test_exclusion_Scala3_4_2/src/main/scala/org/package03/Package03ByeService.scala b/src/it/test_exclusion_Scala3_4_2/src/main/scala/org/package03/Package03ByeService.scala new file mode 100644 index 00000000..56914ec8 --- /dev/null +++ b/src/it/test_exclusion_Scala3_4_2/src/main/scala/org/package03/Package03ByeService.scala @@ -0,0 +1,8 @@ +package org.package03 + +object Package03ByeService { + + // gonna be excluded from coverage report by file exclusion + def bye: String = "Bye from package03" + +} diff --git a/src/it/test_exclusion_Scala3_4_2/src/main/scala/org/package03/Package03HelloService1.scala b/src/it/test_exclusion_Scala3_4_2/src/main/scala/org/package03/Package03HelloService1.scala new file mode 100644 index 00000000..2d05b244 --- /dev/null +++ b/src/it/test_exclusion_Scala3_4_2/src/main/scala/org/package03/Package03HelloService1.scala @@ -0,0 +1,8 @@ +package org.package03 + +object Package03HelloService1 { + + // gonna be excluded from coverage report by file exclusion + def hello: String = "Hello from package03 service 1" + +} diff --git a/src/it/test_exclusion_Scala3_4_2/src/main/scala/org/package03/Package03HelloService2.scala b/src/it/test_exclusion_Scala3_4_2/src/main/scala/org/package03/Package03HelloService2.scala new file mode 100644 index 00000000..38c422b2 --- /dev/null +++ b/src/it/test_exclusion_Scala3_4_2/src/main/scala/org/package03/Package03HelloService2.scala @@ -0,0 +1,8 @@ +package org.package03 + +object Package03HelloService2 { + + // gonna be excluded from coverage report by file exclusion + def hello: String = "Hello from package03 service 2" + +} diff --git a/src/it/test_exclusion_Scala3_4_2/src/main/scala/org/package05/package05objects.scala b/src/it/test_exclusion_Scala3_4_2/src/main/scala/org/package05/package05objects.scala new file mode 100644 index 00000000..7b5cca13 --- /dev/null +++ b/src/it/test_exclusion_Scala3_4_2/src/main/scala/org/package05/package05objects.scala @@ -0,0 +1,14 @@ +// gonna be excluded from coverage report by package exclusion +package org.package05 + +object ImGonnaBeExcludedCauseImInPackage05 { + + def hello: String = "Hello from package05" + +} + +object SameStoryBro { + + def hello: String = "Hello from package05 again" + +} diff --git a/src/it/test_exclusion_Scala3_4_2/src/test/scala/org/package01/Package01HelloServiceTest.scala b/src/it/test_exclusion_Scala3_4_2/src/test/scala/org/package01/Package01HelloServiceTest.scala new file mode 100644 index 00000000..ebe11c6b --- /dev/null +++ b/src/it/test_exclusion_Scala3_4_2/src/test/scala/org/package01/Package01HelloServiceTest.scala @@ -0,0 +1,12 @@ +package org.package01 + +import org.scalatest.wordspec.AnyWordSpec + +class Package01HelloServiceTest extends AnyWordSpec { + + "Package01HelloService" should { + "say hello" in { + assert(Package01HelloService.hello == "Hello from package01") + } + } +} diff --git a/src/it/test_exclusion_Scala3_4_2/validate.groovy b/src/it/test_exclusion_Scala3_4_2/validate.groovy new file mode 100644 index 00000000..ce78045d --- /dev/null +++ b/src/it/test_exclusion_Scala3_4_2/validate.groovy @@ -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 +} diff --git a/src/main/java/org/scoverage/plugin/SCoveragePreCompileMojo.java b/src/main/java/org/scoverage/plugin/SCoveragePreCompileMojo.java index d5fdbdf6..c8beba79 100644 --- a/src/main/java/org/scoverage/plugin/SCoveragePreCompileMojo.java +++ b/src/main/java/org/scoverage/plugin/SCoveragePreCompileMojo.java @@ -296,16 +296,34 @@ public void execute() throws MojoExecutionException if ( !StringUtils.isEmpty( excludedPackages ) ) { - arg = EXCLUDED_PACKAGES_OPTION + excludedPackages.replace( "(empty)", "" ); - _scalacOptions = _scalacOptions + SPACE + quoteArgument( arg ); - addScalacArgs = addScalacArgs + PIPE + arg; + if ( scala2 ) { + arg = SCALA2_EXCLUDED_PACKAGES_OPTION + excludedPackages.replace( "(empty)", "" ); + _scalacOptions = _scalacOptions + SPACE + quoteArgument( arg ); + addScalacArgs = addScalacArgs + PIPE + arg; + } else if ( resolvedScalaVersion.isAtLeast( "3.4.2" ) ) { + String scala3FormatExcludedPackages = excludedPackages.replace( ";", "," ); + arg = SCALA3_EXCLUDED_PACKAGES_OPTION + scala3FormatExcludedPackages; + _scalacOptions = _scalacOptions + SPACE + quoteArgument( arg ); + addScalacArgs = addScalacArgs + PIPE + arg; + } else { + getLog().warn( "Package exclusion is supported since Scala 3.4.2" ); + } } if ( !StringUtils.isEmpty( excludedFiles ) ) { - arg = EXCLUDED_FILES_OPTION + excludedFiles; - _scalacOptions = _scalacOptions + SPACE + quoteArgument( arg ); - addScalacArgs = addScalacArgs + PIPE + arg; + if ( scala2 ) { + arg = SCALA2_EXCLUDED_FILES_OPTION + excludedFiles; + _scalacOptions = _scalacOptions + SPACE + quoteArgument( arg ); + addScalacArgs = addScalacArgs + PIPE + arg; + } else if ( resolvedScalaVersion.isAtLeast( "3.4.2" ) ) { + String scala3FormatExcludedFiles = excludedFiles.replace( ";", "," ); + arg = SCALA3_EXCLUDED_FILES_OPTION + scala3FormatExcludedFiles; + _scalacOptions = _scalacOptions + SPACE + quoteArgument( arg ); + addScalacArgs = addScalacArgs + PIPE + arg; + } else { + getLog().warn( "File exclusion is supported since Scala 3.4.2" ); + } } if ( highlighting && scala2 ) @@ -361,8 +379,10 @@ public void execute() throws MojoExecutionException 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:"; + private static final String SCALA2_EXCLUDED_PACKAGES_OPTION = "-P:scoverage:excludedPackages:"; + private static final String SCALA3_EXCLUDED_PACKAGES_OPTION = "-coverage-exclude-classlikes:"; + private static final String SCALA2_EXCLUDED_FILES_OPTION = "-P:scoverage:excludedFiles:"; + private static final String SCALA3_EXCLUDED_FILES_OPTION = "-coverage-exclude-files:"; private static final String PLUGIN_OPTION = "-Xplugin:"; private static final char DOUBLE_QUOTE = '\"';