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

introduce workbench extension management service

上级 0e874957
......@@ -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,
......
......@@ -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,62 +198,96 @@ export class ExtensionManagementService extends Disposable implements IExtension
return false;
}
async installFromGallery(gallery: IGalleryExtension): Promise<ILocalExtension> {
async updateFromGallery(gallery: IGalleryExtension, extension: ILocalExtension): Promise<ILocalExtension> {
const server = this.getServer(extension);
if (!server) {
return Promise.reject(`Invalid location ${extension.location.toString()}`);
}
// Only local server, install without any checks
if (this.servers.length === 1 && this.extensionManagementServerService.localExtensionManagementServer) {
return this.extensionManagementServerService.localExtensionManagementServer.extensionManagementService.installFromGallery(gallery);
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);
}
}
if (servers.length) {
return Promise.all(servers.map(server => server.extensionManagementService.installFromGallery(gallery, installOptions))).then(([local]) => local);
}
if (this.extensionManagementServerService.remoteExtensionManagementServer) {
const error = new Error(localize('cannot be installed', "Cannot install '{0}' because this extension has defined that it cannot run on the remote server.", gallery.displayName || gallery.name));
error.name = INSTALL_ERROR_NOT_SUPPORTED;
return Promise.reject(error);
}
const error = new Error(localize('cannot be installed on web', "Cannot install '{0}' because this extension has defined that it cannot run on the web server.", gallery.displayName || gallery.name));
error.name = INSTALL_ERROR_NOT_SUPPORTED;
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.extensionManagementService.installFromGallery(gallery);
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.extensionManagementService.installFromGallery(gallery);
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.extensionManagementService.installFromGallery(gallery);
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.extensionManagementService.installFromGallery(gallery);
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.extensionManagementService.installFromGallery(gallery);
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.extensionManagementService.installFromGallery(gallery);
return this.extensionManagementServerService.webExtensionManagementServer;
}
if (this.extensionManagementServerService.remoteExtensionManagementServer) {
const error = new Error(localize('cannot be installed', "Cannot install '{0}' because this extension has defined that it cannot run on the remote server.", gallery.displayName || gallery.name));
error.name = INSTALL_ERROR_NOT_SUPPORTED;
return Promise.reject(error);
}
const error = new Error(localize('cannot be installed on web', "Cannot install '{0}' because this extension has defined that it cannot run on the web server.", gallery.displayName || gallery.name));
error.name = INSTALL_ERROR_NOT_SUPPORTED;
return Promise.reject(error);
return undefined;
}
getExtensionsReport(): Promise<IReportedExtension[]> {
......
......@@ -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);
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册