Skip to content

Aggregate raw coverage data instead of scoverage XML reports #64

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 1 commit into from
Dec 22, 2018
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 2 additions & 2 deletions pom.xml
Original file line number Diff line number Diff line change
Expand Up @@ -90,13 +90,13 @@ under the License.
<maven.version>2.2.1</maven.version>
<maven-plugin-plugin.version>3.5</maven-plugin-plugin.version>

<scalac-scoverage-plugin.version>1.3.0</scalac-scoverage-plugin.version>
<scalac-scoverage-plugin.version>1.4.0-SNAPSHOT</scalac-scoverage-plugin.version>
</properties>

<dependencies>
<dependency>
<groupId>org.scoverage</groupId>
<artifactId>scalac-scoverage-plugin_2.10</artifactId>
<artifactId>scalac-scoverage-plugin_2.12</artifactId>
<version>${scalac-scoverage-plugin.version}</version>
</dependency>

Expand Down
7 changes: 4 additions & 3 deletions src/main/java/org/scoverage/plugin/SCoverageCheckMojo.java
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,7 @@
package org.scoverage.plugin;

import java.io.File;
import java.util.Arrays;
import java.util.List;

import org.apache.maven.plugin.AbstractMojo;
Expand All @@ -28,7 +29,7 @@
import org.apache.maven.plugins.annotations.Parameter;
import org.apache.maven.project.MavenProject;

import scala.Predef$;
import scala.collection.JavaConverters;

import scoverage.Coverage;
import scoverage.IOUtils;
Expand Down Expand Up @@ -147,8 +148,8 @@ public void execute() throws MojoFailureException
}

Coverage coverage = Serializer.deserialize( coverageFile );
File[] measurementFiles = IOUtils.findMeasurementFiles( dataDirectory );
scala.collection.Set<Object> measurements = IOUtils.invoked( Predef$.MODULE$.wrapRefArray( measurementFiles ) );
List<File> measurementFiles = Arrays.asList( IOUtils.findMeasurementFiles( dataDirectory ) );
scala.collection.Set<Object> measurements = IOUtils.invoked( JavaConverters.asScalaBuffer( measurementFiles ) );
coverage.apply( measurements );

int branchCount = coverage.branchCount();
Expand Down
44 changes: 41 additions & 3 deletions src/main/java/org/scoverage/plugin/SCoveragePreCompileMojo.java
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,11 @@

package org.scoverage.plugin;

