【发布时间】:2019-04-30 04:17:14
【问题描述】:
我们正在将我们的内部代码库从 dep 依赖管理器转换为 go 模块(vgo 或内置于 go1.11.2)。想象一下我们有这样的代码:
$GOPATH/src/mycompany/myprogram/main.go:
package main
import (
"fmt"
lib "mycompany/mylib" )
func main() {
fmt.Println("2+3=", lib.add(2, 3))
}
$GOPATH/src/mycompany/myprogram/go.mod:
module mycompany/myprogram
(它没有任何依赖关系;我们的实际代码有)。
$GOPATH/src/mycompany/mylib/lib.go:
package mylib
func Add(x int, y int) int {
return x + y
}
我没有对这段代码进行模块化;我做或不做似乎并不重要。
这些只是简单的示例,但我们的内部代码遵循与过去类似的结构。
由于这些目录位于 Gopath 上,export GO111MODULE=auto 仍然像以前一样构建,并且工作正常(未使用模块,因为我们在 gopath 上)。但是,当我设置 export GO111MODULE=on 时,我立即收到错误消息:
build mycompany/myprogram: cannot find module for path mycompany/mylib
所以我做了一些研究,我想验证我的理解。首先让我说我们的旧方法有效,但我更感兴趣的是更改为使用 go 模块,因为它似乎是 go 项目本身的发展方向。所以。
-
似乎 golang 作者的意图是“无点”路径仅属于标准存储库;那就是域名和项目之间应该有绑定。不出所料,我们不使用 go get 进行内部项目。 Here is the source 具体:
一般来说,无点路径是为标准库保留的; go get (据我所知)从未使用过它们,但 go get 也是使用版本化模块的主要入口点。
谁能比我更了解golang?
我的关键假设是,一旦 go 决定使用模块,所有依赖项都必须是模块,并且 gopath 变得有些无关紧要,除了作为缓存(对于下载的模块)。这是正确的吗?
-
如果这是真的,我们需要在路径上使用私有 gitlab(在我们的例子中)存储库。 There's an open issue on handling this that I'm aware of 所以我们可以在必要时实现它。我对后果更感兴趣,特别是在私有存储库中进行迭代。以前我们可以在提交任何更改之前在本地开发这些库;现在看来我们有一个选择:
- 接受这个远程依赖并迭代。我希望避免像这样远程推拉。如果绝对必要,有一些解决方法可以解决需要互联网连接的问题。
- 将所有内容合并到一个大型 git 存储库中。
如果重要的话,我使用的是go version go1.11.2 linux/amd64,而我的同事使用的是darwin/amd64。如果有帮助,我的 golang 与 Fedora 存储库中安装的完全一样。
所以,tl;dr,我的问题是:go 模块是全有还是全无,因为任何依赖项都必须使用模块系统解决(似乎是 go get)并且 gopath 变得多余了?或者我的设置是否有可能导致此失败?有什么方法可以表明应该从 gopath 显式解析依赖项?
提问后的更新:
- 我可以将
myprogram移出gopath。出现同样的问题(mylib已留在 gopath 中)。 - 我可以运行,也可以不运行,
go mod init mycompany/mylib在 mylib 目录中;完全没有区别。 - 我遇到了Russ Cox's blog post on vgo。
$GOPROXY解决了我对离线开发的担忧,但我尽量不深入研究。
【问题讨论】:
-
看起来你从未在 $GOPATH/src/mycompany 中运行过
go mod init mycompany,因此还没有模块。 // 您引用的关于无点路径的评论是由 Go 维护者之一(或作者,甚至?) bcmills 撰写的。你可以把它当作权威。 // 模块不是“全有或全无”。你可以依赖非模块就好了。 -
@Peter 我把它排除在我的问题之外,但我做到了(否则它不会构建为一个模块,不是吗?)。我会将其编辑到问题中。所以如果这是真的,我的问题就变成了:如果我可以依赖非模块,为什么它不起作用? :P
-
啊,我明白了。您必须在 mycompany/myprogram 中添加 replace statement 才能完成这项工作。
-
@Peter 这听起来正是我所需要的。我在示例中添加了
replace mycompany/mylib => ../mylib/,但没有用。所以,域名问题。所以我将所有mycompany引用重命名为mycompany.com... 现在构建(我 Q 中的示例)挂起,直到互联网超时,然后给我通常的build mycompany.com/myprogram: cannot find module for path mycompany.com/mylib:( -
所以我想我们需要结合这两种方法;使用类似 url 的导入从私有但远程的存储库构建,然后我们可以在本地替换以加快开发速度。
标签: go go-modules