mirror of
https://github.com/astral-sh/ruff.git
synced 2025-10-01 06:11:43 +00:00
Workspace discovery (#14308)
This commit is contained in:
parent
2b58705cc1
commit
81e5830585
38 changed files with 1972 additions and 181 deletions
|
@ -1,12 +1,8 @@
|
|||
// TODO support untitled files for the LSP use case. Wrap a `str` and `String`
|
||||
// The main question is how `as_std_path` would work for untitled files, that can only exist in the LSP case
|
||||
// but there's no compile time guarantee that a [`OsSystem`] never gets an untitled file path.
|
||||
|
||||
use camino::{Utf8Path, Utf8PathBuf};
|
||||
use std::borrow::Borrow;
|
||||
use std::fmt::Formatter;
|
||||
use std::ops::Deref;
|
||||
use std::path::{Path, StripPrefixError};
|
||||
use std::path::{Path, PathBuf, StripPrefixError};
|
||||
|
||||
/// A slice of a path on [`System`](super::System) (akin to [`str`]).
|
||||
///
|
||||
|
@ -23,6 +19,32 @@ impl SystemPath {
|
|||
unsafe { &*(path as *const Utf8Path as *const SystemPath) }
|
||||
}
|
||||
|
||||
/// Takes any path, and when possible, converts Windows UNC paths to regular paths.
|
||||
/// If the path can't be converted, it's returned unmodified.
|
||||
///
|
||||
/// On non-Windows this is no-op.
|
||||
///
|
||||
/// `\\?\C:\Windows` will be converted to `C:\Windows`,
|
||||
/// but `\\?\C:\COM` will be left as-is (due to a reserved filename).
|
||||
///
|
||||
/// Use this to pass arbitrary paths to programs that may not be UNC-aware.
|
||||
///
|
||||
/// It's generally safe to pass UNC paths to legacy programs, because
|
||||
/// these paths contain a reserved prefix, so will gracefully fail
|
||||
/// if used with legacy APIs that don't support UNC.
|
||||
///
|
||||
/// This function does not perform any I/O.
|
||||
///
|
||||
/// Currently paths with unpaired surrogates aren't converted even if they
|
||||
/// could be, due to limitations of Rust's `OsStr` API.
|
||||
///
|
||||
/// To check if a path remained as UNC, use `path.as_os_str().as_encoded_bytes().starts_with(b"\\\\")`.
|
||||
#[inline]
|
||||
pub fn simplified(&self) -> &SystemPath {
|
||||
// SAFETY: simplified only trims the path, that means the returned path must be a valid UTF-8 path.
|
||||
SystemPath::from_std_path(dunce::simplified(self.as_std_path())).unwrap()
|
||||
}
|
||||
|
||||
/// Extracts the file extension, if possible.
|
||||
///
|
||||
/// The extension is:
|
||||
|
@ -123,6 +145,39 @@ impl SystemPath {
|
|||
self.0.parent().map(SystemPath::new)
|
||||
}
|
||||
|
||||
/// Produces an iterator over `SystemPath` and its ancestors.
|
||||
///
|
||||
/// The iterator will yield the `SystemPath` that is returned if the [`parent`] method is used zero
|
||||
/// or more times. That means, the iterator will yield `&self`, `&self.parent().unwrap()`,
|
||||
/// `&self.parent().unwrap().parent().unwrap()` and so on. If the [`parent`] method returns
|
||||
/// [`None`], the iterator will do likewise. The iterator will always yield at least one value,
|
||||
/// namely `&self`.
|
||||
///
|
||||
/// # Examples
|
||||
///
|
||||
/// ```
|
||||
/// use ruff_db::system::SystemPath;
|
||||
///
|
||||
/// let mut ancestors = SystemPath::new("/foo/bar").ancestors();
|
||||
/// assert_eq!(ancestors.next(), Some(SystemPath::new("/foo/bar")));
|
||||
/// assert_eq!(ancestors.next(), Some(SystemPath::new("/foo")));
|
||||
/// assert_eq!(ancestors.next(), Some(SystemPath::new("/")));
|
||||
/// assert_eq!(ancestors.next(), None);
|
||||
///
|
||||
/// let mut ancestors = SystemPath::new("../foo/bar").ancestors();
|
||||
/// assert_eq!(ancestors.next(), Some(SystemPath::new("../foo/bar")));
|
||||
/// assert_eq!(ancestors.next(), Some(SystemPath::new("../foo")));
|
||||
/// assert_eq!(ancestors.next(), Some(SystemPath::new("..")));
|
||||
/// assert_eq!(ancestors.next(), Some(SystemPath::new("")));
|
||||
/// assert_eq!(ancestors.next(), None);
|
||||
/// ```
|
||||
///
|
||||
/// [`parent`]: SystemPath::parent
|
||||
#[inline]
|
||||
pub fn ancestors(&self) -> impl Iterator<Item = &SystemPath> {
|
||||
self.0.ancestors().map(SystemPath::new)
|
||||
}
|
||||
|
||||
/// Produces an iterator over the [`camino::Utf8Component`]s of the path.
|
||||
///
|
||||
/// When parsing the path, there is a small amount of normalization:
|
||||
|
@ -473,6 +528,10 @@ impl SystemPathBuf {
|
|||
self.0
|
||||
}
|
||||
|
||||
pub fn into_std_path_buf(self) -> PathBuf {
|
||||
self.0.into_std_path_buf()
|
||||
}
|
||||
|
||||
#[inline]
|
||||
pub fn as_path(&self) -> &SystemPath {
|
||||
SystemPath::new(&self.0)
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue