Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
microsoft
GitHub Repository: microsoft/vscode
Path: blob/main/src/vs/platform/extensionManagement/common/unsupportedExtensionsMigration.ts
3296 views
1
/*---------------------------------------------------------------------------------------------
2
* Copyright (c) Microsoft Corporation. All rights reserved.
3
* Licensed under the MIT License. See License.txt in the project root for license information.
4
*--------------------------------------------------------------------------------------------*/
5
6
import { CancellationToken } from '../../../base/common/cancellation.js';
7
import { EXTENSION_INSTALL_SKIP_PUBLISHER_TRUST_CONTEXT, IExtensionGalleryService, IExtensionManagementService, IGlobalExtensionEnablementService, InstallOperation } from './extensionManagement.js';
8
import { areSameExtensions, getExtensionId } from './extensionManagementUtil.js';
9
import { IExtensionStorageService } from './extensionStorage.js';
10
import { ExtensionType } from '../../extensions/common/extensions.js';
11
import { ILogService } from '../../log/common/log.js';
12
import * as semver from '../../../base/common/semver/semver.js';
13
14
/**
15
* Migrates the installed unsupported nightly extension to a supported pre-release extension. It includes following:
16
* - Uninstall the Unsupported extension
17
* - Install (with optional storage migration) the Pre-release extension only if
18
* - the extension is not installed
19
* - or it is a release version and the unsupported extension is enabled.
20
*/
21
export async function migrateUnsupportedExtensions(extensionManagementService: IExtensionManagementService, galleryService: IExtensionGalleryService, extensionStorageService: IExtensionStorageService, extensionEnablementService: IGlobalExtensionEnablementService, logService: ILogService): Promise<void> {
22
try {
23
const extensionsControlManifest = await extensionManagementService.getExtensionsControlManifest();
24
if (!extensionsControlManifest.deprecated) {
25
return;
26
}
27
const installed = await extensionManagementService.getInstalled(ExtensionType.User);
28
for (const [unsupportedExtensionId, deprecated] of Object.entries(extensionsControlManifest.deprecated)) {
29
if (!deprecated?.extension) {
30
continue;
31
}
32
const { id: preReleaseExtensionId, autoMigrate, preRelease } = deprecated.extension;
33
if (!autoMigrate) {
34
continue;
35
}
36
const unsupportedExtension = installed.find(i => areSameExtensions(i.identifier, { id: unsupportedExtensionId }));
37
// Unsupported Extension is not installed
38
if (!unsupportedExtension) {
39
continue;
40
}
41
42
const gallery = (await galleryService.getExtensions([{ id: preReleaseExtensionId, preRelease }], { targetPlatform: await extensionManagementService.getTargetPlatform(), compatible: true }, CancellationToken.None))[0];
43
if (!gallery) {
44
logService.info(`Skipping migrating '${unsupportedExtension.identifier.id}' extension because, the comaptible target '${preReleaseExtensionId}' extension is not found`);
45
continue;
46
}
47
48
try {
49
logService.info(`Migrating '${unsupportedExtension.identifier.id}' extension to '${preReleaseExtensionId}' extension...`);
50
51
const isUnsupportedExtensionEnabled = !extensionEnablementService.getDisabledExtensions().some(e => areSameExtensions(e, unsupportedExtension.identifier));
52
await extensionManagementService.uninstall(unsupportedExtension);
53
logService.info(`Uninstalled the unsupported extension '${unsupportedExtension.identifier.id}'`);
54
55
let preReleaseExtension = installed.find(i => areSameExtensions(i.identifier, { id: preReleaseExtensionId }));
56
if (!preReleaseExtension || (!preReleaseExtension.isPreReleaseVersion && isUnsupportedExtensionEnabled)) {
57
preReleaseExtension = await extensionManagementService.installFromGallery(gallery, { installPreReleaseVersion: true, isMachineScoped: unsupportedExtension.isMachineScoped, operation: InstallOperation.Migrate, context: { [EXTENSION_INSTALL_SKIP_PUBLISHER_TRUST_CONTEXT]: true } });
58
logService.info(`Installed the pre-release extension '${preReleaseExtension.identifier.id}'`);
59
if (!isUnsupportedExtensionEnabled) {
60
await extensionEnablementService.disableExtension(preReleaseExtension.identifier);
61
logService.info(`Disabled the pre-release extension '${preReleaseExtension.identifier.id}' because the unsupported extension '${unsupportedExtension.identifier.id}' is disabled`);
62
}
63
if (autoMigrate.storage) {
64
extensionStorageService.addToMigrationList(getExtensionId(unsupportedExtension.manifest.publisher, unsupportedExtension.manifest.name), getExtensionId(preReleaseExtension.manifest.publisher, preReleaseExtension.manifest.name));
65
logService.info(`Added pre-release extension to the storage migration list`);
66
}
67
}
68
logService.info(`Migrated '${unsupportedExtension.identifier.id}' extension to '${preReleaseExtensionId}' extension.`);
69
} catch (error) {
70
logService.error(error);
71
}
72
}
73
74
if (extensionsControlManifest.autoUpdate) {
75
for (const [extensionId, version] of Object.entries(extensionsControlManifest.autoUpdate)) {
76
try {
77
const extensionToAutoUpdate = installed.find(i => areSameExtensions(i.identifier, { id: extensionId }) && semver.lte(i.manifest.version, version));
78
if (!extensionToAutoUpdate) {
79
continue;
80
}
81
82
const gallery = (await galleryService.getExtensions([{ id: extensionId, preRelease: extensionToAutoUpdate.preRelease }], { targetPlatform: await extensionManagementService.getTargetPlatform(), compatible: true }, CancellationToken.None))[0];
83
if (!gallery) {
84
logService.info(`Skipping updating '${extensionToAutoUpdate.identifier.id}' extension because, the compatible target '${extensionId}' extension is not found`);
85
continue;
86
}
87
88
await extensionManagementService.installFromGallery(gallery, { installPreReleaseVersion: extensionToAutoUpdate.preRelease, isMachineScoped: extensionToAutoUpdate.isMachineScoped, operation: InstallOperation.Update, context: { [EXTENSION_INSTALL_SKIP_PUBLISHER_TRUST_CONTEXT]: true } });
89
logService.info(`Autoupdated '${extensionToAutoUpdate.identifier.id}' extension to '${gallery.version}' extension.`);
90
} catch (error) {
91
logService.error(error);
92
}
93
}
94
}
95
96
} catch (error) {
97
logService.error(error);
98
}
99
}
100
101