go path问题
当 Go 在 2009 年首次推出时,它并没有随包管理器一起提供。取而代之的是 go get,通过使用它们的导入路径来获取所有源并将其存储在 $ GOPATH/src 中。没有版本控制并且『master』分支表示该软件包的稳定版本。
它有下面特征:
- 代码开发必须在go path src目录下,不然,就有问题。
- 依赖手动管理
- 依赖包没有版本可言
从上面看, go path不算包管理工具.
go mod
Go Modules 是 golang 1.11 新加的特性。Go Modules 不使用 GOPATH 存储每个软件包的单个 git checkout,而是存储带有 go.mod 标记版本的标记版本,并跟踪每个软件包的版本。它生效的配置依赖 GO111MODULE 环境变量。
GO111MODULE
GO111MODULE 有三个值:off, on和auto(默认值)。
- GO111MODULE=off,go命令行将不会支持module功能,寻找依赖包的方式将会沿用旧版本那种通过vendor目录或者GOPATH模式来查找。
- GO111MODULE=on,go命令行会使用modules,而一点也不会去GOPATH目录下查找。
- GO111MODULE=auto,默认值,go命令行将会根据当前目录来决定是否启用module功能。在 Go 1.13 之后, GO111MODULE 的默认行为 (auto) :
- 当存在 go.mod 文件时或处于 GOPATH 外, 其行为均会等同于于 GO111MODULE=on。这意味着在 Go 1.13 下你可以将所有的代码仓库均存储在 GOPATH 下。
- 当处于 GOPATH 内且没有 go.mod 文件存在时其行为会等同于 GO111MODULE=off。
当modules功能启用时,依赖包的存放位置变更为$GOPATH/pkg,允许同一个package多个版本并存,且多个项目可以共享缓存的 module
go mod命令
golang 提供了 go mod命令来管理包。它有以下命令:
命令 | 说明 |
vendor | make vendored copy of dependencies(将依赖复制到vendor下) |
verify | verify dependencies have expected content (验证依赖是否正确) |
download | download modules to local cache(下载依赖包) |
edit | edit go.mod from tools or scripts(编辑go.mod) |
graph | print module requirement graph (打印模块依赖图) |
init | initialize new module in current directory(在当前目录初始化mod) |
tidy | add missing and remove unused modules(拉取缺少的模块,移除不用的模块) |
why | explain why packages or modules are needed(解释为什么需要依赖) |
使用 go mod
初始化项目
mkdir Gone
cd Gone
go mod init Gone
go.mod文件一旦创建后,它的内容将会被go toolchain全面掌控。go toolchain会在各类命令执行时,比如go get、go build、go mod等修改和维护go.mod文件。
- 可以使用命令 go list -m -u all 来检查可以升级的package,使用go get -u need-upgrade-package 升级后会将新的依赖版本更新到go.mod
- 也可以使用 go get -u 升级所有依赖。
go module 安装 package 的原則是先拉最新的 release tag,若无tag则拉最新的commit
go get升级
运行 go get -u 将会升级到最新的次要版本或者修订版本(x.y.z, z是修订版本号, y是次要版本号)
运行 go get -u=patch 将会升级到最新的修订版本
运行 go get package@version 将会升级到指定的版本号version
运行go get如果有版本的更改,那么go.mod文件也会更改
依赖包中出现版本号
我们在 import 的包中,会看到 "github.com/hajimehoshi/ebiten/v2" 这样的。这个适用gomod的特性。如果仍用这样的方式import,就必须用gomod。用GOPATH会报找不到包的。
模块在 Go 中确定了一个重要的原则,即 “导入兼容性规则”
如果旧包和新包的导入路径相同,新包必须向后兼容旧的包
根据这条原则,一个软件包新的主版本没有向后兼容以前的版本。这意味着这个软件包新的主版本必须使用和之前版本不同的模块路径。从 v2 开始,主版本号必须出现在模块路径的结尾(在 go.mod 文件的 module 语句中声明)。
参考:Go Modules : v2 及更高版本