mirror of https://github.com/astral-sh/ruff
Implement `ruff linter` subcommand
The subcommand lists all supported upstream linters and their prefixes:
$ ruff linter
F Pyflakes
E/W pycodestyle
C90 mccabe
I isort
N pep8-naming
D pydocstyle
UP pyupgrade
YTT flake8-2020
# etc...
Just like with the `rule` subcommand `--format json` is supported:
$ ruff linter --format json
[
{
"prefix": "F",
"name": "Pyflakes"
},
{
"prefix": "",
"name": "pycodestyle",
"categories": [
{
"prefix": "E",
"name": "Error"
},
{
"prefix": "W",
"name": "Warning"
}
]
},
# etc...
This commit is contained in:
parent
b532fce792
commit
d76a47d366
|
|
@ -384,6 +384,7 @@ Usage: ruff [OPTIONS] <COMMAND>
|
||||||
Commands:
|
Commands:
|
||||||
check Run Ruff on the given files or directories (default)
|
check Run Ruff on the given files or directories (default)
|
||||||
rule Explain a rule
|
rule Explain a rule
|
||||||
|
linter List all supported upstream linters
|
||||||
clean Clear any caches in the current directory and any subdirectories
|
clean Clear any caches in the current directory and any subdirectories
|
||||||
help Print this message or the help of the given subcommand(s)
|
help Print this message or the help of the given subcommand(s)
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -53,6 +53,7 @@ similar = { version = "2.2.1" }
|
||||||
textwrap = { version = "0.16.0" }
|
textwrap = { version = "0.16.0" }
|
||||||
update-informer = { version = "0.6.0", default-features = false, features = ["pypi"], optional = true }
|
update-informer = { version = "0.6.0", default-features = false, features = ["pypi"], optional = true }
|
||||||
walkdir = { version = "2.3.2" }
|
walkdir = { version = "2.3.2" }
|
||||||
|
strum = "0.24.1"
|
||||||
|
|
||||||
[dev-dependencies]
|
[dev-dependencies]
|
||||||
assert_cmd = { version = "2.0.4" }
|
assert_cmd = { version = "2.0.4" }
|
||||||
|
|
|
||||||
|
|
@ -41,6 +41,12 @@ pub enum Command {
|
||||||
#[arg(long, value_enum, default_value = "text")]
|
#[arg(long, value_enum, default_value = "text")]
|
||||||
format: HelpFormat,
|
format: HelpFormat,
|
||||||
},
|
},
|
||||||
|
/// List all supported upstream linters
|
||||||
|
Linter {
|
||||||
|
/// Output format
|
||||||
|
#[arg(long, value_enum, default_value = "text")]
|
||||||
|
format: HelpFormat,
|
||||||
|
},
|
||||||
/// Clear any caches in the current directory and any subdirectories.
|
/// Clear any caches in the current directory and any subdirectories.
|
||||||
#[clap(alias = "--clean")]
|
#[clap(alias = "--clean")]
|
||||||
Clean,
|
Clean,
|
||||||
|
|
|
||||||
|
|
@ -27,6 +27,8 @@ use crate::cache;
|
||||||
use crate::diagnostics::{lint_path, lint_stdin, Diagnostics};
|
use crate::diagnostics::{lint_path, lint_stdin, Diagnostics};
|
||||||
use crate::iterators::par_iter;
|
use crate::iterators::par_iter;
|
||||||
|
|
||||||
|
pub mod linter;
|
||||||
|
|
||||||
/// Run the linter over a collection of files.
|
/// Run the linter over a collection of files.
|
||||||
pub fn run(
|
pub fn run(
|
||||||
files: &[PathBuf],
|
files: &[PathBuf],
|
||||||
|
|
|
||||||
|
|
@ -0,0 +1,59 @@
|
||||||
|
use itertools::Itertools;
|
||||||
|
use serde::Serialize;
|
||||||
|
use strum::IntoEnumIterator;
|
||||||
|
|
||||||
|
use ruff::registry::{Linter, LinterCategory, RuleNamespace};
|
||||||
|
|
||||||
|
use crate::args::HelpFormat;
|
||||||
|
|
||||||
|
pub fn linter(format: HelpFormat) {
|
||||||
|
match format {
|
||||||
|
HelpFormat::Text => {
|
||||||
|
for linter in Linter::iter() {
|
||||||
|
let prefix = match linter.common_prefix() {
|
||||||
|
"" => linter
|
||||||
|
.categories()
|
||||||
|
.unwrap()
|
||||||
|
.iter()
|
||||||
|
.map(|LinterCategory(prefix, ..)| prefix)
|
||||||
|
.join("/"),
|
||||||
|
prefix => prefix.to_string(),
|
||||||
|
};
|
||||||
|
println!("{:>4} {}", prefix, linter.name());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
HelpFormat::Json => {
|
||||||
|
let linters: Vec<_> = Linter::iter()
|
||||||
|
.map(|linter_info| LinterInfo {
|
||||||
|
prefix: linter_info.common_prefix(),
|
||||||
|
name: linter_info.name(),
|
||||||
|
categories: linter_info.categories().map(|cats| {
|
||||||
|
cats.iter()
|
||||||
|
.map(|LinterCategory(prefix, name, ..)| LinterCategoryInfo {
|
||||||
|
prefix,
|
||||||
|
name,
|
||||||
|
})
|
||||||
|
.collect()
|
||||||
|
}),
|
||||||
|
})
|
||||||
|
.collect();
|
||||||
|
|
||||||
|
println!("{}", serde_json::to_string_pretty(&linters).unwrap());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
#[derive(Serialize)]
|
||||||
|
struct LinterInfo {
|
||||||
|
prefix: &'static str,
|
||||||
|
name: &'static str,
|
||||||
|
#[serde(skip_serializing_if = "Option::is_none")]
|
||||||
|
categories: Option<Vec<LinterCategoryInfo>>,
|
||||||
|
}
|
||||||
|
|
||||||
|
#[derive(Serialize)]
|
||||||
|
struct LinterCategoryInfo {
|
||||||
|
prefix: &'static str,
|
||||||
|
name: &'static str,
|
||||||
|
}
|
||||||
|
|
@ -78,6 +78,7 @@ quoting the executed command, along with the relevant file contents and `pyproje
|
||||||
|
|
||||||
match command {
|
match command {
|
||||||
Command::Rule { rule, format } => commands::rule(rule, format)?,
|
Command::Rule { rule, format } => commands::rule(rule, format)?,
|
||||||
|
Command::Linter { format } => commands::linter::linter(format),
|
||||||
Command::Clean => commands::clean(log_level)?,
|
Command::Clean => commands::clean(log_level)?,
|
||||||
Command::GenerateShellCompletion { shell } => {
|
Command::GenerateShellCompletion { shell } => {
|
||||||
shell.generate(&mut Args::command(), &mut io::stdout());
|
shell.generate(&mut Args::command(), &mut io::stdout());
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue