-
Notifications
You must be signed in to change notification settings - Fork 2
Match recorded violations in strict packs (Part A) #43
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
base: main
Are you sure you want to change the base?
Changes from all commits
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -39,6 +39,20 @@ pub struct ViolationIdentifier { | |
| pub referencing_pack_name: String, | ||
| pub defining_pack_name: String, | ||
| } | ||
|
|
||
| impl ViolationIdentifier { | ||
| /// `strict` describes how a violation should be treated, not which violation | ||
| /// it is, and `package_todo.yml` has nowhere to record it, so recorded | ||
| /// violations are always rebuilt with `strict: false`. Compare through this | ||
| /// so a violation in a strict pack can still match its recorded entry. | ||
| pub fn recorded_key(&self) -> Self { | ||
| Self { | ||
| strict: false, | ||
| ..self.clone() | ||
| } | ||
| } | ||
| } | ||
|
|
||
| /// A violation combines an identifier with display metadata. | ||
| /// | ||
| /// `source_location` is intentionally separate from `ViolationIdentifier` because: | ||
|
|
@@ -142,7 +156,10 @@ impl<'a> CheckAllBuilder<'a> { | |
| self.found_violations | ||
| .violations | ||
| .iter() | ||
| .filter(|v| !recorded_violations.contains(&v.identifier)) | ||
| .filter(|v| { | ||
| !recorded_violations | ||
| .contains(&v.identifier.recorded_key()) | ||
| }) | ||
| .collect() | ||
| }; | ||
| reportable_violations | ||
|
|
@@ -152,11 +169,11 @@ impl<'a> CheckAllBuilder<'a> { | |
| &mut self, | ||
| recorded_violations: &'a HashSet<ViolationIdentifier>, | ||
| ) -> anyhow::Result<Vec<&'a ViolationIdentifier>> { | ||
| let found_violation_identifiers: HashSet<&ViolationIdentifier> = self | ||
| let found_violation_identifiers: HashSet<ViolationIdentifier> = self | ||
|
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Minor: this moves from If you want the cheaper version, a borrowed key tuple that excludes |
||
| .found_violations | ||
| .violations | ||
| .par_iter() | ||
| .map(|v| &v.identifier) | ||
| .map(|v| v.identifier.recorded_key()) | ||
| .collect(); | ||
| let relative_files = self | ||
| .found_violations | ||
|
|
@@ -196,9 +213,13 @@ impl<'a> CheckAllBuilder<'a> { | |
| Ok(stale_violations) | ||
| } | ||
|
|
||
| /// `found_violation_identifiers` is keyed by [`ViolationIdentifier::recorded_key`]. | ||
| /// `todo_violation_identifier` needs no such normalization: it comes from | ||
| /// `pack_set.all_violations`, which rebuilds every recorded violation with | ||
| /// `strict: false` already, so it is its own recorded key. | ||
| fn is_stale_violation( | ||
| relative_files: &HashSet<&str>, | ||
| found_violation_identifiers: &HashSet<&ViolationIdentifier>, | ||
| found_violation_identifiers: &HashSet<ViolationIdentifier>, | ||
| todo_violation_identifier: &ViolationIdentifier, | ||
| ) -> bool { | ||
| let violation_path_exists = | ||
|
|
||
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Design note, non-blocking, and fine to defer to a follow-up.
Consider moving
strictoffViolationIdentifierand ontoViolationinstead of normalizing at comparison time. Your comment here already says why:strictdescribes how a violation should be treated, not which violation it is. The doc comment just below atchecker.rs:55-64sets the same rule forsource_location, that the identifier defines sameness for comparison againstpackage_todo.yml, "which doesn't store line/column."strictisn't stored there either.The change is mechanical. Every reader of
.identifier.strict(json.rs:56,90;csv.rs:12,53;package_todo.rs:144) already has a full&Violation, andbuild_strict_violation_messagenever reads the field. Constructors arepack.rs:195, which is where #41 starts and which then stops having to inventstrict: false, pluspack_checker.rs:180and four test constructors. You'd get all three comparison sites back to plaincontains(&v.identifier), #41 becomes impossible to express instead of something a future call site has to remember to guard, and the extra allocations go away.One alternative to skip: excluding
strictfrom a manualPartialEq/Hash.Violation's derivedEq/Hashdelegate to the identifier, andget_all_violationsdedupes into aHashSet<Violation>, so makingstrict: trueequalstrict: falselets an insert keep the wrong flag, whichbuild_strict_mode_violationsthen filters on.recorded_key()is correct as written. This is about where the field lives, not about a bug.