From 6f9b61778e553ad830f92183baf15450061edb69 Mon Sep 17 00:00:00 2001 From: Sandeep Somavarapu Date: Wed, 7 Sep 2022 15:04:46 +0200 Subject: [PATCH 1/2] prepare for syncing profiles - refactor extension management services - merge IServerExtensionManagementService into IExtensionManagementService - Expose profile aware extensions management events in IProfileAwareExtensionManagementService --- .../contrib/extensionsCleaner.ts | 6 +-- .../abstractExtensionManagementService.ts | 36 ++++++++-------- .../common/extensionManagement.ts | 43 +++++++------------ .../common/extensionManagementIpc.ts | 34 +++++++-------- .../node/extensionManagementService.ts | 23 +++++----- .../browser/extensionsWorkbenchService.ts | 4 +- .../extensionsActions.test.ts | 2 +- .../extensionsWorkbenchService.test.ts | 2 +- .../browser/extensionEnablementService.ts | 2 +- .../common/extensionManagement.ts | 21 ++++++--- .../extensionManagementServerService.ts | 10 +++-- .../common/extensionManagementService.ts | 14 ++++-- .../common/webExtensionManagementService.ts | 27 +++++++----- .../nativeExtensionManagementService.ts | 21 ++++++--- .../remoteExtensionManagementService.ts | 6 ++- .../extensionEnablementService.test.ts | 8 ++-- .../common/abstractExtensionService.ts | 2 +- .../test/browser/workbenchTestServices.ts | 6 ++- 18 files changed, 147 insertions(+), 120 deletions(-) diff --git a/src/vs/code/electron-browser/sharedProcess/contrib/extensionsCleaner.ts b/src/vs/code/electron-browser/sharedProcess/contrib/extensionsCleaner.ts index 98996fc52663b..a49cc156f35d1 100644 --- a/src/vs/code/electron-browser/sharedProcess/contrib/extensionsCleaner.ts +++ b/src/vs/code/electron-browser/sharedProcess/contrib/extensionsCleaner.ts @@ -5,7 +5,7 @@ import { Disposable, DisposableStore, MutableDisposable, toDisposable } from 'vs/base/common/lifecycle'; import { URI } from 'vs/base/common/uri'; -import { IExtensionGalleryService, IExtensionIdentifier, IGlobalExtensionEnablementService, ServerDidUninstallExtensionEvent, ServerInstallExtensionResult, UninstallOptions } from 'vs/platform/extensionManagement/common/extensionManagement'; +import { IExtensionGalleryService, IExtensionIdentifier, IGlobalExtensionEnablementService, DidUninstallExtensionEvent, InstallExtensionResult, UninstallOptions } from 'vs/platform/extensionManagement/common/extensionManagement'; import { getIdAndVersion } from 'vs/platform/extensionManagement/common/extensionManagementUtil'; import { IExtensionsProfileScannerService } from 'vs/platform/extensionManagement/common/extensionsProfileScannerService'; import { ExtensionStorageService, IExtensionStorageService } from 'vs/platform/extensionManagement/common/extensionStorage'; @@ -102,7 +102,7 @@ class ProfileExtensionsCleaner extends Disposable { } } - private async onDidInstallExtensions(installedExtensions: readonly ServerInstallExtensionResult[]): Promise { + private async onDidInstallExtensions(installedExtensions: readonly InstallExtensionResult[]): Promise { for (const { local, profileLocation } of installedExtensions) { if (!local || !profileLocation) { continue; @@ -111,7 +111,7 @@ class ProfileExtensionsCleaner extends Disposable { } } - private async onDidUninstallExtension(e: ServerDidUninstallExtensionEvent): Promise { + private async onDidUninstallExtension(e: DidUninstallExtensionEvent): Promise { if (!e.profileLocation || !e.version) { return; } diff --git a/src/vs/platform/extensionManagement/common/abstractExtensionManagementService.ts b/src/vs/platform/extensionManagement/common/abstractExtensionManagementService.ts index c0e21d9aa102b..6b805a927685c 100644 --- a/src/vs/platform/extensionManagement/common/abstractExtensionManagementService.ts +++ b/src/vs/platform/extensionManagement/common/abstractExtensionManagementService.ts @@ -14,8 +14,8 @@ import { URI } from 'vs/base/common/uri'; import * as nls from 'vs/nls'; import { ExtensionManagementError, IExtensionGalleryService, IExtensionIdentifier, IExtensionManagementParticipant, IGalleryExtension, IGalleryMetadata, ILocalExtension, InstallOperation, - IExtensionsControlManifest, StatisticType, isTargetPlatformCompatible, TargetPlatformToString, ExtensionManagementErrorCode, IServerExtensionManagementService, - ServerInstallOptions, ServerInstallVSIXOptions, ServerUninstallOptions, Metadata, ServerInstallExtensionEvent, ServerInstallExtensionResult, ServerUninstallExtensionEvent, ServerDidUninstallExtensionEvent + IExtensionsControlManifest, StatisticType, isTargetPlatformCompatible, TargetPlatformToString, ExtensionManagementErrorCode, + InstallOptions, InstallVSIXOptions, UninstallOptions, Metadata, InstallExtensionEvent, DidUninstallExtensionEvent, InstallExtensionResult, UninstallExtensionEvent, IExtensionManagementService } from 'vs/platform/extensionManagement/common/extensionManagement'; import { areSameExtensions, ExtensionKey, getGalleryExtensionTelemetryData, getLocalExtensionTelemetryData } from 'vs/platform/extensionManagement/common/extensionManagementUtil'; import { ExtensionType, IExtensionManifest, isApplicationScopedExtension, TargetPlatform } from 'vs/platform/extensions/common/extensions'; @@ -40,7 +40,7 @@ export interface IUninstallExtensionTask { cancel(): void; } -export abstract class AbstractExtensionManagementService extends Disposable implements IServerExtensionManagementService { +export abstract class AbstractExtensionManagementService extends Disposable implements IExtensionManagementService { declare readonly _serviceBrand: undefined; @@ -49,16 +49,16 @@ export abstract class AbstractExtensionManagementService extends Disposable impl private readonly installingExtensions = new Map(); private readonly uninstallingExtensions = new Map(); - private readonly _onInstallExtension = this._register(new Emitter()); + private readonly _onInstallExtension = this._register(new Emitter()); readonly onInstallExtension = this._onInstallExtension.event; - protected readonly _onDidInstallExtensions = this._register(new Emitter()); + protected readonly _onDidInstallExtensions = this._register(new Emitter()); readonly onDidInstallExtensions = this._onDidInstallExtensions.event; - protected readonly _onUninstallExtension = this._register(new Emitter()); + protected readonly _onUninstallExtension = this._register(new Emitter()); readonly onUninstallExtension = this._onUninstallExtension.event; - protected _onDidUninstallExtension = this._register(new Emitter()); + protected _onDidUninstallExtension = this._register(new Emitter()); readonly onDidUninstallExtension = this._onDidUninstallExtension.event; private readonly participants: IExtensionManagementParticipant[] = []; @@ -84,7 +84,7 @@ export abstract class AbstractExtensionManagementService extends Disposable impl return extension.allTargetPlatforms.some(targetPlatform => isTargetPlatformCompatible(targetPlatform, extension.allTargetPlatforms, currentTargetPlatform)); } - async installFromGallery(extension: IGalleryExtension, options: ServerInstallOptions = {}): Promise { + async installFromGallery(extension: IGalleryExtension, options: InstallOptions = {}): Promise { try { if (!this.galleryService.isEnabled()) { throw new ExtensionManagementError(nls.localize('MarketPlaceDisabled', "Marketplace is not enabled"), ExtensionManagementErrorCode.Internal); @@ -99,7 +99,7 @@ export abstract class AbstractExtensionManagementService extends Disposable impl } } - async uninstall(extension: ILocalExtension, options: ServerUninstallOptions = {}): Promise { + async uninstall(extension: ILocalExtension, options: UninstallOptions = {}): Promise { this.logService.trace('ExtensionManagementService#uninstall', extension.identifier.id); return this.uninstallExtension(extension, options); } @@ -135,7 +135,7 @@ export abstract class AbstractExtensionManagementService extends Disposable impl this.participants.push(participant); } - protected async installExtension(manifest: IExtensionManifest, extension: URI | IGalleryExtension, options: ServerInstallOptions & ServerInstallVSIXOptions): Promise { + protected async installExtension(manifest: IExtensionManifest, extension: URI | IGalleryExtension, options: InstallOptions & InstallVSIXOptions): Promise { const getInstallExtensionTaskKey = (extension: IGalleryExtension) => `${ExtensionKey.create(extension).toString()}${options.profileLocation ? `-${options.profileLocation.toString()}` : ''}`; @@ -152,7 +152,7 @@ export abstract class AbstractExtensionManagementService extends Disposable impl const allInstallExtensionTasks: { task: IInstallExtensionTask; manifest: IExtensionManifest }[] = []; const alreadyRequestedInstallations: Promise[] = []; - const installResults: (ServerInstallExtensionResult & { local: ILocalExtension })[] = []; + const installResults: (InstallExtensionResult & { local: ILocalExtension })[] = []; const installExtensionTask = this.createInstallExtensionTask(manifest, extension, options); if (!URI.isUri(extension)) { this.installingExtensions.set(getInstallExtensionTaskKey(extension), { task: installExtensionTask, waitingTasks: [] }); @@ -467,7 +467,7 @@ export abstract class AbstractExtensionManagementService extends Disposable impl return compatibleExtension; } - private async uninstallExtension(extension: ILocalExtension, options: ServerUninstallOptions): Promise { + private async uninstallExtension(extension: ILocalExtension, options: UninstallOptions): Promise { const getUninstallExtensionTaskKey = (identifier: IExtensionIdentifier) => `${identifier.id.toLowerCase()}${options.versionOnly ? `-${extension.manifest.version}` : ''}${options.profileLocation ? `@${options.profileLocation.toString()}` : ''}`; const uninstallExtensionTask = this.uninstallingExtensions.get(getUninstallExtensionTaskKey(extension.identifier)); if (uninstallExtensionTask) { @@ -475,7 +475,7 @@ export abstract class AbstractExtensionManagementService extends Disposable impl return uninstallExtensionTask.waitUntilTaskIsFinished(); } - const createUninstallExtensionTask = (extension: ILocalExtension, uninstallOptions: ServerUninstallOptions): IUninstallExtensionTask => { + const createUninstallExtensionTask = (extension: ILocalExtension, uninstallOptions: UninstallOptions): IUninstallExtensionTask => { const uninstallExtensionTask = this.createUninstallExtensionTask(extension, uninstallOptions); this.uninstallingExtensions.set(getUninstallExtensionTaskKey(uninstallExtensionTask.extension.identifier), uninstallExtensionTask); if (options.profileLocation) { @@ -645,14 +645,14 @@ export abstract class AbstractExtensionManagementService extends Disposable impl } } - private createInstallExtensionTask(manifest: IExtensionManifest, extension: URI | IGalleryExtension, options: ServerInstallOptions & ServerInstallVSIXOptions): IInstallExtensionTask { + private createInstallExtensionTask(manifest: IExtensionManifest, extension: URI | IGalleryExtension, options: InstallOptions & InstallVSIXOptions): IInstallExtensionTask { if (options.profileLocation && isApplicationScopedExtension(manifest)) { options = { ...options, profileLocation: this.userDataProfilesService.defaultProfile.extensionsResource }; } return this.doCreateInstallExtensionTask(manifest, extension, options); } - private createUninstallExtensionTask(extension: ILocalExtension, options: ServerUninstallOptions): IUninstallExtensionTask { + private createUninstallExtensionTask(extension: ILocalExtension, options: UninstallOptions): IUninstallExtensionTask { if (options.profileLocation && extension.isApplicationScoped) { options = { ...options, profileLocation: this.userDataProfilesService.defaultProfile.extensionsResource }; } @@ -663,15 +663,15 @@ export abstract class AbstractExtensionManagementService extends Disposable impl abstract zip(extension: ILocalExtension): Promise; abstract unzip(zipLocation: URI): Promise; abstract getManifest(vsix: URI): Promise; - abstract install(vsix: URI, options?: ServerInstallVSIXOptions): Promise; + abstract install(vsix: URI, options?: InstallVSIXOptions): Promise; abstract getInstalled(type?: ExtensionType, profileLocation?: URI): Promise; abstract getMetadata(extension: ILocalExtension): Promise; abstract updateMetadata(local: ILocalExtension, metadata: IGalleryMetadata): Promise; abstract updateExtensionScope(local: ILocalExtension, isMachineScoped: boolean): Promise; - protected abstract doCreateInstallExtensionTask(manifest: IExtensionManifest, extension: URI | IGalleryExtension, options: ServerInstallOptions & ServerInstallVSIXOptions): IInstallExtensionTask; - protected abstract doCreateUninstallExtensionTask(extension: ILocalExtension, options: ServerUninstallOptions): IUninstallExtensionTask; + protected abstract doCreateInstallExtensionTask(manifest: IExtensionManifest, extension: URI | IGalleryExtension, options: InstallOptions & InstallVSIXOptions): IInstallExtensionTask; + protected abstract doCreateUninstallExtensionTask(extension: ILocalExtension, options: UninstallOptions): IUninstallExtensionTask; } export function joinErrors(errorOrErrors: (Error | string) | (Array)): Error { diff --git a/src/vs/platform/extensionManagement/common/extensionManagement.ts b/src/vs/platform/extensionManagement/common/extensionManagement.ts index 3c5ec5205122d..4d61d8d2fa07c 100644 --- a/src/vs/platform/extensionManagement/common/extensionManagement.ts +++ b/src/vs/platform/extensionManagement/common/extensionManagement.ts @@ -11,7 +11,7 @@ import { Platform } from 'vs/base/common/platform'; import { URI } from 'vs/base/common/uri'; import { localize } from 'vs/nls'; import { ExtensionType, IExtension, IExtensionManifest, TargetPlatform } from 'vs/platform/extensions/common/extensions'; -import { createDecorator, refineServiceDecorator } from 'vs/platform/instantiation/common/instantiation'; +import { createDecorator } from 'vs/platform/instantiation/common/instantiation'; export const EXTENSION_IDENTIFIER_PATTERN = '^([a-z0-9A-Z][a-z0-9-A-Z]*)\\.([a-z0-9A-Z][a-z0-9-A-Z]*)$'; export const EXTENSION_IDENTIFIER_REGEX = new RegExp(EXTENSION_IDENTIFIER_PATTERN); @@ -344,8 +344,10 @@ export interface IExtensionGalleryService { } export interface InstallExtensionEvent { - identifier: IExtensionIdentifier; - source: URI | IGalleryExtension; + readonly identifier: IExtensionIdentifier; + readonly source: URI | IGalleryExtension; + readonly profileLocation?: URI; + readonly applicationScoped?: boolean; } export interface InstallExtensionResult { @@ -354,16 +356,22 @@ export interface InstallExtensionResult { readonly source?: URI | IGalleryExtension; readonly local?: ILocalExtension; readonly context?: IStringDictionary; + readonly profileLocation?: URI; + readonly applicationScoped?: boolean; } export interface UninstallExtensionEvent { - identifier: IExtensionIdentifier; + readonly identifier: IExtensionIdentifier; + readonly profileLocation?: URI; + readonly applicationScoped?: boolean; } export interface DidUninstallExtensionEvent { readonly identifier: IExtensionIdentifier; readonly version?: string; readonly error?: string; + readonly profileLocation?: URI; + readonly applicationScoped?: boolean; } export enum ExtensionManagementErrorCode { @@ -402,9 +410,10 @@ export type InstallOptions = { * Context passed through to InstallExtensionResult */ context?: IStringDictionary; + profileLocation?: URI; }; export type InstallVSIXOptions = Omit & { installOnlyNewlyAddedFromExtensionPack?: boolean }; -export type UninstallOptions = { readonly donotIncludePack?: boolean; readonly donotCheckDependents?: boolean; readonly versionOnly?: boolean; readonly remove?: boolean }; +export type UninstallOptions = { readonly donotIncludePack?: boolean; readonly donotCheckDependents?: boolean; readonly versionOnly?: boolean; readonly remove?: boolean; readonly profileLocation?: URI }; export interface IExtensionManagementParticipant { postInstall(local: ILocalExtension, source: URI | IGalleryExtension, options: InstallOptions | InstallVSIXOptions, token: CancellationToken): Promise; @@ -428,7 +437,7 @@ export interface IExtensionManagementService { installFromGallery(extension: IGalleryExtension, options?: InstallOptions): Promise; uninstall(extension: ILocalExtension, options?: UninstallOptions): Promise; reinstallFromGallery(extension: ILocalExtension): Promise; - getInstalled(type?: ExtensionType): Promise; + getInstalled(type?: ExtensionType, profileLocation?: URI): Promise; getExtensionsControlManifest(): Promise; getMetadata(extension: ILocalExtension): Promise; @@ -439,28 +448,6 @@ export interface IExtensionManagementService { getTargetPlatform(): Promise; } -export type ServerInstallExtensionEvent = InstallExtensionEvent & { profileLocation?: URI; applicationScoped?: boolean }; -export type ServerInstallExtensionResult = InstallExtensionResult & { profileLocation?: URI; applicationScoped?: boolean }; -export type ServerUninstallExtensionEvent = UninstallExtensionEvent & { profileLocation?: URI; applicationScoped?: boolean }; -export type ServerDidUninstallExtensionEvent = DidUninstallExtensionEvent & { profileLocation?: URI; applicationScoped?: boolean }; - -export type ServerInstallOptions = InstallOptions & { profileLocation?: URI }; -export type ServerInstallVSIXOptions = InstallVSIXOptions & { profileLocation?: URI }; -export type ServerUninstallOptions = UninstallOptions & { profileLocation?: URI }; - -export const IServerExtensionManagementService = refineServiceDecorator(IExtensionManagementService); -export interface IServerExtensionManagementService extends IExtensionManagementService { - readonly _serviceBrand: undefined; - onInstallExtension: Event; - onDidInstallExtensions: Event; - onUninstallExtension: Event; - onDidUninstallExtension: Event; - getInstalled(type?: ExtensionType, profileLocation?: URI): Promise; - install(vsix: URI, options?: ServerInstallVSIXOptions): Promise; - installFromGallery(extension: IGalleryExtension, options?: ServerInstallOptions): Promise; - uninstall(extension: ILocalExtension, options?: ServerUninstallOptions): Promise; -} - export const DISABLED_EXTENSIONS_STORAGE_PATH = 'extensionsIdentifiers/disabled'; export const ENABLED_EXTENSIONS_STORAGE_PATH = 'extensionsIdentifiers/enabled'; export const IGlobalExtensionEnablementService = createDecorator('IGlobalExtensionEnablementService'); diff --git a/src/vs/platform/extensionManagement/common/extensionManagementIpc.ts b/src/vs/platform/extensionManagement/common/extensionManagementIpc.ts index 9c05c43c5f12f..0f59245f80957 100644 --- a/src/vs/platform/extensionManagement/common/extensionManagementIpc.ts +++ b/src/vs/platform/extensionManagement/common/extensionManagementIpc.ts @@ -10,7 +10,7 @@ import { cloneAndChange } from 'vs/base/common/objects'; import { URI, UriComponents } from 'vs/base/common/uri'; import { DefaultURITransformer, IURITransformer, transformAndReviveIncomingURIs } from 'vs/base/common/uriIpc'; import { IChannel, IServerChannel } from 'vs/base/parts/ipc/common/ipc'; -import { IExtensionIdentifier, IExtensionManagementService, IExtensionTipsService, IGalleryExtension, IGalleryMetadata, ILocalExtension, IExtensionsControlManifest, isTargetPlatformCompatible, IServerExtensionManagementService, ServerInstallOptions, ServerInstallVSIXOptions, ServerUninstallOptions, Metadata, ServerUninstallExtensionEvent, ServerInstallExtensionEvent, ServerInstallExtensionResult, ServerDidUninstallExtensionEvent } from 'vs/platform/extensionManagement/common/extensionManagement'; +import { IExtensionIdentifier, IExtensionTipsService, IGalleryExtension, IGalleryMetadata, ILocalExtension, IExtensionsControlManifest, isTargetPlatformCompatible, InstallOptions, InstallVSIXOptions, UninstallOptions, Metadata, IExtensionManagementService, DidUninstallExtensionEvent, InstallExtensionEvent, InstallExtensionResult, UninstallExtensionEvent } from 'vs/platform/extensionManagement/common/extensionManagement'; import { ExtensionType, IExtensionManifest, TargetPlatform } from 'vs/platform/extensions/common/extensions'; function transformIncomingURI(uri: UriComponents, transformer: IURITransformer | null): URI { @@ -34,12 +34,12 @@ function transformOutgoingExtension(extension: ILocalExtension, transformer: IUR export class ExtensionManagementChannel implements IServerChannel { - onInstallExtension: Event; - onDidInstallExtensions: Event; - onUninstallExtension: Event; - onDidUninstallExtension: Event; + onInstallExtension: Event; + onDidInstallExtensions: Event; + onUninstallExtension: Event; + onDidUninstallExtension: Event; - constructor(private service: IServerExtensionManagementService, private getUriTransformer: (requestContext: any) => IURITransformer | null) { + constructor(private service: IExtensionManagementService, private getUriTransformer: (requestContext: any) => IURITransformer | null) { this.onInstallExtension = Event.buffer(service.onInstallExtension, true); this.onDidInstallExtensions = Event.buffer(service.onDidInstallExtensions, true); this.onUninstallExtension = Event.buffer(service.onUninstallExtension, true); @@ -85,24 +85,24 @@ export class ExtensionManagementChannelClient extends Disposable implements IExt declare readonly _serviceBrand: undefined; - private readonly _onInstallExtension = this._register(new Emitter()); + private readonly _onInstallExtension = this._register(new Emitter()); get onInstallExtension() { return this._onInstallExtension.event; } - private readonly _onDidInstallExtensions = this._register(new Emitter()); + private readonly _onDidInstallExtensions = this._register(new Emitter()); get onDidInstallExtensions() { return this._onDidInstallExtensions.event; } - private readonly _onUninstallExtension = this._register(new Emitter()); + private readonly _onUninstallExtension = this._register(new Emitter()); get onUninstallExtension() { return this._onUninstallExtension.event; } - private readonly _onDidUninstallExtension = this._register(new Emitter()); + private readonly _onDidUninstallExtension = this._register(new Emitter()); get onDidUninstallExtension() { return this._onDidUninstallExtension.event; } constructor(private readonly channel: IChannel) { super(); - this._register(this.channel.listen('onInstallExtension')(e => this._onInstallExtension.fire({ identifier: e.identifier, source: this.isUriComponents(e.source) ? URI.revive(e.source) : e.source, profileLocation: URI.revive(e.profileLocation) }))); - this._register(this.channel.listen('onDidInstallExtensions')(results => this._onDidInstallExtensions.fire(results.map(e => ({ ...e, local: e.local ? transformIncomingExtension(e.local, null) : e.local, source: this.isUriComponents(e.source) ? URI.revive(e.source) : e.source, profileLocation: URI.revive(e.profileLocation) }))))); - this._register(this.channel.listen('onUninstallExtension')(e => this._onUninstallExtension.fire({ identifier: e.identifier, profileLocation: URI.revive(e.profileLocation) }))); - this._register(this.channel.listen('onDidUninstallExtension')(e => this._onDidUninstallExtension.fire({ ...e, profileLocation: URI.revive(e.profileLocation) }))); + this._register(this.channel.listen('onInstallExtension')(e => this._onInstallExtension.fire({ identifier: e.identifier, source: this.isUriComponents(e.source) ? URI.revive(e.source) : e.source, profileLocation: URI.revive(e.profileLocation) }))); + this._register(this.channel.listen('onDidInstallExtensions')(results => this._onDidInstallExtensions.fire(results.map(e => ({ ...e, local: e.local ? transformIncomingExtension(e.local, null) : e.local, source: this.isUriComponents(e.source) ? URI.revive(e.source) : e.source, profileLocation: URI.revive(e.profileLocation) }))))); + this._register(this.channel.listen('onUninstallExtension')(e => this._onUninstallExtension.fire({ identifier: e.identifier, profileLocation: URI.revive(e.profileLocation) }))); + this._register(this.channel.listen('onDidUninstallExtension')(e => this._onDidUninstallExtension.fire({ ...e, profileLocation: URI.revive(e.profileLocation) }))); } private isUriComponents(thing: unknown): thing is UriComponents { @@ -134,7 +134,7 @@ export class ExtensionManagementChannelClient extends Disposable implements IExt return Promise.resolve(this.channel.call('unzip', [zipLocation])); } - install(vsix: URI, options?: ServerInstallVSIXOptions): Promise { + install(vsix: URI, options?: InstallVSIXOptions): Promise { return Promise.resolve(this.channel.call('install', [vsix, options])).then(local => transformIncomingExtension(local, null)); } @@ -142,11 +142,11 @@ export class ExtensionManagementChannelClient extends Disposable implements IExt return Promise.resolve(this.channel.call('getManifest', [vsix])); } - installFromGallery(extension: IGalleryExtension, installOptions?: ServerInstallOptions): Promise { + installFromGallery(extension: IGalleryExtension, installOptions?: InstallOptions): Promise { return Promise.resolve(this.channel.call('installFromGallery', [extension, installOptions])).then(local => transformIncomingExtension(local, null)); } - uninstall(extension: ILocalExtension, options?: ServerUninstallOptions): Promise { + uninstall(extension: ILocalExtension, options?: UninstallOptions): Promise { return Promise.resolve(this.channel.call('uninstall', [extension!, options])); } diff --git a/src/vs/platform/extensionManagement/node/extensionManagementService.ts b/src/vs/platform/extensionManagement/node/extensionManagementService.ts index 43714e553e07e..0dd3f11340f0e 100644 --- a/src/vs/platform/extensionManagement/node/extensionManagementService.ts +++ b/src/vs/platform/extensionManagement/node/extensionManagementService.ts @@ -24,9 +24,8 @@ import { IDownloadService } from 'vs/platform/download/common/download'; import { INativeEnvironmentService } from 'vs/platform/environment/common/environment'; import { AbstractExtensionManagementService, AbstractExtensionTask, IInstallExtensionTask, IUninstallExtensionTask, joinErrors } from 'vs/platform/extensionManagement/common/abstractExtensionManagementService'; import { - ExtensionManagementError, ExtensionManagementErrorCode, IExtensionGalleryService, IExtensionIdentifier, IGalleryExtension, IGalleryMetadata, ILocalExtension, InstallOperation, - IServerExtensionManagementService, - Metadata, ServerInstallOptions, ServerInstallVSIXOptions, ServerUninstallOptions + ExtensionManagementError, ExtensionManagementErrorCode, IExtensionGalleryService, IExtensionIdentifier, IExtensionManagementService, IGalleryExtension, IGalleryMetadata, ILocalExtension, InstallOperation, + Metadata, InstallOptions, InstallVSIXOptions, UninstallOptions } from 'vs/platform/extensionManagement/common/extensionManagement'; import { areSameExtensions, computeTargetPlatform, ExtensionKey, getGalleryExtensionId, groupByExtension } from 'vs/platform/extensionManagement/common/extensionManagementUtil'; import { IExtensionsProfileScannerService } from 'vs/platform/extensionManagement/common/extensionsProfileScannerService'; @@ -52,8 +51,8 @@ interface InstallableExtension { metadata?: Metadata; } -export const INativeServerExtensionManagementService = refineServiceDecorator(IServerExtensionManagementService); -export interface INativeServerExtensionManagementService extends IServerExtensionManagementService { +export const INativeServerExtensionManagementService = refineServiceDecorator(IExtensionManagementService); +export interface INativeServerExtensionManagementService extends IExtensionManagementService { readonly _serviceBrand: undefined; removeUninstalledExtensions(removeOutdated: boolean): Promise; getAllUserInstalled(): Promise; @@ -135,7 +134,7 @@ export class ExtensionManagementService extends AbstractExtensionManagementServi return this.extensionsScanner.scanUserExtensions(false); } - async install(vsix: URI, options: ServerInstallVSIXOptions = {}): Promise { + async install(vsix: URI, options: InstallVSIXOptions = {}): Promise { this.logService.trace('ExtensionManagementService#install', vsix.toString()); const { location, cleanup } = await this.downloadVsix(vsix); @@ -196,7 +195,7 @@ export class ExtensionManagementService extends AbstractExtensionManagementServi return { location, cleanup }; } - protected doCreateInstallExtensionTask(manifest: IExtensionManifest, extension: URI | IGalleryExtension, options: ServerInstallOptions & ServerInstallVSIXOptions): IInstallExtensionTask { + protected doCreateInstallExtensionTask(manifest: IExtensionManifest, extension: URI | IGalleryExtension, options: InstallOptions & InstallVSIXOptions): IInstallExtensionTask { let installExtensionTask: IInstallExtensionTask | undefined; if (URI.isUri(extension)) { installExtensionTask = new InstallVSIXTask(manifest, extension, options, this.galleryService, this.extensionsScanner, this.logService); @@ -214,7 +213,7 @@ export class ExtensionManagementService extends AbstractExtensionManagementServi return installExtensionTask; } - protected doCreateUninstallExtensionTask(extension: ILocalExtension, options: ServerUninstallOptions): IUninstallExtensionTask { + protected doCreateUninstallExtensionTask(extension: ILocalExtension, options: UninstallOptions): IUninstallExtensionTask { if (options.profileLocation) { return new UninstallExtensionFromProfileTask(extension, options.profileLocation, this.extensionsProfileScannerService); } @@ -536,7 +535,7 @@ abstract class InstallExtensionTask extends AbstractExtensionTask<{ local: ILoca constructor( readonly identifier: IExtensionIdentifier, readonly source: URI | IGalleryExtension, - protected readonly options: ServerInstallOptions, + protected readonly options: InstallOptions, protected readonly extensionsScanner: ExtensionsScanner, protected readonly logService: ILogService, ) { @@ -591,7 +590,7 @@ class InstallGalleryExtensionTask extends InstallExtensionTask { constructor( private readonly manifest: IExtensionManifest, private readonly gallery: IGalleryExtension, - options: ServerInstallOptions, + options: InstallOptions, private readonly extensionsDownloader: ExtensionsDownloader, extensionsScanner: ExtensionsScanner, logService: ILogService, @@ -676,7 +675,7 @@ class InstallVSIXTask extends InstallExtensionTask { constructor( private readonly manifest: IExtensionManifest, private readonly location: URI, - options: ServerInstallOptions, + options: InstallOptions, private readonly galleryService: IExtensionGalleryService, extensionsScanner: ExtensionsScanner, logService: ILogService, @@ -783,7 +782,7 @@ class UninstallExtensionTask extends AbstractExtensionTask implements IUni constructor( readonly extension: ILocalExtension, - private readonly options: ServerUninstallOptions, + private readonly options: UninstallOptions, private readonly extensionsScanner: ExtensionsScanner, ) { super(); diff --git a/src/vs/workbench/contrib/extensions/browser/extensionsWorkbenchService.ts b/src/vs/workbench/contrib/extensions/browser/extensionsWorkbenchService.ts index 81bf4b28d5b87..26f45b2ed19d3 100644 --- a/src/vs/workbench/contrib/extensions/browser/extensionsWorkbenchService.ts +++ b/src/vs/workbench/contrib/extensions/browser/extensionsWorkbenchService.ts @@ -440,7 +440,7 @@ class Extensions extends Disposable { this._register(server.extensionManagementService.onDidInstallExtensions(e => this.onDidInstallExtensions(e))); this._register(server.extensionManagementService.onUninstallExtension(e => this.onUninstallExtension(e.identifier))); this._register(server.extensionManagementService.onDidUninstallExtension(e => this.onDidUninstallExtension(e))); - this._register(server.extensionManagementService.onDidChangeProfileExtensions(e => this.onDidChangeProfileExtensions(e.added, e.removed))); + this._register(server.extensionManagementService.onDidChangeProfile(e => this.onDidChangeProfile(e.added, e.removed))); this._register(extensionEnablementService.onEnablementChanged(e => this.onEnablementChanged(e))); } @@ -560,7 +560,7 @@ class Extensions extends Disposable { } } - private async onDidChangeProfileExtensions(added: ILocalExtension[], removed: ILocalExtension[]): Promise { + private async onDidChangeProfile(added: ILocalExtension[], removed: ILocalExtension[]): Promise { const extensionsControlManifest = await this.server.extensionManagementService.getExtensionsControlManifest(); for (const addedExtension of added) { if (this.installed.find(e => areSameExtensions(e.identifier, addedExtension.identifier))) { diff --git a/src/vs/workbench/contrib/extensions/test/electron-browser/extensionsActions.test.ts b/src/vs/workbench/contrib/extensions/test/electron-browser/extensionsActions.test.ts index 5b8e51532eda9..88ab0d5b4d6a4 100644 --- a/src/vs/workbench/contrib/extensions/test/electron-browser/extensionsActions.test.ts +++ b/src/vs/workbench/contrib/extensions/test/electron-browser/extensionsActions.test.ts @@ -2425,7 +2425,7 @@ function createExtensionManagementService(installed: ILocalExtension[] = []): IP onDidInstallExtensions: Event.None, onUninstallExtension: Event.None, onDidUninstallExtension: Event.None, - onDidChangeProfileExtensions: Event.None, + onDidChangeProfile: Event.None, getInstalled: () => Promise.resolve(installed), canInstall: async (extension: IGalleryExtension) => { return true; }, installFromGallery: (extension: IGalleryExtension) => Promise.reject(new Error('not supported')), diff --git a/src/vs/workbench/contrib/extensions/test/electron-browser/extensionsWorkbenchService.test.ts b/src/vs/workbench/contrib/extensions/test/electron-browser/extensionsWorkbenchService.test.ts index f2aa03a1782d7..582deae193e65 100644 --- a/src/vs/workbench/contrib/extensions/test/electron-browser/extensionsWorkbenchService.test.ts +++ b/src/vs/workbench/contrib/extensions/test/electron-browser/extensionsWorkbenchService.test.ts @@ -1479,7 +1479,7 @@ suite('ExtensionsWorkbenchServiceTest', () => { onDidInstallExtensions: Event.None, onUninstallExtension: Event.None, onDidUninstallExtension: Event.None, - onDidChangeProfileExtensions: Event.None, + onDidChangeProfile: Event.None, getInstalled: () => Promise.resolve(installed), installFromGallery: (extension: IGalleryExtension) => Promise.reject(new Error('not supported')), updateMetadata: async (local: ILocalExtension, metadata: IGalleryMetadata) => { diff --git a/src/vs/workbench/services/extensionManagement/browser/extensionEnablementService.ts b/src/vs/workbench/services/extensionManagement/browser/extensionEnablementService.ts index 8993ddc797b4a..3c350eae2d8ed 100644 --- a/src/vs/workbench/services/extensionManagement/browser/extensionEnablementService.ts +++ b/src/vs/workbench/services/extensionManagement/browser/extensionEnablementService.ts @@ -687,7 +687,7 @@ class ExtensionsManager extends Disposable { } this._register(this.extensionManagementService.onDidInstallExtensions(e => this.onDidInstallExtensions(e.reduce((result, { local, operation }) => { if (local && operation !== InstallOperation.Migrate) { result.push(local); } return result; }, [])))); this._register(Event.filter(this.extensionManagementService.onDidUninstallExtension, (e => !e.error))(e => this.onDidUninstallExtensions([e.identifier], e.server))); - this._register(this.extensionManagementService.onDidChangeProfileExtensions(({ added, removed, server }) => { this.onDidInstallExtensions(added); this.onDidUninstallExtensions(removed.map(({ identifier }) => identifier), server); })); + this._register(this.extensionManagementService.onDidChangeProfile(({ added, removed, server }) => { this.onDidInstallExtensions(added); this.onDidUninstallExtensions(removed.map(({ identifier }) => identifier), server); })); } private onDidInstallExtensions(extensions: IExtension[]): void { diff --git a/src/vs/workbench/services/extensionManagement/common/extensionManagement.ts b/src/vs/workbench/services/extensionManagement/common/extensionManagement.ts index 1cad71d1c3aa0..34d4367b5252c 100644 --- a/src/vs/workbench/services/extensionManagement/common/extensionManagement.ts +++ b/src/vs/workbench/services/extensionManagement/common/extensionManagement.ts @@ -10,10 +10,15 @@ import { IExtensionManagementService, IGalleryExtension, ILocalExtension, Instal import { URI } from 'vs/base/common/uri'; import { FileAccess } from 'vs/base/common/network'; -export type DidChangeProfileExtensionsEvent = { readonly added: ILocalExtension[]; readonly removed: ILocalExtension[] }; +export type DidChangeProfileEvent = { readonly added: ILocalExtension[]; readonly removed: ILocalExtension[] }; +export const IProfileAwareExtensionManagementService = refineServiceDecorator(IExtensionManagementService); export interface IProfileAwareExtensionManagementService extends IExtensionManagementService { - readonly onDidChangeProfileExtensions: Event; + readonly onProfileAwareInstallExtension: Event; + readonly onProfileAwareDidInstallExtensions: Event; + readonly onProfileAwareUninstallExtension: Event; + readonly onProfileAwareDidUninstallExtension: Event; + readonly onDidChangeProfile: Event; } export interface IExtensionManagementServer { @@ -43,17 +48,21 @@ export const DefaultIconPath = FileAccess.asBrowserUri('./media/defaultIcon.png' export type InstallExtensionOnServerEvent = InstallExtensionEvent & { server: IExtensionManagementServer }; export type UninstallExtensionOnServerEvent = UninstallExtensionEvent & { server: IExtensionManagementServer }; export type DidUninstallExtensionOnServerEvent = DidUninstallExtensionEvent & { server: IExtensionManagementServer }; -export type DidChangeProfileExtensionsOnServerEvent = DidChangeProfileExtensionsEvent & { server: IExtensionManagementServer }; +export type DidChangeProfileForServerEvent = DidChangeProfileEvent & { server: IExtensionManagementServer }; -export const IWorkbenchExtensionManagementService = refineServiceDecorator(IExtensionManagementService); -export interface IWorkbenchExtensionManagementService extends IExtensionManagementService { +export const IWorkbenchExtensionManagementService = refineServiceDecorator(IProfileAwareExtensionManagementService); +export interface IWorkbenchExtensionManagementService extends IProfileAwareExtensionManagementService { readonly _serviceBrand: undefined; onInstallExtension: Event; onDidInstallExtensions: Event; onUninstallExtension: Event; onDidUninstallExtension: Event; - onDidChangeProfileExtensions: Event; + onProfileAwareInstallExtension: Event; + onProfileAwareDidInstallExtensions: Event; + onProfileAwareUninstallExtension: Event; + onProfileAwareDidUninstallExtension: Event; + onDidChangeProfile: Event; installVSIX(location: URI, manifest: IExtensionManifest, installOptions?: InstallVSIXOptions): Promise; installWebExtension(location: URI): Promise; diff --git a/src/vs/workbench/services/extensionManagement/common/extensionManagementServerService.ts b/src/vs/workbench/services/extensionManagement/common/extensionManagementServerService.ts index 9b4274a29fa48..4db3f9b85cc30 100644 --- a/src/vs/workbench/services/extensionManagement/common/extensionManagementServerService.ts +++ b/src/vs/workbench/services/extensionManagement/common/extensionManagementServerService.ts @@ -4,7 +4,7 @@ *--------------------------------------------------------------------------------------------*/ import { localize } from 'vs/nls'; -import { ExtensionInstallLocation, IExtensionManagementServer, IExtensionManagementServerService } from 'vs/workbench/services/extensionManagement/common/extensionManagement'; +import { ExtensionInstallLocation, IExtensionManagementServer, IExtensionManagementServerService, IProfileAwareExtensionManagementService } from 'vs/workbench/services/extensionManagement/common/extensionManagement'; import { IRemoteAgentService } from 'vs/workbench/services/remote/common/remoteAgentService'; import { Schemas } from 'vs/base/common/network'; import { Event } from 'vs/base/common/event'; @@ -32,8 +32,12 @@ export class ExtensionManagementServerService implements IExtensionManagementSer ) { const remoteAgentConnection = remoteAgentService.getConnection(); if (remoteAgentConnection) { - const extensionManagementService = new class extends ExtensionManagementChannelClient { - readonly onDidChangeProfileExtensions = Event.None; + const extensionManagementService = new class extends ExtensionManagementChannelClient implements IProfileAwareExtensionManagementService { + get onProfileAwareInstallExtension() { return super.onInstallExtension; } + get onProfileAwareDidInstallExtensions() { return super.onDidInstallExtensions; } + get onProfileAwareUninstallExtension() { return super.onUninstallExtension; } + get onProfileAwareDidUninstallExtension() { return super.onDidUninstallExtension; } + readonly onDidChangeProfile = Event.None; }(remoteAgentConnection.getChannel('extensions')); this.remoteExtensionManagementServer = { id: 'remote', diff --git a/src/vs/workbench/services/extensionManagement/common/extensionManagementService.ts b/src/vs/workbench/services/extensionManagement/common/extensionManagementService.ts index 1205ab9b412ff..e4955cb1fa300 100644 --- a/src/vs/workbench/services/extensionManagement/common/extensionManagementService.ts +++ b/src/vs/workbench/services/extensionManagement/common/extensionManagementService.ts @@ -7,7 +7,7 @@ import { Event, EventMultiplexer } from 'vs/base/common/event'; import { ILocalExtension, IGalleryExtension, IExtensionIdentifier, IExtensionsControlManifest, IGalleryMetadata, IExtensionGalleryService, InstallOptions, UninstallOptions, InstallVSIXOptions, InstallExtensionResult, ExtensionManagementError, ExtensionManagementErrorCode, Metadata } from 'vs/platform/extensionManagement/common/extensionManagement'; -import { DidChangeProfileExtensionsOnServerEvent, DidUninstallExtensionOnServerEvent, IExtensionManagementServer, IExtensionManagementServerService, InstallExtensionOnServerEvent, IWorkbenchExtensionManagementService, UninstallExtensionOnServerEvent } from 'vs/workbench/services/extensionManagement/common/extensionManagement'; +import { DidChangeProfileForServerEvent, DidUninstallExtensionOnServerEvent, IExtensionManagementServer, IExtensionManagementServerService, InstallExtensionOnServerEvent, IWorkbenchExtensionManagementService, UninstallExtensionOnServerEvent } from 'vs/workbench/services/extensionManagement/common/extensionManagement'; import { ExtensionType, isLanguagePackExtension, IExtensionManifest, getWorkspaceSupportTypeMessage, TargetPlatform } from 'vs/platform/extensions/common/extensions'; import { URI } from 'vs/base/common/uri'; import { Disposable } from 'vs/base/common/lifecycle'; @@ -40,7 +40,11 @@ export class ExtensionManagementService extends Disposable implements IWorkbench readonly onDidInstallExtensions: Event; readonly onUninstallExtension: Event; readonly onDidUninstallExtension: Event; - readonly onDidChangeProfileExtensions: Event; + readonly onProfileAwareInstallExtension: Event; + readonly onProfileAwareDidInstallExtensions: Event; + readonly onProfileAwareUninstallExtension: Event; + readonly onProfileAwareDidUninstallExtension: Event; + readonly onDidChangeProfile: Event; protected readonly servers: IExtensionManagementServer[] = []; @@ -73,7 +77,11 @@ export class ExtensionManagementService extends Disposable implements IWorkbench this.onDidInstallExtensions = this._register(this.servers.reduce((emitter: EventMultiplexer, server) => { emitter.add(server.extensionManagementService.onDidInstallExtensions); return emitter; }, new EventMultiplexer())).event; this.onUninstallExtension = this._register(this.servers.reduce((emitter: EventMultiplexer, server) => { emitter.add(Event.map(server.extensionManagementService.onUninstallExtension, e => ({ ...e, server }))); return emitter; }, new EventMultiplexer())).event; this.onDidUninstallExtension = this._register(this.servers.reduce((emitter: EventMultiplexer, server) => { emitter.add(Event.map(server.extensionManagementService.onDidUninstallExtension, e => ({ ...e, server }))); return emitter; }, new EventMultiplexer())).event; - this.onDidChangeProfileExtensions = this._register(this.servers.reduce((emitter: EventMultiplexer, server) => { emitter.add(Event.map(server.extensionManagementService.onDidChangeProfileExtensions, e => ({ ...e, server }))); return emitter; }, new EventMultiplexer())).event; + this.onProfileAwareInstallExtension = this._register(this.servers.reduce((emitter: EventMultiplexer, server) => { emitter.add(Event.map(server.extensionManagementService.onProfileAwareInstallExtension, e => ({ ...e, server }))); return emitter; }, new EventMultiplexer())).event; + this.onProfileAwareDidInstallExtensions = this._register(this.servers.reduce((emitter: EventMultiplexer, server) => { emitter.add(server.extensionManagementService.onProfileAwareDidInstallExtensions); return emitter; }, new EventMultiplexer())).event; + this.onProfileAwareUninstallExtension = this._register(this.servers.reduce((emitter: EventMultiplexer, server) => { emitter.add(Event.map(server.extensionManagementService.onProfileAwareUninstallExtension, e => ({ ...e, server }))); return emitter; }, new EventMultiplexer())).event; + this.onProfileAwareDidUninstallExtension = this._register(this.servers.reduce((emitter: EventMultiplexer, server) => { emitter.add(Event.map(server.extensionManagementService.onProfileAwareDidUninstallExtension, e => ({ ...e, server }))); return emitter; }, new EventMultiplexer())).event; + this.onDidChangeProfile = this._register(this.servers.reduce((emitter: EventMultiplexer, server) => { emitter.add(Event.map(server.extensionManagementService.onDidChangeProfile, e => ({ ...e, server }))); return emitter; }, new EventMultiplexer())).event; } async getInstalled(type?: ExtensionType): Promise { diff --git a/src/vs/workbench/services/extensionManagement/common/webExtensionManagementService.ts b/src/vs/workbench/services/extensionManagement/common/webExtensionManagementService.ts index a35c50b1cd281..a19ff1b42f919 100644 --- a/src/vs/workbench/services/extensionManagement/common/webExtensionManagementService.ts +++ b/src/vs/workbench/services/extensionManagement/common/webExtensionManagementService.ts @@ -4,7 +4,7 @@ *--------------------------------------------------------------------------------------------*/ import { ExtensionIdentifier, ExtensionType, IExtension, IExtensionIdentifier, IExtensionManifest, TargetPlatform } from 'vs/platform/extensions/common/extensions'; -import { ILocalExtension, IGalleryExtension, IGalleryMetadata, InstallOperation, IExtensionGalleryService, Metadata, ServerInstallOptions, ServerUninstallOptions, IServerExtensionManagementService } from 'vs/platform/extensionManagement/common/extensionManagement'; +import { ILocalExtension, IGalleryExtension, IGalleryMetadata, InstallOperation, IExtensionGalleryService, Metadata, InstallOptions, UninstallOptions } from 'vs/platform/extensionManagement/common/extensionManagement'; import { URI } from 'vs/base/common/uri'; import { Emitter } from 'vs/base/common/event'; import { areSameExtensions, getGalleryExtensionId } from 'vs/platform/extensionManagement/common/extensionManagementUtil'; @@ -21,12 +21,17 @@ import { delta } from 'vs/base/common/arrays'; import { compare } from 'vs/base/common/strings'; import { IUserDataProfilesService } from 'vs/platform/userDataProfile/common/userDataProfile'; -export class WebExtensionManagementService extends AbstractExtensionManagementService implements IProfileAwareExtensionManagementService, IServerExtensionManagementService { +export class WebExtensionManagementService extends AbstractExtensionManagementService implements IProfileAwareExtensionManagementService { declare readonly _serviceBrand: undefined; - private readonly _onDidChangeProfileExtensions = this._register(new Emitter<{ readonly added: ILocalExtension[]; readonly removed: ILocalExtension[] }>()); - readonly onDidChangeProfileExtensions = this._onDidChangeProfileExtensions.event; + get onProfileAwareInstallExtension() { return super.onInstallExtension; } + get onProfileAwareDidInstallExtensions() { return super.onDidInstallExtensions; } + get onProfileAwareUninstallExtension() { return super.onUninstallExtension; } + get onProfileAwareDidUninstallExtension() { return super.onDidUninstallExtension; } + + private readonly _onDidChangeProfile = this._register(new Emitter<{ readonly added: ILocalExtension[]; readonly removed: ILocalExtension[] }>()); + readonly onDidChangeProfile = this._onDidChangeProfile.event; constructor( @IExtensionGalleryService extensionGalleryService: IExtensionGalleryService, @@ -69,7 +74,7 @@ export class WebExtensionManagementService extends AbstractExtensionManagementSe return Promise.all(extensions.map(e => toLocalExtension(e))); } - async install(location: URI, options: ServerInstallOptions = {}): Promise { + async install(location: URI, options: InstallOptions = {}): Promise { this.logService.trace('ExtensionManagementService#install', location.toString()); const manifest = await this.webExtensionsScannerService.scanExtensionManifest(location); if (!manifest) { @@ -102,14 +107,14 @@ export class WebExtensionManagementService extends AbstractExtensionManagementSe return local; } - protected doCreateInstallExtensionTask(manifest: IExtensionManifest, extension: URI | IGalleryExtension, options: ServerInstallOptions): IInstallExtensionTask { + protected doCreateInstallExtensionTask(manifest: IExtensionManifest, extension: URI | IGalleryExtension, options: InstallOptions): IInstallExtensionTask { if (!options.profileLocation) { options = { ...options, profileLocation: this.userDataProfileService.currentProfile.extensionsResource }; } return new InstallExtensionTask(manifest, extension, options, this.webExtensionsScannerService); } - protected doCreateUninstallExtensionTask(extension: ILocalExtension, options: ServerUninstallOptions): IUninstallExtensionTask { + protected doCreateUninstallExtensionTask(extension: ILocalExtension, options: UninstallOptions): IUninstallExtensionTask { if (!options.profileLocation) { options = { ...options, profileLocation: this.userDataProfileService.currentProfile.extensionsResource }; } @@ -134,7 +139,7 @@ export class WebExtensionManagementService extends AbstractExtensionManagementSe const newExtensions = await this.webExtensionsScannerService.scanUserExtensions(currentProfileLocation); const { added, removed } = delta(oldExtensions, newExtensions, (a, b) => compare(`${ExtensionIdentifier.toKey(a.identifier.id)}@${a.manifest.version}`, `${ExtensionIdentifier.toKey(b.identifier.id)}@${b.manifest.version}`)); if (added.length || removed.length) { - this._onDidChangeProfileExtensions.fire({ added: added.map(e => toLocalExtension(e)), removed: removed.map(e => toLocalExtension(e)) }); + this._onDidChangeProfile.fire({ added: added.map(e => toLocalExtension(e)), removed: removed.map(e => toLocalExtension(e)) }); } } } @@ -157,7 +162,7 @@ function toLocalExtension(extension: IExtension): ILocalExtension { }; } -function getMetadata(options?: ServerInstallOptions, existingExtension?: IExtension): Metadata { +function getMetadata(options?: InstallOptions, existingExtension?: IExtension): Metadata { const metadata: Metadata = { ...((existingExtension)?.metadata || {}) }; metadata.isMachineScoped = options?.isMachineScoped || metadata.isMachineScoped; return metadata; @@ -174,7 +179,7 @@ class InstallExtensionTask extends AbstractExtensionTask<{ local: ILocalExtensio constructor( manifest: IExtensionManifest, private readonly extension: URI | IGalleryExtension, - private readonly options: ServerInstallOptions, + private readonly options: InstallOptions, private readonly webExtensionsScannerService: IWebExtensionsScannerService, ) { super(); @@ -215,7 +220,7 @@ class UninstallExtensionTask extends AbstractExtensionTask implements IUni constructor( readonly extension: ILocalExtension, - private readonly options: ServerUninstallOptions, + private readonly options: UninstallOptions, private readonly webExtensionsScannerService: IWebExtensionsScannerService, ) { super(); diff --git a/src/vs/workbench/services/extensionManagement/electron-sandbox/nativeExtensionManagementService.ts b/src/vs/workbench/services/extensionManagement/electron-sandbox/nativeExtensionManagementService.ts index 19b2e78f08c52..3d2c557eced72 100644 --- a/src/vs/workbench/services/extensionManagement/electron-sandbox/nativeExtensionManagementService.ts +++ b/src/vs/workbench/services/extensionManagement/electron-sandbox/nativeExtensionManagementService.ts @@ -29,17 +29,24 @@ export class NativeExtensionManagementService extends ExtensionManagementChannel private readonly disposables = this._register(new DisposableStore()); - override get onInstallExtension() { return Event.filter(super.onInstallExtension, e => this.filterEvent(e), this.disposables); } + get onProfileAwareInstallExtension() { return super.onInstallExtension; } + override get onInstallExtension() { return Event.filter(this.onProfileAwareInstallExtension, e => this.filterEvent(e), this.disposables); } + + get onProfileAwareDidInstallExtensions() { return super.onDidInstallExtensions; } override get onDidInstallExtensions() { return Event.filter( - Event.map(super.onDidInstallExtensions, results => results.filter(e => this.filterEvent(e)), this.disposables), + Event.map(this.onProfileAwareDidInstallExtensions, results => results.filter(e => this.filterEvent(e)), this.disposables), results => results.length > 0, this.disposables); } - override get onUninstallExtension() { return Event.filter(super.onUninstallExtension, e => this.filterEvent(e), this.disposables); } - override get onDidUninstallExtension() { return Event.filter(super.onDidUninstallExtension, e => this.filterEvent(e), this.disposables); } - private readonly _onDidChangeProfileExtensions = this._register(new Emitter<{ readonly added: ILocalExtension[]; readonly removed: ILocalExtension[] }>()); - readonly onDidChangeProfileExtensions = this._onDidChangeProfileExtensions.event; + get onProfileAwareUninstallExtension() { return super.onUninstallExtension; } + override get onUninstallExtension() { return Event.filter(this.onProfileAwareUninstallExtension, e => this.filterEvent(e), this.disposables); } + + get onProfileAwareDidUninstallExtension() { return super.onDidUninstallExtension; } + override get onDidUninstallExtension() { return Event.filter(this.onProfileAwareDidUninstallExtension, e => this.filterEvent(e), this.disposables); } + + private readonly _onDidChangeProfile = this._register(new Emitter<{ readonly added: ILocalExtension[]; readonly removed: ILocalExtension[] }>()); + readonly onDidChangeProfile = this._onDidChangeProfile.event; constructor( channel: IChannel, @@ -110,7 +117,7 @@ export class NativeExtensionManagementService extends ExtensionManagementChannel const newExtensions = await this.getInstalled(ExtensionType.User); const { added, removed } = delta(oldExtensions, newExtensions, (a, b) => compare(`${ExtensionIdentifier.toKey(a.identifier.id)}@${a.manifest.version}`, `${ExtensionIdentifier.toKey(b.identifier.id)}@${b.manifest.version}`)); if (added.length || removed.length) { - this._onDidChangeProfileExtensions.fire({ added, removed }); + this._onDidChangeProfile.fire({ added, removed }); } } } diff --git a/src/vs/workbench/services/extensionManagement/electron-sandbox/remoteExtensionManagementService.ts b/src/vs/workbench/services/extensionManagement/electron-sandbox/remoteExtensionManagementService.ts index f5a3e5ff80f61..c2e3673df9cee 100644 --- a/src/vs/workbench/services/extensionManagement/electron-sandbox/remoteExtensionManagementService.ts +++ b/src/vs/workbench/services/extensionManagement/electron-sandbox/remoteExtensionManagementService.ts @@ -27,7 +27,11 @@ import { IFileService } from 'vs/platform/files/common/files'; export class NativeRemoteExtensionManagementService extends ExtensionManagementChannelClient implements IProfileAwareExtensionManagementService { - readonly onDidChangeProfileExtensions = Event.None; + readonly onDidChangeProfile = Event.None; + get onProfileAwareInstallExtension() { return super.onInstallExtension; } + get onProfileAwareDidInstallExtensions() { return super.onDidInstallExtensions; } + get onProfileAwareUninstallExtension() { return super.onUninstallExtension; } + get onProfileAwareDidUninstallExtension() { return super.onDidUninstallExtension; } constructor( channel: IChannel, diff --git a/src/vs/workbench/services/extensionManagement/test/browser/extensionEnablementService.test.ts b/src/vs/workbench/services/extensionManagement/test/browser/extensionEnablementService.test.ts index 1bfaa725a8aa6..8e8c6678cfcce 100644 --- a/src/vs/workbench/services/extensionManagement/test/browser/extensionEnablementService.test.ts +++ b/src/vs/workbench/services/extensionManagement/test/browser/extensionEnablementService.test.ts @@ -5,7 +5,7 @@ import * as assert from 'assert'; import * as sinon from 'sinon'; import { IExtensionManagementService, DidUninstallExtensionEvent, ILocalExtension, InstallExtensionEvent, InstallExtensionResult, UninstallExtensionEvent } from 'vs/platform/extensionManagement/common/extensionManagement'; -import { IWorkbenchExtensionEnablementService, EnablementState, IExtensionManagementServerService, IExtensionManagementServer, IWorkbenchExtensionManagementService, ExtensionInstallLocation, IProfileAwareExtensionManagementService, DidChangeProfileExtensionsEvent } from 'vs/workbench/services/extensionManagement/common/extensionManagement'; +import { IWorkbenchExtensionEnablementService, EnablementState, IExtensionManagementServerService, IExtensionManagementServer, IWorkbenchExtensionManagementService, ExtensionInstallLocation, IProfileAwareExtensionManagementService, DidChangeProfileEvent } from 'vs/workbench/services/extensionManagement/common/extensionManagement'; import { ExtensionEnablementService } from 'vs/workbench/services/extensionManagement/browser/extensionEnablementService'; import { TestInstantiationService } from 'vs/platform/instantiation/test/common/instantiationServiceMock'; import { Emitter } from 'vs/base/common/event'; @@ -64,7 +64,7 @@ export class TestExtensionEnablementService extends ExtensionEnablementService { onDidInstallExtensions: new Emitter().event, onUninstallExtension: new Emitter().event, onDidUninstallExtension: new Emitter().event, - onDidChangeProfileExtensions: new Emitter().event, + onDidChangeProfile: new Emitter().event, }, }, null, null)); const extensionManagementService = instantiationService.createInstance(ExtensionManagementService); @@ -117,7 +117,7 @@ suite('ExtensionEnablementService Test', () => { const didInstallEvent = new Emitter(); const didUninstallEvent = new Emitter(); - const didChangeProfileExtensionsEvent = new Emitter(); + const didChangeProfileExtensionsEvent = new Emitter(); const installed: ILocalExtension[] = []; setup(() => { @@ -130,7 +130,7 @@ suite('ExtensionEnablementService Test', () => { extensionManagementService: { onDidInstallExtensions: didInstallEvent.event, onDidUninstallExtension: didUninstallEvent.event, - onDidChangeProfileExtensions: didChangeProfileExtensionsEvent.event, + onDidChangeProfile: didChangeProfileExtensionsEvent.event, getInstalled: () => Promise.resolve(installed) }, }, null, null)); diff --git a/src/vs/workbench/services/extensions/common/abstractExtensionService.ts b/src/vs/workbench/services/extensions/common/abstractExtensionService.ts index 9e42970809156..c008162ce5026 100644 --- a/src/vs/workbench/services/extensions/common/abstractExtensionService.ts +++ b/src/vs/workbench/services/extensions/common/abstractExtensionService.ts @@ -236,7 +236,7 @@ export abstract class AbstractExtensionService extends Disposable implements IEx this._handleDeltaExtensions(new DeltaExtensionsQueueItem(toAdd, toRemove)); })); - this._register(this._extensionManagementService.onDidChangeProfileExtensions(({ added, removed }) => this._handleDeltaExtensions(new DeltaExtensionsQueueItem(added, removed)))); + this._register(this._extensionManagementService.onDidChangeProfile(({ added, removed }) => this._handleDeltaExtensions(new DeltaExtensionsQueueItem(added, removed)))); this._register(this._extensionManagementService.onDidInstallExtensions((result) => { const extensions: IExtension[] = []; diff --git a/src/vs/workbench/test/browser/workbenchTestServices.ts b/src/vs/workbench/test/browser/workbenchTestServices.ts index 0e58d24ed2349..db57273f3d368 100644 --- a/src/vs/workbench/test/browser/workbenchTestServices.ts +++ b/src/vs/workbench/test/browser/workbenchTestServices.ts @@ -1953,7 +1953,11 @@ export class TestWorkbenchExtensionManagementService implements IWorkbenchExtens onDidInstallExtensions = Event.None; onUninstallExtension = Event.None; onDidUninstallExtension = Event.None; - onDidChangeProfileExtensions = Event.None; + onProfileAwareInstallExtension = Event.None; + onProfileAwareDidInstallExtensions = Event.None; + onProfileAwareUninstallExtension = Event.None; + onProfileAwareDidUninstallExtension = Event.None; + onDidChangeProfile = Event.None; installVSIX(location: URI, manifest: Readonly, installOptions?: InstallVSIXOptions | undefined): Promise { throw new Error('Method not implemented.'); } From d31d259fdcb04c9e8daa4f1b661c092c0eb3cdb3 Mon Sep 17 00:00:00 2001 From: Sandeep Somavarapu Date: Wed, 7 Sep 2022 15:48:05 +0200 Subject: [PATCH 2/2] fix tests --- .../experiments/test/electron-browser/experimentService.test.ts | 2 +- .../electron-browser/extensionRecommendationsService.test.ts | 2 +- .../extensions/test/electron-browser/extensionsActions.test.ts | 2 +- .../extensions/test/electron-browser/extensionsViews.test.ts | 2 +- .../test/electron-browser/extensionsWorkbenchService.test.ts | 2 +- src/vs/workbench/test/browser/workbenchTestServices.ts | 2 +- 6 files changed, 6 insertions(+), 6 deletions(-) diff --git a/src/vs/workbench/contrib/experiments/test/electron-browser/experimentService.test.ts b/src/vs/workbench/contrib/experiments/test/electron-browser/experimentService.test.ts index 2388b7ee9e051..afcabba3826d8 100644 --- a/src/vs/workbench/contrib/experiments/test/electron-browser/experimentService.test.ts +++ b/src/vs/workbench/contrib/experiments/test/electron-browser/experimentService.test.ts @@ -89,7 +89,7 @@ suite('Experiment Service', () => { instantiationService.stub(IWorkbenchExtensionManagementService, 'onDidInstallExtensions', didInstallEvent.event); instantiationService.stub(IWorkbenchExtensionManagementService, 'onUninstallExtension', uninstallEvent.event); instantiationService.stub(IWorkbenchExtensionManagementService, 'onDidUninstallExtension', didUninstallEvent.event); - instantiationService.stub(IWorkbenchExtensionManagementService, 'onDidChangeProfileExtensions', Event.None); + instantiationService.stub(IWorkbenchExtensionManagementService, 'onDidChangeProfile', Event.None); instantiationService.stub(IWorkbenchExtensionEnablementService, new TestExtensionEnablementService(instantiationService)); instantiationService.stub(ITelemetryService, NullTelemetryService); instantiationService.stub(IURLService, NativeURLService); diff --git a/src/vs/workbench/contrib/extensions/test/electron-browser/extensionRecommendationsService.test.ts b/src/vs/workbench/contrib/extensions/test/electron-browser/extensionRecommendationsService.test.ts index d9176de598a83..e7f9aabc4ce64 100644 --- a/src/vs/workbench/contrib/extensions/test/electron-browser/extensionRecommendationsService.test.ts +++ b/src/vs/workbench/contrib/extensions/test/electron-browser/extensionRecommendationsService.test.ts @@ -216,7 +216,7 @@ suite('ExtensionRecommendationsService Test', () => { onDidInstallExtensions: didInstallEvent.event, onUninstallExtension: uninstallEvent.event, onDidUninstallExtension: didUninstallEvent.event, - onDidChangeProfileExtensions: Event.None, + onDidChangeProfile: Event.None, async getInstalled() { return []; }, async canInstall() { return true; }, async getExtensionsControlManifest() { return { malicious: [], deprecated: {} }; }, diff --git a/src/vs/workbench/contrib/extensions/test/electron-browser/extensionsActions.test.ts b/src/vs/workbench/contrib/extensions/test/electron-browser/extensionsActions.test.ts index 88ab0d5b4d6a4..0d52cc8679a9e 100644 --- a/src/vs/workbench/contrib/extensions/test/electron-browser/extensionsActions.test.ts +++ b/src/vs/workbench/contrib/extensions/test/electron-browser/extensionsActions.test.ts @@ -99,7 +99,7 @@ async function setupTest() { onDidInstallExtensions: didInstallEvent.event, onUninstallExtension: uninstallEvent.event, onDidUninstallExtension: didUninstallEvent.event, - onDidChangeProfileExtensions: Event.None, + onDidChangeProfile: Event.None, async getInstalled() { return []; }, async getExtensionsControlManifest() { return { malicious: [], deprecated: {} }; }, async updateMetadata(local: ILocalExtension, metadata: IGalleryMetadata) { diff --git a/src/vs/workbench/contrib/extensions/test/electron-browser/extensionsViews.test.ts b/src/vs/workbench/contrib/extensions/test/electron-browser/extensionsViews.test.ts index 8eeb60477c406..9d665e5b9347d 100644 --- a/src/vs/workbench/contrib/extensions/test/electron-browser/extensionsViews.test.ts +++ b/src/vs/workbench/contrib/extensions/test/electron-browser/extensionsViews.test.ts @@ -96,7 +96,7 @@ suite('ExtensionsListView Tests', () => { onDidInstallExtensions: didInstallEvent.event, onUninstallExtension: uninstallEvent.event, onDidUninstallExtension: didUninstallEvent.event, - onDidChangeProfileExtensions: Event.None, + onDidChangeProfile: Event.None, async getInstalled() { return []; }, async canInstall() { return true; }, async getExtensionsControlManifest() { return { malicious: [], deprecated: {} }; }, diff --git a/src/vs/workbench/contrib/extensions/test/electron-browser/extensionsWorkbenchService.test.ts b/src/vs/workbench/contrib/extensions/test/electron-browser/extensionsWorkbenchService.test.ts index 582deae193e65..2a1da960c2221 100644 --- a/src/vs/workbench/contrib/extensions/test/electron-browser/extensionsWorkbenchService.test.ts +++ b/src/vs/workbench/contrib/extensions/test/electron-browser/extensionsWorkbenchService.test.ts @@ -94,7 +94,7 @@ suite('ExtensionsWorkbenchServiceTest', () => { onDidInstallExtensions: didInstallEvent.event, onUninstallExtension: uninstallEvent.event, onDidUninstallExtension: didUninstallEvent.event, - onDidChangeProfileExtensions: Event.None, + onDidChangeProfile: Event.None, async getInstalled() { return []; }, async getExtensionsControlManifest() { return { malicious: [], deprecated: {} }; }, async updateMetadata(local: ILocalExtension, metadata: IGalleryMetadata) { diff --git a/src/vs/workbench/test/browser/workbenchTestServices.ts b/src/vs/workbench/test/browser/workbenchTestServices.ts index db57273f3d368..e0465423c62cf 100644 --- a/src/vs/workbench/test/browser/workbenchTestServices.ts +++ b/src/vs/workbench/test/browser/workbenchTestServices.ts @@ -2016,7 +2016,7 @@ export class TestUserDataProfileService implements IUserDataProfileService { export class TestWebExtensionsScannerService implements IWebExtensionsScannerService { _serviceBrand: undefined; - onDidChangeProfileExtensions = Event.None; + onDidChangeProfile = Event.None; async scanSystemExtensions(): Promise { return []; } async scanUserExtensions(): Promise { return []; } async scanExtensionsUnderDevelopment(): Promise { return []; }