7
7
//! * `@rustbot release-assignment`: Removes the commenter's assignment.
8
8
//! * `r? @user`: Assigns to the given user (PRs only).
9
9
//!
10
- //! Note: this module does not handle review assignments issued from the
11
- //! GitHub "Assignees" dropdown menu
12
- //!
13
10
//! This is capable of assigning to any user, even if they do not have write
14
11
//! access to the repo. It does this by fake-assigning the bot and adding a
15
12
//! "claimed by" section to the top-level comment.
23
20
use crate :: {
24
21
config:: AssignConfig ,
25
22
github:: { self , Event , FileDiff , Issue , IssuesAction , Selection } ,
26
- handlers:: { pr_tracking :: has_user_capacity , Context , GithubClient , IssuesEvent } ,
23
+ handlers:: { Context , GithubClient , IssuesEvent } ,
27
24
interactions:: EditIssueBody ,
28
25
} ;
29
26
use anyhow:: { bail, Context as _} ;
@@ -33,7 +30,6 @@ use rand::seq::IteratorRandom;
33
30
use rust_team_data:: v1:: Teams ;
34
31
use std:: collections:: { HashMap , HashSet } ;
35
32
use std:: fmt;
36
- use tokio_postgres:: Client as DbClient ;
37
33
use tracing as log;
38
34
39
35
#[ cfg( test) ]
@@ -79,27 +75,6 @@ const NON_DEFAULT_BRANCH: &str =
79
75
80
76
const SUBMODULE_WARNING_MSG : & str = "These commits modify **submodules**." ;
81
77
82
- pub const SELF_ASSIGN_HAS_NO_CAPACITY : & str = "
83
- You have insufficient capacity to be assigned the pull request at this time. PR assignment has been reverted.
84
-
85
- Please choose another assignee or increase your assignment limit.
86
-
87
- (see [documentation](https://forge.rust-lang.org/triagebot/pr-assignment-tracking.html))" ;
88
-
89
- pub const REVIEWER_HAS_NO_CAPACITY : & str = "
90
- `{username}` has insufficient capacity to be assigned the pull request at this time. PR assignment has been reverted.
91
-
92
- Please choose another assignee.
93
-
94
- (see [documentation](https://forge.rust-lang.org/triagebot/pr-assignment-tracking.html))" ;
95
-
96
- const NO_REVIEWER_HAS_CAPACITY : & str = "
97
- Could not find a reviewer with enough capacity to be assigned at this time. This is a problem.
98
-
99
- Please contact us on [#t-infra](https://rust-lang.zulipchat.com/#narrow/stream/242791-t-infra) on Zulip.
100
-
101
- cc: @jackh726 @apiraino" ;
102
-
103
78
fn on_vacation_msg ( user : & str ) -> String {
104
79
ON_VACATION_WARNING . replace ( "{username}" , user)
105
80
}
@@ -297,8 +272,6 @@ async fn set_assignee(issue: &Issue, github: &GithubClient, username: &str) {
297
272
/// Determines who to assign the PR to based on either an `r?` command, or
298
273
/// based on which files were modified.
299
274
///
300
- /// Will also check if candidates have capacity in their work queue.
301
- ///
302
275
/// Returns `(assignee, from_comment)` where `assignee` is who to assign to
303
276
/// (or None if no assignee could be found). `from_comment` is a boolean
304
277
/// indicating if the assignee came from an `r?` command (it is false if
@@ -309,14 +282,13 @@ async fn determine_assignee(
309
282
config : & AssignConfig ,
310
283
diff : & [ FileDiff ] ,
311
284
) -> anyhow:: Result < ( Option < String > , bool ) > {
312
- let db_client = ctx. db . get ( ) . await ;
313
285
let teams = crate :: team_data:: teams ( & ctx. github ) . await ?;
314
286
if let Some ( name) = find_assign_command ( ctx, event) {
315
287
if is_self_assign ( & name, & event. issue . user . login ) {
316
288
return Ok ( ( Some ( name. to_string ( ) ) , true ) ) ;
317
289
}
318
290
// User included `r?` in the opening PR body.
319
- match find_reviewer_from_names ( & db_client , & teams, config, & event. issue , & [ name] ) . await {
291
+ match find_reviewer_from_names ( & teams, config, & event. issue , & [ name] ) {
320
292
Ok ( assignee) => return Ok ( ( Some ( assignee) , true ) ) ,
321
293
Err ( e) => {
322
294
event
@@ -330,9 +302,7 @@ async fn determine_assignee(
330
302
// Errors fall-through to try fallback group.
331
303
match find_reviewers_from_diff ( config, diff) {
332
304
Ok ( candidates) if !candidates. is_empty ( ) => {
333
- match find_reviewer_from_names ( & db_client, & teams, config, & event. issue , & candidates)
334
- . await
335
- {
305
+ match find_reviewer_from_names ( & teams, config, & event. issue , & candidates) {
336
306
Ok ( assignee) => return Ok ( ( Some ( assignee) , false ) ) ,
337
307
Err ( FindReviewerError :: TeamNotFound ( team) ) => log:: warn!(
338
308
"team {team} not found via diff from PR {}, \
@@ -342,9 +312,7 @@ async fn determine_assignee(
342
312
// TODO: post a comment on the PR if the reviewers were filtered due to being on vacation
343
313
Err (
344
314
e @ FindReviewerError :: NoReviewer { .. }
345
- | e @ FindReviewerError :: AllReviewersFiltered { .. }
346
- | e @ FindReviewerError :: NoReviewerHasCapacity
347
- | e @ FindReviewerError :: ReviewerHasNoCapacity { .. } ,
315
+ | e @ FindReviewerError :: AllReviewersFiltered { .. } ,
348
316
) => log:: trace!(
349
317
"no reviewer could be determined for PR {}: {e}" ,
350
318
event. issue. global_id( )
@@ -362,7 +330,7 @@ async fn determine_assignee(
362
330
}
363
331
364
332
if let Some ( fallback) = config. adhoc_groups . get ( "fallback" ) {
365
- match find_reviewer_from_names ( & db_client , & teams, config, & event. issue , fallback) . await {
333
+ match find_reviewer_from_names ( & teams, config, & event. issue , fallback) {
366
334
Ok ( assignee) => return Ok ( ( Some ( assignee) , false ) ) ,
367
335
Err ( e) => {
368
336
log:: trace!(
@@ -524,20 +492,7 @@ pub(super) async fn handle_command(
524
492
// welcome message).
525
493
return Ok ( ( ) ) ;
526
494
}
527
- let db_client = ctx. db . get ( ) . await ;
528
495
if is_self_assign ( & name, & event. user ( ) . login ) {
529
- match has_user_capacity ( & db_client, & name) . await {
530
- Ok ( work_queue) => work_queue. username ,
531
- Err ( _) => {
532
- issue
533
- . post_comment (
534
- & ctx. github ,
535
- & REVIEWER_HAS_NO_CAPACITY . replace ( "{username}" , & name) ,
536
- )
537
- . await ?;
538
- return Ok ( ( ) ) ;
539
- }
540
- } ;
541
496
name. to_string ( )
542
497
} else {
543
498
let teams = crate :: team_data:: teams ( & ctx. github ) . await ?;
@@ -557,14 +512,8 @@ pub(super) async fn handle_command(
557
512
}
558
513
}
559
514
}
560
- match find_reviewer_from_names (
561
- & db_client,
562
- & teams,
563
- config,
564
- issue,
565
- & [ team_name. to_string ( ) ] ,
566
- )
567
- . await
515
+
516
+ match find_reviewer_from_names ( & teams, config, issue, & [ team_name. to_string ( ) ] )
568
517
{
569
518
Ok ( assignee) => assignee,
570
519
Err ( e) => {
@@ -575,11 +524,7 @@ pub(super) async fn handle_command(
575
524
}
576
525
}
577
526
} ;
578
-
579
- // This user is validated and can accept the PR
580
527
set_assignee ( issue, & ctx. github , & username) . await ;
581
- // This PR will now be registered in the reviewer's work queue
582
- // by the `pr_tracking` handler
583
528
return Ok ( ( ) ) ;
584
529
}
585
530
@@ -637,7 +582,6 @@ pub(super) async fn handle_command(
637
582
638
583
e. apply ( & ctx. github , String :: new ( ) , & data) . await ?;
639
584
640
- // Assign the PR: user's work queue has been checked and can accept this PR
641
585
match issue. set_assignee ( & ctx. github , & to_assign) . await {
642
586
Ok ( ( ) ) => return Ok ( ( ) ) , // we are done
643
587
Err ( github:: AssignmentError :: InvalidAssignee ) => {
@@ -659,7 +603,7 @@ pub(super) async fn handle_command(
659
603
}
660
604
661
605
#[ derive( PartialEq , Debug ) ]
662
- pub enum FindReviewerError {
606
+ enum FindReviewerError {
663
607
/// User specified something like `r? foo/bar` where that team name could
664
608
/// not be found.
665
609
TeamNotFound ( String ) ,
@@ -677,11 +621,6 @@ pub enum FindReviewerError {
677
621
initial : Vec < String > ,
678
622
filtered : Vec < String > ,
679
623
} ,
680
- /// No reviewer has capacity to accept a pull request assignment at this time
681
- NoReviewerHasCapacity ,
682
- /// The requested reviewer has no capacity to accept a pull request
683
- /// assignment at this time
684
- ReviewerHasNoCapacity { username : String } ,
685
624
}
686
625
687
626
impl std:: error:: Error for FindReviewerError { }
@@ -711,23 +650,13 @@ impl fmt::Display for FindReviewerError {
711
650
write ! (
712
651
f,
713
652
"Could not assign reviewer from: `{}`.\n \
714
- User(s) `{}` are either the PR author, already assigned, or on vacation. \
715
- If it's a team, we could not find any candidates.\n \
716
- Please use `r?` to specify someone else to assign.",
653
+ User(s) `{}` are either the PR author, already assigned, or on vacation, \
654
+ and there are no other candidates.\n \
655
+ Use `r?` to specify someone else to assign.",
717
656
initial. join( "," ) ,
718
657
filtered. join( "," ) ,
719
658
)
720
659
}
721
- FindReviewerError :: ReviewerHasNoCapacity { username } => {
722
- write ! (
723
- f,
724
- "{}" ,
725
- REVIEWER_HAS_NO_CAPACITY . replace( "{username}" , username)
726
- )
727
- }
728
- FindReviewerError :: NoReviewerHasCapacity => {
729
- write ! ( f, "{}" , NO_REVIEWER_HAS_CAPACITY )
730
- }
731
660
}
732
661
}
733
662
}
@@ -738,8 +667,7 @@ impl fmt::Display for FindReviewerError {
738
667
/// `@octocat`, or names from the owners map. It can contain GitHub usernames,
739
668
/// auto-assign groups, or rust-lang team names. It must have at least one
740
669
/// entry.
741
- async fn find_reviewer_from_names (
742
- db : & DbClient ,
670
+ fn find_reviewer_from_names (
743
671
teams : & Teams ,
744
672
config : & AssignConfig ,
745
673
issue : & Issue ,
@@ -765,64 +693,14 @@ async fn find_reviewer_from_names(
765
693
//
766
694
// These are all ideas for improving the selection here. However, I'm not
767
695
// sure they are really worth the effort.
768
-
769
- // If we are trying to assign to the ghost GitHub user, bypass every check
770
- let mut filtered_candidates: HashSet < String > = HashSet :: new ( ) ;
771
- if candidates. contains ( "ghost" ) {
772
- filtered_candidates. insert ( "ghost" . to_string ( ) ) ;
773
- } else {
774
- // filter out team members without capacity
775
- filtered_candidates = filter_by_capacity ( db, & candidates)
776
- . await
777
- . expect ( "Error while filtering out team members" ) ;
778
-
779
- if filtered_candidates. is_empty ( ) {
780
- return Err ( FindReviewerError :: AllReviewersFiltered {
781
- initial : names. to_vec ( ) ,
782
- filtered : names. to_vec ( ) ,
783
- } ) ;
784
- }
785
- }
786
-
787
- log:: debug!( "Filtered list of candidates: {:?}" , filtered_candidates) ;
788
-
789
- Ok ( filtered_candidates
696
+ Ok ( candidates
790
697
. into_iter ( )
791
698
. choose ( & mut rand:: thread_rng ( ) )
792
- . expect ( "candidate_reviewers_from_names should return at least one entry" )
699
+ . expect ( "candidate_reviewers_from_names always returns at least one entry" )
793
700
. to_string ( ) )
794
701
}
795
702
796
- // FIXME: this query probably needs to take into account when max_assigned_prs is null
797
- /// Filter out candidates not having review capacity
798
- async fn filter_by_capacity (
799
- db : & DbClient ,
800
- candidates : & HashSet < & str > ,
801
- ) -> anyhow:: Result < HashSet < String > > {
802
- let usernames = candidates
803
- . iter ( )
804
- . map ( |c| * c)
805
- . collect :: < Vec < & str > > ( )
806
- . join ( "," ) ;
807
-
808
- let q = format ! (
809
- "
810
- SELECT username
811
- FROM review_prefs r
812
- JOIN users on users.user_id=r.user_id
813
- AND username = ANY('{{ {} }}')
814
- AND ARRAY_LENGTH(r.assigned_prs, 1) < max_assigned_prs" ,
815
- usernames
816
- ) ;
817
- let result = db. query ( & q, & [ ] ) . await . context ( "Select DB error" ) ?;
818
- let mut candidates: HashSet < String > = HashSet :: new ( ) ;
819
- for row in result {
820
- candidates. insert ( row. get ( "username" ) ) ;
821
- }
822
- Ok ( candidates)
823
- }
824
-
825
- /// returns a list of candidate usernames (from relevant teams) to choose as a reviewer.
703
+ /// Returns a list of candidate usernames to choose as a reviewer.
826
704
fn candidate_reviewers_from_names < ' a > (
827
705
teams : & ' a Teams ,
828
706
config : & ' a AssignConfig ,
0 commit comments