Skip to content

Commit 93ffc17

Browse files
committed
Aggregate raw coverage data instead of scoverage XML reports
Additionally: - use Scala 2.12 compatible Scoverage dependencies (upgrade from Scala 2.10), - save source roots to 'target/scoverage-data/source.roots' file - without this, source roots which are being added to the project dynamically, during the build (e.g. with build-helper-maven-plugin) wouldn't be visible to 'report-only' mojo.
1 parent 244ed42 commit 93ffc17

File tree

4 files changed

+101
-65
lines changed

4 files changed

+101
-65
lines changed

pom.xml

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -90,13 +90,13 @@ under the License.
9090
<maven.version>2.2.1</maven.version>
9191
<maven-plugin-plugin.version>3.5</maven-plugin-plugin.version>
9292

93-
<scalac-scoverage-plugin.version>1.3.0</scalac-scoverage-plugin.version>
93+
<scalac-scoverage-plugin.version>1.4.0-SNAPSHOT</scalac-scoverage-plugin.version>
9494
</properties>
9595

9696
<dependencies>
9797
<dependency>
9898
<groupId>org.scoverage</groupId>
99-
<artifactId>scalac-scoverage-plugin_2.10</artifactId>
99+
<artifactId>scalac-scoverage-plugin_2.12</artifactId>
100100
<version>${scalac-scoverage-plugin.version}</version>
101101
</dependency>
102102

src/main/java/org/scoverage/plugin/SCoverageCheckMojo.java

Lines changed: 4 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -18,6 +18,7 @@
1818
package org.scoverage.plugin;
1919

2020
import java.io.File;
21+
import java.util.Arrays;
2122
import java.util.List;
2223

2324
import org.apache.maven.plugin.AbstractMojo;
@@ -28,7 +29,7 @@
2829
import org.apache.maven.plugins.annotations.Parameter;
2930
import org.apache.maven.project.MavenProject;
3031

31-
import scala.Predef$;
32+
import scala.collection.JavaConverters;
3233

3334
import scoverage.Coverage;
3435
import scoverage.IOUtils;
@@ -147,8 +148,8 @@ public void execute() throws MojoFailureException
147148
}
148149

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

154155
int branchCount = coverage.branchCount();

src/main/java/org/scoverage/plugin/SCoveragePreCompileMojo.java

Lines changed: 41 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -17,7 +17,11 @@
1717

1818
package org.scoverage.plugin;
1919

