56 个版本 (32 个重大更新)
0.34.0 | 2024年8月14日 |
---|---|
0.33.0 | 2024年7月24日 |
0.32.0 | 2024年6月17日 |
0.30.0 | 2024年3月16日 |
0.5.1 | 2022年7月31日 |
在 Cargo 插件 中排名 #52
每月下载量 4,180
用于 4 个库
1.5MB
14K SLoC
cargo-semver-checks
检查您的库 API 变更是否违反 semver 规范。
快速入门
# If you already use `cargo-binstall` for faster tool installations:
$ cargo binstall cargo-semver-checks
# Otherwise:
$ cargo install cargo-semver-checks --locked
# Lint a new release for SemVer breakage before `cargo publish`:
$ cargo semver-checks
或者作为 GitHub Action 使用(在本仓库的 .github/workflows/ci.yml
中使用)
- name: Check semver
uses: obi1kenobi/cargo-semver-checks-action@v2
每次失败的检查都会引用 Cargo SemVer 参考 或其他相关页面中的特定项。它还包括导致问题的项名称和文件位置,以及链接到当前工具版本中该查询的实现。
常见问题解答
cargo-semver-checks
支持哪些 Rust 版本?- 我能否使用
nightly
Rust 与cargo-semver-checks
一起使用? - 如果我的项目需要对支持的 Rust 版本有更强的保证怎么办?
- 我正在检查的库必须在 crates.io 上发布吗?
cargo-semver-checks
在测试的库中启用了哪些功能?cargo-semver-checks
有误报吗?cargo-semver-checks
能捕获每一个 semver 违规吗?- 我能配置单个 lint 吗?
- 如果我真的想要实现一个新功能,我能赞助其开发吗?
cargo-semver-checks
与其他工具相似之处和不同之处是什么?- 为什么有时是
cargo-semver-check
和cargo-semver-checks
? - 关于 semver,MSRV 的政策是什么?
cargo-semver-checks
支持哪些 Rust 版本?
cargo-semver-checks
使用 rustdoc 工具分析软件包的 API。Rustdoc 的 JSON 输出格式不稳定,在新版本的 Rust 中可能会有破坏性变化。
每次 cargo-semver-checks
版本发布时,至少会包括对当时稳定和测试版 Rust 版本的支持。它可能会,但不保证会,额外支持一些夜间 Rust 版本。
GitHub Action 默认使用 cargo-semver-checks
和稳定 Rust 的最新版本,因此应该不受影响。鼓励使用其他方式在 Rust 版本更新时更新 cargo-semver-checks
,以确保持续兼容性。
我能否使用 nightly
Rust 与 cargo-semver-checks
一起使用?
对 nightly
Rust 版本的支持是尽力而为的。它通常会工作,但不总是。如果您 必须 使用 nightly
,强烈建议锁定到特定的 nightly
版本以避免破坏工作流程。
cargo-semver-checks
依赖于不稳定的 rustdoc JSON 格式,该格式经常变化。在新版本的 rustdoc JSON 格式发布到 nightly
后,通常需要几天到几周的时间才能在新版本的 cargo-semver-checks
中得到支持,在这段时间内,无法使用这些 nightly
版本。
还可能出现的情况是,即使旧版本仍然得到支持,也可能取消对某些 nightly
版本的支持。这通常发生在 rustdoc 格式在新版本 Rust 成为任何稳定 Rust 的一部分之前被更新。在这种情况下,我们可能会取消对该格式的支持,以节省维护带宽并加快编译时间。例如,cargo-semver-checks
v0.24 支持 rustdoc 格式 v24、v26 和 v27,但不支持夜间专用的 v25 格式。
如果我的项目需要对支持的 Rust 版本有更强的保证怎么办?
如果您希望对旧版本 Rust 有更长时间的支持,或者对支持新的 nightly
发布有服务级别协议 (SLA),我们很高兴以 商业基础 提供这些服务。这可能是一种正式的支持合同,或者简单地通过电子邮件讨论期望,并设置一个定期 GitHub 赞助,金额由双方商定。
请通过 Cargo.toml 中的电子邮件联系我们,并告知我们这是为什么项目以及他们的需求。
我正在检查的库必须在 crates.io 上发布吗?
不,它不需要在任何地方发布。您只需使用一个标志来帮助 cargo-semver-checks
定位用作 semver-checking 基准的版本。
默认情况下,cargo-semver-checks
使用 crates.io 来查找软件包的上一版本,该版本用作 semver-checking 当前软件包版本的基准。以下标志可以用来显式指定一个基准
--baseline-version <X.Y.Z>
Version from registry to lookup for a baseline
--baseline-rev <REV>
Git revision to lookup for a baseline
--baseline-root <MANIFEST_ROOT>
Directory containing baseline crate source
--baseline-rustdoc <JSON_PATH>
The rustdoc json file to use as a semver baseline
目前不支持自定义注册表(#160),因此发布在其他注册表上的软件包应使用其他生成基准的方法。
cargo-semver-checks
在测试的库中启用了哪些功能?
默认情况下,除了名为 unstable
、nightly
、bench
、no_std
或以 _
为前缀的,或以 unstable-
或 unstable_
开头的特性外,所有特性都将进行检查。因为这些名称通常用于私有或不稳定特性。
此行为可以覆盖。检查的特性集可以更改为
- 所有 特性,使用
--all-features
选择 - 仅使用
--default-features
选择 crate 的默认特性 - 空集,使用
--only-explicit-features
选择
此外,可以使用 --features
、--baseline-features
和 --current-features
标志逐个启用特性。
例如,考虑具有以下特性的 crate serde(版本 v1.0.163)
std
- crate 的唯一默认特性alloc
、derive
、rc
- 可选特性unstable
- 可能会破坏 semver 的特性
使用的标志 | 选定的特性集 | 解释 |
---|---|---|
无 | std 、alloc 、derive 、rc |
默认启发式方法排除了特性 unstable 。 |
--features unstable |
std 、alloc 、derive 、rc 、unstable |
该标志明确将 unstable 添加到启发式选择的集合中。 |
--all-features |
std 、alloc 、derive 、rc 、unstable |
使用所有特性,禁用默认启发式方法。 |
--default-features |
std |
该 crate 只有一个默认特性。 |
--default-features --features derive |
std 、derive |
特性 derive 与 crate 的默认特性一起使用。 |
--only-explicit-features |
无 | 未传递任何显式特性。 |
--only-explicit-features --features unstable |
unstable |
可以显式添加所有特性,无论它们的名称如何。 |
cargo-semver-checks
有误报吗?
"误报" 意味着 cargo-semver-checks
错误地报告了 semver 违规。 cargo-semver-checks
的设计目标是不要有误报。如果确实发生误报,它们被认为是错误。
当 cargo-semver-checks
报告 semver 违规时,它应该始终指向特定文件和大约行号,其中发生指定问题;未能指定文件和行号也视为错误。
如果您认为 cargo-semver-checks
可能存在误报但不确定,请 提交一个问题。 Rust 中的 semver 有许多不明显和复杂的情况 ,尤其是在宏的存在下。我们很乐意与您一起研究,以确定它是否为误报。
cargo-semver-checks
能捕获每一个 semver 违规吗?
不会,现在还没有!有许多方式可以破坏 semver,而 cargo-semver-checks
还没有为所有这些添加 lint。经常添加新的 lint,如果您想贡献新的 lint,我们很乐意指导您!
在检查您的 crate 的 semver 时,附加 --verbose
以查看执行的 semver 检查的完整列表。
以下是 cargo-semver-checks
目前不会捕获 semver 违规的一些示例区域
- 打破类型更改,例如字段或函数参数的类型
- 泛型或生命周期中的打破更改
- 只有所有crate功能的一部分被激活时存在的打破更改
我能配置单个 lint 吗?
是的!请参阅 lint级别配置。
如果我真的想要实现一个新功能,我能赞助其开发吗?
根据功能,可能是的!
请在电子邮件中提前联系我们,以讨论功能范围和赞助。
该功能可能被认为超出范围、过于复杂以构建或维护,或不适合作其他用途。在这种情况下,我们希望在您付款之前通知您,因为GitHub Sponsors没有退款。
如果功能可行且构建所需的工作与赞助金额相称,我们将很高兴构建它。根据您的选择,我们也很乐意在发布说明中宣布该功能时,为赞助该功能进行宣传。
cargo-semver-checks
与其他工具相似之处和不同之处是什么?
rust semverver在rustc内部构建rlib并比较其元数据的基础上构建。这将代码简化到识别更改的基本层面。然而,它与特定的夜间编译器版本紧密耦合,并且需要工作以保持同步。截至2023年4月17日,它似乎已被弃用且不再维护。
cargo breaking实际上运行cargo expand
,并使用syn
重新解析代码,这要求重新实现大量rust的语义,以便随后对API更改进行lint。这仅限于编译的crate功能和目标。截至2022年11月22日,它似乎已被存档且不再维护。
cargo-semver-checks
的数据来源是rustdoc的json输出。虽然json输出格式是不稳定的,但变化的速率相当低,降低了跟进的代价。lints也作为trustfall
“查询一切”引擎的查询编写,减少了创建和维护它们的工作。由于rustdoc包括的额外数据,可能能够引入一些功能/目标意识。
对在docs.rs
上托管rustdoc JSON感兴趣,这意味着semver-checking有一天可以下载基线rustdoc JSON文件而不是生成它。一般来说,检查JSON数据可能比完整编译更快。
cargo-public-api
使用rustdoc,就像cargo-semver-checks
一样,但更关注API diffing(显示哪些项已更改)而不是API linting(解释它们为什么已更改并提供控制权)。
为什么有时是 cargo-semver-check
和 cargo-semver-checks
?
该crate原本打算以cargo-semver-check
的名称发布,并且确实可能有一天会以该名称发布。由于一个不幸的意外,它暂时仍为cargo-semver-checks
。
在crates.io上保留了cargo_semver_check
的名称,但所有版本都是有意撤回的。请使用cargo-semver-checks
crate。
关于 semver,MSRV 的政策是什么?
MSRV的提升不被视为重大更改。
cargo-semver-checks
有两个Rust版本限制,因为它依赖于Rust在编译时和运行时的依赖
- 编译 cargo-semver-checks("编译 MSRV")的最低支持版本(MSRV)目前是 Rust 1.70。这主要取决于我们依赖项的 MSRV。
- 检查 crate 的 MSRV("运行时 MSRV")目前是 Rust 1.71。这是基于 rustdoc JSON 格式版本和已知较旧 rustdoc 版本的错误来确定的。
在尽可能的情况下,运行时 MSRV 的更改将以版本中间数字的增加来体现,例如 0.24.1 -> 0.25.0
或 1.2.3 -> 1.3.0
。
编译 MSRV 的更改可能会在任何类型的版本增加中出现。尽可能的同时,我们希望与运行时 MSRV 的增加同时进行。
配置
lint 级别配置
cargo-semver-checks
允许自定义哪些 lint 被强制执行,它们需要哪些 SemVer 版本,以及违反该 lint 是否会产生 deny / warn / allow
行为。
提醒一下,"lint" 或 "check" 是 cargo-semver-checks
中寻找特定类型问题的规则。例如,function_missing
lint 寻找不再存在于 crate 公共 API 中的函数。cargo-semver-checks
有许多这样的 lint。
lint 可以通过两种方式配置
- lint 级别: 当 lint 发现问题时,lint 级别控制
cargo-semver-checks
如何响应。deny
级别使 lint 成为硬错误:cargo-semver-checks
将以错误退出,并且需要版本增加来解决。warn
级别将打印一个描述问题的警告,但不会导致cargo-semver-checks
以错误代码退出——这意味着它 不会 阻止 CI 运行。allow
级别意味着 lint 的发现应该被静默忽略,因此不需要运行检查。 - 所需更新: 这设置了这个检查发现问题时所需的(对于
deny
级别)或建议的(对于warn
)版本增加类型。例如,默认情况下,function_missing
lint 是major
,因此如果在版本之间删除了公共函数,则需要增加主版本(例如,从 1.2.3 到 2.0.0 或从 0.5.2 到 0.6.0)。这可以配置为major
或minor
(从 1.2.3 到 1.3.0 或从 0.5.2 到 0.5.3)。没有 "patch" 设置,因为这相当于设置一个allow
lint 级别。
要配置 lint 的级别和/或所需更新,首先找到其名称。这将是 snake_case
,并在 CLI 错误/警告中报告,还可以在 lints 文件夹 中作为文件名找到。
- 示例:将错误级别的 lint 降级为警告
- 示例:更改 lint 的 SemVer 要求
- 示例:为整个工作区配置 lint
- 示例:覆盖工作区配置
- 常见配置:使
#[must_use]
lints 只警告 - 常见配置:完全禁用
#[must_use]
lints - 实现细节与限制
示例:将错误级别的 lint 降级为警告
cargo-semver-checks
默认认为将 #[must_use]
添加到现有函数需要提升到 minor
版本,并具有 deny
级别。假设我们的包认为这太严格了,更愿意将 #[must_use]
添加为警告而不是错误。
我们可以在包的 Cargo.toml
清单中添加以下内容来实现这一点
[package.metadata.cargo-semver-checks.lints]
function_must_use_added = "warn"
该选项是简写形式
[package.metadata.cargo-semver-checks.lints]
function_must_use_added = { level = "warn" }
如果我们想同时配置其他 lints,我们也可以将其配置添加到那里:每行一个 lints。
示例:更改 lint 的 SemVer 要求
假设我们希望如果添加 #[must_use]
则强制要求提升到主要版本。
我们将在包的 Cargo.toml
文件中添加以下内容
[package.metadata.cargo-semver-checks.lints]
function_must_use_added = { required-update = "major" }
当然,可以组合 level
和 required-update
设置。例如,以下设置将在没有主要版本提升的情况下添加 function_must_use_added
时产生警告(而不是错误)
[package.metadata.cargo-semver-checks.lints]
function_must_use_added = { level = "warn", required-update = "major" }
示例:为整个工作区配置 lint
cargo-semver-checks
允许在 workspace 级别定义您的 lints 配置,并在每个 crate 中重用它。
首先,将配置添加到 workspace 根 Cargo.toml
,注意使用 workspace.metadata
前缀而不是 package.metadata
[workspace.metadata.cargo-semver-checks.lints]
function_must_use_added = { level = "warn" }
然后,为了在单个包中启用 workspace 配置,向该包的 Cargo.toml
中添加以下键之一
[package.metadata.cargo-semver-checks.lints]
workspace = true
或者,如果 workspace 已经在 [workspace.lints]
中配置了 workspace 级别的 lints(例如 clippy),
[lints]
workspace = true
使用 lints.workspace
键会在 workspace Cargo.toml 中没有 [workspace.lints]
表时导致 cargo 错误。我们支持 lints.workspace
键来简化我们过渡到 将 cargo-semver-checks
合并到 cargo
本身 的过程。
设置 workspace = false
不是一个有效的配置。要使包退出 workspace 的 lints 配置,请从包的 Cargo.toml
中完全省略这两个键。
示例:覆盖工作区配置
当设置 workspace = true
时,仍然可以在包中覆盖单个 lints 设置。
经验法则:对于每个lint的每个配置选项,
- 工作空间配置覆盖lint的默认值,
- 包的配置覆盖上述两者。
例如,如果我们在工作空间的Cargo.toml中,
[workspace.metadata.cargo-semver-checks.lints]
function_missing = { level = "warn", required-update = "minor" }
trait_now_doc_hidden = "warn"
function_must_use_added = "warn"
以及包的Cargo.toml中,
[package.metadata.cargo-semver-checks.lints]
workspace = true
function_missing = "deny"
trait_now_doc_hidden = { required-update = "minor" }
这里是该包的最终配置
- 对于
function_missing
,- 内置默认值为
level = "deny", required-update = "major"
。 - 工作空间覆盖这两个设置为
level = "warn", required-update = "minor"
。 - 包通过
workspace = true
选择工作空间的配置,然后覆盖为level = "deny"
。 - 最终配置:
level = "deny", required-update = "minor"
。
- 内置默认值为
- 对于
trait_now_doc_hidden
,- 内置默认值为
level = "deny", required-update = "major"
。 - 工作空间覆盖为
level = warn"
,但保留required-update
不变。 - 包通过
workspace = true
选择工作空间的配置,然后设置required-update = "minor"
。 - 最终配置:
level = "deny", required-update = "minor"
。
- 内置默认值为
- 对于
function_must_use_added
,- 内置默认值为
level = "deny", required-update = "minor"
。 - 工作空间覆盖为
level = "warn"
,但保留required-update
不变。 - 包通过
workspace = true
选择工作空间的配置。 - 最终配置:
level = "warn", required-update = "minor"
。
- 内置默认值为
常见配置:使 #[must_use]
lints 只警告
在默认配置下,cargo-semver-checks
将在补丁版本中添加 #[must_use]
属性视为错误。其原因是这种添加可能会在下游项目中引入新的代码检查,许多项目将代码检查视为错误,这可能导致项目崩溃。(这种设置是否适合广泛使用,不在 cargo-semver-checks
的讨论范围内。)
要将与 #[must_use]
相关的所有代码检查从错误降级为警告,请将以下行添加到您的包或工作区的 cargo-semver-checks
配置中
function_must_use_added = "warn"
inherent_method_must_use_added = "warn"
struct_must_use_added = "warn"
enum_must_use_added = "warn"
trait_must_use_added = "warn"
union_must_use_added = "warn"
常见配置:完全禁用 #[must_use]
lints
要完全跳过检查 #[must_use]
相关的代码检查,请在您的包或工作区应用以下配置
function_must_use_added = "allow"
inherent_method_must_use_added = "allow"
struct_must_use_added = "allow"
enum_must_use_added = "allow"
trait_must_use_added = "allow"
union_must_use_added = "allow"
实现细节与限制
检查包时,cargo-semver-checks
使用当前主题的 Cargo.toml
文件清单(如果已选择,还包括其工作区配置)。
包的 基线版本 中设置的配置(与正在比较的版本,例如在 crates.io 上发布的现有版本)不会被读取,也没有任何效果。这是因为发布新版本时,使用新版本的配置而不是任何以前的配置是有意义的。
当使用 --manifest-path
选项指定主题包的 Cargo.toml
文件时,这也是配置加载的文件。如果没有指定此 CLI 标志,cargo-semver-checks
将默认尝试查找并使用当前目录下的 Cargo.toml
文件。
如果以跳过读取当前清单的方式(例如使用 --current-rustdoc
标志)执行 cargo-semver-checks
,目前无法配置代码检查。对此限制的兴趣和解决进展在 此问题 中跟踪。
故障排除
本节记录了常见问题和解决它们的最佳方法。
运行 cargo install cargo-semver-checks --locked
产生错误
建议:如果您的平台上有可用的预构建二进制文件,请使用 cargo-binstall
下载预构建二进制文件,而不是从头开始编译。
特定错误及其解决方法
- "错误:运行自定义构建命令失败
libz-ng-sys vX.Y.Z
"- 首选解决方案:使用预构建二进制文件以完全避免此问题。
- 此错误是由系统缺少
cmake
引起的,这是cargo-semver-checks
的一个间接依赖项所必需的。目前cargo
没有提供将此类二进制依赖项声明为必需的机制,也不会在需要时自动安装。 - 您通常可以通过以下命令安装它:
apt install cmake
或brew install cmake
,具体取决于您的平台。
视觉设计
标志由 NUMI 设计
许可证
可在Apache许可证(版本2.0)或MIT许可证下使用,任选其一。
版权所有 © 2022-至今 Predrag Gruevski 和项目贡献者。当前日期由仓库中最新的提交的时间戳确定。项目贡献者包括仓库中所有作者和提交者。
依赖项
~32–51MB
~1M SLoC