GO Modules
也称作go mod
是golang 官方最新的几个golang 版本中推出的包
管理方式或者称作模块
支持golang 中
modules
(模块)是什么意思呢?一个模块是一系列 Go 代码包 的集合,它们保存在同一个文件树中。文件树的根目录中包含了一个
go.mod
文件。go.mod
文件定义了一个模块的 module path,这就是模块根目录的导入路径。go.mod
文件还定义了模块的 dependency requirements(依赖项要求),即为了编译本模块,需要用到哪些其它的模块。每一项依赖项要求都包含了依赖项的 module path,还要指定它的语义版本号。在最新的golang版本
golang 1.13
中是默认的包管理方式,那么在golang的后期版本中Go Modules
基本可以认为是官方推荐的依赖管理工具
GO modules 是解决啥问题的?
Golang在早期的版本中(golang 1.11版本之前) 包管理一直没有一个统一方案,表现出问题如:
- 所有的依赖包都必须在
GOPATH
同一个库只能保存一个版本的代码,那么不同的项目要依赖同一个包的不同版本那就很尴尬了.- 工作目录必须在
GOPATH/src
目录下使用了
Go Modules
之后就可在GOPATh/src
之外创建目录和管理包了我们大概回顾一下
golang 1.5
版本之前所有的依赖包都必须放在GOPATH
下面,没有版本管理golang 1.5
版本之后推出vendor
机制golang 1.9
版本出现了包管理工具dep
golang1.11
版本推出modules
机制对包进行管理,在之后的版本中modules
逐步得到了加强, 在golang1.13
中成为默认的包管理方式并且是默认开启的
go mod
的命令其实不多我们打开命令行工具
$ go help mod Go mod provides access to operations on modules. Note that support for modules is built into all the go commands, not just 'go mod'. For example, day-to-day adding, removing, upgrading, and downgrading of dependencies should be done using 'go get'. See 'go help modules' for an overview of module functionality. Usage: go mod
[arguments] The commands are: download download modules to local cache edit edit go.mod from tools or scripts graph print module requirement graph init initialize new module in current directory tidy add missing and remove unused modules vendor make vendored copy of dependencies verify verify dependencies have expected content why explain why packages or modules are needed Use "go help mod " for more information about a command. 显示的
go mod
实际命令只有如下几个
命令 意思 go mod download 下载依赖的Module到本地缓存 go mod edit 编辑go.mod文件 go mod graph 打印模块依赖图 go mod init 初始化当前目录中的新模块,创建go.mod文件 go mod tidy 增加缺失的Module,删除无效的Module go mod vendor 将依赖复制到vendor下 go mod verify 校验依赖 go mod why 解释package或者modules为啥被依赖
我们在非
GOPATH/src
目录下执行
go mod init
后面是模块名称 ,名称自定义即可$ go mod init github.com/captain/modDemo go: creating new go.mod: module github.com/captain/modDemo
这样在项目(模块)目录下多出了一个文件
go.mod
文件我们看看
go.mod
中的内容module github.com/captain/modDemo go 1.12
我们下载一个依赖包试试
// 执行 如下命令 go get -u github.com/gin-gonic/gin
初次执行下依赖包的命令后会多出一个文件
go.sum
go.sum
是由 go命令行工具维护的,其中记录了每个依赖库的版本和哈希值,其作用是确保项目依赖的模块不会发生变化执行完之后,我们再看看
go.mod
的内容module github.com/apiDemo go 1.12 require ( github.com/gin-gonic/gin v1.5.0 // indirect github.com/go-playground/universal-translator v0.17.0 // indirect github.com/json-iterator/go v1.1.8 // indirect github.com/leodido/go-urn v1.2.0 // indirect github.com/mattn/go-isatty v0.0.10 // indirect github.com/modern-go/concurrent v0.0.0-20180306012644-bacd9c7ef1dd // indirect github.com/modern-go/reflect2 v1.0.1 // indirect github.com/stretchr/objx v0.2.0 // indirect golang.org/x/crypto v0.0.0-20191128160524-b544559bb6d1 // indirect golang.org/x/net v0.0.0-20191126235420-ef20fe5d7933 // indirect golang.org/x/sync v0.0.0-20190911185100-cd5d95a43a6e // indirect golang.org/x/sys v0.0.0-20191128015809-6d18c012aee9 // indirect golang.org/x/tools v0.0.0-20191130070609-6e064ea0cf2d // indirect golang.org/x/xerrors v0.0.0-20191011141410-1b5146add898 // indirect gopkg.in/check.v1 v1.0.0-20190902080502-41f04d3bba15 // indirect gopkg.in/go-playground/validator.v9 v9.30.2 // indirect gopkg.in/yaml.v2 v2.2.7 // indirect )
go.mod
文件简介:
module
用来定义包名和我们初始化的包名是一致的
require
定义依赖的包及其对应的版本
indirect
标识间接引用
go list -m all
列出当前模块和它的依赖库$ go list -m all github.com/captain/modDemo github.com/davecgh/go-spew v1.1.1 github.com/gin-contrib/sse v0.1.0 github.com/gin-gonic/gin v1.5.0 github.com/go-playground/locales v0.13.0 github.com/go-playground/universal-translator v0.17.0 github.com/golang/protobuf v1.3.2 github.com/google/gofuzz v1.0.0 github.com/json-iterator/go v1.1.8 github.com/leodido/go-urn v1.2.0 github.com/mattn/go-isatty v0.0.10 github.com/modern-go/concurrent v0.0.0-20180306012644-bacd9c7ef1dd github.com/modern-go/reflect2 v1.0.1 github.com/pmezard/go-difflib v1.0.0 github.com/stretchr/objx v0.2.0 github.com/stretchr/testify v1.4.0 github.com/ugorji/go v1.1.7 github.com/ugorji/go/codec v1.1.7 golang.org/x/crypto v0.0.0-20191206172530-e9b2fee46413 golang.org/x/net v0.0.0-20191207000613-e7e4b65ae663 golang.org/x/sync v0.0.0-20190911185100-cd5d95a43a6e golang.org/x/sys v0.0.0-20191206220618-eeba5f6aabab golang.org/x/text v0.3.2 golang.org/x/tools v0.0.0-20191206204035-259af5ff87bd golang.org/x/xerrors v0.0.0-20191204190536-9bdfabe68543 gopkg.in/check.v1 v1.0.0-20190902080502-41f04d3bba15 gopkg.in/go-playground/assert.v1 v1.2.1 gopkg.in/go-playground/validator.v9 v9.30.2 gopkg.in/yaml.v2 v2.2.7
go list -m -versions 库名地址
列出一个模块能用的版本$ go list -m -versions github.com/gin-gonic/gin github.com/gin-gonic/gin v1.1.1 v1.1.2 v1.1.3 v1.1.4 v1.3.0 v1.4.0 v1.5.0
go mod tidy
删除无效的modules$ go mod tidy $ go list -m all github.com/captain/modDemo
我们拿比较常见的 一个库xrom
做示例 下载指定的版本
可见
xorm
可用的版本很多
$ go list -m -versions github.com/go-xorm/xorm
github.com/go-xorm/xorm v0.2.1 v0.2.2 v0.2.3 v0.3.1 v0.3.2 v0.4.1 v0.4.2 v0.4.3 v0.4.4 v0.4.5 v0.5.0 v0.5.1 v0.5.2 v0.5.3 v0.5.4 v0.5.6 v0.5.7 v0.5.8 v0.6.2 v0.6.3 v0.6.4 v0.6.5 v0.6.6 v0.7.0 v0.7.1 v0.7.2 v0.7.3 v0.7.4 v0.7.5 v0.7.6 v0.7.7 v0.7.8 v0.7.9
go mod
想下载指定的版本 通常我们有三种做法
go get 包路径@v版本号
go get 包路径@分支
分支是指在github上提交的分支
go get 包路径@git提交的哈希
我们看到目前
xorm
最新版本是v0.7.9
但是我想下载比较旧一点的版本v0.7.5
$ go get github.com/go-xorm/[email protected] go: finding github.com/go-xorm/xorm v0.7.5 go: finding github.com/jackc/pgx v3.3.0+incompatible go: finding xorm.io/core v0.7.0 go: finding github.com/denisenkom/go-mssqldb v0.0.0-20190707035753-2be1aa521ff4 go: finding github.com/cockroachdb/apd v1.1.0 go: finding xorm.io/builder v0.3.5 go: finding github.com/jackc/fake v0.0.0-20150926172116-812a484cc733 go: finding github.com/shopspring/decimal v0.0.0-20180709203117-cd690d0c9e24 go: finding github.com/ziutek/mymysql v1.5.4 go: finding github.com/go-xorm/sqlfiddle v0.0.0-20180821085327-62ce714f951a go: finding golang.org/x/tools v0.0.0-20190606050223-4d9ae51c2468 go: finding google.golang.org/appengine v1.6.0 go: finding golang.org/x/sys v0.0.0-20190602015325-4c4f7f33c9ed go: downloading github.com/go-xorm/xorm v0.7.5 go: extracting github.com/go-xorm/xorm v0.7.5 go: downloading xorm.io/builder v0.3.5 go: downloading xorm.io/core v0.7.0 go: extracting xorm.io/builder v0.3.5 go: extracting xorm.io/core v0.7.0 $ cat go.mod module github.com/captain/modDemo go 1.12 require github.com/go-xorm/xorm v0.7.5 // indirect
通常下载一个包没有明确指定版本,那么下载的包就是当前的最新版本
我们还是拿
xorm
包作为示例$ go get github.com/go-xorm/xorm go: finding github.com/jackc/pgx v3.6.0+incompatible go: finding xorm.io/builder v0.3.6 go: finding xorm.io/core v0.7.2-0.20190928055935-90aeac8d08eb go: downloading github.com/go-xorm/xorm v0.7.9 go: extracting github.com/go-xorm/xorm v0.7.9 go: downloading xorm.io/core v0.7.2-0.20190928055935-90aeac8d08eb go: downloading xorm.io/builder v0.3.6 go: extracting xorm.io/core v0.7.2-0.20190928055935-90aeac8d08eb go: extracting xorm.io/builder v0.3.6 $ cat go.mod module github.com/captain/modDemo go 1.12 require ( github.com/go-xorm/xorm v0.7.9 // indirect github.com/golang/protobuf v1.3.1 // indirect github.com/kr/pretty v0.1.0 // indirect github.com/satori/go.uuid v1.2.0 // indirect golang.org/x/crypto v0.0.0-20190605123033-f99c8df09eb5 // indirect golang.org/x/net v0.0.0-20190603091049-60506f45cf65 // indirect golang.org/x/sys v0.0.0-20190602015325-4c4f7f33c9ed // indirect golang.org/x/text v0.3.2 // indirect golang.org/x/tools v0.0.0-20190606050223-4d9ae51c2468 // indirect )
我们看到了结果现在
xorm
更新到了当前最新版本v0.7.9
那我可不可以更新到一个指定的版本呢?其实做法是一样的就是指定一个版本号就可以了
$ go get github.com/go-xorm/[email protected] go: finding github.com/go-xorm/xorm v0.7.7 go: finding xorm.io/builder v0.3.6-0.20190906062455-b937eb46ecfb go: downloading github.com/go-xorm/xorm v0.7.7 go: extracting github.com/go-xorm/xorm v0.7.7 $ cat go.mod module github.com/captain/modDemo go 1.12 require ( github.com/go-xorm/xorm v0.7.7 // indirect github.com/golang/protobuf v1.3.1 // indirect github.com/kr/pretty v0.1.0 // indirect github.com/satori/go.uuid v1.2.0 // indirect golang.org/x/crypto v0.0.0-20190605123033-f99c8df09eb5 // indirect golang.org/x/net v0.0.0-20190603091049-60506f45cf65 // indirect golang.org/x/sys v0.0.0-20190602015325-4c4f7f33c9ed // indirect golang.org/x/text v0.3.2 // indirect golang.org/x/tools v0.0.0-20190606050223-4d9ae51c2468 // indirect xorm.io/builder v0.3.6 // indirect xorm.io/core v0.7.2-0.20190928055935-90aeac8d08eb // indirect )
go get
命令可以远程拉取更新代码包和依赖包,并自动完成编译和安装
go get
命令实际是分成了两步操作 1. 下载源码包 2.执行go insert
简单的理解是 :
go get
=git clone
+go insert
这是一个常见的远程包的格式 : github.com/go-xorm/xorm
github.com
是网站域名
go-xorm
我们可以理解问作者或者机构名称
xorm
就是项目名称
go get
命令的具体详情可以查看它的帮助命令
对命令附带的可用参数有很详细的介绍
$ go help get
usage: go get [-d] [-m] [-u] [-v] [-insecure] [build flags] [packages]
Get resolves and adds dependencies to the current development module
and then builds and installs them.
The first step is to resolve which dependencies to add.
我们只看几个很常见的
-d
只下载,而不安装
-u
强制使用网络去更新包和它的依赖包
-v
显示执行的命令
-t
同时也下载需要为运行测试所需要的包
-fix
让命令程序在下载代码包后先执行修正动作,而后再进行编译和安装。
-x
打印安装的具体过程
-insecure
允许命令程序使用非安全的scheme(如HTTP)去下载指定的代码包
-f
仅在使用-u
标记时才有效。该标记会让命令程序忽略掉对已下载代码包的导入路径的检查