Skip to content

Commit

Permalink
Refactor rustic_core API & add documentation
Browse files Browse the repository at this point in the history
Co-authored-by: Alexander Weiss <[email protected]>
  • Loading branch information
simonsan and aawsome committed Sep 5, 2023
1 parent 928a2e5 commit 50248e7
Show file tree
Hide file tree
Showing 88 changed files with 6,553 additions and 921 deletions.
557 changes: 274 additions & 283 deletions Cargo.lock

Large diffs are not rendered by default.

12 changes: 6 additions & 6 deletions Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -195,7 +195,7 @@ aho-corasick = "1"
# rest backend
reqwest = { version = "0.11", default-features = false, features = ["json", "rustls-tls-native-roots", "stream", "blocking"] }
backoff = "0.4"
url = "2.3.1"
url = "2.4.0"

# rclone backend
semver = "1"
Expand All @@ -208,7 +208,7 @@ enum-map = "2"
enum-map-derive = "0.13"
rhai = { version = "1.15", features = ["sync", "serde", "no_optimize", "no_module", "no_custom_syntax", "only_i64"] }
simplelog = "0.12"
comfy-table = "6.1.4"
comfy-table = "7.0.1"

# cache
dirs = "5"
Expand All @@ -223,15 +223,15 @@ path-dedot = "3"
dunce = "1"
gethostname = "0.4"
bytesize = "1"
itertools = "0.10"
itertools = "0.11"
humantime = "2"
clap_complete = "4"
clap = { version = "4", features = ["derive", "env", "wrap_help"] }
once_cell = "1.17"
self_update = { version = "0.36", default-features = false, features = ["rustls", "archive-tar", "compression-flate2"] }
once_cell = "1.18"
self_update = { version = "0.37", default-features = false, features = ["rustls", "archive-tar", "compression-flate2"] }

# dev dependencies
rstest = "0.17"
rstest = "0.18"
quickcheck = "1"
quickcheck_macros = "1"
tempfile = "3.8"
Expand Down
1 change: 1 addition & 0 deletions crates/rustic_core/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -132,6 +132,7 @@ rstest = { workspace = true }
rustdoc-json = "0.8.7"
rustup-toolchain = "0.1.4"
simplelog = { workspace = true }
tempfile = { workspace = true }

[profile.dev]
opt-level = 0
Expand Down
13 changes: 8 additions & 5 deletions crates/rustic_core/examples/backup.rs
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
//! `backup` example
use rustic_core::{BackupOpts, PathList, Repository, RepositoryOptions, SnapshotFile};
use rustic_core::{BackupOptions, PathList, Repository, RepositoryOptions, SnapshotOptions};
use simplelog::{Config, LevelFilter, SimpleLogger};
use std::error::Error;

Expand All @@ -13,11 +13,14 @@ fn main() -> Result<(), Box<dyn Error>> {
.password("test");
let repo = Repository::new(&repo_opts)?.open()?.to_indexed_ids()?;

let backup_opts = BackupOpts::default();
let source = PathList::from_string(".", true)?; // true: sanitize the given string
let dry_run = false;
let backup_opts = BackupOptions::default();
let source = PathList::from_string(".")?.sanitize()?;
let snap = SnapshotOptions::default()
.add_tags("tag1,tag2")?
.to_snapshot()?;

let snap = repo.backup(&backup_opts, source, SnapshotFile::default(), dry_run)?;
// Create snapshot
let snap = repo.backup(&backup_opts, source, snap)?;

println!("successfully created snapshot:\n{snap:#?}");
Ok(())
Expand Down
6 changes: 3 additions & 3 deletions crates/rustic_core/examples/check.rs
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
//! `check` example
use rustic_core::{CheckOpts, Repository, RepositoryOptions};
use rustic_core::{CheckOptions, Repository, RepositoryOptions};
use simplelog::{Config, LevelFilter, SimpleLogger};
use std::error::Error;

Expand All @@ -13,8 +13,8 @@ fn main() -> Result<(), Box<dyn Error>> {
.password("test");
let repo = Repository::new(&repo_opts)?.open()?;

// Check respository with standard options
let opts = CheckOpts::default();
// Check respository with standard options but omitting cache checks
let opts = CheckOptions::default().trust_cache(true);
repo.check(opts)?;
Ok(())
}
7 changes: 2 additions & 5 deletions crates/rustic_core/examples/config.rs
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
//! `config` example
use rustic_core::{ConfigOpts, Repository, RepositoryOptions};
use rustic_core::{max_compression_level, ConfigOptions, Repository, RepositoryOptions};
use simplelog::{Config, LevelFilter, SimpleLogger};
use std::error::Error;

Expand All @@ -14,10 +14,7 @@ fn main() -> Result<(), Box<dyn Error>> {
let repo = Repository::new(&repo_opts)?.open()?;

// Set Config, e.g. Compression level
let config_opts = ConfigOpts {
set_compression: Some(22),
..Default::default()
};
let config_opts = ConfigOptions::default().set_compression(max_compression_level());
repo.apply_config(&config_opts)?;
Ok(())
}
4 changes: 1 addition & 3 deletions crates/rustic_core/examples/forget.rs
Original file line number Diff line number Diff line change
Expand Up @@ -15,9 +15,7 @@ fn main() -> Result<(), Box<dyn Error>> {

// Check respository with standard options
let group_by = SnapshotGroupCriterion::default();
let mut keep = KeepOptions::default();
keep.keep_daily = 5;
keep.keep_weekly = 10;
let keep = KeepOptions::default().keep_daily(5).keep_weekly(10);
let snaps = repo.get_forget_snapshots(&keep, group_by, |_| true)?;
println!("{snaps:?}");
// to remove the snapshots-to-forget, uncomment this line:
Expand Down
6 changes: 3 additions & 3 deletions crates/rustic_core/examples/init.rs
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
//! `init` example
use rustic_core::{ConfigOpts, KeyOpts, Repository, RepositoryOptions};
use rustic_core::{ConfigOptions, KeyOptions, Repository, RepositoryOptions};
use simplelog::{Config, LevelFilter, SimpleLogger};
use std::error::Error;

Expand All @@ -11,8 +11,8 @@ fn main() -> Result<(), Box<dyn Error>> {
let repo_opts = RepositoryOptions::default()
.repository("/tmp/repo")
.password("test");
let key_opts = KeyOpts::default();
let config_opts = ConfigOpts::default();
let key_opts = KeyOptions::default();
let config_opts = ConfigOptions::default();
let _repo = Repository::new(&repo_opts)?.init(&key_opts, &config_opts)?;

// -> use _repo for any operation on an open repository
Expand Down
4 changes: 2 additions & 2 deletions crates/rustic_core/examples/key.rs
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
//! `key` example
use rustic_core::{KeyOpts, Repository, RepositoryOptions};
use rustic_core::{KeyOptions, Repository, RepositoryOptions};
use simplelog::{Config, LevelFilter, SimpleLogger};
use std::error::Error;

Expand All @@ -14,7 +14,7 @@ fn main() -> Result<(), Box<dyn Error>> {
let repo = Repository::new(&repo_opts)?.open()?;

// Add a new key with the given password
let key_opts = KeyOpts::default();
let key_opts = KeyOptions::default();
repo.add_key("new_password", &key_opts)?;
Ok(())
}
7 changes: 3 additions & 4 deletions crates/rustic_core/examples/ls.rs
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
//! `ls` example
use rustic_core::{Repository, RepositoryOptions, TreeStreamerOptions};
use rustic_core::{LsOptions, Repository, RepositoryOptions};
use simplelog::{Config, LevelFilter, SimpleLogger};
use std::error::Error;

Expand All @@ -17,9 +17,8 @@ fn main() -> Result<(), Box<dyn Error>> {
let node = repo.node_from_snapshot_path("latest", |_| true)?;

// 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)? {
let ls_opts = LsOptions::default();
for item in repo.ls(&node, &ls_opts)? {
let (path, _) = item?;
println!("{path:?} ");
}
Expand Down
4 changes: 2 additions & 2 deletions crates/rustic_core/examples/merge.rs
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
//! `merge` example
use rustic_core::{latest_node, Repository, RepositoryOptions, SnapshotFile};
use rustic_core::{last_modified_node, repofile::SnapshotFile, Repository, RepositoryOptions};
use simplelog::{Config, LevelFilter, SimpleLogger};
use std::error::Error;

Expand All @@ -16,7 +16,7 @@ fn main() -> Result<(), Box<dyn Error>> {
// Merge all snapshots using the latest entry for duplicate entries
let snaps = repo.get_all_snapshots()?;
// This creates a new snapshot without removing the used ones
let snap = repo.merge_snapshots(&snaps, &latest_node, SnapshotFile::default())?;
let snap = repo.merge_snapshots(&snaps, &last_modified_node, SnapshotFile::default())?;

println!("successfully created snapshot:\n{snap:#?}");
Ok(())
Expand Down
4 changes: 2 additions & 2 deletions crates/rustic_core/examples/prune.rs
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
//! `prune` example
use rustic_core::{PruneOpts, Repository, RepositoryOptions};
use rustic_core::{PruneOptions, Repository, RepositoryOptions};
use simplelog::{Config, LevelFilter, SimpleLogger};
use std::error::Error;

Expand All @@ -13,7 +13,7 @@ fn main() -> Result<(), Box<dyn Error>> {
.password("test");
let repo = Repository::new(&repo_opts)?.open()?;

let prune_opts = PruneOpts::default();
let prune_opts = PruneOptions::default();
let prune_plan = repo.prune_plan(&prune_opts)?;
println!("{:?}", prune_plan.stats);
println!("to repack: {:?}", prune_plan.repack_packs());
Expand Down
11 changes: 4 additions & 7 deletions crates/rustic_core/examples/restore.rs
Original file line number Diff line number Diff line change
@@ -1,7 +1,5 @@
//! `restore` example
use rustic_core::{
LocalDestination, Repository, RepositoryOptions, RestoreOpts, TreeStreamerOptions,
};
use rustic_core::{LocalDestination, LsOptions, Repository, RepositoryOptions, RestoreOptions};
use simplelog::{Config, LevelFilter, SimpleLogger};
use std::error::Error;

Expand All @@ -19,15 +17,14 @@ fn main() -> Result<(), Box<dyn Error>> {
let node = repo.node_from_snapshot_path("latest", |_| true)?;

// use list of the snapshot contents using no additional filtering
let recursive = true;
let streamer_opts = TreeStreamerOptions::default();
let ls = repo.ls(&node, &streamer_opts, recursive)?;
let streamer_opts = LsOptions::default();
let ls = repo.ls(&node, &streamer_opts)?;

let destination = "./restore/"; // restore to this destination dir
let create = true; // create destination dir, if it doesn't exist
let dest = LocalDestination::new(destination, create, !node.is_dir())?;

let opts = RestoreOpts::default();
let opts = RestoreOptions::default();
let dry_run = false;
// create restore infos. Note: this also already creates needed dirs in the destination
let restore_infos = repo.prepare_restore(&opts, ls.clone(), &dest, dry_run)?;
Expand Down
55 changes: 55 additions & 0 deletions crates/rustic_core/src/archiver.rs
Original file line number Diff line number Diff line change
Expand Up @@ -20,17 +20,51 @@ use crate::{
repofile::{configfile::ConfigFile, snapshotfile::SnapshotFile},
Progress, RusticResult,
};

/// The `Archiver` is responsible for archiving files and trees.
/// It will read the file, chunk it, and write the chunks to the backend.
///
/// # Type Parameters
///
/// * `BE` - The backend type.
/// * `I` - The index to read from.
#[allow(missing_debug_implementations)]
pub struct Archiver<BE: DecryptWriteBackend, I: IndexedBackend> {
/// The `FileArchiver` is responsible for archiving files.
file_archiver: FileArchiver<BE, I>,

/// The `TreeArchiver` is responsible for archiving trees.
tree_archiver: TreeArchiver<BE, I>,

/// The parent snapshot to use.
parent: Parent,

/// The SharedIndexer is used to index the data.
indexer: SharedIndexer<BE>,

/// The backend to write to.
be: BE,

/// The SnapshotFile to write to.
snap: SnapshotFile,
}

impl<BE: DecryptWriteBackend, I: IndexedBackend> Archiver<BE, I> {
/// Creates a new `Archiver`.
///
/// # Arguments
///
/// * `be` - The backend to write to.
/// * `index` - The index to read from.
/// * `config` - The config file.
/// * `parent` - The parent snapshot to use.
/// * `snap` - The `SnapshotFile` to write to.
///
/// # Errors
///
/// * [`PackerErrorKind::ZstdError`] - If the zstd compression level is invalid.
/// * [`PackerErrorKind::SendingCrossbeamMessageFailed`] - If sending the message to the raw packer fails.
/// * [`PackerErrorKind::IntConversionFailed`] - If converting the data length to u64 fails
pub fn new(
be: BE,
index: I,
Expand All @@ -54,6 +88,27 @@ impl<BE: DecryptWriteBackend, I: IndexedBackend> Archiver<BE, I> {
})
}

/// Archives the given source.
///
/// This will archive all files and trees in the given source.
///
/// # Type Parameters
///
/// * `R` - The type of the source.
///
/// # Arguments
///
/// * `index` - The index to read from.
/// * `src` - The source to archive.
/// * `backup_path` - The path to the backup.
/// * `as_path` - The path to archive the backup as.
/// * `p` - The progress bar.
///
/// # Errors
///
/// * [`PackerErrorKind::SendingCrossbeamMessageFailed`] - If sending the message to the raw packer fails.
/// * [`CryptBackendErrorKind::SerializingToJsonByteVectorFailed`] - If the index file could not be serialized.
/// * [`SnapshotFileErrorKind::OutOfRange`] - If the time is not in the range of `Local::now()`
pub fn archive<R>(
mut self,
index: &I,
Expand Down
Loading

0 comments on commit 50248e7

Please sign in to comment.