2
2
mirror of https://github.com/Llewellynvdm/nativefier.git synced 2024-12-22 18:18:55 +00:00

macOS: Move handling of "universal" apps to electron-packager instead of our own thing (#1443)

Supported since [electron-packager 15.5.0](https://github.com/electron/electron-packager/releases/tag/v15.5.0).

This should fix #1405  as well
This commit is contained in:
Adam Weeden 2022-08-01 22:44:23 -04:00 committed by GitHub
parent 357f4a9693
commit c8fc0b6923
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
4 changed files with 458 additions and 355 deletions

682
npm-shrinkwrap.json generated

File diff suppressed because it is too large Load Diff

View File

@ -57,9 +57,8 @@
"watch": "npx concurrently \"npm:*:watch\"" "watch": "npx concurrently \"npm:*:watch\""
}, },
"dependencies": { "dependencies": {
"@electron/universal": "^1.2.1",
"axios": "^0.27.0", "axios": "^0.27.0",
"electron-packager": "^15.2.0", "electron-packager": "^15.5.1",
"fs-extra": "^10.0.0", "fs-extra": "^10.0.0",
"gitcloud": "^0.2.3", "gitcloud": "^0.2.3",
"hasbin": "^1.2.3", "hasbin": "^1.2.3",

View File

@ -13,14 +13,9 @@ import {
isWindowsAdmin, isWindowsAdmin,
} from '../helpers/helpers'; } from '../helpers/helpers';
import { useOldAppOptions, findUpgradeApp } from '../helpers/upgrade/upgrade'; import { useOldAppOptions, findUpgradeApp } from '../helpers/upgrade/upgrade';
import { import { AppOptions, RawOptions } from '../../shared/src/options/model';
AppOptions, import { getOptions } from '../options/optionsMain';
OutputOptions,
RawOptions,
} from '../../shared/src/options/model';
import { getOptions, normalizePlatform } from '../options/optionsMain';
import { prepareElectronApp } from './prepareElectronApp'; import { prepareElectronApp } from './prepareElectronApp';
import { makeUniversalApp } from '@electron/universal';
const OPTIONS_REQUIRING_WINDOWS_FOR_WINDOWS_BUILD = [ const OPTIONS_REQUIRING_WINDOWS_FOR_WINDOWS_BUILD = [
'icon', 'icon',
@ -130,19 +125,6 @@ function trimUnprocessableOptions(options: AppOptions): void {
} }
} }
function isInvalidUniversal(options: RawOptions): boolean {
const platform = normalizePlatform(options.platform);
if (
(options.arch ?? '').toLowerCase() === 'universal' &&
platform !== 'darwin' &&
platform !== 'mas'
) {
return true;
}
return false;
}
function getOSRunHelp(platform?: string): string { function getOSRunHelp(platform?: string): string {
if (platform === 'win32') { if (platform === 'win32') {
return `the contained .exe file.`; return `the contained .exe file.`;
@ -219,6 +201,8 @@ export async function buildNativefierApp(
convertIconIfNecessary(options); convertIconIfNecessary(options);
await copyIconsIfNecessary(options, tmpPath); await copyIconsIfNecessary(options, tmpPath);
options.packager.quiet = !rawOptions.verbose;
log.info( log.info(
"\nPackaging... This will take a few seconds, maybe minutes if the requested Electron isn't cached yet...", "\nPackaging... This will take a few seconds, maybe minutes if the requested Electron isn't cached yet...",
); );
@ -281,94 +265,3 @@ export async function buildNativefierApp(
return appPath; return appPath;
} }
function modifyOptionsForUniversal(appPath: string, buildDate: number): void {
const nativefierJSONPath = path.join(
appPath,
'Contents',
'Resources',
'app',
'nativefier.json',
);
const options = JSON.parse(
fs.readFileSync(nativefierJSONPath, 'utf8'),
) as OutputOptions;
options.arch = 'universal';
options.buildDate = buildDate;
fs.writeFileSync(nativefierJSONPath, JSON.stringify(options, null, 2));
}
export async function buildUniversalApp(options: RawOptions): Promise<string> {
if (isInvalidUniversal(options)) {
throw new Error(
'arch of "universal" can only be used with Mac OS app types.',
);
}
const platform = normalizePlatform(options.platform);
const x64Options = { ...options, arch: 'x64' };
const arm64Options = { ...options, arch: 'arm64' };
log.info('Creating universal Mac binary...');
let x64Path: string | undefined;
let arm64Path: string | undefined;
try {
x64Path = path.resolve(await buildNativefierApp(x64Options));
arm64Path = path.resolve(await buildNativefierApp(arm64Options));
const universalAppPath = path
.join(
x64Path,
`${path.parse(x64Path).base.replace(`-${platform}-x64`, '')}.app`,
)
.replace('x64', 'universal');
const x64AppPath = path.join(
x64Path,
`${path.parse(x64Path).base.replace(`-${platform}-x64`, '')}.app`,
);
const arm64AppPath = path.join(
arm64Path,
`${path.parse(arm64Path).base.replace(`-${platform}-arm64`, '')}.app`,
);
// We're going to change the nativefier.json on these to match otherwise we'll see:
// Expected all non-binary files to have identical SHAs when creating a universal build but "Google.app/Contents/Resources/app/nativefier.json" did not
const buildDate = new Date().getTime();
modifyOptionsForUniversal(x64AppPath, buildDate);
modifyOptionsForUniversal(arm64AppPath, buildDate);
await makeUniversalApp({
x64AppPath,
arm64AppPath,
outAppPath: universalAppPath,
force: !!options.overwrite,
});
await fs.copyFile(
path.join(x64Path, 'LICENSE'),
path.join(universalAppPath, '..', 'LICENSE'),
);
await fs.copyFile(
path.join(x64Path, 'LICENSES.chromium.html'),
path.join(universalAppPath, '..', 'LICENSES.chromium.html'),
);
await fs.copyFile(
path.join(x64Path, 'version'),
path.join(universalAppPath, '..', 'version'),
);
const osRunHelp = getOSRunHelp(platform);
log.info(
`App built to ${universalAppPath}, move to wherever it makes sense for you and run ${osRunHelp}`,
);
return universalAppPath;
} finally {
if (x64Path) {
fs.removeSync(x64Path);
}
if (arm64Path) {
fs.removeSync(arm64Path);
}
}
}

View File

@ -16,7 +16,6 @@ import { supportedArchs, supportedPlatforms } from './infer/inferOs';
import { buildNativefierApp } from './main'; import { buildNativefierApp } from './main';
import { RawOptions } from '../shared/src/options/model'; import { RawOptions } from '../shared/src/options/model';
import { parseJson } from './utils/parseUtils'; import { parseJson } from './utils/parseUtils';
import { buildUniversalApp } from './build/buildNativefierApp';
// @types/yargs@17.x started pretending yargs.argv can be a promise: // @types/yargs@17.x started pretending yargs.argv can be a promise:
// https://github.com/DefinitelyTyped/DefinitelyTyped/blob/8e17f9ca957a06040badb53ae7688fbb74229ccf/types/yargs/index.d.ts#L73 // https://github.com/DefinitelyTyped/DefinitelyTyped/blob/8e17f9ca957a06040badb53ae7688fbb74229ccf/types/yargs/index.d.ts#L73
@ -700,13 +699,7 @@ if (require.main === module) {
options.out = process.env.NATIVEFIER_APPS_DIR; options.out = process.env.NATIVEFIER_APPS_DIR;
} }
if ((options.arch ?? '').toLowerCase() === 'universal') {
buildUniversalApp(options).catch((error) => {
log.error('Error during build. Run with --verbose for details.', error);
});
} else {
buildNativefierApp(options).catch((error) => { buildNativefierApp(options).catch((error) => {
log.error('Error during build. Run with --verbose for details.', error); log.error('Error during build. Run with --verbose for details.', error);
}); });
} }
}