diff --git a/lib/modules/manager/poetry/__snapshots__/extract.spec.ts.snap b/lib/modules/manager/poetry/__snapshots__/extract.spec.ts.snap index fcddaf7d39076f94312476db32779105327fd7a3..d8d9774e542b0a6f6fbd0f555b09625cb0d39fad 100644 --- a/lib/modules/manager/poetry/__snapshots__/extract.spec.ts.snap +++ b/lib/modules/manager/poetry/__snapshots__/extract.spec.ts.snap @@ -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", diff --git a/lib/modules/manager/poetry/artifacts.spec.ts b/lib/modules/manager/poetry/artifacts.spec.ts index 72d2f8023a15e64d5385d3a4858a0885edf66a42..14fe5310dd8f1e893f599d17c16ae2fbca5f4841 100644 --- a/lib/modules/manager/poetry/artifacts.spec.ts +++ b/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'; @@ -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'); diff --git a/lib/modules/manager/poetry/artifacts.ts b/lib/modules/manager/poetry/artifacts.ts index bd5dc50a5965ff600921299dffe74382108ae6a6..74a177073f09e6fa164f05ceb237d007decb6ff9 100644 --- a/lib/modules/manager/poetry/artifacts.ts +++ b/lib/modules/manager/poetry/artifacts.ts @@ -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); diff --git a/lib/modules/manager/poetry/extract.spec.ts b/lib/modules/manager/poetry/extract.spec.ts index 6f581b6deef83f0e10bf49e958a80ddee4473301..5826caf2aa9cf813eeeca88fc22ef3cd50f52d75 100644 --- a/lib/modules/manager/poetry/extract.spec.ts +++ b/lib/modules/manager/poetry/extract.spec.ts @@ -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' }, + ], }); }); diff --git a/lib/modules/manager/poetry/extract.ts b/lib/modules/manager/poetry/extract.ts index ef112c9b25e93370997e688c564bff7397406c8e..df5750548e72921d10af329cb039bbba46bda7de 100644 --- a/lib/modules/manager/poetry/extract.ts +++ b/lib/modules/manager/poetry/extract.ts @@ -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; diff --git a/lib/modules/manager/poetry/index.ts b/lib/modules/manager/poetry/index.ts index 1ad1b1912875038be8a530434b318776a1bec7e4..a6b63c5f0c46908b83fe79d5d967a409414e4ece 100644 --- a/lib/modules/manager/poetry/index.ts +++ b/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'; @@ -9,6 +10,7 @@ export { updateLockedDependency } from './update-locked'; export const supportedDatasources = [ PypiDatasource.id, GithubTagsDatasource.id, + DockerDatasource.id, ]; export const supportsLockFileMaintenance = true;