patch.js 7.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207
  1. /*
  2. * @Author: liyxt
  3. * @Date: 2019-12-09 19:54:41
  4. * @LastEditors : liyxt
  5. * @LastEditTime : 2019-12-31 09:44:54
  6. * @Description: file content
  7. */
  8. const configJSON = require('../new-config.json');
  9. const fs = require('fs');
  10. const {resolve, join, sep} = require('path');
  11. const {spawn} = require('child_process');
  12. const yazl = require('yazl');
  13. const build = require('./nrb');
  14. const prompts = require('prompts');
  15. let zipfile = new yazl.ZipFile();
  16. let patchConfig = configJSON.patch || {};
  17. let args = [...process.argv];
  18. args.splice(0, 2);
  19. // 先删除dist目录
  20. delDir('./dist');
  21. delDir('./patch');
  22. // windows下npm执行名不同
  23. const ls = spawn(process.platform === 'win32' ? 'npm.cmd' : 'npm', [
  24. 'run',
  25. 'build',
  26. 'patch',
  27. ...args
  28. ]);
  29. ls.stdout.on('data', data => {
  30. if (data.includes('ERROR')) {
  31. throw new Error(data);
  32. } else {
  33. data && console.log(`${data}`);
  34. }
  35. });
  36. ls.stderr.on('data', data => {
  37. if (data.includes('ERROR')) {
  38. throw new Error(data);
  39. } else {
  40. data && console.log(`${data}`);
  41. }
  42. });
  43. ls.on('close', async code => {
  44. // 加入到zip入口
  45. addEntry(resolve(__dirname, '../dist'));
  46. // 动态修改xml
  47. let xmlconfig = {
  48. id: uuid(),
  49. provider: patchConfig.provider,
  50. department: patchConfig.department,
  51. needRecreatedLoginJar: false,
  52. needDeploy: false,
  53. time: dateFormat('YYYY-mm-dd HH:MM:SS', new Date())
  54. };
  55. let xml = fs.readFileSync(resolve(__dirname, './packmetadata.xml'), 'utf-8');
  56. Object.entries(xmlconfig).forEach(([key, value]) => {
  57. xml = xml.replace(`<!-- ${key} -->`, `<${key}>${value}</${key}>`);
  58. });
  59. fs.writeFileSync(resolve(__dirname, '../dist/packmetadata.xml'), xml, 'utf-8');
  60. zipfile.addFile('./dist/packmetadata.xml', 'packmetadata.xml');
  61. // await addReadMe(xmlconfig)
  62. let date = new Date();
  63. let mon = date.getMonth() + 1;
  64. let monStr = mon < 10 ? "0" : ""
  65. zipfile.outputStream.pipe(fs.createWriteStream(`patch${args.length > 0 ? '_' + args[args.length - 1] : ""}_${date.getFullYear() + monStr + mon + "" + date.getDate() }_${patchConfig['provider']}.zip`)).on('close', function () {
  66. console.log('补丁已出!');
  67. });
  68. zipfile.end();
  69. });
  70. async function addReadMe(config) {
  71. let response;
  72. try {
  73. response = await prompts([{
  74. type: 'text',
  75. name: 'name',
  76. message: '请输入补丁名称:',
  77. }, {
  78. type: 'text',
  79. name: 'version',
  80. message: '请输入产品版本:',
  81. }, {
  82. type: 'text',
  83. name: 'module',
  84. message: '请输入补丁修改模块:',
  85. }], {
  86. onCancel: () => {
  87. throw new Error('Operation cancelled')
  88. }
  89. });
  90. } catch (cancelled) {
  91. console.log(cancelled.message)
  92. return;
  93. }
  94. patchConfig['name'] = response.name;
  95. patchConfig['version'] = response.version;
  96. let content = "\r\n==============================================================================\r\n" +
  97. "1)补丁基本信息\r\n" +
  98. "==============================================================================\r\n" +
  99. "\r\n 补丁名称 - " + (response.name || '修改补丁') + "\r\n" +
  100. " 补丁编号 - " + (config.id) + "\r\n" +
  101. " 产品版本 - " + (response.version || '2111') + "\r\n" +
  102. " 补丁修改模块 - " + (response.module || 'hrhi') + "\r\n" +
  103. " 补丁依赖信息 - 无\r\n" +
  104. " 适用的中间件平台 - Weblogic,Websphere 7.0,Yonyou Middleware V5,Yonyou Middleware V6\r\n" +
  105. " 适用的操作系统平台 - Linux,Windows,AIX,Solaris\r\n" +
  106. " 适用的数据库平台 - DB2 V9.7,SQL Server 2008 R2,Oracle 10,Oracle 11\r\n" +
  107. " 补丁创建时间 - " + (config.time) + "\r\n" +
  108. " 是否需要部署 - false\r\n" +
  109. " 是否需要重新生成客户端Applet Jar包 - false\r\n" +
  110. "\r\n==============================================================================\r\n" +
  111. "2)补丁安装步骤说明\r\n" +
  112. "==============================================================================\r\n" +
  113. "\r\n 补丁安装前置准备工作(比如数据备份)\r\n" +
  114. " ======================================================================\r\n" +
  115. " 无\r\n" +
  116. "\r\n 补丁安装\r\n" +
  117. " ======================================================================\r\n" +
  118. " 无\r\n" +
  119. "\r\n 补丁安装后置工作\r\n" +
  120. " ======================================================================\r\n" +
  121. " 清缓存\r\n" +
  122. "\r\n 补丁安装成功的验证工作\r\n" +
  123. " ======================================================================\r\n" +
  124. " 无\r\n" +
  125. "\r\n 其它信息\r\n" +
  126. " ======================================================================\r\n" +
  127. " 无\r\n" +
  128. "\r\n==============================================================================\r\n" +
  129. "3)补丁修复bug列表说明:" + (response.name || '修改补丁') + "\r\n" +
  130. "=============================================================================="
  131. fs.writeFileSync(resolve(__dirname, '../dist/readme.txt'), content, 'utf-8');
  132. zipfile.addFile('./dist/readme.txt', 'readme.txt');
  133. }
  134. function delDir(path) {
  135. let files = [];
  136. if (fs.existsSync(path)) {
  137. files = fs.readdirSync(path);
  138. files.forEach(file => {
  139. let curPath = path + '/' + file;
  140. if (fs.statSync(curPath).isDirectory()) {
  141. delDir(curPath); //递归删除文件夹
  142. } else {
  143. fs.unlinkSync(curPath); //删除文件
  144. }
  145. });
  146. fs.rmdirSync(path);
  147. }
  148. }
  149. function uuid() {
  150. var s = [];
  151. var hexDigits = '0123456789abcdef';
  152. for (var i = 0; i < 36; i++) {
  153. s[i] = hexDigits.substr(Math.floor(Math.random() * 0x10), 1);
  154. }
  155. s[14] = '4'; // bits 12-15 of the time_hi_and_version field to 0010
  156. s[19] = hexDigits.substr((s[19] & 0x3) | 0x8, 1); // bits 6-7 of the clock_seq_hi_and_reserved to 01
  157. s[8] = s[13] = s[18] = s[23] = '-';
  158. var uuid = s.join('');
  159. return uuid;
  160. }
  161. function addEntry(prefix = './dist') {
  162. //读取目录
  163. var paths = fs.readdirSync(prefix);
  164. paths.forEach(function (path) {
  165. var from = join(prefix, path);
  166. var st = fs.statSync(from);
  167. if (st.isFile()) {
  168. zipfile.addFile(from, join('replacement/hotwebs/nccloud/resources/', from.split(`${sep}dist${sep}`)[1]));
  169. } else if (st.isDirectory()) {
  170. addEntry(from);
  171. }
  172. });
  173. }
  174. function dateFormat(fmt, date) {
  175. let ret;
  176. let opt = {
  177. 'Y+': date.getFullYear().toString(), // 年
  178. 'm+': (date.getMonth() + 1).toString(), // 月
  179. 'd+': date.getDate().toString(), // 日
  180. 'H+': date.getHours().toString(), // 时
  181. 'M+': date.getMinutes().toString(), // 分
  182. 'S+': date.getSeconds().toString() // 秒
  183. // 有其他格式化字符需求可以继续添加,必须转化成字符串
  184. };
  185. for (let k in opt) {
  186. ret = new RegExp('(' + k + ')').exec(fmt);
  187. if (ret) {
  188. fmt = fmt.replace(ret[1], ret[1].length == 1 ? opt[k] : opt[k].padStart(ret[1].length, '0'));
  189. }
  190. }
  191. return fmt;
  192. }