diff --git a/Cargo.lock b/Cargo.lock index 3fd0ec0a..2ca6afc5 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -709,6 +709,12 @@ version = "1.0.11" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "d01a5bd0424d00070b0098dd17ebca6f961a959dead1dbcbbbc1d1cd8d3deeba" +[[package]] +name = "pathdiff" +version = "0.2.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d61c5ce1153ab5b689d0c074c4e7fc613e942dfb7dd9eea5ab202d2ad91fe361" + [[package]] name = "percent-encoding" version = "2.2.0" @@ -933,6 +939,7 @@ dependencies = [ "globset", "lazy_static", "num_cpus", + "pathdiff", "pretty_assertions", "profiling", "selene-lib", diff --git a/selene/Cargo.toml b/selene/Cargo.toml index e5c08751..88424393 100644 --- a/selene/Cargo.toml +++ b/selene/Cargo.toml @@ -35,6 +35,7 @@ tracy-client = { version = "0.14.1", optional = true } threadpool = "1.8" toml.workspace = true ureq = { version = "2.6.2", features = ["json"], optional = true } +pathdiff = "0.2.2" [dev-dependencies] pretty_assertions = "1.3" diff --git a/selene/src/main.rs b/selene/src/main.rs index 4e9bc3ac..5ad0ede8 100644 --- a/selene/src/main.rs +++ b/selene/src/main.rs @@ -643,6 +643,26 @@ fn start(mut options: opts::Options) { let pool = ThreadPool::new(options.num_threads); + // Directory for matching files pattern. + // If user provides a config file, we use that as our working directory, otherwise fallback to the current directory. + // The working directory needs to be an absolute path to match with paths in different directories. + let working_directory = config_directory.or_else(|| current_dir.canonicalize().ok()); + + let is_excluded = |path: &Path| -> bool { + if options.no_exclude { + return false; + } + + // File pattern between the path we are checking and current working directory. + let file_pattern = working_directory.as_ref().and_then(|dir| { + path.canonicalize() + .ok() + .and_then(|path| pathdiff::diff_paths(path, dir)) + }); + + file_pattern.is_some_and(|pattern| exclude_set.is_match(&pattern)) + }; + for filename in &options.files { if filename == "-" { let checker = Arc::clone(&checker); @@ -656,7 +676,7 @@ fn start(mut options: opts::Options) { let checker = Arc::clone(&checker); let filename = filename.to_owned(); - if !options.no_exclude && exclude_set.is_match(&filename) { + if is_excluded(Path::new(&filename)) { continue; } @@ -678,7 +698,7 @@ fn start(mut options: opts::Options) { for entry in glob { match entry { Ok(path) => { - if !options.no_exclude && exclude_set.is_match(&path) { + if is_excluded(&path) { continue; }