Back to Blog

为 Cadmus 贡献:添加 xtask 构建过程自动化

open-source
contribution
rust
xtask
build-automation
cadmus

介绍我如何通过实现 xtask 为 Cadmus Kobo 文档阅读器项目做贡献,实现现代化构建过程自动化

Published on 1/24/2026

今天我向 Cadmus 项目做了另一次开源贡献,这是一个 Kobo 文档阅读器项目,用 Rust 编写。我实现了 xtask 模式来现代化和集中化构建过程,如 issue #74 中所要求的。

问题

Cadmus 项目有几个 shell 脚本(build.sh、bundle.sh、dist.sh 等)用于各种构建和开发任务。该问题要求现代化此过程,引入 xtask 模式,将构建逻辑从 shell 脚本移动到版本控制的 Rust 代码中。

目标是:

  • 减少对 shell 脚本和临时自动化脚本的依赖
  • 启用更丰富的、可测试的 Rust 构建和开发工具
  • 作为构建逻辑的单一真实来源(本地、CI、开发环境)
  • 从 rust-analyzer 的 xtask 实现中获取灵感

解决方案

我实施了一个完整的 xtask 解决方案,包括:

  1. 创建 xtask crate:添加了一个工作空间本地的 xtask crate,用于集中的构建、开发和 CI 逻辑

  2. 实现核心命令

    • xtask build:构建项目
    • xtask test:运行测试
    • xtask lint:运行 clippy lint
    • xtask fmt:格式化代码
    • xtask ci:运行 CI 检查
    • xtask setup-dev:设置开发环境
  3. 更新工作区配置:将 xtask 添加到 Cargo.toml 中的工作区成员

  4. 添加 CI 集成:创建了一个使用 xtask 的 GitHub Actions 工作流

技术实现

xtask 实现使用了流行的 clap crate 进行命令行解析和 anyhow 进行错误处理。结构遵循标准的 xtask 模式:

#[derive(Parser)]
#[command(name = "xtask")]
#[command(about = "Cadmus 开发任务", long_about = None)]
struct Cli {
    #[command(subcommand)]
    command: Commands,
}

#[derive(Subcommand)]
enum Commands {
    /// 构建项目
    Build {
        /// 发布版本构建
        #[arg(long)]
        release: bool,
    },
    // ... 其他命令
}

每个命令都作为一个单独的函数实现,协调适当的 cargo 命令并处理错误。

主要优势

  1. 集中化逻辑:所有构建和开发任务现在都在一个地方,与项目一起进行版本控制
  2. 类型安全:Rust 的类型系统捕获了 shell 脚本可能遗漏的错误
  3. 可测试性:构建逻辑可以像任何其他 Rust 代码一样进行测试
  4. 跨平台:在不同操作系统上一致工作
  5. 可维护性:比 shell 脚本更容易扩展和修改

结论

此贡献通过将 shell 脚本替换为健壮的、可维护的 Rust 驱动解决方案,现代化了 Cadmus 的开发工作流。xtask 模式提供了干净的接口,用于常见的开发任务,同时将所有逻辑保留在版本控制的 Rust 代码中。

拉取请求已提交,可在 OGKevin/cadmus#75 查看。这解决了 OGKevin/cadmus#74 问题,并使 Cadmus 更接近现代 Rust 开发实践。