diff --git a/src/vs/platform/extensionManagement/common/extensionManagementCLI.ts b/src/vs/platform/extensionManagement/common/extensionManagementCLI.ts index 3bc65f49b03f7..f1c3f891d02b5 100644 --- a/src/vs/platform/extensionManagement/common/extensionManagementCLI.ts +++ b/src/vs/platform/extensionManagement/common/extensionManagementCLI.ts @@ -182,6 +182,11 @@ export class ExtensionManagementCLI { const { id, version, installOptions } = installExtensionInfo; const installedExtension = installed.find(i => areSameExtensions(i.identifier, { id })); if (installedExtension) { + const builtinAutoUpdateMessage = this.validateBuiltinExtensionEnabledWithAutoUpdates(installedExtension); + if (builtinAutoUpdateMessage) { + this.logger.info(builtinAutoUpdateMessage); + return false; + } if (!force && (!version || (version === 'prerelease' && installedExtension.preRelease))) { this.logger.info(localize('alreadyInstalled-checkAndUpdate', "Extension '{0}' v{1} is already installed. Use '--force' option to update to latest version or provide '@' to install a specific version, for example: '{2}@1.2.3'.", id, installedExtension.manifest.version, id)); return false; @@ -301,13 +306,22 @@ export class ExtensionManagementCLI { } private async validateVSIX(manifest: IExtensionManifest, force: boolean, profileLocation: URI | undefined, installedExtensions: ILocalExtension[]): Promise { - if (!force) { - const extensionIdentifier = { id: getGalleryExtensionId(manifest.publisher, manifest.name) }; - const newer = installedExtensions.find(local => areSameExtensions(extensionIdentifier, local.identifier) && gt(local.manifest.version, manifest.version)); - if (newer) { - this.logger.info(localize('forceDowngrade', "A newer version of extension '{0}' v{1} is already installed. Use '--force' option to downgrade to older version.", newer.identifier.id, newer.manifest.version, manifest.version)); + const extensionIdentifier = { id: getGalleryExtensionId(manifest.publisher, manifest.name) }; + const existingExtension = installedExtensions.find(local => areSameExtensions(extensionIdentifier, local.identifier)); + + if (existingExtension) { + const builtinAutoUpdateMessage = this.validateBuiltinExtensionEnabledWithAutoUpdates(existingExtension); + if (builtinAutoUpdateMessage) { + this.logger.info(builtinAutoUpdateMessage); return false; } + + if (!force) { + if (gt(existingExtension.manifest.version, manifest.version)) { + this.logger.info(localize('forceDowngrade', "A newer version of extension '{0}' v{1} is already installed. Use '--force' option to downgrade to older version.", existingExtension.identifier.id, existingExtension.manifest.version, manifest.version)); + return false; + } + } } return this.validateExtensionKind(manifest); @@ -371,4 +385,11 @@ export class ExtensionManagementCLI { return this.location ? localize('notInstalleddOnLocation', "Extension '{0}' is not installed on {1}.", id, this.location) : localize('notInstalled', "Extension '{0}' is not installed.", id); } + private validateBuiltinExtensionEnabledWithAutoUpdates(extension: ILocalExtension): string | undefined { + if (extension.isBuiltin && this.productService.builtInExtensionsEnabledWithAutoUpdates.some(e => e.toLowerCase() === extension.identifier.id.toLowerCase()) && !extension.forceAutoUpdate) { + return localize('builtinAutoUpdate', "Extension '{0}' is a built-in extension and not allowed to be updated in the current product quality '{1}'.", extension.identifier.id, this.productService.quality); + } + return undefined; + } + }