From a93efb171b7a4b88dffba3cc7bc03f1bf4d75fd2 Mon Sep 17 00:00:00 2001 From: Alexander Weiss Date: Fri, 7 Jul 2023 11:35:25 +0200 Subject: [PATCH] refactor tag command --- crates/rustic_core/examples/tag.rs | 33 ++++++++++++++++++++++++++++ crates/rustic_core/src/lib.rs | 1 - crates/rustic_core/src/repository.rs | 17 ++++++++++++++ src/commands/tag.rs | 26 +++++----------------- 4 files changed, 56 insertions(+), 21 deletions(-) create mode 100644 crates/rustic_core/examples/tag.rs diff --git a/crates/rustic_core/examples/tag.rs b/crates/rustic_core/examples/tag.rs new file mode 100644 index 0000000..ce48f16 --- /dev/null +++ b/crates/rustic_core/examples/tag.rs @@ -0,0 +1,33 @@ +//! `tag` example +use std::str::FromStr; + +use rustic_core::{Repository, RepositoryOptions, StringList}; +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(); + + // Get all snapshots - use a filter which doesn't filter out. + let snaps = repo.get_matching_snapshots(|_| true).unwrap(); + + // Set tag "test" to all snapshots, filtering out unchanged (i.e. tag was aready preset) snapshots + let tags = vec![StringList::from_str("test").unwrap()]; + let snaps: Vec<_> = snaps + .into_iter() + .filter_map(|mut sn| sn.add_tags(tags.clone()).then_some(sn)) // can also use set_tags or remove_tags + .collect(); + let old_snap_ids: Vec<_> = snaps.iter().map(|sn| sn.id).collect(); + + // remove old snapshots and save changed ones + repo.save_snapshots(snaps).unwrap(); + repo.delete_snapshots(&old_snap_ids).unwrap(); +} diff --git a/crates/rustic_core/src/lib.rs b/crates/rustic_core/src/lib.rs index 51b9d3a..2724acb 100644 --- a/crates/rustic_core/src/lib.rs +++ b/crates/rustic_core/src/lib.rs @@ -147,7 +147,6 @@ pub use crate::{ DeleteOption, PathList, SnapshotFile, SnapshotGroup, SnapshotGroupCriterion, SnapshotOptions, StringList, }, - RepoFile, }, repository::{read_password_from_reader, Open, OpenStatus, Repository, RepositoryOptions}, }; diff --git a/crates/rustic_core/src/repository.rs b/crates/rustic_core/src/repository.rs index 2fd430e..e6c9349 100644 --- a/crates/rustic_core/src/repository.rs +++ b/crates/rustic_core/src/repository.rs @@ -490,6 +490,14 @@ impl Repository { SnapshotFile::from_ids(self.dbe(), ids, &p) } + pub fn get_matching_snapshots( + &self, + filter: impl FnMut(&SnapshotFile) -> bool, + ) -> RusticResult> { + let p = self.pb.progress_counter("getting snapshots..."); + SnapshotFile::all_from_backend(self.dbe(), filter, &p) + } + pub fn get_forget_snapshots( &self, keep: &KeepOptions, @@ -506,6 +514,15 @@ impl Repository { Ok(()) } + pub fn save_snapshots(&self, mut snaps: Vec) -> RusticResult<()> { + for snap in &mut snaps { + snap.id = Id::default(); + } + let p = self.pb.progress_counter("saving snapshots..."); + self.dbe().save_list(snaps.iter(), p)?; + Ok(()) + } + pub fn check(&self, opts: CheckOpts) -> RusticResult<()> { opts.run(self) } diff --git a/src/commands/tag.rs b/src/commands/tag.rs index 93e421b..87efb3e 100644 --- a/src/commands/tag.rs +++ b/src/commands/tag.rs @@ -8,9 +8,7 @@ use abscissa_core::{Command, Runnable, Shutdown}; use chrono::{Duration, Local}; -use rustic_core::{ - DecryptWriteBackend, DeleteOption, FileType, Id, Open, ProgressBars, SnapshotFile, StringList, -}; +use rustic_core::{DeleteOption, StringList}; /// `tag` subcommand @@ -78,13 +76,10 @@ impl TagCmd { let config = RUSTIC_APP.config(); let repo = open_repository(&config)?; - let be = repo.dbe(); - - let p = config.global.progress_options.progress_hidden(); let snapshots = if self.ids.is_empty() { - SnapshotFile::all_from_backend(be, |sn| config.snapshot_filter.matches(sn), &p)? + repo.get_matching_snapshots(|sn| config.snapshot_filter.matches(sn))? } else { - SnapshotFile::from_ids(be, &self.ids, &p)? + repo.get_snapshots(&self.ids)? }; let delete = match ( @@ -98,19 +93,13 @@ impl TagCmd { (false, false, None) => None, }; - let mut snapshots: Vec<_> = snapshots + let snapshots: Vec<_> = snapshots .into_iter() .filter_map(|mut sn| { sn.modify_sn(self.set.clone(), self.add.clone(), &self.remove, &delete) }) .collect(); let old_snap_ids: Vec<_> = snapshots.iter().map(|sn| sn.id).collect(); - // remove old ids from snapshots - for snap in &mut snapshots { - snap.id = Id::default(); - } - - let progress_options = &config.global.progress_options; match (old_snap_ids.is_empty(), config.global.dry_run) { (true, _) => println!("no snapshot changed."), @@ -118,11 +107,8 @@ impl TagCmd { println!("would have modified the following snapshots:\n {old_snap_ids:?}"); } (false, false) => { - let p = progress_options.progress_counter("saving new snapshots..."); - be.save_list(snapshots.iter(), p)?; - - let p = progress_options.progress_counter("deleting old snapshots..."); - be.delete_list(FileType::Snapshot, true, old_snap_ids.iter(), p)?; + repo.save_snapshots(snapshots)?; + repo.delete_snapshots(&old_snap_ids)?; } }