Contents
- 增加Gradle Wrapper
- 使用Gradle Wrapper
- 升级Gradle Wrapper
- 自定义Gradle Wrapper
- 验证Gradle Wrapper JAR的集成 ..
执行Gradle 构建推荐的方式是 通过Gradle Wrapper 的帮助(简称 Wrapper)
Wrapper 是一个脚本 - 它能够执行Gradle 版本声明的Gradle脚本,如果有必要它将在背后下载 ..
因此,开发者能够快速开始并运行一个Gradle项目(而无需手动配置安装程序 - 它将节约公司的时间和金钱) …
工作原理
下图展示了Wrapper的工作原理
简单的说,你能够获得以下的好处:
- 通过给定的Gradle 版本标准化一个项目,导致更加真实(可靠的)以及健壮的构建 …
为不同的用户提供新的Gradle 版本以及执行环境(例如,IDE 或者持续集成服务器) 只需要简单的改变Wrapper 的定义 …
如何让它工作
对于一个用户来说,通常有三种不同的工作流:
你能够配置一个新的Gradle 项目并且你想要为它增加 Wrapper
- 你想要运行一个已经提供了Wrapper的Gradle 项目
- 你想要升级Wrapper 到一个新的Gradle …
以下部分阐述了每一种使用情况
增加Gradle Wrapper
生成Wrapper 文件需要一个已经安装版本的Gradle 运行时(它已经存在你的机器上) …
如何安装一个Gradle 运行时Installation,幸运的是,生成初始化wrapper 文件只需要一次 ..
每一个普通的Gradle 构建都来自一个内置的任务叫做(wrapper).
你能够发现列举在”Build Setup taks”分组下的任务列表 - 当你浏览这些任务时 .
Running the Wrapper task
$ gradle wrapper > Task :wrapper BUILD SUCCESSFUL in 0s 1 actionable task: 1 executed
为了让Wrapper 文件在其他的开发者和执行环境中有效,你将需要将他们放入版本控制 … 所有的Wrapper 文件都包含在一个JAR,并且尺寸非常的小 … 将Wrapper 加入版本控制是建议的. 但是许多组织都不允许项目提交二进制文件到版本控制中.. 目前这没有替代方案 ..
生成的Wrapper 属性文件,gradle/wrapper/gradle-wrapper.properties,存储了关于Gradle 发布的一些信息 …
- Gradle 发布托管的服务器
- Gradle 发布的类型,默认 -bin 发布仅仅包含运行时,没有示例代码和文档 ..
执行此构建的Gradle 版本,默认来说wrapper 任务会抓取被用来生成Wrapper文件的相同Gradle 运行时版本 ..
distributionUrl=https\://services.gradle.org/distributions/gradle-7.4.2-bin.zip
生成配置选项
通过生成Wrapper文件的时候,我们可以指定以下选项,能够获得更多帮助 ..
—gradle-version
指定下载并执行wrapper的Gradle 版本 ..
- —distribution-type
被Wrapper 使用的Gradle 发布类型,可选的是bin / all .默认是bin ..
- —gradle-distribution-url
指向Gradle 发行版ZIP 文件的完整URL,如果使用了此选项会让 —gradle-version 和
—distribution-type 被废弃,因为此URL 已经包含了这些信息..
这个选项是极具价值的,如果你想要在公司内部网络中使用私有托管Gradle 发行 ..
- gradle-distribution-sha256-sum
SHA256 hash 加密文本被用来验证下载的Gradle 发行 …
让我们假设以下使用情况 - 来说明命令行选项 …
例如生成Wrapper,版本7.4.2 使用 -all 发行版去让你的IDE 启用代码补全并且能够导航Gradle 源代码 .. 这些需求仅仅只需要指定以下的命令行选项:
$ gradle wrapper --gradle-version 7.4.2 --distribution-type all
> Task :wrapper
BUILD SUCCESSFUL in 0s
1 actionable task: 1 executed
因此你能够在Wrapper properties文件中发现想要的信息 …
distributionUrl=https\://services.gradle.org/distributions/gradle-7.4.2-all.zip
现在让我们来看一看项目结构并说明期待的Wrapper 文件:
.
├── a-subproject
│ └── build.gradle
├── settings.gradle
├── gradle
│ └── wrapper
│ ├── gradle-wrapper.jar
│ └── gradle-wrapper.properties
├── gradlew
└── gradlew.bat
Gradle 项目通常提供了一个settings.gradle(.kts)文件 以及为每一个子项目提供了一个build.gradle(.kts)文件 ..
这个Wrapper 文件长期位于在gradle 目录中以及项目的根目录中 ..
以下列表解释了它们的目的:
- gradle-wrapper.jar
这个JAR文件包含了一些下载Gradle 发行的代码
- gradle-wrapper.properties
一个properties 文件负责配置Wrapper 运行时行为,例如 Gradle 版本..
注意更加泛化的配置,例如配置Wrapper 使用代理,需要将它们放置在不同的文件中 ..
- gradlew,gradlew.bat
是一个shell 脚本以及window 批处理脚本 用来使用Wrapper 执行构建 ..
你能够继续向前并学习 使用Wrapper 执行构建(而无需安装Gradle 运行时) …
如果项目是工作的,但是没有这些Wrapper 文件,你需要生成它们 …(但是这样的话你就需要安装Gradle 运行时) …
使用Gradle Wrapper
它推荐总是使用Wraper 执行构建,去确保一个更加稳定,可控制的、标准化的构建的执行 …
使用Wrapper 看起来和完全使用Gradle 运行构建完全相同 …
依赖于操作系统(你运行的是gradlew / gradlew.bat 替代 gradle 命令) …
以下的控制台输出说明了如何在window上使用一个基于Java的项目 …
$ gradlew.bat build
Downloading https://services.gradle.org/distributions/gradle-5.0-all.zip
.....................................................................................
Unzipping C:\Documents and Settings\Claudia\.gradle\wrapper\dists\gradle-5.0-all\ac27o8rbd0ic8ih41or9l32mv\gradle-5.0-all.zip to C:\Documents and Settings\Claudia\.gradle\wrapper\dists\gradle-5.0-al\ac27o8rbd0ic8ih41or9l32mv
Set executable permissions for: C:\Documents and Settings\Claudia\.gradle\wrapper\dists\gradle-5.0-all\ac27o8rbd0ic8ih41or9l32mv\gradle-5.0\bin\gradle
BUILD SUCCESSFUL in 12s
1 actionable task: 1 executed
在这种情况下,当前机器没有受支持的Gradle 发行版 .. 然后它会下载并存储到本地文件系统 ..
任何后续的执行将会重用存在的本地发行Gradle (只要Gradle properties中的发行URL 没有发生改变) …
Wrapper shell 脚本以及批处理文件位于单个或者多项目Gradle 构建的根目录中 … 你将需要引用正确的Wrapper 脚本路径,你如果你为了执行一个子项目的对应任务 …
升级Wrapper
项目通常会保持一段时间,但是升级它们的Gradle版本将会获得新特性以及性能提升的优化 …
升级Gradle 版本的方式就是手动更改distributionUrl属性(在gradle-wrapper.properties中进行更改) …
更好的方式并且更加推荐的方式就是运行wrapper 任务并提供目标Gradle version …
使用wrapper 任务确保任何优化会让Wrapper shell / batch 将特定的Gradle应用到项目中 .. 通常 你需要提交对Wrapper 文件的改变到版本控制 ..
注意一旦你运行wrapper 任务将仅仅更新gradle-wrapper.properties,但是gradle-wrapper.file 不会有任何变化 …
这通常很好,因为即使使用古老的包装文件也可以运行新版本的 Gradle ..
如果你想要这些wrapper文件完全更新, 你也需要再次运行包装器任务 …
首先使用wrapper 任务生成 wrapper, 可以通过命令行指定版本 .. 默认当前gradle 运行时版本 …
一旦你更新了wrapper,你能够检测更新过后的版本(./gradlew —version)
$ ./gradlew wrapper --gradle-version 7.4.2
BUILD SUCCESSFUL in 4s
1 actionable task: 1 executed
定制Gradle Wrapper
大多数Gradle 的用户对Wrapper的默认行为很满意,但是由于各种原因,它们可能需要深度的定义Wrapper …
幸运的是,内置的wrapper 任务暴露了大量的选项可能绑定你需要的运行时行为 …
大多数配置选项暴露在Wrapper 任务类型下 …
让我们假设你厌倦了每次在命令行上更新Gradle Wrapper时所指定 -all 发行类型 ..
那么你能够减少键盘敲击(通过重新配置 wrapper 任务即可) …
tasks.named('wrapper') {
distributionType = Wrapper.DistributionType.ALL
}
使用此配置并运行 ./gradlew wrapper —gradle-version 7.4.2 足够在Wrapper 属性文件中产生一个distributionUrl ,它将请求 -all 发布版Gradle ..
distributionUrl=https\://services.gradle.org/distributions/gradle-7.4.2-all.zip
检查API 文档了解更多可用的配置选项 … 你也能够各种示例(在Gradle 发行中配置Wrapper的示例) …
认证Gradle 发行版下载
Wrapper 能够使用HTTP Basic 认证下载需要验证的Gradle 发布版 ..
例如私有Gradle 发行版 …
通过指定username / password ,依赖于你的使用情况,你可以指定为系统属性或者直接嵌入在distributionUrl ..
在系统属性中的凭证将比内嵌在distributionUrl的凭证具有更高的优先级 …
安全警告 Http Basic 认证应该仅仅能够在HTTPS下使用,而不是简单的HTTP,通过Basic 认证,用户能够在纯文本中发送用户凭证
使用环境变量可以在用户家目录中的.gradle/gradle.properties中配置,或者其他方式…
了解Gradle Configuration Properties .
使用系统属性指定HTTP Basic 认证凭证
systemProp.gradle.wrapperUser=username
systemProp.gradle.wrapperPassword=password
内嵌在gradle/wrapper/gradle-wrapper.properties中的distributionUrl中的凭证依旧能够工作 …
请注意这些文件将提交到版本控制系统中,这种方式需要控制它的使用环境 ..
在distributionUrl中指定HTTP Basic 认证凭证
distributionUrl=https://username:password@somehost/path/to/gradle-distribution.zip
并且它能够结合代理(需要认证/或否)使用,查看通过代理访问Web 去了解怎样配置Wrapper 使用代理 …
认证下载的Gradle 发行版
通过SHA-256 hash 加密进行比较 …
这能够增加安全性,阻止中间人攻击 …(减少篡改)
为了启用这个特性,下载与Gradle发行联系的.sha256文件进行验证 ..
下载SHA-256 文件
通过稳定发行版 / 发行候选版 / 或者nightly releases ..
这个文件的格式是一个单行文本(是对应zip文件的SHA-256 hash 值) ..
你能够参考 Gradle 发行 checksums 的列表
配置SHA-256 checksum 校验
增加下载的hash sum 到gradle-wrapper.properties 通过使用distributionSha256Sum 属性或者使用 —gradle-distribution-sha256-sum 进行指定 …
distributionSha256Sum=371cb9fbebbe9880d147f59bab36d61eee122854ef8c9ee1ecf12b82368bcf10
如果checksum 没有匹配在服务器上发现的发行版的SHA-256 checksum,那么将会导致一个失败,Checksum 验证仅仅在配置的Wrapper 发行没有下载时执行 ..
验证 Gradle Wrapper JAR 的完整性
Wrapper JAR 是一个二进制文件 - 执行在开发者或者构建服务器的电脑上 ..
因此你能够确保它们在执行之前是值得信任的 ..
因此Wrapper JAR 通常会放入项目版本控制系统中 …
这可能会有一些危害,例如不怀好意的攻击者替换了原始的JAR …. 等等问题 …
例如通过提交了拉取请求(而隐式的更新了Gradle 的版本) …
为了验证Wrapper JAR …
Gradle 创建了Github Action自动检测Wrapper JAR (通过在拉取请求中针对已知的checksums 进行校验) ..
Gradle 同样会发布Checksum(所有发行版的Checksum) …(除了3.3 - 4.0.2,它们没有生成可用的JAR) …
因此你可以手动的校验Wrapper JAR的完整性 …
在Github上校验Gradle Wrapper JAR
这个Github Action独立发行于Gradle ..
因此检测它的文档并应用到你的项目中 ..
手动验证
手动验证命令 - linux
$ cd gradle/wrapper
$ curl --location --output gradle-wrapper.jar.sha256 \
https://services.gradle.org/distributions/gradle-7.4.2-wrapper.jar.sha256
$ echo " gradle-wrapper.jar" >> gradle-wrapper.jar.sha256
$ sha256sum --check gradle-wrapper.jar.sha256
gradle-wrapper.jar: OK
手动验证Wrapper JAR - macOS
$ cd gradle/wrapper
$ curl --location --output gradle-wrapper.jar.sha256 \
https://services.gradle.org/distributions/gradle-7.4.2-wrapper.jar.sha256
$ echo " gradle-wrapper.jar" >> gradle-wrapper.jar.sha256
$ shasum --check gradle-wrapper.jar.sha256
gradle-wrapper.jar: OK
手动验证Wrapper JAR 通过 (PowerShell) - Windows
> $expected = Invoke-RestMethod -Uri https://services.gradle.org/distributions/gradle-7.4.2-wrapper.jar.sha256
> $actual = (Get-FileHash gradle\wrapper\gradle-wrapper.jar -Algorithm SHA256).Hash.ToLower()
> @{$true = 'OK: Checksum match'; $false = "ERROR: Checksum mismatch!`nExpected: $expected`nActual: $actual"}[$actual -eq $expected]
OK: Checksum match
诊断checksum 不匹配
如果checksum 不匹配你期待的,那么可能升级后的wrapper 任务可能不能执行(不同使用指定的升级后的Gradle 发布执行) …
因此你需要首先检查是否实际的checksum 匹配不同Gradle 版本中的其中一个 ..
这里有一些命令能够运行在主流的操作系统上为Wrapper jar生成实际的checksum ..
在linux 上生成Wrapper JAR的check sum
sha256sum gradle/wrapper/gradle-wrapper.jar
d81e0f23ade952b35e55333dd5f1821585e887c6d24305aeea2fbc8dad564b95 gradle/wrapper/gradle-wrapper.jar
在macOS 上生成Wrapper JAR的 check sum
shasum --algorithm=256 gradle/wrapper/gradle-wrapper.jar
d81e0f23ade952b35e55333dd5f1821585e887c6d24305aeea2fbc8dad564b95 gradle/wrapper/gradle-wrapper.jar
在Windows上使用PowerShell 生成Wrapper JAR的check sum
(Get-FileHash gradle\wrapper\gradle-wrapper.jar -Algorithm SHA256).Hash.ToLower()
d81e0f23ade952b35e55333dd5f1821585e887c6d24305aeea2fbc8dad564b95
一旦你生成了这些实际的checksum,你可以检查发行的checksum是否和你的有所匹配 来验证Wrapper JAR的完整性 …
如果生成Wrapper Jar的Gradle 版本不匹配gradle/wrapper/gradle-wrapper.properties,那么它将安全的升级Wrapper JAR …
如果checksum 没有在发布checksum的网页上发现,那么这个Wrapper JAR可能来自里程碑/ 发行候选/ 每天发布 / 或者由Gradle3.3 - 4.0.2生成的Wrapper JAR …
你应该尝试发现它是如何被生成的(否则不应该信任它) …
如果你认为Wrapper JAR 被损坏 … 请让Gradle 团队知道 …
总结
Wrapper 是用来统一Gradle 项目运行时的,为所有的项目的运行环境提供相同的运行时处理 …
通过它不仅能够加快构建,并且还能够自动升级,便于管理 …
相信它比普通的gradle 确实更加强大 …
并且一般来说我们自己的Gradle Wrapper 脚本没必要进行checksum 认证 …