codeberg_cli/actions/repo/
list.rs

1use crate::render::json::JsonToStdout;
2use crate::render::option::option_display;
3use crate::render::table::TableWrapper;
4use crate::{actions::GeneralArgs, types::context::BergContext};
5use anyhow::Ok;
6use clap::Parser;
7use clap::ValueEnum;
8use forgejo_api::structs::{Repository, UserCurrentListReposQuery};
9use strum::{Display, EnumIter, EnumString, IntoStaticStr};
10
11/// List user current active repositories
12#[derive(Debug, Parser, Clone, Copy)]
13pub struct RepoListArgs {
14    /// The amount of repositories that should be displayed
15    #[arg(short, long, default_value_t = 19)]
16    pub limit: u32,
17
18    /// Order the displayed repositories by different criteria
19    #[arg(short, long, value_enum, name = "ORDER BY", default_value_t = OrderBy::Name)]
20    pub order_by: OrderBy,
21}
22
23#[derive(
24    Debug,
25    Clone,
26    Copy,
27    Default,
28    PartialEq,
29    Eq,
30    Display,
31    EnumString,
32    ValueEnum,
33    EnumIter,
34    IntoStaticStr,
35)]
36pub enum OrderBy {
37    #[default]
38    Name,
39    Id,
40    Newest,
41    Oldest,
42    Recentupdate,
43    Leastupdate,
44    Reversealphabetically,
45    Alphabetically,
46    Reversesize,
47    Size,
48    Reversegitsize,
49    Gitsize,
50    Reverselfssize,
51    Lfssize,
52    Moststars,
53    Feweststars,
54    Mostforks,
55    Fewestforks,
56}
57
58impl RepoListArgs {
59    pub async fn run(self, general_args: GeneralArgs) -> anyhow::Result<()> {
60        let ctx = BergContext::new(self, general_args).await?;
61
62        let (_, repos) = ctx
63            .client
64            .user_current_list_repos(UserCurrentListReposQuery {
65                limit: Some(ctx.args.limit),
66                order_by: Some(ctx.args.order_by.to_string().to_lowercase()),
67                page: None,
68            })
69            .await?;
70
71        match general_args.output_mode {
72            crate::types::output::OutputMode::Pretty => {
73                present_repos(ctx, repos).await?;
74            }
75            crate::types::output::OutputMode::Json => {
76                repos.print_json()?;
77            }
78        }
79
80        Ok(())
81    }
82}
83
84async fn present_repos(
85    ctx: BergContext<RepoListArgs>,
86    repos: Vec<Repository>,
87) -> anyhow::Result<()> {
88    let mut table: TableWrapper = ctx.make_table();
89
90    table
91        .set_header(vec!["Name", "Description", "Size", "Info", "Updated"])
92        .add_rows(repos.iter().map(|repo| {
93            let Repository {
94                name,
95                description,
96                updated_at,
97                private,
98                archived,
99                fork,
100                size,
101                ..
102            } = repo;
103
104            let repo_visibility = if private.unwrap_or(false) {
105                "Private"
106            } else {
107                "Public"
108            };
109            let is_archived = archived.unwrap_or(false);
110            let is_fork = fork.unwrap_or(false);
111
112            let mut info_arr = vec![repo_visibility];
113
114            if is_archived {
115                info_arr.push("Archived");
116            }
117
118            if is_fork {
119                info_arr.push("Fork");
120            }
121
122            vec![
123                option_display(name),
124                option_display(description),
125                option_display(size),
126                info_arr.join(", "),
127                option_display(updated_at),
128            ]
129        }));
130
131    println!("{tbl}", tbl = table.show());
132
133    Ok(())
134}