mirror of https://github.com/astral-sh/ruff
Auto-generate the rules table of contents (#1121)
This commit is contained in:
parent
7abecd4f0e
commit
9c6e8c7644
|
|
@ -68,7 +68,7 @@ of [Conda](https://docs.conda.io/en/latest/):
|
|||
|
||||
1. [Installation and Usage](#installation-and-usage)
|
||||
1. [Configuration](#configuration)
|
||||
1. [Supported Rules](#supported-rules)
|
||||
1. [Supported Rules](#supported-rules) <!-- Begin auto-generated table of contents. -->
|
||||
1. [Pyflakes (F)](#pyflakes-f)
|
||||
1. [pycodestyle (E, W)](#pycodestyle-e-w)
|
||||
1. [mccabe (C90)](#mccabe-c90)
|
||||
|
|
@ -93,7 +93,7 @@ of [Conda](https://docs.conda.io/en/latest/):
|
|||
1. [eradicate (ERA)](#eradicate-era)
|
||||
1. [pygrep-hooks (PGH)](#pygrep-hooks-pgh)
|
||||
1. [Pylint (PLC, PLE, PLR, PLW)](#pylint-plc-ple-plr-plw)
|
||||
1. [Ruff-specific rules (RUF)](#ruff-specific-rules-ruf)
|
||||
1. [Ruff-specific rules (RUF)](#ruff-specific-rules-ruf)<!-- End auto-generated table of contents. -->
|
||||
1. [Editor Integrations](#editor-integrations)
|
||||
1. [FAQ](#faq)
|
||||
1. [Development](#development)
|
||||
|
|
@ -395,7 +395,6 @@ The 🛠 emoji indicates that a rule is automatically fixable by the `--fix` com
|
|||
|
||||
<!-- Sections automatically generated by `cargo dev generate-rules-table`. -->
|
||||
<!-- Begin auto-generated sections. -->
|
||||
|
||||
### Pyflakes (F)
|
||||
|
||||
For more, see [Pyflakes](https://pypi.org/project/pyflakes/2.5.0/) on PyPI.
|
||||
|
|
|
|||
|
|
@ -11,8 +11,11 @@ use itertools::Itertools;
|
|||
use ruff::checks::{CheckCategory, CheckCode};
|
||||
use strum::IntoEnumIterator;
|
||||
|
||||
const BEGIN_PRAGMA: &str = "<!-- Begin auto-generated sections. -->";
|
||||
const END_PRAGMA: &str = "<!-- End auto-generated sections. -->";
|
||||
const TABLE_BEGIN_PRAGMA: &str = "<!-- Begin auto-generated sections. -->";
|
||||
const TABLE_END_PRAGMA: &str = "<!-- End auto-generated sections. -->";
|
||||
|
||||
const TOC_BEGIN_PRAGMA: &str = "<!-- Begin auto-generated table of contents. -->";
|
||||
const TOC_END_PRAGMA: &str = "<!-- End auto-generated table of contents. -->";
|
||||
|
||||
#[derive(Args)]
|
||||
pub struct Cli {
|
||||
|
|
@ -23,52 +26,67 @@ pub struct Cli {
|
|||
|
||||
pub fn main(cli: &Cli) -> Result<()> {
|
||||
// Generate the table string.
|
||||
let mut output = String::new();
|
||||
let mut table_out = String::new();
|
||||
let mut toc_out = String::new();
|
||||
for check_category in CheckCategory::iter() {
|
||||
output.push_str(&format!(
|
||||
"### {} ({})",
|
||||
let codes_csv: String = check_category.codes().iter().map(AsRef::as_ref).join(", ");
|
||||
table_out.push_str(&format!("### {} ({codes_csv})", check_category.title()));
|
||||
table_out.push('\n');
|
||||
table_out.push('\n');
|
||||
|
||||
toc_out.push_str(&format!(
|
||||
" 1. [{} ({})](#{}-{})\n",
|
||||
check_category.title(),
|
||||
check_category.codes().iter().map(AsRef::as_ref).join(", ")
|
||||
codes_csv,
|
||||
check_category.title().to_lowercase().replace(' ', "-"),
|
||||
codes_csv.to_lowercase().replace(',', "-").replace(' ', "")
|
||||
));
|
||||
output.push('\n');
|
||||
output.push('\n');
|
||||
|
||||
if let Some((url, platform)) = check_category.url() {
|
||||
output.push_str(&format!(
|
||||
table_out.push_str(&format!(
|
||||
"For more, see [{}]({}) on {}.",
|
||||
check_category.title(),
|
||||
url,
|
||||
platform
|
||||
));
|
||||
output.push('\n');
|
||||
output.push('\n');
|
||||
table_out.push('\n');
|
||||
table_out.push('\n');
|
||||
}
|
||||
|
||||
output.push_str("| Code | Name | Message | Fix |");
|
||||
output.push('\n');
|
||||
output.push_str("| ---- | ---- | ------- | --- |");
|
||||
output.push('\n');
|
||||
table_out.push_str("| Code | Name | Message | Fix |");
|
||||
table_out.push('\n');
|
||||
table_out.push_str("| ---- | ---- | ------- | --- |");
|
||||
table_out.push('\n');
|
||||
|
||||
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 { "" };
|
||||
output.push_str(&format!(
|
||||
table_out.push_str(&format!(
|
||||
"| {} | {} | {} | {} |",
|
||||
check_kind.code().as_ref(),
|
||||
check_kind.as_ref(),
|
||||
check_kind.summary().replace('|', r"\|"),
|
||||
fix_token
|
||||
));
|
||||
output.push('\n');
|
||||
table_out.push('\n');
|
||||
}
|
||||
}
|
||||
output.push('\n');
|
||||
table_out.push('\n');
|
||||
}
|
||||
|
||||
if cli.dry_run {
|
||||
print!("{output}");
|
||||
print!("Table of Contents: {toc_out}\n Rules Tables: {table_out}");
|
||||
} else {
|
||||
// Extra newline in the markdown numbered list looks weird
|
||||
replace_readme_section(toc_out.trim_end(), TOC_BEGIN_PRAGMA, TOC_END_PRAGMA)?;
|
||||
replace_readme_section(&table_out, TABLE_BEGIN_PRAGMA, TABLE_END_PRAGMA)?;
|
||||
}
|
||||
|
||||
Ok(())
|
||||
}
|
||||
|
||||
fn replace_readme_section(content: &str, begin_pragma: &str, end_pragma: &str) -> Result<()> {
|
||||
// Read the existing file.
|
||||
let file = PathBuf::from(env!("CARGO_MANIFEST_DIR"))
|
||||
.parent()
|
||||
|
|
@ -78,22 +96,21 @@ pub fn main(cli: &Cli) -> Result<()> {
|
|||
|
||||
// Extract the prefix.
|
||||
let index = existing
|
||||
.find(BEGIN_PRAGMA)
|
||||
.find(begin_pragma)
|
||||
.expect("Unable to find begin pragma");
|
||||
let prefix = &existing[..index + BEGIN_PRAGMA.len()];
|
||||
let prefix = &existing[..index + begin_pragma.len()];
|
||||
|
||||
// Extract the suffix.
|
||||
let index = existing
|
||||
.find(END_PRAGMA)
|
||||
.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, "{prefix}\n\n")?;
|
||||
write!(f, "{output}")?;
|
||||
writeln!(f, "{prefix}")?;
|
||||
write!(f, "{content}")?;
|
||||
write!(f, "{suffix}")?;
|
||||
}
|
||||
|
||||
Ok(())
|
||||
}
|
||||
|
|
|
|||
Loading…
Reference in New Issue