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