From 2823487bf8021ac81be0e8c4825731f87ccacb0a Mon Sep 17 00:00:00 2001 From: Charlie Marsh Date: Fri, 20 Sep 2024 15:39:36 -0400 Subject: [PATCH] Respect `lint.exclude` in ruff check `--add-noqa` (#13427) ## Summary Closes https://github.com/astral-sh/ruff/issues/13423. --- crates/ruff/src/commands/add_noqa.rs | 13 ++++++- crates/ruff/tests/lint.rs | 52 ++++++++++++++++++++++++++++ 2 files changed, 64 insertions(+), 1 deletion(-) diff --git a/crates/ruff/src/commands/add_noqa.rs b/crates/ruff/src/commands/add_noqa.rs index 48975f6b4108c..582ce69501a1c 100644 --- a/crates/ruff/src/commands/add_noqa.rs +++ b/crates/ruff/src/commands/add_noqa.rs @@ -10,7 +10,9 @@ use ruff_linter::linter::add_noqa_to_path; use ruff_linter::source_kind::SourceKind; use ruff_linter::warn_user_once; use ruff_python_ast::{PySourceType, SourceType}; -use ruff_workspace::resolver::{python_files_in_path, PyprojectConfig, ResolvedFile}; +use ruff_workspace::resolver::{ + match_exclusion, python_files_in_path, PyprojectConfig, ResolvedFile, +}; use crate::args::ConfigArguments; @@ -57,6 +59,15 @@ pub(crate) fn add_noqa( .and_then(|parent| package_roots.get(parent)) .and_then(|package| *package); let settings = resolver.resolve(path); + if (settings.file_resolver.force_exclude || !resolved_file.is_root()) + && match_exclusion( + resolved_file.path(), + resolved_file.file_name(), + &settings.linter.exclude, + ) + { + return None; + } let source_kind = match SourceKind::from_path(path, source_type) { Ok(Some(source_kind)) => source_kind, Ok(None) => return None, diff --git a/crates/ruff/tests/lint.rs b/crates/ruff/tests/lint.rs index 7209f33e5b46a..450e8e7158dfa 100644 --- a/crates/ruff/tests/lint.rs +++ b/crates/ruff/tests/lint.rs @@ -1619,6 +1619,58 @@ print( Ok(()) } +#[test] +fn add_noqa_exclude() -> Result<()> { + let tempdir = TempDir::new()?; + let ruff_toml = tempdir.path().join("ruff.toml"); + fs::write( + &ruff_toml, + r#" +[lint] +exclude = ["excluded.py"] +select = ["RUF015"] +"#, + )?; + + let test_path = tempdir.path().join("noqa.py"); + + fs::write( + &test_path, + r#" +def first_square(): + return [x * x for x in range(20)][0] +"#, + )?; + + let exclude_path = tempdir.path().join("excluded.py"); + + fs::write( + &exclude_path, + r#" +def first_square(): + return [x * x for x in range(20)][0] +"#, + )?; + + insta::with_settings!({ + filters => vec![(tempdir_filter(&tempdir).as_str(), "[TMP]/")] + }, { + assert_cmd_snapshot!(Command::new(get_cargo_bin(BIN_NAME)) + .current_dir(tempdir.path()) + .args(STDIN_BASE_OPTIONS) + .args(["--add-noqa"]), @r###" + success: true + exit_code: 0 + ----- stdout ----- + + ----- stderr ----- + Added 1 noqa directive. + "###); + }); + + Ok(()) +} + /// Infer `3.11` from `requires-python` in `pyproject.toml`. #[test] fn requires_python() -> Result<()> {