Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

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

Merged
merged 3 commits into from Sep 4, 2023
Merged
Show file tree
Hide file tree
Changes from 2 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
22 changes: 22 additions & 0 deletions lib/modules/manager/poetry/__snapshots__/extract.spec.ts.snap
Expand Up @@ -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": "docker",
},
{
"currentValue": "^3.0",
"datasource": "pypi",
Expand Down Expand Up @@ -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": "docker",
},
{
"currentValue": "*",
"datasource": "pypi",
Expand Down
26 changes: 25 additions & 1 deletion lib/modules/manager/poetry/artifacts.spec.ts
@@ -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';
Expand All @@ -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');
Expand All @@ -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');
Expand Down
25 changes: 23 additions & 2 deletions lib/modules/manager/poetry/artifacts.ts
Expand Up @@ -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(
Expand Down Expand Up @@ -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);
Expand Down
9 changes: 6 additions & 3 deletions lib/modules/manager/poetry/extract.spec.ts
Expand Up @@ -47,8 +47,8 @@

it('extracts multiple dependencies', async () => {
const res = await extractPackageFile(pyproject1toml, filename);
expect(res?.deps).toMatchSnapshot();

Check failure on line 50 in lib/modules/manager/poetry/extract.spec.ts

View workflow job for this annotation

GitHub Actions / test (6/16)

modules/manager/poetry/extract › extractPackageFile() › extracts multiple dependencies

expect(received).toMatchSnapshot() Snapshot name: `modules/manager/poetry/extract extractPackageFile() extracts multiple dependencies 1` - Snapshot - 1 + Received + 1 @@ -47,11 +47,11 @@ "depName": "python", "depType": "dependencies", "managerData": { "nestedVersion": false, }, - "versioning": "docker", + "versioning": "poetry", }, { "currentValue": "^3.0", "datasource": "pypi", "depName": "dev_dep1", at Object.<anonymous> (lib/modules/manager/poetry/extract.spec.ts:50:25)
expect(res?.deps).toHaveLength(9);
expect(res?.deps).toHaveLength(10);
expect(res?.extractedConstraints).toEqual({
python: '~2.7 || ^3.4',
});
Expand All @@ -74,7 +74,7 @@
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 () => {
Expand Down Expand Up @@ -182,9 +182,12 @@
it('resolves lockedVersions from the lockfile', async () => {
fs.readLocalFile.mockResolvedValue(pyproject11tomlLock);
const res = await extractPackageFile(pyproject11toml, filename);
expect(res).toMatchSnapshot({

Check failure on line 185 in lib/modules/manager/poetry/extract.spec.ts

View workflow job for this annotation

GitHub Actions / test (6/16)

modules/manager/poetry/extract › extractPackageFile() › resolves lockedVersions from the lockfile

expect(received).toMatchSnapshot(properties) Snapshot name: `modules/manager/poetry/extract extractPackageFile() resolves lockedVersions from the lockfile 1` - Snapshot - 1 + Received + 1 @@ -7,11 +7,11 @@ "depName": "python", "depType": "dependencies", "managerData": { "nestedVersion": false, }, - "versioning": "docker", + "versioning": "poetry", }, { "currentValue": "*", "datasource": "pypi", "depName": "boto3", at Object.<anonymous> (lib/modules/manager/poetry/extract.spec.ts:185:19)
extractedConstraints: { python: '^3.9' },
deps: [{ lockedVersion: '1.17.5' }],
deps: [
{ depName: 'python', currentValue: '^3.9' },
{ depName: 'boto3', lockedVersion: '1.17.5' },
],
});
});

Expand Down
7 changes: 6 additions & 1 deletion lib/modules/manager/poetry/extract.ts
Expand Up @@ -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';

Expand Down Expand Up @@ -37,7 +38,11 @@ export async function extractPackageFile(
if (dep.currentValue) {
pythonVersion = dep.currentValue;
}
return null;
return {
...dep,
datasource: DockerDatasource.id,
commitMessageTopic: 'Python',
viceice marked this conversation as resolved.
Show resolved Hide resolved
};
}

const packageName = dep.packageName ?? dep.depName;
Expand Down
2 changes: 2 additions & 0 deletions lib/modules/manager/poetry/index.ts
@@ -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';

Expand All @@ -9,6 +10,7 @@ export { updateLockedDependency } from './update-locked';
export const supportedDatasources = [
PypiDatasource.id,
GithubTagsDatasource.id,
DockerDatasource.id,
];

export const supportsLockFileMaintenance = true;
Expand Down