Skip to content

Commit

Permalink
Only run pyproject.toml lint rules when enabled (#5578)
Browse files Browse the repository at this point in the history
## 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.
  • Loading branch information
charliermarsh committed Jul 8, 2023
1 parent d0dae7e commit a1c559e
Show file tree
Hide file tree
Showing 4 changed files with 50 additions and 25 deletions.
51 changes: 31 additions & 20 deletions crates/ruff/src/pyproject_toml.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand All @@ -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,
};

Expand All @@ -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
Expand All @@ -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)
}
2 changes: 2 additions & 0 deletions crates/ruff/src/registry.rs
Original file line number Diff line number Diff line change
Expand Up @@ -252,13 +252,15 @@ pub enum LintSource {
Imports,
Noqa,
Filesystem,
PyprojectToml,
}

impl Rule {
/// The source for the diagnostic (either the AST, the filesystem, or the
/// physical lines).
pub const fn lint_source(&self) -> LintSource {
match self {
Rule::InvalidPyprojectToml => LintSource::PyprojectToml,
Rule::UnusedNOQA => LintSource::Noqa,
Rule::BlanketNOQA
| Rule::BlanketTypeIgnore
Expand Down
5 changes: 4 additions & 1 deletion crates/ruff/src/rules/ruff/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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(())
}
Expand Down
17 changes: 13 additions & 4 deletions crates/ruff_cli/src/diagnostics.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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()
Expand Down

0 comments on commit a1c559e

Please sign in to comment.