From 85614101293050e70abbeea36c1f85ddd40746f8 Mon Sep 17 00:00:00 2001 From: Alexander Weiss Date: Mon, 4 Mar 2024 12:02:37 +0100 Subject: [PATCH 1/2] make json a global option --- config/README.md | 2 +- src/commands/backup.rs | 9 ++------- src/commands/forget.rs | 12 ++++++------ src/commands/merge.rs | 6 +----- src/commands/repoinfo.rs | 6 +----- src/commands/snapshots.rs | 6 +----- src/config.rs | 5 +++++ 7 files changed, 17 insertions(+), 29 deletions(-) diff --git a/config/README.md b/config/README.md index d5a797e69..dabbe6134 100644 --- a/config/README.md +++ b/config/README.md @@ -60,6 +60,7 @@ If you want to contribute your own configuration, please | dry-run | If true, performs a dry run without making any changes. | false | | RUSTIC_DRY_RUN | | log-level | Logging level. Possible values: "off", "error", "warn", "info", "debug", "trace". | "info" | | RUSTIC_LOG_LEVEL | | log-file | Path to the log file. | No log file | "/log/rustic.log" | RUSTIC_LOG_FILE | +| json | If true, returns output of the command as json. | false | | RUSTIC_JSON | | no-progress | If true, disables progress indicators. | false | | RUSTIC_NO_PROGRESS | | progress-interval | The interval at which progress indicators are shown. | "100ms" | "1m" | RUSTIC_PROGRESS_INTERVAL | | use-profile | An array of profiles to use. Allows to recursely use other profiles. | Empty array | | RUSTIC_USE_PROFILE | @@ -133,7 +134,6 @@ can be overwritten in the source-specifc configuration, see below. | ignore-ctime | If true, ignore file change time (ctime). | false | | | ignore-inode | If true, ignore file inode for the backup. | false | | | init | If true, initialize repository if it doesn't exist, yet. | false | | -| json | If true, returns output of the command as json. | false | | | label | Set label fot the snapshot. | Not set | | | no-require-git | (with git-ignore:) Apply .git-ignore files even if they are not in a git repository. | false | | | no-scan | Don't scan the backup source for its size (disables ETA). | false | | diff --git a/src/commands/backup.rs b/src/commands/backup.rs index 9449b0174..9a6190119 100644 --- a/src/commands/backup.rs +++ b/src/commands/backup.rs @@ -53,12 +53,7 @@ pub struct BackupCmd { /// Don't scan the backup source for its size - this disables ETA estimation for backup. #[clap(long)] #[merge(strategy = merge::bool::overwrite_false)] - pub no_scan: bool, - - /// Output generated snapshot in json format - #[clap(long)] - #[merge(strategy = merge::bool::overwrite_false)] - json: bool, + no_scan: bool, /// Don't show any output #[clap(long, conflicts_with = "json")] @@ -228,7 +223,7 @@ impl BackupCmd { .dry_run(config.global.dry_run); let snap = repo.backup(&backup_opts, &source, opts.snap_opts.to_snapshot()?)?; - if opts.json { + if config.global.json { let mut stdout = std::io::stdout(); serde_json::to_writer_pretty(&mut stdout, &snap)?; } else if !opts.quiet { diff --git a/src/commands/forget.rs b/src/commands/forget.rs index 6ce30ee0a..0735d1dab 100644 --- a/src/commands/forget.rs +++ b/src/commands/forget.rs @@ -26,10 +26,6 @@ pub(super) struct ForgetCmd { #[clap(value_name = "ID")] ids: Vec, - /// Show infos in json format - #[clap(long)] - json: bool, - /// Don't show any output #[clap(long, conflicts_with = "json")] quiet: bool, @@ -123,7 +119,7 @@ impl ForgetCmd { ForgetGroups(vec![item]) }; - if self.json { + if config.global.json { let mut stdout = std::io::stdout(); serde_json::to_writer_pretty(&mut stdout, &groups)?; } else if !self.quiet { @@ -132,7 +128,11 @@ impl ForgetCmd { let forget_snaps = groups.into_forget_ids(); - match (forget_snaps.is_empty(), config.global.dry_run, self.json) { + match ( + forget_snaps.is_empty(), + config.global.dry_run, + config.global.json, + ) { (true, _, false) => println!("nothing to remove"), (false, true, false) => { println!("would have removed the following snapshots:\n {forget_snaps:?}"); diff --git a/src/commands/merge.rs b/src/commands/merge.rs index aa102f349..6485d3625 100644 --- a/src/commands/merge.rs +++ b/src/commands/merge.rs @@ -16,10 +16,6 @@ pub(super) struct MergeCmd { #[clap(value_name = "ID")] ids: Vec, - /// Output generated snapshot in json format - #[clap(long)] - json: bool, - /// Remove input snapshots after merging #[clap(long)] delete: bool, @@ -53,7 +49,7 @@ impl MergeCmd { let snap = repo.merge_snapshots(&snapshots, &last_modified_node, snap)?; - if self.json { + if config.global.json { let mut stdout = std::io::stdout(); serde_json::to_writer_pretty(&mut stdout, &snap)?; } diff --git a/src/commands/repoinfo.rs b/src/commands/repoinfo.rs index 16750f6cf..962267880 100644 --- a/src/commands/repoinfo.rs +++ b/src/commands/repoinfo.rs @@ -22,10 +22,6 @@ pub(crate) struct RepoInfoCmd { /// Only scan index #[clap(long)] only_index: bool, - - /// Show infos in json format - #[clap(long)] - json: bool, } impl Runnable for RepoInfoCmd { @@ -66,7 +62,7 @@ impl RepoInfoCmd { .transpose()?, }; - if self.json { + if config.global.json { let mut stdout = std::io::stdout(); serde_json::to_writer_pretty(&mut stdout, &infos)?; return Ok(()); diff --git a/src/commands/snapshots.rs b/src/commands/snapshots.rs index 2b4e0821f..b137ea321 100644 --- a/src/commands/snapshots.rs +++ b/src/commands/snapshots.rs @@ -37,10 +37,6 @@ pub(crate) struct SnapshotCmd { #[arg(long)] long: bool, - /// Show snapshots in json format - #[clap(long, conflicts_with = "long")] - json: bool, - /// Show all snapshots instead of summarizing identical follow-up snapshots #[clap(long, conflicts_with_all = &["long", "json"])] all: bool, @@ -64,7 +60,7 @@ impl SnapshotCmd { config.snapshot_filter.matches(sn) })?; - if self.json { + if config.global.json { let mut stdout = std::io::stdout(); serde_json::to_writer_pretty(&mut stdout, &groups)?; return Ok(()); diff --git a/src/config.rs b/src/config.rs index 3a6d3757c..2ffeb1904 100644 --- a/src/config.rs +++ b/src/config.rs @@ -158,6 +158,11 @@ pub struct GlobalOptions { #[clap(long, global = true, env = "RUSTIC_LOG_FILE", value_name = "LOGFILE")] pub log_file: Option, + /// Output in JSON format + #[clap(long, global = true, env = "RUSTIC_JSON")] + #[merge(strategy = merge::bool::overwrite_false)] + pub json: bool, + /// Settings to customize progress bars #[clap(flatten)] #[serde(flatten)] From fc8ce376390823ae7e25829cd7316e3b6c13099a Mon Sep 17 00:00:00 2001 From: Alexander Weiss Date: Mon, 4 Mar 2024 16:52:11 +0100 Subject: [PATCH 2/2] feat(commands): Add json option to prune --- Cargo.lock | 49 ++++++++++++++++++++++++++++++------------- Cargo.toml | 4 ++-- config/full.toml | 2 +- src/commands/prune.rs | 8 ++++++- 4 files changed, 44 insertions(+), 19 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index e2d6104a6..0fc9c2651 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -330,16 +330,6 @@ version = "2.4.2" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "ed570934406eb16438a4e976b1b4500774099c13b8cb96eec99f620f05090ddf" -[[package]] -name = "bitmask-enum" -version = "2.2.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9990737a6d5740ff51cdbbc0f0503015cb30c390f6623968281eb214a520cfc0" -dependencies = [ - "quote", - "syn 2.0.50", -] - [[package]] name = "block-buffer" version = "0.10.4" @@ -458,6 +448,12 @@ version = "1.0.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "baf1de4339761588bc0619e3cbc0120ee582ebb74b53b4efbf79117bd2da40fd" +[[package]] +name = "cfg_aliases" +version = "0.1.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "fd16c4719339c4530435d38e511904438d07cce7950afa3718a84ac36c10e89e" + [[package]] name = "chrono" version = "0.4.34" @@ -1145,6 +1141,28 @@ dependencies = [ "syn 2.0.50", ] +[[package]] +name = "enumset" +version = "1.1.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "226c0da7462c13fb57e5cc9e0dc8f0635e7d27f276a3a7fd30054647f669007d" +dependencies = [ + "enumset_derive", + "serde", +] + +[[package]] +name = "enumset_derive" +version = "0.8.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e08b6c6ab82d70f08844964ba10c7babb716de2ecaeab9be5717918a5177d3af" +dependencies = [ + "darling 0.20.6", + "proc-macro2", + "quote", + "syn 2.0.50", +] + [[package]] name = "env_logger" version = "0.8.4" @@ -1991,12 +2009,13 @@ dependencies = [ [[package]] name = "nix" -version = "0.27.1" +version = "0.28.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2eb04e9c688eff1c89d72b407f168cf79bb9e867a9d3323ed6c01519eb9cc053" +checksum = "ab2156c4fce2f8df6c499cc1c763e4394b7482525bf2a9701c9d79d215f519e4" dependencies = [ "bitflags 2.4.2", "cfg-if 1.0.0", + "cfg_aliases", "libc", ] @@ -3001,7 +3020,7 @@ dependencies = [ [[package]] name = "rustic_backend" version = "0.1.1" -source = "git+https://github.com/rustic-rs/rustic_core.git#d17439568e046ddac90f9f1cc065e2c2770caf57" +source = "git+https://github.com/rustic-rs/rustic_core.git?branch=enumset#e4b006a209a6fa74357f8cc70c213a3a92301461" dependencies = [ "aho-corasick", "anyhow", @@ -3033,12 +3052,11 @@ dependencies = [ [[package]] name = "rustic_core" version = "0.2.0" -source = "git+https://github.com/rustic-rs/rustic_core.git#d17439568e046ddac90f9f1cc065e2c2770caf57" +source = "git+https://github.com/rustic-rs/rustic_core.git?branch=enumset#e4b006a209a6fa74357f8cc70c213a3a92301461" dependencies = [ "aes256ctr_poly1305aes", "anyhow", "binrw", - "bitmask-enum", "bytes", "bytesize", "cached", @@ -3055,6 +3073,7 @@ dependencies = [ "dunce", "enum-map", "enum-map-derive", + "enumset", "filetime", "futures", "gethostname", diff --git a/Cargo.toml b/Cargo.toml index cbea320c9..dbe9c94f3 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -40,8 +40,8 @@ rustdoc-args = ["--document-private-items", "--generate-link-to-definition"] [dependencies] abscissa_core = { version = "0.7.0", default-features = false, features = ["application"] } -rustic_backend = { git = "https://github.com/rustic-rs/rustic_core.git", features = ["cli"] } -rustic_core = { git = "https://github.com/rustic-rs/rustic_core.git", features = ["cli"] } +rustic_backend = { git = "https://github.com/rustic-rs/rustic_core.git", branch = "enumset", features = ["cli"] } +rustic_core = { git = "https://github.com/rustic-rs/rustic_core.git", branch = "enumset", features = ["cli"] } # allocators jemallocator-global = { version = "0.3.2", optional = true } diff --git a/config/full.toml b/config/full.toml index cc84108e3..8eafa8bc6 100644 --- a/config/full.toml +++ b/config/full.toml @@ -14,6 +14,7 @@ log-file = "/path/to/rustic.log" # Default: not set no-progress = false progress-interval = "100ms" dry-run = false +json = false # Global env variables: These are set by rustic before calling a subcommand, e.g. rclone or commands # defined in the repository options. @@ -99,7 +100,6 @@ exclude-if-present = [".nobackup", "CACHEDIR.TAG"] # Default: not set custom-ignorefile = [".rusticignore", ".backupignore"] # Default: not set one-file-system = false exclude-larger-than = "100MB" # Default: not set -json = false init = false no-scan = false quiet = false diff --git a/src/commands/prune.rs b/src/commands/prune.rs index e71408537..60c8630fb 100644 --- a/src/commands/prune.rs +++ b/src/commands/prune.rs @@ -35,7 +35,13 @@ impl PruneCmd { let pruner = repo.prune_plan(&self.opts)?; - print_stats(&pruner.stats); + if config.global.json { + let mut stdout = std::io::stdout(); + let debug: Vec<_> = pruner.stats.debug.0.iter().collect(); + serde_json::to_writer_pretty(&mut stdout, &debug)?; + } else { + print_stats(&pruner.stats); + } if config.global.dry_run { repo.warm_up(pruner.repack_packs().into_iter())?;