20+
import java.io.BufferedWriter;
2021
import java.io.File;
22+
import java.io.FileOutputStream;
23+
import java.io.IOException;
24+
import java.io.OutputStreamWriter;
2125
import java.util.LinkedHashSet;
2226
import java.util.List;
2327
import java.util.Properties;
@@ -304,6 +308,8 @@ else if ( "2.12".equals( resolvedScalaVersion ) || resolvedScalaVersion.startsWi
304308
// VERY IMPORTANT! Prevents from overwriting regular project artifact file
305309
// with instrumented one during "integration-check" or "integration-report" execution.
306310
project.getBuild().setFinalName( "scoverage-" + project.getBuild().getFinalName() );
311+
312+
saveSourceRootsToFile();
307313
}
308314
catch ( ArtifactNotFoundException e )
309315
{
@@ -313,6 +319,10 @@ else if ( "2.12".equals( resolvedScalaVersion ) || resolvedScalaVersion.startsWi
313319
{
314320
throw new MojoExecutionException( "SCoverage preparation failed", e );
315321
}
322+
catch ( IOException e )
323+
{
324+
throw new MojoExecutionException( "SCoverage preparation failed", e );
325+
}
316326

317327
long te = System.currentTimeMillis();
318328
getLog().debug( String.format( "Mojo execution time: %d ms", te - ts ) );
@@ -391,9 +401,9 @@ private Artifact getScalaScoveragePluginArtifact( String scalaMainVersion )
391401
for ( Artifact artifact : pluginArtifacts )
392402
{
393403
if ( "org.scoverage".equals( artifact.getGroupId() )
394-
&& "scalac-scoverage-plugin_2.10".equals( artifact.getArtifactId() ) )
404+
&& "scalac-scoverage-plugin_2.12".equals( artifact.getArtifactId() ) )
395405
{
396-
if ( "2.10".equals( scalaMainVersion ) )
406+
if ( "2.12".equals( scalaMainVersion ) )
397407
{
398408
return artifact; // shortcut, use the same artifact plugin uses
399409
}
@@ -420,7 +430,7 @@ private Artifact getScalaScoverageRuntimeArtifact( String scalaMainVersion )
420430
for ( Artifact artifact : pluginArtifacts )
421431
{
422432
if ( "org.scoverage".equals( artifact.getGroupId() )
423-
&& "scalac-scoverage-plugin_2.10".equals( artifact.getArtifactId() ) )
433+
&& "scalac-scoverage-plugin_2.12".equals( artifact.getArtifactId() ) )
424434
{
425435
resolvedScalacRuntimeVersion = artifact.getVersion();
426436
break;
@@ -456,4 +466,32 @@ private Artifact getResolvedArtifact( String groupId, String artifactId, String
456466
return artifact;
457467
}
458468

469+
private void saveSourceRootsToFile() throws IOException
470+
{
471+
List<String> sourceRoots = project.getCompileSourceRoots();
472+
if ( !sourceRoots.isEmpty() )
473+
{
474+
if ( !dataDirectory.exists() && !dataDirectory.mkdirs() )
475+
{
476+
throw new IOException( String.format( "Cannot create \"%s\" directory ",
477+
dataDirectory.getAbsolutePath() ) );
478+
}
479+
File sourceRootsFile = new File( dataDirectory, "source.roots" );
480+
BufferedWriter writer = new BufferedWriter(
481+
new OutputStreamWriter( new FileOutputStream( sourceRootsFile ), "UTF-8" ) );
482+
try
483+
{
484+
for ( String sourceRoot: sourceRoots )
485+
{
486+
writer.write( sourceRoot );
487+
writer.newLine();
488+
}
489+
}
490+
finally
491+
{
492+
writer.close();
493+
}
494+
}
495+
}
496+
459497
}

src/main/java/org/scoverage/plugin/SCoverageReportMojo.java

Lines changed: 54 additions & 57 deletions
Original file line numberDiff line numberDiff line change
@@ -17,15 +17,16 @@
1717

1818
package org.scoverage.plugin;
1919

20+
import java.io.BufferedReader;
21+
import java.io.InputStreamReader;
22+
import java.io.IOException;
2023
import java.io.File;
24+
import java.io.FileInputStream;
2125
import java.util.ArrayList;
26+
import java.util.Arrays;
2227
import java.util.List;
2328
import java.util.Locale;
2429
import java.util.ResourceBundle;
25-
import javax.xml.parsers.ParserConfigurationException;
26-
import javax.xml.parsers.SAXParser;
27-
import javax.xml.parsers.SAXParserFactory;
28-
import org.xml.sax.SAXException;
2930

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

4546
import scala.Option;
46-
import scala.Predef$;
47-
import scala.collection.Iterator;
48-
import scala.collection.JavaConversions;
47+
import scala.collection.JavaConverters;
4948
import scala.collection.Seq;
50-
import scala.xml.Elem;
51-
import scala.xml.Node;
52-
import scala.xml.NodeSeq;
53-
import scala.xml.XML$;
5449

5550
import scoverage.Constants;
5651
import scoverage.Coverage;
@@ -89,14 +84,26 @@ public class SCoverageReportMojo
8984
private boolean skip;
9085

9186
/**
92-
* Aggregate SCoverage reports.
87+
* In multi-module project additionally generate aggregated SCoverage report.
9388
* <br>
9489
*
9590
* @since 1.1.0
9691
*/
9792
@Parameter( property = "scoverage.aggregate", defaultValue = "false" )
9893
private boolean aggregate;
9994

95+
/**
96+
* In multi-module project generate only aggregated SCoverage report.
97+
* <br>
98+
* <br>
99+
* Scoverage reports for individual modules will not be generated.
100+
* <br>
101+
*
102+
* @since 1.4.0
103+
*/
104+
@Parameter( property = "scoverage.aggregateOnly", defaultValue = "false" )
105+
private boolean aggregateOnly;
106+
100107
/**
101108
* The file encoding to use when reading Scala sources.
102109
* <br>
@@ -297,6 +304,10 @@ private boolean canGenerateNonAggregatedReport()
297304
{
298305
return false;
299306
}
307+
if ( aggregateOnly && reactorProjects.size() > 1 )
308+
{
309+
return false;
310+
}
300311
File coverageFile = Serializer.coverageFile( dataDirectory );
301312
if ( !coverageFile.exists() || !coverageFile.isFile() )
302313
{
@@ -307,12 +318,13 @@ private boolean canGenerateNonAggregatedReport()
307318

308319
private boolean canGenerateAggregatedReport()
309320
{
310-
return aggregate && reactorProjects.size() > 1 && project == reactorProjects.get( reactorProjects.size() - 1 );
321+
return ( aggregate || aggregateOnly ) && reactorProjects.size() > 1
322+
&& project == reactorProjects.get( reactorProjects.size() - 1 );
311323
}
312324

313325
private boolean canAttachAggregatedReportToSite()
314326
{
315-
return aggregate && reactorProjects.size() > 1 && project.isExecutionRoot();
327+
return ( aggregate || aggregateOnly ) && reactorProjects.size() > 1 && project.isExecutionRoot();
316328
}
317329

318330
/** {@inheritDoc} */
@@ -409,9 +421,8 @@ private void generateReports()
409421

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

417428
getLog().info( "Generating coverage reports..." );
@@ -422,24 +433,7 @@ private void generateReports()
422433
private void generateAggregatedReports()
423434
throws MavenReportException
424435
{
425-
SAXParser saxParser = null;
426-
try
427-
{
428-
SAXParserFactory saxParserFactory = SAXParserFactory.newInstance();
429-
saxParserFactory.setFeature( "http://apache.org/xml/features/nonvalidating/load-dtd-grammar", false );
430-
saxParserFactory.setFeature( "http://apache.org/xml/features/nonvalidating/load-external-dtd", false );
431-
saxParser = saxParserFactory.newSAXParser();
432-
}
433-
catch ( ParserConfigurationException e )
434-
{
435-
throw new MavenReportException( "Cannot configure SAXParser", e );
436-
}
437-
catch ( SAXException e )
438-
{
439-
throw new MavenReportException( "Cannot configure SAXParser", e );
440-
}
441-
442-
List<File> scoverageXmlFiles = new ArrayList<File>();
436+
List<File> scoverageDataDirs = new ArrayList<File>();
443437
List<File> sourceRoots = new ArrayList<File>();
444438
MavenProject topLevelModule = null;
445439
for ( MavenProject module : reactorProjects )
@@ -450,51 +444,54 @@ private void generateAggregatedReports()
450444
}
451445
else if ( !module.getPackaging().equals( "pom" ) )
452446
{
453-
File moduleXmlOutputDirectory = rebase( xmlOutputDirectory, module );
454-
File scoverageXmlFile = new File( moduleXmlOutputDirectory, "scoverage.xml" );
455-
if ( scoverageXmlFile.isFile() )
447+
File scoverageDataDir = rebase( dataDirectory, module );
448+
if ( scoverageDataDir.isDirectory() )
456449
{
457-
scoverageXmlFiles.add( scoverageXmlFile );
450+
scoverageDataDirs.add( scoverageDataDir );
458451

459-
File coberturaXmlFile = new File( moduleXmlOutputDirectory, "cobertura.xml" );
460-
if ( coberturaXmlFile.isFile() )
452+
File sourceRootsFile = new File( scoverageDataDir, "source.roots" );
453+
if ( sourceRootsFile.isFile() )
461454
{
462-
Elem xml = ( Elem ) XML$.MODULE$.withSAXParser( saxParser ).loadFile( coberturaXmlFile );
463-
Node sources = xml.$bslash( "sources" ).head();
464-
NodeSeq sourceSeq = sources.$bslash( "source" );
465-
Iterator<Node> it = sourceSeq.iterator();
466-
while ( it.hasNext() )
455+
try
467456
{
468-
Node source = it.next();
469-
String path = source.text().trim();
470-
if ( !"--source".equals( path ) )
457+
BufferedReader r = new BufferedReader( new InputStreamReader(
458+
new FileInputStream( sourceRootsFile ), "UTF-8" ) );
459+
String path = r.readLine();
460+
while ( path != null )
471461
{
472462
sourceRoots.add( new File( path ) );
463+
path = r.readLine();
473464
}
474465
}
466+
catch ( IOException e )
467+
{
468+
throw new MavenReportException( "...", e );
469+
}
475470
}
476471
}
477472
}
478473
}
479474

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

487-
if ( getLog().isDebugEnabled() && scoverageXmlFiles.size() > 0 )
482+
if ( getLog().isDebugEnabled() && scoverageDataDirs.size() > 0 )
488483
{
489-
getLog().debug( String.format( "Found %d subproject report files:", scoverageXmlFiles.size() ) );
490-
for ( File file: scoverageXmlFiles )
484+
getLog().debug( String.format( "Found %d subproject subproject scoverage data directories:",
485+
scoverageDataDirs.size() ) );
486+
for ( File dataDir: scoverageDataDirs )
491487
{
492-
getLog().debug( String.format( "- %s", file.getAbsolutePath() ) );
488+
getLog().debug( String.format( "- %s", dataDir.getAbsolutePath() ) );
493489
}
494490
}
495491
else
496492
{
497-
getLog().info( String.format( "Found %d subproject report files.", scoverageXmlFiles.size() ) );
493+
getLog().info( String.format( "Found %d subproject scoverage data directories.",
494+
scoverageDataDirs.size() ) );
498495
}
499496

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

506503
Coverage coverage =
507-
CoverageAggregator.aggregatedCoverage( JavaConversions.asScalaBuffer( scoverageXmlFiles ).toSeq() );
504+
CoverageAggregator.aggregatedCoverage( JavaConverters.asScalaBuffer( scoverageDataDirs ).toSeq() );
508505

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

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

0 commit comments

Comments
 (0)