Skip to content

Commit 74ae993

Browse files
committed
Add support for multiple extension management servers
1 parent 36f6604 commit 74ae993

26 files changed

Lines changed: 585 additions & 188 deletions

src/vs/platform/extensionManagement/common/extensionManagement.ts

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -312,6 +312,19 @@ export interface IExtensionManagementService {
312312
updateMetadata(local: ILocalExtension, metadata: IGalleryMetadata): TPromise<ILocalExtension>;
313313
}
314314

315+
export const IExtensionManagementServerService = createDecorator<IExtensionManagementServerService>('extensionManagementServerService');
316+
317+
export interface IExtensionManagementServer {
318+
extensionManagementService: IExtensionManagementService;
319+
location: URI;
320+
}
321+
322+
export interface IExtensionManagementServerService {
323+
_serviceBrand: any;
324+
readonly extensionManagementServers: IExtensionManagementServer[];
325+
getExtensionManagementServer(location: URI): IExtensionManagementServer;
326+
}
327+
315328
export enum EnablementState {
316329
Disabled,
317330
WorkspaceDisabled,
Lines changed: 68 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,68 @@
1+
/*---------------------------------------------------------------------------------------------
2+
* Copyright (c) Microsoft Corporation. All rights reserved.
3+
* Licensed under the MIT License. See License.txt in the project root for license information.
4+
*--------------------------------------------------------------------------------------------*/
5+
6+
import { TPromise } from 'vs/base/common/winjs.base';
7+
import { Event, EventMultiplexer } from 'vs/base/common/event';
8+
import {
9+
IExtensionManagementService, ILocalExtension, IGalleryExtension, LocalExtensionType, InstallExtensionEvent, DidInstallExtensionEvent, IExtensionIdentifier, DidUninstallExtensionEvent, IReportedExtension, IGalleryMetadata,
10+
IExtensionManagementServerService, IExtensionManagementServer
11+
} from 'vs/platform/extensionManagement/common/extensionManagement';
12+
import { flatten } from 'vs/base/common/arrays';
13+
14+
export class MulitExtensionManagementService implements IExtensionManagementService {
15+
16+
_serviceBrand: any;
17+
18+
onInstallExtension: Event<InstallExtensionEvent>;
19+
onDidInstallExtension: Event<DidInstallExtensionEvent>;
20+
onUninstallExtension: Event<IExtensionIdentifier>;
21+
onDidUninstallExtension: Event<DidUninstallExtensionEvent>;
22+
23+
private readonly servers: IExtensionManagementServer[];
24+
25+
constructor(
26+
servers: IExtensionManagementServer[],
27+
@IExtensionManagementServerService private extensionManagementServerService: IExtensionManagementServerService
28+
) {
29+
this.servers = servers ? servers : this.extensionManagementServerService.extensionManagementServers;
30+
this.onInstallExtension = this.servers.reduce((emitter: EventMultiplexer<InstallExtensionEvent>, server) => { emitter.add(server.extensionManagementService.onInstallExtension); return emitter; }, new EventMultiplexer<InstallExtensionEvent>()).event;
31+
this.onDidInstallExtension = this.servers.reduce((emitter: EventMultiplexer<DidInstallExtensionEvent>, server) => { emitter.add(server.extensionManagementService.onDidInstallExtension); return emitter; }, new EventMultiplexer<DidInstallExtensionEvent>()).event;
32+
this.onUninstallExtension = this.servers.reduce((emitter: EventMultiplexer<IExtensionIdentifier>, server) => { emitter.add(server.extensionManagementService.onUninstallExtension); return emitter; }, new EventMultiplexer<IExtensionIdentifier>()).event;
33+
this.onDidUninstallExtension = this.servers.reduce((emitter: EventMultiplexer<DidUninstallExtensionEvent>, server) => { emitter.add(server.extensionManagementService.onDidUninstallExtension); return emitter; }, new EventMultiplexer<DidUninstallExtensionEvent>()).event;
34+
}
35+
36+
getInstalled(type?: LocalExtensionType): TPromise<ILocalExtension[]> {
37+
return TPromise.join(this.servers.map(({ extensionManagementService }) => extensionManagementService.getInstalled(type)))
38+
.then(result => flatten(result));
39+
}
40+
41+
uninstall(extension: ILocalExtension, force?: boolean): TPromise<void> {
42+
return this.getServer(extension).extensionManagementService.uninstall(extension, force);
43+
}
44+
45+
reinstallFromGallery(extension: ILocalExtension): TPromise<ILocalExtension> {
46+
return this.getServer(extension).extensionManagementService.reinstallFromGallery(extension);
47+
}
48+
49+
updateMetadata(extension: ILocalExtension, metadata: IGalleryMetadata): TPromise<ILocalExtension> {
50+
return this.getServer(extension).extensionManagementService.updateMetadata(extension, metadata);
51+
}
52+
53+
install(zipPath: string): TPromise<ILocalExtension> {
54+
return this.servers[0].extensionManagementService.install(zipPath);
55+
}
56+
57+
installFromGallery(extension: IGalleryExtension): TPromise<ILocalExtension> {
58+
return this.servers[0].extensionManagementService.installFromGallery(extension);
59+
}
60+
61+
getExtensionsReport(): TPromise<IReportedExtension[]> {
62+
return this.servers[0].extensionManagementService.getExtensionsReport();
63+
}
64+
65+
private getServer(extension: ILocalExtension): IExtensionManagementServer {
66+
return this.extensionManagementServerService.getExtensionManagementServer(extension.location);
67+
}
68+
}

src/vs/workbench/electron-browser/shell.ts

Lines changed: 6 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -64,7 +64,7 @@ import { getDelayedChannel, IPCClient } from 'vs/base/parts/ipc/common/ipc';
6464
import { connect as connectNet } from 'vs/base/parts/ipc/node/ipc.net';
6565
import { DefaultURITransformer } from 'vs/base/common/uriIpc';
6666
import { IExtensionManagementChannel, ExtensionManagementChannelClient } from 'vs/platform/extensionManagement/common/extensionManagementIpc';
67-
import { IExtensionManagementService, IExtensionEnablementService } from 'vs/platform/extensionManagement/common/extensionManagement';
67+
import { IExtensionManagementService, IExtensionEnablementService, IExtensionManagementServerService } from 'vs/platform/extensionManagement/common/extensionManagement';
6868
import { ExtensionEnablementService } from 'vs/platform/extensionManagement/common/extensionEnablementService';
6969
import { ITimerService } from 'vs/workbench/services/timer/common/timerService';
7070
import { BareFontInfo } from 'vs/editor/common/config/fontInfo';
@@ -98,6 +98,8 @@ import { EventType, addDisposableListener, addClass, getClientArea } from 'vs/ba
9898
import { IOpenerService } from 'vs/platform/opener/common/opener';
9999
import { OpenerService } from 'vs/editor/browser/services/openerService';
100100
import { SearchHistoryService } from 'vs/workbench/services/search/node/searchHistoryService';
101+
import { MulitExtensionManagementService } from 'vs/platform/extensionManagement/common/multiExtensionManagement';
102+
import { ExtensionManagementServerService } from 'vs/workbench/services/extensions/node/extensionManagementServerService';
101103

102104
/**
103105
* Services that we require for the Shell
@@ -408,7 +410,9 @@ export class WorkbenchShell {
408410
this.lifecycleService = lifecycleService;
409411

410412
const extensionManagementChannel = getDelayedChannel<IExtensionManagementChannel>(sharedProcess.then(c => c.getChannel('extensions')));
411-
serviceCollection.set(IExtensionManagementService, new SyncDescriptor(ExtensionManagementChannelClient, extensionManagementChannel, DefaultURITransformer));
413+
const extensionManagementChannelClient = new ExtensionManagementChannelClient(extensionManagementChannel, DefaultURITransformer);
414+
serviceCollection.set(IExtensionManagementServerService, new SyncDescriptor(ExtensionManagementServerService, extensionManagementChannelClient));
415+
serviceCollection.set(IExtensionManagementService, new SyncDescriptor(MulitExtensionManagementService));
412416

413417
const extensionEnablementService = instantiationService.createInstance(ExtensionEnablementService);
414418
serviceCollection.set(IExtensionEnablementService, extensionEnablementService);

src/vs/workbench/parts/extensions/browser/media/loading.svg

Lines changed: 0 additions & 36 deletions
This file was deleted.

src/vs/workbench/parts/extensions/common/extensionQuery.ts

Lines changed: 12 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -5,20 +5,26 @@
55

66
export class Query {
77

8-
constructor(public value: string, public sortBy: string) {
8+
constructor(public value: string, public sortBy: string, public groupBy: string) {
99
this.value = value.trim();
1010
}
1111

1212
static parse(value: string): Query {
1313
let sortBy = '';
14-
1514
value = value.replace(/@sort:(\w+)(-\w*)?/g, (match, by: string, order: string) => {
1615
sortBy = by;
1716

1817
return '';
1918
});
2019

21-
return new Query(value, sortBy);
20+
let groupBy = '';
21+
value = value.replace(/@group:(\w+)(-\w*)?/g, (match, by: string, order: string) => {
22+
groupBy = by;
23+
24+
return '';
25+
});
26+
27+
return new Query(value, sortBy, groupBy);
2228
}
2329

2430
toString(): string {
@@ -27,6 +33,9 @@ export class Query {
2733
if (this.sortBy) {
2834
result = `${result}${result ? ' ' : ''}@sort:${this.sortBy}`;
2935
}
36+
if (this.groupBy) {
37+
result = `${result}${result ? ' ' : ''}@group:${this.groupBy}`;
38+
}
3039

3140
return result;
3241
}

src/vs/workbench/parts/extensions/common/extensionsInput.ts

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -10,13 +10,18 @@ import { TPromise } from 'vs/base/common/winjs.base';
1010
import { EditorInput } from 'vs/workbench/common/editor';
1111
import { IExtension } from 'vs/workbench/parts/extensions/common/extensions';
1212
import URI from 'vs/base/common/uri';
13+
import { IExtensionManagementServerService, IExtensionManagementServer } from 'vs/platform/extensionManagement/common/extensionManagement';
1314

1415
export class ExtensionsInput extends EditorInput {
1516

1617
static readonly ID = 'workbench.extensions.input2';
1718
get extension(): IExtension { return this._extension; }
19+
get servers(): IExtensionManagementServer[] { return this.extensionManagementServerService.extensionManagementServers; }
1820

19-
constructor(private _extension: IExtension) {
21+
constructor(
22+
private _extension: IExtension,
23+
@IExtensionManagementServerService private extensionManagementServerService: IExtensionManagementServerService
24+
) {
2025
super();
2126
}
2227

src/vs/workbench/parts/extensions/electron-browser/extensionEditor.ts

Lines changed: 10 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -31,7 +31,7 @@ import { Renderer, DataSource, Controller } from 'vs/workbench/parts/extensions/
3131
import { RatingsWidget, InstallCountWidget } from 'vs/workbench/parts/extensions/browser/extensionsWidgets';
3232
import { EditorOptions } from 'vs/workbench/common/editor';
3333
import { ActionBar } from 'vs/base/browser/ui/actionbar/actionbar';
34-
import { CombinedInstallAction, UpdateAction, EnableAction, DisableAction, ReloadAction, MaliciousStatusLabelAction, DisabledStatusLabelAction } from 'vs/workbench/parts/extensions/browser/extensionsActions';
34+
import { CombinedInstallAction, UpdateAction, EnableAction, DisableAction, ReloadAction, MaliciousStatusLabelAction, DisabledStatusLabelAction, MultiServerInstallAction, MultiServerUpdateAction } from 'vs/workbench/parts/extensions/electron-browser/extensionsActions';
3535
import { WebviewElement } from 'vs/workbench/parts/webview/electron-browser/webviewElement';
3636
import { KeybindingIO } from 'vs/workbench/services/keybinding/common/keybindingIO';
3737
import { IKeybindingService } from 'vs/platform/keybinding/common/keybinding';
@@ -247,6 +247,12 @@ export class ExtensionEditor extends BaseEditor {
247247
if (action.id === DisableAction.ID) {
248248
return (<DisableAction>action).actionItem;
249249
}
250+
if (action.id === MultiServerInstallAction.ID) {
251+
return (<MultiServerInstallAction>action).actionItem;
252+
}
253+
if (action.id === MultiServerUpdateAction.ID) {
254+
return (<MultiServerUpdateAction>action).actionItem;
255+
}
250256
return null;
251257
}
252258
});
@@ -268,6 +274,7 @@ export class ExtensionEditor extends BaseEditor {
268274
setInput(input: ExtensionsInput, options: EditorOptions, token: CancellationToken): Thenable<void> {
269275
this.editorLoadComplete = false;
270276
const extension = input.extension;
277+
const servers = input.servers;
271278

272279
this.transientDisposables = dispose(this.transientDisposables);
273280

@@ -351,8 +358,8 @@ export class ExtensionEditor extends BaseEditor {
351358

352359
const maliciousStatusAction = this.instantiationService.createInstance(MaliciousStatusLabelAction, true);
353360
const disabledStatusAction = this.instantiationService.createInstance(DisabledStatusLabelAction);
354-
const installAction = this.instantiationService.createInstance(CombinedInstallAction);
355-
const updateAction = this.instantiationService.createInstance(UpdateAction);
361+
const installAction = servers.length === 1 ? this.instantiationService.createInstance(CombinedInstallAction, servers[0]) : this.instantiationService.createInstance(MultiServerInstallAction);
362+
const updateAction = servers.length === 1 ? this.instantiationService.createInstance(UpdateAction, servers[0]) : this.instantiationService.createInstance(MultiServerUpdateAction);
356363
const enableAction = this.instantiationService.createInstance(EnableAction);
357364
const disableAction = this.instantiationService.createInstance(DisableAction);
358365
const reloadAction = this.instantiationService.createInstance(ReloadAction);

src/vs/workbench/parts/extensions/electron-browser/extensionTipsService.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -16,7 +16,7 @@ import { ITextModel } from 'vs/editor/common/model';
1616
import { IStorageService, StorageScope } from 'vs/platform/storage/common/storage';
1717
import product from 'vs/platform/node/product';
1818
import { IInstantiationService } from 'vs/platform/instantiation/common/instantiation';
19-
import { ShowRecommendedExtensionsAction, InstallWorkspaceRecommendedExtensionsAction, InstallRecommendedExtensionAction } from 'vs/workbench/parts/extensions/browser/extensionsActions';
19+
import { ShowRecommendedExtensionsAction, InstallWorkspaceRecommendedExtensionsAction, InstallRecommendedExtensionAction } from 'vs/workbench/parts/extensions/electron-browser/extensionsActions';
2020
import Severity from 'vs/base/common/severity';
2121
import { IWorkspaceContextService, IWorkspaceFolder, IWorkspace, IWorkspaceFoldersChangeEvent, WorkbenchState } from 'vs/platform/workspace/common/workspace';
2222
import { Schemas } from 'vs/base/common/network';

src/vs/workbench/parts/extensions/electron-browser/extensions.contribution.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -23,7 +23,7 @@ import {
2323
OpenExtensionsViewletAction, InstallExtensionsAction, ShowOutdatedExtensionsAction, ShowRecommendedExtensionsAction, ShowRecommendedKeymapExtensionsAction, ShowPopularExtensionsAction,
2424
ShowEnabledExtensionsAction, ShowInstalledExtensionsAction, ShowDisabledExtensionsAction, ShowBuiltInExtensionsAction, UpdateAllAction,
2525
EnableAllAction, EnableAllWorkpsaceAction, DisableAllAction, DisableAllWorkpsaceAction, CheckForUpdatesAction, ShowLanguageExtensionsAction, ShowAzureExtensionsAction, EnableAutoUpdateAction, DisableAutoUpdateAction, ConfigureRecommendedExtensionsCommandsContributor, OpenExtensionsFolderAction, InstallVSIXAction, ReinstallAction
26-
} from 'vs/workbench/parts/extensions/browser/extensionsActions';
26+
} from 'vs/workbench/parts/extensions/electron-browser/extensionsActions';
2727
import { ExtensionsInput } from 'vs/workbench/parts/extensions/common/extensionsInput';
2828
import { ViewletRegistry, Extensions as ViewletExtensions, ViewletDescriptor } from 'vs/workbench/browser/viewlet';
2929
import { ExtensionEditor } from 'vs/workbench/parts/extensions/electron-browser/extensionEditor';

0 commit comments

Comments
 (0)