From 569c6bd3b4f04c9b9b0b99736c8f6446d3ceff14 Mon Sep 17 00:00:00 2001 From: Mark Lee Date: Fri, 16 Jul 2021 15:58:27 -0700 Subject: [PATCH] feat: upgrade to rcedit@^3.0.1 (#1260) --- README.md | 7 ++++--- package.json | 3 ++- src/win32.js | 22 ++++++++++----------- test/win32.js | 55 ++++++++++++++++++++++++++++----------------------- 4 files changed, 46 insertions(+), 41 deletions(-) diff --git a/README.md b/README.md index 0421a8fc..8c04fdd2 100644 --- a/README.md +++ b/README.md @@ -65,10 +65,11 @@ npm install electron-packager -g ### Building Windows apps from non-Windows platforms Building an Electron app for the Windows target platform requires editing the `Electron.exe` file. -Currently, Electron Packager uses [node-rcedit](https://github.com/atom/node-rcedit) to accomplish +Currently, Electron Packager uses [`node-rcedit`](https://github.com/atom/node-rcedit) to accomplish this. A Windows executable is bundled in that Node package and needs to be run in order for this -functionality to work, so on non-Windows host platforms, [Wine](https://www.winehq.org/) 1.6 or -later needs to be installed. On macOS, it is installable via [Homebrew](http://brew.sh/). +functionality to work, so on non-Windows host platforms (not including WSL), +[Wine](https://www.winehq.org/) 1.6 or later needs to be installed. On macOS, it is installable +via [Homebrew](http://brew.sh/). ## Usage diff --git a/package.json b/package.json index 906d456c..3817e5df 100644 --- a/package.json +++ b/package.json @@ -28,6 +28,7 @@ "dependencies": { "@electron/get": "^1.6.0", "asar": "^3.0.0", + "cross-spawn-windows-exe": "^1.2.0", "debug": "^4.0.1", "electron-notarize": "^1.0.0", "electron-osx-sign": "^0.5.0", @@ -39,7 +40,7 @@ "junk": "^3.1.0", "parse-author": "^2.0.0", "plist": "^3.0.0", - "rcedit": "^2.0.0", + "rcedit": "^3.0.1", "resolve": "^1.1.6", "semver": "^7.1.3", "yargs-parser": "^20.0.0" diff --git a/src/win32.js b/src/win32.js index 08e12994..9416617f 100644 --- a/src/win32.js +++ b/src/win32.js @@ -2,17 +2,16 @@ const debug = require('debug')('electron-packager') const path = require('path') +const { WrapperError } = require('cross-spawn-windows-exe') const App = require('./platform') const common = require('./common') function updateWineMissingException (err) { - if (err && err.code === 'ENOENT' && ['spawn wine', 'spawn wine64'].includes(err.syscall)) { - const binary = err.syscall.split(' ')[1] - err.message = `Could not find "${binary}" on your system.\n\n` + + if (err instanceof WrapperError) { + err.message += '\n\n' + 'Wine is required to use the appCopyright, appVersion, buildVersion, icon, and \n' + 'win32metadata parameters for Windows targets.\n\n' + - `Make sure that the "${binary}" executable is in your PATH.\n\n` + 'See https://github.com/electron/electron-packager#building-windows-apps-from-non-windows-platforms for details.' } @@ -85,17 +84,16 @@ class WindowsApp extends App { const rcOpts = this.generateRceditOptionsSansIcon() - try { - const icon = await this.getIconPath() - if (icon) { - rcOpts.icon = icon - } + // Icon might be omitted or only exist in one OS's format, so skip it if normalizeExt reports an error + const icon = await this.getIconPath() + if (icon) { + rcOpts.icon = icon + } - debug(`Running rcedit with the options ${JSON.stringify(rcOpts)}`) + debug(`Running rcedit with the options ${JSON.stringify(rcOpts)}`) + try { await require('rcedit')(this.electronBinaryPath, rcOpts) } catch (err) { - // Icon might be omitted or only exist in one OS's format, so skip it if normalizeExt reports an error - /* istanbul ignore next */ throw updateWineMissingException(err) } } diff --git a/test/win32.js b/test/win32.js index cf7b2593..bdf96133 100644 --- a/test/win32.js +++ b/test/win32.js @@ -6,6 +6,7 @@ const path = require('path') const test = require('ava') const util = require('./_util') const win32 = require('../src/win32') +const { WrapperError } = require('cross-spawn-windows-exe') const win32Opts = { name: 'basicTest', @@ -134,36 +135,40 @@ function setCompanyNameTest (companyName) { 'Company name should match win32metadata value') } -for (const wineBinary of ['wine', 'wine64']) { - test(`better error message when ${wineBinary} is not found`, t => { - let err = Error(`spawn ${wineBinary} ENOENT`) - err.code = 'ENOENT' - err.syscall = `spawn ${wineBinary}` +test('better error message when wine is not found', t => { + const err = new WrapperError('wine-nonexistent') - t.is(err.message, `spawn ${wineBinary} ENOENT`) - err = win32.updateWineMissingException(err) - t.not(err.message, `spawn ${wineBinary} ENOENT`) - }) -} - -test('error message unchanged when error not about wine/wine64', t => { - let errNotEnoent = Error('unchanged') - errNotEnoent.code = 'ESOMETHINGELSE' - errNotEnoent.syscall = 'spawn wine' - - t.is(errNotEnoent.message, 'unchanged') - errNotEnoent = win32.updateWineMissingException(errNotEnoent) - t.is(errNotEnoent.message, 'unchanged') + t.notRegex(err.message, /win32metadata/) + const augmentedError = win32.updateWineMissingException(err) + t.regex(augmentedError.message, /win32metadata/) +}) - let errNotSpawnWine = Error('unchanged') - errNotSpawnWine.code = 'ENOENT' - errNotSpawnWine.syscall = 'spawn foo' +test('error message unchanged when error not about wine missing', t => { + const notWrapperError = Error('Not a wrapper error') - t.is(errNotSpawnWine.message, 'unchanged') - errNotSpawnWine = win32.updateWineMissingException(errNotSpawnWine) - t.is(errNotSpawnWine.message, 'unchanged') + const returnedError = win32.updateWineMissingException(notWrapperError) + t.is(returnedError.message, 'Not a wrapper error') }) +// Wine-using platforms only; macOS exhibits a strange behavior in CI, +// so we're disabling it there as well. +if (process.platform === 'linux') { + test.serial('win32 integration: catches a missing wine executable', util.packagerTest(async (t, opts) => { + process.env.WINE_BINARY = 'wine-nonexistent' + try { + await t.throwsAsync(() => packager({ + ...opts, + ...win32Opts + }), { + instanceOf: WrapperError, + message: /wine-nonexistent.*win32metadata/ms + }) + } finally { + delete process.env.WINE_BINARY + } + })) +} + test('win32metadata defaults', t => { const opts = { name: 'Win32 App' } const rcOpts = generateRceditOptionsSansIcon(opts)