您可以在支持 Gradle 的 IDE 中打开此示例。

在分层多仓库项目中使用复合构建

此示例演示了如何使用复合构建来开发一个由不同 Git 仓库组成的分层项目。与多项目构建中的 Gradle 子项目不同,此示例使用包含在复合构建中的独立 Gradle 构建。

除了多仓库架构的优势外,以这种方式使用 Gradle 复合构建还允许开发者轻松选择将哪些模块作为源依赖项开发,以及将哪些模块通过二进制仓库集成。

运行依赖于包含构建的 multirepo-app

首先,所有必需的依赖项都作为构建存在于 modules 目录中。在实际示例中,这些很可能是不同 Git 仓库的克隆。

为了避免硬编码要加载的包含构建,multirepo-app 中的 settings.gradle 文件会动态加载每个构建

settings.gradle.kts
file("modules").listFiles().forEach { moduleBuild: File ->
    includeBuild(moduleBuild)
}
settings.gradle
file('modules').listFiles().each { File moduleBuild ->
    includeBuild moduleBuild
}

multirepo-app 构建执行时,这些模块构建用于生成依赖的 Artifact

gradle run

并且 'dependencies' 报告显示了依赖替换的效果

gradle app:dependencies --configuration runtimeClasspath
runtimeClasspath - Runtime classpath of source set 'main'.
+--- org.sample:number-utils:1.0 -> project :number-utils
\--- org.sample:string-utils:1.0 -> project :string-utils
     \--- org.apache.commons:commons-lang3:3.12.0

切换到使用二进制依赖

只要模块在二进制仓库中可用,即使您没有在本地安装某些模块,multirepo-app 构建仍将继续工作。在这种情况下,Gradle 将使用从仓库下载的二进制依赖项。

准备二进制仓库

为了演示此功能,我们首先需要将每个模块发布到二进制仓库。在此示例中,我们为此目的使用本地文件仓库

gradle :publishDeps

publishDeps 任务会为每个包含的构建创建并上传 Artifact。它在 multirepo-app 中定义如下

build.gradle.kts
tasks.register("publishDeps") {
    dependsOn(gradle.includedBuilds.map { it.task(":publishMavenPublicationToMavenRepository") })
}
build.gradle
tasks.register('publishDeps') {
    dependsOn gradle.includedBuilds*.task(':publishMavenPublicationToMavenRepository')
}

移除本地模块源码

当模块 Artifact 在仓库中可用后,我们现在可以从构建中移除模块源码。由于复合构建配置为自动加载可用的模块,这就像删除一个或多个模块目录一样简单。

rm -r modules/string-utils
gradle run

请注意,number-utils 依赖项仍然由包含的构建满足,而 string-utils 依赖项现在则从仓库解析。

'dependencies' 报告显示了依赖替换的效果

gradle app:dependencies --configuration runtimeClasspath
runtimeClasspath - Runtime classpath of source set 'main'.
+--- org.sample:number-utils:1.0 -> project :number-utils
\--- org.sample:string-utils:1.0
     \--- org.apache.commons:commons-lang3:3.12.0

将外部库作为子模块包含

通过将外部 'commons-lang' 构建直接添加到复合构建中,可以演示此配置的强大功能。

git clone http://gitbox.apache.org/repos/asf/commons-lang.git modules/commons-lang --branch rel/commons-lang-3.12.0 --depth 1
gradle --project-dir modules/commons-lang init
gradle run

通过运行以下命令,您可以看到外部传递性依赖项 commons-lang 被本地项目依赖项替换

gradle app:dependencies --configuration runtimeClasspath