Gradle 7.0 依赖统一管理的全新方式,了解一下 | 开发者说·DTalk
The following article is from 程序员江同学 Author 程序员江同学
本文原作者: 程序员江同学,原文发布于: 程序员江同学
前言
项目依赖统一管理,在单独文件中配置 不同 Module 中的依赖版本号统一
不同项目中的依赖版本号统一
使用循环优化 Gradle 依赖管理
使用 buildSrc 管理 Gradle 依赖
使用 includeBuild 统一配置依赖版本
上面的方案支持在不同 Module 间统一版本号,同时如果需要在项目间共享,也可以做成 Gradle 插件发布到远端,已经基本可以满足我们的需求。
对所有 module 可见,可统一管理所有 module 的依赖
支持声明依赖 bundles,即总是一起使用的依赖可以组合在一起
支持版本号与依赖名分离,可以在多个依赖间共享版本号
支持在单独的 libs.versions.toml 文件中配置依赖
支持在项目间共享依赖
使用 Version Catalog
enableFeaturePreview('VERSION_CATALOGS')
dependencies {
implementation(libs.retrofit)
implementation(libs.groovy.core)
}
在这种情况下,libs 是一个目录,retrofit 表示该目录中可用的依赖项。与直接在构建脚本中声明依赖项相比,Version Catalog 具有许多优点:
对于每个 catalog,Gradle 都会生成类型安全的访问器,以便您在 IDE 中可以自动补全。(注: 目前在 build.gradle 中还不能自动补全,可能是指 kts 或者开发中?)
声明在 catalog 中的依赖对所有 module 可见,当修改版本号时,可以统一管理统一修改
catalog 支持声明一个依赖 bundles,即一些总是一起使用的依赖的组合
catalog 支持版本号与依赖名分离,可以在多个依赖间共享版本号
声明 Version Catalog
dependencyResolutionManagement {
versionCatalogs {
libs {
alias('retrofit').to('com.squareup.retrofit2:retrofit:2.9.0')
alias('groovy-core').to('org.codehaus.groovy:groovy:3.0.5')
alias('groovy-json').to('org.codehaus.groovy:groovy-json:3.0.5')
alias('groovy-nio').to('org.codehaus.groovy:groovy-nio:3.0.5')
alias('commons-lang3').to('org.apache.commons', 'commons-lang3').version {
strictly '[3.8, 4.0['
prefer '3.9'
}
}
}
}
别名必须由一系列以破折号 (-,推荐)、下划线 (_) 或点 (.) 分隔的标识符组成。
标识符本身必须由 ascii 字符组成,最好是小写,最后是数字。
值得注意的是,groovy-core 会被映射成 libs.groovy.core。
如果您想避免映射可以使用大小写来区分,比如 groovyCore 会被处理成 libs.groovyCore。
具有相同版本号的依赖
dependencyResolutionManagement {
versionCatalogs {
libs {
version('groovy', '3.0.5')
version('compilesdk', '30')
version('targetsdk', '30')
alias('groovy-core').to('org.codehaus.groovy', 'groovy').versionRef('groovy')
alias('groovy-json').to('org.codehaus.groovy', 'groovy-json').versionRef('groovy')
alias('groovy-nio').to('org.codehaus.groovy', 'groovy-nio').versionRef('groovy')
alias('commons-lang3').to('org.apache.commons', 'commons-lang3').version {
strictly '[3.8, 4.0['
prefer '3.9'
}
}
}
}
android {
compileSdk libs.versions.compilesdk.get().toInteger()
defaultConfig {
applicationId "com.zj.gradlecatalog"
minSdk 21
targetSdk libs.versions.targetsdk.get().toInteger()
}
}
依赖 bundles
dependencies {
implementation libs.bundles.groovy
}
dependencyResolutionManagement {
versionCatalogs {
libs {
version('groovy', '3.0.5')
version('checkstyle', '8.37')
alias('groovy-core').to('org.codehaus.groovy', 'groovy').versionRef('groovy')
alias('groovy-json').to('org.codehaus.groovy', 'groovy-json').versionRef('groovy')
alias('groovy-nio').to('org.codehaus.groovy', 'groovy-nio').versionRef('groovy')
alias('commons-lang3').to('org.apache.commons', 'commons-lang3').version {
strictly '[3.8, 4.0['
prefer '3.9'
}
bundle('groovy', ['groovy-core', 'groovy-json', 'groovy-nio'])
}
}
}
插件版本
dependencyResolutionManagement {
versionCatalogs {
libs {
alias('jmh').toPluginId('me.champeau.jmh').version('0.6.5')
}
}
}
plugins {
id 'java-library'
id 'checkstyle'
// 使用声明的插件
alias(libs.plugins.jmh)
}
在单独文件中配置 Catalog
除了在 settings.gradle 中声明 Catalog 外,也可以通过一个单独的文件来配置 Catalog。
如果在根构建的 gradle 目录中找到了 libs.versions.toml 文件,则将使用该文件的内容自动声明一个 Catalog。
[versions] 部分用于声明可以被依赖项引用的版本
[libraries] 部分用于声明 Library 的别名
[bundles] 部分用于声明依赖包
[plugins] 部分用于声明插件
如下所示:
[versions]
groovy = "3.0.5"
checkstyle = "8.37"
compilesdk = "30"
targetsdk = "30"
[libraries]
retrofit = "com.squareup.retrofit2:retrofit:2.9.0"
groovy-core = { module = "org.codehaus.groovy:groovy", version.ref = "groovy" }
groovy-json = { module = "org.codehaus.groovy:groovy-json", version.ref = "groovy" }
groovy-nio = { module = "org.codehaus.groovy:groovy-nio", version.ref = "groovy" }
commons-lang3 = { group = "org.apache.commons", name = "commons-lang3", version = { strictly = "[3.8, 4.0[", prefer="3.9" } }
[bundles]
groovy = ["groovy-core", "groovy-json", "groovy-nio"]
[plugins]
jmh = { id = "me.champeau.jmh", version = "0.6.5" }
如上所示,依赖可以定义成一个字符串,也可以将 module 与 version 分离开来。
其中 versions 可以定义成一个字符串,也可以定义成一个范围,详情可参见 rich-version:
[versions]
my-lib = { strictly = "[1.0, 2.0[", prefer = "1.2" }
在项目间共享 Catalog
Catalog 不仅可以在项目内统一管理依赖,同样可以实现在项目间共享。
例如我们需要在团队内制定一个依赖规范,不同组的不同项目需要共享这些依赖,这是个很常见的需求。
通过文件共享
Catalog 支持通过从 Toml 文件引入依赖,这就让我们可以通过指定文件路径来实现共享依赖。
如下所示,我们在 settins.gradle 中配置如下:
dependencyResolutionManagement {
versionCatalogs {
libs {
from(files("../gradle/libs.versions.toml"))
}
}
}
此技术可用于声明来自不同文件的多个目录:
dependencyResolutionManagement {
versionCatalogs {
// 声明一个'testLibs'目录, 从'test-libs.versions.toml'文件中
testLibs {
from(files('gradle/test-libs.versions.toml'))
}
}
}
发布插件实现共享
虽然从本地文件导入 Catalog 很方便,但它并没有解决在组织或外部消费者中共享 Catalog 的问题。
首先引入两个插件
plugins {
id 'version-catalog'
id 'maven-publish'
}
定义目录
上面引入插件后,即可使用 catalog 扩展定义目录。
catalog {
// 定义目录
versionCatalog {
from files('../libs.versions.toml')
}
}
然后可以通过 maven-publish 插件来发布目录。
publishing {
publications {
maven(MavenPublication) {
groupId = 'com.zj.catalog'
artifactId = 'catalog'
version = '1.0.0'
from components.versionCatalog
}
}
}
我们定义好 groupId,artifactId,version,from 就可以发布了。
我们这里发布到 mavenLocal,您也可以根据需要配置发布到自己的 maven
以上发布的所有代码可见: Catalog 发布相关代码
使用目录
因为我们已经发布到了 mavenLocal,在仓库中引入 mavenLocal 就可以使用插件了。
# settings.gradle
dependencyResolutionManagement {
//...
repositories {
mavenLocal()
//...
}
}
enableFeaturePreview('VERSION_CATALOGS')
dependencyResolutionManagement {
versionCatalogs {
libs {
from("com.zj.catalog:catalog:1.0.0")
// 我们也可以重写覆盖catalog中的groovy版本
version("groovy", "3.0.6")
}
}
}
如上就成功引入了插件,可以使用 catalog 中的依赖了。
这样就完成了依赖的项目间共享,以上使用的所有代码可见: Catalog 使用相关代码。
总结
项目间共享依赖是比较常见的需求,虽然我们也可以通过自定义插件实现,但还是不够方便。
Gradle 官方终于推出了 Catalog,让我们可以方便地实现依赖的共享,Catalog 主要具有以下特性:
对所有 module 可见,可统一管理所有 module 的依赖 支持声明依赖 bundles,即总是一起使用的依赖可以组合在一起
支持版本号与依赖名分离,可以在多个依赖间共享版本号
支持在单独的 libs.versions.toml 文件中配置依赖
支持在项目间共享依赖
长按右侧二维码
查看更多开发者精彩分享
"开发者说·DTalk" 面向