This commit is contained in:
@@ -16,5 +16,8 @@ jobs:
|
|||||||
- name: Checkout repository
|
- name: Checkout repository
|
||||||
uses: https://gitea.com/actions/checkout@v4
|
uses: https://gitea.com/actions/checkout@v4
|
||||||
|
|
||||||
|
- name: Install dependencies
|
||||||
|
run: npm ci
|
||||||
|
|
||||||
- name: Run template tests
|
- name: Run template tests
|
||||||
run: bash tests/run_test.sh
|
run: bash tests/run_test.sh
|
||||||
|
|||||||
@@ -1,5 +1,6 @@
|
|||||||
'use strict';
|
'use strict';
|
||||||
|
|
||||||
|
const { spawnSync } = require('node:child_process');
|
||||||
const fs = require('node:fs');
|
const fs = require('node:fs');
|
||||||
const path = require('node:path');
|
const path = require('node:path');
|
||||||
|
|
||||||
@@ -34,6 +35,41 @@ function platformBinaryCandidates(platform) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
function repairElectronInstall({
|
||||||
|
packageRoot,
|
||||||
|
platform = process.platform,
|
||||||
|
arch = process.arch,
|
||||||
|
}) {
|
||||||
|
const installScript = path.join(packageRoot, 'install.js');
|
||||||
|
if (!fs.existsSync(installScript)) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
const result = spawnSync(process.execPath, [installScript], {
|
||||||
|
cwd: packageRoot,
|
||||||
|
env: {
|
||||||
|
...process.env,
|
||||||
|
npm_config_platform: platform,
|
||||||
|
npm_config_arch: arch,
|
||||||
|
},
|
||||||
|
stdio: 'inherit',
|
||||||
|
});
|
||||||
|
|
||||||
|
if (result.error) {
|
||||||
|
throw result.error;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (result.signal) {
|
||||||
|
throw new Error(`Electron repair was interrupted by ${result.signal}`);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (result.status !== 0) {
|
||||||
|
throw new Error(`Electron repair failed with exit code ${result.status ?? 1}`);
|
||||||
|
}
|
||||||
|
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
function buildMissingElectronError({ packageRoot, distDir, candidatePaths }) {
|
function buildMissingElectronError({ packageRoot, distDir, candidatePaths }) {
|
||||||
const tried = candidatePaths.map((candidate) => ` - ${candidate}`).join('\n');
|
const tried = candidatePaths.map((candidate) => ` - ${candidate}`).join('\n');
|
||||||
return [
|
return [
|
||||||
@@ -57,6 +93,7 @@ function resolveElectronBinary({
|
|||||||
packageRoot = resolveElectronPackageRoot(),
|
packageRoot = resolveElectronPackageRoot(),
|
||||||
platform = process.platform,
|
platform = process.platform,
|
||||||
overrideDistPath = process.env.ELECTRON_OVERRIDE_DIST_PATH || null,
|
overrideDistPath = process.env.ELECTRON_OVERRIDE_DIST_PATH || null,
|
||||||
|
arch = process.arch,
|
||||||
} = {}) {
|
} = {}) {
|
||||||
if (!packageRoot && !overrideDistPath) {
|
if (!packageRoot && !overrideDistPath) {
|
||||||
throw new Error(
|
throw new Error(
|
||||||
@@ -79,6 +116,22 @@ function resolveElectronBinary({
|
|||||||
|
|
||||||
const resolved = candidatePaths.find((candidate) => fs.existsSync(candidate));
|
const resolved = candidatePaths.find((candidate) => fs.existsSync(candidate));
|
||||||
if (!resolved) {
|
if (!resolved) {
|
||||||
|
if (packageRoot && repairElectronInstall({ packageRoot, platform, arch })) {
|
||||||
|
const repairedHint = readElectronPathHint(packageRoot);
|
||||||
|
const repairedCandidates = [];
|
||||||
|
if (repairedHint) {
|
||||||
|
repairedCandidates.push(path.join(distDir, repairedHint));
|
||||||
|
}
|
||||||
|
for (const relativePath of platformBinaryCandidates(platform)) {
|
||||||
|
repairedCandidates.push(path.join(distDir, relativePath));
|
||||||
|
}
|
||||||
|
|
||||||
|
const repaired = repairedCandidates.find((candidate) => fs.existsSync(candidate));
|
||||||
|
if (repaired) {
|
||||||
|
return repaired;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
throw new Error(buildMissingElectronError({ packageRoot, distDir, candidatePaths }));
|
throw new Error(buildMissingElectronError({ packageRoot, distDir, candidatePaths }));
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -88,6 +141,7 @@ function resolveElectronBinary({
|
|||||||
module.exports = {
|
module.exports = {
|
||||||
buildMissingElectronError,
|
buildMissingElectronError,
|
||||||
readElectronPathHint,
|
readElectronPathHint,
|
||||||
|
repairElectronInstall,
|
||||||
resolveElectronBinary,
|
resolveElectronBinary,
|
||||||
resolveElectronPackageRoot,
|
resolveElectronPackageRoot,
|
||||||
platformBinaryCandidates,
|
platformBinaryCandidates,
|
||||||
|
|||||||
@@ -5,7 +5,13 @@ const { spawn } = require('node:child_process');
|
|||||||
|
|
||||||
const { resolveElectronBinary } = require('./electron-launcher');
|
const { resolveElectronBinary } = require('./electron-launcher');
|
||||||
|
|
||||||
const electronPath = resolveElectronBinary();
|
let electronPath;
|
||||||
|
try {
|
||||||
|
electronPath = resolveElectronBinary();
|
||||||
|
} catch (error) {
|
||||||
|
console.error(error && error.message ? error.message : error);
|
||||||
|
process.exit(1);
|
||||||
|
}
|
||||||
const env = { ...process.env };
|
const env = { ...process.env };
|
||||||
delete env.ELECTRON_RUN_AS_NODE;
|
delete env.ELECTRON_RUN_AS_NODE;
|
||||||
|
|
||||||
|
|||||||
@@ -7,6 +7,7 @@ const path = require('node:path');
|
|||||||
|
|
||||||
const {
|
const {
|
||||||
buildMissingElectronError,
|
buildMissingElectronError,
|
||||||
|
repairElectronInstall,
|
||||||
resolveElectronBinary,
|
resolveElectronBinary,
|
||||||
} = require('../../scripts/electron-launcher');
|
} = require('../../scripts/electron-launcher');
|
||||||
const { makeTmpDir, rmrf } = require('./helpers');
|
const { makeTmpDir, rmrf } = require('./helpers');
|
||||||
@@ -38,6 +39,32 @@ test('falls back to the platform binary when path.txt is absent', (t) => {
|
|||||||
);
|
);
|
||||||
});
|
});
|
||||||
|
|
||||||
|
test('repairs a broken Electron install before resolving the binary', (t) => {
|
||||||
|
const root = makeTmpDir('electron-repair');
|
||||||
|
t.after(() => rmrf(root));
|
||||||
|
|
||||||
|
fs.mkdirSync(path.join(root, 'dist'), { recursive: true });
|
||||||
|
fs.writeFileSync(
|
||||||
|
path.join(root, 'install.js'),
|
||||||
|
[
|
||||||
|
"const fs = require('node:fs');",
|
||||||
|
"const path = require('node:path');",
|
||||||
|
"fs.mkdirSync(path.join(__dirname, 'dist'), { recursive: true });",
|
||||||
|
"fs.writeFileSync(path.join(__dirname, 'dist', 'electron.exe'), 'binary');",
|
||||||
|
"fs.writeFileSync(path.join(__dirname, 'path.txt'), 'electron.exe');",
|
||||||
|
].join('\n')
|
||||||
|
);
|
||||||
|
|
||||||
|
assert.equal(
|
||||||
|
repairElectronInstall({ packageRoot: root, platform: 'win32' }),
|
||||||
|
true
|
||||||
|
);
|
||||||
|
assert.equal(
|
||||||
|
resolveElectronBinary({ packageRoot: root, platform: 'win32' }),
|
||||||
|
path.join(root, 'dist', 'electron.exe')
|
||||||
|
);
|
||||||
|
});
|
||||||
|
|
||||||
test('reports a helpful error when the runtime is missing', (t) => {
|
test('reports a helpful error when the runtime is missing', (t) => {
|
||||||
const root = makeTmpDir('electron-missing');
|
const root = makeTmpDir('electron-missing');
|
||||||
t.after(() => rmrf(root));
|
t.after(() => rmrf(root));
|
||||||
|
|||||||
Reference in New Issue
Block a user