如何使用vgo和给定的go.mod下载所有依赖项?

lli*_*lib 8 go docker vgo

我正在使用vgo和一个Dockerfile开展一个go项目,我希望docker能够缓存项目的依赖项,这样它就有两个属性:

  1. 如果go.mod文件更改,将重新下载依赖项
  2. 如果我更改了包中的文件但没有更改go.mod,则不会重新下载依赖项.

现在,我这样做:

...
RUN go get -u golang.org/x/vgo
COPY . /go/src/whatever
RUN vgo install
...
Run Code Online (Sandbox Code Playgroud)

但是,如果您更改了go文件,则必须从该COPY层重建dockerfile .

简而言之,我想做的是:

...
RUN go get -u golang.org/x/vgo
COPY go.mod /go/src/whatever
RUN vgo install_dependencies
COPY . /go/src/whatever
RUN vgo install
...
Run Code Online (Sandbox Code Playgroud)

这样,如果我更改go.mod,将下载并重建所有依赖项,但除此之外,我们可以继续构建二进制文件.

我可以看到几种方法来获得这样的行为,但所有这些方法都有缺点:

  1. 我可以复制$GOPATH/src/mod到docker容器中,但是这将有很多我不需要的文件
  2. 我可以vgo mod -vendor在构建docker容器之前复制供应商目录,但这依赖于开发人员记住vgo mod -vendor每次go.mod更改时都要运行,否则应用程序将无法构建,他们必须vgo mod -vendor在重试docker构建之前运行.

你能想到一种方式让我获得像我想象中的行为vgo install_dependencies吗?我错过了一个vgo技巧吗?

lli*_*lib 6

tl; dr:在当前的go master和将来的go版本中,go mod download将完成此工作。目前,您需要破解。

在地鼠松弛时,有人提到了这个问题:https : //github.com/golang/go/issues/26610,在这里我知道这会或多或少地实现我想要的功能(假设这里使用的是go版本1.11beta3):

# Populate the module cache based on the go.{mod,sum} files.
COPY go.mod .
COPY go.sum .
RUN go list -e $(go list -f '{{.Path}}' -m all)
Run Code Online (Sandbox Code Playgroud)

在该线程的稍后部分,Russ Cox实现了go mod download,它将在下一个版本中提供go,使我可以删除go list上面的愚蠢的技巧。

更新:go mod download现已广泛提供,您应该在1.12及更高版本上使用它