mirror of
https://github.com/astral-sh/uv.git
synced 2025-08-04 10:58:28 +00:00
Store dependency groups separate from dependencies in lockfile (#10148)
## Summary This is necessary for some future improvements to non-`[project]` workspaces and PEP 723 scripts. It's not "breaking", but it will invalidate lockfiles for non-`[project]` workspaces. I think that's okay, since we consider those legacy right now, and they're really rare.
This commit is contained in:
parent
3435777e87
commit
e09b1080f4
21 changed files with 346 additions and 154 deletions
|
@ -12,7 +12,7 @@ use uv_pypi_types::VerbatimParsedUrl;
|
|||
use crate::pyproject::DependencyGroupSpecifier;
|
||||
|
||||
/// PEP 735 dependency groups, with any `include-group` entries resolved.
|
||||
#[derive(Debug, Clone)]
|
||||
#[derive(Debug, Default, Clone)]
|
||||
pub struct FlatDependencyGroups(
|
||||
BTreeMap<GroupName, Vec<uv_pep508::Requirement<VerbatimParsedUrl>>>,
|
||||
);
|
||||
|
@ -104,12 +104,30 @@ impl FlatDependencyGroups {
|
|||
self.0.get(group)
|
||||
}
|
||||
|
||||
/// Return the entry for a given group, if any.
|
||||
pub fn entry(
|
||||
&mut self,
|
||||
group: GroupName,
|
||||
) -> Entry<GroupName, Vec<uv_pep508::Requirement<VerbatimParsedUrl>>> {
|
||||
self.0.entry(group)
|
||||
}
|
||||
|
||||
/// Consume the [`FlatDependencyGroups`] and return the inner map.
|
||||
pub fn into_inner(self) -> BTreeMap<GroupName, Vec<uv_pep508::Requirement<VerbatimParsedUrl>>> {
|
||||
self.0
|
||||
}
|
||||
}
|
||||
|
||||
impl FromIterator<(GroupName, Vec<uv_pep508::Requirement<VerbatimParsedUrl>>)>
|
||||
for FlatDependencyGroups
|
||||
{
|
||||
fn from_iter<
|
||||
T: IntoIterator<Item = (GroupName, Vec<uv_pep508::Requirement<VerbatimParsedUrl>>)>,
|
||||
>(
|
||||
iter: T,
|
||||
) -> Self {
|
||||
Self(iter.into_iter().collect())
|
||||
}
|
||||
}
|
||||
|
||||
impl IntoIterator for FlatDependencyGroups {
|
||||
|
|
|
@ -386,13 +386,24 @@ impl Workspace {
|
|||
/// Returns any requirements that are exclusive to the workspace root, i.e., not included in
|
||||
/// any of the workspace members.
|
||||
///
|
||||
/// For workspaces with non-project roots, returns the dev dependencies in the corresponding
|
||||
/// `pyproject.toml`.
|
||||
/// For now, there are no such requirements.
|
||||
pub fn requirements(&self) -> Vec<uv_pep508::Requirement<VerbatimParsedUrl>> {
|
||||
Vec::new()
|
||||
}
|
||||
|
||||
/// Returns any dependency groups that are exclusive to the workspace root, i.e., not included
|
||||
/// in any of the workspace members.
|
||||
///
|
||||
/// For workspaces with non-`[project]` roots, returns the dependency groups defined in the
|
||||
/// corresponding `pyproject.toml`.
|
||||
///
|
||||
/// Otherwise, returns an empty list.
|
||||
pub fn non_project_requirements(
|
||||
pub fn dependency_groups(
|
||||
&self,
|
||||
) -> Result<Vec<uv_pep508::Requirement<VerbatimParsedUrl>>, DependencyGroupError> {
|
||||
) -> Result<
|
||||
BTreeMap<GroupName, Vec<uv_pep508::Requirement<VerbatimParsedUrl>>>,
|
||||
DependencyGroupError,
|
||||
> {
|
||||
if self
|
||||
.packages
|
||||
.values()
|
||||
|
@ -400,7 +411,7 @@ impl Workspace {
|
|||
{
|
||||
// If the workspace has an explicit root, the root is a member, so we don't need to
|
||||
// include any root-only requirements.
|
||||
Ok(Vec::new())
|
||||
Ok(BTreeMap::default())
|
||||
} else {
|
||||
// Otherwise, return the dependency groups in the non-project workspace root.
|
||||
// First, collect `tool.uv.dev_dependencies`
|
||||
|
@ -419,19 +430,20 @@ impl Workspace {
|
|||
.flatten()
|
||||
.collect::<BTreeMap<_, _>>();
|
||||
|
||||
// Resolve any `include-group` entries in `dependency-groups`.
|
||||
let dependency_groups =
|
||||
// Flatten the dependency groups.
|
||||
let mut dependency_groups =
|
||||
FlatDependencyGroups::from_dependency_groups(&dependency_groups)
|
||||
.map_err(|err| err.with_dev_dependencies(dev_dependencies))?;
|
||||
|
||||
// Concatenate the two sets of requirements.
|
||||
let dev_dependencies = dependency_groups
|
||||
.into_iter()
|
||||
.flat_map(|(_, requirements)| requirements)
|
||||
.chain(dev_dependencies.into_iter().flatten().cloned())
|
||||
.collect();
|
||||
// Add the `dev` group, if `dev-dependencies` is defined.
|
||||
if let Some(dev_dependencies) = dev_dependencies {
|
||||
dependency_groups
|
||||
.entry(DEV_DEPENDENCIES.clone())
|
||||
.or_insert_with(Vec::new)
|
||||
.extend(dev_dependencies.clone());
|
||||
}
|
||||
|
||||
Ok(dev_dependencies)
|
||||
Ok(dependency_groups.into_inner())
|
||||
}
|
||||
}
|
||||
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue