diff --git a/Cargo.lock b/Cargo.lock index 2662004c7..047c17104 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -156,7 +156,7 @@ dependencies = [ [[package]] name = "astral-tokio-tar" version = "0.5.0" -source = "git+https://github.com/astral-sh/tokio-tar?rev=ba2b140f27d081c463335f0d68b5f8df8e6c845e#ba2b140f27d081c463335f0d68b5f8df8e6c845e" +source = "git+https://github.com/astral-sh/tokio-tar?rev=efeaea927c7a40ee66121de2e1bebfd5d7a4a602#efeaea927c7a40ee66121de2e1bebfd5d7a4a602" dependencies = [ "filetime", "futures-core", diff --git a/Cargo.toml b/Cargo.toml index 4adcf0b84..6b7c6b3e0 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -73,7 +73,7 @@ uv-workspace = { path = "crates/uv-workspace" } anstream = { version = "0.6.15" } anyhow = { version = "1.0.89" } arcstr = { version = "1.2.0" } -astral-tokio-tar = { git = "https://github.com/astral-sh/tokio-tar", rev = "ba2b140f27d081c463335f0d68b5f8df8e6c845e" } +astral-tokio-tar = { git = "https://github.com/astral-sh/tokio-tar", rev = "efeaea927c7a40ee66121de2e1bebfd5d7a4a602" } async-channel = { version = "2.3.1" } async-compression = { version = "0.4.12", features = ["bzip2", "gzip", "xz", "zstd"] } async-trait = { version = "0.1.82" } diff --git a/crates/uv/tests/it/build.rs b/crates/uv/tests/it/build.rs index 9233a6ac7..1f4cf328f 100644 --- a/crates/uv/tests/it/build.rs +++ b/crates/uv/tests/it/build.rs @@ -1746,3 +1746,80 @@ fn build_version_mismatch() -> Result<()> { "###); Ok(()) } + +#[cfg(unix)] // Symlinks aren't universally available on windows. +#[test] +fn build_with_symlink() -> Result<()> { + let context = TestContext::new("3.12"); + context + .temp_dir + .child("pyproject.toml.real") + .write_str(indoc! {r#" + [project] + name = "softlinked" + version = "0.1.0" + requires-python = ">=3.12" + + [build-system] + requires = ["hatchling"] + build-backend = "hatchling.build" + "#})?; + std::os::unix::fs::symlink( + context.temp_dir.child("pyproject.toml.real"), + context.temp_dir.child("pyproject.toml"), + )?; + context + .temp_dir + .child("src/softlinked/__init__.py") + .touch()?; + uv_snapshot!(context.filters(), context.build(), @r###" + success: true + exit_code: 0 + ----- stdout ----- + + ----- stderr ----- + Building source distribution... + Building wheel from source distribution... + Successfully built dist/softlinked-0.1.0.tar.gz + Successfully built dist/softlinked-0.1.0-py3-none-any.whl + "###); + Ok(()) +} + +#[test] +fn build_with_hardlink() -> Result<()> { + let context = TestContext::new("3.12"); + context + .temp_dir + .child("pyproject.toml.real") + .write_str(indoc! {r#" + [project] + name = "hardlinked" + version = "0.1.0" + requires-python = ">=3.12" + + [build-system] + requires = ["hatchling"] + build-backend = "hatchling.build" + "#})?; + fs_err::hard_link( + context.temp_dir.child("pyproject.toml.real"), + context.temp_dir.child("pyproject.toml"), + )?; + context + .temp_dir + .child("src/hardlinked/__init__.py") + .touch()?; + uv_snapshot!(context.filters(), context.build(), @r###" + success: true + exit_code: 0 + ----- stdout ----- + + ----- stderr ----- + Building source distribution... + Building wheel from source distribution... + Successfully built dist/hardlinked-0.1.0.tar.gz + Successfully built dist/hardlinked-0.1.0-py3-none-any.whl + "###); + Ok(()) +}