Skip to content

Commit

Permalink
feat(manager/uv): extract packages from lockfile (#31137)
Browse files Browse the repository at this point in the history
Co-authored-by: Michael Kriese <michael.kriese@visualon.de>
  • Loading branch information
mkniewallner and viceice authored Sep 2, 2024
1 parent a35197c commit 058578f
Show file tree
Hide file tree
Showing 3 changed files with 118 additions and 2 deletions.
80 changes: 80 additions & 0 deletions lib/modules/manager/pep621/extract.spec.ts
Original file line number Diff line number Diff line change
Expand Up @@ -411,5 +411,85 @@ describe('modules/manager/pep621/extract', () => {
],
});
});

it('should resolve lockedVersions from uv.lock', async () => {
fs.readLocalFile.mockResolvedValue(
codeBlock`
version = 1
requires-python = ">=3.11"
[[package]]
name = "attrs"
version = "24.2.0"
source = { registry = "https://pypi.org/simple" }
sdist = { url = "https://files.pythonhosted.org/packages/fc/0f/aafca9af9315aee06a89ffde799a10a582fe8de76c563ee80bbcdc08b3fb/attrs-24.2.0.tar.gz", hash = "sha256:5cfb1b9148b5b086569baec03f20d7b6bf3bcacc9a42bebf87ffaaca362f6346", size = 792678 }
wheels = [
{ url = "https://files.pythonhosted.org/packages/6a/21/5b6702a7f963e95456c0de2d495f67bf5fd62840ac655dc451586d23d39a/attrs-24.2.0-py3-none-any.whl", hash = "sha256:81921eb96de3191c8258c199618104dd27ac608d9366f5e35d011eae1867ede2", size = 63001 },
]
[[package]]
name = "pep621-uv"
version = "0.1.0"
source = { virtual = "." }
dependencies = [
{ name = "attrs" },
]
[package.metadata]
requires-dist = [{ name = "attrs", specifier = ">=24.1.0" }]
`,
);

const res = await extractPackageFile(
codeBlock`
[project]
name = "pep621-uv"
version = "0.1.0"
dependencies = ["attrs>=24.1.0"]
requires-python = ">=3.11"
`,
'pyproject.toml',
);
expect(res).toMatchObject({
extractedConstraints: { python: '>=3.11' },
deps: [
{
packageName: 'attrs',
depName: 'attrs',
datasource: 'pypi',
depType: 'project.dependencies',
currentValue: '>=24.1.0',
lockedVersion: '24.2.0',
},
],
});
});

it('should resolve dependencies without locked versions on invalid uv.lock', async () => {
fs.readLocalFile.mockResolvedValue(codeBlock`invalid_toml`);

const res = await extractPackageFile(
codeBlock`
[project]
name = "pep621-uv"
version = "0.1.0"
dependencies = ["attrs>=24.1.0"]
requires-python = ">=3.11"
`,
'pyproject.toml',
);
expect(res).toMatchObject({
extractedConstraints: { python: '>=3.11' },
deps: [
{
packageName: 'attrs',
depName: 'attrs',
datasource: 'pypi',
depType: 'project.dependencies',
currentValue: '>=24.1.0',
},
],
});
});
});
});
25 changes: 23 additions & 2 deletions lib/modules/manager/pep621/processors/uv.ts
Original file line number Diff line number Diff line change
Expand Up @@ -5,13 +5,14 @@ import { logger } from '../../../../logger';
import { exec } from '../../../../util/exec';
import type { ExecOptions, ToolConstraint } from '../../../../util/exec/types';
import { getSiblingFileName, readLocalFile } from '../../../../util/fs';
import { Result } from '../../../../util/result';
import type {
PackageDependency,
UpdateArtifact,
UpdateArtifactsResult,
Upgrade,
} from '../../types';
import { type PyProject } from '../schema';
import { type PyProject, UvLockfileSchema } from '../schema';
import { depTypes, parseDependencyList } from '../utils';
import type { PyProjectProcessor } from './types';

Expand All @@ -34,11 +35,31 @@ export class UvProcessor implements PyProjectProcessor {
return deps;
}

extractLockedVersions(
async extractLockedVersions(
project: PyProject,
deps: PackageDependency[],
packageFile: string,
): Promise<PackageDependency[]> {
const lockFileName = getSiblingFileName(packageFile, 'uv.lock');
const lockFileContent = await readLocalFile(lockFileName, 'utf8');
if (lockFileContent) {
const { val: lockFileMapping, err } = Result.parse(
lockFileContent,
UvLockfileSchema,
).unwrap();

if (err) {
logger.debug({ packageFile, err }, `Error parsing uv lock file`);
} else {
for (const dep of deps) {
const packageName = dep.packageName;
if (packageName && packageName in lockFileMapping) {
dep.lockedVersion = lockFileMapping[packageName];
}
}
}
}

return Promise.resolve(deps);
}

Expand Down
15 changes: 15 additions & 0 deletions lib/modules/manager/pep621/schema.ts
Original file line number Diff line number Diff line change
Expand Up @@ -79,3 +79,18 @@ export const PdmLockfileSchema = Toml.pipe(
),
)
.transform((lock) => ({ lock }));

export const UvLockfileSchema = Toml.pipe(
z.object({
package: LooseArray(
z.object({
name: z.string(),
version: z.string(),
}),
),
}),
).transform(({ package: pkg }) =>
Object.fromEntries(
pkg.map(({ name, version }): [string, string] => [name, version]),
),
);

0 comments on commit 058578f

Please sign in to comment.