查看原文:blog.keyboardman.me
一直以来,对go来说依赖包的版本控制上没有一个好的方案,当前主要有两种方式Import Versioning
和Semantic Versioning
。
- Import Versioning:
gopkg.in
网站,其实是GitHub版本变化的重定向器,你可以通过gopkg.in/yaml.v1
和gopkg.in/yaml.v2
的这样的导入方式来指向Git库的不同提交版本 - Semantic Versioning:制定了一个文件格式规范来描述管理vendor目录下代码的准确源和版本信息(dep、glide)
前几天(2018-02-20)Russ Cox博客上介绍了他为go设计的新工具vgo
,这是为处理软件包版本而设计的go工具的替代品,vgo即versioned go的缩写,意即带版本的go。vgo目前只能运行在go1.10之上,否则会得到vgo objabi: cannot find GOMIPS
这样的错误。
首先安装vgo。
go get -u golang.org/x/vgo
我们先尝试下,跟着官方示例。
mkdir $GOPATH/src/hello
cd $GOPATH/src/hello
curl -sS https://swtch.com/hello.go > hello.go
我们看一下hello.go
的内容。
package main // import "github.com/you/hello"
import (
"fmt"
"rsc.io/quote"
)
func main() {
fmt.Println(quote.Hello())
}
其中// import "github.com/you/hello"
注释用来告诉vgo模块的“导入路径名称”应该是什么,并且使用此模块的其他软件包将用作导入标识符。
创建一个空的go.mod文件来标记此项目的根目录,然后编译一下。
echo >go.mod
vgo build
可以看到生成可执行文件,并修改了go.mod
的内容,自动生成了依赖关系。
module "github.com/you/hello"
require "rsc.io/quote" v1.5.2
go.mod
文件包含了模块所依赖包的最小版本。如果模块没有提供一个tag
版本。对于未命名的提交,v0.0.0-yyyymmddhhmmss-commit
表示一个指定日期的提交。go.mod
文件还可以实现排除和替换的版本,需手动修改go.mod
文件。
exclude "rsc.io/sampler" v1.99.99
replace "rsc.io/quote" v1.5.2 => "../quote"
但是,最重要的变化还是终结了GOPATH
作为Go代码工作空间的设置,由于go.mod
文件包含了完整的模块路径并且还定义了每个使用的依赖的版本,因此包含go.mod
文件的目录就可以被认为是一个目录树的根目录了,该目录树作用于自身的工作空间,并且和其他类似的目录彼此隔离。
vgo其他功能
vgo list -m # 查看所有依赖
vgo list -m -u # 查看所有依赖同时检查更新,会打印出最新版本和当前版本
vgo test all # 执行所有测试,包括依赖包的测试
vgo test http://rsc.io/sampler # 执行指定包测试
vgo get -u # 更新所有依赖
vgo list -t http://rsc.io/sampler # 检查指定包所有可用的版本 即tag
vgo get http://rsc.io/sampler@v1.3.1 # 获取指定版本,并修改go.mod
vgo vendor # 退到vendor 兼容不使用vgo的用户
...
vgo在下载github仓库时,如果当前环境是未认证的账号会受到限流影响,得到如下警告。
GitHub applies fairly small rate limits to unauthenticated users, and
you appear to be hitting them. To authenticate, please visit
https://github.com/settings/tokens and click "Generate New Token" to
create a Personal Access Token. The token only needs "public_repo"
scope, but you can add "repo" if you want to access private
repositories too.
这时候需要获取github token,在github网站依次点击Settings
-Developer settings
-Personal access tokens
-Generate new token
,填写名字和勾选权限后生成token。创建或修改$HOME/.netrc
文件,添加下行,把生成的token填写进去,就能解决了。
machine api.github.com login YOU password TOKEN
目前vgo的文档不够完善,代码也不够健壮,在生产环境可能还不适合去使用。我在测试时就遇到了些问题,比如有的gopkg.in
仓库使用标签而不是分支来标记主要版本。当前vgo处理这些仓库会出错。
import (
_ "gopkg.in/natefinch/lumberjack.v2"
)
将得到如下错误。
import "gopkg.in/natefinch/lumberjack.v2": unexpected status (https://api.github.com/repos/natefinch/lumberjack/commits?sha=v2&until=2018-02-23T03%3A49%3A22Z&per_page=2): 404 Not Found
# 或
vgo: import "gopkg.in/natefinch/lumberjack.v2": unexpected status (https://api.github.com/repos/natefinch/lumberjack): 403 Forbidden
不过vgo应该很快就会修复这些问题。
有疑问加站长微信联系(非本文作者))

设计理念还是很符合go风格的。
在win下 vgo: cannot determine module path for legacy source directory Z:\a\src\hello (outside GOROOT, no import comments) 还没搞明白
原来已经有人提了issue,WIN下默认\r\n, vgo没兼容好