|
| 1 | +const { markdown } = require('danger'); |
| 2 | +const fs = require('fs').promises; |
| 3 | +const gzipSize = require('gzip-size'); |
| 4 | +const git = require('simple-git/promise')(__dirname).silent(true); |
| 5 | + |
| 6 | +// https://stackoverflow.com/questions/15900485/correct-way-to-convert-size-in-bytes-to-kb-mb-gb-in-javascript |
| 7 | +const formatBytes = (bytes, decimals = 2) => { |
| 8 | + if (bytes === 0) return '0 Bytes'; |
| 9 | + |
| 10 | + const k = 1000; |
| 11 | + const dm = decimals < 0 ? 0 : decimals; |
| 12 | + const sizes = ['B', 'KB', 'MB', 'GB', 'TB', 'PB', 'EB', 'ZB', 'YB']; |
| 13 | + |
| 14 | + const i = Math.floor(Math.log(Math.abs(bytes)) / Math.log(k)); |
| 15 | + |
| 16 | + return parseFloat((bytes / Math.pow(k, i)).toFixed(dm)) + ' ' + sizes[i]; |
| 17 | +} |
| 18 | + |
| 19 | +const maybePlus = (from, to) => from < to ? "+" : ""; |
| 20 | + |
| 21 | +const absDiff = (from, to) => { |
| 22 | + if (from === to) { |
| 23 | + return formatBytes(0); |
| 24 | + } |
| 25 | + |
| 26 | + return `${maybePlus(from, to)}${formatBytes(to - from)}`; |
| 27 | +} |
| 28 | + |
| 29 | +const percDiff = (from, to) => { |
| 30 | + if (from === to) { |
| 31 | + return '0%'; |
| 32 | + } |
| 33 | + |
| 34 | + return `${maybePlus(from, to)}${ |
| 35 | + (100 * (to - from) / (from || to)).toFixed(1) |
| 36 | + }%`; |
| 37 | +} |
| 38 | + |
| 39 | +const getSummary = (rows, totalMasterFileSize, totalFileSize) => { |
| 40 | + const numFiles = rows.length; |
| 41 | + const maybeS = rows.length > 0 ? 's' : ''; |
| 42 | + const byteDiff = absDiff(totalMasterFileSize, totalFileSize); |
| 43 | + const percentDiff = percDiff(totalMasterFileSize, totalFileSize); |
| 44 | + |
| 45 | + return `A total of ${numFiles} file${maybeS} have changed, with a combined diff of ${byteDiff} (${percentDiff}).`; |
| 46 | +} |
| 47 | + |
| 48 | +const getChangedMinifiedFiles = async () => { |
| 49 | + const result = await git.diff(['--name-only', '--no-renames', 'master...']); |
| 50 | + |
| 51 | + return result |
| 52 | + ? result.split(/\r?\n/g).filter(file => file.endsWith('.min.js')) |
| 53 | + : []; |
| 54 | +}; |
| 55 | + |
| 56 | +const run = async () => { |
| 57 | + // Check if master exists & check it out if not. |
| 58 | + const result = await git.branch(['--list', 'master']); |
| 59 | + if (result.all.length === 0) { |
| 60 | + await git.branch(['master', 'origin/master']); |
| 61 | + } |
| 62 | + |
| 63 | + const minified = await getChangedMinifiedFiles(); |
| 64 | + |
| 65 | + if (minified.length === 0) { |
| 66 | + markdown(`## No JS Changes`); |
| 67 | + return; |
| 68 | + } |
| 69 | + |
| 70 | + const rows = []; |
| 71 | + let totalFileSize = 0; |
| 72 | + let totalMasterFileSize = 0; |
| 73 | + |
| 74 | + for (const file of minified) { |
| 75 | + const [fileContents, fileMasterContents] = await Promise.all([ |
| 76 | + fs.readFile(file, 'utf-8').catch(() => ''), |
| 77 | + git.show([`master:${file}`]).catch(() => ''), |
| 78 | + ]); |
| 79 | + |
| 80 | + const [fileSize, fileMasterSize] = await Promise.all([ |
| 81 | + gzipSize(fileContents), |
| 82 | + gzipSize(fileMasterContents), |
| 83 | + ]); |
| 84 | + |
| 85 | + totalFileSize += fileSize; |
| 86 | + totalMasterFileSize +=fileMasterSize |
| 87 | + |
| 88 | + rows.push([ |
| 89 | + file, |
| 90 | + formatBytes(fileMasterSize), |
| 91 | + formatBytes(fileSize), |
| 92 | + absDiff(fileMasterSize, fileSize), |
| 93 | + percDiff(fileMasterSize, fileSize), |
| 94 | + ]); |
| 95 | + } |
| 96 | + |
| 97 | + markdown(`## JS File Size Changes (gzipped) |
| 98 | +
|
| 99 | +${getSummary(rows, totalMasterFileSize, totalFileSize)} |
| 100 | +
|
| 101 | +<details> |
| 102 | +
|
| 103 | +| file | master | pull | size diff | % diff | |
| 104 | +| --- | --- | --- | --- | --- | |
| 105 | +${rows.map(row => `| ${row.join(' | ')} |`).join('\n')} |
| 106 | +
|
| 107 | +</details> |
| 108 | +`); |
| 109 | +} |
| 110 | + |
| 111 | +run().catch(err => { |
| 112 | + console.error(err); |
| 113 | + process.exit(1); |
| 114 | +}); |
0 commit comments