文章目录

  • 简介(Introduction)
  • 主要版本和模块路径(Major versions and module paths)
  • 主要版本策略(Major version strategies)
  • 发布 v2 及更高版本(Publishing v2 and beyond)
  • 结论(Conclusion)
  • 相关阅读(Related articles)

简介(Introduction)

翻译自 Go 官方博文 Go Modules: v2 and Beyond。

Jean de Klerk and Tyler Bui-Palsulich
7 November 2019

这篇文章是系列文章的第四部分。

  • Part 1 — Using Go Modules
  • Part 2 — Migrating To Go Modules
  • Part 3 — Publishing Go Modules
  • Part 4 — Go Modules: v2 and Beyond(this post)
  • Part 5 — Keeping Your Modules Compatible

随着一个成功项目的成熟和新需求的增加,过去的特性和设计决策可能不再有意义。开发人员可能希望通过删除不推荐的函数、重命名类型或将复杂的包拆分成可管理的部分来集成他们学到的经验教训。这类更改需要下游用户努力将代码迁移到新的 API,因此,如果不仔细考虑好处大于成本,就不应该进行这些更改。

对于仍处于试验阶段的项目–在主要版本 v0,用户预期会出现偶尔的破坏性更改。对于声明为稳定的项目,在主要版本 v1 或更高版本时,在新的主要版本中必须进行破坏性更改。这篇文章探讨了主要版本的语义,如何创建和发布一个新的主要版本,以及如何维护一个模块的多个主要版本。

主要版本和模块路径(Major versions and module paths)

模块标准化了一个重要原则,导入兼容原则:

如果旧包和新包具有相同的导入路径,则新包必须向后兼容旧包

根据定义,包的新主版本与以前的版本不向后兼容。这意味着模块的新主版本必须具有与以前版本不同的模块路径。从 v2 开始,主版本必须出现在模块路径的末尾(在 go.mod 文件中的 module 语句中声明)。例如,当模块的作者 github.com/googleapis/gax-go 开发 v2 版本后,他们使用了新的模块路径 github.com/googleapis/gax-go/v2。想要使用 v2 的用户必须将其包导入路径更改为github.com/googleapis/gax-go/v2。

对主要版本后缀的要求是 Go 模块与大多数其他依赖关系管理系统的不同之处之一。需要后缀来解决钻石依赖问题。在出现模块前,gopkg.in 允许包维护人员遵循我们现在所称的导入兼容性规则。使用 gopkg.in,如果你依赖一个包的导入路径为 gopkg.in/yaml.v1 和另一个包的导入导入路径为 gopkg.in/yaml.v2,这两个包并不会冲突,因为两个 yaml 包有不同的导入路径,它们使用一个版本后缀,就像 Go 模块一样。因为 gopkg.in 与 Go 模块共享相同的版本后缀方法,Go 命令接受 gopkg.in/yaml.v2 中的 .v2 作为有效的主版本后缀。这是与 gopkg.in 兼容的特例:托管在其他域的模块需要 /v2 这样的斜杠后缀。

主要版本策略(Major version strategies)

推荐的策略是在以主版本为后缀名的目录中开发 /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

这种方法与不知道模块的工具兼容:存储库中的文件路径与 GOPATH 模式下 go get 所期望的路径相匹配。这种策略还允许在不同的目录中共同开发所有主要版本。

其他策略可能会将主要版本保留在不同的分支上。但是,如果 v2+ 源代码位于存储库的默认分支(通常是 master)上,则不知道版本的工具,包括 GOPATH 模式下的 Go 命令,可能无法区分主要版本。

本文中的示例将遵循主版本子目录策略,因为它提供了最大的兼容性。我们建议模块作者遵循这一策略,只要他们有用户在 GOPATH 模式下进行开发。

发布 v2 及更高版本(Publishing v2 and beyond)

