Add --force-exclude setting to force exclusions with pre-commit (#1295)

This commit is contained in:
Charlie Marsh 2022-12-19 20:08:59 -05:00 committed by GitHub
parent 8934f6938d
commit eff7700d92
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
10 changed files with 74 additions and 15 deletions

View file

@ -268,6 +268,7 @@ mod tests {
fix: None,
fixable: None,
format: None,
force_exclude: None,
ignore: Some(vec![]),
ignore_init_module_imports: None,
line_length: None,
@ -317,6 +318,7 @@ mod tests {
fix: None,
fixable: None,
format: None,
force_exclude: None,
ignore: Some(vec![]),
ignore_init_module_imports: None,
line_length: Some(100),
@ -366,6 +368,7 @@ mod tests {
fix: None,
fixable: None,
format: None,
force_exclude: None,
ignore: Some(vec![]),
ignore_init_module_imports: None,
line_length: Some(100),
@ -415,6 +418,7 @@ mod tests {
fix: None,
fixable: None,
format: None,
force_exclude: None,
ignore: Some(vec![]),
ignore_init_module_imports: None,
line_length: None,
@ -464,6 +468,7 @@ mod tests {
fix: None,
fixable: None,
format: None,
force_exclude: None,
ignore: Some(vec![]),
ignore_init_module_imports: None,
line_length: None,
@ -521,6 +526,7 @@ mod tests {
fix: None,
fixable: None,
format: None,
force_exclude: None,
ignore: Some(vec![]),
ignore_init_module_imports: None,
line_length: None,
@ -606,6 +612,7 @@ mod tests {
fix: None,
fixable: None,
format: None,
force_exclude: None,
ignore: Some(vec![]),
ignore_init_module_imports: None,
line_length: None,

View file

@ -32,6 +32,10 @@ build-backend = "maturin"
bindings = "bin"
strip = true
[tool.ruff]
force-exclude = true
exclude = ["setup.py"]
[tool.ruff.isort]
force-wrap-aliases = true
combine-as-imports = true

View file

@ -1,5 +1,6 @@
import sys
import os
from setuptools import setup
sys.stderr.write(

View file

@ -92,6 +92,12 @@ pub struct Cli {
respect_gitignore: bool,
#[clap(long, overrides_with("respect_gitignore"), hide = true)]
no_respect_gitignore: bool,
/// Enforce exclusions, even for paths passed to Ruff directly on the
/// command-line.
#[arg(long, overrides_with("no_show_source"))]
force_exclude: bool,
#[clap(long, overrides_with("force_exclude"), hide = true)]
no_force_exclude: bool,
/// See the files Ruff will be run against with the current settings.
#[arg(long)]
pub show_files: bool,
@ -173,6 +179,7 @@ impl Cli {
// TODO(charlie): Included in `pyproject.toml`, but not inherited.
fix: resolve_bool_arg(self.fix, self.no_fix),
format: self.format,
force_exclude: resolve_bool_arg(self.force_exclude, self.no_force_exclude),
},
)
}
@ -230,6 +237,7 @@ pub struct Overrides {
// TODO(charlie): Captured in pyproject.toml as a default, but not part of `Settings`.
pub fix: Option<bool>,
pub format: Option<SerializationFormat>,
pub force_exclude: Option<bool>,
}
/// Map the CLI settings to a `LogLevel`.

View file

@ -103,6 +103,10 @@ fn inner_main() -> Result<ExitCode> {
// Extract options that are included in `Settings`, but only apply at the top
// level.
let file_strategy = FileDiscovery {
force_exclude: match &pyproject_strategy {
PyprojectDiscovery::Fixed(settings) => settings.force_exclude,
PyprojectDiscovery::Hierarchical(settings) => settings.force_exclude,
},
respect_gitignore: match &pyproject_strategy {
PyprojectDiscovery::Fixed(settings) => settings.respect_gitignore,
PyprojectDiscovery::Hierarchical(settings) => settings.respect_gitignore,

View file

@ -20,6 +20,7 @@ use crate::settings::{pyproject, Settings};
/// The strategy used to discover Python files in the filesystem..
#[derive(Debug)]
pub struct FileDiscovery {
pub force_exclude: bool,
pub respect_gitignore: bool,
}
@ -263,7 +264,7 @@ pub fn python_files_in_path(
// Respect our own exclusion behavior.
if let Ok(entry) = &result {
if entry.depth() > 0 {
if file_strategy.force_exclude || entry.depth() > 0 {
let path = entry.path();
let resolver = resolver.read().unwrap();
let settings = resolver.resolve(path, pyproject_strategy);

View file

@ -31,6 +31,7 @@ pub struct Configuration {
pub fix: Option<bool>,
pub fixable: Option<Vec<CheckCodePrefix>>,
pub format: Option<SerializationFormat>,
pub force_exclude: Option<bool>,
pub ignore: Option<Vec<CheckCodePrefix>>,
pub ignore_init_module_imports: Option<bool>,
pub line_length: Option<usize>,
@ -96,6 +97,7 @@ impl Configuration {
fix: options.fix,
fixable: options.fixable,
format: options.format,
force_exclude: options.force_exclude,
ignore: options.ignore,
ignore_init_module_imports: options.ignore_init_module_imports,
line_length: options.line_length,
@ -159,6 +161,7 @@ impl Configuration {
fix: self.fix.or(config.fix),
fixable: self.fixable.or(config.fixable),
format: self.format.or(config.format),
force_exclude: self.force_exclude.or(config.force_exclude),
ignore: self.ignore.or(config.ignore),
ignore_init_module_imports: self
.ignore_init_module_imports
@ -208,6 +211,9 @@ impl Configuration {
if let Some(format) = overrides.format {
self.format = Some(format);
}
if let Some(force_exclude) = overrides.force_exclude {
self.force_exclude = Some(force_exclude);
}
if let Some(ignore) = overrides.ignore {
self.ignore = Some(ignore);
}

View file

@ -41,6 +41,7 @@ pub struct Settings {
pub fix: bool,
pub fixable: FxHashSet<CheckCode>,
pub format: SerializationFormat,
pub force_exclude: bool,
pub ignore_init_module_imports: bool,
pub line_length: usize,
pub per_file_ignores: Vec<(GlobMatcher, GlobMatcher, FxHashSet<CheckCode>)>,
@ -127,6 +128,7 @@ impl Settings {
.into_iter(),
),
format: config.format.unwrap_or(SerializationFormat::Text),
force_exclude: config.force_exclude.unwrap_or(false),
ignore_init_module_imports: config.ignore_init_module_imports.unwrap_or_default(),
line_length: config.line_length.unwrap_or(88),
per_file_ignores: resolve_per_file_ignores(
@ -199,6 +201,7 @@ impl Settings {
fix: false,
fixable: FxHashSet::from_iter([check_code]),
format: SerializationFormat::Text,
force_exclude: false,
ignore_init_module_imports: false,
line_length: 88,
per_file_ignores: vec![],
@ -231,6 +234,7 @@ impl Settings {
fix: false,
fixable: FxHashSet::from_iter(check_codes),
format: SerializationFormat::Text,
force_exclude: false,
ignore_init_module_imports: false,
line_length: 88,
per_file_ignores: vec![],

View file

@ -165,6 +165,24 @@ pub struct Options {
"#
)]
pub format: Option<SerializationFormat>,
#[option(
doc = r#"
Whether to enforce `exclude` and `extend-exclude` patterns, even for paths that are
passed to Ruff explicitly. Typically, Ruff will lint any paths passed in directly, even
if they would typically be excluded. Setting `force-exclude = true` will cause Ruff to
respect these exclusions unequivocally.
This is useful for [`pre-commit`](https://pre-commit.com/), which explicitly passes all
changed files to the [`ruff-pre-commit`](https://github.com/charliermarsh/ruff-pre-commit)
plugin, regardless of whether they're marked as excluded by Ruff's own settings.
"#,
default = r#"false"#,
value_type = "bool",
example = r#"
force-exclude = true
"#
)]
pub force_exclude: Option<bool>,
#[option(
doc = r"
A list of check code prefixes to ignore. Prefixes can specify exact checks (like

View file

@ -129,6 +129,8 @@ mod tests {
external: None,
fix: None,
fixable: None,
format: None,
force_exclude: None,
ignore: None,
ignore_init_module_imports: None,
line_length: None,
@ -138,7 +140,6 @@ mod tests {
show_source: None,
src: None,
target_version: None,
format: None,
unfixable: None,
flake8_annotations: None,
flake8_bugbear: None,
@ -176,6 +177,8 @@ line-length = 79
external: None,
fix: None,
fixable: None,
force_exclude: None,
format: None,
ignore: None,
ignore_init_module_imports: None,
line_length: Some(79),
@ -185,7 +188,6 @@ line-length = 79
show_source: None,
src: None,
target_version: None,
format: None,
unfixable: None,
flake8_annotations: None,
flake8_bugbear: None,
@ -214,26 +216,27 @@ exclude = ["foo.py"]
Some(Tools {
ruff: Some(Options {
allowed_confusables: None,
line_length: None,
fix: None,
extend: None,
dummy_variable_rgx: None,
exclude: Some(vec!["foo.py".to_string()]),
extend: None,
extend_exclude: None,
select: None,
extend_ignore: None,
extend_select: None,
external: None,
fix: None,
fixable: None,
force_exclude: None,
format: None,
ignore: None,
ignore_init_module_imports: None,
extend_ignore: None,
fixable: None,
format: None,
unfixable: None,
line_length: None,
per_file_ignores: None,
respect_gitignore: None,
dummy_variable_rgx: None,
select: None,
show_source: None,
src: None,
target_version: None,
show_source: None,
unfixable: None,
flake8_annotations: None,
flake8_errmsg: None,
flake8_bugbear: None,
@ -270,6 +273,8 @@ select = ["E501"]
external: None,
fix: None,
fixable: None,
force_exclude: None,
format: None,
ignore: None,
ignore_init_module_imports: None,
line_length: None,
@ -279,7 +284,6 @@ select = ["E501"]
show_source: None,
src: None,
target_version: None,
format: None,
unfixable: None,
flake8_annotations: None,
flake8_bugbear: None,
@ -318,6 +322,8 @@ ignore = ["E501"]
external: None,
fix: None,
fixable: None,
force_exclude: None,
format: None,
ignore: Some(vec![CheckCodePrefix::E501]),
ignore_init_module_imports: None,
line_length: None,
@ -327,7 +333,6 @@ ignore = ["E501"]
show_source: None,
src: None,
target_version: None,
format: None,
unfixable: None,
flake8_annotations: None,
flake8_bugbear: None,
@ -408,6 +413,7 @@ other-attribute = 1
extend_ignore: None,
fixable: None,
format: None,
force_exclude: None,
unfixable: None,
per_file_ignores: Some(FxHashMap::from_iter([(
"__init__.py".to_string(),