go

go mod

go mod的使用技巧

Posted by Liangjf on October 4, 2019

go mod的使用技巧

go mod的强大

go mod 确实方便,无视翻墙问题,下载啥都可以。

go mod常用命令

go mod 一般是使用以下命令:

  • go mod init xxx
  • go mod tidy
  • go mod edit

这里着重说下 go mod edit 的作用。

go mod edit 用来修改 go.mod 文件的包的版本关系。

  • 修改包版本
  • 自定义本地包。方便测试(本地包需要是 module 方式的)

      module test
    
      go 1.12
    
      require (
          gopkg v0.0.0
      )
    
      replace gopkg v0.0.0 => ../gopkg
    

这样就可以实现 module 方式,调用本地包了。

go mod edit 修改 go.mod,然而它有两点缺陷:

  • 首先是它的-require必须接受“package@version”这种形式,缺一不可,而且不能识别文档规定的masterlatest标志。
  • edit只适合用于修改依赖版本,给package改名,屏蔽特定的package这三个功能,不适用于添加依赖。

由于以上两个特点,因此有了新版的 go get特性。

新版的go get特性

  • go get会自动下载并安装package,然后更新到go.mod
  • 使用go get package[@version]来安装指定版本的package,不指定version时默认行为和go get package@latest一样
  • version可以是vx.y.z这种形式或者直接使用commitchecksum,也可以是master或者latest
  • versionlatest时,也就是默认行为,对于有tagspackage,会选取最新的tag,对于没有tagspackage,则选取最新的commit
  • versionmaster时,不管package有没有打tag,都会选择master分支的最新commit
  • 可以在version前使用>,>=,<,<=,表示选取的版本不得超过/低于version,在这个范围内的符合latest条件的版本
  • go get -u可以更新packagelatest版本
  • go get -u=patch将只更新小版本,例如从v1.2.4v1.2.5
  • 当想要修改package的版本时,只需要go get package@指定的version即可

注意两个坑:

  • 没开go mod方式,直接go get,就是拉取最新的master分支。

  • 开启go mod,直接go get,拉取的是有打tag,就下载tag的版本,没打tag,就拉取最新的master分支

例子

背景

公司有两个私有项目放在私有 git 上,这里叫 A 和 B,A 项目有引用 B 的包

  • 1、go mod 会自动下载最新 tag 的代码,如果没有会自动引入最新的 master 提交,这样没问题。但是有 tag 的情况下只会引入 tag,没法引用最新的代码(如果 B 有改动必须打 Tag ?)
  • 2、上面的问题可以用 replace 的方案解决,但是如果团队开发,大家的 gopath 都不一致,go mod 文件会有多份,如何解决?

解决方案

  • 使用replace的相对路径(./或../形式) ,比如:replace github.com/b => ../b
  • 手动go get -u github.com/b@branch(或者是commit),go.mod会自动生成 github.com/b@V0.0.0-data-hash