Skip to content

Commit

Permalink
Make --no-default-groups works with --all-groups
Browse files Browse the repository at this point in the history
  • Loading branch information
j178 committed Jan 23, 2025
1 parent a0620bc commit 26f70b0
Show file tree
Hide file tree
Showing 3 changed files with 66 additions and 55 deletions.
24 changes: 12 additions & 12 deletions crates/uv-cli/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -2778,7 +2778,7 @@ pub struct RunArgs {
/// Include dependencies from the specified dependency group.
///
/// May be provided multiple times.
#[arg(long, conflicts_with("only_group"))]
#[arg(long, conflicts_with_all = ["only_group", "all_groups"])]
pub group: Vec<GroupName>,

/// Exclude dependencies from the specified dependency group.
Expand All @@ -2790,7 +2790,7 @@ pub struct RunArgs {
/// Exclude dependencies from default groups.
///
/// `--group` can be used to include specific groups.
#[arg(long, conflicts_with_all = ["no_group", "only_group"])]
#[arg(long, conflicts_with_all = ["only_group"])]
pub no_default_groups: bool,

/// Only include dependencies from the specified dependency group.
Expand All @@ -2804,7 +2804,7 @@ pub struct RunArgs {
/// Include dependencies from all dependency groups.
///
/// `--no-group` can be used to exclude specific groups.
#[arg(long, conflicts_with_all = [ "group", "only_group" ])]
#[arg(long, conflicts_with_all = ["group", "only_group"])]
pub all_groups: bool,

/// Run a Python module.
Expand Down Expand Up @@ -3049,7 +3049,7 @@ pub struct SyncArgs {
/// `tool.uv.conflicts`, uv will report an error.
///
/// May be provided multiple times.
#[arg(long, conflicts_with("only_group"))]
#[arg(long, conflicts_with_all = ["only_group", "all_groups"])]
pub group: Vec<GroupName>,

/// Exclude dependencies from the specified dependency group.
Expand All @@ -3061,7 +3061,7 @@ pub struct SyncArgs {
/// Exclude dependencies from default groups.
///
/// `--group` can be used to include specific groups.
#[arg(long, conflicts_with_all = ["no_group", "only_group"])]
#[arg(long, conflicts_with_all = ["only_group"])]
pub no_default_groups: bool,

/// Only include dependencies from the specified dependency group.
Expand All @@ -3075,7 +3075,7 @@ pub struct SyncArgs {
/// Include dependencies from all dependency groups.
///
/// `--no-group` can be used to exclude specific groups.
#[arg(long, conflicts_with_all = [ "group", "only_group" ])]
#[arg(long, conflicts_with_all = ["group", "only_group"])]
pub all_groups: bool,

/// Install any editable dependencies, including the project and any workspace members, as
Expand Down Expand Up @@ -3500,7 +3500,7 @@ pub struct TreeArgs {
/// Include dependencies from the specified dependency group.
///
/// May be provided multiple times.
#[arg(long, conflicts_with("only_group"))]
#[arg(long, conflicts_with_all = ["only_group", "all_groups"])]
pub group: Vec<GroupName>,

/// Exclude dependencies from the specified dependency group.
Expand All @@ -3512,7 +3512,7 @@ pub struct TreeArgs {
/// Exclude dependencies from default groups.
///
/// `--group` can be used to include specific groups.
#[arg(long, conflicts_with_all = ["no_group", "only_group"])]
#[arg(long, conflicts_with_all = ["only_group"])]
pub no_default_groups: bool,

/// Only include dependencies from the specified dependency group.
Expand All @@ -3526,7 +3526,7 @@ pub struct TreeArgs {
/// Include dependencies from all dependency groups.
///
/// `--no-group` can be used to exclude specific groups.
#[arg(long, conflicts_with_all = [ "group", "only_group" ])]
#[arg(long, conflicts_with_all = ["group", "only_group"])]
pub all_groups: bool,

/// Assert that the `uv.lock` will remain unchanged.
Expand Down Expand Up @@ -3670,7 +3670,7 @@ pub struct ExportArgs {
/// Include dependencies from the specified dependency group.
///
/// May be provided multiple times.
#[arg(long, conflicts_with("only_group"))]
#[arg(long, conflicts_with_all = ["only_group", "all_groups"])]
pub group: Vec<GroupName>,

/// Exclude dependencies from the specified dependency group.
Expand All @@ -3682,7 +3682,7 @@ pub struct ExportArgs {
/// Exclude dependencies from default groups.
///
/// `--group` can be used to include specific groups.
#[arg(long, conflicts_with_all = ["no_group", "only_group"])]
#[arg(long, conflicts_with_all = ["only_group"])]
pub no_default_groups: bool,

/// Only include dependencies from the specified dependency group.
Expand All @@ -3696,7 +3696,7 @@ pub struct ExportArgs {
/// Include dependencies from all dependency groups.
///
/// `--no-group` can be used to exclude specific groups.
#[arg(long, conflicts_with_all = [ "group", "only_group" ])]
#[arg(long, conflicts_with_all = ["group", "only_group"])]
pub all_groups: bool,

/// Exclude the comment header at the top of the generated output file.
Expand Down
95 changes: 53 additions & 42 deletions crates/uv-configuration/src/dev.rs
Original file line number Diff line number Diff line change
@@ -1,7 +1,5 @@
use std::borrow::Cow;

use either::Either;

use uv_normalize::{GroupName, DEV_DEPENDENCIES};

#[derive(Debug, Default, Clone, Copy, PartialEq, Eq)]
Expand Down Expand Up @@ -67,11 +65,8 @@ pub enum GroupsSpecification {
Include {
include: IncludeGroups,
exclude: Vec<GroupName>,
no_default_groups: bool,
},
/// Include dependencies from the specified groups, omitting any default groups.
///
/// If the list is empty, no group will be included.
Explicit { include: Vec<GroupName> },
/// Only include dependencies from the specified groups, exclude all other dependencies.
///
/// The `include` list is guaranteed to omit groups in the `exclude` list (i.e., they have an
Expand All @@ -88,12 +83,13 @@ impl GroupsSpecification {
Self::Include {
include: IncludeGroups::Some(vec![group]),
exclude: Vec::new(),
no_default_groups: false,
}
}

/// Returns `true` if the specification allows for production dependencies.
pub fn prod(&self) -> bool {
matches!(self, Self::Include { .. } | Self::Explicit { .. })
matches!(self, Self::Include { .. })
}

/// Returns `true` if the specification is limited to a select set of groups.
Expand All @@ -104,7 +100,9 @@ impl GroupsSpecification {
/// Returns the option that was used to request the groups, if any.
pub fn as_flag(&self) -> Option<Cow<'_, str>> {
match self {
Self::Include { include, exclude } => match include {
Self::Include {
include, exclude, ..
} => match include {
IncludeGroups::All => Some(Cow::Borrowed("--all-groups")),
IncludeGroups::Some(groups) => match groups.as_slice() {
[] => match exclude.as_slice() {
Expand All @@ -125,36 +123,34 @@ impl GroupsSpecification {
[group] => Some(Cow::Owned(format!("--only-group {group}"))),
[..] => Some(Cow::Borrowed("--only-group")),
},
Self::Explicit { include } => match include.as_slice() {
[] => Some(Cow::Borrowed("--no-default-groups")),
[group] => Some(Cow::Owned(format!("--group {group}"))),
[..] => Some(Cow::Borrowed("--group")),
},
}
}

/// Iterate over all groups referenced in the [`GroupsSpecification`].
pub fn names(&self) -> impl Iterator<Item = &GroupName> {
match self {
GroupsSpecification::Include { include, exclude } => {
Either::Left(include.names().chain(exclude.iter()))
}
GroupsSpecification::Only { include, exclude } => {
Either::Left(include.iter().chain(exclude.iter()))
}
GroupsSpecification::Explicit { include } => Either::Right(include.iter()),
GroupsSpecification::Include {
include, exclude, ..
} => include.names().chain(exclude.iter()),
GroupsSpecification::Only { include, exclude } => include.iter().chain(exclude.iter()),
}
}

/// Returns `true` if the specification includes the given group.
pub fn contains(&self, group: &GroupName) -> bool {
pub fn contains(&self, group: &GroupName, is_default_group: bool) -> bool {
match self {
GroupsSpecification::Include { include, exclude } => {
GroupsSpecification::Include {
include,
exclude,
no_default_groups,
} => {
if *no_default_groups && is_default_group {
return false;
}
// For `--all-groups`, the group is included unless it is explicitly excluded.
include.contains(group) && !exclude.contains(group)
}
GroupsSpecification::Only { include, .. } => include.contains(group),
GroupsSpecification::Explicit { include } => include.contains(group),
}
}

Expand All @@ -163,6 +159,7 @@ impl GroupsSpecification {
let GroupsSpecification::Include {
include: IncludeGroups::Some(includes),
exclude,
..
} = self
else {
return false;
Expand Down Expand Up @@ -220,15 +217,11 @@ impl DevGroupsSpecification {
None
};

let groups = if no_default_groups {
// Remove groups specified with `--no-group`.
group.retain(|group| !no_group.contains(group));

Some(GroupsSpecification::Explicit { include: group })
} else if all_groups {
let groups = if all_groups {
Some(GroupsSpecification::Include {
include: IncludeGroups::All,
exclude: no_group,
no_default_groups,
})
} else if !group.is_empty() {
if matches!(dev, Some(DevMode::Only)) {
Expand All @@ -241,6 +234,7 @@ impl DevGroupsSpecification {
Some(GroupsSpecification::Include {
include: IncludeGroups::Some(group),
exclude: no_group,
no_default_groups,
})
} else if !only_group.is_empty() {
if matches!(dev, Some(DevMode::Include)) {
Expand All @@ -258,6 +252,13 @@ impl DevGroupsSpecification {
Some(GroupsSpecification::Include {
include: IncludeGroups::Some(Vec::new()),
exclude: no_group,
no_default_groups,
})
} else if no_default_groups {
Some(GroupsSpecification::Include {
include: IncludeGroups::Some(Vec::new()),
exclude: Vec::new(),
no_default_groups,
})
} else {
None
Expand Down Expand Up @@ -300,7 +301,7 @@ impl DevGroupsSpecification {
}

/// Returns `true` if the group is included in the specification.
pub fn contains(&self, group: &GroupName) -> bool {
pub fn contains(&self, group: &GroupName, is_default_group: bool) -> bool {
if group == &*DEV_DEPENDENCIES {
match self.dev.as_ref() {
None => {}
Expand All @@ -315,7 +316,14 @@ impl DevGroupsSpecification {
Some(DevMode::Include) => {
// If `--no-group dev` was provided, exclude dev.
return match self.groups.as_ref() {
Some(GroupsSpecification::Include { exclude, .. }) => {
Some(GroupsSpecification::Include {
exclude,
no_default_groups,
..
}) => {
if *no_default_groups && is_default_group {
return false;
}
!exclude.contains(group)
}
_ => true,
Expand All @@ -326,7 +334,7 @@ impl DevGroupsSpecification {

self.groups
.as_ref()
.is_some_and(|groups| groups.contains(group))
.is_some_and(|groups| groups.contains(group, is_default_group))
}

/// Returns `true` if the specification will have no effect.
Expand Down Expand Up @@ -393,7 +401,7 @@ impl DevGroupsManifest {

/// Returns `true` if the group was enabled by default.
pub fn is_default(&self, group: &GroupName) -> bool {
if self.spec.contains(group) {
if self.spec.contains(group, false) {
// If the group was explicitly requested, then it wasn't enabled by default.
false
} else {
Expand All @@ -405,7 +413,7 @@ impl DevGroupsManifest {

/// Returns `true` if the group is included in the manifest.
pub fn contains(&self, group: &GroupName) -> bool {
if self.spec.contains(group) {
if self.spec.contains(group, self.defaults.contains(group)) {
return true;
}
if self.spec.only() {
Expand All @@ -421,18 +429,21 @@ impl DevGroupsManifest {
};
}

// If `--no-default-groups` was provided, only include group if it's explicitly
// included with `--group <group>`.
if let Some(GroupsSpecification::Explicit { include }) = self.spec.groups() {
return include.contains(group);
}

// If `--no-group` was provided, exclude the group from the list of defaults.
if let Some(GroupsSpecification::Include {
include: _,
include,
exclude,
no_default_groups,
}) = self.spec.groups()
{
// If `--no-default-groups` was provided, only include group if it's explicitly
// included with `--group <group>`.
if *no_default_groups {
if let IncludeGroups::Some(include) = include {
return include.contains(group);
}
return false;
}
// If `--no-group` was provided, exclude the group from the list of defaults.
if exclude.contains(default) {
return false;
}
Expand Down
2 changes: 1 addition & 1 deletion crates/uv-requirements/src/source_tree.rs
Original file line number Diff line number Diff line change
Expand Up @@ -111,7 +111,7 @@ impl<'a, Context: BuildContext> SourceTreeResolver<'a, Context> {

// Apply dependency-groups
for (group_name, group) in &metadata.dependency_groups {
if self.groups.contains(group_name) {
if self.groups.contains(group_name, false) {
requirements.extend(group.iter().cloned());
}
}
Expand Down

0 comments on commit 26f70b0

Please sign in to comment.