@@ -9,15 +9,16 @@ use std::sync::Arc;
99use uuid:: Uuid ;
1010
1111use super :: pr_readiness:: {
12- apply_dynamic_review_state, get_pr_readiness_snapshot, latest_review_head_by_source,
13- load_review_inventory, PrReadinessSnapshot ,
12+ apply_dynamic_review_state, build_pr_readiness_snapshot, build_repo_blocker_rollups,
13+ get_pr_readiness_snapshot, latest_review_head_by_source, load_review_inventory,
14+ PrReadinessSnapshot ,
1415} ;
1516use super :: state:: {
1617 build_progress_callback, count_diff_files, count_reviewed_files, current_timestamp,
1718 emit_wide_event, AppState , FileMetricEvent , HotspotDetail , ReviewEventBuilder , ReviewListItem ,
1819 ReviewSession , ReviewStatus , MAX_DIFF_SIZE ,
1920} ;
20- use crate :: core:: comment:: CommentSynthesizer ;
21+ use crate :: core:: comment:: { CommentSynthesizer , MergeReadiness } ;
2122use crate :: core:: convention_learner:: ConventionStore ;
2223use tracing:: { info, warn} ;
2324
@@ -1580,6 +1581,10 @@ pub struct GhRepo {
15801581 pub language : Option < String > ,
15811582 pub updated_at : String ,
15821583 pub open_prs : usize ,
1584+ #[ serde( default , skip_serializing_if = "Option::is_none" ) ]
1585+ pub open_blockers : Option < usize > ,
1586+ #[ serde( default , skip_serializing_if = "Option::is_none" ) ]
1587+ pub blocking_prs : Option < usize > ,
15831588 pub default_branch : String ,
15841589 pub stargazers_count : u32 ,
15851590 pub private : bool ,
@@ -1649,6 +1654,9 @@ pub async fn get_gh_repos(
16491654 . cloned ( )
16501655 . unwrap_or_default ( ) ;
16511656
1657+ let inventory = load_review_inventory ( & state) . await ;
1658+ let blocker_rollups = build_repo_blocker_rollups ( & inventory) ;
1659+
16521660 let repos: Vec < GhRepo > = items
16531661 . into_iter ( )
16541662 . map ( |item| GhRepo {
@@ -1671,6 +1679,16 @@ pub async fn get_gh_repos(
16711679 . unwrap_or ( "" )
16721680 . to_string ( ) ,
16731681 open_prs : 0 ,
1682+ open_blockers : item
1683+ . get ( "full_name" )
1684+ . and_then ( |v| v. as_str ( ) )
1685+ . and_then ( |repo| blocker_rollups. get ( repo) )
1686+ . map ( |rollup| rollup. open_blockers ) ,
1687+ blocking_prs : item
1688+ . get ( "full_name" )
1689+ . and_then ( |v| v. as_str ( ) )
1690+ . and_then ( |repo| blocker_rollups. get ( repo) )
1691+ . map ( |rollup| rollup. blocking_prs ) ,
16741692 default_branch : item
16751693 . get ( "default_branch" )
16761694 . and_then ( |v| v. as_str ( ) )
@@ -1714,6 +1732,9 @@ pub async fn get_gh_repos(
17141732 )
17151733 } ) ?;
17161734
1735+ let inventory = load_review_inventory ( & state) . await ;
1736+ let blocker_rollups = build_repo_blocker_rollups ( & inventory) ;
1737+
17171738 let repos: Vec < GhRepo > = items
17181739 . into_iter ( )
17191740 . map ( |item| GhRepo {
@@ -1736,6 +1757,16 @@ pub async fn get_gh_repos(
17361757 . unwrap_or ( "" )
17371758 . to_string ( ) ,
17381759 open_prs : 0 ,
1760+ open_blockers : item
1761+ . get ( "full_name" )
1762+ . and_then ( |v| v. as_str ( ) )
1763+ . and_then ( |repo| blocker_rollups. get ( repo) )
1764+ . map ( |rollup| rollup. open_blockers ) ,
1765+ blocking_prs : item
1766+ . get ( "full_name" )
1767+ . and_then ( |v| v. as_str ( ) )
1768+ . and_then ( |repo| blocker_rollups. get ( repo) )
1769+ . map ( |rollup| rollup. blocking_prs ) ,
17391770 default_branch : item
17401771 . get ( "default_branch" )
17411772 . and_then ( |v| v. as_str ( ) )
@@ -1821,6 +1852,10 @@ pub struct GhPullRequest {
18211852 pub base_branch : String ,
18221853 pub labels : Vec < String > ,
18231854 pub draft : bool ,
1855+ #[ serde( default , skip_serializing_if = "Option::is_none" ) ]
1856+ pub open_blockers : Option < usize > ,
1857+ #[ serde( default , skip_serializing_if = "Option::is_none" ) ]
1858+ pub merge_readiness : Option < MergeReadiness > ,
18241859}
18251860
18261861/// Regex for validating repo names: owner/repo
@@ -1896,6 +1931,8 @@ pub async fn get_gh_prs(
18961931 )
18971932 } ) ?;
18981933
1934+ let inventory = load_review_inventory ( & state) . await ;
1935+
18991936 let prs: Vec < GhPullRequest > = items
19001937 . into_iter ( )
19011938 . filter ( |item| {
@@ -1930,8 +1967,20 @@ pub async fn get_gh_prs(
19301967 . to_string ( )
19311968 } ;
19321969
1970+ let pr_number = item. get ( "number" ) . and_then ( |v| v. as_u64 ( ) ) . unwrap_or ( 0 ) as u32 ;
1971+ let current_head_sha = item
1972+ . get ( "head" )
1973+ . and_then ( |v| v. get ( "sha" ) )
1974+ . and_then ( |v| v. as_str ( ) ) ;
1975+ let readiness_snapshot =
1976+ build_pr_readiness_snapshot ( & inventory, & params. repo , pr_number, current_head_sha) ;
1977+ let latest_summary = readiness_snapshot
1978+ . latest_review
1979+ . as_ref ( )
1980+ . and_then ( |review| review. summary . as_ref ( ) ) ;
1981+
19331982 GhPullRequest {
1934- number : item . get ( "number" ) . and_then ( |v| v . as_u64 ( ) ) . unwrap_or ( 0 ) as u32 ,
1983+ number : pr_number ,
19351984 title : item
19361985 . get ( "title" )
19371986 . and_then ( |v| v. as_str ( ) )
@@ -1971,6 +2020,8 @@ pub async fn get_gh_prs(
19712020 . to_string ( ) ,
19722021 labels,
19732022 draft : item. get ( "draft" ) . and_then ( |v| v. as_bool ( ) ) . unwrap_or ( false ) ,
2023+ open_blockers : latest_summary. map ( |summary| summary. open_blockers ) ,
2024+ merge_readiness : latest_summary. map ( |summary| summary. merge_readiness ) ,
19742025 }
19752026 } )
19762027 . collect ( ) ;
@@ -3092,6 +3143,8 @@ mod tests {
30923143 language : Some ( "Rust" . to_string ( ) ) ,
30933144 updated_at : "2024-01-01T00:00:00Z" . to_string ( ) ,
30943145 open_prs : 5 ,
3146+ open_blockers : Some ( 3 ) ,
3147+ blocking_prs : Some ( 2 ) ,
30953148 default_branch : "main" . to_string ( ) ,
30963149 stargazers_count : 42 ,
30973150 private : false ,
@@ -3100,6 +3153,8 @@ mod tests {
31003153 assert_eq ! ( json[ "full_name" ] , "owner/repo" ) ;
31013154 assert_eq ! ( json[ "language" ] , "Rust" ) ;
31023155 assert_eq ! ( json[ "open_prs" ] , 5 ) ;
3156+ assert_eq ! ( json[ "open_blockers" ] , 3 ) ;
3157+ assert_eq ! ( json[ "blocking_prs" ] , 2 ) ;
31033158 assert_eq ! ( json[ "stargazers_count" ] , 42 ) ;
31043159 assert_eq ! ( json[ "private" ] , false ) ;
31053160 }
@@ -3120,12 +3175,16 @@ mod tests {
31203175 base_branch : "main" . to_string ( ) ,
31213176 labels : vec ! [ "bugfix" . to_string( ) ] ,
31223177 draft : false ,
3178+ open_blockers : Some ( 2 ) ,
3179+ merge_readiness : Some ( MergeReadiness :: NeedsAttention ) ,
31233180 } ;
31243181 let json = serde_json:: to_value ( & pr) . unwrap ( ) ;
31253182 assert_eq ! ( json[ "number" ] , 42 ) ;
31263183 assert_eq ! ( json[ "title" ] , "Fix bug" ) ;
31273184 assert_eq ! ( json[ "author" ] , "dev" ) ;
31283185 assert_eq ! ( json[ "draft" ] , false ) ;
3186+ assert_eq ! ( json[ "open_blockers" ] , 2 ) ;
3187+ assert_eq ! ( json[ "merge_readiness" ] , "NeedsAttention" ) ;
31293188 assert_eq ! ( json[ "labels" ] . as_array( ) . unwrap( ) . len( ) , 1 ) ;
31303189 }
31313190
0 commit comments