本指南解释了如何在 Gradle 中用模块源代码的本地 fork 替换模块依赖,前提是该模块本身是使用 Gradle 构建的。

使用本地 fork 可以让你

  • 对依赖项应用和测试自定义补丁

  • 使用库的未发布版本。

  • 避免依赖已发布的二进制版本。

前提条件

  • 该模块必须是用 Gradle 构建的

  • 你必须拥有该模块源代码的本地副本

  • 本地模块应设置为一个 Gradle 构建

Gradle 复合构建会自动将外部依赖项替换为本地 fork。

步骤 1: 创建复合构建

假设你的初始项目结构如下所示

project
├── settings.gradle(.kts)               (1)
└── my-app
    ├── build.gradle(.kts)              (2)
    └── src                             (3)
1 现有 settings 文件
2 现有 build 文件
3 使用外部依赖项的现有 app 项目

在本例中,我们的 app 依赖于 com.squareup.okhttp:okhttp:2.7.5,我们想使用它的一个本地 fork

my-app/build.gradle.kts
dependencies {
    implementation("com.squareup.okhttp:okhttp:2.7.5")
}
my-app/build.gradle
dependencies {
    implementation("com.squareup.okhttp:okhttp:2.7.5")
}

首先,为依赖项的本地 fork 创建一个新文件夹

project
├── settings.gradle(.kts)
├── my-app
│   ├── build.gradle(.kts)
│   └── src
└── my-fork     (1)
1 包含本地 fork 的复合构建的新目录

在根项目的 settings.gradle(.kts) 文件中,添加一个指向 my-forkincludeBuild 语句

settings.gradle.kts
rootProject.name = "how_to_use_a_local_fork"

include("my-app")
includeBuild("my-fork")  // Path to your local fork
settings.gradle
rootProject.name = "how_to_use_a_local_fork"

include("my-app")
includeBuild("my-fork")  // Path to your local fork

这会指示 Gradle 自动用你的本地构建替换外部依赖项坐标。

步骤 2: 包含本地 Fork

复合构建允许我们在只需少量配置更改的情况下使用本地版本的 okhttp

假设本地 fork 已经是 Gradle 构建,将其复制或移动到 my-fork 目录。这个 forked 模块将有它自己的 settings 和 build 文件。

更新后的项目结构如下所示

project
├── settings.gradle(.kts)
├── my-app
│   ├── build.gradle(.kts)
│   └── src
└── my-fork                             (1)
    ├── settings.gradle(.kts)           (2)
    └── okhttp
        ├── build.gradle(.kts)          (3)
        └── src                         (4)
1 新包含的 okhttp fork 构建
2 forked 模块的 Settings 文件
3 forked 模块的 Build 文件
4 forked 模块的源代码

com.squareup.okhttp:okhttp:2.7.5 的源代码位于 okhttp/src 文件夹中。

settings 文件应如下所示

my-fork/settings.gradle.kts
rootProject.name = "my-fork"

include("okhttp") // The forked module as a subproject
my-fork/settings.gradle
rootProject.name = "my-fork"

include("okhttp") // The forked module as a subproject

build 文件必须具有与 my-app 所需相同的 GAV 坐标

my-fork/okhttp/build.gradle.kts
plugins {
    id("java-library")
}

// Matches implementation("com.squareup.okhttp:okhttp:2.7.5") in my-app build file
group = "com.squareup.okhttp" // Matches original dependency
version = "2.7.5" // Matches original dependency version = "2.7.5"
my-fork/okhttp/build.gradle
plugins {
    id("java-library")
}

// Matches implementation("com.squareup.okhttp:okhttp:2.7.5") in my-app build file
group = "com.squareup.okhttp" // Matches original dependency
version = "2.7.5" // Matches original dependency version = "2.7.5"

步骤 3: 正常声明依赖项

在项目的 build.gradle(.kts) 文件中,继续使用与原来相同的外部坐标声明依赖项

my-app/build.gradle.kts
repositories {
    mavenCentral() // Don't remove this!
}

dependencies {
    implementation("com.squareup.okhttp:okhttp:2.7.5") // This doesn't need to change!
}
my-app/build.gradle
repositories {
    mavenCentral() // Don't remove this!
}

dependencies {
    implementation("com.squareup.okhttp:okhttp:2.7.5") // This doesn't need to change!
}

你无需在 build.gradle(.kts) 文件中显式编写替换语句;Gradle 会自动处理替换。

通过此设置,Gradle 将自动使用你的本地 fork,而不是从远程仓库下载依赖项。

步骤 4: 故障排除

如果 Gradle 仍然尝试从外部解析你的依赖项,请验证以下几点

  • 本地 fork 的 (build.gradle.kts) 文件中指定的坐标 (group, nameversion) 与你的外部依赖项完全相同。

  • 你的 settings.gradle.kts 使用 includeBuild 正确引用了你的本地 fork。

总结

Gradle 复合构建提供了一种直接且高效的方法,用本地 fork 替换外部模块依赖项。