@@ -8,10 +8,31 @@ use serde::{Deserialize, Serialize};
88use tokio:: time;
99use tracing:: error;
1010
11- use crate :: { database:: Database , github:: {
12- issues:: { IssueState , IssuesRepositoryIssuesNodesAuthor :: User as userName} ,
13- pull_requests:: PullRequestsRepositoryPullRequestsNodesReviewRequestsNodesRequestedReviewer :: User ,
14- } , settings:: Repository as RepoInfo } ;
11+ use crate :: {
12+ database:: Database ,
13+ github:: {
14+ issues:: {
15+ IssueState , IssuesRepositoryIssuesNodesAuthor :: User as IssueAuthor ,
16+ IssuesRepositoryIssuesNodesClosedByPullRequestsReferencesEdgesNodeAuthor :: User as PullRequestRefAuthor ,
17+ IssuesRepositoryIssuesNodesCommentsNodesAuthor :: User as IssueCommentsAuthor ,
18+ IssuesRepositoryIssuesNodesProjectItemsNodesTodoInitiationOption as TodoInitOption ,
19+ IssuesRepositoryIssuesNodesProjectItemsNodesTodoPendingDays as TodoPendingDays ,
20+ IssuesRepositoryIssuesNodesProjectItemsNodesTodoPriority as TodoPriority ,
21+ IssuesRepositoryIssuesNodesProjectItemsNodesTodoSize as TodoSize ,
22+ IssuesRepositoryIssuesNodesProjectItemsNodesTodoStatus as TodoStatus ,
23+ IssuesRepositoryIssuesNodesSubIssuesNodesAuthor :: User as SubIssueAuthor ,
24+ } ,
25+ pull_requests:: PullRequestsRepositoryPullRequestsNodesReviewRequestsNodesRequestedReviewer :: User ,
26+ } ,
27+ graphql:: {
28+ issue:: {
29+ Comment , CommentConnection , ParentIssue , ProjectV2Item , ProjectV2ItemConnection ,
30+ PullRequestRef , SubIssue , SubIssueConnection ,
31+ } ,
32+ DateTimeUtc ,
33+ } ,
34+ settings:: Repository as RepoInfo ,
35+ } ;
1536
1637const GITHUB_FETCH_SIZE : i64 = 10 ;
1738const GITHUB_URL : & str = "https://api.github.com/graphql" ;
@@ -20,6 +41,9 @@ const INIT_TIME: &str = "1992-06-05T00:00:00Z";
2041
2142type DateTime = Timestamp ;
2243
44+ #[ allow( clippy:: upper_case_acronyms) ]
45+ type URI = String ;
46+
2347#[ derive( GraphQLQuery ) ]
2448#[ graphql(
2549 schema_path = "src/github/schema.graphql" ,
@@ -44,18 +68,28 @@ impl Default for IssueState {
4468
4569#[ derive( Debug , Default , Serialize , Deserialize ) ]
4670pub ( super ) struct GitHubIssue {
47- pub ( super ) number : i64 ,
71+ pub ( super ) id : String ,
72+ pub ( super ) number : i32 ,
4873 pub ( super ) title : String ,
4974 pub ( super ) author : String ,
50- pub ( super ) closed_at : Option < DateTime > ,
51- pub ( super ) created_at : DateTime ,
75+ pub ( super ) body : String ,
5276 pub ( super ) state : IssueState ,
5377 pub ( super ) assignees : Vec < String > ,
78+ pub ( super ) labels : Vec < String > ,
79+ pub ( super ) comments : CommentConnection ,
80+ pub ( super ) project_items : ProjectV2ItemConnection ,
81+ pub ( super ) sub_issues : SubIssueConnection ,
82+ pub ( super ) parent : Option < ParentIssue > ,
83+ pub ( super ) url : String ,
84+ pub ( super ) closed_by_pull_requests : Vec < PullRequestRef > ,
85+ pub ( super ) created_at : DateTimeUtc ,
86+ pub ( super ) updated_at : DateTimeUtc ,
87+ pub ( super ) closed_at : Option < DateTimeUtc > ,
5488}
5589
5690#[ derive( Debug ) ]
5791pub ( super ) struct GitHubPullRequests {
58- pub ( super ) number : i64 ,
92+ pub ( super ) number : i32 ,
5993 pub ( super ) title : String ,
6094 pub ( super ) assignees : Vec < String > ,
6195 pub ( super ) reviewers : Vec < String > ,
@@ -126,6 +160,7 @@ pub(super) async fn fetch_periodically(
126160 }
127161}
128162
163+ #[ allow( clippy:: too_many_lines) ]
129164async fn send_github_issue_query (
130165 owner : & str ,
131166 name : & str ,
@@ -142,45 +177,194 @@ async fn send_github_issue_query(
142177 first : Some ( GITHUB_FETCH_SIZE ) ,
143178 last : None ,
144179 before : None ,
145- after : end_cur,
180+ after : end_cur. take ( ) ,
146181 since : Some ( since. parse :: < DateTime > ( ) ?) ,
147182 } ;
148183 let resp_body: GraphQlResponse < issues:: ResponseData > =
149184 send_query :: < Issues > ( token, var) . await ?. json ( ) . await ?;
150185 if let Some ( data) = resp_body. data {
151186 if let Some ( repository) = data. repository {
152- if let Some ( nodes) = repository. issues . nodes . as_ref ( ) {
153- for issue in nodes. iter ( ) . flatten ( ) {
154- let mut author: String = String :: new ( ) ;
155-
156- let author_ref = issue. author . as_ref ( ) . context ( "Missing issue author" ) ?;
157- if let userName( on_user) = author_ref {
158- author. clone_from ( & on_user. login . clone ( ) ) ;
159- }
160- let assignees =
161- issue. assignees . nodes . as_ref ( ) . map_or ( Vec :: new ( ) , |nodes| {
162- nodes. iter ( ) . flatten ( ) . map ( |a| a. login . clone ( ) ) . collect ( )
163- } ) ;
164- issues. push ( GitHubIssue {
165- number : issue. number ,
166- title : issue. title . to_string ( ) ,
167- author,
168- closed_at : issue. closed_at ,
169- created_at : issue. created_at ,
170- state : issue. state . clone ( ) ,
171- assignees,
172- } ) ;
173- }
174- if !repository. issues . page_info . has_next_page {
175- total_issue. push ( issues) ;
176- break ;
177- }
178- end_cur = repository. issues . page_info . end_cursor ;
179- continue ;
187+ let nodes = repository. issues . nodes . unwrap_or_default ( ) ;
188+ for issue in nodes. into_iter ( ) . flatten ( ) {
189+ let author = match issue. author . context ( "Missing issue author" ) ? {
190+ IssueAuthor ( u) => u. login ,
191+ _ => String :: new ( ) ,
192+ } ;
193+ issues. push ( GitHubIssue {
194+ id : issue. id ,
195+ number : issue. number . try_into ( ) . unwrap_or_default ( ) ,
196+ title : issue. title ,
197+ author,
198+ body : issue. body ,
199+ state : issue. state ,
200+ assignees : issue
201+ . assignees
202+ . nodes
203+ . unwrap_or_default ( )
204+ . into_iter ( )
205+ . flatten ( )
206+ . map ( |n| n. login )
207+ . collect ( ) ,
208+ labels : issue
209+ . labels
210+ . and_then ( |l| l. nodes )
211+ . unwrap_or_default ( )
212+ . into_iter ( )
213+ . flatten ( )
214+ . map ( |node| node. name )
215+ . collect ( ) ,
216+ comments : CommentConnection {
217+ total_count : issue. comments . total_count . try_into ( ) . unwrap_or_default ( ) ,
218+ nodes : issue
219+ . comments
220+ . nodes
221+ . unwrap_or_default ( )
222+ . into_iter ( )
223+ . flatten ( )
224+ . map ( |comment| Comment {
225+ author : match comment. author {
226+ Some ( IssueCommentsAuthor ( u) ) => u. login ,
227+ _ => String :: new ( ) ,
228+ } ,
229+ body : comment. body ,
230+ created_at : DateTimeUtc ( comment. created_at ) ,
231+ id : comment. id ,
232+ repository_name : comment. repository . name ,
233+ updated_at : DateTimeUtc ( comment. updated_at ) ,
234+ url : comment. url ,
235+ } )
236+ . collect ( ) ,
237+ } ,
238+ project_items : ProjectV2ItemConnection {
239+ total_count : issue
240+ . project_items
241+ . total_count
242+ . try_into ( )
243+ . unwrap_or_default ( ) ,
244+ nodes : issue
245+ . project_items
246+ . nodes
247+ . unwrap_or_default ( )
248+ . into_iter ( )
249+ . flatten ( )
250+ . map ( |node| ProjectV2Item {
251+ id : node. id ,
252+ todo_status : node. todo_status . and_then ( |status| match status {
253+ TodoStatus :: ProjectV2ItemFieldSingleSelectValue ( inner) => {
254+ inner. name
255+ }
256+ _ => None ,
257+ } ) ,
258+ todo_priority : node. todo_priority . and_then ( |priority| {
259+ match priority {
260+ TodoPriority :: ProjectV2ItemFieldSingleSelectValue (
261+ inner,
262+ ) => inner. name ,
263+ _ => None ,
264+ }
265+ } ) ,
266+ todo_size : node. todo_size . and_then ( |size| match size {
267+ TodoSize :: ProjectV2ItemFieldSingleSelectValue ( inner) => {
268+ inner. name
269+ }
270+ _ => None ,
271+ } ) ,
272+ todo_initiation_option : node. todo_initiation_option . and_then (
273+ |init| match init {
274+ TodoInitOption :: ProjectV2ItemFieldSingleSelectValue (
275+ inner,
276+ ) => inner. name ,
277+ _ => None ,
278+ } ,
279+ ) ,
280+ todo_pending_days : node. todo_pending_days . and_then ( |days| {
281+ match days {
282+ TodoPendingDays :: ProjectV2ItemFieldNumberValue (
283+ inner,
284+ ) => inner. number ,
285+ _ => None ,
286+ }
287+ } ) ,
288+ } )
289+ . collect ( ) ,
290+ } ,
291+ sub_issues : SubIssueConnection {
292+ total_count : issue
293+ . sub_issues
294+ . total_count
295+ . try_into ( )
296+ . unwrap_or_default ( ) ,
297+ nodes : issue
298+ . sub_issues
299+ . nodes
300+ . unwrap_or_default ( )
301+ . into_iter ( )
302+ . flatten ( )
303+ . map ( |si| SubIssue {
304+ id : si. id ,
305+ number : si. number . try_into ( ) . unwrap_or_default ( ) ,
306+ title : si. title ,
307+ state : si. state ,
308+ created_at : DateTimeUtc ( si. created_at ) ,
309+ updated_at : DateTimeUtc ( si. updated_at ) ,
310+ closed_at : si. closed_at . map ( DateTimeUtc ) ,
311+ author : match si. author {
312+ Some ( SubIssueAuthor ( u) ) => u. login ,
313+ _ => String :: new ( ) ,
314+ } ,
315+ assignees : si
316+ . assignees
317+ . nodes
318+ . unwrap_or_default ( )
319+ . into_iter ( )
320+ . flatten ( )
321+ . map ( |n| n. login )
322+ . collect ( ) ,
323+ } )
324+ . collect ( ) ,
325+ } ,
326+ parent : issue. parent . map ( |parent| ParentIssue {
327+ id : parent. id ,
328+ number : parent. number . try_into ( ) . unwrap_or_default ( ) ,
329+ title : parent. title ,
330+ } ) ,
331+ url : issue. url ,
332+ closed_by_pull_requests : issue
333+ . closed_by_pull_requests_references
334+ . map ( |r| r. edges )
335+ . unwrap_or_default ( )
336+ . into_iter ( )
337+ . flatten ( )
338+ . flatten ( )
339+ . filter_map ( |edge| {
340+ edge. node . map ( |node| PullRequestRef {
341+ number : node. number . try_into ( ) . unwrap_or_default ( ) ,
342+ state : node. state ,
343+ created_at : DateTimeUtc ( node. created_at ) ,
344+ updated_at : DateTimeUtc ( node. updated_at ) ,
345+ closed_at : node. closed_at . map ( DateTimeUtc ) ,
346+ author : match node. author {
347+ Some ( PullRequestRefAuthor ( u) ) => u. login ,
348+ _ => String :: new ( ) ,
349+ } ,
350+ url : node. url ,
351+ } )
352+ } )
353+ . collect ( ) ,
354+ created_at : DateTimeUtc ( issue. created_at ) ,
355+ updated_at : DateTimeUtc ( issue. updated_at ) ,
356+ closed_at : issue. closed_at . map ( DateTimeUtc ) ,
357+ } ) ;
180358 }
359+ if !repository. issues . page_info . has_next_page {
360+ total_issue. push ( issues) ;
361+ break ;
362+ }
363+ end_cur = repository. issues . page_info . end_cursor ;
364+ continue ;
181365 }
366+ bail ! ( "Failed to parse response data" ) ;
182367 }
183- bail ! ( "Failed to parse response data" ) ;
184368 }
185369 Ok ( total_issue)
186370}
@@ -230,7 +414,7 @@ async fn send_github_pr_query(
230414 }
231415
232416 prs. push ( GitHubPullRequests {
233- number : pr. number ,
417+ number : pr. number . try_into ( ) . unwrap_or_default ( ) ,
234418 title : pr. title . to_string ( ) ,
235419 assignees,
236420 reviewers,
0 commit comments