This question is for gradle (>= 2.4). I would like to write a custom task like the following:
https://docs.gradle.org/current/userguide/custom_tasks.html
class GreetingTask extends DefaultTask {
#TaskAction
def greet() {
println 'hello from GreetingTask'
}
}
task hello(type: GreetingTask)
how can I make this task run during execution phase? Is passing an empty closure with
<< {
}
the only solution?
Edit
the task is supposed to be used in a multiproject build with several tasks as dependencies.
I'd like that the command gradle build would build all the projects by saying something like
`build.dependsOn(hello)`
but seems that the task hello is called during configuration phase of the build.
Add the following to a build.gradle file:
class GreetingTask extends DefaultTask {
#TaskAction
def greet() {
println 'hello from GreetingTask'
}
}
task hello(type: GreetingTask) {
println "This is the configuration phase"
doFirst {
println "This is the execution phase"
}
}
Now execute gradle hello. The output you will see is
This is the configuration phase
:hello
This is the execution phase
hello from GreetingTask
BUILD SUCCESSFUL
As you can see, the output from the task occurs after the doFirst(), which definitely happens during the execution phase.
Related
I am trying to create an Zip task in a plugin:
class MyPlugin implements Plugin<Project> {
#Override
void apply(Project project) {
Zip buildFunctionArchive = project.tasks.create("buildFunctionArchive", Zip.class) {
archiveClassifier = "yolo"
from(project.getTasksByName("compileJava", true))
}
}
}
But for some reason even though the compileJava task exists in the project form which I use my plugin. When I print debug output I get: NO-SOURCE
2020-10-05T02:16:03.565+1100 [LIFECYCLE] [class org.gradle.internal.buildevents.TaskExecutionLogger] > Task :buildFunctionArchive NO-SOURCE
If I configure the from in my client project:
buildFunctionArchive{
from compileJava
}
This works, and I even see the yolo in the archive name. But if I remove the from compileJava
buildFunctionArchive{
}
As well as removing the configuration all together and running gradle buildFunctionArchive
The task will not create the archive, even though I have configured this in the MyPlugin class, I will get the NO-SOURCE error. What am I missing? I am wanting to define a Zip task in my plugin but am having no luck.
for example, I have a plugin:
public class PluginA implements Plugin.
and I will create a task taskA. Now I want to set: taskA.dependsOn taskB, but taskB is defined in PluginB.
Does it possible to do this, if can, how to do it?
You don't need to know that taskB comes from PluginB to create the dependency on taskA: you can simply reference taskB by its name, as follows:
class PluginA implements Plugin<Project> {
void apply(Project project) {
Task taskA = project.task('taskA') {
doLast {
println 'Executing task A from plugin A'
}
}
// create dependency from taskA to taskB
project.tasks.matching { it.name == 'taskB'}.each {
taskA.dependsOn it
}
}
}
Please note that if your consuming project which applies PluginA does not apply PluginB, the dependency will not be created. Maybe you want/need to automatically apply PluginB when applying PluginA.
Another way would be to create this dependency only when pluginB is applied, using pluginManager.withPlugin method:
class PluginA implements Plugin<Project> {
void apply(Project project) {
Task taskA = project.task('taskA') {
doLast {
println 'Executing task A from plugin A'
}
}
project.pluginManager.withPlugin('pluginB'){
println "pluginB applied => adding dependency from taskA to taskB"
project.afterEvaluate{
taskA.dependsOn project.tasks.getByName('taskB')
}
}
}
}
setVersionTask sets a member that I want to be used as input by getVersionTask. Here's my code:
class TaskA extends DefaultTask {
#InputFile
File pbxprojectFile
#Optional
String version
#TaskAction
void exec() {
this.version "version_set"
}
}
class TaskB extends DefaultTask {
#Input
String version
}
task setVersionTask(type: TaskA){
pbxprojectFile project.file('foo.txt')
}
task getVersionTask(type: TaskB){
doFirst{
println('version ' + setVersionTask.version)
}
version setVersionTask.version
dependsOn 'setVersionTask'
}
When I go
./gradlew -q getVersion
I get
A problem was found with the configuration of task ':getVersionTask'.
No value has been specified for property 'version'.
How do I accomplish that?
Thanks a bunch!
The trick was to set TaskB's version from TaskA's doLast:
task setVersionTask(type: TaskA){
pbxprojectFile project.file('foo.txt')
doLast{
getVersionTask.version = version
}
}
task getVersionTask(type: TaskB){
doFirst{
println('version ' + getVersionTask.version)
}
dependsOn 'setVersionTask'
}
Is there a command that will instruct Gradle to resolve and download all testRuntime dependencies, but not run the tests?
Preferably, I want to do this without writing a custom task (such that the command can be run against any Gradle project).
For example, if my build.gradle has this dependency:
dependencies {
// ...
testRuntime "org.seleniumhq.selenium:selenium-htmlunit-driver:2.47.1"
}
The JAR files associated with selenium-htmlunit-driver are not downloaded until I run gradle test, which also runs the tests. I can download all other dependencies by running gradle testClasses, but not the testRuntime deps.
Put the following in a file called resolve.gradle
gradle.allprojects { project ->
project.task('resolveTestRuntime') {
doLast {
project.configurations.testRuntime.resolve()
}
}
}
Then run resolve.gradle as an init script
gradlew --init-script resolve.gradle resolveTestRuntime
Modifying the answer from Lance Java into a valid Init script, I was able to accomplish this with the following resolve.gradle:
apply plugin:MyInitPlugin
class MyInitPlugin implements Plugin<Gradle> {
#Override
void apply(Gradle gradle) {
gradle.allprojects{ project ->
project.task('resolveTestRuntime') {
doLast {
project.configurations.testRuntime.resolve()
}
}
}
}
}
Then running:
gradlew --init-script resolve.gradle resolveTestRuntime
I am trying to understand how to set a plugin convention property from a project property.
Here is the customPluginWithConvention example from the gradle distribution (gradle-0.9.2\samples\userguide\organizeBuildLogic\customPluginWithConvention\build.gradle)
apply plugin: GreetingPlugin
greeting = 'Hi from Gradle'
class GreetingPlugin implements Plugin<Project> {
def void apply(Project project) {
project.convention.plugins.greet = new GreetingPluginConvention()
project.task('hello') << {
println project.convention.plugins.greet.greeting
}
}
}
class GreetingPluginConvention {
def String greeting = 'Hello from GreetingPlugin'
}
Running this script with no project property:
>gradle hello
:hello
Hi from Gradle
BUILD SUCCESSFUL
And now trying to set a custom message via setting a project property:
>gradle -Pgreeting=goodbye hello
:hello
Hello from GreetingPlugin
Instead of the expected "goodbye" the default greeting of the convention is shown. Is it possible to override the message?
Is it possible to override the message?
Not yet, but we should try to make it possible. Please create an issue at http://jira.codehaus.org/browse/GRADLE.