mirror of
https://github.com/astral-sh/uv.git
synced 2025-07-24 13:43:45 +00:00
Model groups as a property of requirements (#9545)
## Summary Today, our dependency group implementation is a little awkward... For each package `P`, we check if `P` contains dependencies for each enabled group, then add a dependency on `P` with the group enabled. There are a few issues here: 1. It's sort of backwards... We add a dependency from the base package `P` to `P` with the group enabled. Then `P` with the group enabled adds a dependency on the base package. 2. We can't, e.g., enable different groups for different packages. (We don't have a way for users to specify this on the CLI, but there's no reason that it should be _impossible_ in the resolver.) 3. It's inconsistent with how extras work, which leads to confusing differences in the resolver. Instead, our internal requirement type can now include dependency groups, which makes dependency groups look much, much more like extras in the resolver.
This commit is contained in:
parent
7d1308876e
commit
1ecdc1a31e
22 changed files with 180 additions and 146 deletions
|
@ -287,6 +287,63 @@ impl Workspace {
|
|||
Some(Requirement {
|
||||
name: member.pyproject_toml.project.as_ref()?.name.clone(),
|
||||
extras: vec![],
|
||||
groups: vec![],
|
||||
marker: MarkerTree::TRUE,
|
||||
source: if member.pyproject_toml.is_package() {
|
||||
RequirementSource::Directory {
|
||||
install_path: member.root.clone(),
|
||||
editable: true,
|
||||
r#virtual: false,
|
||||
url,
|
||||
}
|
||||
} else {
|
||||
RequirementSource::Directory {
|
||||
install_path: member.root.clone(),
|
||||
editable: false,
|
||||
r#virtual: true,
|
||||
url,
|
||||
}
|
||||
},
|
||||
origin: None,
|
||||
})
|
||||
})
|
||||
}
|
||||
|
||||
/// Returns the set of requirements that include all packages in the workspace.
|
||||
pub fn group_requirements(&self) -> impl Iterator<Item = Requirement> + '_ {
|
||||
self.packages.values().filter_map(|member| {
|
||||
let url = VerbatimUrl::from_absolute_path(&member.root)
|
||||
.expect("path is valid URL")
|
||||
.with_given(member.root.to_string_lossy());
|
||||
|
||||
let groups = {
|
||||
let mut groups = member
|
||||
.pyproject_toml
|
||||
.dependency_groups
|
||||
.as_ref()
|
||||
.map(|groups| groups.keys().cloned().collect::<Vec<_>>())
|
||||
.unwrap_or_default();
|
||||
if member
|
||||
.pyproject_toml
|
||||
.tool
|
||||
.as_ref()
|
||||
.and_then(|tool| tool.uv.as_ref())
|
||||
.and_then(|uv| uv.dev_dependencies.as_ref())
|
||||
.is_some()
|
||||
{
|
||||
groups.push(DEV_DEPENDENCIES.clone());
|
||||
groups.sort_unstable();
|
||||
}
|
||||
groups
|
||||
};
|
||||
if groups.is_empty() {
|
||||
return None;
|
||||
}
|
||||
|
||||
Some(Requirement {
|
||||
name: member.pyproject_toml.project.as_ref()?.name.clone(),
|
||||
extras: vec![],
|
||||
groups,
|
||||
marker: MarkerTree::TRUE,
|
||||
source: if member.pyproject_toml.is_package() {
|
||||
RequirementSource::Directory {
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue