Implement config subcommand

The synopsis is as follows.

List all top-level config keys:

    $ ruff config
    allowed-confusables
    builtins
    cache-dir
    ... etc.

List all config keys in a specific section:

    $ ruff config mccabe
    max-complexity

Describe a specific config option:

    $ ruff config mccabe.max-complexity
    The maximum McCabe complexity to allow before triggering `C901` errors.

    Default value: 10
    Type: int
    Example usage:
    ```toml
    # Flag errors (`C901`) whenever the complexity level exceeds 5.
    max-complexity = 5
    ```
This commit is contained in:
Martin Fischer 2023-02-11 18:37:11 +01:00 committed by Charlie Marsh
parent bbe44360e8
commit 0e4d5eeea7
5 changed files with 53 additions and 0 deletions

View file

@ -44,6 +44,8 @@ pub enum Command {
#[arg(long, value_enum, default_value = "pretty")]
format: HelpFormat,
},
/// List or describe the available configuration options
Config { option: Option<String> },
/// List all supported upstream linters
Linter {
/// Output format

View file

@ -0,0 +1,48 @@
use ruff::settings::{
options::Options,
options_base::{ConfigurationOptions, OptionEntry, OptionField},
};
use crate::ExitStatus;
#[allow(clippy::print_stdout)]
pub(crate) fn config(option: Option<&str>) -> ExitStatus {
let entries = Options::get_available_options();
let mut entries = &entries;
let mut parts_iter = option.iter().flat_map(|s| s.split('.'));
while let Some(part) = parts_iter.next() {
let Some((_, field)) = entries.iter().find(|(name, _)| *name == part) else {
println!("Unknown option");
return ExitStatus::Error;
};
match field {
OptionEntry::Field(OptionField {
doc,
default,
value_type,
example,
}) => {
if parts_iter.next().is_some() {
println!("Unknown option");
return ExitStatus::Error;
}
println!("{doc}");
println!();
println!("Default value: {default}");
println!("Type: {value_type}");
println!("Example usage:\n```toml\n{example}\n```");
return ExitStatus::Success;
}
OptionEntry::Group(fields) => {
entries = fields;
}
}
}
for (name, _) in entries {
println!("{name}");
}
ExitStatus::Success
}

View file

@ -9,6 +9,7 @@ pub use show_settings::show_settings;
mod add_noqa;
mod clean;
pub mod config;
mod linter;
mod rule;
mod run;

View file

@ -101,6 +101,7 @@ quoting the executed command, along with the relevant file contents and `pyproje
match command {
Command::Rule { rule, format } => commands::rule(&rule, format)?,
Command::Config { option } => return Ok(commands::config::config(option.as_deref())),
Command::Linter { format } => commands::linter(format)?,
Command::Clean => commands::clean(log_level)?,
Command::GenerateShellCompletion { shell } => {