From dd7cf401a947736bee6aea70edb994c374099be1 Mon Sep 17 00:00:00 2001 From: Suzumiya Date: Fri, 11 Sep 2026 21:24:43 +0800 Subject: [PATCH] =?UTF-8?q?=E8=A1=A5=20lint-staged=20=E7=9A=84=20Rust=20?= =?UTF-8?q?=E5=AE=88=E5=8D=AB=EF=BC=9Apre-commit=20=E4=B9=9F=E8=B7=91=20ch?= =?UTF-8?q?eck:rustfmt?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - 新增 scripts/lint-staged-rustfmt.mjs:对 server-rs 与 apps/ai-game-creator-shell/src-tauri 两个 workspace 跑 cargo fmt --all --manifest-path -- --check,只查不改 - 为什么需要包装脚本:lint-staged 会把命中的暂存文件路径追加到命令末尾,而 cargo fmt 只按 workspace 粒度格式化、不接受文件参数,直接写成 npm run check:rustfmt 会被多余参数打断;脚本因此忽略 argv,并按 workspace 逐个检查 - package.json 的 lint-staged 配置新增 "*.rs": ["node scripts/lint-staged-rustfmt.mjs"] - 成因:原配置只覆盖 *.{js,mjs,cjs,ts,tsx},Rust 格式在本地完全没有守卫,唯一防线是 CI 的 check:rustfmt,本 PR 已因此红过一次(见 15660a98b) - 已实测:把包装脚本直接跑一遍 exit 0;lint-staged 分派层面确认 "*.rs" 任务会被真的触发(对 6 个 .rs 文件跑通);脚本本身过 eslint 与 prettier --check --- package.json | 3 +++ scripts/lint-staged-rustfmt.mjs | 32 ++++++++++++++++++++++++++++++++ 2 files changed, 35 insertions(+) create mode 100644 scripts/lint-staged-rustfmt.mjs diff --git a/package.json b/package.json index e7ac811f0..3e8519430 100644 --- a/package.json +++ b/package.json @@ -220,6 +220,9 @@ "*.{js,mjs,cjs,ts,tsx}": [ "node scripts/lint-staged-eslint.mjs", "prettier --write" + ], + "*.rs": [ + "node scripts/lint-staged-rustfmt.mjs" ] }, "devDependencies": { diff --git a/scripts/lint-staged-rustfmt.mjs b/scripts/lint-staged-rustfmt.mjs new file mode 100644 index 000000000..09aea7574 --- /dev/null +++ b/scripts/lint-staged-rustfmt.mjs @@ -0,0 +1,32 @@ +import { spawnSync } from 'node:child_process'; +import process from 'node:process'; + +// lint-staged 会把命中的暂存文件路径追加到命令末尾,而 `cargo fmt` 只按 workspace 粒度格式化、 +// 不接受文件参数(也做不到「只格式化某个文件」),所以这里忽略 argv,直接对两个 workspace 跑 +// `--check`。只查不改:pre-commit 不应该自动改写别人正在改的 Rust 文件。 +const workspaces = [ + 'server-rs/Cargo.toml', + 'apps/ai-game-creator-shell/src-tauri/Cargo.toml', +]; + +for (const manifestPath of workspaces) { + const result = spawnSync( + 'cargo', + ['fmt', '--all', '--manifest-path', manifestPath, '--', '--check'], + { stdio: 'inherit', shell: process.platform === 'win32' }, + ); + if (result.error) { + process.stderr.write( + `Rust 格式检查无法执行:${manifestPath}: ${result.error.message}\n`, + ); + process.exit(1); + } + if (result.status !== 0) { + process.stderr.write( + `Rust 格式检查未通过:${manifestPath}\n` + + `本地复现:npm run check:rustfmt\n` + + `自动修复:cargo fmt --all --manifest-path ${manifestPath}\n`, + ); + process.exit(result.status ?? 1); + } +}