#semver #version #semantic #automatic #cargo #versioning #check

弃用 夜间版 bin+lib semverver

Rust库crate中自动验证SemVer遵从性

51个版本

0.1.52 2024年4月6日
0.1.51 2022年6月23日
0.1.49 2022年4月28日
0.1.48 2021年10月19日
0.1.7 2018年3月30日

#73#versioning

Download history

2,454 每月下载量

自定义许可证

225KB
4.5K SLoC

rust-semverver

弃用通知

此crate已被弃用,请检查以下crate以获取替代方案


Build Status Current Version

rust-semverver 是一个检查Rust库crate中SemVer遵从性的工具。此工具的核心是在2017年Google Summer of Code期间作为学生项目开发的。

有关2017年GSoC期间所做工作的详细信息,请参阅此处.

背景

采用的方法是将crate的两个版本编译为 rlib,并将它们作为第三个空示例crate的依赖项进行链接。然后,在所述示例crate上运行自定义编译器驱动程序,并在该上下文中执行所有必要分析,其中包含类型信息和其它资源。

有关此工具内部工作的更多信息,请参阅此处.

安装

该工具实现为一个cargo插件。目前,可以从此git仓库获取它,从源代码编译或从crates.io安装。请注意,在任何给定时间,仅支持夜间工具链的固定版本(在[rust-toolchain]中)。

建议使用 nightly-2022-08-03 工具链。如果您已经安装了rustup,可以使用以下命令安装它:rustup install nightly-2022-08-03。然后您可以进行以下操作

$ rustup component add rustc-dev llvm-tools-preview --toolchain nightly-2022-08-03
$ cargo +nightly-2022-08-03 install --git https://github.com/rust-lang/rust-semverver

您还需要 cmake 用于一些依赖项,以及一些常见库(如果您因为缺少系统级依赖项而遇到构建失败,请提出问题,以便它们可以添加到此处)。

手动安装和更多详细信息
$ git clone https://github.com/rust-lang/rust-semverver
$ cd rust-semverver
$ cargo install

在此阶段,您可以使用 cargo semver 命令在任何存放项目的目录中调用当前的开发版本。如果您不想将软件安装到 ~/.cargo/bin,在用常规的 cargo build 命令构建后,可以这样调用。

$ PATH=/path/to/repo/target/debug:$PATH cargo semver <args>

如果您使用的是 cargo build --release 命令进行构建,请将路径更改为指向 target 目录下的 release 子目录。

用法

默认情况下,在带有 Cargo 项目的目录中运行 cargo semver 命令将尝试将本地版本与在 crates.io 上最近发布的版本进行比较,并对找到的所有更改显示警告或错误。

使用 cargo semver -h 可以获得最新的帮助信息,其中概述了如何使用 cargo 插件。

$ cargo semver -h
usage: cargo semver [options]

Options:
    -h, --help          print this message and exit
    -V, --version       print version information and exit
    -e, --explain       print detailed error explanations
    -q, --quiet         suppress regular cargo output, print only important
                        messages
        --show-public   print the public types in the current crate given by
                        -c or -C and exit
    -d, --debug         print command to debug and exit
    -a, --api-guidelines
                        report only changes that are breaking according to the
                        API-guidelines
        --features FEATURES
                        Space-separated list of features to activate
        --all-features  Activate all available features
        --no-default-features
                        Do not activate the `default` feature
        --compact       Only output the suggested version on stdout for
                        further processing
    -j, --json          Output a JSON-formatted description of all collected
                        data on stdout.
    -s, --stable-path PATH
                        use local path as stable/old crate
    -c, --current-path PATH
                        use local path as current/new crate
    -S, --stable-pkg NAME:VERSION
                        use a `name:version` string as stable/old crate
    -C, --current-pkg NAME:VERSION
                        use a `name:version` string as current/new crate
        --target <TRIPLE>
                        Build for the target triple

这意味着您可以比较任何两个 crate 的指定版本,只要它们在 crates.io 上可用或在您的文件系统中存在。

CI 配置

假设您使用的是提供 cargo 访问权限的 CI 提供商,您可以使用以下片段来检查您的构建是否符合 semver 规范,并确保版本升级按照与 crates.io 上当前 crate 版本的关系正确执行。

