mirror of
https://github.com/rustic-rs/rustic.git
synced 2025-10-26 11:18:51 +00:00
move dump functionality to rustic_core
This commit is contained in:
parent
375585a9b1
commit
adea0c00fb
@ -1,5 +1,6 @@
|
||||
pub mod cat;
|
||||
pub mod check;
|
||||
pub mod dump;
|
||||
pub mod forget;
|
||||
pub mod prune;
|
||||
pub mod repoinfo;
|
||||
|
||||
23
crates/rustic_core/src/commands/dump.rs
Normal file
23
crates/rustic_core/src/commands/dump.rs
Normal file
@ -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(())
|
||||
}
|
||||
@ -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>;
|
||||
@ -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
|
||||
|
||||
@ -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},
|
||||
};
|
||||
|
||||
@ -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 {
|
||||
@ -448,9 +448,23 @@ 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,
|
||||
@ -458,4 +472,8 @@ impl<P: ProgressBars> IndexedRepository<P> {
|
||||
) -> 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)
|
||||
}
|
||||
}
|
||||
|
||||
@ -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)]
|
||||
@ -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(())
|
||||
}
|
||||
|
||||
Loading…
Reference in New Issue
Block a user