radicle_cli/commands/
ls.rs1mod args;
2
3pub use args::Args;
4
5use radicle::storage::{ReadStorage, RepositoryInfo};
6
7use crate::terminal as term;
8
9use term::Element;
10
11pub fn run(args: Args, ctx: impl term::Context) -> anyhow::Result<()> {
12 let profile = ctx.profile()?;
13 let storage = &profile.storage;
14 let repos = storage.repositories()?;
15 let policy = profile.policies()?;
16 let mut table = term::Table::new(term::TableOptions::bordered());
17 let mut rows = Vec::new();
18
19 if repos.is_empty() {
20 return Ok(());
21 }
22
23 for RepositoryInfo {
24 rid,
25 head,
26 doc,
27 refs,
28 ..
29 } in repos
30 {
31 let refs = match refs {
32 Ok(refs) => refs,
33 Err(_) => {
34 term::warning(format!("Repository {rid} must be migrated by starting your node (e.g. via `rad node start`)."));
35 continue;
36 }
37 };
38
39 if doc.is_public() && args.private {
40 continue;
41 }
42 if !doc.is_public() && args.public {
43 continue;
44 }
45 if refs.is_none() && !args.all && !args.seeded {
46 continue;
47 }
48 let seeded = policy.is_seeding(&rid)?;
49
50 if !seeded && !args.all {
51 continue;
52 }
53 if !seeded && args.seeded {
54 continue;
55 }
56 let proj = match doc.project() {
57 Ok(p) => p,
58 Err(e) => {
59 log::error!(target: "cli", "Error loading project payload for {rid}: {e}");
60 continue;
61 }
62 };
63 let head = term::format::oid(head).into();
64
65 rows.push([
66 term::format::bold(proj.name().to_owned()),
67 term::format::tertiary(rid.urn()),
68 if seeded {
69 term::format::visibility(doc.visibility()).into()
70 } else {
71 term::format::dim("local").into()
72 },
73 term::format::secondary(head),
74 term::format::italic(proj.description().to_owned()),
75 ]);
76 }
77 rows.sort();
78
79 if rows.is_empty() {
80 term::print(term::format::italic("Nothing to show."));
81 } else {
82 table.header([
83 "Name".into(),
84 "RID".into(),
85 "Visibility".into(),
86 "Head".into(),
87 "Description".into(),
88 ]);
89 table.divider();
90 table.extend(rows);
91 table.print();
92 }
93
94 Ok(())
95}