- show warning for unsupported extensions
- action to switch to prerelease
This commit is contained in:
Sandeep Somavarapu 2021-11-26 02:02:41 +01:00
parent 503a9bcd16
commit a45c7f09cc
No known key found for this signature in database
GPG key ID: 1FED25EC4646638B
5 changed files with 80 additions and 18 deletions

View file

@ -30,7 +30,7 @@ import {
UpdateAction, ReloadAction, EnableDropDownAction, DisableDropDownAction, ExtensionStatusLabelAction, SetFileIconThemeAction, SetColorThemeAction,
RemoteInstallAction, ExtensionStatusAction, LocalInstallAction, ToggleSyncExtensionAction, SetProductIconThemeAction,
ActionWithDropDownAction, InstallDropdownAction, InstallingLabelAction, UninstallAction, ExtensionActionWithDropdownActionViewItem, ExtensionDropDownAction,
InstallAnotherVersionAction, ExtensionEditorManageExtensionAction, WebInstallAction, SwitchToPreReleaseVersionAction, SwitchToReleasedVersionAction
InstallAnotherVersionAction, ExtensionEditorManageExtensionAction, WebInstallAction, SwitchToPreReleaseVersionAction, SwitchToReleasedVersionAction, SwitchUnsupportedExtensionToPreReleaseExtensionAction
} from 'vs/workbench/contrib/extensions/browser/extensionsActions';
import { IKeybindingService } from 'vs/platform/keybinding/common/keybinding';
import { DomScrollableElement } from 'vs/base/browser/ui/scrollbar/scrollableElement';
@ -456,6 +456,7 @@ export class ExtensionEditor extends EditorPane {
]),
this.instantiationService.createInstance(SwitchToPreReleaseVersionAction),
this.instantiationService.createInstance(SwitchToReleasedVersionAction),
this.instantiationService.createInstance(SwitchUnsupportedExtensionToPreReleaseExtensionAction),
this.instantiationService.createInstance(ToggleSyncExtensionAction),
new ExtensionEditorManageExtensionAction(this.scopedContextKeyService || this.contextKeyService, this.instantiationService),
];

View file

