From 4162e742a2be04975529dbfe9adbded070e4c711 Mon Sep 17 00:00:00 2001 From: Aarni Koskela Date: Tue, 13 Jun 2023 21:02:50 +0300 Subject: [PATCH] Add `ruff rules-json` subcommand --- Cargo.lock | 1 + crates/ruff_cli/src/args.rs | 2 + crates/ruff_cli/src/commands/mod.rs | 1 + crates/ruff_cli/src/commands/rules_json.rs | 47 ++++++++++++++++++++++ crates/ruff_cli/src/lib.rs | 1 + crates/ruff_dev/Cargo.toml | 1 + docs/configuration.md | 13 +++--- 7 files changed, 60 insertions(+), 6 deletions(-) create mode 100644 crates/ruff_cli/src/commands/rules_json.rs diff --git a/Cargo.lock b/Cargo.lock index 50fd9272f25ef7..a6003c975d3ed7 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -1951,6 +1951,7 @@ dependencies = [ "rustpython-format", "rustpython-parser", "schemars", + "serde", "serde_json", "strum", "strum_macros", diff --git a/crates/ruff_cli/src/args.rs b/crates/ruff_cli/src/args.rs index 09662c827281ad..d547c9a508b449 100644 --- a/crates/ruff_cli/src/args.rs +++ b/crates/ruff_cli/src/args.rs @@ -45,6 +45,8 @@ pub enum Command { #[arg(long, value_enum, default_value = "text")] format: HelpFormat, }, + /// Print a JSON document explaining all of the rules known to Ruff. + RulesJSON, /// List or describe the available configuration options Config { option: Option }, /// List all supported upstream linters diff --git a/crates/ruff_cli/src/commands/mod.rs b/crates/ruff_cli/src/commands/mod.rs index e989f433e03c50..d28b724445c7ae 100644 --- a/crates/ruff_cli/src/commands/mod.rs +++ b/crates/ruff_cli/src/commands/mod.rs @@ -3,6 +3,7 @@ pub(crate) mod clean; pub(crate) mod config; pub(crate) mod linter; pub(crate) mod rule; +pub(crate) mod rules_json; pub(crate) mod run; pub(crate) mod run_stdin; pub(crate) mod show_files; diff --git a/crates/ruff_cli/src/commands/rules_json.rs b/crates/ruff_cli/src/commands/rules_json.rs new file mode 100644 index 00000000000000..944912b580bc72 --- /dev/null +++ b/crates/ruff_cli/src/commands/rules_json.rs @@ -0,0 +1,47 @@ +//! Generate a JSON file describing supported lint rules. +//! NB: the format may change in the future. + +use anyhow::Error; +use std::io::{stdout, Write}; + +use serde::ser::{SerializeMap, Serializer}; + +use serde_json::json; + +use strum::IntoEnumIterator; + +use ruff::registry::{Linter, RuleNamespace}; +use ruff_diagnostics::AutofixKind; + +fn write_rules_json(writer: &mut dyn Write) -> Result<(), Error> { + let mut ser = serde_json::Serializer::pretty(writer); + let mut map = ser.serialize_map(None)?; + for linter in Linter::iter() { + for rule in &linter { + let code = format!( + "{}{}", + linter.common_prefix(), + linter.code_for_rule(rule).unwrap() + ); + let fixable = match rule.autofixable() { + AutofixKind::Sometimes => "sometimes", + AutofixKind::Always => "always", + AutofixKind::None => "none", + }; + let value = json!({ + "name": rule.as_ref(), + "message": rule.message_formats()[0], + "explanation": rule.explanation(), + "fixable": fixable, + "linter": linter.name(), + }); + map.serialize_entry(&code, &value)?; + } + } + map.end()?; + Ok(()) +} + +pub(crate) fn rules_json() -> Result<(), Error> { + write_rules_json(&mut stdout()) +} diff --git a/crates/ruff_cli/src/lib.rs b/crates/ruff_cli/src/lib.rs index 7f7a70f2eb1b68..ee36133cba5b6e 100644 --- a/crates/ruff_cli/src/lib.rs +++ b/crates/ruff_cli/src/lib.rs @@ -113,6 +113,7 @@ quoting the executed command, along with the relevant file contents and `pyproje match command { Command::Rule { rule, format } => commands::rule::rule(rule, format)?, + Command::RulesJSON => commands::rules_json::rules_json()?, Command::Config { option } => return Ok(commands::config::config(option.as_deref())), Command::Linter { format } => commands::linter::linter(format)?, Command::Clean => commands::clean::clean(log_level)?, diff --git a/crates/ruff_dev/Cargo.toml b/crates/ruff_dev/Cargo.toml index 376bb09b8e9680..f67d7d129f4a5b 100644 --- a/crates/ruff_dev/Cargo.toml +++ b/crates/ruff_dev/Cargo.toml @@ -26,6 +26,7 @@ regex = { workspace = true } rustpython-format = { workspace = true } rustpython-parser = { workspace = true } schemars = { workspace = true } +serde = { workspace = true } serde_json = { workspace = true } strum = { workspace = true } strum_macros = { workspace = true } diff --git a/docs/configuration.md b/docs/configuration.md index 91897bac80d8fe..048a87af5e4d6d 100644 --- a/docs/configuration.md +++ b/docs/configuration.md @@ -162,12 +162,13 @@ Ruff: An extremely fast Python linter. Usage: ruff [OPTIONS] Commands: - check Run Ruff on the given files or directories (default) - rule Explain a rule - config List or describe the available configuration options - linter List all supported upstream linters - clean Clear any caches in the current directory and any subdirectories - help Print this message or the help of the given subcommand(s) + check Run Ruff on the given files or directories (default) + rule Explain a rule + rules-json Print a JSON document explaining all of the rules known to Ruff + config List or describe the available configuration options + linter List all supported upstream linters + clean Clear any caches in the current directory and any subdirectories + help Print this message or the help of the given subcommand(s) Options: -h, --help Print help