mirror of
https://github.com/rustic-rs/rustic.git
synced 2025-10-26 11:18:51 +00:00
improve help usage
This commit is contained in:
parent
36dd282bd2
commit
8eeed5fb83
@ -31,11 +31,11 @@ pub struct LocalSourceOptions {
|
||||
#[clap(long, short = 'g')]
|
||||
glob: Vec<String>,
|
||||
|
||||
/// Read glob patterns to exclude/include from a file (can be specified multiple times)
|
||||
/// Read glob patterns to exclude/include from this file (can be specified multiple times)
|
||||
#[clap(long, value_name = "FILE")]
|
||||
glob_file: Vec<String>,
|
||||
|
||||
/// Exclude contents of directories containing filename (can be specified multiple times)
|
||||
/// Exclude contents of directories containing this filename (can be specified multiple times)
|
||||
#[clap(long, value_name = "FILE")]
|
||||
exclude_if_present: Vec<String>,
|
||||
|
||||
|
||||
@ -2,7 +2,7 @@ use std::path::PathBuf;
|
||||
|
||||
use anyhow::{anyhow, Result};
|
||||
use chrono::{Duration, Local};
|
||||
use clap::Parser;
|
||||
use clap::{AppSettings, Parser};
|
||||
use gethostname::gethostname;
|
||||
use path_absolutize::*;
|
||||
use vlog::*;
|
||||
@ -17,6 +17,7 @@ use crate::index::IndexBackend;
|
||||
use crate::repo::{ConfigFile, DeleteOption, SnapshotFile, SnapshotSummary, StringList};
|
||||
|
||||
#[derive(Parser)]
|
||||
#[clap(global_setting(AppSettings::DeriveDisplayOrder))]
|
||||
pub(super) struct Opts {
|
||||
/// Do not upload or write any data, just show what would be done
|
||||
#[clap(long, short = 'n')]
|
||||
@ -45,7 +46,7 @@ pub(super) struct Opts {
|
||||
#[clap(flatten)]
|
||||
ignore_opts: LocalSourceOptions,
|
||||
|
||||
/// backup source
|
||||
/// Backup source
|
||||
source: String,
|
||||
}
|
||||
|
||||
|
||||
@ -19,24 +19,29 @@ pub(super) struct Opts {
|
||||
|
||||
#[derive(Subcommand)]
|
||||
enum Command {
|
||||
/// Display a tree blob
|
||||
TreeBlob(IdOpt),
|
||||
/// Display a data blob
|
||||
DataBlob(IdOpt),
|
||||
/// Display the config file
|
||||
Config,
|
||||
/// Display an index file
|
||||
Index(IdOpt),
|
||||
/// Display a snapshot file
|
||||
Snapshot(IdOpt),
|
||||
/// display a tree within a snapshot
|
||||
/// Display a tree within a snapshot
|
||||
Tree(TreeOpts),
|
||||
}
|
||||
|
||||
#[derive(Default, Parser)]
|
||||
struct IdOpt {
|
||||
/// id to cat
|
||||
/// Id to display
|
||||
id: String,
|
||||
}
|
||||
|
||||
#[derive(Parser)]
|
||||
struct TreeOpts {
|
||||
/// snapshot/path to restore
|
||||
/// Snapshot/path of the tree to display
|
||||
#[clap(value_name = "SNAPSHOT[:PATH]")]
|
||||
snap: String,
|
||||
}
|
||||
|
||||
@ -14,11 +14,11 @@ use crate::repo::{IndexFile, IndexPack, SnapshotFile};
|
||||
|
||||
#[derive(Parser)]
|
||||
pub(super) struct Opts {
|
||||
/// don't verify the data saved in the cache
|
||||
/// Don't verify the data saved in the cache
|
||||
#[clap(long, conflicts_with = "no-cache")]
|
||||
trust_cache: bool,
|
||||
|
||||
/// read all data blobs
|
||||
/// Read all data blobs
|
||||
#[clap(long)]
|
||||
read_data: bool,
|
||||
}
|
||||
|
||||
@ -1,6 +1,6 @@
|
||||
use anyhow::{bail, Result};
|
||||
use bytesize::ByteSize;
|
||||
use clap::Parser;
|
||||
use clap::{AppSettings, Parser};
|
||||
|
||||
use crate::backend::{DecryptBackend, DecryptFullBackend, DecryptWriteBackend, WriteBackend};
|
||||
use crate::repo::ConfigFile;
|
||||
@ -40,12 +40,14 @@ pub(super) async fn execute(
|
||||
}
|
||||
|
||||
#[derive(Parser)]
|
||||
#[clap(global_setting(AppSettings::DeriveDisplayOrder))]
|
||||
pub(super) struct ConfigOpts {
|
||||
/// set compression level, 0 equals no compression
|
||||
/// Set compression level. Allowed levels are 1 to 22 and -1 to -7, see https://facebook.github.io/zstd/.
|
||||
/// Note that 0 equals to no compression
|
||||
#[clap(long, value_name = "LEVEL")]
|
||||
pub set_compression: Option<i32>,
|
||||
|
||||
/// set repository version
|
||||
/// Set repository version. Allowed versions: 1,2
|
||||
#[clap(long, value_name = "VERSION")]
|
||||
pub set_version: Option<u32>,
|
||||
|
||||
@ -61,9 +63,10 @@ pub(super) struct ConfigOpts {
|
||||
#[clap(long, value_name = "SIZE")]
|
||||
pub set_treepack_size_limit: Option<ByteSize>,
|
||||
|
||||
/// Set grow factor for tree packs. The default packsize grows by the square root of the reposize
|
||||
/// multiplied with this factor. This means 32 kiB times this factor per square root of reposize in GiB.
|
||||
/// Defaults to 32 (= 1MB per sqare root of reposize in GiB) if not set.
|
||||
/// Set grow factor for tree packs. The default packsize grows by the square root of the total size of all
|
||||
/// tree packs multiplied with this factor. This means 32 kiB times this factor per square root of total
|
||||
/// treesize in GiB.
|
||||
/// Defaults to 32 (= 1MB per sqare root of total treesize in GiB) if not set.
|
||||
#[clap(long, value_name = "FACTOR")]
|
||||
pub set_treepack_growfactor: Option<u32>,
|
||||
|
||||
@ -73,9 +76,10 @@ pub(super) struct ConfigOpts {
|
||||
#[clap(long, value_name = "SIZE")]
|
||||
pub set_datapack_size: Option<ByteSize>,
|
||||
|
||||
/// set grow factor for data packs. The default packsize grows by the square root of the reposize
|
||||
/// multiplied with this factor. This means 32 kiB times this factor per square root of reposize in GiB.
|
||||
/// Defaults to 32 (= 1MB per sqare root of reposize in GiB) if not set.
|
||||
/// Set grow factor for data packs. The default packsize grows by the square root of the total size of all
|
||||
/// data packs multiplied with this factor. This means 32 kiB times this factor per square root of total
|
||||
/// datasize in GiB.
|
||||
/// Defaults to 32 (= 1MB per sqare root of total datasize in GiB) if not set.
|
||||
#[clap(long, value_name = "FACTOR")]
|
||||
pub set_datapack_growfactor: Option<u32>,
|
||||
|
||||
|
||||
@ -13,11 +13,11 @@ use crate::repo::SnapshotFile;
|
||||
|
||||
#[derive(Parser)]
|
||||
pub(super) struct Opts {
|
||||
/// reference snapshot/path
|
||||
/// Reference snapshot/path
|
||||
#[clap(value_name = "SNAPSHOT1[:PATH1]")]
|
||||
snap1: String,
|
||||
|
||||
/// new snapshot/path [default for PATH2: PATH1]
|
||||
/// New snapshot/path [default for PATH2: PATH1]
|
||||
#[clap(value_name = "SNAPSHOT2[:PATH2]")]
|
||||
snap2: String,
|
||||
}
|
||||
|
||||
@ -1,6 +1,6 @@
|
||||
use anyhow::Result;
|
||||
use chrono::{DateTime, Datelike, Duration, Local, Timelike};
|
||||
use clap::Parser;
|
||||
use clap::{AppSettings, Parser};
|
||||
use derivative::Derivative;
|
||||
use prettytable::{format, row, Table};
|
||||
|
||||
@ -11,11 +11,9 @@ use crate::repo::{
|
||||
};
|
||||
|
||||
#[derive(Parser)]
|
||||
#[clap(global_setting(AppSettings::DeriveDisplayOrder))]
|
||||
pub(super) struct Opts {
|
||||
#[clap(flatten)]
|
||||
filter: SnapshotFilter,
|
||||
|
||||
/// group snapshots by any combination of host,paths,tags
|
||||
/// Group snapshots by any combination of host,paths,tags
|
||||
#[clap(
|
||||
long,
|
||||
short = 'g',
|
||||
@ -24,17 +22,20 @@ pub(super) struct Opts {
|
||||
)]
|
||||
group_by: SnapshotGroupCriterion,
|
||||
|
||||
#[clap(flatten)]
|
||||
#[clap(flatten, help_heading = "SNAPSHOT FILTER OPTIONS")]
|
||||
filter: SnapshotFilter,
|
||||
|
||||
#[clap(flatten, help_heading = "RETENTION OPTIONS")]
|
||||
keep: KeepOptions,
|
||||
|
||||
/// also prune the repository
|
||||
/// Also prune the repository
|
||||
#[clap(long)]
|
||||
prune: bool,
|
||||
|
||||
#[clap(flatten)]
|
||||
#[clap(flatten, help_heading = "PRUNE OPTIONS (only when used with --prune)")]
|
||||
prune_opts: prune::Opts,
|
||||
|
||||
/// don't remove anything, only show what would be done
|
||||
/// Don't remove anything, only show what would be done
|
||||
#[clap(skip)]
|
||||
dry_run: bool,
|
||||
|
||||
@ -137,64 +138,64 @@ pub(super) async fn execute(
|
||||
#[derive(Clone, PartialEq, Derivative, Parser)]
|
||||
#[derivative(Default)]
|
||||
struct KeepOptions {
|
||||
/// keep snapshots with this taglist (can be specified multiple times)
|
||||
#[clap(long, value_name = "TAGS")]
|
||||
/// Keep snapshots with this taglist (can be specified multiple times)
|
||||
#[clap(long, value_name = "TAG[,TAG,..]")]
|
||||
keep_tags: Vec<StringList>,
|
||||
|
||||
/// keep snapshots ids that start with ID (can be specified multiple times)
|
||||
/// Keep snapshots ids that start with ID (can be specified multiple times)
|
||||
#[clap(long = "keep-id", value_name = "ID")]
|
||||
keep_ids: Vec<String>,
|
||||
|
||||
/// keep the last N snapshots
|
||||
/// Keep the last N snapshots
|
||||
#[clap(long, short = 'l', value_name = "N", default_value = "0")]
|
||||
keep_last: u32,
|
||||
|
||||
/// keep the last N hourly snapshots
|
||||
/// Keep the last N hourly snapshots
|
||||
#[clap(long, short = 'H', value_name = "N", default_value = "0")]
|
||||
keep_hourly: u32,
|
||||
|
||||
/// keep the last N daily snapshots
|
||||
/// Keep the last N daily snapshots
|
||||
#[clap(long, short = 'd', value_name = "N", default_value = "0")]
|
||||
keep_daily: u32,
|
||||
|
||||
/// keep the last N weekly snapshots
|
||||
/// Keep the last N weekly snapshots
|
||||
#[clap(long, short = 'w', value_name = "N", default_value = "0")]
|
||||
keep_weekly: u32,
|
||||
|
||||
/// keep the last N monthly snapshots
|
||||
/// Keep the last N monthly snapshots
|
||||
#[clap(long, short = 'm', value_name = "N", default_value = "0")]
|
||||
keep_monthly: u32,
|
||||
|
||||
/// keep the last N yearly snapshots
|
||||
/// Keep the last N yearly snapshots
|
||||
#[clap(long, short = 'y', value_name = "N", default_value = "0")]
|
||||
keep_yearly: u32,
|
||||
|
||||
/// keep snapshots newer than DURATION relative to latest snapshot
|
||||
/// Keep snapshots newer than DURATION relative to latest snapshot
|
||||
#[clap(long, value_name = "DURATION", default_value = "0h")]
|
||||
#[derivative(Default(value = "std::time::Duration::ZERO.into()"))]
|
||||
keep_within: humantime::Duration,
|
||||
|
||||
/// keep hourly snapshots newer than DURATION relative to latest snapshot
|
||||
/// Keep hourly snapshots newer than DURATION relative to latest snapshot
|
||||
#[clap(long, value_name = "DURATION", default_value = "0h")]
|
||||
#[derivative(Default(value = "std::time::Duration::ZERO.into()"))]
|
||||
keep_within_hourly: humantime::Duration,
|
||||
|
||||
/// keep daily snapshots newer than DURATION relative to latest snapshot
|
||||
/// Keep daily snapshots newer than DURATION relative to latest snapshot
|
||||
#[clap(long, value_name = "DURATION", default_value = "0d")]
|
||||
#[derivative(Default(value = "std::time::Duration::ZERO.into()"))]
|
||||
keep_within_daily: humantime::Duration,
|
||||
|
||||
/// keep weekly snapshots newer than DURATION relative to latest snapshot
|
||||
/// Keep weekly snapshots newer than DURATION relative to latest snapshot
|
||||
#[clap(long, value_name = "DURATION", default_value = "0w")]
|
||||
#[derivative(Default(value = "std::time::Duration::ZERO.into()"))]
|
||||
keep_within_weekly: humantime::Duration,
|
||||
|
||||
/// keep monthly snapshots newer than DURATION relative to latest snapshot
|
||||
/// Keep monthly snapshots newer than DURATION relative to latest snapshot
|
||||
#[clap(long, value_name = "DURATION", default_value = "0m")]
|
||||
#[derivative(Default(value = "std::time::Duration::ZERO.into()"))]
|
||||
keep_within_monthly: humantime::Duration,
|
||||
|
||||
/// keep yearly snapshots newer than DURATION relative to latest snapshot
|
||||
/// Keep yearly snapshots newer than DURATION relative to latest snapshot
|
||||
#[clap(long, value_name = "DURATION", default_value = "0y")]
|
||||
#[derivative(Default(value = "std::time::Duration::ZERO.into()"))]
|
||||
keep_within_yearly: humantime::Duration,
|
||||
|
||||
@ -16,10 +16,10 @@ use crate::repo::{ConfigFile, KeyFile};
|
||||
|
||||
#[derive(Parser)]
|
||||
pub(super) struct Opts {
|
||||
#[clap(flatten)]
|
||||
#[clap(flatten, help_heading = "KEY OPTIONS")]
|
||||
key_opts: AddOpts,
|
||||
|
||||
#[clap(flatten)]
|
||||
#[clap(flatten, help_heading = "CONFIG OPTIONS")]
|
||||
config_opts: ConfigOpts,
|
||||
}
|
||||
|
||||
|
||||
@ -2,7 +2,7 @@ use std::fs::File;
|
||||
use std::io::BufReader;
|
||||
|
||||
use anyhow::Result;
|
||||
use clap::{Parser, Subcommand};
|
||||
use clap::{AppSettings, Parser, Subcommand};
|
||||
use rpassword::{prompt_password, read_password_from_bufread};
|
||||
|
||||
use crate::backend::{FileType, WriteBackend};
|
||||
@ -21,22 +21,23 @@ enum Command {
|
||||
}
|
||||
|
||||
#[derive(Parser)]
|
||||
#[clap(global_setting(AppSettings::DeriveDisplayOrder))]
|
||||
pub(crate) struct AddOpts {
|
||||
/// set 'hostname' in public key information
|
||||
/// File from which to read the new password
|
||||
#[clap(long)]
|
||||
pub(crate) new_password_file: Option<String>,
|
||||
|
||||
/// Set 'hostname' in public key information
|
||||
#[clap(long)]
|
||||
pub(crate) hostname: Option<String>,
|
||||
|
||||
/// set 'username' in public key information
|
||||
/// Set 'username' in public key information
|
||||
#[clap(long)]
|
||||
pub(crate) username: Option<String>,
|
||||
|
||||
/// add 'created' date in public key information
|
||||
/// Add 'created' date in public key information
|
||||
#[clap(long)]
|
||||
pub(crate) with_created: bool,
|
||||
|
||||
/// file from which to read the new password
|
||||
#[clap(long)]
|
||||
pub(crate) new_password_file: Option<String>,
|
||||
}
|
||||
|
||||
pub(super) async fn execute(be: &impl WriteBackend, key: Key, opts: Opts) -> Result<()> {
|
||||
|
||||
@ -8,7 +8,7 @@ use crate::repo::IndexFile;
|
||||
|
||||
#[derive(Parser)]
|
||||
pub(super) struct Opts {
|
||||
/// file type to list
|
||||
/// File type to list
|
||||
#[clap(possible_values=["blobs", "index", "packs", "snapshots", "keys"])]
|
||||
tpe: String,
|
||||
}
|
||||
|
||||
@ -11,7 +11,7 @@ use crate::repo::SnapshotFile;
|
||||
|
||||
#[derive(Parser)]
|
||||
pub(super) struct Opts {
|
||||
/// snapshot/path to ls
|
||||
/// Snapshot/path to list
|
||||
#[clap(value_name = "SNAPSHOT[:PATH]")]
|
||||
snap: String,
|
||||
}
|
||||
|
||||
@ -34,11 +34,22 @@ use vlog::*;
|
||||
#[clap(about, version)]
|
||||
struct Opts {
|
||||
/// Repository to use
|
||||
#[clap(short, long, global = true, env = "RUSTIC_REPOSITORY")]
|
||||
#[clap(
|
||||
short,
|
||||
long,
|
||||
global = true,
|
||||
env = "RUSTIC_REPOSITORY",
|
||||
help_heading = "GLOBAL OPTIONS"
|
||||
)]
|
||||
repository: Option<String>,
|
||||
|
||||
/// Repository to use as hot storage
|
||||
#[clap(long, global = true, env = "RUSTIC_REPO_HOT")]
|
||||
#[clap(
|
||||
long,
|
||||
global = true,
|
||||
env = "RUSTIC_REPO_HOT",
|
||||
help_heading = "GLOBAL OPTIONS"
|
||||
)]
|
||||
repo_hot: Option<String>,
|
||||
|
||||
/// File to read the password from
|
||||
@ -47,11 +58,19 @@ struct Opts {
|
||||
long,
|
||||
global = true,
|
||||
parse(from_os_str),
|
||||
env = "RUSTIC_PASSWORD_FILE"
|
||||
env = "RUSTIC_PASSWORD_FILE",
|
||||
help_heading = "GLOBAL OPTIONS"
|
||||
)]
|
||||
password_file: Option<PathBuf>,
|
||||
|
||||
/// Increase verbosity (can be used multiple times)
|
||||
#[clap(long, short = 'v', global = true, parse(from_occurrences))]
|
||||
#[clap(
|
||||
long,
|
||||
short = 'v',
|
||||
global = true,
|
||||
parse(from_occurrences),
|
||||
help_heading = "GLOBAL OPTIONS"
|
||||
)]
|
||||
verbose: i8,
|
||||
|
||||
/// Don't be verbose at all
|
||||
@ -60,21 +79,28 @@ struct Opts {
|
||||
short = 'q',
|
||||
global = true,
|
||||
parse(from_occurrences),
|
||||
conflicts_with = "verbose"
|
||||
conflicts_with = "verbose",
|
||||
help_heading = "GLOBAL OPTIONS"
|
||||
)]
|
||||
quiet: i8,
|
||||
|
||||
/// Don't use a cache.
|
||||
#[clap(long, global = true, env = "RUSTIC_NO_CACHE")]
|
||||
#[clap(
|
||||
long,
|
||||
global = true,
|
||||
env = "RUSTIC_NO_CACHE",
|
||||
help_heading = "GLOBAL OPTIONS"
|
||||
)]
|
||||
no_cache: bool,
|
||||
|
||||
/// Use this dir as cache dir. If not given, rustic searches for rustic cache dirs
|
||||
/// Use this dir as cache dir instead of the standard cache dir
|
||||
#[clap(
|
||||
long,
|
||||
global = true,
|
||||
parse(from_os_str),
|
||||
conflicts_with = "no-cache",
|
||||
env = "RUSTIC_CACHE_DIR"
|
||||
env = "RUSTIC_CACHE_DIR",
|
||||
help_heading = "GLOBAL OPTIONS"
|
||||
)]
|
||||
cache_dir: Option<PathBuf>,
|
||||
|
||||
@ -87,16 +113,16 @@ enum Command {
|
||||
/// Backup to the repository
|
||||
Backup(backup::Opts),
|
||||
|
||||
/// Cat repository files and blobs
|
||||
/// Show raw data of repository files and blobs
|
||||
Cat(cat::Opts),
|
||||
|
||||
/// Change repo configuration
|
||||
/// Change the repository configuration
|
||||
Config(config::Opts),
|
||||
|
||||
/// Check repository
|
||||
/// Check the repository
|
||||
Check(check::Opts),
|
||||
|
||||
/// Compare two snapshots
|
||||
/// Compare two snapshots/paths
|
||||
Diff(diff::Opts),
|
||||
|
||||
/// Remove snapshots from the repository
|
||||
@ -111,22 +137,22 @@ enum Command {
|
||||
/// List repository files
|
||||
List(list::Opts),
|
||||
|
||||
/// Ls snapshots
|
||||
/// List file contents of a snapshot
|
||||
Ls(ls::Opts),
|
||||
|
||||
/// Show snapshots
|
||||
/// Show a detailed overview of the snapshots within the repository
|
||||
Snapshots(snapshots::Opts),
|
||||
|
||||
/// update to the latest rustic release
|
||||
/// Update to the latest rustic release
|
||||
SelfUpdate(self_update::Opts),
|
||||
|
||||
/// Remove unused data
|
||||
/// Remove unused data or repack repository pack files
|
||||
Prune(prune::Opts),
|
||||
|
||||
/// Restore snapshot
|
||||
/// Restore a snapshot/path
|
||||
Restore(restore::Opts),
|
||||
|
||||
/// Show general information about repository
|
||||
/// Show general information about the repository
|
||||
Repoinfo(repoinfo::Opts),
|
||||
|
||||
/// Change tags of snapshots
|
||||
|
||||
@ -5,7 +5,7 @@ use std::str::FromStr;
|
||||
use anyhow::{anyhow, bail, Result};
|
||||
use bytesize::ByteSize;
|
||||
use chrono::{DateTime, Duration, Local};
|
||||
use clap::Parser;
|
||||
use clap::{AppSettings, Parser};
|
||||
use derive_more::Add;
|
||||
use futures::{future, TryStreamExt};
|
||||
use vlog::*;
|
||||
@ -18,58 +18,61 @@ use crate::index::{IndexBackend, IndexCollector, IndexType, IndexedBackend, Inde
|
||||
use crate::repo::{ConfigFile, IndexBlob, IndexFile, IndexPack, SnapshotFile};
|
||||
|
||||
#[derive(Parser)]
|
||||
#[clap(global_setting(AppSettings::DeriveDisplayOrder))]
|
||||
pub(super) struct Opts {
|
||||
/// define maximum data to repack in % of reposize or as size (e.g. '5b', '2 kB', '3M', '4TiB') or 'unlimited'
|
||||
/// Don't remove anything, only show what would be done
|
||||
#[clap(long, short = 'n')]
|
||||
pub(crate) dry_run: bool,
|
||||
|
||||
/// Define maximum data to repack in % of reposize or as size (e.g. '5b', '2 kB', '3M', '4TiB') or 'unlimited'
|
||||
#[clap(long, value_name = "LIMIT", default_value = "unlimited")]
|
||||
max_repack: LimitOption,
|
||||
|
||||
/// tolerate limit of unused data in % of reposize after pruning or as size (e.g. '5b', '2 kB', '3M', '4TiB') or 'unlimited'
|
||||
/// Tolerate limit of unused data in % of reposize after pruning or as size (e.g. '5b', '2 kB', '3M', '4TiB') or 'unlimited'
|
||||
#[clap(long, value_name = "LIMIT", default_value = "5%")]
|
||||
max_unused: LimitOption,
|
||||
|
||||
/// only repack packs which are cacheable [default: true for a hot/cold repository, else false]
|
||||
#[clap(long, value_name = "TRUE/FALSE")]
|
||||
repack_cacheable_only: Option<bool>,
|
||||
/// Minimum duration (e.g. 90d) to keep packs before repacking or removing. More recently created
|
||||
/// packs won't be repacked or marked for deletion within this prune run.
|
||||
#[clap(long, value_name = "DURATION", default_value = "0d")]
|
||||
keep_pack: humantime::Duration,
|
||||
|
||||
/// minimum duration (e.g. 10m) to keep packs marked for deletion
|
||||
/// Minimum duration (e.g. 10m) to keep packs marked for deletion. More recently marked packs won't be
|
||||
/// deleted within this prune run.
|
||||
#[clap(long, value_name = "DURATION", default_value = "23h")]
|
||||
keep_delete: humantime::Duration,
|
||||
|
||||
/// delete files immediately instead of marking them. This also removes all already marked files.
|
||||
/// Delete files immediately instead of marking them. This also removes all files already marked for deletion.
|
||||
/// WARNING: Only use if you are sure the repository is not accessed by parallel processes!
|
||||
#[clap(long)]
|
||||
instant_delete: bool,
|
||||
|
||||
/// minimum duration (e.g. 90d) to keep packs before repacking or removing
|
||||
#[clap(long, value_name = "DURATION", default_value = "0d")]
|
||||
keep_pack: humantime::Duration,
|
||||
|
||||
/// only remove unneded pack file from local cache
|
||||
/// Only remove unneded pack file from local cache. Do not change the repository at all.
|
||||
#[clap(long)]
|
||||
cache_only: bool,
|
||||
|
||||
/// simply copy blobs when repacking instead of decrypting; possibly compressing; encrypting
|
||||
/// Simply copy blobs when repacking instead of decrypting; possibly compressing; encrypting
|
||||
#[clap(long)]
|
||||
fast_repack: bool,
|
||||
|
||||
/// repack packs containing uncompressed blobs. This cannot be used with --fast-repack.
|
||||
/// Repack packs containing uncompressed blobs. This cannot be used with --fast-repack.
|
||||
/// Implies --max-unused=0.
|
||||
#[clap(long, conflicts_with = "fast-repack")]
|
||||
repack_uncompressed: bool,
|
||||
|
||||
/// don't remove anything, only show what would be done
|
||||
#[clap(long, short = 'n')]
|
||||
pub(crate) dry_run: bool,
|
||||
/// Only repack packs which are cacheable [default: true for a hot/cold repository, else false]
|
||||
#[clap(long, value_name = "TRUE/FALSE")]
|
||||
repack_cacheable_only: Option<bool>,
|
||||
|
||||
/// warm up needed data pack files by only requesting them without processing
|
||||
/// Warm up needed data pack files by only requesting them without processing
|
||||
#[clap(long)]
|
||||
warm_up: bool,
|
||||
|
||||
/// warm up needed data pack files by running the command with %id replaced by pack id
|
||||
/// Warm up needed data pack files by running the command with %id replaced by pack id
|
||||
#[clap(long, conflicts_with = "warm-up")]
|
||||
warm_up_command: Option<String>,
|
||||
|
||||
/// duration (e.g. 10m) to wait after warm up before doing the actual restore
|
||||
/// Duration (e.g. 10m) to wait after warm up before doing the actual restore
|
||||
#[clap(long, value_name = "DURATION", conflicts_with = "dry-run")]
|
||||
warm_up_wait: Option<humantime::Duration>,
|
||||
}
|
||||
|
||||
@ -5,7 +5,7 @@ use std::num::NonZeroU32;
|
||||
use std::path::{Path, PathBuf};
|
||||
|
||||
use anyhow::{anyhow, bail, Result};
|
||||
use clap::Parser;
|
||||
use clap::{AppSettings, Parser};
|
||||
use derive_getters::Dissolve;
|
||||
use futures::{stream::FuturesUnordered, TryStreamExt};
|
||||
use ignore::{DirEntry, WalkBuilder};
|
||||
@ -21,37 +21,39 @@ use crate::index::{IndexBackend, IndexedBackend};
|
||||
use crate::repo::SnapshotFile;
|
||||
|
||||
#[derive(Parser)]
|
||||
#[clap(global_setting(AppSettings::DeriveDisplayOrder))]
|
||||
pub(super) struct Opts {
|
||||
/// dry-run: don't restore, only show what would be done
|
||||
/// Dry-run: don't restore, only show what would be done
|
||||
#[clap(long, short = 'n')]
|
||||
dry_run: bool,
|
||||
|
||||
/// warm up needed data pack files by only requesting them without processing
|
||||
#[clap(long)]
|
||||
warm_up: bool,
|
||||
|
||||
/// warm up needed data pack files by running the command with %id replaced by pack id
|
||||
#[clap(long, conflicts_with = "warm-up")]
|
||||
warm_up_command: Option<String>,
|
||||
|
||||
/// duration (e.g. 10m) to wait after warm up before doing the actual restore
|
||||
#[clap(long, value_name = "DURATION", conflicts_with = "dry-run")]
|
||||
warm_up_wait: Option<humantime::Duration>,
|
||||
|
||||
/// remove all files/dirs destination which are not contained in snapshot.
|
||||
/// Warning: Use with care, maybe first try this with --dry-run?
|
||||
/// Remove all files/dirs in destination which are not contained in snapshot.
|
||||
/// WARNING: Use with care, maybe first try this first with --dry-run?
|
||||
#[clap(long)]
|
||||
delete: bool,
|
||||
|
||||
/// use numeric ids instead of user/groug when restoring uid/gui
|
||||
/// Use numeric ids instead of user/group when restoring uid/gui
|
||||
#[clap(long)]
|
||||
numeric_id: bool,
|
||||
|
||||
/// snapshot/path to restore
|
||||
/// Warm up needed data pack files by only requesting them without processing
|
||||
#[clap(long)]
|
||||
warm_up: bool,
|
||||
|
||||
/// Warm up needed data pack files by running the command with %id replaced by pack id
|
||||
#[clap(long, conflicts_with = "warm-up")]
|
||||
warm_up_command: Option<String>,
|
||||
|
||||
/// Duration (e.g. 10m) to wait after warm up before doing the actual restore
|
||||
#[clap(long, value_name = "DURATION", conflicts_with = "dry-run")]
|
||||
warm_up_wait: Option<humantime::Duration>,
|
||||
|
||||
/// Snapshot/path to restore
|
||||
#[clap(value_name = "SNAPSHOT[:PATH]")]
|
||||
snap: String,
|
||||
|
||||
/// restore destination
|
||||
/// Restore destination
|
||||
#[clap(value_name = "DESTINATION")]
|
||||
dest: String,
|
||||
}
|
||||
|
||||
|
||||
@ -13,18 +13,18 @@ use crate::repo::{
|
||||
|
||||
#[derive(Parser)]
|
||||
pub(super) struct Opts {
|
||||
#[clap(flatten)]
|
||||
#[clap(flatten, help_heading = "SNAPSHOT FILTER OPTIONS")]
|
||||
filter: SnapshotFilter,
|
||||
|
||||
/// group snapshots by any combination of host,paths,tags
|
||||
/// Group snapshots by any combination of host,paths,tags
|
||||
#[clap(long, short = 'g', value_name = "CRITERION", default_value = "")]
|
||||
group_by: SnapshotGroupCriterion,
|
||||
|
||||
/// show detailed information about snapshots
|
||||
/// Show detailed information about snapshots
|
||||
#[clap(long)]
|
||||
long: bool,
|
||||
|
||||
/// Snapshots to list
|
||||
/// Snapshots to show
|
||||
#[clap(value_name = "ID")]
|
||||
ids: Vec<String>,
|
||||
}
|
||||
|
||||
@ -1,45 +1,68 @@
|
||||
use anyhow::Result;
|
||||
use chrono::{Duration, Local};
|
||||
use clap::Parser;
|
||||
use clap::{AppSettings, Parser};
|
||||
|
||||
use super::progress_counter;
|
||||
use crate::backend::{DecryptFullBackend, FileType};
|
||||
use crate::repo::{DeleteOption, SnapshotFile, SnapshotFilter, StringList};
|
||||
|
||||
#[derive(Parser)]
|
||||
#[clap(global_setting(AppSettings::DeriveDisplayOrder))]
|
||||
pub(super) struct Opts {
|
||||
#[clap(flatten)]
|
||||
filter: SnapshotFilter,
|
||||
|
||||
/// Tags to add (can be specified multiple times)
|
||||
#[clap(long, value_name = "TAG[,TAG,..]", conflicts_with = "remove")]
|
||||
add: Vec<StringList>,
|
||||
|
||||
/// Tags to remove (can be specified multiple times)
|
||||
#[clap(long, value_name = "TAG[,TAG,..]")]
|
||||
remove: Vec<StringList>,
|
||||
|
||||
/// Tag list to set (can be specified multiple times)
|
||||
#[clap(long, value_name = "TAG[,TAG,..]", conflicts_with = "remove")]
|
||||
set: Vec<StringList>,
|
||||
|
||||
/// Remove any delete mark
|
||||
#[clap(long, conflicts_with_all = &["set-delete-never", "set-delete-after"])]
|
||||
remove_delete: bool,
|
||||
|
||||
/// Mark snapshot as uneraseable
|
||||
#[clap(long, conflicts_with = "set-delete-after")]
|
||||
set_delete_never: bool,
|
||||
|
||||
/// Mark snapshot to be deleted after given duration (e.g. 10d)
|
||||
#[clap(long, value_name = "DURATION")]
|
||||
set_delete_after: Option<humantime::Duration>,
|
||||
|
||||
/// don't change any snapshot, only show which would be modified
|
||||
/// Don't change any snapshot, only show which would be modified
|
||||
#[clap(long, short = 'n')]
|
||||
dry_run: bool,
|
||||
|
||||
/// Snapshots to change tags
|
||||
#[clap(
|
||||
flatten,
|
||||
help_heading = "SNAPSHOT FILTER OPTIONS (if no snapshot is given)"
|
||||
)]
|
||||
filter: SnapshotFilter,
|
||||
|
||||
/// Tags to add (can be specified multiple times)
|
||||
#[clap(
|
||||
long,
|
||||
value_name = "TAG[,TAG,..]",
|
||||
conflicts_with = "remove",
|
||||
help_heading = "TAG OPTIONS"
|
||||
)]
|
||||
add: Vec<StringList>,
|
||||
|
||||
/// Tags to remove (can be specified multiple times)
|
||||
#[clap(long, value_name = "TAG[,TAG,..]", help_heading = "TAG OPTIONS")]
|
||||
remove: Vec<StringList>,
|
||||
|
||||
/// Tag list to set (can be specified multiple times)
|
||||
#[clap(
|
||||
long,
|
||||
value_name = "TAG[,TAG,..]",
|
||||
conflicts_with = "remove",
|
||||
help_heading = "TAG OPTIONS"
|
||||
)]
|
||||
set: Vec<StringList>,
|
||||
|
||||
/// Remove any delete mark
|
||||
#[clap(
|
||||
long,
|
||||
conflicts_with_all = &["set-delete-never", "set-delete-after"],
|
||||
help_heading = "DELETE MARK OPTIONS"
|
||||
)]
|
||||
remove_delete: bool,
|
||||
|
||||
/// Mark snapshot as uneraseable
|
||||
#[clap(
|
||||
long,
|
||||
conflicts_with = "set-delete-after",
|
||||
help_heading = "DELETE MARK OPTIONS"
|
||||
)]
|
||||
set_delete_never: bool,
|
||||
|
||||
/// Mark snapshot to be deleted after given duration (e.g. 10d)
|
||||
#[clap(long, value_name = "DURATION", help_heading = "DELETE MARK OPTIONS")]
|
||||
set_delete_after: Option<humantime::Duration>,
|
||||
|
||||
/// Snapshots to change tags. If none is given, use filter to filter from all
|
||||
/// snapshots.
|
||||
#[clap(value_name = "ID")]
|
||||
ids: Vec<String>,
|
||||
}
|
||||
|
||||
@ -311,11 +311,11 @@ impl Ord for SnapshotFile {
|
||||
#[derive(Parser)]
|
||||
pub struct SnapshotFilter {
|
||||
/// Path list to filter (can be specified multiple times)
|
||||
#[clap(long = "filter-paths")]
|
||||
#[clap(long = "filter-paths", value_name = "PATH[,PATH,..]")]
|
||||
paths: Vec<StringList>,
|
||||
|
||||
/// Tag list to filter (can be specified multiple times)
|
||||
#[clap(long = "filter-tags")]
|
||||
#[clap(long = "filter-tags", value_name = "TAG[,TAG,..]")]
|
||||
tags: Vec<StringList>,
|
||||
|
||||
/// Hostname to filter (can be specified multiple times)
|
||||
|
||||
Loading…
Reference in New Issue
Block a user