Enable globs in excludes list (#64)

This commit is contained in:
Charlie Marsh 2022-08-31 18:53:13 -04:00 committed by GitHub
parent b5edcee9f2
commit 59f009b52d
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
13 changed files with 54 additions and 14 deletions

7
Cargo.lock generated
View File

@ -850,6 +850,12 @@ dependencies = [
"wasi 0.11.0+wasi-snapshot-preview1", "wasi 0.11.0+wasi-snapshot-preview1",
] ]
[[package]]
name = "glob"
version = "0.3.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "9b919933a397b79c37e33b77bb2aa3dc8eb6e165ad809e58ff75bc7db2e34574"
[[package]] [[package]]
name = "gloo-timers" name = "gloo-timers"
version = "0.2.4" version = "0.2.4"
@ -1648,6 +1654,7 @@ dependencies = [
"dirs 4.0.0", "dirs 4.0.0",
"fern", "fern",
"filetime", "filetime",
"glob",
"log", "log",
"notify", "notify",
"rayon", "rayon",

View File

@ -18,6 +18,7 @@ common-path = { version = "1.0.0" }
dirs = { version = "4.0.0" } dirs = { version = "4.0.0" }
fern = { version = "0.6.1" } fern = { version = "0.6.1" }
filetime = { version = "0.2.17" } filetime = { version = "0.2.17" }
glob = { version = "0.3.0"}
log = { version = "0.4.17" } log = { version = "0.4.17" }
notify = { version = "4.0.17" } notify = { version = "4.0.17" }
rayon = { version = "1.5.3" } rayon = { version = "1.5.3" }

View File

View File

@ -0,0 +1,9 @@
a = "abc"
b = f"ghi{'jkl'}"
c = f"def"
d = f"def" + "ghi"
e = (
f"def" +
"ghi"
)

View File

View File

@ -0,0 +1,9 @@
a = "abc"
b = f"ghi{'jkl'}"
c = f"def"
d = f"def" + "ghi"
e = (
f"def" +
"ghi"
)

View File

@ -1,6 +1,6 @@
[tool.ruff] [tool.ruff]
line-length = 88 line-length = 88
exclude = ["excluded.py"] exclude = ["excluded.py", "**/migrations"]
select = [ select = [
"E501", "E501",
"F401", "F401",

View File

@ -3,21 +3,33 @@ use std::io::{BufReader, Read};
use std::path::{Path, PathBuf}; use std::path::{Path, PathBuf};
use anyhow::Result; use anyhow::Result;
use glob::Pattern;
use walkdir::{DirEntry, WalkDir}; use walkdir::{DirEntry, WalkDir};
fn is_not_hidden(entry: &DirEntry) -> bool { fn is_not_hidden(entry: &DirEntry) -> bool {
entry entry
.file_name() .file_name()
.to_str() .to_str()
.map(|s| entry.depth() == 0 || !s.starts_with('.')) .map(|s| (entry.depth() == 0 || !s.starts_with('.')))
.unwrap_or(false) .unwrap_or(false)
} }
pub fn iter_python_files(path: &PathBuf) -> impl Iterator<Item = DirEntry> { fn is_not_excluded(entry: &DirEntry, exclude: &[Pattern]) -> bool {
entry
.path()
.to_str()
.map(|s| !exclude.iter().any(|pattern| pattern.matches(s)))
.unwrap_or(false)
}
pub fn iter_python_files<'a>(
path: &'a PathBuf,
exclude: &'a [Pattern],
) -> impl Iterator<Item = DirEntry> + 'a {
WalkDir::new(path) WalkDir::new(path)
.follow_links(true) .follow_links(true)
.into_iter() .into_iter()
.filter_entry(is_not_hidden) .filter_entry(|entry| is_not_hidden(entry) && is_not_excluded(entry, exclude))
.filter_map(|entry| entry.ok()) .filter_map(|entry| entry.ok())
.filter(|entry| entry.path().to_string_lossy().ends_with(".py")) .filter(|entry| entry.path().to_string_lossy().ends_with(".py"))
} }

View File

@ -51,19 +51,16 @@ struct Cli {
fn run_once(files: &[PathBuf], settings: &Settings, cache: bool) -> Result<Vec<Message>> { fn run_once(files: &[PathBuf], settings: &Settings, cache: bool) -> Result<Vec<Message>> {
// Collect all the files to check. // Collect all the files to check.
let start = Instant::now(); let start = Instant::now();
let files: Vec<DirEntry> = files.iter().flat_map(iter_python_files).collect(); let files: Vec<DirEntry> = files
.iter()
.flat_map(|path| iter_python_files(path, &settings.exclude))
.collect();
let duration = start.elapsed(); let duration = start.elapsed();
debug!("Identified files to lint in: {:?}", duration); debug!("Identified files to lint in: {:?}", duration);
let start = Instant::now(); let start = Instant::now();
let mut messages: Vec<Message> = files let mut messages: Vec<Message> = files
.par_iter() .par_iter()
.filter(|entry| {
!settings
.exclude
.iter()
.any(|exclusion| entry.path().starts_with(exclusion))
})
.map(|entry| { .map(|entry| {
check_path(entry.path(), settings, &cache.into()).unwrap_or_else(|e| { check_path(entry.path(), settings, &cache.into()).unwrap_or_else(|e| {
error!("Failed to check {}: {e:?}", entry.path().to_string_lossy()); error!("Failed to check {}: {e:?}", entry.path().to_string_lossy());

View File

@ -225,7 +225,10 @@ other-attribute = 1
config, config,
Config { Config {
line_length: Some(88), line_length: Some(88),
exclude: Some(vec![Path::new("excluded.py").to_path_buf()]), exclude: Some(vec![
Path::new("excluded.py").to_path_buf(),
Path::new("**/migrations").to_path_buf()
]),
select: Some(BTreeSet::from([ select: Some(BTreeSet::from([
CheckCode::E501, CheckCode::E501,
CheckCode::F401, CheckCode::F401,

View File

@ -1,8 +1,9 @@
use std::collections::BTreeSet; use std::collections::BTreeSet;
use std::hash::{Hash, Hasher}; use std::hash::{Hash, Hasher};
use std::path::{Path, PathBuf}; use std::path::Path;
use anyhow::Result; use anyhow::Result;
use glob::Pattern;
use crate::checks::CheckCode; use crate::checks::CheckCode;
use crate::pyproject::load_config; use crate::pyproject::load_config;
@ -10,7 +11,7 @@ use crate::pyproject::load_config;
#[derive(Debug)] #[derive(Debug)]
pub struct Settings { pub struct Settings {
pub line_length: usize, pub line_length: usize,
pub exclude: Vec<PathBuf>, pub exclude: Vec<Pattern>,
pub select: BTreeSet<CheckCode>, pub select: BTreeSet<CheckCode>,
} }
@ -39,6 +40,7 @@ impl Settings {
path path
} }
}) })
.map(|path| Pattern::new(&path.to_string_lossy()).expect("Invalid pattern."))
.collect(), .collect(),
select: config.select.unwrap_or_else(|| { select: config.select.unwrap_or_else(|| {
BTreeSet::from([ BTreeSet::from([