/** * 需求 0.3.1 生成處理額外分類腳本 * * 執行方式: * node scripts/scanimpl_annalysis_addon_json.js */ const fs = require('fs'); const path = require('path'); // 尋找目標檔案的遞迴函數 function findTargetJsonFiles(dir, fileList = []) { if (!fs.existsSync(dir)) return fileList; const files = fs.readdirSync(dir); for (const file of files) { const filePath = path.join(dir, file); const stat = fs.statSync(filePath); // 略過不需要掃描的系統或依賴目錄 if (stat.isDirectory() && !['node_modules', '.git', 'scripts'].includes(file)) { findTargetJsonFiles(filePath, fileList); } else if (file.startsWith('scanimpl_annalysis.') && file.endsWith('.json')) { fileList.push(filePath); } } return fileList; } function main() { // 設定路徑參數 (以執行時的目錄為基準) const baseDir = path.join(process.cwd(), 'doc/curtis/prompt/scanimpl_analysis'); const classificationFilePath = path.join(baseDir, '02', 'team_tasks_classification.json'); console.log('============================================='); console.log('開始執行額外分類整合...'); console.log(`讀取額外分類檔: ${classificationFilePath}`); if (!fs.existsSync(classificationFilePath)) { console.error(`[錯誤] 找不到額外分類檔: ${classificationFilePath}`); console.log('請確認是否在專案根目錄下執行此腳本。'); return; } // 1. 讀取並解析 team_tasks_classification.json const classificationData = JSON.parse(fs.readFileSync(classificationFilePath, 'utf8')); // 建立 lineno 到 tags 的 Mapping 字典 // 這麼做可以處理同一個 lineno 同時要新增多個不同 tag 的情況 const addonMap = new Map(); classificationData.forEach(item => { if (!item.lineno || !item.tag) return; // 將 lineno 轉為字串以確保後續比對型別一致 const linenoStr = String(item.lineno); if (!addonMap.has(linenoStr)) { addonMap.set(linenoStr, new Set()); } addonMap.get(linenoStr).add(item.tag); }); console.log(`成功載入 ${addonMap.size} 筆需要更新的行號設定。`); // 2. 找出專案內所有的 scanimpl_annalysis.*.json 檔案 const targetFiles = findTargetJsonFiles(baseDir); if (targetFiles.length === 0) { console.warn(`[警告] 在專案中找不到任何 scanimpl_annalysis.*.json 檔案`); return; } let totalUpdatedFiles = 0; let totalAddedTags = 0; // 3. 處理每一個目標 JSON 檔 targetFiles.forEach(filePath => { const fileName = path.basename(filePath); let isModified = false; let fileContent; try { fileContent = JSON.parse(fs.readFileSync(filePath, 'utf8')); } catch (e) { console.error(`[錯誤] 解析檔案 ${fileName} 失敗:`, e.message); return; } // 0.3.1.1 步驟1 變更資料 if (Array.isArray(fileContent)) { fileContent.forEach(methodDef => { const currentLIndex = String(methodDef.lIndex); // 檢查該方法的 lIndex 是否存在於我們要添加的對映表中 if (addonMap.has(currentLIndex)) { const newTags = Array.from(addonMap.get(currentLIndex)); if (!methodDef.tags) { methodDef.tags = []; } newTags.forEach(newTag => { // 避免重複添加相同的 tag if (!methodDef.tags.includes(newTag)) { methodDef.tags.push(newTag); isModified = true; totalAddedTags++; console.log(` [新增] 檔案: ${fileName} | 行號: ${currentLIndex} | 新增 Tag: "${newTag}"`); } }); } }); } // 0.3.1.2 步驟2 寫入資料 if (isModified) { fs.writeFileSync(filePath, JSON.stringify(fileContent, null, 2), 'utf8'); totalUpdatedFiles++; } }); console.log('============================================='); console.log(`執行完畢!`); console.log(`共更新了 ${totalUpdatedFiles} 個檔案,累計新增了 ${totalAddedTags} 個標籤。`); } main();