From fa04884a37b6faeb2d91c54eae7ec7f21a4649e1 Mon Sep 17 00:00:00 2001 From: Johannes Feichtner <343448+Churro@users.noreply.github.com> Date: Tue, 19 Dec 2023 09:50:34 +0100 Subject: [PATCH] feat(manager/pep621): add support for `bumpVersion` option (#26361) Co-authored-by: Rhys Arkins <rhys@arkins.net> --- docs/usage/configuration-options.md | 2 +- lib/modules/manager/pep621/extract.spec.ts | 12 +++++ lib/modules/manager/pep621/extract.ts | 4 +- lib/modules/manager/pep621/index.ts | 1 + lib/modules/manager/pep621/schema.ts | 1 + lib/modules/manager/pep621/update.spec.ts | 51 ++++++++++++++++++++++ lib/modules/manager/pep621/update.ts | 48 ++++++++++++++++++++ 7 files changed, 117 insertions(+), 2 deletions(-) create mode 100644 lib/modules/manager/pep621/update.spec.ts create mode 100644 lib/modules/manager/pep621/update.ts diff --git a/docs/usage/configuration-options.md b/docs/usage/configuration-options.md index d225073659..40f9e3bcc8 100644 --- a/docs/usage/configuration-options.md +++ b/docs/usage/configuration-options.md @@ -410,7 +410,7 @@ This is an advance field and it's recommend you seek a config review before appl ## bumpVersion -Currently this setting supports `helmv3`, `npm`, `nuget`, `maven` and `sbt` only, so raise a feature request if you have a use for it with other package managers. +Currently this setting supports `helmv3`, `npm`, `nuget`, `maven`, `pep621` and `sbt` only, so raise a feature request if you have a use for it with other package managers. Its purpose is if you want Renovate to update the `version` field within your package file any time it updates dependencies within. Usually this is for automatic release purposes, so that you don't need to add another step after Renovate before you can release a new version. diff --git a/lib/modules/manager/pep621/extract.spec.ts b/lib/modules/manager/pep621/extract.spec.ts index 31b6edbb20..63aa8bcbdd 100644 --- a/lib/modules/manager/pep621/extract.spec.ts +++ b/lib/modules/manager/pep621/extract.spec.ts @@ -311,5 +311,17 @@ describe('modules/manager/pep621/extract', () => { }, ]); }); + + it('should extract project version', () => { + const content = codeBlock` + [project] + name = "test" + version = "0.0.2" + dependencies = [ "requests==2.30.0" ] + `; + + const res = extractPackageFile(content, 'pyproject.toml'); + expect(res?.packageFileVersion).toBe('0.0.2'); + }); }); }); diff --git a/lib/modules/manager/pep621/extract.ts b/lib/modules/manager/pep621/extract.ts index f5c5a607f6..d1f8e4accf 100644 --- a/lib/modules/manager/pep621/extract.ts +++ b/lib/modules/manager/pep621/extract.ts @@ -26,6 +26,8 @@ export function extractPackageFile( if (is.nullOrUndefined(def)) { return null; } + + const packageFileVersion = def.project?.version; const pythonConstraint = def.project?.['requires-python']; const extractedConstraints = is.nonEmptyString(pythonConstraint) ? { extractedConstraints: { python: pythonConstraint } } @@ -49,6 +51,6 @@ export function extractPackageFile( } return processedDeps.length - ? { ...extractedConstraints, deps: processedDeps } + ? { ...extractedConstraints, deps: processedDeps, packageFileVersion } : null; } diff --git a/lib/modules/manager/pep621/index.ts b/lib/modules/manager/pep621/index.ts index 1b4326edb1..d71206781f 100644 --- a/lib/modules/manager/pep621/index.ts +++ b/lib/modules/manager/pep621/index.ts @@ -1,5 +1,6 @@ import type { Category } from '../../../constants'; import { PypiDatasource } from '../../datasource/pypi'; +export { bumpPackageVersion } from './update'; export { extractPackageFile } from './extract'; export { updateArtifacts } from './artifacts'; diff --git a/lib/modules/manager/pep621/schema.ts b/lib/modules/manager/pep621/schema.ts index dbf9e1f4f2..880336adb3 100644 --- a/lib/modules/manager/pep621/schema.ts +++ b/lib/modules/manager/pep621/schema.ts @@ -10,6 +10,7 @@ const DependencyRecordSchema = z export const PyProjectSchema = z.object({ project: z .object({ + version: z.string().optional().catch(undefined), 'requires-python': z.string().optional(), dependencies: DependencyListSchema, 'optional-dependencies': DependencyRecordSchema, diff --git a/lib/modules/manager/pep621/update.spec.ts b/lib/modules/manager/pep621/update.spec.ts new file mode 100644 index 0000000000..5b33267b33 --- /dev/null +++ b/lib/modules/manager/pep621/update.spec.ts @@ -0,0 +1,51 @@ +import { codeBlock } from 'common-tags'; +import * as projectUpdater from '.'; + +describe('modules/manager/pep621/update', () => { + describe('bumpPackageVersion()', () => { + const content = codeBlock` + [project] + name = "test" + version = "0.0.2" + description = "test" + `; + + it('increments', () => { + const { bumpedContent } = projectUpdater.bumpPackageVersion( + content, + '0.0.2', + 'patch', + ); + const expected = content.replace('0.0.2', '0.0.3'); + expect(bumpedContent).toEqual(expected); + }); + + it('no ops', () => { + const { bumpedContent } = projectUpdater.bumpPackageVersion( + content, + '0.0.1', + 'patch', + ); + expect(bumpedContent).toEqual(content); + }); + + it('updates', () => { + const { bumpedContent } = projectUpdater.bumpPackageVersion( + content, + '0.0.1', + 'minor', + ); + const expected = content.replace('0.0.2', '0.1.0'); + expect(bumpedContent).toEqual(expected); + }); + + it('returns content if bumping errors', () => { + const { bumpedContent } = projectUpdater.bumpPackageVersion( + content, + '0.0.2', + true as any, + ); + expect(bumpedContent).toEqual(content); + }); + }); +}); diff --git a/lib/modules/manager/pep621/update.ts b/lib/modules/manager/pep621/update.ts new file mode 100644 index 0000000000..d19bb143ed --- /dev/null +++ b/lib/modules/manager/pep621/update.ts @@ -0,0 +1,48 @@ +import { inc } from '@renovatebot/pep440'; +import type { ReleaseType } from 'semver'; +import { logger } from '../../../logger'; +import { regEx } from '../../../util/regex'; +import type { BumpPackageVersionResult } from '../types'; + +export function bumpPackageVersion( + content: string, + currentValue: string, + bumpVersion: ReleaseType, +): BumpPackageVersionResult { + logger.debug( + { bumpVersion, currentValue }, + 'Checking if we should bump pyproject.toml version', + ); + + let bumpedContent = content; + try { + const newProjectVersion = inc(currentValue, bumpVersion); + if (!newProjectVersion) { + throw new Error('pep440 inc failed'); + } + + logger.debug(`newProjectVersion: ${newProjectVersion}`); + bumpedContent = content.replace( + regEx(`^(?<version>version[ \\t]*=[ \\t]*['"])[^'"]*`, 'm'), + `$<version>${newProjectVersion}`, + ); + + if (bumpedContent === content) { + logger.debug('Version was already bumped'); + } else { + logger.debug('Bumped pyproject.toml version'); + } + } catch (err) { + logger.warn( + { + content, + currentValue, + bumpVersion, + manager: 'pep621', + }, + 'Failed to bumpVersion', + ); + } + + return { bumpedContent }; +} -- GitLab