From 7183564710cd2718e42c8fdb0553eaae3a022716 Mon Sep 17 00:00:00 2001 From: Mathieu Kniewallner Date: Sun, 8 Sep 2024 16:27:34 +0200 Subject: [PATCH] fix(manager/uv): skip unsupported sources --- .../manager/pep621/processors/uv.spec.ts | 61 ++++++++++++++++++- lib/modules/manager/pep621/processors/uv.ts | 31 ++++++++++ lib/modules/manager/pep621/schema.ts | 8 +++ 3 files changed, 97 insertions(+), 3 deletions(-) diff --git a/lib/modules/manager/pep621/processors/uv.spec.ts b/lib/modules/manager/pep621/processors/uv.spec.ts index 7488abe4fc8e744..52cf146eb6ac20a 100644 --- a/lib/modules/manager/pep621/processors/uv.spec.ts +++ b/lib/modules/manager/pep621/processors/uv.spec.ts @@ -26,7 +26,7 @@ describe('modules/manager/pep621/processors/uv', () => { describe('process()', () => { it('returns initial dependencies if there is no tool.uv section', () => { const pyproject = { tool: {} }; - const dependencies = [{ packageName: 'dep1' }]; + const dependencies = [{ depName: 'dep1' }]; const result = processor.process(pyproject, dependencies); @@ -37,12 +37,12 @@ describe('modules/manager/pep621/processors/uv', () => { const pyproject = { tool: { uv: { 'dev-dependencies': ['dep2==1.2.3', 'dep3==2.3.4'] } }, }; - const dependencies = [{ packageName: 'dep1' }]; + const dependencies = [{ depName: 'dep1' }]; const result = processor.process(pyproject, dependencies); expect(result).toEqual([ - { packageName: 'dep1' }, + { depName: 'dep1' }, { currentValue: '==1.2.3', currentVersion: '1.2.3', @@ -61,6 +61,61 @@ describe('modules/manager/pep621/processors/uv', () => { }, ]); }); + + it('skips dependencies with unsupported sources', () => { + const pyproject = { + tool: { + uv: { + sources: { + dep2: { workspace: false }, + dep3: { git: 'https://github.com/foo/bar' }, + dep4: { path: '/local-dep.whl' }, + dep5: { url: 'https://example.com' }, + dep6: { workspace: true }, + }, + }, + }, + }; + const dependencies = [ + { depName: 'dep1' }, + { depName: 'dep2' }, + { depName: 'dep3' }, + { depName: 'dep4' }, + { depName: 'dep5' }, + { depName: 'dep6' }, + ]; + + const result = processor.process(pyproject, dependencies); + + expect(result).toEqual([ + { + depName: 'dep1', + }, + { + depName: 'dep2', + }, + { + depName: 'dep3', + currentValue: '', + skipReason: 'git-dependency', + }, + { + depName: 'dep4', + currentValue: '', + skipReason: 'path-dependency', + }, + { + depName: 'dep5', + currentValue: '', + skipReason: 'unsupported-url', + }, + { + depName: 'dep6', + currentValue: '', + skipReason: 'inherited-dependency', + }, + ]); + }); }); describe('updateArtifacts()', () => { diff --git a/lib/modules/manager/pep621/processors/uv.ts b/lib/modules/manager/pep621/processors/uv.ts index f5b6cd5c7f713f0..65f543201411f24 100644 --- a/lib/modules/manager/pep621/processors/uv.ts +++ b/lib/modules/manager/pep621/processors/uv.ts @@ -2,6 +2,7 @@ import is from '@sindresorhus/is'; import { quote } from 'shlex'; import { TEMPORARY_ERROR } from '../../../../constants/error-messages'; import { logger } from '../../../../logger'; +import type { SkipReason } from '../../../../types'; import { exec } from '../../../../util/exec'; import type { ExecOptions, ToolConstraint } from '../../../../util/exec/types'; import { getSiblingFileName, readLocalFile } from '../../../../util/fs'; @@ -32,6 +33,36 @@ export class UvProcessor implements PyProjectProcessor { ), ); + // https://docs.astral.sh/uv/concepts/dependencies/#dependency-sources + // Skip sources that are either not yet handled by Renovate (e.g. git), or do not make sense to handle (e.g. path). + if (uv.sources) { + for (const dep of deps) { + if (!dep.depName) { + continue; + } + + const depSource = uv.sources[dep.depName]; + if (depSource) { + let skipReason: SkipReason | undefined; + + if (depSource.git) { + skipReason = 'git-dependency'; + } else if (depSource.url) { + skipReason = 'unsupported-url'; + } else if (depSource.path) { + skipReason = 'path-dependency'; + } else if (depSource.workspace === true) { + skipReason = 'inherited-dependency'; + } + + if (skipReason) { + dep.currentValue = ''; + dep.skipReason = skipReason; + } + } + } + } + return deps; } diff --git a/lib/modules/manager/pep621/schema.ts b/lib/modules/manager/pep621/schema.ts index 4fc2b80a7dc697c..8f6e42d7963f68f 100644 --- a/lib/modules/manager/pep621/schema.ts +++ b/lib/modules/manager/pep621/schema.ts @@ -35,8 +35,16 @@ const HatchSchema = z.object({ .optional(), }); +const UvSource = z.object({ + git: z.string().optional(), + path: z.string().optional(), + url: z.string().optional(), + workspace: z.boolean().optional(), +}); + const UvSchema = z.object({ 'dev-dependencies': DependencyListSchema, + sources: z.record(z.string(), UvSource).optional(), }); export const PyProjectSchema = z.object({