20
20
//! `assign.owners` config, it will auto-select an assignee based on the files
21
21
//! the PR modifies.
22
22
23
- use crate :: db:: review_prefs:: get_review_prefs_batch;
23
+ use crate :: db:: review_prefs:: { get_review_prefs_batch, RotationMode } ;
24
24
use crate :: github:: UserId ;
25
25
use crate :: handlers:: pr_tracking:: ReviewerWorkqueue ;
26
26
use crate :: {
@@ -75,9 +75,9 @@ Use `r?` to explicitly pick a reviewer";
75
75
const RETURNING_USER_WELCOME_MESSAGE_NO_REVIEWER : & str =
76
76
"@{author}: no appropriate reviewer found, use `r?` to override" ;
77
77
78
- fn on_vacation_warning ( username : & str ) -> String {
78
+ fn reviewer_off_rotation_message ( username : & str ) -> String {
79
79
format ! (
80
- r"{username} is on vacation .
80
+ r"` {username}` is not available for reviewing at the moment .
81
81
82
82
Please choose another assignee."
83
83
)
@@ -347,7 +347,7 @@ async fn determine_assignee(
347
347
e @ FindReviewerError :: NoReviewer { .. }
348
348
| e @ FindReviewerError :: ReviewerIsPrAuthor { .. }
349
349
| e @ FindReviewerError :: ReviewerAlreadyAssigned { .. }
350
- | e @ FindReviewerError :: ReviewerOnVacation { .. }
350
+ | e @ FindReviewerError :: ReviewerOffRotation { .. }
351
351
| e @ FindReviewerError :: DatabaseError ( _)
352
352
| e @ FindReviewerError :: ReviewerAtMaxCapacity { .. } ,
353
353
) => log:: trace!(
@@ -672,9 +672,10 @@ enum FindReviewerError {
672
672
/// This could happen if there is a cyclical group or other misconfiguration.
673
673
/// `initial` is the initial list of candidate names.
674
674
NoReviewer { initial : Vec < String > } ,
675
- /// Requested reviewer is on vacation
676
- /// (i.e. username is in [users_on_vacation] in the triagebot.toml)
677
- ReviewerOnVacation { username : String } ,
675
+ /// Requested reviewer is off the review rotation (e.g. on a vacation).
676
+ /// Either the username is in [users_on_vacation] in `triagebot.toml` or the user has
677
+ /// configured [RotationMode::OffRotation] in their reviewer preferences.
678
+ ReviewerOffRotation { username : String } ,
678
679
/// Requested reviewer is PR author
679
680
ReviewerIsPrAuthor { username : String } ,
680
681
/// Requested reviewer is already assigned to that PR
@@ -708,8 +709,8 @@ impl fmt::Display for FindReviewerError {
708
709
initial. join( "," )
709
710
)
710
711
}
711
- FindReviewerError :: ReviewerOnVacation { username } => {
712
- write ! ( f, "{}" , on_vacation_warning ( username) )
712
+ FindReviewerError :: ReviewerOffRotation { username } => {
713
+ write ! ( f, "{}" , reviewer_off_rotation_message ( username) )
713
714
}
714
715
FindReviewerError :: ReviewerIsPrAuthor { username } => {
715
716
write ! (
@@ -955,7 +956,7 @@ async fn candidate_reviewers_from_names<'a>(
955
956
username : candidate. clone ( ) ,
956
957
} )
957
958
} else if is_on_vacation {
958
- Some ( FindReviewerError :: ReviewerOnVacation {
959
+ Some ( FindReviewerError :: ReviewerOffRotation {
959
960
username : candidate. clone ( ) ,
960
961
} )
961
962
} else if is_already_assigned {
@@ -997,20 +998,22 @@ async fn candidate_reviewers_from_names<'a>(
997
998
let username = username?;
998
999
999
1000
// If no review prefs were found, we assume the default unlimited
1000
- // review capacity.
1001
+ // review capacity and being on rotation .
1001
1002
let Some ( review_prefs) = review_prefs. get ( username. as_str ( ) ) else {
1002
1003
return Ok ( username) ;
1003
1004
} ;
1004
- let Some ( capacity) = review_prefs. max_assigned_prs else {
1005
- return Ok ( username ) ;
1006
- } ;
1007
- let assigned_prs = workqueue . assigned_pr_count ( review_prefs . user_id as UserId ) ;
1008
- // Can we assign one more PR?
1009
- if ( assigned_prs as i32 ) < capacity {
1010
- Ok ( username )
1011
- } else {
1012
- Err ( FindReviewerError :: ReviewerAtMaxCapacity { username } )
1005
+ if let Some ( capacity) = review_prefs. max_assigned_prs {
1006
+ let assigned_prs = workqueue . assigned_pr_count ( review_prefs . user_id as UserId ) ;
1007
+ // Is the reviewer at max capacity?
1008
+ if ( assigned_prs as i32 ) >= capacity {
1009
+ return Err ( FindReviewerError :: ReviewerAtMaxCapacity { username } ) ;
1010
+ }
1011
+ }
1012
+ if review_prefs . rotation_mode == RotationMode :: OffRotation {
1013
+ return Err ( FindReviewerError :: ReviewerOffRotation { username } ) ;
1013
1014
}
1015
+
1016
+ return Ok ( username) ;
1014
1017
} )
1015
1018
. collect ( ) ;
1016
1019
}
@@ -1021,6 +1024,13 @@ async fn candidate_reviewers_from_names<'a>(
1021
1024
. filter_map ( |res| res. as_deref ( ) . ok ( ) )
1022
1025
. collect ( ) ;
1023
1026
1027
+ log:: debug!(
1028
+ "Candidate reviewer results for review request `{}` on `{}`: {:?}" ,
1029
+ names. join( ", " ) ,
1030
+ issue. global_id( ) ,
1031
+ candidates
1032
+ ) ;
1033
+
1024
1034
if valid_candidates. is_empty ( ) {
1025
1035
// If we requested a single user for a review, we return a concrete error message
1026
1036
// describing why they couldn't be assigned.
0 commit comments