go modules的replace使用, 解决fork的项目import问题

探究问题所在

如果直接第三方依赖, golang是可以满足使用的. 但如果我们需要修复第三方依赖的bug, 抑或为第三方依赖添加新feature, 那将是非常反常识的.
在其他语言中, 往往是可以import相对路径的包, 因此改动第三方依赖非常简单, 只需要fork一下, 然后改动相关代码, 然后将自己项目的依赖定位到新的地址即可.
但是在golang中不是这样, golang中, 只允许绝对路径, 所有的import, 都将唯一定位到同一个固定的地方, 下面举例.
如果我们fork了我们的一个依赖的仓库, 它的结构可能如下:

forked-repo
    |--a.go # import了some-dir
    |--b.go # import了some-dir
    |--some-dir # 子module
        |--c.go
        |--d.go

我们可以将自己的项目的依赖地址定位到forked-repo上, 这样我们对a.gob.go的改动, 是可以生效的, 这也很符合我们的常识.
但如果我们需要改动c.go, 那会发现, 我们的改动并不会生效, 因为a.goimport的some-dir, 地址实际上是github.com/源地址/xxxx, 我们fork后的地址是github.com/fork地址/xxx. 这样, 子module依旧是使用原仓库的, 这就是问题所在.

解决方案

1. 替换依赖地址

直接替换所有的依赖地址, 可以通过sed命令或者其他方法. 如果你打算长期依赖于fork后的仓库, 且需要改动的地方不多的时候, 可以考虑这种方式.
但如果你考虑提交pull request的话, 那这种方式无疑很麻烦.

2. 通过go modules的replace

go modules的replace命令一般而言, 是最佳的解决方案. 如果你在使用go modules, 可以考虑这种方式.

官方对replace命令的描述:

replace指令在顶级go.mod中为实际用于满足go源文件或go.mod文件中的依赖项的内容提供附加控制,而在building时忽略除主模块以外的模块中的replace指令.
简而言之就是:

  • 在项目的go.mod中, 使用replace命令的话, 可以对import路径进行替换. 也就是可以达到, 我们import的是a, 但在构建的时候, 实际使用的是b.
  • 可以replace是成VCS(github或者其他地方), 或者文件系统路径(可以是绝对路径, 也可以是相对于项目根目录的相对路径). 使用文件系统路径这种, 在开发调试的使用, 非常有用.
  • 最顶层go.mod的replace命令, 将影响到自身, 以及自身的所有依赖. 也就是可以间接改变依赖的项目的import. 这样我们在fork的项目的import, 不用在fork项目里面的go.mod进行replace, 直接在使用的项目里replace即可.
使用方式

直接编辑go.mod:

module nt-pdf-generator

go 1.12

require (
    github.com/xxx/abc v0.2.0 # replace的依赖, 必须要require
)

replace github.com/xxx/abc => ../github.com/hanFengSan/abc # 文件路径不需要附带版本信息

然后运行一下:

go mod tidy

大功告成.

©著作权归作者所有,转载或内容合作请联系作者
【社区内容提示】社区部分内容疑似由AI辅助生成,浏览时请结合常识与多方信息审慎甄别。
平台声明:文章内容(如有图片或视频亦包括在内)由作者上传并发布,文章内容仅代表作者本人观点,简书系信息发布平台,仅提供信息存储服务。

推荐阅读更多精彩内容

  • Go Module是Go会在1.12中正式推出的包管理机制。 Go mod 简介 Golang一直存在一个被人诟病...
    会飞的鲶鱼阅读 48,153评论 1 14
  • go modules详解 [TOC] go1.11开始,支持使用go modules管理依赖包. 刚加入的适合尝试...
    奶爸撸代码阅读 8,763评论 0 4
  • GO Plugin 编译问题 初始问题 现在用go mod和docker multi-stage生成的plugin...
    唐西铭阅读 7,743评论 1 1
  • 他们都叫他傻子士斤。 九月的天气还是很热的,那间布满青苔的老砖房从昨天开始就散发着一股股令人作呕的...
    tryto_b83f阅读 4,221评论 4 5
  • 时间不是流逝而是飞逝,又到新年开学了,整个寒假什么都没做,感觉没有努力学习,更没有出门旅游,还没有好好休息就结...
    习惯单调阅读 3,414评论 2 1

友情链接更多精彩内容