@@ -37,24 +37,31 @@ impl Generator {
37
37
38
38
self . fcps ( String :: from ( "T-libs-api" ) ) ?;
39
39
40
- IssueQuery :: new ( "Nominated" )
40
+ GithubQuery :: new ( "Nominated" )
41
41
. labels ( & [ "T-libs-api" , "I-nominated" ] )
42
42
. repo ( "rust-lang/libs-team" )
43
43
. repo ( "rust-lang/rust" )
44
44
. repo ( "rust-lang/rfcs" )
45
45
. write ( & mut self ) ?;
46
46
47
- IssueQuery :: new ( "Waiting on team" )
47
+ GithubQuery :: new ( "Waiting on team" )
48
48
. labels ( & [ "T-libs-api" , "S-waiting-on-team" ] )
49
49
. repo ( "rust-lang/rust" )
50
50
. repo ( "rust-lang/rfcs" )
51
51
. write ( & mut self ) ?;
52
52
53
- IssueQuery :: new ( "Needs decision" )
53
+ GithubQuery :: new ( "Needs decision" )
54
54
. labels ( & [ "T-libs-api" , "I-needs-decision" ] )
55
55
. repo ( "rust-lang/rust" )
56
56
. write ( & mut self ) ?;
57
57
58
+ GithubQuery :: new ( "Stalled Tracking Issues" )
59
+ . labels ( & [ "T-libs-api" , "C-tracking-issue" ] )
60
+ . repo ( "rust-lang/rust" )
61
+ . sort ( Sort :: LeastRecentlyUpdated )
62
+ . take ( 5 )
63
+ . write ( & mut self ) ?;
64
+
58
65
writeln ! ( & mut self . agenda,
59
66
"## Actions
60
67
@@ -91,28 +98,28 @@ impl Generator {
91
98
92
99
self . fcps ( String :: from ( "T-libs" ) ) ?;
93
100
94
- IssueQuery :: new ( "Critical" )
101
+ GithubQuery :: new ( "Critical" )
95
102
. labels ( & [ "T-libs" , "P-critical" ] )
96
103
. labels ( & [ "T-libs-api" , "P-critical" ] )
97
104
. repo ( "rust-lang/rust" )
98
105
. repo ( "rust-lang/rfcs" )
99
106
. write ( & mut self ) ?;
100
107
101
- IssueQuery :: new ( "Prioritization Requested" )
108
+ GithubQuery :: new ( "Prioritization Requested" )
102
109
. labels ( & [ "T-libs" , "I-prioritize" ] )
103
110
. labels ( & [ "T-libs-api" , "I-prioritize" ] )
104
111
. repo ( "rust-lang/rust" )
105
112
. repo ( "rust-lang/rfcs" )
106
113
. write ( & mut self ) ?;
107
114
108
- IssueQuery :: new ( "Nominated" )
115
+ GithubQuery :: new ( "Nominated" )
109
116
. labels ( & [ "T-libs" , "I-nominated" ] )
110
117
. repo ( "rust-lang/rust" )
111
118
. repo ( "rust-lang/rfcs" )
112
119
. repo ( "rust-lang/libs-team" )
113
120
. write ( & mut self ) ?;
114
121
115
- IssueQuery :: new ( "Backports" )
122
+ GithubQuery :: new ( "Backports" )
116
123
. labels ( & [ "T-libs" , "stable-nominated" ] )
117
124
. labels ( & [ "T-libs-api" , "stable-nominated" ] )
118
125
. labels ( & [ "T-libs" , "stable-accepted" ] )
@@ -121,11 +128,12 @@ impl Generator {
121
128
. labels ( & [ "T-libs-api" , "beta-nominated" ] )
122
129
. labels ( & [ "T-libs" , "beta-accepted" ] )
123
130
. labels ( & [ "T-libs-api" , "beta-accepted" ] )
131
+ . state ( State :: Any )
124
132
. repo ( "rust-lang/rust" )
125
133
. repo ( "rust-lang/rfcs" )
126
134
. write ( & mut self ) ?;
127
135
128
- IssueQuery :: new ( "Regressions" )
136
+ GithubQuery :: new ( "Regressions" )
129
137
. labels ( & [ "T-libs" , "regression-untriaged" ] )
130
138
. labels ( & [ "T-libs-api" , "regression-untriaged" ] )
131
139
. labels ( & [ "T-libs" , "regression-from-stable-to-stable" ] )
@@ -150,24 +158,24 @@ impl Generator {
150
158
}
151
159
152
160
pub fn error_handling_pg_agenda ( mut self ) -> Result < String > {
153
- IssueQuery :: new ( "Nominated" )
161
+ GithubQuery :: new ( "Nominated" )
154
162
. labels ( & [ "PG-error-handling" , "I-nominated" ] )
155
163
. repo ( "rust-lang/rust" )
156
164
. repo ( "rust-lang/project-error-handling" )
157
165
. write ( & mut self ) ?;
158
166
159
- IssueQuery :: new ( "PG Error Handling" )
167
+ GithubQuery :: new ( "PG Error Handling" )
160
168
. labels ( & [ "PG-error-handling" ] )
161
169
. repo ( "rust-lang/rust" )
162
170
. repo ( "rust-lang/project-error-handling" )
163
171
. write ( & mut self ) ?;
164
172
165
- IssueQuery :: new ( "Area Error Handling" )
173
+ GithubQuery :: new ( "Area Error Handling" )
166
174
. labels ( & [ "A-error-handling" ] )
167
175
. repo ( "rust-lang/rust" )
168
176
. write ( & mut self ) ?;
169
177
170
- IssueQuery :: new ( "PG Error Handling" )
178
+ GithubQuery :: new ( "PG Error Handling" )
171
179
. repo ( "rust-lang/project-error-handling" )
172
180
. write ( & mut self ) ?;
173
181
@@ -348,18 +356,83 @@ impl Generator {
348
356
}
349
357
}
350
358
351
- struct IssueQuery {
359
+ #[ derive( Clone , Copy ) ]
360
+ #[ allow( dead_code) ]
361
+ enum Sort {
362
+ Newest ,
363
+ Oldest ,
364
+ MostCommented ,
365
+ LeastCommented ,
366
+ MostRecentlyUpdated ,
367
+ LeastRecentlyUpdated ,
368
+ }
369
+
370
+ impl Sort {
371
+ fn api_str ( & self ) -> & ' static str {
372
+ match self {
373
+ Sort :: Newest => "&sort=created&direction=desc" ,
374
+ Sort :: Oldest => "&sort=created&direction=asc" ,
375
+ Sort :: MostCommented => "&sort=comments&direction=asc" ,
376
+ Sort :: LeastCommented => "&sort=comments&direction=desc" ,
377
+ Sort :: MostRecentlyUpdated => "&sort=updated&direction=desc" ,
378
+ Sort :: LeastRecentlyUpdated => "&sort=updated&direction=asc" ,
379
+ }
380
+ }
381
+
382
+ fn web_ui_str ( & self ) -> & ' static str {
383
+ match self {
384
+ Sort :: Newest => "+sort:created-desc" ,
385
+ Sort :: Oldest => "+sort:created-asc" ,
386
+ Sort :: MostCommented => "+sort:comments-desc" ,
387
+ Sort :: LeastCommented => "+sort:comments-asc" ,
388
+ Sort :: MostRecentlyUpdated => "+sort:updated-desc" ,
389
+ Sort :: LeastRecentlyUpdated => "+sort:updated-asc" ,
390
+ }
391
+ }
392
+ }
393
+
394
+ struct GithubQuery {
352
395
name : & ' static str ,
353
396
labels : Vec < & ' static [ & ' static str ] > ,
354
397
repos : Vec < & ' static str > ,
398
+ sort : Option < Sort > ,
399
+ count : Option < usize > ,
400
+ state : State ,
401
+ }
402
+
403
+ enum State {
404
+ Open ,
405
+ Closed ,
406
+ Any ,
355
407
}
356
408
357
- impl IssueQuery {
409
+ impl State {
410
+ fn api_str ( & self ) -> & ' static str {
411
+ match self {
412
+ State :: Open => "&state=open" ,
413
+ State :: Closed => "&state=closed" ,
414
+ State :: Any => "&state=all" ,
415
+ }
416
+ }
417
+
418
+ fn web_ui_str ( & self ) -> & ' static str {
419
+ match self {
420
+ State :: Open => "+is:open" ,
421
+ State :: Closed => "+is:closed" ,
422
+ State :: Any => "" ,
423
+ }
424
+ }
425
+ }
426
+
427
+ impl GithubQuery {
358
428
fn new ( name : & ' static str ) -> Self {
359
429
Self {
360
430
name,
361
431
labels : vec ! [ ] ,
362
432
repos : vec ! [ ] ,
433
+ sort : None ,
434
+ count : None ,
435
+ state : State :: Open ,
363
436
}
364
437
}
365
438
@@ -373,6 +446,21 @@ impl IssueQuery {
373
446
self
374
447
}
375
448
449
+ fn sort ( & mut self , sort : Sort ) -> & mut Self {
450
+ self . sort = Some ( sort) ;
451
+ self
452
+ }
453
+
454
+ fn take ( & mut self , count : usize ) -> & mut Self {
455
+ self . count = Some ( count) ;
456
+ self
457
+ }
458
+
459
+ fn state ( & mut self , state : State ) -> & mut Self {
460
+ self . state = state;
461
+ self
462
+ }
463
+
376
464
fn write ( & mut self , generator : & mut Generator ) -> Result < ( ) > {
377
465
writeln ! ( generator. agenda, "### {}" , self . name) ?;
378
466
writeln ! ( generator. agenda, ) ?;
@@ -382,8 +470,21 @@ impl IssueQuery {
382
470
for repo in & self . repos {
383
471
for labels in & self . labels {
384
472
let cs_labels = labels. join ( "," ) ;
385
- let endpoint = format ! ( "repos/{}/issues?labels={}" , repo, cs_labels) ;
386
- let issues = generator. dedup ( github_api ( & endpoint) ?) ;
473
+ let mut endpoint = format ! ( "repos/{}/issues?labels={}" , repo, cs_labels) ;
474
+
475
+ endpoint += self . state . api_str ( ) ;
476
+
477
+ if let Some ( sort) = self . sort {
478
+ endpoint += sort. api_str ( ) ;
479
+ }
480
+
481
+ let mut issues = github_api ( & endpoint) ?;
482
+
483
+ if let Some ( count) = self . count {
484
+ issues. truncate ( count) ;
485
+ }
486
+
487
+ let issues = generator. dedup ( issues) ;
387
488
388
489
if issues. is_empty ( ) {
389
490
continue ;
@@ -393,13 +494,23 @@ impl IssueQuery {
393
494
. iter ( )
394
495
. map ( |label| format ! ( "label:{}" , label) )
395
496
. join ( "+" ) ;
497
+
498
+ let mut url = format ! ( "https://github.com/{}/issues?q={}" , repo, url_labels) ;
499
+
500
+ url += self . state . web_ui_str ( ) ;
501
+
502
+ if let Some ( sort) = self . sort {
503
+ url += sort. web_ui_str ( ) ;
504
+ }
505
+
506
+
396
507
writeln ! (
397
508
generator. agenda,
398
- "- [{} `{repo}` `{labels}` items](https://github.com/{repo}/issues?q=is:open+{url_labels })" ,
509
+ "- [{} `{repo}` `{labels}` items]({url })" ,
399
510
issues. len( ) ,
400
511
repo = repo,
401
512
labels = labels. join( "` `" ) ,
402
- url_labels = url_labels ,
513
+ url = url ,
403
514
) ?;
404
515
generator. write_issues ( & issues) ?;
405
516
@@ -450,8 +561,9 @@ fn escape(v: &str) -> String {
450
561
}
451
562
452
563
fn github_api < T : DeserializeOwned > ( endpoint : & str ) -> Result < T > {
564
+ let url = format ! ( "https://api.github.com/{}" , endpoint) ;
453
565
let mut client = reqwest:: blocking:: Client :: new ( )
454
- . get ( & format ! ( "https://api.github.com/{}" , endpoint ) )
566
+ . get ( & url )
455
567
. header ( USER_AGENT , "rust-lang libs agenda maker" ) ;
456
568
if let Ok ( token) = std:: env:: var ( "GITHUB_TOKEN" ) {
457
569
client = client. header ( AUTHORIZATION , format ! ( "token {}" , token) ) ;
0 commit comments