在Gradle中定义没有依赖的任务顺序?

时间:2013-03-06 15:15:35

标签: gradle

问题

我可以以某种方式确保在另一个任务之前/之后执行任务,同时执行这两个任务吗?我想要在它们之间添加一个始终存在的依赖关系。

背景

我有两个任务,一个启动服务器,另一个运行测试。启动该服务器的任务在新进程中运行它,因此我可以运行gradle startServer runServerTests。由于启动服务器需要一些时间,因此必须可以使用一个gradle进程启动服务器,然后使用另一个gradle进程多次运行测试。

现在我正在尝试创建一个完成CI环境所做的所有事务的任务,包括启动服务器和运行服务器测试。我显然想在运行测试之前确保服务器已启动,但到目前为止我运气不好。

尝试

我的第一次尝试如下,但由于已定义的依赖项is not guaranteed的顺序,这不起作用:

task doItAll(dependsOn: [startServer, runServerTests]) { ... }

我的第二次尝试,调用任务in actions不起作用,is not supported

task doItAll() << {
  tasks.startServer.execute()
  tasks.runServerTests.execute()
}

解决方案在路线图上(GRADLE-294Initializer/Finalizer),但现在对我没有帮助。

5 个答案:

答案 0 :(得分:6)

目前它可能对你没什么帮助,但是我最近在这个领域提交了一个拉取请求,暗示它应该变成1.6(它们目前正在释放1.5而PR没有进入该版本) - 参见讨论here 。最好的办法是等待pull request在1.5版本发布后合并为主版,然后从here获取第一个可用的每晚版本。

修改

Gradle 1.6已经发布了一段时间,现在您只需使用mustRunAfter即可实现。有关详细信息,请参阅the section on task ordering in Gradle manual

答案 1 :(得分:1)

http://issues.gradle.org/browse/GRADLE-294已于5月1日解决(Gradle 1.6),现在为您提供了一种方法来描述任务B应该在A之前运行,如果在任务之间使用mustRunAfter()关系时两者都存在。

因此,我认为你的问题得到了充分的回答。

答案 2 :(得分:1)

gradle任务增强功能finalizedBymustRunAfter可以解决这些问题。但是,与OP一样,我需要根据请求的任务更改依赖关系和最终确定,而不是静态定义。

我希望 gradle integrationTest 执行启动 runTests 并由关闭完成。 我还希望启动 runTests 关闭能够独立运行 - 没有任何依赖关系或最终确定。

您可以静态地创建可以表达此功能的包装器任务,但是随着启动和关闭任务的数量和复杂性的增加,它无法很好地扩展 - 并且依赖于添加更多任务的任何人来添加和维护所需的包装器。

我发现更优雅的是将 integrationTests 实现为任务规则。

tasks.addRule('integrationTest: Full execution of integration tests with setup, startup,  shutdown and clean up') { String taskName ->
    if (taskName.equals('integrationTest')) {
        task(dependsOn: [runTests], taskName)

        // Add ordering and finalization for integration test runs        
        runTests.dependsOn startup
        startup.finalizedBy shutdown

        ... // and many other setup and shutdown tasks you want in the task DAG when running an integration test
    }
}

答案 3 :(得分:0)

您可以通过明确声明单个任务依赖关系来解决排序问题:

runServerTests.dependsOn startServer

task doItAll(dependsOn: runServerTests) << {
   // do something
}

work in the pipeline解决了您提出另一个组件的具体用例,例如用于测试目的的Servlet容器。

答案 4 :(得分:0)

前段时间我遇到了同样的挑战 - 这就是我为解决这个问题所做的工作(全文):

https://caffeineinduced.wordpress.com/2015/01/25/run-a-list-of-gradle-tasks-in-specific-order/

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"