在本地使用带有 go mod 的子包

Using subpackages with go mod locally

我的文件系统中有一个名为 bitbucket.org/me/awesome 的 go 包(不在 $GOPATH 中)。

~/awesome> tree
.
├── main.go
├── go.mod
├── go.sum
├── subpackageA
│   └── main.go

我的 go.mod 看起来像:

module bitbucket.org/me/awesome

require (
       ... # lots of external dependencies
)

replace bitbucket.org/me/awesome => ./

在我的顶级目录main.go中,我调用了一个子包如下:

import "bitbucket.org/me/awesome/subpackageA"

这一切看起来都很正常。 go get 有效。但是,当我第一次将整个存储库克隆到其他地方(比如在 Docker 图像中)和 运行 go get 时,我会收到如下错误:

package bitbucket.org/me/awesome/subpackageA: https://api.bitbucket.org/2.0/repositories/me/awesome?fields=scm: 403 Forbidden

这意味着它没有使用包的本地文件系统版本,即使我告诉它使用 go.mod 文件中的 replace directive

我做错了什么?我如何确保子包是从文件系统中使用的,而不是试图从互联网上获取的?

Go 没有(真实的)"subpackage" 概念。所有包裹基本上都是平等对待的。这意味着 replace bitbucket.org/me/awesome 不会影响包 bitbucket.org/me/awesome/subpackageA,因为它们是两个独立的、不相关的包。文件夹布局没有引入 subpackageA 与 awsome 的关系,反之亦然 *).

因此您需要为子包 A 添加一个单独的替换指令

replace bitbucket.org/me/awesome/subpackageA => ./subpackageA

*) 为绝对正确而挑剔:文件夹布局确实会影响名为 internal 的文件夹(无法从其他项目导入)、名为 vendor 的文件夹(可能包含销售包)和搜索 go.mod 文件在 repo 根目录停止。

对于另一种方法,您可以 go.mod 像这样:

module awesome

然后像这样调用子包:

import "awesome/subpackageA"

https://golang.org/doc/code.html