feat(manager/pip-compile): Allow security updates for transitive dependencies (#27561)

This commit is contained in:
Norbert Szulc 2024-03-30 08:37:27 +01:00 committed by GitHub
parent f8890796bf
commit 0df4ff5ce8
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
3 changed files with 81 additions and 1 deletions

View file

@ -366,6 +366,29 @@ describe('modules/manager/pip-compile/extract', () => {
);
});
it('adds transitive dependency to deps in package file', async () => {
fs.readLocalFile.mockResolvedValueOnce(
getSimpleRequirementsFile(
'pip-compile --output-file=requirements.txt requirements.in',
['friendly-bard==1.0.1', 'bards-friend==1.0.0'],
),
);
fs.readLocalFile.mockResolvedValueOnce('FrIeNdLy-._.-bArD>=1.0.0');
const lockFiles = ['requirements.txt'];
const packageFiles = await extractAllPackageFiles({}, lockFiles);
expect(packageFiles).toBeDefined();
const packageFile = packageFiles!.pop();
expect(packageFile!.deps).toHaveLength(2);
expect(packageFile!.deps[1]).toEqual({
datasource: 'pypi',
depType: 'indirect',
depName: 'bards-friend',
lockedVersion: '1.0.0',
enabled: false,
});
});
it('handles -r reference to another input file', async () => {
fs.readLocalFile.mockImplementation((name): any => {
if (name === '1.in') {

View file

@ -5,7 +5,12 @@ import { ensureLocalPath } from '../../../util/fs/util';
import { normalizeDepName } from '../../datasource/pypi/common';
import { extractPackageFile as extractRequirementsFile } from '../pip_requirements/extract';
import { extractPackageFile as extractSetupPyFile } from '../pip_setup';
import type { ExtractConfig, PackageFile, PackageFileContent } from '../types';
import type {
ExtractConfig,
PackageDependency,
PackageFile,
PackageFileContent,
} from '../types';
import { extractHeaderCommand } from './common';
import type {
DependencyBetweenFiles,
@ -135,6 +140,7 @@ export async function extractAllPackageFiles(
);
const existingPackageFile = packageFiles.get(packageFile)!;
existingPackageFile.lockFiles!.push(fileMatch);
extendWithIndirectDeps(existingPackageFile, lockedDeps);
lockFileSources.set(fileMatch, existingPackageFile);
continue;
}
@ -183,6 +189,7 @@ export async function extractAllPackageFiles(
);
}
}
extendWithIndirectDeps(packageFileContent, lockedDeps);
const newPackageFile: PackageFile = {
...packageFileContent,
lockFiles: [fileMatch],
@ -230,3 +237,47 @@ export async function extractAllPackageFiles(
);
return result;
}
function extendWithIndirectDeps(
packageFileContent: PackageFileContent,
lockedDeps: PackageDependency[],
): void {
for (const lockedDep of lockedDeps) {
if (
!packageFileContent.deps.find(
(dep) =>
normalizeDepName(lockedDep.depName!) ===
normalizeDepName(dep.depName!),
)
) {
packageFileContent.deps.push(indirectDep(lockedDep));
}
}
}
/**
* As indirect dependecies don't exist in the package file, we need to
* create them from the lock file.
*
* By removing currentValue and currentVersion, we ensure that they
* are handled like unconstrained dependencies with locked version.
* Such packages are updated when their update strategy
* is set to 'update-lockfile',
* see: lib/workers/repository/process/lookup/index.ts.
*
* By disabling them by default, we won't create noise by updating them.
* Unless they have vulnerability alert, then they are forced to be updated.
* @param dep dependency extracted from lock file (requirements.txt)
* @returns unconstrained dependency with locked version
*/
function indirectDep(dep: PackageDependency): PackageDependency {
const result = {
...dep,
lockedVersion: dep.currentVersion,
depType: 'indirect',
enabled: false,
};
delete result.currentValue;
delete result.currentVersion;
return result;
}

View file

@ -83,3 +83,9 @@ Renovate reads the `requirements.txt` file and extracts these `pip-compile` argu
- `--output-file`
All other allowed `pip-compile` arguments will be passed over without modification.
### Transitive / indirect dependencies
This manager detects dependencies that only appear in lock files.
They are disabled by default but can be forced to enable by vulnerability alerts.
They will be upgraded with `--upgrade-package` option.