Only run pyproject.toml lint rules when enabled (#5578)

## Summary

I was testing some changes on Airflow, and I realized that we _always_
run the `pyproject.toml` validation rules, even if they're not enabled.
This PR gates them behind the appropriate enablement flags.

## Test Plan

- Ran: `cargo run -p ruff_cli -- check ../airflow -n`. Verified that no
RUF200 violations were raised.
- Run: `cargo run -p ruff_cli -- check ../airflow -n --select RUF200`.
Verified that two RUF200 violations were raised.
This commit is contained in:
Charlie Marsh 2023-07-08 11:05:05 -04:00 committed by GitHub
parent d0dae7e576
commit a1c559eaa4
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
4 changed files with 50 additions and 25 deletions

View file

@ -7,7 +7,9 @@ use ruff_diagnostics::Diagnostic;
use ruff_python_ast::source_code::SourceFile;
use crate::message::Message;
use crate::registry::Rule;
use crate::rules::ruff::rules::InvalidPyprojectToml;
use crate::settings::Settings;
use crate::IOError;
/// Unlike [`pyproject_toml::PyProjectToml`], in our case `build_system` is also optional
@ -20,9 +22,11 @@ struct PyProjectToml {
project: Option<Project>,
}
pub fn lint_pyproject_toml(source_file: SourceFile) -> Result<Vec<Message>> {
pub fn lint_pyproject_toml(source_file: SourceFile, settings: &Settings) -> Result<Vec<Message>> {
let mut messages = vec![];
let err = match toml::from_str::<PyProjectToml>(source_file.source_text()) {
Ok(_) => return Ok(Vec::default()),
Ok(_) => return Ok(messages),
Err(err) => err,
};
@ -32,17 +36,20 @@ pub fn lint_pyproject_toml(source_file: SourceFile) -> Result<Vec<Message>> {
None => TextRange::default(),
Some(range) => {
let Ok(end) = TextSize::try_from(range.end) else {
let diagnostic = Diagnostic::new(
IOError {
message: "pyproject.toml is larger than 4GB".to_string(),
},
TextRange::default(),
);
return Ok(vec![Message::from_diagnostic(
diagnostic,
source_file,
TextSize::default(),
)]);
if settings.rules.enabled(Rule::IOError) {
let diagnostic = Diagnostic::new(
IOError {
message: "pyproject.toml is larger than 4GB".to_string(),
},
TextRange::default(),
);
messages.push(Message::from_diagnostic(
diagnostic,
source_file,
TextSize::default(),
));
}
return Ok(messages);
};
TextRange::new(
// start <= end, so if end < 4GB follows start < 4GB
@ -52,11 +59,15 @@ pub fn lint_pyproject_toml(source_file: SourceFile) -> Result<Vec<Message>> {
}
};
let toml_err = err.message().to_string();
let diagnostic = Diagnostic::new(InvalidPyprojectToml { message: toml_err }, range);
Ok(vec![Message::from_diagnostic(
diagnostic,
source_file,
TextSize::default(),
)])
if settings.rules.enabled(Rule::InvalidPyprojectToml) {
let toml_err = err.message().to_string();
let diagnostic = Diagnostic::new(InvalidPyprojectToml { message: toml_err }, range);
messages.push(Message::from_diagnostic(
diagnostic,
source_file,
TextSize::default(),
));
}
Ok(messages)
}

View file

@ -252,6 +252,7 @@ pub enum LintSource {
Imports,
Noqa,
Filesystem,
PyprojectToml,
}
impl Rule {
@ -259,6 +260,7 @@ impl Rule {
/// physical lines).
pub const fn lint_source(&self) -> LintSource {
match self {
Rule::InvalidPyprojectToml => LintSource::PyprojectToml,
Rule::UnusedNOQA => LintSource::Noqa,
Rule::BlanketNOQA
| Rule::BlanketTypeIgnore

View file

@ -203,7 +203,10 @@ mod tests {
.join("pyproject.toml");
let contents = fs::read_to_string(path)?;
let source_file = SourceFileBuilder::new("pyproject.toml", contents).finish();
let messages = lint_pyproject_toml(source_file)?;
let messages = lint_pyproject_toml(
source_file,
&settings::Settings::for_rule(Rule::InvalidPyprojectToml),
)?;
assert_messages!(snapshot, messages);
Ok(())
}

View file

@ -127,11 +127,20 @@ pub(crate) fn lint_path(
debug!("Checking: {}", path.display());
// We have to special case this here since the python tokenizer doesn't work with toml
// We have to special case this here since the Python tokenizer doesn't work with TOML.
if is_project_toml(path) {
let contents = std::fs::read_to_string(path)?;
let source_file = SourceFileBuilder::new(path.to_string_lossy(), contents).finish();
let messages = lint_pyproject_toml(source_file)?;
let messages = if settings
.lib
.rules
.iter_enabled()
.any(|rule_code| rule_code.lint_source().is_pyproject_toml())
{
let contents = std::fs::read_to_string(path)?;
let source_file = SourceFileBuilder::new(path.to_string_lossy(), contents).finish();
lint_pyproject_toml(source_file, &settings.lib)?
} else {
vec![]
};
return Ok(Diagnostics {
messages,
..Diagnostics::default()