1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
//! `list` subcommand
use std::num::NonZero;
use crate::{Application, RUSTIC_APP, repository::OpenRepo, status_err};
use abscissa_core::{Command, Runnable, Shutdown};
use anyhow::{Result, bail};
use rustic_core::repofile::{IndexFile, IndexId, KeyId, PackId, SnapshotId};
/// `list` subcommand
#[derive(clap::Parser, Command, Debug)]
pub(crate) struct ListCmd {
/// File types to list
#[clap(value_parser=["blobs", "indexpacks", "indexcontent", "index", "packs", "snapshots", "keys"])]
tpe: String,
}
impl Runnable for ListCmd {
fn run(&self) {
if let Err(err) = RUSTIC_APP
.config()
.repository
.run_open(|repo| self.inner_run(repo))
{
status_err!("{}", err);
RUSTIC_APP.shutdown(Shutdown::Crash);
};
}
}
impl ListCmd {
fn inner_run(&self, repo: OpenRepo) -> Result<()> {
let config = RUSTIC_APP.config();
match self.tpe.as_str() {
// special treatment for listing blobs: read the index and display it
"blobs" | "indexpacks" | "indexcontent" => {
for item in repo.stream_files::<IndexFile>()? {
let (_, index) = item?;
for pack in index.packs {
match self.tpe.as_str() {
"blobs" => {
for blob in pack.blobs {
println!("{:?} {:?}", blob.tpe, blob.id);
}
}
"indexcontent" => {
for blob in pack.blobs {
println!(
"{:?} {:?} {:?} {} {}",
blob.tpe,
blob.id,
pack.id,
blob.location.length,
blob.location.uncompressed_length.map_or(0, NonZero::get)
);
}
}
"indexpacks" => println!(
"{:?} {:?} {} {}",
pack.blob_type(),
pack.id,
pack.pack_size(),
pack.time.map_or_else(String::new, |time| config
.global
.format_timestamp(time))
),
t => {
bail!("invalid type: {}", t);
}
}
}
}
}
"index" => {
for id in repo.list::<IndexId>()? {
println!("{id:?}");
}
}
"packs" => {
for id in repo.list::<PackId>()? {
println!("{id:?}");
}
}
"snapshots" => {
for id in repo.list::<SnapshotId>()? {
println!("{id:?}");
}
}
"keys" => {
for id in repo.list::<KeyId>()? {
println!("{id:?}");
}
}
t => {
bail!("invalid type: {}", t);
}
};
Ok(())
}
}