Skip to content

Commit 7dd240d

Browse files
authored
Merge pull request #29 from yaahc/backport-and-tracking
Add tracking issue search and include closed backports
2 parents f59974a + 6019303 commit 7dd240d

File tree

1 file changed

+134
-26
lines changed

1 file changed

+134
-26
lines changed

tools/agenda-generator/src/generator.rs

Lines changed: 134 additions & 26 deletions
Original file line numberDiff line numberDiff line change
@@ -37,24 +37,31 @@ impl Generator {
3737

3838
self.fcps(String::from("T-libs-api"))?;
3939

40-
IssueQuery::new("Nominated")
40+
GithubQuery::new("Nominated")
4141
.labels(&["T-libs-api", "I-nominated"])
4242
.repo("rust-lang/libs-team")
4343
.repo("rust-lang/rust")
4444
.repo("rust-lang/rfcs")
4545
.write(&mut self)?;
4646

47-
IssueQuery::new("Waiting on team")
47+
GithubQuery::new("Waiting on team")
4848
.labels(&["T-libs-api", "S-waiting-on-team"])
4949
.repo("rust-lang/rust")
5050
.repo("rust-lang/rfcs")
5151
.write(&mut self)?;
5252

53-
IssueQuery::new("Needs decision")
53+
GithubQuery::new("Needs decision")
5454
.labels(&["T-libs-api", "I-needs-decision"])
5555
.repo("rust-lang/rust")
5656
.write(&mut self)?;
5757

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+
5865
writeln!(&mut self.agenda,
5966
"## Actions
6067
@@ -91,41 +98,38 @@ impl Generator {
9198

9299
self.fcps(String::from("T-libs"))?;
93100

94-
IssueQuery::new("Critical")
101+
GithubQuery::new("Critical")
95102
.labels(&["T-libs", "P-critical"])
96103
.labels(&["T-libs-api", "P-critical"])
97104
.repo("rust-lang/rust")
98105
.repo("rust-lang/rfcs")
99106
.write(&mut self)?;
100107

101-
IssueQuery::new("Prioritization Requested")
108+
GithubQuery::new("Prioritization Requested")
102109
.labels(&["T-libs", "I-prioritize"])
103110
.labels(&["T-libs-api", "I-prioritize"])
104111
.repo("rust-lang/rust")
105112
.repo("rust-lang/rfcs")
106113
.write(&mut self)?;
107114

108-
IssueQuery::new("Nominated")
115+
GithubQuery::new("Nominated")
109116
.labels(&["T-libs", "I-nominated"])
110117
.repo("rust-lang/rust")
111118
.repo("rust-lang/rfcs")
112119
.repo("rust-lang/libs-team")
113120
.write(&mut self)?;
114121

115-
IssueQuery::new("Backports")
122+
GithubQuery::new("Backports")
116123
.labels(&["T-libs", "stable-nominated"])
117124
.labels(&["T-libs-api", "stable-nominated"])
118-
.labels(&["T-libs", "stable-accepted"])
119-
.labels(&["T-libs-api", "stable-accepted"])
120125
.labels(&["T-libs", "beta-nominated"])
121126
.labels(&["T-libs-api", "beta-nominated"])
122-
.labels(&["T-libs", "beta-accepted"])
123-
.labels(&["T-libs-api", "beta-accepted"])
127+
.state(State::Any)
124128
.repo("rust-lang/rust")
125129
.repo("rust-lang/rfcs")
126130
.write(&mut self)?;
127131

128-
IssueQuery::new("Regressions")
132+
GithubQuery::new("Regressions")
129133
.labels(&["T-libs", "regression-untriaged"])
130134
.labels(&["T-libs-api", "regression-untriaged"])
131135
.labels(&["T-libs", "regression-from-stable-to-stable"])
@@ -150,24 +154,24 @@ impl Generator {
150154
}
151155

152156
pub fn error_handling_pg_agenda(mut self) -> Result<String> {
153-
IssueQuery::new("Nominated")
157+
GithubQuery::new("Nominated")
154158
.labels(&["PG-error-handling", "I-nominated"])
155159
.repo("rust-lang/rust")
156160
.repo("rust-lang/project-error-handling")
157161
.write(&mut self)?;
158162

159-
IssueQuery::new("PG Error Handling")
163+
GithubQuery::new("PG Error Handling")
160164
.labels(&["PG-error-handling"])
161165
.repo("rust-lang/rust")
162166
.repo("rust-lang/project-error-handling")
163167
.write(&mut self)?;
164168

165-
IssueQuery::new("Area Error Handling")
169+
GithubQuery::new("Area Error Handling")
166170
.labels(&["A-error-handling"])
167171
.repo("rust-lang/rust")
168172
.write(&mut self)?;
169173

170-
IssueQuery::new("PG Error Handling")
174+
GithubQuery::new("PG Error Handling")
171175
.repo("rust-lang/project-error-handling")
172176
.write(&mut self)?;
173177

@@ -342,24 +346,89 @@ impl Generator {
342346
Ok(())
343347
}
344348

345-
fn dedup(&mut self, mut issues: Vec<Issue>) -> Vec<Issue> {
346-
issues.retain(|issue| self.seen.insert(issue.html_url.clone()));
347-
issues
349+
fn dedup(&mut self, issues: Vec<Issue>) -> impl Iterator<Item = Issue> + '_ {
350+
issues.into_iter().filter(move |issue| self.seen.insert(issue.html_url.clone()))
351+
}
352+
}
353+
354+
#[derive(Clone, Copy)]
355+
#[allow(dead_code)]
356+
enum Sort {
357+
Newest,
358+
Oldest,
359+
MostCommented,
360+
LeastCommented,
361+
MostRecentlyUpdated,
362+
LeastRecentlyUpdated,
363+
}
364+
365+
impl Sort {
366+
fn api_str(&self) -> &'static str {
367+
match self {
368+
Sort::Newest => "&sort=created&direction=desc",
369+
Sort::Oldest => "&sort=created&direction=asc",
370+
Sort::MostCommented => "&sort=comments&direction=asc",
371+
Sort::LeastCommented => "&sort=comments&direction=desc",
372+
Sort::MostRecentlyUpdated => "&sort=updated&direction=desc",
373+
Sort::LeastRecentlyUpdated => "&sort=updated&direction=asc",
374+
}
375+
}
376+
377+
fn web_ui_str(&self) -> &'static str {
378+
match self {
379+
Sort::Newest => "+sort:created-desc",
380+
Sort::Oldest => "+sort:created-asc",
381+
Sort::MostCommented => "+sort:comments-desc",
382+
Sort::LeastCommented => "+sort:comments-asc",
383+
Sort::MostRecentlyUpdated => "+sort:updated-desc",
384+
Sort::LeastRecentlyUpdated => "+sort:updated-asc",
385+
}
348386
}
349387
}
350388

351-
struct IssueQuery {
389+
struct GithubQuery {
352390
name: &'static str,
353391
labels: Vec<&'static [&'static str]>,
354392
repos: Vec<&'static str>,
393+
sort: Option<Sort>,
394+
count: Option<usize>,
395+
state: State,
396+
}
397+
398+
#[allow(dead_code)]
399+
enum State {
400+
Open,
401+
Closed,
402+
Any,
403+
}
404+
405+
impl State {
406+
fn api_str(&self) -> &'static str {
407+
match self {
408+
State::Open => "&state=open",
409+
State::Closed => "&state=closed",
410+
State::Any => "&state=all",
411+
}
412+
}
413+
414+
fn web_ui_str(&self) -> &'static str {
415+
match self {
416+
State::Open => "+is:open",
417+
State::Closed => "+is:closed",
418+
State::Any => "",
419+
}
420+
}
355421
}
356422

