codeberg_cli/actions/release/
list.rs1use forgejo_api::structs::{Release, RepoListReleasesQuery};
2
3use crate::actions::GeneralArgs;
4use crate::render::json::JsonToStdout;
5use crate::render::option::option_display;
6use crate::render::spinner::spin_until_ready;
7use crate::types::context::BergContext;
8use crate::types::git::OwnerRepo;
9
10use clap::Parser;
11
12#[derive(Parser, Debug)]
14pub struct ListReleaseArgs {
15 #[arg(short, long, value_name = "N")]
17 pub count: Option<u32>,
18}
19
20impl ListReleaseArgs {
21 pub async fn run(self, general_args: GeneralArgs) -> anyhow::Result<()> {
22 let ctx = BergContext::new(self, general_args).await?;
23 let OwnerRepo { repo, owner } = ctx.owner_repo()?;
24 let (_, releases_list) = spin_until_ready(ctx.client.repo_list_releases(
25 owner.as_str(),
26 repo.as_str(),
27 RepoListReleasesQuery {
28 page: ctx.args.count.as_ref().map(|_| 1),
29 limit: ctx.args.count,
30 ..Default::default()
31 },
32 ))
33 .await?;
34
35 match general_args.output_mode {
36 crate::types::output::OutputMode::Pretty => {
37 present_releases_list(&ctx, releases_list);
38 }
39 crate::types::output::OutputMode::Json => {
40 releases_list.print_json()?;
41 }
42 }
43
44 Ok(())
45 }
46}
47
48fn present_releases_list(ctx: &BergContext<ListReleaseArgs>, releases: Vec<Release>) {
49 let releases_empty = releases.is_empty();
50
51 let mut table = ctx.make_table().add_table((!releases_empty).then(|| {
52 let mut inner_table = ctx.make_table();
53 inner_table
54 .set_header(vec!["ID", "Name", "Tag", "Published At"])
55 .add_rows(releases.into_iter().map(|release| {
56 let Release {
57 id,
58 name,
59 tag_name,
60 published_at,
61 ..
62 } = release;
63 vec![
64 option_display(&id),
65 option_display(&name),
66 option_display(&tag_name),
67 option_display(&published_at),
68 ]
69 }));
70 inner_table
71 }));
72
73 table.set_header(vec![format!(
74 "Releases{}",
75 if releases_empty {
76 " (empty)"
77 } else {
78 Default::default()
79 }
80 )]);
81
82 println!("{table}", table = table.show());
83}