From 9b99d8145ad190f5247db1093c978fb2f718473f Mon Sep 17 00:00:00 2001 From: Charlie Marsh Date: Mon, 24 Jun 2024 15:23:25 +0300 Subject: [PATCH] Use rule name rather than message in `--statistics` (#11697) Co-authored-by: Micha Reiser Closes https://github.com/astral-sh/ruff/issues/11097. --- crates/ruff/src/printer.rs | 47 ++++++++++++++++++--------- crates/ruff/tests/integration_test.rs | 31 +++++++++++++++++- 2 files changed, 62 insertions(+), 16 deletions(-) diff --git a/crates/ruff/src/printer.rs b/crates/ruff/src/printer.rs index bf32f55c98342..b8117c82b4d3e 100644 --- a/crates/ruff/src/printer.rs +++ b/crates/ruff/src/printer.rs @@ -36,9 +36,9 @@ bitflags! { } #[derive(Serialize)] -struct ExpandedStatistics<'a> { +struct ExpandedStatistics { code: SerializeRuleAsCode, - message: &'a str, + name: SerializeRuleAsTitle, count: usize, fixable: bool, } @@ -66,6 +66,29 @@ impl From for SerializeRuleAsCode { } } +struct SerializeRuleAsTitle(Rule); + +impl Serialize for SerializeRuleAsTitle { + fn serialize(&self, serializer: S) -> std::result::Result + where + S: serde::Serializer, + { + serializer.serialize_str(self.0.as_ref()) + } +} + +impl Display for SerializeRuleAsTitle { + fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { + write!(f, "{}", self.0.as_ref()) + } +} + +impl From for SerializeRuleAsTitle { + fn from(rule: Rule) -> Self { + Self(rule) + } +} + pub(crate) struct Printer { format: OutputFormat, log_level: LogLevel, @@ -317,29 +340,23 @@ impl Printer { let statistics: Vec = diagnostics .messages .iter() - .map(|message| { - ( - message.kind.rule(), - &message.kind.body, - message.fix.is_some(), - ) - }) + .map(|message| (message.kind.rule(), message.fix.is_some())) .sorted() - .fold(vec![], |mut acc, (rule, body, fixable)| { - if let Some((prev_rule, _, _, count)) = acc.last_mut() { + .fold(vec![], |mut acc, (rule, fixable)| { + if let Some((prev_rule, _, count)) = acc.last_mut() { if *prev_rule == rule { *count += 1; return acc; } } - acc.push((rule, body, fixable, 1)); + acc.push((rule, fixable, 1)); acc }) .iter() - .map(|(rule, message, fixable, count)| ExpandedStatistics { + .map(|(rule, fixable, count)| ExpandedStatistics { code: (*rule).into(), + name: (*rule).into(), count: *count, - message, fixable: *fixable, }) .sorted_by_key(|statistic| Reverse(statistic.count)) @@ -386,7 +403,7 @@ impl Printer { } else { "" }, - statistic.message, + statistic.name, )?; } return Ok(()); diff --git a/crates/ruff/tests/integration_test.rs b/crates/ruff/tests/integration_test.rs index dc096f47181f0..60abf067cac99 100644 --- a/crates/ruff/tests/integration_test.rs +++ b/crates/ruff/tests/integration_test.rs @@ -854,7 +854,36 @@ fn show_statistics() { success: false exit_code: 1 ----- stdout ----- - 1 F401 [*] `sys` imported but unused + 1 F401 [*] unused-import + + ----- stderr ----- + "###); +} + +#[test] +fn show_statistics_json() { + let mut cmd = RuffCheck::default() + .args([ + "--select", + "F401", + "--statistics", + "--output-format", + "json", + ]) + .build(); + assert_cmd_snapshot!(cmd + .pass_stdin("import sys\nimport os\n\nprint(os.getuid())\n"), @r###" + success: false + exit_code: 1 + ----- stdout ----- + [ + { + "code": "F401", + "name": "unused-import", + "count": 1, + "fixable": true + } + ] ----- stderr ----- "###);