mirror of https://github.com/astral-sh/ruff
Handle filesystem errors more consistently (#240)
This commit is contained in:
parent
aa9c1e255c
commit
401b53cc45
|
|
@ -449,9 +449,7 @@ impl CheckKind {
|
||||||
CheckKind::FutureFeatureNotDefined(name) => {
|
CheckKind::FutureFeatureNotDefined(name) => {
|
||||||
format!("future feature '{name}' is not defined")
|
format!("future feature '{name}' is not defined")
|
||||||
}
|
}
|
||||||
CheckKind::IOError(name) => {
|
CheckKind::IOError(message) => message.clone(),
|
||||||
format!("No such file or directory: `{name}`")
|
|
||||||
}
|
|
||||||
CheckKind::IfTuple => "If test is a tuple, which is always `True`".to_string(),
|
CheckKind::IfTuple => "If test is a tuple, which is always `True`".to_string(),
|
||||||
CheckKind::InvalidPrintSyntax => "use of >> is invalid with print function".to_string(),
|
CheckKind::InvalidPrintSyntax => "use of >> is invalid with print function".to_string(),
|
||||||
CheckKind::ImportStarNotPermitted(name) => {
|
CheckKind::ImportStarNotPermitted(name) => {
|
||||||
|
|
|
||||||
|
|
@ -59,7 +59,7 @@ pub fn iter_python_files<'a>(
|
||||||
path: &'a Path,
|
path: &'a Path,
|
||||||
exclude: &'a [FilePattern],
|
exclude: &'a [FilePattern],
|
||||||
extend_exclude: &'a [FilePattern],
|
extend_exclude: &'a [FilePattern],
|
||||||
) -> impl Iterator<Item = DirEntry> + 'a {
|
) -> impl Iterator<Item = Result<DirEntry, walkdir::Error>> + 'a {
|
||||||
// Run some checks over the provided patterns, to enable optimizations below.
|
// Run some checks over the provided patterns, to enable optimizations below.
|
||||||
let has_exclude = !exclude.is_empty();
|
let has_exclude = !exclude.is_empty();
|
||||||
let has_extend_exclude = !extend_exclude.is_empty();
|
let has_extend_exclude = !extend_exclude.is_empty();
|
||||||
|
|
@ -105,10 +105,11 @@ pub fn iter_python_files<'a>(
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
.filter_map(|entry| entry.ok())
|
|
||||||
.filter(|entry| {
|
.filter(|entry| {
|
||||||
|
entry.as_ref().map_or(true, |entry| {
|
||||||
(entry.depth() == 0 && !entry.file_type().is_dir()) || is_included(entry.path())
|
(entry.depth() == 0 && !entry.file_type().is_dir()) || is_included(entry.path())
|
||||||
})
|
})
|
||||||
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Convert any path to an absolute path (based on the current working directory).
|
/// Convert any path to an absolute path (based on the current working directory).
|
||||||
|
|
|
||||||
45
src/main.rs
45
src/main.rs
|
|
@ -1,6 +1,7 @@
|
||||||
extern crate core;
|
extern crate core;
|
||||||
|
|
||||||
use std::path::PathBuf;
|
use std::io;
|
||||||
|
use std::path::{Path, PathBuf};
|
||||||
use std::process::ExitCode;
|
use std::process::ExitCode;
|
||||||
use std::sync::mpsc::channel;
|
use std::sync::mpsc::channel;
|
||||||
use std::time::Instant;
|
use std::time::Instant;
|
||||||
|
|
@ -102,7 +103,7 @@ fn run_once(
|
||||||
) -> Result<Vec<Message>> {
|
) -> Result<Vec<Message>> {
|
||||||
// Collect all the files to check.
|
// Collect all the files to check.
|
||||||
let start = Instant::now();
|
let start = Instant::now();
|
||||||
let paths: Vec<DirEntry> = files
|
let paths: Vec<Result<DirEntry, walkdir::Error>> = files
|
||||||
.iter()
|
.iter()
|
||||||
.flat_map(|path| iter_python_files(path, &settings.exclude, &settings.extend_exclude))
|
.flat_map(|path| iter_python_files(path, &settings.exclude, &settings.extend_exclude))
|
||||||
.collect();
|
.collect();
|
||||||
|
|
@ -113,16 +114,33 @@ fn run_once(
|
||||||
let mut messages: Vec<Message> = paths
|
let mut messages: Vec<Message> = paths
|
||||||
.par_iter()
|
.par_iter()
|
||||||
.map(|entry| {
|
.map(|entry| {
|
||||||
lint_path(entry.path(), settings, &cache.into(), &autofix.into()).unwrap_or_else(|e| {
|
match entry {
|
||||||
if settings.select.contains(&CheckCode::E999) {
|
Ok(entry) => {
|
||||||
|
let path = entry.path();
|
||||||
|
lint_path(path, settings, &cache.into(), &autofix.into())
|
||||||
|
.map_err(|e| (Some(path.to_owned()), e.to_string()))
|
||||||
|
}
|
||||||
|
Err(e) => Err((
|
||||||
|
e.path().map(Path::to_owned),
|
||||||
|
e.io_error()
|
||||||
|
.map_or_else(|| e.to_string(), io::Error::to_string),
|
||||||
|
)),
|
||||||
|
}
|
||||||
|
.unwrap_or_else(|(path, message)| {
|
||||||
|
if let Some(path) = path {
|
||||||
|
if settings.select.contains(&CheckCode::E902) {
|
||||||
vec![Message {
|
vec![Message {
|
||||||
kind: CheckKind::SyntaxError(e.to_string()),
|
kind: CheckKind::IOError(message),
|
||||||
fixed: false,
|
fixed: false,
|
||||||
location: Default::default(),
|
location: Default::default(),
|
||||||
filename: entry.path().to_string_lossy().to_string(),
|
filename: path.to_string_lossy().to_string(),
|
||||||
}]
|
}]
|
||||||
} else {
|
} else {
|
||||||
error!("Failed to check {}: {e:?}", entry.path().to_string_lossy());
|
error!("Failed to check {}: {message}", path.to_string_lossy());
|
||||||
|
vec![]
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
error!("{message}");
|
||||||
vec![]
|
vec![]
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
|
|
@ -130,19 +148,6 @@ fn run_once(
|
||||||
.flatten()
|
.flatten()
|
||||||
.collect();
|
.collect();
|
||||||
|
|
||||||
if settings.select.contains(&CheckCode::E902) {
|
|
||||||
for file in files {
|
|
||||||
if !file.exists() {
|
|
||||||
messages.push(Message {
|
|
||||||
kind: CheckKind::IOError(file.to_string_lossy().to_string()),
|
|
||||||
fixed: false,
|
|
||||||
location: Default::default(),
|
|
||||||
filename: file.to_string_lossy().to_string(),
|
|
||||||
})
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
messages.sort_unstable();
|
messages.sort_unstable();
|
||||||
let duration = start.elapsed();
|
let duration = start.elapsed();
|
||||||
debug!("Checked files in: {:?}", duration);
|
debug!("Checked files in: {:?}", duration);
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue