hive-forge: add comments <number> [--json] [--limit] verb (closes #418)

This commit is contained in:
damocles 2026-05-25 21:09:35 +02:00
commit 9ab241dc24
3 changed files with 66 additions and 0 deletions

View file

@ -55,6 +55,8 @@ enum Verb {
PrCreate(verbs::pr_create::Args),
/// Post a comment on an issue or PR.
Comment(verbs::comment::Args),
/// List all comments on an issue or PR.
Comments(verbs::comments::Args),
/// Print the body (or full JSON) of a single comment by id.
CommentShow(verbs::comment_show::Args),
/// Edit an existing comment by id.
@ -94,6 +96,7 @@ fn main() -> Result<()> {
Verb::Pr(a) => verbs::pr::run(&client, a),
Verb::PrCreate(a) => verbs::pr_create::run(&client, a),
Verb::Comment(a) => verbs::comment::run(&client, a),
Verb::Comments(a) => verbs::comments::run(&client, a),
Verb::CommentShow(a) => verbs::comment_show::run(&client, a),
Verb::CommentEdit(a) => verbs::comment_edit::run(&client, a),
Verb::Assign(a) => verbs::assign::run(&client, a),

View file

@ -0,0 +1,62 @@
//! `comments <number> [--json] [--limit N]` — list all comments on
//! an issue or PR. Closes the curl-fallback gap (#418).
use anyhow::Result;
use clap::Args as ClapArgs;
use serde_json::{Value, json};
use crate::client::Client;
use crate::verbs::print_json;
#[derive(ClapArgs)]
pub struct Args {
/// Issue or PR number.
number: u64,
/// Print as JSON array instead of human-readable markdown.
#[arg(long)]
json: bool,
/// Page size (Forgejo caps at 50 by default).
#[arg(long, default_value_t = 50)]
limit: u64,
}
pub fn run(client: &Client, args: Args) -> Result<()> {
let repo = client.repo();
let v = client.get_json(&format!(
"/repos/{repo}/issues/{}/comments?limit={}",
args.number, args.limit
))?;
if args.json {
let trimmed: Vec<Value> = v
.as_array()
.map(|a| {
a.iter()
.map(|c| {
json!({
"id": c.get("id"),
"user": c.get("user").and_then(|u| u.get("login")),
"created_at": c.get("created_at"),
"updated_at": c.get("updated_at"),
"body": c.get("body"),
"url": c.get("html_url"),
})
})
.collect()
})
.unwrap_or_default();
print_json(&Value::Array(trimmed))
} else {
for c in v.as_array().cloned().unwrap_or_default() {
let user = c
.get("user")
.and_then(|u| u.get("login"))
.and_then(Value::as_str)
.unwrap_or("?");
let ts = c.get("created_at").and_then(Value::as_str).unwrap_or("?");
let body = c.get("body").and_then(Value::as_str).unwrap_or("");
println!("**{user} @ {ts}**: {body}");
println!();
}
Ok(())
}
}

View file

@ -10,6 +10,7 @@ pub mod close;
pub mod comment;
pub mod comment_edit;
pub mod comment_show;
pub mod comments;
pub mod diff;
pub mod issue;
pub mod issue_create;