简体   繁体   English

Go 模块、私有仓库和 gopath

[英]Go modules, private repos and gopath

We are converting our internal codebase from the dep dependency manager to go modules ( vgo or built in with go1.11.2).我们正在将我们的内部代码库从dep依赖管理器转换为 go 模块( vgo或内置于 go1.11.2)。 Imagine we have code like this:想象一下我们有这样的代码:

$GOPATH/src/mycompany/myprogram/main.go: $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: $GOPATH/src/mycompany/myprogram/go.mod:

module mycompany/myprogram

(it doesn't have any dependencies; our real-world code does). (它没有任何依赖项;我们的实际代码有)。

$GOPATH/src/mycompany/mylib/lib.go: $GOPATH/src/mycompany/mylib/lib.go:

package mylib

func Add(x int, y int) int {
        return x + y
}

I didn't module-ize this code;我没有对这段代码进行模块化; it doesn't seem to matter whether I do or don't.我做或不做似乎并不重要。

These are trivial examples but our internal code follows a similar structure as this worked historically.这些都是微不足道的例子,但我们的内部代码遵循与历史上类似的结构。

Since these directories are on the Gopath, export GO111MODULE=auto still builds as before and this works fine (modules not used because we are on the gopath).由于这些目录在 Gopath 上,因此export GO111MODULE=auto仍然像以前一样构建并且工作正常(模块未使用,因为我们在 gopath 上)。 However, when I set export GO111MODULE=on I immediately get the error:但是,当我设置export GO111MODULE=on我立即收到错误消息:

build mycompany/myprogram: cannot find module for path mycompany/mylib

So I did some research and I would like to validate my understanding.所以我做了一些研究,我想验证我的理解。 First let me say our old approach worked, but I am more interested in changing to use go modules as it appears to be where the go project itself is headed.首先让我说我们的旧方法有效,但我更感兴趣的是改为使用 go 模块,因为它似乎是 go 项目本身的方向。 So.所以。

  1. It seems the intention of the golang authors was that "dotless" paths belong to the standard repository only; golang 作者的意图似乎是“无点”路径仅属于标准存储库; that is there should be a binding between domain name and project.那就是域名和项目之间应该有绑定。 We don't use go get on our internal project, unsurprisingly.不出所料,我们在内部项目中不使用 go get。 Here is the source specifically:具体来源如下:

    Dotless paths in general are reserved for the standard library;无点路径一般是为标准库保留的; go get has (to my knowledge) never worked with them, but go get is also the main entry point for working with versioned modules. go get(据我所知)从未与它们合作过,但 go get 也是使用版本化模块的主要入口点。

    Can anyone with more knowledge of golang than me confirm this?任何比我更了解 golang 的人都可以证实这一点吗?

  2. My key assumption is that once go decides to use modules, all dependencies must be modules and the gopath becomes somewhat irrelevant, except as a cache (for downloaded modules).我的关键假设是,一旦 go 决定使用模块,所有依赖项都必须是模块并且 gopath 变得有些无关紧要,除了作为缓存(对于下载的模块)。 Is this correct?这样对吗?

  3. If this is true, we need to use a private gitlab (in our case) repository on the path.如果这是真的,我们需要在路径上使用私有 gitlab(在我们的例子中)存储库。 There's an open issue on handling this that I'm aware of so we can implement this if necessary.我知道在处理这个问题上有一个悬而未决的问题,因此我们可以在必要时实施。 I'm more interested in the consequences, specifically for iterating in the private repositories.我对结果更感兴趣,特别是在私有存储库中进行迭代。 Previously we could develop these libraries locally before committing any changes;以前,我们可以在提交任何更改之前在本地开发这些库; now it seems we have a choice:现在看来我们有一个选择:

    1. Accept this remote dependency and iterate.接受这个远程依赖并迭代。 I was hoping to avoid needing to push and pull remotely like this.我希望避免像这样远程推拉。 There are workarounds to needing an internet connection if strictly necessary.如果绝对必要,有一些解决方法需要互联网连接。
    2. Merge everything into one big git repository.将所有内容合并到一个大的 git 存储库中。

If it matters, I'm using go version go1.11.2 linux/amd64 and my colleagues are using darwin/amd64 .如果重要的话,我正在使用go version go1.11.2 linux/amd64而我的同事正在使用darwin/amd64 If it helps, my golang is exactly as installed by Fedora's repositories.如果有帮助,我的 golang 与 Fedora 的存储库安装的完全一样。

So, tl;dr , my question is: are go modules all-or-nothing, in that any dependency must be resolved using the module system (go get, it seems) and the gopath has become redundant?所以, tl;dr ,我的问题是:go 模块是全有还是全无,因为任何依赖项都必须使用模块系统来解决(go get,似乎)并且 gopath 变得多余? Or is there something about my setup that might trigger this to fail?或者我的设置是否有可能触发此失败? Is there some way to indicate a dependency should be resolved explicitly from the gopath?有什么方法可以指示应该从 gopath 中明确解析依赖项吗?

Updates since asking the question :自提出问题以来的更新

  1. I can move myprogram out of the gopath.我可以移动myprogram出GOPATH的。 The same issue occurs ( mylib has been left in the gopath).发生同样的问题( mylib已留在 gopath 中)。
  2. I can run, or not run, go mod init mycompany/mylib in the mylib directory;我可以运行,也可以不运行,在mylib目录下go mod init mycompany/mylib it makes no difference at all.它根本没有区别。
  3. I came across Russ Cox's blog post on vgo .在 vgo 上看到了 Russ Cox 的博客文章 My concerns about offline development that I tried not to dive into too far are resolved by $GOPROXY . $GOPROXY解决了我对离线开发的担忧,我试图不深入$GOPROXY

I use a workaround with GITHUB_TOKEN to solve this.我使用GITHUB_TOKEN的解决方法来解决这个问题。

  1. Generate GITHUB_TOKEN here https://github.com/settings/tokens在这里生成GITHUB_TOKEN https://github.com/settings/tokens
  2. export GITHUB_TOKEN=xxx
  3. git config --global url."https://${GITHUB_TOKEN}:x-oauth-basic@github.com/mycompany".insteadOf "https://github.com/mycompany"

I wrote up a solution for this on Medium: Go Modules with Private Git Repositories .我在 Medium: Go Modules with Private Git Repositories上为此写了一个解决方案。

The way we handle it is basically the same as the answer above from Alex Pliutau , and the blog goes into some more detail with examples for how to set up your git config with tokens from GitHub/GitLab/BitBucket.我们处理它的方式与上面来自Alex Pliutau的答案基本相同,并且该博客通过示例更详细地介绍了如何使用来自 GitHub/GitLab/BitBucket 的令牌设置您的 git 配置。

The relevant bit for GitLab: GitLab 的相关位:

git config --global \
  url."https://oauth2:${personal_access_token}@privategitlab.com".insteadOf \
  "https://privategitlab.com"

#or 

git config --global \
  url."https://${user}:${personal_access_token}@privategitlab.com".insteadOf \
  "https://privategitlab.com"

I hope it's helpful.我希望它有帮助。

I use ls-remote git command to help resolve private repo tags and go get after it.我使用 ls-remote git 命令来帮助解析私有 repo 标签并继续追踪它。

$ go env GO111MODULE=on
$ go env GOPRIVATE=yourprivaterepo.com
$ git ls-remote -q https://yourprivaterepo.com/yourproject.git
$ go get

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM