codeberg_cli/actions/pull_request/
comment.rs

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
use super::display_pull_request;
use crate::actions::text_manipulation::{edit_prompt_for, select_prompt_for};
use crate::actions::GeneralArgs;
use crate::render::option::option_display;
use crate::render::spinner::spin_until_ready;
use crate::render::ui::fuzzy_select_with_key;
use crate::types::context::BergContext;
use crate::types::git::OwnerRepo;
use anyhow::Context;
use clap::Parser;
use forgejo_api::structs::{CreateIssueCommentOption, PullRequest, RepoListPullRequestsQuery};

/// Add comment to selected pull request
#[derive(Parser, Debug)]
pub struct CommentPullRequestArgs {}

impl CommentPullRequestArgs {
    pub async fn run(self, general_args: GeneralArgs) -> anyhow::Result<()> {
        let _ = general_args;
        let ctx = BergContext::new(self).await?;

        let OwnerRepo { owner, repo } = ctx.owner_repo()?;
        let pull_request = select_pull_request(&ctx).await?;
        let pull_request_id = pull_request
            .id
            .context("Selected milestone doesn't have an ID")?;

        let options = create_options(&ctx, &pull_request).await?;

        let comment = ctx
            .client
            .issue_create_comment(owner.as_str(), repo.as_str(), pull_request_id, options)
            .await?;

        tracing::debug!("{comment:?}");

        Ok(())
    }
}

async fn create_options(
    _ctx: &BergContext<CommentPullRequestArgs>,
    pull_request: &PullRequest,
) -> anyhow::Result<CreateIssueCommentOption> {
    let body = inquire::Editor::new(edit_prompt_for("a comment").as_str())
        .with_predefined_text(
            format!(
                "Write a comment for pull_request \"{}\"",
                option_display(&pull_request.title)
            )
            .as_str(),
        )
        .prompt()?;

    Ok(CreateIssueCommentOption {
        body,
        updated_at: None,
    })
}

async fn select_pull_request(
    ctx: &BergContext<CommentPullRequestArgs>,
) -> anyhow::Result<PullRequest> {
    let OwnerRepo { owner, repo } = ctx.owner_repo()?;
    let pull_requests_list = spin_until_ready(ctx.client.repo_list_pull_requests(
        owner.as_str(),
        repo.as_str(),
        RepoListPullRequestsQuery::default(),
    ))
    .await?;

    fuzzy_select_with_key(
        &pull_requests_list,
        select_prompt_for("pull request"),
        display_pull_request,
    )
    .cloned()
}