I tried both versions defining tasks:
Version 1:
tasks {
task helloWorld {
group 'Testing'
description "I don't do very much."
println "I can print in configuration phase, too. I'm a big boy."
doFirst {
println 'Hello'
}
doLast {
println "world"
}
}
}
Version 2:
task helloWorld {
group 'Testing'
description "I don't do very much."
println "I can print in configuration phase, too. I'm a big boy."
doFirst {
println 'Hello'
}
doLast {
println "world"
}
}
Is there any difference? In my opinion version 1 is way cleaner than version 2, especially working with multiple custom tasks and working with common conventions (https://docs.gradle.org/current/samples/sample_convention_plugins.html).
I want to get sure, I don't break anything, because I have never seen version 1 in any source.
CodePudding user response:
Short answer
- both versions are quite similar and will behave the same, but they both use the "old" Tasks API, creating tasks eagerly; you should consider switching to the "new" API (since Gradle 4.9) and configure tasks lazily, using
TaskContainer.register(...)
methods - version 1 might seem cleaner to you but in fact it's way more confusing than version 2, I'll explain why.
Long answer
Old Tasks API vs New Tasks API
In both version you are using the shorthand notation task myTask { /* task configuration closure */ }
which is a shortcut for TaskContainer.create() method:
// following is equivalent to:
// project.getTasks().create(...).configure( { /* tasks configuration */} )
tasks.create("myTask ") {
// task configuration closure
}
- this notation is specific to Groovy DSL, and will likely be deprecated in future Gradle releases - there will be no replacement for this notation in the new Tasks API (see more information here and here)
- you should better use of the Task configuration avoidance feature and declare your custom tasks lazily
Version 1 vs version 2
Version 2 is the way Gradle docs suggested for declaring tasks in older versions, e.g. Helloworld in Gradle 5.6 (in latest versions the documentation references the new API: Helloworld in Gradle 7.5 )
In your version 1: there are two issues
tasks
property collision
project.tasks
could refer to either Project.getTasks(): TaskContainer
property or to the tasks
Task, thanks to Dynamic Project properties:
tasks {
// here we don't configure the project.TaskContainer as we could expect, but instead the default task named 'tasks'
// proof:
println " configuring task named: " it.name
// => configuring task named: tasks
println " type of current object beeing configured: " it.class.name
// => type of current object beeing configured: org.gradle.api.tasks.diagnostics.TaskReportTask_Decorated
// this will still work, thanks to Groovy closure delegate feature :
// will delegate to parent Project instance => equivalent to project.task("helloWorld3") { /* config */ }
task helloWorld3 {
// tasks configuration
}
}
funny (or not): this would also work, thanks to delegate mechanism:
repositories {
task helloWorldDefinedInRepositories {
// tasks configuration
}
}
dependencies {
task helloWorldDefinedInDependencies {
// tasks configuration
}
}
tasks
(TaskContainer) methods
You could group custom tasks declaration under a common "parent" tasks
section as follows:
tasks.configure {
// here we configure the Project.taskContainer property.
println " type of current object beeing configured: " it.class.name
// => org.gradle.api.internal.tasks.DefaultTaskContainer_Decorated
create("eagerTask") {
// config
}
register("lazyTask") {
// config
}
}
This will work, but it's not clear why you think this will help in handling "common convention" , maybe you could give some more details about this expectation.