refactor ls command

This commit is contained in:
Alexander Weiss 2023-07-07 15:40:21 +02:00
parent abc42a1994
commit bbfd0cd464
5 changed files with 81 additions and 56 deletions

View File

@ -0,0 +1,33 @@
//! `ls` example
use rustic_core::{Repository, RepositoryOptions, TreeStreamerOptions};
use simplelog::{Config, LevelFilter, SimpleLogger};
fn main() {
// Display info logs
let _ = SimpleLogger::init(LevelFilter::Info, Config::default());
// Open repository
let repo_opts = RepositoryOptions {
repository: Some("/tmp/repo".to_string()),
password: Some("test".to_string()),
..Default::default()
};
let repo = Repository::new(&repo_opts)
.unwrap()
.open()
.unwrap()
.to_indexed()
.unwrap();
// use latest snapshot without filtering snapshots
let node = repo.node_from_snapshot_path("latest", |_| true).unwrap();
// recursively list the snapshot contents using no additional filtering
let recursive = true;
let streamer_opts = TreeStreamerOptions::default();
for item in repo.ls(&node, &streamer_opts, recursive).unwrap() {
let (path, _) = item.unwrap();
println!("{path:?} ");
}
}

View File

@ -158,6 +158,7 @@ where
path: PathBuf,
be: BE,
overrides: Option<Override>,
recursive: bool,
}
impl<BE> NodeStreamer<BE>
@ -165,10 +166,15 @@ where
BE: IndexedBackend,
{
pub fn new(be: BE, node: &Node) -> RusticResult<Self> {
Self::new_streamer(be, node, None)
Self::new_streamer(be, node, None, true)
}
fn new_streamer(be: BE, node: &Node, overrides: Option<Override>) -> RusticResult<Self> {
fn new_streamer(
be: BE,
node: &Node,
overrides: Option<Override>,
recursive: bool,
) -> RusticResult<Self> {
let inner = if node.is_dir() {
Tree::from_backend(&be, node.subtree.unwrap())?
.nodes
@ -182,10 +188,16 @@ where
path: PathBuf::new(),
be,
overrides,
recursive,
})
}
pub fn new_with_glob(be: BE, node: &Node, opts: &TreeStreamerOptions) -> RusticResult<Self> {
pub fn new_with_glob(
be: BE,
node: &Node,
opts: &TreeStreamerOptions,
recursive: bool,
) -> RusticResult<Self> {
let mut override_builder = OverrideBuilder::new("/");
for g in &opts.glob {
@ -228,7 +240,7 @@ where
.build()
.map_err(TreeErrorKind::BuildingNodeStreamerFailed)?;
Self::new_streamer(be, node, Some(overrides))
Self::new_streamer(be, node, Some(overrides), recursive)
}
}
@ -246,15 +258,17 @@ where
match self.inner.next() {
Some(node) => {
let path = self.path.join(node.name());
if let Some(id) = node.subtree {
self.path.push(node.name());
let be = self.be.clone();
let tree = match Tree::from_backend(&be, id) {
Ok(tree) => tree,
Err(err) => return Some(Err(err)),
};
let old_inner = mem::replace(&mut self.inner, tree.nodes.into_iter());
self.open_iterators.push(old_inner);
if self.recursive {
if let Some(id) = node.subtree {
self.path.push(node.name());
let be = self.be.clone();
let tree = match Tree::from_backend(&be, id) {
Ok(tree) => tree,
Err(err) => return Some(Err(err)),
};
let old_inner = mem::replace(&mut self.inner, tree.nodes.into_iter());
self.open_iterators.push(old_inner);
}
}
if let Some(overrides) = &self.overrides {

View File

@ -39,8 +39,8 @@ use crate::{
error::{KeyFileErrorKind, RepositoryErrorKind, RusticErrorKind},
repofile::{configfile::ConfigFile, keyfile::find_key_in_backend},
BlobType, DecryptFullBackend, Id, IndexBackend, IndexedBackend, NoProgressBars, Node,
ProgressBars, PruneOpts, PrunePlan, RusticResult, SnapshotFile, SnapshotGroup,
SnapshotGroupCriterion, Tree,
NodeStreamer, ProgressBars, PruneOpts, PrunePlan, RusticResult, SnapshotFile, SnapshotGroup,
SnapshotGroupCriterion, Tree, TreeStreamerOptions,
};
mod warm_up;
@ -607,4 +607,13 @@ impl<P: ProgressBars, S: Indexed> Repository<P, S> {
pub fn dump(&self, node: &Node, w: &mut impl Write) -> RusticResult<()> {
commands::dump::dump(self, node, w)
}
pub fn ls(
&self,
node: &Node,
streamer_opts: &TreeStreamerOptions,
recursive: bool,
) -> RusticResult<impl Iterator<Item = RusticResult<(PathBuf, Node)>>> {
NodeStreamer::new_with_glob(self.index().clone(), node, streamer_opts, recursive)
}
}

View File

@ -7,11 +7,7 @@ use crate::{commands::open_repository, status_err, Application, RUSTIC_APP};
use abscissa_core::{Command, Runnable, Shutdown};
use anyhow::Result;
use std::path::Path;
use rustic_core::{
IndexBackend, NodeStreamer, Open, ProgressBars, SnapshotFile, Tree, TreeStreamerOptions,
};
use rustic_core::TreeStreamerOptions;
/// `ls` subcommand
#[derive(clap::Parser, Command, Debug)]
@ -40,44 +36,17 @@ impl Runnable for LsCmd {
impl LsCmd {
fn inner_run(&self) -> Result<()> {
let config = RUSTIC_APP.config();
let progress_options = &config.global.progress_options;
let repo = open_repository(&config)?;
let repo = open_repository(&config)?.to_indexed()?;
let be = repo.dbe();
let mut recursive = self.recursive;
let node =
repo.node_from_snapshot_path(&self.snap, |sn| config.snapshot_filter.matches(sn))?;
let (id, path) = self.snap.split_once(':').unwrap_or_else(|| {
recursive = true;
(&self.snap, "")
});
let snap = SnapshotFile::from_str(
be,
id,
|sn| config.snapshot_filter.matches(sn),
&progress_options.progress_counter(""),
)?;
let index = IndexBackend::new(be, &progress_options.progress_counter(""))?;
let node = Tree::node_from_path(&index, snap.tree, Path::new(path))?;
let recursive = !self.snap.contains(':') || self.recursive;
if recursive {
NodeStreamer::new_with_glob(index, &node, &self.streamer_opts)?.for_each(|item| {
let (path, _) = match item {
Ok(it) => it,
Err(err) => {
status_err!("{}", err);
RUSTIC_APP.shutdown(Shutdown::Crash);
}
};
println!("{path:?} ");
});
} else if node.is_dir() {
let tree = Tree::from_backend(&index, node.subtree.unwrap())?.nodes;
for node in tree {
println!("{:?} ", node.name());
}
} else {
println!("{:?} ", node.name());
for item in repo.ls(&node, &self.streamer_opts, recursive)? {
let (path, _) = item?;
println!("{path:?} ");
}
Ok(())

View File

@ -278,7 +278,7 @@ impl RestoreCmd {
let mut next_dst = dst_iter.next();
let mut node_streamer =
NodeStreamer::new_with_glob(index.clone(), node, &self.streamer_opts.clone())?;
NodeStreamer::new_with_glob(index.clone(), node, &self.streamer_opts.clone(), true)?;
let mut next_node = node_streamer.next().transpose()?;
loop {
@ -344,7 +344,7 @@ impl RestoreCmd {
) -> Result<()> {
// walk over tree in repository and compare with tree in dest
let mut node_streamer =
NodeStreamer::new_with_glob(index, node, &self.streamer_opts.clone())?;
NodeStreamer::new_with_glob(index, node, &self.streamer_opts.clone(), true)?;
let mut dir_stack = Vec::new();
while let Some((path, node)) = node_streamer.next().transpose()? {
match node.node_type {