import { FileUtil } from "../libs/hammerc/utils/FileUtil" import fs = require("fs"); import path = require("path"); import { process } from "../libs/hammerc/utils/ProcessUtil" import crc32 = require("crc32"); class JfResCompare { private _root: string; private _uiPath: string; private _webPath: string; private _fileNames = ['avatarres/effect', 'resource/assets/icon', 'resource/assets/title']; private _prefixPaths: string[]; constructor(root: string, basePath: string, webPath: string) { this.start(root, basePath, webPath); } /** * @param basePath 台湾-UI简体目录 * @param webPath 台湾-web目录 */ async start(root: string, basePath: string, webPath: string) { let s = this; s._root = root; s._uiPath = path.normalize(basePath); s._webPath = path.normalize(webPath); if (!fs.existsSync(s._uiPath)) { console.log(s._uiPath + "不存在!"); return; } if (!fs.existsSync(s._webPath)) { console.log(s._webPath + "不存在!"); return; } for (let i: number = 0; i < s._fileNames.length; i++) { let p = path.join(s._webPath, s._fileNames[i]); if (!fs.existsSync(p)) { console.log(p + "不存在"); return; } s._fileNames[i] = p; } s._prefixPaths = [s._uiPath].concat(s._fileNames); console.log('比对之前请先确保简体资源已经完善'); let state = true; let svnBat = path.join(root, 'bin'); await s.updateSvn(svnBat, path.resolve(basePath, '../')).catch(e => { state = false; console.log('更新SVN失败', e); }); await s.updateSvn(svnBat, s._webPath).catch(e => { state = false; console.log('更新SVN失败', e); }); if (!state) return; console.log('SVN更新完毕!'); FileUtil.deleteDir(s.updateFileUrl); FileUtil.deleteDir(s.addFileUrl); if (fs.existsSync(s.delsFileUrl)) fs.unlinkSync(s.delsFileUrl); if (fs.existsSync(s.addsTxtUrl)) fs.unlinkSync(s.addsTxtUrl); console.log('开始解析当前文件CRC32.....'); let newLogInfo: any = s.crc32Files();//当前资源CRC32 let oldLogInfo: any; let crcLogURL = path.join(root, 'svnlog.json');//版本信息 if (fs.existsSync(crcLogURL)) { oldLogInfo = JSON.parse(fs.readFileSync(crcLogURL).toString()); } console.log('写入新的日志文件'); fs.writeFileSync(crcLogURL, JSON.stringify(newLogInfo)); console.log('开始比对文件.....'); let compares = s.compareJt(oldLogInfo, newLogInfo);//简体比对 console.log('开始生成修改项!'); s.createChangeFiles(compares); console.log('The End'); } /**生成改变文件 */ private createChangeFiles(compares: { c: string[], a: string[], d: string[] }) { let s = this; let adds = compares.a; let dels = compares.d; let chs = compares.c; let targetUrl: string; for (let u of adds) { let prefix = s.getPrePath(u); targetUrl = path.join(s.addFileUrl, u.replace(prefix, '')); FileUtil.createDir(path.dirname(targetUrl)); fs.writeFileSync(targetUrl, fs.readFileSync(u)); } for (let a of chs) { let prefix = s.getPrePath(a); targetUrl = path.join(s.updateFileUrl, a.replace(prefix, '')); FileUtil.createDir(path.dirname(targetUrl)); fs.writeFileSync(targetUrl, fs.readFileSync(a)); } fs.writeFileSync(s.addsTxtUrl, JSON.stringify(adds)); fs.writeFileSync(s.delsFileUrl, JSON.stringify(dels)); } /**获取根目录前缀 */ private getPrePath(u: string) { let s = this; if (u.indexOf(s._uiPath) >= 0) return s._uiPath; if (u.indexOf(s._webPath) >= 0) return s._webPath; return undefined; } /**比对文件 */ private compareJt(oldLoginfo, newLogInfo) { let changes: string[] = [];//修改项 let adds: string[] = [];//新增项 let dels: string[] = [];//删除项目 if (oldLoginfo) { for (let key in newLogInfo) { if (oldLoginfo[key] && oldLoginfo[key] != newLogInfo[key]) {//有改变 changes[changes.length] = key; } else if (!oldLoginfo[key]) {//是新增 adds[adds.length] = key; } } for (let key in oldLoginfo) { if (!newLogInfo[key]) dels[dels.length] = key;//删除项目 } } else { for (let key in newLogInfo) { adds[adds.length] = key; } } return { c: changes, a: adds, d: dels }; } get updateFileUrl() { return path.join(this._root, '修改项'); } get addFileUrl() { return path.join(this._root, '新增项'); } get delsFileUrl() { return path.join(this._root, 'temp', 'delete.txt'); } get addsTxtUrl() { return path.join(this._root, 'temp', 'add.txt'); } /**crc32目录下面所有文件 */ crc32Files() { let s = this; let t = Date.now(); let fileObj = {}; let filesNames = s._prefixPaths; for (let i: number = 0; i < filesNames.length; i++) { let imgs = FileUtil.getAllFile(filesNames[i], 'png|jpg|jpeg'); if (imgs && imgs.length > 0) { for (let w of imgs) { let content = fs.readFileSync(w); let crcStr = crc32(content); fileObj[w] = crcStr; } } } console.log('耗时:', Date.now() - t); return fileObj; } async updateSvn(root: string, updatePath: string) { let state = true; console.log('正在更新 svn.......', updatePath); await process(root, "svn_up.bat " + updatePath, true).catch((e) => { state = false, console.error('SVN update fail!', e) }); } } class DelFiles { constructor() { if (fs.existsSync('./temp/delete.txt')) { let arr: string[] = JSON.parse(fs.readFileSync('./temp/delete.txt').toString()); if (arr) { let count = 0; arr.forEach(fileUrl => { fileUrl = fileUrl.replace('简体UI', '繁体UI'); if (fs.existsSync(fileUrl)) { console.log('delete:' + fileUrl); count++; fs.unlinkSync(fileUrl); } }) console.log('删除完毕,个数:' + count); } } else { console.log('不存在文件delete.txt'); } } } class CompareMoveRes { constructor() { if (fs.existsSync('./temp/add.txt')) { let arr: string[] = JSON.parse(fs.readFileSync('./temp/add.txt').toString()); if (arr) { let count = 0; arr.forEach(fileUrl => { fileUrl = fileUrl.replace('简体UI', '繁体UI'); fileUrl = fileUrl.replace('assets', 'assets_fanyi'); if (!fs.existsSync(fileUrl)) { console.log('未找到' + fileUrl); count++; } }) console.log('查找完毕,未处理个数:' + count); } } else { console.log('不存在文件add.txt'); } } } /*** * @basePath 简体参考目录 * @comparePath 繁体参考目录 */ export function run(root: string, basePath: string, comparePath: string): void { new JfResCompare(root, basePath, comparePath); } /**删除文件 */ export function del() { new DelFiles(); } export function compareDo() { new CompareMoveRes(); }