如果你还在使用 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.x
B1 vx.x.x // indirect
B2 vx.x.x // indirect
)
直接依赖go.mod 文件中缺失部分依赖
require (
B vx.x.x
B2 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.0
replace 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 key
ssh-keygen -t rsa -C 'yourEmail@xx.com' -f ~/.ssh/gitlab-rsa
为github生成一对秘钥ssh key
ssh-keygen -t rsa -C 'yourEmail2@xx.com' -f ~/.ssh/github-rsa
在~/.ssh目录下新建名称为config的文件(无后缀名)。用于配置多个不同的host使用不同的ssh key,内容如下:
# gitlab
Host gitlab.com
HostName gitlab.com
PreferredAuthentications publickey
IdentityFile ~/.ssh/gitlab_id-rsa
# github
Host github.com
HostName github.com
PreferredAuthentications publickey
IdentityFile ~/.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.com
login your_name
password your_password