New arguments

pull/10/head
Dennis Schwerdel 2017-04-05 12:41:39 +02:00
parent fe894d2d19
commit faf7b4906f
6 changed files with 111 additions and 156 deletions

38
Cargo.lock generated
View File

@ -6,10 +6,10 @@ dependencies = [
"blake2-rfc 0.2.17 (registry+https://github.com/rust-lang/crates.io-index)",
"byteorder 1.0.0 (registry+https://github.com/rust-lang/crates.io-index)",
"chrono 0.3.0 (registry+https://github.com/rust-lang/crates.io-index)",
"clap 2.21.2 (registry+https://github.com/rust-lang/crates.io-index)",
"clap 2.22.2 (registry+https://github.com/rust-lang/crates.io-index)",
"filetime 0.1.10 (registry+https://github.com/rust-lang/crates.io-index)",
"fuse 0.3.0 (registry+https://github.com/rust-lang/crates.io-index)",
"lazy_static 0.2.5 (registry+https://github.com/rust-lang/crates.io-index)",
"lazy_static 0.2.6 (registry+https://github.com/rust-lang/crates.io-index)",
"libc 0.2.21 (registry+https://github.com/rust-lang/crates.io-index)",
"log 0.3.7 (registry+https://github.com/rust-lang/crates.io-index)",
"mmap 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)",
@ -18,9 +18,9 @@ dependencies = [
"quick-error 1.1.0 (registry+https://github.com/rust-lang/crates.io-index)",
"rand 0.3.15 (registry+https://github.com/rust-lang/crates.io-index)",
"regex 0.2.1 (registry+https://github.com/rust-lang/crates.io-index)",
"rmp-serde 0.12.2 (registry+https://github.com/rust-lang/crates.io-index)",
"rmp-serde 0.12.4 (registry+https://github.com/rust-lang/crates.io-index)",
"rustc-serialize 0.3.23 (registry+https://github.com/rust-lang/crates.io-index)",
"serde 0.9.11 (registry+https://github.com/rust-lang/crates.io-index)",
"serde 0.9.12 (registry+https://github.com/rust-lang/crates.io-index)",
"serde_utils 0.5.1 (registry+https://github.com/rust-lang/crates.io-index)",
"serde_yaml 0.6.2 (registry+https://github.com/rust-lang/crates.io-index)",
"sodiumoxide 0.0.14 (registry+https://github.com/rust-lang/crates.io-index)",
@ -60,7 +60,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
[[package]]
name = "bitflags"
version = "0.8.0"
version = "0.8.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
[[package]]
@ -87,12 +87,12 @@ dependencies = [
[[package]]
name = "clap"
version = "2.21.2"
version = "2.22.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
dependencies = [
"ansi_term 0.9.0 (registry+https://github.com/rust-lang/crates.io-index)",
"atty 0.2.2 (registry+https://github.com/rust-lang/crates.io-index)",
"bitflags 0.8.0 (registry+https://github.com/rust-lang/crates.io-index)",
"bitflags 0.8.2 (registry+https://github.com/rust-lang/crates.io-index)",
"strsim 0.6.0 (registry+https://github.com/rust-lang/crates.io-index)",
"term_size 0.2.3 (registry+https://github.com/rust-lang/crates.io-index)",
"unicode-segmentation 1.1.0 (registry+https://github.com/rust-lang/crates.io-index)",
@ -136,7 +136,7 @@ dependencies = [
[[package]]
name = "lazy_static"
version = "0.2.5"
version = "0.2.6"
source = "registry+https://github.com/rust-lang/crates.io-index"
[[package]]
@ -273,12 +273,12 @@ dependencies = [
[[package]]
name = "rmp-serde"
version = "0.12.2"
version = "0.12.4"
source = "registry+https://github.com/rust-lang/crates.io-index"
dependencies = [
"byteorder 1.0.0 (registry+https://github.com/rust-lang/crates.io-index)",
"rmp 0.8.5 (registry+https://github.com/rust-lang/crates.io-index)",
"serde 0.9.11 (registry+https://github.com/rust-lang/crates.io-index)",
"serde 0.9.12 (registry+https://github.com/rust-lang/crates.io-index)",
]
[[package]]
@ -288,7 +288,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
[[package]]
name = "serde"
version = "0.9.11"
version = "0.9.12"
source = "registry+https://github.com/rust-lang/crates.io-index"
[[package]]
@ -296,7 +296,7 @@ name = "serde_utils"
version = "0.5.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
dependencies = [
"serde 0.9.11 (registry+https://github.com/rust-lang/crates.io-index)",
"serde 0.9.12 (registry+https://github.com/rust-lang/crates.io-index)",
]
[[package]]
@ -305,7 +305,7 @@ version = "0.6.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
dependencies = [
"linked-hash-map 0.3.0 (registry+https://github.com/rust-lang/crates.io-index)",
"serde 0.9.11 (registry+https://github.com/rust-lang/crates.io-index)",
"serde 0.9.12 (registry+https://github.com/rust-lang/crates.io-index)",
"yaml-rust 0.3.5 (registry+https://github.com/rust-lang/crates.io-index)",
]
@ -316,7 +316,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
dependencies = [
"libc 0.2.21 (registry+https://github.com/rust-lang/crates.io-index)",
"libsodium-sys 0.0.14 (registry+https://github.com/rust-lang/crates.io-index)",
"serde 0.9.11 (registry+https://github.com/rust-lang/crates.io-index)",
"serde 0.9.12 (registry+https://github.com/rust-lang/crates.io-index)",
]
[[package]]
@ -460,16 +460,16 @@ dependencies = [
"checksum ansi_term 0.9.0 (registry+https://github.com/rust-lang/crates.io-index)" = "23ac7c30002a5accbf7e8987d0632fa6de155b7c3d39d0067317a391e00a2ef6"
"checksum atty 0.2.2 (registry+https://github.com/rust-lang/crates.io-index)" = "d912da0db7fa85514874458ca3651fe2cddace8d0b0505571dbdcd41ab490159"
"checksum bitflags 0.7.0 (registry+https://github.com/rust-lang/crates.io-index)" = "aad18937a628ec6abcd26d1489012cc0e18c21798210f491af69ded9b881106d"
"checksum bitflags 0.8.0 (registry+https://github.com/rust-lang/crates.io-index)" = "826e1ab483fc81a8143faa7203c4a3c02888ebd1a782e37e41fa34753ba9a162"
"checksum bitflags 0.8.2 (registry+https://github.com/rust-lang/crates.io-index)" = "1370e9fc2a6ae53aea8b7a5110edbd08836ed87c88736dfabccade1c2b44bff4"
"checksum blake2-rfc 0.2.17 (registry+https://github.com/rust-lang/crates.io-index)" = "0c6a476f32fef3402f1161f89d0d39822809627754a126f8441ff2a9d45e2d59"
"checksum byteorder 1.0.0 (registry+https://github.com/rust-lang/crates.io-index)" = "c40977b0ee6b9885c9013cd41d9feffdd22deb3bb4dc3a71d901cc7a77de18c8"
"checksum chrono 0.3.0 (registry+https://github.com/rust-lang/crates.io-index)" = "158b0bd7d75cbb6bf9c25967a48a2e9f77da95876b858eadfabaa99cd069de6e"
"checksum clap 2.21.2 (registry+https://github.com/rust-lang/crates.io-index)" = "58ad5e8142f3a5eab0c1cba5011aa383e009842936107fe4d94f1a8d380a1aec"
"checksum clap 2.22.2 (registry+https://github.com/rust-lang/crates.io-index)" = "3cae8c5a1108961e9bafb1096b8cbb6a31c17ab1a276ce9b52334be99962f653"
"checksum constant_time_eq 0.1.2 (registry+https://github.com/rust-lang/crates.io-index)" = "07dcb7959f0f6f1cf662f9a7ff389bcb919924d99ac41cf31f10d611d8721323"
"checksum filetime 0.1.10 (registry+https://github.com/rust-lang/crates.io-index)" = "5363ab8e4139b8568a6237db5248646e5a8a2f89bd5ccb02092182b11fd3e922"
"checksum fuse 0.3.0 (registry+https://github.com/rust-lang/crates.io-index)" = "5087262ce5b36fed6ccd4abf0a8224e48d055a2bb07fecb5605765de6f114a28"
"checksum kernel32-sys 0.2.2 (registry+https://github.com/rust-lang/crates.io-index)" = "7507624b29483431c0ba2d82aece8ca6cdba9382bff4ddd0f7490560c056098d"
"checksum lazy_static 0.2.5 (registry+https://github.com/rust-lang/crates.io-index)" = "4732c563b9a21a406565c4747daa7b46742f082911ae4753f390dc9ec7ee1a97"
"checksum lazy_static 0.2.6 (registry+https://github.com/rust-lang/crates.io-index)" = "2f61b8421c7a4648c391611625d56fdd5c7567da05af1be655fd8cacc643abb3"
"checksum libc 0.1.12 (registry+https://github.com/rust-lang/crates.io-index)" = "e32a70cf75e5846d53a673923498228bbec6a8624708a9ea5645f075d6276122"
"checksum libc 0.2.21 (registry+https://github.com/rust-lang/crates.io-index)" = "88ee81885f9f04bff991e306fea7c1c60a5f0f9e409e99f6b40e3311a3363135"
"checksum libsodium-sys 0.0.14 (registry+https://github.com/rust-lang/crates.io-index)" = "cbbc6e46017815abf8698de0ed4847fad45fd8cad2909ac38ac6de79673c1ad1"
@ -489,9 +489,9 @@ dependencies = [
"checksum regex 0.2.1 (registry+https://github.com/rust-lang/crates.io-index)" = "4278c17d0f6d62dfef0ab00028feb45bd7d2102843f80763474eeb1be8a10c01"
"checksum regex-syntax 0.4.0 (registry+https://github.com/rust-lang/crates.io-index)" = "2f9191b1f57603095f105d317e375d19b1c9c5c3185ea9633a99a6dcbed04457"
"checksum rmp 0.8.5 (registry+https://github.com/rust-lang/crates.io-index)" = "333f01365885cb192edaa22acb06d7e2f196bfd19d6969419e8b61307e0710ea"
"checksum rmp-serde 0.12.2 (registry+https://github.com/rust-lang/crates.io-index)" = "06ec4d0cdea2645de5d0e649f90c3e654205d913e14adefa452257314a24e76e"
"checksum rmp-serde 0.12.4 (registry+https://github.com/rust-lang/crates.io-index)" = "f0b34c070f2a928d7786da44bfdb4372b547326bbc4757bd0696878558eac0bd"
"checksum rustc-serialize 0.3.23 (registry+https://github.com/rust-lang/crates.io-index)" = "684ce48436d6465300c9ea783b6b14c4361d6b8dcbb1375b486a69cc19e2dfb0"
"checksum serde 0.9.11 (registry+https://github.com/rust-lang/crates.io-index)" = "a702319c807c016e51f672e5c77d6f0b46afddd744b5e437d6b8436b888b458f"
"checksum serde 0.9.12 (registry+https://github.com/rust-lang/crates.io-index)" = "f023838e7e1878c679322dc7f66c3648bd33763a215fad752f378a623856898d"
"checksum serde_utils 0.5.1 (registry+https://github.com/rust-lang/crates.io-index)" = "b34a52969c7fc0254e214b82518c9a95dc88c84fc84cd847add314996a031be6"
"checksum serde_yaml 0.6.2 (registry+https://github.com/rust-lang/crates.io-index)" = "f8bd3f24ad8c7bcd34a6d70ba676dc11302b96f4f166aa5f947762e01098844d"
"checksum sodiumoxide 0.0.14 (registry+https://github.com/rust-lang/crates.io-index)" = "bc02c0bc77ffed8e8eaef004399b825cf4fd8aa02d0af6e473225affd583ff4d"

View File

@ -16,7 +16,7 @@ blake2-rfc = "0.2"
murmurhash3 = "0.0.5"
rustc-serialize = "0.3"
chrono = "0.3"
clap = "2.21"
clap = "2.22"
log = "0.3"
byteorder = "1.0"
ansi_term = "0.9"

1
deb/.gitignore vendored
View File

@ -1,6 +1,7 @@
zvault/debian/zvault
zvault/zvault*
libsquash/src
libsquash/debian/libsquash
*/debian/debhelper*
*/debian/files
*.deb

View File

@ -1,12 +1,12 @@
undefine LDFLAGS
build:
(cd src; ./autogen.sh --prefix=/usr)
git clone https://github.com/quixdb/squash -b 5ea579cae2324f9e814cb3d88aa589dff312e9e2 src
(cd src; ./autogen.sh --prefix=/usr --disable-external)
make -C src
clean:
rm -rf src
git clone https://github.com/quixdb/squash src
install:
make -C src install DESTDIR=$(DESTDIR)

@ -1 +0,0 @@
Subproject commit 5ea579cae2324f9e814cb3d88aa589dff312e9e2

View File

@ -1,6 +1,7 @@
use ::prelude::*;
use super::*;
use clap::{App, AppSettings, Arg, SubCommand};
pub enum Arguments {
Init {
@ -233,139 +234,93 @@ fn parse_bundle_id(val: &str) -> Result<BundleId, ErrorCode> {
#[allow(unknown_lints,cyclomatic_complexity)]
pub fn parse() -> Result<Arguments, ErrorCode> {
let args = clap_app!(zvault =>
(version: crate_version!())
(author: crate_authors!(",\n"))
(about: crate_description!())
(@setting SubcommandRequiredElseHelp)
(@setting GlobalVersion)
(@setting VersionlessSubcommands)
(@setting UnifiedHelpMessage)
(@subcommand init =>
(about: "initializes a new repository")
(@arg bundle_size: --bundlesize +takes_value "maximal bundle size in MiB [default: 25]")
(@arg chunker: --chunker +takes_value "chunker algorithm [default: fastcdc/8]")
(@arg compression: --compression -c +takes_value "compression to use [default: brotli/3]")
(@arg encryption: --encryption -e "generate a keypair and enable encryption")
(@arg hash: --hash +takes_value "hash method to use [default: blake2]")
(@arg remote: --remote -r +takes_value +required "path to the mounted remote storage")
(@arg REPO: "path of the repository")
)
(@subcommand backup =>
(about: "creates a new backup")
(@arg full: --full "create a full backup")
(@arg reference: --ref +takes_value "the reference backup to use for partial backup")
(@arg cross_device: --xdev -x "allow to cross filesystem boundaries")
(@arg exclude: --exclude -e ... +takes_value "exclude this path or file")
(@arg excludes_from: --excludesfrom +takes_value "read the list of exludes from this file")
(@arg no_default_excludes: --nodefaultexcludes "do not load the default excludes file")
(@arg tar: --tar "the source is a tar file")
(@arg SRC: +required "source path to backup")
(@arg BACKUP: +required "repository::backup path")
)
(@subcommand restore =>
(about: "restores a backup (or subpath)")
(@arg tar: --tar "restore in form of a tar file")
(@arg BACKUP: +required "repository::backup[::subpath] path")
(@arg DST: +required "destination path for backup")
)
(@subcommand remove =>
(about: "removes a backup or a subpath")
(@arg BACKUP: +required "repository::backup[::subpath] path")
)
(@subcommand prune =>
(about: "removes backups based on age")
(@arg prefix: --prefix +takes_value "only consider backups starting with this prefix")
(@arg daily: --daily +takes_value "keep this number of daily backups")
(@arg weekly: --weekly +takes_value "keep this number of weekly backups")
(@arg monthly: --monthly +takes_value "keep this number of monthly backups")
(@arg yearly: --yearly +takes_value "keep this number of yearly backups")
(@arg force: --force -f "actually run the prunce instead of simulating it")
(@arg REPO: "path of the repository")
)
(@subcommand vacuum =>
(about: "saves space by combining and recompressing bundles")
(@arg ratio: --ratio -r +takes_value "ratio in % of unused space in a bundle to rewrite that bundle")
(@arg force: --force -f "actually run the vacuum instead of simulating it")
(@arg REPO: "path of the repository")
)
(@subcommand check =>
(about: "checks the repository, a backup or a backup subpath")
(@arg full: --full "also check file contents")
(@arg PATH: "repository[::backup] path")
)
(@subcommand list =>
(about: "lists backups or backup contents")
(@arg PATH: "repository[::backup[::subpath]] path")
)
(@subcommand mount =>
(about: "mount a backup for inspection")
(@arg PATH: "repository[::backup[::subpath]] path")
(@arg MOUNTPOINT: +required "where to mount to backup")
)
(@subcommand bundlelist =>
(about: "lists bundles in a repository")
(@arg REPO: "path of the repository")
)
(@subcommand bundleinfo =>
(about: "lists bundles in a repository")
(@arg REPO: "path of the repository")
(@arg BUNDLE: +required "the bundle id")
)
(@subcommand import =>
(about: "reconstruct a repository from the remote files")
(@arg key: --key -k ... +takes_value "a file with a needed to read the bundles")
(@arg REMOTE: +required "remote repository path")
(@arg REPO: "path of the local repository to create")
)
(@subcommand info =>
(about: "displays information on a repository, a backup or a path in a backup")
(@arg PATH: "repository[::backup[::subpath]] path")
)
(@subcommand analyze =>
(about: "analyze the used and reclaimable space of bundles")
(@arg REPO: "repository path")
)
(@subcommand versions =>
(about: "display different versions of a file in all backups")
(@arg REPO: "repository path")
(@arg PATH: +required "the file path")
)
(@subcommand diff =>
(about: "display difference between two backup versions")
(@arg OLD: +required "old repository::backup[::subpath] path")
(@arg NEW: +required "new repository::backup[::subpath] path")
)
(@subcommand config =>
(about: "changes the configuration")
(@arg REPO: "path of the repository")
(@arg bundle_size: --bundlesize +takes_value "maximal bundle size in MiB [default: 25]")
(@arg chunker: --chunker +takes_value "chunker algorithm [default: fastcdc/16]")
(@arg compression: --compression -c +takes_value "compression to use [default: brotli/3]")
(@arg encryption: --encryption -e +takes_value "the public key to use for encryption")
(@arg hash: --hash +takes_value "hash method to use [default: blake2]")
)
(@subcommand genkey =>
(about: "generates a new key pair")
(@arg FILE: +takes_value "the destination file for the keypair")
)
(@subcommand addkey =>
(about: "adds a key to the respository")
(@arg REPO: "path of the repository")
(@arg generate: --generate -g "generate a new key")
(@arg set_default: --default -d "set this key as default")
(@arg FILE: +takes_value "the file containing the keypair")
)
(@subcommand algotest =>
(about: "test a specific algorithm combination")
(@arg bundle_size: --bundlesize +takes_value "maximal bundle size in MiB [default: 25]")
(@arg chunker: --chunker +takes_value "chunker algorithm [default: fastcdc/16]")
(@arg compression: --compression -c +takes_value "compression to use [default: brotli/3]")
(@arg encrypt: --encrypt -e "enable encryption")
(@arg hash: --hash +takes_value "hash method to use [default: blake2]")
(@arg FILE: +required "the file to test the algorithms with")
)
).get_matches();
let args = App::new("zvault").version(crate_version!()).author(crate_authors!(",\n")).about(crate_description!())
.settings(&[AppSettings::GlobalVersion, AppSettings::VersionlessSubcommands, AppSettings::SubcommandRequiredElseHelp])
.global_settings(&[AppSettings::UnifiedHelpMessage, AppSettings::ColoredHelp, AppSettings::ColorAuto])
.subcommand(SubCommand::with_name("init").about("initializes a new repository")
.arg(Arg::from_usage("bundle_size --bundle-size [SIZE] 'maximal bundle size in MiB [default: 25]'"))
.arg(Arg::from_usage("--chunker [CHUNKER] 'chunker algorithm [default: fastcdc/8]'"))
.arg(Arg::from_usage("-c --compression [COMPRESSION] 'compression to use [default: brotli/3]'"))
.arg(Arg::from_usage("-e --encryption [ENCRYPTION] 'generate a keypair and enable encryption'"))
.arg(Arg::from_usage("--hash [HASH] 'hash method to use [default: blake2]'"))
.arg(Arg::from_usage("-r --remote <REMOTE> 'path to the mounted remote storage'"))
.arg(Arg::from_usage("[REPO] 'path of the repository'")))
.subcommand(SubCommand::with_name("backup").about("creates a new backup")
.arg(Arg::from_usage("--full 'create a full backup'"))
.arg(Arg::from_usage("reference --ref [REF] 'the reference backup to use for partial backup'"))
.arg(Arg::from_usage("cross_device -x --xdev 'allow to cross filesystem boundaries'"))
.arg(Arg::from_usage("-e --exclude [PATTERN]... 'exclude this path or file'"))
.arg(Arg::from_usage("excludes_from --excludes-from [FILE] 'read the list of exludes from this file'"))
.arg(Arg::from_usage("no_default_excludes --no-default-excludes 'do not load the default excludes file'"))
.arg(Arg::from_usage("--tar 'the source is a tar file'"))
.arg(Arg::from_usage("<SRC> 'source path to backup'"))
.arg(Arg::from_usage("<BACKUP> 'repository::backup path'")))
.subcommand(SubCommand::with_name("restore").about("restores a backup (or subpath)")
.arg(Arg::from_usage("--tar 'restore in form of a tar file'"))
.arg(Arg::from_usage("<BACKUP> 'repository::backup[::subpath] path'"))
.arg(Arg::from_usage("<DST> 'destination path for backup'")))
.subcommand(SubCommand::with_name("remove").aliases(&["rm", "delete", "del"]).about("removes a backup or a subpath")
.arg(Arg::from_usage("<BACKUP> 'repository::backup[::subpath] path'")))
.subcommand(SubCommand::with_name("prune").about("removes backups based on age")
.arg(Arg::from_usage("--prefix [PREFIX] 'only consider backups starting with this prefix'"))
.arg(Arg::from_usage("--daily [NUM] 'keep this number of daily backups'"))
.arg(Arg::from_usage("--weekly [NUM] 'keep this number of weekly backups'"))
.arg(Arg::from_usage("--monthly [NUM] 'keep this number of monthly backups'"))
.arg(Arg::from_usage("--yearly [NUM] 'keep this number of yearly backups'"))
.arg(Arg::from_usage("-f --force 'actually run the prunce instead of simulating it'"))
.arg(Arg::from_usage("[REPO] 'path of the repository'")))
.subcommand(SubCommand::with_name("vacuum").about("saves space by combining and recompressing bundles")
.arg(Arg::from_usage("-r --ratio [NUM] 'ratio in % of unused space in a bundle to rewrite that bundle'"))
.arg(Arg::from_usage("-f --force 'actually run the vacuum instead of simulating it'"))
.arg(Arg::from_usage("[REPO] 'path of the repository'")))
.subcommand(SubCommand::with_name("check").about("checks the repository, a backup or a backup subpath")
.arg(Arg::from_usage("--full 'also check file contents'"))
.arg(Arg::from_usage("[PATH] 'repository[::backup] path'")))
.subcommand(SubCommand::with_name("list").alias("ls").about("lists backups or backup contents")
.arg(Arg::from_usage("[PATH] 'repository[::backup[::subpath]] path'")))
.subcommand(SubCommand::with_name("mount").about("mount a backup for inspection")
.arg(Arg::from_usage("[PATH] 'repository[::backup[::subpath]] path'"))
.arg(Arg::from_usage("<MOUNTPOINT> 'where to mount to backup'")))
.subcommand(SubCommand::with_name("bundlelist").about("lists bundles in a repository")
.arg(Arg::from_usage("[REPO] 'path of the repository'")))
.subcommand(SubCommand::with_name("bundleinfo").about("lists bundles in a repository")
.arg(Arg::from_usage("[REPO] 'path of the repository'"))
.arg(Arg::from_usage("<BUNDLE> 'the bundle id'")))
.subcommand(SubCommand::with_name("import").about("reconstruct a repository from the remote files")
.arg(Arg::from_usage("-k --key [FILE]... 'a file with a needed to read the bundles'"))
.arg(Arg::from_usage("<REMOTE> 'remote repository path'"))
.arg(Arg::from_usage("[REPO] 'path of the local repository to create'")))
.subcommand(SubCommand::with_name("info").about("displays information on a repository, a backup or a path in a backup")
.arg(Arg::from_usage("[PATH] 'repository[::backup[::subpath]] path'")))
.subcommand(SubCommand::with_name("analyze").about("analyze the used and reclaimable space of bundles")
.arg(Arg::from_usage("[REPO] 'repository path'")))
.subcommand(SubCommand::with_name("versions").about("display different versions of a file in all backups")
.arg(Arg::from_usage("[REPO] 'repository path'"))
.arg(Arg::from_usage("<PATH> 'the file path'")))
.subcommand(SubCommand::with_name("diff").about("display difference between two backup versions")
.arg(Arg::from_usage("<OLD> 'old repository::backup[::subpath] path'"))
.arg(Arg::from_usage("<NEW> 'new repository::backup[::subpath] path'")))
.subcommand(SubCommand::with_name("config").about("changes the configuration")
.arg(Arg::from_usage("[REPO] 'path of the repository'"))
.arg(Arg::from_usage("bundle_size --bundle-size [SIZE] 'maximal bundle size in MiB [default: 25]'"))
.arg(Arg::from_usage("--chunker [CHUNKER] 'chunker algorithm [default: fastcdc/16]'"))
.arg(Arg::from_usage("-c --compression [COMPRESSION] 'compression to use [default: brotli/3]'"))
.arg(Arg::from_usage("-e --encryption [ENCRYPTION] 'the public key to use for encryption'"))
.arg(Arg::from_usage("--hash [HASH] 'hash method to use [default: blake2]'")))
.subcommand(SubCommand::with_name("genkey").about("generates a new key pair")
.arg(Arg::from_usage("[FILE] 'the destination file for the keypair'")))
.subcommand(SubCommand::with_name("addkey").about("adds a key to the respository")
.arg(Arg::from_usage("[REPO] 'path of the repository'"))
.arg(Arg::from_usage("-g --generate 'generate a new key'").conflicts_with("FILE"))
.arg(Arg::from_usage("set_default --default -d 'set this key as default'"))
.arg(Arg::from_usage("[FILE] 'the file containing the keypair'").conflicts_with("generate")))
.subcommand(SubCommand::with_name("algotest").about("test a specific algorithm combination")
.arg(Arg::from_usage("bundle_size --bundle-size [SIZE] 'maximal bundle size in MiB [default: 25]'"))
.arg(Arg::from_usage("--chunker [CHUNKER] 'chunker algorithm [default: fastcdc/16]'"))
.arg(Arg::from_usage("-c --compression [COMPRESSION] 'compression to use [default: brotli/3]'"))
.arg(Arg::from_usage("-e --encrypt 'enable encryption'"))
.arg(Arg::from_usage("--hash [HASH] 'hash method to use [default: blake2]'"))
.arg(Arg::from_usage("<FILE> 'the file to test the algorithms with'"))).get_matches();
if let Some(args) = args.subcommand_matches("init") {
let (repository, _backup, _inode) = try!(parse_repo_path(args.value_of("REPO").unwrap_or(""), Some(false), Some(false)));
return Ok(Arguments::Init {