面向 Rust 项目、Workspace 与单个源码文件的代码度量和质量分析工具,用于统一统计代码规模、复杂度、重复率、unsafe 使用与规则问题,并生成口径明确、可复核、可比较的结构化工程报告,帮助团队持续掌握代码质量变化,构建稳定、可判定、可追溯的 Rust 质量度量流程。
| 文件 | 最后提交记录 | 最后更新时间 |
|---|---|---|
| 7 天前 | ||
| 27 天前 | ||
| 5 天前 | ||
| 10 天前 | ||
| 10 天前 | ||
| 1 个月前 | ||
| 6 天前 | ||
| 10 天前 | ||
| 1 个月前 | ||
| 28 天前 | ||
| 10 天前 | ||
| 10 天前 | ||
| 2 个月前 | ||
| 6 天前 | ||
| 11 天前 | ||
| 2 个月前 |
Rust 源码只读度量工具:分析代码规模、函数复杂度、重复代码与 unsafe 使用,输出可定位的审查发现。
🤔 这是什么
BotMetric 是 Rust 源码体检工具。它读取 Cargo 包(package)、工作空间(workspace)或单个 .rs 文件,统计代码规模、函数复杂度、重复代码和 unsafe 密度,并列出值得审查的位置。每项结果都记录统计范围和可信度,便于复核和比较。
默认分析只读,不修改源码、不运行项目二进制或测试。只有显式启用 --cargo-check、--rustc-check 或 --clippy-check 时,才会调用外部编译器收集诊断;编译失败不会抹掉已经完成的源码指标,而是将报告标为 partial。
| 你想知道什么 | BotMetric 给出的结果 |
|---|---|
| 项目有多大 | 代码行数(NBNC,不计空行和纯注释行)、文件规模和函数体规模。 |
| 哪些位置值得优先检查 | 超大文件/函数、复杂度、unsafe 和重复发现条目。 |
| 结果能否比较 | 每项指标带分子、分母、范围、状态、算法和可信度;比较基准可计算增量。 |
| 编译器发现了什么 | 可选保留 rustc/Cargo/Clippy 的原始诊断、位置与错误码。 |
BotMetric 先区分代码与注释,再用 syn 3.x 解析 Rust 语法树(AST),识别函数、分支和模块等结构。它不提供完整的类型解析、trait 求解、过程宏展开或跨 crate 调用图;需要这些能力时,应使用 rustc 或相应工具。
🛠️ 安装
需要 Rust 1.89+ 和 Cargo,支持 macOS、Linux 与 Windows MSVC。编译诊断会执行项目的构建相关命令,请只对可信项目启用。
cargo install bot-metric --version 1.3.0 --locked
bot-metric --version
🚀 快速开始
Cargo 项目:
cd /path/to/rust-project
bot-metric analyze
指定工作空间或包:
bot-metric analyze --manifest-path /path/to/Cargo.toml
bot-metric analyze --manifest-path /path/to/Cargo.toml --package app
单个文件:
bot-metric analyze /path/to/file.rs --edition 2021
输出结构化结果:
bot-metric analyze --format json --output bot-metric-report.json
bot-metric analyze --format sarif --output bot-metric.sarif
需要编译器诊断时显式打开:
bot-metric analyze --cargo-check
bot-metric analyze /path/to/file.rs --edition 2021 --rustc-check
🗺️ 能力地图
flowchart LR
A[Cargo 项目] --> C[统一源码快照]
B[单个 .rs 文件] --> C
C --> D[代码与注释]
C --> E[Rust 语法树]
C --> F[构建目标与条件编译]
D --> G[规模 / 重复 / unsafe]
E --> H[函数 / 复杂度 / 规则]
F --> I[范围与聚合]
G --> J[Text / JSON / SARIF]
H --> J
I --> J
K[可选 cargo/rustc/clippy] --> J
| 能力 | 说明 |
|---|---|
| 输入发现 | 读取 Cargo 包、工作空间、构建目标、Rust edition、功能开关和本地模块;单文件不要求 Cargo.toml。 |
| 规模与复杂度 | NBNC、文件/函数行数、圈复杂度和超阈值比例。 |
| 安全与重复 | 覆盖 unsafe block/fn/trait/impl,检测完整重复文件和连续代码窗口。 |
| 规则发现条目 | 以 BM 编号、文件位置、原因、定义和建议输出可修复问题。 |
| 条件编译与汇总 | 条件能确定时按设置保留或排除代码,不能确定时保留;共享文件可只计一次,也可按各构建目标分别统计。 |
| 编译诊断 | 可选读取 Cargo、rustc 或 Clippy,保留原始渲染和错误码。 |
| 基线 | 在相同配置和范围下比较指标增量、新增与已解决发现条目。 |
🧭 命令与配置
日常入口按分析目标组织:
| 任务 | 命令 | 分析范围 |
|---|---|---|
| 查看整个 Cargo 项目 | bot-metric analyze |
当前项目源码树,共享文件只统计一次。 |
| 查看一个 Rust 文件 | bot-metric analyze path/to/file.rs |
只读取指定文件,不要求 Cargo.toml。 |
| 连同本地模块一起查看 | bot-metric analyze path/to/file.rs --resolve-modules |
从指定文件继续发现本地 mod。 |
| 检查某个构建目标 | bot-metric analyze --target app --scope reachable |
从该目标的入口出发,只读取本地模块引用到的代码。 |
| 审查一个函数或类型 | bot-metric analyze --item 'fn:crate::parser::parse' |
在本次源码范围内选择对象,多个选择重叠的代码只计一次。 |
| 按团队策略门禁 | bot-metric check PATH --config bot-metric.toml |
按配置生成发现条目并决定退出码。 |
| 保存或比较基准 | baseline create / baseline compare |
在相同配置和范围下比较质量变化。 |
默认使用 scope = auto 和 aggregation = physical:Cargo 项目扫描源码树,每个文件只统计一次。需要按各构建目标及其条件编译设置分别统计时,可使用 --scope reachable --aggregation view。
常用选项包括 --package、--target、--features、--include-tests、--resolve-modules、--format、--config、--cargo-check 和 --clippy-check。完整参数以 bot-metric <command> --help 和命令手册为准。
团队配置可以从下面这份门禁示例开始。quality_targets 默认启用;这里显式写出目标,方便评审和比较基准复用。
[analysis]
source_scope = "auto"
aggregation = "physical"
binding_crates = ["ffi-bindings"] # 按 Cargo 包名指定,不计入 unsafe 密度
[thresholds]
huge_file_lines = 2500
huge_function_lines = 300
huge_complexity = 50
duplication_min_lines = 10
duplication_max_findings = 20
duplication_snippet_lines = 18
duplication_max_index_bytes = 536870912
duplication_max_verifications = 10000000
duplication_output_bytes = 0 # 0 表示不限制报告大小
finding_arena_bytes = 16777216
finding_spill_bytes = 536870912
[rules]
duplication_findings = "off" # off | top | all
unsafe_usage = false # 设为 true 后为每处 unsafe 生成 BM002 审查提示
unknown_policy = "fail"
blocking_severities = ["warning", "error"]
blocking_rules = []
[quality_targets]
item_target = "none" # 选择局部语法项时,可设为 "input" 或 "each_item"
max_average_file_lines = 550
max_average_function_lines = 30
max_average_cyclomatic = 5
max_code_duplication_ratio = 0.15
max_file_duplication_ratio = 0.04
max_unsafe_density = 0.10
# max_code_size_growth_ratio = 0.0 # 默认关闭;取消注释开启,0 表示不允许增长
disabled_targets = []
几个选项容易混淆:
duplication_findings = "off"仍计算重复率,只是不列出 BM006/BM007 的具体重复位置;需要查看时改为top或all。unsafe_usage = false关闭 BM002 的逐处审查提示,但仍计算safety.unsafe_density并检查max_unsafe_density。设为true可打开提示。blocking_severities默认让 warning 和 error 都阻塞检查;团队只希望 error 阻塞时,可改为["error"]。
max_code_size_growth_ratio 默认关闭。配置数值后开启,并通过 check --baseline FILE 提供比较基准;0 表示不允许增长。开启后若缺少基线,且没有其他阻塞发现条目,门禁状态(gate)为 partial,退出码为 3。
命令行阈值优先于配置文件。配置、质量目标和缓存的详细说明见配置手册。
重复检测字段怎样影响大项目
| 字段 | 作用 |
|---|---|
duplication_max_findings |
top 模式最多输出的发现条目组数,不截断入选组的位置。 |
duplication_snippet_lines |
终端重复片段的上下文行数,位置列表不截断。 |
duplication_max_index_bytes |
重复窗口索引内存上限;超限时指标变为 partial 并记录 BM202。 |
duplication_max_verifications |
候选和文件字节精确复核上限;超限时保留已确认的最低值并记录 BM202。 |
duplication_output_bytes |
报告大小上限;0 表示不限制,超限不会写出截断报告。 |
finding_arena_bytes |
在内存中保存发现条目的预算;超出后转入临时存储。 |
finding_spill_bytes |
发现条目临时存储总预算;超限会明确标记不完整,不静默丢弃。 |
📦 输出与结果
人类可读输出
人类可读模式固定先回答“分析是否完成”,再回答“应该检查哪里”。下面用显式设为 50 行的函数阈值演示诊断;当前内置默认值为 300 行:
Execution Status
status: Complete
origin: Cargo
aggregation: Physical
files: 42
metrics: 43
findings: 2
compiler diagnostics: 0
analysis errors: 0
Scope
source scope: Tree
packages: 1
targets: 2
views: 2
compiler check: not requested
Codebase
code lines: 12,480
functions: 436
Key Metrics
avg file lines: 297.1 lines
avg function lines: 21.4 lines
avg complexity: 2.7
code duplication: 4.82%
unsafe density: 0.03%
Finding Breakdown
BM001 1 functions too large
BM004 1 functions too complex
Diagnostics
error[BM001]: function `parse` is too large
--> src/parser.rs:18:8
|
18 | pub fn parse(...) {
| ^^^^^
= reason: 73 code lines exceed the limit of 50 by 23
= definition: code lines exclude blanks and comment-only lines
= help: extract cohesive steps into helper functions
终端会列出每条发现条目的文件位置、源码范围、reason、definition 和 help;编译器问题优先保留 rustc 原始渲染。没有可靠源码位置时只展示消息和日志证据,不伪造行号。
规则与运行诊断
| 诊断码 | 机器规则 ID | 含义 |
|---|---|---|
BM001 |
rust.function.too_large |
函数体代码行数超过配置上限。 |
BM002 |
rust.safety.unsafe_usage |
unsafe 函数或代码块需要审查。 |
BM003 |
rust.file.too_large |
文件代码行数超过配置上限。 |
BM004 |
rust.function.too_complex |
函数圈复杂度超过配置上限。 |
BM005 |
rust.metric.target_exceeded |
已启用的数值质量目标超标,使用整个分析范围的统计结果。 |
BM006 |
rust.code.duplicated_block |
规范化 NBNC 代码片段超过重复阈值。 |
BM007 |
rust.file.exact_duplicate |
文件原始字节完全相同。 |
告警分级:BM002、BM006 和 BM007 为 warning;其它 BM 发现条目(包括项目级质量目标 BM005)为 error。分级只影响发现条目的严重度与阻塞策略,不改变检查、指标或规则 ID。
分析未完成或出错时,也会给出固定编号:BM100–BM199 表示输入与目录扫描问题,BM200–BM299 表示语法解析和源码分析问题,BM300–BM399 表示 Cargo/rustc 启动、超时或非零退出,BM400–BM499 表示配置、输出、比较基准和接口错误。rustc 的 E#### 等原始错误码保持不变。
机器报告与格式约定
| 输出 | 适用场景 |
|---|---|
| JSON | 读取状态、能力矩阵、指标、diagnostics 和发现条目。 |
| SARIF | 上传到代码扫描或 CI 平台。 |
| Baseline | 在相同配置与范围下比较质量变化。 |
报告为每项指标保存分子(numerator)、分母(denominator)、统计范围(scope)、状态(status)、算法标识(algorithm_id)和可信度(confidence)。具体计算方法,以及“不适用”“无法判断”“只完成部分分析”等状态的含义,见指标与发现条目。
退出码为:0 当前命令成功,1 为 check 命中阻塞性发现条目,2 为 CLI/配置/输入/产物错误,3 为分析失败、不完整或必需质量证据不足,4 保留兼容。check 优先报告阻塞发现条目,因此退出码 1 也可能伴随 status = partial;analyze 则不会因发现条目返回 1。自动化应同时读取退出码、分析状态与 gate 证据。
BotMetric 1.3.0 使用 analysis-report-1.2.3.json 定义报告格式,其中 compiler_run.timed_out 可区分编译器超时与普通非零退出。程序应按报告的 Schema URI 选择对应格式;已发布的 1.2.1 和 1.2.0 定义保持不变。
component-info.json 定义组件接口说明的格式。BotGate 接入时应登记报告文件路径,直接读取 diagnostics[] 中的诊断。
📚 文档
| 入口 | 适合解决的问题 |
|---|---|
| 使用手册 | 从输入选择到配置、报告、CI 和发布。 |
| 输入与分析 | Cargo、单文件、scope、cfg 和模块发现。 |
| 指标与发现条目 | 公式、阈值、规则码和状态含义。 |
| 报告与格式约定 | JSON/SARIF、Schema、比较基准和组件接口。 |
| BotGate 集成 | 在质量检查中运行 BotMetric 并读取报告。 |
| 基准说明 | 复现性能数据与资源预算。 |
| 发布与兼容性 | 构建、打包、平台验证和接口与格式检查。 |
版本边界
本文档对应 BotMetric 1.3.0,Rust edition 为 2024,最低支持 Rust 1.89(MSRV)。兼容性承诺包括已发布的报告 Schema URI、component-info.json 组件接口、命令行行为、配置字段、BM 编号和退出码。当前报告格式为 analysis-report-1.2.3.json,已发布的 1.2.0 和 1.2.1 格式继续保留。
内部 Rust 模块、实现细节和未声明的扩展字段不属于稳定 API。