improve unhappy path when installing extensions

This commit is contained in:
Joao Moreno 2016-07-25 16:14:49 +02:00
parent 8ae904ffea
commit 7ee12f6cde
3 changed files with 43 additions and 28 deletions

View file

@ -98,31 +98,39 @@ export class ExtensionManagementService implements IExtensionManagementService {
install(extension: IGalleryExtension): TPromise<void>;
install(zipPath: string): TPromise<void>;
install(arg: any): TPromise<void> {
let id: string;
let result: TPromise<ILocalExtension>;
if (types.isString(arg)) {
const zipPath = arg as string;
return validate(zipPath).then(manifest => {
const id = getExtensionId(manifest, manifest.version);
result = validate(zipPath).then(manifest => {
id = getExtensionId(manifest, manifest.version);
this._onInstallExtension.fire({ id });
return this.installValidExtension(zipPath, id);
});
} else {
const extension = arg as IGalleryExtension;
id = getExtensionId(extension, extension.versions[0].version);
this._onInstallExtension.fire({ id, gallery: extension });
result = this.isObsolete(id).then(obsolete => {
if (obsolete) {
return TPromise.wrapError<ILocalExtension>(new Error(nls.localize('restartCode', "Please restart Code before reinstalling {0}.", extension.displayName || extension.name)));
}
return this.installFromGallery(arg);
});
}
const extension = arg as IGalleryExtension;
const id = getExtensionId(extension, extension.versions[0].version);
this._onInstallExtension.fire({ id, gallery: extension });
return this.isObsolete(id).then(obsolete => {
if (obsolete) {
return TPromise.wrapError<void>(new Error(nls.localize('restartCode', "Please restart Code before reinstalling {0}.", extension.displayName || extension.name)));
}
return this.installFromGallery(arg);
});
return result.then(
local => this._onDidInstallExtension.fire({ id, local }),
error => { this._onDidInstallExtension.fire({ id, error }); return TPromise.wrapError(error); }
);
}
private installFromGallery(extension: IGalleryExtension): TPromise<void> {
private installFromGallery(extension: IGalleryExtension): TPromise<ILocalExtension> {
return this.getLastValidExtensionVersion(extension).then(versionInfo => {
const version = versionInfo.version;
const url = versionInfo.downloadUrl;
@ -170,7 +178,7 @@ export class ExtensionManagementService implements IExtensionManagementService {
});
}
private installValidExtension(zipPath: string, id: string, metadata: IGalleryMetadata = null): TPromise<void> {
private installValidExtension(zipPath: string, id: string, metadata: IGalleryMetadata = null): TPromise<ILocalExtension> {
const extensionPath = path.join(this.extensionsPath, id);
const manifestPath = path.join(extensionPath, 'package.json');
@ -186,10 +194,9 @@ export class ExtensionManagementService implements IExtensionManagementService {
const rawManifest = assign(manifest, { __metadata: metadata });
return pfs.writeFile(manifestPath, JSON.stringify(rawManifest, null, '\t'))
.then(() => this._onDidInstallExtension.fire({ id, local }));
.then(() => local);
});
})
.then<void>(null, error => { this._onDidInstallExtension.fire({ id, error }); return TPromise.wrapError(error); });
});
}
uninstall(extension: ILocalExtension): TPromise<void> {

View file

@ -9,11 +9,13 @@ import { append, emmet as $, addClass, removeClass } from 'vs/base/browser/dom';
import { IDisposable, dispose } from 'vs/base/common/lifecycle';
import { ActionBar } from 'vs/base/browser/ui/actionbar/actionbar';
import { IInstantiationService } from 'vs/platform/instantiation/common/instantiation';
import { IMessageService, Severity } from 'vs/platform/message/common/message';
import { IDelegate } from 'vs/base/browser/ui/list/list';
import { IPagedRenderer } from 'vs/base/browser/ui/list/listPaging';
import { IExtension } from './extensions';
import { CombinedInstallAction, UpdateAction, EnableAction } from './extensionsActions';
import { Label, RatingsWidget, InstallWidget } from './extensionsWidgets';
import { EventType } from 'vs/base/common/events';
export interface ITemplateData {
element: HTMLElement;
@ -36,7 +38,10 @@ const actionOptions = { icon: true, label: true };
export class Renderer implements IPagedRenderer<IExtension, ITemplateData> {
constructor(@IInstantiationService private instantiationService: IInstantiationService) {}
constructor(
@IInstantiationService private instantiationService: IInstantiationService,
@IMessageService private messageService: IMessageService
) {}
get templateId() { return 'extension'; }
@ -54,6 +59,8 @@ export class Renderer implements IPagedRenderer<IExtension, ITemplateData> {
const author = append(footer, $('.author.ellipsis'));
const actionbar = new ActionBar(footer, { animated: false });
actionbar.addListener2(EventType.RUN, ({ error }) => error && this.messageService.show(Severity.Error, error));
const versionWidget = this.instantiationService.createInstance(Label, version, e => e.version);
const installCountWidget = this.instantiationService.createInstance(InstallWidget, installCount, { small: true });
const ratingsWidget = this.instantiationService.createInstance(RatingsWidget, ratings, { small: true });

View file

@ -298,18 +298,19 @@ export class ExtensionsWorkbenchService implements IExtensionsWorkbenchService {
extension.local = local;
extension.needsRestart = true;
let eventName: string = 'extensionGallery:install';
this.installing = this.installing.filter(e => e.id !== id);
const galleryId = local.metadata && local.metadata.id;
const installed = this.installed.filter(e => (e.local.metadata && e.local.metadata.id) === galleryId)[0];
let eventName: string;
if (!error) {
const galleryId = local.metadata && local.metadata.id;
const installed = this.installed.filter(e => (e.local.metadata && e.local.metadata.id) === galleryId)[0];
if (galleryId && installed) {
eventName = 'extensionGallery:update';
installed.local = local;
} else {
eventName = 'extensionGallery:install';
this.installed.push(extension);
if (galleryId && installed) {
eventName = 'extensionGallery:update';
installed.local = local;
} else {
this.installed.push(extension);
}
}
this.reportTelemetry(extension, eventName, !error);