Skip to content

Commit

Permalink
move dump functionality to rustic_core
Browse files Browse the repository at this point in the history
  • Loading branch information
aawsome committed Jun 27, 2023
1 parent 375585a commit adea0c0
Show file tree
Hide file tree
Showing 5 changed files with 55 additions and 39 deletions.
1 change: 1 addition & 0 deletions crates/rustic_core/src/commands.rs
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
pub mod cat;
pub mod check;
pub mod dump;
pub mod forget;
pub mod prune;
pub mod repoinfo;
Expand Down
23 changes: 23 additions & 0 deletions crates/rustic_core/src/commands/dump.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
use std::io::Write;

use crate::{
error::CommandErrorKind, repository::IndexedRepository, BlobType, IndexedBackend, Node,
NodeType, RusticResult,
};

pub(crate) fn dump<P>(
repo: &IndexedRepository<P>,
node: &Node,
w: &mut impl Write,
) -> RusticResult<()> {
if node.node_type != NodeType::File {
return Err(CommandErrorKind::DumpNotSupported(node.node_type.clone()).into());
}

for id in node.content.as_ref().unwrap() {
// TODO: cache blobs which are needed later
let data = repo.index.blob_from_backend(BlobType::Data, id)?;
w.write_all(&data)?;
}
Ok(())
}
4 changes: 3 additions & 1 deletion crates/rustic_core/src/error.rs
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,7 @@ use chrono::OutOfRangeError;
use displaydoc::Display;
use thiserror::Error;

use crate::{id::Id, repofile::indexfile::IndexPack};
use crate::{id::Id, repofile::indexfile::IndexPack, NodeType};

/// Result type often returned from methods that can have rustic `Error`s.
pub type RusticResult<T> = Result<T, RusticError>;
Expand Down Expand Up @@ -160,6 +160,8 @@ pub enum CommandErrorKind {
RepackUncompressedRepoV1,
/// datetime out of range: `{0:?}`
FromOutOfRangeError(#[from] OutOfRangeError),
/// node type {0:?} not supported by dump
DumpNotSupported(NodeType),
}

/// [`CryptoErrorKind`] describes the errors that can happen while dealing with Cryptographic functions
Expand Down
26 changes: 22 additions & 4 deletions crates/rustic_core/src/repository.rs
Original file line number Diff line number Diff line change
@@ -1,8 +1,8 @@
use std::{
collections::HashMap,
fs::File,
io::{BufRead, BufReader},
path::PathBuf,
io::{BufRead, BufReader, Write},
path::{Path, PathBuf},
process::{Command, Stdio},
};

Expand Down Expand Up @@ -37,8 +37,8 @@ use crate::{
crypto::aespoly1305::Key,
error::RepositoryErrorKind,
repofile::{configfile::ConfigFile, keyfile::find_key_in_backend},
BlobType, Id, IndexBackend, NoProgressBars, ProgressBars, PruneOpts, PrunePlan, RusticResult,
SnapshotFile, SnapshotGroup, SnapshotGroupCriterion,
BlobType, Id, IndexBackend, NoProgressBars, Node, ProgressBars, PruneOpts, PrunePlan,
RusticResult, SnapshotFile, SnapshotGroup, SnapshotGroupCriterion, Tree,
};

pub(super) mod constants {
Expand Down Expand Up @@ -448,14 +448,32 @@ pub struct IndexedRepository<P> {
}

impl<P: ProgressBars> IndexedRepository<P> {
pub fn node_from_snapshot_path(
&self,
snap_path: &str,
filter: impl FnMut(&SnapshotFile) -> bool + Send + Sync,
) -> RusticResult<Node> {
let (id, path) = snap_path.split_once(':').unwrap_or((snap_path, ""));

let p = &self.repo.pb.progress_counter("getting snapshot...");
let snap = SnapshotFile::from_str(&self.repo.dbe, id, filter, p)?;

Tree::node_from_path(&self.index, snap.tree, Path::new(path))
}

pub fn cat_blob(&self, tpe: BlobType, id: &str) -> RusticResult<Bytes> {
commands::cat::cat_blob(self, tpe, id)
}

pub fn cat_tree(
&self,
snap: &str,
sn_filter: impl FnMut(&SnapshotFile) -> bool + Send + Sync,
) -> RusticResult<Bytes> {
commands::cat::cat_tree(self, snap, sn_filter)
}

pub fn dump(&self, node: &Node, w: &mut impl Write) -> RusticResult<()> {
commands::dump::dump(self, node, w)
}
}
40 changes: 6 additions & 34 deletions src/commands/dump.rs
Original file line number Diff line number Diff line change
Expand Up @@ -2,19 +2,10 @@

/// App-local prelude includes `app_reader()`/`app_writer()`/`app_config()`
/// accessors along with logging macros. Customize as you see fit.
use crate::{
commands::{get_repository, open_repository},
status_err, Application, RUSTIC_APP,
};
use crate::{commands::get_repository, status_err, Application, RUSTIC_APP};

use abscissa_core::{Command, Runnable, Shutdown};
use anyhow::{bail, Result};

use std::{io::Write, path::Path};

use rustic_core::{
BlobType, IndexBackend, IndexedBackend, NodeType, ProgressBars, SnapshotFile, Tree,
};
use anyhow::Result;

/// `dump` subcommand
#[derive(clap::Parser, Command, Debug)]
Expand All @@ -37,31 +28,12 @@ impl DumpCmd {
fn inner_run(&self) -> Result<()> {
let config = RUSTIC_APP.config();

let repo = open_repository(get_repository(&config));

let be = &repo.dbe;
let progress_options = &config.global.progress_options;

let (id, path) = self.snap.split_once(':').unwrap_or((&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))?;

if node.node_type != NodeType::File {
bail!("dump only supports regular files!");
}
let repo = get_repository(&config).open()?.to_indexed()?;
let node =
repo.node_from_snapshot_path(&self.snap, |sn| config.snapshot_filter.matches(sn))?;

let mut stdout = std::io::stdout();
for id in node.content.unwrap() {
// TODO: cache blobs which are needed later
let data = index.blob_from_backend(BlobType::Data, &id)?;
stdout.write_all(&data)?;
}
repo.dump(&node, &mut stdout)?;

Ok(())
}
Expand Down

0 comments on commit adea0c0

Please sign in to comment.