声明式 Gradle EAP2 - 2024 年 11 月更新
目录
简介 #
一年前,我们宣布了一个名为声明式 Gradle 的新实验性项目。该博文介绍了我们对 Gradle 声明式模型的愿景。它还介绍了我们的开发者中心软件定义概念。此后,我们在 2024 年 7 月发布了第一个早期访问预览版,并伴随了《声明式 Gradle 首次预览》博文。第一个 EAP 引入了一个名为*软件类型 (Software Types)* 的配置模型,一种新的*声明式配置语言 (Declarative Configuration Language, DCL)*,并展示了工具改进和更好的 IDE 支持的潜力。
现在可以更轻松地试用声明式 Gradle。第一个 EAP 基于独立的声明式 Gradle 原型插件。这些原型插件实现了包装现有插件(如 Android Gradle Plugin (AGP) 和 Kotlin Multiplatform (KMP))的软件类型,使其可从 DCL 使用。此后,我们与 Android Studio 团队合作,将他们现有的 Android Gradle Plugin 模型作为软件类型直接暴露在 DCL 中,以在具有复杂 DSL 的实际插件上演示声明式 Gradle。我们还与其他 IDE 进行了实验,并增强了 gradle init
以生成使用 DCL 的入门项目。随着这些工作的完成,我们很高兴地宣布第二个 EAP 版本!
本博文将介绍项目的进展更新,并概述您如何提供反馈以及影响我们的下一步行动。
声明式 Gradle 仍处于实验阶段,**尚未准备好用于生产环境**。我们提供第二个早期访问预览版是为了收集社区的更多反馈。我们邀请您试用示例和演示应用程序,并分享您的反馈。
官方 Android 软件类型预览 #
我们与 Android Studio 团队合作,使 Android Gradle Plugin (AGP) 能够直接将其现有模型(即 Project
扩展)作为软件类型暴露出来,以便在 DCL 中使用。新的 AGP 生态系统插件现在公开了 androidApp
和 androidLibrary
软件类型,您可以使用它们快速定义项目
build.gradle.dcl
androidApp {
compileSdk = 35
defaultConfig {
minSdk = 29
targetSdk = 35
testInstrumentationRunner = "androidx.test.runner.AndroidJUnitRunner"
}
}
这意味着现有的 AGP 模型可以利用所有 DCL 功能。构建定义是声明式的,通用配置可以通过声明式设置文件表达,IDE 支持按预期工作,并且工具可以与构建定义配合使用。
以下是示例构建如何在 DCL 设置文件中声明通用配置
settings.gradle.dcl
// [SNIP] pluginManagement { repositories }
plugins {
id("com.android.ecosystem").version("8.9.0-dev")
}
defaults {
androidLibrary {
compileSdk = 35
}
androidApp {
compileSdk = 35
defaultConfig {
minSdk = 29
targetSdk = 35
testInstrumentationRunner = "androidx.test.runner.AndroidJUnitRunner"
}
}
}
以及子项目如何在它们的 DCL 文件中声明特定配置
lib/build.gradle.dcl
androidLibrary {
namespace = "com.example.lib"
}
app/build.gradle.dcl
androidApp {
namespace = "com.example.app"
}
请注意,**这在常规 AGP 版本中不可用**。要使用此功能,您需要使用特殊的 AGP nightly 版本。另外,请注意 AGP 模型的一些部分目前尚无法用于 DCL 配置。请参阅下方说明如何自行试用。
新的 DCL 语言功能 #
我们通过两个新功能改进了 DCL 语言:**枚举属性 (enum properties)** 和**容器 (containers)**。
现在,软件类型可以公开具有枚举值的属性,并在 DCL 文件中简洁地进行赋值。此新功能基于 Kotlin 的KEEP-379 *使用预期类型改进解析*。枚举值到属性的赋值使用非限定引用。显式不支持限定引用。下面是它的样子
lib/build.gradle.dcl
androidLibrary {
compileOptions {
// Unqualified reference to JavaVersion.VERSION_17 in property assignment
sourceCompatibility = VERSION_17
}
}
同样,现在软件类型可以公开 NamedDomainObjectContainer<T>
嵌套对象,并在 DCL 文件中配置其元素。在 DCL 中配置容器元素的唯一方法是使用具有“*注册或配置*”语义的函数。下面是它在 AGP 模型中关于 Android 构建类型的外观
lib/build.gradle.dcl
androidLibrary {
buildTypes {
buildType("debug") {
isMinifyEnabled = false
}
buildType("release") {
isMinifyEnabled = true
}
}
}
更新的 IDE 支持
Android Studio 团队也将这两项功能的支持集成到了 Android Studio 中。语法高亮和代码补全按预期工作,如下面的屏幕录像所示
在上面的视频中,您可以看到,由于 DCL 的严格性,IDE 助手没有任何干扰。代码补全仅建议当前作用域中可用的属性和嵌套块。
JetBrains 的 IntelliJ IDEA 团队也将相同的 DCL 支持集成到了他们的 IDE 中。
通过 Kotlin DSL 配置软件类型 #
软件类型是开发者优先的声明式构建定义的核心,它允许作者简化诸如 Java 库或 Android 应用程序等通用可交付成果的配置。此功能受到了社区的积极反馈,作为一项实验,我们希望将其提供给通过 Kotlin DSL 定义的构建脚本。
在此第二个 EAP 中,我们实现了通过 Gradle 的 Kotlin DSL 配置软件类型的可能性。鉴于 DCL 语言是 Kotlin 语言的严格子集,因此声明软件类型配置的 Kotlin DSL 文件看起来与声明相同配置的 DCL 文件非常相似,这并不令人意外。
build.gradle.kts
javaApplication {
mainClass = "com.example.Main"
dependencies {
implementation("com.google.guava:guava:31.0-jre")
}
}
build.gradle.dcl
javaApplication {
mainClass = "com.example.Main"
dependencies {
implementation("com.google.guava:guava:31.0-jre")
}
}
通过 Kotlin DSL,您仍然可以在软件类型声明周围添加一些命令式的自定义构建逻辑。如果 .gradle.kts
文件纯粹是声明式地配置软件类型,那么 Gradle 将使用 DCL 解释器来评估该文件。否则,将使用 Kotlin 编译器,并且编译后的脚本会照常执行。
要为 Kotlin DSL 脚本启用软件类型和 DCL 支持,您需要在 gradle.properties
文件中设置一个 Gradle 属性
gradle.properties
org.gradle.kotlin.dsl.dcl=true
添加此功能对于允许未来逐步迁移到软件类型和 DCL 至关重要。我们计划稍后将其添加到我们的 Groovy DSL 中。
示例 - 现在的 Android
利用这一新功能,我们重构了 NowInAndroid 示例应用程序构建的 fork,以在其所有项目中都使用软件类型。其中一些项目是完全声明式的,并使用 DCL 语言中的软件类型;其他项目在声明式部分之上仍需要一些自定义构建逻辑,则使用 Kotlin DSL 构建脚本中的软件类型。
下面是一个 Kotlin DSL 脚本示例,它以声明式方式配置 androidLibrary
软件类型,同时还以命令式方式定义和注册一个临时任务
core/datastore-proto/build.gradle.kts
androidLibrary {
namespace = "com.google.samples.apps.nowinandroid.core.datastore.proto"
protobuf {
enabled = true
option = "lite"
}
}
// Define and register a misc one-off task imperatively
abstract class PrintProtobufTasks : DefaultTask() {
@get:Input abstract val protoTasks: Property<String>
@TaskAction
fun printTasks() {
println("Protobuf tasks report:\n${protoTasks.get()}")
}
}
tasks.register("protobufTasks", PrintProtobufTasks::class) {
protoTasks = tasks.filter { task ->
task.name.lowercase().contains("proto")
}.joinToString("\n")
}
您可以在 NowInAndroid 仓库中更详细地查看 core/datastore-proto/build.gradle.kts 文件,了解如何配置 DCL 尚不支持的 Android Gradle 插件选项。
展望未来,我们将研究如何使迁移尽可能无缝,如何调整 IDE 支持以在过程中提供帮助,以及通过 Kotlin DSL 对软件类型的支持,我们如何保留直接在构建文件中快速原型化命令式构建逻辑的灵活性。
支持 VS Code 和 Eclipse IDE #
在 Android Studio 和 IntelliJ IDEA 中获得 DCL 支持固然很好,但我们希望声明式 Gradle 在所有现代 IDE 中都能获得一流的支持。因此,我们使用语言服务器协议 (Language Server Protocol, LSP)——一个其他 IDE 和开发工具可以使用的标准协议——为 DCL 构建了一个语言服务器。此外,我们还为Visual Studio Code (VS Code) 和Eclipse IDE 构建了集成。
VS Code 和 Eclipse 集成均支持语法高亮、语义错误和代码补全,其水平与 Android Studio 或 IntelliJ IDEA 相同,如上所示。VS Code 集成还支持我们的构建定义修改框架,我们在 7 月份使用演示客户端应用程序进行了演示。可用修改在 IDE 编辑器中显示为用户可以直接在 DCL 文件上执行的操作。
下面是 VS Code 中 DCL 语言支持的屏幕录像
下面是 Eclipse IDE 中 DCL 语言支持的屏幕录像
生成声明式构建 #
为了让您更轻松地试用声明式 Gradle,您现在可以通过 gradle init
来生成使用软件类型和 DCL 的自己的应用程序或库项目。
Gradle 已添加一个实验性系统属性,用于添加 `gradle init` 可以生成的新内容。与本文一起,我们发布了基于我们原型插件的 Java、Kotlin 和 Android 项目的生成器。
请继续阅读有关如何使用此功能的说明。
立即试用声明式 Gradle #
您今天就可以试用以上所有功能,方法是使用 gradle init
生成新的声明式 Gradle 构建,查看示例存储库,并安装特殊版本的 Android Studio 或IntelliJ IDEA,声明式 Gradle 的Eclipse IDE 实验性功能,或我们的声明式 Gradle 的Visual Studio Code 扩展。您将在 declarative.gradle.org 网站上找到执行所有这些操作的说明。
在您试用之后,如果您能提交您的反馈,我们将不胜感激。这只需要几分钟,而且是匿名的,除非您选择提供您的电子邮件地址。
下一步是什么? #
我们的目标是在 2025 年将软件类型和声明式配置语言 (DCL) 作为核心 Gradle 功能进行孵化。在此之前,我们计划在 2025 年初发布另一个 EAP,以解决早期采用者的反馈。现在是分享您的反馈的最佳时机!请参阅公开的声明式 Gradle 路线图,以了解更多关于目标里程碑的信息。
在接下来的几个月里,我们将致力于通过实现多个用例来验证软件类型概念和相关的 API。我们的重点是软件类型的可扩展性和可组合性,以添加新功能。Gradle 插件应该能够扩展现有的软件类型并相互协作。例如,一个 Jacoco Gradle 插件将增强基础 JVM 插件以添加代码覆盖能力和配置,而一个 Compose 插件将增强 Android 插件以添加 Jetpack Compose 能力和配置。
我们的目标是尽快使声明式 Gradle 在实际项目中可用,以获得高质量的反馈,同时保持实验性。目前,存在一些主要缺失的功能,这些功能阻止您在实际项目中使用声明式 Gradle,例如能够添加和配置测试。我们正在努力添加这些缺失的功能。同样,我们正在推进对现有 AGP 模型支持的改进,以确保使用声明式 Gradle 的项目能够完全正常运行。目标是在下一个 EAP 中能够使用声明式 Gradle 构建一个可以发布到 Google Play 商店的 Android 应用程序。这包括添加测试支持和扩展 DCL 语言功能。
了解更多 #
- 声明式 Gradle 网站
- 声明式 Gradle 简介和项目宣言
- 《声明式 Gradle 首次预览》 (EAP1 版本)