mirror of
https://github.com/astral-sh/uv.git
synced 2025-08-04 10:58:28 +00:00
fix handling of --all-groups
and --no-default-groups
flags (#11224)
This is a rewrite of the groups subsystem to have more clear semantics, and some adjustments to the CLI flag constraints. In doing so, the following bugs are fixed: * `--no-default-groups --no-group foo` is no longer needlessly rejected * `--all-groups --no-default-groups` now correctly evaluates to `--all-groups` where previously it was erroneously being interpretted as just `--no-default-groups` * `--all-groups --only-dev` is now illegal, where previously it was accepted and mishandled, as if it was a mythical `--only-all-groups` flag Fixes #10890 Closes #10891
This commit is contained in:
parent
311a96bd28
commit
72d9361ce1
12 changed files with 1198 additions and 605 deletions
|
@ -2702,7 +2702,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", "only_dev"])]
|
||||
pub group: Vec<GroupName>,
|
||||
|
||||
/// Exclude dependencies from the specified dependency group.
|
||||
|
@ -2714,7 +2714,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)]
|
||||
pub no_default_groups: bool,
|
||||
|
||||
/// Only include dependencies from the specified dependency group.
|
||||
|
@ -2722,13 +2722,13 @@ pub struct RunArgs {
|
|||
/// The project itself will also be omitted.
|
||||
///
|
||||
/// May be provided multiple times.
|
||||
#[arg(long, conflicts_with("group"))]
|
||||
#[arg(long, conflicts_with_all = ["group", "dev", "all_groups"])]
|
||||
pub only_group: Vec<GroupName>,
|
||||
|
||||
/// 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 = ["only_group", "only_dev"])]
|
||||
pub all_groups: bool,
|
||||
|
||||
/// Run a Python module.
|
||||
|
@ -2742,7 +2742,7 @@ pub struct RunArgs {
|
|||
/// Omit other dependencies. The project itself will also be omitted.
|
||||
///
|
||||
/// This option is an alias for `--only-group dev`.
|
||||
#[arg(long, conflicts_with("no_dev"))]
|
||||
#[arg(long, conflicts_with_all = ["group", "all_groups", "no_dev"])]
|
||||
pub only_dev: bool,
|
||||
|
||||
/// Install any editable dependencies, including the project and any workspace members, as
|
||||
|
@ -2974,7 +2974,7 @@ pub struct SyncArgs {
|
|||
/// Omit other dependencies. The project itself will also be omitted.
|
||||
///
|
||||
/// This option is an alias for `--only-group dev`.
|
||||
#[arg(long, conflicts_with("no_dev"))]
|
||||
#[arg(long, conflicts_with_all = ["group", "all_groups", "no_dev"])]
|
||||
pub only_dev: bool,
|
||||
|
||||
/// Include dependencies from the specified dependency group.
|
||||
|
@ -2983,7 +2983,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", "only_dev"])]
|
||||
pub group: Vec<GroupName>,
|
||||
|
||||
/// Exclude dependencies from the specified dependency group.
|
||||
|
@ -2995,7 +2995,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)]
|
||||
pub no_default_groups: bool,
|
||||
|
||||
/// Only include dependencies from the specified dependency group.
|
||||
|
@ -3003,13 +3003,13 @@ pub struct SyncArgs {
|
|||
/// The project itself will also be omitted.
|
||||
///
|
||||
/// May be provided multiple times.
|
||||
#[arg(long, conflicts_with("group"))]
|
||||
#[arg(long, conflicts_with_all = ["group", "dev", "all_groups"])]
|
||||
pub only_group: Vec<GroupName>,
|
||||
|
||||
/// 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 = ["only_group", "only_dev"])]
|
||||
pub all_groups: bool,
|
||||
|
||||
/// Install any editable dependencies, including the project and any workspace members, as
|
||||
|
@ -3452,7 +3452,7 @@ pub struct TreeArgs {
|
|||
/// Omit other dependencies. The project itself will also be omitted.
|
||||
///
|
||||
/// This option is an alias for `--only-group dev`.
|
||||
#[arg(long, conflicts_with("no_dev"))]
|
||||
#[arg(long, conflicts_with_all = ["group", "all_groups", "no_dev"])]
|
||||
pub only_dev: bool,
|
||||
|
||||
/// Omit the development dependency group.
|
||||
|
@ -3464,7 +3464,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", "only_dev"])]
|
||||
pub group: Vec<GroupName>,
|
||||
|
||||
/// Exclude dependencies from the specified dependency group.
|
||||
|
@ -3476,7 +3476,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)]
|
||||
pub no_default_groups: bool,
|
||||
|
||||
/// Only include dependencies from the specified dependency group.
|
||||
|
@ -3484,13 +3484,13 @@ pub struct TreeArgs {
|
|||
/// The project itself will also be omitted.
|
||||
///
|
||||
/// May be provided multiple times.
|
||||
#[arg(long, conflicts_with("group"))]
|
||||
#[arg(long, conflicts_with_all = ["group", "dev", "all_groups"])]
|
||||
pub only_group: Vec<GroupName>,
|
||||
|
||||
/// 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 = ["only_group", "only_dev"])]
|
||||
pub all_groups: bool,
|
||||
|
||||
/// Assert that the `uv.lock` will remain unchanged.
|
||||
|
@ -3626,13 +3626,13 @@ pub struct ExportArgs {
|
|||
/// Omit other dependencies. The project itself will also be omitted.
|
||||
///
|
||||
/// This option is an alias for `--only-group dev`.
|
||||
#[arg(long, conflicts_with("no_dev"))]
|
||||
#[arg(long, conflicts_with_all = ["group", "all_groups", "no_dev"])]
|
||||
pub only_dev: bool,
|
||||
|
||||
/// 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", "only_dev"])]
|
||||
pub group: Vec<GroupName>,
|
||||
|
||||
/// Exclude dependencies from the specified dependency group.
|
||||
|
@ -3644,7 +3644,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)]
|
||||
pub no_default_groups: bool,
|
||||
|
||||
/// Only include dependencies from the specified dependency group.
|
||||
|
@ -3652,13 +3652,13 @@ pub struct ExportArgs {
|
|||
/// The project itself will also be omitted.
|
||||
///
|
||||
/// May be provided multiple times.
|
||||
#[arg(long, conflicts_with("group"))]
|
||||
#[arg(long, conflicts_with_all = ["group", "dev", "all_groups"])]
|
||||
pub only_group: Vec<GroupName>,
|
||||
|
||||
/// 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 = ["only_group", "only_dev"])]
|
||||
pub all_groups: bool,
|
||||
|
||||
/// Exclude the comment header at the top of the generated output file.
|
||||
|
|
|
@ -1,9 +1,304 @@
|
|||
use std::borrow::Cow;
|
||||
|
||||
use either::Either;
|
||||
use std::{borrow::Cow, sync::Arc};
|
||||
|
||||
use uv_normalize::{GroupName, DEV_DEPENDENCIES};
|
||||
|
||||
/// Manager of all dependency-group decisions and settings history.
|
||||
///
|
||||
/// This is an Arc mostly just to avoid size bloat on things that contain these.
|
||||
#[derive(Debug, Default, Clone)]
|
||||
pub struct DevGroupsSpecification(Arc<DevGroupsSpecificationInner>);
|
||||
|
||||
/// Manager of all dependency-group decisions and settings history.
|
||||
#[derive(Debug, Default, Clone)]
|
||||
pub struct DevGroupsSpecificationInner {
|
||||
/// Groups to include.
|
||||
include: IncludeGroups,
|
||||
/// Groups to exclude (always wins over include).
|
||||
exclude: Vec<GroupName>,
|
||||
/// Whether an `--only` flag was passed.
|
||||
///
|
||||
/// If true, users of this API should refrain from looking at packages
|
||||
/// that *aren't* specified by the dependency-groups. This is exposed
|
||||
/// via [`DevGroupsSpecificationInner::prod`][].
|
||||
only_groups: bool,
|
||||
/// The "raw" flags/settings we were passed for diagnostics.
|
||||
history: DevGroupsSpecificationHistory,
|
||||
}
|
||||
|
||||
impl DevGroupsSpecification {
|
||||
/// Create from history.
|
||||
///
|
||||
/// This is the "real" constructor, it's basically taking raw CLI flags but in
|
||||
/// a way that's a bit nicer for other constructors to use.
|
||||
fn from_history(history: DevGroupsSpecificationHistory) -> Self {
|
||||
let DevGroupsSpecificationHistory {
|
||||
dev_mode,
|
||||
mut group,
|
||||
mut only_group,
|
||||
mut no_group,
|
||||
all_groups,
|
||||
no_default_groups,
|
||||
mut defaults,
|
||||
} = history.clone();
|
||||
|
||||
// First desugar --dev flags
|
||||
match dev_mode {
|
||||
Some(DevMode::Include) => group.push(DEV_DEPENDENCIES.clone()),
|
||||
Some(DevMode::Only) => only_group.push(DEV_DEPENDENCIES.clone()),
|
||||
Some(DevMode::Exclude) => no_group.push(DEV_DEPENDENCIES.clone()),
|
||||
None => {}
|
||||
}
|
||||
|
||||
// `group` and `only_group` actually have the same meanings: packages to include.
|
||||
// But if `only_group` is non-empty then *other* packages should be excluded.
|
||||
// So we just record whether it was and then treat the two lists as equivalent.
|
||||
let only_groups = !only_group.is_empty();
|
||||
// --only flags imply --no-default-groups
|
||||
let default_groups = !no_default_groups && !only_groups;
|
||||
|
||||
let include = if all_groups {
|
||||
// If this is set we can ignore group/only_group/defaults as irrelevant
|
||||
// (`--all-groups --only-*` is rejected at the CLI level, don't worry about it).
|
||||
IncludeGroups::All
|
||||
} else {
|
||||
// Merge all these lists, they're equivalent now
|
||||
group.append(&mut only_group);
|
||||
if default_groups {
|
||||
group.append(&mut defaults);
|
||||
}
|
||||
IncludeGroups::Some(group)
|
||||
};
|
||||
|
||||
Self(Arc::new(DevGroupsSpecificationInner {
|
||||
include,
|
||||
exclude: no_group,
|
||||
only_groups,
|
||||
history,
|
||||
}))
|
||||
}
|
||||
|
||||
/// Create from raw CLI args
|
||||
#[allow(clippy::fn_params_excessive_bools)]
|
||||
pub fn from_args(
|
||||
dev: bool,
|
||||
no_dev: bool,
|
||||
only_dev: bool,
|
||||
group: Vec<GroupName>,
|
||||
no_group: Vec<GroupName>,
|
||||
no_default_groups: bool,
|
||||
only_group: Vec<GroupName>,
|
||||
all_groups: bool,
|
||||
) -> Self {
|
||||
// Lower the --dev flags into a single dev mode.
|
||||
//
|
||||
// In theory only one of these 3 flags should be set (enforced by CLI),
|
||||
// but we explicitly allow `--dev` and `--only-dev` to both be set,
|
||||
// and "saturate" that to `--only-dev`.
|
||||
let dev_mode = if only_dev {
|
||||
Some(DevMode::Only)
|
||||
} else if no_dev {
|
||||
Some(DevMode::Exclude)
|
||||
} else if dev {
|
||||
Some(DevMode::Include)
|
||||
} else {
|
||||
None
|
||||
};
|
||||
|
||||
Self::from_history(DevGroupsSpecificationHistory {
|
||||
dev_mode,
|
||||
group,
|
||||
only_group,
|
||||
no_group,
|
||||
all_groups,
|
||||
no_default_groups,
|
||||
// This is unknown at CLI-time, use `.with_defaults(...)` to apply this later!
|
||||
defaults: Vec::new(),
|
||||
})
|
||||
}
|
||||
|
||||
/// Helper to make a spec from just a --dev flag
|
||||
pub fn from_dev_mode(dev_mode: DevMode) -> Self {
|
||||
Self::from_history(DevGroupsSpecificationHistory {
|
||||
dev_mode: Some(dev_mode),
|
||||
..Default::default()
|
||||
})
|
||||
}
|
||||
|
||||
/// Helper to make a spec from just a --group
|
||||
pub fn from_group(group: GroupName) -> Self {
|
||||
Self::from_history(DevGroupsSpecificationHistory {
|
||||
group: vec![group],
|
||||
..Default::default()
|
||||
})
|
||||
}
|
||||
|
||||
/// Apply defaults to a base [`DevGroupsSpecification`].
|
||||
///
|
||||
/// This is appropriate in projects, where the `dev` group is synced by default.
|
||||
pub fn with_defaults(&self, defaults: Vec<GroupName>) -> DevGroupsManifest {
|
||||
// Explicitly clone the inner history and set the defaults, then remake the result.
|
||||
let mut history = self.0.history.clone();
|
||||
history.defaults = defaults;
|
||||
|
||||
DevGroupsManifest {
|
||||
cur: Self::from_history(history),
|
||||
prev: self.clone(),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl std::ops::Deref for DevGroupsSpecification {
|
||||
type Target = DevGroupsSpecificationInner;
|
||||
fn deref(&self) -> &Self::Target {
|
||||
&self.0
|
||||
}
|
||||
}
|
||||
|
||||
impl DevGroupsSpecificationInner {
|
||||
/// Returns `true` if packages other than the ones referenced by these
|
||||
/// dependency-groups should be considered.
|
||||
///
|
||||
/// That is, if I tell you to install a project and this is false,
|
||||
/// you should ignore the project itself and all its dependencies,
|
||||
/// and instead just install the dependency-groups.
|
||||
///
|
||||
/// (This is really just asking if an --only flag was passed.)
|
||||
pub fn prod(&self) -> bool {
|
||||
!self.only_groups
|
||||
}
|
||||
|
||||
/// Returns `true` if the specification includes the given group.
|
||||
pub fn contains(&self, group: &GroupName) -> bool {
|
||||
// exclude always trumps include
|
||||
!self.exclude.contains(group) && self.include.contains(group)
|
||||
}
|
||||
|
||||
/// Iterate over all groups that we think should exist.
|
||||
pub fn desugarred_names(&self) -> impl Iterator<Item = &GroupName> {
|
||||
self.include.names().chain(&self.exclude)
|
||||
}
|
||||
|
||||
/// Iterate over all groups the user explicitly asked for on the CLI
|
||||
pub fn explicit_names(&self) -> impl Iterator<Item = &GroupName> {
|
||||
let DevGroupsSpecificationHistory {
|
||||
// Strictly speaking this is an explicit reference to "dev"
|
||||
// but we're currently tolerant of dev not existing when referenced with
|
||||
// these flags, since it kinda implicitly always exists even if
|
||||
// it's not properly defined in a config file.
|
||||
dev_mode: _,
|
||||
group,
|
||||
only_group,
|
||||
no_group,
|
||||
// These reference no groups explicitly
|
||||
all_groups: _,
|
||||
no_default_groups: _,
|
||||
// This doesn't include defaults because the `dev` group may not be defined
|
||||
// but gets implicitly added as a default sometimes!
|
||||
defaults: _,
|
||||
} = self.history();
|
||||
|
||||
group.iter().chain(no_group).chain(only_group)
|
||||
}
|
||||
|
||||
/// Returns `true` if the specification will have no effect.
|
||||
pub fn is_empty(&self) -> bool {
|
||||
self.prod() && self.exclude.is_empty() && self.include.is_empty()
|
||||
}
|
||||
|
||||
/// Get the raw history for diagnostics
|
||||
pub fn history(&self) -> &DevGroupsSpecificationHistory {
|
||||
&self.history
|
||||
}
|
||||
}
|
||||
|
||||
/// Context about a [`DevGroupsSpecification`][] that we've preserved for diagnostics
|
||||
#[derive(Debug, Default, Clone)]
|
||||
pub struct DevGroupsSpecificationHistory {
|
||||
pub dev_mode: Option<DevMode>,
|
||||
pub group: Vec<GroupName>,
|
||||
pub only_group: Vec<GroupName>,
|
||||
pub no_group: Vec<GroupName>,
|
||||
pub all_groups: bool,
|
||||
pub no_default_groups: bool,
|
||||
pub defaults: Vec<GroupName>,
|
||||
}
|
||||
|
||||
impl DevGroupsSpecificationHistory {
|
||||
/// Returns all the CLI flags that this represents.
|
||||
///
|
||||
/// If a flag was provided multiple times (e.g. `--group A --group B`) this will
|
||||
/// elide the arguments and just show the flag once (e.g. just yield "--group").
|
||||
///
|
||||
/// Conceptually this being an empty list should be equivalent to
|
||||
/// [`DevGroupsSpecification::is_empty`][] when there aren't any defaults set.
|
||||
/// When there are defaults the two will disagree, and rightfully so!
|
||||
pub fn as_flags_pretty(&self) -> Vec<Cow<str>> {
|
||||
let DevGroupsSpecificationHistory {
|
||||
dev_mode,
|
||||
group,
|
||||
only_group,
|
||||
no_group,
|
||||
all_groups,
|
||||
no_default_groups,
|
||||
// defaults aren't CLI flags!
|
||||
defaults: _,
|
||||
} = self;
|
||||
|
||||
let mut flags = vec![];
|
||||
if *all_groups {
|
||||
flags.push(Cow::Borrowed("--all-groups"));
|
||||
}
|
||||
if *no_default_groups {
|
||||
flags.push(Cow::Borrowed("--no-default-groups"));
|
||||
}
|
||||
if let Some(dev_mode) = dev_mode {
|
||||
flags.push(Cow::Borrowed(dev_mode.as_flag()));
|
||||
}
|
||||
match &**group {
|
||||
[] => {}
|
||||
[group] => flags.push(Cow::Owned(format!("--group {group}"))),
|
||||
[..] => flags.push(Cow::Borrowed("--group")),
|
||||
}
|
||||
match &**only_group {
|
||||
[] => {}
|
||||
[group] => flags.push(Cow::Owned(format!("--only-group {group}"))),
|
||||
[..] => flags.push(Cow::Borrowed("--only-group")),
|
||||
}
|
||||
match &**no_group {
|
||||
[] => {}
|
||||
[group] => flags.push(Cow::Owned(format!("--no-group {group}"))),
|
||||
[..] => flags.push(Cow::Borrowed("--no-group")),
|
||||
}
|
||||
flags
|
||||
}
|
||||
}
|
||||
|
||||
/// A trivial newtype wrapped around [`DevGroupsSpecification`][] that signifies "defaults applied"
|
||||
///
|
||||
/// It includes a copy of the previous semantics to provide info on if
|
||||
/// the group being a default actually affected it being enabled, because it's obviously "correct".
|
||||
/// (These are Arcs so it's ~free to hold onto the previous semantics)
|
||||
#[derive(Debug, Clone)]
|
||||
pub struct DevGroupsManifest {
|
||||
/// The active semantics
|
||||
cur: DevGroupsSpecification,
|
||||
/// The semantics before defaults were applied
|
||||
prev: DevGroupsSpecification,
|
||||
}
|
||||
|
||||
impl DevGroupsManifest {
|
||||
/// Returns `true` if the specification was enabled, and *only* because it was a default
|
||||
pub fn contains_because_default(&self, group: &GroupName) -> bool {
|
||||
self.cur.contains(group) && !self.prev.contains(group)
|
||||
}
|
||||
}
|
||||
impl std::ops::Deref for DevGroupsManifest {
|
||||
type Target = DevGroupsSpecification;
|
||||
fn deref(&self) -> &Self::Target {
|
||||
&self.cur
|
||||
}
|
||||
}
|
||||
|
||||
#[derive(Debug, Default, Clone, Copy, PartialEq, Eq)]
|
||||
pub enum DevMode {
|
||||
/// Include development dependencies.
|
||||
|
@ -16,16 +311,6 @@ pub enum DevMode {
|
|||
}
|
||||
|
||||
impl DevMode {
|
||||
/// Returns `true` if the specification allows for production dependencies.
|
||||
pub fn prod(&self) -> bool {
|
||||
matches!(self, Self::Exclude | Self::Include)
|
||||
}
|
||||
|
||||
/// Returns `true` if the specification only includes development dependencies.
|
||||
pub fn only(&self) -> bool {
|
||||
matches!(self, Self::Only)
|
||||
}
|
||||
|
||||
/// Returns the flag that was used to request development dependencies.
|
||||
pub fn as_flag(&self) -> &'static str {
|
||||
match self {
|
||||
|
@ -34,141 +319,6 @@ impl DevMode {
|
|||
Self::Only => "--only-dev",
|
||||
}
|
||||
}
|
||||
|
||||
/// Returns `true` if the group is `dev`, and development dependencies should be included.
|
||||
pub fn contains(&self, group: &GroupName) -> bool {
|
||||
match self {
|
||||
DevMode::Exclude => false,
|
||||
DevMode::Include | DevMode::Only => group == &*DEV_DEPENDENCIES,
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#[derive(Default, Debug, Clone)]
|
||||
pub struct DevGroupsSpecification {
|
||||
/// Legacy option for `dependency-groups.dev` and `tool.uv.dev-dependencies`.
|
||||
///
|
||||
/// Requested via the `--dev`, `--no-dev`, and `--only-dev` flags.
|
||||
dev: Option<DevMode>,
|
||||
|
||||
/// The groups to include.
|
||||
///
|
||||
/// Requested via the `--group` and `--only-group` options.
|
||||
groups: Option<GroupsSpecification>,
|
||||
}
|
||||
|
||||
#[derive(Debug, Clone)]
|
||||
pub enum GroupsSpecification {
|
||||
/// Include dependencies from the specified groups alongside the default groups (omitting
|
||||
/// those default groups that are explicitly excluded).
|
||||
///
|
||||
/// If the `include` is `IncludeGroups::Some`, it is guaranteed to omit groups in the `exclude`
|
||||
/// list (i.e., they have an empty intersection).
|
||||
Include {
|
||||
include: IncludeGroups,
|
||||
exclude: Vec<GroupName>,
|
||||
},
|
||||
/// 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
|
||||
/// empty intersection).
|
||||
Only {
|
||||
include: Vec<GroupName>,
|
||||
exclude: Vec<GroupName>,
|
||||
},
|
||||
}
|
||||
|
||||
impl GroupsSpecification {
|
||||
/// Create a [`GroupsSpecification`] that includes the given group.
|
||||
pub fn from_group(group: GroupName) -> Self {
|
||||
Self::Include {
|
||||
include: IncludeGroups::Some(vec![group]),
|
||||
exclude: Vec::new(),
|
||||
}
|
||||
}
|
||||
|
||||
/// Returns `true` if the specification allows for production dependencies.
|
||||
pub fn prod(&self) -> bool {
|
||||
matches!(self, Self::Include { .. } | Self::Explicit { .. })
|
||||
}
|
||||
|
||||
/// Returns `true` if the specification is limited to a select set of groups.
|
||||
pub fn only(&self) -> bool {
|
||||
matches!(self, Self::Only { .. })
|
||||
}
|
||||
|
||||
/// 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 {
|
||||
IncludeGroups::All => Some(Cow::Borrowed("--all-groups")),
|
||||
IncludeGroups::Some(groups) => match groups.as_slice() {
|
||||
[] => match exclude.as_slice() {
|
||||
[] => None,
|
||||
[group] => Some(Cow::Owned(format!("--no-group {group}"))),
|
||||
[..] => Some(Cow::Borrowed("--no-group")),
|
||||
},
|
||||
[group] => Some(Cow::Owned(format!("--group {group}"))),
|
||||
[..] => Some(Cow::Borrowed("--group")),
|
||||
},
|
||||
},
|
||||
Self::Only { include, exclude } => match include.as_slice() {
|
||||
[] => match exclude.as_slice() {
|
||||
[] => None,
|
||||
[group] => Some(Cow::Owned(format!("--no-group {group}"))),
|
||||
[..] => Some(Cow::Borrowed("--no-group")),
|
||||
},
|
||||
[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()),
|
||||
}
|
||||
}
|
||||
|
||||
/// Returns `true` if the specification includes the given group.
|
||||
pub fn contains(&self, group: &GroupName) -> bool {
|
||||
match self {
|
||||
GroupsSpecification::Include { include, exclude } => {
|
||||
// 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),
|
||||
}
|
||||
}
|
||||
|
||||
/// Returns `true` if the specification will have no effect.
|
||||
pub fn is_empty(&self) -> bool {
|
||||
let GroupsSpecification::Include {
|
||||
include: IncludeGroups::Some(includes),
|
||||
exclude,
|
||||
} = self
|
||||
else {
|
||||
return false;
|
||||
};
|
||||
includes.is_empty() && exclude.is_empty()
|
||||
}
|
||||
}
|
||||
|
||||
#[derive(Debug, Clone)]
|
||||
|
@ -188,6 +338,16 @@ impl IncludeGroups {
|
|||
}
|
||||
}
|
||||
|
||||
/// Returns `true` if the specification will have no effect.
|
||||
pub fn is_empty(&self) -> bool {
|
||||
match self {
|
||||
IncludeGroups::Some(groups) => groups.is_empty(),
|
||||
// Although technically this is a noop if they have no groups,
|
||||
// conceptually they're *trying* to have an effect, so treat it as one.
|
||||
IncludeGroups::All => false,
|
||||
}
|
||||
}
|
||||
|
||||
/// Iterate over all groups referenced in the [`IncludeGroups`].
|
||||
pub fn names(&self) -> std::slice::Iter<GroupName> {
|
||||
match self {
|
||||
|
@ -197,249 +357,8 @@ impl IncludeGroups {
|
|||
}
|
||||
}
|
||||
|
||||
impl DevGroupsSpecification {
|
||||
/// Determine the [`DevGroupsSpecification`] policy from the command-line arguments.
|
||||
#[allow(clippy::fn_params_excessive_bools)]
|
||||
pub fn from_args(
|
||||
dev: bool,
|
||||
no_dev: bool,
|
||||
only_dev: bool,
|
||||
mut group: Vec<GroupName>,
|
||||
no_group: Vec<GroupName>,
|
||||
no_default_groups: bool,
|
||||
mut only_group: Vec<GroupName>,
|
||||
all_groups: bool,
|
||||
) -> Self {
|
||||
let dev = if only_dev {
|
||||
Some(DevMode::Only)
|
||||
} else if no_dev {
|
||||
Some(DevMode::Exclude)
|
||||
} else if dev {
|
||||
Some(DevMode::Include)
|
||||
} else {
|
||||
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 {
|
||||
Some(GroupsSpecification::Include {
|
||||
include: IncludeGroups::All,
|
||||
exclude: no_group,
|
||||
})
|
||||
} else if !group.is_empty() {
|
||||
if matches!(dev, Some(DevMode::Only)) {
|
||||
unreachable!("cannot specify both `--only-dev` and `--group`")
|
||||
};
|
||||
|
||||
// Ensure that `--no-group` and `--group` are mutually exclusive.
|
||||
group.retain(|group| !no_group.contains(group));
|
||||
|
||||
Some(GroupsSpecification::Include {
|
||||
include: IncludeGroups::Some(group),
|
||||
exclude: no_group,
|
||||
})
|
||||
} else if !only_group.is_empty() {
|
||||
if matches!(dev, Some(DevMode::Include)) {
|
||||
unreachable!("cannot specify both `--dev` and `--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: IncludeGroups::Some(Vec::new()),
|
||||
exclude: no_group,
|
||||
})
|
||||
} else {
|
||||
None
|
||||
};
|
||||
|
||||
Self { dev, groups }
|
||||
}
|
||||
|
||||
/// Return a new [`DevGroupsSpecification`] with development dependencies included by default.
|
||||
///
|
||||
/// This is appropriate in projects, where the `dev` group is synced by default.
|
||||
#[must_use]
|
||||
pub fn with_defaults(self, defaults: Vec<GroupName>) -> DevGroupsManifest {
|
||||
DevGroupsManifest {
|
||||
spec: self,
|
||||
defaults,
|
||||
}
|
||||
}
|
||||
|
||||
/// Returns `true` if the specification allows for production dependencies.
|
||||
pub fn prod(&self) -> bool {
|
||||
self.dev.as_ref().map_or(true, DevMode::prod)
|
||||
&& self.groups.as_ref().map_or(true, GroupsSpecification::prod)
|
||||
}
|
||||
|
||||
/// Returns `true` if the specification is limited to a select set of groups.
|
||||
pub fn only(&self) -> bool {
|
||||
self.dev.as_ref().is_some_and(DevMode::only)
|
||||
|| self.groups.as_ref().is_some_and(GroupsSpecification::only)
|
||||
}
|
||||
|
||||
/// Returns the flag that was used to request development dependencies, if specified.
|
||||
pub fn dev_mode(&self) -> Option<&DevMode> {
|
||||
self.dev.as_ref()
|
||||
}
|
||||
|
||||
/// Returns the list of groups to include, if specified.
|
||||
pub fn groups(&self) -> Option<&GroupsSpecification> {
|
||||
self.groups.as_ref()
|
||||
}
|
||||
|
||||
/// Returns `true` if the group is included in the specification.
|
||||
pub fn contains(&self, group: &GroupName) -> bool {
|
||||
if group == &*DEV_DEPENDENCIES {
|
||||
match self.dev.as_ref() {
|
||||
None => {}
|
||||
Some(DevMode::Exclude) => {
|
||||
// If `--no-dev` was provided, always exclude dev.
|
||||
return false;
|
||||
}
|
||||
Some(DevMode::Only) => {
|
||||
// If `--only-dev` was provided, always include dev.
|
||||
return true;
|
||||
}
|
||||
Some(DevMode::Include) => {
|
||||
// If `--no-group dev` was provided, exclude dev.
|
||||
return match self.groups.as_ref() {
|
||||
Some(GroupsSpecification::Include { exclude, .. }) => {
|
||||
!exclude.contains(group)
|
||||
}
|
||||
_ => true,
|
||||
};
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
self.groups
|
||||
.as_ref()
|
||||
.is_some_and(|groups| groups.contains(group))
|
||||
}
|
||||
|
||||
/// Returns `true` if the specification will have no effect.
|
||||
pub fn is_empty(&self) -> bool {
|
||||
let groups_empty = self
|
||||
.groups
|
||||
.as_ref()
|
||||
.map(GroupsSpecification::is_empty)
|
||||
.unwrap_or(true);
|
||||
let dev_empty = self.dev_mode().is_none();
|
||||
groups_empty && dev_empty
|
||||
}
|
||||
}
|
||||
|
||||
impl From<DevMode> for DevGroupsSpecification {
|
||||
fn from(dev: DevMode) -> Self {
|
||||
Self {
|
||||
dev: Some(dev),
|
||||
groups: None,
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl From<GroupsSpecification> for DevGroupsSpecification {
|
||||
fn from(groups: GroupsSpecification) -> Self {
|
||||
Self {
|
||||
dev: None,
|
||||
groups: Some(groups),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/// The manifest of `dependency-groups` to include, taking into account the user-provided
|
||||
/// [`DevGroupsSpecification`] and the project-specific default groups.
|
||||
#[derive(Debug, Default, Clone)]
|
||||
pub struct DevGroupsManifest {
|
||||
/// The specification for the development dependencies.
|
||||
pub(crate) spec: DevGroupsSpecification,
|
||||
/// The default groups to include.
|
||||
pub(crate) defaults: Vec<GroupName>,
|
||||
}
|
||||
|
||||
impl DevGroupsManifest {
|
||||
/// Returns a new [`DevGroupsManifest`] with the given default groups.
|
||||
pub fn from_defaults(defaults: Vec<GroupName>) -> Self {
|
||||
Self {
|
||||
spec: DevGroupsSpecification::default(),
|
||||
defaults,
|
||||
}
|
||||
}
|
||||
|
||||
/// Returns a new [`DevGroupsManifest`] with the given specification.
|
||||
pub fn from_spec(spec: DevGroupsSpecification) -> Self {
|
||||
Self {
|
||||
spec,
|
||||
defaults: Vec::new(),
|
||||
}
|
||||
}
|
||||
|
||||
/// Returns `true` if the specification allows for production dependencies.
|
||||
pub fn prod(&self) -> bool {
|
||||
self.spec.prod()
|
||||
}
|
||||
|
||||
/// Returns `true` if the group was enabled by default.
|
||||
pub fn is_default(&self, group: &GroupName) -> bool {
|
||||
if self.spec.contains(group) {
|
||||
// If the group was explicitly requested, then it wasn't enabled by default.
|
||||
false
|
||||
} else {
|
||||
// If the group was enabled, but wasn't explicitly requested, then it was enabled by
|
||||
// default.
|
||||
self.contains(group)
|
||||
}
|
||||
}
|
||||
|
||||
/// Returns `true` if the group is included in the manifest.
|
||||
pub fn contains(&self, group: &GroupName) -> bool {
|
||||
if self.spec.contains(group) {
|
||||
return true;
|
||||
}
|
||||
if self.spec.only() {
|
||||
return false;
|
||||
}
|
||||
self.defaults
|
||||
.iter()
|
||||
.filter(|default| {
|
||||
// If `--no-dev` was provided, exclude the `dev` group from the list of defaults.
|
||||
if matches!(self.spec.dev_mode(), Some(DevMode::Exclude)) {
|
||||
if *default == &*DEV_DEPENDENCIES {
|
||||
return false;
|
||||
};
|
||||
}
|
||||
|
||||
// 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: _,
|
||||
exclude,
|
||||
}) = self.spec.groups()
|
||||
{
|
||||
if exclude.contains(default) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
true
|
||||
})
|
||||
.any(|default| default == group)
|
||||
impl Default for IncludeGroups {
|
||||
fn default() -> Self {
|
||||
Self::Some(Vec::new())
|
||||
}
|
||||
}
|
||||
|
|
|
@ -124,14 +124,12 @@ impl<'a, Context: BuildContext> SourceTreeResolver<'a, Context> {
|
|||
// This is only a warning because *technically* we support passing in
|
||||
// multiple pyproject.tomls, but at this level of abstraction we can't see them all,
|
||||
// so hard erroring on "no pyproject.toml mentions this" is a bit difficult.
|
||||
if let Some(groups) = self.groups.groups() {
|
||||
for name in groups.names() {
|
||||
if !metadata.dependency_groups.contains_key(name) {
|
||||
warn_user_once!(
|
||||
"The dependency-group '{name}' is not defined in {}",
|
||||
path.display()
|
||||
);
|
||||
}
|
||||
for name in self.groups.explicit_names() {
|
||||
if !metadata.dependency_groups.contains_key(name) {
|
||||
warn_user_once!(
|
||||
"The dependency-group '{name}' is not defined in {}",
|
||||
path.display()
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -76,7 +76,11 @@ pub(crate) async fn read_requirements(
|
|||
.into());
|
||||
}
|
||||
if !groups.is_empty() && !requirements.iter().any(RequirementsSource::allows_groups) {
|
||||
return Err(anyhow!("Requesting groups requires a `pyproject.toml`.").into());
|
||||
let flags = groups.history().as_flags_pretty().join(" ");
|
||||
return Err(anyhow!(
|
||||
"Requesting groups requires a `pyproject.toml`. Requested via: {flags}"
|
||||
)
|
||||
.into());
|
||||
}
|
||||
|
||||
// Read all requirements from the provided sources.
|
||||
|
|
|
@ -16,9 +16,8 @@ use uv_cache::Cache;
|
|||
use uv_cache_key::RepositoryUrl;
|
||||
use uv_client::{BaseClientBuilder, Connectivity, FlatIndexClient, RegistryClientBuilder};
|
||||
use uv_configuration::{
|
||||
Concurrency, Constraints, DevGroupsManifest, DevGroupsSpecification, DevMode, EditableMode,
|
||||
ExtrasSpecification, GroupsSpecification, InstallOptions, PreviewMode, SourceStrategy,
|
||||
TrustedHost,
|
||||
Concurrency, Constraints, DevGroupsSpecification, DevMode, EditableMode, ExtrasSpecification,
|
||||
InstallOptions, PreviewMode, SourceStrategy, TrustedHost,
|
||||
};
|
||||
use uv_dispatch::BuildDispatch;
|
||||
use uv_distribution::DistributionDatabase;
|
||||
|
@ -831,23 +830,22 @@ async fn lock_and_sync(
|
|||
let (extras, dev) = match dependency_type {
|
||||
DependencyType::Production => {
|
||||
let extras = ExtrasSpecification::None;
|
||||
let dev = DevGroupsSpecification::from(DevMode::Exclude);
|
||||
let dev = DevGroupsSpecification::from_dev_mode(DevMode::Exclude);
|
||||
(extras, dev)
|
||||
}
|
||||
DependencyType::Dev => {
|
||||
let extras = ExtrasSpecification::None;
|
||||
let dev = DevGroupsSpecification::from(DevMode::Include);
|
||||
let dev = DevGroupsSpecification::from_dev_mode(DevMode::Include);
|
||||
(extras, dev)
|
||||
}
|
||||
DependencyType::Optional(ref extra_name) => {
|
||||
let extras = ExtrasSpecification::Some(vec![extra_name.clone()]);
|
||||
let dev = DevGroupsSpecification::from(DevMode::Exclude);
|
||||
let dev = DevGroupsSpecification::from_dev_mode(DevMode::Exclude);
|
||||
(extras, dev)
|
||||
}
|
||||
DependencyType::Group(ref group_name) => {
|
||||
let extras = ExtrasSpecification::None;
|
||||
let dev =
|
||||
DevGroupsSpecification::from(GroupsSpecification::from_group(group_name.clone()));
|
||||
let dev = DevGroupsSpecification::from_group(group_name.clone());
|
||||
(extras, dev)
|
||||
}
|
||||
};
|
||||
|
@ -869,7 +867,7 @@ async fn lock_and_sync(
|
|||
target,
|
||||
venv,
|
||||
&extras,
|
||||
&DevGroupsManifest::from_spec(dev),
|
||||
&dev.with_defaults(Vec::new()),
|
||||
EditableMode::Editable,
|
||||
InstallOptions::default(),
|
||||
Modifications::Sufficient,
|
||||
|
|
|
@ -12,7 +12,7 @@ use uv_cache_key::cache_digest;
|
|||
use uv_client::{BaseClientBuilder, Connectivity, FlatIndexClient, RegistryClientBuilder};
|
||||
use uv_configuration::{
|
||||
Concurrency, Constraints, DevGroupsManifest, DevGroupsSpecification, ExtrasSpecification,
|
||||
GroupsSpecification, PreviewMode, Reinstall, TrustedHost, Upgrade,
|
||||
PreviewMode, Reinstall, TrustedHost, Upgrade,
|
||||
};
|
||||
use uv_dispatch::{BuildDispatch, SharedState};
|
||||
use uv_distribution::DistributionDatabase;
|
||||
|
@ -288,7 +288,8 @@ impl std::fmt::Display for ConflictError {
|
|||
self.conflicts
|
||||
.iter()
|
||||
.map(|conflict| match conflict {
|
||||
ConflictPackage::Group(ref group) if self.dev.is_default(group) =>
|
||||
ConflictPackage::Group(ref group)
|
||||
if self.dev.contains_because_default(group) =>
|
||||
format!("`{group}` (enabled by default)"),
|
||||
ConflictPackage::Group(ref group) => format!("`{group}`"),
|
||||
ConflictPackage::Extra(..) => unreachable!(),
|
||||
|
@ -307,7 +308,9 @@ impl std::fmt::Display for ConflictError {
|
|||
.map(|(i, conflict)| {
|
||||
let conflict = match conflict {
|
||||
ConflictPackage::Extra(ref extra) => format!("extra `{extra}`"),
|
||||
ConflictPackage::Group(ref group) if self.dev.is_default(group) => {
|
||||
ConflictPackage::Group(ref group)
|
||||
if self.dev.contains_because_default(group) =>
|
||||
{
|
||||
format!("group `{group}` (enabled by default)")
|
||||
}
|
||||
ConflictPackage::Group(ref group) => format!("group `{group}`"),
|
||||
|
@ -1841,11 +1844,7 @@ impl DependencyGroupsTarget<'_> {
|
|||
/// Validate the dependency groups requested by the [`DevGroupsSpecification`].
|
||||
#[allow(clippy::result_large_err)]
|
||||
pub(crate) fn validate(self, dev: &DevGroupsSpecification) -> Result<(), ProjectError> {
|
||||
for group in dev
|
||||
.groups()
|
||||
.into_iter()
|
||||
.flat_map(GroupsSpecification::names)
|
||||
{
|
||||
for group in dev.explicit_names() {
|
||||
match self {
|
||||
Self::Workspace(workspace) => {
|
||||
// The group must be defined in the workspace.
|
||||
|
|
|
@ -10,8 +10,8 @@ use tracing::debug;
|
|||
use uv_cache::Cache;
|
||||
use uv_client::Connectivity;
|
||||
use uv_configuration::{
|
||||
Concurrency, DevGroupsManifest, EditableMode, ExtrasSpecification, InstallOptions, PreviewMode,
|
||||
TrustedHost,
|
||||
Concurrency, DevGroupsSpecification, EditableMode, ExtrasSpecification, InstallOptions,
|
||||
PreviewMode, TrustedHost,
|
||||
};
|
||||
use uv_fs::Simplified;
|
||||
use uv_normalize::DEV_DEPENDENCIES;
|
||||
|
@ -333,7 +333,7 @@ pub(crate) async fn remove(
|
|||
target,
|
||||
venv,
|
||||
&extras,
|
||||
&DevGroupsManifest::from_defaults(defaults),
|
||||
&DevGroupsSpecification::default().with_defaults(defaults),
|
||||
EditableMode::Editable,
|
||||
install_options,
|
||||
Modifications::Exact,
|
||||
|
|
|
@ -17,8 +17,8 @@ use uv_cache::Cache;
|
|||
use uv_cli::ExternalCommand;
|
||||
use uv_client::{BaseClientBuilder, Connectivity};
|
||||
use uv_configuration::{
|
||||
Concurrency, DevGroupsManifest, DevGroupsSpecification, EditableMode, ExtrasSpecification,
|
||||
GroupsSpecification, InstallOptions, PreviewMode, SourceStrategy, TrustedHost,
|
||||
Concurrency, DevGroupsSpecification, EditableMode, ExtrasSpecification, InstallOptions,
|
||||
PreviewMode, SourceStrategy, TrustedHost,
|
||||
};
|
||||
use uv_distribution::LoweredRequirement;
|
||||
use uv_fs::which::is_executable;
|
||||
|
@ -252,7 +252,7 @@ pub(crate) async fn run(
|
|||
lock: &lock,
|
||||
},
|
||||
&ExtrasSpecification::default(),
|
||||
&DevGroupsManifest::default(),
|
||||
&DevGroupsSpecification::default().with_defaults(Vec::new()),
|
||||
InstallOptions::default(),
|
||||
&settings,
|
||||
&interpreter,
|
||||
|
@ -469,14 +469,8 @@ pub(crate) async fn run(
|
|||
if !extras.is_empty() {
|
||||
warn_user!("Extras are not supported for Python scripts with inline metadata");
|
||||
}
|
||||
if let Some(dev_mode) = dev.dev_mode() {
|
||||
warn_user!(
|
||||
"`{}` is not supported for Python scripts with inline metadata",
|
||||
dev_mode.as_flag()
|
||||
);
|
||||
}
|
||||
if let Some(flag) = dev.groups().and_then(GroupsSpecification::as_flag) {
|
||||
warn_user!("`{flag}` is not supported for Python scripts with inline metadata");
|
||||
for flag in dev.history().as_flags_pretty() {
|
||||
warn_user!("`{flag}` is not supported for Python scripts with inline metadata",);
|
||||
}
|
||||
if all_packages {
|
||||
warn_user!(
|
||||
|
@ -544,13 +538,7 @@ pub(crate) async fn run(
|
|||
if !extras.is_empty() {
|
||||
warn_user!("Extras have no effect when used alongside `--no-project`");
|
||||
}
|
||||
if let Some(dev_mode) = dev.dev_mode() {
|
||||
warn_user!(
|
||||
"`{}` has no effect when used alongside `--no-project`",
|
||||
dev_mode.as_flag()
|
||||
);
|
||||
}
|
||||
if let Some(flag) = dev.groups().and_then(GroupsSpecification::as_flag) {
|
||||
for flag in dev.history().as_flags_pretty() {
|
||||
warn_user!("`{flag}` has no effect when used alongside `--no-project`");
|
||||
}
|
||||
if locked {
|
||||
|
@ -567,13 +555,7 @@ pub(crate) async fn run(
|
|||
if !extras.is_empty() {
|
||||
warn_user!("Extras have no effect when used outside of a project");
|
||||
}
|
||||
if let Some(dev_mode) = dev.dev_mode() {
|
||||
warn_user!(
|
||||
"`{}` has no effect when used outside of a project",
|
||||
dev_mode.as_flag()
|
||||
);
|
||||
}
|
||||
if let Some(flag) = dev.groups().and_then(GroupsSpecification::as_flag) {
|
||||
for flag in dev.history().as_flags_pretty() {
|
||||
warn_user!("`{flag}` has no effect when used outside of a project");
|
||||
}
|
||||
if locked {
|
||||
|
|
|
@ -364,7 +364,7 @@ impl TestContext {
|
|||
|
||||
// Exclude `link-mode` on Windows since we set it in the remote test suite
|
||||
if cfg!(windows) {
|
||||
filters.push(("--link-mode <LINK_MODE> ".to_string(), String::new()));
|
||||
filters.push((" --link-mode <LINK_MODE>".to_string(), String::new()));
|
||||
filters.push((r#"link-mode = "copy"\n"#.to_string(), String::new()));
|
||||
}
|
||||
|
||||
|
|
|
@ -1639,7 +1639,7 @@ fn run_group() -> Result<()> {
|
|||
warning: `--group foo` has no effect when used alongside `--no-project`
|
||||
"###);
|
||||
|
||||
uv_snapshot!(context.filters(), context.run().arg("--group").arg("foo").arg("--group").arg("bar").arg("--no-project").arg("main.py"), @r###"
|
||||
uv_snapshot!(context.filters(), context.run().arg("--group").arg("foo").arg("--group").arg("bar").arg("--no-project").arg("main.py"), @r"
|
||||
success: true
|
||||
exit_code: 0
|
||||
----- stdout -----
|
||||
|
@ -1649,7 +1649,7 @@ fn run_group() -> Result<()> {
|
|||
|
||||
----- stderr -----
|
||||
warning: `--group` has no effect when used alongside `--no-project`
|
||||
"###);
|
||||
");
|
||||
|
||||
uv_snapshot!(context.filters(), context.run().arg("--group").arg("dev").arg("--no-project").arg("main.py"), @r###"
|
||||
success: true
|
||||
|
|
|
@ -144,10 +144,24 @@ fn resolve_uv_toml() -> anyhow::Result<()> {
|
|||
},
|
||||
system: false,
|
||||
extras: None,
|
||||
groups: DevGroupsSpecification {
|
||||
dev: None,
|
||||
groups: None,
|
||||
},
|
||||
groups: DevGroupsSpecification(
|
||||
DevGroupsSpecificationInner {
|
||||
include: Some(
|
||||
[],
|
||||
),
|
||||
exclude: [],
|
||||
only_groups: false,
|
||||
history: DevGroupsSpecificationHistory {
|
||||
dev_mode: None,
|
||||
group: [],
|
||||
only_group: [],
|
||||
no_group: [],
|
||||
all_groups: false,
|
||||
no_default_groups: false,
|
||||
defaults: [],
|
||||
},
|
||||
},
|
||||
),
|
||||
break_system_packages: false,
|
||||
target: None,
|
||||
prefix: None,
|
||||
|
@ -301,10 +315,24 @@ fn resolve_uv_toml() -> anyhow::Result<()> {
|
|||
},
|
||||
system: false,
|
||||
extras: None,
|
||||
groups: DevGroupsSpecification {
|
||||
dev: None,
|
||||
groups: None,
|
||||
},
|
||||
groups: DevGroupsSpecification(
|
||||
DevGroupsSpecificationInner {
|
||||
include: Some(
|
||||
[],
|
||||
),
|
||||
exclude: [],
|
||||
only_groups: false,
|
||||
history: DevGroupsSpecificationHistory {
|
||||
dev_mode: None,
|
||||
group: [],
|
||||
only_group: [],
|
||||
no_group: [],
|
||||
all_groups: false,
|
||||
no_default_groups: false,
|
||||
defaults: [],
|
||||
},
|
||||
},
|
||||
),
|
||||
break_system_packages: false,
|
||||
target: None,
|
||||
prefix: None,
|
||||
|
@ -459,10 +487,24 @@ fn resolve_uv_toml() -> anyhow::Result<()> {
|
|||
},
|
||||
system: false,
|
||||
extras: None,
|
||||
groups: DevGroupsSpecification {
|
||||
dev: None,
|
||||
groups: None,
|
||||
},
|
||||
groups: DevGroupsSpecification(
|
||||
DevGroupsSpecificationInner {
|
||||
include: Some(
|
||||
[],
|
||||
),
|
||||
exclude: [],
|
||||
only_groups: false,
|
||||
history: DevGroupsSpecificationHistory {
|
||||
dev_mode: None,
|
||||
group: [],
|
||||
only_group: [],
|
||||
no_group: [],
|
||||
all_groups: false,
|
||||
no_default_groups: false,
|
||||
defaults: [],
|
||||
},
|
||||
},
|
||||
),
|
||||
break_system_packages: false,
|
||||
target: None,
|
||||
prefix: None,
|
||||
|
@ -649,10 +691,24 @@ fn resolve_pyproject_toml() -> anyhow::Result<()> {
|
|||
},
|
||||
system: false,
|
||||
extras: None,
|
||||
groups: DevGroupsSpecification {
|
||||
dev: None,
|
||||
groups: None,
|
||||
},
|
||||
groups: DevGroupsSpecification(
|
||||
DevGroupsSpecificationInner {
|
||||
include: Some(
|
||||
[],
|
||||
),
|
||||
exclude: [],
|
||||
only_groups: false,
|
||||
history: DevGroupsSpecificationHistory {
|
||||
dev_mode: None,
|
||||
group: [],
|
||||
only_group: [],
|
||||
no_group: [],
|
||||
all_groups: false,
|
||||
no_default_groups: false,
|
||||
defaults: [],
|
||||
},
|
||||
},
|
||||
),
|
||||
break_system_packages: false,
|
||||
target: None,
|
||||
prefix: None,
|
||||
|
@ -778,10 +834,24 @@ fn resolve_pyproject_toml() -> anyhow::Result<()> {
|
|||
},
|
||||
system: false,
|
||||
extras: None,
|
||||
groups: DevGroupsSpecification {
|
||||
dev: None,
|
||||
groups: None,
|
||||
},
|
||||
groups: DevGroupsSpecification(
|
||||
DevGroupsSpecificationInner {
|
||||
include: Some(
|
||||
[],
|
||||
),
|
||||
exclude: [],
|
||||
only_groups: false,
|
||||
history: DevGroupsSpecificationHistory {
|
||||
dev_mode: None,
|
||||
group: [],
|
||||
only_group: [],
|
||||
no_group: [],
|
||||
all_groups: false,
|
||||
no_default_groups: false,
|
||||
defaults: [],
|
||||
},
|
||||
},
|
||||
),
|
||||
break_system_packages: false,
|
||||
target: None,
|
||||
prefix: None,
|
||||
|
@ -946,10 +1016,24 @@ fn resolve_pyproject_toml() -> anyhow::Result<()> {
|
|||
},
|
||||
system: false,
|
||||
extras: None,
|
||||
groups: DevGroupsSpecification {
|
||||
dev: None,
|
||||
groups: None,
|
||||
},
|
||||
groups: DevGroupsSpecification(
|
||||
DevGroupsSpecificationInner {
|
||||
include: Some(
|
||||
[],
|
||||
),
|
||||
exclude: [],
|
||||
only_groups: false,
|
||||
history: DevGroupsSpecificationHistory {
|
||||
dev_mode: None,
|
||||
group: [],
|
||||
only_group: [],
|
||||
no_group: [],
|
||||
all_groups: false,
|
||||
no_default_groups: false,
|
||||
defaults: [],
|
||||
},
|
||||
},
|
||||
),
|
||||
break_system_packages: false,
|
||||
target: None,
|
||||
prefix: None,
|
||||
|
@ -1157,10 +1241,24 @@ fn resolve_index_url() -> anyhow::Result<()> {
|
|||
},
|
||||
system: false,
|
||||
extras: None,
|
||||
groups: DevGroupsSpecification {
|
||||
dev: None,
|
||||
groups: None,
|
||||
},
|
||||
groups: DevGroupsSpecification(
|
||||
DevGroupsSpecificationInner {
|
||||
include: Some(
|
||||
[],
|
||||
),
|
||||
exclude: [],
|
||||
only_groups: false,
|
||||
history: DevGroupsSpecificationHistory {
|
||||
dev_mode: None,
|
||||
group: [],
|
||||
only_group: [],
|
||||
no_group: [],
|
||||
all_groups: false,
|
||||
no_default_groups: false,
|
||||
defaults: [],
|
||||
},
|
||||
},
|
||||
),
|
||||
break_system_packages: false,
|
||||
target: None,
|
||||
prefix: None,
|
||||
|
@ -1376,10 +1474,24 @@ fn resolve_index_url() -> anyhow::Result<()> {
|
|||
},
|
||||
system: false,
|
||||
extras: None,
|
||||
groups: DevGroupsSpecification {
|
||||
dev: None,
|
||||
groups: None,
|
||||
},
|
||||
groups: DevGroupsSpecification(
|
||||
DevGroupsSpecificationInner {
|
||||
include: Some(
|
||||
[],
|
||||
),
|
||||
exclude: [],
|
||||
only_groups: false,
|
||||
history: DevGroupsSpecificationHistory {
|
||||
dev_mode: None,
|
||||
group: [],
|
||||
only_group: [],
|
||||
no_group: [],
|
||||
all_groups: false,
|
||||
no_default_groups: false,
|
||||
defaults: [],
|
||||
},
|
||||
},
|
||||
),
|
||||
break_system_packages: false,
|
||||
target: None,
|
||||
prefix: None,
|
||||
|
@ -1558,10 +1670,24 @@ fn resolve_find_links() -> anyhow::Result<()> {
|
|||
},
|
||||
system: false,
|
||||
extras: None,
|
||||
groups: DevGroupsSpecification {
|
||||
dev: None,
|
||||
groups: None,
|
||||
},
|
||||
groups: DevGroupsSpecification(
|
||||
DevGroupsSpecificationInner {
|
||||
include: Some(
|
||||
[],
|
||||
),
|
||||
exclude: [],
|
||||
only_groups: false,
|
||||
history: DevGroupsSpecificationHistory {
|
||||
dev_mode: None,
|
||||
group: [],
|
||||
only_group: [],
|
||||
no_group: [],
|
||||
all_groups: false,
|
||||
no_default_groups: false,
|
||||
defaults: [],
|
||||
},
|
||||
},
|
||||
),
|
||||
break_system_packages: false,
|
||||
target: None,
|
||||
prefix: None,
|
||||
|
@ -1709,10 +1835,24 @@ fn resolve_top_level() -> anyhow::Result<()> {
|
|||
},
|
||||
system: false,
|
||||
extras: None,
|
||||
groups: DevGroupsSpecification {
|
||||
dev: None,
|
||||
groups: None,
|
||||
},
|
||||
groups: DevGroupsSpecification(
|
||||
DevGroupsSpecificationInner {
|
||||
include: Some(
|
||||
[],
|
||||
),
|
||||
exclude: [],
|
||||
only_groups: false,
|
||||
history: DevGroupsSpecificationHistory {
|
||||
dev_mode: None,
|
||||
group: [],
|
||||
only_group: [],
|
||||
no_group: [],
|
||||
all_groups: false,
|
||||
no_default_groups: false,
|
||||
defaults: [],
|
||||
},
|
||||
},
|
||||
),
|
||||
break_system_packages: false,
|
||||
target: None,
|
||||
prefix: None,
|
||||
|
@ -1912,10 +2052,24 @@ fn resolve_top_level() -> anyhow::Result<()> {
|
|||
},
|
||||
system: false,
|
||||
extras: None,
|
||||
groups: DevGroupsSpecification {
|
||||
dev: None,
|
||||
groups: None,
|
||||
},
|
||||
groups: DevGroupsSpecification(
|
||||
DevGroupsSpecificationInner {
|
||||
include: Some(
|
||||
[],
|
||||
),
|
||||
exclude: [],
|
||||
only_groups: false,
|
||||
history: DevGroupsSpecificationHistory {
|
||||
dev_mode: None,
|
||||
group: [],
|
||||
only_group: [],
|
||||
no_group: [],
|
||||
all_groups: false,
|
||||
no_default_groups: false,
|
||||
defaults: [],
|
||||
},
|
||||
},
|
||||
),
|
||||
break_system_packages: false,
|
||||
target: None,
|
||||
prefix: None,
|
||||
|
@ -2098,10 +2252,24 @@ fn resolve_top_level() -> anyhow::Result<()> {
|
|||
},
|
||||
system: false,
|
||||
extras: None,
|
||||
groups: DevGroupsSpecification {
|
||||
dev: None,
|
||||
groups: None,
|
||||
},
|
||||
groups: DevGroupsSpecification(
|
||||
DevGroupsSpecificationInner {
|
||||
include: Some(
|
||||
[],
|
||||
),
|
||||
exclude: [],
|
||||
only_groups: false,
|
||||
history: DevGroupsSpecificationHistory {
|
||||
dev_mode: None,
|
||||
group: [],
|
||||
only_group: [],
|
||||
no_group: [],
|
||||
all_groups: false,
|
||||
no_default_groups: false,
|
||||
defaults: [],
|
||||
},
|
||||
},
|
||||
),
|
||||
break_system_packages: false,
|
||||
target: None,
|
||||
prefix: None,
|
||||
|
@ -2249,10 +2417,24 @@ fn resolve_user_configuration() -> anyhow::Result<()> {
|
|||
},
|
||||
system: false,
|
||||
extras: None,
|
||||
groups: DevGroupsSpecification {
|
||||
dev: None,
|
||||
groups: None,
|
||||
},
|
||||
groups: DevGroupsSpecification(
|
||||
DevGroupsSpecificationInner {
|
||||
include: Some(
|
||||
[],
|
||||
),
|
||||
exclude: [],
|
||||
only_groups: false,
|
||||
history: DevGroupsSpecificationHistory {
|
||||
dev_mode: None,
|
||||
group: [],
|
||||
only_group: [],
|
||||
no_group: [],
|
||||
all_groups: false,
|
||||
no_default_groups: false,
|
||||
defaults: [],
|
||||
},
|
||||
},
|
||||
),
|
||||
break_system_packages: false,
|
||||
target: None,
|
||||
prefix: None,
|
||||
|
@ -2383,10 +2565,24 @@ fn resolve_user_configuration() -> anyhow::Result<()> {
|
|||
},
|
||||
system: false,
|
||||
extras: None,
|
||||
groups: DevGroupsSpecification {
|
||||
dev: None,
|
||||
groups: None,
|
||||
},
|
||||
groups: DevGroupsSpecification(
|
||||
DevGroupsSpecificationInner {
|
||||
include: Some(
|
||||
[],
|
||||
),
|
||||
exclude: [],
|
||||
only_groups: false,
|
||||
history: DevGroupsSpecificationHistory {
|
||||
dev_mode: None,
|
||||
group: [],
|
||||
only_group: [],
|
||||
no_group: [],
|
||||
all_groups: false,
|
||||
no_default_groups: false,
|
||||
defaults: [],
|
||||
},
|
||||
},
|
||||
),
|
||||
break_system_packages: false,
|
||||
target: None,
|
||||
prefix: None,
|
||||
|
@ -2517,10 +2713,24 @@ fn resolve_user_configuration() -> anyhow::Result<()> {
|
|||
},
|
||||
system: false,
|
||||
extras: None,
|
||||
groups: DevGroupsSpecification {
|
||||
dev: None,
|
||||
groups: None,
|
||||
},
|
||||
groups: DevGroupsSpecification(
|
||||
DevGroupsSpecificationInner {
|
||||
include: Some(
|
||||
[],
|
||||
),
|
||||
exclude: [],
|
||||
only_groups: false,
|
||||
history: DevGroupsSpecificationHistory {
|
||||
dev_mode: None,
|
||||
group: [],
|
||||
only_group: [],
|
||||
no_group: [],
|
||||
all_groups: false,
|
||||
no_default_groups: false,
|
||||
defaults: [],
|
||||
},
|
||||
},
|
||||
),
|
||||
break_system_packages: false,
|
||||
target: None,
|
||||
prefix: None,
|
||||
|
@ -2653,10 +2863,24 @@ fn resolve_user_configuration() -> anyhow::Result<()> {
|
|||
},
|
||||
system: false,
|
||||
extras: None,
|
||||
groups: DevGroupsSpecification {
|
||||
dev: None,
|
||||
groups: None,
|
||||
},
|
||||
groups: DevGroupsSpecification(
|
||||
DevGroupsSpecificationInner {
|
||||
include: Some(
|
||||
[],
|
||||
),
|
||||
exclude: [],
|
||||
only_groups: false,
|
||||
history: DevGroupsSpecificationHistory {
|
||||
dev_mode: None,
|
||||
group: [],
|
||||
only_group: [],
|
||||
no_group: [],
|
||||
all_groups: false,
|
||||
no_default_groups: false,
|
||||
defaults: [],
|
||||
},
|
||||
},
|
||||
),
|
||||
break_system_packages: false,
|
||||
target: None,
|
||||
prefix: None,
|
||||
|
@ -2967,10 +3191,24 @@ fn resolve_poetry_toml() -> anyhow::Result<()> {
|
|||
},
|
||||
system: false,
|
||||
extras: None,
|
||||
groups: DevGroupsSpecification {
|
||||
dev: None,
|
||||
groups: None,
|
||||
},
|
||||
groups: DevGroupsSpecification(
|
||||
DevGroupsSpecificationInner {
|
||||
include: Some(
|
||||
[],
|
||||
),
|
||||
exclude: [],
|
||||
only_groups: false,
|
||||
history: DevGroupsSpecificationHistory {
|
||||
dev_mode: None,
|
||||
group: [],
|
||||
only_group: [],
|
||||
no_group: [],
|
||||
all_groups: false,
|
||||
no_default_groups: false,
|
||||
defaults: [],
|
||||
},
|
||||
},
|
||||
),
|
||||
break_system_packages: false,
|
||||
target: None,
|
||||
prefix: None,
|
||||
|
@ -3159,10 +3397,24 @@ fn resolve_both() -> anyhow::Result<()> {
|
|||
},
|
||||
system: false,
|
||||
extras: None,
|
||||
groups: DevGroupsSpecification {
|
||||
dev: None,
|
||||
groups: None,
|
||||
},
|
||||
groups: DevGroupsSpecification(
|
||||
DevGroupsSpecificationInner {
|
||||
include: Some(
|
||||
[],
|
||||
),
|
||||
exclude: [],
|
||||
only_groups: false,
|
||||
history: DevGroupsSpecificationHistory {
|
||||
dev_mode: None,
|
||||
group: [],
|
||||
only_group: [],
|
||||
no_group: [],
|
||||
all_groups: false,
|
||||
no_default_groups: false,
|
||||
defaults: [],
|
||||
},
|
||||
},
|
||||
),
|
||||
break_system_packages: false,
|
||||
target: None,
|
||||
prefix: None,
|
||||
|
@ -3439,10 +3691,24 @@ fn resolve_config_file() -> anyhow::Result<()> {
|
|||
},
|
||||
system: false,
|
||||
extras: None,
|
||||
groups: DevGroupsSpecification {
|
||||
dev: None,
|
||||
groups: None,
|
||||
},
|
||||
groups: DevGroupsSpecification(
|
||||
DevGroupsSpecificationInner {
|
||||
include: Some(
|
||||
[],
|
||||
),
|
||||
exclude: [],
|
||||
only_groups: false,
|
||||
history: DevGroupsSpecificationHistory {
|
||||
dev_mode: None,
|
||||
group: [],
|
||||
only_group: [],
|
||||
no_group: [],
|
||||
all_groups: false,
|
||||
no_default_groups: false,
|
||||
defaults: [],
|
||||
},
|
||||
},
|
||||
),
|
||||
break_system_packages: false,
|
||||
target: None,
|
||||
prefix: None,
|
||||
|
@ -3667,10 +3933,24 @@ fn resolve_skip_empty() -> anyhow::Result<()> {
|
|||
},
|
||||
system: false,
|
||||
extras: None,
|
||||
groups: DevGroupsSpecification {
|
||||
dev: None,
|
||||
groups: None,
|
||||
},
|
||||
groups: DevGroupsSpecification(
|
||||
DevGroupsSpecificationInner {
|
||||
include: Some(
|
||||
[],
|
||||
),
|
||||
exclude: [],
|
||||
only_groups: false,
|
||||
history: DevGroupsSpecificationHistory {
|
||||
dev_mode: None,
|
||||
group: [],
|
||||
only_group: [],
|
||||
no_group: [],
|
||||
all_groups: false,
|
||||
no_default_groups: false,
|
||||
defaults: [],
|
||||
},
|
||||
},
|
||||
),
|
||||
break_system_packages: false,
|
||||
target: None,
|
||||
prefix: None,
|
||||
|
@ -3804,10 +4084,24 @@ fn resolve_skip_empty() -> anyhow::Result<()> {
|
|||
},
|
||||
system: false,
|
||||
extras: None,
|
||||
groups: DevGroupsSpecification {
|
||||
dev: None,
|
||||
groups: None,
|
||||
},
|
||||
groups: DevGroupsSpecification(
|
||||
DevGroupsSpecificationInner {
|
||||
include: Some(
|
||||
[],
|
||||
),
|
||||
exclude: [],
|
||||
only_groups: false,
|
||||
history: DevGroupsSpecificationHistory {
|
||||
dev_mode: None,
|
||||
group: [],
|
||||
only_group: [],
|
||||
no_group: [],
|
||||
all_groups: false,
|
||||
no_default_groups: false,
|
||||
defaults: [],
|
||||
},
|
||||
},
|
||||
),
|
||||
break_system_packages: false,
|
||||
target: None,
|
||||
prefix: None,
|
||||
|
@ -3960,10 +4254,24 @@ fn allow_insecure_host() -> anyhow::Result<()> {
|
|||
},
|
||||
system: false,
|
||||
extras: None,
|
||||
groups: DevGroupsSpecification {
|
||||
dev: None,
|
||||
groups: None,
|
||||
},
|
||||
groups: DevGroupsSpecification(
|
||||
DevGroupsSpecificationInner {
|
||||
include: Some(
|
||||
[],
|
||||
),
|
||||
exclude: [],
|
||||
only_groups: false,
|
||||
history: DevGroupsSpecificationHistory {
|
||||
dev_mode: None,
|
||||
group: [],
|
||||
only_group: [],
|
||||
no_group: [],
|
||||
all_groups: false,
|
||||
no_default_groups: false,
|
||||
defaults: [],
|
||||
},
|
||||
},
|
||||
),
|
||||
break_system_packages: false,
|
||||
target: None,
|
||||
prefix: None,
|
||||
|
@ -4169,10 +4477,24 @@ fn index_priority() -> anyhow::Result<()> {
|
|||
},
|
||||
system: false,
|
||||
extras: None,
|
||||
groups: DevGroupsSpecification {
|
||||
dev: None,
|
||||
groups: None,
|
||||
},
|
||||
groups: DevGroupsSpecification(
|
||||
DevGroupsSpecificationInner {
|
||||
include: Some(
|
||||
[],
|
||||
),
|
||||
exclude: [],
|
||||
only_groups: false,
|
||||
history: DevGroupsSpecificationHistory {
|
||||
dev_mode: None,
|
||||
group: [],
|
||||
only_group: [],
|
||||
no_group: [],
|
||||
all_groups: false,
|
||||
no_default_groups: false,
|
||||
defaults: [],
|
||||
},
|
||||
},
|
||||
),
|
||||
break_system_packages: false,
|
||||
target: None,
|
||||
prefix: None,
|
||||
|
@ -4357,10 +4679,24 @@ fn index_priority() -> anyhow::Result<()> {
|
|||
},
|
||||
system: false,
|
||||
extras: None,
|
||||
groups: DevGroupsSpecification {
|
||||
dev: None,
|
||||
groups: None,
|
||||
},
|
||||
groups: DevGroupsSpecification(
|
||||
DevGroupsSpecificationInner {
|
||||
include: Some(
|
||||
[],
|
||||
),
|
||||
exclude: [],
|
||||
only_groups: false,
|
||||
history: DevGroupsSpecificationHistory {
|
||||
dev_mode: None,
|
||||
group: [],
|
||||
only_group: [],
|
||||
no_group: [],
|
||||
all_groups: false,
|
||||
no_default_groups: false,
|
||||
defaults: [],
|
||||
},
|
||||
},
|
||||
),
|
||||
break_system_packages: false,
|
||||
target: None,
|
||||
prefix: None,
|
||||
|
@ -4551,10 +4887,24 @@ fn index_priority() -> anyhow::Result<()> {
|
|||
},
|
||||
system: false,
|
||||
extras: None,
|
||||
groups: DevGroupsSpecification {
|
||||
dev: None,
|
||||
groups: None,
|
||||
},
|
||||
groups: DevGroupsSpecification(
|
||||
DevGroupsSpecificationInner {
|
||||
include: Some(
|
||||
[],
|
||||
),
|
||||
exclude: [],
|
||||
only_groups: false,
|
||||
history: DevGroupsSpecificationHistory {
|
||||
dev_mode: None,
|
||||
group: [],
|
||||
only_group: [],
|
||||
no_group: [],
|
||||
all_groups: false,
|
||||
no_default_groups: false,
|
||||
defaults: [],
|
||||
},
|
||||
},
|
||||
),
|
||||
break_system_packages: false,
|
||||
target: None,
|
||||
prefix: None,
|
||||
|
@ -4740,10 +5090,24 @@ fn index_priority() -> anyhow::Result<()> {
|
|||
},
|
||||
system: false,
|
||||
extras: None,
|
||||
groups: DevGroupsSpecification {
|
||||
dev: None,
|
||||
groups: None,
|
||||
},
|
||||
groups: DevGroupsSpecification(
|
||||
DevGroupsSpecificationInner {
|
||||
include: Some(
|
||||
[],
|
||||
),
|
||||
exclude: [],
|
||||
only_groups: false,
|
||||
history: DevGroupsSpecificationHistory {
|
||||
dev_mode: None,
|
||||
group: [],
|
||||
only_group: [],
|
||||
no_group: [],
|
||||
all_groups: false,
|
||||
no_default_groups: false,
|
||||
defaults: [],
|
||||
},
|
||||
},
|
||||
),
|
||||
break_system_packages: false,
|
||||
target: None,
|
||||
prefix: None,
|
||||
|
@ -4936,10 +5300,24 @@ fn index_priority() -> anyhow::Result<()> {
|
|||
},
|
||||
system: false,
|
||||
extras: None,
|
||||
groups: DevGroupsSpecification {
|
||||
dev: None,
|
||||
groups: None,
|
||||
},
|
||||
groups: DevGroupsSpecification(
|
||||
DevGroupsSpecificationInner {
|
||||
include: Some(
|
||||
[],
|
||||
),
|
||||
exclude: [],
|
||||
only_groups: false,
|
||||
history: DevGroupsSpecificationHistory {
|
||||
dev_mode: None,
|
||||
group: [],
|
||||
only_group: [],
|
||||
no_group: [],
|
||||
all_groups: false,
|
||||
no_default_groups: false,
|
||||
defaults: [],
|
||||
},
|
||||
},
|
||||
),
|
||||
break_system_packages: false,
|
||||
target: None,
|
||||
prefix: None,
|
||||
|
@ -5125,10 +5503,24 @@ fn index_priority() -> anyhow::Result<()> {
|
|||
},
|
||||
system: false,
|
||||
extras: None,
|
||||
groups: DevGroupsSpecification {
|
||||
dev: None,
|
||||
groups: None,
|
||||
},
|
||||
groups: DevGroupsSpecification(
|
||||
DevGroupsSpecificationInner {
|
||||
include: Some(
|
||||
[],
|
||||
),
|
||||
exclude: [],
|
||||
only_groups: false,
|
||||
history: DevGroupsSpecificationHistory {
|
||||
dev_mode: None,
|
||||
group: [],
|
||||
only_group: [],
|
||||
no_group: [],
|
||||
all_groups: false,
|
||||
no_default_groups: false,
|
||||
defaults: [],
|
||||
},
|
||||
},
|
||||
),
|
||||
break_system_packages: false,
|
||||
target: None,
|
||||
prefix: None,
|
||||
|
@ -5267,10 +5659,24 @@ fn verify_hashes() -> anyhow::Result<()> {
|
|||
},
|
||||
system: false,
|
||||
extras: None,
|
||||
groups: DevGroupsSpecification {
|
||||
dev: None,
|
||||
groups: None,
|
||||
},
|
||||
groups: DevGroupsSpecification(
|
||||
DevGroupsSpecificationInner {
|
||||
include: Some(
|
||||
[],
|
||||
),
|
||||
exclude: [],
|
||||
only_groups: false,
|
||||
history: DevGroupsSpecificationHistory {
|
||||
dev_mode: None,
|
||||
group: [],
|
||||
only_group: [],
|
||||
no_group: [],
|
||||
all_groups: false,
|
||||
no_default_groups: false,
|
||||
defaults: [],
|
||||
},
|
||||
},
|
||||
),
|
||||
break_system_packages: false,
|
||||
target: None,
|
||||
prefix: None,
|
||||
|
@ -5395,10 +5801,24 @@ fn verify_hashes() -> anyhow::Result<()> {
|
|||
},
|
||||
system: false,
|
||||
extras: None,
|
||||
groups: DevGroupsSpecification {
|
||||
dev: None,
|
||||
groups: None,
|
||||
},
|
||||
groups: DevGroupsSpecification(
|
||||
DevGroupsSpecificationInner {
|
||||
include: Some(
|
||||
[],
|
||||
),
|
||||
exclude: [],
|
||||
only_groups: false,
|
||||
history: DevGroupsSpecificationHistory {
|
||||
dev_mode: None,
|
||||
group: [],
|
||||
only_group: [],
|
||||
no_group: [],
|
||||
all_groups: false,
|
||||
no_default_groups: false,
|
||||
defaults: [],
|
||||
},
|
||||
},
|
||||
),
|
||||
break_system_packages: false,
|
||||
target: None,
|
||||
prefix: None,
|
||||
|
@ -5521,10 +5941,24 @@ fn verify_hashes() -> anyhow::Result<()> {
|
|||
},
|
||||
system: false,
|
||||
extras: None,
|
||||
groups: DevGroupsSpecification {
|
||||
dev: None,
|
||||
groups: None,
|
||||
},
|
||||
groups: DevGroupsSpecification(
|
||||
DevGroupsSpecificationInner {
|
||||
include: Some(
|
||||
[],
|
||||
),
|
||||
exclude: [],
|
||||
only_groups: false,
|
||||
history: DevGroupsSpecificationHistory {
|
||||
dev_mode: None,
|
||||
group: [],
|
||||
only_group: [],
|
||||
no_group: [],
|
||||
all_groups: false,
|
||||
no_default_groups: false,
|
||||
defaults: [],
|
||||
},
|
||||
},
|
||||
),
|
||||
break_system_packages: false,
|
||||
target: None,
|
||||
prefix: None,
|
||||
|
@ -5649,10 +6083,24 @@ fn verify_hashes() -> anyhow::Result<()> {
|
|||
},
|
||||
system: false,
|
||||
extras: None,
|
||||
groups: DevGroupsSpecification {
|
||||
dev: None,
|
||||
groups: None,
|
||||
},
|
||||
groups: DevGroupsSpecification(
|
||||
DevGroupsSpecificationInner {
|
||||
include: Some(
|
||||
[],
|
||||
),
|
||||
exclude: [],
|
||||
only_groups: false,
|
||||
history: DevGroupsSpecificationHistory {
|
||||
dev_mode: None,
|
||||
group: [],
|
||||
only_group: [],
|
||||
no_group: [],
|
||||
all_groups: false,
|
||||
no_default_groups: false,
|
||||
defaults: [],
|
||||
},
|
||||
},
|
||||
),
|
||||
break_system_packages: false,
|
||||
target: None,
|
||||
prefix: None,
|
||||
|
@ -5775,10 +6223,24 @@ fn verify_hashes() -> anyhow::Result<()> {
|
|||
},
|
||||
system: false,
|
||||
extras: None,
|
||||
groups: DevGroupsSpecification {
|
||||
dev: None,
|
||||
groups: None,
|
||||
},
|
||||
groups: DevGroupsSpecification(
|
||||
DevGroupsSpecificationInner {
|
||||
include: Some(
|
||||
[],
|
||||
),
|
||||
exclude: [],
|
||||
only_groups: false,
|
||||
history: DevGroupsSpecificationHistory {
|
||||
dev_mode: None,
|
||||
group: [],
|
||||
only_group: [],
|
||||
no_group: [],
|
||||
all_groups: false,
|
||||
no_default_groups: false,
|
||||
defaults: [],
|
||||
},
|
||||
},
|
||||
),
|
||||
break_system_packages: false,
|
||||
target: None,
|
||||
prefix: None,
|
||||
|
@ -5902,10 +6364,24 @@ fn verify_hashes() -> anyhow::Result<()> {
|
|||
},
|
||||
system: false,
|
||||
extras: None,
|
||||
groups: DevGroupsSpecification {
|
||||
dev: None,
|
||||
groups: None,
|
||||
},
|
||||
groups: DevGroupsSpecification(
|
||||
DevGroupsSpecificationInner {
|
||||
include: Some(
|
||||
[],
|
||||
),
|
||||
exclude: [],
|
||||
only_groups: false,
|
||||
history: DevGroupsSpecificationHistory {
|
||||
dev_mode: None,
|
||||
group: [],
|
||||
only_group: [],
|
||||
no_group: [],
|
||||
all_groups: false,
|
||||
no_default_groups: false,
|
||||
defaults: [],
|
||||
},
|
||||
},
|
||||
),
|
||||
break_system_packages: false,
|
||||
target: None,
|
||||
prefix: None,
|
||||
|
|
|
@ -1782,6 +1782,223 @@ fn sync_non_existent_group() -> Result<()> {
|
|||
Ok(())
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn sync_corner_groups() -> Result<()> {
|
||||
// Testing a bunch of random corner cases of flags so their behaviour is tracked.
|
||||
// It's fine if we decide we want to support these later!
|
||||
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]
|
||||
dev = ["iniconfig"]
|
||||
foo = ["sniffio"]
|
||||
bar = ["requests"]
|
||||
"#,
|
||||
)?;
|
||||
|
||||
context.lock().assert().success();
|
||||
|
||||
// --no-dev and --only-dev should error
|
||||
// (This one could be made to work with overloading)
|
||||
uv_snapshot!(context.filters(), context.sync()
|
||||
.arg("--no-dev")
|
||||
.arg("--only-dev"), @r"
|
||||
success: false
|
||||
exit_code: 2
|
||||
----- stdout -----
|
||||
|
||||
----- stderr -----
|
||||
error: the argument '--no-dev' cannot be used with '--only-dev'
|
||||
|
||||
Usage: uv sync --cache-dir [CACHE_DIR] --no-dev --exclude-newer <EXCLUDE_NEWER>
|
||||
|
||||
For more information, try '--help'.
|
||||
");
|
||||
|
||||
// --dev and --only-group should error if they don't match
|
||||
uv_snapshot!(context.filters(), context.sync()
|
||||
.arg("--dev")
|
||||
.arg("--only-group").arg("bar"), @r"
|
||||
success: false
|
||||
exit_code: 2
|
||||
----- stdout -----
|
||||
|
||||
----- stderr -----
|
||||
error: the argument '--dev' cannot be used with '--only-group <ONLY_GROUP>'
|
||||
|
||||
Usage: uv sync --cache-dir [CACHE_DIR] --exclude-newer <EXCLUDE_NEWER>
|
||||
|
||||
For more information, try '--help'.
|
||||
");
|
||||
|
||||
// --dev and --only-group should error even if it's dev still
|
||||
// (This one could be made to work the same as --dev --only-dev)
|
||||
uv_snapshot!(context.filters(), context.sync()
|
||||
.arg("--dev")
|
||||
.arg("--only-group").arg("dev"), @r"
|
||||
success: false
|
||||
exit_code: 2
|
||||
----- stdout -----
|
||||
|
||||
----- stderr -----
|
||||
error: the argument '--dev' cannot be used with '--only-group <ONLY_GROUP>'
|
||||
|
||||
Usage: uv sync --cache-dir [CACHE_DIR] --exclude-newer <EXCLUDE_NEWER>
|
||||
|
||||
For more information, try '--help'.
|
||||
");
|
||||
|
||||
// --group and --only-dev should error if they don't match
|
||||
// (This one could be made to work the same as --dev --only-dev)
|
||||
uv_snapshot!(context.filters(), context.sync()
|
||||
.arg("--only-dev")
|
||||
.arg("--group").arg("bar"), @r"
|
||||
success: false
|
||||
exit_code: 2
|
||||
----- stdout -----
|
||||
|
||||
----- stderr -----
|
||||
error: the argument '--only-dev' cannot be used with '--group <GROUP>'
|
||||
|
||||
Usage: uv sync --cache-dir [CACHE_DIR] --only-dev --exclude-newer <EXCLUDE_NEWER>
|
||||
|
||||
For more information, try '--help'.
|
||||
");
|
||||
|
||||
// --group and --only-dev should error even if it's dev still
|
||||
// (This one could be made to work the same as --dev --only-dev)
|
||||
uv_snapshot!(context.filters(), context.sync()
|
||||
.arg("--only-dev")
|
||||
.arg("--group").arg("dev"), @r"
|
||||
success: false
|
||||
exit_code: 2
|
||||
----- stdout -----
|
||||
|
||||
----- stderr -----
|
||||
error: the argument '--only-dev' cannot be used with '--group <GROUP>'
|
||||
|
||||
Usage: uv sync --cache-dir [CACHE_DIR] --only-dev --exclude-newer <EXCLUDE_NEWER>
|
||||
|
||||
For more information, try '--help'.
|
||||
");
|
||||
|
||||
// --all-groups and --only-dev should error
|
||||
uv_snapshot!(context.filters(), context.sync()
|
||||
.arg("--all-groups")
|
||||
.arg("--only-dev"), @r"
|
||||
success: false
|
||||
exit_code: 2
|
||||
----- stdout -----
|
||||
|
||||
----- stderr -----
|
||||
error: the argument '--all-groups' cannot be used with '--only-dev'
|
||||
|
||||
Usage: uv sync --cache-dir [CACHE_DIR] --all-groups --exclude-newer <EXCLUDE_NEWER>
|
||||
|
||||
For more information, try '--help'.
|
||||
");
|
||||
|
||||
// --all-groups and --only-group should error
|
||||
uv_snapshot!(context.filters(), context.sync()
|
||||
.arg("--all-groups")
|
||||
.arg("--only-group").arg("bar"), @r"
|
||||
success: false
|
||||
exit_code: 2
|
||||
----- stdout -----
|
||||
|
||||
----- stderr -----
|
||||
error: the argument '--all-groups' cannot be used with '--only-group <ONLY_GROUP>'
|
||||
|
||||
Usage: uv sync --cache-dir [CACHE_DIR] --all-groups --exclude-newer <EXCLUDE_NEWER>
|
||||
|
||||
For more information, try '--help'.
|
||||
");
|
||||
|
||||
// --group and --only-group should error if they name disjoint things
|
||||
uv_snapshot!(context.filters(), context.sync()
|
||||
.arg("--group").arg("foo")
|
||||
.arg("--only-group").arg("bar"), @r"
|
||||
success: false
|
||||
exit_code: 2
|
||||
----- stdout -----
|
||||
|
||||
----- stderr -----
|
||||
error: the argument '--group <GROUP>' cannot be used with '--only-group <ONLY_GROUP>'
|
||||
|
||||
Usage: uv sync --cache-dir [CACHE_DIR] --group <GROUP> --exclude-newer <EXCLUDE_NEWER>
|
||||
|
||||
For more information, try '--help'.
|
||||
");
|
||||
|
||||
// --group and --only-group should error if they name same things
|
||||
// (This one would be fair to allow, but... is it worth it?)
|
||||
uv_snapshot!(context.filters(), context.sync()
|
||||
.arg("--group").arg("foo")
|
||||
.arg("--only-group").arg("foo"), @r"
|
||||
success: false
|
||||
exit_code: 2
|
||||
----- stdout -----
|
||||
|
||||
----- stderr -----
|
||||
error: the argument '--group <GROUP>' cannot be used with '--only-group <ONLY_GROUP>'
|
||||
|
||||
Usage: uv sync --cache-dir [CACHE_DIR] --group <GROUP> --exclude-newer <EXCLUDE_NEWER>
|
||||
|
||||
For more information, try '--help'.
|
||||
");
|
||||
|
||||
// --all-groups and --no-default-groups is redundant but should be --all-groups
|
||||
uv_snapshot!(context.filters(), context.sync()
|
||||
.arg("--all-groups")
|
||||
.arg("--no-default-groups"), @r"
|
||||
success: true
|
||||
exit_code: 0
|
||||
----- stdout -----
|
||||
|
||||
----- stderr -----
|
||||
Resolved 9 packages in [TIME]
|
||||
Prepared 8 packages in [TIME]
|
||||
Installed 8 packages in [TIME]
|
||||
+ certifi==2024.2.2
|
||||
+ charset-normalizer==3.3.2
|
||||
+ idna==3.6
|
||||
+ iniconfig==2.0.0
|
||||
+ requests==2.31.0
|
||||
+ sniffio==1.3.1
|
||||
+ typing-extensions==4.10.0
|
||||
+ urllib3==2.2.1
|
||||
");
|
||||
|
||||
// --dev --only-dev should saturate as --only-dev
|
||||
uv_snapshot!(context.filters(), context.sync()
|
||||
.arg("--dev")
|
||||
.arg("--only-dev"), @r"
|
||||
success: true
|
||||
exit_code: 0
|
||||
----- stdout -----
|
||||
|
||||
----- stderr -----
|
||||
Resolved 9 packages in [TIME]
|
||||
Uninstalled 7 packages in [TIME]
|
||||
- certifi==2024.2.2
|
||||
- charset-normalizer==3.3.2
|
||||
- idna==3.6
|
||||
- requests==2.31.0
|
||||
- sniffio==1.3.1
|
||||
- typing-extensions==4.10.0
|
||||
- urllib3==2.2.1
|
||||
");
|
||||
Ok(())
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn sync_non_existent_default_group() -> Result<()> {
|
||||
let context = TestContext::new("3.12");
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue