refactor: use BTreeMap for env in global options (#1360)

Signed-off-by: simonsan <14062932+simonsan@users.noreply.github.com>

---------

Signed-off-by: simonsan <14062932+simonsan@users.noreply.github.com>
Co-authored-by: nardoor <102725206+nardoor@users.noreply.github.com>
This commit is contained in:
simonsan 2024-11-19 22:20:55 +01:00 committed by GitHub
parent 47426dbfb4
commit 99d28fa0c3
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
5 changed files with 541 additions and 5 deletions

View File

@ -7,8 +7,11 @@
pub(crate) mod hooks;
pub(crate) mod progress_options;
use std::fmt::Debug;
use std::{collections::HashMap, path::PathBuf};
use std::{
collections::BTreeMap,
fmt::{self, Display, Formatter},
path::PathBuf,
};
use abscissa_core::{config::Config, path::AbsPathBuf, FrameworkError};
use anyhow::Result;
@ -83,6 +86,15 @@ pub struct RusticConfig {
pub webdav: Option<Value>,
}
impl Display for RusticConfig {
fn fmt(&self, f: &mut Formatter<'_>) -> fmt::Result {
let config = toml::to_string_pretty(self)
.unwrap_or_else(|_| "<Error serializing config>".to_string());
write!(f, "{config}",)
}
}
impl RusticConfig {
/// Merge a profile into the current config by reading the corresponding config file.
/// Also recursively merge all profiles given within this config file.
@ -176,8 +188,8 @@ pub struct GlobalOptions {
/// List of environment variables to set (only in config file)
#[clap(skip)]
#[merge(strategy = conflate::hashmap::append_or_ignore)]
pub env: HashMap<String, String>,
#[merge(strategy = conflate::btreemap::append_or_ignore)]
pub env: BTreeMap<String, String>,
}
/// Get the paths to the config file
@ -245,7 +257,7 @@ fn get_global_config_path() -> Option<PathBuf> {
#[cfg(test)]
mod tests {
use super::*;
use insta::assert_debug_snapshot;
use insta::{assert_debug_snapshot, assert_snapshot};
#[test]
fn test_default_config_passes() {
@ -253,4 +265,35 @@ mod tests {
assert_debug_snapshot!(config);
}
#[test]
fn test_default_config_display_passes() {
let config = RusticConfig::default();
assert_snapshot!(config);
}
#[test]
fn test_global_env_roundtrip_passes() {
let mut config = RusticConfig::default();
for i in 0..10 {
let _ = config
.global
.env
.insert(format!("KEY{}", i), format!("VALUE{}", i));
}
let serialized = toml::to_string(&config).unwrap();
// Check Serialization
assert_snapshot!(serialized);
let deserialized: RusticConfig = toml::from_str(&serialized).unwrap();
// Check Deserialization and Display
assert_snapshot!(deserialized);
// Check Debug
assert_debug_snapshot!(deserialized);
}
}

View File

@ -0,0 +1,89 @@
---
source: src/config.rs
expression: config
---
[global]
use-profiles = []
dry-run = false
check-index = false
no-progress = false
[global.hooks]
run-before = []
run-after = []
run-failed = []
run-finally = []
[global.env]
[repository]
no-cache = false
warm-up = false
[repository.options]
[repository.options-hot]
[repository.options-cold]
[repository.hooks]
run-before = []
run-after = []
run-failed = []
run-finally = []
[snapshot-filter]
filter-hosts = []
filter-labels = []
filter-paths = []
filter-paths-exact = []
filter-tags = []
filter-tags-exact = []
[backup]
stdin-filename = ""
with-atime = false
ignore-devid = false
no-scan = false
json = false
long = false
quiet = false
init = false
skip-identical-parent = false
force = false
ignore-ctime = false
ignore-inode = false
globs = []
iglobs = []
glob-files = []
iglob-files = []
git-ignore = false
no-require-git = false
custom-ignorefiles = []
exclude-if-present = []
one-file-system = false
tags = []
delete-never = false
snapshots = []
sources = []
[backup.hooks]
run-before = []
run-after = []
run-failed = []
run-finally = []
[copy]
targets = []
[forget]
prune = false
filter-hosts = []
filter-labels = []
filter-paths = []
filter-paths-exact = []
filter-tags = []
filter-tags-exact = []
[webdav]
symlinks = false

View File

@ -0,0 +1,99 @@
---
source: src/config.rs
expression: deserialized
---
[global]
use-profiles = []
dry-run = false
check-index = false
no-progress = false
[global.hooks]
run-before = []
run-after = []
run-failed = []
run-finally = []
[global.env]
KEY0 = "VALUE0"
KEY1 = "VALUE1"
KEY2 = "VALUE2"
KEY3 = "VALUE3"
KEY4 = "VALUE4"
KEY5 = "VALUE5"
KEY6 = "VALUE6"
KEY7 = "VALUE7"
KEY8 = "VALUE8"
KEY9 = "VALUE9"
[repository]
no-cache = false
warm-up = false
[repository.options]
[repository.options-hot]
[repository.options-cold]
[repository.hooks]
run-before = []
run-after = []
run-failed = []
run-finally = []
[snapshot-filter]
filter-hosts = []
filter-labels = []
filter-paths = []
filter-paths-exact = []
filter-tags = []
filter-tags-exact = []
[backup]
stdin-filename = ""
with-atime = false
ignore-devid = false
no-scan = false
json = false
long = false
quiet = false
init = false
skip-identical-parent = false
force = false
ignore-ctime = false
ignore-inode = false
globs = []
iglobs = []
glob-files = []
iglob-files = []
git-ignore = false
no-require-git = false
custom-ignorefiles = []
exclude-if-present = []
one-file-system = false
tags = []
delete-never = false
snapshots = []
sources = []
[backup.hooks]
run-before = []
run-after = []
run-failed = []
run-finally = []
[copy]
targets = []
[forget]
prune = false
filter-hosts = []
filter-labels = []
filter-paths = []
filter-paths-exact = []
filter-tags = []
filter-tags-exact = []
[webdav]
symlinks = false

View File

@ -0,0 +1,206 @@
---
source: src/config.rs
expression: deserialized
---
RusticConfig {
global: GlobalOptions {
use_profiles: [],
dry_run: false,
check_index: false,
log_level: None,
log_file: None,
progress_options: ProgressOptions {
no_progress: false,
progress_interval: None,
},
hooks: Hooks {
run_before: [],
run_after: [],
run_failed: [],
run_finally: [],
context: "",
},
env: {
"KEY0": "VALUE0",
"KEY1": "VALUE1",
"KEY2": "VALUE2",
"KEY3": "VALUE3",
"KEY4": "VALUE4",
"KEY5": "VALUE5",
"KEY6": "VALUE6",
"KEY7": "VALUE7",
"KEY8": "VALUE8",
"KEY9": "VALUE9",
},
},
repository: AllRepositoryOptions {
be: BackendOptions {
repository: None,
repo_hot: None,
options: {},
options_hot: {},
options_cold: {},
},
repo: RepositoryOptions {
password: None,
password_file: None,
password_command: None,
no_cache: false,
cache_dir: None,
warm_up: false,
warm_up_command: None,
warm_up_wait: None,
},
hooks: Hooks {
run_before: [],
run_after: [],
run_failed: [],
run_finally: [],
context: "",
},
},
snapshot_filter: SnapshotFilter {
filter_hosts: [],
filter_labels: [],
filter_paths: [],
filter_paths_exact: [],
filter_tags: [],
filter_tags_exact: [],
filter_after: None,
filter_before: None,
filter_size: None,
filter_size_added: None,
filter_fn: None,
},
backup: BackupCmd {
cli_sources: [],
stdin_filename: "",
stdin_command: None,
as_path: None,
ignore_save_opts: LocalSourceSaveOptions {
with_atime: false,
ignore_devid: false,
},
no_scan: false,
json: false,
long: false,
quiet: false,
init: false,
parent_opts: ParentOptions {
group_by: None,
parent: None,
skip_identical_parent: false,
force: false,
ignore_ctime: false,
ignore_inode: false,
},
ignore_filter_opts: LocalSourceFilterOptions {
globs: [],
iglobs: [],
glob_files: [],
iglob_files: [],
git_ignore: false,
no_require_git: false,
custom_ignorefiles: [],
exclude_if_present: [],
one_file_system: false,
exclude_larger_than: None,
},
snap_opts: SnapshotOptions {
label: None,
tags: [],
description: None,
description_from: None,
time: None,
delete_never: false,
delete_after: None,
host: None,
command: None,
},
key_opts: KeyOptions {
hostname: None,
username: None,
with_created: false,
},
config_opts: ConfigOptions {
set_compression: None,
set_version: None,
set_append_only: None,
set_treepack_size: None,
set_treepack_size_limit: None,
set_treepack_growfactor: None,
set_datapack_size: None,
set_datapack_growfactor: None,
set_datapack_size_limit: None,
set_min_packsize_tolerate_percent: None,
set_max_packsize_tolerate_percent: None,
set_extra_verify: None,
},
hooks: Hooks {
run_before: [],
run_after: [],
run_failed: [],
run_finally: [],
context: "",
},
snapshots: [],
sources: [],
},
copy: CopyCmd {
ids: [],
init: false,
targets: [],
key_opts: KeyOptions {
hostname: None,
username: None,
with_created: false,
},
},
forget: ForgetOptions {
group_by: None,
prune: false,
filter: SnapshotFilter {
filter_hosts: [],
filter_labels: [],
filter_paths: [],
filter_paths_exact: [],
filter_tags: [],
filter_tags_exact: [],
filter_after: None,
filter_before: None,
filter_size: None,
filter_size_added: None,
filter_fn: None,
},
keep: KeepOptions {
keep_tags: [],
keep_ids: [],
keep_last: None,
keep_hourly: None,
keep_daily: None,
keep_weekly: None,
keep_monthly: None,
keep_quarter_yearly: None,
keep_half_yearly: None,
keep_yearly: None,
keep_within: None,
keep_within_hourly: None,
keep_within_daily: None,
keep_within_weekly: None,
keep_within_monthly: None,
keep_within_quarter_yearly: None,
keep_within_half_yearly: None,
keep_within_yearly: None,
keep_none: false,
},
},
mount: None,
webdav: WebDavCmd {
address: None,
path_template: None,
time_template: None,
symlinks: false,
file_access: None,
snapshot_path: None,
},
}

View File

@ -0,0 +1,99 @@
---
source: src/config.rs
expression: serialized
---
[global]
use-profiles = []
dry-run = false
check-index = false
no-progress = false
[global.hooks]
run-before = []
run-after = []
run-failed = []
run-finally = []
[global.env]
KEY0 = "VALUE0"
KEY1 = "VALUE1"
KEY2 = "VALUE2"
KEY3 = "VALUE3"
KEY4 = "VALUE4"
KEY5 = "VALUE5"
KEY6 = "VALUE6"
KEY7 = "VALUE7"
KEY8 = "VALUE8"
KEY9 = "VALUE9"
[repository]
no-cache = false
warm-up = false
[repository.options]
[repository.options-hot]
[repository.options-cold]
[repository.hooks]
run-before = []
run-after = []
run-failed = []
run-finally = []
[snapshot-filter]
filter-hosts = []
filter-labels = []
filter-paths = []
filter-paths-exact = []
filter-tags = []
filter-tags-exact = []
[backup]
stdin-filename = ""
with-atime = false
ignore-devid = false
no-scan = false
json = false
long = false
quiet = false
init = false
skip-identical-parent = false
force = false
ignore-ctime = false
ignore-inode = false
globs = []
iglobs = []
glob-files = []
iglob-files = []
git-ignore = false
no-require-git = false
custom-ignorefiles = []
exclude-if-present = []
one-file-system = false
tags = []
delete-never = false
snapshots = []
sources = []
[backup.hooks]
run-before = []
run-after = []
run-failed = []
run-finally = []
[copy]
targets = []
[forget]
prune = false
filter-hosts = []
filter-labels = []
filter-paths = []
filter-paths-exact = []
filter-tags = []
filter-tags-exact = []
[webdav]
symlinks = false