From 3f42537aea9e537d49baeda99f5a2d39c93967bb Mon Sep 17 00:00:00 2001 From: vince-fugnitto Date: Thu, 25 Jun 2020 20:36:49 -0400 Subject: [PATCH 1/5] vsx-registry: fix the licenseUrl link - fixes the `licenseUrl` link for builtin and installed extensions. Signed-off-by: vince-fugnitto --- packages/vsx-registry/src/browser/vsx-extension.tsx | 12 ++++++++---- 1 file changed, 8 insertions(+), 4 deletions(-) diff --git a/packages/vsx-registry/src/browser/vsx-extension.tsx b/packages/vsx-registry/src/browser/vsx-extension.tsx index accbf086b4535..8c6bf78f0b55f 100644 --- a/packages/vsx-registry/src/browser/vsx-extension.tsx +++ b/packages/vsx-registry/src/browser/vsx-extension.tsx @@ -190,12 +190,16 @@ export class VSXExtension implements VSXExtensionData, TreeElement { } get licenseUrl(): string | undefined { - const plugin = this.plugin; - const licenseUrl = plugin && plugin.metadata.model.licenseUrl; + let licenseUrl = this.data['licenseUrl']; if (licenseUrl) { - return new Endpoint({ path: licenseUrl }).getRestUrl().toString(); + return licenseUrl; + } else { + const plugin = this.plugin; + licenseUrl = plugin && plugin.metadata.model.licenseUrl; + if (licenseUrl) { + return new Endpoint({ path: licenseUrl }).getRestUrl().toString(); + } } - return this.data['licenseUrl']; } get repository(): string | undefined { From a62011a5d51462273d35f19635a3722121a568a2 Mon Sep 17 00:00:00 2001 From: Tim Etchells Date: Fri, 26 Jun 2020 11:02:55 -0400 Subject: [PATCH 2/5] Fix modal dialog max size and text wrapping Signed-off-by: Tim Etchells --- .../src/main/browser/dialogs/modal-notification.ts | 2 +- .../browser/dialogs/style/modal-notification.css | 13 ++++--------- 2 files changed, 5 insertions(+), 10 deletions(-) diff --git a/packages/plugin-ext/src/main/browser/dialogs/modal-notification.ts b/packages/plugin-ext/src/main/browser/dialogs/modal-notification.ts index 2b2d3869c13d8..0b9592a541313 100644 --- a/packages/plugin-ext/src/main/browser/dialogs/modal-notification.ts +++ b/packages/plugin-ext/src/main/browser/dialogs/modal-notification.ts @@ -64,7 +64,7 @@ export class ModalNotification extends AbstractDialog { const textContainer = messageNode.appendChild(document.createElement('div')); textContainer.classList.add(TEXT); - const textElement = textContainer.appendChild(document.createElement('pre')); + const textElement = textContainer.appendChild(document.createElement('p')); textElement.textContent = text; actions.forEach((action: MainMessageItem) => { diff --git a/packages/plugin-ext/src/main/browser/dialogs/style/modal-notification.css b/packages/plugin-ext/src/main/browser/dialogs/style/modal-notification.css index 6004158c9119e..7c69b3040c1c1 100644 --- a/packages/plugin-ext/src/main/browser/dialogs/style/modal-notification.css +++ b/packages/plugin-ext/src/main/browser/dialogs/style/modal-notification.css @@ -26,8 +26,8 @@ clear: both; box-sizing: border-box; position: relative; - width: 100%; min-width: 200px; + max-width: min(66vw, 800px); background-color: var(--theia-editorWidget-background); min-height: 35px; margin-bottom: 1px; @@ -60,22 +60,22 @@ .modal-Notification .text { order: 2; display: inline-block; - max-height: calc(100vh - 100px); - max-width: calc(100vw - 100px); + max-height: min(66vh, 600px); -webkit-user-select: text; -moz-user-select: text; -ms-user-select: text; user-select: text; align-self: center; flex: 1 100%; - height: 100%; padding: 10px; overflow: auto; + white-space: pre-wrap; } .modal-Notification .text > p { margin: 0; font-size: var(--theia-ui-font-size1); + font-family: var(--theia-ui-font-family); vertical-align: middle; } @@ -106,8 +106,3 @@ .modal-Notification .buttons > button:hover { background-color: var(--theia-button-hoverBackground); } - -.modal-Notification pre { - font-family: var(--theia-ui-font-family); - font-size: var(--theia-ui-font-size1); -} From a8bd16387f1b539e54829a136d222bb2bf93e253 Mon Sep 17 00:00:00 2001 From: Rob Moran Date: Sun, 28 Jun 2020 21:29:41 +0100 Subject: [PATCH 3/5] handle plugin host activation exceptions Signed-off-by: Rob Moran --- .../src/hosted/node/plugin-host-rpc.ts | 64 +++++++++---------- .../plugin-ext/src/plugin/plugin-manager.ts | 46 ++++++------- 2 files changed, 49 insertions(+), 61 deletions(-) diff --git a/packages/plugin-ext/src/hosted/node/plugin-host-rpc.ts b/packages/plugin-ext/src/hosted/node/plugin-host-rpc.ts index 10054cac27b9a..4fbc8f817b64b 100644 --- a/packages/plugin-ext/src/hosted/node/plugin-host-rpc.ts +++ b/packages/plugin-ext/src/hosted/node/plugin-host-rpc.ts @@ -102,47 +102,43 @@ export class PluginHostRPC { // eslint-disable-next-line @typescript-eslint/no-explicit-any loadPlugin(plugin: Plugin): any { console.log('PLUGIN_HOST(' + process.pid + '): PluginManagerExtImpl/loadPlugin(' + plugin.pluginPath + ')'); - try { - // cleaning the cache for all files of that plug-in. - Object.keys(require.cache).forEach(function (key): void { - const mod: NodeJS.Module = require.cache[key]; + // cleaning the cache for all files of that plug-in. + Object.keys(require.cache).forEach(function (key): void { + const mod: NodeJS.Module = require.cache[key]; - // attempting to reload a native module will throw an error, so skip them - if (mod.id.endsWith('.node')) { - return; - } + // attempting to reload a native module will throw an error, so skip them + if (mod.id.endsWith('.node')) { + return; + } - // remove children that are part of the plug-in - let i = mod.children.length; - while (i--) { - const childMod: NodeJS.Module = mod.children[i]; - // ensure the child module is not null, is in the plug-in folder, and is not a native module (see above) - if (childMod && childMod.id.startsWith(plugin.pluginFolder) && !childMod.id.endsWith('.node')) { - // cleanup exports - note that some modules (e.g. ansi-styles) define their - // exports in an immutable manner, so overwriting the exports throws an error - delete childMod.exports; - mod.children.splice(i, 1); - for (let j = 0; j < childMod.children.length; j++) { - delete childMod.children[j]; - } + // remove children that are part of the plug-in + let i = mod.children.length; + while (i--) { + const childMod: NodeJS.Module = mod.children[i]; + // ensure the child module is not null, is in the plug-in folder, and is not a native module (see above) + if (childMod && childMod.id.startsWith(plugin.pluginFolder) && !childMod.id.endsWith('.node')) { + // cleanup exports - note that some modules (e.g. ansi-styles) define their + // exports in an immutable manner, so overwriting the exports throws an error + delete childMod.exports; + mod.children.splice(i, 1); + for (let j = 0; j < childMod.children.length; j++) { + delete childMod.children[j]; } } + } - if (key.startsWith(plugin.pluginFolder)) { - // delete entry - delete require.cache[key]; - const ix = mod.parent!.children.indexOf(mod); - if (ix >= 0) { - mod.parent!.children.splice(ix, 1); - } + if (key.startsWith(plugin.pluginFolder)) { + // delete entry + delete require.cache[key]; + const ix = mod.parent!.children.indexOf(mod); + if (ix >= 0) { + mod.parent!.children.splice(ix, 1); } - - }); - if (plugin.pluginPath) { - return require(plugin.pluginPath); } - } catch (e) { - console.error(e); + + }); + if (plugin.pluginPath) { + return require(plugin.pluginPath); } }, async init(raw: PluginMetadata[]): Promise<[Plugin[], Plugin[]]> { diff --git a/packages/plugin-ext/src/plugin/plugin-manager.ts b/packages/plugin-ext/src/plugin/plugin-manager.ts index 87b946bd9ffa5..5159f7248aefa 100644 --- a/packages/plugin-ext/src/plugin/plugin-manager.ts +++ b/packages/plugin-ext/src/plugin/plugin-manager.ts @@ -269,20 +269,13 @@ export class PluginManagerExtImpl implements PluginManagerExt, PluginManager { if (plugin.rawModel.extensionDependencies) { for (const dependencyId of plugin.rawModel.extensionDependencies) { const dependency = this.registry.get(dependencyId.toLowerCase()); - const id = plugin.model.displayName || plugin.model.id; if (dependency) { - const depId = dependency.model.displayName || dependency.model.id; const loadedSuccessfully = await this.loadPlugin(dependency, configStorage, visited); if (!loadedSuccessfully) { - const message = `Cannot activate extension '${id}' because it depends on extension '${depId}', which failed to activate.`; - this.messageRegistryProxy.$showMessage(MainMessageType.Error, message, {}, []); - return false; + throw new Error(`Dependent extension '${dependency.model.displayName || dependency.model.id}' failed to activate.`); } } else { - const message = `Cannot activate the '${id}' extension because it depends on the '${dependencyId}' extension, which is not installed.`; - this.messageRegistryProxy.$showMessage(MainMessageType.Error, message, {}, []); - console.warn(message); - return false; + throw new Error(`Dependent extension '${dependencyId}' is not installed.`); } } } @@ -290,7 +283,16 @@ export class PluginManagerExtImpl implements PluginManagerExt, PluginManager { let pluginMain = this.host.loadPlugin(plugin); // see https://github.com/TypeFox/vscode/blob/70b8db24a37fafc77247de7f7cb5bb0195120ed0/src/vs/workbench/api/common/extHostExtensionService.ts#L372-L376 pluginMain = pluginMain || {}; - return await this.startPlugin(plugin, configStorage, pluginMain); + await this.startPlugin(plugin, configStorage, pluginMain); + return true; + } catch (err) { + if (this.pluginActivationPromises.has(plugin.model.id)) { + this.pluginActivationPromises.get(plugin.model.id)!.reject(err); + } + const message = `Activating extension '${plugin.model.displayName || plugin.model.name}' failed: ${err.message}`; + this.messageRegistryProxy.$showMessage(MainMessageType.Error, message, {}, []); + console.error(message); + return false; } finally { this.notificationMain.$stopProgress(progressId); } @@ -330,7 +332,7 @@ export class PluginManagerExtImpl implements PluginManagerExt, PluginManager { } // eslint-disable-next-line @typescript-eslint/no-explicit-any - private async startPlugin(plugin: Plugin, configStorage: ConfigStorage, pluginMain: any): Promise { + private async startPlugin(plugin: Plugin, configStorage: ConfigStorage, pluginMain: any): Promise { const subscriptions: theia.Disposable[] = []; const asAbsolutePath = (relativePath: string): string => join(plugin.pluginFolder, relativePath); const logPath = join(configStorage.hostLogPath, plugin.model.id); // todo check format @@ -354,29 +356,19 @@ export class PluginManagerExtImpl implements PluginManagerExt, PluginManager { } const id = plugin.model.displayName || plugin.model.id; if (typeof pluginMain[plugin.lifecycle.startMethod] === 'function') { - try { - const pluginExport = await pluginMain[plugin.lifecycle.startMethod].apply(getGlobal(), [pluginContext]); - this.activatedPlugins.set(plugin.model.id, new ActivatedPlugin(pluginContext, pluginExport, stopFn)); + const pluginExport = await pluginMain[plugin.lifecycle.startMethod].apply(getGlobal(), [pluginContext]); + this.activatedPlugins.set(plugin.model.id, new ActivatedPlugin(pluginContext, pluginExport, stopFn)); - // resolve activation promise - if (this.pluginActivationPromises.has(plugin.model.id)) { - this.pluginActivationPromises.get(plugin.model.id)!.resolve(); - this.pluginActivationPromises.delete(plugin.model.id); - } - } catch (err) { - if (this.pluginActivationPromises.has(plugin.model.id)) { - this.pluginActivationPromises.get(plugin.model.id)!.reject(err); - } - this.messageRegistryProxy.$showMessage(MainMessageType.Error, `Activating extension ${id} failed: ${err.message}.`, {}, []); - console.error(`Error on activation of ${plugin.model.name}`, err); - return false; + // resolve activation promise + if (this.pluginActivationPromises.has(plugin.model.id)) { + this.pluginActivationPromises.get(plugin.model.id)!.resolve(); + this.pluginActivationPromises.delete(plugin.model.id); } } else { // https://github.com/TypeFox/vscode/blob/70b8db24a37fafc77247de7f7cb5bb0195120ed0/src/vs/workbench/api/common/extHostExtensionService.ts#L400-L401 console.log(`plugin ${id}, ${plugin.lifecycle.startMethod} method is undefined so the module is the extension's exports`); this.activatedPlugins.set(plugin.model.id, new ActivatedPlugin(pluginContext, pluginMain)); } - return true; } getAllPlugins(): Plugin[] { From e4d87c7c9a48f4dae43722f4b57d87b51dc2b4d1 Mon Sep 17 00:00:00 2001 From: Anton Kosyakov Date: Mon, 29 Jun 2020 10:46:56 +0000 Subject: [PATCH 4/5] [monaco] remove unused dependencies Signed-off-by: Anton Kosyakov --- packages/monaco/package.json | 4 +--- yarn.lock | 10 ---------- 2 files changed, 1 insertion(+), 13 deletions(-) diff --git a/packages/monaco/package.json b/packages/monaco/package.json index 18aa3d2ab81be..367eb39fd73a6 100644 --- a/packages/monaco/package.json +++ b/packages/monaco/package.json @@ -14,8 +14,6 @@ "fast-plist": "^0.1.2", "idb": "^4.0.5", "jsonc-parser": "^2.0.2", - "monaco-css": "^2.5.0", - "monaco-html": "^2.5.2", "onigasm": "^2.2.0", "vscode-textmate": "^4.0.1" }, @@ -58,4 +56,4 @@ "nyc": { "extends": "../../configs/nyc.json" } -} +} \ No newline at end of file diff --git a/yarn.lock b/yarn.lock index d45c203823c16..64966b6acbdff 100644 --- a/yarn.lock +++ b/yarn.lock @@ -8762,16 +8762,6 @@ moment@2.24.0, moment@^2.6.0: resolved "https://registry.yarnpkg.com/moment/-/moment-2.24.0.tgz#0d055d53f5052aa653c9f6eb68bb5d12bf5c2b5b" integrity sha512-bV7f+6l2QigeBBZSM/6yTNq4P2fNpSWj/0e7jQcy87A8e7o2nAfP/34/2ky5Vw4B9S446EtIhodAzkFCcR4dQg== -monaco-css@^2.5.0: - version "2.6.0" - resolved "https://registry.yarnpkg.com/monaco-css/-/monaco-css-2.6.0.tgz#40f1291e01ff297b99a92806f5cc12a0394715d7" - integrity sha512-p+qZxteFlSkWx2pXnK9k11FKvC8q3qt1gL2yH4F3bLjKs1ngD65XncVxC5fuKdMhH23im9dv/ZF6rKP93+04tg== - -monaco-html@^2.5.2: - version "2.6.0" - resolved "https://registry.yarnpkg.com/monaco-html/-/monaco-html-2.6.0.tgz#42d4441b9ba3e023d8895e5a1569d1df623c1691" - integrity sha512-UVvgqFFuzCjwsfINKmc2nm4qvQhBsu1luw4lUz+YF3CxAcVQBmscWiz5fb6/MFRG77K0h+7uADseNmc9APzEgA== - monaco-languageclient@^0.13.0: version "0.13.0" resolved "https://registry.yarnpkg.com/monaco-languageclient/-/monaco-languageclient-0.13.0.tgz#59b68b42fb7633171502d6557f597c2752f6c266" From 68a3453ed1de6279dc8a44e7d846b92a0953ebe9 Mon Sep 17 00:00:00 2001 From: David Schafhauser Date: Wed, 17 Jun 2020 14:14:24 +0200 Subject: [PATCH 5/5] fix #7973: Collect env vars lowercase on windows - Populate local copy of environment variables with lowercase keys if on Windows platform - Fix #7973: Environment variables are not retrieved properly on Windows - Update changelog Signed-off-by: David Schafhauser --- CHANGELOG.md | 5 ++++- .../core/src/node/env-variables/env-variables-server.ts | 6 +++++- 2 files changed, 9 insertions(+), 2 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 96fcb7b91ce2f..1f02bea945acf 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,5 +1,9 @@ # Change Log +## v1.4.0 + +- [core] fixed handling of environment variables on Windows [#7973](https://github.com/eclipse-theia/theia/pull/7973) + ## v1.3.0 - [cli] updated the download script to warn about mandatory `theiaPlugins` field [#8058](https://github.com/eclipse-theia/theia/pull/8058) @@ -49,7 +53,6 @@ Breaking Changes: - [shell] updated `ApplicationShell.TrackableWidgetProvider.getTrackableWidgets` to be synchronous in order to register child widgets in the same tick [#7957](https://github.com/eclipse-theia/theia/pull/7957) - use `ApplicationShell.TrackableWidgetProvider.onDidChangeTrackableWidgets` if child widgets are added asynchronously - ## v1.2.0 - [application-manager] added ability for clients to add `windowOptions` using an IPC-Event [#7803](https://github.com/eclipse-theia/theia/pull/7803) diff --git a/packages/core/src/node/env-variables/env-variables-server.ts b/packages/core/src/node/env-variables/env-variables-server.ts index 165fc05c3d2d9..a9efe099b5bae 100644 --- a/packages/core/src/node/env-variables/env-variables-server.ts +++ b/packages/core/src/node/env-variables/env-variables-server.ts @@ -30,7 +30,11 @@ export class EnvVariablesServerImpl implements EnvVariablesServer { constructor() { const prEnv = process.env; Object.keys(prEnv).forEach((key: string) => { - this.envs[key] = { 'name': key, 'value': prEnv[key] }; + let keyName = key; + if (isWindows) { + keyName = key.toLowerCase(); + } + this.envs[keyName] = { 'name': keyName, 'value': prEnv[key] }; }); }