[Updater > Module] Rewrite to deeply integrate custom unzip instead of yauzl polyfill, other unzip improvements and minor source cleanup
This commit is contained in:
parent
a0e288821e
commit
86c17ca29f
|
@ -1,48 +0,0 @@
|
||||||
// Jank replacement for yauzl by just using unzip where it expects and skipping (speed++, size--, jank++)
|
|
||||||
const { execFile } = require('child_process');
|
|
||||||
const mkdirp = require('mkdirp');
|
|
||||||
|
|
||||||
exports.open = async (zipPath, _opts, callback) => {
|
|
||||||
const extractPath = `${global.moduleDataPath}/${zipPath.split('/').pop().split('.')[0].split('-')[0]}`;
|
|
||||||
const listeners = [];
|
|
||||||
|
|
||||||
const errorOut = (err) => {
|
|
||||||
listeners.error(err);
|
|
||||||
};
|
|
||||||
|
|
||||||
const entryCount = await new Promise((res) => {
|
|
||||||
execFile('unzip', ['-l', zipPath]).stdout.on('data', (x) => {
|
|
||||||
const m = x.toString().match(/([0-9]+) files/);
|
|
||||||
if (m) res(parseInt(m[1]));
|
|
||||||
});
|
|
||||||
|
|
||||||
setTimeout(res, 500);
|
|
||||||
});
|
|
||||||
|
|
||||||
callback(null, {
|
|
||||||
on: (event, listener) => {
|
|
||||||
listeners[event] = listener;
|
|
||||||
},
|
|
||||||
|
|
||||||
entryCount
|
|
||||||
});
|
|
||||||
|
|
||||||
mkdirp.sync(extractPath);
|
|
||||||
|
|
||||||
const proc = execFile('unzip', ['-o', zipPath, '-d', extractPath]);
|
|
||||||
|
|
||||||
proc.on('error', (err) => {
|
|
||||||
if (err.code === 'ENOENT') {
|
|
||||||
require('electron').dialog.showErrorBox('Failed Dependency', 'Please install "unzip", exiting');
|
|
||||||
process.exit(1); // Close now
|
|
||||||
}
|
|
||||||
|
|
||||||
errorOut(err);
|
|
||||||
});
|
|
||||||
|
|
||||||
proc.stderr.on('data', errorOut);
|
|
||||||
|
|
||||||
proc.stdout.on('data', (x) => x.toString().split('\n').forEach((x) => x.includes('inflating') && listeners.entry()));
|
|
||||||
|
|
||||||
proc.on('close', () => listeners.end());
|
|
||||||
};
|
|
|
@ -1,8 +1,8 @@
|
||||||
const { join } = require('path');
|
const { join } = require('path');
|
||||||
const fs = require('fs');
|
const fs = require('fs');
|
||||||
const mkdirp = require('mkdirp');
|
const mkdirp = require('mkdirp');
|
||||||
const yauzl = require('yauzl');
|
|
||||||
const Module = require('module');
|
const Module = require('module');
|
||||||
|
const { execFile } = require('child_process');
|
||||||
|
|
||||||
const paths = require('../paths');
|
const paths = require('../paths');
|
||||||
const request = require('./request');
|
const request = require('./request');
|
||||||
|
@ -198,14 +198,9 @@ const downloadModule = async (name, ver) => {
|
||||||
const path = join(downloadPath, name + '-' + ver + '.zip');
|
const path = join(downloadPath, name + '-' + ver + '.zip');
|
||||||
const stream = fs.createWriteStream(path);
|
const stream = fs.createWriteStream(path);
|
||||||
|
|
||||||
let received = 0, progress = 0;
|
|
||||||
stream.on('progress', ([recv, total]) => {
|
stream.on('progress', ([recv, total]) => {
|
||||||
received = recv;
|
const progress = Math.min(100, Math.floor(100 * (recv / total)));
|
||||||
const nProgress = Math.min(100, Math.floor(100 * (recv / total)));
|
|
||||||
|
|
||||||
if (progress === nProgress) return;
|
|
||||||
|
|
||||||
progress = nProgress;
|
|
||||||
events.emit('downloading-module-progress', {
|
events.emit('downloading-module-progress', {
|
||||||
name,
|
name,
|
||||||
progress,
|
progress,
|
||||||
|
@ -235,7 +230,7 @@ const downloadModule = async (name, ver) => {
|
||||||
else downloading.fail++;
|
else downloading.fail++;
|
||||||
|
|
||||||
events.emit('downloaded-module', {
|
events.emit('downloaded-module', {
|
||||||
name: name,
|
name,
|
||||||
current: downloading.total,
|
current: downloading.total,
|
||||||
total: downloading.total
|
total: downloading.total
|
||||||
});
|
});
|
||||||
|
@ -256,7 +251,7 @@ const downloadModule = async (name, ver) => {
|
||||||
installModule(name, ver, path);
|
installModule(name, ver, path);
|
||||||
};
|
};
|
||||||
|
|
||||||
const installModule = (name, ver, path) => {
|
const installModule = async (name, ver, path) => {
|
||||||
installing.total++;
|
installing.total++;
|
||||||
events.emit('installing-module', {
|
events.emit('installing-module', {
|
||||||
name,
|
name,
|
||||||
|
@ -278,38 +273,58 @@ const installModule = (name, ver, path) => {
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
try {
|
// Extract zip via unzip cmd line - replaces yauzl dep (speed++, size--, jank++)
|
||||||
yauzl.open(path, {}, (e, zip) => {
|
const ePath = join(basePath, name);
|
||||||
if (e) return handleErr(e);
|
|
||||||
|
const total = await new Promise((res) => {
|
||||||
const total = zip.entryCount;
|
const p = execFile('unzip', ['-l', path]);
|
||||||
let entries = 0;
|
|
||||||
zip.on('entry', () => {
|
p.stdout.on('data', (x) => {
|
||||||
entries++;
|
const m = x.toString().match(/([0-9]+) files/);
|
||||||
const progress = Math.min(100, Math.floor(entries / total * 100));
|
if (m) res(parseInt(m[1]));
|
||||||
|
|
||||||
events.emit('installing-module-progress', {
|
|
||||||
name,
|
|
||||||
progress,
|
|
||||||
entries,
|
|
||||||
total
|
|
||||||
});
|
|
||||||
});
|
|
||||||
|
|
||||||
zip.on('error', handleErr);
|
|
||||||
|
|
||||||
zip.on('end', () => {
|
|
||||||
if (hasError) return;
|
|
||||||
|
|
||||||
installed[name].installedVersion = ver;
|
|
||||||
commitManifest();
|
|
||||||
|
|
||||||
finishInstall(name, ver, true);
|
|
||||||
});
|
|
||||||
});
|
});
|
||||||
} catch (e) {
|
|
||||||
onError(e);
|
p.stderr.on('data', res); // On error resolve undefined (??'d to 0)
|
||||||
}
|
}) ?? 0;
|
||||||
|
|
||||||
|
mkdirp.sync(ePath);
|
||||||
|
|
||||||
|
const proc = execFile('unzip', ['-o', path, '-d', ePath]);
|
||||||
|
|
||||||
|
proc.on('error', (err) => {
|
||||||
|
if (err.code === 'ENOENT') {
|
||||||
|
require('electron').dialog.showErrorBox('Failed Dependency', 'Please install "unzip"');
|
||||||
|
process.exit(1); // Close now
|
||||||
|
}
|
||||||
|
|
||||||
|
handleErr(err);
|
||||||
|
});
|
||||||
|
|
||||||
|
proc.stderr.on('data', handleErr);
|
||||||
|
|
||||||
|
let entries = 0;
|
||||||
|
proc.stdout.on('data', (x) => x.toString().split('\n').forEach((x) => {
|
||||||
|
if (!x.includes('inflating')) return;
|
||||||
|
|
||||||
|
entries++;
|
||||||
|
const progress = Math.min(100, Math.floor(entries / total * 100));
|
||||||
|
|
||||||
|
events.emit('installing-module-progress', {
|
||||||
|
name,
|
||||||
|
progress,
|
||||||
|
entries,
|
||||||
|
total
|
||||||
|
});
|
||||||
|
}));
|
||||||
|
|
||||||
|
proc.on('close', () => {
|
||||||
|
if (hasError) return;
|
||||||
|
|
||||||
|
installed[name].installedVersion = ver;
|
||||||
|
commitManifest();
|
||||||
|
|
||||||
|
finishInstall(name, ver, true);
|
||||||
|
});
|
||||||
};
|
};
|
||||||
|
|
||||||
const finishInstall = (name, ver, success) => {
|
const finishInstall = (name, ver, success) => {
|
||||||
|
|
Loading…
Reference in New Issue