mirror of https://github.com/astral-sh/uv
Add `--no-group` support to CLI (#8477)
## Summary Now that `default-groups` can include more than just `"dev"`, it makes sense to allow users to remove groups with `--no-group`.
This commit is contained in:
parent
291c4c496d
commit
810b430031
|
|
@ -2617,6 +2617,12 @@ pub struct RunArgs {
|
||||||
#[arg(long, conflicts_with("only_group"))]
|
#[arg(long, conflicts_with("only_group"))]
|
||||||
pub group: Vec<GroupName>,
|
pub group: Vec<GroupName>,
|
||||||
|
|
||||||
|
/// Exclude dependencies from the specified local dependency group.
|
||||||
|
///
|
||||||
|
/// May be provided multiple times.
|
||||||
|
#[arg(long)]
|
||||||
|
pub no_group: Vec<GroupName>,
|
||||||
|
|
||||||
/// Only include dependencies from the specified local dependency group.
|
/// Only include dependencies from the specified local dependency group.
|
||||||
///
|
///
|
||||||
/// May be provided multiple times.
|
/// May be provided multiple times.
|
||||||
|
|
@ -2808,6 +2814,12 @@ pub struct SyncArgs {
|
||||||
#[arg(long, conflicts_with("only_group"))]
|
#[arg(long, conflicts_with("only_group"))]
|
||||||
pub group: Vec<GroupName>,
|
pub group: Vec<GroupName>,
|
||||||
|
|
||||||
|
/// Exclude dependencies from the specified local dependency group.
|
||||||
|
///
|
||||||
|
/// May be provided multiple times.
|
||||||
|
#[arg(long)]
|
||||||
|
pub no_group: Vec<GroupName>,
|
||||||
|
|
||||||
/// Only include dependencies from the specified local dependency group.
|
/// Only include dependencies from the specified local dependency group.
|
||||||
///
|
///
|
||||||
/// May be provided multiple times.
|
/// May be provided multiple times.
|
||||||
|
|
@ -3205,6 +3217,12 @@ pub struct TreeArgs {
|
||||||
#[arg(long, conflicts_with("only_group"))]
|
#[arg(long, conflicts_with("only_group"))]
|
||||||
pub group: Vec<GroupName>,
|
pub group: Vec<GroupName>,
|
||||||
|
|
||||||
|
/// Exclude dependencies from the specified local dependency group.
|
||||||
|
///
|
||||||
|
/// May be provided multiple times.
|
||||||
|
#[arg(long)]
|
||||||
|
pub no_group: Vec<GroupName>,
|
||||||
|
|
||||||
/// Only include dependencies from the specified local dependency group.
|
/// Only include dependencies from the specified local dependency group.
|
||||||
///
|
///
|
||||||
/// May be provided multiple times.
|
/// May be provided multiple times.
|
||||||
|
|
@ -3320,6 +3338,12 @@ pub struct ExportArgs {
|
||||||
#[arg(long, conflicts_with("only_group"))]
|
#[arg(long, conflicts_with("only_group"))]
|
||||||
pub group: Vec<GroupName>,
|
pub group: Vec<GroupName>,
|
||||||
|
|
||||||
|
/// Exclude dependencies from the specified local dependency group.
|
||||||
|
///
|
||||||
|
/// May be provided multiple times.
|
||||||
|
#[arg(long)]
|
||||||
|
pub no_group: Vec<GroupName>,
|
||||||
|
|
||||||
/// Only include dependencies from the specified local dependency group.
|
/// Only include dependencies from the specified local dependency group.
|
||||||
///
|
///
|
||||||
/// May be provided multiple times.
|
/// May be provided multiple times.
|
||||||
|
|
|
||||||
|
|
@ -68,38 +68,76 @@ pub struct DevGroupsSpecification {
|
||||||
#[derive(Debug, Clone)]
|
#[derive(Debug, Clone)]
|
||||||
pub enum GroupsSpecification {
|
pub enum GroupsSpecification {
|
||||||
/// Include dependencies from the specified groups.
|
/// Include dependencies from the specified groups.
|
||||||
Include(Vec<GroupName>),
|
///
|
||||||
|
/// The `include` list is guaranteed to omit groups in the `exclude` list (i.e., they have an
|
||||||
|
/// empty intersection).
|
||||||
|
Include {
|
||||||
|
include: Vec<GroupName>,
|
||||||
|
exclude: Vec<GroupName>,
|
||||||
|
},
|
||||||
/// Only include dependencies from the specified groups, exclude all other dependencies.
|
/// Only include dependencies from the specified groups, exclude all other dependencies.
|
||||||
Only(Vec<GroupName>),
|
///
|
||||||
|
/// The `include` list is guaranteed to omit groups in the `exclude` list (i.e., they have an
|
||||||
|
/// empty intersection).
|
||||||
|
Only {
|
||||||
|
include: Vec<GroupName>,
|
||||||
|
exclude: Vec<GroupName>,
|
||||||
|
},
|
||||||
}
|
}
|
||||||
|
|
||||||
impl GroupsSpecification {
|
impl GroupsSpecification {
|
||||||
|
/// Create a [`GroupsSpecification`] that includes the given group.
|
||||||
|
pub fn from_group(group: GroupName) -> Self {
|
||||||
|
Self::Include {
|
||||||
|
include: vec![group],
|
||||||
|
exclude: Vec::new(),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
/// Returns `true` if the specification allows for production dependencies.
|
/// Returns `true` if the specification allows for production dependencies.
|
||||||
pub fn prod(&self) -> bool {
|
pub fn prod(&self) -> bool {
|
||||||
matches!(self, Self::Include(_))
|
matches!(self, Self::Include { .. })
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Returns `true` if the specification is limited to a select set of groups.
|
/// Returns `true` if the specification is limited to a select set of groups.
|
||||||
pub fn only(&self) -> bool {
|
pub fn only(&self) -> bool {
|
||||||
matches!(self, Self::Only(_))
|
matches!(self, Self::Only { .. })
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Returns the option that was used to request the groups, if any.
|
/// Returns the option that was used to request the groups, if any.
|
||||||
pub fn as_flag(&self) -> Option<Cow<'_, str>> {
|
pub fn as_flag(&self) -> Option<Cow<'_, str>> {
|
||||||
match self {
|
match self {
|
||||||
Self::Include(groups) => match groups.as_slice() {
|
Self::Include { include, exclude } => match include.as_slice() {
|
||||||
|
[] => match exclude.as_slice() {
|
||||||
[] => None,
|
[] => None,
|
||||||
|
[group] => Some(Cow::Owned(format!("--no-group {group}"))),
|
||||||
|
[..] => Some(Cow::Borrowed("--no-group")),
|
||||||
|
},
|
||||||
[group] => Some(Cow::Owned(format!("--group {group}"))),
|
[group] => Some(Cow::Owned(format!("--group {group}"))),
|
||||||
[..] => Some(Cow::Borrowed("--group")),
|
[..] => Some(Cow::Borrowed("--group")),
|
||||||
},
|
},
|
||||||
Self::Only(groups) => match groups.as_slice() {
|
Self::Only { include, exclude } => match include.as_slice() {
|
||||||
|
[] => match exclude.as_slice() {
|
||||||
[] => None,
|
[] => None,
|
||||||
|
[group] => Some(Cow::Owned(format!("--no-group {group}"))),
|
||||||
|
[..] => Some(Cow::Borrowed("--no-group")),
|
||||||
|
},
|
||||||
[group] => Some(Cow::Owned(format!("--only-group {group}"))),
|
[group] => Some(Cow::Owned(format!("--only-group {group}"))),
|
||||||
[..] => Some(Cow::Borrowed("--only-group")),
|
[..] => Some(Cow::Borrowed("--only-group")),
|
||||||
},
|
},
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// Iterate over all groups referenced in the [`DevGroupsSpecification`].
|
||||||
|
pub fn names(&self) -> impl Iterator<Item = &GroupName> {
|
||||||
|
match self {
|
||||||
|
GroupsSpecification::Include { include, exclude }
|
||||||
|
| GroupsSpecification::Only { include, exclude } => {
|
||||||
|
include.iter().chain(exclude.iter())
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
/// Iterate over the group names to include.
|
/// Iterate over the group names to include.
|
||||||
pub fn iter(&self) -> impl Iterator<Item = &GroupName> {
|
pub fn iter(&self) -> impl Iterator<Item = &GroupName> {
|
||||||
<&Self as IntoIterator>::into_iter(self)
|
<&Self as IntoIterator>::into_iter(self)
|
||||||
|
|
@ -112,9 +150,14 @@ impl<'a> IntoIterator for &'a GroupsSpecification {
|
||||||
|
|
||||||
fn into_iter(self) -> Self::IntoIter {
|
fn into_iter(self) -> Self::IntoIter {
|
||||||
match self {
|
match self {
|
||||||
GroupsSpecification::Include(groups) | GroupsSpecification::Only(groups) => {
|
GroupsSpecification::Include {
|
||||||
groups.iter()
|
include,
|
||||||
|
exclude: _,
|
||||||
}
|
}
|
||||||
|
| GroupsSpecification::Only {
|
||||||
|
include,
|
||||||
|
exclude: _,
|
||||||
|
} => include.iter(),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
@ -125,8 +168,9 @@ impl DevGroupsSpecification {
|
||||||
dev: bool,
|
dev: bool,
|
||||||
no_dev: bool,
|
no_dev: bool,
|
||||||
only_dev: bool,
|
only_dev: bool,
|
||||||
group: Vec<GroupName>,
|
mut group: Vec<GroupName>,
|
||||||
only_group: Vec<GroupName>,
|
no_group: Vec<GroupName>,
|
||||||
|
mut only_group: Vec<GroupName>,
|
||||||
) -> Self {
|
) -> Self {
|
||||||
let dev = if only_dev {
|
let dev = if only_dev {
|
||||||
Some(DevMode::Only)
|
Some(DevMode::Only)
|
||||||
|
|
@ -142,12 +186,31 @@ impl DevGroupsSpecification {
|
||||||
if matches!(dev, Some(DevMode::Only)) {
|
if matches!(dev, Some(DevMode::Only)) {
|
||||||
unreachable!("cannot specify both `--only-dev` and `--group`")
|
unreachable!("cannot specify both `--only-dev` and `--group`")
|
||||||
};
|
};
|
||||||
Some(GroupsSpecification::Include(group))
|
|
||||||
|
// Ensure that `--no-group` and `--group` are mutually exclusive.
|
||||||
|
group.retain(|group| !no_group.contains(group));
|
||||||
|
|
||||||
|
Some(GroupsSpecification::Include {
|
||||||
|
include: group,
|
||||||
|
exclude: no_group,
|
||||||
|
})
|
||||||
} else if !only_group.is_empty() {
|
} else if !only_group.is_empty() {
|
||||||
if matches!(dev, Some(DevMode::Include)) {
|
if matches!(dev, Some(DevMode::Include)) {
|
||||||
unreachable!("cannot specify both `--dev` and `--only-group`")
|
unreachable!("cannot specify both `--dev` and `--only-group`")
|
||||||
};
|
};
|
||||||
Some(GroupsSpecification::Only(only_group))
|
|
||||||
|
// Ensure that `--no-group` and `--only-group` are mutually exclusive.
|
||||||
|
only_group.retain(|group| !no_group.contains(group));
|
||||||
|
|
||||||
|
Some(GroupsSpecification::Only {
|
||||||
|
include: only_group,
|
||||||
|
exclude: no_group,
|
||||||
|
})
|
||||||
|
} else if !no_group.is_empty() {
|
||||||
|
Some(GroupsSpecification::Include {
|
||||||
|
include: Vec::new(),
|
||||||
|
exclude: no_group,
|
||||||
|
})
|
||||||
} else {
|
} else {
|
||||||
None
|
None
|
||||||
};
|
};
|
||||||
|
|
@ -270,8 +333,24 @@ impl DevGroupsManifest {
|
||||||
.iter()
|
.iter()
|
||||||
.chain(self.defaults.iter().filter(|default| {
|
.chain(self.defaults.iter().filter(|default| {
|
||||||
// If `--no-dev` was provided, exclude the `dev` group from the list of defaults.
|
// If `--no-dev` was provided, exclude the `dev` group from the list of defaults.
|
||||||
!matches!(self.spec.dev_mode(), Some(DevMode::Exclude))
|
if matches!(self.spec.dev_mode(), Some(DevMode::Exclude)) {
|
||||||
|| *default != &*DEV_DEPENDENCIES
|
if *default == &*DEV_DEPENDENCIES {
|
||||||
|
return false;
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
// If `--no-group` was provided, exclude the group from the list of defaults.
|
||||||
|
if let Some(GroupsSpecification::Include {
|
||||||
|
include: _,
|
||||||
|
exclude,
|
||||||
|
}) = self.spec.groups()
|
||||||
|
{
|
||||||
|
if exclude.contains(default) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
true
|
||||||
})),
|
})),
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -827,9 +827,7 @@ async fn lock_and_sync(
|
||||||
DependencyType::Group(ref group_name) => {
|
DependencyType::Group(ref group_name) => {
|
||||||
let extras = ExtrasSpecification::None;
|
let extras = ExtrasSpecification::None;
|
||||||
let dev =
|
let dev =
|
||||||
DevGroupsSpecification::from(GroupsSpecification::Include(
|
DevGroupsSpecification::from(GroupsSpecification::from_group(group_name.clone()));
|
||||||
vec![group_name.clone()],
|
|
||||||
));
|
|
||||||
(extras, dev)
|
(extras, dev)
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
|
||||||
|
|
@ -8,8 +8,8 @@ use tracing::debug;
|
||||||
use uv_cache::Cache;
|
use uv_cache::Cache;
|
||||||
use uv_client::{BaseClientBuilder, Connectivity, FlatIndexClient, RegistryClientBuilder};
|
use uv_client::{BaseClientBuilder, Connectivity, FlatIndexClient, RegistryClientBuilder};
|
||||||
use uv_configuration::{
|
use uv_configuration::{
|
||||||
Concurrency, Constraints, DevGroupsSpecification, ExtrasSpecification, LowerBound, Reinstall,
|
Concurrency, Constraints, DevGroupsSpecification, ExtrasSpecification, GroupsSpecification,
|
||||||
Upgrade,
|
LowerBound, Reinstall, Upgrade,
|
||||||
};
|
};
|
||||||
use uv_dispatch::BuildDispatch;
|
use uv_dispatch::BuildDispatch;
|
||||||
use uv_distribution::DistributionDatabase;
|
use uv_distribution::DistributionDatabase;
|
||||||
|
|
@ -1370,7 +1370,11 @@ pub(crate) fn validate_dependency_groups(
|
||||||
pyproject_toml: &PyProjectToml,
|
pyproject_toml: &PyProjectToml,
|
||||||
dev: &DevGroupsSpecification,
|
dev: &DevGroupsSpecification,
|
||||||
) -> Result<(), ProjectError> {
|
) -> Result<(), ProjectError> {
|
||||||
for group in dev.groups().into_iter().flatten() {
|
for group in dev
|
||||||
|
.groups()
|
||||||
|
.into_iter()
|
||||||
|
.flat_map(GroupsSpecification::names)
|
||||||
|
{
|
||||||
if !pyproject_toml
|
if !pyproject_toml
|
||||||
.dependency_groups
|
.dependency_groups
|
||||||
.as_ref()
|
.as_ref()
|
||||||
|
|
|
||||||
|
|
@ -253,6 +253,7 @@ impl RunSettings {
|
||||||
dev,
|
dev,
|
||||||
no_dev,
|
no_dev,
|
||||||
group,
|
group,
|
||||||
|
no_group,
|
||||||
only_group,
|
only_group,
|
||||||
module: _,
|
module: _,
|
||||||
only_dev,
|
only_dev,
|
||||||
|
|
@ -282,7 +283,9 @@ impl RunSettings {
|
||||||
flag(all_extras, no_all_extras).unwrap_or_default(),
|
flag(all_extras, no_all_extras).unwrap_or_default(),
|
||||||
extra.unwrap_or_default(),
|
extra.unwrap_or_default(),
|
||||||
),
|
),
|
||||||
dev: DevGroupsSpecification::from_args(dev, no_dev, only_dev, group, only_group),
|
dev: DevGroupsSpecification::from_args(
|
||||||
|
dev, no_dev, only_dev, group, no_group, only_group,
|
||||||
|
),
|
||||||
editable: EditableMode::from_args(no_editable),
|
editable: EditableMode::from_args(no_editable),
|
||||||
with,
|
with,
|
||||||
with_editable,
|
with_editable,
|
||||||
|
|
@ -718,6 +721,7 @@ impl SyncSettings {
|
||||||
only_dev,
|
only_dev,
|
||||||
group,
|
group,
|
||||||
only_group,
|
only_group,
|
||||||
|
no_group,
|
||||||
no_editable,
|
no_editable,
|
||||||
inexact,
|
inexact,
|
||||||
exact,
|
exact,
|
||||||
|
|
@ -745,7 +749,9 @@ impl SyncSettings {
|
||||||
flag(all_extras, no_all_extras).unwrap_or_default(),
|
flag(all_extras, no_all_extras).unwrap_or_default(),
|
||||||
extra.unwrap_or_default(),
|
extra.unwrap_or_default(),
|
||||||
),
|
),
|
||||||
dev: DevGroupsSpecification::from_args(dev, no_dev, only_dev, group, only_group),
|
dev: DevGroupsSpecification::from_args(
|
||||||
|
dev, no_dev, only_dev, group, no_group, only_group,
|
||||||
|
),
|
||||||
editable: EditableMode::from_args(no_editable),
|
editable: EditableMode::from_args(no_editable),
|
||||||
install_options: InstallOptions::new(
|
install_options: InstallOptions::new(
|
||||||
no_install_project,
|
no_install_project,
|
||||||
|
|
@ -1028,6 +1034,7 @@ impl TreeSettings {
|
||||||
only_dev,
|
only_dev,
|
||||||
no_dev,
|
no_dev,
|
||||||
group,
|
group,
|
||||||
|
no_group,
|
||||||
only_group,
|
only_group,
|
||||||
locked,
|
locked,
|
||||||
frozen,
|
frozen,
|
||||||
|
|
@ -1039,7 +1046,9 @@ impl TreeSettings {
|
||||||
} = args;
|
} = args;
|
||||||
|
|
||||||
Self {
|
Self {
|
||||||
dev: DevGroupsSpecification::from_args(dev, no_dev, only_dev, group, only_group),
|
dev: DevGroupsSpecification::from_args(
|
||||||
|
dev, no_dev, only_dev, group, no_group, only_group,
|
||||||
|
),
|
||||||
locked,
|
locked,
|
||||||
frozen,
|
frozen,
|
||||||
universal,
|
universal,
|
||||||
|
|
@ -1090,6 +1099,7 @@ impl ExportSettings {
|
||||||
no_dev,
|
no_dev,
|
||||||
only_dev,
|
only_dev,
|
||||||
group,
|
group,
|
||||||
|
no_group,
|
||||||
only_group,
|
only_group,
|
||||||
header,
|
header,
|
||||||
no_header,
|
no_header,
|
||||||
|
|
@ -1115,7 +1125,9 @@ impl ExportSettings {
|
||||||
flag(all_extras, no_all_extras).unwrap_or_default(),
|
flag(all_extras, no_all_extras).unwrap_or_default(),
|
||||||
extra.unwrap_or_default(),
|
extra.unwrap_or_default(),
|
||||||
),
|
),
|
||||||
dev: DevGroupsSpecification::from_args(dev, no_dev, only_dev, group, only_group),
|
dev: DevGroupsSpecification::from_args(
|
||||||
|
dev, no_dev, only_dev, group, no_group, only_group,
|
||||||
|
),
|
||||||
editable: EditableMode::from_args(no_editable),
|
editable: EditableMode::from_args(no_editable),
|
||||||
hashes: flag(hashes, no_hashes).unwrap_or(true),
|
hashes: flag(hashes, no_hashes).unwrap_or(true),
|
||||||
install_options: InstallOptions::new(
|
install_options: InstallOptions::new(
|
||||||
|
|
|
||||||
|
|
@ -1184,6 +1184,84 @@ fn sync_include_group() -> Result<()> {
|
||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn sync_exclude_group() -> Result<()> {
|
||||||
|
let context = TestContext::new("3.12");
|
||||||
|
|
||||||
|
let pyproject_toml = context.temp_dir.child("pyproject.toml");
|
||||||
|
pyproject_toml.write_str(
|
||||||
|
r#"
|
||||||
|
[project]
|
||||||
|
name = "project"
|
||||||
|
version = "0.1.0"
|
||||||
|
requires-python = ">=3.12"
|
||||||
|
dependencies = ["typing-extensions"]
|
||||||
|
|
||||||
|
[dependency-groups]
|
||||||
|
foo = ["anyio", {include-group = "bar"}]
|
||||||
|
bar = ["iniconfig"]
|
||||||
|
"#,
|
||||||
|
)?;
|
||||||
|
|
||||||
|
context.lock().assert().success();
|
||||||
|
|
||||||
|
uv_snapshot!(context.filters(), context.sync().arg("--group").arg("foo"), @r###"
|
||||||
|
success: true
|
||||||
|
exit_code: 0
|
||||||
|
----- stdout -----
|
||||||
|
|
||||||
|
----- stderr -----
|
||||||
|
Resolved 6 packages in [TIME]
|
||||||
|
Prepared 5 packages in [TIME]
|
||||||
|
Installed 5 packages in [TIME]
|
||||||
|
+ anyio==4.3.0
|
||||||
|
+ idna==3.6
|
||||||
|
+ iniconfig==2.0.0
|
||||||
|
+ sniffio==1.3.1
|
||||||
|
+ typing-extensions==4.10.0
|
||||||
|
"###);
|
||||||
|
|
||||||
|
uv_snapshot!(context.filters(), context.sync().arg("--group").arg("foo").arg("--no-group").arg("foo"), @r###"
|
||||||
|
success: true
|
||||||
|
exit_code: 0
|
||||||
|
----- stdout -----
|
||||||
|
|
||||||
|
----- stderr -----
|
||||||
|
Resolved 6 packages in [TIME]
|
||||||
|
Uninstalled 4 packages in [TIME]
|
||||||
|
- anyio==4.3.0
|
||||||
|
- idna==3.6
|
||||||
|
- iniconfig==2.0.0
|
||||||
|
- sniffio==1.3.1
|
||||||
|
"###);
|
||||||
|
|
||||||
|
uv_snapshot!(context.filters(), context.sync().arg("--only-group").arg("bar"), @r###"
|
||||||
|
success: true
|
||||||
|
exit_code: 0
|
||||||
|
----- stdout -----
|
||||||
|
|
||||||
|
----- stderr -----
|
||||||
|
Resolved 6 packages in [TIME]
|
||||||
|
Uninstalled 1 package in [TIME]
|
||||||
|
Installed 1 package in [TIME]
|
||||||
|
+ iniconfig==2.0.0
|
||||||
|
- typing-extensions==4.10.0
|
||||||
|
"###);
|
||||||
|
|
||||||
|
uv_snapshot!(context.filters(), context.sync().arg("--only-group").arg("bar").arg("--no-group").arg("bar"), @r###"
|
||||||
|
success: true
|
||||||
|
exit_code: 0
|
||||||
|
----- stdout -----
|
||||||
|
|
||||||
|
----- stderr -----
|
||||||
|
Resolved 6 packages in [TIME]
|
||||||
|
Uninstalled 1 package in [TIME]
|
||||||
|
- iniconfig==2.0.0
|
||||||
|
"###);
|
||||||
|
|
||||||
|
Ok(())
|
||||||
|
}
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
fn sync_dev_group() -> Result<()> {
|
fn sync_dev_group() -> Result<()> {
|
||||||
let context = TestContext::new("3.12");
|
let context = TestContext::new("3.12");
|
||||||
|
|
@ -1257,6 +1335,15 @@ fn sync_non_existent_group() -> Result<()> {
|
||||||
error: Group `baz` is not defined in the project's `dependency-group` table
|
error: Group `baz` is not defined in the project's `dependency-group` table
|
||||||
"###);
|
"###);
|
||||||
|
|
||||||
|
uv_snapshot!(context.filters(), context.sync().arg("--no-group").arg("baz"), @r###"
|
||||||
|
success: false
|
||||||
|
exit_code: 2
|
||||||
|
----- stdout -----
|
||||||
|
|
||||||
|
----- stderr -----
|
||||||
|
error: Group `baz` is not defined in the project's `dependency-group` table
|
||||||
|
"###);
|
||||||
|
|
||||||
// Requesting an empty group should succeed.
|
// Requesting an empty group should succeed.
|
||||||
uv_snapshot!(context.filters(), context.sync().arg("--group").arg("foo"), @r###"
|
uv_snapshot!(context.filters(), context.sync().arg("--group").arg("foo"), @r###"
|
||||||
success: true
|
success: true
|
||||||
|
|
@ -1407,6 +1494,38 @@ fn sync_default_groups() -> Result<()> {
|
||||||
+ sniffio==1.3.1
|
+ sniffio==1.3.1
|
||||||
"###);
|
"###);
|
||||||
|
|
||||||
|
// `--no-group` should remove from the defaults.
|
||||||
|
pyproject_toml.write_str(
|
||||||
|
r#"
|
||||||
|
[project]
|
||||||
|
name = "project"
|
||||||
|
version = "0.1.0"
|
||||||
|
requires-python = ">=3.12"
|
||||||
|
dependencies = ["typing-extensions"]
|
||||||
|
|
||||||
|
[dependency-groups]
|
||||||
|
dev = ["iniconfig"]
|
||||||
|
foo = ["anyio"]
|
||||||
|
bar = ["requests"]
|
||||||
|
|
||||||
|
[tool.uv]
|
||||||
|
default-groups = ["foo"]
|
||||||
|
"#,
|
||||||
|
)?;
|
||||||
|
|
||||||
|
uv_snapshot!(context.filters(), context.sync().arg("--no-group").arg("foo"), @r###"
|
||||||
|
success: true
|
||||||
|
exit_code: 0
|
||||||
|
----- stdout -----
|
||||||
|
|
||||||
|
----- stderr -----
|
||||||
|
Resolved 10 packages in [TIME]
|
||||||
|
Uninstalled 3 packages in [TIME]
|
||||||
|
- anyio==4.3.0
|
||||||
|
- idna==3.6
|
||||||
|
- sniffio==1.3.1
|
||||||
|
"###);
|
||||||
|
|
||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -286,6 +286,10 @@ uv run [OPTIONS] [COMMAND]
|
||||||
|
|
||||||
</dd><dt><code>--no-editable</code></dt><dd><p>Install any editable dependencies, including the project and any workspace members, as non-editable</p>
|
</dd><dt><code>--no-editable</code></dt><dd><p>Install any editable dependencies, including the project and any workspace members, as non-editable</p>
|
||||||
|
|
||||||
|
</dd><dt><code>--no-group</code> <i>no-group</i></dt><dd><p>Exclude dependencies from the specified local dependency group.</p>
|
||||||
|
|
||||||
|
<p>May be provided multiple times.</p>
|
||||||
|
|
||||||
</dd><dt><code>--no-index</code></dt><dd><p>Ignore the registry index (e.g., PyPI), instead relying on direct URL dependencies and those provided via <code>--find-links</code></p>
|
</dd><dt><code>--no-index</code></dt><dd><p>Ignore the registry index (e.g., PyPI), instead relying on direct URL dependencies and those provided via <code>--find-links</code></p>
|
||||||
|
|
||||||
</dd><dt><code>--no-progress</code></dt><dd><p>Hide all progress outputs.</p>
|
</dd><dt><code>--no-progress</code></dt><dd><p>Hide all progress outputs.</p>
|
||||||
|
|
@ -1539,6 +1543,10 @@ uv sync [OPTIONS]
|
||||||
|
|
||||||
</dd><dt><code>--no-editable</code></dt><dd><p>Install any editable dependencies, including the project and any workspace members, as non-editable</p>
|
</dd><dt><code>--no-editable</code></dt><dd><p>Install any editable dependencies, including the project and any workspace members, as non-editable</p>
|
||||||
|
|
||||||
|
</dd><dt><code>--no-group</code> <i>no-group</i></dt><dd><p>Exclude dependencies from the specified local dependency group.</p>
|
||||||
|
|
||||||
|
<p>May be provided multiple times.</p>
|
||||||
|
|
||||||
</dd><dt><code>--no-index</code></dt><dd><p>Ignore the registry index (e.g., PyPI), instead relying on direct URL dependencies and those provided via <code>--find-links</code></p>
|
</dd><dt><code>--no-index</code></dt><dd><p>Ignore the registry index (e.g., PyPI), instead relying on direct URL dependencies and those provided via <code>--find-links</code></p>
|
||||||
|
|
||||||
</dd><dt><code>--no-install-package</code> <i>no-install-package</i></dt><dd><p>Do not install the given package(s).</p>
|
</dd><dt><code>--no-install-package</code> <i>no-install-package</i></dt><dd><p>Do not install the given package(s).</p>
|
||||||
|
|
@ -2189,6 +2197,10 @@ uv export [OPTIONS]
|
||||||
|
|
||||||
<p>By default, all workspace members and their dependencies are included in the exported requirements file, with all of their dependencies. The <code>--no-emit-workspace</code> option allows exclusion of all the workspace members while retaining their dependencies.</p>
|
<p>By default, all workspace members and their dependencies are included in the exported requirements file, with all of their dependencies. The <code>--no-emit-workspace</code> option allows exclusion of all the workspace members while retaining their dependencies.</p>
|
||||||
|
|
||||||
|
</dd><dt><code>--no-group</code> <i>no-group</i></dt><dd><p>Exclude dependencies from the specified local dependency group.</p>
|
||||||
|
|
||||||
|
<p>May be provided multiple times.</p>
|
||||||
|
|
||||||
</dd><dt><code>--no-hashes</code></dt><dd><p>Omit hashes in the generated output</p>
|
</dd><dt><code>--no-hashes</code></dt><dd><p>Omit hashes in the generated output</p>
|
||||||
|
|
||||||
</dd><dt><code>--no-header</code></dt><dd><p>Exclude the comment header at the top of the generated output file</p>
|
</dd><dt><code>--no-header</code></dt><dd><p>Exclude the comment header at the top of the generated output file</p>
|
||||||
|
|
@ -2506,6 +2518,10 @@ uv tree [OPTIONS]
|
||||||
|
|
||||||
</dd><dt><code>--no-dev</code></dt><dd><p>Omit development dependencies</p>
|
</dd><dt><code>--no-dev</code></dt><dd><p>Omit development dependencies</p>
|
||||||
|
|
||||||
|
</dd><dt><code>--no-group</code> <i>no-group</i></dt><dd><p>Exclude dependencies from the specified local dependency group.</p>
|
||||||
|
|
||||||
|
<p>May be provided multiple times.</p>
|
||||||
|
|
||||||
</dd><dt><code>--no-index</code></dt><dd><p>Ignore the registry index (e.g., PyPI), instead relying on direct URL dependencies and those provided via <code>--find-links</code></p>
|
</dd><dt><code>--no-index</code></dt><dd><p>Ignore the registry index (e.g., PyPI), instead relying on direct URL dependencies and those provided via <code>--find-links</code></p>
|
||||||
|
|
||||||
</dd><dt><code>--no-progress</code></dt><dd><p>Hide all progress outputs.</p>
|
</dd><dt><code>--no-progress</code></dt><dd><p>Hide all progress outputs.</p>
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue