From bc50babf3cd98c85010a05a659777944ffefdb63 Mon Sep 17 00:00:00 2001 From: Sandeep Somavarapu Date: Thu, 23 Jun 2022 23:55:51 +0200 Subject: filter extension management events per profile (#153036) --- .../common/abstractExtensionManagementService.ts | 44 ++++++++++------------ .../common/extensionManagement.ts | 16 +++++++- .../common/extensionManagementIpc.ts | 34 ++++++++--------- .../node/extensionManagementService.ts | 15 +++++--- .../browser/extensionsWorkbenchService.ts | 2 +- .../extensionRecommendationsService.test.ts | 6 +-- .../electron-browser/extensionsActions.test.ts | 40 ++++++++++---------- .../test/electron-browser/extensionsViews.test.ts | 6 +-- .../extensionsWorkbenchService.test.ts | 14 +++---- .../common/extensionManagement.ts | 4 +- .../profileAwareExtensionManagementService.ts | 18 ++++++++- .../common/webExtensionManagementService.ts | 1 + .../browser/extensionEnablementService.test.ts | 6 +-- 13 files changed, 119 insertions(+), 87 deletions(-) (limited to 'src') diff --git a/src/vs/platform/extensionManagement/common/abstractExtensionManagementService.ts b/src/vs/platform/extensionManagement/common/abstractExtensionManagementService.ts index c9b27a68de8..99d049079ed 100644 --- a/src/vs/platform/extensionManagement/common/abstractExtensionManagementService.ts +++ b/src/vs/platform/extensionManagement/common/abstractExtensionManagementService.ts @@ -7,18 +7,18 @@ import { isNonEmptyArray } from 'vs/base/common/arrays'; import { Barrier, CancelablePromise, createCancelablePromise } from 'vs/base/common/async'; import { CancellationToken } from 'vs/base/common/cancellation'; import { CancellationError, getErrorMessage } from 'vs/base/common/errors'; -import { Emitter, Event } from 'vs/base/common/event'; +import { Emitter } from 'vs/base/common/event'; import { Disposable, toDisposable } from 'vs/base/common/lifecycle'; import { isWeb } from 'vs/base/common/platform'; import { URI } from 'vs/base/common/uri'; import * as nls from 'vs/nls'; import { - DidUninstallExtensionEvent, ExtensionManagementError, IExtensionGalleryService, IExtensionIdentifier, IExtensionManagementParticipant, IGalleryExtension, IGalleryMetadata, ILocalExtension, InstallExtensionEvent, InstallExtensionResult, InstallOperation, - IExtensionsControlManifest, StatisticType, isTargetPlatformCompatible, TargetPlatformToString, ExtensionManagementErrorCode, IServerExtensionManagementService, ServerInstallOptions, ServerInstallVSIXOptions, ServerUninstallOptions, Metadata + ExtensionManagementError, IExtensionGalleryService, IExtensionIdentifier, IExtensionManagementParticipant, IGalleryExtension, IGalleryMetadata, ILocalExtension, InstallOperation, + IExtensionsControlManifest, StatisticType, isTargetPlatformCompatible, TargetPlatformToString, ExtensionManagementErrorCode, IServerExtensionManagementService, ServerInstallOptions, ServerInstallVSIXOptions, ServerUninstallOptions, Metadata, ServerInstallExtensionEvent, ServerInstallExtensionResult, ServerUninstallExtensionEvent, ServerDidUninstallExtensionEvent } from 'vs/platform/extensionManagement/common/extensionManagement'; import { areSameExtensions, ExtensionKey, getGalleryExtensionTelemetryData, getLocalExtensionTelemetryData, getMaliciousExtensionsSet } from 'vs/platform/extensionManagement/common/extensionManagementUtil'; import { IExtensionsProfileScannerService } from 'vs/platform/extensionManagement/common/extensionsProfileScannerService'; -import { ExtensionType, IExtensionManifest, isApplicationScopedExtension, TargetPlatform } from 'vs/platform/extensions/common/extensions'; +import { ExtensionType, IExtensionManifest, TargetPlatform } from 'vs/platform/extensions/common/extensions'; import { ILogService } from 'vs/platform/log/common/log'; import { IProductService } from 'vs/platform/product/common/productService'; import { ITelemetryService } from 'vs/platform/telemetry/common/telemetry'; @@ -52,17 +52,17 @@ export abstract class AbstractExtensionManagementService extends Disposable impl private readonly installingExtensions = new Map(); private readonly uninstallingExtensions = new Map(); - private readonly _onInstallExtension = this._register(new Emitter()); - readonly onInstallExtension: Event = this._onInstallExtension.event; + 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()); - readonly onUninstallExtension: Event = this._onUninstallExtension.event; + protected readonly _onUninstallExtension = this._register(new Emitter()); + readonly onUninstallExtension = this._onUninstallExtension.event; - protected _onDidUninstallExtension = this._register(new Emitter()); - onDidUninstallExtension: Event = this._onDidUninstallExtension.event; + protected _onDidUninstallExtension = this._register(new Emitter()); + readonly onDidUninstallExtension = this._onDidUninstallExtension.event; private readonly participants: IExtensionManagementParticipant[] = []; @@ -154,12 +154,12 @@ export abstract class AbstractExtensionManagementService extends Disposable impl } const allInstallExtensionTasks: { task: IInstallExtensionTask; manifest: IExtensionManifest }[] = []; - const installResults: (InstallExtensionResult & { local: ILocalExtension })[] = []; + const installResults: (ServerInstallExtensionResult & { local: ILocalExtension })[] = []; const installExtensionTask = this.createInstallExtensionTask(manifest, extension, options); if (!URI.isUri(extension)) { this.installingExtensions.set(ExtensionKey.create(extension).toString(), installExtensionTask); } - this._onInstallExtension.fire({ identifier: installExtensionTask.identifier, source: extension }); + this._onInstallExtension.fire({ identifier: installExtensionTask.identifier, source: extension, profileLocation: options.profileLocation }); this.logService.info('Installing extension:', installExtensionTask.identifier.id); allInstallExtensionTasks.push({ task: installExtensionTask, manifest }); let installExtensionHasDependents: boolean = false; @@ -178,7 +178,7 @@ export abstract class AbstractExtensionManagementService extends Disposable impl } else { const task = this.createInstallExtensionTask(manifest, gallery, { ...options, donotIncludePackAndDependencies: true }); this.installingExtensions.set(key, task); - this._onInstallExtension.fire({ identifier: task.identifier, source: gallery }); + this._onInstallExtension.fire({ identifier: task.identifier, source: gallery, profileLocation: options.profileLocation }); this.logService.info('Installing extension:', task.identifier.id); allInstallExtensionTasks.push({ task, manifest }); } @@ -237,7 +237,7 @@ export abstract class AbstractExtensionManagementService extends Disposable impl } catch (error) { /* ignore */ } } } - installResults.push({ local, identifier: task.identifier, operation: task.operation, source: task.source, context: options.context }); + installResults.push({ local, identifier: task.identifier, operation: task.operation, source: task.source, context: options.context, profileLocation: options.profileLocation, applicationScoped: local.isApplicationScoped }); } catch (error) { if (!URI.isUri(task.source)) { reportTelemetry(this.telemetryService, task.operation === InstallOperation.Update ? 'extensionGallery:update' : 'extensionGallery:install', { extensionData: getGalleryExtensionTelemetryData(task.source), duration: new Date().getTime() - startTime, error }); @@ -276,7 +276,7 @@ export abstract class AbstractExtensionManagementService extends Disposable impl } } - this._onDidInstallExtensions.fire(allInstallExtensionTasks.map(({ task }) => ({ identifier: task.identifier, operation: InstallOperation.Install, source: task.source, context: options.context }))); + this._onDidInstallExtensions.fire(allInstallExtensionTasks.map(({ task }) => ({ identifier: task.identifier, operation: InstallOperation.Install, source: task.source, context: options.context, profileLocation: options.profileLocation }))); throw error; } finally { /* Remove the gallery tasks from the cache */ @@ -438,7 +438,7 @@ export abstract class AbstractExtensionManagementService extends Disposable impl const uninstallExtensionTask = this.createUninstallExtensionTask(extension, uninstallOptions, options.profileLocation); this.uninstallingExtensions.set(uninstallExtensionTask.extension.identifier.id.toLowerCase(), uninstallExtensionTask); this.logService.info('Uninstalling extension:', extension.identifier.id); - this._onUninstallExtension.fire(extension.identifier); + this._onUninstallExtension.fire({ identifier: extension.identifier, profileLocation: options.profileLocation, applicationScoped: extension.isApplicationScoped }); return uninstallExtensionTask; }; @@ -449,7 +449,7 @@ export abstract class AbstractExtensionManagementService extends Disposable impl this.logService.info('Successfully uninstalled extension:', extension.identifier.id); } reportTelemetry(this.telemetryService, 'extensionGallery:uninstall', { extensionData: getLocalExtensionTelemetryData(extension), error }); - this._onDidUninstallExtension.fire({ identifier: extension.identifier, error: error?.code }); + this._onDidUninstallExtension.fire({ identifier: extension.identifier, error: error?.code, profileLocation: options.profileLocation, applicationScoped: extension.isApplicationScoped }); }; const allTasks: IUninstallExtensionTask[] = []; @@ -740,11 +740,7 @@ class InstallExtensionInProfileTask implements IInstallExtensionTask { private async waitAndAddExtensionToProfile(): Promise<{ local: ILocalExtension; metadata: Metadata }> { const result = await this.task.waitUntilTaskIsFinished(); - let profileLocation = this.profileLocation; - if (isApplicationScopedExtension(result.local.manifest)) { - profileLocation = this.defaultProfileLocation; - result.metadata = { ...result.metadata, isApplicationScoped: true }; - } + const profileLocation = result.local.isApplicationScoped ? this.defaultProfileLocation : this.profileLocation; await this.extensionsProfileScannerService.addExtensionsToProfile([[result.local, result.metadata]], profileLocation); return result; } @@ -777,7 +773,7 @@ class UninstallExtensionFromProfileTask extends AbstractExtensionTask impl protected async doRun(token: CancellationToken): Promise { const promises: Promise[] = []; promises.push(this.extensionsProfileScannerService.removeExtensionFromProfile(this.extension.identifier, this.profileLocation)); - if (isApplicationScopedExtension(this.extension.manifest) && this.userDataProfilesService.defaultProfile.extensionsResource) { + if (this.extension.isApplicationScoped && this.userDataProfilesService.defaultProfile.extensionsResource) { promises.push(this.extensionsProfileScannerService.removeExtensionFromProfile(this.extension.identifier, this.userDataProfilesService.defaultProfile.extensionsResource)); } await Promise.all(promises); diff --git a/src/vs/platform/extensionManagement/common/extensionManagement.ts b/src/vs/platform/extensionManagement/common/extensionManagement.ts index 3d3e0bf3db8..4e376a1a4c8 100644 --- a/src/vs/platform/extensionManagement/common/extensionManagement.ts +++ b/src/vs/platform/extensionManagement/common/extensionManagement.ts @@ -242,6 +242,7 @@ export type Metadata = Partial; } +export interface UninstallExtensionEvent { + identifier: IExtensionIdentifier; +} + export interface DidUninstallExtensionEvent { identifier: IExtensionIdentifier; error?: string; @@ -411,7 +416,7 @@ export interface IExtensionManagementService { onInstallExtension: Event; onDidInstallExtensions: Event; - onUninstallExtension: Event; + onUninstallExtension: Event; onDidUninstallExtension: Event; zip(extension: ILocalExtension): Promise; @@ -433,6 +438,11 @@ 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 }; @@ -440,6 +450,10 @@ 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; diff --git a/src/vs/platform/extensionManagement/common/extensionManagementIpc.ts b/src/vs/platform/extensionManagement/common/extensionManagementIpc.ts index 894841a4a4b..9636a4291b3 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 { DidUninstallExtensionEvent, IExtensionIdentifier, IExtensionManagementService, IExtensionTipsService, IGalleryExtension, IGalleryMetadata, ILocalExtension, InstallExtensionEvent, InstallExtensionResult, IExtensionsControlManifest, isTargetPlatformCompatible, IServerExtensionManagementService, ServerInstallOptions, ServerInstallVSIXOptions, ServerUninstallOptions, Metadata } from 'vs/platform/extensionManagement/common/extensionManagement'; +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 { ExtensionType, IExtensionManifest, TargetPlatform } from 'vs/platform/extensions/common/extensions'; function transformIncomingURI(uri: UriComponents, transformer: IURITransformer | null): URI { @@ -34,10 +34,10 @@ 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) { this.onInstallExtension = Event.buffer(service.onInstallExtension, true); @@ -85,24 +85,24 @@ export class ExtensionManagementChannelClient extends Disposable implements IExt declare readonly _serviceBrand: undefined; - private readonly _onInstallExtension = this._register(new Emitter()); - readonly onInstallExtension = this._onInstallExtension.event; + private readonly _onInstallExtension = this._register(new Emitter()); + get onInstallExtension() { return this._onInstallExtension.event; } - private readonly _onDidInstallExtensions = this._register(new Emitter()); - readonly onDidInstallExtensions = this._onDidInstallExtensions.event; + private readonly _onDidInstallExtensions = this._register(new Emitter()); + get onDidInstallExtensions() { return this._onDidInstallExtensions.event; } - private readonly _onUninstallExtension = this._register(new Emitter()); - readonly onUninstallExtension = this._onUninstallExtension.event; + private readonly _onUninstallExtension = this._register(new Emitter()); + get onUninstallExtension() { return this._onUninstallExtension.event; } - private readonly _onDidUninstallExtension = this._register(new Emitter()); - readonly onDidUninstallExtension = this._onDidUninstallExtension.event; + 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 }))); - 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 }))))); - this._register(this.channel.listen('onUninstallExtension')(e => this._onUninstallExtension.fire(e))); - this._register(this.channel.listen('onDidUninstallExtension')(e => this._onDidUninstallExtension.fire(e))); + 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 { diff --git a/src/vs/platform/extensionManagement/node/extensionManagementService.ts b/src/vs/platform/extensionManagement/node/extensionManagementService.ts index e220416bffd..4c2d6a47d6b 100644 --- a/src/vs/platform/extensionManagement/node/extensionManagementService.ts +++ b/src/vs/platform/extensionManagement/node/extensionManagementService.ts @@ -25,7 +25,7 @@ import { INativeEnvironmentService } from 'vs/platform/environment/common/enviro import { AbstractExtensionManagementService, AbstractExtensionTask, IInstallExtensionTask, IUninstallExtensionTask, joinErrors, UninstallExtensionTaskOptions } from 'vs/platform/extensionManagement/common/abstractExtensionManagementService'; import { ExtensionManagementError, ExtensionManagementErrorCode, IExtensionGalleryService, IExtensionIdentifier, IGalleryExtension, IGalleryMetadata, ILocalExtension, InstallOperation, - IServerExtensionManagementService, Metadata, ServerInstallOptions, ServerInstallVSIXOptions + Metadata, ServerInstallOptions, ServerInstallVSIXOptions } 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'; @@ -35,7 +35,7 @@ import { ExtensionsLifecycle } from 'vs/platform/extensionManagement/node/extens import { getManifest } from 'vs/platform/extensionManagement/node/extensionManagementUtil'; import { ExtensionsManifestCache } from 'vs/platform/extensionManagement/node/extensionsManifestCache'; import { ExtensionsWatcher } from 'vs/platform/extensionManagement/node/extensionsWatcher'; -import { ExtensionType, IExtensionManifest, TargetPlatform } from 'vs/platform/extensions/common/extensions'; +import { ExtensionType, IExtensionManifest, isApplicationScopedExtension, TargetPlatform } from 'vs/platform/extensions/common/extensions'; import { isEngineValid } from 'vs/platform/extensions/common/extensionValidator'; import { IFileService } from 'vs/platform/files/common/files'; import { IInstantiationService } from 'vs/platform/instantiation/common/instantiation'; @@ -51,7 +51,7 @@ interface InstallableExtension { metadata?: Metadata; } -export class ExtensionManagementService extends AbstractExtensionManagementService implements IServerExtensionManagementService { +export class ExtensionManagementService extends AbstractExtensionManagementService { private readonly extensionsScanner: ExtensionsScanner; private readonly manifestCache: ExtensionsManifestCache; @@ -165,7 +165,7 @@ export class ExtensionManagementService extends AbstractExtensionManagementServi } protected createDefaultInstallExtensionTask(manifest: IExtensionManifest, extension: URI | IGalleryExtension, options: ServerInstallOptions & ServerInstallVSIXOptions): IInstallExtensionTask { - return URI.isUri(extension) ? new InstallVSIXTask(manifest, extension, options, this.galleryService, this.extensionsScanner, this.logService) : new InstallGalleryExtensionTask(extension, options, this.extensionsDownloader, this.extensionsScanner, this.logService); + return URI.isUri(extension) ? new InstallVSIXTask(manifest, extension, options, this.galleryService, this.extensionsScanner, this.logService) : new InstallGalleryExtensionTask(manifest, extension, options, this.extensionsDownloader, this.extensionsScanner, this.logService); } protected createDefaultUninstallExtensionTask(extension: ILocalExtension, options: UninstallExtensionTaskOptions): IUninstallExtensionTask { @@ -406,6 +406,7 @@ class ExtensionsScanner extends Disposable { changelogUrl, publisherDisplayName: extension.metadata?.publisherDisplayName || null, publisherId: extension.metadata?.publisherId || null, + isApplicationScoped: !!extension.metadata?.isApplicationScoped, isMachineScoped: !!extension.metadata?.isMachineScoped, isPreReleaseVersion: !!extension.metadata?.isPreReleaseVersion, preRelease: !!extension.metadata?.preRelease, @@ -537,6 +538,7 @@ abstract class InstallExtensionTask extends AbstractExtensionTask<{ local: ILoca class InstallGalleryExtensionTask extends InstallExtensionTask { constructor( + private readonly manifest: IExtensionManifest, private readonly gallery: IGalleryExtension, options: ServerInstallOptions, private readonly extensionsDownloader: ExtensionsDownloader, @@ -559,6 +561,7 @@ class InstallGalleryExtensionTask extends InstallExtensionTask { publisherId: this.gallery.publisherId, publisherDisplayName: this.gallery.publisherDisplayName, targetPlatform: this.gallery.properties.targetPlatform, + isApplicationScoped: isApplicationScopedExtension(this.manifest), isMachineScoped: this.options.isMachineScoped || existingExtension?.isMachineScoped, isBuiltin: this.options.isBuiltin || existingExtension?.isBuiltin, isSystem: existingExtension?.type === ExtensionType.System ? true : undefined, @@ -571,7 +574,8 @@ class InstallGalleryExtensionTask extends InstallExtensionTask { }; if (existingExtension?.manifest.version === this.gallery.version) { - return { local: existingExtension, metadata }; + const local = await this.extensionsScanner.updateMetadata(existingExtension, metadata); + return { local, metadata }; } const zipPath = await this.downloadExtension(this.gallery, this._operation); @@ -634,6 +638,7 @@ class InstallVSIXTask extends InstallExtensionTask { const installedExtensions = await this.extensionsScanner.scanExtensions(ExtensionType.User, undefined); const existing = installedExtensions.find(i => areSameExtensions(this.identifier, i.identifier)); const metadata = await this.getMetadata(this.identifier.id, this.manifest.version, token); + metadata.isApplicationScoped = isApplicationScopedExtension(this.manifest); metadata.isMachineScoped = this.options.isMachineScoped || existing?.isMachineScoped; metadata.isBuiltin = this.options.isBuiltin || existing?.isBuiltin; diff --git a/src/vs/workbench/contrib/extensions/browser/extensionsWorkbenchService.ts b/src/vs/workbench/contrib/extensions/browser/extensionsWorkbenchService.ts index df347fe1e84..e23dee80a2c 100644 --- a/src/vs/workbench/contrib/extensions/browser/extensionsWorkbenchService.ts +++ b/src/vs/workbench/contrib/extensions/browser/extensionsWorkbenchService.ts @@ -433,7 +433,7 @@ class Extensions extends Disposable { super(); this._register(server.extensionManagementService.onInstallExtension(e => this.onInstallExtension(e))); this._register(server.extensionManagementService.onDidInstallExtensions(e => this.onDidInstallExtensions(e))); - this._register(server.extensionManagementService.onUninstallExtension(e => this.onUninstallExtension(e))); + this._register(server.extensionManagementService.onUninstallExtension(e => this.onUninstallExtension(e.identifier))); this._register(server.extensionManagementService.onDidUninstallExtension(e => this.onDidUninstallExtension(e))); this._register(extensionEnablementService.onEnablementChanged(e => this.onEnablementChanged(e))); } 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 e17bb60de12..6040e37a790 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 @@ -8,7 +8,7 @@ import * as assert from 'assert'; import * as uuid from 'vs/base/common/uuid'; import { IExtensionGalleryService, IGalleryExtensionAssets, IGalleryExtension, IExtensionManagementService, - DidUninstallExtensionEvent, InstallExtensionEvent, IExtensionIdentifier, IExtensionTipsService, InstallExtensionResult, getTargetPlatform + DidUninstallExtensionEvent, InstallExtensionEvent, IExtensionTipsService, InstallExtensionResult, getTargetPlatform, UninstallExtensionEvent } from 'vs/platform/extensionManagement/common/extensionManagement'; import { IWorkbenchExtensionEnablementService } from 'vs/workbench/services/extensionManagement/common/extensionManagement'; import { ExtensionGalleryService } from 'vs/platform/extensionManagement/common/extensionGalleryService'; @@ -191,7 +191,7 @@ suite('ExtensionRecommendationsService Test', () => { let testObject: ExtensionRecommendationsService; let installEvent: Emitter, didInstallEvent: Emitter, - uninstallEvent: Emitter, + uninstallEvent: Emitter, didUninstallEvent: Emitter; let prompted: boolean; const promptedEmitter = new Emitter(); @@ -202,7 +202,7 @@ suite('ExtensionRecommendationsService Test', () => { instantiationService = new TestInstantiationService(); installEvent = new Emitter(); didInstallEvent = new Emitter(); - uninstallEvent = new Emitter(); + uninstallEvent = new Emitter(); didUninstallEvent = new Emitter(); instantiationService.stub(IExtensionGalleryService, ExtensionGalleryService); instantiationService.stub(ISharedProcessService, TestSharedProcessService); 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 ad2e86b38ba..5b8e51532ed 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 @@ -10,7 +10,7 @@ import * as ExtensionsActions from 'vs/workbench/contrib/extensions/browser/exte import { ExtensionsWorkbenchService } from 'vs/workbench/contrib/extensions/browser/extensionsWorkbenchService'; import { IExtensionManagementService, IExtensionGalleryService, ILocalExtension, IGalleryExtension, - DidUninstallExtensionEvent, InstallExtensionEvent, IExtensionIdentifier, InstallOperation, IExtensionTipsService, IGalleryMetadata, InstallExtensionResult, getTargetPlatform, IExtensionsControlManifest + DidUninstallExtensionEvent, InstallExtensionEvent, IExtensionIdentifier, InstallOperation, IExtensionTipsService, IGalleryMetadata, InstallExtensionResult, getTargetPlatform, IExtensionsControlManifest, UninstallExtensionEvent } from 'vs/platform/extensionManagement/common/extensionManagement'; import { IWorkbenchExtensionEnablementService, EnablementState, IExtensionManagementServerService, IExtensionManagementServer, ExtensionInstallLocation, IProfileAwareExtensionManagementService } from 'vs/workbench/services/extensionManagement/common/extensionManagement'; import { IExtensionRecommendationsService } from 'vs/workbench/services/extensionRecommendations/common/extensionRecommendations'; @@ -63,7 +63,7 @@ import { arch } from 'vs/base/common/process'; let instantiationService: TestInstantiationService; let installEvent: Emitter, didInstallEvent: Emitter, - uninstallEvent: Emitter, + uninstallEvent: Emitter, didUninstallEvent: Emitter; let disposables: DisposableStore; @@ -72,7 +72,7 @@ async function setupTest() { disposables = new DisposableStore(); installEvent = new Emitter(); didInstallEvent = new Emitter(); - uninstallEvent = new Emitter(); + uninstallEvent = new Emitter(); didUninstallEvent = new Emitter(); instantiationService = new TestInstantiationService(); @@ -217,7 +217,7 @@ suite('ExtensionsActions', () => { return instantiationService.get(IExtensionsWorkbenchService).queryLocal() .then(extensions => { - uninstallEvent.fire(local.identifier); + uninstallEvent.fire({ identifier: local.identifier }); didUninstallEvent.fire({ identifier: local.identifier }); testObject.extension = extensions[0]; assert.ok(!testObject.enabled); @@ -232,7 +232,7 @@ suite('ExtensionsActions', () => { return instantiationService.get(IExtensionsWorkbenchService).queryLocal() .then(extensions => { - uninstallEvent.fire(local.identifier); + uninstallEvent.fire({ identifier: local.identifier }); didUninstallEvent.fire({ identifier: local.identifier }); testObject.extension = extensions[0]; assert.ok(!testObject.enabled); @@ -255,7 +255,7 @@ suite('ExtensionsActions', () => { return instantiationService.get(IExtensionsWorkbenchService).queryLocal() .then(extensions => { testObject.extension = extensions[0]; - uninstallEvent.fire(local.identifier); + uninstallEvent.fire({ identifier: local.identifier }); assert.ok(!testObject.enabled); assert.strictEqual('Uninstalling', testObject.label); assert.strictEqual('extension-action label uninstall uninstalling', testObject.class); @@ -518,7 +518,7 @@ suite('ExtensionsActions', () => { return instantiationService.get(IExtensionsWorkbenchService).queryLocal() .then(extensions => { testObject.extension = extensions[0]; - uninstallEvent.fire(local.identifier); + uninstallEvent.fire({ identifier: local.identifier }); assert.ok(!testObject.enabled); assert.strictEqual('extension-action icon manage codicon codicon-extensions-manage', testObject.class); @@ -737,7 +737,7 @@ suite('ExtensionsActions', () => { .then(extensions => { const testObject: ExtensionsActions.EnableDropDownAction = instantiationService.createInstance(ExtensionsActions.EnableDropDownAction); testObject.extension = extensions[0]; - uninstallEvent.fire(local.identifier); + uninstallEvent.fire({ identifier: local.identifier }); assert.ok(!testObject.enabled); }); }); @@ -900,7 +900,7 @@ suite('ExtensionsActions', () => { const testObject: ExtensionsActions.DisableGloballyAction = instantiationService.createInstance(ExtensionsActions.DisableGloballyAction, [{ identifier: new ExtensionIdentifier('pub.a'), extensionLocation: URI.file('pub.a') }]); testObject.extension = extensions[0]; instantiationService.createInstance(ExtensionContainers, [testObject]); - uninstallEvent.fire(local.identifier); + uninstallEvent.fire({ identifier: local.identifier }); assert.ok(!testObject.enabled); }); }); @@ -940,7 +940,7 @@ suite('ReloadAction', () => { const extensions = await instantiationService.get(IExtensionsWorkbenchService).queryLocal(); testObject.extension = extensions[0]; - uninstallEvent.fire(local.identifier); + uninstallEvent.fire({ identifier: local.identifier }); assert.ok(!testObject.enabled); }); @@ -1003,7 +1003,7 @@ suite('ReloadAction', () => { const identifier = gallery.identifier; installEvent.fire({ identifier, source: gallery }); didInstallEvent.fire([{ identifier, source: gallery, operation: InstallOperation.Install, local: aLocalExtension('a', gallery, { identifier }) }]); - uninstallEvent.fire(identifier); + uninstallEvent.fire({ identifier }); didUninstallEvent.fire({ identifier }); assert.ok(!testObject.enabled); @@ -1018,7 +1018,7 @@ suite('ReloadAction', () => { const extensions = await instantiationService.get(IExtensionsWorkbenchService).queryLocal(); testObject.extension = extensions[0]; - uninstallEvent.fire(local.identifier); + uninstallEvent.fire({ identifier: local.identifier }); didUninstallEvent.fire({ identifier: local.identifier }); assert.ok(testObject.enabled); assert.strictEqual(testObject.tooltip, 'Please reload Visual Studio Code to complete the uninstallation of this extension.'); @@ -1038,7 +1038,7 @@ suite('ReloadAction', () => { const extensions = await instantiationService.get(IExtensionsWorkbenchService).queryLocal(); testObject.extension = extensions[0]; - uninstallEvent.fire(local.identifier); + uninstallEvent.fire({ identifier: local.identifier }); didUninstallEvent.fire({ identifier: local.identifier }); assert.ok(!testObject.enabled); }); @@ -1052,7 +1052,7 @@ suite('ReloadAction', () => { const extensions = await instantiationService.get(IExtensionsWorkbenchService).queryLocal(); testObject.extension = extensions[0]; - uninstallEvent.fire(local.identifier); + uninstallEvent.fire({ identifier: local.identifier }); didUninstallEvent.fire({ identifier: local.identifier }); const gallery = aGalleryExtension('a'); @@ -1251,7 +1251,7 @@ suite('ReloadAction', () => { const localExtension = aLocalExtension('a', { extensionKind: ['workspace'] }, { location: URI.file('pub.a') }); const remoteExtension = aLocalExtension('a', { extensionKind: ['workspace'] }, { location: URI.file('pub.a').with({ scheme: Schemas.vscodeRemote }) }); const localExtensionManagementService = createExtensionManagementService([localExtension]); - const uninstallEvent = new Emitter(); + const uninstallEvent = new Emitter(); const onDidUninstallEvent = new Emitter<{ identifier: IExtensionIdentifier }>(); localExtensionManagementService.onUninstallExtension = uninstallEvent.event; localExtensionManagementService.onDidUninstallExtension = onDidUninstallEvent.event; @@ -1278,7 +1278,7 @@ suite('ReloadAction', () => { assert.ok(testObject.extension); assert.ok(!testObject.enabled); - uninstallEvent.fire(localExtension.identifier); + uninstallEvent.fire({ identifier: localExtension.identifier }); didUninstallEvent.fire({ identifier: localExtension.identifier }); assert.ok(!testObject.enabled); @@ -1797,7 +1797,7 @@ suite('RemoteInstallAction', () => { assert.ok(testObject.enabled); assert.strictEqual('Install in remote', testObject.label); - uninstallEvent.fire(localWorkspaceExtension.identifier); + uninstallEvent.fire({ identifier: localWorkspaceExtension.identifier }); assert.ok(!testObject.enabled); }); @@ -1941,7 +1941,7 @@ suite('RemoteInstallAction', () => { assert.ok(testObject.enabled); assert.strictEqual('Install in remote', testObject.label); - uninstallEvent.fire(languagePackExtension.identifier); + uninstallEvent.fire({ identifier: languagePackExtension.identifier }); assert.ok(!testObject.enabled); }); }); @@ -2208,7 +2208,7 @@ suite('LocalInstallAction', () => { assert.ok(testObject.enabled); assert.strictEqual('Install Locally', testObject.label); - uninstallEvent.fire(remoteUIExtension.identifier); + uninstallEvent.fire({ identifier: remoteUIExtension.identifier }); assert.ok(!testObject.enabled); }); @@ -2331,7 +2331,7 @@ suite('LocalInstallAction', () => { assert.ok(testObject.enabled); assert.strictEqual('Install Locally', testObject.label); - uninstallEvent.fire(languagePackExtension.identifier); + uninstallEvent.fire({ identifier: languagePackExtension.identifier }); assert.ok(!testObject.enabled); }); 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 f7b374b3387..8eeb60477c4 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 @@ -11,7 +11,7 @@ import { IExtensionsWorkbenchService } from 'vs/workbench/contrib/extensions/com import { ExtensionsWorkbenchService } from 'vs/workbench/contrib/extensions/browser/extensionsWorkbenchService'; import { IExtensionManagementService, IExtensionGalleryService, ILocalExtension, IGalleryExtension, IQueryOptions, - DidUninstallExtensionEvent, InstallExtensionEvent, IExtensionIdentifier, SortBy, InstallExtensionResult, getTargetPlatform, IExtensionInfo + DidUninstallExtensionEvent, InstallExtensionEvent, SortBy, InstallExtensionResult, getTargetPlatform, IExtensionInfo, UninstallExtensionEvent } from 'vs/platform/extensionManagement/common/extensionManagement'; import { IWorkbenchExtensionEnablementService, EnablementState, IExtensionManagementServerService, IExtensionManagementServer, IProfileAwareExtensionManagementService } from 'vs/workbench/services/extensionManagement/common/extensionManagement'; import { IExtensionRecommendationsService, ExtensionRecommendationReason } from 'vs/workbench/services/extensionRecommendations/common/extensionRecommendations'; @@ -54,7 +54,7 @@ suite('ExtensionsListView Tests', () => { let testableView: ExtensionsListView; let installEvent: Emitter, didInstallEvent: Emitter, - uninstallEvent: Emitter, + uninstallEvent: Emitter, didUninstallEvent: Emitter; const localEnabledTheme = aLocalExtension('first-enabled-extension', { categories: ['Themes', 'random'] }); @@ -76,7 +76,7 @@ suite('ExtensionsListView Tests', () => { suiteSetup(() => { installEvent = new Emitter(); didInstallEvent = new Emitter(); - uninstallEvent = new Emitter(); + uninstallEvent = new Emitter(); didUninstallEvent = new Emitter(); instantiationService = new TestInstantiationService(); 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 018ad78c48f..f2aa03a1782 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 @@ -11,7 +11,7 @@ import { IExtensionsWorkbenchService, ExtensionState, AutoCheckUpdatesConfigurat import { ExtensionsWorkbenchService } from 'vs/workbench/contrib/extensions/browser/extensionsWorkbenchService'; import { IExtensionManagementService, IExtensionGalleryService, ILocalExtension, IGalleryExtension, - DidUninstallExtensionEvent, InstallExtensionEvent, IGalleryExtensionAssets, IExtensionIdentifier, InstallOperation, IExtensionTipsService, IGalleryMetadata, InstallExtensionResult, getTargetPlatform, IExtensionsControlManifest + DidUninstallExtensionEvent, InstallExtensionEvent, IGalleryExtensionAssets, InstallOperation, IExtensionTipsService, IGalleryMetadata, InstallExtensionResult, getTargetPlatform, IExtensionsControlManifest, UninstallExtensionEvent } from 'vs/platform/extensionManagement/common/extensionManagement'; import { IWorkbenchExtensionEnablementService, EnablementState, IExtensionManagementServerService, IExtensionManagementServer, IProfileAwareExtensionManagementService } from 'vs/workbench/services/extensionManagement/common/extensionManagement'; import { IExtensionRecommendationsService } from 'vs/workbench/services/extensionRecommendations/common/extensionRecommendations'; @@ -59,13 +59,13 @@ suite('ExtensionsWorkbenchServiceTest', () => { let installEvent: Emitter, didInstallEvent: Emitter, - uninstallEvent: Emitter, + uninstallEvent: Emitter, didUninstallEvent: Emitter; suiteSetup(() => { installEvent = new Emitter(); didInstallEvent = new Emitter(); - uninstallEvent = new Emitter(); + uninstallEvent = new Emitter(); didUninstallEvent = new Emitter(); instantiationService = new TestInstantiationService(); @@ -386,7 +386,7 @@ suite('ExtensionsWorkbenchServiceTest', () => { testObject.uninstall(actual); // Uninstalling - uninstallEvent.fire(identifier); + uninstallEvent.fire({ identifier }); assert.strictEqual(ExtensionState.Uninstalling, actual.state); // Uninstalled @@ -413,7 +413,7 @@ suite('ExtensionsWorkbenchServiceTest', () => { testObject = await aWorkbenchService(); const target = testObject.local[0]; testObject.uninstall(target); - uninstallEvent.fire(local.identifier); + uninstallEvent.fire({ identifier: local.identifier }); didUninstallEvent.fire({ identifier: local.identifier }); assert.ok(!(await testObject.canInstall(target))); @@ -490,7 +490,7 @@ suite('ExtensionsWorkbenchServiceTest', () => { testObject.uninstall(testObject.local[0]); testObject.onChange(target); - uninstallEvent.fire(local.identifier); + uninstallEvent.fire({ identifier: local.identifier }); assert.ok(target.calledOnce); }); @@ -502,7 +502,7 @@ suite('ExtensionsWorkbenchServiceTest', () => { const target = sinon.spy(); testObject.uninstall(testObject.local[0]); - uninstallEvent.fire(local.identifier); + uninstallEvent.fire({ identifier: local.identifier }); testObject.onChange(target); didUninstallEvent.fire({ identifier: local.identifier }); diff --git a/src/vs/workbench/services/extensionManagement/common/extensionManagement.ts b/src/vs/workbench/services/extensionManagement/common/extensionManagement.ts index 66f0b79da91..5e3c46b1a5b 100644 --- a/src/vs/workbench/services/extensionManagement/common/extensionManagement.ts +++ b/src/vs/workbench/services/extensionManagement/common/extensionManagement.ts @@ -6,7 +6,7 @@ import { Event } from 'vs/base/common/event'; import { createDecorator, refineServiceDecorator } from 'vs/platform/instantiation/common/instantiation'; import { IExtension, ExtensionType, IExtensionManifest } from 'vs/platform/extensions/common/extensions'; -import { IExtensionManagementService, IGalleryExtension, IExtensionIdentifier, ILocalExtension, InstallOptions, InstallExtensionEvent, DidUninstallExtensionEvent, InstallExtensionResult, Metadata, InstallVSIXOptions } from 'vs/platform/extensionManagement/common/extensionManagement'; +import { IExtensionManagementService, IGalleryExtension, IExtensionIdentifier, ILocalExtension, InstallOptions, InstallExtensionEvent, DidUninstallExtensionEvent, InstallExtensionResult, Metadata, InstallVSIXOptions, UninstallExtensionEvent } from 'vs/platform/extensionManagement/common/extensionManagement'; import { URI } from 'vs/base/common/uri'; import { FileAccess } from 'vs/base/common/network'; @@ -42,7 +42,7 @@ export interface IExtensionManagementServerService { export const DefaultIconPath = FileAccess.asBrowserUri('./media/defaultIcon.png', require).toString(true); export type InstallExtensionOnServerEvent = InstallExtensionEvent & { server: IExtensionManagementServer }; -export type UninstallExtensionOnServerEvent = IExtensionIdentifier & { server: IExtensionManagementServer }; +export type UninstallExtensionOnServerEvent = UninstallExtensionEvent & { server: IExtensionManagementServer }; export type DidUninstallExtensionOnServerEvent = DidUninstallExtensionEvent & { server: IExtensionManagementServer }; export type DidChangeProfileExtensionsOnServerEvent = DidChangeProfileExtensionsEvent & { server: IExtensionManagementServer }; diff --git a/src/vs/workbench/services/extensionManagement/common/profileAwareExtensionManagementService.ts b/src/vs/workbench/services/extensionManagement/common/profileAwareExtensionManagementService.ts index 94d70ade4d3..291e62a8317 100644 --- a/src/vs/workbench/services/extensionManagement/common/profileAwareExtensionManagementService.ts +++ b/src/vs/workbench/services/extensionManagement/common/profileAwareExtensionManagementService.ts @@ -9,13 +9,25 @@ import { ExtensionManagementChannelClient } from 'vs/platform/extensionManagemen import { URI } from 'vs/base/common/uri'; import { IGalleryExtension, ILocalExtension, InstallOptions, InstallVSIXOptions, UninstallOptions } from 'vs/platform/extensionManagement/common/extensionManagement'; import { ExtensionIdentifier, ExtensionType } from 'vs/platform/extensions/common/extensions'; -import { Emitter } from 'vs/base/common/event'; +import { Emitter, Event } from 'vs/base/common/event'; import { IUriIdentityService } from 'vs/platform/uriIdentity/common/uriIdentity'; import { delta } from 'vs/base/common/arrays'; import { compare } from 'vs/base/common/strings'; +import { DisposableStore } from 'vs/base/common/lifecycle'; export class NativeProfileAwareExtensionManagementService extends ExtensionManagementChannelClient implements IProfileAwareExtensionManagementService { + private readonly disposables = this._register(new DisposableStore()); + + override get onInstallExtension() { return Event.filter(super.onInstallExtension, e => this.filterEvent(e), this.disposables); } + override get onDidInstallExtensions() { + return Event.filter( + Event.map(super.onDidInstallExtensions, 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; @@ -25,6 +37,10 @@ export class NativeProfileAwareExtensionManagementService extends ExtensionManag super(channel); } + private filterEvent({ profileLocation, applicationScoped }: { profileLocation?: URI; applicationScoped?: boolean }): boolean { + return applicationScoped || this.uriIdentityService.extUri.isEqual(this.extensionsProfileResource, profileLocation); + } + override install(vsix: URI, options?: InstallVSIXOptions): Promise { return super.install(vsix, { ...options, profileLocation: this.extensionsProfileResource }); } diff --git a/src/vs/workbench/services/extensionManagement/common/webExtensionManagementService.ts b/src/vs/workbench/services/extensionManagement/common/webExtensionManagementService.ts index 19a97830da7..6c1cba6e975 100644 --- a/src/vs/workbench/services/extensionManagement/common/webExtensionManagementService.ts +++ b/src/vs/workbench/services/extensionManagement/common/webExtensionManagementService.ts @@ -122,6 +122,7 @@ function toLocalExtension(extension: IExtension): ILocalExtension { ...extension, identifier: { id: extension.identifier.id, uuid: metadata.id ?? extension.identifier.uuid }, isMachineScoped: !!metadata.isMachineScoped, + isApplicationScoped: !!metadata.isApplicationScoped, publisherId: metadata.publisherId || null, publisherDisplayName: metadata.publisherDisplayName || null, installedTimestamp: metadata.installedTimestamp, 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 75247ea427d..3fc8b045751 100644 --- a/src/vs/workbench/services/extensionManagement/test/browser/extensionEnablementService.test.ts +++ b/src/vs/workbench/services/extensionManagement/test/browser/extensionEnablementService.test.ts @@ -4,7 +4,7 @@ *--------------------------------------------------------------------------------------------*/ import * as assert from 'assert'; import * as sinon from 'sinon'; -import { IExtensionManagementService, DidUninstallExtensionEvent, ILocalExtension, InstallExtensionEvent, InstallExtensionResult } from 'vs/platform/extensionManagement/common/extensionManagement'; +import { IExtensionManagementService, DidUninstallExtensionEvent, ILocalExtension, InstallExtensionEvent, InstallExtensionResult, UninstallExtensionEvent } from 'vs/platform/extensionManagement/common/extensionManagement'; import { IWorkbenchExtensionEnablementService, EnablementState, IExtensionManagementServerService, IExtensionManagementServer, IWorkbenchExtensionManagementService, ExtensionInstallLocation, IProfileAwareExtensionManagementService } 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'; @@ -12,7 +12,7 @@ import { Emitter, Event } from 'vs/base/common/event'; import { IWorkspace, IWorkspaceContextService, WorkbenchState } from 'vs/platform/workspace/common/workspace'; import { IWorkbenchEnvironmentService } from 'vs/workbench/services/environment/common/environmentService'; import { IStorageService, InMemoryStorageService } from 'vs/platform/storage/common/storage'; -import { IExtensionContributions, ExtensionType, IExtension, IExtensionManifest, IExtensionIdentifier } from 'vs/platform/extensions/common/extensions'; +import { IExtensionContributions, ExtensionType, IExtension, IExtensionManifest } from 'vs/platform/extensions/common/extensions'; import { isUndefinedOrNull } from 'vs/base/common/types'; import { areSameExtensions } from 'vs/platform/extensionManagement/common/extensionManagementUtil'; import { IConfigurationService } from 'vs/platform/configuration/common/configuration'; @@ -62,7 +62,7 @@ export class TestExtensionEnablementService extends ExtensionEnablementService { extensionManagementService: { onInstallExtension: new Emitter().event, onDidInstallExtensions: new Emitter().event, - onUninstallExtension: new Emitter().event, + onUninstallExtension: new Emitter().event, onDidUninstallExtension: new Emitter().event, }, }, null, null)); -- cgit v1.2.3