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

org.jacoco.maven.ReportSupport Maven / Gradle / Ivy

Go to download

The JaCoCo Maven Plugin provides the JaCoCo runtime agent to your tests and allows basic report creation.

There is a newer version: 0.8.12
Show newest version
/*******************************************************************************
 * Copyright (c) 2009, 2019 Mountainminds GmbH & Co. KG and Contributors
 * This program and the accompanying materials are made available under
 * the terms of the Eclipse Public License 2.0 which is available at
 * http://www.eclipse.org/legal/epl-2.0
 *
 * SPDX-License-Identifier: EPL-2.0
 *
 * Contributors:
 *    Evgeny Mandrikov - initial API and implementation
 *    Kyle Lieber - implementation of CheckMojo
 *
 *******************************************************************************/
package org.jacoco.maven;

import static java.lang.String.format;

import java.io.File;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStreamReader;
import java.io.Reader;
import java.util.ArrayList;
import java.util.Collection;
import java.util.List;
import java.util.Locale;

import org.apache.maven.plugin.logging.Log;
import org.apache.maven.project.MavenProject;
import org.jacoco.core.analysis.Analyzer;
import org.jacoco.core.analysis.CoverageBuilder;
import org.jacoco.core.analysis.IBundleCoverage;
import org.jacoco.core.analysis.IClassCoverage;
import org.jacoco.core.tools.ExecFileLoader;
import org.jacoco.report.FileMultiReportOutput;
import org.jacoco.report.IReportGroupVisitor;
import org.jacoco.report.IReportVisitor;
import org.jacoco.report.ISourceFileLocator;
import org.jacoco.report.MultiReportVisitor;
import org.jacoco.report.check.IViolationsOutput;
import org.jacoco.report.check.Rule;
import org.jacoco.report.check.RulesChecker;
import org.jacoco.report.csv.CSVFormatter;
import org.jacoco.report.html.HTMLFormatter;
import org.jacoco.report.xml.XMLFormatter;

