mirror of
https://github.com/astral-sh/uv.git
synced 2025-11-01 04:17:37 +00:00
Avoid overwriting symlinks in pip compile output (#6487)
## Summary Closes https://github.com/astral-sh/uv/issues/6485.
This commit is contained in:
parent
1cd80139af
commit
9b42142fe7
2 changed files with 56 additions and 0 deletions
|
|
@ -1,3 +1,4 @@
|
|||
use std::borrow::Cow;
|
||||
use std::env;
|
||||
use std::io::stdout;
|
||||
use std::path::Path;
|
||||
|
|
@ -643,6 +644,10 @@ impl<'a> OutputWriter<'a> {
|
|||
/// Commit the buffer to the output file.
|
||||
async fn commit(self) -> std::io::Result<()> {
|
||||
if let Some(output_file) = self.output_file {
|
||||
// If the output file is an existing symlink, write to the destination instead.
|
||||
let output_file = fs_err::read_link(output_file)
|
||||
.map(Cow::Owned)
|
||||
.unwrap_or(Cow::Borrowed(output_file));
|
||||
let stream = anstream::adapter::strip_bytes(&self.buffer).into_vec();
|
||||
uv_fs::write_atomic(output_file, &stream).await?;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -11907,3 +11907,54 @@ fn invalid_extra() -> Result<()> {
|
|||
|
||||
Ok(())
|
||||
}
|
||||
|
||||
/// Respect symlinks of output files.
|
||||
#[test]
|
||||
#[cfg(not(windows))]
|
||||
fn symlink() -> Result<()> {
|
||||
let context = TestContext::new("3.8");
|
||||
let requirements_in = context.temp_dir.child("requirements.in");
|
||||
requirements_in.write_str("anyio")?;
|
||||
|
||||
// Create an output file.
|
||||
let requirements_txt = context.temp_dir.child("requirements.txt");
|
||||
requirements_txt.write_str("anyio")?;
|
||||
|
||||
// Create a symlink to the output file.
|
||||
let symlink = context.temp_dir.child("requirements-symlink.txt");
|
||||
symlink.symlink_to_file(requirements_txt.path())?;
|
||||
|
||||
// Write to the symlink.
|
||||
uv_snapshot!(context.pip_compile()
|
||||
.arg("requirements.in")
|
||||
.arg("--output-file")
|
||||
.arg("requirements-symlink.txt"), @r###"
|
||||
success: true
|
||||
exit_code: 0
|
||||
----- stdout -----
|
||||
# This file was autogenerated by uv via the following command:
|
||||
# uv pip compile --cache-dir [CACHE_DIR] requirements.in --output-file requirements-symlink.txt
|
||||
anyio==4.3.0
|
||||
# via -r requirements.in
|
||||
exceptiongroup==1.2.0
|
||||
# via anyio
|
||||
idna==3.6
|
||||
# via anyio
|
||||
sniffio==1.3.1
|
||||
# via anyio
|
||||
typing-extensions==4.10.0
|
||||
# via anyio
|
||||
|
||||
----- stderr -----
|
||||
Resolved 5 packages in [TIME]
|
||||
"###
|
||||
);
|
||||
|
||||
// The symlink should still be a symlink.
|
||||
assert!(symlink.path().symlink_metadata()?.file_type().is_symlink());
|
||||
|
||||
// The destination of the symlink should be the same as the output file.
|
||||
assert_eq!(symlink.path().read_link()?, requirements_txt.path());
|
||||
|
||||
Ok(())
|
||||
}
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue