模块依赖问题共同开发两个独立的 go 模块

Module dependencies issues co-developing two separate go modules

我正在创建一个 small utility, let's call it A, for which I require a small change to another go project,我们称它为 B

首先,我将 B 分叉到 B_forked 中,并创建了所需的 PR。作者还没审核,还好,不着急

但我想暂时让 A 使用我的版本 B_forked。更重要的是,我希望能够共同开发两者(编辑文件并使它们相互接受更改,而不是让 A 坚持 [=44= 的版本]B/B_forked).

所以我编辑了 A 导入 B_forked 并在我的 ~/Projects/A/go.mod 中写了以下内容:

module A

go 1.15

require (
    ... # Other packages
)

replace B_forked => ../B_forked

然后在B_forked中输入(版本号是go自动生成的)下面的~/Projects/B_forked/go.mod:

module B_forked

go 1.15

require (
    B v0.0.0-00010101000000-000000000000
    ... # Other packages
)

replace B => ./

在我的 B_forked 版本中,我不想将代码中的所有 import B/... 替换为 import B_forked/...(因为我想要稍后将更改包含在 B 的 PR 中)。这就是为什么我在这里使用 replace 规则。

不知何故这不起作用,我不明白为什么。建筑 B_forked 似乎有效:

$ cd ~/Projects/B_forked
$ go build
$

但是当我尝试编译 A 时,我得到:

$ cd ~/Projects/A
$ go build

go: found github.com/janpfeifer/webcam in github.com/janpfeifer/webcam v0.0.0-00010101000000-000000000000
go: github.com/janpfeifer/webcam@v0.0.0-00010101000000-000000000000 requires
        github.com/blackjack/webcam@v0.0.0-00010101000000-000000000000: invalid version: unknown revision 000000000000

我可能误解了 go 模块的底层抽象(到目前为止,我花在模块上的时间比花在简单代码本身上的时间要多得多)。任何想法如何设置它?也许有一种我不知道的更简单的滚动方式?

非常感谢!

如果您“fork”一个包含 Go 包或 Go 模块的存储库,您将创建与原始版本完全无关的内容。根据详细信息,您甚至可能无法编译“fork”(甚至无法编译未修改的“fork”)并且“fork”可能无法正常工作。

经验法则:从不 分叉 Go 包或 Go 模块。

In my B_forked version I don't want to replace all import B/... in the code with import B_forked/...

必须如上所述。 B_forked 与 B 完全无关。您 必须 重写所有导入或为所有导入添加替换指令。这里的“必须”二字是慎重选择的:You really must, no tricking or being cream here, especially

That's why I use the replace rule here.

行不通。这根本不是 Go 模块(或包)的工作方式。模块的标识基于模块名称和包在其导入路径上的标识(以其包含的模块名称为前缀)。

主要问题源于“分叉”。只是不要那样做!您不能在叉子上可靠和方便地工作。决不。 replace-directive 魔法无济于事。你不能分叉。

改为执行简单的 git clone。这样你就得到了 module/packages 的正确副本。在那个克隆上工作。将替换指令添加到您的项目 A 指向您的本地克隆(不是“叉子”!)。像这样 B 仍然可以正确构建,不需要 replace-magic 或重写导入路径,A 将获取 B 的本地修改副本。

since I want the changes to be included in a PR to B later on

好的。对于 Github-PR 你需要一个分叉,但这个分叉只需要存在于 Github 上。 执行以下操作:

  1. 您已经克隆了 B 并对其进行了处理。保留那个。
  2. Github GUI 中的分叉 B。
  3. 将该分叉作为附加遥控器添加到您的克隆中。
  4. 当你想创建 PR 时:从你的克隆推送到你的额外的远程分支并创建 PR。
  5. 永远不要尝试编译“fork”。 “fork”仅存在于 Github 上以创建 PR。你所有的工作都是在B的实际代码上完成的。

阅读答案和评论(thx @kostix、@volker)并进行试验后,对我来说最有效的是:

B 分叉到 B_forked,并在 B_forked[ 中有 2 个分支=52=]:

  • 分支 b1 是我用来创建 github 的 PR.

  • 在分支 b2 中,我将 B 的所有 self-imports 更改为 B_forked。之后我使用 b2 到 co-developed 和 A。我git cherry-pick将修改提交回分支b1.

A 我导入了 B_forked,在 go.mod 我将版本设置为 HEAD b2 分支,因此它可以由其他人构建,而 PR 不会进入存储库 B.

在开发过程中,我在 Ago.mod 中添加了一个来自 [=79 的 replace 规则=] 到其本地磁盘目录,因此 B_forked 中的更改会立即在 A.[=13 中看到=]

一旦 B 的 PR 生效,我将把 A 的导入改回 B.