-
Notifications
You must be signed in to change notification settings - Fork 45
Expand file tree
/
Copy pathfile-size.mjs
More file actions
70 lines (58 loc) · 2.08 KB
/
file-size.mjs
File metadata and controls
70 lines (58 loc) · 2.08 KB
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
import { stat, readdir } from 'node:fs/promises';
import path from 'node:path';
import { BASE, HEAD, TITLE } from '../constants.mjs';
const UNITS = ['B', 'KB', 'MB', 'GB'];
/**
* Formats bytes into human-readable format
* @param {number} bytes - Number of bytes
* @returns {string} Formatted string (e.g., "1.50 KB")
*/
const formatBytes = bytes => {
if (!bytes) {
return '0 B';
}
const i = Math.floor(Math.log(Math.abs(bytes)) / Math.log(1024));
return `${(bytes / Math.pow(1024, i)).toFixed(2)} ${UNITS[i]}`;
};
/**
* Gets all files in a directory with their sizes
* @param {string} dir - Directory path to scan
* @returns {Promise<Map<string, number>>} Map of filename to size in bytes
*/
const getStats = async dir => {
const files = await readdir(dir);
return new Map(
await Promise.all(
files.map(async f => [f, (await stat(path.join(dir, f))).size])
)
);
};
// Fetch stats for both directories in parallel
const [baseStats, headStats] = await Promise.all([BASE, HEAD].map(getStats));
const didChange = f =>
baseStats.has(f) && headStats.has(f) && baseStats.get(f) !== headStats.get(f);
const toDiffObject = f => ({
file: f,
base: baseStats.get(f),
head: headStats.get(f),
diff: headStats.get(f) - baseStats.get(f),
});
// Find files that exist in both directories but have different sizes,
// then sort by absolute diff (largest changes first)
const changed = [...new Set([...baseStats.keys(), ...headStats.keys()])]
.filter(didChange)
.map(toDiffObject)
.sort((a, b) => Math.abs(b.diff) - Math.abs(a.diff));
// Output markdown table if there are changes
if (changed.length) {
const rows = changed.map(({ file, base, head, diff }) => {
const sign = diff > 0 ? '+' : '';
const percent = `${sign}${((diff / base) * 100).toFixed(2)}%`;
const diffFormatted = `${sign}${formatBytes(diff)} (${percent})`;
return `| \`${file}\` | ${formatBytes(base)} | ${formatBytes(head)} | ${diffFormatted} |`;
});
console.log(TITLE);
console.log('| File | Base | Head | Diff |');
console.log('|-|-|-|-|');
console.log(rows.join('\n') + '\n');
}