Fix hardlinks in tar unpacking (#11221)

In https://github.com/astral-sh/tokio-tar/pull/2, we accidentally
changed the `target_base` from the target base to the parent of the
file. This would cause hardlink unpacking to fail.

Example: A hardlink at `hardlinked-0.1.0/pyproject.toml` pointing to
`hardlinked-0.1.0/pyproject.toml.real` would try pointing to
`hardlinked-0.1.0/hardlinked-0.1.0/pyproject.toml.real` instead and fail
the unpacking.

The actual fix is in astral-tokio-tar, on the uv side there are only tests.

Fixes #11213
This commit is contained in:
konsti 2025-02-04 18:38:22 +01:00 committed by GitHub
parent 748582ee6f
commit ac1004284a
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
3 changed files with 79 additions and 2 deletions

2
Cargo.lock generated
View File

@ -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",

View File

@ -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" }

View File

@ -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(())
}