Skip to content

Commit 9cc6dce

Browse files
committed
Add handling of labels in check_commits super-handler
1 parent d697f2a commit 9cc6dce

File tree

1 file changed

+61
-6
lines changed

1 file changed

+61
-6
lines changed

src/handlers/check_commits.rs

Lines changed: 61 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -1,10 +1,13 @@
1+
use std::collections::HashSet;
2+
13
use anyhow::bail;
4+
use anyhow::Context as _;
25

36
use super::Context;
47
use crate::{
58
config::Config,
69
db::issue_data::IssueData,
7-
github::{Event, IssuesAction, IssuesEvent, ReportedContentClassifiers},
10+
github::{Event, IssuesAction, IssuesEvent, Label, ReportedContentClassifiers},
811
};
912

1013
#[cfg(test)]
@@ -25,6 +28,8 @@ struct CheckCommitsWarningsState {
2528
last_warnings: Vec<String>,
2629
/// ID of the most recent warning comment.
2730
last_warned_comment: Option<String>,
31+
/// List of the last labels added.
32+
last_labels: Vec<String>,
2833
}
2934

3035
pub(super) async fn handle(ctx: &Context, event: &Event, config: &Config) -> anyhow::Result<()> {
@@ -49,6 +54,7 @@ pub(super) async fn handle(ctx: &Context, event: &Event, config: &Config) -> any
4954
let commits = event.issue.commits(&ctx.github).await?;
5055

5156
let mut warnings = Vec::new();
57+
let mut labels = Vec::new();
5258

5359
// Compute the warnings
5460
if let Some(assign_config) = &config.assign {
@@ -72,14 +78,15 @@ pub(super) async fn handle(ctx: &Context, event: &Event, config: &Config) -> any
7278
warnings.extend(issue_links::issue_links_in_commits(issue_links, &commits));
7379
}
7480

75-
handle_warnings(ctx, event, warnings).await
81+
handle_warnings_and_labels(ctx, event, warnings, labels).await
7682
}
7783

7884
// Add, hide or hide&add a comment with the warnings.
79-
async fn handle_warnings(
85+
async fn handle_warnings_and_labels(
8086
ctx: &Context,
8187
event: &IssuesEvent,
8288
warnings: Vec<String>,
89+
labels: Vec<String>,
8390
) -> anyhow::Result<()> {
8491
// Get the state of the warnings for this PR in the database.
8592
let mut db = ctx.db.get().await;
@@ -105,10 +112,8 @@ async fn handle_warnings(
105112
let warning = warning_from_warnings(&warnings);
106113
let comment = event.issue.post_comment(&ctx.github, &warning).await?;
107114

108-
// Save new state in the database
109115
state.data.last_warnings = warnings;
110116
state.data.last_warned_comment = Some(comment.node_id);
111-
state.save().await?;
112117
} else if warnings.is_empty() {
113118
// No warnings to be shown, let's resolve a previous warnings comment, if there was one.
114119
if let Some(last_warned_comment_id) = state.data.last_warned_comment {
@@ -123,10 +128,46 @@ async fn handle_warnings(
123128

124129
state.data.last_warnings = Vec::new();
125130
state.data.last_warned_comment = None;
126-
state.save().await?;
127131
}
128132
}
129133

134+
// Handle the labels, add the new ones, remove the one no longer required, or don't do anything
135+
if !state.data.last_labels.is_empty() || !labels.is_empty() {
136+
let (labels_to_remove, labels_to_add) =
137+
calculate_label_changes(&state.data.last_labels, &labels);
138+
139+
// Remove the labels no longer required
140+
if !labels_to_remove.is_empty() {
141+
for label in labels_to_remove {
142+
event
143+
.issue
144+
.remove_label(&ctx.github, &label)
145+
.await
146+
.context("failed to remove a label in check_commits")?;
147+
}
148+
}
149+
150+
// Add the labels that are now required
151+
if !labels_to_add.is_empty() {
152+
event
153+
.issue
154+
.add_labels(
155+
&ctx.github,
156+
labels_to_add
157+
.into_iter()
158+
.map(|name| Label { name })
159+
.collect(),
160+
)
161+
.await
162+
.context("failed to add labels in check_commits")?;
163+
}
164+
165+
state.data.last_labels = labels;
166+
}
167+
168+
// Save new state in the database
169+
state.save().await?;
170+
130171
Ok(())
131172
}
132173

@@ -139,6 +180,20 @@ fn warning_from_warnings(warnings: &[String]) -> String {
139180
format!(":warning: **Warning** :warning:\n\n{}", warnings.join("\n"))
140181
}
141182

183+
// Calculate the label changes
184+
fn calculate_label_changes(
185+
previous: &Vec<String>,
186+
current: &Vec<String>,
187+
) -> (Vec<String>, Vec<String>) {
188+
let previous_set: HashSet<String> = previous.into_iter().cloned().collect();
189+
let current_set: HashSet<String> = current.into_iter().cloned().collect();
190+
191+
let removals = previous_set.difference(&current_set).cloned().collect();
192+
let additions = current_set.difference(&previous_set).cloned().collect();
193+
194+
(removals, additions)
195+
}
196+
142197
#[cfg(test)]
143198
fn dummy_commit_from_body(sha: &str, body: &str) -> GithubCommit {
144199
use chrono::{DateTime, FixedOffset};

0 commit comments

Comments
 (0)