Index: src/main/java/org/codehaus/mojo/cobertura/CoberturaReportMojo.java
===================================================================
--- src/main/java/org/codehaus/mojo/cobertura/CoberturaReportMojo.java (revision 13790)
+++ src/main/java/org/codehaus/mojo/cobertura/CoberturaReportMojo.java (working copy)
@@ -20,16 +20,25 @@
*/
import java.io.File;
+import java.io.IOException;
+import java.net.URI;
+import java.util.ArrayList;
+import java.util.HashMap;
+import java.util.Iterator;
import java.util.List;
import java.util.Locale;
+import java.util.Map;
import java.util.ResourceBundle;
+import net.sourceforge.cobertura.coveragedata.CoverageDataFileHandler;
+import net.sourceforge.cobertura.coveragedata.ProjectData;
+import org.apache.maven.doxia.siterenderer.Renderer;
import org.apache.maven.plugin.MojoExecutionException;
import org.apache.maven.project.MavenProject;
import org.apache.maven.reporting.AbstractMavenReport;
import org.apache.maven.reporting.MavenReportException;
import org.codehaus.doxia.sink.Sink;
-import org.codehaus.doxia.site.renderer.SiteRenderer;
+import org.codehaus.mojo.cobertura.tasks.CommandLineArguments;
import org.codehaus.mojo.cobertura.tasks.ReportTask;
/**
@@ -110,13 +119,29 @@
private boolean quiet;
/**
+ * Generate aggregate reports in multi-module projects.
+ *
+ * @parameter expression="${cobertura.aggregate}" default-value="false"
+ */
+ private boolean aggregate;
+
+ /**
* Maven Internal: The Doxia Site Renderer.
*
* @component
*/
- private SiteRenderer siteRenderer;
+ private Renderer siteRenderer;
/**
+ * List of maven project of the current build
+ *
+ * @parameter expression="${reactorProjects}"
+ * @required
+ * @readonly
+ */
+ protected List reactorProjects;
+
+ /**
* Maven Internal: Project to interact with.
*
* @parameter default-value="${project}"
@@ -125,6 +150,10 @@
*/
private MavenProject project;
+ private Map projectChildren;
+ private String relDataFileName;
+ private String relAggregateOutputDir;
+
/**
* @see org.apache.maven.reporting.MavenReport#getName(java.util.Locale)
* @param locale for the message bundle
@@ -167,7 +196,7 @@
* @see org.apache.maven.reporting.AbstractMavenReport#getSiteRenderer()
* @return SiteRenderer
*/
- protected SiteRenderer getSiteRenderer()
+ protected Renderer getSiteRenderer()
{
return siteRenderer;
}
@@ -213,12 +242,83 @@
protected void executeReport( Locale locale )
throws MavenReportException
{
+ if ( canGenerateSimpleReport() )
+ {
+ executeReport(dataFile, outputDirectory, getCompileSourceRoots());
+ }
- if ( !canGenerateReport() )
+ if(canGenerateAggregateReports()) {
+ executeAggregateReport(locale);
+ }
+ }
+
+ /**
+ * Generates aggregate cobertura reports for all multi-module projects.
+ */
+ private void executeAggregateReport( Locale locale )
+ throws MavenReportException
{
+ for(Iterator iter = reactorProjects.iterator(); iter.hasNext(); ) {
+ MavenProject proj = (MavenProject)iter.next();
+ if(!isMultiModule(proj)) {
+ continue;
+ }
+ executeAggregateReport(locale, proj);
+ }
+ }
+
+ /**
+ * Generates an aggregate cobertura report for the given project.
+ */
+ private void executeAggregateReport( Locale locale, MavenProject curProject )
+ throws MavenReportException
+ {
+ List children = new ArrayList();
+ getAllChildren(curProject, children);
+
+ if(children.isEmpty()) {
return;
}
+ List serFiles = getOutputFiles(children);
+ if(serFiles.isEmpty()) {
+ getLog().info("Not executing aggregate cobertura:report for " + curProject.getName() +
+ " as no child cobertura data files could not be found" );
+ return;
+ }
+
+ getLog().info("Executing aggregate cobertura:report for " + curProject.getName());
+
+ ProjectData aggProjectData = new ProjectData();
+ for (Iterator iter = serFiles.iterator(); iter.hasNext(); ) {
+ File serFile = (File)iter.next();
+ ProjectData data = CoverageDataFileHandler.loadCoverageData(serFile);
+ aggProjectData.merge(data);
+ }
+
+ File aggSerFile = new File(curProject.getBasedir(), relDataFileName);
+ aggSerFile.getAbsoluteFile().getParentFile().mkdirs();
+ getLog().info("Saving aggregate cobertura information in " + aggSerFile.getAbsolutePath());
+ CoverageDataFileHandler.saveCoverageData(aggProjectData, aggSerFile);
+
+ // get all compile source roots
+ List aggCompileSourceRoots = new ArrayList();
+ for(Iterator iter = children.iterator(); iter.hasNext(); ) {
+ MavenProject child = (MavenProject)iter.next();
+ aggCompileSourceRoots.addAll(child.getCompileSourceRoots());
+ }
+
+ File reportDir = new File(curProject.getBasedir(), relAggregateOutputDir);
+ reportDir.mkdirs();
+ executeReport(aggSerFile, reportDir, aggCompileSourceRoots);
+ }
+
+ /**
+ * Executes the cobertura report task for the given dataFile, outputDirectory, and compileSourceRoots.
+ */
+ private void executeReport(File curDataFile, File curOutputDirectory, List curCompileSourceRoots)
+ throws MavenReportException
+ {
ReportTask task = new ReportTask();
// task defaults
@@ -228,12 +328,16 @@
// task specifics
task.setMaxmem( maxmem );
- task.setDataFile( dataFile );
- task.setOutputDirectory( outputDirectory );
- task.setCompileSourceRoots( getCompileSourceRoots() );
+ task.setDataFile( curDataFile );
+ task.setOutputDirectory( curOutputDirectory );
+ task.setCompileSourceRoots( curCompileSourceRoots );
task.setSourceEncoding( encoding );
-
+ CommandLineArguments cmdLineArgs;
+ cmdLineArgs = new CommandLineArguments();
+ cmdLineArgs.setUseCommandsFile(true);
+ task.setCmdLineArgs(cmdLineArgs);
+
if ( format != null )
{
formats = new String[] { format };
@@ -266,14 +370,34 @@
*/
public boolean canGenerateReport()
{
+ if(canGenerateSimpleReport()) {
+ return true;
+ }
+ if(canGenerateAggregateReports()) {
+ return true;
+ }
+
+ if(aggregate && isMultiModule(project)) {
+ // unfortunately, we don't know before hand whether we can generate an aggregate report for a
+ // multi-module. if we return false here, then we won't get a link in the main reports list. so we'll
+ // just be optimistic
+ return true;
+ }
+ return false;
+ }
+
+ /**
+ * Returns whether or not we can generate a simple (non-aggregate) report for this project.
+ */
+ private boolean canGenerateSimpleReport()
+ {
/*
* Don't have to check for source directories or java code or the like for report generation. Checks for source
* directories or java project classpath existence should only occur in the Instrument Mojo.
*/
if ( dataFile == null || !dataFile.exists() )
{
- getLog().info(
- "Not executing cobertura:report as the cobertura data file (" + dataFile
+ getLog().info("Not executing cobertura:report as the cobertura data file (" + dataFile
+ ") could not be found" );
return false;
}
@@ -283,6 +407,25 @@
}
}
+ /**
+ * Returns whether or not we can generate any aggregate reports at this time.
+ */
+ private boolean canGenerateAggregateReports()
+ {
+ // we only generate aggregate reports after the last project runs
+ if(aggregate && isLastProject(project, reactorProjects)) {
+ buildAggregateInfo();
+
+ if(!getOutputFiles(reactorProjects).isEmpty()) {
+ return true;
+ }
+ }
+ return false;
+ }
+
+ /**
+ * Returns the compileSourceRoots for the currently executing project.
+ */
private List getCompileSourceRoots()
{
return project.getExecutionProject().getCompileSourceRoots();
@@ -314,4 +457,126 @@
return ResourceBundle.getBundle( "cobertura-report", locale, getClass().getClassLoader() );
}
+ /**
+ * Check whether the element is the last element of the list
+ *
+ * @param project element to check
+ * @param mavenProjectList list of maven project
+ * @return true if project is the last element of mavenProjectList list
+ */
+ private boolean isLastProject(MavenProject project, List mavenProjectList)
+ {
+ return project.equals(mavenProjectList.get(mavenProjectList.size() - 1));
}
+
+ /**
+ * Test if the project has pom packaging
+ *
+ * @param mavenProject Project to test
+ * @return True if it has a pom packaging
+ */
+ private boolean isMultiModule(MavenProject mavenProject)
+ {
+ return mavenProject.getPackaging().equals("pom");
+ }
+
+ /**
+ * Generates various information needed for building aggregate reports.
+ */
+ private void buildAggregateInfo()
+ {
+ if(projectChildren != null) {
+ // already did this work
+ return;
+ }
+
+ // build parent-child map
+ projectChildren = new HashMap();
+ for(Iterator iter = reactorProjects.iterator(); iter.hasNext(); ) {
+ MavenProject proj = (MavenProject)iter.next();
+ List depList = (List)projectChildren.get(proj.getParent());
+ if(depList == null) {
+ depList = new ArrayList();
+ projectChildren.put(proj.getParent(), depList);
+ }
+ depList.add(proj);
+ }
+
+ // attempt to determine where data files and output dir are
+ relDataFileName = relativize(project.getBasedir(), dataFile);
+ if(relDataFileName == null) {
+ getLog().warn("Could not determine relative data file name, defaulting to 'cobertura/cobertura.ser'");
+ relDataFileName = "cobertura/cobertura.ser";
+ }
+ relAggregateOutputDir = relativize(project.getBasedir(), outputDirectory);
+ if(relAggregateOutputDir == null) {
+ getLog().warn("Could not determine relative output dir name, defaulting to 'cobertura'");
+ relAggregateOutputDir = "cobertura";
+ }
+ }
+
+ /**
+ * Returns all the recursive, non-pom children of the given project.
+ */
+ private void getAllChildren(MavenProject parentProject, List allChildren)
+ {
+ List children = (List)projectChildren.get(parentProject);
+ if(children == null) {
+ return;
+ }
+
+ for(Iterator iter = children.iterator(); iter.hasNext(); ) {
+ MavenProject child = (MavenProject)iter.next();
+ if(isMultiModule(child)) {
+ getAllChildren(child, allChildren);
+ } else {
+ allChildren.add(child);
+ }
+ }
+ }
+
+ /**
+ * Returns any existing cobertura data files from the given list of projects.
+ */
+ private List getOutputFiles(List projects)
+ {
+ List files = new ArrayList();
+ for(Iterator iter = projects.iterator(); iter.hasNext(); ) {
+ MavenProject proj = (MavenProject)iter.next();
+ if(isMultiModule(proj)) {
+ continue;
+ }
+ File outputFile = new File(proj.getBasedir(), relDataFileName);
+ if(outputFile.exists()) {
+ files.add(outputFile);
+ }
+ }
+ return files;
+ }
+
+ /**
+ * Attempts to make the given childFile relative to the given parentFile.
+ */
+ private String relativize(File parentFile, File childFile)
+ {
+ try {
+ URI parentURI = parentFile.getCanonicalFile().toURI().normalize();
+ URI childURI = childFile.getCanonicalFile().toURI().normalize();
+
+ URI relativeURI = parentURI.relativize(childURI);
+ if(relativeURI.isAbsolute()) {
+ // child is not relative to parent
+ return null;
+ }
+ String relativePath = relativeURI.getPath();
+ if(File.separatorChar != '/') {
+ relativePath = relativePath.replace('/', File.separatorChar);
+ }
+ return relativePath;
+ } catch(Exception e) {
+ getLog().warn("Failed relativizing " + childFile + " to " + parentFile, e);
+ }
+ return null;
+ }
+
+}
Index: src/it/mcobertura-65/pom.xml
===================================================================
--- src/it/mcobertura-65/pom.xml (revision 0)
+++ src/it/mcobertura-65/pom.xml (revision 0)
@@ -0,0 +1,61 @@
+
+
+ 4.0.0
+ org.codehaus.mojo.cobertura.its
+ agg-report-it
+ pom
+ 2.5-SNAPSHOT
+ agg-report-it
+
+ @sitePluginVersion@
+ @pom.version@
+
+
+
+
+
+
+ junit
+ junit
+ 4.8.2
+ test
+
+
+
+
+ proj1
+ proj2
+
+
+
+
+ org.apache.maven.plugins
+ maven-site-plugin
+ ${site-plugin-version}
+
+
+
+
+ true
+
+
+ org.codehaus.mojo
+ cobertura-maven-plugin
+ ${main-plugin-version}
+
+ true
+
+
+
+
+
+
+ test-dev
+
+ 2.2
+ 2.5-SNAPSHOT
+
+
+
+
+
Property changes on: src/it/mcobertura-65/pom.xml
___________________________________________________________________
Added: svn:mime-type
+ text/plain
Added: svn:eol-style
+ native
Index: src/it/mcobertura-65/proj1/src/main/java/org/codehaus/mojo/cobertura/it/Proj1Code.java
===================================================================
--- src/it/mcobertura-65/proj1/src/main/java/org/codehaus/mojo/cobertura/it/Proj1Code.java (revision 0)
+++ src/it/mcobertura-65/proj1/src/main/java/org/codehaus/mojo/cobertura/it/Proj1Code.java (revision 0)
@@ -0,0 +1,41 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
+package org.codehaus.mojo.cobertura.it;
+
+public class Proj1Code {
+
+ private String str;
+
+ public Proj1Code() {
+ //
+ }
+
+ public void setStr(String str) {
+ this.str = str;
+ }
+
+ public String getStr() {
+ return str;
+ }
+
+ public String toString() {
+ return super.toString() + " {} " + str;
+ }
+}
Property changes on: src/it/mcobertura-65/proj1/src/main/java/org/codehaus/mojo/cobertura/it/Proj1Code.java
___________________________________________________________________
Added: svn:mime-type
+ text/plain
Added: svn:eol-style
+ native
Index: src/it/mcobertura-65/proj1/pom.xml
===================================================================
--- src/it/mcobertura-65/proj1/pom.xml (revision 0)
+++ src/it/mcobertura-65/proj1/pom.xml (revision 0)
@@ -0,0 +1,22 @@
+
+ 4.0.0
+ org.codehaus.mojo.cobertura.its
+ agg-report-it-proj1
+ jar
+ 2.5-SNAPSHOT
+ agg-report-it-proj1
+
+ org.codehaus.mojo.cobertura.its
+ agg-report-it
+ 2.5-SNAPSHOT
+
+
+
+ junit
+ junit
+ 4.8.2
+ test
+
+
+
Property changes on: src/it/mcobertura-65/proj1/pom.xml
___________________________________________________________________
Added: svn:mime-type
+ text/plain
Added: svn:eol-style
+ native
Index: src/it/mcobertura-65/proj2/src/test/java/org/codehaus/mojo/cobertura/it/Proj2Test.java
===================================================================
--- src/it/mcobertura-65/proj2/src/test/java/org/codehaus/mojo/cobertura/it/Proj2Test.java (revision 0)
+++ src/it/mcobertura-65/proj2/src/test/java/org/codehaus/mojo/cobertura/it/Proj2Test.java (revision 0)
@@ -0,0 +1,32 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
+package org.codehaus.mojo.cobertura.it;
+
+import junit.framework.TestCase;
+
+public class Proj2Test extends TestCase {
+
+ public void testSomethingElse() {
+ Proj2Code code = new Proj2Code();
+ code.setStr("Hello Sailor");
+ code.toString();
+ }
+
+}
Property changes on: src/it/mcobertura-65/proj2/src/test/java/org/codehaus/mojo/cobertura/it/Proj2Test.java
___________________________________________________________________
Added: svn:mime-type
+ text/plain
Added: svn:eol-style
+ native
Index: src/it/mcobertura-65/proj2/src/main/java/org/codehaus/mojo/cobertura/it/Proj2Code.java
===================================================================
--- src/it/mcobertura-65/proj2/src/main/java/org/codehaus/mojo/cobertura/it/Proj2Code.java (revision 0)
+++ src/it/mcobertura-65/proj2/src/main/java/org/codehaus/mojo/cobertura/it/Proj2Code.java (revision 0)
@@ -0,0 +1,41 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
+package org.codehaus.mojo.cobertura.it;
+
+public class Proj2Code {
+
+ private String str;
+
+ public Proj2Code() {
+ //
+ }
+
+ public void setStr(String str) {
+ this.str = str;
+ }
+
+ public String getStr() {
+ return str;
+ }
+
+ public String toString() {
+ return super.toString() + " {} " + str;
+ }
+}
Property changes on: src/it/mcobertura-65/proj2/src/main/java/org/codehaus/mojo/cobertura/it/Proj2Code.java
___________________________________________________________________
Added: svn:mime-type
+ text/plain
Added: svn:eol-style
+ native
Index: src/it/mcobertura-65/proj2/pom.xml
===================================================================
--- src/it/mcobertura-65/proj2/pom.xml (revision 0)
+++ src/it/mcobertura-65/proj2/pom.xml (revision 0)
@@ -0,0 +1,23 @@
+
+ 4.0.0
+ org.codehaus.mojo.cobertura.its
+ agg-report-it-proj2
+ jar
+ 2.5-SNAPSHOT
+ agg-report-it-proj2
+
+ org.codehaus.mojo.cobertura.its
+ agg-report-it
+ 2.5-SNAPSHOT
+
+
+
+
+ junit
+ junit
+ 4.8.2
+ test
+
+
+
Property changes on: src/it/mcobertura-65/proj2/pom.xml
___________________________________________________________________
Added: svn:mime-type
+ text/plain
Added: svn:eol-style
+ native
Index: pom.xml
===================================================================
--- pom.xml (revision 13790)
+++ pom.xml (working copy)
@@ -37,7 +37,7 @@
- 2.0.1
+ 2.1
@@ -124,34 +124,30 @@
org.apache.maven
maven-artifact
- 2.0
+ 2.2.1
org.apache.maven
maven-plugin-api
- 2.0
+ 2.2.1
org.apache.maven.reporting
maven-reporting-api
- 2.0
+ 2.2.1
org.apache.maven
maven-project
- 2.0
+ 2.2.1
org.apache.maven.reporting
maven-reporting-impl
- 2.0
+ 2.0.4.2
+
- org.codehaus.plexus
- plexus-container-default
- 1.0-alpha-9
-
-
commons-lang
commons-lang
2.4
@@ -161,6 +157,12 @@
plexus-utils
2.0.2
+
+ org.apache.maven.shared
+ maven-invoker
+ 2.0.11
+
+
httpunit
@@ -171,6 +173,8 @@
junit
junit
+ 4.8.1
+ test
org.apache.maven.shared