357-
impl IssueQuery {
423+
impl GithubQuery {
358424
fn new(name: &'static str) -> Self {
359425
Self {
360426
name,
361427
labels: vec![],
362428
repos: vec![],
429+
sort: None,
430+
count: None,
431+
state: State::Open,
363432
}
364433
}
365434

@@ -373,6 +442,21 @@ impl IssueQuery {
373442
self
374443
}
375444

445+
fn sort(&mut self, sort: Sort) -> &mut Self {
446+
self.sort = Some(sort);
447+
self
448+
}
449+
450+
fn take(&mut self, count: usize) -> &mut Self {
451+
self.count = Some(count);
452+
self
453+
}
454+
455+
fn state(&mut self, state: State) -> &mut Self {
456+
self.state = state;
457+
self
458+
}
459+
376460
fn write(&mut self, generator: &mut Generator) -> Result<()> {
377461
writeln!(generator.agenda, "### {}", self.name)?;
378462
writeln!(generator.agenda,)?;
@@ -382,8 +466,21 @@ impl IssueQuery {
382466
for repo in &self.repos {
383467
for labels in &self.labels {
384468
let cs_labels = labels.join(",");
385-
let endpoint = format!("repos/{}/issues?labels={}", repo, cs_labels);
386-
let issues = generator.dedup(github_api(&endpoint)?);
469+
let mut endpoint = format!("repos/{}/issues?labels={}", repo, cs_labels);
470+
471+
endpoint += self.state.api_str();
472+
473+
if let Some(sort) = self.sort {
474+
endpoint += sort.api_str();
475+
}
476+
477+
let issues = github_api(&endpoint)?;
478+
let issues = generator.dedup(issues);
479+
let issues: Vec<_> = if let Some(count) = self.count {
480+
issues.take(count).collect()
481+
} else {
482+
issues.collect()
483+
};
387484

388485
if issues.is_empty() {
389486
continue;
@@ -393,13 +490,23 @@ impl IssueQuery {
393490
.iter()
394491
.map(|label| format!("label:{}", label))
395492
.join("+");
493+
494+
let mut url = format!("https://github.com/{}/issues?q={}", repo, url_labels);
495+
496+
url += self.state.web_ui_str();
497+
498+
if let Some(sort) = self.sort {
499+
url += sort.web_ui_str();
500+
}
501+
502+
396503
writeln!(
397504
generator.agenda,
398-
"- [{} `{repo}` `{labels}` items](https://github.com/{repo}/issues?q=is:open+{url_labels})",
505+
"- [{} `{repo}` `{labels}` items]({url})",
399506
issues.len(),
400507
repo = repo,
401508
labels = labels.join("` `"),
402-
url_labels = url_labels,
509+
url = url,
403510
)?;
404511
generator.write_issues(&issues)?;
405512

@@ -450,8 +557,9 @@ fn escape(v: &str) -> String {
450557
}
451558

452559
fn github_api<T: DeserializeOwned>(endpoint: &str) -> Result<T> {
560+
let url = format!("https://api.github.com/{}", endpoint);
453561
let mut client = reqwest::blocking::Client::new()
454-
.get(&format!("https://api.github.com/{}", endpoint))
562+
.get(&url)
455563
.header(USER_AGENT, "rust-lang libs agenda maker");
456564
if let Ok(token) = std::env::var("GITHUB_TOKEN") {
457565
client = client.header(AUTHORIZATION, format!("token {}", token));

0 commit comments

Comments
 (0)