build.js 4.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153
  1. // @ts-check
  2. const {spawn, execSync} = require('child_process');
  3. const fs = require('fs');
  4. const path = require('path');
  5. const keepAsset = require('./keepAsset');
  6. const {NodeSSH} = require('node-ssh');
  7. const zlib = require('zlib');
  8. const npmCmd = /^win/.test(process.platform) ? 'npm.cmd' : 'npm';
  9. const version = process.argv[2] || 'same';
  10. const changelog = process.argv[3] || '';
  11. const child = spawn(npmCmd, ['run', 'change-version', version, changelog].filter(Boolean), {shell: true});
  12. child.stdout.on('data', (chunk) => {
  13. console.log(chunk.toString());
  14. });
  15. const publicPath = __dirname + '/public/';
  16. const distPath = __dirname + '/dist/';
  17. let sshConfig;
  18. try {
  19. sshConfig = JSON.parse(fs.readFileSync(path.join(__dirname, 'ssh.json'), 'utf8'));
  20. } catch(err) {
  21. console.log('No SSH config, skipping upload');
  22. }
  23. function copyFiles(source, destination) {
  24. if(!fs.existsSync(destination)) {
  25. fs.mkdirSync(destination);
  26. }
  27. const files = fs.readdirSync(source, {withFileTypes: true});
  28. files.forEach((file) => {
  29. const sourcePath = path.join(source, file.name);
  30. const destinationPath = path.join(destination, file.name);
  31. if(file.isFile()) {
  32. fs.copyFileSync(sourcePath, destinationPath);
  33. } else if(file.isDirectory()) {
  34. copyFiles(sourcePath, destinationPath);
  35. }
  36. });
  37. }
  38. function clearOldFiles() {
  39. const bundleFiles = fs.readdirSync(distPath);
  40. const files = fs.readdirSync(publicPath, {withFileTypes: true});
  41. files.forEach((file) => {
  42. if(file.isDirectory() ||
  43. bundleFiles.some((bundleFile) => bundleFile === file.name) ||
  44. keepAsset(file.name)) {
  45. return;
  46. }
  47. fs.unlinkSync(publicPath + file.name);
  48. });
  49. }
  50. child.on('close', (code) => {
  51. if(code != 0) {
  52. console.log(`child process exited with code ${code}`);
  53. }
  54. const child = spawn(npmCmd, ['run', 'build'], {shell: true});
  55. child.stdout.on('data', (chunk) => {
  56. console.log(chunk.toString());
  57. });
  58. let error = '';
  59. child.stderr.on('data', (chunk) => {
  60. error += chunk.toString();
  61. });
  62. child.on('close', (code) => {
  63. if(code != 0) {
  64. console.error(error, `build child process exited with code ${code}`);
  65. } else {
  66. onCompiled();
  67. }
  68. });
  69. });
  70. const ssh = new NodeSSH();
  71. const onCompiled = async() => {
  72. console.log('Compiled successfully.');
  73. copyFiles(distPath, publicPath);
  74. clearOldFiles();
  75. if(!sshConfig) {
  76. return;
  77. }
  78. const archiveName = 'archive.zip';
  79. const archivePath = path.join(__dirname, archiveName);
  80. execSync(`zip -r ${archivePath} *`, {
  81. cwd: publicPath
  82. });
  83. await ssh.connect({
  84. ...sshConfig,
  85. tryKeyboard: true
  86. });
  87. console.log('SSH connected');
  88. await ssh.execCommand(`rm -rf ${sshConfig.publicPath}/*`);
  89. console.log('Cleared old files');
  90. await ssh.putFile(archivePath, path.join(sshConfig.publicPath, archiveName));
  91. console.log('Uploaded archive');
  92. await ssh.execCommand(`cd ${sshConfig.publicPath} && unzip ${archiveName} && rm ${archiveName}`);
  93. console.log('Unzipped archive');
  94. fs.unlinkSync(archivePath);
  95. ssh.connection?.destroy();
  96. };
  97. function compressFolder(folderPath) {
  98. const archive = {};
  99. function processFolder(folderPath, parentKey) {
  100. const folderName = path.basename(folderPath);
  101. const folderKey = parentKey ? `${parentKey}/${folderName}` : folderName;
  102. archive[folderKey] = {};
  103. const files = fs.readdirSync(folderPath);
  104. for(const file of files) {
  105. const filePath = path.join(folderPath, file);
  106. const stats = fs.statSync(filePath);
  107. if(stats.isFile()) {
  108. const fileContent = fs.readFileSync(filePath);
  109. const compressedContent = zlib.deflateSync(fileContent);
  110. archive[folderKey][file] = compressedContent;
  111. break;
  112. }/* else if(stats.isDirectory()) {
  113. processFolder(filePath, folderKey);
  114. } */
  115. }
  116. }
  117. processFolder(folderPath);
  118. const compressedArchive = zlib.gzipSync(JSON.stringify(archive));
  119. return compressedArchive;
  120. }
  121. /* exec(`npm run change-version ${version}${changelog ? ' ' + changelog : ''}; npm run build`, (err, stdout, stderr) => {
  122. if(err) {
  123. return;
  124. }
  125. // the *entire* stdout and stderr (buffered)
  126. console.log(`stdout: ${stdout}`);
  127. console.log(`stderr: ${stderr}`);
  128. }); */