在Gradle中定义没有依赖项的任务顺序? 问题:

在Gradle中定义没有依赖项的任务顺序? 问题:,gradle,Gradle,当两个任务都要执行时,我是否可以确保在另一个任务之前/之后执行一个任务?我不想在它们之间添加一个始终存在的依赖关系 背景 我有两个任务,一个是启动服务器,另一个是对服务器运行测试。启动该服务器的任务在新进程中运行它,因此我可以运行gradlestartserver runServerTests。由于启动服务器需要一些时间,因此必须能够使用一个gradle进程启动服务器,然后使用另一个gradle进程运行测试数次 现在,我尝试创建一个单一的任务来完成CI环境的所有工作,包括启动服务器和运行服务器测

当两个任务都要执行时,我是否可以确保在另一个任务之前/之后执行一个任务?我不想在它们之间添加一个始终存在的依赖关系

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

现在,我尝试创建一个单一的任务来完成CI环境的所有工作,包括启动服务器和运行服务器测试。显然,我希望在运行测试之前确保服务器已启动,但到目前为止我运气不佳

尝试 我的第一次尝试如下所示,但由于已定义依赖项的顺序不同,因此这不起作用:

我的第二次尝试调用任务无效,并且:


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

runServerTests.dependsOn startServer

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

task doItAll(dependsOn:runServerTests)目前可能对您没有多大帮助,但我最近在这方面提交了一个pull请求,有人暗示它应该进入1.6版本(他们目前正在发布1.5,PR没有进入该版本)-见讨论。您最好的选择是等待1.5版本后合并到master中,然后从中获取第一个可用的夜间构建

编辑

Gradle 1.6已经发布了一段时间,现在您可以简单地使用
mustRunAfter
来实现这一点。有关详细信息,请参阅。

已于5月1日(Gradle 1.6)解决,现在为您提供了一种方法来描述任务B应该在a之前运行,如果在任务之间使用mustRunAfter()关系时两者都存在的话


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

gradle任务增强,并以某种方式解决这些问题。但是,与OP一样,我需要根据请求的任务(而不是静态定义的任务)更改依赖项和终结

我想gradle integrationTest执行启动运行测试,并在关闭时完成。 我还希望启动运行测试关闭能够独立运行—无需任何依赖项或最终确定

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

我发现更优雅的方法是将集成测试作为任务规则来实现

tasks.addRule('integrationTest:通过设置、启动、关闭和清理完整执行集成测试){String taskName->
if(taskName.equals('integrationTest')){
任务(dependsOn:[runTests],任务名)
//添加集成测试运行的排序和最终确定
runTests.dependsOn启动
startup.finalizedBy shutdown
…//以及运行集成测试时需要在任务DAG中执行的许多其他设置和关闭任务
}
}

不久前,我遇到了同样的挑战——以下是我为解决这个问题所做的工作(完整故事):

TLDR;版本:

/---构建别名:如果您想要运行多个目标的快捷方式,请在此处定义同义词
def构建别名=[
'all':['clean'、'assembly'、'runProvisioner'、'stopTomcat'、'installTomcat'、'deployToTomcat'、'startTomcat'],
“重建”:[“清理”、“组装”]
]
def expandedTaskList=[]
gradle.startParameter.taskNames.each{

expandedTaskList我在过去几年里断断续续地阅读了Gradle dev的邮件列表,imo Gradle受到了过度工程的困扰。你的一些链接就是这方面的证据——你可以看到相对基本/基本的bug和功能请求在Jira中被搁置了四年多,没有任何活动,因为“它们都将在下一次大的重构/重新架构(不是一个实际的引用,而是一种心态)之后得到处理。”当然,它们不能在重构之前得到修复,因为那将是一个“黑客”".Classic overengineering。我想补充一点,尽管它存在一些问题和我提到的流程问题,但我认为它在当前的形式下是一个很棒的工具。像这样指定
runServerTests.dependsOn startServer
将始终使
startServer
在执行任务
runServerTests
之前运行。我尝试我想清楚这不是我想要的,但也许我不够清楚?那么我一定误解了你的要求。我认为这就是你需要的。你希望服务器在什么条件下启动?我希望服务器在
runservetests
之前启动,但仅当用户执行
doItAll
时启动。我想保留今天在已经运行的服务器上执行
runServerTests
的能力。可以通过提前手动执行
startServer
来启动服务器,这会使服务器在后台进程中运行。啊,好的。当你说
startServer
可以手动启动时,这是否意味着它也可以手动启动发生在不同的Gradle流程中,或者始终是同一流程的一部分?是的,它可以发生在不同的Gradle流程中。干得好,看起来很棒!因为这已经在了,我假设它会进入下一个版本。是的,它看起来会在1.6版本中,因为该功能现在是公共Gradle API的一部分,您能更新吗你的答案是关于如何使用它的功能描述?希望这应该是足够的。请尝试发布解决方案,或者至少是一个最小值
task doItAll() << {
  tasks.startServer.execute()
  tasks.runServerTests.execute()
}
runServerTests.dependsOn startServer

task doItAll(dependsOn: runServerTests) << {
   // do something
}
//--- 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"