Gradle 8.12, using Groovy syntax.
I want to include the distribution
plugin in my build but I don't want its tasks automatically placed in the build
dependency tree. In other words, I want to "opt-in" to running distZip
only when needed, not whenever build
task is run.
Right now, if I run gradlew build
, distZip
is included. When I want to use distZip
I want to explicitly request it (ie, with gradlew distZip
).
I do not want to totally disable distZip
, just make it an explicit choice.
What's the cleanest/simplest way to accomplish that?
Gradle 8.12, using Groovy syntax.
I want to include the distribution
plugin in my build but I don't want its tasks automatically placed in the build
dependency tree. In other words, I want to "opt-in" to running distZip
only when needed, not whenever build
task is run.
Right now, if I run gradlew build
, distZip
is included. When I want to use distZip
I want to explicitly request it (ie, with gradlew distZip
).
I do not want to totally disable distZip
, just make it an explicit choice.
What's the cleanest/simplest way to accomplish that?
Share Improve this question asked Mar 6 at 17:46 E-RizE-Riz 33.1k14 gold badges105 silver badges152 bronze badges2 Answers
Reset to default 1You can use onlyIf
to run only if some condition is met. For example, the someProperty
value must be set in order for the task to run:
tasks {
distZip {
onlyIf("property present") {
hasProperty("someProperty")
}
}
}
The distZip
will only run when someProperty
is set, so ./gradlew build
would not execute distZip
.
But ./gradlew build -PsomeProperty
will since someProperty
is specified.
Discussion
If you inspect the code of the Distribution plugin1, you'll see that the dependency of the build
task on distZip
arises because assemble
is given a dependency on distZip
(and build
by default depends on assemble
).
That suggests three possible approaches:
Remove the the dependency of
assemble
ondistZip
This the most obvious and desirable. However it turns out this is not straightforward to do.2
Write your own version of the
build
taskThis is maybe do-able, but it dodges the original question and could be hard to maintain as the build grows. Still, it the most Gradle-esque approach.
Call the parts of the Distribution plugin you want manually
It turns out the Distribution plugin is pretty simple and you can fairly easily call the bits of code you want. To do this, probably against my better judgement I've pulled together a plugin to call the essential bits of the Distribution plugin and omit
assemble
's dependency. It was necessary to write a plugin as getting hold of the dependencies of the Distribution Plugin requires accessing Gradle's internal dependency injection mechanisms, which I don't believe is possible within a build script.I've included the code for this below. To make it work, put it in the file
buildSrc/main/java/AlteredDistributionPlugin.java
and also add the suppliedbuildSrc
build file atbuildSrc/build.gradle
(or make similar amendements to an existing one). You can then apply the plugin instead of the Distribution plugin with the idalteredDistribution
in theplugins
block. You can check that task dependency has been removed with the command./gradlew build --dry-run
.Please note the arrangement, but not the functionality, of the Distribution Plugin code changed in Gradle 8.13, with most moving to a Distribution Base Plugin. The supplied code will thus need to be amended to be compatible with Gradle 8.13 as it depends on the plugin's implementation details.
Code
// buildSrc/main/java/AlteredDistributionPlugin.java
import .gradle.api.Plugin;
import .gradle.api.Project;
import .gradle.api.distribution.DistributionContainer;
import .gradle.api.distribution.internal.DefaultDistributionContainer;
import .gradle.api.distribution.Distribution;
import .gradle.api.distribution.plugins.DistributionPlugin;
import .gradle.api.internal.CollectionCallbackActionDecorator;
import .gradle.api.internal.file.FileOperations;
import .gradle.api.tasks.bundling.AbstractArchiveTask;
import .gradle.api.tasks.bundling.Zip;
import .gradle.internal.reflect.Instantiator;
import javax.inject.Inject;
import java.lang.reflect.Method;
public class AlteredDistributionPlugin implements Plugin<Project> {
private final Instantiator instantiator;
private final FileOperations fileOperations;
private final CollectionCallbackActionDecorator callbackActionDecorator;
@Inject
public AlteredDistributionPlugin(
Instantiator instantiator,
FileOperations fileOperations,
CollectionCallbackActionDecorator callbackActionDecorator
) {
this.instantiator = instantiator;
this.fileOperations = fileOperations;
this.callbackActionDecorator = callbackActionDecorator;
}
@Override
public void apply(final Project project) {
DistributionContainer distributions = project.getExtensions().create(DistributionContainer.class, "distributionsAltered", DefaultDistributionContainer.class, Distribution.class, instantiator, project.getObjects(), fileOperations, callbackActionDecorator);
distributions.all(dist -> {
dist.getContents().from("src/" + dist.getName() + "/dist");
addArchiveTaskByReflection(project, "distZip", Zip.class, dist);
});
distributions.create(DistributionPlugin.MAIN_DISTRIBUTION_NAME);
}
@SuppressWarnings("SameParameterValue")
private void addArchiveTaskByReflection(final Project project, String taskName, Class<? extends AbstractArchiveTask> type, final Distribution distribution) {
DistributionPlugin distributionPlugin = new DistributionPlugin(instantiator, fileOperations, callbackActionDecorator) {};
try {
Method addArchiveTask;
addArchiveTask = DistributionPlugin.class.getDeclaredMethod("addArchiveTask", Project.class, String.class, Class.class, Distribution.class);
addArchiveTask.setAccessible(true);
addArchiveTask.invoke(distributionPlugin, project, taskName, type, distribution);
}
catch (Exception e) {
throw new RuntimeException(e);
}
}
}
// buildSrc/build.gradle
plugins {
id 'java'
id 'java-gradle-plugin'
}
gradlePlugin {
plugins {
register('alteredDistribution') {
id = 'alteredDistribution'
implementationClass = "AlteredDistributionPlugin"
}
}
}
1 Code at version 8.12
2 Eg you can try and work with the dependsOn
property of assemble
, but this returns a collection of AbstractTaskDependency
s, an internal Gradle class loaded by a different class loader, so you are fighting Gradle fairly hard by that route.
发布者:admin,转转请注明出处:http://www.yc00.com/questions/1744958215a4603326.html
评论列表(0条)