9 个版本

0.2.9 2024年2月5日
0.2.8 2023年8月27日
0.2.7 2023年7月30日
0.2.5 2022年5月10日

#145Cargo 插件

Download history 120/week @ 2024-04-07 176/week @ 2024-04-14 99/week @ 2024-04-21 125/week @ 2024-04-28 130/week @ 2024-05-05 176/week @ 2024-05-12 195/week @ 2024-05-19 185/week @ 2024-05-26 143/week @ 2024-06-02 172/week @ 2024-06-09 228/week @ 2024-06-16 163/week @ 2024-06-23 213/week @ 2024-06-30 226/week @ 2024-07-07 150/week @ 2024-07-14 248/week @ 2024-07-21

847 每月下载量

MIT/Apache

120KB
2.5K SLoC

cargo-hackerman

License: MIT OR Apache-2.0 cargo-hackerman on crates.io cargo-hackerman on docs.rs Source Code Repository cargo-hackerman on deps.rs

Hackerman 解决以下问题

命令行摘要

功能统一,这对用户意味着什么?

作为与工作空间一起工作的部分,cargo 执行功能统一: https://doc.rust-lang.net.cn/cargo/reference/features.html#feature-unification

这意味着什么?

假设你有一个工作空间

[workspace]
members = [ "mega", "potato" ]

包含两个成员: mega

[package]
name = "mega"

[dependencies]
potatoer = { version = "0.2.1", features = ["mega"] }

potato

[package]
name = "potato"

[dependencies]
potatoer = { version = "0.2.1", features = ["potato"] }

它们都依赖于一个共同的第三方 crate potatoer,但具有不同的功能:mega"mega" 功能感兴趣,potato"potato" 功能感兴趣。

当运行不同的命令时,你会需要几个不同版本的 potatoer crate。

  • 整个工作空间命令将使用统一功能的版本

    cargo check # this will use potatoer with both "mega" and "potato"
    
  • 操作单个 crate 的命令将使用未经统一的版本

    cargo check -p mega           # this will use potatoer with "mega" feature
    cargo check -p potatoer       # this will use potatoer with "potato" feature
    cargo check -p mega -p potato # this will require both "mega" and "potato"
    

如果缺少具有所需组合的依赖项,cargo 将编译它。

避免此问题的一种方法确保工作空间成员如果依赖于某个 crate,则它们依赖于具有相同功能集的 crate。手动维护容易出错,这就是 hackerman hackhackerman restore 的作用。

当与 --lock 选项一起使用时,hackerman 将对所有依赖项进行校验和计算,并将结果保存在 Cargo.toml 文件中的 ["package.metadata.hackerman.lock"] 部分,后续的检查将确认此校验和的有效性。

这确保了原始(未修改)的依赖项被保存,并在以后可以恢复。

可以将 --lock 选项硬编码在定义工作区的 Cargo.toml 文件中

[workspace.metadata.hackerman]
lock = true

目前,统一操作仅针对当前目标执行,且不支持交叉编译。如果你使用不同于版本或 {} 的语法指定依赖项,工作区 toml 文件的自动更新可能无法正常工作。

potato = "3.14"               # this is okay
banana = { version = "3.14" } # this is also okay

Hackerman 合并工具

解决由 hackerman 修改的 Cargo.toml 文件的合并和变基冲突

要使用它,你想要这样的东西

全局 .gitconfig 或局部 .git/config

[merge "hackerman"]
    name = merge restored files with hackerman
    driver = cargo hackerman merge %O %A %B %P

gitattributes 文件,可以是项目本地或全局的

Cargo.toml merge=hackerman

要创建一个全局 gitattributes 文件,您需要在全局 git 配置中指定其路径

[core]
    attributesfile = ~/.gitattributes

Hackerman 与无修改、单修改crate的比较

在这里,我比较了不同统一方法对工作区的影响。没有任何修改,整个工作区的干净检查涉及编译所有外部依赖项,耗时 672 秒。

工作区包含许多crate,我从其中选择了 abc 等 crate,使得 crate b 导入 crate a,crate c 导入 crate b,等等。crate a 不包含外部依赖项,其他crate则包含。

  • 无修改 - 检查是在没有任何修改的情况下进行的。
  • hackerman - 使用 cargo hackerman hack 命令生成的修改,并将新依赖项添加到每个 crate 中
  • 手动修改 - 修改由一个包含所有具有不同功能组合的 crate 组成,该新 crate 被作为依赖项包含在每个工作区的 crate 中

