Automatically update README.md from generate_rules_table.rs (#606)

This commit is contained in:
Charlie Marsh 2022-11-05 15:33:47 -04:00 committed by GitHub
parent c48c7669a8
commit 2e1799dd80
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
3 changed files with 104 additions and 46 deletions

View file

@ -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

View file

@ -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(())
}

View file

@ -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(())
}