From 27a2ca85f458bd2248ce28533f63fde3d0984c44 Mon Sep 17 00:00:00 2001 From: Josh Spicer <23246594+joshspicer@users.noreply.github.com> Date: Thu, 13 Mar 2025 15:30:11 -0700 Subject: [PATCH] Install remote default extensions only if already installed locally (#243499) remote default extensions only if local --- src/vs/platform/remote/common/remote.ts | 2 +- .../electron-sandbox/remoteExtensionsInit.ts | 21 +++++++++++++++---- .../remote/common/remote.contribution.ts | 8 +++---- 3 files changed, 22 insertions(+), 9 deletions(-) diff --git a/src/vs/platform/remote/common/remote.ts b/src/vs/platform/remote/common/remote.ts index a2d098fa8d1..eba717a7eb1 100644 --- a/src/vs/platform/remote/common/remote.ts +++ b/src/vs/platform/remote/common/remote.ts @@ -3,4 +3,4 @@ * Licensed under the MIT License. See License.txt in the project root for license information. *--------------------------------------------------------------------------------------------*/ -export const REMOTE_DEFAULT_EXTENSIONS = 'remote.defaultExtensions'; +export const REMOTE_DEFAULT_IF_LOCAL_EXTENSIONS = 'remote.defaultExtensionsIfInstalledLocally'; diff --git a/src/vs/workbench/contrib/extensions/electron-sandbox/remoteExtensionsInit.ts b/src/vs/workbench/contrib/extensions/electron-sandbox/remoteExtensionsInit.ts index 3895b768694..1b0fadda14f 100644 --- a/src/vs/workbench/contrib/extensions/electron-sandbox/remoteExtensionsInit.ts +++ b/src/vs/workbench/contrib/extensions/electron-sandbox/remoteExtensionsInit.ts @@ -8,12 +8,13 @@ import { IConfigurationService } from '../../../../platform/configuration/common import { IEnvironmentService } from '../../../../platform/environment/common/environment.js'; import { EXTENSION_INSTALL_SKIP_PUBLISHER_TRUST_CONTEXT, IExtensionGalleryService, IExtensionManagementService, InstallExtensionInfo } from '../../../../platform/extensionManagement/common/extensionManagement.js'; import { areSameExtensions } from '../../../../platform/extensionManagement/common/extensionManagementUtil.js'; +import { ExtensionType } from '../../../../platform/extensions/common/extensions.js'; import { IFileService } from '../../../../platform/files/common/files.js'; import { IInstantiationService } from '../../../../platform/instantiation/common/instantiation.js'; import { ServiceCollection } from '../../../../platform/instantiation/common/serviceCollection.js'; import { ILogService } from '../../../../platform/log/common/log.js'; import { IProductService } from '../../../../platform/product/common/productService.js'; -import { REMOTE_DEFAULT_EXTENSIONS } from '../../../../platform/remote/common/remote.js'; +import { REMOTE_DEFAULT_IF_LOCAL_EXTENSIONS } from '../../../../platform/remote/common/remote.js'; import { IRemoteAuthorityResolverService } from '../../../../platform/remote/common/remoteAuthorityResolver.js'; import { IRemoteExtensionsScannerService } from '../../../../platform/remote/common/remoteExtensionsScanner.js'; import { IStorageService, IS_NEW_KEY, StorageScope, StorageTarget } from '../../../../platform/storage/common/storage.js'; @@ -53,7 +54,12 @@ export class InstallRemoteExtensionsContribution implements IWorkbenchContributi return; } - const settingValue = this.configurationService.getValue(REMOTE_DEFAULT_EXTENSIONS); + if (!this.extensionManagementServerService.localExtensionManagementServer) { + this.logService.error('No local extension management server available'); + return; + } + + const settingValue = this.configurationService.getValue(REMOTE_DEFAULT_IF_LOCAL_EXTENSIONS); if (!settingValue?.length) { return; } @@ -62,17 +68,24 @@ export class InstallRemoteExtensionsContribution implements IWorkbenchContributi const preferPrerelease = this.productService.quality !== 'stable'; const galleryExtensions = await this.extensionGalleryService.getExtensions(settingValue.map((id) => ({ id })), CancellationToken.None); - const alreadyInstalledExtensions = await this.extensionManagementServerService.remoteExtensionManagementServer.extensionManagementService.getInstalled(); + const alreadyInstalledInRemote = await this.extensionManagementServerService.remoteExtensionManagementServer.extensionManagementService.getInstalled(ExtensionType.User); + const alreadyInstalledLocally = await this.extensionManagementServerService.localExtensionManagementServer.extensionManagementService.getInstalled(ExtensionType.User); const prereleaseExtensionInfo: InstallExtensionInfo[] = []; const extensionInfo: InstallExtensionInfo[] = []; for (const id of settingValue) { - const alreadyInstalled = alreadyInstalledExtensions.some(e => areSameExtensions(e.identifier, { id })); + const alreadyInstalled = alreadyInstalledInRemote.some(e => areSameExtensions(e.identifier, { id })); if (alreadyInstalled) { this.logService.trace(`Default remote extension '${id}' is already installed`); continue; } + const installedLocally = alreadyInstalledLocally.some(e => areSameExtensions(e.identifier, { id })); + if (!installedLocally) { + this.logService.trace(`Default remote extension '${id}' is not already installed locally`); + continue; + } + const extension = galleryExtensions.find(e => areSameExtensions(e.identifier, { id })); if (!extension) { this.logService.warn(`Default remote extension '${id}' is not found`); diff --git a/src/vs/workbench/contrib/remote/common/remote.contribution.ts b/src/vs/workbench/contrib/remote/common/remote.contribution.ts index a278220924f..f2bb13dad7f 100644 --- a/src/vs/workbench/contrib/remote/common/remote.contribution.ts +++ b/src/vs/workbench/contrib/remote/common/remote.contribution.ts @@ -26,7 +26,7 @@ import { PersistentConnection } from '../../../../platform/remote/common/remoteA import { IDownloadService } from '../../../../platform/download/common/download.js'; import { DownloadServiceChannel } from '../../../../platform/download/common/downloadIpc.js'; import { RemoteLoggerChannelClient } from '../../../../platform/log/common/logIpc.js'; -import { REMOTE_DEFAULT_EXTENSIONS } from '../../../../platform/remote/common/remote.js'; +import { REMOTE_DEFAULT_IF_LOCAL_EXTENSIONS } from '../../../../platform/remote/common/remote.js'; const EXTENSION_IDENTIFIER_PATTERN = '([a-z0-9A-Z][a-z0-9-A-Z]*)\\.([a-z0-9A-Z][a-z0-9-A-Z]*)$'; @@ -360,9 +360,9 @@ Registry.as(ConfigurationExtensions.Configuration) default: 'localhost', description: localize('remote.localPortHost', "Specifies the local host name that will be used for port forwarding.") }, - [REMOTE_DEFAULT_EXTENSIONS]: { + [REMOTE_DEFAULT_IF_LOCAL_EXTENSIONS]: { type: 'array', - markdownDescription: localize('remote.defaultExtensions.markdownDescription', 'List of extensions to install automatically on all remotes.'), + markdownDescription: localize('remote.defaultExtensionsIfInstalledLocally.markdownDescription', 'List of extensions to install automatically on all remotes if already installed locally.'), default: [ 'GitHub.copilot', 'GitHub.copilot-chat' @@ -370,7 +370,7 @@ Registry.as(ConfigurationExtensions.Configuration) items: { type: 'string', pattern: EXTENSION_IDENTIFIER_PATTERN, - patternErrorMessage: localize('remote.defaultExtensions.invalidFormat', 'Extension identifier must be in format "publisher.name".') + patternErrorMessage: localize('remote.defaultExtensionsIfInstalledLocally.invalidFormat', 'Extension identifier must be in format "publisher.name".') }, } }