Skip to content

Commit

Permalink
Don't walk past project root when figuring out exclusion (#2471)
Browse files Browse the repository at this point in the history
  • Loading branch information
akx committed Feb 3, 2023
1 parent a26b1f4 commit ae20a72
Show file tree
Hide file tree
Showing 5 changed files with 49 additions and 1 deletion.
5 changes: 5 additions & 0 deletions resources/test/package/pyproject.toml
Original file line number Diff line number Diff line change
@@ -1,2 +1,7 @@
[tool.ruff]
src = ["."]

# This will make sure that `exclude` paths are rooted
# to where the configuration file was found; this file exists
# in a `resources/test` hierarchy.
exclude = ["resources"]
4 changes: 4 additions & 0 deletions resources/test/package/resources/ignored.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
# This file should be ignored, but it would otherwise trigger
# an unused import error:

import math
38 changes: 37 additions & 1 deletion src/resolver.rs
Original file line number Diff line number Diff line change
Expand Up @@ -411,6 +411,11 @@ fn is_file_excluded(
return true;
}
}
if path == settings.project_root {
// Bail out; we'd end up past the project root on the next iteration
// (excludes etc. are thus "rooted" to the project).
break;
}
}
false
}
Expand All @@ -424,8 +429,13 @@ mod tests {
use path_absolutize::Absolutize;

use crate::fs;
use crate::resolver::{is_python_path, match_exclusion};
use crate::resolver::{
is_file_excluded, is_python_path, match_exclusion, resolve_settings_with_processor,
NoOpProcessor, PyprojectDiscovery, Relativity, Resolver,
};
use crate::settings::pyproject::find_settings_toml;
use crate::settings::types::FilePattern;
use crate::test::test_resource_path;

#[test]
fn inclusions() {
Expand Down Expand Up @@ -567,4 +577,30 @@ mod tests {

Ok(())
}

#[test]
fn rooted_exclusion() -> Result<()> {
let package_root = test_resource_path("package");
let resolver = Resolver::default();
let ppd = PyprojectDiscovery::Hierarchical(resolve_settings_with_processor(
&find_settings_toml(&package_root)?.unwrap(),
&Relativity::Parent,
&NoOpProcessor,
)?);
// src/app.py should not be excluded even if it lives in a hierarchy that should be
// excluded by virtue of the pyproject.toml having `resources/*` in it.
assert!(!is_file_excluded(
&package_root.join("src/app.py"),
&resolver,
&ppd,
));
// However, resources/ignored.py should be ignored, since that `resources` is beneath
// the package root.
assert!(is_file_excluded(
&package_root.join("resources/ignored.py"),
&resolver,
&ppd,
));
Ok(())
}
}
1 change: 1 addition & 0 deletions src/settings/defaults.rs
Original file line number Diff line number Diff line change
Expand Up @@ -71,6 +71,7 @@ impl Default for Settings {
respect_gitignore: true,
show_source: false,
src: vec![path_dedot::CWD.clone()],
project_root: path_dedot::CWD.clone(),
target_version: TARGET_VERSION,
task_tags: TASK_TAGS.iter().map(ToString::to_string).collect(),
typing_modules: vec![],
Expand Down
2 changes: 2 additions & 0 deletions src/settings/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -90,6 +90,7 @@ pub struct Settings {
pub extend_exclude: HashableGlobSet,
pub force_exclude: bool,
pub respect_gitignore: bool,
pub project_root: PathBuf,

// Rule-specific settings
pub allowed_confusables: HashableHashSet<char>,
Expand Down Expand Up @@ -167,6 +168,7 @@ impl Settings {
src: config
.src
.unwrap_or_else(|| vec![project_root.to_path_buf()]),
project_root: project_root.to_path_buf(),
target_version: config.target_version.unwrap_or(defaults::TARGET_VERSION),
task_tags: config.task_tags.unwrap_or_else(|| {
defaults::TASK_TAGS
Expand Down

0 comments on commit ae20a72

Please sign in to comment.