6

问题

当两个任务都被执行时,我能否以某种方式确保一个任务将在另一个任务之前/之后执行?我不想在它们之间添加始终存在的依赖关系。

背景

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

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

尝试

我的第一次尝试如下,但这不起作用,因为不能保证定义的依赖项的顺序:

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

我的第二次尝试,在操作中调用任务不起作用并且不受支持

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

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

4

5 回答 5

6

目前它可能对你没有多大帮助,但我最近在这方面提交了一个拉取请求,并暗示它应该进入 1.6(他们目前正在发布 1.5,而 PR 没有进入该版本) - 请参阅此处的讨论。最好的办法是等待1.5 发布后将拉取请求合并到 master 中,然后从这里获取第一个可用的夜间构建。

编辑

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

于 2013-03-07T23:07:30.843 回答
2

gradle 任务增强finalizedBymustRunAfter在某种程度上解决了这些问题。但是,像 OP 一样,我需要根据请求的任务而不是静态定义来更改依赖项和完成。

我希望gradle integrationTest执行startuprunTests并通过shutdown完成。我还希望startuprunTestsshutdown能够独立运行——没有任何依赖或终结。

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

我发现更优雅的是将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
    }
}
于 2014-02-17T23:19:57.853 回答
1

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

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

于 2013-05-28T07:15:17.013 回答
0

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

runServerTests.dependsOn startServer

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

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

于 2013-03-06T18:51:00.213 回答
0

不久前我遇到了同样的挑战 - 这是我为解决它所做的(完整故事):

https://caffeineducing.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"
于 2015-05-09T12:20:02.657 回答