mirror of
https://github.com/astral-sh/uv.git
synced 2025-11-22 20:45:25 +00:00
Add --no-install-local option to uv sync, uv add and uv export (#15328)
Some checks are pending
CI / check system | conda3.11 on windows x86-64 (push) Blocked by required conditions
CI / check system | alpine (push) Blocked by required conditions
CI / check system | python on macos aarch64 (push) Blocked by required conditions
CI / cargo clippy | ubuntu (push) Blocked by required conditions
CI / Determine changes (push) Waiting to run
CI / cargo test | macos (push) Blocked by required conditions
CI / lint (push) Waiting to run
CI / cargo clippy | windows (push) Blocked by required conditions
CI / cargo dev generate-all (push) Blocked by required conditions
CI / cargo shear (push) Waiting to run
CI / cargo test | ubuntu (push) Blocked by required conditions
CI / cargo test | windows (push) Blocked by required conditions
CI / check windows trampoline | aarch64 (push) Blocked by required conditions
CI / check windows trampoline | i686 (push) Blocked by required conditions
CI / check windows trampoline | x86_64 (push) Blocked by required conditions
CI / smoke test | macos (push) Blocked by required conditions
CI / test windows trampoline | aarch64 (push) Blocked by required conditions
CI / test windows trampoline | i686 (push) Blocked by required conditions
CI / test windows trampoline | x86_64 (push) Blocked by required conditions
CI / build binary | linux musl (push) Blocked by required conditions
CI / typos (push) Waiting to run
CI / mkdocs (push) Waiting to run
CI / build binary | linux libc (push) Blocked by required conditions
CI / build binary | linux aarch64 (push) Blocked by required conditions
CI / build binary | macos aarch64 (push) Blocked by required conditions
CI / build binary | macos x86_64 (push) Blocked by required conditions
CI / build binary | windows x86_64 (push) Blocked by required conditions
CI / build binary | windows aarch64 (push) Blocked by required conditions
CI / build binary | msrv (push) Blocked by required conditions
CI / build binary | freebsd (push) Blocked by required conditions
CI / ecosystem test | pydantic/pydantic-core (push) Blocked by required conditions
CI / ecosystem test | prefecthq/prefect (push) Blocked by required conditions
CI / ecosystem test | pallets/flask (push) Blocked by required conditions
CI / smoke test | linux (push) Blocked by required conditions
CI / smoke test | linux aarch64 (push) Blocked by required conditions
CI / smoke test | windows x86_64 (push) Blocked by required conditions
CI / smoke test | windows aarch64 (push) Blocked by required conditions
CI / integration test | conda on ubuntu (push) Blocked by required conditions
CI / integration test | deadsnakes python3.9 on ubuntu (push) Blocked by required conditions
CI / integration test | pypy on windows (push) Blocked by required conditions
CI / integration test | free-threaded on windows (push) Blocked by required conditions
CI / integration test | aarch64 windows implicit (push) Blocked by required conditions
CI / integration test | github actions (push) Blocked by required conditions
CI / integration test | free-threaded python on github actions (push) Blocked by required conditions
CI / integration test | pyenv on wsl x86-64 (push) Blocked by required conditions
CI / integration test | uv_build (push) Blocked by required conditions
CI / check system | python on debian (push) Blocked by required conditions
CI / check system | python on rocky linux 8 (push) Blocked by required conditions
CI / check system | python on rocky linux 9 (push) Blocked by required conditions
CI / integration test | aarch64 windows explicit (push) Blocked by required conditions
CI / integration test | pypy on ubuntu (push) Blocked by required conditions
CI / integration test | graalpy on ubuntu (push) Blocked by required conditions
CI / integration test | graalpy on windows (push) Blocked by required conditions
CI / integration test | pyodide on ubuntu (push) Blocked by required conditions
CI / integration test | determine publish changes (push) Blocked by required conditions
CI / integration test | registries (push) Blocked by required conditions
CI / integration test | uv publish (push) Blocked by required conditions
CI / check cache | ubuntu (push) Blocked by required conditions
CI / check cache | macos aarch64 (push) Blocked by required conditions
CI / check system | python on fedora (push) Blocked by required conditions
CI / check system | python on ubuntu (push) Blocked by required conditions
CI / check system | graalpy on ubuntu (push) Blocked by required conditions
CI / check system | pypy on ubuntu (push) Blocked by required conditions
CI / check system | pyston (push) Blocked by required conditions
CI / check system | python on macos x86-64 (push) Blocked by required conditions
CI / check system | python3.10 on windows x86 (push) Blocked by required conditions
CI / check system | python3.13 on windows x86-64 (push) Blocked by required conditions
CI / check system | homebrew python on macos aarch64 (push) Blocked by required conditions
CI / check system | python3.10 on windows x86-64 (push) Blocked by required conditions
CI / check system | x86-64 python3.13 on windows aarch64 (push) Blocked by required conditions
CI / check system | aarch64 python3.13 on windows aarch64 (push) Blocked by required conditions
CI / check system | windows registry (push) Blocked by required conditions
CI / check system | python3.12 via chocolatey (push) Blocked by required conditions
CI / check system | python3.9 via pyenv (push) Blocked by required conditions
CI / check system | conda3.11 on macos aarch64 (push) Blocked by required conditions
CI / check system | conda3.8 on macos aarch64 (push) Blocked by required conditions
CI / check system | python3.13 (push) Blocked by required conditions
CI / check system | conda3.11 on linux x86-64 (push) Blocked by required conditions
CI / check system | conda3.8 on linux x86-64 (push) Blocked by required conditions
CI / check system | conda3.8 on windows x86-64 (push) Blocked by required conditions
CI / check system | amazonlinux (push) Blocked by required conditions
CI / check system | embedded python3.10 on windows x86-64 (push) Blocked by required conditions
CI / benchmarks | walltime aarch64 linux (push) Blocked by required conditions
CI / benchmarks | instrumented (push) Blocked by required conditions
zizmor / Run zizmor (push) Waiting to run
Some checks are pending
CI / check system | conda3.11 on windows x86-64 (push) Blocked by required conditions
CI / check system | alpine (push) Blocked by required conditions
CI / check system | python on macos aarch64 (push) Blocked by required conditions
CI / cargo clippy | ubuntu (push) Blocked by required conditions
CI / Determine changes (push) Waiting to run
CI / cargo test | macos (push) Blocked by required conditions
CI / lint (push) Waiting to run
CI / cargo clippy | windows (push) Blocked by required conditions
CI / cargo dev generate-all (push) Blocked by required conditions
CI / cargo shear (push) Waiting to run
CI / cargo test | ubuntu (push) Blocked by required conditions
CI / cargo test | windows (push) Blocked by required conditions
CI / check windows trampoline | aarch64 (push) Blocked by required conditions
CI / check windows trampoline | i686 (push) Blocked by required conditions
CI / check windows trampoline | x86_64 (push) Blocked by required conditions
CI / smoke test | macos (push) Blocked by required conditions
CI / test windows trampoline | aarch64 (push) Blocked by required conditions
CI / test windows trampoline | i686 (push) Blocked by required conditions
CI / test windows trampoline | x86_64 (push) Blocked by required conditions
CI / build binary | linux musl (push) Blocked by required conditions
CI / typos (push) Waiting to run
CI / mkdocs (push) Waiting to run
CI / build binary | linux libc (push) Blocked by required conditions
CI / build binary | linux aarch64 (push) Blocked by required conditions
CI / build binary | macos aarch64 (push) Blocked by required conditions
CI / build binary | macos x86_64 (push) Blocked by required conditions
CI / build binary | windows x86_64 (push) Blocked by required conditions
CI / build binary | windows aarch64 (push) Blocked by required conditions
CI / build binary | msrv (push) Blocked by required conditions
CI / build binary | freebsd (push) Blocked by required conditions
CI / ecosystem test | pydantic/pydantic-core (push) Blocked by required conditions
CI / ecosystem test | prefecthq/prefect (push) Blocked by required conditions
CI / ecosystem test | pallets/flask (push) Blocked by required conditions
CI / smoke test | linux (push) Blocked by required conditions
CI / smoke test | linux aarch64 (push) Blocked by required conditions
CI / smoke test | windows x86_64 (push) Blocked by required conditions
CI / smoke test | windows aarch64 (push) Blocked by required conditions
CI / integration test | conda on ubuntu (push) Blocked by required conditions
CI / integration test | deadsnakes python3.9 on ubuntu (push) Blocked by required conditions
CI / integration test | pypy on windows (push) Blocked by required conditions
CI / integration test | free-threaded on windows (push) Blocked by required conditions
CI / integration test | aarch64 windows implicit (push) Blocked by required conditions
CI / integration test | github actions (push) Blocked by required conditions
CI / integration test | free-threaded python on github actions (push) Blocked by required conditions
CI / integration test | pyenv on wsl x86-64 (push) Blocked by required conditions
CI / integration test | uv_build (push) Blocked by required conditions
CI / check system | python on debian (push) Blocked by required conditions
CI / check system | python on rocky linux 8 (push) Blocked by required conditions
CI / check system | python on rocky linux 9 (push) Blocked by required conditions
CI / integration test | aarch64 windows explicit (push) Blocked by required conditions
CI / integration test | pypy on ubuntu (push) Blocked by required conditions
CI / integration test | graalpy on ubuntu (push) Blocked by required conditions
CI / integration test | graalpy on windows (push) Blocked by required conditions
CI / integration test | pyodide on ubuntu (push) Blocked by required conditions
CI / integration test | determine publish changes (push) Blocked by required conditions
CI / integration test | registries (push) Blocked by required conditions
CI / integration test | uv publish (push) Blocked by required conditions
CI / check cache | ubuntu (push) Blocked by required conditions
CI / check cache | macos aarch64 (push) Blocked by required conditions
CI / check system | python on fedora (push) Blocked by required conditions
CI / check system | python on ubuntu (push) Blocked by required conditions
CI / check system | graalpy on ubuntu (push) Blocked by required conditions
CI / check system | pypy on ubuntu (push) Blocked by required conditions
CI / check system | pyston (push) Blocked by required conditions
CI / check system | python on macos x86-64 (push) Blocked by required conditions
CI / check system | python3.10 on windows x86 (push) Blocked by required conditions
CI / check system | python3.13 on windows x86-64 (push) Blocked by required conditions
CI / check system | homebrew python on macos aarch64 (push) Blocked by required conditions
CI / check system | python3.10 on windows x86-64 (push) Blocked by required conditions
CI / check system | x86-64 python3.13 on windows aarch64 (push) Blocked by required conditions
CI / check system | aarch64 python3.13 on windows aarch64 (push) Blocked by required conditions
CI / check system | windows registry (push) Blocked by required conditions
CI / check system | python3.12 via chocolatey (push) Blocked by required conditions
CI / check system | python3.9 via pyenv (push) Blocked by required conditions
CI / check system | conda3.11 on macos aarch64 (push) Blocked by required conditions
CI / check system | conda3.8 on macos aarch64 (push) Blocked by required conditions
CI / check system | python3.13 (push) Blocked by required conditions
CI / check system | conda3.11 on linux x86-64 (push) Blocked by required conditions
CI / check system | conda3.8 on linux x86-64 (push) Blocked by required conditions
CI / check system | conda3.8 on windows x86-64 (push) Blocked by required conditions
CI / check system | amazonlinux (push) Blocked by required conditions
CI / check system | embedded python3.10 on windows x86-64 (push) Blocked by required conditions
CI / benchmarks | walltime aarch64 linux (push) Blocked by required conditions
CI / benchmarks | instrumented (push) Blocked by required conditions
zizmor / Run zizmor (push) Waiting to run
<!-- Thank you for contributing to uv! To help us out with reviewing, please consider the following: - Does this pull request include a summary of the change? (See below.) - Does this pull request include a descriptive title? - Does this pull request include references to any relevant issues? --> ## Summary <!-- What's the purpose of the change? What does it do, and why? --> Closes #14866. Adds a `no-install-local` flag to the sync and export commands that excludes locally defined packages from being installed. This helps with if you're caching your virtual environment. You can exclude local packages since they're more likely to change between builds. ## Test Plan snapshot test: `sync::no_install_local` CI ## Notes I made an `InstallOptions` struct to avoid a crate isolation issue I was running into while implementing. Thanks for maintaining this project!
This commit is contained in:
parent
f231d0f2a5
commit
6e2fbbc30f
10 changed files with 185 additions and 14 deletions
|
|
@ -3435,6 +3435,14 @@ pub struct SyncArgs {
|
|||
#[arg(long)]
|
||||
pub no_install_workspace: bool,
|
||||
|
||||
/// Do not install local path dependencies
|
||||
///
|
||||
/// Skips the current project, workspace members, and any other local (path or editable)
|
||||
/// packages. Only remote/indexed dependencies are installed. Useful in Docker builds to cache
|
||||
/// heavy third-party dependencies first and layer local packages separately.
|
||||
#[arg(long)]
|
||||
pub no_install_local: bool,
|
||||
|
||||
/// Do not install the given package(s).
|
||||
///
|
||||
/// By default, all of the project's dependencies are installed into the environment. The
|
||||
|
|
@ -3503,6 +3511,7 @@ pub struct SyncArgs {
|
|||
conflicts_with = "package",
|
||||
conflicts_with = "no_install_project",
|
||||
conflicts_with = "no_install_workspace",
|
||||
conflicts_with = "no_install_local",
|
||||
conflicts_with = "extra",
|
||||
conflicts_with = "all_extras",
|
||||
conflicts_with = "no_extra",
|
||||
|
|
@ -3847,6 +3856,14 @@ pub struct AddArgs {
|
|||
/// allows optimal layer caching.
|
||||
#[arg(long, conflicts_with = "frozen", conflicts_with = "no_sync")]
|
||||
pub no_install_workspace: bool,
|
||||
|
||||
/// Do not install local path dependencies
|
||||
///
|
||||
/// Skips the current project, workspace members, and any other local (path or editable)
|
||||
/// packages. Only remote/indexed dependencies are installed. Useful in Docker builds to cache
|
||||
/// heavy third-party dependencies first and layer local packages separately.
|
||||
#[arg(long, conflicts_with = "frozen", conflicts_with = "no_sync")]
|
||||
pub no_install_local: bool,
|
||||
}
|
||||
|
||||
#[derive(Args)]
|
||||
|
|
@ -4239,6 +4256,14 @@ pub struct ExportArgs {
|
|||
#[arg(long, alias = "no-install-workspace")]
|
||||
pub no_emit_workspace: bool,
|
||||
|
||||
/// Do not include local path dependencies in the exported requirements.
|
||||
///
|
||||
/// Omits the current project, workspace members, and any other local (path or editable)
|
||||
/// packages from the export. Only remote/indexed dependencies are written. Useful for Docker
|
||||
/// and CI flows that want to export and cache third-party dependencies first.
|
||||
#[arg(long, alias = "no-install-local")]
|
||||
pub no_emit_local: bool,
|
||||
|
||||
/// Do not emit the given package(s).
|
||||
///
|
||||
/// By default, all of the project's dependencies are included in the exported requirements
|
||||
|
|
|
|||
|
|
@ -4,12 +4,23 @@ use tracing::debug;
|
|||
|
||||
use uv_normalize::PackageName;
|
||||
|
||||
/// Minimal view of a package used to apply install filters.
|
||||
#[derive(Debug, Clone, Copy)]
|
||||
pub struct InstallTarget<'a> {
|
||||
/// The package name.
|
||||
pub name: &'a PackageName,
|
||||
/// Whether the package refers to a local source (path, directory, editable, etc.).
|
||||
pub is_local: bool,
|
||||
}
|
||||
|
||||
#[derive(Debug, Clone, Default)]
|
||||
pub struct InstallOptions {
|
||||
/// Omit the project itself from the resolution.
|
||||
pub no_install_project: bool,
|
||||
/// Omit all workspace members (including the project itself) from the resolution.
|
||||
pub no_install_workspace: bool,
|
||||
/// Omit all local packages from the resolution.
|
||||
pub no_install_local: bool,
|
||||
/// Omit the specified packages from the resolution.
|
||||
pub no_install_package: Vec<PackageName>,
|
||||
}
|
||||
|
|
@ -18,11 +29,13 @@ impl InstallOptions {
|
|||
pub fn new(
|
||||
no_install_project: bool,
|
||||
no_install_workspace: bool,
|
||||
no_install_local: bool,
|
||||
no_install_package: Vec<PackageName>,
|
||||
) -> Self {
|
||||
Self {
|
||||
no_install_project,
|
||||
no_install_workspace,
|
||||
no_install_local,
|
||||
no_install_package,
|
||||
}
|
||||
}
|
||||
|
|
@ -30,15 +43,18 @@ impl InstallOptions {
|
|||
/// Returns `true` if a package passes the install filters.
|
||||
pub fn include_package(
|
||||
&self,
|
||||
package: &PackageName,
|
||||
target: InstallTarget<'_>,
|
||||
project_name: Option<&PackageName>,
|
||||
members: &BTreeSet<PackageName>,
|
||||
) -> bool {
|
||||
let package_name = target.name;
|
||||
// If `--no-install-project` is set, remove the project itself.
|
||||
if self.no_install_project {
|
||||
if let Some(project_name) = project_name {
|
||||
if package == project_name {
|
||||
debug!("Omitting `{package}` from resolution due to `--no-install-project`");
|
||||
if package_name == project_name {
|
||||
debug!(
|
||||
"Omitting `{package_name}` from resolution due to `--no-install-project`"
|
||||
);
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
|
@ -51,24 +67,32 @@ impl InstallOptions {
|
|||
// is set.)
|
||||
if !self.no_install_project {
|
||||
if let Some(project_name) = project_name {
|
||||
if package == project_name {
|
||||
if package_name == project_name {
|
||||
debug!(
|
||||
"Omitting `{package}` from resolution due to `--no-install-workspace`"
|
||||
"Omitting `{package_name}` from resolution due to `--no-install-workspace`"
|
||||
);
|
||||
return false;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if members.contains(package) {
|
||||
debug!("Omitting `{package}` from resolution due to `--no-install-workspace`");
|
||||
if members.contains(package_name) {
|
||||
debug!("Omitting `{package_name}` from resolution due to `--no-install-workspace`");
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
// If `--no-install-local` is set, remove local packages.
|
||||
if self.no_install_local {
|
||||
if target.is_local {
|
||||
debug!("Omitting `{package_name}` from resolution due to `--no-install-local`");
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
// If `--no-install-package` is provided, remove the requested packages.
|
||||
if self.no_install_package.contains(package) {
|
||||
debug!("Omitting `{package}` from resolution due to `--no-install-package`");
|
||||
if self.no_install_package.contains(package_name) {
|
||||
debug!("Omitting `{package_name}` from resolution due to `--no-install-package`");
|
||||
return false;
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -303,7 +303,7 @@ impl<'lock> ExportableRequirements<'lock> {
|
|||
})
|
||||
.filter(|(_index, package)| {
|
||||
install_options.include_package(
|
||||
&package.id.name,
|
||||
package.as_install_target(),
|
||||
target.project_name(),
|
||||
target.lock().members(),
|
||||
)
|
||||
|
|
|
|||
|
|
@ -563,7 +563,7 @@ pub trait Installable<'lock> {
|
|||
install_options: &InstallOptions,
|
||||
) -> Result<Node, LockError> {
|
||||
if install_options.include_package(
|
||||
package.name(),
|
||||
package.as_install_target(),
|
||||
self.project_name(),
|
||||
self.lock().members(),
|
||||
) {
|
||||
|
|
|
|||
|
|
@ -19,7 +19,7 @@ use tracing::debug;
|
|||
use url::Url;
|
||||
|
||||
use uv_cache_key::RepositoryUrl;
|
||||
use uv_configuration::{BuildOptions, Constraints};
|
||||
use uv_configuration::{BuildOptions, Constraints, InstallTarget};
|
||||
use uv_distribution::{DistributionDatabase, FlatRequiresDist};
|
||||
use uv_distribution_filename::{
|
||||
BuildTag, DistExtension, ExtensionError, SourceDistExtension, WheelFilename,
|
||||
|
|
@ -3123,6 +3123,14 @@ impl Package {
|
|||
pub fn resolved_dependency_groups(&self) -> &BTreeMap<GroupName, Vec<Dependency>> {
|
||||
&self.dependency_groups
|
||||
}
|
||||
|
||||
/// Returns an [`InstallTarget`] view for filtering decisions.
|
||||
pub fn as_install_target(&self) -> InstallTarget<'_> {
|
||||
InstallTarget {
|
||||
name: self.name(),
|
||||
is_local: self.id.source.is_local(),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/// Attempts to construct a `VerbatimUrl` from the given normalized `Path`.
|
||||
|
|
@ -3688,6 +3696,14 @@ impl Source {
|
|||
}
|
||||
}
|
||||
}
|
||||
|
||||
/// Check if a package is local by examining its source.
|
||||
pub(crate) fn is_local(&self) -> bool {
|
||||
matches!(
|
||||
self,
|
||||
Self::Path(_) | Self::Directory(_) | Self::Editable(_) | Self::Virtual(_)
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
#[derive(Clone, Debug, serde::Deserialize)]
|
||||
|
|
|
|||
|
|
@ -71,6 +71,7 @@ pub(crate) async fn add(
|
|||
no_sync: bool,
|
||||
no_install_project: bool,
|
||||
no_install_workspace: bool,
|
||||
no_install_local: bool,
|
||||
requirements: Vec<RequirementsSource>,
|
||||
constraints: Vec<RequirementsSource>,
|
||||
marker: Option<MarkerTree>,
|
||||
|
|
@ -738,6 +739,7 @@ pub(crate) async fn add(
|
|||
locked,
|
||||
no_install_project,
|
||||
no_install_workspace,
|
||||
no_install_local,
|
||||
&defaulted_extras,
|
||||
&defaulted_groups,
|
||||
raw,
|
||||
|
|
@ -968,6 +970,7 @@ async fn lock_and_sync(
|
|||
locked: bool,
|
||||
no_install_project: bool,
|
||||
no_install_workspace: bool,
|
||||
no_install_local: bool,
|
||||
extras: &ExtrasSpecificationWithDefaults,
|
||||
groups: &DependencyGroupsWithDefaults,
|
||||
raw: bool,
|
||||
|
|
@ -1154,7 +1157,12 @@ async fn lock_and_sync(
|
|||
extras,
|
||||
groups,
|
||||
EditableMode::Editable,
|
||||
InstallOptions::new(no_install_project, no_install_workspace, vec![]),
|
||||
InstallOptions::new(
|
||||
no_install_project,
|
||||
no_install_workspace,
|
||||
no_install_local,
|
||||
vec![],
|
||||
),
|
||||
Modifications::Sufficient,
|
||||
None,
|
||||
settings.into(),
|
||||
|
|
|
|||
|
|
@ -1978,6 +1978,7 @@ async fn run_project(
|
|||
args.no_sync,
|
||||
args.no_install_project,
|
||||
args.no_install_workspace,
|
||||
args.no_install_local,
|
||||
requirements,
|
||||
constraints,
|
||||
args.marker,
|
||||
|
|
|
|||
|
|
@ -1221,6 +1221,7 @@ impl SyncSettings {
|
|||
exact,
|
||||
no_install_project,
|
||||
no_install_workspace,
|
||||
no_install_local,
|
||||
no_install_package,
|
||||
locked,
|
||||
frozen,
|
||||
|
|
@ -1286,6 +1287,7 @@ impl SyncSettings {
|
|||
install_options: InstallOptions::new(
|
||||
no_install_project,
|
||||
no_install_workspace,
|
||||
no_install_local,
|
||||
no_install_package,
|
||||
),
|
||||
modifications: if flag(exact, inexact, "inexact").unwrap_or(true) {
|
||||
|
|
@ -1377,6 +1379,7 @@ pub(crate) struct AddSettings {
|
|||
pub(crate) workspace: Option<bool>,
|
||||
pub(crate) no_install_project: bool,
|
||||
pub(crate) no_install_workspace: bool,
|
||||
pub(crate) no_install_local: bool,
|
||||
pub(crate) install_mirrors: PythonInstallMirrors,
|
||||
pub(crate) refresh: Refresh,
|
||||
pub(crate) indexes: Vec<Index>,
|
||||
|
|
@ -1418,6 +1421,7 @@ impl AddSettings {
|
|||
no_workspace,
|
||||
no_install_project,
|
||||
no_install_workspace,
|
||||
no_install_local,
|
||||
} = args;
|
||||
|
||||
let dependency_type = if let Some(extra) = optional {
|
||||
|
|
@ -1521,6 +1525,7 @@ impl AddSettings {
|
|||
workspace: flag(workspace, no_workspace, "workspace"),
|
||||
no_install_project,
|
||||
no_install_workspace,
|
||||
no_install_local,
|
||||
editable: flag(editable, no_editable, "editable"),
|
||||
extras: extra.unwrap_or_default(),
|
||||
refresh: Refresh::from(refresh),
|
||||
|
|
@ -1820,6 +1825,7 @@ impl ExportSettings {
|
|||
no_emit_project,
|
||||
no_emit_workspace,
|
||||
no_emit_package,
|
||||
no_emit_local,
|
||||
locked,
|
||||
frozen,
|
||||
resolver,
|
||||
|
|
@ -1862,6 +1868,7 @@ impl ExportSettings {
|
|||
install_options: InstallOptions::new(
|
||||
no_emit_project,
|
||||
no_emit_workspace,
|
||||
no_emit_local,
|
||||
no_emit_package,
|
||||
),
|
||||
output_file,
|
||||
|
|
|
|||
|
|
@ -5197,6 +5197,90 @@ fn no_install_workspace() -> Result<()> {
|
|||
Ok(())
|
||||
}
|
||||
|
||||
/// Avoid syncing local packages when `--no-install-local` is provided.
|
||||
#[test]
|
||||
fn no_install_local() -> Result<()> {
|
||||
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 = ["anyio==3.7.0", "local", "local-editable", "workspace-member"]
|
||||
|
||||
[build-system]
|
||||
requires = ["setuptools>=42"]
|
||||
build-backend = "setuptools.build_meta"
|
||||
|
||||
[tool.uv.sources]
|
||||
local = { path = "./local" }
|
||||
local-editable = { path = "./local-editable", editable = true }
|
||||
workspace-member = { workspace = true }
|
||||
|
||||
[tool.uv.workspace]
|
||||
members = ["workspace-member"]
|
||||
"#,
|
||||
)?;
|
||||
|
||||
// Add a local package, local editable package, and then a workspace member
|
||||
// as a dependency.
|
||||
let local = context.temp_dir.child("local");
|
||||
local.create_dir_all()?;
|
||||
let local_pyproject = local.child("pyproject.toml");
|
||||
local_pyproject.write_str(
|
||||
r#"
|
||||
[project]
|
||||
name = "local"
|
||||
version = "0.1.0"
|
||||
requires-python = ">=3.12"
|
||||
"#,
|
||||
)?;
|
||||
|
||||
let local_editable = context.temp_dir.child("local-editable");
|
||||
local_editable.create_dir_all()?;
|
||||
let local_editable_pyproject = local_editable.child("pyproject.toml");
|
||||
local_editable_pyproject.write_str(
|
||||
r#"
|
||||
[project]
|
||||
name = "local-editable"
|
||||
version = "0.1.0"
|
||||
requires-python = ">=3.12"
|
||||
"#,
|
||||
)?;
|
||||
|
||||
let workspace_member = context.temp_dir.child("workspace-member");
|
||||
workspace_member.create_dir_all()?;
|
||||
let member_pyproject = workspace_member.child("pyproject.toml");
|
||||
member_pyproject.write_str(
|
||||
r#"
|
||||
[project]
|
||||
name = "workspace-member"
|
||||
version = "0.1.0"
|
||||
requires-python = ">=3.12"
|
||||
"#,
|
||||
)?;
|
||||
|
||||
context.lock().assert().success();
|
||||
uv_snapshot!(context.filters(), context.sync().arg("--no-install-local"), @r"
|
||||
success: true
|
||||
exit_code: 0
|
||||
----- stdout -----
|
||||
|
||||
----- stderr -----
|
||||
Resolved 7 packages in [TIME]
|
||||
Prepared 3 packages in [TIME]
|
||||
Installed 3 packages in [TIME]
|
||||
+ anyio==3.7.0
|
||||
+ idna==3.6
|
||||
+ sniffio==1.3.1
|
||||
");
|
||||
|
||||
Ok(())
|
||||
}
|
||||
|
||||
/// Avoid syncing the target package when `--no-install-package` is provided.
|
||||
#[test]
|
||||
fn no_install_package() -> Result<()> {
|
||||
|
|
|
|||
|
|
@ -540,6 +540,8 @@ uv add [OPTIONS] <PACKAGES|--requirements <REQUIREMENTS>>
|
|||
<p>May also be set with the <code>UV_NO_CACHE</code> environment variable.</p></dd><dt id="uv-add--no-config"><a href="#uv-add--no-config"><code>--no-config</code></a></dt><dd><p>Avoid discovering configuration files (<code>pyproject.toml</code>, <code>uv.toml</code>).</p>
|
||||
<p>Normally, configuration files are discovered in the current directory, parent directories, or user configuration directories.</p>
|
||||
<p>May also be set with the <code>UV_NO_CONFIG</code> environment variable.</p></dd><dt id="uv-add--no-index"><a href="#uv-add--no-index"><code>--no-index</code></a></dt><dd><p>Ignore the registry index (e.g., PyPI), instead relying on direct URL dependencies and those provided via <code>--find-links</code></p>
|
||||
</dd><dt id="uv-add--no-install-local"><a href="#uv-add--no-install-local"><code>--no-install-local</code></a></dt><dd><p>Do not install local path dependencies</p>
|
||||
<p>Skips the current project, workspace members, and any other local (path or editable) packages. Only remote/indexed dependencies are installed. Useful in Docker builds to cache heavy third-party dependencies first and layer local packages separately.</p>
|
||||
</dd><dt id="uv-add--no-install-project"><a href="#uv-add--no-install-project"><code>--no-install-project</code></a></dt><dd><p>Do not install the current project.</p>
|
||||
<p>By default, the current project is installed into the environment with all of its dependencies. The <code>--no-install-project</code> option allows the project to be excluded, but all of its dependencies are still installed. This is particularly useful in situations like building Docker images where installing the project separately from its dependencies allows optimal layer caching.</p>
|
||||
</dd><dt id="uv-add--no-install-workspace"><a href="#uv-add--no-install-workspace"><code>--no-install-workspace</code></a></dt><dd><p>Do not install any workspace members, including the current project.</p>
|
||||
|
|
@ -1127,6 +1129,8 @@ uv sync [OPTIONS]
|
|||
<p>This option always takes precedence over default groups, <code>--all-groups</code>, and <code>--group</code>.</p>
|
||||
<p>May be provided multiple times.</p>
|
||||
</dd><dt id="uv-sync--no-index"><a href="#uv-sync--no-index"><code>--no-index</code></a></dt><dd><p>Ignore the registry index (e.g., PyPI), instead relying on direct URL dependencies and those provided via <code>--find-links</code></p>
|
||||
</dd><dt id="uv-sync--no-install-local"><a href="#uv-sync--no-install-local"><code>--no-install-local</code></a></dt><dd><p>Do not install local path dependencies</p>
|
||||
<p>Skips the current project, workspace members, and any other local (path or editable) packages. Only remote/indexed dependencies are installed. Useful in Docker builds to cache heavy third-party dependencies first and layer local packages separately.</p>
|
||||
</dd><dt id="uv-sync--no-install-package"><a href="#uv-sync--no-install-package"><code>--no-install-package</code></a> <i>no-install-package</i></dt><dd><p>Do not install the given package(s).</p>
|
||||
<p>By default, all of the project's dependencies are installed into the environment. The <code>--no-install-package</code> option allows exclusion of specific packages. Note this can result in a broken environment, and should be used with caution.</p>
|
||||
</dd><dt id="uv-sync--no-install-project"><a href="#uv-sync--no-install-project"><code>--no-install-project</code></a></dt><dd><p>Do not install the current project.</p>
|
||||
|
|
@ -1544,7 +1548,9 @@ uv export [OPTIONS]
|
|||
</dd><dt id="uv-export--no-dev"><a href="#uv-export--no-dev"><code>--no-dev</code></a></dt><dd><p>Disable the development dependency group.</p>
|
||||
<p>This option is an alias of <code>--no-group dev</code>. See <code>--no-default-groups</code> to disable all default groups instead.</p>
|
||||
<p>May also be set with the <code>UV_NO_DEV</code> environment variable.</p></dd><dt id="uv-export--no-editable"><a href="#uv-export--no-editable"><code>--no-editable</code></a></dt><dd><p>Export any editable dependencies, including the project and any workspace members, as non-editable</p>
|
||||
<p>May also be set with the <code>UV_NO_EDITABLE</code> environment variable.</p></dd><dt id="uv-export--no-emit-package"><a href="#uv-export--no-emit-package"><code>--no-emit-package</code></a>, <code>--no-install-package</code> <i>no-emit-package</i></dt><dd><p>Do not emit the given package(s).</p>
|
||||
<p>May also be set with the <code>UV_NO_EDITABLE</code> environment variable.</p></dd><dt id="uv-export--no-emit-local"><a href="#uv-export--no-emit-local"><code>--no-emit-local</code></a>, <code>--no-install-local</code></dt><dd><p>Do not include local path dependencies in the exported requirements.</p>
|
||||
<p>Omits the current project, workspace members, and any other local (path or editable) packages from the export. Only remote/indexed dependencies are written. Useful for Docker and CI flows that want to export and cache third-party dependencies first.</p>
|
||||
</dd><dt id="uv-export--no-emit-package"><a href="#uv-export--no-emit-package"><code>--no-emit-package</code></a>, <code>--no-install-package</code> <i>no-emit-package</i></dt><dd><p>Do not emit the given package(s).</p>
|
||||
<p>By default, all of the project's dependencies are included in the exported requirements file. The <code>--no-emit-package</code> option allows exclusion of specific packages.</p>
|
||||
</dd><dt id="uv-export--no-emit-project"><a href="#uv-export--no-emit-project"><code>--no-emit-project</code></a>, <code>--no-install-project</code></dt><dd><p>Do not emit the current project.</p>
|
||||
<p>By default, the current project is included in the exported requirements file with all of its dependencies. The <code>--no-emit-project</code> option allows the project to be excluded, but all of its dependencies to remain included.</p>
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue