Skip to content

Commit 2b2be73

Browse files
committed
Merge tag 'v0.20.3-beta'
2 parents 3bd7edc + 7de05c2 commit 2b2be73

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

45 files changed

+5238
-751
lines changed

.claude/skills/cargo-check-all.md

Lines changed: 41 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,41 @@
1+
# cargo-check-all
2+
3+
对整个 workspace 执行完整的 Rust 代码质量检查,依次运行编译检查、clippy 静态分析和全量测试,汇总报告结果。
4+
5+
## 工作流程
6+
7+
依次执行以下三个阶段,任何阶段失败时分析原因并给出修复建议:
8+
9+
### 阶段 1:编译检查
10+
11+
```bash
12+
cargo check --workspace 2>&1
13+
```
14+
15+
### 阶段 2:Clippy 静态分析
16+
17+
```bash
18+
cargo clippy --workspace -- -D warnings 2>&1
19+
```
20+
21+
### 阶段 3:全量测试
22+
23+
```bash
24+
cargo test --workspace 2>&1
25+
```
26+
27+
## 结果汇总
28+
29+
所有阶段执行完毕后,输出汇总表格:
30+
31+
| 阶段 | 状态 | 备注 |
32+
|------|------|------|
33+
| cargo check | PASS/FAIL | 编译错误数 |
34+
| cargo clippy | PASS/FAIL | 警告数 |
35+
| cargo test | PASS/FAIL | 通过/失败/忽略数 |
36+
37+
## 失败处理
38+
39+
- 如果 clippy 报出警告,列出所有警告并提供逐条修复方案
40+
- 如果测试失败,区分是已知的 flaky test(如 test_sql_debug 并发竞争)还是真正的回归
41+
- 编译失败时直接展示错误并分析原因

.claude/skills/commit.md

Lines changed: 68 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,68 @@
1+
# commit
2+
3+
分析当前工作区的改动,按项目规范生成 commit message 并提交。
4+
5+
## 工作流程
6+
7+
### 第一步:检查工作区状态
8+
9+
```bash
10+
git status
11+
git diff --stat
12+
git diff --staged --stat
13+
```
14+
15+
### 第二步:分析改动内容
16+
17+
读取所有已修改的文件 diff,理解改动的目的和范围:
18+
19+
```bash
20+
git diff
21+
git diff --staged
22+
```
23+
24+
如果有未追踪的新文件,检查是否需要纳入提交(排除 .env、credentials 等敏感文件)。
25+
26+
### 第三步:生成 commit message
27+
28+
根据改动内容生成简洁的 commit message:
29+
30+
**格式规范:**
31+
- 首行:祈使句式,概括改动目的(不超过 72 字符)
32+
- 空行
33+
- 可选的详细说明
34+
35+
**动词选择:**
36+
- `Add` — 全新功能或文件
37+
- `Update` — 对已有功能的增强
38+
- `Fix` — Bug 修复
39+
- `Remove` — 删除代码或功能
40+
- `Refactor` — 重构(不改变行为)
41+
- `Bump` — 依赖版本升级
42+
43+
**示例:**
44+
```
45+
Add semantic config to control NLP dictionary loading
46+
```
47+
48+
### 第四步:向用户确认
49+
50+
展示:
51+
1. 将要提交的文件列表
52+
2. 生成的 commit message
53+
54+
等待用户确认或修改后再执行提交。
55+
56+
### 第五步:执行提交
57+
58+
```bash
59+
git add <specific-files>
60+
git commit -m "<message>"
61+
```
62+
63+
## 注意事项
64+
65+
- 优先使用 `git add <具体文件>` 而非 `git add -A`
66+
- 不要提交 .env、credentials.json 等敏感文件
67+
- 不自动 push,提交后告知用户结果
68+
- 如果工作区没有改动,告知用户无需提交

.claude/skills/release-prep.md

Lines changed: 63 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,63 @@
1+
# release-prep
2+
3+
准备新版本发布:更新版本号、CHANGELOG 日期、打 git tag。
4+
5+
## 前置条件
6+
7+
执行前先确认:
8+
1. 所有代码已提交(工作区干净)
9+
2. 测试全部通过(建议先运行 /cargo-check-all)
10+
11+
## 工作流程
12+
13+
### 第一步:确认发布版本
14+
15+
```bash
16+
# 查看当前版本和最近的 tag
17+
git log --oneline --decorate -10 | grep tag
18+
head -20 CHANGELOG.md
19+
```
20+
21+
读取 CHANGELOG.md 顶部的 `[x.y.z Unreleased]` 确认要发布的版本号。
22+
如果没有 Unreleased 段落,询问用户要发布的版本号。
23+
24+
### 第二步:询问用户确认
25+
26+
向用户确认:
27+
- 版本号是否正确
28+
- CHANGELOG 中的改动是否完整
29+
- 是否需要调整任何条目
30+
31+
### 第三步:更新 CHANGELOG 日期
32+
33+
`## [x.y.z Unreleased]` 改为 `## [x.y.z] - YYYY-MM-DD`(使用今天的日期)。
34+
35+
### 第四步:更新 Cargo.toml 版本号
36+
37+
检查根 `Cargo.toml` 和各 crate 的 `Cargo.toml` 中的 version 字段:
38+
39+
```bash
40+
grep -n '^version' Cargo.toml
41+
```
42+
43+
如果版本号需要更新,逐一修改。注意只改需要变动的 crate。
44+
45+
### 第五步:提交版本变更
46+
47+
```bash
48+
git add CHANGELOG.md Cargo.toml Cargo.lock
49+
git commit -m "Release vx.y.z"
50+
```
51+
52+
### 第六步:打 tag
53+
54+
```bash
55+
git tag vx.y.z
56+
```
57+
58+
## 注意事项
59+
60+
- 每一步都需要用户确认后再继续
61+
- 不自动 push 到远端,留给用户决定
62+
- tag 格式统一为 `vx.y.z`(如 `v1.17.0`
63+
- 打完 tag 后,提示用户可以运行 `git push && git push --tags`

.claude/skills/rust-add-module.md

Lines changed: 80 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,80 @@
1+
# rust-add-module
2+
3+
在指定 crate 下新增模块:创建文件、注册 mod、添加基本结构和测试骨架。
4+
5+
## 输入
6+
7+
用户需要提供:
8+
1. 目标 crate 名称(如 `wf-core``wf-lang`
9+
2. 模块名称
10+
3. 模块用途简述
11+
12+
如果用户未提供,通过提问确认。
13+
14+
## 工作流程
15+
16+
### 第一步:确认目标位置
17+
18+
```bash
19+
ls crates/<crate-name>/src/
20+
```
21+
22+
了解现有模块结构,确认新模块应放在哪一层(顶层 mod 还是子模块)。
23+
24+
### 第二步:创建模块文件
25+
26+
根据模块复杂度决定结构:
27+
28+
- **简单模块**:创建 `crates/<crate>/src/<module>.rs`
29+
- **复杂模块**:创建 `crates/<crate>/src/<module>/mod.rs`,按需拆分子文件
30+
31+
### 第三步:注册模块
32+
33+
在父模块(通常是 `lib.rs``main.rs`)中添加 `mod` 声明:
34+
35+
```rust
36+
pub mod <module>;
37+
```
38+
39+
遵循现有代码的可见性风格(`pub mod` vs `mod` vs `pub(crate) mod`)。
40+
41+
### 第四步:添加基本结构
42+
43+
根据模块用途创建骨架代码,通常包含:
44+
45+
- 核心 struct / enum 定义
46+
- 必要的 `impl`
47+
- 必要的 trait 实现
48+
- 如果模块需要对外暴露,在 `lib.rs` 中添加 `pub use` re-export
49+
50+
### 第五步:添加测试骨架
51+
52+
在模块文件底部添加测试模块:
53+
54+
```rust
55+
#[cfg(test)]
56+
mod tests {
57+
use super::*;
58+
59+
#[test]
60+
fn test_placeholder() {
61+
// TODO: 根据实际功能补充测试
62+
}
63+
}
64+
```
65+
66+
### 第六步:验证编译
67+
68+
```bash
69+
cargo check -p <crate-name> 2>&1
70+
```
71+
72+
确保新模块能通过编译。
73+
74+
## 注意事项
75+
76+
- 遵循项目现有的命名风格(snake_case 模块名)
77+
- 查看相邻模块的 `use` 导入风格并保持一致
78+
- edition 2024 不需要 `mod.rs` 来声明子模块目录,但要检查项目现有风格
79+
- 如果 crate 间有依赖关系,可能需要在 `Cargo.toml` 中添加依赖
80+
- 不要过度设计——先创建最小可用的骨架,让用户在此基础上扩展

.claude/skills/rust-add-test.md

Lines changed: 130 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,130 @@
1+
# rust-add-test
2+
3+
为指定函数或模块编写单元测试和集成测试。
4+
5+
## 输入
6+
7+
用户需要提供:
8+
1. 要测试的函数/模块/类型名称或文件路径
9+
2. 可选:需要覆盖的具体场景
10+
11+
如果用户只给了模糊描述(如"给 parser 加测试"),先阅读代码理解后再设计测试用例。
12+
13+
## 工作流程
14+
15+
### 第一步:理解待测代码
16+
17+
阅读目标代码,分析:
18+
- 函数签名(输入类型、返回类型、是否返回 Result)
19+
- 边界条件(空输入、极端值、错误路径)
20+
- 依赖关系(是否需要 mock 或构造复杂上下文)
21+
- 现有测试(避免重复)
22+
23+
```bash
24+
# 查看现有测试
25+
cargo test -p <crate> -- --list 2>&1 | grep <module>
26+
```
27+
28+
### 第二步:设计测试用例
29+
30+
为每个函数设计测试矩阵:
31+
32+
| 类别 | 用例 | 预期结果 |
33+
|------|------|----------|
34+
| 正常路径 | 典型输入 | 正确输出 |
35+
| 边界条件 | 空输入/极值 | 合理行为 |
36+
| 错误路径 | 非法输入 | 返回 Err 或 panic |
37+
38+
### 第三步:编写单元测试
39+
40+
在目标模块文件的底部添加或扩展 `#[cfg(test)]` 模块:
41+
42+
```rust
43+
#[cfg(test)]
44+
mod tests {
45+
use super::*;
46+
47+
#[test]
48+
fn test_function_normal_case() {
49+
let result = target_function(valid_input);
50+
assert_eq!(result, expected);
51+
}
52+
53+
#[test]
54+
fn test_function_edge_case() {
55+
let result = target_function(edge_input);
56+
assert_eq!(result, expected);
57+
}
58+
59+
#[test]
60+
fn test_function_error_case() {
61+
let result = target_function(invalid_input);
62+
assert!(result.is_err());
63+
}
64+
}
65+
```
66+
67+
**命名规范:**
68+
- 测试函数名:`test_<函数名>_<场景>`
69+
- 使用描述性名称,让失败信息一目了然
70+
71+
### 第四步:编写集成测试(如需要)
72+
73+
如果需要跨模块或端到端测试,在 `crates/<crate>/tests/` 目录下创建测试文件:
74+
75+
```rust
76+
// crates/<crate>/tests/integration_test.rs
77+
use <crate>::<module>::<function>;
78+
79+
#[test]
80+
fn test_integration_scenario() {
81+
// 构造环境
82+
// 执行操作
83+
// 验证结果
84+
}
85+
```
86+
87+
### 第五步:运行测试
88+
89+
```bash
90+
# 运行新增的测试
91+
cargo test -p <crate> <test_name> -- --nocapture 2>&1
92+
93+
# 确认全量测试无回归
94+
cargo test -p <crate> 2>&1
95+
```
96+
97+
### 第六步:检查覆盖情况
98+
99+
确认测试覆盖了:
100+
- [ ] 正常路径(happy path)
101+
- [ ] 边界条件
102+
- [ ] 错误处理路径
103+
- [ ] 返回值的所有变体(如 enum 的所有 variant)
104+
105+
## 测试工具箱
106+
107+
### 断言宏
108+
- `assert_eq!(actual, expected)` — 相等比较
109+
- `assert_ne!(actual, unexpected)` — 不等比较
110+
- `assert!(condition)` — 布尔条件
111+
- `assert!(result.is_ok())` / `assert!(result.is_err())` — Result 检查
112+
- `assert!(matches!(value, Pattern))` — 模式匹配
113+
114+
### 测试辅助
115+
- `#[should_panic(expected = "message")]` — 预期 panic
116+
- `#[ignore]` — 暂时跳过(附注释说明原因)
117+
- 使用 `indoc!` 宏编写多行字符串测试输入(如果项目已依赖 indoc)
118+
119+
### 构造测试数据
120+
- 优先使用 builder pattern 或工厂函数构造复杂测试数据
121+
- 将通用的测试 fixture 提取到 `mod tests` 内的辅助函数中
122+
- 避免在测试中硬编码大段文本——使用 `include_str!` 加载测试 fixture 文件
123+
124+
## 注意事项
125+
126+
- 测试应该是确定性的,避免依赖系统时间、随机数或文件系统状态
127+
- 每个测试只验证一个行为点
128+
- 测试名称要能说明"测什么"和"预期什么"
129+
- 不要为了凑覆盖率写无意义的测试——每个测试应该验证一个有价值的行为
130+
- 遵循项目现有测试的风格和组织方式

0 commit comments

Comments
 (0)