From 22cbb8e95808da4c5280592983f3aa3a89491ed7 Mon Sep 17 00:00:00 2001 From: Robo Date: Fri, 16 Sep 2022 19:41:52 +0900 Subject: [PATCH] chore: update electron@19.0.17 (#161027) * chore: update electron@19.0.17 * chore: update API typings * fix: compilation errors * build: add libcups dependency --- .yarnrc | 2 +- build/linux/debian/dep-lists.js | 3 + build/linux/debian/dep-lists.ts | 3 + build/linux/rpm/dep-lists.js | 3 + build/linux/rpm/dep-lists.ts | 3 + cgmanifest.json | 4 +- package.json | 2 +- src/bootstrap-fork.js | 18 +- .../electron-main/extensionHostStarter.ts | 165 ++++++++++++++---- yarn.lock | 8 +- 10 files changed, 161 insertions(+), 50 deletions(-) diff --git a/.yarnrc b/.yarnrc index afa220d0f75..f5edf10bc83 100644 --- a/.yarnrc +++ b/.yarnrc @@ -1,4 +1,4 @@ disturl "https://electronjs.org/headers" -target "19.0.12" +target "19.0.17" runtime "electron" build_from_source "true" diff --git a/build/linux/debian/dep-lists.js b/build/linux/debian/dep-lists.js index f61968c5170..a6e2cdf1f5e 100644 --- a/build/linux/debian/dep-lists.js +++ b/build/linux/debian/dep-lists.js @@ -31,6 +31,7 @@ exports.referenceGeneratedDepsByArch = { 'libc6 (>= 2.17)', 'libc6 (>= 2.2.5)', 'libcairo2 (>= 1.6.0)', + 'libcups2 (>= 1.6.0)', 'libcurl3-gnutls | libcurl3-nss | libcurl4 | libcurl3', 'libdbus-1-3 (>= 1.5.12)', 'libdrm2 (>= 2.4.38)', @@ -67,6 +68,7 @@ exports.referenceGeneratedDepsByArch = { 'libc6 (>= 2.4)', 'libc6 (>= 2.9)', 'libcairo2 (>= 1.6.0)', + 'libcups2 (>= 1.6.0)', 'libcurl3-gnutls | libcurl3-nss | libcurl4 | libcurl3', 'libdbus-1-3 (>= 1.5.12)', 'libdrm2 (>= 2.4.38)', @@ -105,6 +107,7 @@ exports.referenceGeneratedDepsByArch = { 'libatspi2.0-0 (>= 2.9.90)', 'libc6 (>= 2.17)', 'libcairo2 (>= 1.6.0)', + 'libcups2 (>= 1.6.0)', 'libcurl3-gnutls | libcurl3-nss | libcurl4 | libcurl3', 'libdbus-1-3 (>= 1.0.2)', 'libdrm2 (>= 2.4.38)', diff --git a/build/linux/debian/dep-lists.ts b/build/linux/debian/dep-lists.ts index 63b14bf16f0..528448a1961 100644 --- a/build/linux/debian/dep-lists.ts +++ b/build/linux/debian/dep-lists.ts @@ -31,6 +31,7 @@ export const referenceGeneratedDepsByArch = { 'libc6 (>= 2.17)', 'libc6 (>= 2.2.5)', 'libcairo2 (>= 1.6.0)', + 'libcups2 (>= 1.6.0)', 'libcurl3-gnutls | libcurl3-nss | libcurl4 | libcurl3', 'libdbus-1-3 (>= 1.5.12)', 'libdrm2 (>= 2.4.38)', @@ -67,6 +68,7 @@ export const referenceGeneratedDepsByArch = { 'libc6 (>= 2.4)', 'libc6 (>= 2.9)', 'libcairo2 (>= 1.6.0)', + 'libcups2 (>= 1.6.0)', 'libcurl3-gnutls | libcurl3-nss | libcurl4 | libcurl3', 'libdbus-1-3 (>= 1.5.12)', 'libdrm2 (>= 2.4.38)', @@ -105,6 +107,7 @@ export const referenceGeneratedDepsByArch = { 'libatspi2.0-0 (>= 2.9.90)', 'libc6 (>= 2.17)', 'libcairo2 (>= 1.6.0)', + 'libcups2 (>= 1.6.0)', 'libcurl3-gnutls | libcurl3-nss | libcurl4 | libcurl3', 'libdbus-1-3 (>= 1.0.2)', 'libdrm2 (>= 2.4.38)', diff --git a/build/linux/rpm/dep-lists.js b/build/linux/rpm/dep-lists.js index 45c413f7934..2339e3703b6 100644 --- a/build/linux/rpm/dep-lists.js +++ b/build/linux/rpm/dep-lists.js @@ -53,6 +53,7 @@ exports.referenceGeneratedDepsByArch = { 'libc.so.6(GLIBC_2.8)(64bit)', 'libc.so.6(GLIBC_2.9)(64bit)', 'libcairo.so.2()(64bit)', + 'libcups.so.2()(64bit)', 'libcurl.so.4()(64bit)', 'libdbus-1.so.3()(64bit)', 'libdl.so.2()(64bit)', @@ -133,6 +134,7 @@ exports.referenceGeneratedDepsByArch = { 'libc.so.6(GLIBC_2.8)', 'libc.so.6(GLIBC_2.9)', 'libcairo.so.2', + 'libcups.so.2', 'libcurl.so.4()(64bit)', 'libdbus-1.so.3', 'libdl.so.2', @@ -221,6 +223,7 @@ exports.referenceGeneratedDepsByArch = { 'libc.so.6()(64bit)', 'libc.so.6(GLIBC_2.17)(64bit)', 'libcairo.so.2()(64bit)', + 'libcups.so.2()(64bit)', 'libcurl.so.4()(64bit)', 'libdbus-1.so.3()(64bit)', 'libdbus-1.so.3(LIBDBUS_1_3)(64bit)', diff --git a/build/linux/rpm/dep-lists.ts b/build/linux/rpm/dep-lists.ts index d80c86416a6..7df703fa060 100644 --- a/build/linux/rpm/dep-lists.ts +++ b/build/linux/rpm/dep-lists.ts @@ -52,6 +52,7 @@ export const referenceGeneratedDepsByArch = { 'libc.so.6(GLIBC_2.8)(64bit)', 'libc.so.6(GLIBC_2.9)(64bit)', 'libcairo.so.2()(64bit)', + 'libcups.so.2()(64bit)', 'libcurl.so.4()(64bit)', 'libdbus-1.so.3()(64bit)', 'libdl.so.2()(64bit)', @@ -132,6 +133,7 @@ export const referenceGeneratedDepsByArch = { 'libc.so.6(GLIBC_2.8)', 'libc.so.6(GLIBC_2.9)', 'libcairo.so.2', + 'libcups.so.2', 'libcurl.so.4()(64bit)', 'libdbus-1.so.3', 'libdl.so.2', @@ -220,6 +222,7 @@ export const referenceGeneratedDepsByArch = { 'libc.so.6()(64bit)', 'libc.so.6(GLIBC_2.17)(64bit)', 'libcairo.so.2()(64bit)', + 'libcups.so.2()(64bit)', 'libcurl.so.4()(64bit)', 'libdbus-1.so.3()(64bit)', 'libdbus-1.so.3(LIBDBUS_1_3)(64bit)', diff --git a/cgmanifest.json b/cgmanifest.json index 3d2387b7ee9..df82bc993e4 100644 --- a/cgmanifest.json +++ b/cgmanifest.json @@ -502,12 +502,12 @@ "git": { "name": "electron", "repositoryUrl": "https://github.com/electron/electron", - "commitHash": "b05ccd812e3bb3de5b1546a313e298961653e942" + "commitHash": "0e6da36264d52656d5cd36a4c15937a6a6ca778e" } }, "isOnlyProductionDependency": true, "license": "MIT", - "version": "19.0.12" + "version": "19.0.17" }, { "component": { diff --git a/package.json b/package.json index 7458844c9bf..63c841c5fe9 100644 --- a/package.json +++ b/package.json @@ -140,7 +140,7 @@ "cssnano": "^4.1.11", "debounce": "^1.0.0", "deemon": "^1.4.0", - "electron": "19.0.12", + "electron": "19.0.17", "eslint": "8.7.0", "eslint-plugin-header": "3.1.1", "eslint-plugin-jsdoc": "^39.3.2", diff --git a/src/bootstrap-fork.js b/src/bootstrap-fork.js index 10db71ff3eb..90da6dd16f6 100644 --- a/src/bootstrap-fork.js +++ b/src/bootstrap-fork.js @@ -241,13 +241,17 @@ function listenForMessagePort() { // We need to listen for the 'port' event as soon as possible, // otherwise we might miss the event. But we should also be // prepared in case the event arrives late. - process.on('port', (e) => { - if (global.vscodePortsCallback) { - global.vscodePortsCallback(e.ports); - } else { - global.vscodePorts = e.ports; - } - }); + // @ts-ignore + if (process.parentPort) { + // @ts-ignore + process.parentPort.on('message', (e) => { + if (global.vscodePortsCallback) { + global.vscodePortsCallback(e.ports); + } else { + global.vscodePorts = e.ports; + } + }); + } } //#endregion diff --git a/src/vs/platform/extensions/electron-main/extensionHostStarter.ts b/src/vs/platform/extensions/electron-main/extensionHostStarter.ts index 277f3de4294..9da8b146c18 100644 --- a/src/vs/platform/extensions/electron-main/extensionHostStarter.ts +++ b/src/vs/platform/extensions/electron-main/extensionHostStarter.ts @@ -4,7 +4,7 @@ *--------------------------------------------------------------------------------------------*/ import { canceled, SerializedError, transformErrorForSerialization } from 'vs/base/common/errors'; -import { Disposable, IDisposable, toDisposable } from 'vs/base/common/lifecycle'; +import { Disposable, IDisposable } from 'vs/base/common/lifecycle'; import { IExtensionHostProcessOptions, IExtensionHostStarter } from 'vs/platform/extensions/common/extensionHostStarter'; import { Emitter, Event } from 'vs/base/common/event'; import { ILogService } from 'vs/platform/log/common/log'; @@ -22,18 +22,113 @@ import * as electron from 'electron'; import { IWindowsMainService } from 'vs/platform/windows/electron-main/windows'; declare namespace UtilityProcessProposedApi { - interface UtilityProcessOptions { - serviceName?: string | undefined; - execArgv?: string[] | undefined; - env?: NodeJS.ProcessEnv | undefined; + interface UtilityProcessConstructorOptions { + /** + * Environment key-value pairs. Default is `process.env`. + */ + env?: NodeJS.ProcessEnv; + /** + * List of string arguments passed to the executable. Default is + * `process.execArgv`. + */ + execArgv?: string[]; + /** + * Child's stdout and stderr configuration. Default is `pipe`. String value can be + * one of `pipe`, `ignore`, `inherit`, for more details on these values you can + * refer to stdio documentation from Node.js. Currently this option does not allow + * configuring stdin and is always set to `ignore`. For example, the supported + * values will be processed as following: + */ + stdio?: (Array<'pipe' | 'ignore' | 'inherit'>) | (string); + /** + * Name of the process that will appear in `name` property of `child-process-gone` + * event of `app`. Default is `node.mojom.NodeService`. + */ + serviceName?: string; + /** + * With this flag, the utility process will be launched via the `Electron Helper + * (Plugin).app` helper executable on macOS, which can be codesigned with + * `com.apple.security.cs.disable-library-validation` and + * `com.apple.security.cs.allow-unsigned-executable-memory` entitlements. This will + * allow the utility process to load unsigned libraries. Unless you specifically + * need this capability, it is best to leave this disabled. Default is `false`. + * + * @platform darwin + */ + allowLoadingUnsignedLibraries?: boolean; } - export class UtilityProcess extends EventEmitter { - readonly pid?: number | undefined; - constructor(modulePath: string, args?: string[] | undefined, options?: UtilityProcessOptions); - postMessage(channel: string, message: any, transfer?: Electron.MessagePortMain[]): void; - kill(signal?: number | string): boolean; - on(event: 'exit', listener: (event: Electron.Event, code: number) => void): this; - on(event: 'spawn', listener: () => void): this; + class UtilityProcess extends EventEmitter { + + // Docs: https://electronjs.org/docs/api/utility-process + + /** + * Emitted after the child process ends. `code` contains the exit code for the + * process obtained from waitpid on posix, or GetExitCodeProcess on windows. + */ + on(event: 'exit', listener: (event: Electron.Event, + code: number) => void): this; + once(event: 'exit', listener: (event: Electron.Event, + code: number) => void): this; + addListener(event: 'exit', listener: (event: Electron.Event, + code: number) => void): this; + removeListener(event: 'exit', listener: (event: Electron.Event, + code: number) => void): this; + /** + * Emitted when the child process sends a message using + * `process.parentPort.postMessage()`. + */ + on(event: 'message', listener: (event: Electron.Event, + message: any) => void): this; + once(event: 'message', listener: (event: Electron.Event, + message: any) => void): this; + addListener(event: 'message', listener: (event: Electron.Event, + message: any) => void): this; + removeListener(event: 'message', listener: (event: Electron.Event, + message: any) => void): this; + /** + * Emitted once the child process has spawned successfully. + */ + on(event: 'spawn', listener: Function): this; + once(event: 'spawn', listener: Function): this; + addListener(event: 'spawn', listener: Function): this; + removeListener(event: 'spawn', listener: Function): this; + /** + * UtilityProcess + */ + constructor(modulePath: string, args?: string[], options?: UtilityProcessConstructorOptions); + /** + * Terminates the process gracefully. On POSIX, it uses SIGTERM but will ensure to + * reap the process on exit. This function returns true if kill succeeds, and false + * otherwise. + */ + kill(): boolean; + /** + * Send a message to the child process, optionally transferring ownership of zero + * or more [`MessagePortMain`][] objects. + * + * For example: + */ + postMessage(message: any, transfer?: Electron.MessagePortMain[]): void; + /** + * A `Integer | undefined` representing the process identifier (PID) of the child + * process. If the child process fails to spawn due to errors, then the value is + * `undefined`. + */ + pid: (number) | (undefined); + /** + * A `NodeJS.ReadableStream | null | undefined` that represents the child process's + * stderr. If the child was spawned with options.stdio[2] set to anything other + * than 'pipe', then this will be `null`. The property will be `undefined` if the + * child process could not be successfully spawned. + */ + stderr: (NodeJS.ReadableStream) | (null) | (undefined); + /** + * A `NodeJS.ReadableStream | null | undefined` that represents the child process's + * stdout. If the child was spawned with options.stdio[1] set to anything other + * than 'pipe', then this will be `null`. The property will be `undefined` if the + * child process could not be successfully spawned. + */ + stdout: (NodeJS.ReadableStream) | (null) | (undefined); } } const UtilityProcess = ((electron as any).UtilityProcess); @@ -286,10 +381,14 @@ class ExtensionHostProcess extends Disposable { class UtilityExtensionHostProcess extends Disposable { - readonly onStdout = Event.None; - readonly onStderr = Event.None; readonly onError = Event.None; + readonly _onStdout = this._register(new Emitter()); + readonly onStdout = this._onStdout.event; + + readonly _onStderr = this._register(new Emitter()); + readonly onStderr = this._onStderr.event; + readonly _onMessage = this._register(new Emitter()); readonly onMessage = this._onMessage.event; @@ -335,6 +434,22 @@ class UtilityExtensionHostProcess extends Disposable { this._process = new UtilityProcess(modulePath, args, { serviceName, env, execArgv }); + const stdoutDecoder = new StringDecoder('utf-8'); + this._process.stdout?.on('data', (chunk) => { + const strChunk = typeof chunk === 'string' ? chunk : stdoutDecoder.write(chunk); + this._onStdout.fire(strChunk); + }); + + const stderrDecoder = new StringDecoder('utf-8'); + this._process.stderr?.on('data', (chunk) => { + const strChunk = typeof chunk === 'string' ? chunk : stderrDecoder.write(chunk); + this._onStderr.fire(strChunk); + }); + + this._process.on('message', msg => { + this._onMessage.fire(msg); + }); + this._register(Event.fromNodeEventEmitter(this._process, 'spawn')(() => { this._logService.info(`UtilityProcess<${this.id}>: received spawn event.`); })); @@ -344,26 +459,10 @@ class UtilityExtensionHostProcess extends Disposable { this._hasExited = true; this._onExit.fire({ pid: this._process!.pid!, code, signal: '' }); })); - const listener = (event: electron.Event, details: electron.Details) => { - if (details.type !== 'Utility') { - return; - } - // Despite the fact that we pass the argument `seviceName`, - // the details have a field called `name` where this value appears - if (details.name === serviceName) { - this._logService.info(`UtilityProcess<${this.id}>: terminated unexpectedly with code ${details.exitCode}.`); - this._hasExited = true; - this._onExit.fire({ pid: this._process!.pid!, code: details.exitCode, signal: '' }); - } - }; - electron.app.on('child-process-gone', listener); - this._register(toDisposable(() => { - electron.app.off('child-process-gone', listener); - })); const { port1, port2 } = new electron.MessageChannelMain(); - this._process.postMessage('port', null, [port2]); + this._process.postMessage('null', [port2]); responseWindow.webContents.postMessage(opts.responseChannel, opts.responseNonce, [port1]); } @@ -382,10 +481,6 @@ class UtilityExtensionHostProcess extends Disposable { // use (undocumented) _debugProcess feature of node (process)._debugProcess!(this._process.pid!); return true; - } else if (!platform.isWindows) { - // use KILL USR1 on non-windows platforms (fallback) - this._process.kill('SIGUSR1'); - return true; } else { // not supported... return false; diff --git a/yarn.lock b/yarn.lock index 4c8f3c14e8d..a4b2b57951f 100644 --- a/yarn.lock +++ b/yarn.lock @@ -3932,10 +3932,10 @@ electron-to-chromium@^1.4.202: resolved "https://registry.yarnpkg.com/electron-to-chromium/-/electron-to-chromium-1.4.207.tgz#9c3310ebace2952903d05dcaba8abe3a4ed44c01" integrity sha512-piH7MJDJp4rJCduWbVvmUd59AUne1AFBJ8JaRQvk0KzNTSUnZrVXHCZc+eg+CGE4OujkcLJznhGKD6tuAshj5Q== -electron@19.0.12: - version "19.0.12" - resolved "https://registry.yarnpkg.com/electron/-/electron-19.0.12.tgz#73d11cc2a3e4dbcd61fdc1c39561e7a7911046e9" - integrity sha512-GOvG0t2NCeJYIfmC3g/dnEAQ71k3nQDbRVqQhpi2YbsYMury0asGJwqnVAv2uZQEwCwSx4XOwOQARTFEG/msWw== +electron@19.0.17: + version "19.0.17" + resolved "https://registry.yarnpkg.com/electron/-/electron-19.0.17.tgz#850d806e88b1ef141b88b491dc41661778691c27" + integrity sha512-3Offu61K+d19EZIc76MhKRsSCqfe3jDiqtD0p8jXr6p/TW7+7/jOQp407ZaZu0nQN6/xDIEi2sP4XQBom6GjTQ== dependencies: "@electron/get" "^1.14.1" "@types/node" "^16.11.26"