diff --git a/Cargo.lock b/Cargo.lock index fe517ce49..bab43c043 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -1854,6 +1854,7 @@ dependencies = [ "tracing", "uv-fs", "uv-normalize", + "uv-warnings", "walkdir", "zip", ] diff --git a/crates/install-wheel-rs/Cargo.toml b/crates/install-wheel-rs/Cargo.toml index a05e47caa..c7eda5cbc 100644 --- a/crates/install-wheel-rs/Cargo.toml +++ b/crates/install-wheel-rs/Cargo.toml @@ -23,9 +23,10 @@ name = "install_wheel_rs" distribution-filename = { workspace = true } pep440_rs = { workspace = true } platform-tags = { workspace = true } -uv-normalize = { workspace = true } -uv-fs = { workspace = true } pypi-types = { workspace = true } +uv-fs = { workspace = true } +uv-normalize = { workspace = true } +uv-warnings = { workspace = true } clap = { workspace = true, optional = true, features = ["derive"] } configparser = { workspace = true } diff --git a/crates/install-wheel-rs/src/linker.rs b/crates/install-wheel-rs/src/linker.rs index a71b8a32d..c943483cd 100644 --- a/crates/install-wheel-rs/src/linker.rs +++ b/crates/install-wheel-rs/src/linker.rs @@ -16,6 +16,7 @@ use distribution_filename::WheelFilename; use pep440_rs::Version; use pypi_types::DirectUrl; use uv_normalize::PackageName; +use uv_warnings::warn_user_once; use crate::script::{scripts_from_ini, Script}; use crate::wheel::{ @@ -355,7 +356,8 @@ fn clone_recursive( debug!( "Failed to clone `{}` to temporary location `{}`, attempting to copy files as a fallback", from.display(), - tempfile.display()); + tempfile.display(), + ); *attempt = Attempt::UseCopyFallback; fs::copy(&from, &to)?; } @@ -401,6 +403,7 @@ fn clone_recursive( } else { fs::copy(&from, &to)?; } + warn_user_once!("Failed to clone files; falling back to full copy. This may lead to degraded performance. If this is intentional, use `--link-mode=copy` to suppress this warning.\n\nhint: If the cache and target directories are on different filesystems, reflinking may not be supported."); } } @@ -524,6 +527,7 @@ fn hardlink_wheel_files( } Attempt::UseCopyFallback => { fs::copy(path, &out_path)?; + warn_user_once!("Failed to hardlink files; falling back to full copy. This may lead to degraded performance. If this is intentional, use `--link-mode=copy` to suppress this warning.\n\nhint: If the cache and target directories are on different filesystems, hardlinking may not be supported."); } } diff --git a/crates/uv/tests/pip_sync.rs b/crates/uv/tests/pip_sync.rs index c739d1c37..9fe22150a 100644 --- a/crates/uv/tests/pip_sync.rs +++ b/crates/uv/tests/pip_sync.rs @@ -5104,6 +5104,10 @@ fn target_no_build_isolation() -> Result<()> { /// Sync to a `--prefix` directory. #[test] +#[cfg_attr( + target_os = "macos", + ignore = "On macOS, we fail to reflink due to a non-existent site-packages directory" +)] fn prefix() -> Result<()> { let context = TestContext::new("3.12"); @@ -5111,10 +5115,12 @@ fn prefix() -> Result<()> { let requirements_in = context.temp_dir.child("requirements.in"); requirements_in.write_str("iniconfig==2.0.0")?; + let prefix = context.temp_dir.child("prefix"); + uv_snapshot!(context.pip_sync() .arg("requirements.in") .arg("--prefix") - .arg("prefix"), @r###" + .arg(prefix.path()), @r###" success: true exit_code: 0 ----- stdout ----- @@ -5149,7 +5155,7 @@ fn prefix() -> Result<()> { uv_snapshot!(context.pip_sync() .arg("requirements.in") .arg("--prefix") - .arg("prefix"), @r###" + .arg(prefix.path()), @r###" success: true exit_code: 0 ----- stdout -----