究竟什么被认为是图书馆箱子的重大改变?

时间:2016-12-16 13:01:48

标签: rust rust-cargo semantic-versioning

Rust crates使用Semantic Versioning。因此,每个具有突破性更改的版本都会导致主要版本的崩溃。 重大变更通常被认为可能破坏下游的包装箱(代码取决于相关的库)。

然而,在Rust中,很多都有可能打破下游板条箱。例如,更改(仅包括添加到)公共符号集可能是一个重大变化,因为下游包可以使用glob-imports(use foo::*;)将我们库的符号拉入命名空间。因此,添加符号也可以破坏相关的条件箱;见this example

同样,更改(添加或更改版本)我们的依赖项集可能会破坏下游构建。您还可以想象下游包依赖于我们的一种公共类型的特定大小。如果有的话,这很少有用;我只是想表明:如果只有下游的箱子足够努力,一切都可能是一个突破性的变化。

这有什么指导方针吗? 究竟什么是真正的改变,什么不是(因为它被认为"用户的错误")?

1 个答案:

答案 0 :(得分:6)

有关此主题的Rust RFC:RFC 1105: API Evolution。它适用于任何Rust库项目,它涵盖了所有类型的更改(不仅仅是重大更改)以及它们如何影响语义版本控制。我将尝试总结RFC中的关键点,以便不将此答案作为仅链接答案。 :)

RFC承认,对库的任何更改都会导致客户端突然停止编译。因此,它定义了一组主要更改,它需要主要版本号的冲击,以及一组次要更改,这需要次要版本的冲击数;并非所有重大变更都是主要变更

微小变化的关键属性是必须有一种方法,客户可以通过稍微改变其源代码来预先避免破坏(例如,将glob导入更改为非glob导入,消除使用UFCS的模糊调用的歧义以这种方式使代码与更改之前的版本兼容,并与包含更改的版本兼容(假设它是次要版本)。一个微小的变化也不得强迫下游板条箱进行重大的破碎变化以解决破损问题。

RFC中定义的主要更改(截至commit 721f2d74)是:

  • 将项目从与稳定编译器兼容切换为仅与夜间编译器兼容。
  • 重命名,移动或移除模块中的任何公共item
  • 当所有当前字段都是公共字段时,向结构添加私有字段。
  • 将公共字段添加到没有私有字段的结构中。
  • 为枚举添加新变体。
  • 向枚举变体添加新字段。
  • 将非默认项目添加到特征中。
  • 对特征项目签名的任何非平凡变更。
  • 在现有类型上实施fundamental特征。
  • 加强现有类型参数的界限。
  • 添加或删除函数的参数。
  • 未在RFC中列为次要更改的任何其他重大更改。

RFC中定义的次要更改(从commit 721f2d74开始,除非另有说明,否则为:

  • 改变货箱上货物特征的使用。
  • 在模块中添加新的公共项目。
  • 在结构中添加或删除至少一个私有字段(在更改之前和之后) [not breaking]
  • 将包含所有私有字段(至少有一个字段)的元组结构转换为普通结构,反之亦然。
  • 将默认项目添加到特征中。
  • 将默认类型参数添加到特征 [not breaking]
  • 在现有类型上实施任何非基本特征。
  • 将任何项目添加到固有impl
  • 更改函数的未记录行为。
  • 放宽现有类型参数 [not breaking] 的边界。
  • 将默认类型参数添加到类型或特征 [not breaking]
  • 通过将新类型参数替换为默认为上一个类型 [断开issue 27336已修复] 的新类型参数来对其现有结构或枚举字段进行泛化。
  • 向现有函数引入新类型参数。
  • 通过将类型替换为可以实例化为先前类型的新类型参数来泛化现有函数的参数或返回类型。
  • 介绍新的lint警告/错误。

有关解释和示例,请参阅the RFC