#workspace #ci #formatting #fix #features #error #workflow

bin+lib zepter

在您的 Rust 工作区中分析、修复和格式化功能

29 个版本 (8 个稳定版)

1.5.1 2024 年 7 月 19 日
1.4.0 2024 年 4 月 9 日
1.3.1 2024 年 3 月 6 日
0.15.0 2023 年 11 月 14 日
0.7.3 2023 年 7 月 31 日

#152解析实现

Download history 911/week @ 2024-04-26 314/week @ 2024-05-03 300/week @ 2024-05-10 767/week @ 2024-05-17 379/week @ 2024-05-24 363/week @ 2024-05-31 377/week @ 2024-06-07 379/week @ 2024-06-14 442/week @ 2024-06-21 395/week @ 2024-06-28 378/week @ 2024-07-05 411/week @ 2024-07-12 660/week @ 2024-07-19 604/week @ 2024-07-26 361/week @ 2024-08-02 443/week @ 2024-08-09

2,152 每月下载量

GPL-3.0-only

250KB
5K SLoC

Zepter

Rust crates.io MSRV docs.rs

在您的 Rust 工作区中分析、修复和格式化功能。这个工具的目的是让 CI 准备好,以防止 Rust 功能中常见的错误。

安装

cargo install zepter -f --locked

命令

zepter

  • : 与 run 相同。
  • run: 从配置文件中运行工作流程。如果没有指定,则使用 default
  • format
    • features: 格式化功能布局并删除重复项。
  • trace: 跟踪依赖路径。
  • lint
    • propagate-features: 检查功能是否向下传递。
    • never-enables: 一个功能不应启用另一个功能。
    • never-implies (⚠️ 不稳定): 一个功能不应间接暗示另一个功能。
    • only-enables (⚠️ 不稳定): 功能应仅启用另一个功能。
    • why-enables (⚠️ 不稳定): 了解为什么特定的功能被启用。
  • debug: (⚠️ 不稳定) 仅用于快速调试一些内容。
  • transpose (⚠️ 不稳定)
    • dependency
      • lift-to-workspace: 将crate依赖提升到工作区。

示例 - 使用工作区依赖项

目前这仅适用于外部依赖项,并且有一些情况不适用。然而,它所做的所有更改都应该正确。

例如,您可以在这里看到它的实际效果,或者自己尝试。例如,将所有 serde* crates 提升至工作区的样子

zepter transpose dependency lift-to-workspace "regex:^serde.*" --ignore-errors

它可能会打印出某些版本不匹配的消息。Zepter 默认行为是谨慎的,以避免通过提升它们意外更新某些依赖项。为了绕过这一点并实际进行更改,您可以这样做

zepter transpose dependency lift-to-workspace "regex:^serde.*" --ignore-errors --fix --version-resolver=highest

这将尝试选择每个crate的“最高”SemVer版本。

示例 - 功能格式化

要确保您的功能具有规范格式,只需运行

zepter format features
# Or shorter:
zepter f f

输出将告诉您哪些功能缺少格式

Found 37 crates with unformatted features:
  polkadot-cli
  polkadot-runtime-common
  polkadot-runtime-parachains
  ...
Run again with `--fix` to format them.

再次运行带有 --fix/-f

Found 37 crates with unformatted features:
  polkadot-cli
  polkadot-parachain
  polkadot-core-primitives
  polkadot-primitives
  ...
Formatted 37 crates (all fixed).

查看此命令产生的差异;Zepter假设默认行宽为80。对于单行特性,它们将被空格填充

-default = [
-       "static_assertions",
-]
+default = [ "static_assertions" ]

条目排序,注释保留,缩进为一个制表符,方便您使用 😊

-       # Hi
-       "xcm/std",
        "xcm-builder/std",
+       # Hi
+       "xcm/std",

示例 - 修复特性传播

让我们检查 runtime-benchmarks 特性是否正确传递到 Substrate 的工作空间中所有 frame-support 仓库的依赖项。您可以使用提交 395853ac15 来自行验证

zepter lint propagate-feature --feature runtime-benchmarks -p frame-support --workspace

输出显示,一些依赖项公开了该特性,但未将其传递下去

crate 'frame-support'
  feature 'runtime-benchmarks'
    must propagate to:
      frame-system
      sp-runtime
      sp-staking
Found 3 issues and fixed 0 issues.

