【office2pdf】 项目规则(CLAUDE.md)

  • 始终使用英语进行沟通和工作。
  • 在开始开发之前,检查项目根目录是否存在 PRD.md。如果存在,在整个开发过程中阅读并遵循其中定义的需求。
  • 重要:始终优先使用 Rust 原生实现。 避免不必要的外部依赖,尽可能利用 Rust 标准库。只有在有明确、合理的需求时才使用第三方 crate。
  • 重要:遵循测试驱动开发(TDD)。 详细规则请参见下面的**测试(TDD)**部分。
  • 重要:在开始任何任务之前,阅读并遵循 METHODOLOGY.md
  • 在编辑 CLAUDE.md 时,使用最少的词汇和句子来传达 100% 的含义。
  • 完成每个计划中的任务后,运行测试并提交,然后才能继续下一个任务。如果更改对运行时行为没有影响(例如文档、注释、CI 配置),则跳过测试。 对运行时配置文件(YAML、JSON 等会被代码读取的文件)的更改仍然必须触发测试。
  • 在任何代码更改(功能添加、错误修复、重构、PR 合并)之后,检查 README.md 是否需要更新。 如果项目描述、用法、设置、架构或 API 发生更改,请使用清晰简洁的语言更新 README.md。保持最小化------只记录用户需要知道的内容。

测试 (TDD)

  • 先编写测试。遵循红-绿-重构:(1) 失败的测试,(2) 最少的代码使其通过,(3) 重构。
  • 在测试中使用真实世界的场景和真实数据。优先使用实际用例,而不是琐碎/刻意的例子。
  • 切勿过度拟合测试。 实现必须解决通用问题,而不仅仅是特定的测试用例。不允许硬编码返回值、不允许输入匹配条件、不允许只处理测试值的逻辑。使用三角测量------当伪造/硬编码的实现通过时,添加不同输入的测试以强制泛化。
  • 测试行为,而不是实现。断言可观察的结果,而不是内部细节------测试必须在重构后仍然有效。
  • 每个新功能或错误修复都必须有相应的测试。
  • 优化测试执行速度。 并行运行独立的测试。使用 cargo test 的默认并行性。保持每个测试隔离------无共享可变状态------以便并行执行是安全的。
  • 对于 I/O 密集型测试(网络、文件),优先使用异步或使用 mock 来避免阻塞。对于 CPU 密集型测试,使用多线程并行。
  • 如果完整测试套件超过 30 秒,进行调查:将较慢的集成测试与快速单元测试分离,先运行单元测试以获得快速反馈。
  • 无运行时影响时跳过测试。 在 CI/CD 中,使用路径过滤器,仅在修改源代码、测试文件或运行时配置文件时触发测试。非运行时更改(文档、README、.md、CI 流水线配置)不应触发测试运行。

日志记录

  • 在关键决策点、状态转换和外部调用处添加结构化日志------而不是每一行。仅凭日志应能揭示执行流程和根本原因。
  • 包含上下文:请求/关联 ID、输入参数、耗时和结果(成功/失败及原因)。
  • 使用适当的日志级别:error! 用于需要采取行动的故障,warn! 用于可恢复的问题,info! 用于业务事件,debug!/trace! 用于开发诊断。
  • 使用 tracing crate 进行结构化、异步安全的日志记录。优先使用 tracing::instrument 进行自动 span 创建。
  • 切勿记录敏感数据(凭证、令牌、PII)。应对其进行屏蔽或省略。
  • 避免在热路径中过度记录------日志记录不得明显影响性能或增加延迟。

命名

  • 名称必须是自描述的------无需阅读周围代码即可理解。避免使用晦涩的缩写(procmgrtmp)。
  • 优先考虑清晰度而非简洁性,但不要过度冗长。user_email > ecalculate_shipping_cost > calc
  • 布尔值应读作是/否问题:is_validhas_permissionshould_retry
  • 函数/方法应描述操作和目标:parse_configsend_notificationvalidate_input

