声明式 Gradle
目录
简介
注意: 声明式 Gradle 是一个正在积极开发中的实验性项目,在实施过程中会频繁发生更改。要了解有关当前状态的更多信息,请访问 GitHub 上的 声明式 Gradle 存储库。 在这里,您可以访问当前的文档和原型。订阅 Gradle 构建工具新闻邮件 以接收有关该项目的每月更新 - 上次更新于 2024 年 5 月 11 日
我们对 Gradle 构建工具的愿景之一是提供一种优雅且可扩展的声明式构建语言,使开发人员能够以清晰易懂的方式描述任何类型的软件。
Gradle 的构建语言在最基本的方面已经具有可扩展性,这带来了高度的灵活性。这是 Gradle 成为众多公司(包括大型企业)的首选构建系统,以及 Android 和 Kotlin Multiplatform 的默认构建系统的主要原因之一。
然而,我们当前的构建语言并不总是完全声明式、清晰和易于理解。虽然长期以来最佳实践一直是构建脚本应该是声明式的,并且构建逻辑应该保存在插件中,但这并不是许多项目的现实情况。我们已经看到一些项目在实际应用中混合了声明式和命令式代码,导致构建脚本冗长而复杂。构建脚本中使用的 Gradle 特定概念并不总是为软件开发人员所熟悉。这可能会使 Gradle 对于不熟悉 Gradle 的开发人员来说不太容易上手。与此同时,这也使得 IDE 难以为编辑构建脚本提供可靠的支持。
这篇博文解释了 Gradle 团队对我们称之为开发者优先的软件定义或简称声明式 Gradle 的看法。 这篇文章概述了我们使“优雅且声明式的构建语言”成为我们愿景一部分的计划。
软件开发者和构建工程师 #
首先,让我们澄清 Gradle 用户的两个最大群体之间的区别:软件开发者和构建工程师。
大多数 Gradle 构建工具用户是软件开发者。他们的工作是通过交付功能、修复错误等来改进他们的软件产品。软件开发者不会以运行构建为目标开始他们的一天。虽然他们依赖构建系统来完成他们的任务,但这并不是他们的主要关注点。
第二组用户是构建工程师。与软件开发者不同,他们的责任是维护构建本身。这个群体历来很欣赏 Gradle 的灵活性,可以满足即使是最复杂的构建自动化需求。
在实践中,这两个角色之间经常存在重叠。在较小的团队中,一些熟悉 Gradle 的工程师倾向于负责构建。在较大的团队中,通常有专门的构建工程师。
软件定义 vs 构建逻辑 #
接下来,让我们澄清软件定义和构建逻辑之间的区别。
软件定义 是什么需要构建。它定义了正在生成的软件的结构,并包括诸如以下信息:
- 正在生成什么类型的软件?
- 软件是用哪种语言实现的?
- 软件的目标平台是什么?
- 软件的依赖项是什么?
- 应该使用哪些工具链来编译/链接/检测/捆绑/文档化软件?
- 在软件发布之前需要完成哪些质量检查?
构建逻辑 是如何构建软件。它是为 Gradle 添加新功能、集成不同工具并为软件定义提供约定的代码。
软件定义旨在由软件开发者阅读和修改。构建逻辑旨在由构建工程师阅读和修改。
在 Gradle 中,软件定义存在于 Groovy DSL 和 Kotlin DSL 构建脚本和设置中。建议将构建逻辑保存在插件中。然而,用户可以灵活地将构建逻辑与软件定义一起包含在构建脚本中。这导致了软件开发者和构建工程师的关注点和需求之间的界限模糊。
什么是开发者优先的软件定义 #
我们的战略目标是使软件定义对于开发者来说更清晰、更简单。
我们看到了实现这一目标的两个关键步骤:
使用受限 DSL 分离软件定义和构建逻辑 #
如上所述,不建议混合软件定义和构建逻辑。
我们计划提供一种受限 DSL,将软件定义和构建逻辑分开,以便构建语言完全是声明式的。这将有效地强制执行现有的最佳实践。
受限 DSL 将只允许有限的构造集,例如嵌套块、赋值和选定的方法调用。通用控制流和对任意方法的调用将被禁止。您可以使用任何 JVM 语言(例如 Java、Kotlin 或 Groovy)编写构建逻辑,但该逻辑将驻留在插件中(本地插件或已发布的插件)。
这将更好地分离软件开发者和构建工程师的关注点,以及更简单的构建视图,而不会限制工具的灵活性。
使软件定义与软件领域相匹配 #
虽然受限 DSL 是朝着正确方向迈出的一步,但这只是使软件定义真正以开发者为中心的部分解决方案。
另一个问题是,当前的软件定义并非在所有情况下都使用反映底层软件领域概念的概念。要使用 Gradle,开发人员通常需要理解 Gradle 特定的构建块,例如依赖项配置和任务。这些概念是构建逻辑特有的,因此只应与构建工程师相关。在大多数情况下,软件开发者应该能够通过使用他们已经熟悉的概念(例如库、应用程序、版本和测试套件)来配置他们需要的一切。
Android Gradle 插件是基于 Gradle 的更具声明性的软件定义 DSL 的一个很好的例子。虽然更广泛的 JVM 生态系统尚未达到我们期望的状态,但最近的功能(例如 测试套件 和 工具链)是朝着这个方向迈出的重要一步。
我们的目标之一是提供更广泛的此类高级构造,这些构造可以在生态系统之间共享。这将使现有的生态系统更加一致,例如 Java、Android 和 KMP。这也将使在未来更容易实现对新生态系统(例如 iOS 或 .NET)的支持。
IDE 体验 #
开发者优先的软件定义的关键方面是,它使提供出色的 IDE 体验变得更容易。
软件定义传统上是手工编辑的。使用 Groovy DSL,由于 Groovy 语言的动态特性,只能提供基本的 IDE 辅助功能。使用 Kotlin DSL,在受支持的 IDE(例如 IntelliJ IDEA 和 Android Studio)中可以获得出色的支持。这包括自动完成、智能内容辅助、快速访问文档、导航到源代码以及上下文相关的重构。使用 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 的软件开发者和构建工程师都更快乐。与此同时,我们也意识到目前有数十亿行代码与这种方法不兼容。
我们的目标之一是让团队在新软件定义可用后能够轻松地逐步迁移到新软件定义。我们目前正在研究使用与现有声明式 Kotlin DSL 脚本兼容的受限 DSL 语法。受限 DSL 将是 Groovy 和 Kotlin DSL 之外的附加选项。现有的 DSL 将继续得到完全支持,并且我们正在探索允许将构建文件逐步迁移到受限 DSL 的方法。我们还在研究可以协助过渡的工具。
反馈 #
我们很想知道您对我们关于开发者优先的软件定义的愿景和计划有何看法。如果您有任何问题或反馈,请随时通过我们的论坛或社区 Slack 中的 #declarative-gradle
频道与我们联系。
了解更多 #
- 声明式 Gradle 存储库,包含示例和文档
- 项目看板,包含正在进行的计划
- Gradle 构建工具新闻邮件,定期更新声明式 Gradle 的信息
- Gradle 社区 Slack,
#declarative-gradle
频道 - YouTube 播放列表,包含声明式 Gradle 的精选视频