mirror of
https://github.com/Microsoft/vscode
synced 2024-10-12 14:30:13 +00:00
Fix #119265
This commit is contained in:
parent
78c865d70d
commit
1176faf27f
|
@ -203,6 +203,7 @@ export class ExtensionManagementError extends Error {
|
|||
}
|
||||
|
||||
export type InstallOptions = { isBuiltin?: boolean, isMachineScoped?: boolean, donotIncludePackAndDependencies?: boolean };
|
||||
export type InstallVSIXOptions = InstallOptions & { installOnlyNewlyAddedFromExtensionPack?: boolean };
|
||||
export type UninstallOptions = { donotIncludePack?: boolean, donotCheckDependents?: boolean };
|
||||
|
||||
export const IExtensionManagementService = createDecorator<IExtensionManagementService>('extensionManagementService');
|
||||
|
@ -217,7 +218,7 @@ export interface IExtensionManagementService {
|
|||
zip(extension: ILocalExtension): Promise<URI>;
|
||||
unzip(zipLocation: URI): Promise<IExtensionIdentifier>;
|
||||
getManifest(vsix: URI): Promise<IExtensionManifest>;
|
||||
install(vsix: URI, options?: InstallOptions): Promise<ILocalExtension>;
|
||||
install(vsix: URI, options?: InstallVSIXOptions): Promise<ILocalExtension>;
|
||||
canInstall(extension: IGalleryExtension): Promise<boolean>;
|
||||
installFromGallery(extension: IGalleryExtension, options?: InstallOptions): Promise<ILocalExtension>;
|
||||
uninstall(extension: ILocalExtension, options?: UninstallOptions): Promise<void>;
|
||||
|
|
|
@ -4,7 +4,7 @@
|
|||
*--------------------------------------------------------------------------------------------*/
|
||||
|
||||
import { IChannel, IServerChannel } from 'vs/base/parts/ipc/common/ipc';
|
||||
import { IExtensionManagementService, ILocalExtension, InstallExtensionEvent, DidInstallExtensionEvent, IGalleryExtension, DidUninstallExtensionEvent, IExtensionIdentifier, IGalleryMetadata, IReportedExtension, IExtensionTipsService, InstallOptions, UninstallOptions } from 'vs/platform/extensionManagement/common/extensionManagement';
|
||||
import { IExtensionManagementService, ILocalExtension, InstallExtensionEvent, DidInstallExtensionEvent, IGalleryExtension, DidUninstallExtensionEvent, IExtensionIdentifier, IGalleryMetadata, IReportedExtension, IExtensionTipsService, InstallOptions, UninstallOptions, InstallVSIXOptions } from 'vs/platform/extensionManagement/common/extensionManagement';
|
||||
import { Emitter, Event } from 'vs/base/common/event';
|
||||
import { URI, UriComponents } from 'vs/base/common/uri';
|
||||
import { IURITransformer, DefaultURITransformer, transformAndReviveIncomingURIs } from 'vs/base/common/uriIpc';
|
||||
|
@ -62,7 +62,7 @@ export class ExtensionManagementChannel implements IServerChannel {
|
|||
switch (command) {
|
||||
case 'zip': return this.service.zip(transformIncomingExtension(args[0], uriTransformer)).then(uri => transformOutgoingURI(uri, uriTransformer));
|
||||
case 'unzip': return this.service.unzip(transformIncomingURI(args[0], uriTransformer));
|
||||
case 'install': return this.service.install(transformIncomingURI(args[0], uriTransformer));
|
||||
case 'install': return this.service.install(transformIncomingURI(args[0], uriTransformer), args[1]);
|
||||
case 'getManifest': return this.service.getManifest(transformIncomingURI(args[0], uriTransformer));
|
||||
case 'canInstall': return this.service.canInstall(args[0]);
|
||||
case 'installFromGallery': return this.service.installFromGallery(args[0], args[1]);
|
||||
|
@ -112,8 +112,8 @@ export class ExtensionManagementChannelClient extends Disposable implements IExt
|
|||
return Promise.resolve(this.channel.call('unzip', [zipLocation]));
|
||||
}
|
||||
|
||||
install(vsix: URI): Promise<ILocalExtension> {
|
||||
return Promise.resolve(this.channel.call<ILocalExtension>('install', [vsix])).then(local => transformIncomingExtension(local, null));
|
||||
install(vsix: URI, options?: InstallVSIXOptions): Promise<ILocalExtension> {
|
||||
return Promise.resolve(this.channel.call<ILocalExtension>('install', [vsix, options])).then(local => transformIncomingExtension(local, null));
|
||||
}
|
||||
|
||||
getManifest(vsix: URI): Promise<IExtensionManifest> {
|
||||
|
|
|
@ -21,7 +21,8 @@ import {
|
|||
INSTALL_ERROR_INCOMPATIBLE,
|
||||
ExtensionManagementError,
|
||||
InstallOptions,
|
||||
UninstallOptions
|
||||
UninstallOptions,
|
||||
InstallVSIXOptions
|
||||
} from 'vs/platform/extensionManagement/common/extensionManagement';
|
||||
import { areSameExtensions, getGalleryExtensionId, getMaliciousExtensionsSet, getGalleryExtensionTelemetryData, getLocalExtensionTelemetryData, ExtensionIdentifierWithVersion } from 'vs/platform/extensionManagement/common/extensionManagementUtil';
|
||||
import { INativeEnvironmentService } from 'vs/platform/environment/common/environment';
|
||||
|
@ -159,7 +160,7 @@ export class ExtensionManagementService extends Disposable implements IExtension
|
|||
return files.map(f => (<IFile>{ path: `extension/${path.relative(extension.location.fsPath, f)}`, localPath: f }));
|
||||
}
|
||||
|
||||
async install(vsix: URI, options: InstallOptions = {}): Promise<ILocalExtension> {
|
||||
async install(vsix: URI, options: InstallVSIXOptions = {}): Promise<ILocalExtension> {
|
||||
this.logService.trace('ExtensionManagementService#install', vsix.toString());
|
||||
return createCancelablePromise(async token => {
|
||||
|
||||
|
@ -211,7 +212,7 @@ export class ExtensionManagementService extends Disposable implements IExtension
|
|||
} catch (e) { /* Ignore */ }
|
||||
|
||||
try {
|
||||
const local = await this.installFromZipPath(identifierWithVersion, zipPath, { ...(metadata || {}), ...options }, options, operation, token);
|
||||
const local = await this.installFromZipPath(identifierWithVersion, zipPath, options.installOnlyNewlyAddedFromExtensionPack ? existing : undefined, { ...(metadata || {}), ...options }, options, operation, token);
|
||||
this.logService.info('Successfully installed the extension:', identifier.id);
|
||||
return local;
|
||||
} catch (e) {
|
||||
|
@ -234,11 +235,13 @@ export class ExtensionManagementService extends Disposable implements IExtension
|
|||
return downloadedLocation;
|
||||
}
|
||||
|
||||
private async installFromZipPath(identifierWithVersion: ExtensionIdentifierWithVersion, zipPath: string, metadata: IMetadata | undefined, options: InstallOptions, operation: InstallOperation, token: CancellationToken): Promise<ILocalExtension> {
|
||||
private async installFromZipPath(identifierWithVersion: ExtensionIdentifierWithVersion, zipPath: string, existing: ILocalExtension | undefined, metadata: IMetadata | undefined, options: InstallOptions, operation: InstallOperation, token: CancellationToken): Promise<ILocalExtension> {
|
||||
try {
|
||||
const local = await this.installExtension({ zipPath, identifierWithVersion, metadata }, token);
|
||||
try {
|
||||
await this.installDependenciesAndPackExtensions(local, undefined, options);
|
||||
if (!options.donotIncludePackAndDependencies) {
|
||||
await this.installDependenciesAndPackExtensions(local, existing, options);
|
||||
}
|
||||
} catch (error) {
|
||||
if (isNonEmptyArray(local.manifest.extensionDependencies)) {
|
||||
this.logService.warn(`Cannot install dependencies of extension:`, local.identifier.id, error.message);
|
||||
|
|
|
@ -251,14 +251,29 @@ CommandsRegistry.registerCommand({
|
|||
description: localize('workbench.extensions.installExtension.description', "Install the given extension"),
|
||||
args: [
|
||||
{
|
||||
name: localize('workbench.extensions.installExtension.arg.name', "Extension id or VSIX resource uri"),
|
||||
name: 'extensionIdOrVSIXUri',
|
||||
description: localize('workbench.extensions.installExtension.arg.decription', "Extension id or VSIX resource uri"),
|
||||
constraint: (value: any) => typeof value === 'string' || value instanceof URI,
|
||||
},
|
||||
{
|
||||
name: 'options',
|
||||
description: '(optional) Options for installing the extension. Object with the following properties: ' +
|
||||
'`installOnlyNewlyAddedFromExtensionPackVSIX`: When enabled, VS Code installs only newly added extensions from the extension pack VSIX. This option is considered only when installing VSIX. ',
|
||||
isOptional: true,
|
||||
schema: {
|
||||
'type': ['object', 'string']
|
||||
'type': 'object',
|
||||
'properties': {
|
||||
'installOnlyNewlyAddedFromExtensionPackVSIX': {
|
||||
'type': 'boolean',
|
||||
'description': localize('workbench.extensions.installExtension.option.installOnlyNewlyAddedFromExtensionPackVSIX', "When enabled, VS Code installs only newly added extensions from the extension pack VSIX. This option is considered only while installing a VSIX."),
|
||||
default: false
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
]
|
||||
},
|
||||
handler: async (accessor, arg: string | UriComponents) => {
|
||||
handler: async (accessor, arg: string | UriComponents, options?: { installOnlyNewlyAddedFromExtensionPackVSIX?: boolean }) => {
|
||||
const extensionManagementService = accessor.get(IExtensionManagementService);
|
||||
const extensionGalleryService = accessor.get(IExtensionGalleryService);
|
||||
try {
|
||||
|
@ -271,7 +286,7 @@ CommandsRegistry.registerCommand({
|
|||
}
|
||||
} else {
|
||||
const vsix = URI.revive(arg);
|
||||
await extensionManagementService.install(vsix);
|
||||
await extensionManagementService.install(vsix, { installOnlyNewlyAddedFromExtensionPack: options?.installOnlyNewlyAddedFromExtensionPackVSIX });
|
||||
}
|
||||
} catch (e) {
|
||||
onUnexpectedError(e);
|
||||
|
|
|
@ -5,7 +5,7 @@
|
|||
|
||||
import { Event, EventMultiplexer } from 'vs/base/common/event';
|
||||
import {
|
||||
ILocalExtension, IGalleryExtension, InstallExtensionEvent, DidInstallExtensionEvent, IExtensionIdentifier, DidUninstallExtensionEvent, IReportedExtension, IGalleryMetadata, IExtensionGalleryService, InstallOptions, UninstallOptions, INSTALL_ERROR_NOT_SUPPORTED
|
||||
ILocalExtension, IGalleryExtension, InstallExtensionEvent, DidInstallExtensionEvent, IExtensionIdentifier, DidUninstallExtensionEvent, IReportedExtension, IGalleryMetadata, IExtensionGalleryService, InstallOptions, UninstallOptions, INSTALL_ERROR_NOT_SUPPORTED, InstallVSIXOptions
|
||||
} from 'vs/platform/extensionManagement/common/extensionManagement';
|
||||
import { IExtensionManagementServer, IExtensionManagementServerService, IWorkbenchExtensionManagementService } from 'vs/workbench/services/extensionManagement/common/extensionManagement';
|
||||
import { ExtensionType, isLanguagePackExtension, IExtensionManifest } from 'vs/platform/extensions/common/extensions';
|
||||
|
@ -171,35 +171,35 @@ export class ExtensionManagementService extends Disposable implements IWorkbench
|
|||
.map(({ extensionManagementService }) => extensionManagementService.unzip(zipLocation))).then(([extensionIdentifier]) => extensionIdentifier);
|
||||
}
|
||||
|
||||
async install(vsix: URI): Promise<ILocalExtension> {
|
||||
async install(vsix: URI, options?: InstallVSIXOptions): Promise<ILocalExtension> {
|
||||
if (this.extensionManagementServerService.localExtensionManagementServer && this.extensionManagementServerService.remoteExtensionManagementServer) {
|
||||
const manifest = await this.getManifest(vsix);
|
||||
if (isLanguagePackExtension(manifest)) {
|
||||
// Install on both servers
|
||||
const [local] = await Promises.settled([this.extensionManagementServerService.localExtensionManagementServer, this.extensionManagementServerService.remoteExtensionManagementServer].map(server => this.installVSIX(vsix, server)));
|
||||
const [local] = await Promises.settled([this.extensionManagementServerService.localExtensionManagementServer, this.extensionManagementServerService.remoteExtensionManagementServer].map(server => this.installVSIX(vsix, server, options)));
|
||||
return local;
|
||||
}
|
||||
if (this.extensionManifestPropertiesService.prefersExecuteOnUI(manifest)) {
|
||||
// Install only on local server
|
||||
return this.installVSIX(vsix, this.extensionManagementServerService.localExtensionManagementServer);
|
||||
return this.installVSIX(vsix, this.extensionManagementServerService.localExtensionManagementServer, options);
|
||||
}
|
||||
// Install only on remote server
|
||||
return this.installVSIX(vsix, this.extensionManagementServerService.remoteExtensionManagementServer);
|
||||
return this.installVSIX(vsix, this.extensionManagementServerService.remoteExtensionManagementServer, options);
|
||||
}
|
||||
if (this.extensionManagementServerService.localExtensionManagementServer) {
|
||||
return this.installVSIX(vsix, this.extensionManagementServerService.localExtensionManagementServer);
|
||||
return this.installVSIX(vsix, this.extensionManagementServerService.localExtensionManagementServer, options);
|
||||
}
|
||||
if (this.extensionManagementServerService.remoteExtensionManagementServer) {
|
||||
return this.installVSIX(vsix, this.extensionManagementServerService.remoteExtensionManagementServer);
|
||||
return this.installVSIX(vsix, this.extensionManagementServerService.remoteExtensionManagementServer, options);
|
||||
}
|
||||
return Promise.reject('No Servers to Install');
|
||||
}
|
||||
|
||||
protected async installVSIX(vsix: URI, server: IExtensionManagementServer): Promise<ILocalExtension> {
|
||||
protected async installVSIX(vsix: URI, server: IExtensionManagementServer, options: InstallVSIXOptions | undefined): Promise<ILocalExtension> {
|
||||
const manifest = await this.getManifest(vsix);
|
||||
if (manifest) {
|
||||
await this.checkForWorkspaceTrust(manifest);
|
||||
return server.extensionManagementService.install(vsix);
|
||||
return server.extensionManagementService.install(vsix, options);
|
||||
}
|
||||
return Promise.reject('Unable to get the extension manifest.');
|
||||
}
|
||||
|
|
|
@ -4,7 +4,7 @@
|
|||
*--------------------------------------------------------------------------------------------*/
|
||||
|
||||
import { generateUuid } from 'vs/base/common/uuid';
|
||||
import { ILocalExtension, IExtensionGalleryService } from 'vs/platform/extensionManagement/common/extensionManagement';
|
||||
import { ILocalExtension, IExtensionGalleryService, InstallVSIXOptions } 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';
|
||||
|
@ -38,7 +38,7 @@ export class ExtensionManagementService extends BaseExtensionManagementService {
|
|||
super(extensionManagementServerService, extensionGalleryService, configurationService, productService, downloadService, userDataAutoSyncEnablementService, userDataSyncResourceEnablementService, dialogService, workspaceTrustRequestService, extensionManifestPropertiesService);
|
||||
}
|
||||
|
||||
protected override async installVSIX(vsix: URI, server: IExtensionManagementServer): Promise<ILocalExtension> {
|
||||
protected override async installVSIX(vsix: URI, server: IExtensionManagementServer, options: InstallVSIXOptions | undefined): Promise<ILocalExtension> {
|
||||
if (vsix.scheme === Schemas.vscodeRemote && server === this.extensionManagementServerService.localExtensionManagementServer) {
|
||||
const downloadedLocation = joinPath(this.environmentService.tmpDir, generateUuid());
|
||||
await this.downloadService.download(vsix, downloadedLocation);
|
||||
|
@ -47,7 +47,7 @@ export class ExtensionManagementService extends BaseExtensionManagementService {
|
|||
const manifest = await this.getManifest(vsix);
|
||||
if (manifest) {
|
||||
await this.checkForWorkspaceTrust(manifest);
|
||||
return server.extensionManagementService.install(vsix);
|
||||
return server.extensionManagementService.install(vsix, options);
|
||||
}
|
||||
|
||||
return Promise.reject('Unable to get the extension manifest.');
|
||||
|
|
|
@ -4,7 +4,7 @@
|
|||
*--------------------------------------------------------------------------------------------*/
|
||||
|
||||
import { IChannel } from 'vs/base/parts/ipc/common/ipc';
|
||||
import { IExtensionManagementService, ILocalExtension, IGalleryExtension, IExtensionGalleryService, InstallOperation, InstallOptions } from 'vs/platform/extensionManagement/common/extensionManagement';
|
||||
import { IExtensionManagementService, ILocalExtension, IGalleryExtension, IExtensionGalleryService, InstallOperation, InstallOptions, InstallVSIXOptions } from 'vs/platform/extensionManagement/common/extensionManagement';
|
||||
import { URI } from 'vs/base/common/uri';
|
||||
import { ExtensionType, IExtensionManifest } from 'vs/platform/extensions/common/extensions';
|
||||
import { areSameExtensions } from 'vs/platform/extensionManagement/common/extensionManagementUtil';
|
||||
|
@ -41,8 +41,8 @@ export class NativeRemoteExtensionManagementService extends WebRemoteExtensionMa
|
|||
this.localExtensionManagementService = localExtensionManagementServer.extensionManagementService;
|
||||
}
|
||||
|
||||
override async install(vsix: URI): Promise<ILocalExtension> {
|
||||
const local = await super.install(vsix);
|
||||
override async install(vsix: URI, options?: InstallVSIXOptions): Promise<ILocalExtension> {
|
||||
const local = await super.install(vsix, options);
|
||||
await this.installUIDependenciesAndPackedExtensions(local);
|
||||
return local;
|
||||
}
|
||||
|
|
Loading…
Reference in a new issue