mirror of
https://github.com/microsoft/vscode.git
synced 2026-04-28 04:23:32 +01:00
#14821 Move extension enablement closer to extension management
This commit is contained in:
@@ -11,7 +11,8 @@ import { localize } from 'vs/nls';
|
||||
import * as path from 'path';
|
||||
import URI from 'vs/base/common/uri';
|
||||
import { AbstractExtensionService, ActivatedExtension } from 'vs/platform/extensions/common/abstractExtensionService';
|
||||
import { IExtensionRuntimeService, IMessage, IExtensionDescription, IExtensionsStatus } from 'vs/platform/extensions/common/extensions';
|
||||
import { IMessage, IExtensionDescription, IExtensionsStatus } from 'vs/platform/extensions/common/extensions';
|
||||
import { IExtensionEnablementService } from 'vs/platform/extensionManagement/common/extensionManagement';
|
||||
import { ExtensionsRegistry, ExtensionPoint, IExtensionPointUser, ExtensionMessageCollector } from 'vs/platform/extensions/common/extensionsRegistry';
|
||||
import { ExtensionScanner, MessagesCollector } from 'vs/workbench/node/extensionPoints';
|
||||
import { IMessageService } from 'vs/platform/message/common/message';
|
||||
@@ -61,7 +62,7 @@ export class MainProcessExtensionService extends AbstractExtensionService<Activa
|
||||
@IThreadService threadService: IThreadService,
|
||||
@IMessageService messageService: IMessageService,
|
||||
@IEnvironmentService private environmentService: IEnvironmentService,
|
||||
@IExtensionRuntimeService extensionsRuntimeService: IExtensionRuntimeService
|
||||
@IExtensionEnablementService extensionEnablementService: IExtensionEnablementService
|
||||
) {
|
||||
super(false);
|
||||
this._isDev = !environmentService.isBuilt || !!environmentService.extensionDevelopmentPath;
|
||||
@@ -71,7 +72,7 @@ export class MainProcessExtensionService extends AbstractExtensionService<Activa
|
||||
this._proxy = this._threadService.get(ExtHostContext.ExtHostExtensionService);
|
||||
this._extensionsStatus = {};
|
||||
|
||||
const disabledExtensions = [...extensionsRuntimeService.getGloballyDisabledExtensions(), ...extensionsRuntimeService.getWorkspaceDisabledExtensions()];
|
||||
const disabledExtensions = [...extensionEnablementService.getGloballyDisabledExtensions(), ...extensionEnablementService.getWorkspaceDisabledExtensions()];
|
||||
this.scanExtensions().done(extensionDescriptions => {
|
||||
this._onExtensionDescriptions(disabledExtensions.length ? extensionDescriptions.filter(e => disabledExtensions.indexOf(`${e.publisher}.${e.name}`) === -1) : extensionDescriptions);
|
||||
});
|
||||
|
||||
@@ -64,7 +64,7 @@ import { IThreadService } from 'vs/workbench/services/thread/common/threadServic
|
||||
import { ICommandService } from 'vs/platform/commands/common/commands';
|
||||
import { CommandService } from 'vs/platform/commands/common/commandService';
|
||||
import { IWorkspaceContextService, IWorkspace } from 'vs/platform/workspace/common/workspace';
|
||||
import { IExtensionService, IExtensionRuntimeService } from 'vs/platform/extensions/common/extensions';
|
||||
import { IExtensionService } from 'vs/platform/extensions/common/extensions';
|
||||
import { MainThreadModeServiceImpl } from 'vs/editor/common/services/modeServiceImpl';
|
||||
import { IModeService } from 'vs/editor/common/services/modeService';
|
||||
import { IUntitledEditorService, UntitledEditorService } from 'vs/workbench/services/untitled/common/untitledEditorService';
|
||||
@@ -75,13 +75,13 @@ import { getDelayedChannel } from 'vs/base/parts/ipc/common/ipc';
|
||||
import { connect as connectNet } from 'vs/base/parts/ipc/node/ipc.net';
|
||||
import { Client as ElectronIPCClient } from 'vs/base/parts/ipc/electron-browser/ipc.electron-browser';
|
||||
import { IExtensionManagementChannel, ExtensionManagementChannelClient } from 'vs/platform/extensionManagement/common/extensionManagementIpc';
|
||||
import { IExtensionManagementService } from 'vs/platform/extensionManagement/common/extensionManagement';
|
||||
import { IExtensionManagementService, IExtensionEnablementService } from 'vs/platform/extensionManagement/common/extensionManagement';
|
||||
import { ExtensionEnablementService } from 'vs/platform/extensionManagement/common/extensionEnablementService';
|
||||
import { URLChannelClient } from 'vs/platform/url/common/urlIpc';
|
||||
import { IURLService } from 'vs/platform/url/common/url';
|
||||
import { ReloadWindowAction } from 'vs/workbench/electron-browser/actions';
|
||||
import { WorkspaceConfigurationService } from 'vs/workbench/services/configuration/node/configurationService';
|
||||
import { ExtensionHostProcessWorker } from 'vs/workbench/electron-browser/extensionHost';
|
||||
import { ExtensionRuntimeService } from 'vs/workbench/services/extensions/common/extensionRuntimeService';
|
||||
import { remote } from 'electron';
|
||||
|
||||
// self registering services
|
||||
@@ -292,9 +292,9 @@ export class WorkbenchShell {
|
||||
const extensionManagementChannelClient = new ExtensionManagementChannelClient(extensionManagementChannel);
|
||||
serviceCollection.set(IExtensionManagementService, extensionManagementChannelClient);
|
||||
|
||||
const extensionsRuntimeService = instantiationService.createInstance(ExtensionRuntimeService);
|
||||
serviceCollection.set(IExtensionRuntimeService, extensionsRuntimeService);
|
||||
disposables.add(extensionsRuntimeService);
|
||||
const extensionEnablementService = instantiationService.createInstance(ExtensionEnablementService);
|
||||
serviceCollection.set(IExtensionEnablementService, extensionEnablementService);
|
||||
disposables.add(extensionEnablementService);
|
||||
|
||||
const extensionHostProcessWorker = instantiationService.createInstance(ExtensionHostProcessWorker);
|
||||
this.threadService = instantiationService.createInstance(MainThreadService, extensionHostProcessWorker.messagingProtocol);
|
||||
|
||||
@@ -17,7 +17,7 @@ import { IContextMenuService } from 'vs/platform/contextview/browser/contextView
|
||||
import { IDisposable, dispose } from 'vs/base/common/lifecycle';
|
||||
import { ReloadWindowAction } from 'vs/workbench/electron-browser/actions';
|
||||
import { IExtension, ExtensionState, IExtensionsWorkbenchService, VIEWLET_ID, IExtensionsViewlet, ConfigurationKey } from '../common/extensions';
|
||||
import { LocalExtensionType } from 'vs/platform/extensionManagement/common/extensionManagement';
|
||||
import { LocalExtensionType, IExtensionEnablementService } from 'vs/platform/extensionManagement/common/extensionManagement';
|
||||
import { IInstantiationService } from 'vs/platform/instantiation/common/instantiation';
|
||||
import { IMessageService } from 'vs/platform/message/common/message';
|
||||
import { IEnvironmentService } from 'vs/platform/environment/common/environment';
|
||||
@@ -30,7 +30,7 @@ import { ExtensionsConfigurationInitialContent } from 'vs/workbench/parts/extens
|
||||
import { IFileService } from 'vs/platform/files/common/files';
|
||||
import { IWorkspaceContextService } from 'vs/platform/workspace/common/workspace';
|
||||
import URI from 'vs/base/common/uri';
|
||||
import { IExtensionService, IExtensionRuntimeService, IExtensionDescription } from 'vs/platform/extensions/common/extensions';
|
||||
import { IExtensionService, IExtensionDescription } from 'vs/platform/extensions/common/extensions';
|
||||
import { IWindowService } from 'vs/workbench/services/window/electron-browser/windowService';
|
||||
|
||||
const dialog = remote.dialog;
|
||||
@@ -360,7 +360,7 @@ export class ManageExtensionAction extends Action {
|
||||
constructor(
|
||||
@IWorkspaceContextService private workspaceContextService: IWorkspaceContextService,
|
||||
@IExtensionsWorkbenchService private extensionsWorkbenchService: IExtensionsWorkbenchService,
|
||||
@IExtensionRuntimeService private extensionRuntimeService: IExtensionRuntimeService,
|
||||
@IExtensionEnablementService private extensionEnablementService: IExtensionEnablementService,
|
||||
@IInstantiationService private instantiationService: IInstantiationService
|
||||
) {
|
||||
super(ManageExtensionAction.ID);
|
||||
@@ -409,7 +409,7 @@ export class EnableForWorkspaceAction extends Action implements IExtensionAction
|
||||
constructor(label: string,
|
||||
@IWorkspaceContextService private workspaceContextService: IWorkspaceContextService,
|
||||
@IExtensionsWorkbenchService private extensionsWorkbenchService: IExtensionsWorkbenchService,
|
||||
@IExtensionRuntimeService private extensionRuntimeService: IExtensionRuntimeService,
|
||||
@IExtensionEnablementService private extensionEnablementService: IExtensionEnablementService,
|
||||
@IInstantiationService private instantiationService: IInstantiationService
|
||||
) {
|
||||
super(EnableForWorkspaceAction.ID, label);
|
||||
@@ -421,7 +421,7 @@ export class EnableForWorkspaceAction extends Action implements IExtensionAction
|
||||
private update(): void {
|
||||
this.enabled = false;
|
||||
if (this.extension) {
|
||||
this.enabled = !this.extension.disabledGlobally && this.extension.disabledForWorkspace && this.extensionRuntimeService.canEnable(this.extension.identifier);
|
||||
this.enabled = !this.extension.disabledGlobally && this.extension.disabledForWorkspace && this.extensionEnablementService.canEnable(this.extension.identifier);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -448,7 +448,7 @@ export class EnableGloballyAction extends Action implements IExtensionAction {
|
||||
|
||||
constructor(label: string,
|
||||
@IExtensionsWorkbenchService private extensionsWorkbenchService: IExtensionsWorkbenchService,
|
||||
@IExtensionRuntimeService private extensionRuntimeService: IExtensionRuntimeService,
|
||||
@IExtensionEnablementService private extensionEnablementService: IExtensionEnablementService,
|
||||
@IInstantiationService private instantiationService: IInstantiationService
|
||||
) {
|
||||
super(EnableGloballyAction.ID, label);
|
||||
@@ -460,7 +460,7 @@ export class EnableGloballyAction extends Action implements IExtensionAction {
|
||||
private update(): void {
|
||||
this.enabled = false;
|
||||
if (this.extension) {
|
||||
this.enabled = this.extension.disabledGlobally && this.extensionRuntimeService.canEnable(this.extension.identifier);
|
||||
this.enabled = this.extension.disabledGlobally && this.extensionEnablementService.canEnable(this.extension.identifier);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -493,7 +493,7 @@ export class EnableAction extends Action {
|
||||
constructor(
|
||||
@IInstantiationService private instantiationService: IInstantiationService,
|
||||
@IExtensionsWorkbenchService private extensionsWorkbenchService: IExtensionsWorkbenchService,
|
||||
@IExtensionRuntimeService private extensionRuntimeService: IExtensionRuntimeService
|
||||
@IExtensionEnablementService private extensionEnablementService: IExtensionEnablementService
|
||||
) {
|
||||
super(EnableAction.ID, localize('enableAction', "Enable"), EnableAction.DisabledClass, false);
|
||||
|
||||
@@ -511,7 +511,7 @@ export class EnableAction extends Action {
|
||||
return;
|
||||
}
|
||||
|
||||
this.enabled = this.extension.state === ExtensionState.Installed && (this.extension.disabledGlobally || this.extension.disabledForWorkspace) && this.extensionRuntimeService.canEnable(this.extension.identifier);
|
||||
this.enabled = this.extension.state === ExtensionState.Installed && (this.extension.disabledGlobally || this.extension.disabledForWorkspace) && this.extensionEnablementService.canEnable(this.extension.identifier);
|
||||
this.class = this.enabled ? EnableAction.EnabledClass : EnableAction.DisabledClass;
|
||||
}
|
||||
|
||||
@@ -1204,7 +1204,7 @@ export class DisableAllAction extends Action {
|
||||
constructor(
|
||||
id: string = DisableAllAction.ID, label: string = DisableAllAction.LABEL,
|
||||
@IExtensionsWorkbenchService private extensionsWorkbenchService: IExtensionsWorkbenchService,
|
||||
@IExtensionRuntimeService private extensionRuntimeService: IExtensionRuntimeService
|
||||
@IExtensionEnablementService private extensionEnablementService: IExtensionEnablementService
|
||||
) {
|
||||
super(id, label);
|
||||
this.update();
|
||||
@@ -1236,7 +1236,7 @@ export class DisableAllWorkpsaceAction extends Action {
|
||||
id: string = DisableAllWorkpsaceAction.ID, label: string = DisableAllWorkpsaceAction.LABEL,
|
||||
@IWorkspaceContextService private workspaceContextService: IWorkspaceContextService,
|
||||
@IExtensionsWorkbenchService private extensionsWorkbenchService: IExtensionsWorkbenchService,
|
||||
@IExtensionRuntimeService private extensionRuntimeService: IExtensionRuntimeService
|
||||
@IExtensionEnablementService private extensionEnablementService: IExtensionEnablementService
|
||||
) {
|
||||
super(id, label);
|
||||
this.update();
|
||||
@@ -1267,7 +1267,7 @@ export class EnableAllAction extends Action {
|
||||
constructor(
|
||||
id: string = EnableAllAction.ID, label: string = EnableAllAction.LABEL,
|
||||
@IExtensionsWorkbenchService private extensionsWorkbenchService: IExtensionsWorkbenchService,
|
||||
@IExtensionRuntimeService private extensionRuntimeService: IExtensionRuntimeService
|
||||
@IExtensionEnablementService private extensionEnablementService: IExtensionEnablementService
|
||||
) {
|
||||
super(id, label);
|
||||
this.update();
|
||||
@@ -1275,7 +1275,7 @@ export class EnableAllAction extends Action {
|
||||
}
|
||||
|
||||
private update(): void {
|
||||
this.enabled = this.extensionsWorkbenchService.local.some(e => this.extensionRuntimeService.canEnable(e.identifier) && e.disabledGlobally);
|
||||
this.enabled = this.extensionsWorkbenchService.local.some(e => this.extensionEnablementService.canEnable(e.identifier) && e.disabledGlobally);
|
||||
}
|
||||
|
||||
run(): TPromise<any> {
|
||||
@@ -1299,7 +1299,7 @@ export class EnableAllWorkpsaceAction extends Action {
|
||||
id: string = EnableAllWorkpsaceAction.ID, label: string = EnableAllWorkpsaceAction.LABEL,
|
||||
@IWorkspaceContextService private workspaceContextService: IWorkspaceContextService,
|
||||
@IExtensionsWorkbenchService private extensionsWorkbenchService: IExtensionsWorkbenchService,
|
||||
@IExtensionRuntimeService private extensionRuntimeService: IExtensionRuntimeService
|
||||
@IExtensionEnablementService private extensionEnablementService: IExtensionEnablementService
|
||||
) {
|
||||
super(id, label);
|
||||
this.update();
|
||||
@@ -1307,7 +1307,7 @@ export class EnableAllWorkpsaceAction extends Action {
|
||||
}
|
||||
|
||||
private update(): void {
|
||||
this.enabled = !!this.workspaceContextService.getWorkspace() && this.extensionsWorkbenchService.local.some(e => this.extensionRuntimeService.canEnable(e.identifier) && !e.disabledGlobally && e.disabledForWorkspace);
|
||||
this.enabled = !!this.workspaceContextService.getWorkspace() && this.extensionsWorkbenchService.local.some(e => this.extensionEnablementService.canEnable(e.identifier) && !e.disabledGlobally && e.disabledForWorkspace);
|
||||
}
|
||||
|
||||
run(): TPromise<any> {
|
||||
|
||||
@@ -22,7 +22,7 @@ import { IPager, mapPager, singlePagePager } from 'vs/base/common/paging';
|
||||
import { ITelemetryService } from 'vs/platform/telemetry/common/telemetry';
|
||||
import {
|
||||
IExtensionManagementService, IExtensionGalleryService, ILocalExtension, IGalleryExtension, IQueryOptions, IExtensionManifest,
|
||||
InstallExtensionEvent, DidInstallExtensionEvent, LocalExtensionType, DidUninstallExtensionEvent
|
||||
InstallExtensionEvent, DidInstallExtensionEvent, LocalExtensionType, DidUninstallExtensionEvent, IExtensionEnablementService
|
||||
} from 'vs/platform/extensionManagement/common/extensionManagement';
|
||||
import { getGalleryExtensionTelemetryData, getLocalExtensionTelemetryData } from 'vs/platform/extensionManagement/common/extensionTelemetry';
|
||||
import { IInstantiationService } from 'vs/platform/instantiation/common/instantiation';
|
||||
@@ -34,7 +34,6 @@ import { IExtension, IExtensionDependencies, ExtensionState, IExtensionsWorkbenc
|
||||
import { IWorkbenchEditorService } from 'vs/workbench/services/editor/common/editorService';
|
||||
import { IURLService } from 'vs/platform/url/common/url';
|
||||
import { ExtensionsInput } from 'vs/workbench/parts/extensions/common/extensionsInput';
|
||||
import { IExtensionRuntimeService } from 'vs/platform/extensions/common/extensions';
|
||||
import { IWorkspaceContextService } from 'vs/platform/workspace/common/workspace';
|
||||
|
||||
interface IExtensionStateProvider {
|
||||
@@ -299,10 +298,6 @@ export class ExtensionsWorkbenchService implements IExtensionsWorkbenchService {
|
||||
private autoUpdateDelayer: ThrottledDelayer<void>;
|
||||
private disposables: IDisposable[] = [];
|
||||
|
||||
// TODO: @sandy - Remove these when IExtensionRuntimeService exposes sync API to get extensions.
|
||||
private newlyInstalled: Extension[] = [];
|
||||
private unInstalled: Extension[] = [];
|
||||
|
||||
private _onChange: Emitter<void> = new Emitter<void>();
|
||||
get onChange(): Event<void> { return this._onChange.event; }
|
||||
|
||||
@@ -315,7 +310,7 @@ export class ExtensionsWorkbenchService implements IExtensionsWorkbenchService {
|
||||
@ITelemetryService private telemetryService: ITelemetryService,
|
||||
@IMessageService private messageService: IMessageService,
|
||||
@IURLService urlService: IURLService,
|
||||
@IExtensionRuntimeService private extensionRuntimeService: IExtensionRuntimeService,
|
||||
@IExtensionEnablementService private extensionEnablementService: IExtensionEnablementService,
|
||||
@IWorkspaceContextService private workspaceContextService: IWorkspaceContextService,
|
||||
) {
|
||||
this.stateProvider = ext => this.getExtensionState(ext);
|
||||
@@ -346,8 +341,8 @@ export class ExtensionsWorkbenchService implements IExtensionsWorkbenchService {
|
||||
queryLocal(): TPromise<IExtension[]> {
|
||||
return this.extensionService.getInstalled().then(result => {
|
||||
const installedById = index(this.installed, e => e.local.id);
|
||||
const globallyDisabledExtensions = this.extensionRuntimeService.getGloballyDisabledExtensions();
|
||||
const workspaceDisabledExtensions = this.extensionRuntimeService.getWorkspaceDisabledExtensions();
|
||||
const globallyDisabledExtensions = this.extensionEnablementService.getGloballyDisabledExtensions();
|
||||
const workspaceDisabledExtensions = this.extensionEnablementService.getWorkspaceDisabledExtensions();
|
||||
this.installed = result.map(local => {
|
||||
const extension = installedById[local.id] || new Extension(this.galleryService, this.stateProvider, local);
|
||||
extension.local = local;
|
||||
@@ -489,12 +484,7 @@ export class ExtensionsWorkbenchService implements IExtensionsWorkbenchService {
|
||||
}
|
||||
|
||||
return this.doSetEnablement(extension, enable, workspace).then(reload => {
|
||||
// update the disable flags
|
||||
const globallyDisabledExtensions = this.extensionRuntimeService.getGloballyDisabledExtensions();
|
||||
const workspaceDisabledExtensions = this.extensionRuntimeService.getWorkspaceDisabledExtensions();
|
||||
extension.disabledGlobally = globallyDisabledExtensions.indexOf(extension.identifier) !== -1;
|
||||
extension.disabledForWorkspace = workspaceDisabledExtensions.indexOf(extension.identifier) !== -1;
|
||||
|
||||
this.updatedDisableFlags(extension);
|
||||
this.telemetryService.publicLog(enable ? 'extension:enable' : 'extension:disable', extension.telemetryData);
|
||||
this._onChange.fire();
|
||||
});
|
||||
@@ -517,14 +507,14 @@ export class ExtensionsWorkbenchService implements IExtensionsWorkbenchService {
|
||||
|
||||
private doSetEnablement(extension: IExtension, enable: boolean, workspace: boolean): TPromise<boolean> {
|
||||
if (workspace) {
|
||||
return this.extensionRuntimeService.setEnablement(extension.identifier, enable, workspace);
|
||||
return this.extensionEnablementService.setEnablement(extension.identifier, enable, workspace);
|
||||
}
|
||||
|
||||
const globalElablement = this.extensionRuntimeService.setEnablement(extension.identifier, enable, false);
|
||||
const globalElablement = this.extensionEnablementService.setEnablement(extension.identifier, enable, false);
|
||||
if (!this.workspaceContextService.getWorkspace()) {
|
||||
return globalElablement;
|
||||
}
|
||||
return TPromise.join([globalElablement, this.extensionRuntimeService.setEnablement(extension.identifier, enable, true)])
|
||||
return TPromise.join([globalElablement, this.extensionEnablementService.setEnablement(extension.identifier, enable, true)])
|
||||
.then(values => values[0] || values[1]);
|
||||
}
|
||||
|
||||
@@ -560,7 +550,6 @@ export class ExtensionsWorkbenchService implements IExtensionsWorkbenchService {
|
||||
this.installing = this.installing.filter(e => e.id !== id);
|
||||
|
||||
if (!error) {
|
||||
this.newlyInstalled.push(extension);
|
||||
extension.local = local;
|
||||
|
||||
const galleryId = local.metadata && local.metadata.id;
|
||||
@@ -599,10 +588,7 @@ export class ExtensionsWorkbenchService implements IExtensionsWorkbenchService {
|
||||
}
|
||||
|
||||
private onDidUninstallExtension({id, error}: DidUninstallExtensionEvent): void {
|
||||
let newlyInstalled = false;
|
||||
if (!error) {
|
||||
newlyInstalled = this.newlyInstalled.filter(e => e.local.id === id).length > 0;
|
||||
this.newlyInstalled = this.newlyInstalled.filter(e => e.local.id !== id);
|
||||
this.installed = this.installed.filter(e => e.local.id !== id);
|
||||
}
|
||||
|
||||
@@ -613,17 +599,20 @@ export class ExtensionsWorkbenchService implements IExtensionsWorkbenchService {
|
||||
}
|
||||
|
||||
if (!error) {
|
||||
this.unInstalled.push(uninstalling.extension);
|
||||
const globallyDisabledExtensions = this.extensionRuntimeService.getGloballyDisabledExtensions();
|
||||
const workspaceDisabledExtensions = this.extensionRuntimeService.getWorkspaceDisabledExtensions();
|
||||
uninstalling.extension.disabledGlobally = globallyDisabledExtensions.indexOf(uninstalling.extension.identifier) !== -1;
|
||||
uninstalling.extension.disabledForWorkspace = workspaceDisabledExtensions.indexOf(uninstalling.extension.identifier) !== -1;
|
||||
this.updatedDisableFlags(uninstalling.extension);
|
||||
this.reportTelemetry(uninstalling, true);
|
||||
}
|
||||
|
||||
this._onChange.fire();
|
||||
}
|
||||
|
||||
private updatedDisableFlags(extension: IExtension) {
|
||||
const globallyDisabledExtensions = this.extensionEnablementService.getGloballyDisabledExtensions();
|
||||
const workspaceDisabledExtensions = this.extensionEnablementService.getWorkspaceDisabledExtensions();
|
||||
extension.disabledGlobally = globallyDisabledExtensions.indexOf(extension.identifier) !== -1;
|
||||
extension.disabledForWorkspace = workspaceDisabledExtensions.indexOf(extension.identifier) !== -1;
|
||||
}
|
||||
|
||||
private getExtensionState(extension: Extension): ExtensionState {
|
||||
if (extension.gallery && this.installing.some(e => e.extension.gallery.id === extension.gallery.id)) {
|
||||
return ExtensionState.Installing;
|
||||
|
||||
@@ -1,144 +0,0 @@
|
||||
/*---------------------------------------------------------------------------------------------
|
||||
* Copyright (c) Microsoft Corporation. All rights reserved.
|
||||
* Licensed under the MIT License. See License.txt in the project root for license information.
|
||||
*--------------------------------------------------------------------------------------------*/
|
||||
|
||||
import { localize } from 'vs/nls';
|
||||
import { TPromise } from 'vs/base/common/winjs.base';
|
||||
import { distinct } from 'vs/base/common/arrays';
|
||||
import { IDisposable, dispose } from 'vs/base/common/lifecycle';
|
||||
import { IExtensionManagementService, DidUninstallExtensionEvent } from 'vs/platform/extensionManagement/common/extensionManagement';
|
||||
import { IWorkspaceContextService, IWorkspace } from 'vs/platform/workspace/common/workspace';
|
||||
import { IExtensionRuntimeService } from 'vs/platform/extensions/common/extensions';
|
||||
import { IStorageService, StorageScope } from 'vs/platform/storage/common/storage';
|
||||
import { IMessageService } from 'vs/platform/message/common/message';
|
||||
import { IEnvironmentService } from 'vs/platform/environment/common/environment';
|
||||
|
||||
const DISABLED_EXTENSIONS_STORAGE_PATH = 'extensions/disabled';
|
||||
|
||||
export class ExtensionRuntimeService implements IExtensionRuntimeService {
|
||||
|
||||
_serviceBrand: any;
|
||||
|
||||
private workspace: IWorkspace;
|
||||
private disposables: IDisposable[] = [];
|
||||
|
||||
constructor(
|
||||
@IStorageService private storageService: IStorageService,
|
||||
@IWorkspaceContextService contextService: IWorkspaceContextService,
|
||||
@IMessageService private messageService: IMessageService,
|
||||
@IEnvironmentService private environmentService: IEnvironmentService,
|
||||
@IExtensionManagementService private extensionManagementService: IExtensionManagementService
|
||||
) {
|
||||
this.workspace = contextService.getWorkspace();
|
||||
extensionManagementService.onDidUninstallExtension(this.onDidUninstallExtension, this, this.disposables);
|
||||
}
|
||||
|
||||
public getGloballyDisabledExtensions(): string[] {
|
||||
return this.getDisabledExtensionsFromStorage(StorageScope.GLOBAL);
|
||||
}
|
||||
|
||||
public getWorkspaceDisabledExtensions(): string[] {
|
||||
return this.getDisabledExtensionsFromStorage(StorageScope.WORKSPACE);
|
||||
}
|
||||
|
||||
public canEnable(identifier: string): boolean {
|
||||
return !this.environmentService.disableExtensions && this.isDisabled(identifier);
|
||||
}
|
||||
|
||||
public setEnablement(identifier: string, enable: boolean, workspace: boolean = false): TPromise<boolean> {
|
||||
if (workspace && !this.workspace) {
|
||||
return TPromise.wrapError(localize('noWorkspace', "No workspace."));
|
||||
}
|
||||
|
||||
if (this.environmentService.disableExtensions) {
|
||||
return TPromise.wrap(false);
|
||||
}
|
||||
|
||||
if (this.isDisabled(identifier) === !enable) {
|
||||
return TPromise.wrap(false);
|
||||
}
|
||||
|
||||
if (enable) {
|
||||
if (workspace) {
|
||||
this.enableExtension(identifier, StorageScope.WORKSPACE);
|
||||
} else {
|
||||
this.enableExtension(identifier, StorageScope.GLOBAL);
|
||||
}
|
||||
} else {
|
||||
if (workspace) {
|
||||
this.disableExtension(identifier, StorageScope.WORKSPACE);
|
||||
} else {
|
||||
this.disableExtension(identifier, StorageScope.GLOBAL);
|
||||
}
|
||||
}
|
||||
|
||||
return TPromise.wrap(true);
|
||||
}
|
||||
|
||||
private getDisabledExtensions(): string[] {
|
||||
const globalDisabledExtensions = this.getGloballyDisabledExtensions();
|
||||
const workspaceDisabledExtensions = this.getWorkspaceDisabledExtensions();
|
||||
return distinct([...workspaceDisabledExtensions, ...globalDisabledExtensions]);
|
||||
}
|
||||
|
||||
private isDisabled(identifier: string): boolean {
|
||||
return this.getDisabledExtensions().indexOf(identifier) !== -1;
|
||||
}
|
||||
|
||||
private getDisabledExtensionsFromStorage(scope?: StorageScope): string[] {
|
||||
if (scope !== void 0) {
|
||||
return this._getDisabledExtensions(scope);
|
||||
}
|
||||
|
||||
const globallyDisabled = this._getDisabledExtensions(StorageScope.GLOBAL);
|
||||
const workspaceDisabled = this._getDisabledExtensions(StorageScope.WORKSPACE);
|
||||
return [...globallyDisabled, ...workspaceDisabled];
|
||||
}
|
||||
|
||||
private disableExtension(identifier: string, scope: StorageScope): TPromise<boolean> {
|
||||
let disabledExtensions = this._getDisabledExtensions(scope);
|
||||
disabledExtensions.push(identifier);
|
||||
this._setDisabledExtensions(disabledExtensions, scope);
|
||||
return TPromise.wrap(true);
|
||||
}
|
||||
|
||||
private enableExtension(identifier: string, scope: StorageScope): TPromise<boolean> {
|
||||
let disabledExtensions = this._getDisabledExtensions(scope);
|
||||
const index = disabledExtensions.indexOf(identifier);
|
||||
if (index !== -1) {
|
||||
disabledExtensions.splice(index, 1);
|
||||
this._setDisabledExtensions(disabledExtensions, scope);
|
||||
}
|
||||
return TPromise.wrap(true);
|
||||
}
|
||||
|
||||
private _getDisabledExtensions(scope: StorageScope): string[] {
|
||||
const value = this.storageService.get(DISABLED_EXTENSIONS_STORAGE_PATH, scope, '');
|
||||
return value ? distinct(value.split(',')) : [];
|
||||
}
|
||||
|
||||
private _setDisabledExtensions(disabledExtensions: string[], scope: StorageScope): void {
|
||||
if (disabledExtensions.length) {
|
||||
this.storageService.store(DISABLED_EXTENSIONS_STORAGE_PATH, disabledExtensions.join(','), scope);
|
||||
} else {
|
||||
this.storageService.remove(DISABLED_EXTENSIONS_STORAGE_PATH, scope);
|
||||
}
|
||||
}
|
||||
|
||||
private onDidUninstallExtension({id, error}: DidUninstallExtensionEvent): void {
|
||||
if (!error) {
|
||||
id = stripVersion(id);
|
||||
this.enableExtension(id, StorageScope.WORKSPACE);
|
||||
this.enableExtension(id, StorageScope.GLOBAL);
|
||||
}
|
||||
}
|
||||
|
||||
dispose(): void {
|
||||
this.disposables = dispose(this.disposables);
|
||||
}
|
||||
}
|
||||
|
||||
function stripVersion(id: string): string {
|
||||
return id.replace(/-\d+\.\d+\.\d+$/, '');
|
||||
}
|
||||
Reference in New Issue
Block a user