摘自:html
http://blueskykong.com/2019/02/18/go-dep-1/git
https://www.cnblogs.com/apocelipes/p/10295096.html#vcs-semvergithub
GOROOT的目的就是告知go当前的安装位置,默认go会安装在/usr/local/go下,但也容许自定义安装位置(经过 export GOROOT=$HOME/go1.9.3
指定)。编译的时候从GOROOT去找SDK的system libarirygolang
GOPATH必需要设置,GOPATH告知go,须要代码(包括本项目即内部依赖和引用外部项目的代码即外部依赖)的时候去哪里查找。GOPATH能够随着项目的不一样而从新设置。chrome
GOPATH下会有3个目录:src、bin、pkg。json
内部依赖管理缓存
$GOPATH/src/
目录去查找须要的代码GOPATH来管理外部依赖工具
go容许import不一样代码库的代码,例如github.com, k8s.io, golang.org等等;对于须要import的代码,可使用 go get 命令取下来放到GOPATH对应的目录中去。例如go get github.com/globalsign/mgo
(下载和建立项目要保持目录一致,这样才能保证可以正确的引用外部导入和内部导入),会下载到$GOPATH/src/github.com/globalsign/mgo
中去,当其余项目在import github.com/globalsign/mgo
的时候也就能找到对应的代码了。fetch
$GOPATH/src
之后,就能够进去go build了(注意,必须将kube-keepalived-vip项目拷贝到$GOPATH/src
目录中,不然go会无视vendor目录,仍然去$GOPATH/src
中去找依赖包)。该工具将项目依赖的外部包拷贝到项目下的 vendor 目录下,并经过 vendor.json 文件来记录依赖包的版本,方便用户使用相对稳定的依赖。ui
使用步骤
#安装 go get -u github.com/kardianos/govendor # 进入项目的根目录 # 建立 vendor 文件夹和 vendor.json 文件,此时文件中只有本项目的信息 govendor init # 拷贝GOPATH下的代码到vendor目录中,更新vendor.json govendor add +external # 列出已经存在的依赖包 govendor list # 找出使用的对应包 govendor list -v fmt # 拉取指定版本的包 govendor fetch golang.org/x/net/context@a4bbce9fcae005b22ae5443f6af064d80a6f5a55 govendor fetch golang.org/x/net/context@v1 # Get latest v1.*.* tag or branch. govendor fetch golang.org/x/net/context@=v1 # Get the tag or branch named "v1".
govendor还能够直接指定依赖包版原本获取包
go module 是go包的集合,是源代码交换和版本化控制的基本单元
go.mod
文件的目录,能够存放于文件系统上的任何位置,而不用管 GOPATH
路径究竟是什么要使用go module
,首先要设置GO111MODULE=on
。
on
,那么不管模块在于何种路径,都会启用模块支持,始终使用 module-aware mode,只根据 go.mod 下载 dependency 而彻底忽略 GOPATH 以及 vendor 目录off
,禁用 go module 功能,go compiler 会始终使用 GOPATH mode,即不管要构建的源码目录是否在 GOPATH 路径下,go compiler 都会在传统的 GOPATH 和 vendor 目录 (仅支持在 GOPATH 目录下的 package) 下搜索目标程序依赖的 go package;auto
,知足如下任一条件时才使用 module-aware mode:
假设你已经有了一个go 项目, 好比在$GOPATH/github.com/smallnest/rpcx
下, 你可使用go mod init github.com/smallnest/rpcx
在这个文件夹下(即模块根目录)建立一个空的go.mod
(只有第一行 module github.com/smallnest/rpcx
即模块导入名称)。
下面是一个简化的go.mod的内容
module my/thing //模块名称 require (//要求的依赖项列表以及版本 one/thing v1.3.2 other/thing v2.5.0 // indirect ... ) exclude (//排除的依赖项,仅在当前模块为主模块时生效 bad/thing v0.7.3 ) replace (//替换的依赖项,仅在当前模块为主模块时生效 src/thing 1.0.2 => dst/thing v1.1.0 )
go get ./...
查找依赖,并记录在go.mod
文件中(你还能够指定 -tags
,这样能够把tags的依赖都查找到)。
执行上面的命令会把go.mod
的latest
版本换成实际的最新的版本,而且会生成一个go.sum
记录每一个依赖库的版本和哈希值,用于验证缓存的依赖项是否知足模块要求
你能够在GOPATH
以外建立新的项目。
go mod init packagename
能够建立一个空的go.mod
,而后你能够在其中增长require github.com/smallnest/rpcx latest
依赖,或者像上面同样让go自动发现和维护。
go mod download
能够下载所须要的依赖,可是依赖并非下载到$GOPATH
中,而是$GOPATH/pkg/mod
中,用来当作缓存,多个项目能够共享缓存的module。
//download 下载依赖的module到本地cache //edit edit go.mod from tools or scripts (编辑go.mod文件) 例如 go mod edit -require="github.com/chromedp/chromedp@v0.1.0",修改依赖关系使用chromedp 的v0.1.0版本 //tidy 增长丢失的module,去掉未用的module,如在项目的开发过程当中, 依赖有变动, 可以使用 go mod tidy 来应用这些变动到 go.mod 文件. //graph print module requirement graph (打印模块依赖图)) //init 在当前文件夹下初始化一个新的module, 建立go.mod文件 //vendor 在项目发布时会要将依赖复制到项目中,会复制modules下载到vendor中, 貌似只会下载你代码中引用的库,而不是go.mod中定义所有的module。 //verify verify dependencies have expected content (校验依赖) //why explain why packages or modules are needed (解释为何须要依赖) //go list -m -json all //依赖详情
go module 功能被集成到 go
命令行工具中,例如,在调用诸如 go build
,go install
,go run
,go test
之类的命令时,将启动相应的操做,如缓存,建立或更新 go.mod
和 go.sum
等
go get -u
将会升级到最新的次要版本或者修订版本go get -u=patch
将会升级到最新的修订版本go get package@version
将会升级到指定的版本号version
golang官方推荐的最佳实践叫作semver
,写全了就是Semantic Versioning
(语义化版本)。形如vX.Y.Z
的形式显然比一串hash更直观,x.y.z, z是修订版本号, y是次要版本号,如此一来包的导入路径发生了变化,不一样的导入路径意味着不一样的包,更具体的规范在这里。