mirror of
https://github.com/astral-sh/ruff.git
synced 2025-08-04 18:58:04 +00:00
[red-knot] Add --respect-ignore-files flag (#17569)
Co-authored-by: Micha Reiser <micha@reiser.io>
This commit is contained in:
parent
cfa1505068
commit
2e95475f57
6 changed files with 136 additions and 3 deletions
|
@ -105,6 +105,19 @@ pub(crate) struct CheckCommand {
|
|||
/// Watch files for changes and recheck files related to the changed files.
|
||||
#[arg(long, short = 'W')]
|
||||
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 {
|
||||
|
@ -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 {
|
||||
environment: Some(EnvironmentOptions {
|
||||
python_version: self
|
||||
|
@ -144,6 +164,7 @@ impl CheckCommand {
|
|||
error_on_warning: self.error_on_warning,
|
||||
}),
|
||||
rules,
|
||||
respect_ignore_files,
|
||||
..Default::default()
|
||||
}
|
||||
}
|
||||
|
|
|
@ -5,6 +5,99 @@ use std::path::{Path, PathBuf};
|
|||
use std::process::Command;
|
||||
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
|
||||
let case = TestCase::with_files([(".ignore", "test.py"), ("test.py", "~")])?;
|
||||
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
|
||||
let case = TestCase::with_files([
|
||||
("knot.toml", "respect-ignore-files = false"),
|
||||
(".ignore", "test.py"),
|
||||
("test.py", "~"),
|
||||
])?;
|
||||
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
|
||||
let case = TestCase::with_files([
|
||||
("knot.toml", "respect-ignore-files = false"),
|
||||
(".ignore", "test.py"),
|
||||
("test.py", "~"),
|
||||
])?;
|
||||
assert_cmd_snapshot!(case.command().arg("--respect-ignore-files"), @r"
|
||||
success: true
|
||||
exit_code: 0
|
||||
----- stdout -----
|
||||
All checks passed!
|
||||
|
||||
----- stderr -----
|
||||
WARN No python files found under the given path(s)
|
||||
");
|
||||
|
||||
// Ensure --no-respect-ignore-files takes precedence over config file
|
||||
let case = TestCase::with_files([
|
||||
("knot.toml", "respect-ignore-files = true"),
|
||||
(".ignore", "test.py"),
|
||||
("test.py", "~"),
|
||||
])?;
|
||||
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
|
||||
/// project's configuration. Here, this is tested for the Python version.
|
||||
#[test]
|
||||
|
|
|
@ -32,6 +32,9 @@ pub struct Options {
|
|||
|
||||
#[serde(skip_serializing_if = "Option::is_none")]
|
||||
pub terminal: Option<TerminalOptions>,
|
||||
|
||||
#[serde(skip_serializing_if = "Option::is_none")]
|
||||
pub respect_ignore_files: Option<bool>,
|
||||
}
|
||||
|
||||
impl Options {
|
||||
|
@ -133,7 +136,7 @@ impl Options {
|
|||
pub(crate) fn to_settings(&self, db: &dyn Db) -> (Settings, Vec<OptionDiagnostic>) {
|
||||
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() {
|
||||
settings.set_terminal(TerminalSettings {
|
||||
|
|
|
@ -21,13 +21,16 @@ pub struct Settings {
|
|||
rules: Arc<RuleSelection>,
|
||||
|
||||
terminal: TerminalSettings,
|
||||
|
||||
respect_ignore_files: bool,
|
||||
}
|
||||
|
||||
impl Settings {
|
||||
pub fn new(rules: RuleSelection) -> Self {
|
||||
pub fn new(rules: RuleSelection, respect_ignore_files: Option<bool>) -> Self {
|
||||
Self {
|
||||
rules: Arc::new(rules),
|
||||
terminal: TerminalSettings::default(),
|
||||
respect_ignore_files: respect_ignore_files.unwrap_or(true),
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -35,6 +38,10 @@ impl Settings {
|
|||
&self.rules
|
||||
}
|
||||
|
||||
pub fn respect_ignore_files(&self) -> bool {
|
||||
self.respect_ignore_files
|
||||
}
|
||||
|
||||
pub fn to_rules(&self) -> Arc<RuleSelection> {
|
||||
self.rules.clone()
|
||||
}
|
||||
|
|
|
@ -129,7 +129,10 @@ impl<'a> ProjectFilesWalker<'a> {
|
|||
{
|
||||
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 {
|
||||
walker = walker.add(path);
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue