Skip to content

Commit f3318be

Browse files
committed
Add --group and --only-group to uv run
1 parent ec9bfa6 commit f3318be

File tree

6 files changed

+253
-21
lines changed

6 files changed

+253
-21
lines changed

crates/uv-cli/src/lib.rs

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2611,6 +2611,20 @@ pub struct RunArgs {
26112611
#[arg(long, overrides_with("dev"))]
26122612
pub no_dev: bool,
26132613

2614+
/// Include dependencies from the specified local dependency group.
2615+
///
2616+
/// May be provided multiple times.
2617+
#[arg(long, conflicts_with("only_group"))]
2618+
pub group: Vec<GroupName>,
2619+
2620+
/// Only include dependencies from the specified local dependency group.
2621+
///
2622+
/// May be provided multiple times.
2623+
///
2624+
/// The project itself will also be omitted.
2625+
#[arg(long, conflicts_with("group"))]
2626+
pub only_group: Vec<GroupName>,
2627+
26142628
/// Run a Python module.
26152629
///
26162630
/// Equivalent to `python -m <module>`.

crates/uv-configuration/src/dev.rs

Lines changed: 25 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,5 @@
1+
use std::borrow::Cow;
2+
13
use either::Either;
24
use uv_normalize::{GroupName, DEV_DEPENDENCIES};
35

@@ -50,6 +52,29 @@ impl DevSpecification {
5052
pub fn prod(&self) -> bool {
5153
matches!(self, Self::Exclude | Self::Include(_))
5254
}
55+
56+
/// Returns the name of the flag that was used to request dev dependencies, if any.
57+
pub fn as_flag(&self) -> Option<Cow<'_, str>> {
58+
match self {
59+
Self::Exclude => None,
60+
Self::Include(groups) => match groups.as_slice() {
61+
[] => None,
62+
[group] if *group == *DEV_DEPENDENCIES => {
63+
Some(Cow::Borrowed("`--group dev` or `--dev`"))
64+
}
65+
[group] => Some(Cow::Owned(format!("`--group {group}`"))),
66+
[..] => Some(Cow::Borrowed("`--group`")),
67+
},
68+
Self::Only(groups) => match groups.as_slice() {
69+
[] => None,
70+
[group] if *group == *DEV_DEPENDENCIES => {
71+
Some(Cow::Borrowed("`--only-group dev` or `--only-dev`"))
72+
}
73+
[group] => Some(Cow::Owned(format!("`--only-group {group}`"))),
74+
[..] => Some(Cow::Borrowed("`--only-group`")),
75+
},
76+
}
77+
}
5378
}
5479

5580
impl From<DevMode> for DevSpecification {

crates/uv/src/commands/project/run.rs

Lines changed: 10 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -17,8 +17,8 @@ use uv_cache::Cache;
1717
use uv_cli::ExternalCommand;
1818
use uv_client::{BaseClientBuilder, Connectivity};
1919
use uv_configuration::{
20-
Concurrency, DevMode, DevSpecification, EditableMode, ExtrasSpecification, InstallOptions,
21-
LowerBound, SourceStrategy,
20+
Concurrency, DevSpecification, EditableMode, ExtrasSpecification, InstallOptions, LowerBound,
21+
SourceStrategy,
2222
};
2323
use uv_distribution::LoweredRequirement;
2424
use uv_fs::which::is_executable;
@@ -68,7 +68,7 @@ pub(crate) async fn run(
6868
no_project: bool,
6969
no_config: bool,
7070
extras: ExtrasSpecification,
71-
dev: DevMode,
71+
dev: DevSpecification,
7272
editable: EditableMode,
7373
python: Option<String>,
7474
settings: ResolverInstallerSettings,
@@ -336,11 +336,8 @@ pub(crate) async fn run(
336336
if !extras.is_empty() {
337337
warn_user!("Extras are not supported for Python scripts with inline metadata");
338338
}
339-
if matches!(dev, DevMode::Exclude) {
340-
warn_user!("`--no-dev` is not supported for Python scripts with inline metadata");
341-
}
342-
if matches!(dev, DevMode::Only) {
343-
warn_user!("`--only-dev` is not supported for Python scripts with inline metadata");
339+
if let Some(flag) = dev.as_flag() {
340+
warn_user!("{flag} is not supported for Python scripts with inline metadata");
344341
}
345342
if package.is_some() {
346343
warn_user!(
@@ -413,11 +410,8 @@ pub(crate) async fn run(
413410
if !extras.is_empty() {
414411
warn_user!("Extras have no effect when used alongside `--no-project`");
415412
}
416-
if matches!(dev, DevMode::Exclude) {
417-
warn_user!("`--no-dev` has no effect when used alongside `--no-project`");
418-
}
419-
if matches!(dev, DevMode::Only) {
420-
warn_user!("`--only-dev` has no effect when used alongside `--no-project`");
413+
if let Some(flag) = dev.as_flag() {
414+
warn_user!("{flag} has no effect when used alongside `--no-project`");
421415
}
422416
if locked {
423417
warn_user!("`--locked` has no effect when used alongside `--no-project`");
@@ -433,11 +427,8 @@ pub(crate) async fn run(
433427
if !extras.is_empty() {
434428
warn_user!("Extras have no effect when used outside of a project");
435429
}
436-
if matches!(dev, DevMode::Exclude) {
437-
warn_user!("`--no-dev` has no effect when used outside of a project");
438-
}
439-
if matches!(dev, DevMode::Only) {
440-
warn_user!("`--only-dev` has no effect when used outside of a project");
430+
if let Some(flag) = dev.as_flag() {
431+
warn_user!("{flag} has no when used outside of a project");
441432
}
442433
if locked {
443434
warn_user!("`--locked` has no effect when used outside of a project");
@@ -590,7 +581,7 @@ pub(crate) async fn run(
590581
&venv,
591582
result.lock(),
592583
&extras,
593-
&DevSpecification::from(dev),
584+
&dev,
594585
editable,
595586
install_options,
596587
Modifications::Sufficient,

crates/uv/src/settings.rs

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -227,7 +227,7 @@ pub(crate) struct RunSettings {
227227
pub(crate) locked: bool,
228228
pub(crate) frozen: bool,
229229
pub(crate) extras: ExtrasSpecification,
230-
pub(crate) dev: DevMode,
230+
pub(crate) dev: DevSpecification,
231231
pub(crate) editable: EditableMode,
232232
pub(crate) with: Vec<String>,
233233
pub(crate) with_editable: Vec<String>,
@@ -252,6 +252,8 @@ impl RunSettings {
252252
no_all_extras,
253253
dev,
254254
no_dev,
255+
group,
256+
only_group,
255257
module: _,
256258
only_dev,
257259
no_editable,
@@ -280,7 +282,7 @@ impl RunSettings {
280282
flag(all_extras, no_all_extras).unwrap_or_default(),
281283
extra.unwrap_or_default(),
282284
),
283-
dev: DevMode::from_args(dev, no_dev, only_dev),
285+
dev: DevSpecification::from_args(dev, no_dev, only_dev, group, only_group),
284286
editable: EditableMode::from_args(no_editable),
285287
with,
286288
with_editable,

0 commit comments

Comments
 (0)