Skip to content

Commit

Permalink
refactor ls command
Browse files Browse the repository at this point in the history
  • Loading branch information
aawsome committed Jul 7, 2023
1 parent abc42a1 commit bbfd0cd
Show file tree
Hide file tree
Showing 5 changed files with 81 additions and 56 deletions.
33 changes: 33 additions & 0 deletions crates/rustic_core/examples/ls.rs
Original file line number Diff line number Diff line change
@@ -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:?} ");
}
}
40 changes: 27 additions & 13 deletions crates/rustic_core/src/blob/tree.rs
Original file line number Diff line number Diff line change
Expand Up @@ -158,17 +158,23 @@ where
path: PathBuf,
be: BE,
overrides: Option<Override>,
recursive: bool,
}

impl<BE> NodeStreamer<BE>
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
Expand All @@ -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 {
Expand Down Expand Up @@ -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)
}
}

Expand All @@ -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 {
Expand Down
13 changes: 11 additions & 2 deletions crates/rustic_core/src/repository.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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;
Expand Down Expand 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)
}
}
47 changes: 8 additions & 39 deletions src/commands/ls.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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)]
Expand Down Expand Up @@ -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(())
Expand Down
4 changes: 2 additions & 2 deletions src/commands/restore.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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 {
Expand Down Expand Up @@ -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 {
Expand Down

0 comments on commit bbfd0cd

Please sign in to comment.