#15756 - handle incompatible pre-release versions

This commit is contained in:
Sandeep Somavarapu
2021-11-23 12:06:30 +01:00
parent 465b806ed2
commit ed5ebcbb03
6 changed files with 37 additions and 17 deletions
@@ -352,7 +352,7 @@ export abstract class AbstractExtensionManagementService extends Disposable impl
return allDependenciesAndPacks.filter(e => !installed.some(i => areSameExtensions(i.identifier, e.gallery.identifier)));
}
private async checkAndGetCompatibleVersion(extension: IGalleryExtension, fetchCompatibleVersion: boolean, includePreRelease: boolean): Promise<{ extension: IGalleryExtension, manifest: IExtensionManifest }> {
private async checkAndGetCompatibleVersion(extension: IGalleryExtension, fetchCompatibleVersion: boolean, installPreRelease: boolean): Promise<{ extension: IGalleryExtension, manifest: IExtensionManifest }> {
if (await this.isMalicious(extension)) {
throw new ExtensionManagementError(nls.localize('malicious extension', "Can't install '{0}' extension since it was reported to be problematic.", extension.identifier.id), ExtensionManagementErrorCode.Malicious);
}
@@ -362,10 +362,10 @@ export abstract class AbstractExtensionManagementService extends Disposable impl
throw new ExtensionManagementError(nls.localize('incompatible platform', "The '{0}' extension is not available in {1} for {2}.", extension.identifier.id, this.productService.nameLong, TargetPlatformToString(targetPlatform)), ExtensionManagementErrorCode.IncompatibleTargetPlatform);
}
const compatibleExtension = await this.getCompatibleVersion(extension, fetchCompatibleVersion, includePreRelease);
const compatibleExtension = await this.getCompatibleVersion(extension, fetchCompatibleVersion, installPreRelease);
if (compatibleExtension) {
if (includePreRelease && !compatibleExtension.properties.isPreReleaseVersion && extension.hasPreReleaseVersion) {
throw new ExtensionManagementError(nls.localize('notFoundCompatiblePrereleaseDependency', "Can't install pre-release version of '{0}' extension because it is not compatible with the current version of {1} (version {2}).", extension.identifier.id, this.productService.nameLong, this.productService.version), ExtensionManagementErrorCode.Incompatible);
if (installPreRelease && extension.hasPreReleaseVersion && !compatibleExtension.properties.isPreReleaseVersion) {
throw new ExtensionManagementError(nls.localize('notFoundCompatiblePrereleaseDependency', "Can't install pre-release version of '{0}' extension because it is not compatible with the current version of {1} (version {2}).", extension.identifier.id, this.productService.nameLong, this.productService.version), ExtensionManagementErrorCode.IncompatiblePreRelease);
}
} else {
throw new ExtensionManagementError(nls.localize('notFoundCompatibleDependency', "Can't install '{0}' extension because it is not compatible with the current version of {1} (version {2}).", extension.identifier.id, this.productService.nameLong, this.productService.version), ExtensionManagementErrorCode.Incompatible);
@@ -365,6 +365,7 @@ export enum ExtensionManagementErrorCode {
Unsupported = 'Unsupported',
Malicious = 'Malicious',
Incompatible = 'Incompatible',
IncompatiblePreRelease = 'IncompatiblePreRelease',
IncompatibleTargetPlatform = 'IncompatibleTargetPlatform',
Invalid = 'Invalid',
Download = 'Download',
@@ -419,7 +419,7 @@ export class ExtensionsSynchroniser extends AbstractSynchroniser implements IUse
}
} catch (error) {
addToSkipped.push(e);
if (error instanceof ExtensionManagementError && (error.code === ExtensionManagementErrorCode.Incompatible || error.code === ExtensionManagementErrorCode.IncompatibleTargetPlatform)) {
if (error instanceof ExtensionManagementError && [ExtensionManagementErrorCode.Incompatible, ExtensionManagementErrorCode.IncompatiblePreRelease, ExtensionManagementErrorCode.IncompatibleTargetPlatform].includes(error.code)) {
this.logService.info(`${this.syncResourceLogLabel}: Skipped synchronizing extension because the compatible extension is not found.`, extension.displayName || extension.identifier.id);
} else {
this.logService.error(error);
@@ -612,7 +612,7 @@ class ExtensionsContributions extends Disposable implements IWorkbenchContributi
try {
await this.extensionsWorkbenchService.install(extension);
} catch (err) {
runAction(this.instantiationService.createInstance(PromptExtensionInstallFailureAction, extension, extension.latestVersion, InstallOperation.Update, err));
runAction(this.instantiationService.createInstance(PromptExtensionInstallFailureAction, extension, extension.latestVersion, InstallOperation.Update, undefined, err));
}
}));
}
@@ -105,6 +105,7 @@ export class PromptExtensionInstallFailureAction extends Action {
private readonly extension: IExtension,
private readonly version: string,
private readonly installOperation: InstallOperation,
private readonly installOptions: InstallOptions | undefined,
private readonly error: Error,
@IProductService private readonly productService: IProductService,
@IOpenerService private readonly openerService: IOpenerService,
@@ -113,6 +114,7 @@ export class PromptExtensionInstallFailureAction extends Action {
@ICommandService private readonly commandService: ICommandService,
@ILogService private readonly logService: ILogService,
@IExtensionManagementServerService private readonly extensionManagementServerService: IExtensionManagementServerService,
@IInstantiationService private readonly instantiationService: IInstantiationService,
) {
super('extension.promptExtensionInstallFailure');
}
@@ -139,8 +141,26 @@ export class PromptExtensionInstallFailureAction extends Action {
return;
}
let operationMessage = this.installOperation === InstallOperation.Update ? localize('update operation', "Error while updating '{0}' extension.", this.extension.displayName || this.extension.identifier.id)
: localize('install operation', "Error while installing '{0}' extension.", this.extension.displayName || this.extension.identifier.id);
let additionalMessage;
const promptChoices: IPromptChoice[] = [];
if (this.extension.gallery && this.productService.extensionsGallery && (this.extensionManagementServerService.localExtensionManagementServer || this.extensionManagementServerService.remoteExtensionManagementServer) && !isIOS) {
if (ExtensionManagementErrorCode.IncompatiblePreRelease === (<ExtensionManagementErrorCode>this.error.name)) {
operationMessage = getErrorMessage(this.error);
additionalMessage = localize('install release version', "Would you like to install the released version?");
promptChoices.push({
label: localize('install released version', "Install Released Version"),
run: () => {
const installAction = this.installOptions?.isMachineScoped ? this.instantiationService.createInstance(InstallAction, !!this.installOptions.installPreReleaseVersion) : this.instantiationService.createInstance(InstallAndSyncAction, !!this.installOptions?.installPreReleaseVersion);
installAction.extension = this.extension;
return installAction.run();
}
});
}
else if (this.extension.gallery && this.productService.extensionsGallery && (this.extensionManagementServerService.localExtensionManagementServer || this.extensionManagementServerService.remoteExtensionManagementServer) && !isIOS) {
additionalMessage = localize('check logs', "Please check the [log]({0}) for more details.", `command:${Constants.showWindowLogActionId}`);
promptChoices.push({
label: localize('download', "Try Downloading Manually..."),
run: () => this.openerService.open(URI.parse(`${this.productService.extensionsGallery!.serviceUrl}/publishers/${this.extension.publisher}/vsextensions/${this.extension.name}/${this.version}/vspackage`)).then(() => {
@@ -156,10 +176,8 @@ export class PromptExtensionInstallFailureAction extends Action {
});
}
const operationMessage = this.installOperation === InstallOperation.Update ? localize('update operation', "Error while updating '{0}' extension.", this.extension.displayName || this.extension.identifier.id)
: localize('install operation', "Error while installing '{0}' extension.", this.extension.displayName || this.extension.identifier.id);
const checkLogsMessage = localize('check logs', "Please check the [log]({0}) for more details.", `command:${Constants.showWindowLogActionId}`);
this.notificationService.prompt(Severity.Error, `${operationMessage} ${checkLogsMessage}`, promptChoices);
let message = `${operationMessage}${additionalMessage ? ` ${additionalMessage}` : ''}`;
this.notificationService.prompt(Severity.Error, message, promptChoices);
}
}
@@ -310,10 +328,11 @@ export abstract class AbstractInstallAction extends ExtensionAction {
}
private async install(extension: IExtension): Promise<IExtension | undefined> {
const installOptions = this.getInstallOptions();
try {
return await this.extensionsWorkbenchService.install(extension, this.getInstallOptions());
return await this.extensionsWorkbenchService.install(extension, installOptions);
} catch (error) {
await this.instantiationService.createInstance(PromptExtensionInstallFailureAction, extension, extension.latestVersion, InstallOperation.Install, error).run();
await this.instantiationService.createInstance(PromptExtensionInstallFailureAction, extension, extension.latestVersion, InstallOperation.Install, installOptions, error).run();
return undefined;
}
}
@@ -761,7 +780,7 @@ export class UpdateAction extends ExtensionAction {
await this.extensionsWorkbenchService.install(extension);
alert(localize('updateExtensionComplete', "Updating extension {0} to version {1} completed.", extension.displayName, extension.latestVersion));
} catch (err) {
this.instantiationService.createInstance(PromptExtensionInstallFailureAction, extension, extension.latestVersion, InstallOperation.Update, err).run();
this.instantiationService.createInstance(PromptExtensionInstallFailureAction, extension, extension.latestVersion, InstallOperation.Update, undefined, err).run();
}
}
@@ -1124,7 +1143,7 @@ export class InstallAnotherVersionAction extends ExtensionAction {
await this.extensionsWorkbenchService.installVersion(this.extension!, pick.id);
}
} catch (error) {
this.instantiationService.createInstance(PromptExtensionInstallFailureAction, this.extension!, pick.latest ? this.extension!.latestVersion : pick.id, InstallOperation.Install, error).run();
this.instantiationService.createInstance(PromptExtensionInstallFailureAction, this.extension!, pick.latest ? this.extension!.latestVersion : pick.id, InstallOperation.Install, undefined, error).run();
}
}
return null;
@@ -1715,7 +1734,7 @@ export class InstallRecommendedExtensionAction extends Action {
try {
await this.extensionWorkbenchService.install(extension);
} catch (err) {
this.instantiationService.createInstance(PromptExtensionInstallFailureAction, extension, extension.latestVersion, InstallOperation.Install, err).run();
this.instantiationService.createInstance(PromptExtensionInstallFailureAction, extension, extension.latestVersion, InstallOperation.Install, undefined, err).run();
}
}
}
@@ -103,7 +103,7 @@ export class NativeRemoteExtensionManagementService extends ExtensionManagementC
const compatible = await this.galleryService.getCompatibleExtension(extension, includePreRelease, await this.getTargetPlatform());
if (compatible) {
if (includePreRelease && !compatible.properties.isPreReleaseVersion && extension.hasPreReleaseVersion) {
throw new ExtensionManagementError(localize('notFoundCompatiblePrereleaseDependency', "Can't install pre-release version of '{0}' extension because it is not compatible with the current version of {1} (version {2}).", extension.identifier.id, this.productService.nameLong, this.productService.version), ExtensionManagementErrorCode.Incompatible);
throw new ExtensionManagementError(localize('notFoundCompatiblePrereleaseDependency', "Can't install pre-release version of '{0}' extension because it is not compatible with the current version of {1} (version {2}).", extension.identifier.id, this.productService.nameLong, this.productService.version), ExtensionManagementErrorCode.IncompatiblePreRelease);
}
} else {
throw new ExtensionManagementError(localize('notFoundCompatibleDependency', "Can't install '{0}' extension because it is not compatible with the current version of {1} (version {2}).", extension.identifier.id, this.productService.nameLong, this.productService.version), ExtensionManagementErrorCode.Incompatible);