Rust公共API文档生成库public-api的使用,自动生成Rust库的公共接口文档与版本控制
Rust公共API文档生成库public-api的使用,自动生成Rust库的公共接口文档与版本控制
public-api是一个通过分析rustdoc +nightly
的JSON输出文件来列出和比较Rust库crate公共API的工具。
使用方法
作为Rust库使用
可以在项目中使用public-api作为库来生成和分析公共API文档。
作为CLI使用
可以使用cargo public-api
命令行工具。
作为CI检查
通过常规的cargo test
在CI中运行,你可以:
- 防止对公共API的意外更改
- 审查故意更改的公共API差异
首先将推荐库的最新版本添加到你的[dev-dependencies]
中:
cargo add --dev \
rustup-toolchain \
rustdoc-json \
public-api \
insta
然后添加以下测试到你的项目中:
#[test]
fn public_api() {
// 安装兼容的nightly工具链(如果缺失)
rustup_toolchain::install(public_api::MINIMUM_NIGHTLY_RUST_VERSION).unwrap();
// 构建rustdoc JSON
let rustdoc_json = rustdoc_json::Builder::default()
.toolchain(public_api::MINIMUM_NIGHTLY_RUST_VERSION)
.build()
.unwrap();
// 从rustdoc JSON派生公共API
let public_api = public_api::Builder::from_rustdoc_json(rustdoc_json)
.build()
.unwrap();
// 断言公共API看起来正确
insta::assert_snapshot!(public_api);
}
第一次运行测试前,需要批准当前的公共API:
INSTA_UPDATE=always cargo test
这会在你的项目中创建一个tests/snapshots/<module>_public_api.snap
文件,你需要将其与其他项目文件一起git add
。之后,常规的:
cargo test
会在你的公共API被意外或故意更改时失败。再次运行:
INSTA_UPDATE=always cargo test
来审查并接受公共API的更改。
完整示例
下面是一个完整的示例展示如何使用public-api来生成和测试公共API:
- 首先添加必要的依赖到Cargo.toml:
[dev-dependencies]
rustup-toolchain = "0.2"
rustdoc-json = "0.8"
public-api = "0.49"
insta = "1.34"
- 创建一个测试文件
tests/public_api.rs
:
#[test]
fn public_api() {
// 确保安装了正确的nightly工具链
rustup_toolchain::install(public_api::MINIMUM_NIGHTLY_RUST_VERSION).unwrap();
// 生成rustdoc JSON
let rustdoc_json = rustdoc_json::Builder::default()
.toolchain(public_api::MINIMUM_NIGHTLY_RUST_VERSION)
.build()
.unwrap();
// 分析并生成公共API
let public_api = public_api::Builder::from_rustdoc_json(rustdoc_json)
.build()
.unwrap();
// 使用insta进行快照测试
insta::assert_snapshot!(public_api);
}
- 首次运行测试并生成快照:
INSTA_UPDATE=always cargo test
- 将生成的快照文件添加到版本控制:
git add tests/snapshots/*.snap
git commit -m "Add initial public API snapshot"
- 后续更改后,可以运行以下命令查看差异:
cargo test
- 如果更改是预期的,更新快照:
INSTA_UPDATE=always cargo test
注意事项
- 作为解决一个已知问题,你可能需要在
.gitattributes
中添加*.snap linguist-language=txt
- 确保使用兼容的nightly Rust版本
- 快照文件应被纳入版本控制以跟踪API变化
这个工具特别适合在库开发中使用,可以帮助维护者清晰地跟踪公共API的变化,并在CI流程中自动检测意外的API变动。
1 回复
Rust公共API文档生成库public-api的使用指南
public-api
是一个用于自动生成Rust库公共接口文档并进行版本控制的工具库。它可以帮助开发者更好地管理和跟踪公共API的变化。
主要功能
- 自动识别和列出库的公共API项
- 生成易于阅读的API文档
- 支持API版本比较和变更跟踪
- 可与CI/CD流程集成
安装方法
在Cargo.toml中添加依赖:
[dependencies]
public-api = "0.1.0"
或者使用cargo命令:
cargo add public-api
基本使用方法
1. 生成公共API列表
use public_api::PublicApi;
fn main() {
// 从当前crate生成公共API列表
let public_api = PublicApi::from_rustc_json().unwrap();
// 打印所有公共API项
for item in public_api.items() {
println!("{}", item);
}
}
2. 生成文档
use public_api::PublicApi;
fn main() {
let public_api = PublicApi::from_rustc_json().unwrap();
// 生成Markdown格式的文档
let markdown = public_api.to_markdown();
println!("{}", markdown);
// 或者生成JSON格式
let json = public_api.to_json();
println!("{}", json);
}
3. API版本比较
use public_api::{PublicApi, diff::PublicApiDiff};
fn main() {
let old_api = PublicApi::from_json_file("old_api.json").unwrap();
let new_api = PublicApi::from_rustc_json().unwrap();
// 比较两个版本的API
let diff = PublicApiDiff::between(old_api, new_api);
// 打印新增的API项
println!("Added items:");
for item in diff.added_items() {
println!("+ {}", item);
}
// 打印移除的API项
println!("Removed items:");
for item in diff.removed_items() {
println!("- {}", item);
}
}
高级用法
与CI集成
可以在CI流程中添加API检查步骤,确保公共API变更被正确记录:
# 生成当前API文档
cargo run --bin generate-api-doc > current_api.json
# 与上次提交的API进行比较
cargo run --bin check-api-changes -- old_api.json current_api.json
自定义输出格式
use public_api::PublicApi;
use serde_json::json;
fn main() {
let public_api = PublicApi::from_rustc_json().unwrap();
// 自定义JSON输出结构
let custom_json = json!({
"version": "1.0.0",
"timestamp": chrono::Utc::now().to_rfc3339(),
"api_items": public_api.items()
.iter()
.map(|item| item.to_string())
.collect::<Vec<_>>()
});
println!("{}", serde_json::to_string_pretty(&custom_json).unwrap());
}
实际应用示例
假设你有一个库my_lib
,想要跟踪其API变化:
- 首先创建一个生成API文档的工具:
// tools/api_checker.rs
use public_api::PublicApi;
use std::fs;
fn main() {
let public_api = PublicApi::from_rustc_json().unwrap();
fs::write("api_snapshot.json", public_api.to_json()).unwrap();
}
- 然后创建一个比较工具:
// tools/api_diff.rs
use public_api::{PublicApi, diff::PublicApiDiff};
fn main() {
let args: Vec<String> = std::env::args().collect();
if args.len() != 3 {
eprintln!("Usage: api_diff <old_api.json> <new_api.json>");
std::process::exit(1);
}
let old_api = PublicApi::from_json_file(&args[1]).unwrap();
let new_api = PublicApi::from_json_file(&args[2]).unwrap();
let diff = PublicApiDiff::between(old_api, new_api);
if !diff.is_empty() {
println!("API changes detected!");
diff.print_changes();
std::process::exit(1);
}
}
- 在CI配置中添加检查步骤:
# .github/workflows/ci.yml
jobs:
check_api:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v2
- uses: actions-rs/toolchain@v1
with:
toolchain: stable
- run: cargo build
- run: cargo run --bin api_checker
- name: Check API changes
run: cargo run --bin api_diff -- api_snapshot.json new_api_snapshot.json
注意事项
public-api
依赖于Rust编译器的JSON输出,确保使用nightly
工具链或支持JSON输出的Rust版本- 对于大型项目,生成API可能需要较长时间
- 建议将API快照文件纳入版本控制,以便跟踪历史变更
通过public-api
库,你可以更系统地管理Rust项目的公共接口,确保API变更的可控性和可追溯性。