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 16import ExcelJS from 'exceljs'; 17import path from 'path'; 18import fs from 'fs'; 19import { LogUtil } from '../utils/logUtil'; 20import { ToolNameExcelCallback, joinNewMessage, joinOldMessage, ToolReturnData } from './config'; 21import { BasicDiffInfo, diffTypeMap } from '../typedef/diff/ApiInfoDiff'; 22import { OptionObjType } from './config'; 23import { SyscapProcessorHelper } from '../coreImpl/diff/syscapFieldProcessor'; 24 25export namespace WriterHelper { 26 export function JSONReporter(data: string, dest: string, fileName: string) { 27 const outputFile = path.resolve(dest, fileName); 28 fs.writeFileSync(outputFile, data); 29 LogUtil.i('JSONReporter', `report is in ${outputFile}`); 30 } 31 32 export async function ExcelReporter( 33 data: ToolReturnData, 34 dest: string, 35 fileName: string, 36 callback: ToolNameExcelCallback | undefined, 37 options?: OptionObjType 38 ) { 39 const workbook: ExcelJS.Workbook = new ExcelJS.Workbook(); 40 if (typeof callback === 'function') { 41 //callback是一个函数,才能当回调函数使用 42 callback(data, workbook, dest, options); 43 } 44 45 const buffer: NodeJS.ArrayBufferView = (await workbook.xlsx.writeBuffer()) as NodeJS.ArrayBufferView; 46 const outputFile: string = path.resolve(dest, fileName); 47 fs.writeFileSync(outputFile, buffer); 48 LogUtil.i('ExcelReporter', `report is in ${outputFile}`); 49 } 50 51 export class MarkdownReporter { 52 static writeInMarkdown(data: BasicDiffInfo[], dest: string | undefined): void { 53 const kitInfoSet: Set<string> = MarkdownReporter.getAllKitInfo(data); 54 kitInfoSet.forEach((kitInfo: string) => { 55 let diffsInSameKit: BasicDiffInfo[] = []; 56 data.forEach((diffInfo: BasicDiffInfo) => { 57 if (SyscapProcessorHelper.getSingleKitInfo(diffInfo) === kitInfo) { 58 diffsInSameKit.push(diffInfo); 59 } 60 }); 61 62 if (diffsInSameKit.length === 0) { 63 return; 64 } 65 66 MarkdownReporter.sortDiffInfoByFile(diffsInSameKit, kitInfo, dest); 67 }); 68 } 69 70 /** 71 * 获取所有的kit信息 72 * 73 * @param {BasicDiffInfo[]} data 74 * @returns 75 */ 76 static getAllKitInfo(data: BasicDiffInfo[]): Set<string> { 77 const kitInfoSet: Set<string> = new Set(); 78 data.forEach((diffInfo) => { 79 kitInfoSet.add(diffInfo.getOldKitInfo()); 80 kitInfoSet.add(diffInfo.getNewKitInfo()); 81 }); 82 return kitInfoSet; 83 } 84 85 static getSingleKitInfo(data: BasicDiffInfo): string { 86 if (data.getNewKitInfo() !== '') { 87 return data.getNewKitInfo(); 88 } 89 return data.getOldKitInfo(); 90 } 91 92 static getFileNameInkit(diffsInSameSystem: BasicDiffInfo[]): Set<string> { 93 const fileNameSet: Set<string> = new Set(); 94 diffsInSameSystem.forEach((diffInfo) => { 95 if (diffInfo.getNewDtsName() !== '') { 96 fileNameSet.add(diffInfo.getNewDtsName()); 97 } else { 98 fileNameSet.add(diffInfo.getOldDtsName()); 99 } 100 }); 101 return fileNameSet; 102 } 103 104 static getSingleFileName(data: BasicDiffInfo): string { 105 if (data.getNewDtsName() !== '') { 106 return data.getNewDtsName(); 107 } 108 return data.getOldDtsName(); 109 } 110 111 /** 112 * 使用文件名进行排序 113 * 114 * @param { BasicDiffInfo[] } diffsInSameKit 所属kit一样的diffInfo 115 * @param { string } kitInfo kit信息 116 * @param dest 117 */ 118 static sortDiffInfoByFile(diffsInSameKit: BasicDiffInfo[], kitInfo: string, dest: string | undefined): void { 119 const fileNameSet = MarkdownReporter.getFileNameInkit(diffsInSameKit); 120 const diffInfosInSameFile: BasicDiffInfo[] = []; 121 fileNameSet.forEach((fileName: string) => { 122 diffsInSameKit.forEach((diffInfo: BasicDiffInfo) => { 123 if (MarkdownReporter.getSingleFileName(diffInfo) === fileName) { 124 diffInfosInSameFile.push(diffInfo); 125 } 126 }); 127 MarkdownReporter.sortDiffInfoByStatus(diffInfosInSameFile, kitInfo, dest); 128 }); 129 } 130 131 static sortDiffInfoByStatus(diffsInSameSystem: BasicDiffInfo[], kitInfo: string, dest: string | undefined): void { 132 const sortDiffInfos: BasicDiffInfo[] = []; 133 for (const type of diffTypeMap.keys()) { 134 diffsInSameSystem.forEach((diffInfo) => { 135 if (diffInfo.getDiffType() === type) { 136 sortDiffInfos.push(diffInfo); 137 } 138 }); 139 } 140 MarkdownReporter.exportDiffMd(kitInfo, sortDiffInfos, dest); 141 } 142 143 static exportDiffMd(kitInfo: string, diffInfos: BasicDiffInfo[], dest: string | undefined): void { 144 let markDownContent: string = 145 '| 操作 | 旧版本 | 新版本 | d.ts文件 |\n' + '| ---- | ------ | ------ | -------- |\n'; 146 for (let i = 0; i < diffInfos.length; i++) { 147 let diffInfo: BasicDiffInfo = diffInfos[i]; 148 const dtsName = diffInfo.getNewDtsName() ? diffInfo.getNewDtsName() : diffInfo.getOldDtsName(); 149 markDownContent += 150 `|${diffTypeMap.get(diffInfo.getDiffType())}|${MarkdownReporter.formatDiffMessage( 151 joinOldMessage(diffInfo) 152 )}` + `|${MarkdownReporter.formatDiffMessage(joinNewMessage(diffInfo))}|${dtsName.replace(/\\/g, '/')}|\n`; 153 } 154 const mdFilesDir = `${dest}\\diff合集`; 155 if (!fs.existsSync(mdFilesDir)) { 156 fs.mkdirSync(mdFilesDir); 157 } 158 159 fs.writeFileSync(`${dest}\\diff合集\\js-apidiff-${kitInfo}.md`, markDownContent); 160 } 161 162 static formatDiffMessage(diffMessage: string): string { 163 const message = diffMessage 164 .replace(/\r|\n/g, '<br>') 165 .replace(/\|/g, '\\|') 166 .replace(/\<(?!br>)/g, '\\<'); 167 return message; 168 } 169 } 170} 171