bookworm-smart-assistant/scripts/patches/patch-sync-cleanup-paths.js

75 lines
3.0 KiB
JavaScript
Raw Permalink Normal View History

#!/usr/bin/env node
/**
* 同步项目脱敏补丁 2026-04-21
*
* 问题: scripts/auto-cleanup.js:36 + scripts/paths.config.js:13-14 含硬编码用户名 leesu
*
* 修复: os.homedir() 替代字面 'C:/Users/leesu', 注释里的示例改占位符
* 行为: 同硬编码原值 (本机 os.homedir() === C:\Users\leesu), 零行为变更
* 幂等: sentinel = 'CLEANUP_PATHS_PORTABLE_2026_04_21'
*
* : 文件为 CRLF, 用正则 (而非字面字符串) 匹配以兼容
*/
'use strict';
const fs = require('fs');
const path = require('path');
const CLAUDE_ROOT = path.join(__dirname, '..', '..');
const SENTINEL = 'CLEANUP_PATHS_PORTABLE_2026_04_21';
function patchFile(rel, regex, replacement) {
const abs = path.join(CLAUDE_ROOT, rel);
if (!fs.existsSync(abs)) {
console.error(`[patch-sync-cleanup] 目标不存在: ${rel}`);
return false;
}
const before = fs.readFileSync(abs, 'utf8');
if (before.includes(SENTINEL)) {
console.log(`[patch-sync-cleanup] ${rel} 已打过补丁,跳过`);
return true;
}
if (!regex.test(before)) {
console.error(`[patch-sync-cleanup] ${rel} 锚点未找到 (regex)`);
return false;
}
const backup = abs + '.bak.sync-portable';
if (!fs.existsSync(backup)) fs.copyFileSync(abs, backup);
// 重置 lastIndex (g flag 副作用), 用 String.replace
const after = before.replace(regex, replacement);
if (after === before) {
console.error(`[patch-sync-cleanup] ${rel} 替换未生效`);
return false;
}
if (!after.includes(SENTINEL)) {
console.error(`[patch-sync-cleanup] ${rel} sentinel 未写入`);
return false;
}
const tmp = abs + '.tmp.sync-portable';
fs.writeFileSync(tmp, after, 'utf8');
fs.renameSync(tmp, abs);
console.log(`[patch-sync-cleanup] ${rel} OK`);
return true;
}
// auto-cleanup.js: 匹配 _detectedRoot 三元赋值整行
const autoCleanupRegex = /(\r?\n)(\s*)const IS_WSL = process\.platform === 'linux' && fs\.existsSync\('\/mnt\/c'\);\r?\n\s*_detectedRoot = IS_WSL \? '\/mnt\/c\/Users\/leesu\/\.claude' : 'C:\/Users\/leesu\/\.claude';/;
const autoCleanupReplace =
`$1$2const os = require('os');$1` +
`$2const IS_WSL = process.platform === 'linux' && fs.existsSync('/mnt/c');$1` +
`$2// ${SENTINEL}: 跨机可移植, 用 os.homedir() 替代硬编码用户名$1` +
`$2_detectedRoot = IS_WSL$1` +
`$2 ? path.join('/mnt/c/Users', path.basename(os.homedir()), '.claude')$1` +
`$2 : path.join(os.homedir(), '.claude');`;
// paths.config.js: 匹配两行注释
const pathsCfgRegex = / \* 3\. WSL 默认: \/mnt\/c\/Users\/leesu\/\.claude\r?\n \* 4\. Windows 默认: C:\/Users\/leesu\/\.claude/;
const pathsCfgReplace =
` * 3. WSL 默认: /mnt/c/Users/<USER>/.claude (从 os.homedir() 动态推断) [${SENTINEL}]\r\n` +
` * 4. Windows 默认: <USER_HOME>/.claude (从 os.homedir() 动态推断)`;
const ok1 = patchFile('scripts/auto-cleanup.js', autoCleanupRegex, autoCleanupReplace);
const ok2 = patchFile('scripts/paths.config.js', pathsCfgRegex, pathsCfgReplace);
process.exit(ok1 && ok2 ? 0 : 2);