org.gradle.testing.jacoco.plugins.JacocoTaskExtension Maven / Gradle / Ivy
Go to download
Show more of this group Show more artifacts with this name
Show all versions of gradle-api Show documentation
Show all versions of gradle-api Show documentation
Gradle 6.9.1 API redistribution.
/*
* Copyright 2013 the original author or authors.
*
* 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.
*/
package org.gradle.testing.jacoco.plugins;
import com.google.common.base.Joiner;
import org.apache.commons.lang.StringUtils;
import org.gradle.api.Incubating;
import org.gradle.api.Project;
import org.gradle.api.file.FileCollection;
import org.gradle.api.provider.Property;
import org.gradle.api.provider.Provider;
import org.gradle.api.tasks.Classpath;
import org.gradle.api.tasks.Input;
import org.gradle.api.tasks.Internal;
import org.gradle.api.tasks.LocalState;
import org.gradle.api.tasks.Optional;
import org.gradle.api.tasks.OutputFile;
import org.gradle.internal.Factory;
import org.gradle.internal.jacoco.JacocoAgentJar;
import org.gradle.process.JavaForkOptions;
import org.gradle.util.DeprecationLogger;
import org.gradle.util.RelativePathUtil;
import javax.annotation.Nullable;
import java.io.File;
import java.util.ArrayList;
import java.util.Collection;
import java.util.List;
/**
* Extension for tasks that should run with a Jacoco agent to generate coverage execution data.
*/
public class JacocoTaskExtension {
/**
* The types of output that the agent can use for execution data.
*/
public enum Output {
FILE,
TCP_SERVER,
TCP_CLIENT,
NONE;
/**
* Gets type in format of agent argument.
*/
public String getAsArg() {
return toString().toLowerCase().replaceAll("_", "");
}
}
private final JacocoAgentJar agent;
private final JavaForkOptions task;
private boolean enabled = true;
private final Property destinationFile;
private boolean append = true;
private List includes = new ArrayList();
private List excludes = new ArrayList();
private List excludeClassLoaders = new ArrayList();
private boolean includeNoLocationClasses;
private String sessionId;
private boolean dumpOnExit = true;
private Output output = Output.FILE;
private String address;
private int port;
private File classDumpDir;
private boolean jmx;
/**
* Creates a Jacoco task extension.
*
* @param project the project
* @param agent the agent JAR to use for analysis
* @param task the task we extend
*/
public JacocoTaskExtension(Project project, JacocoAgentJar agent, JavaForkOptions task) {
this.agent = agent;
this.task = task;
destinationFile = project.getObjects().property(File.class);
}
/**
* Whether or not the task should generate execution data. Defaults to {@code true}.
*/
@Input
public boolean isEnabled() {
return enabled;
}
public void setEnabled(boolean enabled) {
this.enabled = enabled;
}
/**
* The path for the execution data to be written to.
*/
@Nullable
@Optional
@OutputFile
public File getDestinationFile() {
return destinationFile.getOrNull();
}
/**
* Set the provider for calculating the destination file.
*
* @param destinationFile Destination file provider
* @since 4.0
*/
@Incubating
public void setDestinationFile(Provider destinationFile) {
this.destinationFile.set(destinationFile);
}
public void setDestinationFile(File destinationFile) {
this.destinationFile.set(destinationFile);
}
/**
* Whether or not data should be appended if the {@link #getDestinationFile()} already exists. Defaults to {@code true}.
*
* @deprecated The Jacoco plugin now deletes the old coverage file before task execution, so the data will never be appended to an existing coverage file from another task.
* Use {@link org.gradle.testing.jacoco.tasks.JacocoMerge} to merge different execution files or use {@link org.gradle.testing.jacoco.tasks.JacocoReportBase#setExecutionData(FileCollection)} to generate a report from multiple execution files at once.
* Append is set to true for the agent since this allows multiple JVMs spawned by one task to write to the same {@link #getDestinationFile() destination file}.
*/
@Deprecated
@Input
public boolean isAppend() {
nagAboutDeprecatedAppendProperty();
return append;
}
@Deprecated
public void setAppend(boolean append) {
nagAboutDeprecatedAppendProperty();
this.append = append;
}
private void nagAboutDeprecatedAppendProperty() {
DeprecationLogger.nagUserOfDiscontinuedProperty("append", "Append should always be true.");
}
/**
* List of class names that should be included in analysis. Names can use wildcards (* and ?). If left empty, all classes will be included. Defaults to an empty list.
*/
@Nullable
@Optional
@Input
public List getIncludes() {
return includes;
}
public void setIncludes(@Nullable List includes) {
this.includes = includes;
}
/**
* List of class names that should be excluded from analysis. Names can use wildcard (* and ?). Defaults to an empty list.
*/
@Nullable
@Optional
@Input
public List getExcludes() {
return excludes;
}
public void setExcludes(@Nullable List excludes) {
this.excludes = excludes;
}
/**
* List of classloader names that should be excluded from analysis. Names can use wildcards (* and ?). Defaults to an empty list.
*/
@Nullable
@Optional
@Input
public List getExcludeClassLoaders() {
return excludeClassLoaders;
}
public void setExcludeClassLoaders(@Nullable List excludeClassLoaders) {
this.excludeClassLoaders = excludeClassLoaders;
}
/**
* Whether or not classes without source location should be instrumented. Defaults to {@code false}.
*
* This property is only taken into account if the used JaCoCo version supports this option (JaCoCo version >= 0.7.6)
*/
@Input
public boolean isIncludeNoLocationClasses() {
return includeNoLocationClasses;
}
public void setIncludeNoLocationClasses(boolean includeNoLocationClasses) {
this.includeNoLocationClasses = includeNoLocationClasses;
}
/**
* An identifier for the session written to the execution data. Defaults to an auto-generated identifier.
*/
@Nullable
@Optional
@Input
public String getSessionId() {
return sessionId;
}
public void setSessionId(@Nullable String sessionId) {
this.sessionId = sessionId;
}
/**
* Whether or not to dump the coverage data at VM shutdown. Defaults to {@code true}.
*/
@Input
public boolean isDumpOnExit() {
return dumpOnExit;
}
public void setDumpOnExit(boolean dumpOnExit) {
this.dumpOnExit = dumpOnExit;
}
/**
* The type of output to generate. Defaults to {@link Output#FILE}.
*/
@Input
public Output getOutput() {
return output;
}
public void setOutput(Output output) {
this.output = output;
}
/**
* IP address or hostname to use with {@link Output#TCP_SERVER} or {@link Output#TCP_CLIENT}. Defaults to localhost.
*/
@Nullable
@Optional
@Input
public String getAddress() {
return address;
}
public void setAddress(@Nullable String address) {
this.address = address;
}
/**
* Port to bind to for {@link Output#TCP_SERVER} or {@link Output#TCP_CLIENT}. Defaults to 6300.
*/
@Input
public int getPort() {
return port;
}
public void setPort(int port) {
this.port = port;
}
/**
* Path to dump all class files the agent sees are dumped to. Defaults to no dumps.
*
* @since 3.4
*/
@Nullable
@Optional
@LocalState
public File getClassDumpDir() {
return classDumpDir;
}
/**
* Sets path to dump all class files the agent sees are dumped to. Defaults to no dumps.
*
* @since 3.4
*/
public void setClassDumpDir(@Nullable File classDumpDir) {
this.classDumpDir = classDumpDir;
}
/**
* Whether or not to expose functionality via JMX under {@code org.jacoco:type=Runtime}. Defaults to {@code false}.
*
* The configuration of the jmx property is only taken into account if the used JaCoCo version supports this option (JaCoCo version >= 0.6.2)
*/
@Input
public boolean isJmx() {
return jmx;
}
public void setJmx(boolean jmx) {
this.jmx = jmx;
}
/**
* The Jacoco agent classpath.
*
* This contains only one file - the agent jar.
*
* @since 4.6
*/
@Incubating
@Classpath
public FileCollection getAgentClasspath() {
return agent.getAgentConf();
}
/**
* Gets all properties in the format expected of the agent JVM argument.
*
* @return state of extension in a JVM argument
*/
@Internal
public String getAsJvmArg() {
StringBuilder builder = new StringBuilder();
ArgumentAppender argument = new ArgumentAppender(builder, task.getWorkingDir());
builder.append("-javaagent:");
builder.append(RelativePathUtil.relativePath(task.getWorkingDir(), agent.getJar()));
builder.append('=');
argument.append("destfile", getDestinationFile());
argument.append("append", DeprecationLogger.whileDisabled(new Factory() {
@Override
public Boolean create() {
return isAppend();
}
}));
argument.append("includes", getIncludes());
argument.append("excludes", getExcludes());
argument.append("exclclassloader", getExcludeClassLoaders());
if (agent.supportsInclNoLocationClasses()) {
argument.append("inclnolocationclasses", isIncludeNoLocationClasses());
}
argument.append("sessionid", getSessionId());
argument.append("dumponexit", isDumpOnExit());
argument.append("output", getOutput().getAsArg());
argument.append("address", getAddress());
argument.append("port", getPort());
argument.append("classdumpdir", getClassDumpDir());
if (agent.supportsJmx()) {
argument.append("jmx", isJmx());
}
return builder.toString();
}
private static class ArgumentAppender {
private final StringBuilder builder;
private final File workingDirectory;
private boolean anyArgs;
public ArgumentAppender(StringBuilder builder, File workingDirectory) {
this.builder = builder;
this.workingDirectory = workingDirectory;
}
public void append(String name, @Nullable Object value) {
if (value != null
&& !((value instanceof Collection) && ((Collection) value).isEmpty())
&& !((value instanceof String) && (StringUtils.isEmpty((String) value)))
&& !((value instanceof Integer) && (value == Integer.valueOf(0)))) {
if (anyArgs) {
builder.append(',');
}
builder.append(name).append('=');
if (value instanceof Collection) {
builder.append(Joiner.on(':').join((Collection) value));
} else if (value instanceof File) {
builder.append(RelativePathUtil.relativePath(workingDirectory, (File) value));
} else {
builder.append(value);
}
anyArgs = true;
}
}
}
}
© 2015 - 2025 Weber Informatics LLC | Privacy Policy