All Downloads are FREE. Search and download functionalities are using the official Maven repository.

org.codehaus.mojo.cobertura.CoberturaReportMojo Maven / Gradle / Ivy

Go to download

This is the Mojo's Maven plugin for Cobertura. Cobertura is a free Java tool that calculates the percentage of code accessed by tests. It can be used to identify which parts of your Java program are lacking test coverage.

The newest version!
/*
 * #%L
 * Mojo's Maven plugin for Cobertura
 * %%
 * Copyright (C) 2005 - 2013 Codehaus
 * %%
 * Licensed 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.
 * #L%
 */
package org.codehaus.mojo.cobertura;

import net.sourceforge.cobertura.coveragedata.CoverageDataFileHandler;
import net.sourceforge.cobertura.coveragedata.ProjectData;
import org.apache.maven.artifact.Artifact;
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.mojo.cobertura.configuration.MaxHeapSizeUtil;
import org.codehaus.mojo.cobertura.tasks.CommandLineArguments;
import org.codehaus.mojo.cobertura.tasks.ReportTask;

import java.io.File;
import java.net.URI;
import java.util.ArrayList;
import java.util.Collections;
import java.util.HashMap;
import java.util.List;
import java.util.Locale;
import java.util.Map;
import java.util.ResourceBundle;

/**
 * Instrument the compiled classes, run the unit tests and generate a Cobertura
 * report.
 *
 * @author Will Gwaltney
 * @author Joakim Erdfelt
 * @goal cobertura
 * @execute phase="test" lifecycle="cobertura"
 */
