关于 rust-dependencies
rust-dependencies 面向维护 Cargo 项目的 Rust 开发者,指导依赖治理,涵盖版本与来源选择、安全和策略检查、依赖分析及更新自动化。
主要功能
- 01选择 Cargo 版本要求
- 02评估依赖来源
- 03配置 cargo-deny 策略检查
- 04审计 RustSec 安全公告
- 05分析依赖树与重复版本
- 06管理并自动化依赖更新
适用场景
- 01为 Rust 项目制定依赖规则
- 02排查重复或循环依赖
- 03审查拟议的 Cargo.lock 更新
- 04检查依赖的安全公告与许可证策略
安装
复制下面的命令,在终端中运行。
npx skills add https:/ / github.com/ full-stack-skills/ rust-skills --skill rust-dependencies安装后在 Claude Code 中输入/rust-dependencies确认已加载。
包含的文件
除 SKILL.md 外,安装时一起下载的参考资料和脚本。
agents/openai.yamlexamples/private-registry.mdexamples/golden-deps/Cargo.lockCargo.tomlexamples/golden-deps/src/lib.rsreferences/cargo-deny-cookbook.mdversion-requirements.md详细介绍
Rust 依赖管理与治理
权威参考:Cargo — 指定依赖项,Cargo — 依赖解析,Cargo — 源替换,Cargo — 凭据,cargo-deny,cargo-audit,RustSec。
本技能负责依赖治理:如何安全地声明依赖、它们会引入什么、哪些依赖可以纳入,以及出现问题时该如何处理。本技能不负责 Cargo.toml 字段参考(rust-cargo-build)、semver(rust-semver)或工作区拓扑结构(rust-workspace)。
能力边界
✅ 优势
- 选择合适的版本要求(
"1"与"1.2"与"=1.2.3") - 评估依赖来源(crates.io / git / path / 私有注册表)
- 为供应商化或镜像注册表设置源替换
- 配置
cargo-deny(4 个表:advisories、licenses、bans、sources) - 运行
cargo-audit并响应 RustSec 安全公告 - 通过
cargo tree诊断依赖循环和重复版本问题 - 设置支持 MSRV 的解析器行为
- 使用 Renovate / Dependabot 自动更新依赖
- 为组织制定供应链政策
⚠️ 前置要求
- Cargo 清单基础知识——参见
rust-cargo-build - Semver 术语——参见
rust-semver
❌ 不在范围内
- Cargo.toml 字段逐项参考 →
rust-cargo-build - 工作区布局 →
rust-workspace - Clippy / lint 政策 →
rust-style-clippy - 测试依赖注入 →
rust-testing
数据隐私
本技能不会收集、存储或传输用户数据。访问私有注册表和使用凭据均须由用户授权;切勿记录凭据或在构建产物中暴露令牌。
第 1 部分:版本要求语法
Cargo 默认使用 SemVer 版本要求(而不是精确版本)。
| 语法 | 含义 | 兼容性 |
|---|---|---|
"1" 或 "^1" | >=1.0.0, <2.0.0 | 默认值——在主版本内自动更新 |
"1.2" 或 "^1.2" | >=1.2.0, <2.0.0 | 至少为 1.2.x |
"1.2.3" 或 "^1.2.3" | >=1.2.3, <2.0.0 | 至少为 1.2.3,也可能引入 1.5.0 |
"=1.2.3" | 精确为 1.2.3 | 锁定——用于确保可复现性 |
"~1.2" | >=1.2.0, <1.3.0 | 仅限同一次版本 |
"~1.2.3" | >=1.2.3, <1.3.0 | 仅限同一次版本 |
">=1.0, <2.0" | 范围 | 显式边界 |
"*" | 任意版本 | crates.io 禁止——范围过宽 |
"0.1" 或 "^0.1" | >=0.1.0, <0.2.0 | 1.0 之前:次版本视为主版本 |
"0.0.1" | >=0.0.1, <0.0.2 | 0.1 之前:补丁版本视为主版本 |
默认值是插入符号(^)
[dependencies]
serde = "1" # caret by default
serde = { version = "1" } # same
通常这样就合适。你会自动获得错误修复和不破坏兼容性的功能。
何时使用其他写法
| 需求 | 使用 | 示例 |
|---|---|---|
| 锁定版本以确保可复现性 | = | "=1.2.3" |
| 仅限制在次版本内 | ~ | "~1.2"(不包括 1.3.x) |
| 限定范围 | >=, < | ">=1.0, <1.5" |
| 1.0 之前且次版本更新会破坏兼容性 | 锁定次版本 | "0.7.3"(Cargo 将其视为 <0.8) |
| Git 最新提交 | git | { git = "..." } |
1.0 之前的插入符号规则
# These are equivalent and both mean <0.2:
my-crate = "0.1"
my-crate = "^0.1"
# 0.0.x is even more restrictive:
my-crate = "0.0.3" # means >=0.0.3, <0.0.4 — almost a pin
之所以存在 1.0 之前的规则,是因为 SemVer 规范将 0.x 视为“任何变更都可能发生”。Cargo 则采用了社区惯例:0.x 中的次版本递增意味着不兼容变更。
第 2 部分:依赖来源
crates.io(默认)
[dependencies]
serde = "1"
公开且不可变,并由 crates.io 审核。这是 99% 的依赖应使用的来源。
Git
[dependencies]
# Branch / tag / rev / default
my-crate = { git = "https://github.com/user/repo", branch = "dev" }
my-crate = { git = "https://github.com/user/repo", tag = "v1.0.0" }
my-crate = { git = "https://github.com/user/repo", rev = "abc1234" }
my-crate = { git = "https://github.com/user/repo" }
请谨慎使用:Git 依赖会降低 Cargo.lock 的可移植性、拖慢 CI;除非该 Git 依赖也已发布,否则无法发布到 crates.io。优先选择 crates.io、以其他名称发布的分叉版本,或 cargo vendor。
路径(本地 / 工作区)
[dependencies]
my-core = { path = "../core", version = "0.1" }
工作区内部依赖必需。发布时始终与 version 配对(否则 cargo publish 会失败)。
私有注册表
# .cargo/config.toml
[registries.my-registry]
index = "sparse+https://my-registry.example.com/index/"
[registry]
default = "my-registry" # optional: make this the default
# Cargo.toml
[dependencies]
my-private-crate = { version = "1.0", registry = "my-registry" }
源替换(透明)
Cargo Source Replacement 可让你用镜像替换 crates.io,而无需编辑每个 Cargo.toml:
# .cargo/config.toml
[source.my-mirror]
registry = "sparse+https://mirrors.example.com/crates.io-index"
[source.crates-io]
replace-with = "my-mirror"
使用场景:企业代理、中国镜像(RsProxy、tuna)、离线构建时使用 vendored 依赖。
Vendored
cargo vendor vendor/ # downloads all deps to vendor/
# .cargo/config.toml
[source.crates-io]
replace-with = "vendored-sources"
[source.vendored-sources]
directory = "vendor"
适用于隔离网络 / 可复现构建。将 vendor/ 纳入 git(它体积较大,但稳定)。
第 3 部分:依赖树分析
cargo tree
cargo tree # full tree
cargo tree --depth 2 # limit
cargo tree --invert --package X # what depends on X?
cargo tree -e features # show feature unification
cargo tree -e no-dev # exclude dev-deps
cargo tree -e no-build # exclude build-deps
查找重复项
cargo tree --duplicates # show crates with multiple versions
如果你同时看到版本为 1.0.180 和 1.0.195 的 serde,说明依赖树中存在两个版本。常见原因:
- 某个旧的传递依赖要求旧版本
- 某个 git 依赖拉取了特定版本
- 你自己的版本要求过于严格
解决重复项
cargo update -p serde # bump to latest matching req
cargo update -p serde --precise 1.0.200
如果某个传递依赖锁定了旧版本,你可以:
- 更新该传递依赖(
cargo update -p that-crate) - 接受重复版本(通常没有问题)
- 将该传递依赖替换为一个 fork
检测循环依赖
Cargo 禁止依赖图中存在循环。如果你看到:
error: cyclic package dependency: package `a` depends on `b`. package `b` depends on `a`.
这表明存在真正的设计缺陷——需要重构(通常是提取一个双方都依赖的共享 crate c)。
第 4 部分:依赖更新治理
关于当前 Cargo.lock 版本控制的指导,以及 --locked、--offline 和 --frozen 的确切行为,请使用 rust-cargo-build。当前 Cargo 指南建议:如有疑问,请提交 Cargo.lock;此处不要套用针对应用与库的禁止规则。
本技能负责规定如何提出、审查和批准已解析依赖的变更:
cargo update # bump all to latest within reqs
cargo update --precise 1.0.200 -p serde # pin a specific version
cargo update --dry-run # see what would change
- 优先使用限定到特定软件包的更新,避免无关的依赖图变动。
- 审查锁文件中源、校验和、版本、功能及重复版本的变更。
- 对拟议的依赖图运行安全公告、许可证、禁用项和源策略检查。
- 控制自动更新拉取请求的范围,并确保其变更可观察。
- 如果库需要测试新解析的依赖版本范围,请使用单独的定期兼容性流程。
- 绝不要仅为通过过时锁文件检查,就在必需的 CI 中无条件添加
cargo update。
第 5 部分:cargo-deny(供应链治理)
cargo-deny 是依赖策略事实上的标准工具。包含四项检查:
5.1 advisories — RustSec
# deny.toml
[advisories]
db-urls = ["https://github.com/rustsec/advisory-db"]
yanked = "deny"
ignore = [
# "RUSTSEC-2024-0001", # ignore specific advisory with justification
]
cargo deny check advisories
5.2 licenses — 策略
# deny.toml
[licenses]
allow = [
"MIT",
"Apache-2.0",
"BSD-3-Clause",
"ISC",
"Unicode-DFS-2016",
]
confidence-threshold = 0.93
[[licenses.exceptions]]
allow = ["Zlib"]
name = "some-zlib-crate"
version = "1.0"
cargo deny check licenses
默认策略较宽松;请根据组织的策略收紧。
5.3 bans — 禁用的 crate
# deny.toml
[bans]
multiple-versions = "warn"
wildcards = "deny" # don't allow "2.*" requirements
[[bans.deny]]
name = "openssl" # prefer rustls
version = "*"
[[bans.deny]]
name = "chrono"
version = "<0.5" # only old versions
[bans.workspace-dependencies]
duplicates = "deny" # require [workspace.dependencies]
cargo deny check bans
5.4 sources — 依赖来源
# deny.toml
[sources]
unknown-registry = "deny" # disallow non-crates.io registries
unknown-git = "deny" # disallow non-allowlisted git sources
allow-registry = ["crates-io"]
allow-git = []
cargo deny check sources
一站式检查
cargo deny check # runs all four
CI 集成:
- uses: EmbarkStudios/cargo-deny-action@v2
with:
command: check
第 6 部分:cargo-audit
cargo-audit 会根据 RustSec 安全公告数据库扫描 Cargo.lock。
cargo install cargo-audit --locked
cargo audit # scan
cargo audit --deny warnings # fail CI on warnings
cargo audit --ignore RUSTSEC-XXXX # ignore specific advisory
与 cargo-deny 的区别:
cargo-audit仅检查安全公告(侧重安全)cargo-deny涵盖安全公告 + 许可证 + 禁用项 + 来源
大多数项目会使用功能更全面的 cargo-deny。有些项目会同时使用两者(纵深防御)。
响应安全公告
- 运行
cargo audit,找出存在漏洞的 crate 及其版本 - 在 RustSec 中查找已修复的版本
- 执行
cargo update -p vulnerable-crate --precise X.Y.Z - 如果没有修复版本:切换到受维护的 fork、移除该依赖,或禁用受影响的功能
- 如果这是一个新漏洞,请向上游提交 issue
第 7 部分:自动化
Renovate
Renovate 会在依赖更新时自动创建 PR。它开箱即支持 Cargo:
// .renovaterc.json
{
"extends": ["config:recommended", ":semanticCommits"],
"schedule": ["before 6am on Monday"]
}
Dependabot
Dependabot 是 GitHub 原生工具:
# .github/dependabot.yml
version: 2
updates:
- package-ecosystem: "cargo"
directory: "/"
schedule:
interval: "weekly"
Cargo 自带的自动更新
Cargo 没有内置的“cargo update PR”工具,但你可以编写脚本:
cargo update
git diff Cargo.lock
# Commit + push to a branch
第 8 部分:精简功能
[dependencies]
serde = { version = "1", features = ["derive"] } # only what you use
tokio = { version = "1", features = ["rt-multi-thread", "macros"] }
每启用一项功能,都会增加编译时间、二进制大小和攻击面。如果只需要部分功能,请禁用默认功能:
[dependencies]
tokio = { version = "1", default-features = false, features = ["rt", "net"] }
检查功能
cargo tree -e features # which features are enabled, where
cargo tree -e features -p tokio # just tokio's features
如果传递依赖中的 tokio 显示为 [full],说明你为用不到的功能付出了代价。
工作区依赖治理
# root Cargo.toml
[workspace.dependencies]
serde = { version = "1", features = ["derive"] } # pin features once
# crates/abc/Cargo.toml
[dependencies]
serde.workspace = true # inherits feature set
防止工作区成员之间的功能配置逐渐偏离。
工作流
- 盘点 —
cargo tree -e features、cargo tree --duplicates - 审计 —
cargo audit(安全公告)+cargo deny check(完整策略检查) - 收紧版本 — 将
"*"替换为"1";仅在需要可复现时固定精确版本 - 精简功能 — 设置
default-features = false,并仅列出用到的功能 - 选择来源 — 优先使用 crates.io;仅在有正当理由时使用 git/path
- 配置 CI —
cargo build --locked、cargo deny check,以及按计划运行的cargo audit - 自动更新 — 使用 Renovate 或 Dependabot,并采用语义化提交
决策速查
| 问题 | 答案 |
|---|---|
| 固定版本还是使用插入符? | 默认使用插入符("1");仅为确保可复现时固定版本("=1.2.3") |
| 使用 crates.io 还是 git? | 除非有具体理由,否则使用 crates.io |
| 立即用最新版本还是等待? | 新主版本发布后等待 1-2 周;补丁版本自动更新 |
允许使用 "*" 版本要求吗? | 不允许 — crates.io 会拒绝,而且它们会掩盖升级 |
serde 应有多少个版本? | 一个。如果有重复项,通过 cargo tree --duplicates 追查 |
| 库项目要提交 Cargo.lock 吗? | 不要 — 下游项目负责管理锁文件 |
CI 用 --locked 还是 --frozen? | 常规 CI 使用 --locked;隔离网络环境使用 --frozen |
资源
- Cargo — 指定依赖项 — 完整语法参考
- cargo-deny 配置指南 — 四表策略
- 私有注册表设置 — 凭据、源替换
examples/golden-deps/— 包含精简且经过审计的依赖集合的小型 crate