真的,Go的包管理工具之发展过程充分体现了什么叫折腾
。 (叹气~~~)
想想Java的Maven, Nodejs的NPM,还有我们赞颂一万遍也不过分的Python包管理,为什么生命总要浪费在这些事情上面呢? 陷入了深深的沉思~~
从Go1.11版本发布Go MODULE之后,我希望这是最后一次折腾包管理
这件事情,神呐,诚心诚意的祈祷中~~
摘抄备忘下:
Modules 是作为 experiment feature 加入到不久前正式发布的 Go 1.11 中的。 按照 Go 的惯例,在新的 experiment feature 首次加入时,都会有一个特性开关,go modules 也不例外,GO111MODULE 这个临时的环境变量就是 go modules 特性的 experiment 开关。
download download modules to local cache (下载依赖的 modules 到本地 cache)
edit edit go.mod from tools or scripts (编辑 go.mod 文件)
graph print module requirement graph (打印模块依赖图)
init initialize new module in current directory (再当前文件夹下初始化一个新的 module, 创建 go.mod 文件)
tidy add missing and remove unused modules (增加丢失的 modules,去掉未用的 modules)
vendor make vendored copy of dependencies (将依赖复制到 vendor 下)
verify verify dependencies have expected content (校验依赖)
why explain why packages or modules are needed (解释为什么需要依赖)
假设你已经有了一个 go 项目, 比如在$GOPATH/github.com/brain-zhang/hello下, 你可以使用go mod init github.com/brain-zhang/hello在这个文件夹下创建一个空的 go.mod (只有第一行 module github.com/brain-zhang/hello)。
然后你可以通过 go get ./…让它查找依赖,并记录在 go.mod 文件中 (你还可以指定 -tags, 这样可以把 tags 的依赖都查找到)。
通过go mod tidy也可以用来为 go.mod 增加丢失的依赖,删除不需要的依赖,但是我不确定它怎么处理tags。
执行上面的命令会把 go.mod 的latest版本换成实际的最新的版本,并且会生成一个go.sum记录每个依赖库的版本和哈希值。
在国内访问golang.org/x的各个包都需要,你可以在 go.mod 中使用replace替换成 github 上对应的库。
replace (
golang.org/x/crypto v0.0.0-20180820150726-614d502a4dac => github.com/golang/crypto v0.0.0-20180820150726-614d502a4dac
golang.org/x/net v0.0.0-20180821023952-922f4815f713 => github.com/golang/net v0.0.0-20180826012351-8a410e7b638d
golang.org/x/text v0.3.0 => github.com/golang/text v0.3.0
)
依赖库中的replace对你的主 go.mod 不起作用,比如github.com/brain-zhang/hello的 go.mod 已经增加了replace, 但是你的 go.mod 虽然require了rpcx的库,但是没有设置replace的话, go get还是会访问golang.org/x。
所以如果想编译哪个项目,就在哪个项目中增加replace。
下面的版本都是合法的:
gopkg.in/tomb.v1 v1.0.0-20141024135613-dd632973f1e7
gopkg.in/vmihailenco/msgpack.v2 v2.9.1
gopkg.in/yaml.v2 <=v2.2.1
github.com/tatsushid/go-fastping v0.0.0-20160109021039-d7bb493dee3e
latest
版本号遵循如下规律:
vX.Y.Z-pre.0.yyyymmddhhmmss-abcdefabcdef
vX.0.0-yyyymmddhhmmss-abcdefabcdef
vX.Y.(Z+1)-0.yyyymmddhhmmss-abcdefabcdef
vX.Y.Z
也就是版本号 + 时间戳 + hash,我们自己指定版本时只需要制定版本号即可,没有版本 tag 的则需要找到对应 commit 的时间和 hash 值。
另外版本号是支持 query 表达式的,其求值算法是 “选择最接近于比较目标的版本 (tagged version)”,即上文中的 gopkg.in/yaml.v2 会找不高于 v2.2.1 的最高版本。
https://roberto.selbach.ca/intro-to-go-modules/
https://github.com/golang/go/wiki/Modules
https://windmt.com/2018/11/08/first-look-go-modules/