75 lines
3.0 KiB
JavaScript
75 lines
3.0 KiB
JavaScript
|
|
#!/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);
|