如果你还在使用 GOPATH 模式来开发Golang程序,那么你可以参考本文来告别 GOPATH,并带给你一个方便的包管理工具。
环境准备
- go version>1.11
- 新增环境变量,GO111MODULE=on
- 新增环境变量,GOPROXY=https://goproxy.io,必须设代理,因为墙走了太多弯路…..
走通流程
1.新建文件夹demo加入gopath,然后在demo中新建src文件夹并在src下新建test文件夹,D:\demo\src\test
2.cmd进入D:\demo\src\test,执行go mod init ,初始化,会生成一个go.mod文件
3.导入你需要的包,go mod vendor,会生成vendor文件夹,里面就是该项目目前需要的依赖

4.如果依赖包需要更新或修改,直接修改go.mod即可
5.当需要新增包时,你只需要import 再 go mod vendor即可,它会帮你扫描整个项目文件
注意:goland的moudle下,不会引入vendor下的包,使用go mod tidy拉包
常见问题
- go mod init 时报错
go: cannot determine module path for source directory D:\test\src\111 (outside GOPATH, no import comments):这是因为你没在GOPATH下进行操作,不能直接用go mod init ,而要在init 后加上你的项目名
例如:项目目录:aaa/bbb/ccc ,首先进入aaa/bbb/ccc,然后 go mod init ccc 就会在ccc下生成mod文件
- 没用vendor虚拟环境,导包报红但不影响运行的情况

