[Gradle7.0] Una nueva forma de confiar en la gestión unificada, infórmese al respecto~

prefacio

Con el desarrollo continuo del proyecto, cada vez hay más dependencias en el proyecto, y en ocasiones puede haber cientos de ellas. En este momento, es necesario tener una gestión unificada de las dependencias del proyecto. Generalmente tenemos los siguientes requisitos:

  1. Las dependencias del proyecto se administran de manera uniforme y se configuran en un archivo separado
  2. ModuleNúmeros de versión unificados de dependencias en diferentes
  3. Números de versión unificados de dependencias en diferentes proyectos

En respuesta a estas necesidades, ya existen algunas soluciones:

  1. Optimización de la gestión de dependencias de Gradle con bucles
  2. Usar buildSrc para administrar las dependencias de Gradle
  3. Utilice includeBuild para configurar de manera uniforme las versiones de dependencia

La solución anterior admite el Modulenúmero de versión unificado entre diferentes proyectos. Al mismo tiempo, si es necesario compartirlo entre proyectos, también se puede convertir en un Gradlecomplemento y lanzarlo al extremo remoto, lo que básicamente puede satisfacer nuestras necesidades.
Sin embargo Gradle7.0, se ha introducido una nueva característica, utilizando una Catalogversión de dependencia unificada, se admiten las siguientes características:

  1. Visible para todos module, gestión unificada modulede todas las dependencias
  2. Compatibilidad con dependencias declarativas bundles, es decir, las dependencias que siempre se usan juntas se pueden agrupar
  3. Admite la separación de números de versión y nombres de dependencia, y puede compartir números de versión entre múltiples dependencias
  4. Soporte libs.versions.tomlpara configurar dependencias en archivos separados
  5. Soporte para compartir dependencias entre proyectos

utilizarVersion Catalog

Tenga en cuenta que Catalogtodavía es una función de incubación, si desea usarla, debe settings.gradleagregarle lo siguiente:

enableFeaturePreview('VERSION_CATALOGS')
复制代码

También se puede ver por el nombre que en Version Catalogrealidad es una versión del directorio. Podemos seleccionar las dependencias que necesitamos del directorio para usar. Podemos usar las dependencias declaradas de las
siguientes manerasCatalog

dependencies {
    implementation(libs.retrofit)
    implementation(libs.groovy.core)
}
复制代码

En este caso, libsun directorio retrofitque representa las dependencias disponibles en ese directorio. Version CatalogTiene muchas ventajas sobre la declaración de dependencias directamente en el script de compilación :

  • 对于每个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由它们的groupartifactversion表示,但Gradle插件仅由它们的idversion标识。
因此,插件需要单独声明:

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" }
复制代码

如上所示,依赖可以定义成一个字符串,也可以将moduleversion分离开来
其中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的问题。
我们还可能通过Catalog插件来发布目录,这样用户直接引入这个插件即可

Gradle提供了一个Catalog插件,它提供了声明然后发布Catalog的能力。

1. 首先引入两个插件

plugins {
    id 'version-catalog'
    id 'maven-publish'
}
复制代码

然后,此插件将公开可用于声明目录的catalog扩展

2. 定义目录

上面引入插件后,即可使用catalog扩展定义目录

catalog {
    // 定义目录
    versionCatalog {
        from files('../libs.versions.toml')
    }
}
复制代码

然后可以通过maven-publish插件来发布目录

3. 发布目录

publishing {
    publications {
        maven(MavenPublication) {
            groupId = 'com.zj.catalog'
            artifactId = 'catalog'
            version = '1.0.0'
            from components.versionCatalog
        }
    }
}
复制代码

我们定义好groupId,artifactId,version,from就可以发布了
我们这里发布到mavenLocal,你也可以根据需要配置发布到自己的maven
以上发布的所有代码可见:Catalog发布相关代码

4. 使用目录

因为我们已经发布到了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主要具有以下特性:

  1. 对所有module可见,可统一管理所有module的依赖
  2. Compatibilidad con dependencias declarativas bundles, es decir, las dependencias que siempre se usan juntas se pueden agrupar
  3. Admite la separación de números de versión y nombres de dependencia, y puede compartir números de versión entre múltiples dependencias
  4. Soporte libs.versions.tomlpara configurar dependencias en archivos separados
  5. Soporte para compartir dependencias entre proyectos

Todo el código relevante en este artículo

El catálogo publica código relacionado El
catálogo usa código relacionado

Referencias

Compartir versiones de dependencia entre proyectos

Supongo que te gusta

Origin juejin.im/post/6997396071055900680
Recomendado
Clasificación