patched-vscode/extensions/sagemaker-extensions-sync/src/extension.ts (80 lines of code) (raw):

import * as process from "process"; import * as vscode from 'vscode'; import { ExtensionInfo, IMAGE_EXTENSIONS_DIR, LOG_PREFIX, PERSISTENT_VOLUME_EXTENSIONS_DIR, } from "./constants" import { getExtensionsFromDirectory, getInstalledExtensions, installExtension, refreshExtensionsMetadata } from "./utils" export async function activate() { // this extension will only activate within a sagemaker app const isSageMakerApp = !!process.env?.SAGEMAKER_APP_TYPE_LOWERCASE; if (!isSageMakerApp) { return; } // get installed extensions. this could be different from pvExtensions b/c vscode sometimes doesn't delete the assets // for an old extension when uninstalling or changing versions const installedExtensions = new Set(await getInstalledExtensions()); console.log(`${LOG_PREFIX} Found installed extensions: `, Array.from(installedExtensions)); const prePackagedExtensions: ExtensionInfo[] = await getExtensionsFromDirectory(IMAGE_EXTENSIONS_DIR); const prePackagedExtensionsById: Record<string, ExtensionInfo> = {}; prePackagedExtensions.forEach(extension => { prePackagedExtensionsById[extension.identifier] = extension; }); console.log(`${LOG_PREFIX} Found pre-packaged extensions: `, prePackagedExtensions); const pvExtensions = await getExtensionsFromDirectory(PERSISTENT_VOLUME_EXTENSIONS_DIR); const pvExtensionsByName: Record<string, ExtensionInfo> = {}; const pvExtensionsById: Record<string, ExtensionInfo> = {}; pvExtensions.forEach(extension => { if (installedExtensions.has(extension.identifier)) { // only index extensions that are installed pvExtensionsByName[extension.name] = extension; pvExtensionsById[extension.identifier] = extension; } }); console.log(`${LOG_PREFIX} Found installed extensions in persistent volume: `, pvExtensionsById); // check each pre-packaged extension, record if it is not in installed extensions or version mismatch // store unsynced extensions as {identifier pre-packaged ext: currently installed version} const unsyncedExtensions: Record<string, string | null> = {} prePackagedExtensions.forEach(extension => { const id = extension.identifier; if (!(installedExtensions.has(id))){ unsyncedExtensions[id] = pvExtensionsByName[extension.name]?.version ?? null; } }); console.log(`${LOG_PREFIX} Unsynced extensions: `, unsyncedExtensions); if (Object.keys(unsyncedExtensions).length !== 0) { const selection = await vscode.window.showWarningMessage( 'Warning: You have unsynchronized extensions from SageMaker Distribution \ which could result in incompatibilities with Code Editor. Do you want to install them?', "Synchronize Extensions", "Dismiss"); if (selection === "Synchronize Extensions") { const quickPick = vscode.window.createQuickPick(); quickPick.items = Object.keys(unsyncedExtensions).map(extensionId => ({ label: extensionId, description: unsyncedExtensions[extensionId] ? `Currently installed version: ${unsyncedExtensions[extensionId]}` : undefined, })); quickPick.placeholder = 'Select extensions to install'; quickPick.canSelectMany = true; quickPick.ignoreFocusOut = true; quickPick.onDidAccept(async () => { const selectedExtensions = quickPick.selectedItems.map(item => item.label); for (const extensionId of selectedExtensions) { const extensionName = prePackagedExtensionsById[extensionId].name; await installExtension(prePackagedExtensionsById[extensionId], pvExtensionsByName[extensionName]); } await refreshExtensionsMetadata(); quickPick.hide(); await vscode.window.showInformationMessage( 'Extensions have been installed. \nWould you like to reload the window?', { modal: true }, 'Reload' ).then(selection => { if (selection === 'Reload') { vscode.commands.executeCommand('workbench.action.reloadWindow'); } }); }); quickPick.show(); } } }