这篇文章以 github.com/googlevis/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-gogo 1.9require (github.com/golang/protobuf v1.3.1golang.org/x/exp v0.0.0-20190221220918-438050ddec5egolang.org/x/lint v0.0.0-20181026193005-c67002cb31c3golang.org/x/tools v0.0.0-20190114222345-bf090417da8bgoogle.golang.org/grpc v1.19.0honnef.co/go/tools v0.0.0-20190102054323-c2f93a96b099
)
$

为了开发 github.com/googlevis/gax-go 的 v2 版本,我们创建一个新的 v2/ 目录并将我们的包复制到其中。

$ mkdir v2
$ cp *.go v2/
building file list ... done
call_option.go
gax.go
header.go
invoke.go
tools.gosent 10588 bytes  received 130 bytes  21436.00 bytes/sec
total size is 10208  speedup is 0.95
$

现在,让我们通过复制当前 go.mod 文件并向模块路径添加 v2/ 后缀来创建 v2 go.mod 文件:

$ cp go.mod v2/go.mod
$ go mod edit -module github.com/googleapis/gax-go/v2 v2/go.mod
$

请注意,v2 版本被视为与 v0/v1 版本不同的模块,两者可能在同一个构建中共存。因此,如果 v2+ 模块有多个包,则应该更新它们以使用新 /v2 导入路径,否则,v2+ 模块将依赖于 v0/v1 模块。例如,要将所有 github.com/my/project 引用更新为 github.com/my/project/v2,可以使用 find 和 sed:

$ find . -type f \-name '*.go' \-exec sed -i -e 's,github.com/my/project,github.com/my/project/v2,g' {} \;
$

现在我们有了 v2 模块,但是我们希望在发布发行版之前进行实验和修改。在我们发布 v2.0.0(或任何没有预发布后缀的版本)之前,我们可以对新 API 进行破坏性的更改。如果我们希望用户能够在正式版本前对新 API 进行实验,我们可以发布 v2 预发布版本:

$ git tag v2.0.0-alpha.1
$ git push origin v2.0.0-alpha.1
$

旦我们对 v2 API 感到满意,并且确信我们不需要任何其他破坏性的更改,我们就可以标记 v2.0.0:

$ git tag v2.0.0
$ git push origin v2.0.0
$

截至目前,现在有两个主要的版本需要维护。向后兼容的更改和错误修复将导致新的次要版本和补丁版本(例如,v1.1.0、v2.0.1等)。

结论(Conclusion)

主要版本更改会导致开发和维护开销,并需要下游用户的变更迁移。项目越大,这些间接成本就越大。一个重大的版本更改应该在找出一个令人信服的原因之后才能进行。一旦确定了重大更改的令人信服的原因,我们建议在主分支中开发多个主要版本,因为它与更广泛的现有工具兼容。

对 v1+ 模块的破坏性更改应该总是发生在一个新的 vN+1 模块中。当一个新模块发布时,这意味着维护人员和需要迁移到新包的用户需要额外的工作。因此,在发布稳定版本之前,维护人员应该验证他们的 API,并仔细考虑在 v1 之后是否真的需要破坏性更改。

相关阅读(Related articles)

  • Using Go Modules
  • Keeping Your Modules Compatible
  • Go Modules: v2 and Beyond
  • Publishing Go Modules
  • Module Mirror and Checksum Database Launched
  • Go Modules in 2019
  • A Proposal for Package Versioning in Go
  • The cover story
  • The App Engine SDK and workspaces (GOPATH)
  • Organizing Go code