# install a current version of rust-semverver
cargo +nightly-2022-08-03 install --git https://github.com/rust-lang/rust-semverver
# fetch the version in the manifest of your crate (adapt this to your usecase if needed)
eval "current_version=$(grep -e '^version = .*$' Cargo.toml | cut -d ' ' -f 3)"
# run the semver checks and output them for convenience
cargo semver | tee semver_out
# fail the build if necessary
(head -n 1 semver_out | grep "\-> $current_version") || (echo "versioning mismatch" && return 1)

请确保您使用的是夜间工具链进行上述操作。请查看您 CI 提供商的文档了解如何做到这一点。

JSON 输出

通过传递 -j 标志,所有输出都将格式化为机器可读的 JSON blob。这对于与其他工具集成很有用,并且总是生成所有可能的输出(忽略其他输出相关的标志)。输出格式定义如下。

顶层对象包含键 old_versionnew_versionchanges。前两个键包含格式为 major.minor.patch 的版本号,后者是一个对象,描述了 crate 版本之间的更改,包含两个键 path_changeschanges 中的数组。

path_changes 数组包含描述项目添加和删除的对象,具有以下键。

  • name:项目的名称。
  • def_span:一个对象,描述了项目在其中一个 crate 中的位置。
  • additions:一个描述项目添加位置的 spans 数组。
  • removals:一个描述项目删除位置的 spans 数组。

示例对象可能如下所示。

{
  "name": "NFT_META_CGROUP",
  "def_span": {
    "file": "/path/to/libc-0.2.48/src/unix/notbsd/linux/other/mod.rs",
    "line_lo": 776,
    "line_hi": 776,
    "col_lo": 0,
    "col_hi": 40
  },
  "additions": [
    {
      "file": "/path/to/libc-0.2.48/src/lib.rs",
      "line_lo": 195,
      "line_hi": 195,
      "col_lo": 16,
      "col_hi": 23
    }
  ],
  "removals": []
}

changes 数组包含描述所有其他更改的对象,具有以下键。

  • name:项目的名称。
  • max_category:此项目的最严重更改类别,作为字符串。
    • 可能的值有 PatchNonBreakingTechnicallyBreakingBreaking
  • new_span:一个描述项目在新的 crate 中的位置的 object(见示例)。
  • changes:包含错误消息和可选子范围(如果不存在则为null)的2元素序列数组

示例对象可能如下所示。

{
  "name": "<new::util::enumerate::Enumerate<T> as new::prelude::Stream>",
  "max_category": "TechnicallyBreaking",
  "new_span": {
    "file": "/path/to/tokio-0.1.17/src/util/enumerate.rs",
    "line_lo": 46,
    "line_hi": 63,
    "col_lo": 0,
    "col_hi": 1
  },
  "changes": [
    [
      "trait impl generalized or newly added",
      null
    ]
  ]
}

为了参考,所有描述范围的对象都有相同的键

  • file:文件名。
  • line_lo:范围开始的行。
  • line_hi:范围结束的行。
  • col_lo:范围开始的列。
  • col_hi:范围结束的列。

功能

实现semver兼容性所使用的指南是API进化RFC,它将语义版本化的原则应用于Rust语言的语义。根据RFC,大多数更改已被正确识别,尽管在一些边缘情况下某些类型检查仍然表现不正确。一个长期目标是修复编译器中的这个问题。

在撰写本文时,以下类型的更改已被识别并正确分类

  • 项目从pub移动到非pub以及相反情况
  • 项目更改其类型,例如从struct更改为enum
  • 在项目声明中添加或删除区域参数
  • 在项目声明中添加或删除(可能已默认)类型参数
  • 类型和区域参数的可变性更改
  • 枚举变体的添加和删除
  • 枚举变体或结构体字段的添加和删除
  • 从元组结构体或变体更改为结构体变体以及相反情况
  • 函数或方法的const属性更改
  • 在方法上添加或删除self参数
  • 添加或删除(可能已默认)特质项
  • 正确处理“密封”特质
  • 特质的不可靠性更改
  • 所有顶级项的类型更改,以及固有实现和特质定义中的关联项
  • 固有实现或其中包含的方法的添加和删除
  • 特质实现的添加和删除

然而,请注意,提供给用户的结果仅仅是所需版本策略的一个近似。

贡献

请参阅CONTRIBUTING.md

许可证

rust-semverver在3条款BSD许可证下分发。

有关详细信息,请参阅LICENSE。

依赖项

~51MB
~1M SLoC