飞道的博客

Go 1.16 中关于 go get 和 go install 你必须注意的地方

737人阅读  评论(0)

Go (golang) 已于 18 日发布了 1.16 beta1 版本,至此其主体功能已经基本确定。我看大多数人都在关注 Go 在苹果(Apple) M1 上的支持,甚至 Go 官方博客中也有一篇专门的说明 Go on ARM and Beyond[1] ,来介绍 Go 在此方面的支持。

我就不凑热闹了,我来聊聊 Go 1.16 中关于 go getgo install 你需要注意的地方。

目前 Docker 官方镜像尚未发布,我是本地构建了个镜像来使用。


   
  1. (MoeLove) ➜   go version
  2. go version go1 .16beta1 linux/amd64

概览

Go 1.16 中包含着大量的 Modules 相关的更新,详细内容可直接查看其 Release Note[2]。整体而言,包含以下要点:

  • GO111MODULE 默认为 on ,如果要恢复到之前的行为,则需要将 GO111MODULE 设置为 auto ,这样差不多意味着 GOPATH 模式要逐步淡出人们的视野了;

  • go install 命令可以接受一个版本后缀了,(例如,go install sigs.k8s.io/kind@v0.9.0),并且它是在模块感知的模式下运行,可忽略当前目录或上层目录的 go.mod 文件。这对于在不影响主模块依赖的情况下,安装二进制很方便;

  • 在将来,go install 被设计为“用于构建和安装二进制文件”, go get 则被设计为 “用于编辑 go.mod 变更依赖”,并且使用时,应该与 -d 参数共用,在将来版本中 -d 可能会默认启用;

  • go buildgo test 默认情况下不再修改 go.modgo.sum。可通过 go mod tidygo get 或者手动完成;

总结而言,关于 go installgo get 必须要注意的是:

  • 基本上 go install <package>@<version> 是用于命令的全局安装:

    • 例如:go install sigs.k8s.io/kind@v0.9.0;

  • go get 安装二进制的功能,后续版本将会删除;

  • go get 主要被设计为修改 go.mod 追加依赖之类的,但还存在类似 go mod tidy 之类的命令,所以使用频率可能不会很高;

Go 1.16 中已解决的工具安装问题

到目前为止,Go 一直使用 go get 命令,将我们需要的工具安装到 $GOPATH/bin 目录下,但这种方式存在一个很严重的问题。go get 由于具备更改 go.mod 文件的能力,因此我们 必须要避免执行 go get 命令时,让它接触到我们的 go.mod 文件 ,否则它会将我们安装的工具作为一个依赖。

目前的解决方案通常是:

(MoeLove) ➜  cd $(mktemp -d); GO111MODULE=on go get sigs.k8s.io/kind@v0.9.0

自 1.16 开始,我们可以直接使用下面的方式:

(MoeLove) ➜  go install sigs.k8s.io/kind@v0.9.0

非常的简单直观。需要注意的是 go install <package>@<version> 是从 1.16 开始增加的,无论你当前是否在一个模块下,此命令都会在 $GOPATH/bin 下安装指定版本的工具。

此外由于 Go 1.16 中 GO111MODULE 默认是打开的,go install 不会修改 go.mod 之类的文件,不会造成任何意外。

注意:

@version 只能安装主软件包。非主程序包不受此格式约束。

关于不带 @versiongo install

  • 在模块外,不带 @version 是无法安装的,会有如下错误:


   
  1. (MoeLove) ➜   go install  -v sigs.k8s.io/kind
  2. go install: version is required when current directory is not in a module
  3.         Try  'go install sigs.k8s.io/kind@latest' to install the latest version
  • 如果你在模块目录中,并且你不带 @version 执行安装的话,只能安装 go.mod 中已经包含的版本。并且不能安装未出现在 go.mod 中的包。


   
  1. (MoeLove) ➜  mkdir -p / go/src/github.com/moelove/iris
  2. (MoeLove) ➜  cd / go/src/github.com/moelove/iris
  3. # 初始化模块
  4. (MoeLove) ➜  / go/src/github.com/moelove/iris  go mod init
  5. go: creating  new  go.mod: module github.com/moelove/iris
  6. (MoeLove) ➜  / go/src/github.com/moelove/iris cat  go.mod 
  7. module github.com/moelove/iris
  8. go  1.16
  9. # 不带 @version 无法安装
  10. (MoeLove) ➜  / go/src/github.com/moelove/iris  go install -v sigs.k8s.io/kind
  11. no required module provides  package sigs.k8s.io/kind; try  'go get -d sigs.k8s.io/kind' to add it
  12. # 用  go get -d 下载
  13. (MoeLove) ➜  / go/src/github.com/moelove/iris  go get -d sigs.k8s.io/kind
  14. go get: added sigs.k8s.io/kind v0 .9 .0
  15. # 可以看到已经被添加到了模块依赖中
  16. (MoeLove) ➜  / go/src/github.com/moelove/iris cat  go.mod 
  17. module github.com/moelove/iris
  18. go  1.16
  19. require sigs.k8s.io/kind v0 .9 .0  // indirect
  20. # 删除本地的 kind 工具
  21. (MoeLove) ➜  / go/src/github.com/moelove/iris which kind
  22. / go/bin/kind
  23. (MoeLove) ➜  / go/src/github.com/moelove/iris rm / go/bin/kind
  24. (MoeLove) ➜  / go/src/github.com/moelove/iris which kind
  25. # 不带 @version 进行安装
  26. (MoeLove) ➜  / go/src/github.com/moelove/iris  go install -v sigs.k8s.io/kind
  27. (MoeLove) ➜  / go/src/github.com/moelove/iris which kind
  28. / go/bin/kind
  29. (MoeLove) ➜  / go/src/github.com/moelove/iris kind version
  30. kind v0 .9 .0 go1 .16beta1 linux/amd64

关于 go getgo.mod

go get 将二进制安装相关的功能都转移到了 go install, 仅作为用于编辑 go.mod 文件的命令存在。在后续版本(计划是 Go 1.17)中删掉 go get 安装二进制的功能,接下来 go get 的行为就等同于我们现在执行 go get -d 命令了,仅需下载源码,并将依赖添加至 go.mod 即可。

go.mod 如何编辑

在 Go 1.16 中,另一个行为变更是 go buildgo test 不会自动编辑 go.mod 了,基于以上信息,Go 1.16 中将进行如下处理:

  • 通过在代码中修改 import 语句,来修改 go.mod

    • go get 可用于添加新模块;

    • go mod tidy 删除掉无用的模块;

  • 将未导入的模块写入 go.mod:

    • go get <package>[@<version>];

    • go mod tidy 也可以;

    • 手动编辑;

从 1.15 升级需要注意什么?

由于 go buildgo test 不会自动编辑 go.mod 了,所以可以将原本的行为通过 go mod tidy 共同处理。

总结

Go 1.16 中 go installgo get 方面有些不兼容的变更,但是 1.16 中模块更加简洁,减少了使用时的心智负担,我还是很期待这个版本的。


欢迎订阅我的文章公众号【MoeLove】

TheMoeLove

参考资料

[1]

Go on ARM and Beyond: https://blog.golang.org/ports

[2]

Go 1.16 Release Note: https://tip.golang.org/doc/go1.16#tools


转载:https://blog.csdn.net/tao12345666333/article/details/111413070
查看评论
* 以上用户言论只代表其个人观点,不代表本网站的观点或立场