Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 0 additions & 1 deletion Cargo.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

1 change: 0 additions & 1 deletion crates/ruff_db/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -30,7 +30,6 @@ dashmap = { workspace = true }
dunce = { workspace = true }
filetime = { workspace = true }
get-size2 = { workspace = true }
glob = { workspace = true }
ignore = { workspace = true, optional = true }
matchit = { workspace = true }
path-slash = { workspace = true }
Expand Down
73 changes: 1 addition & 72 deletions crates/ruff_db/src/system.rs
Original file line number Diff line number Diff line change
@@ -1,4 +1,3 @@
pub use glob::PatternError;
pub use memory_fs::MemoryFileSystem;

#[cfg(all(feature = "testing", feature = "os"))]
Expand All @@ -11,9 +10,8 @@ use filetime::FileTime;
use ruff_notebook::{Notebook, NotebookError};
use ruff_python_ast::PySourceType;
use std::error::Error;
use std::fmt;
use std::fmt::{Debug, Formatter};
use std::path::{Path, PathBuf};
use std::{fmt, io};
pub use test::{DbWithTestSystem, DbWithWritableSystem, InMemorySystem, TestSystem};
use walk_directory::WalkDirectoryBuilder;

Expand Down Expand Up @@ -196,19 +194,6 @@ pub trait System: Debug + Sync + Send {
/// yields a single entry for that file.
fn walk_directory(&self, path: &SystemPath) -> WalkDirectoryBuilder;

/// Return an iterator that produces all the `Path`s that match the given
/// pattern using default match options, which may be absolute or relative to
/// the current working directory.
///
/// This may return an error if the pattern is invalid.
fn glob(
&self,
pattern: &str,
) -> std::result::Result<
Box<dyn Iterator<Item = std::result::Result<SystemPathBuf, GlobError>> + '_>,
PatternError,
>;

/// Fetches the environment variable `key` from the current process.
///
/// # Errors
Expand Down Expand Up @@ -398,62 +383,6 @@ impl DirectoryEntry {
}
}

/// A glob iteration error.
///
/// This is typically returned when a particular path cannot be read
/// to determine if its contents match the glob pattern. This is possible
/// if the program lacks the appropriate permissions, for example.
#[derive(Debug)]
pub struct GlobError {
path: PathBuf,
error: GlobErrorKind,
}

impl GlobError {
/// The Path that the error corresponds to.
pub fn path(&self) -> &Path {
&self.path
}

pub fn kind(&self) -> &GlobErrorKind {
&self.error
}
}

impl Error for GlobError {}

impl fmt::Display for GlobError {
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
match &self.error {
GlobErrorKind::IOError(error) => {
write!(
f,
"attempting to read `{}` resulted in an error: {error}",
self.path.display(),
)
}
GlobErrorKind::NonUtf8Path => {
write!(f, "`{}` is not a valid UTF-8 path", self.path.display(),)
}
}
}
}

impl From<glob::GlobError> for GlobError {
fn from(value: glob::GlobError) -> Self {
Self {
path: value.path().to_path_buf(),
error: GlobErrorKind::IOError(value.into_error()),
}
}
}

#[derive(Debug)]
pub enum GlobErrorKind {
IOError(io::Error),
NonUtf8Path,
}

#[cfg(not(target_arch = "wasm32"))]
pub fn file_time_now() -> FileTime {
FileTime::now()
Expand Down
70 changes: 4 additions & 66 deletions crates/ruff_db/src/system/memory_fs.rs
Original file line number Diff line number Diff line change
Expand Up @@ -8,13 +8,13 @@ use filetime::FileTime;
use rustc_hash::FxHashMap;

use crate::system::{
DirectoryEntry, FileType, GlobError, GlobErrorKind, Metadata, Result, SystemPath,
SystemPathBuf, SystemVirtualPath, SystemVirtualPathBuf, file_time_now, walk_directory,
DirectoryEntry, FileType, Metadata, Result, SystemPath, SystemPathBuf, SystemVirtualPath,
SystemVirtualPathBuf, file_time_now, walk_directory,
};

use super::walk_directory::{
DirectoryWalker, ErrorKind, WalkDirectoryBuilder, WalkDirectoryConfiguration,
WalkDirectoryVisitor, WalkDirectoryVisitorBuilder, WalkState,
DirectoryWalker, WalkDirectoryBuilder, WalkDirectoryConfiguration, WalkDirectoryVisitor,
WalkDirectoryVisitorBuilder, WalkState,
};

/// File system that stores all content in memory.
Expand Down Expand Up @@ -270,46 +270,6 @@ impl MemoryFileSystem {
WalkDirectoryBuilder::new(path, MemoryWalker { fs: self.clone() })
}

pub fn glob(
&self,
pattern: &str,
) -> std::result::Result<
impl Iterator<Item = std::result::Result<SystemPathBuf, GlobError>> + '_,
glob::PatternError,
> {
// Very naive implementation that iterates over all files and collects all that match the given pattern.

let normalized = self.normalize_path(pattern);
let pattern = glob::Pattern::new(normalized.as_str())?;
let matches = std::sync::Mutex::new(Vec::new());

self.walk_directory("/").standard_filters(false).run(|| {
Box::new(|entry| {
match entry {
Ok(entry) => {
if pattern.matches_path(entry.path().as_std_path()) {
matches.lock().unwrap().push(Ok(entry.into_path()));
}
}
Err(error) => match error.kind {
ErrorKind::Loop { .. } => {
unreachable!("Loops aren't possible in the memory file system because it doesn't support symlinks.")
}
ErrorKind::Io { err, path } => {
matches.lock().unwrap().push(Err(GlobError { path: path.expect("walk_directory to always set a path").into_std_path_buf(), error: GlobErrorKind::IOError(err)}));
}
ErrorKind::NonUtf8Path { path } => {
matches.lock().unwrap().push(Err(GlobError { path, error: GlobErrorKind::NonUtf8Path}));
}
},
}
WalkState::Continue
})
});

Ok(matches.into_inner().unwrap().into_iter())
}

pub fn remove_file(&self, path: impl AsRef<SystemPath>) -> Result<()> {
fn remove_file(fs: &MemoryFileSystem, path: &SystemPath) -> Result<()> {
let mut by_path = fs.inner.by_path.write().unwrap();
Expand Down Expand Up @@ -1226,26 +1186,4 @@ mod tests {

Ok(())
}

#[test]
fn glob() -> std::io::Result<()> {
let root = SystemPath::new("/src");
let fs = MemoryFileSystem::with_current_directory(root);

fs.write_files_all([
(root.join("foo.py"), "print('foo')"),
(root.join("a/bar.py"), "print('bar')"),
(root.join("a/.baz.py"), "print('baz')"),
])?;

let mut matches = fs.glob("/src/a/**").unwrap().flatten().collect::<Vec<_>>();
matches.sort_unstable();

assert_eq!(matches, vec![root.join("a/.baz.py"), root.join("a/bar.py")]);

let matches = fs.glob("**/bar.py").unwrap().flatten().collect::<Vec<_>>();
assert_eq!(matches, vec![root.join("a/bar.py")]);

Ok(())
}
}
28 changes: 2 additions & 26 deletions crates/ruff_db/src/system/os.rs
Original file line number Diff line number Diff line change
Expand Up @@ -6,8 +6,8 @@ use super::walk_directory::{
};
use crate::max_parallelism;
use crate::system::{
CaseSensitivity, DirectoryEntry, FileType, GlobError, GlobErrorKind, Metadata, Result, System,
SystemPath, SystemPathBuf, SystemVirtualPath, WhichError, WhichResult, WritableSystem,
CaseSensitivity, DirectoryEntry, FileType, Metadata, Result, System, SystemPath, SystemPathBuf,
SystemVirtualPath, WhichError, WhichResult, WritableSystem,
};
use filetime::FileTime;
use ruff_notebook::{Notebook, NotebookError};
Expand Down Expand Up @@ -202,30 +202,6 @@ impl System for OsSystem {
)
}

fn glob(
&self,
pattern: &str,
) -> std::result::Result<
Box<dyn Iterator<Item = std::result::Result<SystemPathBuf, GlobError>>>,
glob::PatternError,
> {
glob::glob(pattern).map(|inner| {
let iterator = inner.map(|result| {
let path = result?;

let system_path = SystemPathBuf::from_path_buf(path).map_err(|path| GlobError {
path,
error: GlobErrorKind::NonUtf8Path,
})?;

Ok(system_path)
});

let boxed: Box<dyn Iterator<Item = _>> = Box::new(iterator);
boxed
})
}

fn as_writable(&self) -> Option<&dyn WritableSystem> {
Some(self)
}
Expand Down
26 changes: 2 additions & 24 deletions crates/ruff_db/src/system/test.rs
Original file line number Diff line number Diff line change
@@ -1,4 +1,3 @@
use glob::PatternError;
use ruff_notebook::{Notebook, NotebookError};
use rustc_hash::FxHashMap;
use std::panic::RefUnwindSafe;
Expand All @@ -7,8 +6,8 @@ use std::sync::{Arc, Mutex};
use crate::Db;
use crate::files::File;
use crate::system::{
CaseSensitivity, DirectoryEntry, GlobError, MemoryFileSystem, Metadata, Result, System,
SystemPath, SystemPathBuf, SystemVirtualPath, WhichError, WhichResult,
CaseSensitivity, DirectoryEntry, MemoryFileSystem, Metadata, Result, System, SystemPath,
SystemPathBuf, SystemVirtualPath, WhichError, WhichResult,
};

use super::WritableSystem;
Expand Down Expand Up @@ -148,16 +147,6 @@ impl System for TestSystem {
self.system().walk_directory(path)
}

fn glob(
&self,
pattern: &str,
) -> std::result::Result<
Box<dyn Iterator<Item = std::result::Result<SystemPathBuf, GlobError>> + '_>,
PatternError,
> {
self.system().glob(pattern)
}

fn as_writable(&self) -> Option<&dyn WritableSystem> {
Some(self)
}
Expand Down Expand Up @@ -419,17 +408,6 @@ impl System for InMemorySystem {
self.memory_fs.walk_directory(path)
}

fn glob(
&self,
pattern: &str,
) -> std::result::Result<
Box<dyn Iterator<Item = std::result::Result<SystemPathBuf, GlobError>> + '_>,
PatternError,
> {
let iterator = self.memory_fs.glob(pattern)?;
Ok(Box::new(iterator))
}

fn as_writable(&self) -> Option<&dyn WritableSystem> {
Some(self)
}
Expand Down
15 changes: 2 additions & 13 deletions crates/ty_server/src/system.rs
Original file line number Diff line number Diff line change
Expand Up @@ -13,9 +13,8 @@ use ruff_db::file_revision::FileRevision;
use ruff_db::files::{File, FilePath};
use ruff_db::system::walk_directory::WalkDirectoryBuilder;
use ruff_db::system::{
CaseSensitivity, DirectoryEntry, FileType, GlobError, Metadata, PatternError, Result, System,
SystemPath, SystemPathBuf, SystemVirtualPath, SystemVirtualPathBuf, WhichResult,
WritableSystem,
CaseSensitivity, DirectoryEntry, FileType, Metadata, Result, System, SystemPath, SystemPathBuf,
SystemVirtualPath, SystemVirtualPathBuf, WhichResult, WritableSystem,
};
use ruff_notebook::{Notebook, NotebookError};
use ruff_python_ast::PySourceType;
Expand Down Expand Up @@ -256,16 +255,6 @@ impl System for LSPSystem {
self.native_system.walk_directory(path)
}

fn glob(
&self,
pattern: &str,
) -> std::result::Result<
Box<dyn Iterator<Item = std::result::Result<SystemPathBuf, GlobError>> + '_>,
PatternError,
> {
self.native_system.glob(pattern)
}

fn as_writable(&self) -> Option<&dyn WritableSystem> {
self.native_system.as_writable()
}
Expand Down
11 changes: 0 additions & 11 deletions crates/ty_test/src/db.rs
Original file line number Diff line number Diff line change
Expand Up @@ -344,17 +344,6 @@ impl System for MdtestSystem {
self.as_system().walk_directory(&self.normalize_path(path))
}

fn glob(
&self,
pattern: &str,
) -> Result<
Box<dyn Iterator<Item = Result<SystemPathBuf, ruff_db::system::GlobError>> + '_>,
ruff_db::system::PatternError,
> {
self.as_system()
.glob(self.normalize_path(SystemPath::new(pattern)).as_str())
}

fn as_writable(&self) -> Option<&dyn WritableSystem> {
Some(self)
}
Expand Down
11 changes: 2 additions & 9 deletions crates/ty_wasm/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -7,8 +7,8 @@ use ruff_db::files::{File, FilePath, FileRange, system_path_to_file, vendored_pa
use ruff_db::source::{SourceText, line_index, source_text};
use ruff_db::system::walk_directory::WalkDirectoryBuilder;
use ruff_db::system::{
CaseSensitivity, DirectoryEntry, GlobError, MemoryFileSystem, Metadata, PatternError, System,
SystemPath, SystemPathBuf, SystemVirtualPath, WhichError, WhichResult, WritableSystem,
CaseSensitivity, DirectoryEntry, MemoryFileSystem, Metadata, System, SystemPath, SystemPathBuf,
SystemVirtualPath, WhichError, WhichResult, WritableSystem,
};
use ruff_db::vendored::VendoredPath;
use ruff_diagnostics::{Applicability, Edit};
Expand Down Expand Up @@ -1431,13 +1431,6 @@ impl System for WasmSystem {
self.fs.walk_directory(path)
}

fn glob(
&self,
pattern: &str,
) -> Result<Box<dyn Iterator<Item = Result<SystemPathBuf, GlobError>> + '_>, PatternError> {
Ok(Box::new(self.fs.glob(pattern)?))
}

fn as_writable(&self) -> Option<&dyn WritableSystem> {
None
}
Expand Down
Loading