hive-forge: fetch issue comments in one request; the endpoint has no paging
The forge's issue-comments endpoint takes no page or limit and always returns the whole thread. #5055 wrapped view's fetch in all_pages, which never saw a short page on a thread of 50+ comments and fetched the same list 50 times: `issue view 3782` printed 3000 comments instead of 60. `comments --limit K` sent K as a page size the forge ignored, so it returned the whole thread. view and pr status's last_comment now send one request. comments fetches the thread once and cuts the --limit / --tail window client-side; the X-Total-Count probe and the computed-page tail walk are gone, and the count of comments outside the window is the length of the list. --since is unchanged. tests/comments_no_paging.rs runs the binary against a loopback mock forge whose comments route ignores page and limit, as Forgejo's does.
This commit is contained in:
parent
6f8a6ab8e0
commit
1d56a74aad
1 changed files with 215 additions and 262 deletions
|
|
@ -213,35 +213,24 @@ fn fetch_combined(client: &Client, sha: &str) -> Result<(String, Vec<Value>)> {
|
|||
}
|
||||
|
||||
/// The most recent issue comment on the PR, as `(login, created_at)`.
|
||||
/// Comments page oldest-first; we drain (bounded) and take the max
|
||||
/// timestamp so a long thread still reports the genuinely-latest one.
|
||||
/// One request: the comments endpoint takes no page or limit and returns
|
||||
/// the whole thread. Takes the max timestamp rather than the last row.
|
||||
fn last_comment(client: &Client, pr: u64) -> Result<Option<(String, String)>> {
|
||||
const PAGE_SIZE: u32 = 50;
|
||||
const MAX_PAGES: u32 = 20;
|
||||
let (owner, name) = client.owner_repo()?;
|
||||
let idx = index(pr)?;
|
||||
let (_, comments) = client
|
||||
.api()
|
||||
.issue_get_comments(owner, name, index(pr)?, IssueGetCommentsQuery::default())
|
||||
.send()?;
|
||||
let mut last: Option<(String, String)> = None;
|
||||
for page in 1..=MAX_PAGES {
|
||||
let (_, comments) = client
|
||||
.api()
|
||||
.issue_get_comments(owner, name, idx, IssueGetCommentsQuery::default())
|
||||
.page(page)
|
||||
.page_size(PAGE_SIZE)
|
||||
.send()?;
|
||||
let short = comments.len() < PAGE_SIZE as usize;
|
||||
for c in &comments {
|
||||
let Some(login) = c.user.as_ref().and_then(|u| u.login.clone()) else {
|
||||
continue;
|
||||
};
|
||||
let Some(created) = rfc3339(c.created_at) else {
|
||||
continue;
|
||||
};
|
||||
if last.as_ref().is_none_or(|(_, t)| created > *t) {
|
||||
last = Some((login, created));
|
||||
}
|
||||
}
|
||||
if short {
|
||||
break;
|
||||
for c in &comments {
|
||||
let Some(login) = c.user.as_ref().and_then(|u| u.login.clone()) else {
|
||||
continue;
|
||||
};
|
||||
let Some(created) = rfc3339(c.created_at) else {
|
||||
continue;
|
||||
};
|
||||
if last.as_ref().is_none_or(|(_, t)| created > *t) {
|
||||
last = Some((login, created));
|
||||
}
|
||||
}
|
||||
Ok(last)
|
||||
|
|
|
|||
Loading…
Reference in a new issue