mirror of https://github.com/astral-sh/ruff
143 lines
3.8 KiB
Rust
143 lines
3.8 KiB
Rust
//! Generate typescript file defining options to be used by the web playground.
|
|
|
|
use std::fs::OpenOptions;
|
|
use std::io::Write;
|
|
use std::path::PathBuf;
|
|
|
|
use anyhow::Result;
|
|
use clap::Args;
|
|
use itertools::Itertools;
|
|
use ruff::settings::options::Options;
|
|
use ruff::settings::options_base::{ConfigurationOptions, OptionEntry, OptionField};
|
|
|
|
#[derive(Args)]
|
|
pub struct Cli {
|
|
/// Write the generated table to stdout (rather than to `TODO`).
|
|
#[arg(long)]
|
|
pub(crate) dry_run: bool,
|
|
}
|
|
|
|
fn emit_field(output: &mut String, field: &OptionField) {
|
|
output.push_str(&textwrap::indent(
|
|
&textwrap::dedent(&format!(
|
|
"
|
|
{{
|
|
\"name\": \"{}\",
|
|
\"default\": '{}',
|
|
\"type\": '{}',
|
|
}},",
|
|
field.name, field.default, field.value_type
|
|
)),
|
|
" ",
|
|
));
|
|
}
|
|
|
|
pub fn main(cli: &Cli) -> Result<()> {
|
|
let mut output = String::new();
|
|
|
|
// Generate all the top-level fields.
|
|
output.push_str(&format!("{{\"name\": \"{}\", \"fields\": [", "globals"));
|
|
for field in Options::get_available_options()
|
|
.into_iter()
|
|
.filter_map(|entry| {
|
|
if let OptionEntry::Field(field) = entry {
|
|
Some(field)
|
|
} else {
|
|
None
|
|
}
|
|
})
|
|
// Filter out options that don't make sense in the playground.
|
|
.filter(|field| {
|
|
!matches!(
|
|
field.name,
|
|
"src"
|
|
| "fix"
|
|
| "format"
|
|
| "exclude"
|
|
| "extend"
|
|
| "extend-exclude"
|
|
| "fixable"
|
|
| "force-exclude"
|
|
| "ignore-init-module-imports"
|
|
| "respect-gitignore"
|
|
| "show-source"
|
|
| "cache-dir"
|
|
| "per-file-ignores"
|
|
)
|
|
})
|
|
.sorted_by_key(|field| field.name)
|
|
{
|
|
emit_field(&mut output, &field);
|
|
}
|
|
output.push_str("\n]},\n");
|
|
|
|
// Generate all the sub-groups.
|
|
for group in Options::get_available_options()
|
|
.into_iter()
|
|
.filter_map(|entry| {
|
|
if let OptionEntry::Group(group) = entry {
|
|
Some(group)
|
|
} else {
|
|
None
|
|
}
|
|
})
|
|
.sorted_by_key(|group| group.name)
|
|
{
|
|
output.push_str(&format!("{{\"name\": \"{}\", \"fields\": [", group.name));
|
|
for field in group
|
|
.fields
|
|
.iter()
|
|
.filter_map(|entry| {
|
|
if let OptionEntry::Field(field) = entry {
|
|
Some(field)
|
|
} else {
|
|
None
|
|
}
|
|
})
|
|
.sorted_by_key(|field| field.name)
|
|
{
|
|
emit_field(&mut output, field);
|
|
}
|
|
output.push_str("\n]},\n");
|
|
}
|
|
|
|
let prefix = textwrap::dedent(
|
|
r"
|
|
// This file is auto-generated by `cargo dev generate-playground-options`.
|
|
export interface OptionGroup {
|
|
name: string;
|
|
fields: {
|
|
name: string;
|
|
default: string;
|
|
type: string;
|
|
}[];
|
|
};
|
|
|
|
export const AVAILABLE_OPTIONS: OptionGroup[] = [
|
|
",
|
|
);
|
|
let postfix = "];";
|
|
|
|
if cli.dry_run {
|
|
print!("{output}");
|
|
} else {
|
|
let file = PathBuf::from(env!("CARGO_MANIFEST_DIR"))
|
|
.parent()
|
|
.expect("Failed to find root directory")
|
|
.join("playground")
|
|
.join("src")
|
|
.join("ruff_options.ts");
|
|
|
|
let mut f = OpenOptions::new()
|
|
.create(true)
|
|
.write(true)
|
|
.truncate(true)
|
|
.open(file)?;
|
|
write!(f, "{prefix}")?;
|
|
write!(f, "{}", textwrap::indent(&output, " "))?;
|
|
write!(f, "{postfix}")?;
|
|
}
|
|
|
|
Ok(())
|
|
}
|