Skip to content

Commit 57854bb

Browse files
committed
Optionally pass project uri to PackageManager methods
1 parent ab7e086 commit 57854bb

10 files changed

Lines changed: 176 additions & 62 deletions

File tree

‎src/extension.ts‎

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -367,7 +367,11 @@ export async function activate(context: ExtensionContext): Promise<PythonEnviron
367367
return;
368368
}
369369
try {
370-
resolved.packageManager.manage(resolved.environment, { install: [] });
370+
resolved.packageManager.manage(
371+
resolved.environment,
372+
{ install: [] },
373+
{ projectUri: resolved.projectUri },
374+
);
371375
} catch (err) {
372376
traceError('Error when running command python-envs.packages', err);
373377
}

‎src/features/envCommands.ts‎

Lines changed: 17 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -344,7 +344,9 @@ export async function handlePackageUninstall(context: unknown, em: EnvironmentMa
344344
const moduleName = context.pkg.name;
345345
const environment = context.parent.environment;
346346
const packageManager = em.getPackageManager(environment);
347-
await packageManager?.manage(environment, { uninstall: [moduleName], install: [] });
347+
const operationContext =
348+
context instanceof ProjectPackage ? { projectUri: context.parent.parent.project.uri } : undefined;
349+
await packageManager?.manage(environment, { uninstall: [moduleName], install: [] }, operationContext);
348350
return;
349351
}
350352
traceError(`Invalid context for uninstall command: ${typeof context}`);
@@ -432,10 +434,16 @@ export async function managePackageVersion(context: unknown, em: EnvironmentMana
432434
return;
433435
}
434436

