com.gradle.develocity.agent.maven.api.cache.MojoMetadataProvider Maven / Gradle / Ivy
Show all versions of develocity-maven-extension Show documentation
package com.gradle.develocity.agent.maven.api.cache;
import org.apache.maven.execution.MavenSession;
import org.apache.maven.model.Plugin;
import org.apache.maven.plugin.MojoExecution;
import org.apache.maven.project.MavenProject;
import java.util.List;
import java.util.function.Consumer;
/**
* Allows users to configure caching for Mojos that the Develocity Maven Extension does not support out of the box.
*
* @since 1.21
*/
public interface MojoMetadataProvider {
/**
* Called for each goal as Maven is about to execute it. The context object provides access to the goal and allows users to customize its caching.
*
* @param context provides access to the mojo execution and allows users to customize the inputs and outputs
*/
void provideMetadata(Context context);
/**
* Allows configuring the inputs and outputs of a Mojo.
*
* @since 1.21
*/
interface Context {
/**
* The object underlying the current context. The root context will return the {@link org.apache.maven.plugin.Mojo} instance,
* while contexts created by {@link #nested(String, Consumer)} and {@link #iterate(String, Consumer)} will return the nested property value.
*/
Object getUnderlyingObject();
/**
* The goal execution being analyzed.
*/
MojoExecution getMojoExecution();
/**
* The project that the goal execution is part of.
*/
MavenProject getProject();
/**
* The session associated with the project.
*/
MavenSession getSession();
/**
* Executes a given {@code action} if the supplied {@code artifactId} matches {@link Plugin#getArtifactId()}.
* If two plugins have the same artifactId but different groupIds the action will be executed for both.
*
* @param artifactId the artifact id for which to execute the {@code action}
* @param action the action to be executed
*/
void withPlugin(String artifactId, Runnable action);
/**
* The goal execution will be skipped, if any of the given boolean properties is {@code true}.
*
* @param propertyNames the names of the boolean properties to be checked
*/
Context skipIfTrue(String... propertyNames);
/**
* The goal execution will be skipped, if any of the given boolean properties is {@code true}.
*
* @param propertyNames the names of the boolean properties to be checked
*/
Context skipIfTrue(List propertyNames);
/**
* The inputs of a goal determine its cache key.
*
* @param action to be executed on the supplied {@link Inputs}
* @see Inputs for more details
*/
Context inputs(Consumer super Inputs> action);
/**
* The outputs of a goal are packed into the cache entry.
*
* @param action to be executed on the supplied {@link Outputs}
* @see Outputs for more details
*/
Context outputs(Consumer super Outputs> action);
/**
* Local state is deleted if the outputs of a goal are retrieved from the build cache.
* A common example would be temporary files or incremental analysis data.
*
* @param action to be executed on the supplied {@link LocalState}
* @see LocalState for more details
*/
Context localState(Consumer super LocalState> action);
/**
* Creates a nested context by looking for a property with the given name on the current context and calling the given action
* on it if it exists. All property names in the nested context will be prefixed with the given property name.
*
* @param propertyName the name of the property to look for on the current context
* @param action the action to be executed if the supplied {@code propertyName} is found on the current context
*/
Context nested(String propertyName, Consumer super Context> action);
/**
* Creates nested contexts by looking for a property of type {@link Iterable} or {@code Object[]} with the given name in the current context
* and calling the given action on each item in the {@link Iterable} or {@code Object[]}, if it exists.
* All property names in the nested contexts will be prefixed with the given property name and the index of the
* item in the {@link Iterable} or {@code Object[]}.
*
* @param propertyName the name of the property to look for on the current context
* @param action the action to be executed if the supplied {@code propertyName} is found on the current context
*/
Context iterate(String propertyName, Consumer super Context> action);
/**
* The inputs of a goal determine its cache key. All fields annotated with @{@link org.apache.maven.plugin.descriptor.Parameter} need to be
* declared as either an input, output, local state or ignored using the {@link #ignore(String...)} method. Any unhandled parameters will make
* the goal execution non-cacheable.
*
* @since 1.21
*/
interface Inputs {
/**
* Marks the given properties as scalar input properties.
*
* @param propertyNames the names of the properties to be marked as scalar inputs
* @see #property(String, Object)
*/
Inputs properties(String... propertyNames);
/**
* Adds the given object as an additional input property.
* Supported types are all primitives, enums and Strings, as well as arrays, collections and maps of these types.
*
* @param propertyName the name of the property to be added
* @param value the value of the property to be added. Supported types are all primitives, enums and Strings,
* as well as arrays, collections and maps of these types
*/
Inputs property(String propertyName, Object value);
/**
* Marks the given property as a set of input files.
*
* @param propertyName the name of the property to be marked as a set of input files
* @param action an action to configure the {@link FileSet}
* @see #fileSet(String, Object, Consumer)
*/
Inputs fileSet(String propertyName, Consumer action);
/**
* Adds the given files as input files under the given property name.
*
* May be zero, one or many files and directories.
*
* @param propertyName the name of the property to be marked as a set of input files
* @param files can be an {@link Iterable}, an array or a single object of type {@link String}, {@link java.nio.file.Path}, {@link java.net.URI} or {@link java.io.File}.
* Each element can represent an absolute path or a relative path to a file.
* If it is a relative path, it will be resolved using the current project's base directory.
* @param action an action to configure the {@link FileSet}
*/
Inputs fileSet(String propertyName, Object files, Consumer action);
/**
* Ignores the given properties. Use this for any input parameters that don't affect the output files of the goal,
* e.g. parameters that only affect the console output or parameters that affect how work is parallelized.
*
* @param propertyNames the names of the properties to be ignored
*/
Inputs ignore(String... propertyNames);
}
/**
* Holds a set of files and directories and allows configuring the {@link FileSet.NormalizationStrategy}, {@link FileSet.LineEndingHandling} and {@link FileSet.EmptyDirectoryHandling}.
*
* Supports ANT-style include and exclude patterns:
*
* * matches zero or more characters
* ? matches one character
* ** matches zero or more characters across directory levels
*
*
* @since 1.21
*/
interface FileSet {
/**
* Marks the given property as ANT-style include patterns for this file set.
*
* @param includePropertyName the name of the property to be marked as includes
* @see #include(List)
*/
FileSet includesProperty(String includePropertyName);
/**
* Adds the given ANT-style include patterns to the file set.
*
* @param includePatterns the ANT-style include patterns to be added
*/
FileSet include(List includePatterns);
/**
* Adds the given ANT-style include patterns to the file set.
*
* @param includePatterns the ANT-style include patterns to be added
*/
FileSet include(String... includePatterns);
/**
* Marks the given property as ANT-style exclude patterns for this file set.
*
* @param excludePropertyName the name of the property to be marked as excludes
* @see #exclude(List)
*/
FileSet excludesProperty(String excludePropertyName);
/**
* Adds the given ANT-style exclude patterns to the file set.
*
* @param excludePatterns the ANT-style exclude patterns to be added
*/
FileSet exclude(List excludePatterns);
/**
* Adds the given ANT-style exclude patterns to the file set.
*
* @param excludePatterns the ANT-style exclude patterns to be added
*/
FileSet exclude(String... excludePatterns);
/**
* Defines the normalization strategy for this property.
*
* @param normalizationStrategy the normalization strategy to be used for this {@link FileSet}
*/
FileSet normalizationStrategy(FileSet.NormalizationStrategy normalizationStrategy);
/**
* Defines the handling of empty directories.
*
* @param emptyDirectoryHandling the empty directory handling to be used for this {@link FileSet}
*/
FileSet emptyDirectoryHandling(FileSet.EmptyDirectoryHandling emptyDirectoryHandling);
/**
* Defines the handling of line endings.
*
* @param lineEndingHandling the line ending handling to be used for this {@link FileSet}
*/
FileSet lineEndingHandling(FileSet.LineEndingHandling lineEndingHandling);
/**
* Allows specifying a way of ignoring changes to input files that are irrelevant for the goal execution.
*
* @since 1.21
*/
enum NormalizationStrategy {
/**
* Considers the full content of files as well as their absolute path.
* Using this strategy is strongly discouraged, as it means that cache hits across different machines
* are generally impossible, since the project directory (and thus all absolute paths) are usually different.
*/
ABSOLUTE_PATH,
/**
* Considers only the information relevant for running Java code.
*/
CLASSPATH,
/**
* Considers only the information relevant for compiling Java code. This means for example that only class files are
* considered and private implementation details like method bodies are ignored.
*/
COMPILE_CLASSPATH,
/**
* Considers the full content of files, but ignores their path.
*/
IGNORED_PATH,
/**
* Considers the full content of files, but only tracks their name and not the rest of their path.
*/
NAME_ONLY,
/**
* Considers the full content of files, but only tracks their path relative to their root directory.
* The root directory is the directory that was added as an input. The path of that root directory itself
* is ignored.
*/
RELATIVE_PATH
}
/**
* Allows controlling the sensitivity to the presence of empty directories in the source tree.
*
* @since 1.21
*/
enum EmptyDirectoryHandling {
/**
* Empty directories will be taken into account.
*/
DEFAULT,
/**
* Empty directories are ignored.
*/
IGNORE
}
/**
* Allows specifying whether line endings should be normalized for Build Cache checks, so that files that only differ by line endings will be considered identical.
*
* @since 1.21
*/
enum LineEndingHandling {
/**
* No normalization.
*/
DEFAULT,
/**
* Normalize line endings for text files with ASCII encoding or its supersets.
*/
NORMALIZE
}
}
/**
* The outputs of a goal are packed into the cache entry and restored when they are loaded from the build cache.
* Every goal execution starts out as "not supported". It has to be explicitly marked as cacheable in order to benefit from build caching.
* If any reason for being non-cacheable is given (e.g. via {@link #notCacheableBecause(String)}), the goal execution's outputs will
* not be cached, even if it was marked as cacheable.
*
* @since 1.21
*/
interface Outputs {
/**
* Marks the given property as an output file.
*
* @param propertyName the name of the property to be marked as an output file
* @see #file(String, Object)
*/
Outputs file(String propertyName);
/**
* Registers the given file as an output property.
*
* @param propertyName the name of the property to be registered as an output file
* @param file can be a {@link String}, {@link java.nio.file.Path}, {@link java.net.URI} or {@link java.io.File} represented through an absolute or a relative path to a file.
* If it is a relative path, it will be resolved using the current project's base directory.
*/
Outputs file(String propertyName, Object file);
/**
* Marks the given property as an output directory.
*
* @param propertyName the name of the property to be marked as an output directory
* @see #directory(String, Object)
*/
Outputs directory(String propertyName);
/**
* Registers the given file as an output property.
*
* @param propertyName the name of the property to be registered as an output directory
* @param directory can be a {@link String}, {@link java.nio.file.Path}, {@link java.net.URI} or {@link java.io.File} represented through an absolute or a relative path to a directory.
* If it is a relative path, it will be resolved using the current project's base directory.
*/
Outputs directory(String propertyName, Object directory);
/**
* Marks the outputs of this goal execution as cacheable.
* The supplied reason should fit well in the following sentence:
* "Build caching was enabled for this goal execution because ...".
*
* @param reason the reason why the goal execution's outputs are cacheable
*/
Outputs cacheable(String reason);
/**
* Disables caching of the outputs of this goal execution.
* The supplied reason should fit well in the following sentence:
* "Build caching was not enabled for this goal execution because ...".
*
* @param reason the reason why the goal execution's outputs are not cacheable
*/
Outputs notCacheableBecause(String reason);
/**
* Configures whether results for this goal should be stored in the build cache or only read from it.
* This can be useful when the outputs of this goal are only safe to be stored under certain circumstances,
* e.g. only on clean builds or only on CI builds.
*
* @param enabled whether results for this goal should be stored in the build cache
*/
Outputs storeEnabled(boolean enabled);
}
/**
* Configures local state. Local state files are neither inputs, nor outputs. A typical example would be temporary directories.
* They are deleted when the outputs of a goal execution are loaded from the cache.
*
* @since 1.21
*/
interface LocalState {
/**
* Marks the given property as local state.
*
* @param propertyName the name of the property to be marked as local state
* @see #files(String, Object)
*/
LocalState files(String propertyName);
/**
* Marks the given files as a local state property.
*
* @param propertyName the name of the property to be marked as local state
* @param value can be an {@link Iterable}, an array or a single object of type {@link String}, {@link java.nio.file.Path}, {@link java.net.URI} or {@link java.io.File}.
* Each element can represent an absolute path or a relative path to a file or directory.
* If it is a relative path, it will be resolved using the current project's base directory.
*/
LocalState files(String propertyName, Object value);
}
}
}