Part 4 —— Go 模块:v2 及更高版本相关推荐

  1. java: -source 1.6 中不支持 diamond 运算符, (请使用 -source 7 或更高版本以启用 diamond 运算符)

    正在调的项目,突然编译爆红,提示为:java: -source 1.6 中不支持 diamond 运算符, (请使用 -source 7 或更高版本以启用 diamond 运算符),文件为:biz 改 ...

  2. PostgreSQL 14及更高版本改进

    PostgreSQL 14及更高版本 本文谈谈PG14中的关键特性及社区中正在谈论PG15及更高版本的内容. PG14的主要特性 逻辑复制的改进 PG14中对逻辑复制进行了几项增强: 1) 正在进行中 ...

  3. Idea报错 -source 1.5 中不支持 diamond 运算符 (请使用 -source 7 或更高版本以启用 diamond 运算符)

    一. Idea 在启动项目的时候报错: Error:(190, 51) java: -source 1.5 中不支持 diamond 运算符 (请使用 -source 7 或更高版本以启用 diamo ...

  4. IDEA报错解决:Error:(33, 35) java: -source 7 中不支持 lambda 表达式 (请使用 -source 8 或更高版本以启用 lambda 表达式)

    晚上在用IDEA的时候遇到了报错: Error:(33, 35) java: -source 7 中不支持 lambda 表达式(请使用 -source 8 或更高版本以启用 lambda 表达式) ...

  5. Dubbo 高危反序列化漏洞,存在远程代码执行风险,建议及时升级到2.7.7或更高版本!...

    点击上方蓝色"程序猿DD",选择"设为星标" 回复"资源"获取独家整理的学习资料! 以下内容转载自安全客,原文链接:https://www. ...

  6. System.Data.OracleClient 需要 Oracle 客户端软件 8.1.7 或更高版本?

    System.Data.OracleClient 需要 Oracle 客户端软件 8.1.7 或更高版本? 环境: Win XP SP2+Oracle 10 g+VS 2005 错误:System.D ...

  7. oracle 12 问题:需要 Oracle 客户端软件 8.1.7 或更高版本

    环境:win server 2008 r2 oracle 12C 错误提示: System.Web.Services.Protocols.SoapException: 服务器无法处理请求. ---&g ...

  8. 棉花糖多少钱_如何在6.0棉花糖及更高版本中访问Android的正在运行的应用程序列表...

    棉花糖多少钱 In Android 5.x and below, accessing your list of running apps was simple-you'd jump into Sett ...

  9. Maven编译项目时报错:不再支持源选项 5。请使用 6 或更高版本。 不再支持目标选项 1.5。请使用 1.6 或更高版本。

    在使用Maven编译项目时报错: 不再支持源选项 5.请使用 6 或更高版本. 不再支持目标选项 1.5.请使用 1.6 或更高版本. 在项目pom.xml文件中增加maven编译的jdk版本设置,m ...

最新文章

  1. rundll32.exe文件详解
  2. 给ModalPopupExtender控件添加弹出关闭等事件
  3. iOS Cookie学习(NSHTTPCookieStorage的使用)
  4. IOS中的数据存储 简单总结
  5. 数字声级计行业调研报告 - 市场现状分析与发展前景预测
  6. linux中tar命令怎么用,linux tar命令使用详解
  7. 小程序纵向选项卡可以滑动_微信小程序实现选项卡滑动切换
  8. 802.11系列标准简介
  9. 在线考试系统html源码,jQuery在线答题考试系统代码
  10. 卡内基梅陇大学计算机学院,卡内基梅隆大学计算机学院
  11. 阿里品牌数据银行:最全数据银行介绍
  12. 【Linux系列文章】软件包管理
  13. 两因素身份验证增强您的Spring Security
  14. 跨境电商四大推广路径都有哪些?站斧浏览器带你挑选最适合你的引流渠道
  15. SpringBoot 整合activiti5.22 实现一个完整的请假流程
  16. 设置微信分享的标题 缩略图 连接 描述
  17. 美国各州边界矢量划分图
  18. android集成Crosswalk内核,屏蔽返回键问题。
  19. 如何编写Python爬虫
  20. html星空炫彩粒子,炫彩粒子模拟器游戏

热门文章

  1. 洛谷3916 图的遍历
  2. 京东物流首架全货机首航 久未露面的刘强东还发声推广
  3. 3年10亿怎么花?支付宝小程序公布生态孵化细则!
  4. CocoaPods 安装与使用
  5. 阿里笔试的一道算法题
  6. RHEL6 Tiny Linux 的制作
  7. PXE环境下安装系统(DHCP+TFTP+HTTP+kickstart)
  8. Ant构建与部署Java项目---入门
  9. lua中table函数库
  10. Truncate Table 删除表内容避免产生过多日志