mirror of https://github.com/astral-sh/uv
Avoid error for `--group` defined in non-root workspace member (#8734)
## Summary Closes https://github.com/astral-sh/uv/issues/8722.
This commit is contained in:
parent
24ad43e79c
commit
5a46b5e52c
|
|
@ -73,7 +73,7 @@ pub(crate) async fn export(
|
||||||
};
|
};
|
||||||
|
|
||||||
// Determine the default groups to include.
|
// Determine the default groups to include.
|
||||||
validate_dependency_groups(project.pyproject_toml(), &dev)?;
|
validate_dependency_groups(&project, &dev)?;
|
||||||
let defaults = default_dependency_groups(project.pyproject_toml())?;
|
let defaults = default_dependency_groups(project.pyproject_toml())?;
|
||||||
|
|
||||||
let VirtualProject::Project(project) = project else {
|
let VirtualProject::Project(project) = project else {
|
||||||
|
|
|
||||||
|
|
@ -38,7 +38,7 @@ use uv_types::{BuildIsolation, EmptyInstalledPackages, HashStrategy};
|
||||||
use uv_warnings::{warn_user, warn_user_once};
|
use uv_warnings::{warn_user, warn_user_once};
|
||||||
use uv_workspace::dependency_groups::DependencyGroupError;
|
use uv_workspace::dependency_groups::DependencyGroupError;
|
||||||
use uv_workspace::pyproject::PyProjectToml;
|
use uv_workspace::pyproject::PyProjectToml;
|
||||||
use uv_workspace::Workspace;
|
use uv_workspace::{VirtualProject, Workspace};
|
||||||
|
|
||||||
use crate::commands::pip::loggers::{InstallLogger, ResolveLogger};
|
use crate::commands::pip::loggers::{InstallLogger, ResolveLogger};
|
||||||
use crate::commands::pip::operations::{Changelog, Modifications};
|
use crate::commands::pip::operations::{Changelog, Modifications};
|
||||||
|
|
@ -126,7 +126,10 @@ pub(crate) enum ProjectError {
|
||||||
),
|
),
|
||||||
|
|
||||||
#[error("Group `{0}` is not defined in the project's `dependency-group` table")]
|
#[error("Group `{0}` is not defined in the project's `dependency-group` table")]
|
||||||
MissingGroup(GroupName),
|
MissingGroupProject(GroupName),
|
||||||
|
|
||||||
|
#[error("Group `{0}` is not defined in any project's `dependency-group` table")]
|
||||||
|
MissingGroupWorkspace(GroupName),
|
||||||
|
|
||||||
#[error("Default group `{0}` (from `tool.uv.default-groups`) is not defined in the project's `dependency-group` table")]
|
#[error("Default group `{0}` (from `tool.uv.default-groups`) is not defined in the project's `dependency-group` table")]
|
||||||
MissingDefaultGroup(GroupName),
|
MissingDefaultGroup(GroupName),
|
||||||
|
|
@ -1366,7 +1369,7 @@ pub(crate) async fn script_python_requirement(
|
||||||
/// Validate the dependency groups requested by the [`DevGroupsSpecification`].
|
/// Validate the dependency groups requested by the [`DevGroupsSpecification`].
|
||||||
#[allow(clippy::result_large_err)]
|
#[allow(clippy::result_large_err)]
|
||||||
pub(crate) fn validate_dependency_groups(
|
pub(crate) fn validate_dependency_groups(
|
||||||
pyproject_toml: &PyProjectToml,
|
project: &VirtualProject,
|
||||||
dev: &DevGroupsSpecification,
|
dev: &DevGroupsSpecification,
|
||||||
) -> Result<(), ProjectError> {
|
) -> Result<(), ProjectError> {
|
||||||
for group in dev
|
for group in dev
|
||||||
|
|
@ -1374,12 +1377,38 @@ pub(crate) fn validate_dependency_groups(
|
||||||
.into_iter()
|
.into_iter()
|
||||||
.flat_map(GroupsSpecification::names)
|
.flat_map(GroupsSpecification::names)
|
||||||
{
|
{
|
||||||
if !pyproject_toml
|
match project {
|
||||||
.dependency_groups
|
VirtualProject::Project(project) => {
|
||||||
.as_ref()
|
// The group must be defined in the target project.
|
||||||
.is_some_and(|groups| groups.contains_key(group))
|
if !project
|
||||||
{
|
.current_project()
|
||||||
return Err(ProjectError::MissingGroup(group.clone()));
|
.pyproject_toml()
|
||||||
|
.dependency_groups
|
||||||
|
.as_ref()
|
||||||
|
.is_some_and(|groups| groups.contains_key(group))
|
||||||
|
{
|
||||||
|
return Err(ProjectError::MissingGroupProject(group.clone()));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
VirtualProject::NonProject(workspace) => {
|
||||||
|
// The group must be defined in at least one workspace package.
|
||||||
|
if !workspace
|
||||||
|
.pyproject_toml()
|
||||||
|
.dependency_groups
|
||||||
|
.as_ref()
|
||||||
|
.is_some_and(|groups| groups.contains_key(group))
|
||||||
|
{
|
||||||
|
if workspace.packages().values().all(|package| {
|
||||||
|
!package
|
||||||
|
.pyproject_toml()
|
||||||
|
.dependency_groups
|
||||||
|
.as_ref()
|
||||||
|
.is_some_and(|groups| groups.contains_key(group))
|
||||||
|
}) {
|
||||||
|
return Err(ProjectError::MissingGroupWorkspace(group.clone()));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
Ok(())
|
Ok(())
|
||||||
|
|
|
||||||
|
|
@ -551,7 +551,7 @@ pub(crate) async fn run(
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
// Determine the default groups to include.
|
// Determine the default groups to include.
|
||||||
validate_dependency_groups(project.pyproject_toml(), &dev)?;
|
validate_dependency_groups(&project, &dev)?;
|
||||||
let defaults = default_dependency_groups(project.pyproject_toml())?;
|
let defaults = default_dependency_groups(project.pyproject_toml())?;
|
||||||
|
|
||||||
// Determine the lock mode.
|
// Determine the lock mode.
|
||||||
|
|
|
||||||
|
|
@ -96,7 +96,7 @@ pub(crate) async fn sync(
|
||||||
}
|
}
|
||||||
|
|
||||||
// Determine the default groups to include.
|
// Determine the default groups to include.
|
||||||
validate_dependency_groups(project.pyproject_toml(), &dev)?;
|
validate_dependency_groups(&project, &dev)?;
|
||||||
let defaults = default_dependency_groups(project.pyproject_toml())?;
|
let defaults = default_dependency_groups(project.pyproject_toml())?;
|
||||||
|
|
||||||
// Discover or create the virtual environment.
|
// Discover or create the virtual environment.
|
||||||
|
|
|
||||||
|
|
@ -9,7 +9,7 @@ use uv_configuration::{Concurrency, DevGroupsSpecification, LowerBound, TargetTr
|
||||||
use uv_pep508::PackageName;
|
use uv_pep508::PackageName;
|
||||||
use uv_python::{PythonDownloads, PythonPreference, PythonRequest, PythonVersion};
|
use uv_python::{PythonDownloads, PythonPreference, PythonRequest, PythonVersion};
|
||||||
use uv_resolver::TreeDisplay;
|
use uv_resolver::TreeDisplay;
|
||||||
use uv_workspace::{DiscoveryOptions, Workspace};
|
use uv_workspace::{DiscoveryOptions, VirtualProject, Workspace};
|
||||||
|
|
||||||
use crate::commands::pip::loggers::DefaultResolveLogger;
|
use crate::commands::pip::loggers::DefaultResolveLogger;
|
||||||
use crate::commands::pip::resolution_markers;
|
use crate::commands::pip::resolution_markers;
|
||||||
|
|
@ -50,7 +50,7 @@ pub(crate) async fn tree(
|
||||||
let workspace = Workspace::discover(project_dir, &DiscoveryOptions::default()).await?;
|
let workspace = Workspace::discover(project_dir, &DiscoveryOptions::default()).await?;
|
||||||
|
|
||||||
// Determine the default groups to include.
|
// Determine the default groups to include.
|
||||||
validate_dependency_groups(workspace.pyproject_toml(), &dev)?;
|
validate_dependency_groups(&VirtualProject::NonProject(workspace.clone()), &dev)?;
|
||||||
let defaults = default_dependency_groups(workspace.pyproject_toml())?;
|
let defaults = default_dependency_groups(workspace.pyproject_toml())?;
|
||||||
|
|
||||||
// Find an interpreter for the project, unless `--frozen` and `--universal` are both set.
|
// Find an interpreter for the project, unless `--frozen` and `--universal` are both set.
|
||||||
|
|
|
||||||
|
|
@ -502,6 +502,9 @@ fn sync_legacy_non_project_group() -> Result<()> {
|
||||||
requires-python = ">=3.12"
|
requires-python = ">=3.12"
|
||||||
dependencies = ["iniconfig>1"]
|
dependencies = ["iniconfig>1"]
|
||||||
|
|
||||||
|
[dependency-groups]
|
||||||
|
baz = ["typing-extensions"]
|
||||||
|
|
||||||
[build-system]
|
[build-system]
|
||||||
requires = ["setuptools>=42"]
|
requires = ["setuptools>=42"]
|
||||||
build-backend = "setuptools.build_meta"
|
build-backend = "setuptools.build_meta"
|
||||||
|
|
@ -559,6 +562,29 @@ fn sync_legacy_non_project_group() -> Result<()> {
|
||||||
+ typing-extensions==4.10.0
|
+ typing-extensions==4.10.0
|
||||||
"###);
|
"###);
|
||||||
|
|
||||||
|
uv_snapshot!(context.filters(), context.sync().arg("--group").arg("baz"), @r###"
|
||||||
|
success: true
|
||||||
|
exit_code: 0
|
||||||
|
----- stdout -----
|
||||||
|
|
||||||
|
----- stderr -----
|
||||||
|
Resolved 6 packages in [TIME]
|
||||||
|
Uninstalled 1 package in [TIME]
|
||||||
|
Installed 2 packages in [TIME]
|
||||||
|
+ child==0.1.0 (from file://[TEMP_DIR]/child)
|
||||||
|
+ iniconfig==2.0.0
|
||||||
|
- typing-extensions==4.10.0
|
||||||
|
"###);
|
||||||
|
|
||||||
|
uv_snapshot!(context.filters(), context.sync().arg("--group").arg("bop"), @r###"
|
||||||
|
success: false
|
||||||
|
exit_code: 2
|
||||||
|
----- stdout -----
|
||||||
|
|
||||||
|
----- stderr -----
|
||||||
|
error: Group `bop` is not defined in any project's `dependency-group` table
|
||||||
|
"###);
|
||||||
|
|
||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue