fix(core): silent failures when linking forge dependencies in tests (#3219)
This commit is contained in:
Родитель
6ac014e085
Коммит
e5fc303734
|
@ -51,7 +51,7 @@ yarn link:prepare
|
|||
|
||||
Then, you want to initialize a new project with the `electron-forge init` command (which is the
|
||||
underlying CLI command for `create-electron-app`). To use the symlinks you created in the last step,
|
||||
pass in the `LINK_FORGE_DEPENDENCIES_ON_INIT` environment variable.
|
||||
pass in the `LINK_FORGE_DEPENDENCIES_ON_INIT=1` environment variable.
|
||||
|
||||
You can choose to run this command via your local build as shown below or run the production init
|
||||
for versions 6.0.1 and up.
|
||||
|
|
|
@ -17,7 +17,8 @@
|
|||
"lerna:publish": "lerna publish --force-publish --conventional-commits --no-changelog --exact",
|
||||
"lint": "prettier --check . && eslint .",
|
||||
"lint:fix": "prettier --write .",
|
||||
"link:prepare": "lerna exec -- node ../../../tools/silent.js yarn link --link-folder ../../../.links --silent --no-bin-links",
|
||||
"link:prepare": "lerna exec -- node ../../../tools/silent.js yarn link --silent --no-bin-links --link-folder ../../../.links",
|
||||
"link:remove": "lerna exec -- node ../../../tools/silent.js yarn unlink --silent --no-bin-links --link-folder ../../../.links",
|
||||
"test": "xvfb-maybe cross-env LINK_FORGE_DEPENDENCIES_ON_INIT=1 TS_NODE_PROJECT='./tsconfig.test.json' TS_NODE_FILES=1 mocha './tools/test-globber.ts'",
|
||||
"test:fast": "xvfb-maybe cross-env LINK_FORGE_DEPENDENCIES_ON_INIT=1 TS_NODE_PROJECT='./tsconfig.test.json' TEST_FAST_ONLY=1 TS_NODE_FILES=1 mocha './tools/test-globber.ts'",
|
||||
"test:slow": "xvfb-maybe cross-env LINK_FORGE_DEPENDENCIES_ON_INIT=1 TS_NODE_PROJECT='./tsconfig.test.json' TEST_SLOW_ONLY=1 TS_NODE_FILES=1 mocha './tools/test-globber.ts'",
|
||||
|
|
|
@ -0,0 +1,38 @@
|
|||
import path from 'path';
|
||||
|
||||
import { safeYarnOrNpm, yarnOrNpmSpawn } from '@electron-forge/core-utils';
|
||||
import { ForgeListrTask } from '@electron-forge/shared-types';
|
||||
import debug from 'debug';
|
||||
|
||||
import { readRawPackageJson } from '../../util/read-package-json';
|
||||
|
||||
const d = debug('electron-forge:init:link');
|
||||
|
||||
/**
|
||||
* Link local forge dependencies
|
||||
*
|
||||
* This allows developers working on forge itself to easily init
|
||||
* a local template and have it use their local plugins / core / cli packages.
|
||||
*
|
||||
* Note: `yarn link:prepare` needs to run first before dependencies can be
|
||||
* linked.
|
||||
*/
|
||||
export async function initLink<T>(dir: string, task?: ForgeListrTask<T>) {
|
||||
const shouldLink = process.env.LINK_FORGE_DEPENDENCIES_ON_INIT;
|
||||
if (shouldLink) {
|
||||
d('Linking forge dependencies');
|
||||
const packageJson = await readRawPackageJson(dir);
|
||||
const packageManager = safeYarnOrNpm();
|
||||
const linkFolder = path.resolve(__dirname, '..', '..', '..', '..', '..', '..', '.links');
|
||||
for (const packageName of Object.keys(packageJson.devDependencies)) {
|
||||
if (packageName.startsWith('@electron-forge/')) {
|
||||
if (task) task.output = `${packageManager} link --link-folder ${linkFolder} ${packageName}`;
|
||||
await yarnOrNpmSpawn(['link', '--link-folder', linkFolder, packageName], {
|
||||
cwd: dir,
|
||||
});
|
||||
}
|
||||
}
|
||||
} else {
|
||||
d('LINK_FORGE_DEPENDENCIES_ON_INIT is falsy. Skipping.');
|
||||
}
|
||||
}
|
|
@ -1,12 +1,11 @@
|
|||
import path from 'path';
|
||||
|
||||
import { safeYarnOrNpm, yarnOrNpmSpawn } from '@electron-forge/core-utils';
|
||||
import { safeYarnOrNpm } from '@electron-forge/core-utils';
|
||||
import { ForgeListrTask } from '@electron-forge/shared-types';
|
||||
import debug from 'debug';
|
||||
import fs from 'fs-extra';
|
||||
|
||||
import installDepList, { DepType, DepVersionRestriction } from '../../util/install-dependencies';
|
||||
import { readRawPackageJson } from '../../util/read-package-json';
|
||||
|
||||
const d = debug('electron-forge:init:npm');
|
||||
const corePackage = fs.readJsonSync(path.resolve(__dirname, '../../../package.json'));
|
||||
|
@ -19,7 +18,7 @@ export const deps = ['electron-squirrel-startup'];
|
|||
export const devDeps = [siblingDep('cli'), siblingDep('maker-squirrel'), siblingDep('maker-zip'), siblingDep('maker-deb'), siblingDep('maker-rpm')];
|
||||
export const exactDevDeps = ['electron'];
|
||||
|
||||
export const initNPM = async (dir: string, task: ForgeListrTask<any>): Promise<void> => {
|
||||
export const initNPM = async <T>(dir: string, task: ForgeListrTask<T>): Promise<void> => {
|
||||
d('installing dependencies');
|
||||
const packageManager = safeYarnOrNpm();
|
||||
task.output = `${packageManager} install ${deps.join(' ')}`;
|
||||
|
@ -34,19 +33,4 @@ export const initNPM = async (dir: string, task: ForgeListrTask<any>): Promise<v
|
|||
task.output = `${packageManager} install --dev --exact ${packageName}`;
|
||||
await installDepList(dir, [packageName], DepType.DEV, DepVersionRestriction.EXACT);
|
||||
}
|
||||
|
||||
// This logic allows developers working on forge itself to easily init
|
||||
// a local template and have it use their local plugins / core / cli packages
|
||||
if (process.env.LINK_FORGE_DEPENDENCIES_ON_INIT) {
|
||||
const packageJson = await readRawPackageJson(dir);
|
||||
const linkFolder = path.resolve(__dirname, '..', '..', '..', '..', '..', '..', '.links');
|
||||
for (const packageName of Object.keys(packageJson.devDependencies)) {
|
||||
if (packageName.startsWith('@electron-forge/')) {
|
||||
task.output = `${packageManager} link --link-folder ${linkFolder} ${packageName}`;
|
||||
await yarnOrNpmSpawn(['link', '--link-folder', linkFolder, packageName], {
|
||||
cwd: dir,
|
||||
});
|
||||
}
|
||||
}
|
||||
}
|
||||
};
|
||||
|
|
|
@ -12,6 +12,7 @@ import { readRawPackageJson } from '../util/read-package-json';
|
|||
import { findTemplate } from './init-scripts/find-template';
|
||||
import { initDirectory } from './init-scripts/init-directory';
|
||||
import { initGit } from './init-scripts/init-git';
|
||||
import { initLink } from './init-scripts/init-link';
|
||||
import { initNPM } from './init-scripts/init-npm';
|
||||
|
||||
const d = debug('electron-forge:init');
|
||||
|
@ -108,6 +109,7 @@ export default async ({ dir = process.cwd(), interactive = false, copyCIFiles =
|
|||
}
|
||||
return await installDepList(dir, templateModule.dependencies || [], DepType.PROD, DepVersionRestriction.RANGE);
|
||||
},
|
||||
exitOnError: false,
|
||||
},
|
||||
{
|
||||
title: 'Installing development dependencies',
|
||||
|
@ -118,17 +120,32 @@ export default async ({ dir = process.cwd(), interactive = false, copyCIFiles =
|
|||
}
|
||||
await installDepList(dir, templateModule.devDependencies || [], DepType.DEV);
|
||||
},
|
||||
exitOnError: false,
|
||||
},
|
||||
{
|
||||
title: 'Finalizing dependencies',
|
||||
task: async (_, task) => {
|
||||
await initNPM(dir, task);
|
||||
return task.newListr([
|
||||
{
|
||||
title: 'Installing common dependencies',
|
||||
task: async (_, task) => {
|
||||
await initNPM(dir, task);
|
||||
},
|
||||
exitOnError: false,
|
||||
},
|
||||
{
|
||||
title: process.env.LINK_FORGE_DEPENDENCIES_ON_INIT ? 'Linking forge dependencies' : 'Skip linking forge dependencies',
|
||||
task: async (_, task) => {
|
||||
await initLink(dir, task);
|
||||
},
|
||||
exitOnError: true,
|
||||
},
|
||||
]);
|
||||
},
|
||||
},
|
||||
],
|
||||
{
|
||||
concurrent: false,
|
||||
exitOnError: false,
|
||||
}
|
||||
);
|
||||
},
|
||||
|
|
|
@ -2,6 +2,7 @@ import assert from 'assert';
|
|||
import { execSync } from 'child_process';
|
||||
import path from 'path';
|
||||
|
||||
import { yarnOrNpmSpawn } from '@electron-forge/core-utils';
|
||||
import { createDefaultCertificate } from '@electron-forge/maker-appx';
|
||||
import { ForgeConfig, IForgeResolvableMaker } from '@electron-forge/shared-types';
|
||||
import { ensureTestDirIsNonexistent, expectLintToPass, expectProjectPathExists } from '@electron-forge/test-utils';
|
||||
|
@ -39,6 +40,10 @@ for (const nodeInstaller of ['npm', 'yarn']) {
|
|||
describe(`electron-forge API (with installer=${nodeInstaller})`, () => {
|
||||
let dir: string;
|
||||
|
||||
before(async () => {
|
||||
await yarnOrNpmSpawn(['link:prepare']);
|
||||
});
|
||||
|
||||
const beforeInitTest = (params?: Partial<InitOptions>, beforeInit?: BeforeInitFunction) => {
|
||||
before(async () => {
|
||||
dir = await ensureTestDirIsNonexistent();
|
||||
|
@ -217,12 +222,20 @@ for (const nodeInstaller of ['npm', 'yarn']) {
|
|||
await fs.remove(dir);
|
||||
});
|
||||
});
|
||||
|
||||
after(async () => {
|
||||
await yarnOrNpmSpawn(['link:remove']);
|
||||
});
|
||||
});
|
||||
}
|
||||
|
||||
describe('Electron Forge API', () => {
|
||||
let dir: string;
|
||||
|
||||
before(async () => {
|
||||
await yarnOrNpmSpawn(['link:prepare']);
|
||||
});
|
||||
|
||||
describe('after init', () => {
|
||||
let devCert: string;
|
||||
|
||||
|
@ -484,4 +497,8 @@ describe('Electron Forge API', () => {
|
|||
|
||||
after(() => fs.remove(dir));
|
||||
});
|
||||
|
||||
after(async () => {
|
||||
await yarnOrNpmSpawn(['link:remove']);
|
||||
});
|
||||
});
|
||||
|
|
|
@ -7,11 +7,13 @@ import glob from 'fast-glob';
|
|||
import fs from 'fs-extra';
|
||||
|
||||
import { api } from '../../../api/core';
|
||||
import { initLink } from '../../../api/core/src/api/init-scripts/init-link';
|
||||
|
||||
describe('WebpackTypeScriptTemplate', () => {
|
||||
let dir: string;
|
||||
|
||||
before(async () => {
|
||||
await yarnOrNpmSpawn(['link:prepare']);
|
||||
dir = await testUtils.ensureTestDirIsNonexistent();
|
||||
});
|
||||
|
||||
|
@ -74,6 +76,11 @@ describe('WebpackTypeScriptTemplate', () => {
|
|||
await yarnOrNpmSpawn(['install'], {
|
||||
cwd: dir,
|
||||
});
|
||||
|
||||
// Installing deps removes symlinks that were added at the start of this
|
||||
// spec via `api.init`. So we should re-link local forge dependencies
|
||||
// again.
|
||||
await initLink(dir);
|
||||
});
|
||||
|
||||
after(() => {
|
||||
|
@ -89,6 +96,7 @@ describe('WebpackTypeScriptTemplate', () => {
|
|||
});
|
||||
|
||||
after(async () => {
|
||||
await yarnOrNpmSpawn(['link:remove']);
|
||||
await fs.remove(dir);
|
||||
});
|
||||
});
|
||||
|
|
|
@ -1,12 +1,13 @@
|
|||
const cp = require('child_process');
|
||||
/**
|
||||
* Silences warnings and other stdio logs produced from commands
|
||||
*
|
||||
* It does not silence errors.
|
||||
*/
|
||||
|
||||
const { spawn } = require('@malept/cross-spawn-promise');
|
||||
|
||||
const [cmd, ...args] = process.argv.slice(2);
|
||||
|
||||
const child = cp.spawn(cmd, args, {
|
||||
spawn(cmd, args, {
|
||||
stdio: 'pipe',
|
||||
});
|
||||
|
||||
child.on('exit', (code, signal) => {
|
||||
if (signal) process.exit(1);
|
||||
else process.exit(code);
|
||||
});
|
||||
|
|
Загрузка…
Ссылка в новой задаче