Skip to content

Commit

Permalink
Merge branch 'release'
Browse files Browse the repository at this point in the history
  • Loading branch information
blindpirate committed May 22, 2019
2 parents ec13121 + b174d73 commit 5683d73
Show file tree
Hide file tree
Showing 83 changed files with 877 additions and 262 deletions.
Expand Up @@ -451,6 +451,42 @@ public interface DependencyHandler extends ExtensionAware {
/**
* Registers an artifact transform.
*
* <p>
* The registration action needs to specify the {@code from} and {@code to} attributes.
* It may also provide parameters for the transform action by using {@link TransformSpec#parameters(Action)}.
* </p>
*
* <p>Example: When you have a transform action like this:</p>
*
* <pre class='autoTested'>
* abstract class MyTransform implements TransformAction&lt;Parameters&gt; {
* interface Parameters extends TransformParameters {
* {@literal @}Input
* Property&lt;String&gt; getStringParameter();
* {@literal @}InputFiles
* ConfigurableFileCollection getInputFiles();
* }
*
* void transform(TransformOutputs outputs) {
* // ...
* }
* }
*
* // Then you can register the action like this:
*
* def artifactType = Attribute.of('artifactType', String)
*
* dependencies.registerTransform(MyTransform) {
* from.attribute(artifactType, "jar")
* to.attribute(artifactType, "java-classes-directory")
*
* parameters {
* stringParameter.set("Some string")
* inputFiles.from("my-input-file")
* }
* }
* </pre>
*
* @see TransformAction
* @since 5.3
*/
Expand Down
Expand Up @@ -24,10 +24,34 @@
import java.lang.annotation.Target;

/**
* <p>Attached to an {@link TransformAction} type to indicate that the build cache should be used for artifact transforms of this type.</p>
* Attached to a {@link TransformAction} type it indicates that the build cache should be used for artifact transforms of this type.
*
* <p>Only an artifact transform that produces reproducible and relocatable outputs should be marked with {@code CacheableTransform}.</p>
*
* <p>
* Normalization must be specified for each file parameter of a cacheable transform.
* For example:
* </p>
* <pre class='autoTested'>
* import org.gradle.api.artifacts.transform.TransformParameters;
*
* {@literal @}CacheableTransform
* public abstract class MyTransform implements TransformAction&lt;TransformParameters.None&gt; {
* {@literal @}PathSensitive(PathSensitivity.NAME_ONLY)
* {@literal @}InputArtifact
* public abstract Provider&lt;FileSystemLocation&gt; getInputArtifact();
*
* {@literal @}Classpath
* {@literal @}InputArtifactDependencies
* public abstract FileCollection getDependencies();
*
* {@literal @}Override
* public void transform(TransformOutputs outputs) {
* // ...
* }
* }
* </pre>
*
* @since 5.3
*/
@Incubating
Expand Down
Expand Up @@ -29,11 +29,27 @@
import java.lang.annotation.Target;

/**
* Attached to a property that should receive the <em>input artifact</em> for an artifact transform. This is the artifact that the transform should be applied to.
* Attached to a property that should receive the <em>input artifact</em> for an artifact transform.
* This is the artifact that the transform is applied to.
*
* <p>
* The input artifact can be injected as a {@link Provider}&lt;{@link org.gradle.api.file.FileSystemLocation}&gt;.
* </p>
* <p>The input artifact can be injected as a {@link Provider}&lt;{@link org.gradle.api.file.FileSystemLocation}&gt;.</p>
*
* <p>Example usage:</p>
*
* <pre class='autoTested'>
* import org.gradle.api.artifacts.transform.TransformParameters;
*
* public abstract class MyTransform implements TransformAction&lt;TransformParameters.None&gt; {
*
* {@literal @}InputArtifact
* public abstract Provider&lt;FileSystemLocation&gt; getInputArtifact();
* {@literal @}Override
* public void transform(TransformOutputs outputs) {
* File input = getInputArtifact().get().getAsFile();
* // Do something with the input
* }
* }
* </pre>
*
* @since 5.3
*/
Expand Down
Expand Up @@ -29,8 +29,32 @@
/**
* Attached to a property that should receive the <em>artifact dependencies</em> of the {@link InputArtifact} of an artifact transform.
*
* The order of the files match that of the dependencies in the source artifact view.
* The type of the injected dependencies is {@link org.gradle.api.file.FileCollection}.
* <p>
* The order of the files match that of the dependencies in the source artifact view.
* The type of the injected dependencies is {@link org.gradle.api.file.FileCollection}.
* For example, when a project depends on {@code spring-web}, when the project is transformed (i.e. the project is the input artifact),
* the input artifact dependencies are the file collection containing the {@code spring-web} JAR and all its dependencies like e.g. the {@code spring-core} JAR.
* </p>
*
* <p>Example usage:</p>
* <pre class='autoTested'>
* import org.gradle.api.artifacts.transform.TransformParameters;
*
* public abstract class MyTransform implements TransformAction&lt;TransformParameters.None&gt; {
*
* {@literal @}InputArtifact
* public abstract Provider&lt;FileSystemLocation&gt; getInputArtifact();
*
* {@literal @}InputArtifactDependencies
* public abstract FileCollection getDependencies();
*
* {@literal @}Override
* public void transform(TransformOutputs outputs) {
* FileCollection dependencies = getDependencies();
* // Do something with the dependencies
* }
* }
* </pre>
*
* @since 5.3
*/
Expand Down
Expand Up @@ -16,20 +16,42 @@

package org.gradle.api.artifacts.transform;

import org.gradle.api.Action;
import org.gradle.api.Incubating;

import javax.inject.Inject;

/**
* Interface for artifact transform actions.
*
* <p>Implementations must provide a public constructor.</p>
* <p>
* A transform action implementation is an abstract class implementing the {@link #transform(TransformOutputs)} method.
* A minimal implementation may look like this:
* </p>
*
* <p>Implementations can receive parameters by using annotated abstract getter methods.</p>
* <pre class='autoTested'>
* import org.gradle.api.artifacts.transform.TransformParameters;
*
* <p>A property annotated with {@link InputArtifact} will receive the <em>input artifact</em> location, which is the file or directory that the transform should be applied to.
* public abstract class MyTransform implements TransformAction&lt;TransformParameters.None&gt; {
* {@literal @}InputArtifact
* public abstract Provider&lt;FileSystemLocation&gt; getInputArtifact();
*
* <p>A property annotated with {@link InputArtifactDependencies} will receive the <em>dependencies</em> of its input artifact.
* {@literal @}Override
* public void transform(TransformOutputs outputs) {
* File input = getInputArtifact().get().getAsFile();
* File output = outputs.file(input.getName() + ".transformed");
* // Do something to generate output from input
* }
* }
* </pre>
*
* <ul>
* <li>Do not implement {@link #getParameters()} in your class, the method will be implemented by Gradle.</li>
* <li>Implementations may only have a default constructor.</li>
* <li>Implementations can receive parameters by using annotated abstract getter methods.</li>
* <li>A property annotated with {@link InputArtifact} will receive the <em>input artifact</em> location, which is the file or directory that the transform should be applied to.</li>
* <li>A property annotated with {@link InputArtifactDependencies} will receive the <em>dependencies</em> of its input artifact.</li>
* </ul>
*
* @param <T> Parameter type for the transform action. Should be {@link TransformParameters.None} if the action does not have parameters.
* @since 5.3
Expand All @@ -38,14 +60,21 @@
public interface TransformAction<T extends TransformParameters> {

/**
* The object provided by {@link TransformSpec#getParameters()}.
* The object provided by {@link TransformSpec#getParameters()} when registering the artifact transform.
*
* <p>
* Do not implement this method in your subclass.
* Gradle provides the implementation when registering the transform action via {@link org.gradle.api.artifacts.dsl.DependencyHandler#registerTransform(Class, Action)}.
* </p>
*/
@Inject
T getParameters();

/**
* Executes the transform.
*
* <p>This method must be implemented in the subclass.</p>
*
* @param outputs Receives the outputs of the transform.
*/
void transform(TransformOutputs outputs);
Expand Down
Expand Up @@ -35,7 +35,46 @@
public interface TransformOutputs {
/**
* Registers an output directory.
* For a relative path, a location for the output directory is provided.
*
* <p>
* For an <strong>absolute path</strong>, the location is registered as an output directory of the {@link TransformAction}.
* The path is required to point to the {@link InputArtifact}, or point inside the input artifact if it is a directory.
* Example:
* </p>
* <pre class='autoTested'>
* import org.gradle.api.artifacts.transform.TransformParameters;
*
* public abstract class MyTransform implements TransformAction&lt;TransformParameters.None&gt; {
* {@literal @}InputArtifact
* public abstract Provider&lt;FileSystemLocation&gt; getInputArtifact();
* {@literal @}Override
* public void transform(TransformOutputs outputs) {
* outputs.dir(getInputArtifact().get().getAsFile());
* outputs.dir(new File(getInputArtifact().get().getAsFile(), "sub-dir"));
* }
* }
* </pre>
*
* <p>
* For a <strong>relative path</strong>, a location for the output directory is provided by Gradle, so that the {@link TransformAction} can produce its outputs at that location.
* The directory is created automatically when calling the method.
* Example:
* </p>
* <pre class='autoTested'>
* import org.gradle.api.artifacts.transform.TransformParameters;
*
* public abstract class MyTransform implements TransformAction&lt;TransformParameters.None&gt; {
* {@literal @}Override
* public void transform(TransformOutputs outputs) {
* File myOutput = outputs.dir("my-output");
* Files.write(myOutput.toPath().resolve("file.txt"), "Generated text");
* }
* }
* </pre>
*
* <p>
* <strong>Note:</strong> it is an error if the registered directory does not exist when the {@link TransformAction#transform(TransformOutputs)} method finishes.
* </p>
*
* @param path path of the output directory
* @return determined location of the output
Expand All @@ -44,9 +83,52 @@ public interface TransformOutputs {

/**
* Registers an output file.
* For a relative path, a location for the output file is provided.
*
* @param path path of the output directory
* <p>
* For an absolute path, the location is registered as an output file of the {@link TransformAction}.
* The path is required to point to the {@link InputArtifact} or be inside it if the input artifact is a directory.
* Example:
* </p>
* <pre class='autoTested'>
* import org.gradle.api.artifacts.transform.TransformParameters;
*
* public abstract class MyTransform implements TransformAction&lt;TransformParameters.None&gt; {
* {@literal @}InputArtifact
* public abstract Provider&lt;FileSystemLocation&gt; getInputArtifact();
* {@literal @}Override
* public void transform(TransformOutputs outputs) {
* File input = getInputArtifact().get().getAsFile();
* if (input.isFile()) {
* outputs.file(input);
* } else {
* outputs.file(new File(input, "file-in-input-artifact.txt"));
* }
* }
* }
* </pre>
*
* <p>
* For a relative path, a location for the output file is provided by Gradle, so that the {@link TransformAction} can produce its outputs at that location.
* The parent directory of the provided location is created automatically when calling the method.
* Example:
* </p>
* <pre class='autoTested'>
* import org.gradle.api.artifacts.transform.TransformParameters;
*
* public abstract class MyTransform implements TransformAction&lt;TransformParameters.None&gt; {
* {@literal @}InputArtifact
* public abstract Provider&lt;FileSystemLocation&gt; getInputArtifact();
* {@literal @}Override
* public void transform(TransformOutputs outputs) {
* File myOutput = outputs.file("my-output.transformed");
* Files.write(myOutput.toPath(), "Generated text");
* }
* }
* </pre>
*
* <p>The registered file needs to exist when the {@link TransformAction#transform(TransformOutputs)} method finishes.</p>
*
* @param path path of the output file
* @return determined location of the output
*/
File file(Object path);
Expand Down
Expand Up @@ -21,13 +21,31 @@
/**
* Marker interface for parameter objects to {@link TransformAction}s.
*
* <p>
* Parameter types should be interfaces, only declaring getters for {@link org.gradle.api.provider.Property}-like objects.
* All getters must be annotated with an input annotation like {@link org.gradle.api.tasks.Input} or {@link org.gradle.api.tasks.InputFiles}.
* Normalization annotations such as {@link org.gradle.api.tasks.PathSensitive} or {@link org.gradle.api.tasks.Classpath} can be used as well.
* See the <a href="https://docs.gradle.org/current/userguide/more_about_tasks.html#table:incremental_build_annotations">table of incremental build property type annotations</a> for all annotations which can be used.
* Example:
* </p>
* <pre class='autoTested'>
* public interface MyParameters extends TransformParameters {
* {@literal @}Input
* Property&lt;String&gt; getStringParameter();
* {@literal @}InputFiles
* ConfigurableFileCollection getInputFiles();
* }
* </pre>
*
* @since 5.3
*/
@Incubating
public interface TransformParameters {
/**
* Used for {@link TransformAction}s without parameters.
*
* <p>When {@link None} is used as parameters, calling {@link TransformAction#getParameters()} throws an exception.</p>
*
* @since 5.3
*/
@Incubating
Expand Down
Expand Up @@ -23,28 +23,37 @@
/**
* Base configuration for artifact transform registrations.
*
* @see org.gradle.api.artifacts.dsl.DependencyHandler#registerTransform(Class, Action)
* @param <T> The transform specific parameter type.
* @since 5.3
*/
@Incubating
public interface TransformSpec<T extends TransformParameters> {
/**
* Attributes that match the variant that is consumed.
*
* @see org.gradle.api.artifacts.dsl.DependencyHandler#registerTransform(Class, Action)
*/
AttributeContainer getFrom();

/**
* Attributes that match the variant that is produced.
*
* @see org.gradle.api.artifacts.dsl.DependencyHandler#registerTransform(Class, Action)
*/
AttributeContainer getTo();

/**
* The parameters for the transform action.
*
* @see org.gradle.api.artifacts.dsl.DependencyHandler#registerTransform(Class, Action)
*/
T getParameters();

/**
* Configure the parameters for the transform action.
*
* @see org.gradle.api.artifacts.dsl.DependencyHandler#registerTransform(Class, Action)
*/
void parameters(Action<? super T> action);
}

0 comments on commit 5683d73

Please sign in to comment.