提交 2f06eb98 编写于 作者: S Sandeep Somavarapu

Fix #79116

上级 a8a448d1
......@@ -14,7 +14,7 @@ import { IPager, mapPager, singlePagePager } from 'vs/base/common/paging';
import { ITelemetryService } from 'vs/platform/telemetry/common/telemetry';
import {
IExtensionManagementService, IExtensionGalleryService, ILocalExtension, IGalleryExtension, IQueryOptions,
InstallExtensionEvent, DidInstallExtensionEvent, DidUninstallExtensionEvent, IExtensionIdentifier
InstallExtensionEvent, DidInstallExtensionEvent, DidUninstallExtensionEvent, IExtensionIdentifier, InstallOperation
} from 'vs/platform/extensionManagement/common/extensionManagement';
import { IExtensionEnablementService, EnablementState, IExtensionManagementServerService, IExtensionManagementServer } from 'vs/workbench/services/extensionManagement/common/extensionManagement';
import { getGalleryExtensionTelemetryData, getLocalExtensionTelemetryData, areSameExtensions, getMaliciousExtensionsSet, groupByExtension, ExtensionIdentifierWithVersion } from 'vs/platform/extensionManagement/common/extensionManagementUtil';
......@@ -308,8 +308,8 @@ ${this.description}
class Extensions extends Disposable {
private readonly _onChange: Emitter<Extension | undefined> = new Emitter<Extension | undefined>();
get onChange(): Event<Extension | undefined> { return this._onChange.event; }
private readonly _onChange: Emitter<{ extension: Extension, operation?: InstallOperation } | undefined> = this._register(new Emitter<{ extension: Extension, operation?: InstallOperation } | undefined>());
get onChange(): Event<{ extension: Extension, operation?: InstallOperation } | undefined> { return this._onChange.event; }
private installing: Extension[] = [];
private uninstalling: Extension[] = [];
......@@ -370,7 +370,7 @@ class Extensions extends Disposable {
const local = extension.local.metadata ? extension.local : await this.server.extensionManagementService.updateMetadata(extension.local, { id: compatible.identifier.uuid, publisherDisplayName: compatible.publisherDisplayName, publisherId: compatible.publisherId });
extension.local = local;
extension.gallery = compatible;
this._onChange.fire(extension);
this._onChange.fire({ extension });
return true;
}
return false;
......@@ -397,7 +397,7 @@ class Extensions extends Disposable {
const extension = this.installed.filter(e => areSameExtensions(e.identifier, gallery.identifier))[0]
|| this.instantiationService.createInstance(Extension, this.stateProvider, this.server, undefined, gallery);
this.installing.push(extension);
this._onChange.fire(extension);
this._onChange.fire({ extension });
}
}
......@@ -421,9 +421,10 @@ class Extensions extends Disposable {
if (!extension.gallery) {
extension.gallery = gallery;
}
extension.enablementState = this.extensionEnablementService.getEnablementState(local);
}
}
this._onChange.fire(error ? undefined : extension);
this._onChange.fire(error || !extension ? undefined : { extension, operation: event.operation });
}
private onUninstallExtension(identifier: IExtensionIdentifier): void {
......@@ -431,7 +432,7 @@ class Extensions extends Disposable {
if (extension) {
const uninstalling = this.uninstalling.filter(e => areSameExtensions(e.identifier, identifier))[0] || extension;
this.uninstalling = [uninstalling, ...this.uninstalling.filter(e => !areSameExtensions(e.identifier, identifier))];
this._onChange.fire(uninstalling);
this._onChange.fire(uninstalling ? { extension: uninstalling } : undefined);
}
}
......@@ -442,7 +443,7 @@ class Extensions extends Disposable {
const uninstalling = this.uninstalling.filter(e => areSameExtensions(e.identifier, identifier))[0];
this.uninstalling = this.uninstalling.filter(e => !areSameExtensions(e.identifier, identifier));
if (uninstalling) {
this._onChange.fire(uninstalling);
this._onChange.fire({ extension: uninstalling });
}
}
......@@ -453,7 +454,7 @@ class Extensions extends Disposable {
const enablementState = this.extensionEnablementService.getEnablementState(extension.local);
if (enablementState !== extension.enablementState) {
(extension as Extension).enablementState = enablementState;
this._onChange.fire(extension as Extension);
this._onChange.fire({ extension: extension as Extension });
}
}
}
......@@ -506,11 +507,13 @@ export class ExtensionsWorkbenchService extends Disposable implements IExtension
super();
if (this.extensionManagementServerService.localExtensionManagementServer) {
this.localExtensions = this._register(instantiationService.createInstance(Extensions, extensionManagementServerService.localExtensionManagementServer, ext => this.getExtensionState(ext)));
this._register(this.localExtensions.onChange(e => this._onChange.fire(e)));
this._register(this.localExtensions.onChange(e => this._onChange.fire(e ? e.extension : undefined)));
this._register(Event.filter(this.localExtensions.onChange, e => !!e && e.operation === InstallOperation.Install)(e => this.onDidInstallExtension(e!.extension)));
}
if (this.extensionManagementServerService.remoteExtensionManagementServer) {
this.remoteExtensions = this._register(instantiationService.createInstance(Extensions, extensionManagementServerService.remoteExtensionManagementServer, ext => this.getExtensionState(ext)));
this._register(this.remoteExtensions.onChange(e => this._onChange.fire(e)));
this._register(this.remoteExtensions.onChange(e => this._onChange.fire(e ? e.extension : undefined)));
this._register(Event.filter(this.remoteExtensions.onChange, e => !!e && e.operation === InstallOperation.Install)(e => this.onDidInstallExtension(e!.extension)));
}
this.syncDelayer = new ThrottledDelayer<void>(ExtensionsWorkbenchService.SyncPeriod);
......@@ -784,7 +787,6 @@ export class ExtensionsWorkbenchService extends Disposable implements IExtension
if (extension instanceof URI) {
return this.installWithProgress(async () => {
const { identifier } = await this.extensionService.install(extension);
this.checkAndEnableDisabledDependencies(identifier);
return this.local.filter(local => areSameExtensions(local.identifier, identifier))[0];
});
}
......@@ -801,7 +803,6 @@ export class ExtensionsWorkbenchService extends Disposable implements IExtension
return this.installWithProgress(async () => {
await this.installFromGallery(extension, gallery);
this.checkAndEnableDisabledDependencies(gallery.identifier);
return this.local.filter(local => areSameExtensions(local.identifier, gallery.identifier))[0];
}, gallery.displayName);
}
......@@ -887,15 +888,8 @@ export class ExtensionsWorkbenchService extends Disposable implements IExtension
}
}
private checkAndEnableDisabledDependencies(extensionIdentifier: IExtensionIdentifier): Promise<void> {
const extension = this.local.filter(e => (e.local || e.gallery) && areSameExtensions(extensionIdentifier, e.identifier))[0];
if (extension) {
const disabledDepencies = this.getExtensionsRecursively([extension], this.local, EnablementState.EnabledGlobally, { dependencies: true, pack: false });
if (disabledDepencies.length) {
return this.setEnablement(disabledDepencies, EnablementState.EnabledGlobally);
}
}
return Promise.resolve();
private onDidInstallExtension(extension: IExtension): void {
this.setEnablement(extension, EnablementState.EnabledGlobally);
}
private promptAndSetEnablement(extensions: IExtension[], enablementState: EnablementState): Promise<any> {
......
......@@ -942,6 +942,46 @@ suite('ExtensionsWorkbenchServiceTest', () => {
});
});
test('test installing an extension re-eanbles it when disabled globally', async () => {
testObject = await aWorkbenchService();
const local = aLocalExtension('pub.a');
await instantiationService.get(IExtensionEnablementService).setEnablement([local], EnablementState.DisabledGlobally);
didInstallEvent.fire({ local, identifier: local.identifier, operation: InstallOperation.Install });
instantiationService.stubPromise(IExtensionManagementService, 'getInstalled', [local]);
const actual = await testObject.queryLocal();
assert.equal(actual[0].enablementState, EnablementState.EnabledGlobally);
});
test('test updating an extension does not re-eanbles it when disabled globally', async () => {
testObject = await aWorkbenchService();
const local = aLocalExtension('pub.a');
await instantiationService.get(IExtensionEnablementService).setEnablement([local], EnablementState.DisabledGlobally);
didInstallEvent.fire({ local, identifier: local.identifier, operation: InstallOperation.Update });
instantiationService.stubPromise(IExtensionManagementService, 'getInstalled', [local]);
const actual = await testObject.queryLocal();
assert.equal(actual[0].enablementState, EnablementState.DisabledGlobally);
});
test('test installing an extension re-eanbles it when workspace disabled', async () => {
testObject = await aWorkbenchService();
const local = aLocalExtension('pub.a');
await instantiationService.get(IExtensionEnablementService).setEnablement([local], EnablementState.DisabledWorkspace);
didInstallEvent.fire({ local, identifier: local.identifier, operation: InstallOperation.Install });
instantiationService.stubPromise(IExtensionManagementService, 'getInstalled', [local]);
const actual = await testObject.queryLocal();
assert.equal(actual[0].enablementState, EnablementState.EnabledGlobally);
});
test('test updating an extension does not re-eanbles it when workspace disabled', async () => {
testObject = await aWorkbenchService();
const local = aLocalExtension('pub.a');
await instantiationService.get(IExtensionEnablementService).setEnablement([local], EnablementState.DisabledWorkspace);
didInstallEvent.fire({ local, identifier: local.identifier, operation: InstallOperation.Update });
instantiationService.stubPromise(IExtensionManagementService, 'getInstalled', [local]);
const actual = await testObject.queryLocal();
assert.equal(actual[0].enablementState, EnablementState.DisabledWorkspace);
});
async function aWorkbenchService(): Promise<ExtensionsWorkbenchService> {
const workbenchService: ExtensionsWorkbenchService = instantiationService.createInstance(ExtensionsWorkbenchService);
await workbenchService.queryLocal();
......
......@@ -6,7 +6,7 @@
import { localize } from 'vs/nls';
import { Event, Emitter } from 'vs/base/common/event';
import { Disposable } from 'vs/base/common/lifecycle';
import { IExtensionManagementService, DidUninstallExtensionEvent, IExtensionIdentifier, DidInstallExtensionEvent, InstallOperation } from 'vs/platform/extensionManagement/common/extensionManagement';
import { IExtensionManagementService, DidUninstallExtensionEvent, IExtensionIdentifier } from 'vs/platform/extensionManagement/common/extensionManagement';
import { IExtensionEnablementService, EnablementState, IExtensionManagementServerService } from 'vs/workbench/services/extensionManagement/common/extensionManagement';
import { areSameExtensions } from 'vs/platform/extensionManagement/common/extensionManagementUtil';
import { IWorkspaceContextService, WorkbenchState } from 'vs/platform/workspace/common/workspace';
......@@ -43,7 +43,6 @@ export class ExtensionEnablementService extends Disposable implements IExtension
super();
this.storageManger = this._register(new StorageManager(storageService));
this._register(this.storageManger.onDidChange(extensions => this.onDidChangeStorage(extensions)));
this._register(extensionManagementService.onDidInstallExtension(this._onDidInstallExtension, this));
this._register(extensionManagementService.onDidUninstallExtension(this._onDidUninstallExtension, this));
}
......@@ -286,16 +285,6 @@ export class ExtensionEnablementService extends Disposable implements IExtension
this._onEnablementChanged.fire(extensions);
}
private _onDidInstallExtension(event: DidInstallExtensionEvent): void {
if (event.local && event.operation === InstallOperation.Install) {
const wasDisabled = !this.isEnabled(event.local);
this._reset(event.local.identifier);
if (wasDisabled) {
this._onEnablementChanged.fire([event.local]);
}
}
}
private _onDidUninstallExtension({ identifier, error }: DidUninstallExtensionEvent): void {
if (!error) {
this._reset(identifier);
......
......@@ -4,7 +4,7 @@
*--------------------------------------------------------------------------------------------*/
import * as assert from 'assert';
import * as sinon from 'sinon';
import { IExtensionManagementService, DidUninstallExtensionEvent, ILocalExtension, DidInstallExtensionEvent, InstallOperation } from 'vs/platform/extensionManagement/common/extensionManagement';
import { IExtensionManagementService, DidUninstallExtensionEvent, ILocalExtension, DidInstallExtensionEvent } from 'vs/platform/extensionManagement/common/extensionManagement';
import { IExtensionEnablementService, EnablementState, IExtensionManagementServerService } from 'vs/workbench/services/extensionManagement/common/extensionManagement';
import { ExtensionEnablementService } from 'vs/workbench/services/extensionManagement/common/extensionEnablementService';
import { TestInstantiationService } from 'vs/platform/instantiation/test/common/instantiationServiceMock';
......@@ -71,12 +71,11 @@ suite('ExtensionEnablementService Test', () => {
let testObject: IExtensionEnablementService;
const didUninstallEvent = new Emitter<DidUninstallExtensionEvent>();
const didInstallEvent = new Emitter<DidInstallExtensionEvent>();
setup(() => {
instantiationService = new TestInstantiationService();
instantiationService.stub(IConfigurationService, new TestConfigurationService());
instantiationService.stub(IExtensionManagementService, { onDidUninstallExtension: didUninstallEvent.event, onDidInstallExtension: didInstallEvent.event, getInstalled: () => Promise.resolve([] as ILocalExtension[]) } as IExtensionManagementService);
instantiationService.stub(IExtensionManagementService, { onDidUninstallExtension: didUninstallEvent.event, getInstalled: () => Promise.resolve([] as ILocalExtension[]) } as IExtensionManagementService);
instantiationService.stub(IExtensionManagementServerService, <IExtensionManagementServerService>{
localExtensionManagementServer: {
extensionManagementService: instantiationService.get(IExtensionManagementService)
......@@ -338,90 +337,6 @@ suite('ExtensionEnablementService Test', () => {
assert.equal(testObject.getEnablementState(extension), EnablementState.EnabledGlobally);
});
test('test installing an extension re-eanbles it when disabled globally', async () => {
const local = aLocalExtension('pub.a');
await testObject.setEnablement([local], EnablementState.DisabledGlobally);
didInstallEvent.fire({ local, identifier: local.identifier, operation: InstallOperation.Install });
assert.ok(testObject.isEnabled(local));
assert.equal(testObject.getEnablementState(local), EnablementState.EnabledGlobally);
});
test('test updating an extension does not re-eanbles it when disabled globally', async () => {
const local = aLocalExtension('pub.a');
await testObject.setEnablement([local], EnablementState.DisabledGlobally);
didInstallEvent.fire({ local, identifier: local.identifier, operation: InstallOperation.Update });
assert.ok(!testObject.isEnabled(local));
assert.equal(testObject.getEnablementState(local), EnablementState.DisabledGlobally);
});
test('test installing an extension fires enablement change event when disabled globally', async () => {
const local = aLocalExtension('pub.a');
await testObject.setEnablement([local], EnablementState.DisabledGlobally);
return new Promise((c, e) => {
testObject.onEnablementChanged(([e]) => {
if (e.identifier.id === local.identifier.id) {
c();
}
});
didInstallEvent.fire({ local, identifier: local.identifier, operation: InstallOperation.Install });
});
});
test('test updating an extension does not fires enablement change event when disabled globally', async () => {
const target = sinon.spy();
const local = aLocalExtension('pub.a');
await testObject.setEnablement([local], EnablementState.DisabledGlobally);
testObject.onEnablementChanged(target);
didInstallEvent.fire({ local, identifier: local.identifier, operation: InstallOperation.Update });
assert.ok(!target.called);
});
test('test installing an extension re-eanbles it when workspace disabled', async () => {
const local = aLocalExtension('pub.a');
await testObject.setEnablement([local], EnablementState.DisabledWorkspace);
didInstallEvent.fire({ local, identifier: local.identifier, operation: InstallOperation.Install });
assert.ok(testObject.isEnabled(local));
assert.equal(testObject.getEnablementState(local), EnablementState.EnabledGlobally);
});
test('test updating an extension does not re-eanbles it when workspace disabled', async () => {
const local = aLocalExtension('pub.a');
await testObject.setEnablement([local], EnablementState.DisabledWorkspace);
didInstallEvent.fire({ local, identifier: local.identifier, operation: InstallOperation.Update });
assert.ok(!testObject.isEnabled(local));
assert.equal(testObject.getEnablementState(local), EnablementState.DisabledWorkspace);
});
test('test installing an extension fires enablement change event when workspace disabled', async () => {
const local = aLocalExtension('pub.a');
await testObject.setEnablement([local], EnablementState.DisabledWorkspace);
return new Promise((c, e) => {
testObject.onEnablementChanged(([e]) => {
if (e.identifier.id === local.identifier.id) {
c();
}
});
didInstallEvent.fire({ local, identifier: local.identifier, operation: InstallOperation.Install });
});
});
test('test updating an extension does not fires enablement change event when workspace disabled', async () => {
const target = sinon.spy();
const local = aLocalExtension('pub.a');
await testObject.setEnablement([local], EnablementState.DisabledWorkspace);
testObject.onEnablementChanged(target);
didInstallEvent.fire({ local, identifier: local.identifier, operation: InstallOperation.Update });
assert.ok(!target.called);
});
test('test installing an extension should not fire enablement change event when extension is not disabled', async () => {
const target = sinon.spy();
const local = aLocalExtension('pub.a');
testObject.onEnablementChanged(target);
didInstallEvent.fire({ local, identifier: local.identifier, operation: InstallOperation.Install });
assert.ok(!target.called);
});
test('test remove an extension from disablement list when uninstalled', async () => {
const extension = aLocalExtension('pub.a');
await testObject.setEnablement([extension], EnablementState.DisabledWorkspace);
......@@ -480,7 +395,7 @@ suite('ExtensionEnablementService Test', () => {
test('test extension is disabled when disabled in enviroment', async () => {
const extension = aLocalExtension('pub.a');
instantiationService.stub(IWorkbenchEnvironmentService, { disableExtensions: ['pub.a'] } as IWorkbenchEnvironmentService);
instantiationService.stub(IExtensionManagementService, { onDidUninstallExtension: didUninstallEvent.event, onDidInstallExtension: didInstallEvent.event, getInstalled: () => Promise.resolve([extension, aLocalExtension('pub.b')]) } as IExtensionManagementService);
instantiationService.stub(IExtensionManagementService, { onDidUninstallExtension: didUninstallEvent.event, getInstalled: () => Promise.resolve([extension, aLocalExtension('pub.b')]) } as IExtensionManagementService);
testObject = new TestExtensionEnablementService(instantiationService);
assert.ok(!testObject.isEnabled(extension));
assert.deepEqual(testObject.getEnablementState(extension), EnablementState.DisabledByEnvironemt);
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册