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); + } +}