mirror of
https://github.com/microsoft/vscode.git
synced 2026-07-13 15:35:20 +01:00
introduce workbench extension management service
This commit is contained in:
@@ -13,10 +13,10 @@ import { Disposable } from 'vs/base/common/lifecycle';
|
||||
import { IPager, mapPager, singlePagePager } from 'vs/base/common/paging';
|
||||
import { ITelemetryService } from 'vs/platform/telemetry/common/telemetry';
|
||||
import {
|
||||
IExtensionManagementService, IExtensionGalleryService, ILocalExtension, IGalleryExtension, IQueryOptions,
|
||||
IExtensionGalleryService, ILocalExtension, IGalleryExtension, IQueryOptions,
|
||||
InstallExtensionEvent, DidInstallExtensionEvent, DidUninstallExtensionEvent, IExtensionIdentifier, InstallOperation, DefaultIconPath
|
||||
} from 'vs/platform/extensionManagement/common/extensionManagement';
|
||||
import { IWorkbenchExtensionEnablementService, EnablementState, IExtensionManagementServerService, IExtensionManagementServer } from 'vs/workbench/services/extensionManagement/common/extensionManagement';
|
||||
import { IWorkbenchExtensionEnablementService, EnablementState, IExtensionManagementServerService, IExtensionManagementServer, IWorkbenchExtensioManagementService } from 'vs/workbench/services/extensionManagement/common/extensionManagement';
|
||||
import { getGalleryExtensionTelemetryData, getLocalExtensionTelemetryData, areSameExtensions, getMaliciousExtensionsSet, groupByExtension, ExtensionIdentifierWithVersion, getGalleryExtensionId } from 'vs/platform/extensionManagement/common/extensionManagementUtil';
|
||||
import { IInstantiationService } from 'vs/platform/instantiation/common/instantiation';
|
||||
import { IConfigurationService, ConfigurationTarget } from 'vs/platform/configuration/common/configuration';
|
||||
@@ -33,7 +33,7 @@ import * as resources from 'vs/base/common/resources';
|
||||
import { CancellationToken } from 'vs/base/common/cancellation';
|
||||
import { IStorageService, StorageScope } from 'vs/platform/storage/common/storage';
|
||||
import { IFileService } from 'vs/platform/files/common/files';
|
||||
import { IExtensionManifest, ExtensionType, IExtension as IPlatformExtension, isLanguagePackExtension } from 'vs/platform/extensions/common/extensions';
|
||||
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 { getIgnoredExtensions } from 'vs/platform/userDataSync/common/extensionsMerge';
|
||||
@@ -511,7 +511,7 @@ export class ExtensionsWorkbenchService extends Disposable implements IExtension
|
||||
constructor(
|
||||
@IInstantiationService private readonly instantiationService: IInstantiationService,
|
||||
@IEditorService private readonly editorService: IEditorService,
|
||||
@IExtensionManagementService private readonly extensionService: IExtensionManagementService,
|
||||
@IWorkbenchExtensioManagementService private readonly extensionManagementService: IWorkbenchExtensioManagementService,
|
||||
@IExtensionGalleryService private readonly galleryService: IExtensionGalleryService,
|
||||
@IConfigurationService private readonly configurationService: IConfigurationService,
|
||||
@ITelemetryService private readonly telemetryService: ITelemetryService,
|
||||
@@ -629,7 +629,7 @@ export class ExtensionsWorkbenchService extends Disposable implements IExtension
|
||||
const options: IQueryOptions = CancellationToken.isCancellationToken(arg1) ? {} : arg1;
|
||||
const token: CancellationToken = CancellationToken.isCancellationToken(arg1) ? arg1 : arg2;
|
||||
options.text = options.text ? this.resolveQueryText(options.text) : options.text;
|
||||
return this.extensionService.getExtensionsReport()
|
||||
return this.extensionManagementService.getExtensionsReport()
|
||||
.then(report => {
|
||||
const maliciousSet = getMaliciousExtensionsSet(report);
|
||||
|
||||
@@ -937,7 +937,7 @@ export class ExtensionsWorkbenchService extends Disposable implements IExtension
|
||||
location: ProgressLocation.Extensions,
|
||||
title: nls.localize('uninstallingExtension', 'Uninstalling extension....'),
|
||||
source: `${toUninstall.identifier.id}`
|
||||
}, () => this.extensionService.uninstall(toUninstall).then(() => undefined));
|
||||
}, () => this.extensionManagementService.uninstall(toUninstall).then(() => undefined));
|
||||
}
|
||||
|
||||
installVersion(extension: IExtension, version: string): Promise<IExtension> {
|
||||
@@ -976,7 +976,7 @@ export class ExtensionsWorkbenchService extends Disposable implements IExtension
|
||||
return this.progressService.withProgress({
|
||||
location: ProgressLocation.Extensions,
|
||||
source: `${toReinstall.identifier.id}`
|
||||
}, () => this.extensionService.reinstallFromGallery(toReinstall).then(() => this.local.filter(local => areSameExtensions(local.identifier, extension.identifier))[0]));
|
||||
}, () => this.extensionManagementService.reinstallFromGallery(toReinstall).then(() => this.local.filter(local => areSameExtensions(local.identifier, extension.identifier))[0]));
|
||||
}
|
||||
|
||||
isExtensionIgnoredToSync(extension: IExtension): boolean {
|
||||
@@ -1019,9 +1019,9 @@ export class ExtensionsWorkbenchService extends Disposable implements IExtension
|
||||
}
|
||||
|
||||
private async installFromVSIX(vsix: URI): Promise<IExtension> {
|
||||
const manifest = await this.extensionService.getManifest(vsix);
|
||||
const manifest = await this.extensionManagementService.getManifest(vsix);
|
||||
const existingExtension = this.local.find(local => areSameExtensions(local.identifier, { id: getGalleryExtensionId(manifest.publisher, manifest.name) }));
|
||||
const { identifier } = await this.extensionService.install(vsix);
|
||||
const { identifier } = await this.extensionManagementService.install(vsix);
|
||||
|
||||
if (existingExtension && existingExtension.latestVersion !== manifest.version) {
|
||||
this.ignoreAutoUpdate(new ExtensionIdentifierWithVersion(identifier, manifest.version));
|
||||
@@ -1034,8 +1034,11 @@ export class ExtensionsWorkbenchService extends Disposable implements IExtension
|
||||
this.installing.push(extension);
|
||||
this._onChange.fire(extension);
|
||||
try {
|
||||
const extensionService = extension.server && extension.local && !isLanguagePackExtension(extension.local.manifest) ? extension.server.extensionManagementService : this.extensionService;
|
||||
await extensionService.installFromGallery(gallery);
|
||||
if (extension.state === ExtensionState.Installed && extension.local) {
|
||||
await this.extensionManagementService.updateFromGallery(gallery, extension.local);
|
||||
} else {
|
||||
await this.extensionManagementService.installFromGallery(gallery);
|
||||
}
|
||||
const ids: string[] | undefined = extension.identifier.uuid ? [extension.identifier.uuid] : undefined;
|
||||
const names: string[] | undefined = extension.identifier.uuid ? undefined : [extension.identifier.id];
|
||||
this.queryGallery({ names, ids, pageSize: 1 }, CancellationToken.None);
|
||||
|
||||
@@ -6,17 +6,16 @@
|
||||
import { Event } from 'vs/base/common/event';
|
||||
import { createDecorator } from 'vs/platform/instantiation/common/instantiation';
|
||||
import { IExtension, IScannedExtension, ExtensionType, ITranslatedScannedExtension } from 'vs/platform/extensions/common/extensions';
|
||||
import { IExtensionManagementService, IGalleryExtension, IExtensionIdentifier } from 'vs/platform/extensionManagement/common/extensionManagement';
|
||||
import { IExtensionManagementService, IGalleryExtension, IExtensionIdentifier, ILocalExtension } from 'vs/platform/extensionManagement/common/extensionManagement';
|
||||
import { URI } from 'vs/base/common/uri';
|
||||
|
||||
export const IExtensionManagementServerService = createDecorator<IExtensionManagementServerService>('extensionManagementServerService');
|
||||
|
||||
export interface IExtensionManagementServer {
|
||||
id: string;
|
||||
label: string;
|
||||
extensionManagementService: IExtensionManagementService;
|
||||
}
|
||||
|
||||
export const IExtensionManagementServerService = createDecorator<IExtensionManagementServerService>('extensionManagementServerService');
|
||||
export interface IExtensionManagementServerService {
|
||||
readonly _serviceBrand: undefined;
|
||||
readonly localExtensionManagementServer: IExtensionManagementServer | null;
|
||||
@@ -25,6 +24,12 @@ export interface IExtensionManagementServerService {
|
||||
getExtensionManagementServer(extension: IExtension): IExtensionManagementServer | null;
|
||||
}
|
||||
|
||||
export const IWorkbenchExtensioManagementService = createDecorator<IWorkbenchExtensioManagementService>('extensionManagementService');
|
||||
export interface IWorkbenchExtensioManagementService extends IExtensionManagementService {
|
||||
readonly _serviceBrand: undefined;
|
||||
updateFromGallery(gallery: IGalleryExtension, extension: ILocalExtension): Promise<ILocalExtension>;
|
||||
}
|
||||
|
||||
export const enum EnablementState {
|
||||
DisabledByExtensionKind,
|
||||
DisabledByEnvironemt,
|
||||
|
||||
+71
-37
@@ -5,9 +5,9 @@
|
||||
|
||||
import { Event, EventMultiplexer } from 'vs/base/common/event';
|
||||
import {
|
||||
IExtensionManagementService, ILocalExtension, IGalleryExtension, InstallExtensionEvent, DidInstallExtensionEvent, IExtensionIdentifier, DidUninstallExtensionEvent, IReportedExtension, IGalleryMetadata, IExtensionGalleryService, INSTALL_ERROR_NOT_SUPPORTED
|
||||
ILocalExtension, IGalleryExtension, InstallExtensionEvent, DidInstallExtensionEvent, IExtensionIdentifier, DidUninstallExtensionEvent, IReportedExtension, IGalleryMetadata, IExtensionGalleryService, INSTALL_ERROR_NOT_SUPPORTED, InstallOptions
|
||||
} from 'vs/platform/extensionManagement/common/extensionManagement';
|
||||
import { IExtensionManagementServer, IExtensionManagementServerService } from 'vs/workbench/services/extensionManagement/common/extensionManagement';
|
||||
import { IExtensionManagementServer, IExtensionManagementServerService, IWorkbenchExtensioManagementService } from 'vs/workbench/services/extensionManagement/common/extensionManagement';
|
||||
import { ExtensionType, isLanguagePackExtension, IExtensionManifest } from 'vs/platform/extensions/common/extensions';
|
||||
import { URI } from 'vs/base/common/uri';
|
||||
import { Disposable } from 'vs/base/common/lifecycle';
|
||||
@@ -21,7 +21,7 @@ import { Schemas } from 'vs/base/common/network';
|
||||
import { IDownloadService } from 'vs/platform/download/common/download';
|
||||
import { flatten } from 'vs/base/common/arrays';
|
||||
|
||||
export class ExtensionManagementService extends Disposable implements IExtensionManagementService {
|
||||
export class ExtensionManagementService extends Disposable implements IWorkbenchExtensioManagementService {
|
||||
|
||||
declare readonly _serviceBrand: undefined;
|
||||
|
||||
@@ -198,51 +198,45 @@ export class ExtensionManagementService extends Disposable implements IExtension
|
||||
return false;
|
||||
}
|
||||
|
||||
async installFromGallery(gallery: IGalleryExtension): Promise<ILocalExtension> {
|
||||
|
||||
// Only local server, install without any checks
|
||||
if (this.servers.length === 1 && this.extensionManagementServerService.localExtensionManagementServer) {
|
||||
return this.extensionManagementServerService.localExtensionManagementServer.extensionManagementService.installFromGallery(gallery);
|
||||
async updateFromGallery(gallery: IGalleryExtension, extension: ILocalExtension): Promise<ILocalExtension> {
|
||||
const server = this.getServer(extension);
|
||||
if (!server) {
|
||||
return Promise.reject(`Invalid location ${extension.location.toString()}`);
|
||||
}
|
||||
|
||||
const servers: IExtensionManagementServer[] = [];
|
||||
|
||||
// Update Language pack on all servers
|
||||
if (isLanguagePackExtension(extension.manifest)) {
|
||||
servers.push(...this.servers);
|
||||
} else {
|
||||
servers.push(server);
|
||||
}
|
||||
|
||||
return Promise.all(servers.map(server => server.extensionManagementService.installFromGallery(gallery))).then(([local]) => local);
|
||||
}
|
||||
|
||||
async installFromGallery(gallery: IGalleryExtension, installOptions?: InstallOptions): Promise<ILocalExtension> {
|
||||
|
||||
const manifest = await this.extensionGalleryService.getManifest(gallery, CancellationToken.None);
|
||||
if (!manifest) {
|
||||
return Promise.reject(localize('Manifest is not found', "Installing Extension {0} failed: Manifest is not found.", gallery.displayName || gallery.name));
|
||||
}
|
||||
|
||||
const servers: IExtensionManagementServer[] = [];
|
||||
|
||||
// Install Language pack on all servers
|
||||
if (isLanguagePackExtension(manifest)) {
|
||||
return Promise.all(this.servers.map(server => server.extensionManagementService.installFromGallery(gallery))).then(([local]) => local);
|
||||
servers.push(...this.servers);
|
||||
} else {
|
||||
const server = this.getExtensionManagementServerToInstall(manifest);
|
||||
if (server) {
|
||||
servers.push(server);
|
||||
}
|
||||
}
|
||||
|
||||
// 1. Install on preferred location
|
||||
|
||||
// Install UI preferred extension on local server
|
||||
if (prefersExecuteOnUI(manifest, this.productService, this.configurationService) && this.extensionManagementServerService.localExtensionManagementServer) {
|
||||
return this.extensionManagementServerService.localExtensionManagementServer.extensionManagementService.installFromGallery(gallery);
|
||||
}
|
||||
// Install Workspace preferred extension on remote server
|
||||
if (prefersExecuteOnWorkspace(manifest, this.productService, this.configurationService) && this.extensionManagementServerService.remoteExtensionManagementServer) {
|
||||
return this.extensionManagementServerService.remoteExtensionManagementServer.extensionManagementService.installFromGallery(gallery);
|
||||
}
|
||||
// Install Web preferred extension on web server
|
||||
if (prefersExecuteOnWeb(manifest, this.productService, this.configurationService) && this.extensionManagementServerService.webExtensionManagementServer) {
|
||||
return this.extensionManagementServerService.webExtensionManagementServer.extensionManagementService.installFromGallery(gallery);
|
||||
}
|
||||
|
||||
// 2. Install on supported location
|
||||
|
||||
// Install UI supported extension on local server
|
||||
if (canExecuteOnUI(manifest, this.productService, this.configurationService) && this.extensionManagementServerService.localExtensionManagementServer) {
|
||||
return this.extensionManagementServerService.localExtensionManagementServer.extensionManagementService.installFromGallery(gallery);
|
||||
}
|
||||
// Install Workspace supported extension on remote server
|
||||
if (canExecuteOnWorkspace(manifest, this.productService, this.configurationService) && this.extensionManagementServerService.remoteExtensionManagementServer) {
|
||||
return this.extensionManagementServerService.remoteExtensionManagementServer.extensionManagementService.installFromGallery(gallery);
|
||||
}
|
||||
// Install Web supported extension on web server
|
||||
if (canExecuteOnWeb(manifest, this.productService, this.configurationService) && this.extensionManagementServerService.webExtensionManagementServer) {
|
||||
return this.extensionManagementServerService.webExtensionManagementServer.extensionManagementService.installFromGallery(gallery);
|
||||
if (servers.length) {
|
||||
return Promise.all(servers.map(server => server.extensionManagementService.installFromGallery(gallery, installOptions))).then(([local]) => local);
|
||||
}
|
||||
|
||||
if (this.extensionManagementServerService.remoteExtensionManagementServer) {
|
||||
@@ -256,6 +250,46 @@ export class ExtensionManagementService extends Disposable implements IExtension
|
||||
return Promise.reject(error);
|
||||
}
|
||||
|
||||
private getExtensionManagementServerToInstall(manifest: IExtensionManifest): IExtensionManagementServer | undefined {
|
||||
|
||||
// Only local server
|
||||
if (this.servers.length === 1 && this.extensionManagementServerService.localExtensionManagementServer) {
|
||||
return this.extensionManagementServerService.localExtensionManagementServer;
|
||||
}
|
||||
|
||||
// 1. Install on preferred location
|
||||
|
||||
// Install UI preferred extension on local server
|
||||
if (prefersExecuteOnUI(manifest, this.productService, this.configurationService) && this.extensionManagementServerService.localExtensionManagementServer) {
|
||||
return this.extensionManagementServerService.localExtensionManagementServer;
|
||||
}
|
||||
// Install Workspace preferred extension on remote server
|
||||
if (prefersExecuteOnWorkspace(manifest, this.productService, this.configurationService) && this.extensionManagementServerService.remoteExtensionManagementServer) {
|
||||
return this.extensionManagementServerService.remoteExtensionManagementServer;
|
||||
}
|
||||
// Install Web preferred extension on web server
|
||||
if (prefersExecuteOnWeb(manifest, this.productService, this.configurationService) && this.extensionManagementServerService.webExtensionManagementServer) {
|
||||
return this.extensionManagementServerService.webExtensionManagementServer;
|
||||
}
|
||||
|
||||
// 2. Install on supported location
|
||||
|
||||
// Install UI supported extension on local server
|
||||
if (canExecuteOnUI(manifest, this.productService, this.configurationService) && this.extensionManagementServerService.localExtensionManagementServer) {
|
||||
return this.extensionManagementServerService.localExtensionManagementServer;
|
||||
}
|
||||
// Install Workspace supported extension on remote server
|
||||
if (canExecuteOnWorkspace(manifest, this.productService, this.configurationService) && this.extensionManagementServerService.remoteExtensionManagementServer) {
|
||||
return this.extensionManagementServerService.remoteExtensionManagementServer;
|
||||
}
|
||||
// Install Web supported extension on web server
|
||||
if (canExecuteOnWeb(manifest, this.productService, this.configurationService) && this.extensionManagementServerService.webExtensionManagementServer) {
|
||||
return this.extensionManagementServerService.webExtensionManagementServer;
|
||||
}
|
||||
|
||||
return undefined;
|
||||
}
|
||||
|
||||
getExtensionsReport(): Promise<IReportedExtension[]> {
|
||||
if (this.extensionManagementServerService.localExtensionManagementServer) {
|
||||
return this.extensionManagementServerService.localExtensionManagementServer.extensionManagementService.getExtensionsReport();
|
||||
|
||||
+3
-3
@@ -4,11 +4,11 @@
|
||||
*--------------------------------------------------------------------------------------------*/
|
||||
|
||||
import { generateUuid } from 'vs/base/common/uuid';
|
||||
import { ILocalExtension, IExtensionManagementService, IExtensionGalleryService } from 'vs/platform/extensionManagement/common/extensionManagement';
|
||||
import { ILocalExtension, IExtensionGalleryService } from 'vs/platform/extensionManagement/common/extensionManagement';
|
||||
import { URI } from 'vs/base/common/uri';
|
||||
import { ExtensionManagementService as BaseExtensionManagementService } from 'vs/workbench/services/extensionManagement/common/extensionManagementService';
|
||||
import { registerSingleton } from 'vs/platform/instantiation/common/extensions';
|
||||
import { IExtensionManagementServer, IExtensionManagementServerService } from 'vs/workbench/services/extensionManagement/common/extensionManagement';
|
||||
import { IExtensionManagementServer, IExtensionManagementServerService, IWorkbenchExtensioManagementService } from 'vs/workbench/services/extensionManagement/common/extensionManagement';
|
||||
import { Schemas } from 'vs/base/common/network';
|
||||
import { IConfigurationService } from 'vs/platform/configuration/common/configuration';
|
||||
import { IDownloadService } from 'vs/platform/download/common/download';
|
||||
@@ -39,4 +39,4 @@ export class ExtensionManagementService extends BaseExtensionManagementService {
|
||||
}
|
||||
}
|
||||
|
||||
registerSingleton(IExtensionManagementService, ExtensionManagementService);
|
||||
registerSingleton(IWorkbenchExtensioManagementService, ExtensionManagementService);
|
||||
|
||||
@@ -58,8 +58,9 @@ import { IContextMenuService } from 'vs/platform/contextview/browser/contextView
|
||||
import { ContextMenuService } from 'vs/platform/contextview/browser/contextMenuService';
|
||||
import { IBackupFileService } from 'vs/workbench/services/backup/common/backup';
|
||||
import { BackupFileService } from 'vs/workbench/services/backup/common/backupFileService';
|
||||
import { IExtensionManagementService, IExtensionTipsService } from 'vs/platform/extensionManagement/common/extensionManagement';
|
||||
import { IExtensionTipsService } from 'vs/platform/extensionManagement/common/extensionManagement';
|
||||
import { ExtensionTipsService } from 'vs/platform/extensionManagement/common/extensionTipsService';
|
||||
import { IWorkbenchExtensioManagementService } from 'vs/workbench/services/extensionManagement/common/extensionManagement';
|
||||
import { ExtensionManagementService } from 'vs/workbench/services/extensionManagement/common/extensionManagementService';
|
||||
import { ITunnelService, TunnelService } from 'vs/platform/remote/common/tunnel';
|
||||
import { ILoggerService } from 'vs/platform/log/common/log';
|
||||
@@ -79,7 +80,7 @@ import { ITitleService } from 'vs/workbench/services/title/common/titleService';
|
||||
import { TitlebarPart } from 'vs/workbench/browser/parts/titlebar/titlebarPart';
|
||||
import { ITimerService, TimerService } from 'vs/workbench/services/timer/browser/timerService';
|
||||
|
||||
registerSingleton(IExtensionManagementService, ExtensionManagementService);
|
||||
registerSingleton(IWorkbenchExtensioManagementService, ExtensionManagementService);
|
||||
registerSingleton(IBackupFileService, BackupFileService);
|
||||
registerSingleton(IAccessibilityService, AccessibilityService, true);
|
||||
registerSingleton(IContextMenuService, ContextMenuService);
|
||||
|
||||
Reference in New Issue
Block a user