在运行命令之前,我清理了编译结果,然后依次运行每个列的命令

命令 无修改 hackerman 手动修改
检查-p a 0.86秒 0.80秒 215.39秒
检查-p b 211.30秒 240.15秒 113.56秒
检查-p c 362.69秒 233.38秒 176.73秒
检查-p d 36.16秒 0.24秒 0.25秒
检查-p e 385.35秒 66.34秒 375.22秒
检查 267.06秒 93.29秒 81.50秒
总计 1263.42 634.20 962.65

命令摘要

cargo hackerman

一组帮助您的项目空间快速编译的工具集

用法: cargo hackerman COMMAND ...

可用选项

  • -h, --help — 打印帮助信息
  • -V, --version — 打印版本信息

可用命令

  • hack — 在工作空间中统一各个crate的依赖关系
  • restore — 移除由hack命令添加的crate依赖关系统一
  • check — 检查是否需要统一以及校验和是否正确
  • merge — 恢复文件并与默认合并驱动程序合并
  • explain — 解释为什么某些依赖存在。功能和版本都是可选的
  • dupes — 列出工作空间中的所有重复项
  • tree — 将依赖关系制作成树形结构
  • show — 显示crate清单、readme、仓库或文档

您可以通过两次传递--help来获取更详细的帮助

cargo hackerman hack

在工作空间中统一各个crate的依赖关系

用法: cargo hackerman hack CARGO_OPTS [--dry] [--lock] [-D]

您可以使用cargo hackerman restore来撤销这些更改。

Cargo选项

  • --manifest-path=PATH — Cargo.toml文件的路径
  • --frozen — 要求Cargo.lock和缓存是最新的
  • --locked — 要求Cargo.lock是最新的
  • --offline — 不访问网络运行
  • -v, --verbose — 增加详细程度,可以多次使用

可用选项

  • --dry — 不执行操作,仅显示

  • --lock — 将依赖关系的校验和包含到stash中

    这有助于确保您能够返回到原始(未篡改)依赖项:要能够恢复原始依赖项,hackerman需要将它们存放在Cargo.toml文件中。如果CI检测到校验和不匹配,这意味着依赖项已更新为篡改源。您应该恢复它们,然后再次更新并篡改。

    您可以通过将以下内容添加到工作空间的Cargo.toml来将锁定设置为默认行为

    [workspace.metadata.hackerman]
    lock = true
    
  • -D--no-dev — 不要统一开发依赖项

  • -h, --help — 打印帮助信息

cargo-hackerman hack计算并添加一组最小额外依赖项,以便在将其作为整个工作区的一部分或单独使用时,所有依赖项的功能保持不变。

一旦篡改了依赖项,您应该在做出任何更改之前恢复它们。

cargo hackerman restore

删除由hack命令添加的crate依赖项统一

用法cargo hackerman restore CARGO_OPTS [TOML]...

Cargo选项

  • --manifest-path=PATH — Cargo.toml文件的路径
  • --frozen — 要求Cargo.lock和缓存是最新的
  • --locked — 要求Cargo.lock是最新的
  • --offline — 不访问网络运行
  • -v, --verbose — 增加详细程度,可以多次使用

可用的位置参数

  • TOML — 恢复单个文件而不是整个工作区

可用选项

  • -h, --help — 打印帮助信息

cargo hackerman check

检查是否需要统一,以及校验和是否正确

类似于cargo-hackerman hack --dry,但还将退出状态设置为1,因此您可以将其用作CI过程的一部分

用法cargo hackerman check CARGO_OPTS [-D]

Cargo选项

  • --manifest-path=PATH — Cargo.toml文件的路径
  • --frozen — 要求Cargo.lock和缓存是最新的
  • --locked — 要求Cargo.lock是最新的
  • --offline — 不访问网络运行
  • -v, --verbose — 增加详细程度,可以多次使用

可用选项

  • -D--no-dev — 不要统一开发依赖项
  • -h, --help — 打印帮助信息

cargo hackerman merge

