go mod常用命令 已经 常见问题
最近接触到go mod,网上查了查资料,这里记录一下。
1 介绍
1.1、go mod是什么
go mod 是Golang 1.11 版本引入的官方包(package)依赖管理工具,用于解决之前没有地方记录依赖包具体版本的问题,方便依赖包的管理。
之前Golang 主要依靠vendor和GOPATH来管理依赖库,vendor相对主流,但现在官方更提倡go mod。
1.2、go mod初始化及使用
下载官方包1.11(及其以上版本将会自动支持gomod) 默认GO111MODULE=auto(auto是指如果在gopath下不启用mod)
Golang 提供一个环境变量 GO111MODULE 来设置是否使用mod,它有3个可选值,分别是off, on, auto(默认值),具体含义如下:
- off: GOPATH mode,查找vendor和GOPATH目录
- on:module-aware mode,使用 go module,忽略GOPATH目录
- auto:如果当前目录不在$GOPATH 并且 当前目录(或者父目录)下有go.mod文件,则使用 GO111MODULE, 否则仍旧使用 GOPATH mode。
修改 GO111MODULE 的值的语句是:set GO111MODULE=on 。
在使用模块的时候, GOPATH
是无意义的,不过它还是会把下载的依赖储存在 GOPATH/src/mod
中,也会把 go install
的结果放在 GOPATH/bin
(如果 GOBIN
不存在的话)
go mod download
下载模块到本地缓存,缓存路径是$GOPATH/pkg/mod/cache
go mod edit
是提供了命令版编辑go.mod
的功能,例如go mod edit -fmt go.mod
会格式化go.mod
go mod graph
把模块之间的依赖图显示出来go mod init
初始化模块(例如把原本dep管理的依赖关系转换过来)go mod tidy
增加缺失的包,移除没用的包go mod vendor
把依赖拷贝到vendor/
目录下go mod verify
确认依赖关系go mod why
解释为什么需要包和模块
注意有几个坑的地方:
go mod
命令在$GOPATH
里默认是执行不了的,因为GO111MODULE
的默认值是auto
。默认在$GOPATH
里是不会执行, 如果一定要强制执行,就设置环境变量为on
。go mod init
在没有接module名字的时候是执行不了的,会报错go: cannot determine module path for source directory
。可以这样执行:$ go mod init github.com/jiajunhuang/hello
否则就要在
main.go
里加上导入声明,例如:$ cat main.go
package main func main() {
println("Hello world")
}
$ go mod init
go: cannot determine module path for source directory /Users/jiajun/hello (outside GOPATH, no import comments)
$ vim go.mod
$ cat go.mod
module github.com/jiajunhuang/hello
$ go mod init
go mod init: go.mod already exists
$ rm go.mod
$ vim main.go
$ cat main.go
package main // import "github.com/jiajunhuang/hello" func main() {
println("Hello world")
}
$ go mod init
go: creating new go.mod: module github.com/jiajunhuang/hello
$ ls
go.mod main.go
$ cat go.mod
module github.com/jiajunhuang/hello当然,如果在已有代码的仓库里执行是不存在这个问题的。
2 命令
2.1 指定module的根目录并生成go.mod文件
go mod init example.com/hello
2.2 下载并添加依赖到go.mod文件中
go build, go test
2.3 查看module下的所有依赖
go list -m all
2.4 更新稳定版依赖
go get rsc.io/sampler
2.5 更新为指定版本依赖
- go list -m -versions rsc.io/sampler
- rsc.io/sampler v1.0.0 v1.2.0 v1.2.1 v1.3.0 v1.3.1 v1.99.99
- go get rsc.io/sampler@v1.3.1
2.6 清理无用的依赖
go mod tidy
2.7 将依赖复制到项目路径的vendor文件夹中
go mod vendor
2.8 忽略cache里的包,只使用vendor目录里的依赖进行编译
go build -mod=vendor
2.9 校验依赖并查看是否有修改
go mod verify
3 问题
3.1 go: modules disabled inside GOPATH/src by GO111MODULE=auto; see 'go help modules'
go mod init
go: modules disabled inside GOPATH/src by GO111MODULE=auto; see 'go help modules'
开启go module:
set GO111MODULE=on //windows
export GO111MODULE=on //linux
3.2 $GOPATH/go.mod exists but should not
GO 1.11或之后模块遇到这个问题:
$GOPATH/go.mod exists but should not
开启模块支持后(set GO111MODULE=on),并不能与$GOPATH共存,所以把$GOPATH从env中移出即可(unset GOPATH),可运行“unset GOPATH && make”。
4 例子
4.1 例子1
go mod初始化:在$GOPATH外建一个文件夹,把个人代码放进去,我的测试代码路径:https://github.com/kevinhao8/go-mod-example。
首先main入口代码所在文件夹创建mod
创建语句 go mod init [module name]
比如我的测试代码 redisTest.go,创建语句就是 go mod init redisTest,成功创建时返回 go: creating new go.mod: module redisTest
此时文件夹下出现 go.mod文件,打开发现只有2行如下,并没有记录依赖库。
module redisTest
go 1.12
此时需要输入go test语句,根据需要的依赖自动生成require,也就是依赖包,此时go.mod多了如下内容(红字是我写的注释,文件里面没有)
require (
github.com/gin-contrib/sse v0.0.0-20190301062529-5545eab6dad3 // indirect(有indirect注释的代表间接依赖,没有的代表直接依赖)
github.com/gin-gonic/gin v1.3.0
github.com/golang/protobuf v1.3.1 // indirect
github.com/mattn/go-isatty v0.0.7 // indirect
github.com/ugorji/go/codec v0.0.0-20190316192920-e2bddce071ad // indirect(这里是版本号+时间戳+hash)
gopkg.in/go-playground/validator.v8 v8.18.2 // indirect
gopkg.in/yaml.v2 v2.2.2 // indirect
)
此时会有如下失败提示,此处为我踩得第一个坑!!!花了挺长时间才解决
build redisTest: cannot load dbredis: cannot find module providing package dbredis
dbredis是我写的私有包,代码是没有问题的,为什么找不到呢?从网上查了一圈,发现私有包如果不想发布到网上,需要手动添加require ,然后replace 进行替换,将私有包指向本地module所在的绝对或相对路径。一般用相对路径更通用。
此时手动将go.mod改为如下,红字为新加
require (
dbredis v0.0.0
github.com/gin-contrib/sse v0.0.0-20190301062529-5545eab6dad3 // indirect
github.com/gin-gonic/gin v1.3.0
github.com/golang/protobuf v1.3.1 // indirect
github.com/mattn/go-isatty v0.0.7 // indirect
github.com/ugorji/go/codec v0.0.0-20190316192920-e2bddce071ad // indirect
gopkg.in/go-playground/validator.v8 v8.18.2 // indirect
gopkg.in/yaml.v2 v2.2.2 // indirect
)
replace dbredis v0.0.0 => ./dbredis
再度运行go test 命令,发现仍有失败提示如下,找不到dbredis文件夹下的go.mod文件。
go: parsing dbredis\go.mod: open E:\code\go-mod-example\dbredis\go.mod: The system cannot find the file specified.
go: error loading module requirements
从网上查资料发现,这种情况下需要给私有包也生成mod,这样整个工程的依赖才能完整。故运行如下命令:
cd dbredis
go mod init dbredis(此处我写的mod名跟package名一致,不知道不一致行不行)
go test
三条命令依次运行通过,dbredis文件夹下的go.mod文件如下:
module dbredis
go 1.12
require github.com/go-redis/redis v6.15.2+incompatible
此时再运行如下命令:
cd ..(回到上层文件夹)
go test
运行通过,不再有报错。运行命令 go build redisTest.go 也能够正常生成redisTest.exe
至此通过mod来管理依赖包基本实现,我们的程序能基本脱离$GOPATH编译。
5 go mod 和 dep 比较
go mod
支持代理,以后就可以使用私有镜像源了~,具体请搜索GOPROXY
go mod
速度比dep
快很多go.mod
中列出了所有的依赖,这一点其实我不是很喜欢,因为当项目一大,历史一久,只要升级其中一个依赖,很可能整个依赖 就挂了。我还是比较喜欢只要列出顶级依赖,由程序处理子依赖的情况。
一个生成的 go.mod
的示例
module github.com/my/module/v3 // 这是你的包的声明 // require 里是依赖。需要带上路径和版本。
require (
github.com/some/dependency v1.2.3
github.com/another/dependency v0.1.0
github.com/additional/dependency/v4 v4.0.0
)
其他
windows下的尝试:
gomod初尝试
下载官方包1.11(及其以上版本将会自动支持gomod) 默认GO111MODULE=auto(auto是指如果在gopath下不启用mod)
go mod help查看帮助
go mod init<项目模块名称>初始化模块,会在项目根目录下生成 go.mod文件。
go mod tidy根据go.mod文件来处理依赖关系。
go mod vendor将依赖包复制到项目下的 vendor目录。建议一些使用了被墙包的话可以这么处理,方便用户快速使用命令go build -mod=vendor编译
go list -m all显示依赖关系。go list -m -json all显示详细依赖关系。
go mod download <path@version>下载依赖。参数<path@version>是非必写的,path是包的路径,version是包的版本。
在gopath外新建一个项目,单独开一个cmd设置set GO111MODULE=on(习惯性的和git初始化一样)go mod init然后报错了。 正解如下:go mod init xxx(module名称可与文件名不同)
在项目目录下执行go mod tidy下载完成后项目路径下会生成go.mod和go.sum
go.mod文件必须要提交到git仓库,但go.sum文件可以不用提交到git仓库(git忽略文件.gitignore中设置一下)。
go模块版本控制的下载文件及信息会存储到GOPATH的pkg/mod文件夹里。
--------------------分割线---------------------------------------------------------
gopath 与go mod的区别
- 环境变量GOPATH不再用于解析imports包路径,即原有的GOPATH/src/下的包,通过import是找不到了。
- Go Module功能开启后,下载的包将存放与$GOPATH/pkg/mod路径
- $GOPATH/bin路径的功能依旧保持
go get 流程的变化
- 老的go get取包过程类似:git clone + go install , 开启Go Module功能后go get就只有 git clone 或者 download过程了。
- 新老实现还有一个不同是,两者存包的位置不同。前者,存放在$GOPATH/src目录下;后者,存放在$GOPATH/pkg/mod目录下。
- 老的go get取完主包后,会对其repo下的submodule进行循环拉取。新的go get不再支持submodule子模块拉取。
依赖包的变化
- 三方远程包:
- 检查远程仓库最新的tag版本,有就取得该版本
- 远程仓库没有tag版本时,直接获取master分支的HEAD版本
- 如果在go.mod文件中指定了具体版本,go get直接获取该指定版本
- go.mod中除了可以指定具体版本号以外,还支持分支名
- 本地包:
- 通过replace()进行替换
私有仓库权限和私有vcs非标准路径取包问题
- 权限问题
- windows10下:
- 控制面板>用户账户>凭据管理手动添加普通凭据即可
- linux下:
- 增加 $HOME/.gitconfig 配置:
- [url "ssh://git@github.com/MYORGANIZATION/"]
- insteadOf = https://github.com/MYORGANIZA...
- 增加 $HOME/.netrc:
- machine github.com login YOU password APIKEY
- 将其中的 APIKEY 换成自己的登录KEY。
- 非标准路径问题(https://private.vcs.com:20000)
- 搭建一个中间服务:https://private.vcs.com 能够通过go get的包路径匹配查询正确的仓库地址。
参考:
https://blog.csdn.net/Lazybones_3/article/details/89355133
https://blog.csdn.net/kevinh531/article/details/88691870
https://jiajunhuang.com/articles/2018_09_03-go_module.md.html
https://blog.csdn.net/qq_33296108/article/details/88184060
go mod常用命令 已经 常见问题的更多相关文章
- MySQL常用命令和常见问题
MySQL常用命令和常见问题 --创建数据库并设置字符集 create database wip default character set utf8 collate utf8_general_ci; ...
- docker 常用命令 以及常见问题
常见命令 windos 在搜索框 输入 windows powershell,打开.然后输入以下命令#查看镜像列表 docker images ls #删除单个镜像 docker rmi image- ...
- git常用命令及常见问题解析
1.查看状态 1.git status 2.git status -a 2.初始化一个git仓库 git init git clone 'git仓库地址' 3.添加到暂存区 //目录 git add ...
- repo常用命令及常见问题汇总
1.执行repo命令的时候,总是显示“project xx no found” 解决: (1)先执行“repo forall -c pwd” 显示所有project的路径,按照这个来写project参 ...
- mysql5.7安装配置,常用命令,常见问题
1.安装配置 参考:http://www.cnblogs.com/Fiona20170420/p/6738185.html 1. 下载 2. 解压缩 3. 添加path环境变量,路径指向mysql所在 ...
- git开发流程、常用命令及工具、TortoiseGit使用及常见问题
根据我最近使用git的一些经历,git是基于分支的版本控制工具,分支有远程分支和本地分支. 一.开发流程 - 从远程服务器的master,clone一份项目文件到本地,然后本地master的基础上br ...
- ionic的常用命令总结以及正式发布的准备
常用命令: npm install -g ionic cordova(需要安装node) ionic start cutePuppyPics --v2(建app cutePuppyPics app名字 ...
- ubuntu的一些常用命令,测试版本:Ubuntu 12.04.5 LTS
最近配置了一台Linux服务器,选用的是Ubuntu 12.04.5 LTS版本. 把之前放在Windows Server 2003上的网站移到了现在的服务器上,给我的感受用一个字形容:真JB快! 网 ...
- Java的cmd配置(也即Java的JDK配置及相关常用命令)——找不到或无法加载主类 的解决方法
Java的cmd配置(也即Java的JDK配置及相关常用命令) ——找不到或无法加载主类 的解决方法 这段时间一直纠结于cmd下Java无法编译运行的问题.主要问题描述如下: javac 命令可以正 ...
- MongoDB与Mysql常用命令解释
原文 本文旨在介绍MongoDB,Mysql的常用命令:将MongoDB 和传统的关系型数据库的常用命令对照起来学习,更加便于记忆和理解. MongoDB是由数据库(database/reposito ...
随机推荐
- rh358 005 dhcp dhcp6 打印机 ansible配置dhcp和打印机
部署dhcp服务器 主机发送Discover报文 目标为广播地址 同一网段的dhcp收到报文后,dhcp响应一个offer报文 offer报文:dhcp自己的ip地址.和客户端ip以及使用周期,和客户 ...
- 如何自动清理 KingbaseES SYS_LOG
KingbaseES 初始化完成后,默认不会对 sys_log进行清理.如果需要对sys_log进行自动清理,需要设置相关参数. 与日志自动清理有关的参数(默认值)如下: log_filename | ...
- 在Windows客户端自动设置AD用户头像
Windows现在可以设置用户头像,并在开始菜单显示.如果你安装了Exchange或者Lync,那么可以在Outlook或者Skype里看到用户的头像.这个图片是存储在AD用户属性里的.对于桌面电脑的 ...
- 常用的清理 Kubernetes 集群资源命令
1. Kubernetes 基础对象清理 清理 Evicted 状态的 Pod kubectl get pods --all-namespaces -o wide | grep Evicted | a ...
- Elasticsearch方案选型必须了解的10件事!
文章转载自: https://mp.weixin.qq.com/s?__biz=MzI2NDY1MTA3OQ==&mid=2247484372&idx=1&sn=e863e46 ...
- Elasticsearch:Node 介绍 - 7.9 之后版本
文章转载自:https://elasticstack.blog.csdn.net/article/details/110947372 在 Elastic Stack 7.9 之后的发布中,我们可以直接 ...
- PostgreSQL 删除数据库
PostgreSQL 删除数据库可以用以下三种方式: 1.使用 DROP DATABASE SQL 语句来删除. 2.使用 dropdb 命令来删除. 3.使用 pgAdmin 工具. 注意:删除数据 ...
- 绝杀processOn,这款UML画图神器,阿里字节都用疯了,你还不知道?
大家好,我是陶朱公Boy,又和大家见面了. 前言 在文章开始前,想先问大家一个问题,大家平时在项目需求评审完后,是直接开始编码了呢?还是会先写详细设计文档,后再开始进行编码开发? ☆现实 这个时候可能 ...
- Docker安装MongoDB并使用Navicat连接
MongoDB简介: MongoDB是一个基于分布式文件存储的数据库.由C++语言编写.旨在为WEB应用提供可扩展的高性能数据存储解决方案.是一个介于关系数据库和非关系数据库之间的产品,是非关系数据库 ...
- 5.MongoDB系列之索引(二)
1. $运算符如何使用索引 1.1 低效的运算符 $ne.$not查询可以使用索引,但不是很有效,尽量避免 1.2 范围查询 范围查询其实是多值查询,根据复核索引规则,尽可能先等值精确匹配,然后范围查 ...