codeberg_cli/actions/repo/
list.rs1use 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#[derive(Debug, Parser, Clone, Copy)]
15pub struct RepoListArgs {
16 #[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}