From 6cadaf3f8d16658f48dd3f82a39b77be453fb7b4 Mon Sep 17 00:00:00 2001 From: "copilot-swe-agent[bot]" <198982749+Copilot@users.noreply.github.com> Date: Mon, 9 Nov 2026 23:44:44 +0000 Subject: [PATCH 1/2] Initial plan From 793d96de40f6af70b9544f2e1fb0ee9f9ec5b0aa Mon Sep 17 00:00:00 2001 From: "copilot-swe-agent[bot]" <198982749+Copilot@users.noreply.github.com> Date: Mon, 9 Nov 2026 23:58:58 +0000 Subject: [PATCH 2/2] Cache manager version lookups Co-authored-by: edvilme <5952839+edvilme@users.noreply.github.com> --- src/managers/common/registeredManagers.ts | 16 ++++++- ...isteredManagers.versionLookup.unit.test.ts | 42 ++++++++++++++++++- 2 files changed, 54 insertions(+), 4 deletions(-) diff --git a/src/managers/common/registeredManagers.ts b/src/managers/common/registeredManagers.ts index 23d6470e9..497779090 100644 --- a/src/managers/common/registeredManagers.ts +++ b/src/managers/common/registeredManagers.ts @@ -55,6 +55,8 @@ import type { */ export class InternalEnvironmentManager implements EnvironmentManager { + private _version?: Promise; + public constructor( public readonly id: string, private readonly manager: EnvironmentManager, @@ -87,7 +89,8 @@ export class InternalEnvironmentManager implements EnvironmentManager { } public getVersion(): Promise { - return this.manager.getVersion ? this.manager.getVersion() : Promise.resolve(undefined); + this._version ??= this.manager.getVersion ? this.manager.getVersion() : Promise.resolve(undefined); + return this._version; } public get capabilities(): EnvironmentManager['capabilities'] { @@ -240,6 +243,7 @@ function inferPackageManagementTrigger( } export class InternalPackageManager implements PackageManager { + private readonly _version = new Map>(); private readonly relatedManagers: WeakSet; private readonly packageChangeEventValue: Event | undefined; private isDisposed = false; @@ -386,7 +390,15 @@ export class InternalPackageManager implements PackageManager { getVersion(environment: PythonEnvironment): Promise { this.throwIfDisposed(); - return this.manager.getVersion ? this.manager.getVersion(environment) : Promise.resolve(undefined); + const environmentId = environment.envId.id; + let version = this._version.get(environmentId); + if (!version) { + version = this.manager.getVersion + ? this.manager.getVersion(environment) + : Promise.resolve(undefined); + this._version.set(environmentId, version); + } + return version; } getPackageAvailableVersions( diff --git a/src/test/managers/common/registeredManagers.versionLookup.unit.test.ts b/src/test/managers/common/registeredManagers.versionLookup.unit.test.ts index 0599f9244..6b842cd8c 100644 --- a/src/test/managers/common/registeredManagers.versionLookup.unit.test.ts +++ b/src/test/managers/common/registeredManagers.versionLookup.unit.test.ts @@ -2,9 +2,47 @@ // Licensed under the MIT License. import * as assert from 'assert'; +import { explain as parsePep440Version } from '@renovatebot/pep440'; +import * as sinon from 'sinon'; import { isPackageVersionLookupNotSupportedError } from '../../../publicErrors'; -import type { PackageManager, PythonEnvironment } from '../../../types'; -import { InternalPackageManager } from '../../../managers/common/registeredManagers'; +import type { EnvironmentManager, PackageManager, PythonEnvironment } from '../../../types'; +import { + InternalEnvironmentManager, + InternalPackageManager, +} from '../../../managers/common/registeredManagers'; + +suite('Internal manager getVersion', () => { + const version = parsePep440Version('1.2.3'); + + test('caches an environment manager version', async () => { + const getVersion = sinon.stub().resolves(version); + const manager = new InternalEnvironmentManager('test:manager', { + getVersion, + } as unknown as EnvironmentManager); + + assert.deepStrictEqual(await manager.getVersion(), version); + assert.deepStrictEqual(await manager.getVersion(), version); + assert.strictEqual(getVersion.callCount, 1); + }); + + test('caches a package manager version', async () => { + const environment = { envId: { id: 'env', managerId: 'mgr' } } as PythonEnvironment; + const otherEnvironment = { envId: { id: 'other-env', managerId: 'mgr' } } as PythonEnvironment; + const otherVersion = parsePep440Version('2.0.0'); + const getVersion = sinon.stub(); + getVersion.withArgs(environment).resolves(version); + getVersion.withArgs(otherEnvironment).resolves(otherVersion); + const manager = new InternalPackageManager('test:manager', { + getVersion, + } as unknown as PackageManager); + + assert.deepStrictEqual(await manager.getVersion(environment), version); + assert.deepStrictEqual(await manager.getVersion(environment), version); + assert.deepStrictEqual(await manager.getVersion(otherEnvironment), otherVersion); + assert.deepStrictEqual(await manager.getVersion(otherEnvironment), otherVersion); + assert.strictEqual(getVersion.callCount, 2); + }); +}); suite('InternalPackageManager.getPackageAvailableVersions', () => { const environment = { envId: { id: 'env', managerId: 'mgr' } } as PythonEnvironment;