Add a CLI flag to force-ignore noqa directives (#3296)

This commit is contained in:
Charlie Marsh 2023-03-01 22:28:13 -05:00 committed by GitHub
parent 4a70a4c323
commit 3ed539d50e
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
10 changed files with 55 additions and 15 deletions

View file

@ -201,8 +201,8 @@ pub fn check(contents: &str, options: JsValue) -> Result<JsValue, JsValue> {
&indexer, &indexer,
&directives, &directives,
&settings, &settings,
flags::Autofix::Enabled,
flags::Noqa::Enabled, flags::Noqa::Enabled,
flags::Autofix::Enabled,
); );
let messages: Vec<ExpandedMessage> = diagnostics let messages: Vec<ExpandedMessage> = diagnostics

View file

@ -62,8 +62,8 @@ pub fn check_path(
indexer: &Indexer, indexer: &Indexer,
directives: &Directives, directives: &Directives,
settings: &Settings, settings: &Settings,
autofix: flags::Autofix,
noqa: flags::Noqa, noqa: flags::Noqa,
autofix: flags::Autofix,
) -> LinterResult<Vec<Diagnostic>> { ) -> LinterResult<Vec<Diagnostic>> {
// Aggregate all diagnostics. // Aggregate all diagnostics.
let mut diagnostics = vec![]; let mut diagnostics = vec![];
@ -255,8 +255,8 @@ pub fn add_noqa_to_path(path: &Path, package: Option<&Path>, settings: &Settings
&indexer, &indexer,
&directives, &directives,
settings, settings,
flags::Autofix::Disabled,
flags::Noqa::Disabled, flags::Noqa::Disabled,
flags::Autofix::Disabled,
); );
// Log any parse errors. // Log any parse errors.
@ -287,6 +287,7 @@ pub fn lint_only(
path: &Path, path: &Path,
package: Option<&Path>, package: Option<&Path>,
settings: &Settings, settings: &Settings,
noqa: flags::Noqa,
autofix: flags::Autofix, autofix: flags::Autofix,
) -> LinterResult<Vec<Message>> { ) -> LinterResult<Vec<Message>> {
// Tokenize once. // Tokenize once.
@ -316,8 +317,8 @@ pub fn lint_only(
&indexer, &indexer,
&directives, &directives,
settings, settings,
noqa,
autofix, autofix,
flags::Noqa::Enabled,
); );
// Convert from diagnostics to messages. // Convert from diagnostics to messages.
@ -345,6 +346,7 @@ pub fn lint_fix<'a>(
contents: &'a str, contents: &'a str,
path: &Path, path: &Path,
package: Option<&Path>, package: Option<&Path>,
noqa: flags::Noqa,
settings: &Settings, settings: &Settings,
) -> Result<(LinterResult<Vec<Message>>, Cow<'a, str>, FixTable)> { ) -> Result<(LinterResult<Vec<Message>>, Cow<'a, str>, FixTable)> {
let mut transformed = Cow::Borrowed(contents); let mut transformed = Cow::Borrowed(contents);
@ -387,8 +389,8 @@ pub fn lint_fix<'a>(
&indexer, &indexer,
&directives, &directives,
settings, settings,
noqa,
flags::Autofix::Enabled, flags::Autofix::Enabled,
flags::Noqa::Enabled,
); );
if iterations == 0 { if iterations == 0 {

View file

@ -41,8 +41,8 @@ mod tests {
&indexer, &indexer,
&directives, &directives,
&settings, &settings,
flags::Autofix::Enabled,
flags::Noqa::Enabled, flags::Noqa::Enabled,
flags::Autofix::Enabled,
); );
let actual = diagnostics let actual = diagnostics
.iter() .iter()

View file

@ -263,8 +263,8 @@ mod tests {
&indexer, &indexer,
&directives, &directives,
&settings, &settings,
flags::Autofix::Enabled,
flags::Noqa::Enabled, flags::Noqa::Enabled,
flags::Autofix::Enabled,
); );
diagnostics.sort_by_key(|diagnostic| diagnostic.location); diagnostics.sort_by_key(|diagnostic| diagnostic.location);
let actual = diagnostics let actual = diagnostics

View file

@ -43,8 +43,8 @@ pub fn test_path(path: &Path, settings: &Settings) -> Result<Vec<Diagnostic>> {
&indexer, &indexer,
&directives, &directives,
settings, settings,
flags::Autofix::Enabled,
flags::Noqa::Enabled, flags::Noqa::Enabled,
flags::Autofix::Enabled,
); );
// Detect autofixes that don't converge after multiple iterations. // Detect autofixes that don't converge after multiple iterations.
@ -76,8 +76,8 @@ pub fn test_path(path: &Path, settings: &Settings) -> Result<Vec<Diagnostic>> {
&indexer, &indexer,
&directives, &directives,
settings, settings,
flags::Autofix::Enabled,
flags::Noqa::Enabled, flags::Noqa::Enabled,
flags::Autofix::Enabled,
); );
if let Some((fixed_contents, _)) = fix_file(&diagnostics, &locator) { if let Some((fixed_contents, _)) = fix_file(&diagnostics, &locator) {
if iterations < max_iterations { if iterations < max_iterations {

View file

@ -93,6 +93,9 @@ pub struct CheckArgs {
fix_only: bool, fix_only: bool,
#[clap(long, overrides_with("fix_only"), hide = true)] #[clap(long, overrides_with("fix_only"), hide = true)]
no_fix_only: bool, no_fix_only: bool,
/// Ignore any `# noqa` comments.
#[arg(long)]
ignore_noqa: bool,
/// Output serialization format for violations. /// Output serialization format for violations.
#[arg(long, value_enum, env = "RUFF_FORMAT")] #[arg(long, value_enum, env = "RUFF_FORMAT")]
pub format: Option<SerializationFormat>, pub format: Option<SerializationFormat>,
@ -258,6 +261,7 @@ pub struct CheckArgs {
conflicts_with = "show_files", conflicts_with = "show_files",
conflicts_with = "show_settings", conflicts_with = "show_settings",
// Unsupported default-command arguments. // Unsupported default-command arguments.
conflicts_with = "ignore_noqa",
conflicts_with = "statistics", conflicts_with = "statistics",
conflicts_with = "stdin_filename", conflicts_with = "stdin_filename",
conflicts_with = "watch", conflicts_with = "watch",
@ -272,6 +276,7 @@ pub struct CheckArgs {
// conflicts_with = "show_files", // conflicts_with = "show_files",
conflicts_with = "show_settings", conflicts_with = "show_settings",
// Unsupported default-command arguments. // Unsupported default-command arguments.
conflicts_with = "ignore_noqa",
conflicts_with = "statistics", conflicts_with = "statistics",
conflicts_with = "stdin_filename", conflicts_with = "stdin_filename",
conflicts_with = "watch", conflicts_with = "watch",
@ -285,6 +290,7 @@ pub struct CheckArgs {
conflicts_with = "show_files", conflicts_with = "show_files",
// conflicts_with = "show_settings", // conflicts_with = "show_settings",
// Unsupported default-command arguments. // Unsupported default-command arguments.
conflicts_with = "ignore_noqa",
conflicts_with = "statistics", conflicts_with = "statistics",
conflicts_with = "stdin_filename", conflicts_with = "stdin_filename",
conflicts_with = "watch", conflicts_with = "watch",
@ -357,6 +363,7 @@ impl CheckArgs {
exit_zero: self.exit_zero, exit_zero: self.exit_zero,
exit_non_zero_on_fix: self.exit_non_zero_on_fix, exit_non_zero_on_fix: self.exit_non_zero_on_fix,
files: self.files, files: self.files,
ignore_noqa: self.ignore_noqa,
isolated: self.isolated, isolated: self.isolated,
no_cache: self.no_cache, no_cache: self.no_cache,
show_files: self.show_files, show_files: self.show_files,
@ -415,6 +422,7 @@ pub struct Arguments {
pub exit_zero: bool, pub exit_zero: bool,
pub exit_non_zero_on_fix: bool, pub exit_non_zero_on_fix: bool,
pub files: Vec<PathBuf>, pub files: Vec<PathBuf>,
pub ignore_noqa: bool,
pub isolated: bool, pub isolated: bool,
pub no_cache: bool, pub no_cache: bool,
pub show_files: bool, pub show_files: bool,

View file

@ -26,6 +26,7 @@ pub fn run(
pyproject_strategy: &PyprojectDiscovery, pyproject_strategy: &PyprojectDiscovery,
overrides: &Overrides, overrides: &Overrides,
cache: flags::Cache, cache: flags::Cache,
noqa: flags::Noqa,
autofix: fix::FixMode, autofix: fix::FixMode,
) -> Result<Diagnostics> { ) -> Result<Diagnostics> {
// Collect all the Python files to check. // Collect all the Python files to check.
@ -84,7 +85,7 @@ pub fn run(
.and_then(|parent| package_roots.get(parent)) .and_then(|parent| package_roots.get(parent))
.and_then(|package| *package); .and_then(|package| *package);
let settings = resolver.resolve_all(path, pyproject_strategy); let settings = resolver.resolve_all(path, pyproject_strategy);
lint_path(path, package, settings, cache, autofix) lint_path(path, package, settings, cache, noqa, autofix)
.map_err(|e| (Some(path.to_owned()), e.to_string())) .map_err(|e| (Some(path.to_owned()), e.to_string()))
} }
Err(e) => Err(( Err(e) => Err((

View file

@ -4,6 +4,7 @@ use std::path::Path;
use anyhow::Result; use anyhow::Result;
use ruff::resolver::PyprojectDiscovery; use ruff::resolver::PyprojectDiscovery;
use ruff::settings::flags;
use ruff::{fix, packaging, resolver}; use ruff::{fix, packaging, resolver};
use crate::args::Overrides; use crate::args::Overrides;
@ -21,6 +22,7 @@ pub fn run_stdin(
filename: Option<&Path>, filename: Option<&Path>,
pyproject_strategy: &PyprojectDiscovery, pyproject_strategy: &PyprojectDiscovery,
overrides: &Overrides, overrides: &Overrides,
noqa: flags::Noqa,
autofix: fix::FixMode, autofix: fix::FixMode,
) -> Result<Diagnostics> { ) -> Result<Diagnostics> {
if let Some(filename) = filename { if let Some(filename) = filename {
@ -33,7 +35,7 @@ pub fn run_stdin(
.and_then(Path::parent) .and_then(Path::parent)
.and_then(|path| packaging::detect_package_root(path, &settings.lib.namespace_packages)); .and_then(|path| packaging::detect_package_root(path, &settings.lib.namespace_packages));
let stdin = read_from_stdin()?; let stdin = read_from_stdin()?;
let mut diagnostics = lint_stdin(filename, package_root, &stdin, &settings.lib, autofix)?; let mut diagnostics = lint_stdin(filename, package_root, &stdin, &settings.lib, noqa, autofix)?;
diagnostics.messages.sort_unstable(); diagnostics.messages.sort_unstable();
Ok(diagnostics) Ok(diagnostics)
} }

View file

@ -57,6 +57,7 @@ pub fn lint_path(
package: Option<&Path>, package: Option<&Path>,
settings: &AllSettings, settings: &AllSettings,
cache: flags::Cache, cache: flags::Cache,
noqa: flags::Noqa,
autofix: fix::FixMode, autofix: fix::FixMode,
) -> Result<Diagnostics> { ) -> Result<Diagnostics> {
// Check the cache. // Check the cache.
@ -65,7 +66,9 @@ pub fn lint_path(
// to cache `fixer::Mode::Apply`, since a file either has no fixes, or we'll // to cache `fixer::Mode::Apply`, since a file either has no fixes, or we'll
// write the fixes to disk, thus invalidating the cache. But it's a bit hard // write the fixes to disk, thus invalidating the cache. But it's a bit hard
// to reason about. We need to come up with a better solution here.) // to reason about. We need to come up with a better solution here.)
let metadata = if cache.into() && matches!(autofix, fix::FixMode::None | fix::FixMode::Generate) let metadata = if cache.into()
&& noqa.into()
&& matches!(autofix, fix::FixMode::None | fix::FixMode::Generate)
{ {
let metadata = path.metadata()?; let metadata = path.metadata()?;
if let Some(messages) = if let Some(messages) =
@ -90,7 +93,8 @@ pub fn lint_path(
}, },
fixed, fixed,
) = if matches!(autofix, fix::FixMode::Apply | fix::FixMode::Diff) { ) = if matches!(autofix, fix::FixMode::Apply | fix::FixMode::Diff) {
if let Ok((result, transformed, fixed)) = lint_fix(&contents, path, package, &settings.lib) if let Ok((result, transformed, fixed)) =
lint_fix(&contents, path, package, noqa, &settings.lib)
{ {
if !fixed.is_empty() { if !fixed.is_empty() {
if matches!(autofix, fix::FixMode::Apply) { if matches!(autofix, fix::FixMode::Apply) {
@ -108,12 +112,26 @@ pub fn lint_path(
(result, fixed) (result, fixed)
} else { } else {
// If we fail to autofix, lint the original source code. // If we fail to autofix, lint the original source code.
let result = lint_only(&contents, path, package, &settings.lib, autofix.into()); let result = lint_only(
&contents,
path,
package,
&settings.lib,
noqa,
autofix.into(),
);
let fixed = FxHashMap::default(); let fixed = FxHashMap::default();
(result, fixed) (result, fixed)
} }
} else { } else {
let result = lint_only(&contents, path, package, &settings.lib, autofix.into()); let result = lint_only(
&contents,
path,
package,
&settings.lib,
noqa,
autofix.into(),
);
let fixed = FxHashMap::default(); let fixed = FxHashMap::default();
(result, fixed) (result, fixed)
}; };
@ -158,6 +176,7 @@ pub fn lint_stdin(
package: Option<&Path>, package: Option<&Path>,
contents: &str, contents: &str,
settings: &Settings, settings: &Settings,
noqa: flags::Noqa,
autofix: fix::FixMode, autofix: fix::FixMode,
) -> Result<Diagnostics> { ) -> Result<Diagnostics> {
// Lint the inputs. // Lint the inputs.
@ -172,6 +191,7 @@ pub fn lint_stdin(
contents, contents,
path.unwrap_or_else(|| Path::new("-")), path.unwrap_or_else(|| Path::new("-")),
package, package,
noqa,
settings, settings,
) { ) {
if matches!(autofix, fix::FixMode::Apply) { if matches!(autofix, fix::FixMode::Apply) {
@ -201,6 +221,7 @@ pub fn lint_stdin(
path.unwrap_or_else(|| Path::new("-")), path.unwrap_or_else(|| Path::new("-")),
package, package,
settings, settings,
noqa,
autofix.into(), autofix.into(),
); );
let fixed = FxHashMap::default(); let fixed = FxHashMap::default();
@ -218,6 +239,7 @@ pub fn lint_stdin(
path.unwrap_or_else(|| Path::new("-")), path.unwrap_or_else(|| Path::new("-")),
package, package,
settings, settings,
noqa,
autofix.into(), autofix.into(),
); );
let fixed = FxHashMap::default(); let fixed = FxHashMap::default();

View file

@ -172,6 +172,7 @@ fn check(args: CheckArgs, log_level: LogLevel) -> Result<ExitStatus> {
fix::FixMode::None fix::FixMode::None
}; };
let cache = !cli.no_cache; let cache = !cli.no_cache;
let noqa = !cli.ignore_noqa;
let mut printer_flags = PrinterFlags::empty(); let mut printer_flags = PrinterFlags::empty();
if !(cli.diff || fix_only) { if !(cli.diff || fix_only) {
printer_flags |= PrinterFlags::SHOW_VIOLATIONS; printer_flags |= PrinterFlags::SHOW_VIOLATIONS;
@ -222,6 +223,7 @@ fn check(args: CheckArgs, log_level: LogLevel) -> Result<ExitStatus> {
&pyproject_strategy, &pyproject_strategy,
&overrides, &overrides,
cache.into(), cache.into(),
noqa.into(),
fix::FixMode::None, fix::FixMode::None,
)?; )?;
printer.write_continuously(&messages)?; printer.write_continuously(&messages)?;
@ -251,6 +253,7 @@ fn check(args: CheckArgs, log_level: LogLevel) -> Result<ExitStatus> {
&pyproject_strategy, &pyproject_strategy,
&overrides, &overrides,
cache.into(), cache.into(),
noqa.into(),
fix::FixMode::None, fix::FixMode::None,
)?; )?;
printer.write_continuously(&messages)?; printer.write_continuously(&messages)?;
@ -268,6 +271,7 @@ fn check(args: CheckArgs, log_level: LogLevel) -> Result<ExitStatus> {
cli.stdin_filename.map(fs::normalize_path).as_deref(), cli.stdin_filename.map(fs::normalize_path).as_deref(),
&pyproject_strategy, &pyproject_strategy,
&overrides, &overrides,
noqa.into(),
autofix, autofix,
)? )?
} else { } else {
@ -276,6 +280,7 @@ fn check(args: CheckArgs, log_level: LogLevel) -> Result<ExitStatus> {
&pyproject_strategy, &pyproject_strategy,
&overrides, &overrides,
cache.into(), cache.into(),
noqa.into(),
autofix, autofix,
)? )?
}; };