mirror of
https://github.com/astral-sh/uv.git
synced 2025-08-01 09:32:18 +00:00
Add --package
to uv sync
(#5656)
## Summary Closes https://github.com/astral-sh/uv/issues/5008.
This commit is contained in:
parent
37a60a57e8
commit
176e9c4deb
5 changed files with 89 additions and 4 deletions
|
@ -2008,6 +2008,10 @@ pub struct SyncArgs {
|
||||||
#[command(flatten)]
|
#[command(flatten)]
|
||||||
pub refresh: RefreshArgs,
|
pub refresh: RefreshArgs,
|
||||||
|
|
||||||
|
/// Sync a specific package in the workspace.
|
||||||
|
#[arg(long)]
|
||||||
|
pub package: Option<PackageName>,
|
||||||
|
|
||||||
/// The Python interpreter to use to build the run environment.
|
/// The Python interpreter to use to build the run environment.
|
||||||
///
|
///
|
||||||
/// By default, uv uses the virtual environment in the current working directory or any parent
|
/// By default, uv uses the virtual environment in the current working directory or any parent
|
||||||
|
|
|
@ -1,4 +1,4 @@
|
||||||
use anyhow::Result;
|
use anyhow::{Context, Result};
|
||||||
|
|
||||||
use uv_auth::store_credentials_from_url;
|
use uv_auth::store_credentials_from_url;
|
||||||
use uv_cache::Cache;
|
use uv_cache::Cache;
|
||||||
|
@ -10,11 +10,12 @@ use uv_dispatch::BuildDispatch;
|
||||||
use uv_distribution::DEV_DEPENDENCIES;
|
use uv_distribution::DEV_DEPENDENCIES;
|
||||||
use uv_fs::CWD;
|
use uv_fs::CWD;
|
||||||
use uv_installer::SitePackages;
|
use uv_installer::SitePackages;
|
||||||
|
use uv_normalize::PackageName;
|
||||||
use uv_python::{PythonEnvironment, PythonFetch, PythonPreference, PythonRequest};
|
use uv_python::{PythonEnvironment, PythonFetch, PythonPreference, PythonRequest};
|
||||||
use uv_resolver::{FlatIndex, Lock};
|
use uv_resolver::{FlatIndex, Lock};
|
||||||
use uv_types::{BuildIsolation, HashStrategy};
|
use uv_types::{BuildIsolation, HashStrategy};
|
||||||
use uv_warnings::warn_user_once;
|
use uv_warnings::warn_user_once;
|
||||||
use uv_workspace::{DiscoveryOptions, VirtualProject};
|
use uv_workspace::{DiscoveryOptions, VirtualProject, Workspace};
|
||||||
|
|
||||||
use crate::commands::pip::operations::Modifications;
|
use crate::commands::pip::operations::Modifications;
|
||||||
use crate::commands::project::lock::do_safe_lock;
|
use crate::commands::project::lock::do_safe_lock;
|
||||||
|
@ -28,6 +29,7 @@ use crate::settings::{InstallerSettingsRef, ResolverInstallerSettings};
|
||||||
pub(crate) async fn sync(
|
pub(crate) async fn sync(
|
||||||
locked: bool,
|
locked: bool,
|
||||||
frozen: bool,
|
frozen: bool,
|
||||||
|
package: Option<PackageName>,
|
||||||
extras: ExtrasSpecification,
|
extras: ExtrasSpecification,
|
||||||
dev: bool,
|
dev: bool,
|
||||||
modifications: Modifications,
|
modifications: Modifications,
|
||||||
|
@ -46,8 +48,17 @@ pub(crate) async fn sync(
|
||||||
warn_user_once!("`uv sync` is experimental and may change without warning");
|
warn_user_once!("`uv sync` is experimental and may change without warning");
|
||||||
}
|
}
|
||||||
|
|
||||||
// Identify the project
|
// Identify the project.
|
||||||
let project = VirtualProject::discover(&CWD, &DiscoveryOptions::default()).await?;
|
let project = if let Some(package) = package {
|
||||||
|
VirtualProject::Project(
|
||||||
|
Workspace::discover(&CWD, &DiscoveryOptions::default())
|
||||||
|
.await?
|
||||||
|
.with_current_project(package.clone())
|
||||||
|
.with_context(|| format!("Package `{package}` not found in workspace"))?,
|
||||||
|
)
|
||||||
|
} else {
|
||||||
|
VirtualProject::discover(&CWD, &DiscoveryOptions::default()).await?
|
||||||
|
};
|
||||||
|
|
||||||
// Discover or create the virtual environment.
|
// Discover or create the virtual environment.
|
||||||
let venv = project::get_or_init_environment(
|
let venv = project::get_or_init_environment(
|
||||||
|
|
|
@ -979,6 +979,7 @@ async fn run_project(
|
||||||
commands::sync(
|
commands::sync(
|
||||||
args.locked,
|
args.locked,
|
||||||
args.frozen,
|
args.frozen,
|
||||||
|
args.package,
|
||||||
args.extras,
|
args.extras,
|
||||||
args.dev,
|
args.dev,
|
||||||
args.modifications,
|
args.modifications,
|
||||||
|
|
|
@ -543,6 +543,7 @@ pub(crate) struct SyncSettings {
|
||||||
pub(crate) extras: ExtrasSpecification,
|
pub(crate) extras: ExtrasSpecification,
|
||||||
pub(crate) dev: bool,
|
pub(crate) dev: bool,
|
||||||
pub(crate) modifications: Modifications,
|
pub(crate) modifications: Modifications,
|
||||||
|
pub(crate) package: Option<PackageName>,
|
||||||
pub(crate) python: Option<String>,
|
pub(crate) python: Option<String>,
|
||||||
pub(crate) refresh: Refresh,
|
pub(crate) refresh: Refresh,
|
||||||
pub(crate) settings: ResolverInstallerSettings,
|
pub(crate) settings: ResolverInstallerSettings,
|
||||||
|
@ -564,6 +565,7 @@ impl SyncSettings {
|
||||||
installer,
|
installer,
|
||||||
build,
|
build,
|
||||||
refresh,
|
refresh,
|
||||||
|
package,
|
||||||
python,
|
python,
|
||||||
} = args;
|
} = args;
|
||||||
|
|
||||||
|
@ -582,6 +584,7 @@ impl SyncSettings {
|
||||||
),
|
),
|
||||||
dev: flag(dev, no_dev).unwrap_or(true),
|
dev: flag(dev, no_dev).unwrap_or(true),
|
||||||
modifications,
|
modifications,
|
||||||
|
package,
|
||||||
python,
|
python,
|
||||||
refresh: Refresh::from(refresh),
|
refresh: Refresh::from(refresh),
|
||||||
settings: ResolverInstallerSettings::combine(
|
settings: ResolverInstallerSettings::combine(
|
||||||
|
|
|
@ -205,3 +205,69 @@ fn empty() -> Result<()> {
|
||||||
|
|
||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// Sync an individual package within a workspace.
|
||||||
|
#[test]
|
||||||
|
fn package() -> 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 = ["child", "anyio>3"]
|
||||||
|
|
||||||
|
[tool.uv.sources]
|
||||||
|
child = { workspace = true }
|
||||||
|
|
||||||
|
[tool.uv.workspace]
|
||||||
|
members = ["child"]
|
||||||
|
"#,
|
||||||
|
)?;
|
||||||
|
|
||||||
|
let src = context.temp_dir.child("src").child("albatross");
|
||||||
|
src.create_dir_all()?;
|
||||||
|
|
||||||
|
let init = src.child("__init__.py");
|
||||||
|
init.touch()?;
|
||||||
|
|
||||||
|
let child = context.temp_dir.child("child");
|
||||||
|
fs_err::create_dir_all(&child)?;
|
||||||
|
|
||||||
|
let pyproject_toml = child.child("pyproject.toml");
|
||||||
|
pyproject_toml.write_str(
|
||||||
|
r#"
|
||||||
|
[project]
|
||||||
|
name = "child"
|
||||||
|
version = "0.1.0"
|
||||||
|
requires-python = ">=3.12"
|
||||||
|
dependencies = ["iniconfig>1"]
|
||||||
|
"#,
|
||||||
|
)?;
|
||||||
|
|
||||||
|
let src = child.child("src").child("albatross");
|
||||||
|
src.create_dir_all()?;
|
||||||
|
|
||||||
|
let init = src.child("__init__.py");
|
||||||
|
init.touch()?;
|
||||||
|
|
||||||
|
uv_snapshot!(context.filters(), context.sync().arg("--package").arg("child"), @r###"
|
||||||
|
success: true
|
||||||
|
exit_code: 0
|
||||||
|
----- stdout -----
|
||||||
|
|
||||||
|
----- stderr -----
|
||||||
|
warning: `uv sync` is experimental and may change without warning
|
||||||
|
warning: `uv.sources` is experimental and may change without warning
|
||||||
|
Resolved 6 packages in [TIME]
|
||||||
|
Prepared 2 packages in [TIME]
|
||||||
|
Installed 2 packages in [TIME]
|
||||||
|
+ child==0.1.0 (from file://[TEMP_DIR]/child)
|
||||||
|
+ iniconfig==2.0.0
|
||||||
|
"###);
|
||||||
|
|
||||||
|
Ok(())
|
||||||
|
}
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue