Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

fix(packager): "packaging application" log never stops when building for multiple architectures #3006

Merged
merged 4 commits into from
Oct 31, 2022
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion package.json
Original file line number Diff line number Diff line change
Expand Up @@ -52,7 +52,7 @@
"cross-spawn": "^7.0.3",
"cross-zip": "^4.0.0",
"debug": "^4.3.1",
"electron-packager": "^17.0.0",
"electron-packager": "^17.1.0",
"electron-rebuild": "^3.2.6",
"express": "^4.17.1",
"express-ws": "^5.0.2",
Expand Down
2 changes: 1 addition & 1 deletion packages/api/core/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -52,7 +52,7 @@
"@malept/cross-spawn-promise": "^2.0.0",
"chalk": "^4.0.0",
"debug": "^4.3.1",
"electron-packager": "^17.0.0",
"electron-packager": "^17.1.0",
"electron-rebuild": "^3.2.6",
"fast-glob": "^3.2.7",
"filenamify": "^4.1.0",
Expand Down
96 changes: 66 additions & 30 deletions packages/api/core/src/api/package.ts
Original file line number Diff line number Diff line change
@@ -1,13 +1,13 @@
import path from 'path';
import { promisify } from 'util';

import { fakeOra, OraImpl, ora as realOra } from '@electron-forge/async-ora';
import { fakeOra, ora as realOra } from '@electron-forge/async-ora';
import { getElectronVersion } from '@electron-forge/core-utils';
import { ForgeArch, ForgePlatform } from '@electron-forge/shared-types';
import { getHostArch } from '@electron/get';
import chalk from 'chalk';
import debug from 'debug';
import packager, { HookFunction } from 'electron-packager';
import packager, { FinalizePackageTargetsHookFunction, HookFunction, TargetDefinition } from 'electron-packager';
import glob from 'fast-glob';
import fs from 'fs-extra';

Expand All @@ -25,16 +25,17 @@ const d = debug('electron-forge:packager');
/**
* Resolves hooks if they are a path to a file (instead of a `Function`).
*/
function resolveHooks(hooks: (string | HookFunction)[] | undefined, dir: string) {
function resolveHooks<F = HookFunction>(hooks: (string | F)[] | undefined, dir: string) {
if (hooks) {
return hooks.map((hook) => (typeof hook === 'string' ? (requireSearch<HookFunction>(dir, [hook]) as HookFunction) : hook));
return hooks.map((hook) => (typeof hook === 'string' ? (requireSearch<F>(dir, [hook]) as F) : hook));
}

return [];
}

type DoneFunction = () => void;
type DoneFunction = (err?: Error) => void;
type PromisifiedHookFunction = (buildPath: string, electronVersion: string, platform: string, arch: string) => Promise<void>;
type PromisifiedFinalizePackageTargetsHookFunction = (targets: TargetDefinition[]) => Promise<void>;

/**
* Runs given hooks sequentially by mapping them to promises and iterating
Expand All @@ -44,12 +45,30 @@ function sequentialHooks(hooks: HookFunction[]): PromisifiedHookFunction[] {
return [
async (buildPath: string, electronVersion: string, platform: string, arch: string, done: DoneFunction) => {
for (const hook of hooks) {
await promisify(hook)(buildPath, electronVersion, platform, arch);
try {
await promisify(hook)(buildPath, electronVersion, platform, arch);
} catch (err) {
return done(err as Error);
}
}
done();
},
] as PromisifiedHookFunction[];
}
function sequentialFinalizePackageTargetsHooks(hooks: FinalizePackageTargetsHookFunction[]): PromisifiedFinalizePackageTargetsHookFunction[] {
return [
async (targets: TargetDefinition[], done: DoneFunction) => {
for (const hook of hooks) {
try {
await promisify(hook)(targets);
} catch (err) {
return done(err as Error);
}
}
done();
},
] as PromisifiedFinalizePackageTargetsHookFunction[];
}

export interface PackageOptions {
/**
Expand Down Expand Up @@ -83,8 +102,7 @@ export default async ({
}: PackageOptions): Promise<void> => {
const ora = interactive ? realOra : fakeOra;

let prepareSpinner = ora(`Preparing to Package Application for arch: ${chalk.cyan(arch === 'all' ? 'ia32' : arch)}`).start();
let prepareCounter = 0;
let spinner = ora(`Preparing to Package Application`).start();

const resolvedDir = await resolveDir(dir);
if (!resolvedDir) {
Expand All @@ -100,45 +118,63 @@ export default async ({
}

const calculatedOutDir = outDir || getCurrentOutDir(dir, forgeConfig);
let packagerSpinner: OraImpl | undefined;

let pending: TargetDefinition[] = [];

function readableTargets(targets: TargetDefinition[]) {
return targets.map(({ platform, arch }) => `${platform}:${arch}`).join(', ');
}

const afterFinalizePackageTargetsHooks: FinalizePackageTargetsHookFunction[] = [
(matrix, done) => {
spinner.succeed();
spinner = ora(`Packaging for ${chalk.cyan(readableTargets(matrix))}`).start();
pending.push(...matrix);
done();
},
...resolveHooks(forgeConfig.packagerConfig.afterFinalizePackageTargets, dir),
];

const pruneEnabled = !('prune' in forgeConfig.packagerConfig) || forgeConfig.packagerConfig.prune;

const afterCopyHooks: HookFunction[] = [
async (buildPath, electronVersion, pPlatform, pArch, done) => {
if (packagerSpinner) {
packagerSpinner.succeed();
prepareCounter += 1;
prepareSpinner = ora(`Preparing to Package Application for arch: ${chalk.cyan(prepareCounter === 2 ? 'armv7l' : 'x64')}`).start();
}
const bins = await glob(path.join(buildPath, '**/.bin/**/*'));
for (const bin of bins) {
await fs.remove(bin);
}
done();
},
async (buildPath, electronVersion, pPlatform, pArch, done) => {
prepareSpinner.succeed();
await runHook(forgeConfig, 'packageAfterCopy', buildPath, electronVersion, pPlatform, pArch);
done();
},
async (buildPath, electronVersion, pPlatform, pArch, done) => {
await rebuildHook(buildPath, electronVersion, pPlatform, pArch, forgeConfig.rebuildConfig);
packagerSpinner = ora('Packaging Application').start();
done();
},
];

afterCopyHooks.push(async (buildPath, electronVersion, pPlatform, pArch, done) => {
const copiedPackageJSON = await readMutatedPackageJson(buildPath, forgeConfig);
if (copiedPackageJSON.config && copiedPackageJSON.config.forge) {
delete copiedPackageJSON.config.forge;
}
await fs.writeJson(path.resolve(buildPath, 'package.json'), copiedPackageJSON, { spaces: 2 });
done();
});
async (buildPath, electronVersion, pPlatform, pArch, done) => {
const copiedPackageJSON = await readMutatedPackageJson(buildPath, forgeConfig);
if (copiedPackageJSON.config && copiedPackageJSON.config.forge) {
delete copiedPackageJSON.config.forge;
}
await fs.writeJson(path.resolve(buildPath, 'package.json'), copiedPackageJSON, { spaces: 2 });
done();
},
...resolveHooks(forgeConfig.packagerConfig.afterCopy, dir),
async (buildPath, electronVersion, pPlatform, pArch, done) => {
spinner.text = `Packaging for ${chalk.cyan(pArch)} complete`;
spinner.succeed();
pending = pending.filter(({ arch, platform }) => !(arch === pArch && platform === pPlatform));
if (pending.length > 0) {
spinner = ora(`Packaging for ${chalk.cyan(readableTargets(pending))}`).start();
} else {
spinner = ora(`Packaging complete`).start();
}

afterCopyHooks.push(...resolveHooks(forgeConfig.packagerConfig.afterCopy, dir));
done();
},
];

const afterPruneHooks = [];

Expand Down Expand Up @@ -168,6 +204,7 @@ export default async ({
dir,
arch: arch as PackagerArch,
platform,
afterFinalizePackageTargets: sequentialFinalizePackageTargetsHooks(afterFinalizePackageTargetsHooks),
afterCopy: sequentialHooks(afterCopyHooks),
afterExtract: sequentialHooks(afterExtractHooks),
afterPrune: sequentialHooks(afterPruneHooks),
Expand Down Expand Up @@ -202,9 +239,8 @@ export default async ({
arch,
outputPaths,
platform,
spinner: packagerSpinner,
spinner,
});

// eslint-disable-next-line @typescript-eslint/no-non-null-assertion
if (packagerSpinner) packagerSpinner!.succeed();
if (spinner) spinner.succeed();
};
2 changes: 1 addition & 1 deletion packages/plugin/webpack/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,7 @@
"@malept/cross-spawn-promise": "^2.0.0",
"@types/node": "^18.0.3",
"chai": "^4.3.3",
"electron-packager": "^17.0.0",
"electron-packager": "^17.1.0",
"mocha": "^9.0.1",
"sinon": "^13.0.1",
"which": "^2.0.2",
Expand Down
2 changes: 1 addition & 1 deletion packages/utils/types/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@
"typings": "dist/index.d.ts",
"dependencies": {
"@electron-forge/async-ora": "6.0.0-beta.70",
"electron-packager": "^17.0.0",
"electron-packager": "^17.1.0",
"electron-rebuild": "^3.2.6",
"ora": "^5.0.0"
},
Expand Down
26 changes: 13 additions & 13 deletions yarn.lock
Original file line number Diff line number Diff line change
Expand Up @@ -1141,6 +1141,14 @@
global-agent "^3.0.0"
global-tunnel-ng "^2.7.1"

"@electron/notarize@^1.2.3":
version "1.2.3"
resolved "https://registry.yarnpkg.com/@electron/notarize/-/notarize-1.2.3.tgz#38056a629e5a0b5fd56c975c4828c0f74285b644"
integrity sha512-9oRzT56rKh5bspk3KpAVF8lPKHYQrBnRwcgiOeR0hdilVEQmszDaAu0IPCPrwwzJN0ugNs0rRboTreHMt/6mBQ==
dependencies:
debug "^4.1.1"
fs-extra "^9.0.1"

"@electron/osx-sign@^1.0.1":
version "1.0.1"
resolved "https://registry.yarnpkg.com/@electron/osx-sign/-/osx-sign-1.0.1.tgz#ab4fceded7fed9f2f18c25650f46c1e3a6f17054"
Expand Down Expand Up @@ -3904,26 +3912,18 @@ electron-installer-snap@^5.1.0:
which "^2.0.1"
yargs "^15.0.1"

electron-notarize@^1.1.1:
version "1.1.1"
resolved "https://registry.yarnpkg.com/electron-notarize/-/electron-notarize-1.1.1.tgz#3ed274b36158c1beb1dbef14e7faf5927e028629"
integrity sha512-kufsnqh86CTX89AYNG3NCPoboqnku/+32RxeJ2+7A4Rbm4bbOx0Nc7XTy3/gAlBfpj9xPAxHfhZLOHgfi6cJVw==
dependencies:
debug "^4.1.1"
fs-extra "^9.0.1"

electron-packager@^17.0.0:
version "17.0.0"
resolved "https://registry.yarnpkg.com/electron-packager/-/electron-packager-17.0.0.tgz#09e86734da51049de08b14cee8fc6b2d424efeec"
integrity sha512-dDy/gMR7Zl9t5AOFNIDjX+7T0d6GEifh1o/ciDUUf/fnHpVVNjDG92HsWgToGN/H9CZi5NEdlHWUQ49Wj7TN5g==
electron-packager@^17.1.0:
version "17.1.0"
resolved "https://registry.yarnpkg.com/electron-packager/-/electron-packager-17.1.0.tgz#e9653aa57dc523cdb3e0de7ec1a8e0112a1befec"
integrity sha512-60TBoutfZuAcfJJL1IVWXDZnZ+Yn88HX3UhOLhHbdB/DKA8RAfwXUhSmsWWozh118gbqYRG/WEk9aDL1xVSMKQ==
dependencies:
"@electron/asar" "^3.2.1"
"@electron/get" "^2.0.0"
"@electron/notarize" "^1.2.3"
"@electron/osx-sign" "^1.0.1"
"@electron/universal" "^1.3.2"
cross-spawn-windows-exe "^1.2.0"
debug "^4.0.1"
electron-notarize "^1.1.1"
extract-zip "^2.0.0"
filenamify "^4.1.0"
fs-extra "^10.1.0"
Expand Down