Skip to content

Commit c669644

Browse files
authored
Merge pull request #141 from nikomatsakis/see-also
Implement support for see-also, improve docs
2 parents df1fd73 + f659189 commit c669644

File tree

5 files changed

+133
-43
lines changed

5 files changed

+133
-43
lines changed

.devcontainer/devcontainer.json

Lines changed: 35 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,35 @@
1+
// For format details, see https://aka.ms/devcontainer.json. For config options, see the
2+
// README at: https://github.com/devcontainers/templates/tree/main/src/rust
3+
{
4+
"name": "Rust",
5+
// Or use a Dockerfile or Docker Compose file. More info: https://containers.dev/guide/dockerfile
6+
"image": "mcr.microsoft.com/devcontainers/rust:1-1-bullseye",
7+
"features": {
8+
"ghcr.io/eitsupi/devcontainer-features/mdbook:1": {},
9+
"ghcr.io/guiyomh/features/just:0": {}
10+
}
11+
12+
// Use 'mounts' to make the cargo cache persistent in a Docker Volume.
13+
// "mounts": [
14+
// {
15+
// "source": "devcontainer-cargo-cache-${devcontainerId}",
16+
// "target": "/usr/local/cargo",
17+
// "type": "volume"
18+
// }
19+
// ]
20+
21+
// Features to add to the dev container. More info: https://containers.dev/features.
22+
// "features": {},
23+
24+
// Use 'forwardPorts' to make a list of ports inside the container available locally.
25+
// "forwardPorts": [],
26+
27+
// Use 'postCreateCommand' to run commands after the container is created.
28+
// "postCreateCommand": "rustc --version",
29+
30+
// Configure tool-specific properties.
31+
// "customizations": {},
32+
33+
// Uncomment to connect as root instead. More info: https://aka.ms/dev-containers-non-root.
34+
// "remoteUser": "root"
35+
}

mdbook-goals/src/gh/issues.rs

Lines changed: 38 additions & 22 deletions
Original file line numberDiff line numberDiff line change
@@ -118,6 +118,21 @@ pub fn count_issues_matching_search(
118118
Ok(count_issues)
119119
}
120120

121+
pub fn fetch_issue(repository: &Repository, issue: u64) -> anyhow::Result<ExistingGithubIssue> {
122+
let output = Command::new("gh")
123+
.arg("-R")
124+
.arg(&repository.to_string())
125+
.arg("view")
126+
.arg(&format!("{issue}"))
127+
.arg("--json")
128+
.arg("title,assignees,number,comments,body,state,labels")
129+
.output()?;
130+
131+
let e_i: ExistingGithubIssueJson = serde_json::from_slice(&output.stdout)?;
132+
133+
Ok(ExistingGithubIssue::from(e_i))
134+
}
135+
121136
pub fn list_issue_titles_in_milestone(
122137
repository: &Repository,
123138
timeframe: &str,
@@ -139,28 +154,7 @@ pub fn list_issue_titles_in_milestone(
139154

140155
Ok(existing_issues
141156
.into_iter()
142-
.map(|e_i| {
143-
(
144-
e_i.title,
145-
ExistingGithubIssue {
146-
number: e_i.number,
147-
assignees: e_i.assignees.into_iter().map(|a| a.login).collect(),
148-
comments: e_i
149-
.comments
150-
.into_iter()
151-
.map(|c| ExistingGithubComment {
152-
author: format!("@{}", c.author.login),
153-
body: c.body,
154-
url: c.url,
155-
created_at: c.created_at,
156-
})
157-
.collect(),
158-
body: e_i.body,
159-
state: e_i.state,
160-
labels: e_i.labels,
161-
},
162-
)
163-
})
157+
.map(|e_i| (e_i.title.clone(), ExistingGithubIssue::from(e_i)))
164158
.collect())
165159
}
166160

@@ -296,3 +290,25 @@ impl ExistingGithubComment {
296290
.expect("failed to parse date")
297291
}
298292
}
293+
294+
impl From<ExistingGithubIssueJson> for ExistingGithubIssue {
295+
fn from(e_i: ExistingGithubIssueJson) -> Self {
296+
ExistingGithubIssue {
297+
number: e_i.number,
298+
assignees: e_i.assignees.into_iter().map(|a| a.login).collect(),
299+
comments: e_i
300+
.comments
301+
.into_iter()
302+
.map(|c| ExistingGithubComment {
303+
author: format!("@{}", c.author.login),
304+
body: c.body,
305+
url: c.url,
306+
created_at: c.created_at,
307+
})
308+
.collect(),
309+
body: e_i.body,
310+
state: e_i.state,
311+
labels: e_i.labels,
312+
}
313+
}
314+
}

mdbook-goals/src/json.rs