/**
 * Encapsulates the tasks to create reports for Maven projects. Instances are
 * supposed to be used in the following sequence:
 *
 * 
    *
  1. Create an instance
  2. *
  3. Load one or multiple exec files with * loadExecutionData()
  4. *
  5. Add one or multiple formatters with addXXX() methods
  6. *
  7. Create the root visitor with initRootVisitor()
  8. *
  9. Process one or multiple projects with processProject()
  10. *
*/ final class ReportSupport { private final Log log; private final ExecFileLoader loader; private final List formatters; /** * Construct a new instance with the given log output. * * @param log * for log output */ public ReportSupport(final Log log) { this.log = log; this.loader = new ExecFileLoader(); this.formatters = new ArrayList(); } /** * Loads the given execution data file. * * @param execFile * execution data file to load * @throws IOException * if the file can't be loaded */ public void loadExecutionData(final File execFile) throws IOException { log.info("Loading execution data file " + execFile); loader.load(execFile); } public void addXmlFormatter(final File targetfile, final String encoding) throws IOException { final XMLFormatter xml = new XMLFormatter(); xml.setOutputEncoding(encoding); formatters.add(xml.createVisitor(new FileOutputStream(targetfile))); } public void addCsvFormatter(final File targetfile, final String encoding) throws IOException { final CSVFormatter csv = new CSVFormatter(); csv.setOutputEncoding(encoding); formatters.add(csv.createVisitor(new FileOutputStream(targetfile))); } public void addHtmlFormatter(final File targetdir, final String encoding, final String footer, final Locale locale) throws IOException { final HTMLFormatter htmlFormatter = new HTMLFormatter(); htmlFormatter.setOutputEncoding(encoding); htmlFormatter.setLocale(locale); if (footer != null) { htmlFormatter.setFooterText(footer); } formatters.add(htmlFormatter .createVisitor(new FileMultiReportOutput(targetdir))); } public void addAllFormatters(final File targetdir, final String encoding, final String footer, final Locale locale) throws IOException { targetdir.mkdirs(); addXmlFormatter(new File(targetdir, "jacoco.xml"), encoding); addCsvFormatter(new File(targetdir, "jacoco.csv"), encoding); addHtmlFormatter(targetdir, encoding, footer, locale); } public void addRulesChecker(final List rules, final IViolationsOutput output) { final RulesChecker checker = new RulesChecker(); checker.setRules(rules); formatters.add(checker.createVisitor(output)); } public IReportVisitor initRootVisitor() throws IOException { final IReportVisitor visitor = new MultiReportVisitor(formatters); visitor.visitInfo(loader.getSessionInfoStore().getInfos(), loader.getExecutionDataStore().getContents()); return visitor; } /** * Calculates coverage for the given project and emits it to the report * group without source references * * @param visitor * group visitor to emit the project's coverage to * @param project * the MavenProject * @param includes * list of includes patterns * @param excludes * list of excludes patterns * @throws IOException * if class files can't be read */ public void processProject(final IReportGroupVisitor visitor, final MavenProject project, final List includes, final List excludes) throws IOException { processProject(visitor, project.getArtifactId(), project, includes, excludes, new NoSourceLocator()); } /** * Calculates coverage for the given project and emits it to the report * group including source references * * @param visitor * group visitor to emit the project's coverage to * @param bundeName * name for this project in the report * @param project * the MavenProject * @param includes * list of includes patterns * @param excludes * list of excludes patterns * @param srcEncoding * encoding of the source files within this project * @throws IOException * if class files can't be read */ public void processProject(final IReportGroupVisitor visitor, final String bundeName, final MavenProject project, final List includes, final List excludes, final String srcEncoding) throws IOException { processProject(visitor, bundeName, project, includes, excludes, new SourceFileCollection(project, srcEncoding)); } private void processProject(final IReportGroupVisitor visitor, final String bundeName, final MavenProject project, final List includes, final List excludes, final ISourceFileLocator locator) throws IOException { final CoverageBuilder builder = new CoverageBuilder(); final File classesDir = new File( project.getBuild().getOutputDirectory()); if (classesDir.isDirectory()) { final Analyzer analyzer = new Analyzer( loader.getExecutionDataStore(), builder); final FileFilter filter = new FileFilter(includes, excludes); for (final File file : filter.getFiles(classesDir)) { analyzer.analyzeAll(file); } } final IBundleCoverage bundle = builder.getBundle(bundeName); logBundleInfo(bundle, builder.getNoMatchClasses()); visitor.visitBundle(bundle, locator); } private void logBundleInfo(final IBundleCoverage bundle, final Collection nomatch) { log.info(format("Analyzed bundle '%s' with %s classes", bundle.getName(), Integer.valueOf(bundle.getClassCounter().getTotalCount()))); if (!nomatch.isEmpty()) { log.warn(format( "Classes in bundle '%s' do no match with execution data. " + "For report generation the same class files must be used as at runtime.", bundle.getName())); for (final IClassCoverage c : nomatch) { log.warn(format("Execution data for class %s does not match.", c.getName())); } } if (bundle.containsCode() && bundle.getLineCounter().getTotalCount() == 0) { log.warn( "To enable source code annotation class files have to be compiled with debug information."); } } private class NoSourceLocator implements ISourceFileLocator { public Reader getSourceFile(final String packageName, final String fileName) { return null; } public int getTabWidth() { return 0; } } private class SourceFileCollection implements ISourceFileLocator { private final List sourceRoots; private final String encoding; public SourceFileCollection(final MavenProject project, final String encoding) { this.sourceRoots = getCompileSourceRoots(project); this.encoding = encoding; } public Reader getSourceFile(final String packageName, final String fileName) throws IOException { final String r; if (packageName.length() > 0) { r = packageName + '/' + fileName; } else { r = fileName; } for (final File sourceRoot : sourceRoots) { final File file = new File(sourceRoot, r); if (file.exists() && file.isFile()) { return new InputStreamReader(new FileInputStream(file), encoding); } } return null; } public int getTabWidth() { return 4; } } private static List getCompileSourceRoots( final MavenProject project) { final List result = new ArrayList(); for (final Object path : project.getCompileSourceRoots()) { result.add(resolvePath(project, (String) path)); } return result; } private static File resolvePath(final MavenProject project, final String path) { File file = new File(path); if (!file.isAbsolute()) { file = new File(project.getBasedir(), path); } return file; } }




© 2015 - 2024 Weber Informatics LLC | Privacy Policy