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

org.jboss.maven.plugin.coverage.CoverageMojo Maven / Gradle / Ivy

/*
 * JBoss, Home of Professional Open Source
 * Copyright 2015 Red Hat Inc. and/or its affiliates and other
 * contributors as indicated by the @author tags. All rights reserved.
 * See the copyright.txt in the distribution for a full listing of
 * individual contributors.
 *
 * This is free software; you can redistribute it and/or modify it
 * under the terms of the GNU Lesser General Public License as
 * published by the Free Software Foundation; either version 2.1 of
 * the License, or (at your option) any later version.
 *
 * This software is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
 * Lesser General Public License for more details.
 *
 * You should have received a copy of the GNU Lesser General Public
 * License along with this software; if not, write to the Free
 * Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
 * 02110-1301 USA, or see the FSF site: http://www.fsf.org.
 */

package org.jboss.maven.plugin.coverage;

import java.io.BufferedReader;
import java.io.File;
import java.io.FileReader;
import java.io.IOException;
import java.net.MalformedURLException;
import java.net.URL;
import java.net.URLClassLoader;
import java.util.ArrayList;
import java.util.List;

import org.apache.maven.artifact.DependencyResolutionRequiredException;
import org.apache.maven.model.Build;
import org.apache.maven.plugin.AbstractMojo;
import org.apache.maven.plugin.MojoExecutionException;
import org.apache.maven.plugin.MojoFailureException;
import org.apache.maven.plugins.annotations.LifecyclePhase;
import org.apache.maven.plugins.annotations.Mojo;
import org.apache.maven.plugins.annotations.Parameter;
import org.apache.maven.plugins.annotations.ResolutionScope;
import org.apache.maven.project.MavenProject;

/**
 * @author Ales Justin
 */
@Mojo(name = "coverage", defaultPhase = LifecyclePhase.PROCESS_TEST_CLASSES, requiresDependencyResolution = ResolutionScope.RUNTIME)
public class CoverageMojo extends AbstractMojo implements Configuration {
    /**
     * The Maven Project Object
     */
    @Parameter(required = true, property = "project")
    protected MavenProject project;

    /**
     * Module.
     */
    @Parameter
    protected String module;

    /**
     * Tests.
     */
    @Parameter
    protected boolean tests = true;

    /**
     * Exclusion.
     */
    @Parameter
    protected String exclusion;

    /**
     * Interfaces.
     */
    @Parameter
    protected List interfaces;

    /**
     * Coverage file.
     */
    @Parameter
    protected String coverageFile = "coverage.txt";

    /**
     * Repository host.
     */
    @Parameter
    protected String repositoryHost = "github.com";

    /**
     * Repository user.
     */
    @Parameter
    protected String repositoryUser;

    /**
     * Repository project.
     */
    @Parameter
    protected String repositoryProject;

    /**
     * Repository branch.
     */
    @Parameter
    protected String repositoryBranch = "master";

    /**
     * Coverage title.
     */
    @Parameter
    protected String coverageTitle;

    /**
     * Javadoc root.
     */
    @Parameter
    protected String javadocRoot;

    public void execute() throws MojoExecutionException, MojoFailureException {
        List classPathUrls = getClassPathUrls(tests);
        ClassLoader cl = new URLClassLoader(classPathUrls.toArray(new URL[classPathUrls.size()]), getClass().getClassLoader());
        Build build = project.getBuild();
        File classesToScan = tests ? new File(build.getTestOutputDirectory()) : new File(build.getOutputDirectory());
        getLog().info("Classes to scan: " + classesToScan);
        List classes = new ArrayList<>();
        if (interfaces != null) {
            classes.addAll(interfaces);
        }
        try {
            readInterfaces(classesToScan, classes);
            MethodExclusion me = createExclusion(cl, classesToScan);
            CodeCoverage.report(this, module, cl, project.getBasedir(), classesToScan, me, classes.toArray(new String[classes.size()]));
        } catch (Exception e) {
            throw new MojoExecutionException("Failed to execute coverage report.", e);
        }
    }

