diff --git a/crates/ruff_cli/src/printer.rs b/crates/ruff_cli/src/printer.rs index 11d5fbeaf6460..d5d5c624a8966 100644 --- a/crates/ruff_cli/src/printer.rs +++ b/crates/ruff_cli/src/printer.rs @@ -1,6 +1,8 @@ use std::cmp::Reverse; +use std::collections::hash_map::DefaultHasher; use std::collections::BTreeMap; use std::fmt::Display; +use std::hash::{Hash, Hasher}; use std::io; use std::io::{BufWriter, Write}; use std::path::Path; @@ -350,7 +352,7 @@ impl Printer { json!({ "description": format!("({}) {}", message.kind.rule().noqa_code(), message.kind.body), "severity": "major", - "fingerprint": message.kind.rule().noqa_code().to_string(), + "fingerprint": fingerprint(message), "location": { "path": message.filename, "lines": { @@ -553,6 +555,18 @@ fn num_digits(n: usize) -> usize { .max(1) } +/// Generate a unique fingerprint to identify a violation. +fn fingerprint(message: &Message) -> String { + let mut hasher = DefaultHasher::new(); + message.kind.rule().hash(&mut hasher); + message.location.row().hash(&mut hasher); + message.location.column().hash(&mut hasher); + message.end_location.row().hash(&mut hasher); + message.end_location.column().hash(&mut hasher); + message.filename.hash(&mut hasher); + format!("{:x}", hasher.finish()) +} + struct CodeAndBody<'a>(&'a Message, fix::FixMode); impl Display for CodeAndBody<'_> {