@ -64,6 +64,7 @@ import { escapeMarkdownSyntaxTokens, IMarkdownString, MarkdownString } from 'vs/
import { IPaneCompositePartService } from 'vs/workbench/services/panecomposite/browser/panecomposite';
import { ViewContainerLocation } from 'vs/workbench/common/views';
import { flatten } from 'vs/base/common/arrays';
import { isBoolean } from 'vs/base/common/types';
function getRelativeDateLabel(date: Date): string {
const delta = new Date().getTime() - date.getTime();
@ -1125,20 +1126,46 @@ export class SwitchToReleasedVersionAction extends ExtensionAction {
}
}
export class SwitchUnsupportedExtensionToPreReleaseExtensionAction extends Action {
export class SwitchUnsupportedExtensionToPreReleaseExtensionAction extends ExtensionAction {
private static readonly Class = `${ExtensionAction.LABEL_ACTION_CLASS} hide-when-disabled`;
constructor(
@IExtensionGalleryService private readonly galleryService: IExtensionGalleryService,
@IInstantiationService private readonly instantiationService: IInstantiationService,
) {
super('workbench.extensions.action.switchUnsupportedExtensionToPreReleaseExtension', '', SwitchUnsupportedExtensionToPreReleaseExtensionAction.Class);
}
update(): void {
this.enabled = false;
if (!!this.extension && !!this.extension.local && this.extension.isUnsupported && !isBoolean(this.extension.isUnsupported) && this.extension.state === ExtensionState.Installed) {
this.enabled = true;
this.label = localize('switchUnsupportedExtensionToPreReleaseExtension', "Switch to '{0}' Pre-Release version", this.extension.isUnsupported.preReleaseExtension.displayName);
}
}
override async run(): Promise<any> {
if (!!this.extension && !!this.extension.local && this.extension.isUnsupported && !isBoolean(this.extension.isUnsupported)) {
const gallery = (await this.galleryService.getExtensions([{ id: this.extension.isUnsupported.preReleaseExtension.id }], true, CancellationToken.None))[0];
return this.instantiationService.createInstance(SwitchUnsupportedExtensionToPreReleaseExtensionCommandAction, this.extension.local, gallery, false).run();
}
}
}
export class SwitchUnsupportedExtensionToPreReleaseExtensionCommandAction extends Action {
constructor(
private readonly local: ILocalExtension,
private readonly gallery: IGalleryExtension,
private promptReload: boolean,
@IExtensionManagementService private readonly extensionManagementService: IExtensionManagementService,
@IProductService private readonly productService: IProductService,
@IHostService private readonly hostService: IHostService,
@IWorkbenchExtensionEnablementService private readonly workbenchExtensionEnablementService: IWorkbenchExtensionEnablementService,
@INotificationService private readonly notificationService: INotificationService,
) {
super('workbench.extensions.action.switchUnsupportedExtensionToPreReleaseExtension', localize('switchUnsupportedExtensionToPreReleaseExtension', "Switch to '{0}' Pre-Release version", gallery.displayName), SwitchUnsupportedExtensionToPreReleaseExtensionAction.Class);
super('workbench.extensions.action.switchUnsupportedExtensionToPreReleaseExtensionCommand', localize('switchUnsupportedExtensionToPreReleaseExtension', "Switch to '{0}' Pre-Release version", gallery.displayName));
}
override async run(): Promise<any> {
@ -1147,15 +1174,17 @@ export class SwitchUnsupportedExtensionToPreReleaseExtensionAction extends Actio
this.extensionManagementService.installFromGallery(this.gallery, { installPreReleaseVersion: true, isMachineScoped: this.local.isMachineScoped })
.then(local => this.workbenchExtensionEnablementService.setEnablement([this.local], EnablementState.EnabledGlobally)),
]);
this.notificationService.prompt(
Severity.Info,
localize('SwitchToAnotherReleaseExtension.successReload', "Please reload {0} to complete switching to the '{1}' extension.", this.productService.nameLong, this.gallery.displayName),
[{
label: localize('reloadNow', "Reload Now"),
run: () => this.hostService.reload()
}],
{ sticky: true }
);
if (this.promptReload) {
this.notificationService.prompt(
Severity.Info,
localize('SwitchToAnotherReleaseExtension.successReload', "Please reload {0} to complete switching to the '{1}' extension.", this.productService.nameLong, this.gallery.displayName),
[{
label: localize('reloadNow', "Reload Now"),
run: () => this.hostService.reload()
}],
{ sticky: true }
);
}
}
}
@ -2211,12 +2240,21 @@ export class ExtensionStatusAction extends ExtensionAction {
return;
}
if (this.extension.gallery && this.extension.state === ExtensionState.Uninstalled && !await this.extensionsWorkbenchService.canInstall(this.extension)) {
if (this.extension.isMalicious) {
this.updateStatus({ icon: warningIcon, message: new MarkdownString(localize('malicious tooltip', "This extension was reported to be problematic.")) }, true);
return;
if (this.extension.isMalicious) {
this.updateStatus({ icon: warningIcon, message: new MarkdownString(localize('malicious tooltip', "This extension was reported to be problematic.")) }, true);
return;
}
if (this.extension.isUnsupported) {
if (isBoolean(this.extension.isUnsupported)) {
this.updateStatus({ icon: warningIcon, message: new MarkdownString(localize('unsupported tooltip', "This extension no longer supported.")) }, true);
} else {
const link = `[${this.extension.isUnsupported.preReleaseExtension.displayName}](${URI.parse(`command:extension.open?${encodeURIComponent(JSON.stringify([this.extension.isUnsupported.preReleaseExtension.id]))}`)})`;
this.updateStatus({ icon: warningIcon, message: new MarkdownString(localize('unsupported prerelease tooltip', "This extension is now part of the {0} extension as a pre-release version and it is no longer supported.", link)) }, true);
}
return;
}
if (this.extension.gallery && this.extension.state === ExtensionState.Uninstalled && !await this.extensionsWorkbenchService.canInstall(this.extension)) {
if (this.extensionManagementServerService.localExtensionManagementServer || this.extensionManagementServerService.remoteExtensionManagementServer) {
const targetPlatform = await (this.extensionManagementServerService.localExtensionManagementServer ? this.extensionManagementServerService.localExtensionManagementServer!.extensionManagementService.getTargetPlatform() : this.extensionManagementServerService.remoteExtensionManagementServer!.extensionManagementService.getTargetPlatform());
const message = new MarkdownString(`${localize('incompatible platform', "The '{0}' extension is not available in {1} for {2}.", this.extension.displayName || this.extension.identifier.id, this.productService.nameLong, TargetPlatformToString(targetPlatform))} [${localize('learn more', "Learn More")}](https://aka.ms/vscode-platform-specific-extensions)`);

View file

@ -186,6 +186,7 @@ class Extension implements IExtension {
}
public isMalicious: boolean = false;
public isUnsupported: boolean | { preReleaseExtension: { id: string, displayName: string } } = false;
get installCount(): number | undefined {
return this.gallery ? this.gallery.installCount : undefined;
@ -440,6 +441,17 @@ class Extensions extends Disposable {
hasChanged = true;
}
const unsupportedPreRelease = extensionsControlManifest.unsupportedPreReleaseExtensions ? extensionsControlManifest.unsupportedPreReleaseExtensions[extension.identifier.id.toLowerCase()] : undefined;
if (unsupportedPreRelease) {
if (isBoolean(extension.isUnsupported) || !areSameExtensions({ id: extension.isUnsupported.preReleaseExtension.id }, { id: unsupportedPreRelease.id })) {
extension.isUnsupported = { preReleaseExtension: unsupportedPreRelease };
hasChanged = true;
}
} else if (extension.isUnsupported) {
extension.isUnsupported = false;
hasChanged = true;
}
if (hasChanged) {
this._onChange.fire({ extension });
}
@ -913,6 +925,12 @@ export class ExtensionsWorkbenchService extends Disposable implements IExtension
if (extensionsControlManifest.malicious.some(identifier => areSameExtensions(extension.identifier, identifier))) {
extension.isMalicious = true;
}
const unsupportedPreRelease = extensionsControlManifest.unsupportedPreReleaseExtensions ? extensionsControlManifest.unsupportedPreReleaseExtensions[extension.identifier.id.toLowerCase()] : undefined;
if (unsupportedPreRelease) {
if (isBoolean(extension.isUnsupported) || !areSameExtensions({ id: extension.isUnsupported.preReleaseExtension.id }, { id: unsupportedPreRelease.id })) {
extension.isUnsupported = { preReleaseExtension: unsupportedPreRelease };
}
}
return extension;
}
@ -1034,6 +1052,10 @@ export class ExtensionsWorkbenchService extends Disposable implements IExtension
return false;
}
if (extension.isUnsupported) {
return false;
}
if (!extension.gallery) {
return false;
}

View file

@ -11,7 +11,7 @@ import { ExtensionType, IExtensionIdentifier } from 'vs/platform/extensions/comm
import { IInstantiationService } from 'vs/platform/instantiation/common/instantiation';
import { INotificationService, Severity } from 'vs/platform/notification/common/notification';
import { IWorkbenchContribution } from 'vs/workbench/common/contributions';
import { SwitchUnsupportedExtensionToPreReleaseExtensionAction } from 'vs/workbench/contrib/extensions/browser/extensionsActions';
import { SwitchUnsupportedExtensionToPreReleaseExtensionCommandAction } from 'vs/workbench/contrib/extensions/browser/extensionsActions';
export class UnsupportedPreReleaseExtensionsChecker implements IWorkbenchContribution {
@ -56,7 +56,7 @@ export class UnsupportedPreReleaseExtensionsChecker implements IWorkbenchContrib
if (unsupportedPreReleaseExtensions.length === 1) {
const [local, gallery] = unsupportedPreReleaseExtensions[0];
const action = this.instantiationService.createInstance(SwitchUnsupportedExtensionToPreReleaseExtensionAction, unsupportedPreReleaseExtensions[0][0], unsupportedPreReleaseExtensions[0][1]);
const action = this.instantiationService.createInstance(SwitchUnsupportedExtensionToPreReleaseExtensionCommandAction, unsupportedPreReleaseExtensions[0][0], unsupportedPreReleaseExtensions[0][1], true);
this.notificationService.notify({
severity: Severity.Info,
message: localize('unsupported prerelease message', "'{0}' extension is now part of the '{1}' extension as a pre-release version and it is no longer supported. Would you like to switch to '{2}' extension?", local.manifest.displayName || local.identifier.id, gallery.displayName, gallery.displayName),

View file

@ -76,6 +76,7 @@ export interface IExtension {
readonly local?: ILocalExtension;
gallery?: IGalleryExtension;
readonly isMalicious: boolean;
readonly isUnsupported: boolean | { preReleaseExtension: { id: string, displayName: string } };
}
export const SERVICE_ID = 'extensionsWorkbenchService';