codeberg_cli/actions/repo/
list.rs1use 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#[derive(Debug, Parser, Clone, Copy)]
13pub struct RepoListArgs {
14 #[arg(short, long, default_value_t = 19)]
16 pub limit: u32,
17
18 #[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}