Overwrite existing files when hardlinking (#402)

## Summary

Closes https://github.com/astral-sh/puffin/issues/390.

## Test Plan

Installed `jupyter_core==5.5.0`, then removed the `jupyter_core` and
`jupyter_core-5.5.0.dist-info` directories from my virtualenv manually,
but left `jupyter.py`. I then re-ran `puffin pip-compile`, and verified
that it errored on `main` but succeeded here.
This commit is contained in:
Charlie Marsh 2023-11-10 12:24:19 -08:00 committed by GitHub
parent 56a4b51eb6
commit 06b312de7e
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23

View file

@ -403,16 +403,32 @@ fn hardlink_wheel_files(
// Fallback to copying if hardlinks aren't supported for this installation.
match attempt {
Attempt::Initial => {
// Once https://github.com/rust-lang/rust/issues/86442 is stable, use that
if fs::hard_link(entry.path(), &out_path).is_err() {
fs::copy(entry.path(), &out_path)?;
attempt = Attempt::UseCopyFallback;
} else {
attempt = Attempt::Subsequent;
// Once https://github.com/rust-lang/rust/issues/86442 is stable, use that.
attempt = Attempt::Subsequent;
if let Err(err) = fs::hard_link(entry.path(), &out_path) {
// If the file already exists, remove it and try again.
if err.kind() == std::io::ErrorKind::AlreadyExists {
fs::remove_file(&out_path)?;
if fs::hard_link(entry.path(), &out_path).is_err() {
fs::copy(entry.path(), &out_path)?;
attempt = Attempt::UseCopyFallback;
}
} else {
fs::copy(entry.path(), &out_path)?;
attempt = Attempt::UseCopyFallback;
}
}
}
Attempt::Subsequent => {
fs::hard_link(entry.path(), &out_path)?;
if let Err(err) = fs::hard_link(entry.path(), &out_path) {
// If the file already exists, remove it and try again.
if err.kind() == std::io::ErrorKind::AlreadyExists {
fs::remove_file(&out_path)?;
fs::hard_link(entry.path(), &out_path)?;
} else {
return Err(err.into());
}
}
}
Attempt::UseCopyFallback => {
fs::copy(entry.path(), &out_path)?;