1/* 2 * Copyright (c) 2023 Huawei Device Co., Ltd. 3 * Licensed under the Apache License, Version 2.0 (the "License"); 4 * you may not use this file except in compliance with the License. 5 * You may obtain a copy of the License at 6 * 7 * http://www.apache.org/licenses/LICENSE-2.0 8 * 9 * Unless required by applicable law or agreed to in writing, software 10 * distributed under the License is distributed on an "AS IS" BASIS, 11 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 * See the License for the specific language governing permissions and 13 * limitations under the License. 14 */ 15 16const excel = require('exceljs'); 17const path = require('path'); 18const fs = require('fs'); 19const { StatusCode, StatusMessages } = require('./reporter'); 20 21let subsystemMap = new Map(); 22let fileNameMap = new Map(); 23 24function getSubsystemMap() { 25 const subsystemFilePath = path.join(__dirname, '..', 'subsystem.json'); 26 const fileContent = JSON.parse(fs.readFileSync(subsystemFilePath, 'utf-8')); 27 fileContent.forEach(content => { 28 subsystemMap.set(content.syscap, content.subsystem); 29 fileNameMap.set(content.syscap, content.fileName); 30 }); 31} 32 33 34exports.JSONReporter = { 35 write: function (diffs, dest, oldVersion, newVersion) { 36 const outputFile = path.resolve(dest, `diff(${oldVersion}_${newVersion}).json`); 37 fs.writeFileSync(outputFile, JSON.stringify(diffs)); 38 console.log(`report is in ${outputFile}`); 39 }, 40}; 41 42exports.ChangelogReporter = { 43 write: function (diffs, dest) { 44 const outputFile = path.resolve(dest, 'changelog.json'); 45 fs.writeFileSync(outputFile, JSON.stringify(diffs)); 46 console.log(`report is in ${outputFile}`); 47 }, 48}; 49 50exports.ExcelReporter = { 51 write: async function (diffs, dest, oldVersion, newVersion) { 52 getSubsystemMap(); 53 const workbook = new excel.Workbook(); 54 const sheet = workbook.addWorksheet('api差异', { viers: [{ xSplit: 1 }] }); 55 sheet.getRow(1).values = ['操作标记', '差异项-旧版本', '差异项-新版本', 'd.ts文件', '归属子系统']; 56 diffs.forEach((diffInfo, index) => { 57 const messageObj = getDiffMessage(diffInfo); 58 const syscap = diffInfo.syscap ? diffInfo.syscap : ''; 59 const subsystem = diffInfo.packageName === 'ArkUI' ? 'ACE开发框架' : subsystemMap.get(syscap); 60 const ADD_NUMBER = 2; 61 sheet.getRow(index + ADD_NUMBER).values = [ 62 diffInfo.status, 63 messageObj.oldMessage, 64 messageObj.newMessage, 65 diffInfo.dtsName, 66 subsystem 67 ]; 68 }); 69 const buffer = await workbook.xlsx.writeBuffer(); 70 const outputFile = path.resolve(dest, 'diff.xlsx'); 71 fs.writeFileSync(outputFile, buffer); 72 console.log(`report is in ${outputFile}`); 73 }, 74}; 75 76exports.MarkDownReporter = { 77 write: function (diffs, dest) { 78 fileNameMap.forEach((fileName, syscap) => { 79 let diffsInSameSystem = []; 80 diffs.forEach(diffInfo => { 81 if (diffInfo.syscap === syscap) { 82 diffsInSameSystem.push(diffInfo); 83 } 84 }); 85 if (diffsInSameSystem.length === 0) { 86 return; 87 } 88 89 sortDiffInfoByStatus(diffsInSameSystem, fileName, dest); 90 }); 91 }, 92}; 93 94function sortDiffInfoByStatus(diffsInSameSystem, fileName, dest) { 95 const sortDiffInfos = []; 96 StatusMessages.forEach(status => { 97 diffsInSameSystem.forEach(diffInfo => { 98 if (diffInfo.status === status) { 99 sortDiffInfos.push(diffInfo); 100 } 101 }); 102 }); 103 exportDiffMd(fileName, sortDiffInfos, dest); 104} 105 106function exportDiffMd(fileName, diffInfos, dest) { 107 let finalContent = '| 操作 | 旧版本 | 新版本 | d.ts文件 |\n' + '| ---- | ------ | ------ | -------- |\n'; 108 for (let i = 0; i < diffInfos.length; i++) { 109 let apiData = diffInfos[i]; 110 const messageObj = getDiffMessage(apiData); 111 const oldData = messageObj.oldMessage.replace(/\r|\n/g, '<br>').replace(/\|/g, '\\|').replace(/\<(?!br>)/g, '\\<'); 112 const newData = messageObj.newMessage.replace(/\r|\n/g, '<br>').replace(/\|/g, '\\|').replace(/\<(?!br>)/g, '\\<'); 113 finalContent += `|${apiData.status}|${oldData}|${newData}|${apiData.dtsName}|\n`; 114 } 115 const mdFilesDir = `${dest}\\diff合集`; 116 if (!fs.existsSync(mdFilesDir)) { 117 fs.mkdirSync(mdFilesDir); 118 } 119 120 fs.writeFileSync(`${dest}\\diff合集\\js-apidiff-${fileName}.md`, finalContent); 121 122} 123 124 125function getDiffMessage(diffInfo) { 126 let oldMessage = 'NA'; 127 let newMessage = 'NA'; 128 if (diffInfo.statusCode === StatusCode.DELETE) { 129 oldMessage = `类名:${diffInfo.className};\n方法or属性:${diffInfo.rawText}`; 130 } else if (diffInfo.statusCode === StatusCode.DELETE_CLASS) { 131 oldMessage = `类名声明:${diffInfo.rawText}`; 132 } else if (diffInfo.statusCode === StatusCode.NEW_API) { 133 newMessage = `类名:${diffInfo.className};\n方法or属性:${diffInfo.rawText}`; 134 } else if (diffInfo.statusCode === StatusCode.DELETE_DTS) { 135 oldMessage = `文件名:${diffInfo.dtsName}`; 136 } else if (diffInfo.statusCode === StatusCode.FUNCTION_CHANGES) { 137 oldMessage = `类名:${diffInfo.className};\n方法or属性:${diffInfo.oldMessage}`; 138 newMessage = `类名:${diffInfo.className};\n方法or属性:${diffInfo.newMessage}`; 139 } else if (diffInfo.statusCode === StatusCode.DEPRECATED_CHNAGES) { 140 const useinsteadInfo = diffInfo.hint.replace('useinstead:', ''); 141 oldMessage = `类名:${diffInfo.className};\n方法or属性:${diffInfo.rawText}\n旧版本信息:${diffInfo.oldMessage}`; 142 newMessage = `类名:${diffInfo.className};\n方法or属性:${diffInfo.rawText}\n新版本信息:${diffInfo.newMessage}\n代替接口:${useinsteadInfo}`; 143 } else { 144 oldMessage = `类名:${diffInfo.className};\n方法or属性:${diffInfo.rawText}\n旧版本信息:${diffInfo.oldMessage}`; 145 newMessage = `类名:${diffInfo.className};\n方法or属性:${diffInfo.rawText}\n新版本信息:${diffInfo.newMessage}`; 146 } 147 return { oldMessage, newMessage }; 148}