提交 cbb9fa73 编写于 作者: S Sandeep Somavarapu

Fix #59481

上级 c2c2e48d
...@@ -7,6 +7,7 @@ import { localize } from 'vs/nls'; ...@@ -7,6 +7,7 @@ import { localize } from 'vs/nls';
import product from 'vs/platform/node/product'; import product from 'vs/platform/node/product';
import pkg from 'vs/platform/node/package'; import pkg from 'vs/platform/node/package';
import * as path from 'path'; import * as path from 'path';
import * as semver from 'semver';
import { TPromise } from 'vs/base/common/winjs.base'; import { TPromise } from 'vs/base/common/winjs.base';
import { sequence } from 'vs/base/common/async'; import { sequence } from 'vs/base/common/async';
...@@ -35,10 +36,7 @@ import { StateService } from 'vs/platform/state/node/stateService'; ...@@ -35,10 +36,7 @@ import { StateService } from 'vs/platform/state/node/stateService';
import { createSpdLogService } from 'vs/platform/log/node/spdlogService'; import { createSpdLogService } from 'vs/platform/log/node/spdlogService';
import { ILogService, getLogLevel } from 'vs/platform/log/common/log'; import { ILogService, getLogLevel } from 'vs/platform/log/common/log';
import { isPromiseCanceledError } from 'vs/base/common/errors'; import { isPromiseCanceledError } from 'vs/base/common/errors';
import { IDialogService } from 'vs/platform/dialogs/common/dialogs'; import { areSameExtensions, getGalleryExtensionIdFromLocal, adoptToGalleryExtensionId, getGalleryExtensionId } from 'vs/platform/extensionManagement/common/extensionManagementUtil';
import { CommandLineDialogService } from 'vs/platform/dialogs/node/dialogService';
import { areSameExtensions, getGalleryExtensionIdFromLocal, adoptToGalleryExtensionId } from 'vs/platform/extensionManagement/common/extensionManagementUtil';
import Severity from 'vs/base/common/severity';
import { URI } from 'vs/base/common/uri'; import { URI } from 'vs/base/common/uri';
import { getManifest } from 'vs/platform/extensionManagement/node/extensionManagementUtil'; import { getManifest } from 'vs/platform/extensionManagement/node/extensionManagementUtil';
...@@ -72,8 +70,7 @@ class Main { ...@@ -72,8 +70,7 @@ class Main {
constructor( constructor(
@IEnvironmentService private environmentService: IEnvironmentService, @IEnvironmentService private environmentService: IEnvironmentService,
@IExtensionManagementService private extensionManagementService: IExtensionManagementService, @IExtensionManagementService private extensionManagementService: IExtensionManagementService,
@IExtensionGalleryService private extensionGalleryService: IExtensionGalleryService, @IExtensionGalleryService private extensionGalleryService: IExtensionGalleryService
@IDialogService private dialogService: IDialogService
) { } ) { }
run(argv: ParsedArgs): TPromise<any> { run(argv: ParsedArgs): TPromise<any> {
...@@ -111,17 +108,22 @@ class Main { ...@@ -111,17 +108,22 @@ class Main {
.filter(e => /\.vsix$/i.test(e)) .filter(e => /\.vsix$/i.test(e))
.map(id => () => { .map(id => () => {
const extension = path.isAbsolute(id) ? id : path.join(process.cwd(), id); const extension = path.isAbsolute(id) ? id : path.join(process.cwd(), id);
return this.validate(extension, force)
return this.extensionManagementService.install(URI.file(extension)).then(() => { .then(valid => {
console.log(localize('successVsixInstall', "Extension '{0}' was successfully installed!", getBaseLabel(extension))); if (valid) {
}, error => { return this.extensionManagementService.install(URI.file(extension)).then(() => {
if (isPromiseCanceledError(error)) { console.log(localize('successVsixInstall', "Extension '{0}' was successfully installed!", getBaseLabel(extension)));
console.log(localize('cancelVsixInstall', "Cancelled installing Extension '{0}'.", getBaseLabel(extension))); }, error => {
if (isPromiseCanceledError(error)) {
console.log(localize('cancelVsixInstall', "Cancelled installing Extension '{0}'.", getBaseLabel(extension)));
return null;
} else {
return TPromise.wrapError(error);
}
});
}
return null; return null;
} else { });
return TPromise.wrapError(error);
}
});
}); });
const galleryTasks: Task[] = extensions const galleryTasks: Task[] = extensions
...@@ -153,15 +155,8 @@ class Main { ...@@ -153,15 +155,8 @@ class Main {
console.log(localize('updateMessage', "Updating the Extension '{0}' to the version {1}", id, extension.version)); console.log(localize('updateMessage', "Updating the Extension '{0}' to the version {1}", id, extension.version));
return this.installFromGallery(id, extension); return this.installFromGallery(id, extension);
} else { } else {
const updateMessage = localize('updateConfirmationMessage', "Extension '{0}' v{1} is already installed, but a newer version {2} is available in the marketplace. Would you like to update?", id, installedExtension.manifest.version, extension.version); console.log(localize('forceUpdate', "Extension '{0}' v{1} is already installed, but a newer version {2} is available in the marketplace. Use '--force' option to update to newer version.", id, installedExtension.manifest.version, extension.version));
return this.dialogService.show(Severity.Info, updateMessage, [localize('yes', "Yes"), localize('no', "No")]) return Promise.resolve(null);
.then(option => {
if (option === 0) {
return this.installFromGallery(id, extension);
}
console.log(localize('cancelInstall', "Cancelled installing Extension '{0}'.", id));
return TPromise.as(null);
});
} }
} else { } else {
console.log(localize('alreadyInstalled', "Extension '{0}' is already installed.", version ? `${id}@${version}` : id)); console.log(localize('alreadyInstalled', "Extension '{0}' is already installed.", version ? `${id}@${version}` : id));
...@@ -178,6 +173,26 @@ class Main { ...@@ -178,6 +173,26 @@ class Main {
return sequence([...vsixTasks, ...galleryTasks]); return sequence([...vsixTasks, ...galleryTasks]);
} }
private validate(vsix: string, force: boolean): Thenable<boolean> {
return getManifest(vsix)
.then(manifest => {
if (manifest) {
const extensionIdentifier = { id: getGalleryExtensionId(manifest.publisher, manifest.name) };
return this.extensionManagementService.getInstalled(LocalExtensionType.User)
.then(installedExtensions => {
const newer = installedExtensions.filter(local => areSameExtensions(extensionIdentifier, { id: getGalleryExtensionIdFromLocal(local) }) && semver.gt(local.manifest.version, manifest.version))[0];
if (newer && !force) {
console.log(localize('forceDowngrade', "A newer version of this extension '{0}' v{1} is already installed. Use '--force' option to downgrade to older version.", newer.galleryIdentifier.id, newer.manifest.version, manifest.version));
return false;
}
return true;
});
} else {
return Promise.reject(new Error('Invalid vsix'));
}
});
}
private installFromGallery(id: string, extension: IGalleryExtension): TPromise<void> { private installFromGallery(id: string, extension: IGalleryExtension): TPromise<void> {
console.log(localize('installing', "Installing...")); console.log(localize('installing', "Installing..."));
return this.extensionManagementService.installFromGallery(extension) return this.extensionManagementService.installFromGallery(extension)
...@@ -252,7 +267,6 @@ export function main(argv: ParsedArgs): TPromise<void> { ...@@ -252,7 +267,6 @@ export function main(argv: ParsedArgs): TPromise<void> {
services.set(IRequestService, new SyncDescriptor(RequestService)); services.set(IRequestService, new SyncDescriptor(RequestService));
services.set(IExtensionManagementService, new SyncDescriptor(ExtensionManagementService)); services.set(IExtensionManagementService, new SyncDescriptor(ExtensionManagementService));
services.set(IExtensionGalleryService, new SyncDescriptor(ExtensionGalleryService)); services.set(IExtensionGalleryService, new SyncDescriptor(ExtensionGalleryService));
services.set(IDialogService, new SyncDescriptor(CommandLineDialogService));
const appenders: AppInsightsAppender[] = []; const appenders: AppInsightsAppender[] = [];
if (isBuilt && !extensionDevelopmentLocationURI && !envService.args['disable-telemetry'] && product.enableTelemetry) { if (isBuilt && !extensionDevelopmentLocationURI && !envService.args['disable-telemetry'] && product.enableTelemetry) {
......
...@@ -6,7 +6,6 @@ ...@@ -6,7 +6,6 @@
import * as nls from 'vs/nls'; import * as nls from 'vs/nls';
import * as path from 'path'; import * as path from 'path';
import * as pfs from 'vs/base/node/pfs'; import * as pfs from 'vs/base/node/pfs';
import * as errors from 'vs/base/common/errors';
import { assign } from 'vs/base/common/objects'; import { assign } from 'vs/base/common/objects';
import { toDisposable, Disposable } from 'vs/base/common/lifecycle'; import { toDisposable, Disposable } from 'vs/base/common/lifecycle';
import { flatten } from 'vs/base/common/arrays'; import { flatten } from 'vs/base/common/arrays';
...@@ -34,8 +33,6 @@ import pkg from 'vs/platform/node/package'; ...@@ -34,8 +33,6 @@ import pkg from 'vs/platform/node/package';
import { isMacintosh, isWindows } from 'vs/base/common/platform'; import { isMacintosh, isWindows } from 'vs/base/common/platform';
import { ILogService } from 'vs/platform/log/common/log'; import { ILogService } from 'vs/platform/log/common/log';
import { ExtensionsManifestCache } from 'vs/platform/extensionManagement/node/extensionsManifestCache'; import { ExtensionsManifestCache } from 'vs/platform/extensionManagement/node/extensionsManifestCache';
import { IDialogService } from 'vs/platform/dialogs/common/dialogs';
import Severity from 'vs/base/common/severity';
import { ExtensionsLifecycle } from 'vs/platform/extensionManagement/node/extensionLifecycle'; import { ExtensionsLifecycle } from 'vs/platform/extensionManagement/node/extensionLifecycle';
import { toErrorMessage } from 'vs/base/common/errorMessage'; import { toErrorMessage } from 'vs/base/common/errorMessage';
import { ITelemetryService } from 'vs/platform/telemetry/common/telemetry'; import { ITelemetryService } from 'vs/platform/telemetry/common/telemetry';
...@@ -131,7 +128,6 @@ export class ExtensionManagementService extends Disposable implements IExtension ...@@ -131,7 +128,6 @@ export class ExtensionManagementService extends Disposable implements IExtension
constructor( constructor(
@IEnvironmentService private environmentService: IEnvironmentService, @IEnvironmentService private environmentService: IEnvironmentService,
@IDialogService private dialogService: IDialogService,
@IExtensionGalleryService private galleryService: IExtensionGalleryService, @IExtensionGalleryService private galleryService: IExtensionGalleryService,
@ILogService private logService: ILogService, @ILogService private logService: ILogService,
@optional(IDownloadService) private downloadService: IDownloadService, @optional(IDownloadService) private downloadService: IDownloadService,
...@@ -206,9 +202,14 @@ export class ExtensionManagementService extends Disposable implements IExtension ...@@ -206,9 +202,14 @@ export class ExtensionManagementService extends Disposable implements IExtension
} }
return this.removeIfExists(identifier.id) return this.removeIfExists(identifier.id)
.then( .then(
() => this.checkOutdated(manifest) () => {
.then(validated => { const extensionIdentifier = { id: getGalleryExtensionId(manifest.publisher, manifest.name) };
if (validated) { return this.getInstalled(LocalExtensionType.User)
.then(installedExtensions => {
const newer = installedExtensions.filter(local => areSameExtensions(extensionIdentifier, { id: getGalleryExtensionIdFromLocal(local) }) && semver.gt(local.manifest.version, manifest.version))[0];
return newer ? this.uninstall(newer, true) : null;
})
.then(() => {
this.logService.info('Installing the extension:', identifier.id); this.logService.info('Installing the extension:', identifier.id);
this._onInstallExtension.fire({ identifier, zipPath }); this._onInstallExtension.fire({ identifier, zipPath });
return this.getMetadata(getGalleryExtensionId(manifest.publisher, manifest.name)) return this.getMetadata(getGalleryExtensionId(manifest.publisher, manifest.name))
...@@ -221,9 +222,8 @@ export class ExtensionManagementService extends Disposable implements IExtension ...@@ -221,9 +222,8 @@ export class ExtensionManagementService extends Disposable implements IExtension
this.logService.error('Failed to install the extension:', identifier.id, e.message); this.logService.error('Failed to install the extension:', identifier.id, e.message);
return Promise.reject(e); return Promise.reject(e);
}); });
} });
return null; },
}),
e => Promise.reject(new Error(nls.localize('restartCode', "Please restart VS Code before reinstalling {0}.", manifest.displayName || manifest.name)))); e => Promise.reject(new Error(nls.localize('restartCode', "Please restart VS Code before reinstalling {0}.", manifest.displayName || manifest.name))));
}); });
}); });
...@@ -247,29 +247,6 @@ export class ExtensionManagementService extends Disposable implements IExtension ...@@ -247,29 +247,6 @@ export class ExtensionManagementService extends Disposable implements IExtension
.then(existing => existing ? this.removeExtension(existing, 'existing') : null); .then(existing => existing ? this.removeExtension(existing, 'existing') : null);
} }
private checkOutdated(manifest: IExtensionManifest): Promise<boolean> {
const extensionIdentifier = { id: getGalleryExtensionId(manifest.publisher, manifest.name) };
return this.getInstalled(LocalExtensionType.User)
.then(installedExtensions => {
const newer = installedExtensions.filter(local => areSameExtensions(extensionIdentifier, { id: getGalleryExtensionIdFromLocal(local) }) && semver.gt(local.manifest.version, manifest.version))[0];
if (newer) {
const message = nls.localize('installingOutdatedExtension', "A newer version of this extension is already installed. Would you like to override this with the older version?");
const buttons = [
nls.localize('override', "Override"),
nls.localize('cancel', "Cancel")
];
return this.dialogService.show(Severity.Info, message, buttons, { cancelId: 1 })
.then<boolean>(value => {
if (value === 0) {
return this.uninstall(newer, true).then(() => true);
}
return Promise.reject(errors.canceled());
});
}
return true;
});
}
private installFromZipPath(identifier: IExtensionIdentifier, zipPath: string, metadata: IGalleryMetadata, type: LocalExtensionType, token: CancellationToken): Promise<ILocalExtension> { private installFromZipPath(identifier: IExtensionIdentifier, zipPath: string, metadata: IGalleryMetadata, type: LocalExtensionType, token: CancellationToken): Promise<ILocalExtension> {
return this.toNonCancellablePromise(this.getInstalled() return this.toNonCancellablePromise(this.getInstalled()
.then(installed => { .then(installed => {
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册