@@ -21,11 +21,14 @@ mod no_merges;
21
21
mod non_default_branch;
22
22
23
23
/// 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" ;
25
25
26
26
/// State stored in the database
27
27
#[ 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 ) > ,
29
32
/// List of the last warnings in the most recent comment.
30
33
last_warnings : Vec < String > ,
31
34
/// ID of the most recent warning comment.
@@ -61,6 +64,7 @@ pub(super) async fn handle(ctx: &Context, event: &Event, config: &Config) -> any
61
64
let commits = event. issue . commits ( & ctx. github ) . await ?;
62
65
let diff = & compare. files ;
63
66
67
+ let mut errors = Vec :: new ( ) ;
64
68
let mut warnings = Vec :: new ( ) ;
65
69
let mut labels = Vec :: new ( ) ;
66
70
@@ -108,20 +112,44 @@ pub(super) async fn handle(ctx: &Context, event: &Event, config: &Config) -> any
108
112
}
109
113
}
110
114
111
- handle_warnings_and_labels ( ctx, event, warnings, labels) . await
115
+ handle_new_state ( ctx, event, errors , warnings, labels) . await
112
116
}
113
117
114
118
// Add, hide or hide&add a comment with the warnings.
115
- async fn handle_warnings_and_labels (
119
+ async fn handle_new_state (
116
120
ctx : & Context ,
117
121
event : & IssuesEvent ,
122
+ errors : Vec < String > ,
118
123
warnings : Vec < String > ,
119
124
labels : Vec < String > ,
120
125
) -> anyhow:: Result < ( ) > {
121
126
// Get the state of the warnings for this PR in the database.
122
127
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
+ }
125
153
126
154
// We only post a new comment when we haven't posted one with the same warnings before.
127
155
if !warnings. is_empty ( ) && state. data . last_warnings != warnings {
@@ -225,6 +253,28 @@ fn calculate_label_changes(
225
253
( removals, additions)
226
254
}
227
255
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
+
228
278
#[ cfg( test) ]
229
279
fn dummy_commit_from_body ( sha : & str , body : & str ) -> GithubCommit {
230
280
use chrono:: { DateTime , FixedOffset } ;
0 commit comments