类型

  • 优先使用显式类型注解而非类型推断。始终为函数签名(参数和返回类型)添加注解。
  • 当变量类型从赋值中不明显时,为变量添加注解。
  • 使用 newtype 来强制执行领域语义(例如,使用 struct Emu(f64) 而不是裸 f64)。

注释

  • 解释原因,而不是内容。代码已经显示了它做了什么------注释应捕捉意图、约束和非显而易见的决策。
  • 注释业务规则、变通方法和"为什么采用这种方法而不是显而易见的方法"------这些是从代码本身无法推断出的背景信息。
  • 使用 TODO(reason)FIXME(reason) 标记已知限制------始终包含原因,而不仅仅是内容。
  • 当代码更改时删除注释------过时的注释比没有注释更糟糕。

参考项目

  • 当面临设计决策或实现挑战时,首先检查是否存在 references/INDEX.md 并找到相关的参考项目。
  • 如果 references/ 中不存在相关项目,请在网上搜索解决类似问题的维护良好的开源项目。搜索所有语言------架构模式可以跨语言迁移。
  • 当发现新的有用项目且 references/ 存在时,将其添加到 references/INDEX.md 并创建相应的详细信息文件。将详细信息文件保持在 50 行以内。
  • 在应用参考项目的模式时,引用是哪个参考项目启发了您的方法。

保密性

  • 切勿在提交消息、PR 标题/描述、问题评论或任何公开文本中提及 tests/classified_fixtures/ 的内容(文件名、路径、公司名称、个人姓名、文档标题)。
  • 使用通用引用代替:"机密测试夹具"、"内部测试文档"、"基准真值 PDF"等。

Git 配置

  • 所有提交必须使用本地 git 配置 user.nameuser.email。在提交前使用 git config user.namegit config user.email 进行验证。
  • 所有提交必须包含 Signed-off-by 行(始终使用 git commit -s)。Signed-off-by 名称必须与提交作者匹配。

分支与 PR 工作流

  • 所有更改都通过拉取请求进行。不允许直接提交到 main
  • 分支命名:<类型>/<简短描述>(例如,feat/add-parserfix/table-bug)。
  • 一个分支 = 一个聚焦的工作单元。
  • 对所有分支工作使用 git worktrees。 不要在主仓库中使用 git checkout/git switch
    • 创建:git worktree add ../<仓库名>-<分支名> -b <类型>/<简短描述>
    • 在 worktree 内工作和推送。
    • 不要在任务完成后立即删除 worktree------仅在新工作开始或用户确认后删除。

PR 合并流程

按顺序执行所有步骤:

  1. 如果 PR 描述为空或不清晰,通过 gh pr edit 重写。包括:更改了什么、为什么更改、主要更改和相关背景。
  2. 交叉引用相关 issue(gh issue list)。使用 "Related: #N"------除非另有指示,否则避免使用自动关闭关键字。
  3. 检查冲突。如果 main 有进展,根据需要变基/合并。
  4. 等待 CI 通过:gh pr checks <编号> --watch。如果测试失败则中止。
  5. 通过 gh pr diff <编号> 进行最终代码审查------检查调试语句、硬编码路径、凭据、未使用的导入。
  6. 合并:gh pr merge <编号> --merge切勿使用 --delete-branch(worktree 依赖于该分支)。
  7. 返回主仓库,执行 git pull 同步。
  8. 删除 worktree:git worktree remove ../<仓库名>-<分支名>
  9. 删除本地分支:git branch -d <分支名>
  10. 删除远程分支:git push origin --delete <分支名>

MSRV 策略 --- 6 个月滚动最低版本

