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

Luk*_*odt 12 rust semantic-versioning rust-cargo

Rust crates使用语义版本控制.因此,每个具有突破性更改的版本都会导致主要版本的崩溃.一个重大更改通常被认为的东西,可能会破坏下游板条箱(代码依赖于问题的库).

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

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

这有什么指导方针吗?究竟什么被认为是一个突破性的变化,什么不是(因为它被认为是"用户的错")?

Fra*_*gné 9

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

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

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


RFC(作为提交721f2d74)中定义的主要更改是:

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

RFC中定义的次要更改(截至提交721f2d74,断开除非指定):

  • 改变货箱上货物特征的使用.
  • 在模块中添加新的公共项目.
  • 当至少一个已经存在(在更改之前和之后)[不中断]时,在结构中添加或删除私有字段.
  • 将具有所有私有字段(具有至少一个字段)的元组结构转换为普通结构,反之亦然.
  • 将默认项添加到特征中.
  • 将默认类型参数添加到特征[不破坏].
  • 在现有类型上实现任何非基本特征.
  • 将任何项目添加到固有项目impl.
  • 更改函数的未记录行为.
  • 松开现有类型参数[不中断]的边界.
  • 将默认类型参数添加到类型或特征[不破坏].
  • 通过用默认为先前类型的新类型参数替换其类型来推广现有的struct或enum字段[在问题27336修复之前一直存在].
  • 向现有函数引入新类型参数.
  • 通过用可以实例化为先前类型的新类型参数替换类型来泛化现有函数的参数或返回类型.
  • 引入新的lint警告/错误.

有关说明和示例,请参阅RFC.