-
Notifications
You must be signed in to change notification settings - Fork 0
/
dangerfile.js
140 lines (113 loc) · 3.61 KB
/
dangerfile.js
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
139
140
const { markdown } = require('danger');
const fs = require('fs').promises;
const gzipSize = require('gzip-size');
const git = require('simple-git').gitP(__dirname);
/**
* 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);
});