use donotIncludePackAndDependencies option when downloading remote extensions locally and install

This commit is contained in:
Sandeep Somavarapu
2021-08-20 14:18:51 +02:00
parent fa153583f1
commit 2622a2fa0c
@@ -10,7 +10,7 @@ import { ExtensionType, IExtensionManifest } from 'vs/platform/extensions/common
import { areSameExtensions } from 'vs/platform/extensionManagement/common/extensionManagementUtil';
import { ILogService } from 'vs/platform/log/common/log';
import { toErrorMessage } from 'vs/base/common/errorMessage';
import { coalesce, isNonEmptyArray } from 'vs/base/common/arrays';
import { isNonEmptyArray } from 'vs/base/common/arrays';
import { CancellationToken } from 'vs/base/common/cancellation';
import { localize } from 'vs/nls';
import { IProductService } from 'vs/platform/product/common/productService';
@@ -55,19 +55,14 @@ export class NativeRemoteExtensionManagementService extends WebRemoteExtensionMa
private async doInstallFromGallery(extension: IGalleryExtension, installOptions?: InstallOptions): Promise<ILocalExtension> {
if (this.configurationService.getValue('remote.downloadExtensionsLocally')) {
this.logService.trace(`Download '${extension.identifier.id}' extension locally and install`);
return this.downloadCompatibleAndInstall(extension);
return this.downloadAndInstall(extension, installOptions || {});
}
try {
const local = await super.installFromGallery(extension, installOptions);
return local;
return await super.installFromGallery(extension, installOptions);
} catch (error) {
try {
this.logService.error(`Error while installing '${extension.identifier.id}' extension in the remote server.`, toErrorMessage(error));
this.logService.info(`Trying to download '${extension.identifier.id}' extension locally and install`);
const local = await this.downloadCompatibleAndInstall(extension);
this.logService.info(`Successfully installed '${extension.identifier.id}' extension`);
return local;
return await this.downloadAndInstall(extension, installOptions || {});
} catch (e) {
this.logService.error(e);
throw error;
@@ -75,31 +70,41 @@ export class NativeRemoteExtensionManagementService extends WebRemoteExtensionMa
}
}
private async downloadCompatibleAndInstall(extension: IGalleryExtension): Promise<ILocalExtension> {
private async downloadAndInstall(extension: IGalleryExtension, installOptions: InstallOptions): Promise<ILocalExtension> {
this.logService.info(`Downloading the '${extension.identifier.id}' extension locally and install`);
installOptions = { ...installOptions, donotIncludePackAndDependencies: true };
const installed = await this.getInstalled(ExtensionType.User);
const workspaceExtensions = await this.getAllWorkspaceDependenciesAndPackedExtensions(extension, CancellationToken.None);
if (workspaceExtensions.length) {
this.logService.info(`Downloading the workspace dependencies and packed extensions of '${extension.identifier.id}' locally and install`);
for (const workspaceExtension of workspaceExtensions) {
await this.downloadCompatibleAndInstall(workspaceExtension, installed, installOptions);
}
}
return await this.downloadCompatibleAndInstall(extension, installed, installOptions);
}
private async downloadCompatibleAndInstall(extension: IGalleryExtension, installed: ILocalExtension[], installOptions: InstallOptions): Promise<ILocalExtension> {
const compatible = await this.galleryService.getCompatibleExtension(extension);
if (!compatible) {
return Promise.reject(new Error(localize('incompatible', "Unable to install extension '{0}' as it is not compatible with VS Code '{1}'.", extension.identifier.id, this.productService.version)));
}
const manifest = await this.galleryService.getManifest(compatible, CancellationToken.None);
if (manifest) {
const workspaceExtensions = await this.getAllWorkspaceDependenciesAndPackedExtensions(manifest, CancellationToken.None);
await Promises.settled(workspaceExtensions.map(e => this.downloadAndInstall(e, installed)));
}
return this.downloadAndInstall(extension, installed);
}
private async downloadAndInstall(extension: IGalleryExtension, installed: ILocalExtension[]): Promise<ILocalExtension> {
const location = joinPath(this.environmentService.tmpDir, generateUuid());
await this.galleryService.download(extension, location, installed.filter(i => areSameExtensions(i.identifier, extension.identifier))[0] ? InstallOperation.Update : InstallOperation.Install);
return super.install(location);
this.logService.info('Downloaded extension:', compatible.identifier.id, location.path);
await this.galleryService.download(compatible, location, installed.filter(i => areSameExtensions(i.identifier, compatible.identifier))[0] ? InstallOperation.Update : InstallOperation.Install);
const local = await super.install(location, installOptions);
this.logService.info(`Successfully installed '${compatible.identifier.id}' extension`);
return local;
}
private async installUIDependenciesAndPackedExtensions(local: ILocalExtension): Promise<void> {
const uiExtensions = await this.getAllUIDependenciesAndPackedExtensions(local.manifest, CancellationToken.None);
const installed = await this.localExtensionManagementService.getInstalled();
const toInstall = uiExtensions.filter(e => installed.every(i => !areSameExtensions(i.identifier, e.identifier)));
await Promises.settled(toInstall.map(d => this.localExtensionManagementService.installFromGallery(d)));
if (toInstall.length) {
this.logService.info(`Installing UI dependencies and packed extensions of '${local.identifier.id}' locally`);
await Promises.settled(toInstall.map(d => this.localExtensionManagementService.installFromGallery(d)));
}
}
private async getAllUIDependenciesAndPackedExtensions(manifest: IExtensionManifest, token: CancellationToken): Promise<IGalleryExtension[]> {
@@ -109,10 +114,15 @@ export class NativeRemoteExtensionManagementService extends WebRemoteExtensionMa
return [...result.values()];
}
private async getAllWorkspaceDependenciesAndPackedExtensions(manifest: IExtensionManifest, token: CancellationToken): Promise<IGalleryExtension[]> {
private async getAllWorkspaceDependenciesAndPackedExtensions(extension: IGalleryExtension, token: CancellationToken): Promise<IGalleryExtension[]> {
const result = new Map<string, IGalleryExtension>();
const extensions = [...(manifest.extensionPack || []), ...(manifest.extensionDependencies || [])];
await this.getDependenciesAndPackedExtensionsRecursively(extensions, result, false, token);
result.set(extension.identifier.id.toLowerCase(), extension);
const manifest = await this.galleryService.getManifest(extension, token);
if (manifest) {
const extensions = [...(manifest.extensionPack || []), ...(manifest.extensionDependencies || [])];
await this.getDependenciesAndPackedExtensionsRecursively(extensions, result, false, token);
}
result.delete(extension.identifier.id);
return [...result.values()];
}
@@ -121,7 +131,7 @@ export class NativeRemoteExtensionManagementService extends WebRemoteExtensionMa
return Promise.resolve();
}
const extensions = coalesce(await Promises.settled(toGet.map(id => this.galleryService.getCompatibleExtension({ id }))));
const extensions = await this.galleryService.getExtensions(toGet, token);
const manifests = await Promise.all(extensions.map(e => this.galleryService.getManifest(e, token)));
const extensionsManifests: IExtensionManifest[] = [];
for (let idx = 0; idx < extensions.length; idx++) {