mirror of
https://github.com/astral-sh/uv.git
synced 2025-07-07 13:25:00 +00:00
Use fs_err for cachedir errors (#3304)
When running ``` set UV_CACHE_DIR=%LOCALAPPDATA%\uv\cache-foo && uv venv venv ``` in windows CMD, the error would be just ``` error: The system cannot find the path specified. (os error 3) ``` The problem is that the first action in the cache dir is adding the tag, and the `cachedir` crate is using `std::fs` instead of `fs_err`. I've copied the two functions we use from the crate and changed the import from `std::fs` to `fs_err`. The new error is ``` error: failed to open file `C:\Users\Konstantin\AppData\Local\uv\cache-foo \CACHEDIR.TAG` Caused by: The system cannot find the path specified. (os error 3) ``` which correctly explains the problem. Closes #3280
This commit is contained in:
parent
22d8619c37
commit
1344cfae4b
10 changed files with 78 additions and 7 deletions
3
Cargo.lock
generated
3
Cargo.lock
generated
|
@ -4540,7 +4540,6 @@ name = "uv-cache"
|
|||
version = "0.0.1"
|
||||
dependencies = [
|
||||
"cache-key",
|
||||
"cachedir",
|
||||
"clap",
|
||||
"directories",
|
||||
"distribution-types",
|
||||
|
@ -4761,6 +4760,7 @@ name = "uv-fs"
|
|||
version = "0.0.1"
|
||||
dependencies = [
|
||||
"backoff",
|
||||
"cachedir",
|
||||
"dunce",
|
||||
"encoding_rs_io",
|
||||
"fs-err",
|
||||
|
@ -5011,7 +5011,6 @@ name = "uv-virtualenv"
|
|||
version = "0.0.4"
|
||||
dependencies = [
|
||||
"anstream",
|
||||
"cachedir",
|
||||
"clap",
|
||||
"directories",
|
||||
"fs-err",
|
||||
|
|
|
@ -20,7 +20,6 @@ pypi-types = { workspace = true }
|
|||
uv-fs = { workspace = true, features = ["tokio"] }
|
||||
uv-normalize = { workspace = true }
|
||||
|
||||
cachedir = { workspace = true }
|
||||
clap = { workspace = true, features = ["derive", "env"], optional = true }
|
||||
directories = { workspace = true }
|
||||
fs-err = { workspace = true, features = ["tokio"] }
|
||||
|
|
|
@ -13,7 +13,7 @@ use tracing::debug;
|
|||
|
||||
use distribution_types::InstalledDist;
|
||||
use pypi_types::Metadata23;
|
||||
use uv_fs::directories;
|
||||
use uv_fs::{cachedir, directories};
|
||||
use uv_normalize::PackageName;
|
||||
|
||||
pub use crate::by_timestamp::CachedByTimestamp;
|
||||
|
|
|
@ -16,6 +16,7 @@ workspace = true
|
|||
uv-warnings = { workspace = true }
|
||||
|
||||
backoff = { workspace = true }
|
||||
cachedir = { workspace = true }
|
||||
dunce = { workspace = true }
|
||||
encoding_rs_io = { workspace = true }
|
||||
fs-err = { workspace = true }
|
||||
|
|
42
crates/uv-fs/src/cachedir.rs
Normal file
42
crates/uv-fs/src/cachedir.rs
Normal file
|
@ -0,0 +1,42 @@
|
|||
//! Vendored from cachedir 0.3.1 to replace `std::fs` with `fs_err`.
|
||||
|
||||
use std::io::Write;
|
||||
use std::{io, path};
|
||||
|
||||
use cachedir::HEADER;
|
||||
|
||||
/// Adds a tag to the specified `directory`.
|
||||
///
|
||||
/// Will return an error if:
|
||||
///
|
||||
/// * The `directory` exists and contains a `CACHEDIR.TAG` file, regardless of its content.
|
||||
/// * The file can't be created for any reason (the `directory` doesn't exist, permission error,
|
||||
/// can't write to the file etc.)
|
||||
pub fn add_tag<P: AsRef<path::Path>>(directory: P) -> io::Result<()> {
|
||||
let directory = directory.as_ref();
|
||||
match fs_err::OpenOptions::new()
|
||||
.write(true)
|
||||
.create_new(true)
|
||||
.open(directory.join("CACHEDIR.TAG"))
|
||||
{
|
||||
Ok(mut cachedir_tag) => cachedir_tag.write_all(HEADER),
|
||||
Err(e) => Err(e),
|
||||
}
|
||||
}
|
||||
|
||||
/// Ensures the tag exists in `directory`.
|
||||
///
|
||||
/// This function considers the `CACHEDIR.TAG` file in `directory` existing, regardless of its
|
||||
/// content, as a success.
|
||||
///
|
||||
/// Will return an error if The tag file doesn't exist and can't be created for any reason
|
||||
/// (the `directory` doesn't exist, permission error, can't write to the file etc.).
|
||||
pub fn ensure_tag<P: AsRef<path::Path>>(directory: P) -> io::Result<()> {
|
||||
match add_tag(directory) {
|
||||
Err(e) => match e.kind() {
|
||||
io::ErrorKind::AlreadyExists => Ok(()),
|
||||
_ => Err(e),
|
||||
},
|
||||
other => other,
|
||||
}
|
||||
}
|
|
@ -10,6 +10,7 @@ use uv_warnings::warn_user;
|
|||
|
||||
pub use crate::path::*;
|
||||
|
||||
pub mod cachedir;
|
||||
mod path;
|
||||
|
||||
/// Reads data from the path and requires that it be valid UTF-8.
|
||||
|
|
|
@ -29,7 +29,6 @@ uv-interpreter = { workspace = true }
|
|||
uv-version = { workspace = true }
|
||||
|
||||
anstream = { workspace = true }
|
||||
cachedir = { workspace = true }
|
||||
clap = { workspace = true, features = ["derive"], optional = true }
|
||||
directories = { workspace = true }
|
||||
fs-err = { workspace = true }
|
||||
|
|
|
@ -12,7 +12,7 @@ use pypi_types::Scheme;
|
|||
use tracing::info;
|
||||
|
||||
use crate::{Error, Prompt};
|
||||
use uv_fs::Simplified;
|
||||
use uv_fs::{cachedir, Simplified};
|
||||
use uv_interpreter::{Interpreter, Virtualenv};
|
||||
use uv_version::version;
|
||||
|
||||
|
|
|
@ -5,7 +5,6 @@ use std::vec;
|
|||
|
||||
use anstream::eprint;
|
||||
use anyhow::Result;
|
||||
|
||||
use itertools::Itertools;
|
||||
use miette::{Diagnostic, IntoDiagnostic};
|
||||
use owo_colors::OwoColorize;
|
||||
|
|
|
@ -527,3 +527,34 @@ fn verify_nested_pyvenv_cfg() -> Result<()> {
|
|||
|
||||
Ok(())
|
||||
}
|
||||
|
||||
/// See <https://github.com/astral-sh/uv/issues/3280>
|
||||
#[test]
|
||||
#[cfg(windows)]
|
||||
fn path_with_trailing_space_gives_proper_error() {
|
||||
let context = VenvTestContext::new(&["3.12"]);
|
||||
|
||||
let mut filters = context.filters();
|
||||
filters.push((
|
||||
regex::escape(&context.cache_dir.path().display().to_string()).to_string(),
|
||||
r"C:\Path\to\Cache\dir".to_string(),
|
||||
));
|
||||
// Create a virtual environment at `.venv`.
|
||||
uv_snapshot!(filters, Command::new(get_bin())
|
||||
.arg("venv")
|
||||
.arg(context.venv.as_os_str())
|
||||
.arg("--python")
|
||||
.arg("3.12")
|
||||
.env("UV_CACHE_DIR", format!("{} ", context.cache_dir.path().display()))
|
||||
.env("UV_TEST_PYTHON_PATH", context.python_path.clone())
|
||||
.current_dir(context.temp_dir.path()), @r###"
|
||||
success: false
|
||||
exit_code: 2
|
||||
----- stdout -----
|
||||
|
||||
----- stderr -----
|
||||
error: failed to open file `C:\Path\to\Cache\dir \CACHEDIR.TAG`
|
||||
Caused by: The system cannot find the path specified. (os error 3)
|
||||
"###
|
||||
);
|
||||
}
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue