diff --git a/lib/util/exec/containerbase.spec.ts b/lib/util/exec/containerbase.spec.ts index 8f5602a89b..82203115e3 100644 --- a/lib/util/exec/containerbase.spec.ts +++ b/lib/util/exec/containerbase.spec.ts @@ -337,6 +337,27 @@ describe('util/exec/containerbase', () => { generateInstallCommands(toolConstraints, true), ).resolves.toEqual(['install-tool composer 2.2.0']); }); + + it('re-issues the install command when switching back to an earlier version', async () => { + const toolConstraints: ToolConstraint[] = [{ toolName: 'composer' }]; + await expect( + generateInstallCommands(toolConstraints, true), + ).resolves.toEqual(['install-tool composer 2.1.0']); + + datasource.getPkgReleases.mockResolvedValueOnce({ + releases: [{ version: '2.2.0' }], + }); + await expect( + generateInstallCommands(toolConstraints, true), + ).resolves.toEqual(['install-tool composer 2.2.0']); + + datasource.getPkgReleases.mockResolvedValueOnce({ + releases: [{ version: '2.1.0' }], + }); + await expect( + generateInstallCommands(toolConstraints, true), + ).resolves.toEqual(['install-tool composer 2.1.0']); + }); }); }); }); diff --git a/lib/util/exec/containerbase.ts b/lib/util/exec/containerbase.ts index 56997113b5..d28c384965 100644 --- a/lib/util/exec/containerbase.ts +++ b/lib/util/exec/containerbase.ts @@ -382,7 +382,9 @@ export async function resolveConstraint( // Docker execs run in a fresh `--rm` container each time, so `memoize` must // stay false there - only the persistent-host (binarySource=install) path -// can safely skip a tool it has already installed this run. +// can safely skip a tool whose requested version is already active. +// `install-tool` also activates the version it installs, so the memo tracks +// the active version per tool, not every installed version. export async function generateInstallCommands( toolConstraints: Opt, memoize = false, @@ -393,11 +395,11 @@ export async function generateInstallCommands( const toolVersion = await resolveConstraint(toolConstraint); const { toolName } = toolConstraint; if (memoize) { - const cacheKey = `containerbase-installed:${toolName}:${toolVersion}`; - if (memCache.get(cacheKey)) { + const cacheKey = `containerbase-active:${toolName}`; + if (memCache.get(cacheKey) === toolVersion) { continue; } - memCache.set(cacheKey, true); + memCache.set(cacheKey, toolVersion); } const installCommand = `install-tool ${toolName} ${quote(toolVersion)}`; installCommands.push(installCommand);