-
Notifications
You must be signed in to change notification settings - Fork 2.9k
Add --force flag for uv cache clean
#15992
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Changes from all commits
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -652,6 +652,20 @@ pub fn is_virtualenv_base(path: impl AsRef<Path>) -> bool { | |
| path.as_ref().join("pyvenv.cfg").is_file() | ||
| } | ||
|
|
||
| /// 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; | ||
| } | ||
|
|
||
| // 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. | ||
| #[derive(Debug)] | ||
| #[must_use] | ||
|
|
@@ -671,7 +685,7 @@ impl LockedFile { | |
| } | ||
| Err(err) => { | ||
| // Log error code and enum kind to help debugging more exotic failures. | ||
| if err.kind() != std::io::ErrorKind::WouldBlock { | ||
| if !is_known_already_locked_error(&err) { | ||
| debug!("Try lock error: {err:?}"); | ||
| } | ||
| info!( | ||
|
|
@@ -693,6 +707,28 @@ impl LockedFile { | |
| } | ||
| } | ||
|
|
||
| /// Inner implementation for [`LockedFile::acquire_no_wait`]. | ||
| fn lock_file_no_wait(file: fs_err::File, resource: &str) -> Option<Self> { | ||
| trace!( | ||
| "Checking lock for `{resource}` at `{}`", | ||
| file.path().user_display() | ||
| ); | ||
| match file.file().try_lock_exclusive() { | ||
| Ok(()) => { | ||
| debug!("Acquired lock for `{resource}`"); | ||
| Some(Self(file)) | ||
| } | ||
| Err(err) => { | ||
| // Log error code and enum kind to help debugging more exotic failures. | ||
| if !is_known_already_locked_error(&err) { | ||
| debug!("Try lock error: {err:?}"); | ||
| } | ||
| debug!("Lock is busy for `{resource}`"); | ||
| None | ||
| } | ||
| } | ||
| } | ||
|
|
||
| /// Inner implementation for [`LockedFile::acquire_shared_blocking`] and | ||
| /// [`LockedFile::acquire_blocking`]. | ||
| fn lock_file_shared_blocking( | ||
|
|
@@ -711,7 +747,7 @@ impl LockedFile { | |
| } | ||
| Err(err) => { | ||
| // Log error code and enum kind to help debugging more exotic failures. | ||
| if err.kind() != std::io::ErrorKind::WouldBlock { | ||
| if !is_known_already_locked_error(&err) { | ||
| debug!("Try lock error: {err:?}"); | ||
| } | ||
| info!( | ||
|
|
@@ -782,6 +818,17 @@ impl LockedFile { | |
| .await? | ||
| } | ||
|
|
||
| /// Acquire a cross-process lock for a resource using a file at the provided path | ||
| /// | ||
| /// Unlike [`LockedFile::acquire`] this function will not wait for the lock to become available. | ||
| /// | ||
| /// If the lock is not immediately available, [`None`] is returned. | ||
|
Member
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Should we not propagate the error?
Member
Author
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. We could, but we treat all errors as "the lock could not be acquired" so I don't think the error has semantic meaning to a consumer at this time. |
||
| pub fn acquire_no_wait(path: impl AsRef<Path>, resource: impl Display) -> Option<Self> { | ||
| let file = Self::create(path).ok()?; | ||
| let resource = resource.to_string(); | ||
| Self::lock_file_no_wait(file, &resource) | ||
| } | ||
|
|
||
| #[cfg(unix)] | ||
| fn create(path: impl AsRef<Path>) -> Result<fs_err::File, std::io::Error> { | ||
| use std::os::unix::fs::PermissionsExt; | ||
|
|
||
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
We should loop on
EINTR, and probably in the blocking cases too, unless I'm missing something that already does that.There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Deferring to #15996