Skip to content

Commit 1a554f9

Browse files
committed
Add errors handling check-commits super-handler
1 parent b19e02c commit 1a554f9

File tree

1 file changed

+56
-6
lines changed

1 file changed

+56
-6
lines changed

src/handlers/check_commits.rs

Lines changed: 56 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -21,11 +21,14 @@ mod no_merges;
2121
mod non_default_branch;
2222

2323
/// Key for the state in the database
24-
const CHECK_COMMITS_WARNINGS_KEY: &str = "check-commits-warnings";
24+
const CHECK_COMMITS_KEY: &str = "check-commits-warnings";
2525

2626
/// State stored in the database
2727
#[derive(Debug, Default, serde::Deserialize, serde::Serialize, Clone, PartialEq)]
28-
struct CheckCommitsWarningsState {
28+
struct CheckCommitsState {
29+
/// List of the last errors (comment body, comment node-id).
30+
#[serde(default)]
31+
last_errors: Vec<(String, String)>,
2932
/// List of the last warnings in the most recent comment.
3033
last_warnings: Vec<String>,
3134
/// ID of the most recent warning comment.
@@ -61,6 +64,7 @@ pub(super) async fn handle(ctx: &Context, event: &Event, config: &Config) -> any
6164
let commits = event.issue.commits(&ctx.github).await?;
6265
let diff = &compare.files;
6366

67+
let mut errors = Vec::new();
6468
let mut warnings = Vec::new();
6569
let mut labels = Vec::new();
6670

@@ -108,20 +112,44 @@ pub(super) async fn handle(ctx: &Context, event: &Event, config: &Config) -> any
108112
}
109113
}
110114

111-
handle_warnings_and_labels(ctx, event, warnings, labels).await
115+
handle_new_state(ctx, event, errors, warnings, labels).await
112116
}
113117

114118
// Add, hide or hide&add a comment with the warnings.
115-
async fn handle_warnings_and_labels(
119+
async fn handle_new_state(
116120
ctx: &Context,
117121
event: &IssuesEvent,
122+
errors: Vec<String>,
118123
warnings: Vec<String>,
119124
labels: Vec<String>,
120125
) -> anyhow::Result<()> {
121126
// Get the state of the warnings for this PR in the database.
122127
let mut db = ctx.db.get().await;
123-
let mut state: IssueData<'_, CheckCommitsWarningsState> =
124-
IssueData::load(&mut db, &event.issue, CHECK_COMMITS_WARNINGS_KEY).await?;
128+
let mut state: IssueData<'_, CheckCommitsState> =
129+
IssueData::load(&mut db, &event.issue, CHECK_COMMITS_KEY).await?;
130+
131+
// Handles the errors, post the new ones, hide resolved ones and don't touch the one still active
132+
if !state.data.last_errors.is_empty() || !errors.is_empty() {
133+
let (errors_to_remove, errors_to_add) =
134+
calculate_error_changes(&state.data.last_errors, &errors);
135+
136+
for error_to_remove in errors_to_remove {
137+
event
138+
.issue
139+
.hide_comment(
140+
&ctx.github,
141+
&error_to_remove.1,
142+
ReportedContentClassifiers::Resolved,
143+
)
144+
.await?;
145+
state.data.last_errors.retain(|e| e != &error_to_remove);
146+
}
147+
148+
for error_to_add in errors_to_add {
149+
let comment = event.issue.post_comment(&ctx.github, &error_to_add).await?;
150+
state.data.last_errors.push((error_to_add, comment.node_id));
151+
}
152+
}
125153

126154
// We only post a new comment when we haven't posted one with the same warnings before.
127155
if !warnings.is_empty() && state.data.last_warnings != warnings {
@@ -225,6 +253,28 @@ fn calculate_label_changes(
225253
(removals, additions)
226254
}
227255

256+
// Calculate the error changes
257+
fn calculate_error_changes(
258+
previous: &Vec<(String, String)>,
259+
current: &Vec<String>,
260+
) -> (Vec<(String, String)>, Vec<String>) {
261+
let previous_set: HashSet<(String, String)> = previous.into_iter().cloned().collect();
262+
let current_set: HashSet<String> = current.into_iter().cloned().collect();
263+
264+
let removals = previous_set
265+
.iter()
266+
.filter(|(e, _)| !current_set.contains(e))
267+
.cloned()
268+
.collect();
269+
let additions = current_set
270+
.iter()
271+
.filter(|e| !previous_set.iter().any(|(e2, _)| e == &e2))
272+
.cloned()
273+
.collect();
274+
275+
(removals, additions)
276+
}
277+
228278
#[cfg(test)]
229279
fn dummy_commit_from_body(sha: &str, body: &str) -> GithubCommit {
230280
use chrono::{DateTime, FixedOffset};

0 commit comments

Comments
 (0)