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



问题

我能以某种方式确保一个任务将在另一个任务之前/之后执行吗?我不想在它们之间添加一个始终存在的依赖项。

背景

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

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

尝试

我的第一次尝试是在下面,但这不起作用,因为定义的依赖关系的顺序不能保证:

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

我的第二次尝试,调用行动中的任务不起作用,也不受支持:

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

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

目前它可能对你没有太大帮助,但我最近在这个领域提交了一个pull请求,并暗示它应该变成1.6(他们目前发布的是1.5,PR没有进入该版本(-请参阅此处的讨论。你最好的选择是在1.5发布后等待pull请求合并到master中,然后从这里获得第一个可用的夜间构建。

编辑

Gradle 1.6已经发布了一段时间,现在您可以简单地使用mustRunAfter来实现这一点。有关详细信息,请参阅Gradle手册中关于任务排序的部分。

gradle Task增强功能finalizedBy和mustRunAfter在一定程度上解决了这些问题。然而,与OP一样,我需要更改依赖关系,并基于完成请求的任务,而不是静态定义的。

我希望gradle integrationTest执行启动运行测试并在关闭后完成。我还希望启动运行测试关闭能够独立运行,而不需要任何依赖项或终结。

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

我发现更优雅的是将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
    }
}

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

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

您可以通过显式声明单个任务依赖项来解决排序问题:

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

管道中有一些工作可以解决您的特定用例,以启动另一个组件,例如用于测试目的的Servlet容器。

不久前我也遇到了同样的挑战——以下是我所做的解决方法(完整故事(:

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 "nntexpanded task list: ${gradle.startParameter.taskNames }nn"

相关内容

最新更新