-
Notifications
You must be signed in to change notification settings - Fork 136
/
postinstall.js
106 lines (96 loc) · 3.36 KB
/
postinstall.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
// This is a workaround for a problem where, when yarn installs/upgrades packages,
// it will delete native modules and may not rebuild them, meaning that after a
// "yarn add" or "yarn upgrade", node_modules is in an invalid state
const https = require('https');
const path = require('path');
const fs = require('fs/promises');
const { spawn } = require('child_process');
const prebuildRC = require('prebuild-install/rc');
const prebuildUtil = require('prebuild-install/util');
const packageManager = 'yarn';
// verify these modules are installed
const verifyModules = [
['xxhash-addon', path.join('build', 'Release', 'addon.node'), false],
['libxmljs', path.join('build', 'Release', 'xmljs.node'), false],
['vortexmt', path.join('build', 'Release', 'vortexmt.node'), true],
['drivelist', path.join('build', 'Release', 'drivelist.node'), true],
['diskusage', path.join('build', 'Release', 'diskusage.node'), true],
['fomod-installer', path.join('dist', 'ModInstallerIPC.exe'), false],
];
if (process.platform === 'win32') {
verifyModules.push(
['winapi-bindings', path.join('build', 'Release', 'winapi.node'), true],
['native-errors', path.join('build', 'Release', 'native-errors.node'), true],
['crash-dump', path.join('build', 'Release', 'windump.node'), true],
);
}
async function verifyModulesInstalled() {
console.log('checking native modules');
for (const module of verifyModules) {
const modPath = path.join(__dirname, 'node_modules', module[0], module[1]);
try {
await fs.stat(modPath);
} catch (err) {
console.log('missing native module', modPath);
const pkgcli = process.platform === 'win32' ? `${packageManager}.cmd` : packageManager;
await new Promise(resolve => {
const proc = spawn(pkgcli, ['install'], { shell: true, cwd: path.join(__dirname, 'node_modules', module[0]) });
proc.on('exit', resolve);
});
try {
await fs.stat(modPath);
} catch (err) {
console.error('failed to build native module', modPath);
process.exit(1);
}
}
}
}
async function testURL(targetURL) {
return new Promise((resolve, reject) => {
const req = https.get(targetURL, {}, res => {
if ([200, 302].includes(res.statusCode)) {
resolve(true);
} else {
resolve(false);
}
req.end();
req.destroy();
res.destroy();
})
.on('error', err => {
console.log('connection failed', err);
resolve(false);
});
});
}
async function verifyPrebuild() {
console.log('checking modules are prebuilt');
for (const module of verifyModules) {
if (!module[2]) {
// not expected to be prebuilt
continue;
}
const pkg = require(path.join(__dirname, 'node_modules', module[0], 'package.json'));
if ((pkg.name === undefined) || (pkg.repository === undefined)) {
console.log('misconfigured module', module[0]);
continue;
}
if (pkg.config === undefined) {
pkg.config = {};
}
pkg.config.arch = pkg.config.arch ?? 'x64';
pkg.config.runtime = pkg.config.runtime ?? 'napi';
const opts = { ...prebuildRC(pkg), abi: '4', pkg };
const dlURL = prebuildUtil.getDownloadUrl(opts);
const exists = await testURL(dlURL);
if (!exists) {
console.log('module not prebuilt', module[0]);
}
}
}
async function main() {
verifyPrebuild();
verifyModulesInstalled();
}
main();