    /**
     * Builds a classpath based on the maven project's compile classpath elements.
     *
     * @param isTest do we modify tests
     * @return The {@link ClassLoader} made up of the maven project's compile classpath elements.
     * @throws MojoExecutionException Indicates an issue processing one of the classpath elements
     */
    private List getClassPathUrls(boolean isTest) throws MojoExecutionException {
        List classPathUrls = new ArrayList<>();
        for (String path : projectCompileClasspathElements(isTest)) {
            try {
                getLog().debug("Adding project compile classpath element : " + path);
                classPathUrls.add(new File(path).toURI().toURL());
            } catch (MalformedURLException e) {
                throw new MojoExecutionException("Unable to build path URL [" + path + "]");
            }
        }
        return classPathUrls;
    }

    /**
     * Essentially a call to {@link MavenProject#getCompileClasspathElements} except that here we
     * cast it to the generic type and internally handle {@link org.apache.maven.artifact.DependencyResolutionRequiredException}.
     *
     * @param isTest do we modify tests
     * @return The compile classpath elements
     * @throws MojoExecutionException Indicates a {@link org.apache.maven.artifact.DependencyResolutionRequiredException} was encountered
     */
    private List projectCompileClasspathElements(boolean isTest) throws MojoExecutionException {
        try {
            if (isTest) {
                return project.getTestClasspathElements();
            } else {
                return project.getCompileClasspathElements();
            }
        } catch (DependencyResolutionRequiredException e) {
            throw new MojoExecutionException("Call to MavenProject#getCompileClasspathElements required dependency resolution");
        }
    }

    @SuppressWarnings("unchecked")
    private MethodExclusion createExclusion(ClassLoader cl, File root) throws Exception {
        if (exclusion != null) {
            Class clazz = (Class) cl.loadClass(exclusion);
            return clazz.getConstructor(File.class).newInstance(root);
        } else {
            return FileMethodExclusion.create(root);
        }
    }

    private void readInterfaces(File root, List classes) throws IOException {
        String cf = System.getProperty("coverage.file", coverageFile);
        File coverage = new File(root, cf);
        if (coverage.exists()) {
            getLog().info("Reading interfaces from " + coverage);
            try (BufferedReader reader = new BufferedReader(new FileReader(coverage))) {
                String line;
                while ((line = reader.readLine()) != null) {
                    if (line.length() > 0 && line.startsWith("#") == false) {
                        classes.add(line);
                    }
                }
            }
        }
    }

    public MavenProject getProject() {
        return project;
    }

    public void setProject(MavenProject project) {
        this.project = project;
    }

    public boolean isTests() {
        return tests;
    }

    public void setTests(boolean tests) {
        this.tests = tests;
    }

    public String getExclusion() {
        return exclusion;
    }

    public void setExclusion(String exclusion) {
        this.exclusion = exclusion;
    }

    public List getInterfaces() {
        return interfaces;
    }

    public void setInterfaces(List interfaces) {
        this.interfaces = interfaces;
    }

    public String getCoverageFile() {
        return coverageFile;
    }

    public void setCoverageFile(String coverageFile) {
        this.coverageFile = coverageFile;
    }

    public String getRepositoryHost() {
        return repositoryHost;
    }

    public void setRepositoryHost(String repositoryHost) {
        this.repositoryHost = repositoryHost;
    }

    public String getRepositoryUser() {
        return repositoryUser;
    }

    public void setRepositoryUser(String repositoryUser) {
        this.repositoryUser = repositoryUser;
    }

    public String getRepositoryProject() {
        return repositoryProject;
    }

    public void setRepositoryProject(String repositoryProject) {
        this.repositoryProject = repositoryProject;
    }

    public String getRepositoryBranch() {
        return repositoryBranch;
    }

    public void setRepositoryBranch(String repositoryBranch) {
        this.repositoryBranch = repositoryBranch;
    }

    public String getCoverageTitle() {
        return coverageTitle;
    }

    public void setCoverageTitle(String coverageTitle) {
        this.coverageTitle = coverageTitle;
    }

    public String getJavadocRoot() {
        return javadocRoot;
    }

    public void setJavadocRoot(String javadocRoot) {
        this.javadocRoot = javadocRoot;
    }
}




© 2015 - 2025 Weber Informatics LLC | Privacy Policy