diff --git a/Cargo.lock b/Cargo.lock index 5efe51109..f27858fb2 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -1443,16 +1443,6 @@ dependencies = [ "tokio", ] -[[package]] -name = "fs2" -version = "0.4.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9564fc758e15025b46aa6643b1b77d047d1a56a1aea6e01002ac0c7026876213" -dependencies = [ - "libc", - "winapi", -] - [[package]] name = "futures" version = "0.3.31" @@ -5892,7 +5882,6 @@ dependencies = [ "either", "encoding_rs_io", "fs-err", - "fs2", "junction", "path-slash", "percent-encoding", diff --git a/Cargo.toml b/Cargo.toml index 92092b822..d93880be4 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -112,7 +112,6 @@ encoding_rs_io = { version = "0.1.7" } etcetera = { version = "0.11.0" } flate2 = { version = "1.0.33", default-features = false, features = ["zlib-rs"] } fs-err = { version = "3.0.0", features = ["tokio"] } -fs2 = { version = "0.4.3" } futures = { version = "0.3.30" } glob = { version = "0.3.1" } globset = { version = "0.4.15" } diff --git a/crates/uv-fs/Cargo.toml b/crates/uv-fs/Cargo.toml index a9ac2126d..35608e7bd 100644 --- a/crates/uv-fs/Cargo.toml +++ b/crates/uv-fs/Cargo.toml @@ -20,14 +20,13 @@ dunce = { workspace = true } either = { workspace = true } encoding_rs_io = { workspace = true } fs-err = { workspace = true } -fs2 = { workspace = true } path-slash = { workspace = true } percent-encoding = { workspace = true } same-file = { workspace = true } schemars = { workspace = true, optional = true } serde = { workspace = true, optional = true } tempfile = { workspace = true } -tokio = { workspace = true, optional = true} +tokio = { workspace = true, optional = true } tracing = { workspace = true } [target.'cfg(any(unix, target_os = "wasi", target_os = "redox"))'.dependencies] diff --git a/crates/uv-fs/src/lib.rs b/crates/uv-fs/src/lib.rs index c73f486f8..f5ad66cef 100644 --- a/crates/uv-fs/src/lib.rs +++ b/crates/uv-fs/src/lib.rs @@ -1,9 +1,7 @@ use std::borrow::Cow; use std::fmt::Display; -use std::io; use std::path::{Path, PathBuf}; -use fs2::FileExt; use tempfile::NamedTempFile; use tracing::{debug, error, info, trace, warn}; @@ -555,10 +553,12 @@ pub fn persist_with_retry_sync( /// Iterate over the subdirectories of a directory. /// /// If the directory does not exist, returns an empty iterator. -pub fn directories(path: impl AsRef) -> Result, io::Error> { +pub fn directories( + path: impl AsRef, +) -> Result, std::io::Error> { let entries = match path.as_ref().read_dir() { Ok(entries) => Some(entries), - Err(err) if err.kind() == io::ErrorKind::NotFound => None, + Err(err) if err.kind() == std::io::ErrorKind::NotFound => None, Err(err) => return Err(err), }; Ok(entries @@ -578,10 +578,10 @@ pub fn directories(path: impl AsRef) -> Result) -> Result, io::Error> { +pub fn entries(path: impl AsRef) -> Result, std::io::Error> { let entries = match path.as_ref().read_dir() { Ok(entries) => Some(entries), - Err(err) if err.kind() == io::ErrorKind::NotFound => None, + Err(err) if err.kind() == std::io::ErrorKind::NotFound => None, Err(err) => return Err(err), }; Ok(entries @@ -600,10 +600,10 @@ pub fn entries(path: impl AsRef) -> Result, /// Iterate over the files in a directory. /// /// If the directory does not exist, returns an empty iterator. -pub fn files(path: impl AsRef) -> Result, io::Error> { +pub fn files(path: impl AsRef) -> Result, std::io::Error> { let entries = match path.as_ref().read_dir() { Ok(entries) => Some(entries), - Err(err) if err.kind() == io::ErrorKind::NotFound => None, + Err(err) if err.kind() == std::io::ErrorKind::NotFound => None, Err(err) => return Err(err), }; Ok(entries @@ -653,17 +653,17 @@ pub fn is_virtualenv_base(path: impl AsRef) -> bool { } /// Whether the error is due to a lock being held. -fn is_known_already_locked_error(err: &std::io::Error) -> bool { - if matches!(err.kind(), std::io::ErrorKind::WouldBlock) { - return true; +fn is_known_already_locked_error(err: &std::fs::TryLockError) -> bool { + match err { + std::fs::TryLockError::WouldBlock => true, + std::fs::TryLockError::Error(err) => { + // On Windows, we've seen: Os { code: 33, kind: Uncategorized, message: "The process cannot access the file because another process has locked a portion of the file." } + if cfg!(windows) && err.raw_os_error() == Some(33) { + return true; + } + false + } } - - // On Windows, we've seen: Os { code: 33, kind: Uncategorized, message: "The process cannot access the file because another process has locked a portion of the file." } - if cfg!(windows) && err.raw_os_error() == Some(33) { - return true; - } - - false } /// A file lock that is automatically released when dropped. @@ -678,7 +678,7 @@ impl LockedFile { "Checking lock for `{resource}` at `{}`", file.path().user_display() ); - match file.file().try_lock_exclusive() { + match file.file().try_lock() { Ok(()) => { debug!("Acquired lock for `{resource}`"); Ok(Self(file)) @@ -692,15 +692,7 @@ impl LockedFile { "Waiting to acquire lock for `{resource}` at `{}`", file.path().user_display(), ); - file.file().lock_exclusive().map_err(|err| { - // Not an fs_err method, we need to build our own path context - std::io::Error::other(format!( - "Could not acquire lock for `{resource}` at `{}`: {}", - file.path().user_display(), - err - )) - })?; - + file.lock()?; debug!("Acquired lock for `{resource}`"); Ok(Self(file)) } @@ -713,7 +705,7 @@ impl LockedFile { "Checking lock for `{resource}` at `{}`", file.path().user_display() ); - match file.file().try_lock_exclusive() { + match file.try_lock() { Ok(()) => { debug!("Acquired lock for `{resource}`"); Some(Self(file)) @@ -739,8 +731,7 @@ impl LockedFile { "Checking shared lock for `{resource}` at `{}`", file.path().user_display() ); - // TODO(konsti): Update fs_err to support this. - match FileExt::try_lock_shared(file.file()) { + match file.try_lock_shared() { Ok(()) => { debug!("Acquired shared lock for `{resource}`"); Ok(Self(file)) @@ -754,15 +745,7 @@ impl LockedFile { "Waiting to acquire shared lock for `{resource}` at `{}`", file.path().user_display(), ); - FileExt::lock_shared(file.file()).map_err(|err| { - // Not an fs_err method, we need to build our own path context - std::io::Error::other(format!( - "Could not acquire shared lock for `{resource}` at `{}`: {}", - file.path().user_display(), - err - )) - })?; - + file.lock_shared()?; debug!("Acquired shared lock for `{resource}`"); Ok(Self(file)) } @@ -884,11 +867,10 @@ impl LockedFile { impl Drop for LockedFile { fn drop(&mut self) { - if let Err(err) = fs2::FileExt::unlock(self.0.file()) { + if let Err(err) = self.0.unlock() { error!( - "Failed to unlock {}; program may be stuck: {}", - self.0.path().display(), - err + "Failed to unlock resource at `{}`; program may be stuck: {err}", + self.0.path().display() ); } else { debug!("Released lock at `{}`", self.0.path().display());