hive-forge: add pr-commits verb (PR commit list, survives rebase-rewritten shas)
This commit is contained in:
parent
3cec0a69eb
commit
9f9c1167ae
3 changed files with 55 additions and 0 deletions
|
|
@ -57,6 +57,10 @@ enum Verb {
|
||||||
IssueEdit(verbs::issue_edit::Args),
|
IssueEdit(verbs::issue_edit::Args),
|
||||||
/// Print key fields of a PR as JSON.
|
/// Print key fields of a PR as JSON.
|
||||||
Pr(verbs::pr::Args),
|
Pr(verbs::pr::Args),
|
||||||
|
/// List a PR's commits as JSON (sha, message, author date, author).
|
||||||
|
/// Survives rebase-rewritten shas — message + author date let a
|
||||||
|
/// caller match the rows against linear `main` history.
|
||||||
|
PrCommits(verbs::pr_commits::Args),
|
||||||
/// Create a pull request. Prints the PR URL on success.
|
/// Create a pull request. Prints the PR URL on success.
|
||||||
PrCreate(verbs::pr_create::Args),
|
PrCreate(verbs::pr_create::Args),
|
||||||
/// Post a comment on an issue or PR.
|
/// Post a comment on an issue or PR.
|
||||||
|
|
@ -146,6 +150,7 @@ fn main() -> Result<()> {
|
||||||
Verb::IssueCreate(a) => verbs::issue_create::run(&client, a),
|
Verb::IssueCreate(a) => verbs::issue_create::run(&client, a),
|
||||||
Verb::IssueEdit(a) => verbs::issue_edit::run(&client, a),
|
Verb::IssueEdit(a) => verbs::issue_edit::run(&client, a),
|
||||||
Verb::Pr(a) => verbs::pr::run(&client, a),
|
Verb::Pr(a) => verbs::pr::run(&client, a),
|
||||||
|
Verb::PrCommits(a) => verbs::pr_commits::run(&client, a),
|
||||||
Verb::PrCreate(a) => verbs::pr_create::run(&client, a),
|
Verb::PrCreate(a) => verbs::pr_create::run(&client, a),
|
||||||
Verb::Comment(a) => verbs::comment::run(&client, a),
|
Verb::Comment(a) => verbs::comment::run(&client, a),
|
||||||
Verb::Comments(a) => verbs::comments::run(&client, a),
|
Verb::Comments(a) => verbs::comments::run(&client, a),
|
||||||
|
|
|
||||||
|
|
@ -24,6 +24,7 @@ pub mod lint;
|
||||||
pub mod list;
|
pub mod list;
|
||||||
pub mod milestone;
|
pub mod milestone;
|
||||||
pub mod pr;
|
pub mod pr;
|
||||||
|
pub mod pr_commits;
|
||||||
pub mod pr_create;
|
pub mod pr_create;
|
||||||
pub mod pr_merge;
|
pub mod pr_merge;
|
||||||
pub mod pr_reviews;
|
pub mod pr_reviews;
|
||||||
|
|
|
||||||
49
hive-forge/src/verbs/pr_commits.rs
Normal file
49
hive-forge/src/verbs/pr_commits.rs
Normal file
|
|
@ -0,0 +1,49 @@
|
||||||
|
//! `pr-commits <number> [repo]` — list a PR's commits as JSON
|
||||||
|
//! (sha, message, author date, author login), paginated.
|
||||||
|
//!
|
||||||
|
//! The forge stores a PR's commits against its branch ref, so this
|
||||||
|
//! returns them even for a PR whose shas were rewritten by a rebase
|
||||||
|
//! merge. The commit message and author date survive a rebase
|
||||||
|
//! unchanged, so a caller can match these rows against the linear
|
||||||
|
//! `main` history to recover the merged-final commits when the PR's
|
||||||
|
//! recorded shas no longer resolve.
|
||||||
|
|
||||||
|
use anyhow::Result;
|
||||||
|
use clap::Args as ClapArgs;
|
||||||
|
use serde_json::json;
|
||||||
|
|
||||||
|
use crate::client::Client;
|
||||||
|
use crate::verbs::print_json;
|
||||||
|
|
||||||
|
/// Page cap for the commit list. Forgejo serves up to 50 commits per
|
||||||
|
/// page; 40 pages (2000 commits) is far beyond any real PR.
|
||||||
|
const MAX_PAGES: u32 = 40;
|
||||||
|
|
||||||
|
#[derive(ClapArgs)]
|
||||||
|
pub struct Args {
|
||||||
|
/// PR number.
|
||||||
|
number: u64,
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn run(client: &Client, args: Args) -> Result<()> {
|
||||||
|
let repo = client.repo();
|
||||||
|
let commits = client.get_json_all(
|
||||||
|
&format!("/repos/{repo}/pulls/{}/commits", args.number),
|
||||||
|
MAX_PAGES,
|
||||||
|
)?;
|
||||||
|
let trimmed: Vec<_> = commits
|
||||||
|
.iter()
|
||||||
|
.map(|c| {
|
||||||
|
let commit = c.get("commit");
|
||||||
|
json!({
|
||||||
|
"sha": c.get("sha"),
|
||||||
|
"message": commit.and_then(|x| x.get("message")),
|
||||||
|
"author_date": commit
|
||||||
|
.and_then(|x| x.get("author"))
|
||||||
|
.and_then(|a| a.get("date")),
|
||||||
|
"author": c.get("author").and_then(|u| u.get("login")),
|
||||||
|
})
|
||||||
|
})
|
||||||
|
.collect();
|
||||||
|
print_json(&json!(trimmed))
|
||||||
|
}
|
||||||
Loading…
Reference in a new issue