33

我正在 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 来修复原始目标,但这似乎没有影响。

任何帮助表示赞赏。

4

4 回答 4

42

似乎我偶然发现了GRADLE-427中正在讨论的问题,其中 gradle 确定了执行任务的最佳顺序。我按照其中的建议解决了我的问题,该建议也记录在Gradle 用户指南 - 第 15.5 节中,以建立不同任务之间的排序。因此,我的最终ci目标显示为:

task ci(dependsOn: ['clean', 'build', 'uploadArchives'])
build.mustRunAfter clean
uploadArchives.mustRunAfter build

现在一切都按预期工作。

于 2013-07-19T23:27:15.360 回答
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://caffeineducing.wordpress.com/2015/01/25/run-a-list-of-gradle-tasks-in-specific-order/

于 2015-10-29T19:22:24.483 回答
4

我宁愿不添加包装任务只是为了确保订单。

在这种情况下,我的解决方案如下 -

run.dependsOn 'clean' compileJava.mustRunAfter 'clean'

这可以确保clean任务在 gradle 执行之前执行compileJava。如此有效,您将始终创建一个全新的构建。

希望这可以帮助。

于 2015-01-17T06:36:11.047 回答
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]
}

这样,您就可以在一个地方放置任务列表。

于 2016-01-12T12:56:52.290 回答