引入持续构建执行
优化构建-编辑-构建循环 #
过去,我们曾建议您启用 Gradle Daemon(以及 并行执行,但有一些注意事项)以获得 Gradle 的最佳性能。我们还讨论过使用 增量构建 通过跳过不必要的工作来加速构建-编辑-构建反馈循环。现在有了另一项优化——一项可以让您让开道路,让 Gradle 为您启动构建。
从 2.5 版本开始,Gradle 支持持续构建执行,当检测到输入文件发生更改时,它会自动重新执行构建。社区中曾有一些插件支持 Gradle 的“观察”模式,Gradle “watch” mode 具有类似的功能。
在 Maven 中,相同的观察功能需要为每个插件实现,或者您必须使用具有预定义目标集的插件。我们希望做得更好。我们希望任何插件都能利用持续构建的强大功能,而无需提供额外信息。我们也希望要执行的任务集是完全临时的。由于 Gradle 需要知道任务的输入和输出才能进行增量构建,因此我们拥有启动文件更改监视所需的所有信息。
使用持续构建 #
持续构建 可用于任何具有已定义输入和输出的任务或任务集。如果您使用的是行为良好的任务,那么对于大多数构建来说,这应该不是问题。如果您发现您的构建没有像您期望的那样使用持续构建重新构建,这可能表明您的构建脚本存在问题。
命令行选项 #
您可以通过 `-t` 或 `--continuous` 命令行选项以及您想运行的任何任务(我们称之为任务选择器)来启用持续构建。至少有一个运行的任务需要定义输入才能进入持续构建模式。
例如,在一个典型的 Java 项目中,
$ gradle -t test
将启用持续构建,并在主源代码或测试源代码发生更改时重新运行测试。
我们不限于单个任务,因此我们也可以使用以下命令重新运行测试和 FindBugs:
$ gradle -t test findBugsMain.
确定何时再次运行构建 #
当您使用持续构建选项运行 Gradle 时,Gradle 会像往常一样执行构建,不同的是 Gradle 还会向文件监视服务注册所有任务的输入。即使是 `UP-TO-DATE` 的任务,其输入也会被记录下来,以便在触发新构建时考虑所有输入。这意味着您不必从干净构建开始,Gradle 就能知道在持续构建模式下哪些输入可能会发生更改。
构建结束后,Gradle 将开始监视基于收集到的输入的文件系统更改。Gradle 命令行界面将在控制台上显示消息“等待任务输入文件的更改”,然后等待输入发生更改。如果任何输入文件被更改或删除,Gradle 将使用相同的任务选择器集执行另一个构建。Gradle 可以检测到简单文件(删除、修改)以及目录(删除或新增文件)的更改。
观看演示
退出持续构建 #
一旦 Gradle 进入持续构建模式,它将不会退出,即使构建不成功。要退出持续构建,您应该使用 `Ctrl-D` 取消构建。在 Microsoft Windows 上,您还必须在 `Ctrl-D` 之后按 `ENTER` 或 `RETURN`。
如果您使用 `Ctrl-C`,Gradle 将会异常退出,并杀死 Gradle Daemon。
更新:从 Gradle 3.1 开始,`Ctrl-C` 不再杀死 Gradle Daemon。
局限性 #
用户指南章节 User Guide chapter 描述了持续构建的所有局限性和特殊情况。
需要 Java 7 或更高版本 #
Gradle 使用 Java 7 的 WatchService 来监视输入的更改。此功能仅在 JDK 7 或更高版本可用。
Mac OS X 性能 #
对于 GNU/Linux 和 Microsoft Windows,文件系统更改事件通过内核服务提供。对于 Mac OS X,Java 会回退到基于轮询的系统。这意味着在 Mac OS X 上,大量输入文件的更改检测可能会延迟,在某些情况下甚至可能导致死锁。这两个问题都被追踪为 JDK 错误:JDK-7133447 和 JDK-8079620。
构建脚本更改 #
Gradle 在持续构建模式下不考虑构建逻辑的更改。构建逻辑由 `build.gradle`、`settings.gradle`、`gradle.properties` 和其他来源创建。如果您更改了构建脚本,您需要退出持续构建并重新启动 Gradle。未来版本的 Gradle 将使描述构建逻辑的输入更容易,以便持续构建也能处理这些。
未来改进 #
除了缓解当前实现的一些限制之外,还有其他有趣的方面我们可以利用持续构建来实现。
目前,没有受支持的公共方式来管理 Gradle 启动的需要在构建之间保持存在的进程。Gradle 期望通过(例如通过 `Exec`)启动的进程会在构建过程中退出。
在下一个版本(2.6)中,Gradle 将支持 Play 框架,届时您可以在本地开发中将 Play 应用程序启动到单独的 JVM 中。启用持续构建后,每当类或资产发生更改时,Gradle 将热重载 Play 应用程序。Play 插件通过将 Play JVM 注册到 Gradle 的方式来实现这一点,使其能够在构建之间幸存。
我们希望最终将这种 Play 特定重载功能发展成一项通用功能,以便插件可以拥有自己的“热重载”行为。
另一个改进机会是最新检查。对于非常大的项目,在无操作的情况下,最新检查可能非常耗时。在查找过时文件时,Gradle 必须扫描整个目录或重新计算文件校验和。在使用持续构建时,Gradle 必须跟踪文件和目录的更改,因此在某些情况下,Gradle 可能会跳过对已知未更改文件的检查。
反馈 #
如果您在使用此新功能时遇到任何意外情况,请在 论坛 上告诉我们。