ruff/crates/ruff_dev/src/generate_options.rs

53 lines
1.9 KiB
Rust

//! Generate a Markdown-compatible listing of configuration options.
use itertools::Itertools;
use ruff::settings::options::Options;
use ruff::settings::options_base::{ConfigurationOptions, OptionEntry, OptionField};
fn emit_field(output: &mut String, name: &str, field: &OptionField, group_name: Option<&str>) {
output.push_str(&format!("#### [`{name}`](#{name})\n"));
output.push('\n');
output.push_str(field.doc);
output.push_str("\n\n");
output.push_str(&format!("**Default value**: `{}`\n", field.default));
output.push('\n');
output.push_str(&format!("**Type**: `{}`\n", field.value_type));
output.push('\n');
output.push_str(&format!(
"**Example usage**:\n\n```toml\n[tool.ruff{}]\n{}\n```\n",
if group_name.is_some() {
format!(".{}", group_name.unwrap())
} else {
String::new()
},
field.example
));
output.push('\n');
}
pub fn generate() -> String {
let mut output: String = "### Top-level\n\n".into();
let mut sorted_options = Options::get_available_options();
sorted_options.sort_by_key(|(name, _)| *name);
// Generate all the top-level fields.
for (name, entry) in &sorted_options {
let OptionEntry::Field(field) = entry else { continue; };
emit_field(&mut output, name, field, None);
output.push_str("---\n\n");
}
// Generate all the sub-groups.
for (group_name, entry) in &sorted_options {
let OptionEntry::Group(fields) = entry else { continue; };
output.push_str(&format!("### `{group_name}`\n"));
output.push('\n');
for (name, entry) in fields.iter().sorted_by_key(|(name, _)| name) {
let OptionEntry::Field(field) = entry else { continue; };
emit_field(&mut output, name, field, Some(group_name));
output.push_str("---\n\n");
}
}
output
}