Skip to content

Commit c9506f3

Browse files
Make the trait internal and rely on providing project name explicitely in resolve
1 parent 1191fdc commit c9506f3

File tree

4 files changed

+45
-44
lines changed

4 files changed

+45
-44
lines changed

src/has_recursion.rs

Lines changed: 3 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -5,19 +5,10 @@ use thiserror::Error;
55

66
/// A trait that resolves recursions for groups of requirements that can be mapped to `IndexMap<String, Vec<T>>`
77
/// where T is a type that can be mapped to either a Requirement or a reference to other groups of requirements.
8-
pub trait HasRecursion<T>: Deref<Target = IndexMap<String, Vec<T>>>
8+
pub(crate) trait HasRecursion<T>: Deref<Target = IndexMap<String, Vec<T>>>
99
where
1010
T: RecursionItem,
1111
{
12-
/// Resolve the groups into lists of requirements.
13-
///
14-
/// This function will recursively resolve all groups, including those that
15-
/// reference other groups. It will return an error if there is a cycle in the
16-
/// groups or if a group references another group that does not exist.
17-
fn resolve(&self) -> Result<IndexMap<String, Vec<Requirement>>, RecursionResolutionError> {
18-
self.resolve_all(None)
19-
}
20-
2112
/// Resolves the groups of requirements into flat lists of requirements.
2213
fn resolve_all(
2314
&self,
@@ -81,7 +72,7 @@ where
8172
}
8273
}
8374
/// A trait that defines how to parse a recursion item.
84-
pub trait RecursionItem {
75+
pub(crate) trait RecursionItem {
8576
/// Parse the item into a requirement or a reference to other groups.
8677
fn parse<'a>(&'a self, name: Option<&str>) -> Item<'a>;
8778
/// The name of the group in the TOML file.
@@ -90,7 +81,7 @@ pub trait RecursionItem {
9081
fn table_name() -> String;
9182
}
9283

93-
pub enum Item<'a> {
84+
pub(crate) enum Item<'a> {
9485
Requirement(Requirement),
9586
Groups(Vec<&'a str>),
9687
}

src/lib.rs

Lines changed: 3 additions & 25 deletions
Original file line numberDiff line numberDiff line change
@@ -120,17 +120,13 @@ impl Project {
120120
/// The `[project.optional-dependencies]` section of pyproject.toml
121121
#[derive(Serialize, Deserialize, Debug, Clone, PartialEq, Eq)]
122122
#[serde(transparent)]
123-
pub struct OptionalDependencies {
124-
pub inner: IndexMap<String, Vec<Requirement>>,
125-
#[serde(skip)]
126-
pub self_reference_name: Option<String>,
127-
}
123+
pub struct OptionalDependencies(pub IndexMap<String, Vec<Requirement>>);
128124

129125
impl Deref for OptionalDependencies {
130126
type Target = IndexMap<String, Vec<Requirement>>;
131127

132128
fn deref(&self) -> &Self::Target {
133-
&self.inner
129+
&self.0
134130
}
135131
}
136132

@@ -247,17 +243,7 @@ pub enum DependencyGroupSpecifier {
247243
impl PyProjectToml {
248244
/// Parse `pyproject.toml` content
249245
pub fn new(content: &str) -> Result<Self, toml::de::Error> {
250-
let mut pyproject: PyProjectToml = toml::de::from_str(content)?;
251-
252-
// Set the project name as optional-dependencies self_reference_name
253-
if let Some(project) = pyproject.project.as_mut() {
254-
let name = project.name.clone();
255-
if let Some(od) = project.optional_dependencies.as_mut() {
256-
od.self_reference_name = Some(name);
257-
}
258-
}
259-
260-
Ok(pyproject)
246+
toml::de::from_str(content)
261247
}
262248
}
263249

@@ -366,14 +352,6 @@ tomatoes = "spam:main_tomatoes""#;
366352
project.gui_scripts.as_ref().unwrap()["spam-gui"],
367353
"spam:main_gui"
368354
);
369-
assert_eq!(
370-
project
371-
.optional_dependencies
372-
.as_ref()
373-
.unwrap()
374-
.self_reference_name,
375-
Some("spam".to_string())
376-
);
377355
}
378356

379357
#[test]

src/optional_dependencies_resolve.rs

Lines changed: 25 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -5,9 +5,22 @@ use crate::{
55
use indexmap::IndexMap;
66
use pep508_rs::Requirement;
77

8-
impl HasRecursion<Requirement> for OptionalDependencies {
9-
fn resolve(&self) -> Result<IndexMap<String, Vec<Requirement>>, RecursionResolutionError> {
10-
self.resolve_all(self.self_reference_name.as_deref())
8+
impl HasRecursion<Requirement> for OptionalDependencies {}
9+
10+
impl OptionalDependencies {
11+
/// Resolve the optional dependency groups into lists of requirements.
12+
///
13+
/// This function will recursively resolve all optional dependency groups, including those that
14+
/// reference other groups. It will return an error if there is a cycle in the
15+
/// groups or if a group references another group that does not exist.
16+
///
17+
/// `self_reference_name` is the name of the project itself, which is used to identify self-references
18+
/// in the optional dependencies. If None, self-references will be treated as normal dependencies.
19+
pub fn resolve(
20+
&self,
21+
self_reference_name: Option<&str>,
22+
) -> Result<IndexMap<String, Vec<Requirement>>, RecursionResolutionError> {
23+
self.resolve_all(self_reference_name)
1124
}
1225
}
1326

@@ -53,7 +66,7 @@ iota = ["spam[alpha]"]
5366
.unwrap();
5467

5568
assert_eq!(
56-
optional_dependencies.resolve().unwrap()["iota"],
69+
optional_dependencies.resolve(Some("spam")).unwrap()["iota"],
5770
vec![
5871
Requirement::from_str("beta").unwrap(),
5972
Requirement::from_str("gamma").unwrap(),
@@ -80,7 +93,10 @@ iota = ["spam[alpha]"]
8093
.as_ref()
8194
.unwrap();
8295
assert_eq!(
83-
optional_dependencies.resolve().unwrap_err().to_string(),
96+
optional_dependencies
97+
.resolve(Some("spam"))
98+
.unwrap_err()
99+
.to_string(),
84100
String::from(
85101
"Detected a cycle in `project.optional-dependencies`: `alpha` -> `iota` -> `alpha`"
86102
)
@@ -104,7 +120,10 @@ iota = ["spam[alpha]"]
104120
.as_ref()
105121
.unwrap();
106122
assert_eq!(
107-
optional_dependencies.resolve().unwrap_err().to_string(),
123+
optional_dependencies
124+
.resolve(Some("spam"))
125+
.unwrap_err()
126+
.to_string(),
108127
String::from("Failed to find optional dependency group `alpha` included by `iota`")
109128
)
110129
}

src/pep735_resolve.rs

Lines changed: 14 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,9 +1,22 @@
1-
use crate::has_recursion::{HasRecursion, Item, RecursionItem};
1+
use indexmap::IndexMap;
2+
use pep508_rs::Requirement;
3+
4+
use crate::has_recursion::{HasRecursion, Item, RecursionItem, RecursionResolutionError};
25

36
use crate::{DependencyGroupSpecifier, DependencyGroups};
47

58
impl HasRecursion<DependencyGroupSpecifier> for DependencyGroups {}
69

10+
impl DependencyGroups {
11+
/// Resolve the dependency groups into lists of requirements.
12+
///
13+
/// This function will recursively resolve all dependency groups, including those that
14+
/// reference other groups. It will return an error if there is a cycle in the
15+
/// groups or if a group references another group that does not exist.
16+
pub fn resolve(&self) -> Result<IndexMap<String, Vec<Requirement>>, RecursionResolutionError> {
17+
self.resolve_all(None)
18+
}
19+
}
720
impl RecursionItem for DependencyGroupSpecifier {
821
fn parse(&self, _name: Option<&str>) -> Item {
922
match self {

0 commit comments

Comments
 (0)