mirror of https://github.com/astral-sh/ruff
[red-knot] Add --respect-ignore-files flag (#17645)
Co-authored-by: Micha Reiser <micha@reiser.io>
This commit is contained in:
parent
b0d475f353
commit
4443f6653c
|
|
@ -105,6 +105,19 @@ pub(crate) struct CheckCommand {
|
||||||
/// Watch files for changes and recheck files related to the changed files.
|
/// Watch files for changes and recheck files related to the changed files.
|
||||||
#[arg(long, short = 'W')]
|
#[arg(long, short = 'W')]
|
||||||
pub(crate) watch: bool,
|
pub(crate) watch: bool,
|
||||||
|
|
||||||
|
/// Respect file exclusions via `.gitignore` and other standard ignore files.
|
||||||
|
/// Use `--no-respect-gitignore` to disable.
|
||||||
|
#[arg(
|
||||||
|
long,
|
||||||
|
overrides_with("no_respect_ignore_files"),
|
||||||
|
help_heading = "File selection",
|
||||||
|
default_missing_value = "true",
|
||||||
|
num_args = 0..1
|
||||||
|
)]
|
||||||
|
respect_ignore_files: Option<bool>,
|
||||||
|
#[clap(long, overrides_with("respect_ignore_files"), hide = true)]
|
||||||
|
no_respect_ignore_files: bool,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl CheckCommand {
|
impl CheckCommand {
|
||||||
|
|
@ -120,6 +133,13 @@ impl CheckCommand {
|
||||||
)
|
)
|
||||||
};
|
};
|
||||||
|
|
||||||
|
// --no-respect-gitignore defaults to false and is set true by CLI flag. If passed, override config file
|
||||||
|
// Otherwise, only pass this through if explicitly set (don't default to anything here to
|
||||||
|
// make sure that doesn't take precedence over an explicitly-set config file value)
|
||||||
|
let respect_ignore_files = self
|
||||||
|
.no_respect_ignore_files
|
||||||
|
.then_some(false)
|
||||||
|
.or(self.respect_ignore_files);
|
||||||
Options {
|
Options {
|
||||||
environment: Some(EnvironmentOptions {
|
environment: Some(EnvironmentOptions {
|
||||||
python_version: self
|
python_version: self
|
||||||
|
|
@ -144,6 +164,7 @@ impl CheckCommand {
|
||||||
error_on_warning: self.error_on_warning,
|
error_on_warning: self.error_on_warning,
|
||||||
}),
|
}),
|
||||||
rules,
|
rules,
|
||||||
|
respect_ignore_files,
|
||||||
..Default::default()
|
..Default::default()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -5,6 +5,74 @@ use std::path::{Path, PathBuf};
|
||||||
use std::process::Command;
|
use std::process::Command;
|
||||||
use tempfile::TempDir;
|
use tempfile::TempDir;
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn test_respect_ignore_files() -> anyhow::Result<()> {
|
||||||
|
// First test that the default option works correctly (the file is skipped)
|
||||||
|
let case = TestCase::with_files([(".ignore", "test.py"), ("test.py", "~")])?;
|
||||||
|
assert_cmd_snapshot!(case.command(), @r"
|
||||||
|
success: true
|
||||||
|
exit_code: 0
|
||||||
|
----- stdout -----
|
||||||
|
All checks passed!
|
||||||
|
|
||||||
|
----- stderr -----
|
||||||
|
WARN No python files found under the given path(s)
|
||||||
|
");
|
||||||
|
|
||||||
|
// Test that we can set to false via CLI
|
||||||
|
assert_cmd_snapshot!(case.command().arg("--no-respect-ignore-files"), @r"
|
||||||
|
success: false
|
||||||
|
exit_code: 1
|
||||||
|
----- stdout -----
|
||||||
|
error: invalid-syntax
|
||||||
|
--> <temp_dir>/test.py:1:2
|
||||||
|
|
|
||||||
|
1 | ~
|
||||||
|
| ^ Expected an expression
|
||||||
|
|
|
||||||
|
|
||||||
|
Found 1 diagnostic
|
||||||
|
|
||||||
|
----- stderr -----
|
||||||
|
");
|
||||||
|
|
||||||
|
// Test that we can set to false via config file
|
||||||
|
case.write_file("knot.toml", "respect-ignore-files = false")?;
|
||||||
|
assert_cmd_snapshot!(case.command(), @r"
|
||||||
|
success: false
|
||||||
|
exit_code: 1
|
||||||
|
----- stdout -----
|
||||||
|
error: invalid-syntax
|
||||||
|
--> <temp_dir>/test.py:1:2
|
||||||
|
|
|
||||||
|
1 | ~
|
||||||
|
| ^ Expected an expression
|
||||||
|
|
|
||||||
|
|
||||||
|
Found 1 diagnostic
|
||||||
|
|
||||||
|
----- stderr -----
|
||||||
|
");
|
||||||
|
|
||||||
|
// Ensure CLI takes precedence
|
||||||
|
case.write_file("knot.toml", "respect-ignore-files = true")?;
|
||||||
|
assert_cmd_snapshot!(case.command().arg("--no-respect-ignore-files"), @r"
|
||||||
|
success: false
|
||||||
|
exit_code: 1
|
||||||
|
----- stdout -----
|
||||||
|
error: invalid-syntax
|
||||||
|
--> <temp_dir>/test.py:1:2
|
||||||
|
|
|
||||||
|
1 | ~
|
||||||
|
| ^ Expected an expression
|
||||||
|
|
|
||||||
|
|
||||||
|
Found 1 diagnostic
|
||||||
|
|
||||||
|
----- stderr -----
|
||||||
|
");
|
||||||
|
Ok(())
|
||||||
|
}
|
||||||
/// Specifying an option on the CLI should take precedence over the same setting in the
|
/// Specifying an option on the CLI should take precedence over the same setting in the
|
||||||
/// project's configuration. Here, this is tested for the Python version.
|
/// project's configuration. Here, this is tested for the Python version.
|
||||||
#[test]
|
#[test]
|
||||||
|
|
|
||||||
|
|
@ -32,6 +32,9 @@ pub struct Options {
|
||||||
|
|
||||||
#[serde(skip_serializing_if = "Option::is_none")]
|
#[serde(skip_serializing_if = "Option::is_none")]
|
||||||
pub terminal: Option<TerminalOptions>,
|
pub terminal: Option<TerminalOptions>,
|
||||||
|
|
||||||
|
#[serde(skip_serializing_if = "Option::is_none")]
|
||||||
|
pub respect_ignore_files: Option<bool>,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl Options {
|
impl Options {
|
||||||
|
|
@ -133,7 +136,7 @@ impl Options {
|
||||||
pub(crate) fn to_settings(&self, db: &dyn Db) -> (Settings, Vec<OptionDiagnostic>) {
|
pub(crate) fn to_settings(&self, db: &dyn Db) -> (Settings, Vec<OptionDiagnostic>) {
|
||||||
let (rules, diagnostics) = self.to_rule_selection(db);
|
let (rules, diagnostics) = self.to_rule_selection(db);
|
||||||
|
|
||||||
let mut settings = Settings::new(rules);
|
let mut settings = Settings::new(rules, self.respect_ignore_files);
|
||||||
|
|
||||||
if let Some(terminal) = self.terminal.as_ref() {
|
if let Some(terminal) = self.terminal.as_ref() {
|
||||||
settings.set_terminal(TerminalSettings {
|
settings.set_terminal(TerminalSettings {
|
||||||
|
|
|
||||||
|
|
@ -21,13 +21,16 @@ pub struct Settings {
|
||||||
rules: Arc<RuleSelection>,
|
rules: Arc<RuleSelection>,
|
||||||
|
|
||||||
terminal: TerminalSettings,
|
terminal: TerminalSettings,
|
||||||
|
|
||||||
|
respect_ignore_files: bool,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl Settings {
|
impl Settings {
|
||||||
pub fn new(rules: RuleSelection) -> Self {
|
pub fn new(rules: RuleSelection, respect_ignore_files: Option<bool>) -> Self {
|
||||||
Self {
|
Self {
|
||||||
rules: Arc::new(rules),
|
rules: Arc::new(rules),
|
||||||
terminal: TerminalSettings::default(),
|
terminal: TerminalSettings::default(),
|
||||||
|
respect_ignore_files: respect_ignore_files.unwrap_or(true),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -35,6 +38,10 @@ impl Settings {
|
||||||
&self.rules
|
&self.rules
|
||||||
}
|
}
|
||||||
|
|
||||||
|
pub fn respect_ignore_files(&self) -> bool {
|
||||||
|
self.respect_ignore_files
|
||||||
|
}
|
||||||
|
|
||||||
pub fn to_rules(&self) -> Arc<RuleSelection> {
|
pub fn to_rules(&self) -> Arc<RuleSelection> {
|
||||||
self.rules.clone()
|
self.rules.clone()
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -129,7 +129,10 @@ impl<'a> ProjectFilesWalker<'a> {
|
||||||
{
|
{
|
||||||
let mut paths = paths.into_iter();
|
let mut paths = paths.into_iter();
|
||||||
|
|
||||||
let mut walker = db.system().walk_directory(paths.next()?.as_ref());
|
let mut walker = db
|
||||||
|
.system()
|
||||||
|
.walk_directory(paths.next()?.as_ref())
|
||||||
|
.standard_filters(db.project().settings(db).respect_ignore_files());
|
||||||
|
|
||||||
for path in paths {
|
for path in paths {
|
||||||
walker = walker.add(path);
|
walker = walker.add(path);
|
||||||
|
|
|
||||||
|
|
@ -15,6 +15,12 @@
|
||||||
}
|
}
|
||||||
]
|
]
|
||||||
},
|
},
|
||||||
|
"respect-ignore-files": {
|
||||||
|
"type": [
|
||||||
|
"boolean",
|
||||||
|
"null"
|
||||||
|
]
|
||||||
|
},
|
||||||
"rules": {
|
"rules": {
|
||||||
"description": "Configures the enabled lints and their severity.",
|
"description": "Configures the enabled lints and their severity.",
|
||||||
"anyOf": [
|
"anyOf": [
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue