I know there are some Groovy syntax under the Gradle. like following command:
task myTask { configure closure }
will become: task(name, configureClosure)
But how about:
task myTask(type: SomeType) { configure closure }
How this command translate to Groovy task command?
Thanks.
Hi,
SomeType
is short notation for SomeType.class
(Groovy feature), and type: SomeType
is short notation for Map (again Groovy feature).
To use named arguments in Groovy, the method must define the Map<String, ?>
as the first argument. The Closure can only reside outside argument list if it is the last one.
With these information, we can nail the actual method down to https://docs.gradle.org/current/javadoc/org/gradle/api/Project.html#task-java.util.Map-java.lang.String-groovy.lang.Closure-
Thanks for your reply Pierre1.
How about myTask
? is this a method?
I know task
is a method,
type: SomeType
is named argument.
{ configure closure }
is closure.
What is myTask
part?
As you said, task
is a method. The method signature is:
Task task​(Map<String,​?> args, String name, Closure configureClosure)
You’re just calling that method when you write:
task myTask(type: SomeType) { configure closure }
Named arguments appear first in the method signature. Otherwise, you’re looking at the same arguments. myTask
is just the value passed for the String name
argument.
Now, you might say that myTask
isn’t 'myTask'
or "myTask"
, so how is it treated as a String
? That’s not Groovy syntax. That’s just because Gradle is doing an AST transform and converting what would normally be a variable reference to a String when evaluating the Gradle file. Therefore, the quotes are optional, but if you don’t add them, the AST transform is effectively just adding them for you.
Thanks @jjustinic for your reply.
If it is task (myTask, type: SomeType) { configure closure }
, I understand the myTask
is the name
inside:
Task task​(Map<String,​?> args, String name, Closure configureClosure)
but, it is the: myTask(type: SomeType)
, there is ()
, it looks like a function call. How this function
works?
What you’re writing is not a function call. You’re removing the function call and writing only the arguments. task(...)
is the function call. Parenthesis are usually optional in Groovy.
With the AST transform to quote the task name, this function call:
task myTask(type: SomeType) { configure closure }
can be written any of these ways (plus more):
task(myTask, type: SomeType) { configure closure }
task('myTask', type: SomeType) { configure closure }
task myTask, type: SomeType, { configure closure }
task 'myTask', type: SomeType, { configure closure }
task(type: SomeType, 'myTask') { configure closure }
They’re all the same function call. Groovy is just flexible with how you list the arguments and only including the parenthesis around some of the arguments.
Thanks @jjustinic.
I try:
task hello(type:Copy) {
doLast {
println 'Hello world!'
}
}
it works, but if I try:
task hello, type:Copy {
doLast {
println 'Hello world!'
}
}
it is not working, I am using Gradle version 6.5.
Sorry, I missed a comma in the no parenthesis examples (edited above).
In the case of a type
, you need the comma before the closure. The comma would be optional for some of the other named arguments with different argument types, like dependsOn: 'otherTask'
. It just depends on if the syntax is unambiguous to Groovy.
Regardless, just because you can call the task
function many different ways, there’s not really a good reason to do so. The convention for an eager task is to write it as (but it’s still the same method call as the other ways):
task hello(type: Copy) {
I try with the comma, it works now.
And I search in the internet, here is article about it:
it is another way to explain it, I am not sure about the
methodmissing
in the article, but I know, the myTask
is argument for the task
method.Thanks @jjustinic.