没有 -p,它会检测到更多问题。您可以验证 frame-support,它确实缺少 sp-runtime 的特性,而 sp-runtime 显然支持它 🤔。

可以通过附加 --fix 标志来修复此问题,这将产生以下差异

-runtime-benchmarks = []
+runtime-benchmarks = [
+       "frame-system/runtime-benchmarks",
+       "sp-runtime/runtime-benchmarks",
+       "sp-staking/runtime-benchmarks",
+]

自动修复可以通过以下方式配置为启用特定的可选依赖项:例如,使用 --feature-enables-dep="runtime-benchmarks:frame-benchmarking"。在这种情况下,如果启用了 runtime-benchmarks 特性,则 frame-benchmarking 依赖项将被启用为非可选。

示例 - 特性跟踪

假设您要确保某些特性默认情况下永远不会启用。为此示例,我们将使用 Substratetry-runtime 特性。查看分支 oty-faulty-feature-demo 并尝试

zepter lint never-implies --precondition default --stays-disabled try-runtime --offline --workspace

precondition 定义了蕴含左边的特性,而 stays-disabled 表示前提条件永远不会启用此特性。

正确地出现错误

Feature 'default' implies 'try-runtime' via path:
  frame-benchmarking/default -> frame-benchmarking/std -> frame-system/std -> frame-support/wrong -> frame-support/wrong2 -> frame-support/try-runtime

如果有多个路径,只显示第一条。

示例 - 依赖跟踪

最近在 Substrate 主 CI 中出现了构建错误,这是由下游依赖项 snow 引起的。为了调查此问题,查看 Substrate 如何依赖它是有用的。

让我们找出 node-cli 依赖于 snow 的方式(例如,在提交 dd6aedee3b8d5 上)

zepter trace node-cli snow

它报告说 snow 是从 libp2p 中拉入的 - 很好的信息。在这种情况下,显示了所有路径。

node-cli -> try-runtime-cli -> substrate-rpc-client -> sc-rpc-api -> sc-chain-spec -> sc-telemetry -> libp2p -> libp2p-webrtc -> libp2p-noise -> snow

配置文件

⚠️ 工作流语法的语法非常实验性,并且可能发生变化。

首先,Zepter 检查它是否在一个 Rust 工作空间中执行。否则,它将直接失败。然后按以下方式找到工作流文件

  • $WORKSPACE/zepter.yaml
  • $WORKSPACE/.zepter.yaml
  • $WORKSPACE/.cargo/zepter.yaml
  • $WORKSPACE/.cargo/.zepter.yaml
  • $WORKSPACE/.config/zepter.yaml
  • $WORKSPACE/.config/.zepter.yaml

它使用找到的第一个文件,如果没有找到任何文件,则出错。目前无法在子文件夹中覆盖配置。

工作流

[!NOTE] 可以在 Polkadot-SDK 或在 presets 中找到生产示例。

可以将长命令聚合到工作流中,而不是每次都输入。Zepter 试图定位配置文件,并在没有参数的情况下裸调用时运行 default 工作流。
或者,可以使用zepter run default,或任何其他工作流名称。

配置文件可以包含如下工作流

workflows:
  default:
    - [ 'propagate-features', ... ]
    - ...

也可以扩展之前的步骤

workflows:
  check:
    - ...
  default:
    - [ $check.0, '--fix' ]
    - ...

CI 使用

Zepter 目前正在 Polkadot-SDK CI 中使用,以检测缺失的功能。[查看链接](https://github.com/paritytech/polkadot-sdk/pull/1194)
当这两个实验证明了 Zepter 在 CI 应用中的实用性和可靠性时,将引入更简洁的流程(可能是 CI 操作的形式)。

测试

单元测试:cargo test UI 和下游集成测试:cargo test -- --ignored

环境覆盖存在,以供 UI 测试使用

  • OVERWRITE:更新 UI 差异锁定。
  • UI_FILTER:正则表达式以选择性地运行 UI 测试。
  • KEEP_GOING:打印 FAILED 但不在第一次失败的 UI 测试时中止。

开发原则

  • 编译时间是人类时间。编译时间应该 始终 大大低于 1 分钟。
  • 最小外部依赖。减少错误来源和编译时间。
  • 测试。到目前为止,该工具已在 CI 中广泛使用了一年以上,从未收到过错误报告。它应该保持这样。

依赖项

~6–19MB
~280K SLoC