mirror of
https://github.com/astral-sh/ruff.git
synced 2025-10-01 14:21:53 +00:00
Add --output-format
to ruff config
CLI (#11438)
This is useful for extracting the defaults in order to construct equivalent configs by external scripts. This is my first non-hello-world rust code, comments and suggested tests appreciated. ## Summary We already have `ruff linter --output-format json`, this provides `ruff config x --output-format json` as well. I plan to use this to construct an equivalent config snippet to include in some managed repos, so when we update their version of ruff and it adds new lints, they get a PR that includes the commented-out new lints. Note that the no-args form of `ruff config` ignores output-format currently, but probably should obey it (although array-of-strings doesn't seem that useful, looking for input on format). ## Test Plan I could use a hand coming up with a typical way to write automated tests for this. ```sh-session (.venv) [timhatch:ruff ]$ ./target/debug/ruff config lint.select A list of rule codes or prefixes to enable. Prefixes can specify exact rules (like `F841`), entire categories (like `F`), or anything in between. When breaking ties between enabled and disabled rules (via `select` and `ignore`, respectively), more specific prefixes override less specific prefixes. Default value: ["E4", "E7", "E9", "F"] Type: list[RuleSelector] Example usage: ``toml # On top of the defaults (`E4`, E7`, `E9`, and `F`), enable flake8-bugbear (`B`) and flake8-quotes (`Q`). select = ["E4", "E7", "E9", "F", "B", "Q"] `` (.venv) [timhatch:ruff ]$ ./target/debug/ruff config lint.select --output-format json { "Field": { "doc": "A list of rule codes or prefixes to enable. Prefixes can specify exact\nrules (like `F841`), entire categories (like `F`), or anything in\nbetween.\n\nWhen breaking ties between enabled and disabled rules (via `select` and\n`ignore`, respectively), more specific prefixes override less\nspecific prefixes.", "default": "[\"E4\", \"E7\", \"E9\", \"F\"]", "value_type": "list[RuleSelector]", "scope": null, "example": "# On top of the defaults (`E4`, E7`, `E9`, and `F`), enable flake8-bugbear (`B`) and flake8-quotes (`Q`).\nselect = [\"E4\", \"E7\", \"E9\", \"F\", \"B\", \"Q\"]", "deprecated": null } } ```
This commit is contained in:
parent
b3e4d39f64
commit
27da223e9f
5 changed files with 137 additions and 12 deletions
|
@ -1,3 +1,6 @@
|
|||
use serde::{Serialize, Serializer};
|
||||
use std::collections::BTreeMap;
|
||||
|
||||
use std::fmt::{Debug, Display, Formatter};
|
||||
|
||||
/// Visits [`OptionsMetadata`].
|
||||
|
@ -39,12 +42,13 @@ where
|
|||
}
|
||||
|
||||
/// Metadata of an option that can either be a [`OptionField`] or [`OptionSet`].
|
||||
#[derive(Clone, PartialEq, Eq, Debug)]
|
||||
#[derive(Clone, PartialEq, Eq, Debug, Serialize)]
|
||||
#[serde(untagged)]
|
||||
pub enum OptionEntry {
|
||||
/// A single option.
|
||||
Field(OptionField),
|
||||
|
||||
/// A set of options
|
||||
/// A set of options.
|
||||
Set(OptionSet),
|
||||
}
|
||||
|
||||
|
@ -325,13 +329,51 @@ impl Display for OptionSet {
|
|||
}
|
||||
}
|
||||
|
||||
struct SerializeVisitor<'a> {
|
||||
entries: &'a mut BTreeMap<String, OptionField>,
|
||||
}
|
||||
|
||||
impl<'a> Visit for SerializeVisitor<'a> {
|
||||
fn record_set(&mut self, name: &str, set: OptionSet) {
|
||||
// Collect the entries of the set.
|
||||
let mut entries = BTreeMap::new();
|
||||
let mut visitor = SerializeVisitor {
|
||||
entries: &mut entries,
|
||||
};
|
||||
set.record(&mut visitor);
|
||||
|
||||
// Insert the set into the entries.
|
||||
for (key, value) in entries {
|
||||
self.entries.insert(format!("{name}.{key}"), value);
|
||||
}
|
||||
}
|
||||
|
||||
fn record_field(&mut self, name: &str, field: OptionField) {
|
||||
self.entries.insert(name.to_string(), field);
|
||||
}
|
||||
}
|
||||
|
||||
impl Serialize for OptionSet {
|
||||
fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error>
|
||||
where
|
||||
S: Serializer,
|
||||
{
|
||||
let mut entries = BTreeMap::new();
|
||||
let mut visitor = SerializeVisitor {
|
||||
entries: &mut entries,
|
||||
};
|
||||
self.record(&mut visitor);
|
||||
entries.serialize(serializer)
|
||||
}
|
||||
}
|
||||
|
||||
impl Debug for OptionSet {
|
||||
fn fmt(&self, f: &mut Formatter<'_>) -> std::fmt::Result {
|
||||
Display::fmt(self, f)
|
||||
}
|
||||
}
|
||||
|
||||
#[derive(Debug, Eq, PartialEq, Clone)]
|
||||
#[derive(Debug, Eq, PartialEq, Clone, Serialize)]
|
||||
pub struct OptionField {
|
||||
pub doc: &'static str,
|
||||
/// Ex) `"false"`
|
||||
|
@ -344,7 +386,7 @@ pub struct OptionField {
|
|||
pub deprecated: Option<Deprecated>,
|
||||
}
|
||||
|
||||
#[derive(Debug, Clone, Eq, PartialEq)]
|
||||
#[derive(Debug, Clone, Eq, PartialEq, Serialize)]
|
||||
pub struct Deprecated {
|
||||
pub since: Option<&'static str>,
|
||||
pub message: Option<&'static str>,
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue