赞
踩
前言
随着项目的不断发展,项目中的依赖也越来越多,有时可能会有几百个,这个时候对项目依赖做一个统一的管理很有必要,我们一般会有以下需求:
项目依赖统一管理,在单独文件中配置
不同Module
中的依赖版本号统一
不同项目中的依赖版本号统一
针对这些需求,目前其实已经有了一些方案:
使用循环优化Gradle依赖管理[1]
使用buildSrc管理Gradle依赖[2]
使用includeBuild统一配置依赖版本[3]
上面的方案支持在不同Module
间统一版本号,同时如果需要在项目间共享,也可以做成Gradle
插件发布到远端,已经基本可以满足我们的需求
不过Gradle7.0
推出了一个新的特性,使用Catalog
统一依赖版本,它支持以下特性:
对所有module
可见,可统一管理所有module
的依赖
支持声明依赖bundles
,即总是一起使用的依赖可以组合在一起
支持版本号与依赖名分离,可以在多个依赖间共享版本号
支持在单独的libs.versions.toml
文件中配置依赖
支持在项目间共享依赖
Version Catalog
注意,Catalog
仍然是一个孵化中的特性,如需使用,需要在settings.gradle
中添加以下内容:
enableFeaturePreview('VERSION_CATALOGS')
从命名上也可以看出,Version Catalog
其实就是一个版本的目录,我们可以从目录中选出我们需要的依赖使用
我们可以通过如下方式使用Catalog
中声明的依赖
- 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
Version Catalog
可以在settings.gradle(.kts)
文件中声明。
- 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
在上面的示例中,我们可以看到三个groovy
依赖具有相同的版本号,我们可以把它们统一起来
- 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'
- }
- }
- }
- }
除了在依赖中,我们同样可以在build.gradle
中获取版本,比如可以用来指定compileSdk
等
- android {
- compileSdk libs.versions.compilesdk.get().toInteger()
-
-
- defaultConfig {
- applicationId "com.zj.gradlecatalog"
- minSdk 21
- targetSdk libs.versions.targetsdk.get().toInteger()
- }
- }
如上,可以使用catalog
统一compileSdk
,targetSdk
,minSdk
的版本号
bundles
因为在不同的项目中经常系统地一起使用某些依赖项,所以Catalog
提供了bundle
(依赖包)的概念。依赖包基本上是几个依赖项打包的别名。
例如,你可以这样使用一个依赖包,而不是像上面那样声明 3 个单独的依赖项:
- dependencies {
- implementation libs.bundles.groovy
- }
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'])
- }
- }
- }
如上所示:添加groovy
依赖包等同于添加依赖包下的所有依赖项
除了Library
之外,Catalog
还支持声明插件版本。
因为library
由它们的group
、artifact
和version
表示,但Gradle
插件仅由它们的id
和version
标识。
因此,插件需要单独声明:
- dependencyResolutionManagement {
- versionCatalogs {
- libs {
- alias('jmh').toPluginId('me.champeau.jmh').version('0.6.5')
- }
- }
- }
然后可以在plugins
块下面使用
- plugins {
- id 'java-library'
- id 'checkstyle'
- // 使用声明的插件
- alias(libs.plugins.jmh)
- }
Catalog
除了在settings.gradle
中声明Catalog
外,也可以通过一个单独的文件来配置Catalog
如果在根构建的gradle
目录中找到了libs.versions.toml
文件,则将使用该文件的内容自动声明一个Catalog
TOML
文件主要由4个部分组成:
[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[4]
- [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
的问题。
我们还可能通过Catalog
插件来发布目录,这样用户直接引入这个插件即可
Gradle
提供了一个Catalog
插件,它提供了声明然后发布Catalog
的能力。
- plugins {
- id 'version-catalog'
- id 'maven-publish'
- }
然后,此插件将公开可用于声明目录的catalog
扩展
上面引入插件后,即可使用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发布相关代码[5]
因为我们已经发布到了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使用相关代码[6]
项目间共享依赖是比较常见的需求,虽然我们也可以通过自定义插件实现,但还是不够方便
Gradle
官方终于推出了Catalog
,让我们可以方便地实现依赖的共享,Catalog
主要具有以下特性:
对所有module
可见,可统一管理所有module
的依赖
支持声明依赖bundles
,即总是一起使用的依赖可以组合在一起
支持版本号与依赖名分离,可以在多个依赖间共享版本号
支持在单独的libs.versions.toml
文件中配置依赖
支持在项目间共享依赖
Catalog发布相关代码[7]
Catalog使用相关代码[8]
Sharing dependency versions between projects[9]
[1]
https://juejin.cn/post/6947675376835362846#heading-2
[2]https://juejin.cn/post/6844903615346245646
[3]https://juejin.cn/post/6844904169833234439
[4]https://docs.gradle.org/current/userguide/rich_versions.html#rich-version-constraints
[5]https://github.com/shenzhen2017/GradleCatalog
[6]https://github.com/shenzhen2017/GradleCatalog/tree/feature/useCatalog
[7]https://github.com/shenzhen2017/GradleCatalog
[8]https://github.com/shenzhen2017/GradleCatalog/tree/feature/useCatalog
[9]https://docs.gradle.org/current/userguide/platforms.html
转自:掘金 RicardoMJiang
https://juejin.cn/post/6997396071055900680
PS:如果觉得我的分享不错,欢迎大家随手点赞、转发、在看。
PS:欢迎在留言区留下你的观点,一起讨论提高。如果今天的文章让你有新的启发,欢迎转发分享给更多人。
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。