77 lines
2.1 KiB
Rust
77 lines
2.1 KiB
Rust
//! `view <number> [repo]` — dump title + body + all comments as
|
|
//! markdown.
|
|
|
|
use anyhow::Result;
|
|
use clap::Args as ClapArgs;
|
|
use forgejo_api::structs::{IssueGetCommentsQuery, StateType};
|
|
|
|
use crate::client::{Client, index};
|
|
use crate::notify;
|
|
|
|
#[derive(ClapArgs)]
|
|
pub struct Args {
|
|
/// Issue or PR number.
|
|
pub(crate) number: u64,
|
|
}
|
|
|
|
pub fn run(client: &Client, args: Args) -> Result<()> {
|
|
let repo = client.repo();
|
|
// Reading the thread clears its unread notification so the
|
|
// read-before-comment guard (in `comment`) lets a reply through.
|
|
notify::mark_read_best_effort(client, repo, args.number);
|
|
let (owner, name) = client.owner_repo()?;
|
|
let issue = client
|
|
.api()
|
|
.issue_get_issue(owner, name, index(args.number)?)
|
|
.send()?;
|
|
let title = issue.title.as_deref().unwrap_or("");
|
|
let body = issue.body.as_deref().unwrap_or("");
|
|
let state = match issue.state {
|
|
Some(StateType::Open) => "open",
|
|
Some(StateType::Closed) => "closed",
|
|
None => "?",
|
|
};
|
|
let user = issue
|
|
.user
|
|
.as_ref()
|
|
.and_then(|u| u.login.as_deref())
|
|
.unwrap_or("?");
|
|
let kind = if issue.pull_request.is_some() {
|
|
"PR"
|
|
} else {
|
|
"issue"
|
|
};
|
|
println!("# {kind} #{} [{state}] by {user}", args.number);
|
|
println!("{title}");
|
|
if !body.is_empty() {
|
|
println!();
|
|
println!("{body}");
|
|
}
|
|
let (_, comments) = client
|
|
.api()
|
|
.issue_get_comments(
|
|
owner,
|
|
name,
|
|
index(args.number)?,
|
|
IssueGetCommentsQuery::default(),
|
|
)
|
|
.page_size(50)
|
|
.send()?;
|
|
if !comments.is_empty() {
|
|
println!();
|
|
println!("---");
|
|
println!("## Comments ({})", comments.len());
|
|
println!();
|
|
for c in &comments {
|
|
let cu = c
|
|
.user
|
|
.as_ref()
|
|
.and_then(|u| u.login.as_deref())
|
|
.unwrap_or("?");
|
|
let cb = c.body.as_deref().unwrap_or("");
|
|
println!("**{cu}**: {cb}");
|
|
println!();
|
|
}
|
|
}
|
|
Ok(())
|
|
}
|