mirror of
https://github.com/renovatebot/renovate.git
synced 2025-01-12 23:16:26 +00:00
feat(manager/pip-compile): Allow security updates for transitive dependencies (#27561)
This commit is contained in:
parent
f8890796bf
commit
0df4ff5ce8
3 changed files with 81 additions and 1 deletions
|
@ -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 () => {
|
it('handles -r reference to another input file', async () => {
|
||||||
fs.readLocalFile.mockImplementation((name): any => {
|
fs.readLocalFile.mockImplementation((name): any => {
|
||||||
if (name === '1.in') {
|
if (name === '1.in') {
|
||||||
|
|
|
@ -5,7 +5,12 @@ import { ensureLocalPath } from '../../../util/fs/util';
|
||||||
import { normalizeDepName } from '../../datasource/pypi/common';
|
import { normalizeDepName } from '../../datasource/pypi/common';
|
||||||
import { extractPackageFile as extractRequirementsFile } from '../pip_requirements/extract';
|
import { extractPackageFile as extractRequirementsFile } from '../pip_requirements/extract';
|
||||||
import { extractPackageFile as extractSetupPyFile } from '../pip_setup';
|
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 { extractHeaderCommand } from './common';
|
||||||
import type {
|
import type {
|
||||||
DependencyBetweenFiles,
|
DependencyBetweenFiles,
|
||||||
|
@ -135,6 +140,7 @@ export async function extractAllPackageFiles(
|
||||||
);
|
);
|
||||||
const existingPackageFile = packageFiles.get(packageFile)!;
|
const existingPackageFile = packageFiles.get(packageFile)!;
|
||||||
existingPackageFile.lockFiles!.push(fileMatch);
|
existingPackageFile.lockFiles!.push(fileMatch);
|
||||||
|
extendWithIndirectDeps(existingPackageFile, lockedDeps);
|
||||||
lockFileSources.set(fileMatch, existingPackageFile);
|
lockFileSources.set(fileMatch, existingPackageFile);
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
@ -183,6 +189,7 @@ export async function extractAllPackageFiles(
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
extendWithIndirectDeps(packageFileContent, lockedDeps);
|
||||||
const newPackageFile: PackageFile = {
|
const newPackageFile: PackageFile = {
|
||||||
...packageFileContent,
|
...packageFileContent,
|
||||||
lockFiles: [fileMatch],
|
lockFiles: [fileMatch],
|
||||||
|
@ -230,3 +237,47 @@ export async function extractAllPackageFiles(
|
||||||
);
|
);
|
||||||
return result;
|
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;
|
||||||
|
}
|
||||||
|
|
|
@ -83,3 +83,9 @@ Renovate reads the `requirements.txt` file and extracts these `pip-compile` argu
|
||||||
- `--output-file`
|
- `--output-file`
|
||||||
|
|
||||||
All other allowed `pip-compile` arguments will be passed over without modification.
|
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.
|
||||||
|
|
Loading…
Reference in a new issue