I have a multiproject and after the last subproject is built, I'd like to process all jars. Therefore I created a task in the root-project:
task install(dependsOn: 'build', type: Copy) {
doLast {
println "exec install task"
}
}
Upon calling ./gradlew install
in the root directory, I'm facing this error:
FAILURE: Build failed with an exception.
* What went wrong:
Could not determine the dependencies of task ':install'.
> Task with path 'build' not found in root project 'foo'.
However, calling ./gradlew tasks
shows me these tasks:
:tasks
------------------------------------------------------------
All tasks runnable from root project
------------------------------------------------------------
Build tasks
-----------
assemble - Assembles the outputs of this project.
build - Assembles and tests this project.
...
How can I achieve the desired functionality?
I assume, that your root project organizes the build, but does not define build action taken by itself. The build
task is often defined by language plugins (in most cases via apply plugin: 'java'
), but if your root project does not use any of them, it won't have a build
task.
The description of the help task tasks
, which you used, says:
Displays the tasks runnable from root project 'projectReports' (some of the displayed tasks may belong to subprojects).
The help task followes the same logic as the task activation via the command line. You can provide a task name and any task with the name in any subproject will be executed (thats why gradle build
works).
But if you define a dependsOn
dependency, the given string is evaluated as task path for a single task. Since each task name can only be used once in a project, the name is unique for tasks in the root project, but many tasks could be found, if subprojects would be considered. Therefor, one can use the syntax :<projectName>:<taskName>
to identify tasks in subprojects.
Now, let's face your specific problem: If the install
task should depend on the build
task of one single subproject, you could use dependsOn ':<mySubproject>:build'
. But I assume you want the install
task to depend on each subproject build
task, so I'd like to propose this approach:
task install(type: Copy) {
dependsOn subprojects*.tasks*.findByName('build').minus(null)
doLast {
println "exec install task"
}
}
This way, for each registered subproject, findByName('build')
is called and the result (the found task or null
) is put into a list, which is then used as task dependency list. I added the .minus(null)
part to remove null
entries from the list, because I am not sure how Gradle handles such entries in a dependency collection. If you are sure, that each subproject provides a build
task, you can use getByName('build')
, too.
EDIT: OP found the optionally recursive getTasksByName
method, which suits this case even better than iterating over all subprojects manually:
dependsOn getTasksByName('build', true)
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With