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