rustic_rs/commands/
repoinfo.rs1use crate::{
4 Application, RUSTIC_APP,
5 helpers::{bytes_size_to_string, table_right_from},
6 repository::Repo,
7 status_err,
8};
9
10use abscissa_core::{Command, Runnable, Shutdown};
11use serde::Serialize;
12
13use anyhow::Result;
14use rustic_core::{IndexInfos, RepoFileInfo, RepoFileInfos};
15
16#[derive(clap::Parser, Command, Debug)]
18pub(crate) struct RepoInfoCmd {
19 #[clap(long)]
21 only_files: bool,
22
23 #[clap(long)]
25 only_index: bool,
26
27 #[clap(long)]
29 json: bool,
30}
31
32impl Runnable for RepoInfoCmd {
33 fn run(&self) {
34 if let Err(err) = RUSTIC_APP
35 .config()
36 .repository
37 .run(|repo| self.inner_run(repo))
38 {
39 status_err!("{}", err);
40 RUSTIC_APP.shutdown(Shutdown::Crash);
41 };
42 }
43}
44
45#[serde_with::apply(Option => #[serde(default, skip_serializing_if = "Option::is_none")])]
49#[derive(Serialize)]
50struct Infos {
51 files: Option<RepoFileInfos>,
52 index: Option<IndexInfos>,
53}
54
55impl RepoInfoCmd {
56 fn inner_run(&self, repo: Repo) -> Result<()> {
57 let config = RUSTIC_APP.config();
58 let infos = Infos {
59 files: (!self.only_index)
60 .then(|| -> Result<_> { Ok(repo.infos_files()?) })
61 .transpose()?,
62 index: (!self.only_files)
63 .then(|| -> Result<_> {
64 Ok(repo
65 .open(&config.repository.credential_opts)?
66 .infos_index()?)
67 })
68 .transpose()?,
69 };
70
71 if self.json {
72 let mut stdout = std::io::stdout();
73 serde_json::to_writer_pretty(&mut stdout, &infos)?;
74 return Ok(());
75 }
76
77 if let Some(file_info) = infos.files {
78 print_file_info("repository files", file_info.repo);
79 if let Some(info) = file_info.repo_hot {
80 print_file_info("hot repository files", info);
81 }
82 }
83
84 if let Some(index_info) = infos.index {
85 print_index_info(index_info);
86 }
87 Ok(())
88 }
89}
90
91pub fn print_file_info(text: &str, info: Vec<RepoFileInfo>) {
98 let mut table = table_right_from(1, ["File type", "Count", "Total Size"]);
99 let mut total_count = 0;
100 let mut total_size = 0;
101 for row in info {
102 _ = table.add_row([
103 format!("{:?}", row.tpe),
104 row.count.to_string(),
105 bytes_size_to_string(row.size),
106 ]);
107 total_count += row.count;
108 total_size += row.size;
109 }
110 println!("{text}");
111 _ = table.add_row([
112 "Total".to_string(),
113 total_count.to_string(),
114 bytes_size_to_string(total_size),
115 ]);
116
117 println!();
118 println!("{table}");
119 println!();
120}
121
122pub fn print_index_info(index_info: IndexInfos) {
128 let mut table = table_right_from(
129 1,
130 ["Blob type", "Count", "Total Size", "Total Size in Packs"],
131 );
132
133 let mut total_count = 0;
134 let mut total_data_size = 0;
135 let mut total_size = 0;
136
137 for blobs in &index_info.blobs {
138 _ = table.add_row([
139 format!("{:?}", blobs.blob_type),
140 blobs.count.to_string(),
141 bytes_size_to_string(blobs.data_size),
142 bytes_size_to_string(blobs.size),
143 ]);
144 total_count += blobs.count;
145 total_data_size += blobs.data_size;
146 total_size += blobs.size;
147 }
148 for blobs in &index_info.blobs_delete {
149 if blobs.count > 0 {
150 _ = table.add_row([
151 format!("{:?} to delete", blobs.blob_type),
152 blobs.count.to_string(),
153 bytes_size_to_string(blobs.data_size),
154 bytes_size_to_string(blobs.size),
155 ]);
156 total_count += blobs.count;
157 total_data_size += blobs.data_size;
158 total_size += blobs.size;
159 }
160 }
161
162 _ = table.add_row([
163 "Total".to_string(),
164 total_count.to_string(),
165 bytes_size_to_string(total_data_size),
166 bytes_size_to_string(total_size),
167 ]);
168
169 println!();
170 println!("{table}");
171
172 let mut table = table_right_from(
173 1,
174 ["Blob type", "Pack Count", "Minimum Size", "Maximum Size"],
175 );
176
177 for packs in index_info.packs {
178 _ = table.add_row([
179 format!("{:?} packs", packs.blob_type),
180 packs.count.to_string(),
181 packs
182 .min_size
183 .map_or_else(|| "-".to_string(), bytes_size_to_string),
184 packs
185 .max_size
186 .map_or_else(|| "-".to_string(), bytes_size_to_string),
187 ]);
188 }
189 for packs in index_info.packs_delete {
190 if packs.count > 0 {
191 _ = table.add_row([
192 format!("{:?} packs to delete", packs.blob_type),
193 packs.count.to_string(),
194 packs
195 .min_size
196 .map_or_else(|| "-".to_string(), bytes_size_to_string),
197 packs
198 .max_size
199 .map_or_else(|| "-".to_string(), bytes_size_to_string),
200 ]);
201 }
202 }
203 println!();
204 println!("{table}");
205}