Skip to content

Commit 37cce34

Browse files
committed
Add new range-diff endpoint for full ranges
1 parent ccd848f commit 37cce34

File tree

2 files changed

+89
-0
lines changed

2 files changed

+89
-0
lines changed

src/gh_range_diff.rs

Lines changed: 85 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -141,6 +141,91 @@ pub async fn gh_range_diff(
141141
)
142142
}
143143

144+
/// Compute and renders an emulated `git range-diff` between two pushes (old and new).
145+
///
146+
/// - `oldbasehead` is `OLDBASE..OLDHEAD`
147+
/// - `newbasehead` is `NEWBASE..NEWHEAD`
148+
pub async fn gh_ranges_diff(
149+
Path((owner, repo, oldbasehead, newbasehead)): Path<(String, String, String, String)>,
150+
State(ctx): State<Arc<Context>>,
151+
host: Host,
152+
) -> axum::response::Result<impl IntoResponse, AppError> {
153+
let Some((oldbase, oldhead)) = oldbasehead.split_once("..") else {
154+
return Ok((
155+
StatusCode::BAD_REQUEST,
156+
HeaderMap::new(),
157+
format!("`{oldbasehead}` is not in the form `base..head`"),
158+
));
159+
};
160+
161+
let Some((newbase, newhead)) = newbasehead.split_once("..") else {
162+
return Ok((
163+
StatusCode::BAD_REQUEST,
164+
HeaderMap::new(),
165+
format!("`{newbasehead}` is not in the form `base..head`"),
166+
));
167+
};
168+
169+
let repos = ctx
170+
.team
171+
.repos()
172+
.await
173+
.context("unable to retrieve team repos")?;
174+
175+
// Verify that the request org is part of the Rust project
176+
let Some(repos) = repos.repos.get(&owner) else {
177+
return Ok((
178+
StatusCode::BAD_REQUEST,
179+
HeaderMap::new(),
180+
format!("organization `{owner}` is not part of the Rust Project team repos"),
181+
));
182+
};
183+
184+
// Verify that the request repo is part of the Rust project
185+
if !repos.iter().any(|r| r.name == repo) {
186+
return Ok((
187+
StatusCode::BAD_REQUEST,
188+
HeaderMap::new(),
189+
format!("repository `{owner}` is not part of the Rust Project team repos"),
190+
));
191+
}
192+
193+
let issue_repo = github::IssueRepository {
194+
organization: owner.to_string(),
195+
repository: repo.to_string(),
196+
};
197+
198+
// Get the comparison between the oldbase..oldhead
199+
let old = async {
200+
ctx.github
201+
.compare(&issue_repo, &oldbase, oldhead)
202+
.await
203+
.with_context(|| {
204+
format!("failed to retrive the comparison between {oldbase} and {oldhead}")
205+
})
206+
};
207+
208+
// Get the comparison between the newbase..newhead
209+
let new = async {
210+
ctx.github
211+
.compare(&issue_repo, &newbase, newhead)
212+
.await
213+
.with_context(|| {
214+
format!("failed to retrive the comparison between {newbase} and {newhead}")
215+
})
216+
};
217+
218+
// Wait for both futures and early exit if there is an error
219+
let (old, new) = futures::try_join!(old, new)?;
220+
221+
process_old_new(
222+
host,
223+
(&owner, &repo),
224+
(&oldbase, oldhead, old),
225+
(&newbase, newhead, new),
226+
)
227+
}
228+
144229
fn process_old_new(
145230
Host(host): Host,
146231
(owner, repo): (&str, &str),

src/main.rs

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -189,6 +189,10 @@ async fn run_server(addr: SocketAddr) -> anyhow::Result<()> {
189189
"/gh-range-diff/{owner}/{repo}/{basehead}",
190190
get(triagebot::gh_range_diff::gh_range_diff),
191191
)
192+
.route(
193+
"/gh-range-diff/{owner}/{repo}/{oldbasehead}/{newbasehead}",
194+
get(triagebot::gh_range_diff::gh_ranges_diff),
195+
)
192196
.nest("/agenda", agenda)
193197
.route("/bors-commit-list", get(triagebot::bors::bors_commit_list))
194198
.route(

0 commit comments

Comments
 (0)