mirror of
https://github.com/rustic-rs/rustic.git
synced 2025-10-26 11:18:51 +00:00
Add scriptable snapshot filter option
This commit is contained in:
parent
59b89a8b2d
commit
fa28427126
99
Cargo.lock
generated
99
Cargo.lock
generated
@ -44,6 +44,19 @@ dependencies = [
|
||||
"zeroize",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "ahash"
|
||||
version = "0.8.3"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "2c99f64d1e06488f620f932677e24bc6e2897582980441ae90a671415bd7ec2f"
|
||||
dependencies = [
|
||||
"cfg-if",
|
||||
"const-random",
|
||||
"getrandom",
|
||||
"once_cell",
|
||||
"version_check",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "aho-corasick"
|
||||
version = "0.7.20"
|
||||
@ -326,6 +339,28 @@ dependencies = [
|
||||
"windows-sys 0.42.0",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "const-random"
|
||||
version = "0.1.15"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "368a7a772ead6ce7e1de82bfb04c485f3db8ec744f72925af5735e29a22cc18e"
|
||||
dependencies = [
|
||||
"const-random-macro",
|
||||
"proc-macro-hack",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "const-random-macro"
|
||||
version = "0.1.15"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "9d7d6ab3c3a2282db210df5f02c4dab6e0a7057af0fb7ebd4070f30fe05c0ddb"
|
||||
dependencies = [
|
||||
"getrandom",
|
||||
"once_cell",
|
||||
"proc-macro-hack",
|
||||
"tiny-keccak",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "convert_case"
|
||||
version = "0.4.0"
|
||||
@ -424,6 +459,12 @@ dependencies = [
|
||||
"winapi",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "crunchy"
|
||||
version = "0.2.2"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "7a81dae078cea95a014a339291cec439d2f232ebe854a9d672b796c6afafa9b7"
|
||||
|
||||
[[package]]
|
||||
name = "crypto-common"
|
||||
version = "0.1.6"
|
||||
@ -1497,6 +1538,12 @@ dependencies = [
|
||||
"version_check",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "proc-macro-hack"
|
||||
version = "0.5.20+deprecated"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "dc375e1527247fe1a97d8b7156678dfe7c1af2fc075c9a4db3690ecd2a148068"
|
||||
|
||||
[[package]]
|
||||
name = "proc-macro2"
|
||||
version = "1.0.52"
|
||||
@ -1676,6 +1723,33 @@ dependencies = [
|
||||
"winreg",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "rhai"
|
||||
version = "1.13.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "fd29fa1f740be6dc91982013957e08c3c4232d7efcfe19e12da87d50bad47758"
|
||||
dependencies = [
|
||||
"ahash",
|
||||
"bitflags",
|
||||
"instant",
|
||||
"num-traits",
|
||||
"rhai_codegen",
|
||||
"serde",
|
||||
"smallvec",
|
||||
"smartstring",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "rhai_codegen"
|
||||
version = "1.5.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "db74e3fdd29d969a0ec1f8e79171a6f0f71d0429293656901db382d248c4c021"
|
||||
dependencies = [
|
||||
"proc-macro2",
|
||||
"quote",
|
||||
"syn 1.0.109",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "ring"
|
||||
version = "0.16.20"
|
||||
@ -1793,6 +1867,7 @@ dependencies = [
|
||||
"rand",
|
||||
"rayon",
|
||||
"reqwest",
|
||||
"rhai",
|
||||
"rpassword",
|
||||
"rstest",
|
||||
"scrypt",
|
||||
@ -2093,6 +2168,21 @@ name = "smallvec"
|
||||
version = "1.10.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "a507befe795404456341dfab10cef66ead4c041f62b8b11bbb92bffe5d0953e0"
|
||||
dependencies = [
|
||||
"serde",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "smartstring"
|
||||
version = "1.0.1"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "3fb72c633efbaa2dd666986505016c32c3044395ceaf881518399d2f4127ee29"
|
||||
dependencies = [
|
||||
"autocfg",
|
||||
"serde",
|
||||
"static_assertions",
|
||||
"version_check",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "socket2"
|
||||
@ -2267,6 +2357,15 @@ dependencies = [
|
||||
"time-core",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "tiny-keccak"
|
||||
version = "2.0.2"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "2c9d3793400a45f954c52e73d068316d76b6f4e36977e3fcebb13a2721e80237"
|
||||
dependencies = [
|
||||
"crunchy",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "tinyvec"
|
||||
version = "1.6.0"
|
||||
|
||||
@ -87,7 +87,8 @@ humantime = "2"
|
||||
itertools = "0.10"
|
||||
simplelog = "0.12"
|
||||
comfy-table = "6.1.4"
|
||||
libc="0.2"
|
||||
libc = "0.2"
|
||||
rhai = {version = "1.13", features = ["sync", "serde", "no_optimize", "no_module", "no_custom_syntax", "only_i64"]}
|
||||
|
||||
[target.'cfg(not(windows))'.dependencies]
|
||||
users = "0.11"
|
||||
|
||||
@ -9,6 +9,7 @@ Bugs fixed:
|
||||
|
||||
New features:
|
||||
- Experimental windows support has been added.
|
||||
- New option --filter-fn allows to implement your own snapshot filter using the Rhai language.
|
||||
- New command dump has been added.
|
||||
- New command merge has been added.
|
||||
- Extra or wrong fields in the config file now lead to rustic complaining and aborting.
|
||||
|
||||
@ -114,7 +114,7 @@ impl RcloneBackend {
|
||||
bail!("url must start with http://! url: {url}");
|
||||
}
|
||||
|
||||
let url = "http://".to_string() + &user + ":" + &password + "@" + &url[7..];
|
||||
let url = "http://".to_string() + user.as_str() + ":" + password.as_str() + "@" + &url[7..];
|
||||
|
||||
debug!("using REST backend with url {url}.");
|
||||
let rest = RestBackend::new(&url)?;
|
||||
|
||||
@ -14,6 +14,8 @@ use itertools::Itertools;
|
||||
use log::*;
|
||||
use merge::Merge;
|
||||
use path_dedot::ParseDot;
|
||||
use rhai::serde::to_dynamic;
|
||||
use rhai::{Dynamic, Engine, FnPtr, AST};
|
||||
use serde::{Deserialize, Serialize};
|
||||
use serde_with::{serde_as, DisplayFromStr};
|
||||
|
||||
@ -339,6 +341,19 @@ impl SnapshotFile {
|
||||
}
|
||||
|
||||
pub fn matches(&self, filter: &SnapshotFilter) -> bool {
|
||||
if let Some(filter_fn) = &filter.filter_fn {
|
||||
match filter_fn.call::<bool>(self) {
|
||||
Ok(result) => {
|
||||
if !result {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
Err(err) => {
|
||||
warn!("Error evaluating filter-fn for snapshot {}: {err}", self.id);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
self.paths.matches(&filter.filter_paths)
|
||||
&& self.tags.matches(&filter.filter_tags)
|
||||
&& (filter.filter_host.is_empty() || filter.filter_host.contains(&self.hostname))
|
||||
@ -404,6 +419,25 @@ impl Ord for SnapshotFile {
|
||||
}
|
||||
}
|
||||
|
||||
struct SnapshotFn(FnPtr, AST);
|
||||
impl FromStr for SnapshotFn {
|
||||
type Err = anyhow::Error;
|
||||
fn from_str(s: &str) -> Result<Self> {
|
||||
let engine = Engine::new();
|
||||
let ast = engine.compile(s)?;
|
||||
let func = engine.eval_ast::<FnPtr>(&ast)?;
|
||||
Ok(Self(func, ast))
|
||||
}
|
||||
}
|
||||
|
||||
impl SnapshotFn {
|
||||
fn call<T: Clone + Send + Sync + 'static>(&self, sn: &SnapshotFile) -> Result<T> {
|
||||
let engine = Engine::new();
|
||||
let sn: Dynamic = to_dynamic(sn)?;
|
||||
Ok(self.0.call::<T>(&engine, &self.1, (sn,))?)
|
||||
}
|
||||
}
|
||||
|
||||
#[serde_as]
|
||||
#[derive(Default, Parser, Deserialize, Merge)]
|
||||
#[serde(default, rename_all = "kebab-case", deny_unknown_fields)]
|
||||
@ -429,6 +463,11 @@ pub struct SnapshotFilter {
|
||||
#[serde_as(as = "Vec<DisplayFromStr>")]
|
||||
#[merge(strategy=merge::vec::overwrite_empty)]
|
||||
filter_tags: Vec<StringList>,
|
||||
|
||||
/// Function to filter snapshots
|
||||
#[clap(long, value_name = "FUNC")]
|
||||
#[serde_as(as = "Option<DisplayFromStr>")]
|
||||
filter_fn: Option<SnapshotFn>,
|
||||
}
|
||||
|
||||
#[derive(Clone, Default, Deserialize)]
|
||||
|
||||
Loading…
Reference in New Issue
Block a user