435-
await packageManager.manage(environment, {
436-
install: [packageManager.formatInstallSpec(pkg.name, version)],
437-
uninstall: [],
438-
});
437+
const operationContext =
438+
context instanceof ProjectPackage ? { projectUri: context.parent.parent.project.uri } : undefined;
439+
await packageManager.manage(
440+
environment,
441+
{
442+
install: [packageManager.formatInstallSpec(pkg.name, version)],
443+
uninstall: [],
444+
},
445+
operationContext,
446+
);
439447
} else {
440448
traceError(`Invalid context for manage package version command: ${typeof context}`);
441449
}
@@ -756,6 +764,7 @@ export async function getPackageCommandOptions(
756764
): Promise<{
757765
packageManager: InternalPackageManager;
758766
environment: PythonEnvironment;
767+
projectUri?: Uri;
759768
}> {
760769
const options = await resolvePackageCommandOptions(e, em, pm);
761770
// The tree view hides package actions for inline-script environments, but the command palette
@@ -773,6 +782,7 @@ async function resolvePackageCommandOptions(
773782
): Promise<{
774783
packageManager: InternalPackageManager;
775784
environment: PythonEnvironment;
785+
projectUri?: Uri;
776786
}> {
777787
if (e === undefined) {
778788
const project = await pickProject(pm.getProjects());
@@ -785,7 +795,7 @@ async function resolvePackageCommandOptions(
785795
const environment = e.environment;
786796
const packageManager = em.getPackageManager(e.parent.project.uri);
787797
if (packageManager) {
788-
return { environment, packageManager };
798+
return { environment, packageManager, projectUri: e.parent.project.uri };
789799
}
790800
}
791801

@@ -801,7 +811,7 @@ async function resolvePackageCommandOptions(
801811
const environment = await em.getEnvironmentManager(e)?.get(e);
802812
const packageManager = em.getPackageManager(e);
803813
if (environment && packageManager) {
804-
return { environment, packageManager };
814+
return { environment, packageManager, projectUri: e };
805815
}
806816
}
807817

‎src/features/views/projectView.ts‎

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -245,8 +245,9 @@ export class ProjectView implements TreeDataProvider<ProjectTreeItem> {
245245
return [new ProjectEnvironmentInfo(environmentItem, ProjectViews.noPackageManager)];
246246
}
247247

248-
await pkgManager.refresh(environment);
249-
const packages = await pkgManager.getPackages(environment);
248+
const context = { projectUri: uri };
249+
await pkgManager.refresh(environment, context);
250+
const packages = await pkgManager.getPackages(environment, undefined, context);
250251
if (!packages) {
251252
return [new ProjectEnvironmentInfo(environmentItem, ProjectViews.noPackages)];
252253
}

‎src/managers/builtin/pipPackageManager.ts‎

Lines changed: 16 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -19,6 +19,7 @@ import {
1919
Package,
2020
PackageManagementOptions,
2121
PackageManager,
22+
PackageOperationContext,
2223
PackageVersionLookupNotSupportedError,
2324
PythonEnvironment,
2425
PythonEnvironmentApi,
@@ -71,7 +72,11 @@ export class PipPackageManager implements PackageManager, Disposable {
7172
readonly tooltip?: string | MarkdownString;
7273
readonly iconPath?: IconPath;
7374

74-
async manage(environment: PythonEnvironment, options: PackageManagementOptions): Promise<void> {
75+
async manage(
76+
environment: PythonEnvironment,
77+
options: PackageManagementOptions,
78+
_context?: PackageOperationContext,
79+
): Promise<void> {
7580
let toInstall: string[] = [...(options.install ?? [])];
7681
let toUninstall: string[] = [...(options.uninstall ?? [])];
7782

@@ -177,7 +182,7 @@ export class PipPackageManager implements PackageManager, Disposable {
177182
);
178183
}
179184

180-
async refresh(environment: PythonEnvironment): Promise<void> {
185+
async refresh(environment: PythonEnvironment, _context?: PackageOperationContext): Promise<void> {
181186
await withProgress(
182187
{
183188
location: ProgressLocation.Window,
@@ -199,7 +204,11 @@ export class PipPackageManager implements PackageManager, Disposable {
199204
);
200205
}
201206

202-
async getPackages(environment: PythonEnvironment, options?: GetPackagesOptions): Promise<Package[] | undefined> {
207+
async getPackages(
208+
environment: PythonEnvironment,
209+
options?: GetPackagesOptions,
210+
_context?: PackageOperationContext,
211+
): Promise<Package[] | undefined> {
203212
if (options?.skipCache || !this.packages.has(environment.envId.id)) {
204213
return this.fetchPackages(environment);
205214
}
@@ -321,7 +330,10 @@ export class PipPackageManager implements PackageManager, Disposable {
321330
* dependency tree), not necessarily packages the user explicitly installed. pip/uv
322331
* do not track install intent.
323332
*/
324-
async getDirectPackageNames(environment: PythonEnvironment): Promise<Set<string> | undefined> {
333+
async getDirectPackageNames(
334+
environment: PythonEnvironment,
335+
_context?: PackageOperationContext,
336+
): Promise<Set<string> | undefined> {
325337
const pythonExecutable = environment.execInfo?.run?.executable;
326338
if (!pythonExecutable) {
327339
return undefined;

‎src/managers/common/packageChanges.ts‎

Lines changed: 5 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
// Copyright (c) Microsoft Corporation. All rights reserved.
22
// Licensed under the MIT License.
33

4-
import { Package, PackageChangeKind, PackageManager, PythonEnvironment } from '../../api';
4+
import { Package, PackageChangeKind, PackageManager, PackageOperationContext, PythonEnvironment } from '../../api';
55
import { normalizePackageName } from './packageUtils';
66

77
/**
@@ -49,18 +49,20 @@ export function getPackageChanges(before: Package[], after: Package[]): { kind:
4949
* @param before The package snapshot from before the operation.
5050
* @param onChanges Callback invoked when package changes are detected.
5151
* @param fetchPackages Optional internal fetcher for operation-specific refresh behavior.
52+
* @param context Optional project context for the operation.
5253
*/
5354
export async function updatePackagesAndNotify(
5455
packageManager: PackageManager,
5556
environment: PythonEnvironment,
5657
before: Package[] | undefined,
5758
onChanges: PackageChangesCallback,
5859
fetchPackages?: PackageFetcher,
60+
context?: PackageOperationContext,
5961
): Promise<Package[] | undefined> {
6062
const [after, afterDirectDependenciesNames] = await Promise.all([
61-
fetchPackages?.() ?? packageManager.getPackages(environment, { skipCache: true }),
63+
fetchPackages?.() ?? packageManager.getPackages(environment, { skipCache: true }, context),
6264
// Handle transitive dependencies (best-effort, don't break package refresh on failure)
63-
packageManager.getDirectPackageNames?.(environment).catch(() => undefined),
65+
packageManager.getDirectPackageNames?.(environment, context).catch(() => undefined),
6466
]);
6567

6668
if (after === undefined) {

‎src/managers/common/registeredManagers.ts‎

Lines changed: 20 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -26,6 +26,7 @@ import type {
2626
Package,
2727
PackageManagementOptions,
2828
PackageManager,
29+
PackageOperationContext,
2930
PythonEnvironment,
3031
QuickCreateConfig,
3132
RefreshEnvironmentsScope,
@@ -234,11 +235,15 @@ export class InternalPackageManager implements PackageManager {
234235
return this.manager.log;
235236
}
236237

237-
async manage(environment: PythonEnvironment, options: PackageManagementOptions): Promise<void> {
238+
async manage(
239+
environment: PythonEnvironment,
240+
options: PackageManagementOptions,
241+
context?: PackageOperationContext,
242+
): Promise<void> {
238243
const stopWatch = new StopWatch();
239244
const triggerSource = inferPackageManagementTrigger(options);
240245
try {
241-
await this.manager.manage(environment, options);
246+
await this.manager.manage(environment, options, context);
242247
sendTelemetryEvent(EventNames.PACKAGE_MANAGEMENT, stopWatch.elapsedTime, {
243248
managerId: this.id,
244249
result: 'success',
@@ -263,12 +268,16 @@ export class InternalPackageManager implements PackageManager {
263268
}
264269
}
265270

266-
refresh(environment: PythonEnvironment): Promise<void> {
267-
return this.manager.refresh(environment);
271+
refresh(environment: PythonEnvironment, context?: PackageOperationContext): Promise<void> {
272+
return this.manager.refresh(environment, context);
268273
}
269274

270-
getPackages(environment: PythonEnvironment, options?: GetPackagesOptions): Promise<Package[] | undefined> {
271-
return this.manager.getPackages(environment, options);
275+
getPackages(
276+
environment: PythonEnvironment,
277+
options?: GetPackagesOptions,
278+
context?: PackageOperationContext,
279+
): Promise<Package[] | undefined> {
280+
return this.manager.getPackages(environment, options, context);
272281
}
273282

274283
getPackageWatchTargets(environment: PythonEnvironment): RelativePattern[] {
@@ -328,9 +337,12 @@ export class InternalPackageManager implements PackageManager {
328337
}
329338
}
330339

331-
getDirectPackageNames(environment: PythonEnvironment): Promise<Set<string> | undefined> {
340+
getDirectPackageNames(
341+
environment: PythonEnvironment,
342+
context?: PackageOperationContext,
343+
): Promise<Set<string> | undefined> {
332344
return this.manager.getDirectPackageNames
333-
? this.manager.getDirectPackageNames(environment)
345+
? this.manager.getDirectPackageNames(environment, context)
334346
: Promise.resolve(undefined);
335347
}
336348

‎src/managers/conda/condaPackageManager.ts‎

Lines changed: 12 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -19,6 +19,7 @@ import {
1919
Package,
2020
PackageManagementOptions,
2121
PackageManager,
22+
PackageOperationContext,
2223
PythonEnvironment,
2324
PythonEnvironmentApi,
2425
} from '../../api';
@@ -59,7 +60,11 @@ export class CondaPackageManager implements PackageManager, Disposable {
5960
tooltip?: string | MarkdownString;
6061
iconPath?: IconPath;
6162

62-
async manage(environment: PythonEnvironment, options: PackageManagementOptions): Promise<void> {
63+
async manage(
64+
environment: PythonEnvironment,
65+
options: PackageManagementOptions,
66+
_context?: PackageOperationContext,
67+
): Promise<void> {
6368
let toInstall: string[] = [...(options.install ?? [])];
6469
let toUninstall: string[] = [...(options.uninstall ?? [])];
6570

@@ -139,7 +144,7 @@ export class CondaPackageManager implements PackageManager, Disposable {
139144
);
140145
}
141146

142-
async refresh(environment: PythonEnvironment): Promise<void> {
147+
async refresh(environment: PythonEnvironment, _context?: PackageOperationContext): Promise<void> {
143148
await withProgress(
144149
{
145150
location: ProgressLocation.Window,
@@ -162,7 +167,11 @@ export class CondaPackageManager implements PackageManager, Disposable {
162167
);
163168
}
164169

165-
async getPackages(environment: PythonEnvironment, options?: GetPackagesOptions): Promise<Package[] | undefined> {
170+
async getPackages(
171+
environment: PythonEnvironment,
172+
options?: GetPackagesOptions,
173+
_context?: PackageOperationContext,
174+
): Promise<Package[] | undefined> {
166175
if (options?.skipCache || !this.packages.has(environment.envId.id)) {
167176
return (await this.fetchPackages(environment)) ?? [];
168177
}

0 commit comments

Comments
 (0)