Skip to content

Commit 2d23c42

Browse files
authored
Merge pull request microsoft#128112 from microsoft/sandy081/1.58/fix128088
Bulk install event for python extensions
2 parents 62fddf3 + df338a7 commit 2d23c42

File tree

6 files changed

+42
-8
lines changed

6 files changed

+42
-8
lines changed

src/vs/platform/extensionManagement/common/extensionManagement.ts

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -185,6 +185,7 @@ export interface DidInstallExtensionEvent {
185185
gallery?: IGalleryExtension;
186186
local?: ILocalExtension;
187187
error?: string;
188+
isBulkInstall?: boolean;
188189
}
189190

190191
export interface DidUninstallExtensionEvent {
@@ -213,6 +214,7 @@ export interface IExtensionManagementService {
213214

214215
onInstallExtension: Event<InstallExtensionEvent>;
215216
onDidInstallExtension: Event<DidInstallExtensionEvent>;
217+
onDidInstallExtensions: Event<DidInstallExtensionEvent[]>;
216218
onUninstallExtension: Event<IExtensionIdentifier>;
217219
onDidUninstallExtension: Event<DidUninstallExtensionEvent>;
218220

src/vs/platform/extensionManagement/common/extensionManagementIpc.ts

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -35,12 +35,14 @@ export class ExtensionManagementChannel implements IServerChannel {
3535

3636
onInstallExtension: Event<InstallExtensionEvent>;
3737
onDidInstallExtension: Event<DidInstallExtensionEvent>;
38+
onDidInstallExtensions: Event<DidInstallExtensionEvent[]>;
3839
onUninstallExtension: Event<IExtensionIdentifier>;
3940
onDidUninstallExtension: Event<DidUninstallExtensionEvent>;
4041

4142
constructor(private service: IExtensionManagementService, private getUriTransformer: (requestContext: any) => IURITransformer | null) {
4243
this.onInstallExtension = Event.buffer(service.onInstallExtension, true);
4344
this.onDidInstallExtension = Event.buffer(service.onDidInstallExtension, true);
45+
this.onDidInstallExtensions = Event.buffer(service.onDidInstallExtensions, true);
4446
this.onUninstallExtension = Event.buffer(service.onUninstallExtension, true);
4547
this.onDidUninstallExtension = Event.buffer(service.onDidUninstallExtension, true);
4648
}
@@ -50,6 +52,7 @@ export class ExtensionManagementChannel implements IServerChannel {
5052
switch (event) {
5153
case 'onInstallExtension': return this.onInstallExtension;
5254
case 'onDidInstallExtension': return Event.map(this.onDidInstallExtension, i => ({ ...i, local: i.local ? transformOutgoingExtension(i.local, uriTransformer) : i.local }));
55+
case 'onDidInstallExtensions': return Event.map(this.onDidInstallExtensions, i => i.map(e => ({ ...e, local: e.local ? transformOutgoingExtension(e.local, uriTransformer) : e.local })));
5356
case 'onUninstallExtension': return this.onUninstallExtension;
5457
case 'onDidUninstallExtension': return this.onDidUninstallExtension;
5558
}
@@ -88,6 +91,9 @@ export class ExtensionManagementChannelClient extends Disposable implements IExt
8891
private readonly _onDidInstallExtension = this._register(new Emitter<DidInstallExtensionEvent>());
8992
readonly onDidInstallExtension = this._onDidInstallExtension.event;
9093

94+
private readonly _onDidInstallExtensions = this._register(new Emitter<DidInstallExtensionEvent[]>());
95+
readonly onDidInstallExtensions = this._onDidInstallExtensions.event;
96+
9197
private readonly _onUninstallExtension = this._register(new Emitter<IExtensionIdentifier>());
9298
readonly onUninstallExtension = this._onUninstallExtension.event;
9399

@@ -100,6 +106,7 @@ export class ExtensionManagementChannelClient extends Disposable implements IExt
100106
super();
101107
this._register(this.channel.listen<InstallExtensionEvent>('onInstallExtension')(e => this._onInstallExtension.fire(e)));
102108
this._register(this.channel.listen<DidInstallExtensionEvent>('onDidInstallExtension')(e => this._onDidInstallExtension.fire({ ...e, local: e.local ? transformIncomingExtension(e.local, null) : e.local })));
109+
this._register(this.channel.listen<DidInstallExtensionEvent[]>('onDidInstallExtensions')(e => this._onDidInstallExtensions.fire(e.map(event => ({ ...event, local: event.local ? transformIncomingExtension(event.local, null) : event.local })))));
103110
this._register(this.channel.listen<IExtensionIdentifier>('onUninstallExtension')(e => this._onUninstallExtension.fire(e)));
104111
this._register(this.channel.listen<DidUninstallExtensionEvent>('onDidUninstallExtension')(e => this._onDidUninstallExtension.fire(e)));
105112
}

src/vs/platform/extensionManagement/node/extensionManagementService.ts

Lines changed: 14 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -91,6 +91,9 @@ export class ExtensionManagementService extends Disposable implements IExtension
9191
private readonly _onDidInstallExtension = this._register(new Emitter<DidInstallExtensionEvent>());
9292
readonly onDidInstallExtension: Event<DidInstallExtensionEvent> = this._onDidInstallExtension.event;
9393

94+
private readonly _onDidInstallExtensions = this._register(new Emitter<DidInstallExtensionEvent[]>());
95+
readonly onDidInstallExtensions = this._onDidInstallExtensions.event;
96+
9497
private readonly _onUninstallExtension = this._register(new Emitter<IExtensionIdentifier>());
9598
readonly onUninstallExtension: Event<IExtensionIdentifier> = this._onUninstallExtension.event;
9699

@@ -294,12 +297,13 @@ export class ExtensionManagementService extends Disposable implements IExtension
294297
this.logService.info('Extensions is already requested to install', extension.identifier.id);
295298
return (await installExtensionTask.resultPromise).local;
296299
} else {
297-
installExtensionTask = this.createInstallFromGalleryExtensionTask(extension, options);
298-
return (await this.runInstallGalleryExtensionTask(installExtensionTask, options)).local;
300+
const isBulkInstall = ['ms-python.python', 'ms-python.vscode-pylance'].includes(extension.identifier.id.toLowerCase());
301+
installExtensionTask = this.createInstallFromGalleryExtensionTask(extension, options, isBulkInstall);
302+
return (await this.runInstallGalleryExtensionTask(installExtensionTask, options, isBulkInstall)).local;
299303
}
300304
}
301305

302-
private createInstallFromGalleryExtensionTask(extension: IGalleryExtension, options: InstallOptions): InstallExtensionTask {
306+
private createInstallFromGalleryExtensionTask(extension: IGalleryExtension, options: InstallOptions, isBulkInstall: boolean): InstallExtensionTask {
303307
const key = new ExtensionIdentifierWithVersion(extension.identifier, extension.version).key();
304308
this._onInstallExtension.fire({ identifier: extension.identifier, gallery: extension });
305309
this.logService.info('Installing extension:', extension.identifier.id);
@@ -315,7 +319,7 @@ export class ExtensionManagementService extends Disposable implements IExtension
315319
try {
316320
const result = await this.installGalleryExtension(extension, options, token);
317321
this.logService.info(`Extensions installed successfully:`, extension.identifier.id);
318-
this._onDidInstallExtension.fire({ identifier: extension.identifier, gallery: result.gallery, local: result.local, operation: result.operation });
322+
this._onDidInstallExtension.fire({ identifier: extension.identifier, gallery: result.gallery, local: result.local, operation: result.operation, isBulkInstall });
319323
return result;
320324
} catch (error) {
321325
const errorCode = error && (<ExtensionManagementError>error).code ? (<ExtensionManagementError>error).code : ERROR_UNKNOWN;
@@ -344,7 +348,7 @@ export class ExtensionManagementService extends Disposable implements IExtension
344348
return installExtensionTask;
345349
}
346350

347-
private async runInstallGalleryExtensionTask(installExtensionTask: InstallExtensionTask, options: InstallOptions): Promise<InstallResult> {
351+
private async runInstallGalleryExtensionTask(installExtensionTask: InstallExtensionTask, options: InstallOptions, isBulkInstall: boolean): Promise<InstallResult> {
348352
if (options.donotIncludePackAndDependencies) {
349353
this.logService.info('Installing the extension without checking dependencies and pack', installExtensionTask.extension.identifier.id);
350354
return installExtensionTask.run();
@@ -369,7 +373,7 @@ export class ExtensionManagementService extends Disposable implements IExtension
369373
if (this.installingExtensions.has(new ExtensionIdentifierWithVersion(gallery.identifier, gallery.version).key())) {
370374
this.logService.info('Extension is already requested to install', gallery.identifier.id);
371375
} else {
372-
const task = this.createInstallFromGalleryExtensionTask(gallery, { ...options, donotIncludePackAndDependencies: true });
376+
const task = this.createInstallFromGalleryExtensionTask(gallery, { ...options, donotIncludePackAndDependencies: true }, isBulkInstall);
373377
extensionsToInstallMap.set(gallery.identifier.id.toLowerCase(), { task, manifest });
374378
}
375379
}
@@ -405,6 +409,10 @@ export class ExtensionManagementService extends Disposable implements IExtension
405409
installExtensionTask.cancel();
406410
}
407411
throw error;
412+
} finally {
413+
if (installResults.length && isBulkInstall) {
414+
this._onDidInstallExtensions.fire(installResults.map(({ gallery, local, operation }) => ({ identifier: local.identifier, gallery, local, operation })));
415+
}
408416
}
409417

410418
}

src/vs/workbench/services/extensionManagement/common/extensionManagementService.ts

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,7 @@
55

66
import { Event, EventMultiplexer } from 'vs/base/common/event';
77
import {
8-
ILocalExtension, IGalleryExtension, IExtensionIdentifier, IReportedExtension, IGalleryMetadata, IExtensionGalleryService, InstallOptions, UninstallOptions, INSTALL_ERROR_NOT_SUPPORTED, InstallVSIXOptions
8+
ILocalExtension, IGalleryExtension, IExtensionIdentifier, IReportedExtension, IGalleryMetadata, IExtensionGalleryService, InstallOptions, UninstallOptions, INSTALL_ERROR_NOT_SUPPORTED, InstallVSIXOptions, DidInstallExtensionEvent
99
} from 'vs/platform/extensionManagement/common/extensionManagement';
1010
import { DidInstallExtensionOnServerEvent, DidUninstallExtensionOnServerEvent, IExtensionManagementServer, IExtensionManagementServerService, InstallExtensionOnServerEvent, IWorkbenchExtensionManagementService, UninstallExtensionOnServerEvent } from 'vs/workbench/services/extensionManagement/common/extensionManagement';
1111
import { ExtensionType, isLanguagePackExtension, IExtensionManifest } from 'vs/platform/extensions/common/extensions';
@@ -35,6 +35,7 @@ export class ExtensionManagementService extends Disposable implements IWorkbench
3535
readonly onDidInstallExtension: Event<DidInstallExtensionOnServerEvent>;
3636
readonly onUninstallExtension: Event<UninstallExtensionOnServerEvent>;
3737
readonly onDidUninstallExtension: Event<DidUninstallExtensionOnServerEvent>;
38+
readonly onDidInstallExtensions: Event<DidInstallExtensionEvent[]>;
3839

3940
protected readonly servers: IExtensionManagementServer[] = [];
4041

@@ -63,6 +64,7 @@ export class ExtensionManagementService extends Disposable implements IWorkbench
6364

6465
this.onInstallExtension = this._register(this.servers.reduce((emitter: EventMultiplexer<InstallExtensionOnServerEvent>, server) => { emitter.add(Event.map(server.extensionManagementService.onInstallExtension, e => ({ ...e, server }))); return emitter; }, new EventMultiplexer<InstallExtensionOnServerEvent>())).event;
6566
this.onDidInstallExtension = this._register(this.servers.reduce((emitter: EventMultiplexer<DidInstallExtensionOnServerEvent>, server) => { emitter.add(Event.map(server.extensionManagementService.onDidInstallExtension, e => ({ ...e, server }))); return emitter; }, new EventMultiplexer<DidInstallExtensionOnServerEvent>())).event;
67+
this.onDidInstallExtensions = this._register(this.servers.reduce((emitter: EventMultiplexer<DidInstallExtensionEvent[]>, server) => { emitter.add(server.extensionManagementService.onDidInstallExtensions); return emitter; }, new EventMultiplexer<DidInstallExtensionEvent[]>())).event;
6668
this.onUninstallExtension = this._register(this.servers.reduce((emitter: EventMultiplexer<UninstallExtensionOnServerEvent>, server) => { emitter.add(Event.map(server.extensionManagementService.onUninstallExtension, e => ({ ...e, server }))); return emitter; }, new EventMultiplexer<UninstallExtensionOnServerEvent>())).event;
6769
this.onDidUninstallExtension = this._register(this.servers.reduce((emitter: EventMultiplexer<DidUninstallExtensionOnServerEvent>, server) => { emitter.add(Event.map(server.extensionManagementService.onDidUninstallExtension, e => ({ ...e, server }))); return emitter; }, new EventMultiplexer<DidUninstallExtensionOnServerEvent>())).event;
6870
}

src/vs/workbench/services/extensionManagement/common/webExtensionManagementService.ts

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -30,6 +30,9 @@ export class WebExtensionManagementService extends Disposable implements IExtens
3030
private readonly _onDidInstallExtension = this._register(new Emitter<DidInstallExtensionEvent>());
3131
readonly onDidInstallExtension: Event<DidInstallExtensionEvent> = this._onDidInstallExtension.event;
3232

33+
private readonly _onDidInstallExtensions = this._register(new Emitter<DidInstallExtensionEvent[]>());
34+
readonly onDidInstallExtensions = this._onDidInstallExtensions.event;
35+
3336
private readonly _onUninstallExtension = this._register(new Emitter<IExtensionIdentifier>());
3437
readonly onUninstallExtension: Event<IExtensionIdentifier> = this._onUninstallExtension.event;
3538

src/vs/workbench/services/extensions/common/abstractExtensionService.ts

Lines changed: 13 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -222,14 +222,26 @@ export abstract class AbstractExtensionService extends Disposable implements IEx
222222
}));
223223

224224
this._register(this._extensionManagementService.onDidInstallExtension((event) => {
225-
if (event.local) {
225+
if (event.local && !event.isBulkInstall) {
226226
if (this._safeInvokeIsEnabled(event.local)) {
227227
// an extension has been installed
228228
this._handleDeltaExtensions(new DeltaExtensionsQueueItem([event.local], []));
229229
}
230230
}
231231
}));
232232

233+
this._register(this._extensionManagementService.onDidInstallExtensions((events) => {
234+
const extensions: IExtension[] = [];
235+
for (const { local } of events) {
236+
if (local && this._safeInvokeIsEnabled(local)) {
237+
extensions.push(local);
238+
}
239+
}
240+
if (extensions.length) {
241+
this._handleDeltaExtensions(new DeltaExtensionsQueueItem(extensions, []));
242+
}
243+
}));
244+
233245
this._register(this._extensionManagementService.onDidUninstallExtension((event) => {
234246
if (!event.error) {
235247
// an extension has been uninstalled

0 commit comments

Comments
 (0)