mirror of
https://github.com/rustic-rs/rustic.git
synced 2025-10-26 11:18:51 +00:00
Merge pull request #705 from rustic-rs/refactor-snapshots
move getting snapshots to rustic_core
This commit is contained in:
commit
208cbe6728
@ -2,3 +2,4 @@ pub mod cat;
|
||||
pub mod check;
|
||||
pub mod prune;
|
||||
pub mod repoinfo;
|
||||
pub mod snapshots;
|
||||
|
||||
39
crates/rustic_core/src/commands/snapshots.rs
Normal file
39
crates/rustic_core/src/commands/snapshots.rs
Normal file
@ -0,0 +1,39 @@
|
||||
//! `smapshot` subcommand
|
||||
|
||||
use crate::{
|
||||
OpenRepository, ProgressBars, RusticResult, SnapshotFile, SnapshotGroup, SnapshotGroupCriterion,
|
||||
};
|
||||
|
||||
pub(crate) fn get_snapshot_group<P: ProgressBars>(
|
||||
repo: &OpenRepository<P>,
|
||||
ids: &[String],
|
||||
group_by: SnapshotGroupCriterion,
|
||||
filter: impl FnMut(&SnapshotFile) -> bool,
|
||||
) -> RusticResult<Vec<(SnapshotGroup, Vec<SnapshotFile>)>> {
|
||||
let pb = &repo.pb;
|
||||
let p = pb.progress_counter("getting snapshots...");
|
||||
let groups = match ids {
|
||||
[] => SnapshotFile::group_from_backend(&repo.dbe, filter, group_by, &p)?,
|
||||
[id] if id == "latest" => {
|
||||
SnapshotFile::group_from_backend(&repo.dbe, filter, group_by, &p)?
|
||||
.into_iter()
|
||||
.map(|(group, mut snaps)| {
|
||||
snaps.sort_unstable();
|
||||
let last_idx = snaps.len() - 1;
|
||||
snaps.swap(0, last_idx);
|
||||
snaps.truncate(1);
|
||||
(group, snaps)
|
||||
})
|
||||
.collect::<Vec<_>>()
|
||||
}
|
||||
_ => {
|
||||
let item = (
|
||||
SnapshotGroup::default(),
|
||||
SnapshotFile::from_ids(&repo.dbe, ids, &p)?,
|
||||
);
|
||||
vec![item]
|
||||
}
|
||||
};
|
||||
|
||||
Ok(groups)
|
||||
}
|
||||
@ -341,7 +341,7 @@ impl SnapshotFile {
|
||||
pub fn group_from_backend<B, F>(
|
||||
be: &B,
|
||||
filter: F,
|
||||
crit: &SnapshotGroupCriterion,
|
||||
crit: SnapshotGroupCriterion,
|
||||
p: &impl Progress,
|
||||
) -> RusticResult<Vec<(SnapshotGroup, Vec<Self>)>>
|
||||
where
|
||||
@ -349,7 +349,7 @@ impl SnapshotFile {
|
||||
F: FnMut(&Self) -> bool,
|
||||
{
|
||||
let mut snaps = Self::all_from_backend(be, filter, p)?;
|
||||
snaps.sort_unstable_by(|sn1, sn2| sn1.cmp_group(*crit, sn2));
|
||||
snaps.sort_unstable_by(|sn1, sn2| sn1.cmp_group(crit, sn2));
|
||||
|
||||
let mut result = Vec::new();
|
||||
for (group, snaps) in &snaps
|
||||
@ -528,7 +528,7 @@ impl Display for SnapshotGroup {
|
||||
|
||||
impl SnapshotGroup {
|
||||
#[must_use]
|
||||
pub fn from_sn(sn: &SnapshotFile, crit: &SnapshotGroupCriterion) -> Self {
|
||||
pub fn from_sn(sn: &SnapshotFile, crit: SnapshotGroupCriterion) -> Self {
|
||||
Self {
|
||||
hostname: crit.hostname.then(|| sn.hostname.clone()),
|
||||
label: crit.label.then(|| sn.label.clone()),
|
||||
|
||||
@ -37,7 +37,7 @@ use crate::{
|
||||
error::RepositoryErrorKind,
|
||||
repofile::{configfile::ConfigFile, keyfile::find_key_in_backend},
|
||||
BlobType, IndexBackend, NoProgressBars, ProgressBars, PruneOpts, PrunePlan, RusticResult,
|
||||
SnapshotFile,
|
||||
SnapshotFile, SnapshotGroup, SnapshotGroupCriterion,
|
||||
};
|
||||
|
||||
pub(super) mod constants {
|
||||
@ -373,6 +373,15 @@ pub struct OpenRepository<P> {
|
||||
}
|
||||
|
||||
impl<P: ProgressBars> OpenRepository<P> {
|
||||
pub fn get_snapshot_group(
|
||||
&self,
|
||||
ids: &[String],
|
||||
group_by: SnapshotGroupCriterion,
|
||||
filter: impl FnMut(&SnapshotFile) -> bool,
|
||||
) -> RusticResult<Vec<(SnapshotGroup, Vec<SnapshotFile>)>> {
|
||||
commands::snapshots::get_snapshot_group(self, ids, group_by, filter)
|
||||
}
|
||||
|
||||
pub fn cat_file(&self, tpe: FileType, id: &str) -> RusticResult<Bytes> {
|
||||
commands::cat::cat_file(self, tpe, id)
|
||||
}
|
||||
|
||||
@ -252,7 +252,7 @@ impl BackupCmd {
|
||||
// get suitable snapshot group from snapshot and opts.group_by. This is used to filter snapshots for the parent detection
|
||||
let group = SnapshotGroup::from_sn(
|
||||
&snap,
|
||||
&opts.group_by.unwrap_or_else(|| {
|
||||
opts.group_by.unwrap_or_else(|| {
|
||||
SnapshotGroupCriterion::from_str("host,label,paths").unwrap()
|
||||
}),
|
||||
);
|
||||
|
||||
@ -113,7 +113,7 @@ impl ForgetCmd {
|
||||
SnapshotFile::group_from_backend(
|
||||
be,
|
||||
|sn| config.forget.filter.matches(sn),
|
||||
&group_by,
|
||||
group_by,
|
||||
&p,
|
||||
)?
|
||||
} else {
|
||||
|
||||
@ -3,20 +3,18 @@
|
||||
/// 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},
|
||||
commands::get_repository,
|
||||
helpers::{bold_cell, bytes_size_to_string, table, table_right_from},
|
||||
status_err, Application, RUSTIC_APP,
|
||||
};
|
||||
|
||||
use abscissa_core::{Command, Runnable, Shutdown};
|
||||
use anyhow::Result;
|
||||
use comfy_table::Cell;
|
||||
use humantime::format_duration;
|
||||
|
||||
use abscissa_core::{Command, Runnable, Shutdown};
|
||||
|
||||
use itertools::Itertools;
|
||||
|
||||
use rustic_core::DeleteOption;
|
||||
use rustic_core::{ProgressBars, SnapshotFile, SnapshotGroup, SnapshotGroupCriterion};
|
||||
use rustic_core::{DeleteOption, SnapshotFile, SnapshotGroupCriterion};
|
||||
|
||||
/// `snapshot` subcommand
|
||||
#[derive(clap::Parser, Command, Debug)]
|
||||
@ -56,42 +54,13 @@ impl Runnable for SnapshotCmd {
|
||||
}
|
||||
|
||||
impl SnapshotCmd {
|
||||
fn inner_run(&self) -> anyhow::Result<()> {
|
||||
fn inner_run(&self) -> Result<()> {
|
||||
let config = RUSTIC_APP.config();
|
||||
let repo = get_repository(&config).open()?;
|
||||
|
||||
let repo = open_repository(get_repository(&config));
|
||||
|
||||
let p = config.global.progress_options.progress_hidden();
|
||||
let groups = match &self.ids[..] {
|
||||
[] => SnapshotFile::group_from_backend(
|
||||
&repo.dbe,
|
||||
|sn| config.snapshot_filter.matches(sn),
|
||||
&self.group_by,
|
||||
&p,
|
||||
)?,
|
||||
[id] if id == "latest" => SnapshotFile::group_from_backend(
|
||||
&repo.dbe,
|
||||
|sn| config.snapshot_filter.matches(sn),
|
||||
&self.group_by,
|
||||
&p,
|
||||
)?
|
||||
.into_iter()
|
||||
.map(|(group, mut snaps)| {
|
||||
snaps.sort_unstable();
|
||||
let last_idx = snaps.len() - 1;
|
||||
snaps.swap(0, last_idx);
|
||||
snaps.truncate(1);
|
||||
(group, snaps)
|
||||
})
|
||||
.collect::<Vec<_>>(),
|
||||
_ => {
|
||||
let item = (
|
||||
SnapshotGroup::default(),
|
||||
SnapshotFile::from_ids(&repo.dbe, &self.ids, &p)?,
|
||||
);
|
||||
vec![item]
|
||||
}
|
||||
};
|
||||
let groups = repo.get_snapshot_group(&self.ids, self.group_by, |sn| {
|
||||
config.snapshot_filter.matches(sn)
|
||||
})?;
|
||||
|
||||
if self.json {
|
||||
let mut stdout = std::io::stdout();
|
||||
@ -99,6 +68,7 @@ impl SnapshotCmd {
|
||||
return Ok(());
|
||||
}
|
||||
|
||||
let mut total_count = 0;
|
||||
for (group, mut snapshots) in groups {
|
||||
if !group.is_empty() {
|
||||
println!("\nsnapshots for {group}");
|
||||
@ -160,7 +130,10 @@ impl SnapshotCmd {
|
||||
println!("{table}");
|
||||
}
|
||||
println!("{count} snapshot(s)");
|
||||
total_count += count;
|
||||
}
|
||||
println!();
|
||||
println!("total: {total_count} snapshot(s)");
|
||||
|
||||
Ok(())
|
||||
}
|
||||
|
||||
@ -77,10 +77,10 @@ fn test_backup_and_check_passes() -> TestResult<()> {
|
||||
let mut output = String::new();
|
||||
cmd.stdout().read_to_string(&mut output)?;
|
||||
|
||||
let patterns = &["1 snapshot(s)"];
|
||||
let patterns = &["total: 1 snapshot(s)"];
|
||||
let matches = get_matches(patterns, output)?;
|
||||
|
||||
assert_eq!(matches, vec![(PatternID::must(0), 13)]);
|
||||
assert_eq!(matches, vec![(PatternID::must(0), 20)]);
|
||||
|
||||
cmd.wait()?.expect_success();
|
||||
}
|
||||
@ -111,10 +111,10 @@ fn test_backup_and_check_passes() -> TestResult<()> {
|
||||
let mut output = String::new();
|
||||
cmd.stdout().read_to_string(&mut output)?;
|
||||
|
||||
let patterns = &["2 snapshot(s)"];
|
||||
let patterns = &["total: 2 snapshot(s)"];
|
||||
let matches = get_matches(patterns, output)?;
|
||||
|
||||
assert_eq!(matches, vec![(PatternID::must(0), 13)]);
|
||||
assert_eq!(matches, vec![(PatternID::must(0), 20)]);
|
||||
|
||||
cmd.wait()?.expect_success();
|
||||
}
|
||||
|
||||
Loading…
Reference in New Issue
Block a user