介绍持续构建执行

优化构建-编辑-构建循环

过去,我们建议您启用 Gradle 守护进程(以及 并行执行,带有一些注意事项)以获得 Gradle 的最佳性能。我们还讨论了使用 增量构建 通过跳过不必要的操作来加快构建-编辑-构建反馈循环。现在,另一种优化方法可以使用——它可以让您置身事外,让 Gradle 为您启动构建。

从 2.5 版本开始,Gradle 支持持续构建执行,当检测到其输入发生更改时,它将自动重新执行构建。有一些社区插件添加了对 Gradle“监视”模式 的支持,这些插件执行类似的操作。

在 Maven 中,需要为每个插件实现相同的 watch 功能,或者使用具有预定义目标集的插件。我们希望做得更好。我们希望任何插件都能利用持续构建的强大功能,而无需提供额外的信息。我们还希望执行的任务集完全是临时的。由于 Gradle 需要知道任务的输入和输出才能进行增量构建,因此我们拥有开始监视更改所需的所有信息。

使用持续构建

持续构建 可用于任何定义了输入和输出的任务或任务集。如果您使用的是行为良好的任务,这对于大多数构建来说应该不成问题。如果您发现您的构建没有按照预期那样使用持续构建重建,这可能表明您的构建脚本存在问题。

命令行选项

您可以使用 -t--continuous 命令行选项以及您要运行的任何任务(我们称之为任务选择器)来启用持续构建。至少需要运行一个定义了输入的任务才能进入持续构建模式。

例如,在一个典型的 Java 项目中,

$ gradle -t test 

将启用持续构建,并在主源代码或测试源代码发生更改时重新运行测试。

我们并不局限于单个任务,因此我们还可以使用以下方法重新运行测试和 FindBugs 对主源代码进行测试:

$ gradle -t test findBugsMain.

确定何时运行另一个构建

当您使用持续构建选项运行 Gradle 时,Gradle 会像往常一样执行构建,但 Gradle 还会使用文件监视服务注册所有任务的输入。即使是 UP-TO-DATE 的任务也会记录其输入,因此在触发新构建时可以考虑所有输入。这意味着您不必从干净的构建开始,Gradle 就能知道哪些输入可能在持续构建模式下发生更改。

构建结束后,Gradle 将根据收集的输入开始监视文件系统更改。Gradle 命令行界面将在控制台上显示消息 Waiting for changes to input files of tasks,并等待输入更改。如果任何输入文件发生更改或删除,Gradle 将使用相同的任务选择器集执行另一个构建。Gradle 可以检测对简单文件(删除、修改)和对目录(删除或新文件)的更改。

查看此功能的演示

退出持续构建

一旦 Gradle 在持续构建中运行,即使构建不成功,它也不会退出。要退出持续构建,您应该使用 Ctrl-D 取消构建。在 Microsoft Windows 上,您还必须在 Ctrl-D 后按 ENTERRETURN

如果您使用 Ctrl-C,Gradle 将突然退出并杀死 Gradle 守护进程。

更新:从 Gradle 3.1 开始,Ctrl-C 不再杀死 Gradle 守护进程

限制

用户指南章节 描述了持续构建的所有限制和怪癖。

需要 Java 7 或更高版本

Gradle 使用 Java 7 的 WatchService 来监视输入的变化。此功能仅在 JDK 7 或更高版本上可用。

Mac OS X 性能

对于 GNU/Linux 和 Microsoft Windows,文件系统更改事件通过内核服务提供。对于 Mac OS X,Java 回退到基于轮询的系统。这意味着在 Mac OS X 上,对非常非常多的输入文件的更改检测可能会延迟,在某些情况下会导致死锁。这两个问题都被跟踪为 JDK 错误:JDK-7133447JDK-8079620

构建脚本的更改

Gradle 在持续构建模式下不会考虑对构建逻辑的更改。构建逻辑是从 build.gradlesettings.gradlegradle.properties 和其他来源创建的。如果您对构建脚本进行了更改,则需要退出持续构建并重新启动 Gradle。未来的 Gradle 版本将使描述构建逻辑的输入变得更容易,以便持续构建也能处理这些输入。

未来的改进

除了减轻当前实现的一些限制之外,我们还可以使用持续构建来完成其他有趣的事情。

现在,还没有任何受支持的、公开的方法来管理由 Gradle 启动的需要在构建之间存在的进程。Gradle 预计由(例如,通过 Exec)启动的进程将作为构建的一部分退出。

在下一个版本(2.6)中,Play 支持将加入 Gradle,有了它,您将能够在单独的 JVM 中启动 Play 应用程序以进行本地开发。在启用持续构建的情况下,Gradle 将在类或资产发生更改时热重载 Play 应用程序。Play 插件通过以一种在构建之间存活的方式将 Play JVM 注册到 Gradle 来实现这一点。

我们希望最终将这种特定于 Play 的重新加载功能演变成一个通用功能,以便插件可以拥有自己的“热重载”式行为。

另一个改进的机会是最新检查。对于非常大的项目,最新检查对于无操作情况来说可能很耗时。在查找过时文件时,Gradle 必须扫描整个目录或重新计算文件校验和。在使用持续构建时,Gradle 必须已经跟踪文件和目录更改,因此在某些情况下,Gradle 可能能够跳过对已知未更改文件的检查。

反馈

如果您在使用此新功能时遇到任何意外情况,请在 论坛 上告知我们。

讨论