diff --git a/src/common/localize.ts b/src/common/localize.ts index ab39e50e..f9864f7c 100644 --- a/src/common/localize.ts +++ b/src/common/localize.ts @@ -29,6 +29,7 @@ export namespace PackageManagement { export const selectPackagesToUninstall = l10n.t('Select packages to uninstall'); export const enterPackagesPlaceHolder = l10n.t('Enter package names separated by space'); export const editArguments = l10n.t('Edit arguments'); + export const skipPackageInstallation = l10n.t('Skip package installation'); } export namespace Pickers { diff --git a/src/managers/builtin/pipUtils.ts b/src/managers/builtin/pipUtils.ts index 9a4fa943..259e5ceb 100644 --- a/src/managers/builtin/pipUtils.ts +++ b/src/managers/builtin/pipUtils.ts @@ -8,6 +8,7 @@ import { PythonEnvironmentApi, PythonProject } from '../../api'; import { findFiles } from '../../common/workspace.apis'; import { EXTENSION_ROOT_DIR } from '../../common/constants'; import { Installable, selectFromCommonPackagesToInstall, selectFromInstallableToInstall } from '../common/pickers'; +import { traceInfo } from '../../common/logging'; async function tomlParse(fsPath: string, log?: LogOutputChannel): Promise { try { @@ -75,47 +76,56 @@ async function selectWorkspaceOrCommon( installable: Installable[], common: Installable[], ): Promise { - if (installable.length > 0) { - const selected = await showQuickPickWithButtons( - [ - { - label: PackageManagement.workspaceDependencies, - description: PackageManagement.workspaceDependenciesDescription, - }, - { - label: PackageManagement.commonPackages, - description: PackageManagement.commonPackagesDescription, - }, - ], - { - placeHolder: Pickers.Packages.selectOption, - ignoreFocusOut: true, - showBackButton: true, - matchOnDescription: false, - matchOnDetail: false, - }, - ); - if (selected && !Array.isArray(selected)) { - try { - if (selected.label === PackageManagement.workspaceDependencies) { - return await selectFromInstallableToInstall(installable); - } else if (selected.label === PackageManagement.commonPackages) { - return await selectFromCommonPackagesToInstall(common); - } - // eslint-disable-next-line @typescript-eslint/no-explicit-any - } catch (ex: any) { - if (ex === QuickInputButtons.Back) { - return selectWorkspaceOrCommon(installable, common); - } - } - } + if (installable.length === 0 && common.length === 0) { return undefined; } + const items = []; + if (installable.length > 0) { + items.push({ + label: PackageManagement.workspaceDependencies, + description: PackageManagement.workspaceDependenciesDescription, + }); + } + if (common.length > 0) { - return selectFromCommonPackagesToInstall(common); + items.push({ + label: PackageManagement.commonPackages, + description: PackageManagement.commonPackagesDescription, + }); } + if (items.length > 0) { + items.push({ label: PackageManagement.skipPackageInstallation }); + } else { + return undefined; + } + + const selected = await showQuickPickWithButtons(items, { + placeHolder: Pickers.Packages.selectOption, + ignoreFocusOut: true, + showBackButton: true, + matchOnDescription: false, + matchOnDetail: false, + }); + + if (selected && !Array.isArray(selected)) { + try { + if (selected.label === PackageManagement.workspaceDependencies) { + return await selectFromInstallableToInstall(installable); + } else if (selected.label === PackageManagement.commonPackages) { + return await selectFromCommonPackagesToInstall(common); + } else { + traceInfo('Package Installer: user selected skip package installation'); + return undefined; + } + // eslint-disable-next-line @typescript-eslint/no-explicit-any + } catch (ex: any) { + if (ex === QuickInputButtons.Back) { + return selectWorkspaceOrCommon(installable, common); + } + } + } return undefined; } diff --git a/src/managers/conda/condaUtils.ts b/src/managers/conda/condaUtils.ts index cd8dd4cf..a0bd2971 100644 --- a/src/managers/conda/condaUtils.ts +++ b/src/managers/conda/condaUtils.ts @@ -14,7 +14,15 @@ import { import * as path from 'path'; import * as os from 'os'; import * as fse from 'fs-extra'; -import { CancellationError, CancellationToken, l10n, LogOutputChannel, ProgressLocation, Uri } from 'vscode'; +import { + CancellationError, + CancellationToken, + l10n, + LogOutputChannel, + ProgressLocation, + QuickInputButtons, + Uri, +} from 'vscode'; import { ENVS_EXTENSION_ID, EXTENSION_ROOT_DIR } from '../../common/constants'; import { createDeferred } from '../../common/utils/deferred'; import { @@ -29,9 +37,9 @@ import { getGlobalPersistentState, getWorkspacePersistentState } from '../../com import which from 'which'; import { isWindows, shortVersion, sortEnvironments, untildify } from '../common/utils'; import { pickProject } from '../../common/pickers/projects'; -import { CondaStrings } from '../../common/localize'; +import { CondaStrings, PackageManagement, Pickers } from '../../common/localize'; import { showErrorMessage } from '../../common/errors/utils'; -import { showInputBox, showQuickPick, withProgress } from '../../common/window.apis'; +import { showInputBox, showQuickPick, showQuickPickWithButtons, withProgress } from '../../common/window.apis'; import { Installable, selectFromCommonPackagesToInstall } from '../common/pickers'; import { quoteArgs } from '../../features/execution/execUtils'; import { traceInfo } from '../../common/logging'; @@ -758,11 +766,53 @@ async function getCommonPackages(): Promise { } } -export async function getCommonCondaPackagesToInstall(): Promise { - const common = await getCommonPackages(); +async function selectCommonPackagesOrSkip(common: Installable[]): Promise { if (common.length === 0) { return undefined; } - const selected = await selectFromCommonPackagesToInstall(common); + + const items = []; + if (common.length > 0) { + items.push({ + label: PackageManagement.commonPackages, + description: PackageManagement.commonPackagesDescription, + }); + } + + if (items.length > 0) { + items.push({ label: PackageManagement.skipPackageInstallation }); + } else { + return undefined; + } + + const selected = await showQuickPickWithButtons(items, { + placeHolder: Pickers.Packages.selectOption, + ignoreFocusOut: true, + showBackButton: true, + matchOnDescription: false, + matchOnDetail: false, + }); + + if (selected && !Array.isArray(selected)) { + try { + if (selected.label === PackageManagement.commonPackages) { + return await selectFromCommonPackagesToInstall(common); + } else { + traceInfo('Package Installer: user selected skip package installation'); + return undefined; + } + // eslint-disable-next-line @typescript-eslint/no-explicit-any + } catch (ex: any) { + if (ex === QuickInputButtons.Back) { + return selectCommonPackagesOrSkip(common); + } + } + } + return undefined; +} + +export async function getCommonCondaPackagesToInstall(): Promise { + const common = await getCommonPackages(); + const selected = await selectCommonPackagesOrSkip(common); return selected; }