public class CoberturaReportMojo
    extends AbstractMavenReport
{
    /**
     * The format of the report. Supports 'html' or 'xml'. Defaults to 'html'.
     *
     * @parameter expression="${cobertura.report.format}"
     * @deprecated
     */
    private String format;

    /**
     * The formats of the report. Can be 'html' and/or 'xml'. Defaults to 'html'.
     *
     * @parameter
     */
    private String[] formats = new String[]{ "html" };

    /**
     * The encoding for the java source code files.
     *
     * @parameter expression="${project.build.sourceEncoding}" default-value="UTF-8".
     * @since 2.4
     */
    private String encoding;

    /**
     * Maximum memory to pass to the JVM for Cobertura processes.
     *
     * @parameter expression="${cobertura.maxmem}"
     */
    private String maxmem = "64m";

    /**
     * 

* The Datafile Location. *

* * @parameter expression="${cobertura.datafile}" default-value="${project.build.directory}/cobertura/cobertura.ser" * @required * @readonly */ private File dataFile; /** * Maven Internal: List of artifacts for the plugin. * * @parameter default-value="${plugin.artifacts}" * @required * @readonly */ private List pluginClasspathList; /** * The output directory for the report. * * @parameter default-value="${project.reporting.outputDirectory}/cobertura" * @required */ private File outputDirectory; /** * Only output Cobertura errors, avoid info messages. * * @parameter expression="${quiet}" default-value="false" * @since 2.1 */ private boolean quiet; /** * Generate aggregate reports in multi-module projects. * * @parameter expression="${cobertura.aggregate}" default-value="false" * @since 2.5 */ private boolean aggregate; /** * Whether to remove GPL licensed files from the generated report. * This is required to distribute the report as part of a distribution, * which is licensed under the ASL, or a similar license, which is * incompatible with the GPL. * * @parameter default-value="false" expression="${cobertura.omitGplFiles}" * @since 2.5 */ private boolean omitGplFiles; /** * Maven Internal: The Doxia Site Renderer. * * @component */ private Renderer siteRenderer; /** * List of maven project of the current build * * @parameter expression="${reactorProjects}" * @required * @readonly */ private List reactorProjects; /** * Maven Internal: Project to interact with. * * @parameter default-value="${project}" * @required * @readonly */ private MavenProject project; private Map> projectChildren; private String relDataFileName; private String relAggregateOutputDir; /** * Constructs a CoberturaReportMojo. * Sets the max memory to the maven max memory if set, otherwise * the default CoberturaReportMojo value is used. */ public CoberturaReportMojo() { if ( MaxHeapSizeUtil.getInstance().envHasMavenMaxMemSetting() ) { maxmem = MaxHeapSizeUtil.getInstance().getMavenMaxMemSetting(); } } /** * @param locale for the message bundle * @return localized cobertura name * @see org.apache.maven.reporting.MavenReport#getName(java.util.Locale) */ public String getName( Locale locale ) { return getBundle( locale ).getString( "report.cobertura.name" ); } /** * @param locale for the message bundle * @return localized description * @see org.apache.maven.reporting.MavenReport#getDescription(java.util.Locale) */ public String getDescription( Locale locale ) { return getBundle( locale ).getString( "report.cobertura.description" ); } @Override protected String getOutputDirectory() { return outputDirectory.getAbsolutePath(); } @Override protected MavenProject getProject() { return project; } @Override protected Renderer getSiteRenderer() { return siteRenderer; } /** * perform the actual reporting * * @param task * @param outputFormat * @throws MavenReportException */ private void executeReportTask( ReportTask task, String outputFormat ) throws MavenReportException { task.setOutputFormat( outputFormat ); // execute task try { task.execute(); } catch ( MojoExecutionException e ) { // throw new MavenReportException( "Error in Cobertura Report generation: " + e.getMessage(), e ); // better don't break the build if report is not generated, also due to the sporadic MCOBERTURA-56 getLog().error( "Error in Cobertura Report generation: " + e.getMessage(), e ); } } /** * {@inheritDoc} */ @Override protected void executeReport( Locale locale ) throws MavenReportException { if ( canGenerateSimpleReport() ) { executeReport( getDataFile(), outputDirectory, getCompileSourceRoots() ); } if ( canGenerateAggregateReports() ) { executeAggregateReport( locale ); } } /** * Generates aggregate cobertura reports for all multi-module projects. */ private void executeAggregateReport( Locale locale ) throws MavenReportException { for ( MavenProject proj : reactorProjects ) { 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 = getAllChildren( curProject ); 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 ( File serFile : serFiles ) { 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 ( MavenProject child : children ) { 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 task.setLog( getLog() ); task.setPluginClasspathList( pluginClasspathList ); task.setQuiet( quiet ); // task specifics task.setMaxmem( maxmem ); 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 }; } for ( int i = 0; i < formats.length; i++ ) { executeReportTask( task, formats[i] ); } removeGplFiles(); } /** * Removes files from the generated report, which are distributed under * the GPL. */ private void removeGplFiles() throws MavenReportException { if ( omitGplFiles ) { final String[] files = new String[]{ "js/customsorttypes.js", "js/sortabletable.js", "js/stringbuilder.js" }; for ( int i = 0; i < files.length; i++ ) { final File f = new File( outputDirectory, files[i] ); if ( f.exists() ) { if ( f.delete() ) { getLog().debug( "Removed GPL licensed file " + f.getPath() ); } else { throw new MavenReportException( "Unable to remove GPL licensed file " + f.getPath() ); } } else { getLog().info( "GPL licensed file " + f.getPath() + " not found." ); } } } } /** * {@inheritDoc} */ public String getOutputName() { return "cobertura/index"; } @Override public boolean isExternalReport() { return true; } @Override public boolean canGenerateReport() { if ( canGenerateSimpleReport() ) { return true; } else { getLog().info( "Not executing cobertura:report as the cobertura data file (" + getDataFile() + ") could not be found" ); } 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. * * @return true if a simple report can be generated, otherwise false */ 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. */ return getDataFile().exists() && getDataFile().isFile(); } /** * 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. */ @SuppressWarnings( "unchecked" ) private List getCompileSourceRoots() { return project.getExecutionProject().getCompileSourceRoots(); } @Override public void setReportOutputDirectory( File reportOutputDirectory ) { if ( ( reportOutputDirectory != null ) && ( !reportOutputDirectory.getAbsolutePath().endsWith( "cobertura" ) ) ) { this.outputDirectory = new File( reportOutputDirectory, "cobertura" ); } else { this.outputDirectory = reportOutputDirectory; } } /** * Gets the resource bundle for the report text. * * @param locale The locale for the report, must not be null. * @return The resource bundle for the requested locale. */ private ResourceBundle getBundle( Locale locale ) { return ResourceBundle.getBundle( "cobertura-report", locale ); } /** * 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 "pom".equals( mavenProject.getPackaging() ); } /** * 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 ( MavenProject proj : reactorProjects ) { List depList = 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(), getDataFile() ); 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 a list containing all the recursive, non-pom children of the given project, never null. */ private List getAllChildren( MavenProject parentProject ) { List children = projectChildren.get( parentProject ); if ( children == null ) { return Collections.emptyList(); } List result = new ArrayList(); for ( MavenProject child : children ) { if ( isMultiModule( child ) ) { result.addAll( getAllChildren( child ) ); } else { result.add( child ); } } return result; } /** * Returns any existing cobertura data files from the given list of projects. */ private List getOutputFiles( List projects ) { List files = new ArrayList(); for ( MavenProject proj : projects ) { 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; } /** * Get the data file which is or will be generated by Cobertura, never null. * * @return the data file */ private File getDataFile() { return dataFile; } }




© 2015 - 2025 Weber Informatics LLC | Privacy Policy