codeberg_cli/actions/release/
list.rs

1use 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/// List all releases in the current repository
13#[derive(Parser, Debug)]
14pub struct ListReleaseArgs {
15    /// Number of releases to be displayed
16    #[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}