作者:@apocelipes
本文为作者原创,转载请注明出处:https://www.cnblogs.com/apocelipes/p/10295096.html
还有半个月go1.12就要发布了。这是首个将go modules纳入正式支持的稳定版本。
距离go modules随着go1.11正式面向广大开发者进行体验也已经过去了半年,这段时间go modules也发生了一些变化,借此机会我想再次深入探讨go modules的使用,同时对这个新生包管理方案做一些思考。
本文索引
版本控制和语义化版本
包的版本控制总是一个包管理器绕不开的古老话题,自然对于我们的go modules也是这样。
我们将学习一种新的版本指定方式,然后深入地探讨一下golang官方推荐的semver即语义化版本。
控制包版本
在讨论go get进行包管理时我们曾经讨论过如何对包版本进行控制(文章在此),支持的格式如下:
vX.Y.Z-pre.0.yyyymmddhhmmss-abcdefabcdef vX.0.0-yyyymmddhhmmss-abcdefabcdef vX.Y.(Z+1)-0.yyyymmddhhmmss-abcdefabcdef vX.Y.Z在go.mod文件中我们也需要这样指定,否则go mod无法正常工作,这带来了2个痛点:
- 目标库需要打上符合要求的tag,如果tag不符合要求不排除日后出现兼容问题(目前来说只要正确指定tag就行,唯一的特殊情况在下一节介绍)
- 如果目标库没有打上tag,那么就必须毫无差错的编写大串的版本信息,大大加重了使用者的负担
基于以上原因,现在可以直接使用commit的hash来指定版本,如下:
# 使用go get时 go get github.com/mqu/go-notify@ef6f6f49 # 在go.mod中指定 module my-module require ( // other packages github.com/mqu/go-notify ef6f6f49 )随后我们运行go build或go mod tidy,这两条命令会整理并更新go.mod文件,更新后的文件会是这样:
module my-module require ( github.com/mattn/go-gtk v0.0.0-20181205025739-e9a6766929f6 // indirect github.com/mqu/go-notify v0.0.0-20130719194048-ef6f6f49d093 )可以看到hash信息自动扩充成了符合要求的版本信息,今后可以依赖这一特性简化包版本的指定。
对于hash信息只有两个要求:
- 指定hash信息时不要在前面加上
v,只需要给出commit hash即可 - hash至少需要8位,与git等工具不同,少于8位会导致go mod无法找到包的对应版本,推荐与go mod保持一致给出12位长度的hash
然而这和我们理想中的版本控制方式似乎还是有些出入,是不是觉得。。。有点不直观?接下来介绍的语义化版本也许能带来一些改观。
语义化版本
golang官方推荐的最佳实践叫做semver,这是一个简称,写全了就是Semantic Versioning,也就是语义化版本。
何谓语义化
通俗地说,就是一种清晰可读的,明确反应版本信息的版本格式,更具体的规范在这里。
