我正在gradle中完成一项需要调用许多其他任务的任务。
这就是我所拥有的:
task ci(dependsOn: [
clean,
build,
test
])
我看到的输出有多奇怪:
gradle ci
:compileJava
:processResources UP-TO-DATE
:classes
:jar
:assemble
:compileTestJava UP-TO-DATE
:processTestResources UP-TO-DATE
:testClasses UP-TO-DATE
:test UP-TO-DATE
:check UP-TO-DATE
:clean // cleaning after the build
:build
:ci
请注意,清理发生在构建目标之后,这会清除我的构建。
如果我将任务更改为:
task ci(dependsOn: [
clean,
test
])
然后它似乎以正确的顺序执行:
:clean UP-TO-DATE // cleaning before the build
:compileJava
:processResources UP-TO-DATE
:classes
:compileTestJava UP-TO-DATE
:processTestResources UP-TO-DATE
:testClasses UP-TO-DATE
:test UP-TO-DATE
:ci UP-TO-DATE
我尝试通过添加build.dependsOn clean来修复原始目标,但这似乎没有任何影响。
感谢任何帮助。
答案 0 :(得分:39)
似乎我偶然发现了GRADLE-427中争论的问题,其中gradle决定了执行任务的最佳顺序。 我通过遵循其中的建议解决了我的问题,Gradle User Guide - Section 15.5中也记录了这些建议,以便在不同的任务之间建立排序。我的最终 ci 目标因此显示为:
task ci(dependsOn: ['clean', 'build', 'uploadArchives'])
build.mustRunAfter clean
uploadArchives.mustRunAfter build
现在一切都按预期工作了。
答案 1 :(得分:9)
TLDR版本:以下是我在其中一个项目中的表现(不引入人工依赖)。
//--- build aliases : define a synonym here if you want a shortcut to run multiple targets
def buildAliases = [
'all' : ['clean', 'assemble', 'runProvisioner', 'stopTomcat', 'installTomcat', 'deployToTomcat', 'startTomcat'],
'rebuild' : ['clean', 'assemble']
]
def expandedTaskList = []
gradle.startParameter.taskNames.each {
expandedTaskList << (buildAliases[it] ? buildAliases[it] : it)
}
gradle.startParameter.taskNames = expandedTaskList.flatten()
println "\n\n\texpanded task list: ${gradle.startParameter.taskNames }\n\n"
为了使用这些别名,请将它们称为任务。例子:
./gradlew all
./gradlew rebuild
或
gradle all
gradle rebuild
有关更多背景信息,请参阅:
https://caffeineinduced.wordpress.com/2015/01/25/run-a-list-of-gradle-tasks-in-specific-order/
答案 2 :(得分:2)
我宁愿不添加包装器任务只是为了确保订单。
在这种情况下,我的解决方案如下 -
run.dependsOn 'clean'
compileJava.mustRunAfter 'clean'
这可确保在gradle执行clean
之前执行compileJava
任务。如此有效,您将始终创建一个新的构建。
希望这有帮助。
答案 3 :(得分:0)
使用一些Groovy / Gradle优势,可以通过以下方式进一步改进解决方案:
def taskNames = [...] // list of task names
task('lastTask', dependsOn: taskNames)
taskNames.inject(null) { acc, val ->
if (acc != null) tasks[val].mustRunAfter acc
tasks[val]
}
通过这种方式,你可以拥有一个包含任务列表的地方。