codeberg_cli/actions/pull_request/
list.rsuse forgejo_api::structs::{
PullRequest, RepoListPullRequestsQuery, RepoListPullRequestsQueryState,
};
use itertools::Itertools;
use crate::actions::GeneralArgs;
use crate::render::option::{option_debug_display, option_display};
use crate::render::spinner::spin_until_ready;
use crate::types::api::pr_query_sort::{self, PullRequestsQuerySort};
use crate::types::context::BergContext;
use crate::types::api::state_type::ViewStateType;
use crate::types::git::OwnerRepo;
use clap::Parser;
#[derive(Parser, Debug, Clone, Copy)]
pub struct ListPullRequestArgs {
#[arg(short, long, value_name = "N", default_value_t = 5)]
pub count: u32,
#[arg(long, default_value_t = pr_query_sort::PullRequestsQuerySort::Recentupdate)]
pub sort: PullRequestsQuerySort,
#[arg(short, long, default_value_t = ViewStateType::All)]
pub state: ViewStateType,
}
impl ListPullRequestArgs {
pub async fn run(self, general_args: GeneralArgs) -> anyhow::Result<()> {
let _ = general_args;
let ctx = BergContext::new(self, general_args).await?;
let state = match self.state {
ViewStateType::All => RepoListPullRequestsQueryState::All,
ViewStateType::Closed => RepoListPullRequestsQueryState::Closed,
ViewStateType::Open => RepoListPullRequestsQueryState::Open,
};
let query = RepoListPullRequestsQuery {
state: Some(state),
sort: Some(self.sort.into()),
limit: Some(self.count),
..Default::default()
};
let OwnerRepo { repo, owner } = ctx.owner_repo()?;
let pull_requests_list = spin_until_ready(ctx.client.repo_list_pull_requests(
owner.as_str(),
repo.as_str(),
query,
))
.await?;
present_pull_requests_list(&ctx, pull_requests_list);
Ok(())
}
}
fn present_pull_requests_list(
ctx: &BergContext<ListPullRequestArgs>,
pull_requests: Vec<PullRequest>,
) {
let pull_requests_empty = pull_requests.is_empty();
let mut table = ctx.make_table();
table.set_header(vec![format!(
"Pull Requests {}",
pull_requests_empty
.then_some(" (empty)")
.unwrap_or_default()
)]);
let mut inner_table = ctx.make_table();
if !pull_requests_empty {
inner_table
.set_header(vec!["Number", "Status", "Name", "Labels"])
.add_rows(pull_requests.iter().map(|issue| {
let PullRequest {
title,
number,
labels,
state,
..
} = issue;
let labels = option_display(&labels.as_ref().map(|labels| {
if labels.is_empty() {
String::from("x")
} else {
labels
.iter()
.filter_map(|label| label.name.as_ref())
.join(",")
}
}));
vec![
option_display(number),
option_debug_display(state),
option_display(title),
labels,
]
}));
table.add_row(vec![format!(
"{inner_table}",
inner_table = inner_table.show()
)]);
}
println!("{table}", table = table.show());
}