Lines changed: 47 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -14,7 +14,7 @@ use crate::{
1414
gh::{
1515
issue_id::Repository,
1616
issues::{
17-
count_issues_matching_search, list_issue_titles_in_milestone, CountIssues,
17+
count_issues_matching_search, fetch_issue, list_issue_titles_in_milestone, CountIssues,
1818
ExistingGithubComment, ExistingGithubIssue, ExistingIssueState,
1919
},
2020
},
@@ -131,38 +131,66 @@ struct TrackingIssueUpdate {
131131
///
132132
/// Returns a tuple (completed, total) with the number of completed items and the total number of items.
133133
fn checkboxes(issue: &ExistingGithubIssue) -> anyhow::Result<Progress> {
134-
let mut checkboxes = None;
135-
let mut issues = None;
134+
let mut completed = 0;
135+
let mut total = 0;
136136

137137
for line in issue.body.lines() {
138138
// Does this match TRACKED_ISSUES?
139139
if let Some(c) = re::TRACKED_ISSUES_QUERY.captures(line) {
140-
let repo = Repository::from_str(&c[1])?;
141-
let query = &c[2];
142-
143-
if issues.is_some() {
144-
anyhow::bail!("found multiple search queries for Tracked Issues");
145-
}
140+
let repo = Repository::from_str(&c["repo"])?;
141+
let query = &c["query"];
146142

147143
let CountIssues { open, closed } = count_issues_matching_search(&repo, query)?;
148-
issues = Some((closed, open + closed));
144+
completed += closed;
145+
total += open + closed;
146+
continue;
149147
}
150148

151-
let (checked, total) = checkboxes.unwrap_or((0, 0));
149+
if let Some(c) = re::SEE_ALSO_QUERY.captures(line) {
150+
let issue_urls = c["issues"].split(&[',', ' ']).filter(|s| !s.is_empty());
151+
152+
for issue_url in issue_urls {
153+
let Some(c) = re::SEE_ALSO_ISSUE.captures(issue_url) else {
154+
anyhow::bail!("invalid issue URL `{issue_url}`")
155+
};
156+
let repository = Repository::new(&c["org"], &c["repo"]);
157+
let issue_number = c["issue"].parse::<u64>()?;
158+
let issue = fetch_issue(&repository, issue_number)?;
159+
match checkboxes(&issue)? {
160+
Progress::Binary => {
161+
if issue.state == ExistingIssueState::Closed {
162+
completed += 1;
163+
}
164+
total += 1;
165+
}
166+
167+
Progress::Tracked {
168+
completed: c,
169+
total: t,
170+
} => {
171+
completed += c;
172+
total += t;
173+
}
174+
175+
Progress::Error { message } => {
176+
anyhow::bail!("error parsing {repository}#{issue_number}: {message}")
177+
}
178+
}
179+
}
180+
}
152181

153182
if re::CHECKED_CHECKBOX.is_match(line) {
154-
checkboxes = Some((checked + 1, total + 1));
183+
total += 1;
184+
completed += 1;
155185
} else if re::CHECKBOX.is_match(line) {
156-
checkboxes = Some((checked, total + 1));
186+
total += 1;
157187
}
158188
}
159189

160-
match (checkboxes, issues) {
161-
(Some((completed, total)), None) | (None, Some((completed, total))) => {
162-
Ok(Progress::Tracked { completed, total })
163-
}
164-
(None, None) => Ok(Progress::Binary),
165-
(Some(_), Some(_)) => anyhow::bail!("found both Tracked Issues and checkboxes"),
190+
if total == 0 && completed == 0 {
191+
Ok(Progress::Binary)
192+
} else {
193+
Ok(Progress::Tracked { completed, total })
166194
}
167195
}
168196

mdbook-goals/src/re.rs

Lines changed: 11 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -35,5 +35,15 @@ lazy_static! {
3535

3636
lazy_static! {
3737
pub static ref TRACKED_ISSUES_QUERY: Regex =
38-
Regex::new(r"^\| *Tracked +issues *\| *\[([^ ]*) ([^]]*)\]\(.*\) *\| *$").unwrap();
38+
Regex::new(r"^\| *Tracked +issues *\| *\[(?P<repo>[^ ]*) (?P<query>[^]]*)\]\(.*\) *\| *$")
39+
.unwrap();
40+
}
41+
42+
lazy_static! {
43+
pub static ref SEE_ALSO_QUERY: Regex =
44+
Regex::new(r"^\| *See also *\| (?P<issues>[^, ]+,|[^, ] )+ *\| *$").unwrap();
45+
}
46+
47+
lazy_static! {
48+
pub static ref SEE_ALSO_ISSUE: Regex = Regex::new(r"(?P<org>[^#/]*)/(?P<repo>[^#/]*)#(?P<issue>[0-9]+)|https://github.com/(?P<org>[^#/]*)/(?P<repo>[^#/]*)/issues/(?P<issue>[0-9]+)").unwrap();
3949
}

src/2024h2/Rust-for-SciComp.md

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,8 @@
55
| Owner(s) | @ZuseZ4 |
66
| Teams | [lang], [compiler] |
77
| Status | Accepted |
8-
| Tracking issue | [rust-lang/rust-project-goals#109, rust-lang/rust/issues/124509, rust-lang/rust/issues/124509] |
8+
| Tracking issue | [rust-lang/rust-project-goals#109] |
9+
| Other tracking issues | [rust-lang/rust#124509], [rust-lang/rust#124509] |
910

1011

1112
## Summary

0 commit comments

Comments
 (0)