前言
成功的项目随着逐步成熟以及新功能的加入,过去的特性和设计方案可能不能满足需求。开发者可能想整合一下他们所学的知识比如移除废弃函数、重命名参数或者分割复杂的包为多个可维护模块。这些变更都需要下游用户付出努力来迁移他们的代码来适配新的API,所以他们不会没有认真权衡过收益和成本而做出变更的。
对于一些还在实验中的项目,比如主版本为v0的项目,用户会预期到偶尔的重大变更。对于已经发布为稳定版本的项目,比如主版本为v1或者更高版本的项目,重大的变更需要在一个大版本上进行。这篇文章主要介绍了大版本策略、如果创建并发布一个新的大版本以及如何维护一个module的多个主版本。
主版本与module path
modules模式规范了一个重要的原则,导入兼容性原则:
如果一个老版本的包和一个新版本的包使用相同的导入path,那么新版本的包必须向后兼容老版本的包。
go.modmodulegithub.com/googleapis/gax-gov2github.com/googleapis/gax-go/v2v2github.com/googleapis/gax-go/v2
菱形依赖问题gopkg.ingopkg.in/yaml.v1gopkg.in/yaml.v2yamlgopkg.ingopkg.ingopkg.in.v2gopkg.in/v2
主版本策略
在开发v2以及后续版本时推荐的方式是创建一个对应版本号的文件目录。
github.com/googleapis/gax-go @ master branch
/go.mod → module github.com/googleapis/gax-go
/v2/go.mod → module github.com/googleapis/gax-go/v2
GOPATHgo get
GOPATH
GOPATH
发布v2及后续版本
github.com/googleapis/gax-go
$ pwd
/tmp/gax-go
$ ls
CODE_OF_CONDUCT.md call_option.go internal
CONTRIBUTING.md gax.go invoke.go
LICENSE go.mod tools.go
README.md go.sum RELEASING.md
header.go
$ cat go.mod
module github.com/googleapis/gax-go
go 1.9
require (
github.com/golang/protobuf v1.3.1
golang.org/x/exp v0.0.0-20190221220918-438050ddec5e
golang.org/x/lint v0.0.0-20181026193005-c67002cb31c3
golang.org/x/tools v0.0.0-20190114222345-bf090417da8b
google.golang.org/grpc v1.19.0
honnef.co/go/tools v0.0.0-20190102054323-c2f93a96b099
)
$
github.com/googleapis/gax-gov2v2
$ mkdir v2
$ cp *.go v2/
building file list ... done
call_option.go
gax.go
header.go
invoke.go
tools.go
sent 10588 bytes received 130 bytes 21436.00 bytes/sec
total size is 10208 speedup is 0.95
$
go.modv2go.modv2
$ cp go.mod v2/go.mod
$ go mod edit -module github.com/googleapis/gax-go/v2 v2/go.mod
$
github.com/my/projectgithub.com/my/project/v2
$ find . -type f \
-name '*.go' \
-exec sed -i -e 's,github.com/my/project,github.com/my/project/v2,g' {} \;
$
现在我们已经有v2版本的module了,但是我们想在发布之前做一些预发布与更改。在我们发布v2.0.0之前可以做出我们想开发的新API的重大变更,但如果我们想让用户能够体验到预发布版本而不是正式稳定版本,我们可以发布一个预览版本:
$ git tag v2.0.0-alpha.1
$ git push origin v2.0.0-alpha.1
$
v2.0.0
$ git tag v2.0.0
$ git push origin v2.0.0
$
v1.1.0v2.0.1
综述
大版本的变更会带来开发和维护的开销,同时也需要下游用户为了迁移而投入。项目越大,开销越大。大版本的变更应当有一个令人信服的原因。对于一个重大的变更一旦被说服,我们建议你在主分支同时开发多个大版本因为这对于已经存在的工具集来说是可兼容的。
v1版本以后的module的重大变更会出现一个新的vN+1的module。当一个新的module版本发布时,这对维护者和哪些想升级到新版本的用户来说都是额外的工作量。因此module维护者在发布一个稳定版本时一定要验证这些API,在以后的版本中小心谨慎的评估是否需要重大的变更。