From 83f2bf46d36a6d905cdf40adbbef3bb36c9af043 Mon Sep 17 00:00:00 2001 From: Stephen Rosen Date: Sun, 13 Oct 2024 01:05:02 -0500 Subject: [PATCH 1/2] Initial implementation of dependency-groups --- src/lib.rs | 57 +++++++++++++++++++++++++++++++++++++++++++++++++++++- 1 file changed, 56 insertions(+), 1 deletion(-) diff --git a/src/lib.rs b/src/lib.rs index 897c7a6..daf4030 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -23,6 +23,8 @@ pub struct PyProjectToml { pub build_system: Option, /// Project metadata pub project: Option, + /// Dependency groups table + pub dependency_groups: Option, } /// PEP 621 project metadata @@ -161,6 +163,24 @@ pub struct Contact { pub email: Option, } +/// The `[dependency-groups]` section of pyproject.toml, as specified in PEP 735 +type DependencyGroups = IndexMap>; + +/// A specifier item in a Dependency Group +#[derive(Serialize, Deserialize, Debug, Clone, PartialEq, Eq)] +#[serde(rename_all = "kebab-case")] +#[serde(untagged)] +pub enum DependencyGroupSpecifier { + /// PEP 508 requirement string + String(Requirement), + /// DependencyGroupInclude + #[serde(rename_all = "kebab-case")] + Table { + /// The name of the group to include + include_group: Option, + }, +} + impl PyProjectToml { /// Parse `pyproject.toml` content pub fn new(content: &str) -> Result { @@ -170,7 +190,7 @@ impl PyProjectToml { #[cfg(test)] mod tests { - use super::{License, LicenseFiles, PyProjectToml, ReadMe}; + use super::{DependencyGroupSpecifier, License, LicenseFiles, PyProjectToml, ReadMe}; use pep440_rs::{Version, VersionSpecifiers}; use pep508_rs::Requirement; use std::str::FromStr; @@ -408,4 +428,39 @@ readme = {text = "ReadMe!", content-type = "text/plain"} }) ); } + + #[test] + fn test_parse_pyproject_toml_dependency_groups() { + let source = r#"[dependency-groups] +alpha = ["beta", "gamma", "delta"] +epsilon = ["eta<2.0", "theta==2024.09.01"] +iota = [{include-group = "alpha"}] +"#; + let project_toml = PyProjectToml::new(source).unwrap(); + let dependency_groups = project_toml.dependency_groups.as_ref().unwrap(); + + assert_eq!( + dependency_groups["alpha"], + vec![ + DependencyGroupSpecifier::String(Requirement::from_str("beta").unwrap()), + DependencyGroupSpecifier::String(Requirement::from_str("gamma").unwrap()), + DependencyGroupSpecifier::String(Requirement::from_str("delta").unwrap(),) + ] + ); + assert_eq!( + dependency_groups["epsilon"], + vec![ + DependencyGroupSpecifier::String(Requirement::from_str("eta<2.0").unwrap()), + DependencyGroupSpecifier::String( + Requirement::from_str("theta==2024.09.01").unwrap() + ) + ] + ); + assert_eq!( + dependency_groups["iota"], + vec![DependencyGroupSpecifier::Table { + include_group: Some("alpha".to_string()) + }] + ); + } } From 3daa40a53c6ce4c48118fcf1211ec1cb07efba08 Mon Sep 17 00:00:00 2001 From: konstin Date: Sun, 13 Oct 2024 09:48:55 +0200 Subject: [PATCH 2/2] Make `DependencyGroups` a newtype and bump version This allows implementing methods on it. --- Cargo.lock | 2 +- Cargo.toml | 2 +- Changelog.md | 4 ++++ src/lib.rs | 20 +++++++++++++++----- 4 files changed, 21 insertions(+), 7 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index 573984b..76bfcba 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -130,7 +130,7 @@ dependencies = [ [[package]] name = "pyproject-toml" -version = "0.11.0" +version = "0.12.0" dependencies = [ "indexmap", "pep440_rs", diff --git a/Cargo.toml b/Cargo.toml index d3d2173..89d0baf 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "pyproject-toml" -version = "0.11.0" +version = "0.12.0" description = "pyproject.toml parser in Rust" edition = "2021" license = "MIT" diff --git a/Changelog.md b/Changelog.md index 32855f1..97c7f5f 100644 --- a/Changelog.md +++ b/Changelog.md @@ -1,5 +1,9 @@ # Changelog +## 0.12.0 + +* Support dependency groups (PEP 735) + ## 0.11.0 * Update pep440_rs to 0.6.0 diff --git a/src/lib.rs b/src/lib.rs index daf4030..1e0678b 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -2,6 +2,7 @@ use indexmap::IndexMap; use pep440_rs::{Version, VersionSpecifiers}; use pep508_rs::Requirement; use serde::{Deserialize, Serialize}; +use std::ops::Deref; /// The `[build-system]` section of a pyproject.toml as specified in PEP 517 #[derive(Serialize, Deserialize, Debug, Clone, PartialEq, Eq)] @@ -43,7 +44,7 @@ pub struct Project { pub requires_python: Option, /// License pub license: Option, - /// License Files (PEP 639) - https://peps.python.org/pep-0639/#add-license-files-key + /// License Files (PEP 639) - pub license_files: Option, /// The people or organizations considered to be the "authors" of the project pub authors: Option>, @@ -164,16 +165,25 @@ pub struct Contact { } /// The `[dependency-groups]` section of pyproject.toml, as specified in PEP 735 -type DependencyGroups = IndexMap>; +#[derive(Serialize, Deserialize, Debug, Clone, PartialEq, Eq)] +#[serde(transparent)] +pub struct DependencyGroups(pub IndexMap>); + +impl Deref for DependencyGroups { + type Target = IndexMap>; + + fn deref(&self) -> &Self::Target { + &self.0 + } +} /// A specifier item in a Dependency Group #[derive(Serialize, Deserialize, Debug, Clone, PartialEq, Eq)] -#[serde(rename_all = "kebab-case")] -#[serde(untagged)] +#[serde(rename_all = "kebab-case", untagged)] pub enum DependencyGroupSpecifier { /// PEP 508 requirement string String(Requirement), - /// DependencyGroupInclude + /// Include another dependency group #[serde(rename_all = "kebab-case")] Table { /// The name of the group to include