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:

  1. 首先添加必要的依赖到Cargo.toml:
[dev-dependencies]
rustup-toolchain = "0.2"
rustdoc-json = "0.8"
public-api = "0.49"
insta = "1.34"
  1. 创建一个测试文件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);
}
  1. 首次运行测试并生成快照:
INSTA_UPDATE=always cargo test
  1. 将生成的快照文件添加到版本控制:
git add tests/snapshots/*.snap
git commit -m "Add initial public API snapshot"
  1. 后续更改后,可以运行以下命令查看差异:
cargo test
  1. 如果更改是预期的,更新快照:
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的变化。

主要功能

  1. 自动识别和列出库的公共API项
  2. 生成易于阅读的API文档
  3. 支持API版本比较和变更跟踪
  4. 可与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变化:

  1. 首先创建一个生成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();
}
  1. 然后创建一个比较工具:
// 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);
    }
}
  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

注意事项

  1. public-api依赖于Rust编译器的JSON输出,确保使用nightly工具链或支持JSON输出的Rust版本
  2. 对于大型项目,生成API可能需要较长时间
  3. 建议将API快照文件纳入版本控制,以便跟踪历史变更

通过public-api库,你可以更系统地管理Rust项目的公共接口,确保API变更的可控性和可追溯性。

回到顶部