This makes it easier to see which rules you're enabling when selecting one of the pylint codes (like `PLC`). This also makes it clearer what those abbreviations stand for. When I first saw the pylint section, I was very confused by that, so other might be as well. See it rendered here: https://github.com/thomkeh/ruff/blob/patch-1/README.md#pylint-plc-ple-plr-plw
95 lines
3.1 KiB
Rust
95 lines
3.1 KiB
Rust
//! Generate a Markdown-compatible table of supported lint rules.
|
|
|
|
use anyhow::Result;
|
|
use clap::Args;
|
|
use ruff::registry::{Prefixes, RuleCodePrefix, RuleOrigin};
|
|
use strum::IntoEnumIterator;
|
|
|
|
use crate::utils::replace_readme_section;
|
|
|
|
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 {
|
|
/// Write the generated table to stdout (rather than to `README.md`).
|
|
#[arg(long)]
|
|
pub(crate) dry_run: bool,
|
|
}
|
|
|
|
fn generate_table(table_out: &mut String, prefix: &RuleCodePrefix) {
|
|
table_out.push_str("| Code | Name | Message | Fix |");
|
|
table_out.push('\n');
|
|
table_out.push_str("| ---- | ---- | ------- | --- |");
|
|
table_out.push('\n');
|
|
for rule_code in prefix.codes() {
|
|
let kind = rule_code.kind();
|
|
let fix_token = if kind.fixable() { "🛠" } else { "" };
|
|
table_out.push_str(&format!(
|
|
"| {} | {} | {} | {} |",
|
|
kind.code().as_ref(),
|
|
kind.as_ref(),
|
|
kind.summary().replace('|', r"\|"),
|
|
fix_token
|
|
));
|
|
table_out.push('\n');
|
|
}
|
|
table_out.push('\n');
|
|
}
|
|
|
|
pub fn main(cli: &Cli) -> Result<()> {
|
|
// Generate the table string.
|
|
let mut table_out = String::new();
|
|
let mut toc_out = String::new();
|
|
for origin in RuleOrigin::iter() {
|
|
let prefixes = origin.prefixes();
|
|
let codes_csv: String = prefixes.as_list(", ");
|
|
table_out.push_str(&format!("### {} ({codes_csv})", origin.title()));
|
|
table_out.push('\n');
|
|
table_out.push('\n');
|
|
|
|
toc_out.push_str(&format!(
|
|
" 1. [{} ({})](#{}-{})\n",
|
|
origin.title(),
|
|
codes_csv,
|
|
origin.title().to_lowercase().replace(' ', "-"),
|
|
codes_csv.to_lowercase().replace(',', "-").replace(' ', "")
|
|
));
|
|
|
|
if let Some((url, platform)) = origin.url() {
|
|
table_out.push_str(&format!(
|
|
"For more, see [{}]({}) on {}.",
|
|
origin.title(),
|
|
url,
|
|
platform
|
|
));
|
|
table_out.push('\n');
|
|
table_out.push('\n');
|
|
}
|
|
|
|
match prefixes {
|
|
Prefixes::Single(prefix) => generate_table(&mut table_out, &prefix),
|
|
Prefixes::Multiple(entries) => {
|
|
for (prefix, category) in entries {
|
|
table_out.push_str(&format!("#### {category} ({})", prefix.as_ref()));
|
|
table_out.push('\n');
|
|
generate_table(&mut table_out, &prefix);
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
if cli.dry_run {
|
|
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(())
|
|
}
|