From ca280cc4a826074d0e525e9b26091a489aa1b887 Mon Sep 17 00:00:00 2001 From: Sandeep Somavarapu Date: Wed, 29 May 2024 13:56:26 +0200 Subject: [PATCH] fix #211965 --- src/vs/server/node/remoteExtensionsScanner.ts | 2 +- .../browser/extensionsWorkbenchService.ts | 29 +++++++++++++++---- .../extensions/browser/extensionService.ts | 2 +- .../extensions/common/extensionsUtil.ts | 9 +++++- .../cachedExtensionScanner.ts | 6 ++-- 5 files changed, 37 insertions(+), 11 deletions(-) diff --git a/src/vs/server/node/remoteExtensionsScanner.ts b/src/vs/server/node/remoteExtensionsScanner.ts index 54418aebfc277..19a50f7b067ff 100644 --- a/src/vs/server/node/remoteExtensionsScanner.ts +++ b/src/vs/server/node/remoteExtensionsScanner.ts @@ -133,7 +133,7 @@ export class RemoteExtensionsScannerService implements IRemoteExtensionsScannerS this._scanDevelopedExtensions(language, extensionDevelopmentPath) ]); - return dedupExtensions(builtinExtensions, [...installedExtensions, ...workspaceInstalledExtensions], developedExtensions, this._logService); + return dedupExtensions(builtinExtensions, installedExtensions, workspaceInstalledExtensions, developedExtensions, this._logService); } private async _scanDevelopedExtensions(language: string, extensionDevelopmentPaths?: string[]): Promise { diff --git a/src/vs/workbench/contrib/extensions/browser/extensionsWorkbenchService.ts b/src/vs/workbench/contrib/extensions/browser/extensionsWorkbenchService.ts index 077879d57e04a..3eb8c7ee130fa 100644 --- a/src/vs/workbench/contrib/extensions/browser/extensionsWorkbenchService.ts +++ b/src/vs/workbench/contrib/extensions/browser/extensionsWorkbenchService.ts @@ -690,11 +690,28 @@ class Extensions extends Disposable { all.push(...await this.workbenchExtensionManagementService.getInstalledWorkspaceExtensions(true)); } - // dedup user and system extensions by giving priority to user extensions. + // dedup workspace, user and system extensions by giving priority to workspace first and then to user extension. const installed = groupByExtension(all, r => r.identifier).reduce((result, extensions) => { - const extension = extensions.length === 1 ? extensions[0] - : extensions.find(e => e.type === ExtensionType.User) || extensions.find(e => e.type === ExtensionType.System); - result.push(extension!); + if (extensions.length === 1) { + result.push(extensions[0]); + } else { + let workspaceExtension: ILocalExtension | undefined, + userExtension: ILocalExtension | undefined, + systemExtension: ILocalExtension | undefined; + for (const extension of extensions) { + if (extension.isWorkspaceScoped) { + workspaceExtension = extension; + } else if (extension.type === ExtensionType.User) { + userExtension = extension; + } else { + systemExtension = extension; + } + } + const extension = workspaceExtension ?? userExtension ?? systemExtension; + if (extension) { + result.push(extension); + } + } return result; }, []); @@ -1300,7 +1317,9 @@ export class ExtensionsWorkbenchService extends Disposable implements IExtension if (isUninstalled) { const canRemoveRunningExtension = runningExtension && this.extensionService.canRemoveExtension(runningExtension); - const isSameExtensionRunning = runningExtension && (!extension.server || extension.server === this.extensionManagementServerService.getExtensionManagementServer(toExtension(runningExtension))); + const isSameExtensionRunning = runningExtension + && (!extension.server || extension.server === this.extensionManagementServerService.getExtensionManagementServer(toExtension(runningExtension))) + && (!extension.resourceExtension || this.uriIdentityService.extUri.isEqual(extension.resourceExtension.location, runningExtension.extensionLocation)); if (!canRemoveRunningExtension && isSameExtensionRunning && !runningExtension.isUnderDevelopment) { return { action: reloadAction, reason: nls.localize('postUninstallTooltip', "Please {0} to complete the uninstallation of this extension.", reloadActionLabel) }; } diff --git a/src/vs/workbench/services/extensions/browser/extensionService.ts b/src/vs/workbench/services/extensions/browser/extensionService.ts index a181772e8c42f..1611fb028703f 100644 --- a/src/vs/workbench/services/extensions/browser/extensionService.ts +++ b/src/vs/workbench/services/extensions/browser/extensionService.ts @@ -141,7 +141,7 @@ export class ExtensionService extends AbstractExtensionService implements IExten } catch (error) { this._logService.error(error); } - return dedupExtensions(system, user, development, this._logService); + return dedupExtensions(system, user, [], development, this._logService); } protected async _resolveExtensionsDefault() { diff --git a/src/vs/workbench/services/extensions/common/extensionsUtil.ts b/src/vs/workbench/services/extensions/common/extensionsUtil.ts index 5effbeda604eb..a1d2090c747bc 100644 --- a/src/vs/workbench/services/extensions/common/extensionsUtil.ts +++ b/src/vs/workbench/services/extensions/common/extensionsUtil.ts @@ -9,7 +9,7 @@ import { ILogService } from 'vs/platform/log/common/log'; import * as semver from 'vs/base/common/semver/semver'; // TODO: @sandy081 merge this with deduping in extensionsScannerService.ts -export function dedupExtensions(system: IExtensionDescription[], user: IExtensionDescription[], development: IExtensionDescription[], logService: ILogService): IExtensionDescription[] { +export function dedupExtensions(system: IExtensionDescription[], user: IExtensionDescription[], workspace: IExtensionDescription[], development: IExtensionDescription[], logService: ILogService): IExtensionDescription[] { const result = new ExtensionIdentifierMap(); system.forEach((systemExtension) => { const extension = result.get(systemExtension.identifier); @@ -37,6 +37,13 @@ export function dedupExtensions(system: IExtensionDescription[], user: IExtensio } result.set(userExtension.identifier, userExtension); }); + workspace.forEach(workspaceExtension => { + const extension = result.get(workspaceExtension.identifier); + if (extension) { + logService.warn(localize('overwritingWithWorkspaceExtension', "Overwriting {0} with Workspace Extension {1}.", extension.extensionLocation.fsPath, workspaceExtension.extensionLocation.fsPath)); + } + result.set(workspaceExtension.identifier, workspaceExtension); + }); development.forEach(developedExtension => { logService.info(localize('extensionUnderDevelopment', "Loading development extension at {0}", developedExtension.extensionLocation.fsPath)); const extension = result.get(developedExtension.identifier); diff --git a/src/vs/workbench/services/extensions/electron-sandbox/cachedExtensionScanner.ts b/src/vs/workbench/services/extensions/electron-sandbox/cachedExtensionScanner.ts index 1c2168068b14e..681138c04815f 100644 --- a/src/vs/workbench/services/extensions/electron-sandbox/cachedExtensionScanner.ts +++ b/src/vs/workbench/services/extensions/electron-sandbox/cachedExtensionScanner.ts @@ -99,10 +99,10 @@ export class CachedExtensionScanner { } const system = scannedSystemExtensions.map(e => toExtensionDescriptionFromScannedExtension(e, false)); - const userGlobal = scannedUserExtensions.map(e => toExtensionDescriptionFromScannedExtension(e, false)); - const userWorkspace = workspaceExtensions.map(e => toExtensionDescription(e, false)); + const user = scannedUserExtensions.map(e => toExtensionDescriptionFromScannedExtension(e, false)); + const workspace = workspaceExtensions.map(e => toExtensionDescription(e, false)); const development = scannedDevelopedExtensions.map(e => toExtensionDescriptionFromScannedExtension(e, true)); - const r = dedupExtensions(system, [...userGlobal, ...userWorkspace], development, this._logService); + const r = dedupExtensions(system, user, workspace, development, this._logService); if (!hasErrors) { const disposable = this._extensionsScannerService.onDidChangeCache(() => {