在根项目中找不到路径为“build”的任务

use*_*453 5 gradle build.gradle

我有一个多项目,在构建最后一个子项目后,我想处理所有 jars。因此我在根项目中创建了一个任务:

task install(dependsOn: 'build', type: Copy) {
    doLast {
        println "exec install task"
    }
}
Run Code Online (Sandbox Code Playgroud)

./gradlew install根目录中调用时,我遇到了这个错误:

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'.
Run Code Online (Sandbox Code Playgroud)

但是,呼叫./gradlew tasks向我展示了这些任务:

:tasks

------------------------------------------------------------
All tasks runnable from root project
------------------------------------------------------------

Build tasks
-----------
assemble - Assembles the outputs of this project.
build - Assembles and tests this project.
...
Run Code Online (Sandbox Code Playgroud)

我怎样才能实现所需的功能?

Luk*_*fer 8

我假设您的根项目组织了构建,但没有定义自己采取的构建操作。该build任务通常由语言的插件定义(通过在大多数情况下apply plugin: 'java'),但如果你的根项目不使用其中任何一个,它不会有一个build任务。

tasks您使用的帮助任务的描述

显示可从根项目“projectReports”运行的任务(某些显示的任务可能属于子项目)

帮助任务遵循与通过命令行激活任务相同的逻辑。您可以提供任务名称,任何子项目中具有该名称的任何任务都将被执行(这就是gradle build工作的原因)。

但是如果你定义了一个dependsOn依赖项,给定的字符串被评估为单个任务的任务路径。由于每个任务名称在一个项目中只能使用一次,因此根项目中的任务名称是唯一的,但如果考虑子项目,则可以找到许多任务。因此,可以使用语法:<projectName>:<taskName>来识别子项目中的任务。

现在,让我们面对您的具体问题:如果install任务应该依赖于build一个子项目的任务,您可以使用dependsOn ':<mySubproject>:build'. 但是我假设您希望install任务依赖于每个子项目build任务,所以我想提出这种方法:

task install(type: Copy) {
    dependsOn subprojects*.tasks*.findByName('build').minus(null)
    doLast {
        println "exec install task"
    }
}
Run Code Online (Sandbox Code Playgroud)

这样,对于每个注册的子项目,findByName('build')都会调用并将结果(找到的任务或null)放入一个列表中,然后将其用作任务依赖项列表。我添加了从列表中.minus(null)删除null条目的部分,因为我不确定 Gradle 如何处理依赖项集合中的这些条目。如果您确定每个子项目都提供了一个build任务,您也可以使用getByName('build')

编辑: OP 找到了可选的递归getTasksByName方法,它比手动迭代所有子项目更适合这种情况:

dependsOn getTasksByName('build', true)
Run Code Online (Sandbox Code Playgroud)

  • 我终于找到时间尝试你的解决方案。不幸的是,“findByName”似乎不起作用,但这行代码符合我的预期:“dependsOn subprojects*.getTasksByName("build", true)”。请随意更新您的解决方案,我很高兴接受它。非常感谢。 (2认同)
  • 是的,我立即发现了我的错误:`findByName` 是`TaskContainer` 类的方法而不是`project` 类的方法,所以我需要先访问`TaskContainer` 实例:`dependsOn subprojects*.tasks*.findByName ('build').减号(空)`。但是,您找到的方法似乎更适合该问题,但是您可以直接在根项目上调用它,因为它提供了递归任务搜索。因此,`dependsOn getTasksByName('build', true)` 也应该有效。 (2认同)