Skip to main content

codeberg_cli/actions/pull_request/
comment.rs

1use super::display_pull_request;
2use crate::actions::text_manipulation::select_prompt_for;
3use crate::render::json::JsonToStdout;
4use crate::render::option::option_display;
5use crate::render::spinner::spin_until_ready;
6use crate::render::ui::fuzzy_select_with_key;
7use crate::types::context::BergContext;
8use crate::types::git::OwnerRepo;
9use crate::{actions::GlobalArgs, types::output::OutputMode};
10use clap::Parser;
11use forgejo_api::structs::{CreateIssueCommentOption, PullRequest, RepoListPullRequestsQuery};
12use miette::{Context, IntoDiagnostic};
13
14/// Add comment to selected pull request
15#[derive(Parser, Debug)]
16pub struct CommentPullRequestArgs {}
17
18impl CommentPullRequestArgs {
19    pub async fn run(self, global_args: GlobalArgs) -> miette::Result<()> {
20        let ctx = BergContext::new(self, global_args).await?;
21
22        let OwnerRepo { owner, repo } = ctx.owner_repo()?;
23        let pull_request = select_pull_request(&ctx).await?;
24        let pull_request_id = pull_request
25            .id
26            .context("Selected milestone doesn't have an ID")?;
27
28        let options = create_options(&ctx, &pull_request).await?;
29
30        let comment = ctx
31            .client
32            .issue_create_comment(owner.as_str(), repo.as_str(), pull_request_id, options)
33            .await
34            .into_diagnostic()?;
35
36        match ctx.global_args.output_mode {
37            OutputMode::Pretty => {
38                tracing::debug!("{comment:?}");
39            }
40            OutputMode::Json => comment.print_json()?,
41        }
42
43        Ok(())
44    }
45}
46
47async fn create_options(
48    ctx: &BergContext<CommentPullRequestArgs>,
49    pull_request: &PullRequest,
50) -> miette::Result<CreateIssueCommentOption> {
51    let body = ctx.editor_for(
52        "a comment",
53        format!(
54            "Write a comment for pull_request \"{}\"",
55            option_display(&pull_request.title)
56        )
57        .as_str(),
58    )?;
59
60    Ok(CreateIssueCommentOption {
61        body,
62        updated_at: None,
63    })
64}
65
66async fn select_pull_request(
67    ctx: &BergContext<CommentPullRequestArgs>,
68) -> miette::Result<PullRequest> {
69    let OwnerRepo { owner, repo } = ctx.owner_repo()?;
70    let (_, pull_requests_list) = spin_until_ready(
71        ctx.client
72            .repo_list_pull_requests(
73                owner.as_str(),
74                repo.as_str(),
75                RepoListPullRequestsQuery::default(),
76            )
77            .send(),
78    )
79    .await
80    .into_diagnostic()?;
81
82    fuzzy_select_with_key(
83        &pull_requests_list,
84        select_prompt_for("pull request"),
85        display_pull_request,
86    )
87    .cloned()
88}