恢复文件并与默认合并驱动程序合并

用法cargo hackerman merge BASE LOCAL REMOTE RESULT

可用选项

  • -h, --help — 打印帮助信息

要使用它,您可以在~/.gitconfig.git/config中添加类似的内容

[merge "hackerman"]
name = merge restored files with hackerman
driver = cargo hackerman merge %O %A %B %P

并在.git/gitattributes中添加类似的内容

Cargo.toml merge=hackerman

cargo hackerman explain

解释为什么某些依赖项存在。功能和版本都是可选的

用法cargo hackerman explain CARGO_OPTS [-T] [-P] [-s] CRATE [FEATURE] [VERSION]

Cargo选项

  • --manifest-path=PATH — Cargo.toml文件的路径
  • --frozen — 要求Cargo.lock和缓存是最新的
  • --locked — 要求Cargo.lock是最新的
  • --offline — 不访问网络运行
  • -v, --verbose — 增加详细程度,可以多次使用

可用选项

  • -T--no-transitive-opt — 不要删除冗余链接
  • -P--package-nodes — 使用包节点而不是功能节点
  • -s--stdout — 将点文件打印到stdout而不是启动xdot
  • -h, --help — 打印帮助信息

对于大量依赖项,可能很难确定为什么确切地包含某些子依赖项。hackerman explain通过从目标到工作区的依赖链追踪来解决这个问题。

explain 从指定的crate/feature开始,沿着反向依赖关系追踪,直到达到与工作区的所有交叉点,但不进入工作区本身。

白色节点表示工作区成员,圆形节点表示特性,八边形节点表示基础crate。点线表示仅开发依赖,虚线表示既有开发依赖又有正常依赖,但它们具有不同的特性。目标通常会被突出显示。默认情况下,hackerman会展开特性节点上的包信息,可以使用-P来撤销此操作 - 这可以通过-T来撤销。

如果一个crate存在多个版本,你可以指定你感兴趣的版本,但这不是必需的。

你也可以指定要查找的特性,否则hackerman将查找所有特性。

cargo hackerman dupes

列出工作区中的所有重复项

用法: cargo hackerman dupes CARGO_OPTS

Cargo选项

  • --manifest-path=PATH — Cargo.toml文件的路径
  • --frozen — 要求Cargo.lock和缓存是最新的
  • --locked — 要求Cargo.lock是最新的
  • --offline — 不访问网络运行
  • -v, --verbose — 增加详细程度,可以多次使用

可用选项

  • -h, --help — 打印帮助信息

cargo hackerman tree

从依赖关系中生成树

用法: cargo hackerman tree CARGO_OPTS [-T] [-D] [-P] [-w] [-s] [CRATE] [FEATURE] [VERSION]

Cargo选项

  • --manifest-path=PATH — Cargo.toml文件的路径
  • --frozen — 要求Cargo.lock和缓存是最新的
  • --locked — 要求Cargo.lock是最新的
  • --offline — 不访问网络运行
  • -v, --verbose — 增加详细程度,可以多次使用

可用选项

  • -T--no-transitive-opt — 不要删除冗余链接
  • -D, --no-dev — 不包含开发依赖
  • -P--package-nodes — 使用包节点而不是功能节点
  • -w, --workspace — 保持在工作区内
  • -s--stdout — 将点文件打印到stdout而不是启动xdot
  • -h, --help — 打印帮助信息

示例

cargo hackerman tree rand 0.8.4
cargo hackerman tree serde_json preserve_order

cargo hackerman show

显示crate清单、readme、仓库或文档

用法: cargo hackerman show CARGO_OPTS [-m | -r | -d | -R] CRATE [VERSION]

Cargo选项

  • --manifest-path=PATH — Cargo.toml文件的路径
  • --frozen — 要求Cargo.lock和缓存是最新的
  • --locked — 要求Cargo.lock是最新的
  • --offline — 不访问网络运行
  • -v, --verbose — 增加详细程度,可以多次使用

可用选项

  • -m, --manifest — 显示crate清单
  • -r, --readme — 显示crate readme
  • -d, --doc — 打开文档URL
  • -R, --repository — 仓库
  • -h, --help — 打印帮助信息

示例

cargo hackerman show --repository syn

依赖

~10–26MB
~346K SLoC