import java.io.BufferedWriter;
import java.io.File;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.OutputStreamWriter;
import java.util.LinkedHashSet;
import java.util.List;
import java.util.Properties;
Expand Down Expand Up @@ -304,6 +308,8 @@ else if ( "2.12".equals( resolvedScalaVersion ) || resolvedScalaVersion.startsWi
// VERY IMPORTANT! Prevents from overwriting regular project artifact file
// with instrumented one during "integration-check" or "integration-report" execution.
project.getBuild().setFinalName( "scoverage-" + project.getBuild().getFinalName() );

saveSourceRootsToFile();
}
catch ( ArtifactNotFoundException e )
{
Expand All @@ -313,6 +319,10 @@ else if ( "2.12".equals( resolvedScalaVersion ) || resolvedScalaVersion.startsWi
{
throw new MojoExecutionException( "SCoverage preparation failed", e );
}
catch ( IOException e )
{
throw new MojoExecutionException( "SCoverage preparation failed", e );
}

long te = System.currentTimeMillis();
getLog().debug( String.format( "Mojo execution time: %d ms", te - ts ) );
Expand Down Expand Up @@ -391,9 +401,9 @@ private Artifact getScalaScoveragePluginArtifact( String scalaMainVersion )
for ( Artifact artifact : pluginArtifacts )
{
if ( "org.scoverage".equals( artifact.getGroupId() )
&& "scalac-scoverage-plugin_2.10".equals( artifact.getArtifactId() ) )
&& "scalac-scoverage-plugin_2.12".equals( artifact.getArtifactId() ) )
{
if ( "2.10".equals( scalaMainVersion ) )
if ( "2.12".equals( scalaMainVersion ) )
{
return artifact; // shortcut, use the same artifact plugin uses
}
Expand All @@ -420,7 +430,7 @@ private Artifact getScalaScoverageRuntimeArtifact( String scalaMainVersion )
for ( Artifact artifact : pluginArtifacts )
{
if ( "org.scoverage".equals( artifact.getGroupId() )
&& "scalac-scoverage-plugin_2.10".equals( artifact.getArtifactId() ) )
&& "scalac-scoverage-plugin_2.12".equals( artifact.getArtifactId() ) )
{
resolvedScalacRuntimeVersion = artifact.getVersion();
break;
Expand Down Expand Up @@ -456,4 +466,32 @@ private Artifact getResolvedArtifact( String groupId, String artifactId, String
return artifact;
}

private void saveSourceRootsToFile() throws IOException
{
List<String> sourceRoots = project.getCompileSourceRoots();
if ( !sourceRoots.isEmpty() )
{
if ( !dataDirectory.exists() && !dataDirectory.mkdirs() )
{
throw new IOException( String.format( "Cannot create \"%s\" directory ",
dataDirectory.getAbsolutePath() ) );
}
File sourceRootsFile = new File( dataDirectory, "source.roots" );
BufferedWriter writer = new BufferedWriter(
new OutputStreamWriter( new FileOutputStream( sourceRootsFile ), "UTF-8" ) );
try
{
for ( String sourceRoot: sourceRoots )
{
writer.write( sourceRoot );
writer.newLine();
}
}
finally
{
writer.close();
}
}
}

}
111 changes: 54 additions & 57 deletions src/main/java/org/scoverage/plugin/SCoverageReportMojo.java
Original file line number Diff line number Diff line change
Expand Up @@ -17,15 +17,16 @@

package org.scoverage.plugin;

import java.io.BufferedReader;
import java.io.InputStreamReader;
import java.io.IOException;
import java.io.File;
import java.io.FileInputStream;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
import java.util.Locale;
import java.util.ResourceBundle;
import javax.xml.parsers.ParserConfigurationException;
import javax.xml.parsers.SAXParser;
import javax.xml.parsers.SAXParserFactory;
import org.xml.sax.SAXException;

import org.apache.maven.doxia.module.xhtml.decoration.render.RenderingContext;
import org.apache.maven.doxia.siterenderer.sink.SiteRendererSink;
Expand All @@ -43,14 +44,8 @@
import org.codehaus.plexus.util.StringUtils;

import scala.Option;
import scala.Predef$;
import scala.collection.Iterator;
import scala.collection.JavaConversions;
import scala.collection.JavaConverters;
import scala.collection.Seq;
import scala.xml.Elem;
import scala.xml.Node;
import scala.xml.NodeSeq;
import scala.xml.XML$;

import scoverage.Constants;
import scoverage.Coverage;
Expand Down Expand Up @@ -89,14 +84,26 @@ public class SCoverageReportMojo
private boolean skip;

/**
* Aggregate SCoverage reports.
* In multi-module project additionally generate aggregated SCoverage report.
* <br>
*
* @since 1.1.0
*/
@Parameter( property = "scoverage.aggregate", defaultValue = "false" )
private boolean aggregate;

/**
* In multi-module project generate only aggregated SCoverage report.
* <br>
* <br>
* Scoverage reports for individual modules will not be generated.
* <br>
*
* @since 1.4.0
*/
@Parameter( property = "scoverage.aggregateOnly", defaultValue = "false" )
private boolean aggregateOnly;

/**
* The file encoding to use when reading Scala sources.
* <br>
Expand Down Expand Up @@ -297,6 +304,10 @@ private boolean canGenerateNonAggregatedReport()
{
return false;
}
if ( aggregateOnly && reactorProjects.size() > 1 )
{
return false;
}
File coverageFile = Serializer.coverageFile( dataDirectory );
if ( !coverageFile.exists() || !coverageFile.isFile() )
{
Expand All @@ -307,12 +318,13 @@ private boolean canGenerateNonAggregatedReport()

private boolean canGenerateAggregatedReport()
{
return aggregate && reactorProjects.size() > 1 && project == reactorProjects.get( reactorProjects.size() - 1 );
return ( aggregate || aggregateOnly ) && reactorProjects.size() > 1
&& project == reactorProjects.get( reactorProjects.size() - 1 );
}

private boolean canAttachAggregatedReportToSite()
{
return aggregate && reactorProjects.size() > 1 && project.isExecutionRoot();
return ( aggregate || aggregateOnly ) && reactorProjects.size() > 1 && project.isExecutionRoot();
}

/** {@inheritDoc} */
Expand Down Expand Up @@ -409,9 +421,8 @@ private void generateReports()

getLog().info( String.format( "Reading scoverage measurements [%s*]...",
new File( dataDirectory, Constants.MeasurementsPrefix() ).getAbsolutePath() ) );
File[] measurementFiles = IOUtils.findMeasurementFiles( dataDirectory );
scala.collection.Set<Object> measurements = IOUtils.invoked( Predef$.MODULE$
.wrapRefArray( measurementFiles ) );
List<File> measurementFiles = Arrays.asList( IOUtils.findMeasurementFiles( dataDirectory ) );
scala.collection.Set<Object> measurements = IOUtils.invoked( JavaConverters.asScalaBuffer( measurementFiles ) );
coverage.apply( measurements );

getLog().info( "Generating coverage reports..." );
Expand All @@ -422,24 +433,7 @@ private void generateReports()
private void generateAggregatedReports()
throws MavenReportException
{
SAXParser saxParser = null;
try
{
SAXParserFactory saxParserFactory = SAXParserFactory.newInstance();
saxParserFactory.setFeature( "http://apache.org/xml/features/nonvalidating/load-dtd-grammar", false );
saxParserFactory.setFeature( "http://apache.org/xml/features/nonvalidating/load-external-dtd", false );
saxParser = saxParserFactory.newSAXParser();
}
catch ( ParserConfigurationException e )
{
throw new MavenReportException( "Cannot configure SAXParser", e );
}
catch ( SAXException e )
{
throw new MavenReportException( "Cannot configure SAXParser", e );
}

List<File> scoverageXmlFiles = new ArrayList<File>();
List<File> scoverageDataDirs = new ArrayList<File>();
List<File> sourceRoots = new ArrayList<File>();
MavenProject topLevelModule = null;
for ( MavenProject module : reactorProjects )
Expand All @@ -450,51 +444,54 @@ private void generateAggregatedReports()
}
else if ( !module.getPackaging().equals( "pom" ) )
{
File moduleXmlOutputDirectory = rebase( xmlOutputDirectory, module );
File scoverageXmlFile = new File( moduleXmlOutputDirectory, "scoverage.xml" );
if ( scoverageXmlFile.isFile() )
File scoverageDataDir = rebase( dataDirectory, module );
if ( scoverageDataDir.isDirectory() )
{
scoverageXmlFiles.add( scoverageXmlFile );
scoverageDataDirs.add( scoverageDataDir );

File coberturaXmlFile = new File( moduleXmlOutputDirectory, "cobertura.xml" );
if ( coberturaXmlFile.isFile() )
File sourceRootsFile = new File( scoverageDataDir, "source.roots" );
if ( sourceRootsFile.isFile() )
{
Elem xml = ( Elem ) XML$.MODULE$.withSAXParser( saxParser ).loadFile( coberturaXmlFile );
Node sources = xml.$bslash( "sources" ).head();
NodeSeq sourceSeq = sources.$bslash( "source" );
Iterator<Node> it = sourceSeq.iterator();
while ( it.hasNext() )
try
{
Node source = it.next();
String path = source.text().trim();
if ( !"--source".equals( path ) )
BufferedReader r = new BufferedReader( new InputStreamReader(
new FileInputStream( sourceRootsFile ), "UTF-8" ) );
String path = r.readLine();
while ( path != null )
{
sourceRoots.add( new File( path ) );
path = r.readLine();
}
}
catch ( IOException e )
{
throw new MavenReportException( "...", e );
}
}
}
}
}

/* Empty report must be generated or top-level site will contain invalid link to non-existent Scoverage report
if ( scoverageXmlFiles.isEmpty() )
if ( scoverageDataDirs.isEmpty() )
{
getLog().info( "No subproject data to aggregate, skipping SCoverage report generation" );
return;
}*/

if ( getLog().isDebugEnabled() && scoverageXmlFiles.size() > 0 )
if ( getLog().isDebugEnabled() && scoverageDataDirs.size() > 0 )
{
getLog().debug( String.format( "Found %d subproject report files:", scoverageXmlFiles.size() ) );
for ( File file: scoverageXmlFiles )
getLog().debug( String.format( "Found %d subproject subproject scoverage data directories:",
scoverageDataDirs.size() ) );
for ( File dataDir: scoverageDataDirs )
{
getLog().debug( String.format( "- %s", file.getAbsolutePath() ) );
getLog().debug( String.format( "- %s", dataDir.getAbsolutePath() ) );
}
}
else
{
getLog().info( String.format( "Found %d subproject report files.", scoverageXmlFiles.size() ) );
getLog().info( String.format( "Found %d subproject scoverage data directories.",
scoverageDataDirs.size() ) );
}

File topLevelModuleOutputDirectory = rebase( outputDirectory, topLevelModule );
Expand All @@ -504,7 +501,7 @@ else if ( !module.getPackaging().equals( "pom" ) )
mkdirs( topLevelModuleXmlOutputDirectory );

Coverage coverage =
CoverageAggregator.aggregatedCoverage( JavaConversions.asScalaBuffer( scoverageXmlFiles ).toSeq() );
CoverageAggregator.aggregatedCoverage( JavaConverters.asScalaBuffer( scoverageDataDirs ).toSeq() );

getLog().info( "Generating coverage aggregated reports..." );
writeReports( coverage, sourceRoots, topLevelModuleXmlOutputDirectory, topLevelModuleXmlOutputDirectory,
Expand All @@ -515,7 +512,7 @@ else if ( !module.getPackaging().equals( "pom" ) )
private void writeReports( Coverage coverage, List<File> sourceRoots, File coberturaXmlOutputDirectory,
File scoverageXmlOutputDirectory, File scoverageHtmlOutputDirectory )
{
Seq<File> sourceRootsAsScalaSeq = JavaConversions.asScalaBuffer( sourceRoots );
Seq<File> sourceRootsAsScalaSeq = JavaConverters.asScalaBuffer( sourceRoots );

new CoberturaXmlWriter( sourceRootsAsScalaSeq, coberturaXmlOutputDirectory ).write( coverage );
getLog().info( String.format( "Written Cobertura XML report [%s]",
Expand Down