依赖管理系统 go modules

  • golang在1.11版本中引入了新的包管理工具 go mod

  • 类似于maven包管理(多项目公用),而之前的vendor类似于node的node_modules管理(各个项目一份)

  • 依赖信息添加到go.mod文件中,依赖版本哈希信息存到go.sum文件中

  • 使用go mod时,必须在GOPATH目录之外新建一个目录

  • 当我们使用 go build、go test 以及 go list 时,Go 会自动更新 go.mod 文件,并且将依赖关系写入其中

  • go mudules 版本规则,举例:vX.0.0-yyyymmddhhmmss-abcdefabcdef

    • vX.Y.Z 是仓库打的标签版本,go modules是根据仓库标签来确定版本号的,因此我们发布版本时,需要给我们的仓库打上一个标签版本号。
    • yyyymmddhhmmss 是时间戳
    • abcdefabcdef是hash值,我们自己指定版本时只需要制定版本号即可,没有版本tag的则需要找到对应commit的时间和hash值。
  • go get

    首先,go get解析需要新增哪些依赖。可以通过在包名后添加@version或者@branch等方式来取代命令的默认更新行为。如果后缀指定为@none,则表明该依赖应该被移除。

    其次,go get会下载、编译、安装指定的包。包的安装模式也是被允许的,比如使用go get golang.org/x/perf/cmd/..来更新cmd下的所有子包。

    • 运行 go get -u 将会升级到最新的次要版本或者修订版本(x.y.z, z是修订版本号, y是次要版本号)
    • 运行 go get -u=patch 将会升级到最新的修订版本
    • 运行 go get package@version 将会升级到指定的版本号version
    • 运行go get如果有版本的更改,那么go.mod文件也会更改
    go get -v github.com/gorilla/mux    # 匹配最新的一个 tag
    go get -v github.com/gorilla/mux@latest    # 和上面一样
    go get -v github.com/gorilla/mux@v1.6.2    # 匹配 v1.6.2
    go get github.com/gorilla/mux@e3702bed2 # 匹配 v1.6.2
    go get github.com/gorilla/mux@c856192   # 匹配 c85619274f5d
    go get github.com/gorilla/mux@master    # 匹配 master 分支

    latest 匹配最新的 tag。
    v1.2.6 完整版本的写法。
    v1、v1.2 匹配带这个前缀的最新版本,如果最新版是 1.2.7,它们会匹配 1.2.7。
    c856192 版本 hash 前缀、分支名、无语义化的标签,在 go.mod 里都会会使用约定写法 v0.0.0-20180517173623-c85619274f5d,也被称作伪版本
  • 设置 GO111MODULE:可以用环境变量 GO111MODULE 开启或关闭模块支持,它有三个可选值:off、on、auto,默认值是 auto。

    • GO111MODULE=off 无模块支持,go 会从 GOPATH 和 vendor 文件夹寻找包。
    • GO111MODULE=on 模块支持,go 会忽略 GOPATH 和 vendor 文件夹,只根据 go.mod 下载依赖。
    • GO111MODULE=auto 在 $GOPATH/src 外面且根目录有 go.mod 文件时,开启模块支持。

    在使用模块的时候,GOPATH 是无意义的,不过它还是会把下载的依赖储存在 $GOPATH/pkg/mod 中,也会把 go install 的结果放在 $GOPATH/bin 中

  • Modules and vendoring

    当使用module时,Go命令会完全忽略vendor目录。为了跟之前Go的依赖管理相兼容,我们可以使用go mod vendor 创建vendor目录来存储编译代码的依赖包。如果在编译的时候要使用vendor中的依赖包,需要使用go build -mod=vendor命令。

  • go module设置代理:export GOPROXY=https://goproxy.io

  • go.mod文件

    • module 语句指定包的名字(路径)

    • require 语句指定的依赖项模块

    • exclude 语句可以忽略依赖项模块

    • indirect 表示这个库是间接引用进来的

    • incompatible 猜测意思:主要版本不兼容

    • replace 语句可以替换依赖项模块

      由于某些已知的原因,并不是所有的package都能成功下载,比如:golang.org下的包。
      modules 可以通过在 go.mod 文件中使用 replace 指令替换成github上对应的库,比如:

      replace (
              golang.org/x/crypto v0.0.0-20190313024323-a1f597ede03a => github.com/golang/crypto v0.0.0-20190313024323-a1f597ede03a
              golang.org/x/text v0.3.0 => github.com/golang/text v0.3.0
      )
      

      依赖库中的replace对你的主go.mod不起作用,比如github.com/smallnest/rpcx的go.mod已经增加了replace,但是你的go.mod虽然require了rpcx的库,但是没有设置replace的话, go get还是会访问golang.org/x

  • 命令:

    • go mod init 初始化module
    • go mod edit -require="github.com/gin-gonic/gin@v1.1.4" 可以主动修改 go.md 文件中依赖的版本号
    • go mod tidy 自动清理掉不需要的依赖项,同时可以将依赖项更新到当前版本
    • go list -m --json all 以json格式显示所有项目使用的依赖包
    • go mod edit -fmt 格式化 go.mod 文件
    • go mod vendor 生成 vendor 文件夹,方便利用vendor进行编译打包
    • go get 获取依赖的特定版本,用来升级和降级依赖。可以自动修改 go.mod 文件,而且依赖的依赖版本号也可能会变。
      在 go.mod 中使用 exclude 排除的包,不能 go get 下来
    • go build -mod=vendor 使用vendor目录构建
    • go build -mod=readonly 防止隐式修改go.mod,如果遇到有隐式修改的情况会报错,可以用来测试 go.mod 中的依赖是否整洁,但如果明确调用了go mod、go get 命令则依然会导致 go.mod 文件被修改
    • go mod download 命令用于将依赖包缓存到本地Cache起来,类似于maven的.m2/repository。Mod Cache 路径默认在$GOPATH/pkg 下面:$GOPATH/pkg/mod
    • go mod graph 打印模块依赖图
    • go mod verify 验证依赖是否正确
    • go list -m -u all 来检查可以升级的package
    • go get -u 升级所有依赖

refer to

1、goland

2、working with go modules

3、go modules详解

4、Modules

5、Go依赖模块版本之Module避坑使用详解

6、跳出Go module的泥潭

7、golang进阶:go1.12 mod 教程

posted @ 2019-05-01 00:19  脚本小娃子  阅读(1746)  评论(0编辑  收藏  举报