Skip to content

Commit aed7a92

Browse files
committed
feat: improve package management
1 parent faab63f commit aed7a92

19 files changed

+253
-392
lines changed

package-lock.json

Lines changed: 8 additions & 8 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

package.json

Lines changed: 2 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -6,13 +6,12 @@
66
"publisher": "ms-python",
77
"preview": true,
88
"engines": {
9-
"vscode": "^1.99.0-20250317"
9+
"vscode": "^1.100.0-20250407"
1010
},
1111
"categories": [
1212
"Other"
1313
],
1414
"enabledApiProposals": [
15-
"terminalShellType",
1615
"terminalShellEnv"
1716
],
1817
"capabilities": {
@@ -142,7 +141,6 @@
142141
{
143142
"command": "python-envs.reset",
144143
"title": "%python-envs.reset.title%",
145-
"shortTitle": "Reset Environment",
146144
"category": "Python",
147145
"icon": "$(sync)"
148146
},
@@ -174,7 +172,6 @@
174172
{
175173
"command": "python-envs.packages",
176174
"title": "%python-envs.packages.title%",
177-
"shortTitle": "Modify Packages",
178175
"category": "Python",
179176
"icon": "$(package)"
180177
},
@@ -534,7 +531,7 @@
534531
"@types/node": "20.2.5",
535532
"@types/sinon": "^17.0.3",
536533
"@types/stack-trace": "0.0.29",
537-
"@types/vscode": "^1.97.0",
534+
"@types/vscode": "^1.99.0",
538535
"@types/which": "^3.0.4",
539536
"@typescript-eslint/eslint-plugin": "^8.16.0",
540537
"@typescript-eslint/parser": "^8.16.0",

package.nls.json

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -16,12 +16,12 @@
1616
"python-envs.createAny.title": "Create Environment",
1717
"python-envs.set.title": "Set Workspace Environment",
1818
"python-envs.setEnv.title": "Set As Workspace Environment",
19-
"python-envs.reset.title": "Reset Environment Selection to Default",
19+
"python-envs.reset.title": "Reset to Default",
2020
"python-envs.remove.title": "Delete Environment",
2121
"python-envs.refreshAllManagers.title": "Refresh All Environment Managers",
2222
"python-envs.refreshManager.title": "Refresh Environments List",
2323
"python-envs.refreshPackages.title": "Refresh Packages List",
24-
"python-envs.packages.title": "Install or Remove Packages",
24+
"python-envs.packages.title": "Manage Packages",
2525
"python-envs.clearCache.title": "Clear Cache",
2626
"python-envs.runInTerminal.title": "Run in Terminal",
2727
"python-envs.createTerminal.title": "Create Python Terminal",

src/api.ts

Lines changed: 44 additions & 33 deletions
Original file line numberDiff line numberDiff line change
@@ -575,20 +575,12 @@ export interface PackageManager {
575575
log?: LogOutputChannel;
576576

577577
/**
578-
* Installs packages in the specified Python environment.
578+
* Installs/Uninstall packages in the specified Python environment.
579579
* @param environment - The Python environment in which to install packages.
580580
* @param packages - The packages to install.
581581
* @returns A promise that resolves when the installation is complete.
582582
*/
583-
install(environment: PythonEnvironment, packages?: string[], options?: PackageInstallOptions): Promise<void>;
584-
585-
/**
586-
* Uninstalls packages from the specified Python environment.
587-
* @param environment - The Python environment from which to uninstall packages.
588-
* @param packages - The packages to uninstall, which can be an array of packages or strings.
589-
* @returns A promise that resolves when the uninstall is complete.
590-
*/
591-
uninstall(environment: PythonEnvironment, packages?: Package[] | string[]): Promise<void>;
583+
manage(environment: PythonEnvironment, options: PackageManagementOptions): Promise<void>;
592584

593585
/**
594586
* Refreshes the package list for the specified Python environment.
@@ -713,20 +705,47 @@ export interface DidChangePythonProjectsEventArgs {
713705
removed: PythonProject[];
714706
}
715707

716-
/**
717-
* Options for package installation.
718-
*/
719-
export interface PackageInstallOptions {
720-
/**
721-
* Upgrade the packages if it is already installed.
722-
*/
723-
upgrade?: boolean;
708+
export type PackageManagementOptions =
709+
| {
710+
/**
711+
* Upgrade the packages if it is already installed.
712+
*/
713+
upgrade?: boolean;
724714

725-
/**
726-
* Show option to skip package installation
727-
*/
728-
showSkipOption?: boolean;
729-
}
715+
/**
716+
* Show option to skip package installation
717+
*/
718+
showSkipOption?: boolean;
719+
/**
720+
* The list of packages to install.
721+
*/
722+
install: string[];
723+
724+
/**
725+
* The list of packages to uninstall.
726+
*/
727+
uninstall?: string[];
728+
}
729+
| {
730+
/**
731+
* Upgrade the packages if it is already installed.
732+
*/
733+
upgrade?: boolean;
734+
735+
/**
736+
* Show option to skip package installation
737+
*/
738+
showSkipOption?: boolean;
739+
/**
740+
* The list of packages to install.
741+
*/
742+
install?: string[];
743+
744+
/**
745+
* The list of packages to uninstall.
746+
*/
747+
uninstall: string[];
748+
};
730749

731750
export interface PythonProcess {
732751
/**
@@ -909,21 +928,13 @@ export interface PythonPackageItemApi {
909928

910929
export interface PythonPackageManagementApi {
911930
/**
912-
* Install packages into a Python Environment.
931+
* Install/Uninstall packages into a Python Environment.
913932
*
914933
* @param environment The Python Environment into which packages are to be installed.
915934
* @param packages The packages to install.
916935
* @param options Options for installing packages.
917936
*/
918-
installPackages(environment: PythonEnvironment, packages: string[], options?: PackageInstallOptions): Promise<void>;
919-
920-
/**
921-
* Uninstall packages from a Python Environment.
922-
*
923-
* @param environment The Python Environment from which packages are to be uninstalled.
924-
* @param packages The packages to uninstall.
925-
*/
926-
uninstallPackages(environment: PythonEnvironment, packages: PackageInfo[] | string[]): Promise<void>;
937+
managePackages(environment: PythonEnvironment, options: PackageManagementOptions): Promise<void>;
927938
}
928939

929940
export interface PythonPackageManagerApi

src/common/localize.ts

Lines changed: 6 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -20,10 +20,14 @@ export namespace Interpreter {
2020
}
2121

2222
export namespace PackageManagement {
23+
export const install = l10n.t('Install');
24+
export const uninstall = l10n.t('Uninstall');
25+
export const installed = l10n.t('Installed');
26+
export const commonPackages = l10n.t('Common Packages');
2327
export const selectPackagesToInstall = l10n.t('Select packages to install');
2428
export const enterPackageNames = l10n.t('Enter package names');
25-
export const commonPackages = l10n.t('Search common `PyPI` packages');
26-
export const commonPackagesDescription = l10n.t('Search and Install common `PyPI` packages');
29+
export const searchCommonPackages = l10n.t('Search common `PyPI` packages');
30+
export const searchCommonPackagesDescription = l10n.t('Search and Install common `PyPI` packages');
2731
export const workspaceDependencies = l10n.t('Install workspace dependencies');
2832
export const workspaceDependenciesDescription = l10n.t('Install dependencies found in the current workspace.');
2933
export const selectPackagesToUninstall = l10n.t('Select packages to uninstall');
@@ -40,8 +44,6 @@ export namespace Pickers {
4044

4145
export namespace Packages {
4246
export const selectOption = l10n.t('Select an option');
43-
export const installPackages = l10n.t('Install packages');
44-
export const uninstallPackages = l10n.t('Uninstall packages');
4547
}
4648

4749
export namespace Managers {

src/common/pickers/packages.ts

Lines changed: 0 additions & 22 deletions
This file was deleted.

src/extension.ts

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,6 @@ import {
88
createEnvironmentCommand,
99
createTerminalCommand,
1010
getPackageCommandOptions,
11-
handlePackagesCommand,
1211
refreshManagerCommand,
1312
removeEnvironmentCommand,
1413
removePythonProject,
@@ -138,7 +137,7 @@ export async function activate(context: ExtensionContext): Promise<PythonEnviron
138137
envManagers,
139138
projectManager,
140139
);
141-
await handlePackagesCommand(packageManager, environment);
140+
packageManager.manage(environment, { install: [] });
142141
}),
143142
commands.registerCommand('python-envs.uninstallPackage', async (context: unknown) => {
144143
await handlePackageUninstall(context, envManagers);

src/features/envCommands.ts

Lines changed: 1 addition & 23 deletions
Original file line numberDiff line numberDiff line change
@@ -33,10 +33,8 @@ import {
3333
PackageTreeItem,
3434
ProjectPackage,
3535
} from './views/treeViewItems';
36-
import { Common } from '../common/localize';
3736
import { pickEnvironment } from '../common/pickers/environments';
3837
import { pickEnvironmentManager, pickPackageManager, pickCreator } from '../common/pickers/managers';
39-
import { pickPackageOptions } from '../common/pickers/packages';
4038
import { pickProject, pickProjectMany } from '../common/pickers/projects';
4139
import { TerminalManager } from './terminal/terminalManager';
4240
import { runInTerminal } from './terminal/runInTerminal';
@@ -180,32 +178,12 @@ export async function removeEnvironmentCommand(context: unknown, managers: Envir
180178
}
181179
}
182180

183-
export async function handlePackagesCommand(
184-
packageManager: InternalPackageManager,
185-
environment: PythonEnvironment,
186-
): Promise<void> {
187-
const action = await pickPackageOptions();
188-
189-
try {
190-
if (action === Common.install) {
191-
await packageManager.install(environment, undefined, { showSkipOption: false });
192-
} else if (action === Common.uninstall) {
193-
await packageManager.uninstall(environment);
194-
}
195-
} catch (ex) {
196-
if (ex === QuickInputButtons.Back) {
197-
return handlePackagesCommand(packageManager, environment);
198-
}
199-
throw ex;
200-
}
201-
}
202-
203181
export async function handlePackageUninstall(context: unknown, em: EnvironmentManagers) {
204182
if (context instanceof PackageTreeItem || context instanceof ProjectPackage) {
205183
const moduleName = context.pkg.name;
206184
const environment = context.parent.environment;
207185
const packageManager = em.getPackageManager(environment);
208-
await packageManager?.uninstall(environment, [moduleName]);
186+
await packageManager?.manage(environment, { uninstall: [moduleName], install: [] });
209187
return;
210188
}
211189
traceError(`Invalid context for uninstall command: ${typeof context}`);

src/features/pythonApi.ts

Lines changed: 3 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -21,7 +21,7 @@ import {
2121
PackageId,
2222
PythonProjectCreator,
2323
ResolveEnvironmentContext,
24-
PackageInstallOptions,
24+
PackageManagementOptions,
2525
PythonProcess,
2626
PythonTaskExecutionOptions,
2727
PythonTerminalExecutionOptions,
@@ -216,19 +216,12 @@ class PythonEnvironmentApiImpl implements PythonEnvironmentApi {
216216
}
217217
return new Disposable(() => disposables.forEach((d) => d.dispose()));
218218
}
219-
installPackages(context: PythonEnvironment, packages: string[], options: PackageInstallOptions): Promise<void> {
219+
managePackages(context: PythonEnvironment, options: PackageManagementOptions): Promise<void> {
220220
const manager = this.envManagers.getPackageManager(context);
221221
if (!manager) {
222222
return Promise.reject(new Error('No package manager found'));
223223
}
224-
return manager.install(context, packages, options);
225-
}
226-
uninstallPackages(context: PythonEnvironment, packages: Package[] | string[]): Promise<void> {
227-
const manager = this.envManagers.getPackageManager(context);
228-
if (!manager) {
229-
return Promise.reject(new Error('No package manager found'));
230-
}
231-
return manager.uninstall(context, packages);
224+
return manager.manage(context, options);
232225
}
233226
refreshPackages(context: PythonEnvironment): Promise<void> {
234227
const manager = this.envManagers.getPackageManager(context);

src/internal.api.ts

Lines changed: 6 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -22,7 +22,7 @@ import {
2222
PackageInfo,
2323
PythonProjectCreator,
2424
ResolveEnvironmentContext,
25-
PackageInstallOptions,
25+
PackageManagementOptions,
2626
EnvironmentGroupInfo,
2727
} from './api';
2828
import { CreateEnvironmentNotSupported, RemoveEnvironmentNotSupported } from './common/errors/NotSupportedError';
@@ -225,22 +225,22 @@ export class InternalPackageManager implements PackageManager {
225225
return this.manager.log;
226226
}
227227

228-
install(environment: PythonEnvironment, packages?: string[], options?: PackageInstallOptions): Promise<void> {
229-
return this.manager.install(environment, packages, options);
230-
}
231-
uninstall(environment: PythonEnvironment, packages?: Package[] | string[]): Promise<void> {
232-
return this.manager.uninstall(environment, packages);
228+
manage(environment: PythonEnvironment, options: PackageManagementOptions): Promise<void> {
229+
return this.manager.manage(environment, options);
233230
}
231+
234232
refresh(environment: PythonEnvironment): Promise<void> {
235233
return this.manager.refresh(environment);
236234
}
235+
237236
getPackages(environment: PythonEnvironment): Promise<Package[] | undefined> {
238237
return this.manager.getPackages(environment);
239238
}
240239

241240
onDidChangePackages(handler: (e: DidChangePackagesEventArgs) => void): Disposable {
242241
return this.manager.onDidChangePackages ? this.manager.onDidChangePackages(handler) : new Disposable(() => {});
243242
}
243+
244244
equals(other: PackageManager): boolean {
245245
return this.manager === other;
246246
}

0 commit comments

Comments
 (0)