Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Task with path 'build' not found in root project

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?

like image 459
user3105453 Avatar asked Apr 07 '17 09:04

user3105453


1 Answers

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)
like image 104
Lukas Körfer Avatar answered Nov 15 '22 04:11

Lukas Körfer