命令
| 命令 | 说明 |
|---|---|
| download | 下载依赖包到本地的CACHE |
| edit | 编辑go.mod |
| graph | 打印模块依赖图 |
| init [项目名] | 初始化mod,如果不在gopath下,项目名必须加,否则报错 |
| tidy | 拉取缺少的模块,移除不用的模块 |
| vendor | 新建vendor目录,将所有依赖全部拉进来 |
| verify | 验证依赖是否正确 |
| why | 解释为什么需要依赖 |
| go build -mod=vendor | 忽略cache中的包,使用vendor目录的依赖进行编译 |
indirect
在使用 Go module 过程中,随着引入的依赖增多,也许你会发现go.mod文件中部分依赖包后面会出现一个// indirect的标识。这个标识总是出现在require指令中,其中// 与代码的行注释一样表示注释的开始,indirect表示间接的依赖
在执行命令go mod tidy时,Go module 会自动整理go.mod 文件,如果有必要会在部分依赖包的后面增加// indirect注释。一般而言,被添加注释的包肯定是间接依赖的包,而没有添加// indirect注释的包则是直接依赖的包,即明确的出现在某个import语句中。
然而,这里需要着重强调的是:并不是所有的间接依赖都会出现在 go.mod文件中。
间接依赖出现在go.mod文件的情况,可能符合下面所列场景的一种或多种:
直接依赖未启用 Go module
require (B vx.x.xB1 vx.x.x // indirectB2 vx.x.x // indirect)

直接依赖go.mod 文件中缺失部分依赖
require (B vx.x.xB2 vx.x.x // indirect)

incompatible
以Module github.com/RainbowMango/m 为例,假如其当前版本为v3.6.0,因为其Module名字未遵循Golang所推荐的风格,即Module名中附带版本信息,我们称这个Module为不规范的Module。
不规范的Module还是可以引用的,但跟引用规范的Module略有差别。
如果我们在项目A中引用了该module,使用命令go mod tidy,go 命令会自动查找Module m的最新版本,即v3.6.0。 由于Module为不规范的Module,为了加以区分,go 命令会在go.mod中增加+incompatible 标识
require (github.com/RainbowMango/m v3.6.0+incompatible)
除了增加+incompatible(不兼容)标识外,在其使用上没有区别。
命名规范
Module的版本号需要遵循v<major>.<minor>.<patch>的格式,此外,如果major版本号大于1时,其版本号还需要体现在Module名字中。
比如Module github.com/RainbowMango/m,如果其版本号增长到v2.x.x时,其Module名字也需要相应的改变为: github.com/RainbowMango/m/v2。
实例
replace:

注意:也可以使用提交的hash
例如:replace github.com/coreos/go-systemd => github.com/coreos/go-systemd/v22 b51e752执行 go mod tidy 后自动变成replace github.com/coreos/go-systemd => github.com/coreos/go-systemd/v22 v22.1.0
不同项目之间的引用:

采坑记
ambiguous import

解决
将一个替换为另外一个,如:replace google.golang.org/grpc v1.31.1 => google.golang.org/grpc/examples v0.0.0-20200826230536-d31b6710005d
但是replace google.golang.org/grpc v1.31.1我本身就做了replace
会出现如下的错误
正确的应该是
replace google.golang.org/grpc v1.31.1 => google.golang.org/grpc v1.27.0replace google.golang.org/grpc v1.27.0 => google.golang.org/grpc/examples v0.0.0-20200826230536-d31b6710005d
这时这个问题又出现了….
检查mod文件
发现require中这个包已经被间接引用,删除require里重复的这个即可
按上面解决后可能会出现 used for two different module paths 
检查go.mod文件,发现需要替换的,在require中且是被间接引用,我们把require中框红的这个删除即可
go mod拉取私有项目
比如我的项目是https://github/ABDC/logs
设置环境变量,重启IDE
GOPRIVATE=github.com/ABCD
TOKEN
如果还有权限问题,win下的操作如下,在.gitconfig 新增
从你gitlab平台生成一个token
[http]extraheader = PRIVATE-TOKEN: 你的token[url]insteadOf = https://gitlab.你的gitlab服务器.com

对本项目生效:
git config http.extraheader "PRIVATE-TOKEN:YOUR_PRIVATE_TOKEN"
对所有git项目生效:
git config --global http.extraheader "PRIVATE-TOKEN:YOUR_PRIVATE_TOKEN"
SSH Key
1.打开本地git bash,使用如下命令生成ssh公钥和私钥对ssh-keygen -t rsa -C 'xxx@xxx.com' 然后一路回车(-C 参数是你的邮箱地址)
2.然后打开~/.ssh/id_rsa.pub文件(~表示用户目录,比如我的windows就是C:\Users\Administrator),复制其中的内容
3.打开gitlab,找到Profile Settings—>SSH Keys—->Add SSH Key,并把上一步中复制的内容粘贴到Key所对应的文本框,在Title对应的文本框中给这个sshkey设置一个名字,点击Add key按钮
4. 到此就完成了gitlab配置ssh key的所有步骤,我们就可以愉快的使用ssh协议进行代码的拉取以及提交等操作了
- 再试一下拉取代码和提交代码,应该就不需要输入密码了
本地配置多个ssh key
大多数时候,我们的机器上会有很多的git host,比如公司gitlab、github、oschina等,那我们就需要在本地配置多个ssh key,使得不同的host能使用不同的ssh key ,做法如下(以公司gitlab和github为例):
为公司生成一对秘钥ssh keyssh-keygen -t rsa -C 'yourEmail@xx.com' -f ~/.ssh/gitlab-rsa为github生成一对秘钥ssh keyssh-keygen -t rsa -C 'yourEmail2@xx.com' -f ~/.ssh/github-rsa
在~/.ssh目录下新建名称为config的文件(无后缀名)。用于配置多个不同的host使用不同的ssh key,内容如下:
# gitlabHost gitlab.comHostName gitlab.comPreferredAuthentications publickeyIdentityFile ~/.ssh/gitlab_id-rsa# githubHost github.comHostName github.comPreferredAuthentications publickeyIdentityFile ~/.ssh/github_id-rsa# 配置文件参数# Host : Host可以看作是一个你要识别的模式,对识别的模式,进行配置对应的的主机名和ssh文件# HostName : 要登录主机的主机名# User : 登录名# IdentityFile : 指明上面User对应的identityFile路径
按照上面的步骤分别往gitlab和github上添加生成的公钥gitlab_id-rsa.pub和github_id-rsa.pub
OK,大功告成,再次执行git命令验证是不是已经不需要再次验证权限了。
go get 拉取私有项目
在 ~/.netrc 中按照下面的写法添加你的 GitLab 账号和密码。这些内容在安装内部的私有包时需要用到。如果不存在这个文件就创建它
machine xxx.comlogin your_namepassword your_password
