diff --git a/lib/workers/repository/update/branch/get-updated.spec.ts b/lib/workers/repository/update/branch/get-updated.spec.ts index 4a6590790e673477ea11bd61d3c7b313494ab7c4..ab63ca482a5246aefd9d9fbe114b0fbe64e97597 100644 --- a/lib/workers/repository/update/branch/get-updated.spec.ts +++ b/lib/workers/repository/update/branch/get-updated.spec.ts @@ -6,6 +6,8 @@ import * as _composer from '../../../../modules/manager/composer'; import * as _gitSubmodules from '../../../../modules/manager/git-submodules'; import * as _helmv3 from '../../../../modules/manager/helmv3'; import * as _npm from '../../../../modules/manager/npm'; +import * as _pep621 from '../../../../modules/manager/pep621'; +import * as _poetry from '../../../../modules/manager/poetry'; import type { BranchConfig, BranchUpgradeConfig } from '../../../types'; import * as _autoReplace from './auto-replace'; import { getUpdatedPackageFiles } from './get-updated'; @@ -17,6 +19,8 @@ const helmv3 = mocked(_helmv3); const npm = mocked(_npm); const batectWrapper = mocked(_batectWrapper); const autoReplace = mocked(_autoReplace); +const pep621 = mocked(_pep621); +const poetry = mocked(_poetry); jest.mock('../../../../modules/manager/bundler'); jest.mock('../../../../modules/manager/composer'); @@ -24,6 +28,8 @@ jest.mock('../../../../modules/manager/helmv3'); jest.mock('../../../../modules/manager/npm'); jest.mock('../../../../modules/manager/git-submodules'); jest.mock('../../../../modules/manager/batect-wrapper'); +jest.mock('../../../../modules/manager/pep621'); +jest.mock('../../../../modules/manager/poetry'); jest.mock('../../../../util/git'); jest.mock('./auto-replace'); @@ -532,6 +538,26 @@ describe('workers/repository/update/branch/get-updated', () => { }); }); + it('handles package files updated by multiple managers', async () => { + config.upgrades.push({ + packageFile: 'pyproject.toml', + manager: 'poetry', + branchName: '', + }); + config.upgrades.push({ + packageFile: 'pyproject.toml', + manager: 'pep621', + branchName: '', + }); + autoReplace.doAutoReplace.mockResolvedValueOnce('my-new-dep:1.0.0'); + autoReplace.doAutoReplace.mockResolvedValueOnce('my-new-dep:1.0.0'); + + await getUpdatedPackageFiles(config); + + expect(pep621.updateArtifacts).toHaveBeenCalledOnce(); + expect(poetry.updateArtifacts).toHaveBeenCalledOnce(); + }); + describe('when some artifacts have changed and others have not', () => { const pushGemUpgrade = (opts: Partial<BranchUpgradeConfig>) => config.upgrades.push({ diff --git a/lib/workers/repository/update/branch/get-updated.ts b/lib/workers/repository/update/branch/get-updated.ts index 1adfb25bd34637c3168d2d280df52b4920f50bc8..ab15de8e7b74c1a627f91ebba4b79dc1e13be566 100644 --- a/lib/workers/repository/update/branch/get-updated.ts +++ b/lib/workers/repository/update/branch/get-updated.ts @@ -45,7 +45,7 @@ export async function getUpdatedPackageFiles( ); let updatedFileContents: Record<string, string> = {}; const nonUpdatedFileContents: Record<string, string> = {}; - const packageFileManagers: Record<string, string> = {}; + const packageFileManagers: Record<string, Set<string>> = {}; const packageFileUpdatedDeps: Record<string, PackageDependency[]> = {}; const lockFileMaintenanceFiles = []; let firstUpdate = true; @@ -57,9 +57,9 @@ export async function getUpdatedPackageFiles( const newVersion = upgrade.newVersion!; const currentVersion = upgrade.currentVersion!; const updateLockedDependency = get(manager, 'updateLockedDependency')!; - packageFileManagers[packageFile] = manager; - packageFileUpdatedDeps[packageFile] = - packageFileUpdatedDeps[packageFile] || []; + packageFileManagers[packageFile] ??= new Set<string>(); + packageFileManagers[packageFile].add(manager); + packageFileUpdatedDeps[packageFile] ??= []; packageFileUpdatedDeps[packageFile].push({ ...upgrade }); const packageFileContent = await getFileContent( updatedFileContents, @@ -286,24 +286,28 @@ export async function getUpdatedPackageFiles( const updatedArtifacts: FileChange[] = []; const artifactErrors: ArtifactError[] = []; for (const packageFile of updatedPackageFiles) { - const manager = packageFileManagers[packageFile.path]; const updatedDeps = packageFileUpdatedDeps[packageFile.path]; - const updateArtifacts = get(manager, 'updateArtifacts'); - if (updateArtifacts) { - const results = await updateArtifacts({ - packageFileName: packageFile.path, - updatedDeps, - // TODO #22198 - newPackageFileContent: packageFile.contents!.toString(), - config, - }); - if (is.nonEmptyArray(results)) { - for (const res of results) { - const { file, artifactError } = res; - if (file) { - updatedArtifacts.push(file); - } else if (artifactError) { - artifactErrors.push(artifactError); + const managers = packageFileManagers[packageFile.path]; + if (is.nonEmptySet(managers)) { + for (const manager of managers) { + const updateArtifacts = get(manager, 'updateArtifacts'); + if (updateArtifacts) { + const results = await updateArtifacts({ + packageFileName: packageFile.path, + updatedDeps, + // TODO #22198 + newPackageFileContent: packageFile.contents!.toString(), + config, + }); + if (is.nonEmptyArray(results)) { + for (const res of results) { + const { file, artifactError } = res; + if (file) { + updatedArtifacts.push(file); + } else if (artifactError) { + artifactErrors.push(artifactError); + } + } } } } @@ -317,26 +321,30 @@ export async function getUpdatedPackageFiles( contents: nonUpdatedFileContents[name], })); for (const packageFile of nonUpdatedPackageFiles) { - const manager = packageFileManagers[packageFile.path]; const updatedDeps = packageFileUpdatedDeps[packageFile.path]; - const updateArtifacts = get(manager, 'updateArtifacts'); - if (updateArtifacts) { - const results = await updateArtifacts({ - packageFileName: packageFile.path, - updatedDeps, - // TODO #22198 - newPackageFileContent: packageFile.contents!.toString(), - config, - }); - if (is.nonEmptyArray(results)) { - updatedPackageFiles.push(packageFile); - for (const res of results) { - const { file, artifactError } = res; - // istanbul ignore else - if (file) { - updatedArtifacts.push(file); - } else if (artifactError) { - artifactErrors.push(artifactError); + const managers = packageFileManagers[packageFile.path]; + if (is.nonEmptySet(managers)) { + for (const manager of managers) { + const updateArtifacts = get(manager, 'updateArtifacts'); + if (updateArtifacts) { + const results = await updateArtifacts({ + packageFileName: packageFile.path, + updatedDeps, + // TODO #22198 + newPackageFileContent: packageFile.contents!.toString(), + config, + }); + if (is.nonEmptyArray(results)) { + updatedPackageFiles.push(packageFile); + for (const res of results) { + const { file, artifactError } = res; + // istanbul ignore else + if (file) { + updatedArtifacts.push(file); + } else if (artifactError) { + artifactErrors.push(artifactError); + } + } } } } @@ -345,25 +353,29 @@ export async function getUpdatedPackageFiles( if (!reuseExistingBranch) { // Only perform lock file maintenance if it's a fresh commit for (const packageFile of lockFileMaintenanceFiles) { - const manager = packageFileManagers[packageFile]; - const updateArtifacts = get(manager, 'updateArtifacts'); - if (updateArtifacts) { - const packageFileContents = - updatedFileContents[packageFile] || - (await getFile(packageFile, config.baseBranch)); - const results = await updateArtifacts({ - packageFileName: packageFile, - updatedDeps: [], - newPackageFileContent: packageFileContents!, - config, - }); - if (is.nonEmptyArray(results)) { - for (const res of results) { - const { file, artifactError } = res; - if (file) { - updatedArtifacts.push(file); - } else if (artifactError) { - artifactErrors.push(artifactError); + const managers = packageFileManagers[packageFile]; + if (is.nonEmptySet(managers)) { + for (const manager of managers) { + const updateArtifacts = get(manager, 'updateArtifacts'); + if (updateArtifacts) { + const packageFileContents = + updatedFileContents[packageFile] || + (await getFile(packageFile, config.baseBranch)); + const results = await updateArtifacts({ + packageFileName: packageFile, + updatedDeps: [], + newPackageFileContent: packageFileContents!, + config, + }); + if (is.nonEmptyArray(results)) { + for (const res of results) { + const { file, artifactError } = res; + if (file) { + updatedArtifacts.push(file); + } else if (artifactError) { + artifactErrors.push(artifactError); + } + } } } }