Skip to content

Commit

Permalink
Merge pull request #118664 from microsoft/aeschli/extensionKindContro…
Browse files Browse the repository at this point in the history
…ller

add ExtensionKindController
  • Loading branch information
aeschli authored Mar 11, 2021
2 parents 3fb39ad + 7cae7b5 commit 97efcde
Show file tree
Hide file tree
Showing 11 changed files with 132 additions and 87 deletions.
12 changes: 8 additions & 4 deletions src/vs/workbench/api/browser/mainThreadCLICommands.ts
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,7 @@ import { IOpenerService } from 'vs/platform/opener/common/opener';
import { IProductService } from 'vs/platform/product/common/productService';
import { IWorkbenchEnvironmentService } from 'vs/workbench/services/environment/common/environmentService';
import { IExtensionManagementServerService } from 'vs/workbench/services/extensionManagement/common/extensionManagement';
import { canExecuteOnWorkspace } from 'vs/workbench/services/extensions/common/extensionsUtil';
import { ExtensionKindController } from 'vs/workbench/services/extensions/common/extensionsUtil';
import { IExtensionManifest } from 'vs/workbench/workbench.web.api';


Expand Down Expand Up @@ -78,10 +78,12 @@ class RemoteExtensionCLIManagementService extends ExtensionManagementCLIService

private _location: string | undefined;

private readonly _extensionKindController: ExtensionKindController;

constructor(
@IExtensionManagementService extensionManagementService: IExtensionManagementService,
@IProductService private readonly productService: IProductService,
@IConfigurationService private readonly configurationService: IConfigurationService,
@IProductService productService: IProductService,
@IConfigurationService configurationService: IConfigurationService,
@IExtensionGalleryService extensionGalleryService: IExtensionGalleryService,
@ILocalizationsService localizationsService: ILocalizationsService,
@ILabelService labelService: ILabelService,
Expand All @@ -91,14 +93,16 @@ class RemoteExtensionCLIManagementService extends ExtensionManagementCLIService

const remoteAuthority = envService.remoteAuthority;
this._location = remoteAuthority ? labelService.getHostLabel(Schemas.vscodeRemote, remoteAuthority) : undefined;

this._extensionKindController = new ExtensionKindController(productService, configurationService);
}

protected get location(): string | undefined {
return this._location;
}

protected validateExtensionKind(manifest: IExtensionManifest, output: CLIOutput): boolean {
if (!canExecuteOnWorkspace(manifest, this.productService, this.configurationService)) {
if (!this._extensionKindController.canExecuteOnWorkspace(manifest)) {
output.log(localize('cannot be installed', "Cannot install the '{0}' extension because it is declared to not run in this setup.", getExtensionId(manifest.publisher, manifest.name)));
return false;
}
Expand Down
48 changes: 30 additions & 18 deletions src/vs/workbench/contrib/extensions/browser/extensionsActions.ts
Original file line number Diff line number Diff line change
Expand Up @@ -45,7 +45,7 @@ import { alert } from 'vs/base/browser/ui/aria/aria';
import { coalesce } from 'vs/base/common/arrays';
import { IWorkbenchThemeService, IWorkbenchTheme, IWorkbenchColorTheme, IWorkbenchFileIconTheme, IWorkbenchProductIconTheme } from 'vs/workbench/services/themes/common/workbenchThemeService';
import { ILabelService } from 'vs/platform/label/common/label';
import { prefersExecuteOnUI, prefersExecuteOnWorkspace, canExecuteOnUI, canExecuteOnWorkspace, prefersExecuteOnWeb } from 'vs/workbench/services/extensions/common/extensionsUtil';
import { ExtensionKindController } from 'vs/workbench/services/extensions/common/extensionsUtil';
import { ITextFileService } from 'vs/workbench/services/textfile/common/textfiles';
import { IProductService } from 'vs/platform/product/common/productService';
import { IDialogService } from 'vs/platform/dialogs/common/dialogs';
Expand Down Expand Up @@ -435,6 +435,8 @@ export abstract class InstallInOtherServerAction extends ExtensionAction {
private static readonly Class = `${ExtensionAction.LABEL_ACTION_CLASS} prominent install`;
private static readonly InstallingClass = `${ExtensionAction.LABEL_ACTION_CLASS} install installing`;

private _extensionKindController: ExtensionKindController;

updateWhenCounterExtensionChanges: boolean = true;

constructor(
Expand All @@ -443,11 +445,13 @@ export abstract class InstallInOtherServerAction extends ExtensionAction {
private readonly canInstallAnyWhere: boolean,
@IExtensionsWorkbenchService private readonly extensionsWorkbenchService: IExtensionsWorkbenchService,
@IExtensionManagementServerService protected readonly extensionManagementServerService: IExtensionManagementServerService,
@IProductService private readonly productService: IProductService,
@IConfigurationService private readonly configurationService: IConfigurationService,
@IProductService productService: IProductService,
@IConfigurationService configurationService: IConfigurationService,
) {
super(id, InstallInOtherServerAction.INSTALL_LABEL, InstallInOtherServerAction.Class, false);
this.update();

this._extensionKindController = new ExtensionKindController(productService, configurationService);
}

update(): void {
Expand Down Expand Up @@ -489,28 +493,28 @@ export abstract class InstallInOtherServerAction extends ExtensionAction {
}

// Prefers to run on UI
if (this.server === this.extensionManagementServerService.localExtensionManagementServer && prefersExecuteOnUI(this.extension.local.manifest, this.productService, this.configurationService)) {
if (this.server === this.extensionManagementServerService.localExtensionManagementServer && this._extensionKindController.prefersExecuteOnUI(this.extension.local.manifest)) {
return true;
}

// Prefers to run on Workspace
if (this.server === this.extensionManagementServerService.remoteExtensionManagementServer && prefersExecuteOnWorkspace(this.extension.local.manifest, this.productService, this.configurationService)) {
if (this.server === this.extensionManagementServerService.remoteExtensionManagementServer && this._extensionKindController.prefersExecuteOnWorkspace(this.extension.local.manifest)) {
return true;
}

// Prefers to run on Web
if (this.server === this.extensionManagementServerService.webExtensionManagementServer && prefersExecuteOnWeb(this.extension.local.manifest, this.productService, this.configurationService)) {
if (this.server === this.extensionManagementServerService.webExtensionManagementServer && this._extensionKindController.prefersExecuteOnWeb(this.extension.local.manifest)) {
return true;
}

if (this.canInstallAnyWhere) {
// Can run on UI
if (this.server === this.extensionManagementServerService.localExtensionManagementServer && canExecuteOnUI(this.extension.local.manifest, this.productService, this.configurationService)) {
if (this.server === this.extensionManagementServerService.localExtensionManagementServer && this._extensionKindController.canExecuteOnUI(this.extension.local.manifest)) {
return true;
}

// Can run on Workspace
if (this.server === this.extensionManagementServerService.remoteExtensionManagementServer && canExecuteOnWorkspace(this.extension.local.manifest, this.productService, this.configurationService)) {
if (this.server === this.extensionManagementServerService.remoteExtensionManagementServer && this._extensionKindController.canExecuteOnWorkspace(this.extension.local.manifest)) {
return true;
}
}
Expand Down Expand Up @@ -1193,18 +1197,22 @@ export class ReloadAction extends ExtensionAction {
updateWhenCounterExtensionChanges: boolean = true;
private _runningExtensions: IExtensionDescription[] | null = null;

private _extensionKindController: ExtensionKindController;

constructor(
@IExtensionsWorkbenchService private readonly extensionsWorkbenchService: IExtensionsWorkbenchService,
@IHostService private readonly hostService: IHostService,
@IExtensionService private readonly extensionService: IExtensionService,
@IWorkbenchExtensionEnablementService private readonly extensionEnablementService: IWorkbenchExtensionEnablementService,
@IExtensionManagementServerService private readonly extensionManagementServerService: IExtensionManagementServerService,
@IProductService private readonly productService: IProductService,
@IConfigurationService private readonly configurationService: IConfigurationService,
@IProductService productService: IProductService,
@IConfigurationService configurationService: IConfigurationService,
) {
super('extensions.reload', localize('reloadAction', "Reload"), ReloadAction.DisabledClass, false);
this._register(this.extensionService.onDidChangeExtensions(this.updateRunningExtensions, this));
this.updateRunningExtensions();

this._extensionKindController = new ExtensionKindController(productService, configurationService);
}

private updateRunningExtensions(): void {
Expand Down Expand Up @@ -1272,15 +1280,15 @@ export class ReloadAction extends ExtensionAction {
const extensionInOtherServer = this.extensionsWorkbenchService.installed.filter(e => areSameExtensions(e.identifier, this.extension!.identifier) && e.server !== this.extension!.server)[0];
if (extensionInOtherServer) {
// This extension prefers to run on UI/Local side but is running in remote
if (runningExtensionServer === this.extensionManagementServerService.remoteExtensionManagementServer && prefersExecuteOnUI(this.extension.local!.manifest, this.productService, this.configurationService)) {
if (runningExtensionServer === this.extensionManagementServerService.remoteExtensionManagementServer && this._extensionKindController.prefersExecuteOnUI(this.extension.local!.manifest)) {
this.enabled = true;
this.label = localize('reloadRequired', "Reload Required");
this.tooltip = localize('enable locally', "Please reload Visual Studio Code to enable this extension locally.");
return;
}

// This extension prefers to run on Workspace/Remote side but is running in local
if (runningExtensionServer === this.extensionManagementServerService.localExtensionManagementServer && prefersExecuteOnWorkspace(this.extension.local!.manifest, this.productService, this.configurationService)) {
if (runningExtensionServer === this.extensionManagementServerService.localExtensionManagementServer && this._extensionKindController.prefersExecuteOnWorkspace(this.extension.local!.manifest)) {
this.enabled = true;
this.label = localize('reloadRequired', "Reload Required");
this.tooltip = localize('enable remote', "Please reload Visual Studio Code to enable this extension in {0}.", this.extensionManagementServerService.remoteExtensionManagementServer?.label);
Expand All @@ -1292,15 +1300,15 @@ export class ReloadAction extends ExtensionAction {

if (this.extension.server === this.extensionManagementServerService.localExtensionManagementServer && runningExtensionServer === this.extensionManagementServerService.remoteExtensionManagementServer) {
// This extension prefers to run on UI/Local side but is running in remote
if (prefersExecuteOnUI(this.extension.local!.manifest, this.productService, this.configurationService)) {
if (this._extensionKindController.prefersExecuteOnUI(this.extension.local!.manifest)) {
this.enabled = true;
this.label = localize('reloadRequired', "Reload Required");
this.tooltip = localize('postEnableTooltip', "Please reload Visual Studio Code to enable this extension.");
}
}
if (this.extension.server === this.extensionManagementServerService.remoteExtensionManagementServer && runningExtensionServer === this.extensionManagementServerService.localExtensionManagementServer) {
// This extension prefers to run on Workspace/Remote side but is running in local
if (prefersExecuteOnWorkspace(this.extension.local!.manifest, this.productService, this.configurationService)) {
if (this._extensionKindController.prefersExecuteOnWorkspace(this.extension.local!.manifest)) {
this.enabled = true;
this.label = localize('reloadRequired', "Reload Required");
this.tooltip = localize('postEnableTooltip', "Please reload Visual Studio Code to enable this extension.");
Expand Down Expand Up @@ -2064,20 +2072,24 @@ export class SystemDisabledWarningAction extends ExtensionAction {
updateWhenCounterExtensionChanges: boolean = true;
private _runningExtensions: IExtensionDescription[] | null = null;

private _extensionKindController: ExtensionKindController;

constructor(
@IExtensionManagementServerService private readonly extensionManagementServerService: IExtensionManagementServerService,
@ILabelService private readonly labelService: ILabelService,
@IExtensionsWorkbenchService private readonly extensionsWorkbenchService: IExtensionsWorkbenchService,
@IExtensionService private readonly extensionService: IExtensionService,
@IProductService private readonly productService: IProductService,
@IConfigurationService private readonly configurationService: IConfigurationService,
@IProductService productService: IProductService,
@IConfigurationService configurationService: IConfigurationService,
@IWorkspaceTrustService private readonly workspaceTrustService: IWorkspaceTrustService
) {
super('extensions.install', '', `${SystemDisabledWarningAction.CLASS} hide`, false);
this._register(this.labelService.onDidChangeFormatters(() => this.update(), this));
this._register(this.extensionService.onDidChangeExtensions(this.updateRunningExtensions, this));
this.updateRunningExtensions();
this.update();

this._extensionKindController = new ExtensionKindController(productService, configurationService);
}

private updateRunningExtensions(): void {
Expand Down Expand Up @@ -2123,14 +2135,14 @@ export class SystemDisabledWarningAction extends ExtensionAction {
const runningExtension = this._runningExtensions.filter(e => areSameExtensions({ id: e.identifier.value, uuid: e.uuid }, this.extension!.identifier))[0];
const runningExtensionServer = runningExtension ? this.extensionManagementServerService.getExtensionManagementServer(toExtension(runningExtension)) : null;
if (this.extension.server === this.extensionManagementServerService.localExtensionManagementServer && runningExtensionServer === this.extensionManagementServerService.remoteExtensionManagementServer) {
if (prefersExecuteOnWorkspace(this.extension.local!.manifest, this.productService, this.configurationService)) {
if (this._extensionKindController.prefersExecuteOnWorkspace(this.extension.local!.manifest)) {
this.class = `${SystemDisabledWarningAction.INFO_CLASS}`;
this.tooltip = localize('disabled locally', "Extension is enabled on '{0}' and disabled locally.", this.extensionManagementServerService.remoteExtensionManagementServer.label);
}
return;
}
if (this.extension.server === this.extensionManagementServerService.remoteExtensionManagementServer && runningExtensionServer === this.extensionManagementServerService.localExtensionManagementServer) {
if (prefersExecuteOnUI(this.extension.local!.manifest, this.productService, this.configurationService)) {
if (this._extensionKindController.prefersExecuteOnUI(this.extension.local!.manifest)) {
this.class = `${SystemDisabledWarningAction.INFO_CLASS}`;
this.tooltip = localize('disabled remotely', "Extension is enabled locally and disabled on '{0}'.", this.extensionManagementServerService.remoteExtensionManagementServer.label);
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -36,7 +36,7 @@ import { IFileService } from 'vs/platform/files/common/files';
import { IExtensionManifest, ExtensionType, IExtension as IPlatformExtension } from 'vs/platform/extensions/common/extensions';
import { IModeService } from 'vs/editor/common/services/modeService';
import { IProductService } from 'vs/platform/product/common/productService';
import { getExtensionKind } from 'vs/workbench/services/extensions/common/extensionsUtil';
import { ExtensionKindController } from 'vs/workbench/services/extensions/common/extensionsUtil';
import { FileAccess } from 'vs/base/common/network';
import { IIgnoredExtensionsManagementService } from 'vs/platform/userDataSync/common/ignoredExtensions';
import { IUserDataAutoSyncService } from 'vs/platform/userDataSync/common/userDataSync';
Expand Down Expand Up @@ -506,6 +506,8 @@ export class ExtensionsWorkbenchService extends Disposable implements IExtension

private installing: IExtension[] = [];

private readonly extensionKindController: ExtensionKindController;

constructor(
@IInstantiationService private readonly instantiationService: IInstantiationService,
@IEditorService private readonly editorService: IEditorService,
Expand Down Expand Up @@ -568,6 +570,8 @@ export class ExtensionsWorkbenchService extends Disposable implements IExtension
this.updateContexts();
this.updateActivity();
}));

this.extensionKindController = new ExtensionKindController(productService, configurationService);
}

get local(): IExtension[] {
Expand Down Expand Up @@ -694,7 +698,7 @@ export class ExtensionsWorkbenchService extends Disposable implements IExtension
return extensionsToChoose[0];
}

const extensionKinds = getExtensionKind(manifest, this.productService, this.configurationService);
const extensionKinds = this.extensionKindController.getExtensionKind(manifest);

let extension = extensionsToChoose.find(extension => {
for (const extensionKind of extensionKinds) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,7 @@ import { IStorageService, StorageScope } from 'vs/platform/storage/common/storag
import { IWorkbenchEnvironmentService } from 'vs/workbench/services/environment/common/environmentService';
import { IExtension, isAuthenticaionProviderExtension, isLanguagePackExtension } from 'vs/platform/extensions/common/extensions';
import { IConfigurationService } from 'vs/platform/configuration/common/configuration';
import { getExtensionKind } from 'vs/workbench/services/extensions/common/extensionsUtil';
import { ExtensionKindController } from 'vs/workbench/services/extensions/common/extensionsUtil';
import { registerSingleton } from 'vs/platform/instantiation/common/extensions';
import { IProductService } from 'vs/platform/product/common/productService';
import { StorageManager } from 'vs/platform/extensionManagement/common/extensionEnablementService';
Expand All @@ -40,6 +40,8 @@ export class ExtensionEnablementService extends Disposable implements IWorkbench
private readonly storageManger: StorageManager;
private extensionsDisabledByTrustRequirement: IExtension[] = [];

private readonly extensionKindController: ExtensionKindController;

constructor(
@IStorageService storageService: IStorageService,
@IGlobalExtensionEnablementService protected readonly globalExtensionEnablementService: IGlobalExtensionEnablementService,
Expand All @@ -48,7 +50,7 @@ export class ExtensionEnablementService extends Disposable implements IWorkbench
@IExtensionManagementService private readonly extensionManagementService: IExtensionManagementService,
@IConfigurationService private readonly configurationService: IConfigurationService,
@IExtensionManagementServerService private readonly extensionManagementServerService: IExtensionManagementServerService,
@IProductService private readonly productService: IProductService,
@IProductService productService: IProductService,
@IUserDataAutoSyncEnablementService private readonly userDataAutoSyncEnablementService: IUserDataAutoSyncEnablementService,
@IUserDataSyncAccountService private readonly userDataSyncAccountService: IUserDataSyncAccountService,
@ILifecycleService private readonly lifecycleService: ILifecycleService,
Expand Down Expand Up @@ -86,6 +88,8 @@ export class ExtensionEnablementService extends Disposable implements IWorkbench
}]);
});
}

this.extensionKindController = new ExtensionKindController(productService, configurationService);
}

private get hasWorkspace(): boolean {
Expand Down Expand Up @@ -244,7 +248,7 @@ export class ExtensionEnablementService extends Disposable implements IWorkbench
private _isDisabledByExtensionKind(extension: IExtension): boolean {
if (this.extensionManagementServerService.remoteExtensionManagementServer || this.extensionManagementServerService.webExtensionManagementServer) {
const server = this.extensionManagementServerService.getExtensionManagementServer(extension);
for (const extensionKind of getExtensionKind(extension.manifest, this.productService, this.configurationService)) {
for (const extensionKind of this.extensionKindController.getExtensionKind(extension.manifest)) {
if (extensionKind === 'ui') {
if (this.extensionManagementServerService.localExtensionManagementServer && this.extensionManagementServerService.localExtensionManagementServer === server) {
return false;
Expand Down
Loading

0 comments on commit 97efcde

Please sign in to comment.