feat(manager/poetry): extract python as a dependency from pyproject.toml (#24236)

This commit is contained in:
Joshua Tang 2023-09-05 01:17:25 +10:00 committed by GitHub
parent 0f54d4a806
commit 46c10be305
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
6 changed files with 84 additions and 7 deletions

View file

@ -471,6 +471,17 @@ exports[`modules/manager/poetry/extract extractPackageFile() extracts multiple d
},
"versioning": "poetry",
},
{
"commitMessageTopic": "Python",
"currentValue": "~2.7 || ^3.4",
"datasource": "docker",
"depName": "python",
"depType": "dependencies",
"managerData": {
"nestedVersion": false,
},
"versioning": "poetry",
},
{
"currentValue": "^3.0",
"datasource": "pypi",
@ -554,6 +565,17 @@ exports[`modules/manager/poetry/extract extractPackageFile() handles multiple co
exports[`modules/manager/poetry/extract extractPackageFile() resolves lockedVersions from the lockfile 1`] = `
{
"deps": [
{
"commitMessageTopic": "Python",
"currentValue": "^3.9",
"datasource": "docker",
"depName": "python",
"depType": "dependencies",
"managerData": {
"nestedVersion": false,
},
"versioning": "poetry",
},
{
"currentValue": "*",
"datasource": "pypi",

View file

@ -1,3 +1,4 @@
import { codeBlock } from 'common-tags';
import { join } from 'upath';
import { envMock, mockExecAll } from '../../../../test/exec-util';
import { Fixtures } from '../../../../test/fixtures';
@ -8,7 +9,7 @@ import * as docker from '../../../util/exec/docker';
import * as _hostRules from '../../../util/host-rules';
import * as _datasource from '../../datasource';
import type { UpdateArtifactsConfig } from '../types';
import { getPoetryRequirement } from './artifacts';
import { getPoetryRequirement, getPythonConstraint } from './artifacts';
import { updateArtifacts } from '.';
const pyproject1toml = Fixtures.get('pyproject.1.toml');
@ -33,6 +34,29 @@ const adminConfig: RepoGlobalConfig = {
const config: UpdateArtifactsConfig = {};
describe('modules/manager/poetry/artifacts', () => {
describe('getPythonConstraint', () => {
const pythonVersion = '3.11.3';
const poetryLock = codeBlock`
[metadata]
python-versions = "${pythonVersion}"
`;
it('detects from pyproject.toml', () => {
const pythonVersion = '3.11.5';
const pyprojectContent = codeBlock`
[tool.poetry.dependencies]
python = "${pythonVersion}"
`;
expect(getPythonConstraint(pyprojectContent, poetryLock)).toBe(
pythonVersion
);
});
it('detects from poetry.ock', () => {
expect(getPythonConstraint('', poetryLock)).toBe(pythonVersion);
});
});
describe('getPoetryRequirement', () => {
const poetry12lock = Fixtures.get('poetry12.lock');
const poetry142lock = Fixtures.get('poetry142.lock');

View file

@ -22,12 +22,33 @@ import { Lockfile, PoetrySchemaToml } from './schema';
import type { PoetryFile, PoetrySource } from './types';
export function getPythonConstraint(
pyProjectContent: string,
existingLockFileContent: string
): string | null {
return Result.parse(
// Read Python version from `pyproject.toml` first as it could have been updated
const pyprojectPythonConstraint = Result.parse(
pyProjectContent,
PoetrySchemaToml.transform(
({ packageFileContent }) =>
packageFileContent.deps.find((dep) => dep.depName === 'python')
?.currentValue
)
).unwrapOrNull();
if (pyprojectPythonConstraint) {
logger.debug('Using python version from pyproject.toml');
return pyprojectPythonConstraint;
}
const lockfilePythonConstraint = Result.parse(
existingLockFileContent,
Lockfile.transform(({ pythonVersions }) => pythonVersions)
).unwrapOrNull();
if (lockfilePythonConstraint) {
logger.debug('Using python version from poetry.lock');
return lockfilePythonConstraint;
}
return null;
}
export function getPoetryRequirement(
@ -158,7 +179,7 @@ export async function updateArtifacts({
}
const pythonConstraint =
config?.constraints?.python ??
getPythonConstraint(existingLockFileContent);
getPythonConstraint(newPackageFileContent, existingLockFileContent);
const poetryConstraint =
config.constraints?.poetry ??
getPoetryRequirement(newPackageFileContent, existingLockFileContent);

View file

@ -48,7 +48,7 @@ describe('modules/manager/poetry/extract', () => {
it('extracts multiple dependencies', async () => {
const res = await extractPackageFile(pyproject1toml, filename);
expect(res?.deps).toMatchSnapshot();
expect(res?.deps).toHaveLength(9);
expect(res?.deps).toHaveLength(10);
expect(res?.extractedConstraints).toEqual({
python: '~2.7 || ^3.4',
});
@ -74,7 +74,7 @@ describe('modules/manager/poetry/extract', () => {
it('can parse TOML v1 heterogeneous arrays', async () => {
const res = await extractPackageFile(pyproject12toml, filename);
expect(res).not.toBeNull();
expect(res?.deps).toHaveLength(2);
expect(res?.deps).toHaveLength(3);
});
it('extracts registries', async () => {
@ -184,7 +184,10 @@ describe('modules/manager/poetry/extract', () => {
const res = await extractPackageFile(pyproject11toml, filename);
expect(res).toMatchSnapshot({
extractedConstraints: { python: '^3.9' },
deps: [{ lockedVersion: '1.17.5' }],
deps: [
{ depName: 'python', currentValue: '^3.9' },
{ depName: 'boto3', lockedVersion: '1.17.5' },
],
});
});

View file

@ -7,6 +7,7 @@ import {
readLocalFile,
} from '../../../util/fs';
import { Result } from '../../../util/result';
import { DockerDatasource } from '../../datasource/docker';
import type { PackageFileContent } from '../types';
import { Lockfile, PoetrySchemaToml } from './schema';
@ -37,7 +38,11 @@ export async function extractPackageFile(
if (dep.currentValue) {
pythonVersion = dep.currentValue;
}
return null;
return {
...dep,
datasource: DockerDatasource.id,
commitMessageTopic: 'Python',
};
}
const packageName = dep.packageName ?? dep.depName;

View file

@ -1,4 +1,5 @@
import type { Category } from '../../../constants';
import { DockerDatasource } from '../../datasource/docker';
import { GithubTagsDatasource } from '../../datasource/github-tags';
import { PypiDatasource } from '../../datasource/pypi';
@ -9,6 +10,7 @@ export { updateLockedDependency } from './update-locked';
export const supportedDatasources = [
PypiDatasource.id,
GithubTagsDatasource.id,
DockerDatasource.id,
];
export const supportsLockFileMaintenance = true;