本项目遵循 6 个月滚动 MSRV 策略 (与 tokio 和其他主要 crate 保持一致):

  • Cargo.toml 中的 rust-version 必须目标指向至少 6 个月前发布的 Rust 稳定版
  • Rust 稳定版每 6 周发布一次------具体日期请查阅 releases.rs
  • 当较新的 Rust 版本超过 6 个月阈值时,允许但不要求更新 MSRV------仅当较新的语言特性或依赖项要求时才升级
  • 下限: MSRV 绝不能低于 Cargo.tomledition 要求的最低版本(edition 2024 = Rust 1.85)

在任何 MSRV 变更之前:

  1. 验证未使用目标版本以上的专属语言特性或 API
  2. 确认所有依赖项都能在目标版本上编译(使用目标工具链执行 cargo check,或检查依赖项 MSRV 元数据)
  3. 更新 CI 矩阵以包含新的 MSRV 版本

视觉对比工作流

在将 PDF 输出与基准真值(机密测试夹具)进行比较时:

  1. 运行 cargo test -p office2pdf --test artifact_generator -- --ignored --nocapture 生成产物。
  2. 读取 tests/classified_fixtures/_work/report.json------包含每个文件的页数、文本长度和 PNG 路径。
  3. 识别最差文件:页数不匹配、文本长度差异大、转换错误。
  4. 对于最差文件,使用读取工具 查看 tests/classified_fixtures/_work/<work_dir>/ 中的 PNG 图片:
    • output-*.png --- office2pdf 输出渲染的页面
    • gt-*.png --- 基准真值 PDF 渲染的页面
    • output.txt / gt.txt --- 提取的文本
  5. 直观地比较输出和 GT 的 PNG 图片,以识别特定的渲染差异(布局、字体、表格、图片、边距、分页等)。
  6. 对于 macOS 上用户提供的 DOCX/XLSX/PPTX 文件,如果该文件类型有可用的 Word/Excel/PowerPoint,则首先从原生 Microsoft 应用程序导出 PDF,然后再进行推测比较。
  7. 通过 TDD 修复解析器/代码生成器中的根本原因。优先考虑能改进多个文件的高杠杆修复。

发布流程

当要求"发布"时,始终执行 GitHub Release 和 crates.io 发布

  1. 版本升级 --- 创建一个 PR(chore/publish-<版本号>),该 PR 在 crates/office2pdf/Cargo.tomlcrates/office2pdf-cli/Cargo.toml 中升级 version,并更新 CLI 的 office2pdf 依赖版本。通过标准 PR 工作流合并。
  2. GitHub Release --- gh release create v<版本号>,包含更新日志和贡献者部分。
    • 使用 git log <上一标签>..HEAD --format='%an' | sort -u 查找贡献者。列出每个贡献者并附上其 GitHub 个人资料链接。
  3. crates.io 发布 --- 先发布库,再发布 CLI:
    • cargo publish -p office2pdf
    • cargo publish -p office2pdf-cli
  4. 标签对齐 --- 确保 GitHub 发布标签(v<版本号>)与 Cargo.toml 中的版本一致。
相关推荐
望眼欲穿的程序猿4 小时前
MacOS自定义安装Rust
开发语言·macos·rust
Source.Liu5 小时前
【office2pdf】PPTX 字体解析与文本样式继承(PPTX_FONT_RESOLUTION.md)
rust·office2pdf
Rust研习社6 小时前
手把手带你写 Rust 文档
rust
迷藏4947 小时前
# 发散创新:用Rust构建高性能分布式账本节点——从零实现共识算法与链上数据存储
java·python·rust·共识算法·分布式账本
古城小栈7 小时前
Tonic:构建高性能 Rust gRPC 服务
开发语言·rust
Rust语言中文社区1 天前
【Rust日报】 Danube Messaging - 云原生消息平台
开发语言·后端·rust
Rust研习社1 天前
构建可扩展 Rust 项目:从模块化到 Workspace 工程化实践
rust
好家伙VCC1 天前
**发散创新:用 Rust实现数据编织(DataWrangling)的高效流式处理架构**在现
java·开发语言·python·架构·rust
本地化文档2 天前
rustdoc-book-l10n
rust·github·gitcode