diff --git a/pom.xml b/pom.xml index d26566e0..b36ca214 100644 --- a/pom.xml +++ b/pom.xml @@ -90,14 +90,14 @@ under the License. 2.2.1 3.6.0 - 1.4.11 - 2.12.15 + 2.0.7 + 2.13 org.scoverage - scalac-scoverage-plugin_${scalac-scoverage-plugin.scala.version} + scalac-scoverage-reporter_${scalac-scoverage-plugin.scala.version} ${scalac-scoverage-plugin.version} @@ -264,12 +264,12 @@ under the License. umlgraph 5.6.6 - + -inferrel -inferdep -quiet -hide (java|javax)\..* -collpackages java\.util\..* -qualify -postfixpackage -nodefontsize 9 -nodefontpackagesize 7 - + @@ -380,7 +380,7 @@ under the License. org.codehaus.mojo.signature - java16 + java18 1.0 diff --git a/src/main/java/org/scoverage/plugin/SCoverageCheckMojo.java b/src/main/java/org/scoverage/plugin/SCoverageCheckMojo.java index 688e7a40..42d19af2 100644 --- a/src/main/java/org/scoverage/plugin/SCoverageCheckMojo.java +++ b/src/main/java/org/scoverage/plugin/SCoverageCheckMojo.java @@ -30,11 +30,11 @@ import org.apache.maven.project.MavenProject; import scala.Tuple2; -import scala.collection.JavaConverters; +import scala.jdk.javaapi.CollectionConverters; -import scoverage.Coverage; -import scoverage.IOUtils; -import scoverage.Serializer; +import scoverage.domain.Coverage; +import scoverage.reporter.IOUtils; +import scoverage.serialize.Serializer; /** * Checks if minimum code coverage by unit tests reached @@ -93,6 +93,15 @@ public class SCoverageCheckMojo @Parameter( property = "scoverage.failOnMinimumCoverage", defaultValue = "false" ) private boolean failOnMinimumCoverage; + /** + * The file encoding to use when reading Scala sources. + *
+ * + * @since 1.4.12 + */ + @Parameter( property = "encoding", defaultValue = "${project.build.sourceEncoding}" ) + private String encoding; + /** * Maven project to interact with. */ @@ -148,10 +157,10 @@ public void execute() throws MojoFailureException return; } - Coverage coverage = Serializer.deserialize( coverageFile ); + Coverage coverage = Serializer.deserialize( coverageFile, project.getBasedir() ); List measurementFiles = Arrays.asList( IOUtils.findMeasurementFiles( dataDirectory ) ); scala.collection.Set> measurements = - IOUtils.invoked( JavaConverters.asScalaBuffer( measurementFiles ) ); + IOUtils.invoked( CollectionConverters.asScala( measurementFiles ).toSeq(), encoding ); coverage.apply( measurements ); int branchCount = coverage.branchCount(); @@ -165,7 +174,7 @@ public void execute() throws MojoFailureException invokedBranchesCount, branchCount, invokedStatementCount, statementCount ) ); if ( minimumCoverage > 0.0 ) { - String minimumCoverageFormatted = scoverage.DoubleFormat.twoFractionDigits( minimumCoverage ); + String minimumCoverageFormatted = scoverage.domain.DoubleFormat.twoFractionDigits( minimumCoverage ); if ( is100( minimumCoverage ) && is100( coverage.statementCoveragePercent() ) ) { getLog().info( "100% Coverage !" ); diff --git a/src/main/java/org/scoverage/plugin/SCoveragePreCompileMojo.java b/src/main/java/org/scoverage/plugin/SCoveragePreCompileMojo.java index c57ef7ba..ca621eab 100644 --- a/src/main/java/org/scoverage/plugin/SCoveragePreCompileMojo.java +++ b/src/main/java/org/scoverage/plugin/SCoveragePreCompileMojo.java @@ -22,19 +22,19 @@ import java.io.FileOutputStream; import java.io.IOException; import java.io.OutputStreamWriter; -import java.util.HashMap; -import java.util.LinkedHashSet; -import java.util.List; -import java.util.Map; -import java.util.Properties; -import java.util.Set; +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; import org.apache.maven.artifact.resolver.ArtifactNotFoundException; import org.apache.maven.artifact.resolver.ArtifactResolutionException; import org.apache.maven.artifact.resolver.ArtifactResolver; +import org.apache.maven.artifact.versioning.ArtifactVersion; +import org.apache.maven.artifact.versioning.DefaultArtifactVersion; import org.apache.maven.model.Dependency; import org.apache.maven.plugin.AbstractMojo; import org.apache.maven.plugin.MojoExecutionException; @@ -286,20 +286,19 @@ else if ( "2.13".equals( resolvedScalaVersion ) || resolvedScalaVersion.startsWi try { - Artifact pluginArtifact = getScalaScoveragePluginArtifact( resolvedScalaVersion, scalaBinaryVersion ); + List pluginArtifacts = getScalaScoveragePluginArtifacts( resolvedScalaVersion, scalaBinaryVersion ); Artifact runtimeArtifact = getScalaScoverageRuntimeArtifact( scalaBinaryVersion ); - if ( pluginArtifact == null ) - { - return; // scoverage plugin will not be configured - } - addScoverageDependenciesToClasspath( runtimeArtifact ); String arg = DATA_DIR_OPTION + dataDirectory.getAbsolutePath(); String _scalacOptions = quoteArgument( arg ); String addScalacArgs = arg; + arg = SOURCE_ROOT_OPTION + project.getBasedir().getAbsolutePath(); + _scalacOptions = _scalacOptions + SPACE + quoteArgument( arg ); + addScalacArgs = addScalacArgs + PIPE + arg; + if ( !StringUtils.isEmpty( excludedPackages ) ) { arg = EXCLUDED_PACKAGES_OPTION + excludedPackages.replace( "(empty)", "" ); @@ -320,11 +319,10 @@ else if ( "2.13".equals( resolvedScalaVersion ) || resolvedScalaVersion.startsWi addScalacArgs = addScalacArgs + PIPE + "-Yrangepos"; } - String _scalacPlugins = - String.format( "%s:%s:%s", pluginArtifact.getGroupId(), pluginArtifact.getArtifactId(), - pluginArtifact.getVersion() ); + String _scalacPlugins = pluginArtifacts.stream() + .map(x -> String.format("%s:%s:%s", x.getGroupId(), x.getArtifactId(),x.getVersion())).collect(Collectors.joining(" ")); - arg = PLUGIN_OPTION + pluginArtifact.getFile().getAbsolutePath(); + 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(); @@ -371,6 +369,7 @@ else if ( "2.13".equals( resolvedScalaVersion ) || resolvedScalaVersion.startsWi private static final String SCALA_LIBRARY_ARTIFACT_ID = "scala-library"; private static final String DATA_DIR_OPTION = "-P:scoverage:dataDir:"; + 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 PLUGIN_OPTION = "-Xplugin:"; @@ -427,7 +426,7 @@ private void setProperty( Properties projectProperties, String propertyName, Str } } - private Artifact getScalaScoveragePluginArtifact( String resolvedScalaVersion, String scalaMainVersion ) + private List getScalaScoveragePluginArtifacts(String resolvedScalaVersion, String scalaMainVersion ) throws ArtifactNotFoundException, ArtifactResolutionException { String resolvedScalacPluginVersion = scalacPluginVersion; @@ -444,22 +443,39 @@ private Artifact getScalaScoveragePluginArtifact( String resolvedScalaVersion, S } } - try + // There are 3 cases depending on the version of scalac-scoverage-plugin + // * Version 2.0.0 onwards - 3 artifacts, plugin using resolvedScalaVersion + // * Version 1.4.2 - 1 artifact, plugin using resolvedScalaVersion falling back to scalaMainVersion + // * Version 1.4.1 older - 1 artifact, plugin using scalaMainVersion + // + final ArtifactVersion pluginArtifactVersion = new DefaultArtifactVersion(resolvedScalacPluginVersion); + if(pluginArtifactVersion.getMajorVersion() >= 2) { + List 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)); + return resolvedArtifacts; + } else if (pluginArtifactVersion.getMajorVersion() == 1 && pluginArtifactVersion.getMinorVersion() == 4 && pluginArtifactVersion.getIncrementalVersion() == 2) { - return getResolvedArtifact( - "org.scoverage", "scalac-scoverage-plugin_" + resolvedScalaVersion, - resolvedScalacPluginVersion ); - } - catch ( ArtifactNotFoundException | ArtifactResolutionException e ) - { - getLog().warn( String.format( "Artifact \"org.scoverage:scalac-scoverage-plugin_%s:%s\" not found, " + - "falling back to \"org.scoverage:scalac-scoverage-plugin_%s:%s\"", - resolvedScalaVersion, resolvedScalacPluginVersion, scalaMainVersion, resolvedScalacPluginVersion ) ); - - // for scalac-scoverage-plugin versions up to 1.4.1 - return getResolvedArtifact( - "org.scoverage", "scalac-scoverage-plugin_" + scalaMainVersion, - resolvedScalacPluginVersion ); + try + { + return Collections.singletonList( + getResolvedArtifact("org.scoverage", "scalac-scoverage-plugin_" + resolvedScalaVersion, resolvedScalacPluginVersion ) + ); + } + catch ( ArtifactNotFoundException | ArtifactResolutionException e2 ) + { + getLog().warn( String.format( "Artifact \"org.scoverage:scalac-scoverage-plugin_%s:%s\" not found, " + + "falling back to \"org.scoverage:scalac-scoverage-plugin_%s:%s\"", + resolvedScalaVersion, resolvedScalacPluginVersion, scalaMainVersion, resolvedScalacPluginVersion ) ); + return Collections.singletonList( + getResolvedArtifact("org.scoverage", "scalac-scoverage-plugin_" + scalaMainVersion, resolvedScalacPluginVersion ) + ); + } + } else { + return Collections.singletonList( + getResolvedArtifact("org.scoverage", "scalac-scoverage-plugin_" + scalaMainVersion, resolvedScalacPluginVersion ) + ); } } diff --git a/src/main/java/org/scoverage/plugin/SCoverageReportMojo.java b/src/main/java/org/scoverage/plugin/SCoverageReportMojo.java index 20f9b0e3..855883ee 100644 --- a/src/main/java/org/scoverage/plugin/SCoverageReportMojo.java +++ b/src/main/java/org/scoverage/plugin/SCoverageReportMojo.java @@ -27,6 +27,7 @@ import java.util.List; import java.util.Locale; import java.util.ResourceBundle; +import java.util.concurrent.atomic.AtomicInteger; import org.apache.maven.doxia.module.xhtml.decoration.render.RenderingContext; import org.apache.maven.doxia.sink.Sink; @@ -46,17 +47,18 @@ import scala.Option; import scala.Tuple2; -import scala.collection.JavaConverters; -import scala.collection.Seq; - -import scoverage.Constants; -import scoverage.Coverage; -import scoverage.IOUtils; -import scoverage.Serializer; -import scoverage.report.CoberturaXmlWriter; -import scoverage.report.CoverageAggregator; -import scoverage.report.ScoverageHtmlWriter; -import scoverage.report.ScoverageXmlWriter; +import scala.collection.immutable.Seq; +import scala.jdk.javaapi.CollectionConverters; + +import scoverage.domain.Constants; +import scoverage.domain.Coverage; +import scoverage.domain.Statement; +import scoverage.reporter.IOUtils; +import scoverage.serialize.Serializer; +import scoverage.reporter.CoberturaXmlWriter; +import scoverage.reporter.CoverageAggregator; +import scoverage.reporter.ScoverageHtmlWriter; +import scoverage.reporter.ScoverageXmlWriter; /** * Generates code coverage by unit tests report in forked {@code scoverage} life cycle. @@ -419,13 +421,13 @@ private void generateReports() File coverageFile = Serializer.coverageFile( dataDirectory ); getLog().info( String.format( "Reading scoverage instrumentation [%s]...", coverageFile.getAbsolutePath() ) ); - Coverage coverage = Serializer.deserialize( coverageFile ); + Coverage coverage = Serializer.deserialize( coverageFile, project.getBasedir() ); getLog().info( String.format( "Reading scoverage measurements [%s*]...", new File( dataDirectory, Constants.MeasurementsPrefix() ).getAbsolutePath() ) ); List measurementFiles = Arrays.asList( IOUtils.findMeasurementFiles( dataDirectory ) ); scala.collection.Set> measurements = - IOUtils.invoked( JavaConverters.asScalaBuffer( measurementFiles ) ); + IOUtils.invoked( CollectionConverters.asScala( measurementFiles ).toSeq(), encoding ); coverage.apply( measurements ); getLog().info( "Generating coverage reports..." ); @@ -436,6 +438,8 @@ private void generateReports() private void generateAggregatedReports() throws MavenReportException { + Coverage coverage = new Coverage(); + AtomicInteger id = new AtomicInteger(); List scoverageDataDirs = new ArrayList(); List sourceRoots = new ArrayList(); MavenProject topLevelModule = null; @@ -451,6 +455,33 @@ else if ( !module.getPackaging().equals( "pom" ) ) if ( scoverageDataDir.isDirectory() ) { scoverageDataDirs.add( scoverageDataDir ); + File coverageFile = Serializer.coverageFile(scoverageDataDir); + if (coverageFile.exists()) { + Coverage subCoverage = Serializer.deserialize(coverageFile, module.getBasedir()); + List measurementFiles = Arrays.asList( IOUtils.findMeasurementFiles( scoverageDataDir ) ); + scala.collection.Set> measurements = + IOUtils.invoked( CollectionConverters.asScala( measurementFiles ).toSeq(), encoding ); + subCoverage.apply( measurements ); + subCoverage.statements().foreach(statement -> { + int statementId = id.getAndIncrement(); + Statement copy = statement.copy( + statement.location(), + statementId, + statement.start(), + statement.end(), + statement.line(), + statement.desc(), + statement.symbolName(), + statement.treeName(), + statement.branch(), + statement.count(), + statement.ignored(), + statement.tests() + ); + coverage.add(copy); + return null; + }); + } File sourceRootsFile = new File( scoverageDataDir, "source.roots" ); if ( sourceRootsFile.isFile() ) @@ -510,9 +541,6 @@ else if ( !module.getPackaging().equals( "pom" ) ) mkdirs( topLevelModuleOutputDirectory ); mkdirs( topLevelModuleXmlOutputDirectory ); - Coverage coverage = - CoverageAggregator.aggregatedCoverage( JavaConverters.asScalaBuffer( scoverageDataDirs ).toSeq() ); - getLog().info( "Generating coverage aggregated reports..." ); writeReports( coverage, sourceRoots, topLevelModuleXmlOutputDirectory, topLevelModuleXmlOutputDirectory, topLevelModuleOutputDirectory ); @@ -522,13 +550,13 @@ else if ( !module.getPackaging().equals( "pom" ) ) private void writeReports( Coverage coverage, List sourceRoots, File coberturaXmlOutputDirectory, File scoverageXmlOutputDirectory, File scoverageHtmlOutputDirectory ) { - Seq sourceRootsAsScalaSeq = JavaConverters.asScalaBuffer( sourceRoots ); + Seq sourceRootsAsScalaSeq = CollectionConverters.asScala( sourceRoots ).toSeq(); - new CoberturaXmlWriter( sourceRootsAsScalaSeq, coberturaXmlOutputDirectory ).write( coverage ); + new CoberturaXmlWriter( sourceRootsAsScalaSeq, coberturaXmlOutputDirectory, Option.apply( encoding ) ).write( coverage ); getLog().info( String.format( "Written Cobertura XML report [%s]", new File( coberturaXmlOutputDirectory, "cobertura.xml" ).getAbsolutePath() ) ); - new ScoverageXmlWriter( sourceRootsAsScalaSeq, scoverageXmlOutputDirectory, false ).write( coverage ); + new ScoverageXmlWriter( sourceRootsAsScalaSeq, scoverageXmlOutputDirectory, false, Option.apply( encoding ) ).write( coverage ); getLog().info( String.format( "Written XML coverage report [%s]", new File( scoverageXmlOutputDirectory, "scoverage.xml" ).getAbsolutePath() ) );