声明式 Gradle
目录
引言
注意:声明式 Gradle 是一个实验性项目,正在积极开发中,实施过程中会有频繁的更改。要了解当前状态,请访问 GitHub 上的 Declarative Gradle 仓库。在此,您可以访问当前文档和原型。订阅 Gradle Build Tool Newsletter 以接收该项目的每月更新 - 最后更新于 2024 年 5 月 11 日
我们 Gradle Build Tool 的愿景之一是提供一种优雅且可扩展的声明式构建语言,让开发者能够以清晰易懂的方式描述任何类型的软件。
Gradle 的构建语言在最基本的方式上已经具有可扩展性,这带来了高度的灵活性。这也是 Gradle 成为许多公司(包括大型企业)的首选构建系统,以及 Android 和 Kotlin Multiplatform 的默认构建系统的主要原因之一。
然而,我们当前的构建语言并非总是完全声明式、清晰且易于理解。虽然长期以来,构建脚本应声明化,构建逻辑应保留在插件中的做法一直被认为是最佳实践,但这在许多项目中并非现实。我们看到许多项目混合了声明式和命令式代码,编写了冗长而复杂的构建脚本。构建脚本中使用的 Gradle 特定概念并非软件开发者总是熟悉的。这使得不熟悉 Gradle 的开发者在入门 Gradle 时不够友好。同时,这也使得 IDE 难以提供可靠的构建脚本编辑支持。
这篇博文解释了 Gradle 团队对我们称之为“面向开发者的软件定义”或简称为“声明式 Gradle”的看法。本文概述了我们实现“优雅且声明式构建语言”愿景的计划。
软件开发者和构建工程师 #
首先,让我们理清 Gradle 最主要的两个用户群体之间的区别:软件开发者和构建工程师。
Gradle Build Tool 的大多数用户是软件开发者。他们的工作是通过交付功能、修复 bug 等来改进他们的软件产品。软件开发者不会以运行构建为目的开始他们的一天。虽然他们依赖构建系统来完成任务,但这并不是他们的主要关注点。
第二类用户是构建工程师。与软件开发者不同,他们的职责是维护构建本身。这一群体历来欣赏 Gradle 在满足最复杂的构建自动化需求方面的灵活性。
在实践中,这两种角色之间经常存在重叠。在小型团队中,一些熟悉 Gradle 的工程师往往负责构建。在大型团队中,通常有专门的构建工程师。
软件定义 vs 构建逻辑 #
接下来,让我们理清软件定义和构建逻辑之间的区别。
软件定义是什么需要被构建。它定义了正在生产的软件的结构,并包含以下信息:
- 正在生产什么类型的软件?
- 软件是用什么语言实现的?
- 软件以哪些平台为目标?
- 软件的依赖项是什么?
- 应该使用哪些工具链来编译/链接/插桩/打包/文档化软件?
- 在软件发布之前需要进行哪些质量检查?
构建逻辑是软件如何被构建。它是为 Gradle 添加新功能、集成不同工具并为软件定义提供约定的代码。
软件定义供软件开发者阅读和修改。构建逻辑供构建工程师阅读和修改。
在 Gradle 中,软件定义存在于 Groovy DSL 和 Kotlin DSL 的构建脚本和设置中。建议将构建逻辑保留在插件中。然而,用户可以灵活地将构建逻辑与软件定义一起包含在构建脚本中。这导致了软件开发者和构建工程师的关注点和需求之间的界限模糊。
什么是面向开发者的软件定义 #
我们的战略目标是使软件定义对开发者来说更清晰、更简单。
我们认为实现这一目标有两个关键步骤:
通过受限 DSL 分离软件定义和构建逻辑 #
如上所述,不建议混合软件定义和构建逻辑。
我们计划提供一个受限 DSL,将软件定义和构建逻辑分离,从而使构建语言完全声明化。这将有效地强制执行现有的最佳实践。
受限 DSL 将只允许有限的构造,例如嵌套块、赋值和选定的方法调用。通用的控制流和任意方法调用将被禁止。您将能够使用任何 JVM 语言(如 Java、Kotlin 或 Groovy)编写构建逻辑,但该逻辑将保留在插件(本地或已发布)中。
这将提供软件开发者和构建工程师关注点之间的更好分离,并提供更简洁的构建视图,同时不限制工具的灵活性。
将软件定义与软件领域相匹配 #
虽然受限 DSL 是一个正确的方向,但它只是使软件定义真正面向开发者的部分解决方案。
另一个问题是,软件定义在所有情况下都没有使用反映底层软件领域的概念。为了使用 Gradle,开发者通常需要理解 Gradle 特定的构建块,例如依赖项配置和任务。这些概念是构建逻辑特有的,因此应该只由构建工程师关注。在大多数情况下,软件开发者应该能够使用他们已经熟悉的aughts,如库、应用程序、版本和测试套件来配置他们所需的一切。
Android Gradle Plugin 是一个基于 Gradle 的更声明式软件定义 DSL 的好例子。虽然更广泛的 JVM 生态系统尚未达到我们期望的状态,但最近的功能,例如 测试套件 和 工具链,是朝着这个方向迈出的重要一步。
我们的目标之一是提供更广泛的高级构造集,可以在不同生态系统之间共享。这将使现有的生态系统(如 Java、Android 和 KMP)更加一致。未来,它还将使实现对新生态系统(如 iOS 或 .NET)的支持变得更加容易。
IDE 体验 #
面向开发者的软件定义的一个关键方面是,它使提供卓越的 IDE 体验更加容易。
软件定义传统上是手工编辑的。对于 Groovy DSL,由于 Groovy 语言的动态特性,只能提供基础的 IDE 辅助。对于 Kotlin DSL,在 IntelliJ IDEA 和 Android Studio 等受支持的 IDE 中提供了出色的支持。这包括自动完成、智能内容辅助、快速访问文档、导航到源代码以及上下文感知重构。使用 Kotlin DSL,您可以像处理生产代码一样,使用相同的编辑体验来编辑构建逻辑。
然而,对于 IDE 供应商来说,当构建脚本中允许任意代码时,自动更改软件定义或创建 UI 编辑器是困难的。通过使软件定义完全声明化,支持将变得更加容易。我们知道 IDE 供应商对提供这种功能非常感兴趣。这样,软件开发者就可以根据他们的偏好和专业知识水平选择编辑模式(UI 或手动)。
还有性能方面的考虑。例如,IDE 同步过程涉及一系列步骤,包括依赖解析等复杂计算,以在 IDE 中提供项目的完整视图。通过完全声明式且可快速可靠解析的软件定义,即使对于大型项目,我们也可以在 IDE 中快速提供项目的初始视图。
Gradle、Google 和 JetBrains 之间的协作 #
Gradle、Google 和 JetBrains 之间有着悠久而富有成效的协作历史。我们最近一次重要的合作成果是 Kotlin DSL 成为新 Gradle 构建的默认设置。这极大地提高了 Kotlin DSL 的受欢迎程度,并使许多用户能够在受支持的 IDE 中从 Gradle 构建脚本获得完整的 IDE 辅助。
今年 10 月,我们与这三家公司的代表进行了面对面会谈,我们将大部分注意力放在声明式软件定义上。我们都认识到,在许多项目中,软件定义与构建逻辑和低级构造的混合给用户体验带来了限制。Gradle、Google 和 JetBrains 正在合作解决这些问题。我们正在密切合作,以确保该解决方案能够很好地适用于 Android 和 Kotlin Multiplatform 生态系统,并提供出色的 IDE 支持。
Gradle 团队主导此项目,并与 JetBrains 和 Google 密切合作,以确保 IntelliJ IDEA 和 Android Studio 具有出色的 IDE 支持。此项目是 Gradle 的重点项目之一。我们已经在积极开发一个初步原型。明年初,我们计划与早期采用者分享一个简单的项目初步解决方案,从 Android 开始。
与此同时,JetBrains 正在进行一项名为 Amper 的类似目标的实验。我们的目标之一是利用这项实验来促进声明式 Gradle 的开发,并为 Kotlin 和 Kotlin Multiplatform 提供出色的用户体验。因此,除了专注于声明式 Gradle 的专用团队外,我们还在与 JetBrains 的 Amper 团队密切合作。
我们希望这次合作能够改善包括 Java、Android 和 Kotlin Multiplatform 在内的多个生态系统的用户体验。
迁移 #
我们对面向开发者的软件定义感到兴奋,并坚信这将使使用 Gradle 的软件开发者和构建工程师都更加满意。同时,我们也意识到目前有数十亿行代码与这种方法不兼容。
我们的目标之一是让团队在新的软件定义可用后能够轻松地对其进行增量迁移。我们目前正在研究使用一种受限的 DSL 语法,该语法将与现有的声明式 Kotlin DSL 脚本兼容。受限 DSL 将成为 Groovy 和 Kotlin DSL 之外的另一个选项。现有的 DSL 将继续得到全面支持,我们正在探索方法,允许将现有构建文件增量迁移到受限 DSL。我们还在研究可以协助迁移的工具。
反馈 #
我们很乐意了解您对我们面向开发者的软件定义的愿景和计划的看法。如果您有任何问题或反馈,请随时在我们的 论坛 或 Community Slack 的 #declarative-gradle
频道中联系我们。
了解更多 #
- Declarative Gradle 仓库,包含示例和文档
- 项目看板,包含正在进行的计划
- Gradle Build Tool Newsletter,包含声明式 Gradle 的定期更新
- Gradle Community Slack,
#declarative-gradle
频道 - YouTube 播放列表,包含声明式 Gradle 的精选视频