提交 53f92c70 编写于 作者: S Sandeep Somavarapu

ExtensionEnablementService:

- Remove getDisabledExtensions and instead use isEnabled or getEnablementState methods
上级 6ca123d6
......@@ -47,36 +47,6 @@ export class ExtensionEnablementService extends Disposable implements IExtension
return this.environmentService.disableExtensions === true;
}
async getDisabledExtensions(): Promise<IExtensionIdentifier[]> {
let result = this._getDisabledExtensions(StorageScope.GLOBAL);
if (this.hasWorkspace) {
for (const e of this._getDisabledExtensions(StorageScope.WORKSPACE)) {
if (!result.some(r => areSameExtensions(r, e))) {
result.push(e);
}
}
const workspaceEnabledExtensions = this._getEnabledExtensions(StorageScope.WORKSPACE);
if (workspaceEnabledExtensions.length) {
result = result.filter(r => !workspaceEnabledExtensions.some(e => areSameExtensions(e, r)));
}
}
if (this.environmentService.disableExtensions) {
const allInstalledExtensions = await this.extensionManagementService.getInstalled();
for (const installedExtension of allInstalledExtensions) {
if (this._isExtensionDisabledInEnvironment(installedExtension)) {
if (!result.some(r => areSameExtensions(r, installedExtension.identifier))) {
result.push(installedExtension.identifier);
}
}
}
}
return result;
}
getEnablementState(extension: IExtension): EnablementState {
if (this._isExtensionDisabledInEnvironment(extension)) {
return EnablementState.Disabled;
......@@ -260,7 +230,7 @@ export class ExtensionEnablementService extends Disposable implements IExtension
return false;
}
private _getEnabledExtensions(scope: StorageScope): IExtensionIdentifier[] {
protected _getEnabledExtensions(scope: StorageScope): IExtensionIdentifier[] {
return this._getExtensions(ENABLED_EXTENSIONS_STORAGE_PATH, scope);
}
......@@ -268,7 +238,7 @@ export class ExtensionEnablementService extends Disposable implements IExtension
this._setExtensions(ENABLED_EXTENSIONS_STORAGE_PATH, enabledExtensions, scope);
}
private _getDisabledExtensions(scope: StorageScope): IExtensionIdentifier[] {
protected _getDisabledExtensions(scope: StorageScope): IExtensionIdentifier[] {
return this._getExtensions(DISABLED_EXTENSIONS_STORAGE_PATH, scope);
}
......
......@@ -241,12 +241,6 @@ export interface IExtensionEnablementService {
*/
onEnablementChanged: Event<IExtension[]>;
/**
* Returns all disabled extension identifiers for current workspace
* Returns an empty array if none exist
*/
getDisabledExtensions(): Promise<IExtensionIdentifier[]>;
/**
* Returns the enablement state for the given extension
*/
......
......@@ -10,9 +10,10 @@ import { TestInstantiationService } from 'vs/platform/instantiation/test/common/
import { Emitter } from 'vs/base/common/event';
import { IWorkspaceContextService, WorkbenchState } from 'vs/platform/workspace/common/workspace';
import { IEnvironmentService } from 'vs/platform/environment/common/environment';
import { IStorageService, InMemoryStorageService } from 'vs/platform/storage/common/storage';
import { IStorageService, InMemoryStorageService, StorageScope } from 'vs/platform/storage/common/storage';
import { IExtensionContributions, ExtensionType, IExtension } from 'vs/platform/extensions/common/extensions';
import { isUndefinedOrNull } from 'vs/base/common/types';
import { areSameExtensions } from 'vs/platform/extensionManagement/common/extensionManagementUtil';
function storageService(instantiationService: TestInstantiationService): IStorageService {
let service = instantiationService.get(IStorageService);
......@@ -36,8 +37,18 @@ export class TestExtensionEnablementService extends ExtensionEnablementService {
{ onDidInstallExtension: new Emitter<DidInstallExtensionEvent>().event, onDidUninstallExtension: new Emitter<DidUninstallExtensionEvent>().event } as IExtensionManagementService));
}
public async reset(): Promise<void> {
return this.getDisabledExtensions().then(extensions => extensions.forEach(d => this.setEnablement([aLocalExtension(d.id)], EnablementState.Enabled)));
public reset(): void {
let extensions = this._getDisabledExtensions(StorageScope.GLOBAL);
for (const e of this._getDisabledExtensions(StorageScope.WORKSPACE)) {
if (!extensions.some(r => areSameExtensions(r, e))) {
extensions.push(e);
}
}
const workspaceEnabledExtensions = this._getEnabledExtensions(StorageScope.WORKSPACE);
if (workspaceEnabledExtensions.length) {
extensions = extensions.filter(r => !workspaceEnabledExtensions.some(e => areSameExtensions(e, r)));
}
extensions.forEach(d => this.setEnablement([aLocalExtension(d.id)], EnablementState.Enabled));
}
}
......@@ -59,22 +70,11 @@ suite('ExtensionEnablementService Test', () => {
(<ExtensionEnablementService>testObject).dispose();
});
test('test when no extensions are disabled', () => {
return testObject.getDisabledExtensions().then(extensions => assert.deepEqual([], extensions));
});
test('test when no extensions are disabled for workspace when there is no workspace', () => {
return testObject.setEnablement([aLocalExtension('pub.a')], EnablementState.WorkspaceDisabled)
.then(() => {
instantiationService.stub(IWorkspaceContextService, 'getWorkbenchState', WorkbenchState.EMPTY);
return testObject.getDisabledExtensions().then(extensions => assert.deepEqual([], extensions));
});
});
test('test disable an extension globally', () => {
return testObject.setEnablement([aLocalExtension('pub.a')], EnablementState.Disabled)
.then(() => testObject.getDisabledExtensions())
.then(extensions => assert.deepEqual([{ id: 'pub.a' }], extensions));
test('test disable an extension globally', async () => {
const extension = aLocalExtension('pub.a');
await testObject.setEnablement([extension], EnablementState.Disabled);
assert.ok(!testObject.isEnabled(extension));
assert.equal(testObject.getEnablementState(extension), EnablementState.Disabled);
});
test('test disable an extension globally should return truthy promise', () => {
......@@ -109,10 +109,11 @@ suite('ExtensionEnablementService Test', () => {
.then(() => assert.equal(testObject.getEnablementState(aLocalExtension('pub.a')), EnablementState.Enabled));
});
test('test disable an extension for workspace', () => {
return testObject.setEnablement([aLocalExtension('pub.a')], EnablementState.WorkspaceDisabled)
.then(() => testObject.getDisabledExtensions())
.then(extensions => assert.deepEqual([{ id: 'pub.a' }], extensions));
test('test disable an extension for workspace', async () => {
const extension = aLocalExtension('pub.a');
await testObject.setEnablement([extension], EnablementState.WorkspaceDisabled);
assert.ok(!testObject.isEnabled(extension));
assert.equal(testObject.getEnablementState(extension), EnablementState.WorkspaceDisabled);
});
test('test disable an extension for workspace returns a truthy promise', () => {
......@@ -183,11 +184,12 @@ suite('ExtensionEnablementService Test', () => {
.then(() => assert.equal(testObject.getEnablementState(aLocalExtension('pub.a')), EnablementState.Enabled));
});
test('test disable an extension for workspace and then globally', () => {
return testObject.setEnablement([aLocalExtension('pub.a')], EnablementState.WorkspaceDisabled)
.then(() => testObject.setEnablement([aLocalExtension('pub.a')], EnablementState.Disabled))
.then(() => testObject.getDisabledExtensions())
.then(extensions => assert.deepEqual([{ id: 'pub.a' }], extensions));
test('test disable an extension for workspace and then globally', async () => {
const extension = aLocalExtension('pub.a');
await testObject.setEnablement([extension], EnablementState.WorkspaceDisabled);
await testObject.setEnablement([extension], EnablementState.Disabled);
assert.ok(!testObject.isEnabled(extension));
assert.equal(testObject.getEnablementState(extension), EnablementState.Disabled);
});
test('test disable an extension for workspace and then globally return a truthy promise', () => {
......@@ -207,11 +209,12 @@ suite('ExtensionEnablementService Test', () => {
});
});
test('test disable an extension globally and then for workspace', () => {
return testObject.setEnablement([aLocalExtension('pub.a')], EnablementState.Disabled)
.then(() => testObject.setEnablement([aLocalExtension('pub.a')], EnablementState.WorkspaceDisabled))
.then(() => testObject.getDisabledExtensions())
.then(extensions => assert.deepEqual([{ id: 'pub.a' }], extensions));
test('test disable an extension globally and then for workspace', async () => {
const extension = aLocalExtension('pub.a');
await testObject.setEnablement([extension], EnablementState.Disabled);
await testObject.setEnablement([extension], EnablementState.WorkspaceDisabled);
assert.ok(!testObject.isEnabled(extension));
assert.equal(testObject.getEnablementState(extension), EnablementState.WorkspaceDisabled);
});
test('test disable an extension globally and then for workspace return a truthy promise', () => {
......@@ -237,11 +240,12 @@ suite('ExtensionEnablementService Test', () => {
.then(() => assert.fail('should throw an error'), error => assert.ok(error));
});
test('test enable an extension globally', () => {
return testObject.setEnablement([aLocalExtension('pub.a')], EnablementState.Disabled)
.then(() => testObject.setEnablement([aLocalExtension('pub.a')], EnablementState.Enabled))
.then(() => testObject.getDisabledExtensions())
.then(extensions => assert.deepEqual([], extensions));
test('test enable an extension globally', async () => {
const extension = aLocalExtension('pub.a');
await testObject.setEnablement([extension], EnablementState.Disabled);
await testObject.setEnablement([extension], EnablementState.Enabled);
assert.ok(testObject.isEnabled(extension));
assert.equal(testObject.getEnablementState(extension), EnablementState.Enabled);
});
test('test enable an extension globally return truthy promise', () => {
......@@ -266,11 +270,12 @@ suite('ExtensionEnablementService Test', () => {
.then(value => assert.ok(!value[0]));
});
test('test enable an extension for workspace', () => {
return testObject.setEnablement([aLocalExtension('pub.a')], EnablementState.WorkspaceDisabled)
.then(() => testObject.setEnablement([aLocalExtension('pub.a')], EnablementState.WorkspaceEnabled))
.then(() => testObject.getDisabledExtensions())
.then(extensions => assert.deepEqual([], extensions));
test('test enable an extension for workspace', async () => {
const extension = aLocalExtension('pub.a');
await testObject.setEnablement([extension], EnablementState.WorkspaceDisabled);
await testObject.setEnablement([extension], EnablementState.WorkspaceEnabled);
assert.ok(testObject.isEnabled(extension));
assert.equal(testObject.getEnablementState(extension), EnablementState.WorkspaceEnabled);
});
test('test enable an extension for workspace return truthy promise', () => {
......@@ -295,36 +300,39 @@ suite('ExtensionEnablementService Test', () => {
.then(value => assert.ok(value));
});
test('test enable an extension for workspace when disabled in workspace and gloablly', () => {
return testObject.setEnablement([aLocalExtension('pub.a')], EnablementState.WorkspaceDisabled)
.then(() => testObject.setEnablement([aLocalExtension('pub.a')], EnablementState.Disabled))
.then(() => testObject.setEnablement([aLocalExtension('pub.a')], EnablementState.WorkspaceEnabled))
.then(() => testObject.getDisabledExtensions())
.then(extensions => assert.deepEqual([], extensions));
test('test enable an extension for workspace when disabled in workspace and gloablly', async () => {
const extension = aLocalExtension('pub.a');
await testObject.setEnablement([extension], EnablementState.WorkspaceDisabled);
await testObject.setEnablement([extension], EnablementState.Disabled);
await testObject.setEnablement([extension], EnablementState.WorkspaceEnabled);
assert.ok(testObject.isEnabled(extension));
assert.equal(testObject.getEnablementState(extension), EnablementState.WorkspaceEnabled);
});
test('test enable an extension globally when disabled in workspace and gloablly', () => {
return testObject.setEnablement([aLocalExtension('pub.a')], EnablementState.WorkspaceDisabled)
.then(() => testObject.setEnablement([aLocalExtension('pub.a')], EnablementState.Disabled))
.then(() => testObject.setEnablement([aLocalExtension('pub.a')], EnablementState.Enabled))
.then(() => testObject.getDisabledExtensions())
.then(extensions => assert.deepEqual([], extensions));
test('test enable an extension globally when disabled in workspace and gloablly', async () => {
const extension = aLocalExtension('pub.a');
await testObject.setEnablement([extension], EnablementState.WorkspaceEnabled);
await testObject.setEnablement([extension], EnablementState.WorkspaceDisabled);
await testObject.setEnablement([extension], EnablementState.Disabled);
await testObject.setEnablement([extension], EnablementState.Enabled);
assert.ok(testObject.isEnabled(extension));
assert.equal(testObject.getEnablementState(extension), EnablementState.Enabled);
});
test('test installing an extension re-eanbles it when disabled globally', async () => {
const local = aLocalExtension('pub.a');
await testObject.setEnablement([local], EnablementState.Disabled);
didInstallEvent.fire({ local, identifier: local.identifier, operation: InstallOperation.Install });
const extensions = await testObject.getDisabledExtensions();
assert.deepEqual([], extensions);
assert.ok(testObject.isEnabled(local));
assert.equal(testObject.getEnablementState(local), EnablementState.Enabled);
});
test('test updating an extension does not re-eanbles it when disabled globally', async () => {
const local = aLocalExtension('pub.a');
await testObject.setEnablement([local], EnablementState.Disabled);
didInstallEvent.fire({ local, identifier: local.identifier, operation: InstallOperation.Update });
const extensions = await testObject.getDisabledExtensions();
assert.deepEqual([{ id: 'pub.a' }], extensions);
assert.ok(!testObject.isEnabled(local));
assert.equal(testObject.getEnablementState(local), EnablementState.Disabled);
});
test('test installing an extension fires enablement change event when disabled globally', async () => {
......@@ -353,16 +361,16 @@ suite('ExtensionEnablementService Test', () => {
const local = aLocalExtension('pub.a');
await testObject.setEnablement([local], EnablementState.WorkspaceDisabled);
didInstallEvent.fire({ local, identifier: local.identifier, operation: InstallOperation.Install });
const extensions = await testObject.getDisabledExtensions();
assert.deepEqual([], extensions);
assert.ok(testObject.isEnabled(local));
assert.equal(testObject.getEnablementState(local), EnablementState.Enabled);
});
test('test updating an extension does not re-eanbles it when workspace disabled', async () => {
const local = aLocalExtension('pub.a');
await testObject.setEnablement([local], EnablementState.WorkspaceDisabled);
didInstallEvent.fire({ local, identifier: local.identifier, operation: InstallOperation.Update });
const extensions = await testObject.getDisabledExtensions();
assert.deepEqual([{ id: 'pub.a' }], extensions);
assert.ok(!testObject.isEnabled(local));
assert.equal(testObject.getEnablementState(local), EnablementState.WorkspaceDisabled);
});
test('test installing an extension fires enablement change event when workspace disabled', async () => {
......@@ -395,12 +403,13 @@ suite('ExtensionEnablementService Test', () => {
assert.ok(!target.called);
});
test('test remove an extension from disablement list when uninstalled', () => {
return testObject.setEnablement([aLocalExtension('pub.a')], EnablementState.WorkspaceDisabled)
.then(() => testObject.setEnablement([aLocalExtension('pub.a')], EnablementState.Disabled))
.then(() => didUninstallEvent.fire({ identifier: { id: 'pub.a' } }))
.then(() => testObject.getDisabledExtensions())
.then(extensions => assert.deepEqual([], extensions));
test('test remove an extension from disablement list when uninstalled', async () => {
const extension = aLocalExtension('pub.a');
await testObject.setEnablement([extension], EnablementState.WorkspaceDisabled);
await testObject.setEnablement([extension], EnablementState.Disabled);
didUninstallEvent.fire({ identifier: { id: 'pub.a' } });
assert.ok(testObject.isEnabled(extension));
assert.equal(testObject.getEnablementState(extension), EnablementState.Enabled);
});
test('test isEnabled return false extension is disabled globally', () => {
......@@ -449,15 +458,13 @@ suite('ExtensionEnablementService Test', () => {
assert.equal(testObject.canChangeEnablement(extension), true);
});
test('test getDisabledExtensions include extensions disabled in enviroment', () => {
test('test extension is disabled when disabled in enviroment', async () => {
const extension = aLocalExtension('pub.a');
instantiationService.stub(IEnvironmentService, { disableExtensions: ['pub.a'] } as IEnvironmentService);
instantiationService.stub(IExtensionManagementService, { onDidUninstallExtension: didUninstallEvent.event, onDidInstallExtension: didInstallEvent.event, getInstalled: () => Promise.resolve([aLocalExtension('pub.a'), aLocalExtension('pub.b')]) } as IExtensionManagementService);
instantiationService.stub(IExtensionManagementService, { onDidUninstallExtension: didUninstallEvent.event, onDidInstallExtension: didInstallEvent.event, getInstalled: () => Promise.resolve([extension, aLocalExtension('pub.b')]) } as IExtensionManagementService);
testObject = new TestExtensionEnablementService(instantiationService);
return testObject.getDisabledExtensions()
.then(actual => {
assert.equal(actual.length, 1);
assert.equal(actual[0].id, 'pub.a');
});
assert.ok(!testObject.isEnabled(extension));
assert.deepEqual(testObject.getEnablementState(extension), EnablementState.Disabled);
});
});
......
......@@ -115,20 +115,16 @@ export function onExtensionChanged(accessor: ServicesAccessor): Event<IExtension
});
}
export function getInstalledExtensions(accessor: ServicesAccessor): Promise<IExtensionStatus[]> {
export async function getInstalledExtensions(accessor: ServicesAccessor): Promise<IExtensionStatus[]> {
const extensionService = accessor.get(IExtensionManagementService);
const extensionEnablementService = accessor.get(IExtensionEnablementService);
return extensionService.getInstalled().then(extensions => {
return extensionEnablementService.getDisabledExtensions()
.then(disabledExtensions => {
return extensions.map(extension => {
return {
identifier: extension.identifier,
local: extension,
globallyEnabled: disabledExtensions.every(disabled => !areSameExtensions(disabled, extension.identifier))
};
});
});
const extensions = await extensionService.getInstalled();
return extensions.map(extension => {
return {
identifier: extension.identifier,
local: extension,
globallyEnabled: extensionEnablementService.isEnabled(extension)
};
});
}
......
......@@ -662,70 +662,67 @@ export class ExtensionService extends Disposable implements IExtensionService {
return false;
}
private _getRuntimeExtensions(allExtensions: IExtensionDescription[]): Promise<IExtensionDescription[]> {
return this._extensionEnablementService.getDisabledExtensions()
.then(disabledExtensions => {
const runtimeExtensions: IExtensionDescription[] = [];
const extensionsToDisable: IExtensionDescription[] = [];
const userMigratedSystemExtensions: IExtensionIdentifier[] = [{ id: BetterMergeId }];
let enableProposedApiFor: string | string[] = this._environmentService.args['enable-proposed-api'] || [];
const notFound = (id: string) => nls.localize('notFound', "Extension \`{0}\` cannot use PROPOSED API as it cannot be found", id);
if (enableProposedApiFor.length) {
let allProposed = (enableProposedApiFor instanceof Array ? enableProposedApiFor : [enableProposedApiFor]);
allProposed.forEach(id => {
if (!allExtensions.some(description => ExtensionIdentifier.equals(description.identifier, id))) {
console.error(notFound(id));
}
});
// Make enabled proposed API be lowercase for case insensitive comparison
if (Array.isArray(enableProposedApiFor)) {
enableProposedApiFor = enableProposedApiFor.map(id => id.toLowerCase());
} else {
enableProposedApiFor = enableProposedApiFor.toLowerCase();
}
private async _getRuntimeExtensions(allExtensions: IExtensionDescription[]): Promise<IExtensionDescription[]> {
const runtimeExtensions: IExtensionDescription[] = [];
const extensionsToDisable: IExtensionDescription[] = [];
const userMigratedSystemExtensions: IExtensionIdentifier[] = [{ id: BetterMergeId }];
let enableProposedApiFor: string | string[] = this._environmentService.args['enable-proposed-api'] || [];
const notFound = (id: string) => nls.localize('notFound', "Extension \`{0}\` cannot use PROPOSED API as it cannot be found", id);
if (enableProposedApiFor.length) {
let allProposed = (enableProposedApiFor instanceof Array ? enableProposedApiFor : [enableProposedApiFor]);
allProposed.forEach(id => {
if (!allExtensions.some(description => ExtensionIdentifier.equals(description.identifier, id))) {
console.error(notFound(id));
}
});
// Make enabled proposed API be lowercase for case insensitive comparison
if (Array.isArray(enableProposedApiFor)) {
enableProposedApiFor = enableProposedApiFor.map(id => id.toLowerCase());
} else {
enableProposedApiFor = enableProposedApiFor.toLowerCase();
}
}
const enableProposedApiForAll = !this._environmentService.isBuilt ||
(!!this._environmentService.extensionDevelopmentLocationURI && product.nameLong !== 'Visual Studio Code') ||
(enableProposedApiFor.length === 0 && 'enable-proposed-api' in this._environmentService.args);
const enableProposedApiForAll = !this._environmentService.isBuilt ||
(!!this._environmentService.extensionDevelopmentLocationURI && product.nameLong !== 'Visual Studio Code') ||
(enableProposedApiFor.length === 0 && 'enable-proposed-api' in this._environmentService.args);
for (const extension of allExtensions) {
for (const extension of allExtensions) {
// Do not disable extensions under development
if (!this.isExtensionUnderDevelopment(extension)) {
if (disabledExtensions.some(disabled => areSameExtensions(disabled, { id: extension.identifier.value }))) {
continue;
}
}
// Do not disable extensions under development
if (!this.isExtensionUnderDevelopment(extension)) {
if (!this._extensionEnablementService.isEnabled(toExtension(extension))) {
continue;
}
}
if (!extension.isBuiltin) {
// Check if the extension is changed to system extension
const userMigratedSystemExtension = userMigratedSystemExtensions.filter(userMigratedSystemExtension => areSameExtensions(userMigratedSystemExtension, { id: extension.identifier.value }))[0];
if (userMigratedSystemExtension) {
extensionsToDisable.push(extension);
continue;
}
}
runtimeExtensions.push(this._updateEnableProposedApi(extension, enableProposedApiForAll, enableProposedApiFor));
if (!extension.isBuiltin) {
// Check if the extension is changed to system extension
const userMigratedSystemExtension = userMigratedSystemExtensions.filter(userMigratedSystemExtension => areSameExtensions(userMigratedSystemExtension, { id: extension.identifier.value }))[0];
if (userMigratedSystemExtension) {
extensionsToDisable.push(extension);
continue;
}
}
runtimeExtensions.push(this._updateEnableProposedApi(extension, enableProposedApiForAll, enableProposedApiFor));
}
this._telemetryService.publicLog('extensionsScanned', {
totalCount: runtimeExtensions.length,
disabledCount: disabledExtensions.length
});
this._telemetryService.publicLog('extensionsScanned', {
totalCount: runtimeExtensions.length,
disabledCount: allExtensions.length - runtimeExtensions.length
});
if (extensionsToDisable.length) {
return this._extensionEnablementService.setEnablement(extensionsToDisable.map(e => toExtension(e)), EnablementState.Disabled)
.then(() => runtimeExtensions);
} else {
return runtimeExtensions;
}
});
if (extensionsToDisable.length) {
return this._extensionEnablementService.setEnablement(extensionsToDisable.map(e => toExtension(e)), EnablementState.Disabled)
.then(() => runtimeExtensions);
} else {
return runtimeExtensions;
}
}
private _updateEnableProposedApi(extension: IExtensionDescription, enableProposedApiForAll: boolean, enableProposedApiFor: string | string[]): IExtensionDescription {
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册