From 98dccfffbc7aa7020fff0bcdac8bb291c9cf16d5 Mon Sep 17 00:00:00 2001 From: Jonathan Berthias Date: Mon, 16 Oct 2023 17:44:48 +0200 Subject: [PATCH] feat(manager/pep621): support hatch environments (#25211) Co-authored-by: Sebastian Poxhofer Co-authored-by: Michael Kriese --- .../__fixtures__/pyproject_with_hatch.toml | 29 +++++++++++++ lib/modules/manager/pep621/extract.spec.ts | 43 +++++++++++++++++++ .../manager/pep621/processors/hatch.ts | 43 +++++++++++++++++++ .../manager/pep621/processors/index.ts | 3 +- lib/modules/manager/pep621/readme.md | 4 +- lib/modules/manager/pep621/schema.ts | 15 +++++++ 6 files changed, 135 insertions(+), 2 deletions(-) create mode 100644 lib/modules/manager/pep621/__fixtures__/pyproject_with_hatch.toml create mode 100644 lib/modules/manager/pep621/processors/hatch.ts diff --git a/lib/modules/manager/pep621/__fixtures__/pyproject_with_hatch.toml b/lib/modules/manager/pep621/__fixtures__/pyproject_with_hatch.toml new file mode 100644 index 00000000000000..593ce278a5e177 --- /dev/null +++ b/lib/modules/manager/pep621/__fixtures__/pyproject_with_hatch.toml @@ -0,0 +1,29 @@ +[build-system] +requires = ["hatchling"] +build-backend = "hatchling.build" + +[project] +name = "hatch" +dependencies = [ + "requests==2.30.0" +] + +[tool.hatch.envs.default] +dependencies = [ + "coverage[toml]==6.5", + "pytest", +] + +[[tool.hatch.envs.all.matrix]] +python = ["3.7", "3.8", "3.9", "3.10", "3.11"] + +[tool.hatch.envs.lint] +detached = true +dependencies = [ + "black>=23.1.0", +] + +[tool.hatch.envs.experimental] +extra-dependencies = [ + "baz", +] diff --git a/lib/modules/manager/pep621/extract.spec.ts b/lib/modules/manager/pep621/extract.spec.ts index f7a5cea44f7630..80cb00c1394fb3 100644 --- a/lib/modules/manager/pep621/extract.spec.ts +++ b/lib/modules/manager/pep621/extract.spec.ts @@ -268,5 +268,48 @@ describe('modules/manager/pep621/extract', () => { }, ]); }); + + it('should extract dependencies from hatch environments', function () { + const hatchPyProject = Fixtures.get('pyproject_with_hatch.toml'); + const result = extractPackageFile(hatchPyProject, 'pyproject.toml'); + + expect(result?.deps).toEqual([ + { + currentValue: '==2.30.0', + datasource: 'pypi', + depName: 'requests', + depType: 'project.dependencies', + packageName: 'requests', + }, + { + currentValue: '==6.5', + datasource: 'pypi', + depName: 'coverage', + depType: 'tool.hatch.envs.default', + packageName: 'coverage', + }, + { + datasource: 'pypi', + depName: 'pytest', + depType: 'tool.hatch.envs.default', + packageName: 'pytest', + skipReason: 'unspecified-version', + }, + { + currentValue: '>=23.1.0', + datasource: 'pypi', + depName: 'black', + depType: 'tool.hatch.envs.lint', + packageName: 'black', + }, + { + datasource: 'pypi', + depName: 'baz', + depType: 'tool.hatch.envs.experimental', + packageName: 'baz', + skipReason: 'unspecified-version', + }, + ]); + }); }); }); diff --git a/lib/modules/manager/pep621/processors/hatch.ts b/lib/modules/manager/pep621/processors/hatch.ts new file mode 100644 index 00000000000000..3a709518482a05 --- /dev/null +++ b/lib/modules/manager/pep621/processors/hatch.ts @@ -0,0 +1,43 @@ +import is from '@sindresorhus/is'; +import type { + PackageDependency, + UpdateArtifact, + UpdateArtifactsResult, +} from '../../types'; +import type { PyProject } from '../schema'; +import { parseDependencyList } from '../utils'; +import type { PyProjectProcessor } from './types'; + +export class HatchProcessor implements PyProjectProcessor { + process( + pyproject: PyProject, + deps: PackageDependency[] + ): PackageDependency[] { + const hatch_envs = pyproject.tool?.hatch?.envs; + if (is.nullOrUndefined(hatch_envs)) { + return deps; + } + + for (const [envName, env] of Object.entries(hatch_envs)) { + const depType = `tool.hatch.envs.${envName}`; + const envDeps = parseDependencyList(depType, env?.dependencies); + deps.push(...envDeps); + const extraDeps = parseDependencyList( + depType, + env?.['extra-dependencies'] + ); + deps.push(...extraDeps); + } + + return deps; + } + + updateArtifacts( + updateArtifact: UpdateArtifact, + project: PyProject + ): Promise { + // Hatch does not have lock files at the moment + // https://github.com/pypa/hatch/issues/749 + return Promise.resolve(null); + } +} diff --git a/lib/modules/manager/pep621/processors/index.ts b/lib/modules/manager/pep621/processors/index.ts index ba80de12ccbe20..9529f131065bd3 100644 --- a/lib/modules/manager/pep621/processors/index.ts +++ b/lib/modules/manager/pep621/processors/index.ts @@ -1,3 +1,4 @@ +import { HatchProcessor } from './hatch'; import { PdmProcessor } from './pdm'; -export const processors = [new PdmProcessor()]; +export const processors = [new HatchProcessor(), new PdmProcessor()]; diff --git a/lib/modules/manager/pep621/readme.md b/lib/modules/manager/pep621/readme.md index 073e1bf787c172..344e3948559e4e 100644 --- a/lib/modules/manager/pep621/readme.md +++ b/lib/modules/manager/pep621/readme.md @@ -2,10 +2,12 @@ This manager supports updating dependencies inside `pyproject.toml` files. In addition to standard dependencies, these toolsets are also supported: -- `pdm` ( including `pdm.lock` files ) +- `pdm` (including `pdm.lock` files) +- `hatch` Available `depType`s: - `project.dependencies` - `project.optional-dependencies` - `tool.pdm.dev-dependencies` +- `tool.hatch.envs.` diff --git a/lib/modules/manager/pep621/schema.ts b/lib/modules/manager/pep621/schema.ts index c4a7443ebbf8ed..220cdc3ebd3d82 100644 --- a/lib/modules/manager/pep621/schema.ts +++ b/lib/modules/manager/pep621/schema.ts @@ -31,6 +31,21 @@ export const PyProjectSchema = z.object({ .optional(), }) .optional(), + hatch: z + .object({ + envs: z + .record( + z.string(), + z + .object({ + dependencies: DependencyListSchema, + 'extra-dependencies': DependencyListSchema, + }) + .optional() + ) + .optional(), + }) + .optional(), }) .optional(), });