我有一个多项目,在最后一个子项目建成后,我想处理所有的罐子。 因此我在root项目中创建了一个任务:
task install(dependsOn: 'build', type: Copy) {
doLast {
println "exec install task"
}
}
在根目录中调用./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'.
然而,调用./gradlew tasks
向我展示了这些任务:
:tasks
------------------------------------------------------------
All tasks runnable from root project
------------------------------------------------------------
Build tasks
-----------
assemble - Assembles the outputs of this project.
build - Assembles and tests this project.
...
如何实现所需的功能?
答案 0 :(得分:4)
我假设您的根项目组织了构建,但没有定义自己构建的构建操作。 build
任务通常由语言插件定义(在大多数情况下通过apply plugin: 'java'
),但如果您的根项目不使用其中任何一个,则它将没有build
任务。
您使用的帮助任务tasks
的说明says:
显示可从根项目'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"
}
}
这样,对于每个已注册的子项目,调用findByName('build')
并将结果(找到的任务或null
)放入列表中,然后将其用作任务依赖性列表。我添加了.minus(null)
部分以从列表中删除null
条目,因为我不确定Gradle如何处理依赖项集合中的此类条目。如果您确定每个子项目都提供了build
任务,那么您也可以使用getByName('build')
。
编辑: OP找到了可选的递归getTasksByName
方法,它比手动迭代所有子项目更适合这种情况:
dependsOn getTasksByName('build', true)