mirror of
https://github.com/astral-sh/ruff.git
synced 2025-10-01 14:21:53 +00:00
Automatically update README.md from generate_rules_table.rs (#606)
This commit is contained in:
parent
c48c7669a8
commit
2e1799dd80
3 changed files with 104 additions and 46 deletions
31
README.md
31
README.md
|
@ -295,9 +295,12 @@ By default, Ruff enables all `E` and `F` error codes, which correspond to those
|
|||
|
||||
The 🛠 emoji indicates that a rule is automatically fixable by the `--fix` command-line option.
|
||||
|
||||
<!-- Sections automatically generated by examples/generate_rules_table.rs. -->
|
||||
<!-- Begin auto-generated sections. -->
|
||||
|
||||
### Pyflakes
|
||||
|
||||
| Code | Name | Message | Fix |
|
||||
| Coade | Name | Message | Fix |
|
||||
| ---- | ---- | ------- | --- |
|
||||
| F401 | UnusedImport | `...` imported but unused | 🛠 |
|
||||
| F402 | ImportShadowedByLoopVar | Import `...` from line 1 shadowed by loop variable | |
|
||||
|
@ -330,7 +333,7 @@ The 🛠 emoji indicates that a rule is automatically fixable by the `--fix` com
|
|||
|
||||
### pycodestyle (error)
|
||||
|
||||
| Code | Name | Message | Fix |
|
||||
| Coade | Name | Message | Fix |
|
||||
| ---- | ---- | ------- | --- |
|
||||
| E402 | ModuleImportNotAtTopOfFile | Module level import not at top of file | |
|
||||
| E501 | LineTooLong | Line too long (89 > 88 characters) | |
|
||||
|
@ -349,14 +352,14 @@ The 🛠 emoji indicates that a rule is automatically fixable by the `--fix` com
|
|||
|
||||
### pycodestyle (warning)
|
||||
|
||||
| Code | Name | Message | Fix |
|
||||
| Coade | Name | Message | Fix |
|
||||
| ---- | ---- | ------- | --- |
|
||||
| W292 | NoNewLineAtEndOfFile | No newline at end of file | |
|
||||
| W605 | InvalidEscapeSequence | Invalid escape sequence: '\c' | |
|
||||
|
||||
### pydocstyle
|
||||
|
||||
| Code | Name | Message | Fix |
|
||||
| Coade | Name | Message | Fix |
|
||||
| ---- | ---- | ------- | --- |
|
||||
| D100 | PublicModule | Missing docstring in public module | |
|
||||
| D101 | PublicClass | Missing docstring in public class | |
|
||||
|
@ -405,7 +408,7 @@ The 🛠 emoji indicates that a rule is automatically fixable by the `--fix` com
|
|||
|
||||
### pyupgrade
|
||||
|
||||
| Code | Name | Message | Fix |
|
||||
| Coade | Name | Message | Fix |
|
||||
| ---- | ---- | ------- | --- |
|
||||
| U001 | UselessMetaclassType | `__metaclass__ = type` is implied | 🛠 |
|
||||
| U002 | UnnecessaryAbspath | `abspath(__file__)` is unnecessary in Python 3.9 and later | 🛠 |
|
||||
|
@ -418,7 +421,7 @@ The 🛠 emoji indicates that a rule is automatically fixable by the `--fix` com
|
|||
|
||||
### pep8-naming
|
||||
|
||||
| Code | Name | Message | Fix |
|
||||
| Coade | Name | Message | Fix |
|
||||
| ---- | ---- | ------- | --- |
|
||||
| N801 | InvalidClassName | Class name `...` should use CapWords convention | |
|
||||
| N802 | InvalidFunctionName | Function name `...` should be lowercase | |
|
||||
|
@ -438,7 +441,7 @@ The 🛠 emoji indicates that a rule is automatically fixable by the `--fix` com
|
|||
|
||||
### flake8-comprehensions
|
||||
|
||||
| Code | Name | Message | Fix |
|
||||
| Coade | Name | Message | Fix |
|
||||
| ---- | ---- | ------- | --- |
|
||||
| C400 | UnnecessaryGeneratorList | Unnecessary generator (rewrite as a `list` comprehension) | 🛠 |
|
||||
| C401 | UnnecessaryGeneratorSet | Unnecessary generator (rewrite as a `set` comprehension) | 🛠 |
|
||||
|
@ -459,7 +462,7 @@ The 🛠 emoji indicates that a rule is automatically fixable by the `--fix` com
|
|||
|
||||
### flake8-bugbear
|
||||
|
||||
| Code | Name | Message | Fix |
|
||||
| Coade | Name | Message | Fix |
|
||||
| ---- | ---- | ------- | --- |
|
||||
| B002 | UnaryPrefixIncrement | Python does not support the unary prefix increment. | |
|
||||
| B003 | AssignmentToOsEnviron | Assigning to `os.environ` doesn't clear the environment. | |
|
||||
|
@ -477,7 +480,7 @@ The 🛠 emoji indicates that a rule is automatically fixable by the `--fix` com
|
|||
|
||||
### flake8-builtins
|
||||
|
||||
| Code | Name | Message | Fix |
|
||||
| Coade | Name | Message | Fix |
|
||||
| ---- | ---- | ------- | --- |
|
||||
| A001 | BuiltinVariableShadowing | Variable `...` is shadowing a python builtin | |
|
||||
| A002 | BuiltinArgumentShadowing | Argument `...` is shadowing a python builtin | |
|
||||
|
@ -485,14 +488,14 @@ The 🛠 emoji indicates that a rule is automatically fixable by the `--fix` com
|
|||
|
||||
### flake8-print
|
||||
|
||||
| Code | Name | Message | Fix |
|
||||
| Coade | Name | Message | Fix |
|
||||
| ---- | ---- | ------- | --- |
|
||||
| T201 | PrintFound | `print` found | 🛠 |
|
||||
| T203 | PPrintFound | `pprint` found | 🛠 |
|
||||
|
||||
### flake8-quotes
|
||||
|
||||
| Code | Name | Message | Fix |
|
||||
| Coade | Name | Message | Fix |
|
||||
| ---- | ---- | ------- | --- |
|
||||
| Q000 | BadQuotesInlineString | Single quotes found but double quotes preferred | |
|
||||
| Q001 | BadQuotesMultilineString | Single quote multiline found but double quotes preferred | |
|
||||
|
@ -501,17 +504,19 @@ The 🛠 emoji indicates that a rule is automatically fixable by the `--fix` com
|
|||
|
||||
### Ruff-specific rules
|
||||
|
||||
| Code | Name | Message | Fix |
|
||||
| Coade | Name | Message | Fix |
|
||||
| ---- | ---- | ------- | --- |
|
||||
| RUF001 | AmbiguousUnicodeCharacterString | String contains ambiguous unicode character '𝐁' (did you mean 'B'?) | 🛠 |
|
||||
| RUF002 | AmbiguousUnicodeCharacterDocstring | Docstring contains ambiguous unicode character '𝐁' (did you mean 'B'?) | 🛠 |
|
||||
|
||||
### Meta rules
|
||||
|
||||
| Code | Name | Message | Fix |
|
||||
| Coade | Name | Message | Fix |
|
||||
| ---- | ---- | ------- | --- |
|
||||
| M001 | UnusedNOQA | Unused `noqa` directive | 🛠 |
|
||||
|
||||
<!-- End auto-generated sections. -->
|
||||
|
||||
## Editor Integrations
|
||||
|
||||
### PyCharm
|
||||
|
|
|
@ -1,6 +1,5 @@
|
|||
use std::collections::{BTreeMap, BTreeSet};
|
||||
use std::fs::OpenOptions;
|
||||
use std::io;
|
||||
use std::io::Write;
|
||||
|
||||
use anyhow::Result;
|
||||
|
@ -10,6 +9,8 @@ use itertools::Itertools;
|
|||
use ruff::checks::CheckCode;
|
||||
use strum::IntoEnumIterator;
|
||||
|
||||
const FILE: &str = "src/checks_gen.rs";
|
||||
|
||||
#[derive(Parser)]
|
||||
#[command(author, version, about, long_about = None)]
|
||||
/// Generate the `CheckCodePrefix` enum.
|
||||
|
@ -115,29 +116,28 @@ fn main() -> Result<()> {
|
|||
}
|
||||
gen.line("}");
|
||||
|
||||
// Write the output to `src/checks_gen.rs`.
|
||||
let mut writer = if cli.dry_run {
|
||||
Box::new(io::stdout()) as Box<dyn Write>
|
||||
} else {
|
||||
let f = OpenOptions::new()
|
||||
.write(true)
|
||||
.truncate(true)
|
||||
.open("src/checks_gen.rs")
|
||||
.expect("unable to open file");
|
||||
Box::new(f) as Box<dyn Write>
|
||||
};
|
||||
// Construct the output contents.
|
||||
let mut output = String::new();
|
||||
output.push_str("//! File automatically generated by examples/generate_check_code_prefix.rs.");
|
||||
output.push('\n');
|
||||
output.push('\n');
|
||||
output.push_str("use serde::{{Serialize, Deserialize}};");
|
||||
output.push('\n');
|
||||
output.push_str("use strum_macros::EnumString;");
|
||||
output.push('\n');
|
||||
output.push('\n');
|
||||
output.push_str("use crate::checks::CheckCode;");
|
||||
output.push('\n');
|
||||
output.push('\n');
|
||||
output.push_str(&format!("{}", scope.to_string()));
|
||||
|
||||
writeln!(
|
||||
writer,
|
||||
"//! File automatically generated by examples/generate_check_code_prefix.rs."
|
||||
)?;
|
||||
writeln!(writer)?;
|
||||
writeln!(writer, "use serde::{{Serialize, Deserialize}};")?;
|
||||
writeln!(writer, "use strum_macros::EnumString;")?;
|
||||
writeln!(writer)?;
|
||||
writeln!(writer, "use crate::checks::CheckCode;")?;
|
||||
writeln!(writer)?;
|
||||
writeln!(writer, "{}", scope.to_string())?;
|
||||
// Write the output to `src/checks_gen.rs` (or stdout).
|
||||
if cli.dry_run {
|
||||
println!("{}", output);
|
||||
} else {
|
||||
let mut f = OpenOptions::new().write(true).truncate(true).open(FILE)?;
|
||||
write!(f, "{}", output)?;
|
||||
}
|
||||
|
||||
Ok(())
|
||||
}
|
||||
|
|
|
@ -1,28 +1,81 @@
|
|||
//! Generate a Markdown-compatible table of supported lint rules.
|
||||
use std::fs;
|
||||
use std::fs::OpenOptions;
|
||||
use std::io::Write;
|
||||
|
||||
use anyhow::Result;
|
||||
use clap::Parser;
|
||||
use ruff::checks::{CheckCategory, CheckCode};
|
||||
use strum::IntoEnumIterator;
|
||||
|
||||
fn main() {
|
||||
for check_category in CheckCategory::iter() {
|
||||
println!("### {}", check_category.title());
|
||||
println!();
|
||||
const FILE: &str = "README.md";
|
||||
const BEGIN_PRAGMA: &str = "<!-- Begin auto-generated sections. -->";
|
||||
const END_PRAGMA: &str = "<!-- End auto-generated sections. -->";
|
||||
|
||||
#[derive(Parser)]
|
||||
#[command(author, version, about, long_about = None)]
|
||||
/// Generate a Markdown-compatible table of supported lint rules.
|
||||
struct Cli {
|
||||
/// Write the generated table to stdout (rather than to `README.md`).
|
||||
#[arg(long)]
|
||||
dry_run: bool,
|
||||
}
|
||||
|
||||
fn main() -> Result<()> {
|
||||
let cli = Cli::parse();
|
||||
|
||||
// Generate the table string.
|
||||
let mut output = String::new();
|
||||
for check_category in CheckCategory::iter() {
|
||||
output.push_str(&format!("### {}", check_category.title()));
|
||||
output.push('\n');
|
||||
output.push('\n');
|
||||
|
||||
output.push_str("| Coade | Name | Message | Fix |");
|
||||
output.push('\n');
|
||||
output.push_str("| ---- | ---- | ------- | --- |");
|
||||
output.push('\n');
|
||||
|
||||
println!("| Code | Name | Message | Fix |");
|
||||
println!("| ---- | ---- | ------- | --- |");
|
||||
for check_code in CheckCode::iter() {
|
||||
if check_code.category() == check_category {
|
||||
let check_kind = check_code.kind();
|
||||
let fix_token = if check_kind.fixable() { "🛠" } else { "" };
|
||||
println!(
|
||||
output.push_str(&format!(
|
||||
"| {} | {} | {} | {} |",
|
||||
check_kind.code().as_ref(),
|
||||
check_kind.as_ref(),
|
||||
check_kind.summary().replace("|", r"\|"),
|
||||
fix_token
|
||||
);
|
||||
));
|
||||
output.push('\n');
|
||||
}
|
||||
}
|
||||
println!();
|
||||
output.push('\n');
|
||||
}
|
||||
|
||||
if cli.dry_run {
|
||||
print!("{}", output);
|
||||
} else {
|
||||
// Read the existing file.
|
||||
let existing = fs::read_to_string(FILE)?;
|
||||
|
||||
// Extract the prefix.
|
||||
let index = existing
|
||||
.find(BEGIN_PRAGMA)
|
||||
.expect("Unable to find begin pragma.");
|
||||
let prefix = &existing[..index + BEGIN_PRAGMA.len()];
|
||||
|
||||
// Extract the suffix.
|
||||
let index = existing
|
||||
.find(END_PRAGMA)
|
||||
.expect("Unable to find end pragma.");
|
||||
let suffix = &existing[index..];
|
||||
|
||||
// Write the prefix, new contents, and suffix.
|
||||
let mut f = OpenOptions::new().write(true).truncate(true).open(FILE)?;
|
||||
write!(f, "{}\n\n", prefix)?;
|
||||
write!(f, "{}", output)?;
|
||||
write!(f, "{}", suffix)?;
|
||||
}
|
||||
|
||||
Ok(())
|
||||
}
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue