diff --git a/README.md b/README.md index 62e3175a..89d3c15e 100644 --- a/README.md +++ b/README.md @@ -50,7 +50,7 @@ This crate exposes a few features for controlling dependency usage: - **cli** - Enables support for CLI features by enabling `merge` and `clap` features. *This feature is disabled by default*. - **merge** - Enables support for merging multiple values into one, which - enables the `merge` dependency. This is needed for parsing commandline + enables the `conflate` dependency. This is needed for parsing commandline arguments and merging them into one (e.g. `config`). *This feature is disabled by default*. - **clap** - Enables a dependency on the `clap` crate and enables parsing from diff --git a/crates/backend/Cargo.toml b/crates/backend/Cargo.toml index b4234f0c..5ddb8ade 100644 --- a/crates/backend/Cargo.toml +++ b/crates/backend/Cargo.toml @@ -33,7 +33,7 @@ edition = "2021" [features] default = ["opendal", "rest", "rclone"] cli = ["merge", "clap"] -merge = ["dep:merge"] +merge = ["dep:conflate"] clap = ["dep:clap"] opendal = ["dep:opendal", "dep:rayon", "dep:tokio", "tokio/rt-multi-thread"] rest = ["dep:reqwest", "dep:backoff"] @@ -66,7 +66,7 @@ url = "2.5.2" # cli support clap = { version = "4.5.16", optional = true, features = ["derive", "env", "wrap_help"] } -merge = { version = "0.1.0", optional = true } +conflate = { version = "0.2.0", optional = true } # local backend aho-corasick = { workspace = true } diff --git a/crates/backend/README.md b/crates/backend/README.md index 20422223..11078ac8 100644 --- a/crates/backend/README.md +++ b/crates/backend/README.md @@ -58,7 +58,7 @@ This crate exposes a few features for controlling dependency usage: the commandline. *This feature is disabled by default*. - **merge** - Enables support for merging multiple values into one, which - enables the `merge` dependency. This is needed for parsing commandline + enables the `conflate` dependency. This is needed for parsing commandline arguments and merging them into one (e.g. `config`). *This feature is disabled by default*. diff --git a/crates/backend/src/choose.rs b/crates/backend/src/choose.rs index 62f7fb88..7dbd425e 100644 --- a/crates/backend/src/choose.rs +++ b/crates/backend/src/choose.rs @@ -27,7 +27,7 @@ use clap::ValueHint; /// Options for a backend. #[cfg_attr(feature = "clap", derive(clap::Parser))] -#[cfg_attr(feature = "merge", derive(merge::Merge))] +#[cfg_attr(feature = "merge", derive(conflate::Merge))] #[derive(Clone, Default, Debug, serde::Deserialize, serde::Serialize, Setters)] #[serde(default, rename_all = "kebab-case", deny_unknown_fields)] #[setters(into, strip_option)] @@ -37,6 +37,7 @@ pub struct BackendOptions { feature = "clap", clap(short, long, global = true, visible_alias = "repo", env = "RUSTIC_REPOSITORY", value_hint = ValueHint::DirPath) )] + #[cfg_attr(feature = "merge", merge(strategy = conflate::option::overwrite_none))] pub repository: Option, /// Repository to use as hot storage @@ -44,6 +45,7 @@ pub struct BackendOptions { feature = "clap", clap(long, global = true, alias = "repository_hot", env = "RUSTIC_REPO_HOT") )] + #[cfg_attr(feature = "merge", merge(strategy = conflate::option::overwrite_none))] pub repo_hot: Option, /// Other options for this repository (hot and cold part) diff --git a/crates/core/Cargo.toml b/crates/core/Cargo.toml index 7119afd3..bfb5df6b 100644 --- a/crates/core/Cargo.toml +++ b/crates/core/Cargo.toml @@ -31,7 +31,7 @@ edition = "2021" [features] default = [] cli = ["merge", "clap"] -merge = ["dep:merge"] +merge = ["dep:conflate"] clap = ["dep:clap"] webdav = ["dep:dav-server", "dep:futures"] @@ -87,7 +87,7 @@ dirs = "5.0.1" # cli support clap = { version = "4.5.16", optional = true, features = ["derive", "env", "wrap_help"] } -merge = { version = "0.1.0", optional = true } +conflate = { version = "0.2.0", optional = true } # vfs support dav-server = { version = "0.7.0", default-features = false, optional = true } diff --git a/crates/core/src/backend/ignore.rs b/crates/core/src/backend/ignore.rs index 4f437625..fa191f3a 100644 --- a/crates/core/src/backend/ignore.rs +++ b/crates/core/src/backend/ignore.rs @@ -42,7 +42,7 @@ pub struct LocalSource { #[serde_as] #[cfg_attr(feature = "clap", derive(clap::Parser))] -#[cfg_attr(feature = "merge", derive(merge::Merge))] +#[cfg_attr(feature = "merge", derive(conflate::Merge))] #[derive(serde::Deserialize, serde::Serialize, Default, Clone, Copy, Debug, Setters)] #[serde(default, rename_all = "kebab-case", deny_unknown_fields)] #[setters(into)] @@ -50,18 +50,18 @@ pub struct LocalSource { pub struct LocalSourceSaveOptions { /// Save access time for files and directories #[cfg_attr(feature = "clap", clap(long))] - #[cfg_attr(feature = "merge", merge(strategy = merge::bool::overwrite_false))] + #[cfg_attr(feature = "merge", merge(strategy = conflate::bool::overwrite_false))] pub with_atime: bool, /// Don't save device ID for files and directories #[cfg_attr(feature = "clap", clap(long))] - #[cfg_attr(feature = "merge", merge(strategy = merge::bool::overwrite_false))] + #[cfg_attr(feature = "merge", merge(strategy = conflate::bool::overwrite_false))] pub ignore_devid: bool, } #[serde_as] #[cfg_attr(feature = "clap", derive(clap::Parser))] -#[cfg_attr(feature = "merge", derive(merge::Merge))] +#[cfg_attr(feature = "merge", derive(conflate::Merge))] #[derive(serde::Deserialize, serde::Serialize, Default, Clone, Debug, Setters)] #[serde(default, rename_all = "kebab-case", deny_unknown_fields)] #[setters(into)] @@ -69,32 +69,32 @@ pub struct LocalSourceSaveOptions { pub struct LocalSourceFilterOptions { /// Glob pattern to exclude/include (can be specified multiple times) #[cfg_attr(feature = "clap", clap(long = "glob", value_name = "GLOB"))] - #[cfg_attr(feature = "merge", merge(strategy = merge::vec::overwrite_empty))] + #[cfg_attr(feature = "merge", merge(strategy = conflate::vec::overwrite_empty))] pub globs: Vec, /// Same as --glob pattern but ignores the casing of filenames #[cfg_attr(feature = "clap", clap(long = "iglob", value_name = "GLOB"))] - #[cfg_attr(feature = "merge", merge(strategy = merge::vec::overwrite_empty))] + #[cfg_attr(feature = "merge", merge(strategy = conflate::vec::overwrite_empty))] pub iglobs: Vec, /// Read glob patterns to exclude/include from this file (can be specified multiple times) #[cfg_attr(feature = "clap", clap(long = "glob-file", value_name = "FILE"))] - #[cfg_attr(feature = "merge", merge(strategy = merge::vec::overwrite_empty))] + #[cfg_attr(feature = "merge", merge(strategy = conflate::vec::overwrite_empty))] pub glob_files: Vec, /// Same as --glob-file ignores the casing of filenames in patterns #[cfg_attr(feature = "clap", clap(long = "iglob-file", value_name = "FILE"))] - #[cfg_attr(feature = "merge", merge(strategy = merge::vec::overwrite_empty))] + #[cfg_attr(feature = "merge", merge(strategy = conflate::vec::overwrite_empty))] pub iglob_files: Vec, /// Ignore files based on .gitignore files #[cfg_attr(feature = "clap", clap(long))] - #[cfg_attr(feature = "merge", merge(strategy = merge::bool::overwrite_false))] + #[cfg_attr(feature = "merge", merge(strategy = conflate::bool::overwrite_false))] pub git_ignore: bool, /// Do not require a git repository to apply git-ignore rule #[cfg_attr(feature = "clap", clap(long))] - #[cfg_attr(feature = "merge", merge(strategy = merge::bool::overwrite_false))] + #[cfg_attr(feature = "merge", merge(strategy = conflate::bool::overwrite_false))] pub no_require_git: bool, /// Treat the provided filename like a .gitignore file (can be specified multiple times) @@ -102,22 +102,23 @@ pub struct LocalSourceFilterOptions { feature = "clap", clap(long = "custom-ignorefile", value_name = "FILE") )] - #[cfg_attr(feature = "merge", merge(strategy = merge::vec::overwrite_empty))] + #[cfg_attr(feature = "merge", merge(strategy = conflate::vec::overwrite_empty))] pub custom_ignorefiles: Vec, /// Exclude contents of directories containing this filename (can be specified multiple times) #[cfg_attr(feature = "clap", clap(long, value_name = "FILE"))] - #[cfg_attr(feature = "merge", merge(strategy = merge::vec::overwrite_empty))] + #[cfg_attr(feature = "merge", merge(strategy = conflate::vec::overwrite_empty))] pub exclude_if_present: Vec, /// Exclude other file systems, don't cross filesystem boundaries and subvolumes #[cfg_attr(feature = "clap", clap(long, short = 'x'))] - #[cfg_attr(feature = "merge", merge(strategy = merge::bool::overwrite_false))] + #[cfg_attr(feature = "merge", merge(strategy = conflate::bool::overwrite_false))] pub one_file_system: bool, /// Maximum size of files to be backed up. Larger files will be excluded. #[cfg_attr(feature = "clap", clap(long, value_name = "SIZE"))] #[serde_as(as = "Option")] + #[cfg_attr(feature = "merge", merge(strategy = conflate::option::overwrite_none))] pub exclude_larger_than: Option, } diff --git a/crates/core/src/commands/backup.rs b/crates/core/src/commands/backup.rs index 5b5cc449..1d6b60d0 100644 --- a/crates/core/src/commands/backup.rs +++ b/crates/core/src/commands/backup.rs @@ -32,7 +32,7 @@ use clap::ValueHint; /// `backup` subcommand #[serde_as] #[cfg_attr(feature = "clap", derive(clap::Parser))] -#[cfg_attr(feature = "merge", derive(merge::Merge))] +#[cfg_attr(feature = "merge", derive(conflate::Merge))] #[derive(Clone, Default, Debug, Deserialize, Serialize, Setters)] #[serde(default, rename_all = "kebab-case", deny_unknown_fields)] #[setters(into)] @@ -43,6 +43,7 @@ pub struct ParentOptions { /// Group snapshots by any combination of host,label,paths,tags to find a suitable parent (default: host,label,paths) #[cfg_attr(feature = "clap", clap(long, short = 'g', value_name = "CRITERION",))] #[serde_as(as = "Option")] + #[cfg_attr(feature = "merge", merge(strategy = conflate::option::overwrite_none))] pub group_by: Option, /// Snapshot to use as parent @@ -50,26 +51,27 @@ pub struct ParentOptions { feature = "clap", clap(long, value_name = "SNAPSHOT", conflicts_with = "force",) )] + #[cfg_attr(feature = "merge", merge(strategy = conflate::option::overwrite_none))] pub parent: Option, /// Skip writing of snapshot if nothing changed w.r.t. the parent snapshot. #[cfg_attr(feature = "clap", clap(long))] - #[cfg_attr(feature = "merge", merge(strategy = merge::bool::overwrite_false))] + #[cfg_attr(feature = "merge", merge(strategy = conflate::bool::overwrite_false))] pub skip_identical_parent: bool, /// Use no parent, read all files #[cfg_attr(feature = "clap", clap(long, short, conflicts_with = "parent",))] - #[cfg_attr(feature = "merge", merge(strategy = merge::bool::overwrite_false))] + #[cfg_attr(feature = "merge", merge(strategy = conflate::bool::overwrite_false))] pub force: bool, /// Ignore ctime changes when checking for modified files #[cfg_attr(feature = "clap", clap(long, conflicts_with = "force",))] - #[cfg_attr(feature = "merge", merge(strategy = merge::bool::overwrite_false))] + #[cfg_attr(feature = "merge", merge(strategy = conflate::bool::overwrite_false))] pub ignore_ctime: bool, /// Ignore inode number changes when checking for modified files #[cfg_attr(feature = "clap", clap(long, conflicts_with = "force",))] - #[cfg_attr(feature = "merge", merge(strategy = merge::bool::overwrite_false))] + #[cfg_attr(feature = "merge", merge(strategy = conflate::bool::overwrite_false))] pub ignore_inode: bool, } @@ -127,7 +129,7 @@ impl ParentOptions { } #[cfg_attr(feature = "clap", derive(clap::Parser))] -#[cfg_attr(feature = "merge", derive(merge::Merge))] +#[cfg_attr(feature = "merge", derive(conflate::Merge))] #[derive(Clone, Default, Debug, Deserialize, Serialize, Setters)] #[serde(default, rename_all = "kebab-case", deny_unknown_fields)] #[setters(into)] @@ -144,20 +146,22 @@ pub struct BackupOptions { /// Call the given command and use its output as stdin #[cfg_attr(feature = "clap", clap(long, value_name = "COMMAND"))] + #[cfg_attr(feature = "merge", merge(strategy = conflate::option::overwrite_none))] pub stdin_command: Option, /// Manually set backup path in snapshot #[cfg_attr(feature = "clap", clap(long, value_name = "PATH", value_hint = ValueHint::DirPath))] + #[cfg_attr(feature = "merge", merge(strategy = conflate::option::overwrite_none))] pub as_path: Option, /// Don't scan the backup source for its size - this disables ETA estimation for backup. #[cfg_attr(feature = "clap", clap(long))] - #[cfg_attr(feature = "merge", merge(strategy = merge::bool::overwrite_false))] + #[cfg_attr(feature = "merge", merge(strategy = conflate::bool::overwrite_false))] pub no_scan: bool, /// Dry-run mode: Don't write any data or snapshot #[cfg_attr(feature = "clap", clap(long))] - #[cfg_attr(feature = "merge", merge(strategy = merge::bool::overwrite_false))] + #[cfg_attr(feature = "merge", merge(strategy = conflate::bool::overwrite_false))] pub dry_run: bool, #[cfg_attr(feature = "clap", clap(flatten))] diff --git a/crates/core/src/commands/forget.rs b/crates/core/src/commands/forget.rs index 4fe4db07..0bfd4c42 100644 --- a/crates/core/src/commands/forget.rs +++ b/crates/core/src/commands/forget.rs @@ -100,7 +100,7 @@ pub(crate) fn get_forget_snapshots( } #[cfg_attr(feature = "clap", derive(clap::Parser))] -#[cfg_attr(feature = "merge", derive(merge::Merge))] +#[cfg_attr(feature = "merge", derive(conflate::Merge))] #[skip_serializing_none] #[serde_as] #[derive(Clone, Debug, PartialEq, Eq, Default, Serialize, Deserialize, Setters)] @@ -111,14 +111,14 @@ pub(crate) fn get_forget_snapshots( pub struct KeepOptions { /// Keep snapshots with this taglist (can be specified multiple times) #[cfg_attr(feature = "clap", clap(long, value_name = "TAG[,TAG,..]"))] - #[cfg_attr(feature = "merge", merge(strategy=merge::vec::overwrite_empty))] + #[cfg_attr(feature = "merge", merge(strategy=conflate::vec::overwrite_empty))] #[serde_as(as = "Vec")] #[serde(skip_serializing_if = "Vec::is_empty")] pub keep_tags: Vec, /// Keep snapshots ids that start with ID (can be specified multiple times) #[cfg_attr(feature = "clap", clap(long = "keep-id", value_name = "ID"))] - #[cfg_attr(feature = "merge", merge(strategy=merge::vec::overwrite_empty))] + #[cfg_attr(feature = "merge", merge(strategy=conflate::vec::overwrite_empty))] #[serde(skip_serializing_if = "Vec::is_empty")] pub keep_ids: Vec, @@ -127,6 +127,7 @@ pub struct KeepOptions { feature = "clap", clap(long, short = 'l', value_name = "N", allow_hyphen_values = true, value_parser = clap::value_parser!(i32).range(-1..)) )] + #[cfg_attr(feature = "merge", merge(strategy = conflate::option::overwrite_none))] pub keep_last: Option, /// Keep the last N hourly snapshots (N == -1: keep all hourly snapshots) @@ -134,6 +135,7 @@ pub struct KeepOptions { feature = "clap", clap(long, short = 'H', value_name = "N", allow_hyphen_values = true, value_parser = clap::value_parser!(i32).range(-1..)) )] + #[cfg_attr(feature = "merge", merge(strategy = conflate::option::overwrite_none))] pub keep_hourly: Option, /// Keep the last N daily snapshots (N == -1: keep all daily snapshots) @@ -141,6 +143,7 @@ pub struct KeepOptions { feature = "clap", clap(long, short = 'd', value_name = "N", allow_hyphen_values = true, value_parser = clap::value_parser!(i32).range(-1..)) )] + #[cfg_attr(feature = "merge", merge(strategy = conflate::option::overwrite_none))] pub keep_daily: Option, /// Keep the last N weekly snapshots (N == -1: keep all weekly snapshots) @@ -148,6 +151,7 @@ pub struct KeepOptions { feature = "clap", clap(long, short = 'w', value_name = "N", allow_hyphen_values = true, value_parser = clap::value_parser!(i32).range(-1..)) )] + #[cfg_attr(feature = "merge", merge(strategy = conflate::option::overwrite_none))] pub keep_weekly: Option, /// Keep the last N monthly snapshots (N == -1: keep all monthly snapshots) @@ -155,6 +159,7 @@ pub struct KeepOptions { feature = "clap", clap(long, short = 'm', value_name = "N", allow_hyphen_values = true, value_parser = clap::value_parser!(i32).range(-1..)) )] + #[cfg_attr(feature = "merge", merge(strategy = conflate::option::overwrite_none))] pub keep_monthly: Option, /// Keep the last N quarter-yearly snapshots (N == -1: keep all quarter-yearly snapshots) @@ -162,6 +167,7 @@ pub struct KeepOptions { feature = "clap", clap(long, value_name = "N", allow_hyphen_values = true, value_parser = clap::value_parser!(i32).range(-1..)) )] + #[cfg_attr(feature = "merge", merge(strategy = conflate::option::overwrite_none))] pub keep_quarter_yearly: Option, /// Keep the last N half-yearly snapshots (N == -1: keep all half-yearly snapshots) @@ -169,6 +175,7 @@ pub struct KeepOptions { feature = "clap", clap(long, value_name = "N", allow_hyphen_values = true, value_parser = clap::value_parser!(i32).range(-1..)) )] + #[cfg_attr(feature = "merge", merge(strategy = conflate::option::overwrite_none))] pub keep_half_yearly: Option, /// Keep the last N yearly snapshots (N == -1: keep all yearly snapshots) @@ -176,51 +183,60 @@ pub struct KeepOptions { feature = "clap", clap(long, short = 'y', value_name = "N", allow_hyphen_values = true, value_parser = clap::value_parser!(i32).range(-1..)) )] + #[cfg_attr(feature = "merge", merge(strategy = conflate::option::overwrite_none))] pub keep_yearly: Option, /// Keep snapshots newer than DURATION relative to latest snapshot #[cfg_attr(feature = "clap", clap(long, value_name = "DURATION"))] #[serde_as(as = "Option")] + #[cfg_attr(feature = "merge", merge(strategy = conflate::option::overwrite_none))] pub keep_within: Option, /// Keep hourly snapshots newer than DURATION relative to latest snapshot #[cfg_attr(feature = "clap", clap(long, value_name = "DURATION"))] #[serde_as(as = "Option")] + #[cfg_attr(feature = "merge", merge(strategy = conflate::option::overwrite_none))] pub keep_within_hourly: Option, /// Keep daily snapshots newer than DURATION relative to latest snapshot #[cfg_attr(feature = "clap", clap(long, value_name = "DURATION"))] #[serde_as(as = "Option")] + #[cfg_attr(feature = "merge", merge(strategy = conflate::option::overwrite_none))] pub keep_within_daily: Option, /// Keep weekly snapshots newer than DURATION relative to latest snapshot #[cfg_attr(feature = "clap", clap(long, value_name = "DURATION"))] #[serde_as(as = "Option")] + #[cfg_attr(feature = "merge", merge(strategy = conflate::option::overwrite_none))] pub keep_within_weekly: Option, /// Keep monthly snapshots newer than DURATION relative to latest snapshot #[cfg_attr(feature = "clap", clap(long, value_name = "DURATION"))] #[serde_as(as = "Option")] + #[cfg_attr(feature = "merge", merge(strategy = conflate::option::overwrite_none))] pub keep_within_monthly: Option, /// Keep quarter-yearly snapshots newer than DURATION relative to latest snapshot #[cfg_attr(feature = "clap", clap(long, value_name = "DURATION"))] #[serde_as(as = "Option")] + #[cfg_attr(feature = "merge", merge(strategy = conflate::option::overwrite_none))] pub keep_within_quarter_yearly: Option, /// Keep half-yearly snapshots newer than DURATION relative to latest snapshot #[cfg_attr(feature = "clap", clap(long, value_name = "DURATION"))] #[serde_as(as = "Option")] + #[cfg_attr(feature = "merge", merge(strategy = conflate::option::overwrite_none))] pub keep_within_half_yearly: Option, /// Keep yearly snapshots newer than DURATION relative to latest snapshot #[cfg_attr(feature = "clap", clap(long, value_name = "DURATION"))] #[serde_as(as = "Option")] + #[cfg_attr(feature = "merge", merge(strategy = conflate::option::overwrite_none))] pub keep_within_yearly: Option, /// Allow to keep no snapshot #[cfg_attr(feature = "clap", clap(long))] - #[cfg_attr(feature = "merge", merge(strategy=merge::bool::overwrite_false))] + #[cfg_attr(feature = "merge", merge(strategy=conflate::bool::overwrite_false))] #[serde(skip_serializing_if = "std::ops::Not::not")] pub keep_none: bool, } diff --git a/crates/core/src/repofile/snapshotfile.rs b/crates/core/src/repofile/snapshotfile.rs index 035c32b3..5141aa54 100644 --- a/crates/core/src/repofile/snapshotfile.rs +++ b/crates/core/src/repofile/snapshotfile.rs @@ -36,14 +36,14 @@ use clap::ValueHint; /// /// # Features /// -/// * With the feature `merge` enabled, this also derives [`merge::Merge`] to allow merging [`SnapshotOptions`] from multiple sources. +/// * With the feature `merge` enabled, this also derives [`conflate::Merge`] to allow merging [`SnapshotOptions`] from multiple sources. /// * With the feature `clap` enabled, this also derives [`clap::Parser`] allowing it to be used as CLI options. /// /// # Note /// /// The preferred way is to use [`SnapshotFile::from_options`] to create a SnapshotFile for a new backup. #[serde_as] -#[cfg_attr(feature = "merge", derive(merge::Merge))] +#[cfg_attr(feature = "merge", derive(conflate::Merge))] #[cfg_attr(feature = "clap", derive(clap::Parser))] #[derive(Deserialize, Serialize, Clone, Default, Debug, Setters)] #[serde(default, rename_all = "kebab-case", deny_unknown_fields)] @@ -52,16 +52,18 @@ use clap::ValueHint; pub struct SnapshotOptions { /// Label snapshot with given label #[cfg_attr(feature = "clap", clap(long, value_name = "LABEL"))] + #[cfg_attr(feature = "merge", merge(strategy = conflate::option::overwrite_none))] pub label: Option, /// Tags to add to snapshot (can be specified multiple times) #[serde_as(as = "Vec")] #[cfg_attr(feature = "clap", clap(long = "tag", value_name = "TAG[,TAG,..]"))] - #[cfg_attr(feature = "merge", merge(strategy = merge::vec::overwrite_empty))] + #[cfg_attr(feature = "merge", merge(strategy = conflate::vec::overwrite_empty))] pub tags: Vec, /// Add description to snapshot #[cfg_attr(feature = "clap", clap(long, value_name = "DESCRIPTION"))] + #[cfg_attr(feature = "merge", merge(strategy = conflate::option::overwrite_none))] pub description: Option, /// Add description to snapshot from file @@ -69,28 +71,33 @@ pub struct SnapshotOptions { feature = "clap", clap(long, value_name = "FILE", conflicts_with = "description", value_hint = ValueHint::FilePath) )] + #[cfg_attr(feature = "merge", merge(strategy = conflate::option::overwrite_none))] pub description_from: Option, /// Set the backup time manually #[cfg_attr(feature = "clap", clap(long))] + #[cfg_attr(feature = "merge", merge(strategy = conflate::option::overwrite_none))] pub time: Option>, /// Mark snapshot as uneraseable #[cfg_attr(feature = "clap", clap(long, conflicts_with = "delete_after"))] - #[cfg_attr(feature = "merge", merge(strategy = merge::bool::overwrite_false))] + #[cfg_attr(feature = "merge", merge(strategy = conflate::bool::overwrite_false))] pub delete_never: bool, /// Mark snapshot to be deleted after given duration (e.g. 10d) #[cfg_attr(feature = "clap", clap(long, value_name = "DURATION"))] #[serde_as(as = "Option")] + #[cfg_attr(feature = "merge", merge(strategy = conflate::option::overwrite_none))] pub delete_after: Option, /// Set the host name manually #[cfg_attr(feature = "clap", clap(long, value_name = "NAME"))] + #[cfg_attr(feature = "merge", merge(strategy = conflate::option::overwrite_none))] pub host: Option, /// Set the backup command manually #[cfg_attr(feature = "clap", clap(long))] + #[cfg_attr(feature = "merge", merge(strategy = conflate::option::overwrite_none))] pub command: Option, } diff --git a/crates/core/src/repository.rs b/crates/core/src/repository.rs index 81ae9d16..f098f1fe 100644 --- a/crates/core/src/repository.rs +++ b/crates/core/src/repository.rs @@ -80,7 +80,7 @@ mod constants { /// Options for using and opening a [`Repository`] #[serde_as] #[cfg_attr(feature = "clap", derive(clap::Parser))] -#[cfg_attr(feature = "merge", derive(merge::Merge))] +#[cfg_attr(feature = "merge", derive(conflate::Merge))] #[derive(Clone, Default, Debug, serde::Deserialize, serde::Serialize, Setters)] #[serde(default, rename_all = "kebab-case", deny_unknown_fields)] #[setters(into, strip_option)] @@ -95,6 +95,7 @@ pub struct RepositoryOptions { clap(long, global = true, env = "RUSTIC_PASSWORD", hide_env_values = true) )] // TODO: Security related: use `secrecy` library (#663) + #[cfg_attr(feature = "merge", merge(strategy = conflate::option::overwrite_none))] pub password: Option, /// File to read the password from @@ -109,6 +110,7 @@ pub struct RepositoryOptions { value_hint = ValueHint::FilePath, ) )] + #[cfg_attr(feature = "merge", merge(strategy = conflate::option::overwrite_none))] pub password_file: Option, /// Command to read the password from. Password is read from stdout @@ -118,11 +120,12 @@ pub struct RepositoryOptions { env = "RUSTIC_PASSWORD_COMMAND", conflicts_with_all = &["password", "password_file"], ))] + #[cfg_attr(feature = "merge", merge(strategy = conflate::option::overwrite_none))] pub password_command: Option, /// Don't use a cache. #[cfg_attr(feature = "clap", clap(long, global = true, env = "RUSTIC_NO_CACHE"))] - #[cfg_attr(feature = "merge", merge(strategy = merge::bool::overwrite_false))] + #[cfg_attr(feature = "merge", merge(strategy = conflate::bool::overwrite_false))] pub no_cache: bool, /// Use this dir as cache dir instead of the standard cache dir @@ -136,11 +139,12 @@ pub struct RepositoryOptions { value_hint = ValueHint::DirPath, ) )] + #[cfg_attr(feature = "merge", merge(strategy = conflate::option::overwrite_none))] pub cache_dir: Option, /// Warm up needed data pack files by only requesting them without processing #[cfg_attr(feature = "clap", clap(long, global = true))] - #[cfg_attr(feature = "merge", merge(strategy = merge::bool::overwrite_false))] + #[cfg_attr(feature = "merge", merge(strategy = conflate::bool::overwrite_false))] pub warm_up: bool, /// Warm up needed data pack files by running the command with %id replaced by pack id @@ -148,11 +152,13 @@ pub struct RepositoryOptions { feature = "clap", clap(long, global = true, conflicts_with = "warm_up",) )] + #[cfg_attr(feature = "merge", merge(strategy = conflate::option::overwrite_none))] pub warm_up_command: Option, /// Duration (e.g. 10m) to wait after warm up #[cfg_attr(feature = "clap", clap(long, global = true, value_name = "DURATION"))] #[serde_as(as = "Option")] + #[cfg_attr(feature = "merge", merge(strategy = conflate::option::overwrite_none))] pub warm_up_wait: Option, }