mirror of https://github.com/astral-sh/uv
Allow non-root packages in uv sync
This commit is contained in:
parent
31d031c319
commit
e03b033de0
|
|
@ -65,7 +65,7 @@ pub trait Installable<'lock> {
|
||||||
for root_name in self.roots() {
|
for root_name in self.roots() {
|
||||||
let dist = self
|
let dist = self
|
||||||
.lock()
|
.lock()
|
||||||
.find_by_name(root_name)
|
.find_by_markers(root_name, marker_env.markers())
|
||||||
.map_err(|_| LockErrorKind::MultipleRootPackages {
|
.map_err(|_| LockErrorKind::MultipleRootPackages {
|
||||||
name: root_name.clone(),
|
name: root_name.clone(),
|
||||||
})?
|
})?
|
||||||
|
|
@ -97,7 +97,7 @@ pub trait Installable<'lock> {
|
||||||
for root_name in self.roots() {
|
for root_name in self.roots() {
|
||||||
let dist = self
|
let dist = self
|
||||||
.lock()
|
.lock()
|
||||||
.find_by_name(root_name)
|
.find_by_markers(root_name, marker_env.markers())
|
||||||
.map_err(|_| LockErrorKind::MultipleRootPackages {
|
.map_err(|_| LockErrorKind::MultipleRootPackages {
|
||||||
name: root_name.clone(),
|
name: root_name.clone(),
|
||||||
})?
|
})?
|
||||||
|
|
|
||||||
|
|
@ -3,7 +3,7 @@ use std::ops::Deref;
|
||||||
use std::path::Path;
|
use std::path::Path;
|
||||||
use std::sync::Arc;
|
use std::sync::Arc;
|
||||||
|
|
||||||
use anyhow::{Context, Result};
|
use anyhow::Result;
|
||||||
use itertools::Itertools;
|
use itertools::Itertools;
|
||||||
use owo_colors::OwoColorize;
|
use owo_colors::OwoColorize;
|
||||||
use serde::Serialize;
|
use serde::Serialize;
|
||||||
|
|
@ -99,39 +99,15 @@ pub(crate) async fn sync(
|
||||||
SyncTarget::Script(script)
|
SyncTarget::Script(script)
|
||||||
} else {
|
} else {
|
||||||
// Identify the project.
|
// Identify the project.
|
||||||
let project = if frozen {
|
let discovery = if frozen {
|
||||||
VirtualProject::discover(
|
DiscoveryOptions {
|
||||||
project_dir,
|
|
||||||
&DiscoveryOptions {
|
|
||||||
members: MemberDiscovery::None,
|
members: MemberDiscovery::None,
|
||||||
..DiscoveryOptions::default()
|
..DiscoveryOptions::default()
|
||||||
},
|
}
|
||||||
&workspace_cache,
|
|
||||||
)
|
|
||||||
.await?
|
|
||||||
} else if let [name] = package.as_slice() {
|
|
||||||
VirtualProject::Project(
|
|
||||||
Workspace::discover(project_dir, &DiscoveryOptions::default(), &workspace_cache)
|
|
||||||
.await?
|
|
||||||
.with_current_project(name.clone())
|
|
||||||
.with_context(|| format!("Package `{name}` not found in workspace"))?,
|
|
||||||
)
|
|
||||||
} else {
|
} else {
|
||||||
let project = VirtualProject::discover(
|
DiscoveryOptions::default()
|
||||||
project_dir,
|
|
||||||
&DiscoveryOptions::default(),
|
|
||||||
&workspace_cache,
|
|
||||||
)
|
|
||||||
.await?;
|
|
||||||
|
|
||||||
for name in &package {
|
|
||||||
if !project.workspace().packages().contains_key(name) {
|
|
||||||
return Err(anyhow::anyhow!("Package `{name}` not found in workspace",));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
project
|
|
||||||
};
|
};
|
||||||
|
let project = VirtualProject::discover(project_dir, &discovery, &workspace_cache).await?;
|
||||||
|
|
||||||
// TODO(lucab): improve warning content
|
// TODO(lucab): improve warning content
|
||||||
// <https://github.com/astral-sh/uv/issues/7428>
|
// <https://github.com/astral-sh/uv/issues/7428>
|
||||||
|
|
|
||||||
|
|
@ -377,6 +377,96 @@ fn multiple_packages() -> Result<()> {
|
||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// Sync a non-workspace member.
|
||||||
|
#[test]
|
||||||
|
fn non_root() -> Result<()> {
|
||||||
|
let context = TestContext::new("3.12");
|
||||||
|
|
||||||
|
let pyproject_toml = context.temp_dir.child("pyproject.toml");
|
||||||
|
pyproject_toml.write_str(
|
||||||
|
r#"
|
||||||
|
[project]
|
||||||
|
name = "root"
|
||||||
|
version = "0.1.0"
|
||||||
|
requires-python = ">=3.12"
|
||||||
|
dependencies = [
|
||||||
|
"anyio==4.3.0 ; sys_platform == 'darwin'",
|
||||||
|
"anyio==4.2.0 ; sys_platform == 'win32'",
|
||||||
|
]
|
||||||
|
"#,
|
||||||
|
)?;
|
||||||
|
|
||||||
|
context.lock().assert().success();
|
||||||
|
|
||||||
|
uv_snapshot!(context.filters(), context.sync().arg("--package").arg("anyio"), @r"
|
||||||
|
success: true
|
||||||
|
exit_code: 0
|
||||||
|
----- stdout -----
|
||||||
|
|
||||||
|
----- stderr -----
|
||||||
|
Resolved 5 packages in [TIME]
|
||||||
|
Prepared 3 packages in [TIME]
|
||||||
|
Installed 3 packages in [TIME]
|
||||||
|
+ anyio==4.3.0
|
||||||
|
+ idna==3.6
|
||||||
|
+ sniffio==1.3.1
|
||||||
|
");
|
||||||
|
|
||||||
|
uv_snapshot!(context.filters(), context.sync().arg("--package").arg("iniconfig"), @r"
|
||||||
|
success: false
|
||||||
|
exit_code: 2
|
||||||
|
----- stdout -----
|
||||||
|
|
||||||
|
----- stderr -----
|
||||||
|
Resolved 5 packages in [TIME]
|
||||||
|
error: Could not find root package `iniconfig`
|
||||||
|
");
|
||||||
|
|
||||||
|
Ok(())
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Attempt to sync an ambiguous non-workspace member.
|
||||||
|
#[test]
|
||||||
|
fn non_root_non_unique() -> Result<()> {
|
||||||
|
let context = TestContext::new("3.12");
|
||||||
|
|
||||||
|
let pyproject_toml = context.temp_dir.child("pyproject.toml");
|
||||||
|
pyproject_toml.write_str(
|
||||||
|
r#"
|
||||||
|
[project]
|
||||||
|
name = "root"
|
||||||
|
version = "0.1.0"
|
||||||
|
requires-python = ">=3.12"
|
||||||
|
|
||||||
|
[project.optional-dependencies]
|
||||||
|
foo = ["anyio==4.3.0"]
|
||||||
|
bar = ["anyio==4.2.0"]
|
||||||
|
|
||||||
|
[tool.uv]
|
||||||
|
conflicts = [
|
||||||
|
[
|
||||||
|
{ extra = "foo" },
|
||||||
|
{ extra = "bar" },
|
||||||
|
],
|
||||||
|
]
|
||||||
|
"#,
|
||||||
|
)?;
|
||||||
|
|
||||||
|
context.lock().assert().success();
|
||||||
|
|
||||||
|
uv_snapshot!(context.filters(), context.sync().arg("--package").arg("anyio"), @r"
|
||||||
|
success: false
|
||||||
|
exit_code: 2
|
||||||
|
----- stdout -----
|
||||||
|
|
||||||
|
----- stderr -----
|
||||||
|
Resolved 5 packages in [TIME]
|
||||||
|
error: Found multiple packages matching `anyio`
|
||||||
|
");
|
||||||
|
|
||||||
|
Ok(())
|
||||||
|
}
|
||||||
|
|
||||||
/// Test json output
|
/// Test json output
|
||||||
#[test]
|
#[test]
|
||||||
fn sync_json() -> Result<()> {
|
fn sync_json() -> Result<()> {
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue