mirror of
https://github.com/astral-sh/ruff.git
synced 2025-08-04 10:48:32 +00:00
Check pyproject.toml
correctly when it is passed via stdin (#16971)
## Summary
Resolves #16950 and [a 1.5-year-old TODO
comment](8d16a5c8c9/crates/ruff/src/diagnostics.rs (L380)
).
After this change, a `pyproject.toml` will be linted the same as any
Python files would when passed via stdin.
## Test Plan
Integration tests.
This commit is contained in:
parent
b9a7328789
commit
6ef522159d
2 changed files with 220 additions and 5 deletions
|
@ -367,8 +367,7 @@ pub(crate) fn lint_path(
|
|||
})
|
||||
}
|
||||
|
||||
/// Generate `Diagnostic`s from source code content derived from
|
||||
/// stdin.
|
||||
/// Generate `Diagnostic`s from source code content derived from stdin.
|
||||
pub(crate) fn lint_stdin(
|
||||
path: Option<&Path>,
|
||||
package: Option<PackageRoot<'_>>,
|
||||
|
@ -377,13 +376,37 @@ pub(crate) fn lint_stdin(
|
|||
noqa: flags::Noqa,
|
||||
fix_mode: flags::FixMode,
|
||||
) -> Result<Diagnostics> {
|
||||
// TODO(charlie): Support `pyproject.toml`.
|
||||
let source_type = match path.and_then(|path| settings.linter.extension.get(path)) {
|
||||
None => match path.map(SourceType::from).unwrap_or_default() {
|
||||
SourceType::Python(source_type) => source_type,
|
||||
SourceType::Toml(_) => {
|
||||
return Ok(Diagnostics::default());
|
||||
|
||||
SourceType::Toml(source_type) if source_type.is_pyproject() => {
|
||||
if !settings
|
||||
.linter
|
||||
.rules
|
||||
.iter_enabled()
|
||||
.any(|rule_code| rule_code.lint_source().is_pyproject_toml())
|
||||
{
|
||||
return Ok(Diagnostics::default());
|
||||
}
|
||||
|
||||
let path = path.unwrap();
|
||||
let source_file =
|
||||
SourceFileBuilder::new(path.to_string_lossy(), contents.clone()).finish();
|
||||
|
||||
match fix_mode {
|
||||
flags::FixMode::Diff | flags::FixMode::Generate => {}
|
||||
flags::FixMode::Apply => write!(&mut io::stdout().lock(), "{contents}")?,
|
||||
}
|
||||
|
||||
return Ok(Diagnostics {
|
||||
messages: lint_pyproject_toml(source_file, &settings.linter),
|
||||
fixed: FixMap::from_iter([(fs::relativize_path(path), FixTable::default())]),
|
||||
notebook_indexes: FxHashMap::default(),
|
||||
});
|
||||
}
|
||||
|
||||
SourceType::Toml(_) => return Ok(Diagnostics::default()),
|
||||
},
|
||||
Some(language) => PySourceType::from(language),
|
||||
};
|
||||
|
|
|
@ -2233,3 +2233,195 @@ unfixable = ["RUF"]
|
|||
|
||||
Ok(())
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn pyproject_toml_stdin_syntax_error() {
|
||||
let mut cmd = RuffCheck::default()
|
||||
.args(["--stdin-filename", "pyproject.toml", "--select", "RUF200"])
|
||||
.build();
|
||||
|
||||
assert_cmd_snapshot!(
|
||||
cmd.pass_stdin("[project"),
|
||||
@r"
|
||||
success: false
|
||||
exit_code: 1
|
||||
----- stdout -----
|
||||
pyproject.toml:1:9: RUF200 Failed to parse pyproject.toml: invalid table header
|
||||
expected `.`, `]`
|
||||
|
|
||||
1 | [project
|
||||
| ^ RUF200
|
||||
|
|
||||
|
||||
Found 1 error.
|
||||
|
||||
----- stderr -----
|
||||
"
|
||||
);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn pyproject_toml_stdin_schema_error() {
|
||||
let mut cmd = RuffCheck::default()
|
||||
.args(["--stdin-filename", "pyproject.toml", "--select", "RUF200"])
|
||||
.build();
|
||||
|
||||
assert_cmd_snapshot!(
|
||||
cmd.pass_stdin("[project]\nname = 1"),
|
||||
@r"
|
||||
success: false
|
||||
exit_code: 1
|
||||
----- stdout -----
|
||||
pyproject.toml:2:8: RUF200 Failed to parse pyproject.toml: invalid type: integer `1`, expected a string
|
||||
|
|
||||
1 | [project]
|
||||
2 | name = 1
|
||||
| ^ RUF200
|
||||
|
|
||||
|
||||
Found 1 error.
|
||||
|
||||
----- stderr -----
|
||||
"
|
||||
);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn pyproject_toml_stdin_no_applicable_rules_selected() {
|
||||
let mut cmd = RuffCheck::default()
|
||||
.args(["--stdin-filename", "pyproject.toml"])
|
||||
.build();
|
||||
|
||||
assert_cmd_snapshot!(
|
||||
cmd.pass_stdin("[project"),
|
||||
@r"
|
||||
success: true
|
||||
exit_code: 0
|
||||
----- stdout -----
|
||||
All checks passed!
|
||||
|
||||
----- stderr -----
|
||||
"
|
||||
);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn pyproject_toml_stdin_no_applicable_rules_selected_2() {
|
||||
let mut cmd = RuffCheck::default()
|
||||
.args(["--stdin-filename", "pyproject.toml", "--select", "F401"])
|
||||
.build();
|
||||
|
||||
assert_cmd_snapshot!(
|
||||
cmd.pass_stdin("[project"),
|
||||
@r"
|
||||
success: true
|
||||
exit_code: 0
|
||||
----- stdout -----
|
||||
All checks passed!
|
||||
|
||||
----- stderr -----
|
||||
"
|
||||
);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn pyproject_toml_stdin_no_errors() {
|
||||
let mut cmd = RuffCheck::default()
|
||||
.args(["--stdin-filename", "pyproject.toml"])
|
||||
.build();
|
||||
|
||||
assert_cmd_snapshot!(
|
||||
cmd.pass_stdin(r#"[project]\nname = "ruff"\nversion = "0.0.0""#),
|
||||
@r"
|
||||
success: true
|
||||
exit_code: 0
|
||||
----- stdout -----
|
||||
All checks passed!
|
||||
|
||||
----- stderr -----
|
||||
"
|
||||
);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn pyproject_toml_stdin_schema_error_fix() {
|
||||
let mut cmd = RuffCheck::default()
|
||||
.args([
|
||||
"--stdin-filename",
|
||||
"pyproject.toml",
|
||||
"--select",
|
||||
"RUF200",
|
||||
"--fix",
|
||||
])
|
||||
.build();
|
||||
|
||||
assert_cmd_snapshot!(
|
||||
cmd.pass_stdin("[project]\nname = 1"),
|
||||
@r"
|
||||
success: false
|
||||
exit_code: 1
|
||||
----- stdout -----
|
||||
[project]
|
||||
name = 1
|
||||
----- stderr -----
|
||||
pyproject.toml:2:8: RUF200 Failed to parse pyproject.toml: invalid type: integer `1`, expected a string
|
||||
|
|
||||
1 | [project]
|
||||
2 | name = 1
|
||||
| ^ RUF200
|
||||
|
|
||||
|
||||
Found 1 error.
|
||||
"
|
||||
);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn pyproject_toml_stdin_schema_error_fix_only() {
|
||||
let mut cmd = RuffCheck::default()
|
||||
.args([
|
||||
"--stdin-filename",
|
||||
"pyproject.toml",
|
||||
"--select",
|
||||
"RUF200",
|
||||
"--fix-only",
|
||||
])
|
||||
.build();
|
||||
|
||||
assert_cmd_snapshot!(
|
||||
cmd.pass_stdin("[project]\nname = 1"),
|
||||
@r"
|
||||
success: true
|
||||
exit_code: 0
|
||||
----- stdout -----
|
||||
[project]
|
||||
name = 1
|
||||
----- stderr -----
|
||||
"
|
||||
);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn pyproject_toml_stdin_schema_error_fix_diff() {
|
||||
let mut cmd = RuffCheck::default()
|
||||
.args([
|
||||
"--stdin-filename",
|
||||
"pyproject.toml",
|
||||
"--select",
|
||||
"RUF200",
|
||||
"--fix",
|
||||
"--diff",
|
||||
])
|
||||
.build();
|
||||
|
||||
assert_cmd_snapshot!(
|
||||
cmd.pass_stdin("[project]\nname = 1"),
|
||||
@r"
|
||||
success: true
|
||||
exit_code: 0
|
||||
----- stdout -----
|
||||
|
||||
----- stderr -----
|
||||
"
|
||||
);
|
||||
}
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue