Hash :
45b0e82a
Author :
Date :
2021-02-12T21:30:45
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138
const { markdown } = require('danger');
const fs = require('fs').promises;
const gzipSize = require('gzip-size');
const git = require('simple-git/promise')(__dirname).silent(true);
/**
* Returns the contents of a text file in the base of the PR.
*
* The base is usually PrismJS/prism/master.
*
* @param {string} path
* @returns {Promise<string>}
*/
function readBaseFile(path) {
return fs.readFile(path, 'utf-8');
}
/**
* Returns the contents of a text file in the pull request branch.
*
* @param {string} path
* @returns {Promise<string>}
*/
function readPRFile(path) {
return git.show([`pr:${path}`]);
}
/**
* Returns the relative paths of all files changed in the PR.
*
* @returns {Promise<string[]>}
*/
const getChangedFiles = async () => {
// Determine the merge base between master and the PR branch.
// If files changed in master since PR was branched they would show in the diff otherwise.
// https://stackoverflow.com/questions/25071579/list-all-files-changed-in-a-pull-request-in-git-github
const mergeBase = (await git.raw(['merge-base', 'pr', 'HEAD'])).trim();
const result = await git.diff(['--name-only', '--no-renames', 'pr', mergeBase]);
return (result || '').trim().split(/\r?\n/g);
};
const getChangedMinifiedFiles = async () => {
const changed = await getChangedFiles();
return changed.filter(file => file.endsWith('.min.js'));
};
// https://stackoverflow.com/questions/15900485/correct-way-to-convert-size-in-bytes-to-kb-mb-gb-in-javascript
const formatBytes = (bytes, decimals = 2) => {
if (bytes === 0) return '0 Bytes';
const k = 1000;
const dm = decimals < 0 ? 0 : decimals;
const sizes = ['B', 'KB', 'MB', 'GB', 'TB', 'PB', 'EB', 'ZB', 'YB'];
const i = Math.floor(Math.log(Math.abs(bytes)) / Math.log(k));
return parseFloat((bytes / Math.pow(k, i)).toFixed(dm)) + ' ' + sizes[i];
}
const maybePlus = (from, to) => from < to ? "+" : "";
const absDiff = (from, to) => {
if (from === to) {
return formatBytes(0);
}
return `${maybePlus(from, to)}${formatBytes(to - from)}`;
}
const percDiff = (from, to) => {
if (from === to) {
return '0%';
}
return `${maybePlus(from, to)}${(100 * (to - from) / (from || to)).toFixed(1)}%`;
}
const getSummary = (rows, totalMasterFileSize, totalFileSize) => {
const numFiles = rows.length;
const maybeS = rows.length > 0 ? 's' : '';
const byteDiff = absDiff(totalMasterFileSize, totalFileSize);
const percentDiff = percDiff(totalMasterFileSize, totalFileSize);
return `A total of ${numFiles} file${maybeS} have changed, with a combined diff of ${byteDiff} (${percentDiff}).`;
}
const run = async () => {
const minified = await getChangedMinifiedFiles();
if (minified.length === 0) {
markdown(`## No JS Changes`);
return;
}
const rows = [];
let totalFileSize = 0;
let totalMasterFileSize = 0;
for (const file of minified) {
const [fileContents, fileMasterContents] = await Promise.all([
readPRFile(file).catch(() => ''),
readBaseFile(file).catch(() => ''),
]);
const [fileSize, fileMasterSize] = await Promise.all([
gzipSize(fileContents),
gzipSize(fileMasterContents),
]);
totalFileSize += fileSize;
totalMasterFileSize += fileMasterSize
rows.push([
file,
formatBytes(fileMasterSize),
formatBytes(fileSize),
absDiff(fileMasterSize, fileSize),
percDiff(fileMasterSize, fileSize),
]);
}
markdown(`## JS File Size Changes (gzipped)
${getSummary(rows, totalMasterFileSize, totalFileSize)}
<details>
| file | master | pull | size diff | % diff |
| --- | --- | --- | --- | --- |
${rows.map(row => `| ${row.join(' | ')} |`).join('\n')}
</details>
`);
}
run().catch(err => {
console.error(err);
process.exit(1);
});