mirror of
https://github.com/Microsoft/vscode
synced 2024-08-27 13:00:58 +00:00
Implement microsoft/vscode-remote-release/issues/157
This commit is contained in:
parent
105f843840
commit
ed6c5c5259
|
@ -44,6 +44,7 @@ import { ExtensionDependencyChecker } from 'vs/workbench/contrib/extensions/brow
|
|||
import { CancellationToken } from 'vs/base/common/cancellation';
|
||||
import { ExtensionType } from 'vs/platform/extensions/common/extensions';
|
||||
import { IWorkbenchEnvironmentService } from 'vs/workbench/services/environment/common/environmentService';
|
||||
import { RemoteExtensionsInstaller } from 'vs/workbench/contrib/extensions/browser/remoteExtensionsInstaller';
|
||||
|
||||
// Singletons
|
||||
registerSingleton(IExtensionsWorkbenchService, ExtensionsWorkbenchService);
|
||||
|
@ -372,3 +373,4 @@ workbenchRegistry.registerWorkbenchContribution(KeymapExtensions, LifecyclePhase
|
|||
workbenchRegistry.registerWorkbenchContribution(ExtensionsViewletViewsContribution, LifecyclePhase.Starting);
|
||||
workbenchRegistry.registerWorkbenchContribution(ExtensionActivationProgress, LifecyclePhase.Eventually);
|
||||
workbenchRegistry.registerWorkbenchContribution(ExtensionDependencyChecker, LifecyclePhase.Eventually);
|
||||
workbenchRegistry.registerWorkbenchContribution(RemoteExtensionsInstaller, LifecyclePhase.Eventually);
|
||||
|
|
|
@ -61,6 +61,7 @@ import { ITextFileService } from 'vs/workbench/services/textfile/common/textfile
|
|||
import { IProductService } from 'vs/platform/product/common/product';
|
||||
import { IClipboardService } from 'vs/platform/clipboard/common/clipboardService';
|
||||
import { IFileDialogService } from 'vs/platform/dialogs/common/dialogs';
|
||||
import { IProgressService, ProgressLocation } from 'vs/platform/progress/common/progress';
|
||||
|
||||
export function toExtensionDescription(local: ILocalExtension): IExtensionDescription {
|
||||
return {
|
||||
|
@ -324,7 +325,6 @@ export class InstallInOtherServerAction extends ExtensionAction {
|
|||
&& (this.extension.enablementState === EnablementState.DisabledByExtensionKind || isLanguagePackExtension(this.extension.local.manifest))
|
||||
// Not installed in other server and can install in other server
|
||||
&& !this.extensionsWorkbenchService.installed.some(e => areSameExtensions(e.identifier, this.extension.identifier) && e.server === this.server)
|
||||
&& this.extensionsWorkbenchService.canInstall(this.extension)
|
||||
) {
|
||||
this.enabled = true;
|
||||
this.updateLabel();
|
||||
|
@ -338,8 +338,14 @@ export class InstallInOtherServerAction extends ExtensionAction {
|
|||
this.update();
|
||||
this.extensionsWorkbenchService.open(this.extension);
|
||||
alert(localize('installExtensionStart', "Installing extension {0} started. An editor is now open with more details on this extension", this.extension.displayName));
|
||||
if (this.extension.gallery) {
|
||||
await this.server.extensionManagementService.installFromGallery(this.extension.gallery);
|
||||
try {
|
||||
if (this.extension.gallery) {
|
||||
await this.server.extensionManagementService.installFromGallery(this.extension.gallery);
|
||||
} else {
|
||||
const vsix = await this.extension.server!.extensionManagementService.zip(this.extension.local!);
|
||||
await this.server.extensionManagementService.install(vsix);
|
||||
}
|
||||
} finally {
|
||||
this.installing = false;
|
||||
this.update();
|
||||
}
|
||||
|
@ -3017,6 +3023,111 @@ export class InstallSpecificVersionOfExtensionAction extends Action {
|
|||
}
|
||||
}
|
||||
|
||||
interface IExtensionPickItem extends IQuickPickItem {
|
||||
extension?: IExtension;
|
||||
}
|
||||
|
||||
export class InstallLocalExtensionsOnRemoteAction extends Action {
|
||||
|
||||
constructor(
|
||||
@IExtensionsWorkbenchService private readonly extensionsWorkbenchService: IExtensionsWorkbenchService,
|
||||
@IExtensionManagementServerService private readonly extensionManagementServerService: IExtensionManagementServerService,
|
||||
@IExtensionGalleryService private readonly extensionGalleryService: IExtensionGalleryService,
|
||||
@IQuickInputService private readonly quickInputService: IQuickInputService,
|
||||
@INotificationService private readonly notificationService: INotificationService,
|
||||
@IWindowService private readonly windowService: IWindowService,
|
||||
@IProgressService private readonly progressService: IProgressService
|
||||
) {
|
||||
super('workbench.extensions.actions.installLocalExtensionsOnRemote');
|
||||
this.enabled = !!this.extensionManagementServerService.localExtensionManagementServer && !!this.extensionManagementServerService.remoteExtensionManagementServer;
|
||||
}
|
||||
|
||||
async run(): Promise<void> {
|
||||
if (this.enabled) {
|
||||
await this.selectAndInstallLocalExtensions();
|
||||
}
|
||||
}
|
||||
|
||||
private async getLocalExtensionsToInstall(): Promise<IExtension[]> {
|
||||
const localExtensions = await this.extensionsWorkbenchService.queryLocal(this.extensionManagementServerService.localExtensionManagementServer!);
|
||||
const remoteExtensions = await this.extensionsWorkbenchService.queryLocal(this.extensionManagementServerService.remoteExtensionManagementServer!);
|
||||
const remoteExtensionsIds: Set<string> = new Set<string>();
|
||||
const remoteExtensionsUUIDs: Set<string> = new Set<string>();
|
||||
for (const extension of remoteExtensions) {
|
||||
remoteExtensionsIds.add(extension.identifier.id.toLowerCase());
|
||||
if (extension.identifier.uuid) {
|
||||
remoteExtensionsUUIDs.add(extension.identifier.uuid);
|
||||
}
|
||||
}
|
||||
const localExtensionsToInstall: IExtension[] = [];
|
||||
for (const localExtension of localExtensions) {
|
||||
if (localExtension.type === ExtensionType.User
|
||||
&& (isLanguagePackExtension(localExtension.local!.manifest) || localExtension.enablementState === EnablementState.DisabledByExtensionKind)) {
|
||||
if (!remoteExtensionsIds.has(localExtension.identifier.id.toLowerCase()) || (localExtension.identifier.uuid && !remoteExtensionsUUIDs.has(localExtension.identifier.uuid))) {
|
||||
localExtensionsToInstall.push(localExtension);
|
||||
}
|
||||
}
|
||||
}
|
||||
return localExtensionsToInstall;
|
||||
}
|
||||
|
||||
private async selectAndInstallLocalExtensions(): Promise<void> {
|
||||
const result = await this.quickInputService.pick<IExtensionPickItem>(
|
||||
this.getLocalExtensionsToInstall()
|
||||
.then(extensions => {
|
||||
if (extensions.length) {
|
||||
extensions = extensions.sort((e1, e2) => e1.displayName.localeCompare(e2.displayName));
|
||||
return extensions.map<IExtensionPickItem>(extension => ({ extension, label: extension.displayName, description: extension.version }));
|
||||
}
|
||||
return [{ label: localize('no local extensions', "There are no extensions to install.") }];
|
||||
}),
|
||||
{
|
||||
canPickMany: true,
|
||||
placeHolder: localize('select extensions to install', "Select extensions to install")
|
||||
}
|
||||
);
|
||||
if (result) {
|
||||
const localExtensionsToInstall = result.filter(r => !!r.extension).map(r => r.extension!);
|
||||
if (localExtensionsToInstall.length) {
|
||||
this.progressService.withProgress(
|
||||
{
|
||||
location: ProgressLocation.Notification,
|
||||
title: localize('installing extensions', "Installing Extensions...")
|
||||
},
|
||||
() => this.installLocalExtensions(localExtensionsToInstall));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private async installLocalExtensions(localExtensionsToInstall: IExtension[]): Promise<void> {
|
||||
const galleryExtensions: IGalleryExtension[] = [];
|
||||
const vsixs: URI[] = [];
|
||||
await Promise.all(localExtensionsToInstall.map(async extension => {
|
||||
if (this.extensionGalleryService.isEnabled()) {
|
||||
const gallery = await this.extensionGalleryService.getCompatibleExtension(extension.identifier, extension.version);
|
||||
if (gallery) {
|
||||
galleryExtensions.push(gallery);
|
||||
return;
|
||||
}
|
||||
}
|
||||
const vsix = await this.extensionManagementServerService.localExtensionManagementServer!.extensionManagementService.zip(extension.local!);
|
||||
vsixs.push(vsix);
|
||||
}));
|
||||
|
||||
await Promise.all(galleryExtensions.map(gallery => this.extensionManagementServerService.remoteExtensionManagementServer!.extensionManagementService.installFromGallery(gallery)));
|
||||
await Promise.all(vsixs.map(vsix => this.extensionManagementServerService.remoteExtensionManagementServer!.extensionManagementService.install(vsix)));
|
||||
|
||||
this.notificationService.notify({
|
||||
severity: Severity.Info,
|
||||
message: localize('finished installing', "Completed installing the extensions. Please reload the window now."),
|
||||
actions: {
|
||||
primary: [new Action('realod', localize('reload', "Realod Window"), '', true,
|
||||
() => this.windowService.reloadWindow())]
|
||||
}
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
CommandsRegistry.registerCommand('workbench.extensions.action.showExtensionsForLanguage', function (accessor: ServicesAccessor, fileExtension: string) {
|
||||
const viewletService = accessor.get(IViewletService);
|
||||
|
||||
|
|
|
@ -0,0 +1,43 @@
|
|||
/*---------------------------------------------------------------------------------------------
|
||||
* Copyright (c) Microsoft Corporation. All rights reserved.
|
||||
* Licensed under the MIT License. See License.txt in the project root for license information.
|
||||
*--------------------------------------------------------------------------------------------*/
|
||||
|
||||
import { IWorkbenchContribution } from 'vs/workbench/common/contributions';
|
||||
import { CommandsRegistry } from 'vs/platform/commands/common/commands';
|
||||
import { MenuRegistry, MenuId } from 'vs/platform/actions/common/actions';
|
||||
import { localize } from 'vs/nls';
|
||||
import { Disposable, toDisposable } from 'vs/base/common/lifecycle';
|
||||
import { IExtensionManagementServerService } from 'vs/workbench/services/extensionManagement/common/extensionManagement';
|
||||
import { ILabelService } from 'vs/platform/label/common/label';
|
||||
import { IInstantiationService } from 'vs/platform/instantiation/common/instantiation';
|
||||
import { InstallLocalExtensionsOnRemoteAction } from 'vs/workbench/contrib/extensions/browser/extensionsActions';
|
||||
|
||||
export class RemoteExtensionsInstaller extends Disposable implements IWorkbenchContribution {
|
||||
|
||||
constructor(
|
||||
@IExtensionManagementServerService private readonly extensionManagementServerService: IExtensionManagementServerService,
|
||||
@ILabelService labelService: ILabelService,
|
||||
@IInstantiationService instantiationService: IInstantiationService
|
||||
) {
|
||||
super();
|
||||
if (this.extensionManagementServerService.localExtensionManagementServer && this.extensionManagementServerService.remoteExtensionManagementServer) {
|
||||
CommandsRegistry.registerCommand('workbench.extensions.installLocalExtensions', () => instantiationService.createInstance(InstallLocalExtensionsOnRemoteAction).run());
|
||||
let disposable = Disposable.None;
|
||||
const appendMenuItem = () => {
|
||||
disposable.dispose();
|
||||
disposable = MenuRegistry.appendMenuItem(MenuId.CommandPalette, {
|
||||
command: {
|
||||
id: 'workbench.extensions.installLocalExtensions',
|
||||
category: localize('extensions', "Extensions"),
|
||||
title: localize('istall local extensions', "Install Local Extensions on {0}", this.extensionManagementServerService.remoteExtensionManagementServer!.label)
|
||||
}
|
||||
});
|
||||
};
|
||||
appendMenuItem();
|
||||
this._register(labelService.onDidChangeFormatters(e => appendMenuItem()));
|
||||
this._register(toDisposable(() => disposable.dispose()));
|
||||
}
|
||||
}
|
||||
|
||||
}
|
|
@ -130,7 +130,11 @@ export class ExtensionManagementService extends Disposable implements IExtension
|
|||
}
|
||||
|
||||
zip(extension: ILocalExtension): Promise<URI> {
|
||||
throw new Error('Not Supported');
|
||||
const server = this.getServer(extension);
|
||||
if (server) {
|
||||
return server.extensionManagementService.zip(extension);
|
||||
}
|
||||
return Promise.reject(`Invalid location ${extension.location.toString()}`);
|
||||
}
|
||||
|
||||
unzip(zipLocation: URI, type: ExtensionType): Promise<IExtensionIdentifier> {
|
||||
|
|
Loading…
Reference in a new issue