#!/usr/bin/env node // 批量跑 legacy-layer → Cocos prefab CLI。 // 每条 target: → → .prefab + .diff. // // 设计要点: // - 全部输出到隔离 OUT_DIR (out/legacy-migration/), 不直接覆盖 YouleNexus 现有 prefab. // - 单个 target 失败 (例如 ImgResID 未导入 sprite) 不阻塞后续 target, 日志记录后继续. // - per "下游不兜底" 原则: CLI 本身必须 throw 让错误暴露; batch 仅负责捕获 + 汇总, 不做修补. import { execSync } from 'node:child_process'; import { join } from 'node:path'; import { ROOT } from './lib/paths.mjs'; const OUT_DIR = join(ROOT, 'YouleNexus', 'out', 'legacy-migration'); const SOURCE = join(ROOT, '..', 'projects', 'Game_Surface_3', 'save'); // 按 spec 已核实映射表 (11 个 prefab). Layer10_Protocol + Login_Layer + Layer619_BackOtherGame 三个 PoC 已存在, // 但 batch 仍会重新生成它们 (idempotent — 覆盖 out/legacy-migration/*.prefab + .diff). const targets = [ { xml: 'Layer00002.xml', prefab: 'YouleNexus/assets/framework/ui/prefabs/Login_Layer.prefab', name: 'Login_Layer', note: 'PoC 3 (Layer00002)' }, { xml: 'Layer00017.xml', prefab: 'YouleNexus/assets/framework/ui/prefabs/views/PlayerInfoView.prefab', name: 'MenuPlayerInfo_Layer', note: '拍板 A (Layer00017)' }, { xml: 'Layer00029.xml', prefab: 'YouleNexus/assets/framework/ui/prefabs/widgets/Group106_PhoneVerify.prefab', name: 'phoneInfo' }, { xml: 'Layer00010.xml', prefab: 'YouleNexus/assets/framework/ui/prefabs/widgets/Layer10_Protocol.prefab', name: 'Protol_Layer', note: 'PoC 2 (Layer00010)' }, { xml: 'Layer00609.xml', prefab: 'YouleNexus/assets/framework/ui/prefabs/widgets/Layer609_Setting.prefab', name: 'Setting_Layer' }, { xml: 'Layer00612.xml', prefab: 'YouleNexus/assets/framework/ui/prefabs/widgets/Layer612_Tips.prefab', name: 'Tips_Layer' }, { xml: 'Layer00613.xml', prefab: 'YouleNexus/assets/framework/ui/prefabs/widgets/Layer613_RoomCardUpdate.prefab', name: 'updateRoomCard_Layer' }, { xml: 'Layer00614.xml', prefab: 'YouleNexus/assets/framework/ui/prefabs/widgets/Layer614_Loading.prefab', name: 'Loading_Layer' }, { xml: 'Layer00615.xml', prefab: 'YouleNexus/assets/framework/ui/prefabs/widgets/Layer615_Reconnect.prefab', name: 'Reconnect_Layer' }, { xml: 'Layer00616.xml', prefab: 'YouleNexus/assets/framework/ui/prefabs/widgets/Layer616_Kick.prefab', name: 'Kick_Layer' }, { xml: 'Layer00008.xml', prefab: 'YouleNexus/assets/framework/ui/prefabs/widgets/Layer617_Notice.prefab', name: 'Notice_Layer', note: '拍板 B (Layer00008)' }, { xml: 'Layer00619.xml', prefab: 'YouleNexus/assets/framework/ui/prefabs/widgets/Layer619_BackOtherGame.prefab', name: 'BackHall_Layer', note: 'PoC 1 (Layer00619)' }, { xml: 'Layer00620.xml', prefab: 'YouleNexus/assets/framework/ui/prefabs/widgets/Layer620_Record.prefab', name: 'recordLayer' }, ]; const results = { ok: [], failed: [] }; console.log(`Generating ${targets.length} prefabs to ${OUT_DIR}\n`); for (const t of targets) { console.log(`\n=== Processing ${t.name} (${t.xml}) ===`); try { execSync( `node scripts/legacy-layer-to-cocos-prefab-cli.mjs "${SOURCE}/${t.xml}" "${ROOT}/${t.prefab}" "${OUT_DIR}"`, { stdio: 'inherit' } ); results.ok.push(t.name); } catch (e) { console.error(` ⚠️ FAILED: ${t.name}: ${(e.message || String(e)).slice(0, 200)}`); results.failed.push({ name: t.name, xml: t.xml, error: (e.message || String(e)).slice(0, 200) }); // Continue with next target — partial success acceptable per "不静默兜底" + batch resilience } } console.log('\n=== Batch complete ==='); console.log(`Output dir: ${OUT_DIR}`); console.log(`OK: ${results.ok.length} | FAILED: ${results.failed.length}`); if (results.failed.length > 0) { console.log('\nFailed targets:'); for (const f of results.failed) { console.log(` - ${f.name} (${f.xml}): ${f.error}`); } } console.log('\nNext step: human reviews each .diff and decides whether to overwrite YouleNexus original prefabs.'); process.exitCode = results.failed.length > 0 ? 1 : 0;