Wrap --help output to 120 characters (#7626)
* Update Clap dependency and remove workarounds * WIP * Remove line breaks in help messages for now * Multiple values can only be separated by commas (closes #7428) * Grumbles; refactor repeating code; add constant * Use a single Wrapper rather than allocate a new one for each call * Wrap --help to 120 characters rather than 100 characters
This commit is contained in:
parent
f5c68c601e
commit
fee88d04d4
13
Cargo.lock
generated
13
Cargo.lock
generated
@ -1970,6 +1970,8 @@ dependencies = [
|
|||||||
"serde_derive 1.0.27 (registry+https://github.com/rust-lang/crates.io-index)",
|
"serde_derive 1.0.27 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
"serde_json 1.0.9 (registry+https://github.com/rust-lang/crates.io-index)",
|
"serde_json 1.0.9 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
"tempdir 0.3.5 (registry+https://github.com/rust-lang/crates.io-index)",
|
"tempdir 0.3.5 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
|
"term_size 0.3.1 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
|
"textwrap 0.9.0 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
"time 0.1.38 (registry+https://github.com/rust-lang/crates.io-index)",
|
"time 0.1.38 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
"toml 0.4.5 (registry+https://github.com/rust-lang/crates.io-index)",
|
"toml 0.4.5 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
"winapi 0.2.8 (registry+https://github.com/rust-lang/crates.io-index)",
|
"winapi 0.2.8 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
@ -3084,6 +3086,16 @@ dependencies = [
|
|||||||
"winapi 0.2.8 (registry+https://github.com/rust-lang/crates.io-index)",
|
"winapi 0.2.8 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
]
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "term_size"
|
||||||
|
version = "0.3.1"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
dependencies = [
|
||||||
|
"kernel32-sys 0.2.2 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
|
"libc 0.2.31 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
|
"winapi 0.2.8 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "textwrap"
|
name = "textwrap"
|
||||||
version = "0.9.0"
|
version = "0.9.0"
|
||||||
@ -3788,6 +3800,7 @@ dependencies = [
|
|||||||
"checksum target_info 0.1.0 (registry+https://github.com/rust-lang/crates.io-index)" = "c63f48baada5c52e65a29eef93ab4f8982681b67f9e8d29c7b05abcfec2b9ffe"
|
"checksum target_info 0.1.0 (registry+https://github.com/rust-lang/crates.io-index)" = "c63f48baada5c52e65a29eef93ab4f8982681b67f9e8d29c7b05abcfec2b9ffe"
|
||||||
"checksum tempdir 0.3.5 (registry+https://github.com/rust-lang/crates.io-index)" = "87974a6f5c1dfb344d733055601650059a3363de2a6104819293baff662132d6"
|
"checksum tempdir 0.3.5 (registry+https://github.com/rust-lang/crates.io-index)" = "87974a6f5c1dfb344d733055601650059a3363de2a6104819293baff662132d6"
|
||||||
"checksum term 0.4.6 (registry+https://github.com/rust-lang/crates.io-index)" = "fa63644f74ce96fbeb9b794f66aff2a52d601cbd5e80f4b97123e3899f4570f1"
|
"checksum term 0.4.6 (registry+https://github.com/rust-lang/crates.io-index)" = "fa63644f74ce96fbeb9b794f66aff2a52d601cbd5e80f4b97123e3899f4570f1"
|
||||||
|
"checksum term_size 0.3.1 (registry+https://github.com/rust-lang/crates.io-index)" = "9e5b9a66db815dcfd2da92db471106457082577c3c278d4138ab3e3b4e189327"
|
||||||
"checksum textwrap 0.9.0 (registry+https://github.com/rust-lang/crates.io-index)" = "c0b59b6b4b44d867f1370ef1bd91bfb262bf07bf0ae65c202ea2fbc16153b693"
|
"checksum textwrap 0.9.0 (registry+https://github.com/rust-lang/crates.io-index)" = "c0b59b6b4b44d867f1370ef1bd91bfb262bf07bf0ae65c202ea2fbc16153b693"
|
||||||
"checksum thread_local 0.3.4 (registry+https://github.com/rust-lang/crates.io-index)" = "1697c4b57aeeb7a536b647165a2825faddffb1d3bad386d507709bd51a90bb14"
|
"checksum thread_local 0.3.4 (registry+https://github.com/rust-lang/crates.io-index)" = "1697c4b57aeeb7a536b647165a2825faddffb1d3bad386d507709bd51a90bb14"
|
||||||
"checksum threadpool 1.7.1 (registry+https://github.com/rust-lang/crates.io-index)" = "e2f0c90a5f3459330ac8bc0d2f879c693bb7a2f59689c1083fc4ef83834da865"
|
"checksum threadpool 1.7.1 (registry+https://github.com/rust-lang/crates.io-index)" = "e2f0c90a5f3459330ac8bc0d2f879c693bb7a2f59689c1083fc4ef83834da865"
|
||||||
|
@ -11,6 +11,8 @@ env_logger = "0.4"
|
|||||||
rustc-hex = "1.0"
|
rustc-hex = "1.0"
|
||||||
docopt = "0.8"
|
docopt = "0.8"
|
||||||
clap = "2"
|
clap = "2"
|
||||||
|
term_size = "0.3"
|
||||||
|
textwrap = "0.9"
|
||||||
time = "0.1"
|
time = "0.1"
|
||||||
num_cpus = "1.2"
|
num_cpus = "1.2"
|
||||||
number_prefix = "0.2"
|
number_prefix = "0.2"
|
||||||
|
@ -257,12 +257,7 @@ usage! {
|
|||||||
|
|
||||||
ARG arg_mode: (String) = "last", or |c: &Config| otry!(c.parity).mode.clone(),
|
ARG arg_mode: (String) = "last", or |c: &Config| otry!(c.parity).mode.clone(),
|
||||||
"--mode=[MODE]",
|
"--mode=[MODE]",
|
||||||
"Set the operating mode. MODE can be one of:
|
"Set the operating mode. MODE can be one of: last - Uses the last-used mode, active if none; active - Parity continuously syncs the chain; passive - Parity syncs initially, then sleeps and wakes regularly to resync; dark - Parity syncs only when the RPC is active; offline - Parity doesn't sync.",
|
||||||
last - Uses the last-used mode, active if none.
|
|
||||||
active - Parity continuously syncs the chain.
|
|
||||||
passive - Parity syncs initially, then sleeps and wakes regularly to resync.
|
|
||||||
dark - Parity syncs only when the RPC is active.
|
|
||||||
offline - Parity doesn't sync.",
|
|
||||||
|
|
||||||
ARG arg_mode_timeout: (u64) = 300u64, or |c: &Config| otry!(c.parity).mode_timeout.clone(),
|
ARG arg_mode_timeout: (u64) = 300u64, or |c: &Config| otry!(c.parity).mode_timeout.clone(),
|
||||||
"--mode-timeout=[SECS]",
|
"--mode-timeout=[SECS]",
|
||||||
@ -274,19 +269,11 @@ usage! {
|
|||||||
|
|
||||||
ARG arg_auto_update: (String) = "critical", or |c: &Config| otry!(c.parity).auto_update.clone(),
|
ARG arg_auto_update: (String) = "critical", or |c: &Config| otry!(c.parity).auto_update.clone(),
|
||||||
"--auto-update=[SET]",
|
"--auto-update=[SET]",
|
||||||
"Set a releases set to automatically update and install.
|
"Set a releases set to automatically update and install. SET can be one of: all - All updates in the our release track; critical - Only consensus/security updates; none - No updates will be auto-installed.",
|
||||||
all - All updates in the our release track.
|
|
||||||
critical - Only consensus/security updates.
|
|
||||||
none - No updates will be auto-installed.",
|
|
||||||
|
|
||||||
ARG arg_release_track: (String) = "current", or |c: &Config| otry!(c.parity).release_track.clone(),
|
ARG arg_release_track: (String) = "current", or |c: &Config| otry!(c.parity).release_track.clone(),
|
||||||
"--release-track=[TRACK]",
|
"--release-track=[TRACK]",
|
||||||
"Set which release track we should use for updates.
|
"Set which release track we should use for updates. TRACK can be one of: stable - Stable releases; beta - Beta releases; nightly - Nightly releases (unstable); testing - Testing releases (do not use); current - Whatever track this executable was released on.",
|
||||||
stable - Stable releases.
|
|
||||||
beta - Beta releases.
|
|
||||||
nightly - Nightly releases (unstable).
|
|
||||||
testing - Testing releases (do not use).
|
|
||||||
current - Whatever track this executable was released on",
|
|
||||||
|
|
||||||
ARG arg_chain: (String) = "foundation", or |c: &Config| otry!(c.parity).chain.clone(),
|
ARG arg_chain: (String) = "foundation", or |c: &Config| otry!(c.parity).chain.clone(),
|
||||||
"--chain=[CHAIN]",
|
"--chain=[CHAIN]",
|
||||||
@ -311,8 +298,7 @@ usage! {
|
|||||||
["Convenience options"]
|
["Convenience options"]
|
||||||
FLAG flag_unsafe_expose: (bool) = false, or |c: &Config| otry!(c.misc).unsafe_expose,
|
FLAG flag_unsafe_expose: (bool) = false, or |c: &Config| otry!(c.misc).unsafe_expose,
|
||||||
"--unsafe-expose",
|
"--unsafe-expose",
|
||||||
"All servers will listen on external interfaces and will be remotely accessible. It's equivalent with setting the following: --{{ws,jsonrpc,ui,ipfs,secret_store,stratum}}-interface=all --*-hosts=all
|
"All servers will listen on external interfaces and will be remotely accessible. It's equivalent with setting the following: --{{ws,jsonrpc,ui,ipfs,secret_store,stratum}}-interface=all --*-hosts=all This option is UNSAFE and should be used with great care!",
|
||||||
This option is UNSAFE and should be used with great care!",
|
|
||||||
|
|
||||||
ARG arg_config: (String) = "$BASE/config.toml", or |_| None,
|
ARG arg_config: (String) = "$BASE/config.toml", or |_| None,
|
||||||
"-c, --config=[CONFIG]",
|
"-c, --config=[CONFIG]",
|
||||||
@ -498,7 +484,7 @@ usage! {
|
|||||||
|
|
||||||
ARG arg_ws_hosts: (String) = "none", or |c: &Config| otry!(c.websockets).hosts.as_ref().map(|vec| vec.join(",")),
|
ARG arg_ws_hosts: (String) = "none", or |c: &Config| otry!(c.websockets).hosts.as_ref().map(|vec| vec.join(",")),
|
||||||
"--ws-hosts=[HOSTS]",
|
"--ws-hosts=[HOSTS]",
|
||||||
"List of allowed Host header values. This option will validate the Host header sent by the browser, it is additional security against some attack vectors. Special options: \"all\", \"none\",.",
|
"List of allowed Host header values. This option will validate the Host header sent by the browser, it is additional security against some attack vectors. Special options: \"all\", \"none\".",
|
||||||
|
|
||||||
["API and console options – IPC"]
|
["API and console options – IPC"]
|
||||||
FLAG flag_no_ipc: (bool) = false, or |c: &Config| otry!(c.ipc).disable.clone(),
|
FLAG flag_no_ipc: (bool) = false, or |c: &Config| otry!(c.ipc).disable.clone(),
|
||||||
@ -586,7 +572,7 @@ usage! {
|
|||||||
|
|
||||||
ARG arg_secretstore_path: (String) = "$BASE/secretstore", or |c: &Config| otry!(c.secretstore).path.clone(),
|
ARG arg_secretstore_path: (String) = "$BASE/secretstore", or |c: &Config| otry!(c.secretstore).path.clone(),
|
||||||
"--secretstore-path=[PATH]",
|
"--secretstore-path=[PATH]",
|
||||||
"Specify directory where Secret Store should save its data..",
|
"Specify directory where Secret Store should save its data.",
|
||||||
|
|
||||||
ARG arg_secretstore_secret: (Option<String>) = None, or |c: &Config| otry!(c.secretstore).self_secret.clone(),
|
ARG arg_secretstore_secret: (Option<String>) = None, or |c: &Config| otry!(c.secretstore).self_secret.clone(),
|
||||||
"--secretstore-secret=[SECRET]",
|
"--secretstore-secret=[SECRET]",
|
||||||
@ -675,7 +661,7 @@ usage! {
|
|||||||
|
|
||||||
ARG arg_tx_queue_gas: (String) = "off", or |c: &Config| otry!(c.mining).tx_queue_gas.clone(),
|
ARG arg_tx_queue_gas: (String) = "off", or |c: &Config| otry!(c.mining).tx_queue_gas.clone(),
|
||||||
"--tx-queue-gas=[LIMIT]",
|
"--tx-queue-gas=[LIMIT]",
|
||||||
"Maximum amount of total gas for external transactions in the queue. LIMIT can be either an amount of gas or 'auto' or 'off'. 'auto' sets the limit to be 20x the current block gas limit..",
|
"Maximum amount of total gas for external transactions in the queue. LIMIT can be either an amount of gas or 'auto' or 'off'. 'auto' sets the limit to be 20x the current block gas limit.",
|
||||||
|
|
||||||
ARG arg_tx_queue_strategy: (String) = "gas_price", or |c: &Config| otry!(c.mining).tx_queue_strategy.clone(),
|
ARG arg_tx_queue_strategy: (String) = "gas_price", or |c: &Config| otry!(c.mining).tx_queue_strategy.clone(),
|
||||||
"--tx-queue-strategy=[S]",
|
"--tx-queue-strategy=[S]",
|
||||||
@ -782,7 +768,7 @@ usage! {
|
|||||||
|
|
||||||
ARG arg_pruning_history: (u64) = 64u64, or |c: &Config| otry!(c.footprint).pruning_history.clone(),
|
ARG arg_pruning_history: (u64) = 64u64, or |c: &Config| otry!(c.footprint).pruning_history.clone(),
|
||||||
"--pruning-history=[NUM]",
|
"--pruning-history=[NUM]",
|
||||||
"Set a minimum number of recent states to keep when pruning is active..",
|
"Set a minimum number of recent states to keep when pruning is active.",
|
||||||
|
|
||||||
ARG arg_pruning_memory: (usize) = 32usize, or |c: &Config| otry!(c.footprint).pruning_memory.clone(),
|
ARG arg_pruning_memory: (usize) = 32usize, or |c: &Config| otry!(c.footprint).pruning_memory.clone(),
|
||||||
"--pruning-memory=[MB]",
|
"--pruning-memory=[MB]",
|
||||||
@ -1327,12 +1313,15 @@ mod tests {
|
|||||||
let args = Args::parse(&["parity", "--secretstore-nodes", "abc@127.0.0.1:3333,cde@10.10.10.10:4444"]).unwrap();
|
let args = Args::parse(&["parity", "--secretstore-nodes", "abc@127.0.0.1:3333,cde@10.10.10.10:4444"]).unwrap();
|
||||||
assert_eq!(args.arg_secretstore_nodes, "abc@127.0.0.1:3333,cde@10.10.10.10:4444");
|
assert_eq!(args.arg_secretstore_nodes, "abc@127.0.0.1:3333,cde@10.10.10.10:4444");
|
||||||
|
|
||||||
// Arguments with a single value shouldn't accept multiple values
|
let args = Args::parse(&["parity", "--password", "~/.safe/1", "--password", "~/.safe/2", "--ui-port", "8123", "ui"]).unwrap();
|
||||||
let args = Args::parse(&["parity", "--auto-update", "critical", "all"]);
|
|
||||||
assert!(args.is_err());
|
|
||||||
|
|
||||||
let args = Args::parse(&["parity", "--password", "~/.safe/1", "~/.safe/2"]).unwrap();
|
|
||||||
assert_eq!(args.arg_password, vec!["~/.safe/1".to_owned(), "~/.safe/2".to_owned()]);
|
assert_eq!(args.arg_password, vec!["~/.safe/1".to_owned(), "~/.safe/2".to_owned()]);
|
||||||
|
assert_eq!(args.arg_ui_port, 8123);
|
||||||
|
assert_eq!(args.cmd_ui, true);
|
||||||
|
|
||||||
|
let args = Args::parse(&["parity", "--password", "~/.safe/1,~/.safe/2", "--ui-port", "8123", "ui"]).unwrap();
|
||||||
|
assert_eq!(args.arg_password, vec!["~/.safe/1".to_owned(), "~/.safe/2".to_owned()]);
|
||||||
|
assert_eq!(args.arg_ui_port, 8123);
|
||||||
|
assert_eq!(args.cmd_ui, true);
|
||||||
}
|
}
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
|
@ -150,14 +150,20 @@ macro_rules! usage {
|
|||||||
}
|
}
|
||||||
) => {
|
) => {
|
||||||
use toml;
|
use toml;
|
||||||
use std::{fs, io, process};
|
use std::{fs, io, process, cmp};
|
||||||
use std::io::{Read, Write};
|
use std::io::{Read, Write};
|
||||||
use parity_version::version;
|
use parity_version::version;
|
||||||
use clap::{Arg, App, SubCommand, AppSettings, ArgMatches as ClapArgMatches, Error as ClapError, ErrorKind as ClapErrorKind};
|
use clap::{Arg, App, SubCommand, AppSettings, ArgSettings, Error as ClapError, ErrorKind as ClapErrorKind};
|
||||||
use dir::helpers::replace_home;
|
use dir::helpers::replace_home;
|
||||||
use std::ffi::OsStr;
|
use std::ffi::OsStr;
|
||||||
use std::collections::HashMap;
|
use std::collections::HashMap;
|
||||||
|
|
||||||
|
extern crate textwrap;
|
||||||
|
extern crate term_size;
|
||||||
|
use self::textwrap::{Wrapper};
|
||||||
|
|
||||||
|
const MAX_TERM_WIDTH: usize = 120;
|
||||||
|
|
||||||
#[cfg(test)]
|
#[cfg(test)]
|
||||||
use regex::Regex;
|
use regex::Regex;
|
||||||
|
|
||||||
@ -365,11 +371,23 @@ macro_rules! usage {
|
|||||||
#[allow(unused_mut)] // subc_subc_exist may be assigned true by the macro
|
#[allow(unused_mut)] // subc_subc_exist may be assigned true by the macro
|
||||||
#[allow(unused_assignments)] // Rust issue #22630
|
#[allow(unused_assignments)] // Rust issue #22630
|
||||||
pub fn print_help() -> String {
|
pub fn print_help() -> String {
|
||||||
|
|
||||||
|
const TAB: &str = " ";
|
||||||
|
const TAB_TAB: &str = " ";
|
||||||
|
|
||||||
|
let term_width = match term_size::dimensions() {
|
||||||
|
None => MAX_TERM_WIDTH,
|
||||||
|
Some((w, _)) => {
|
||||||
|
cmp::min(w, MAX_TERM_WIDTH)
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
let mut help : String = include_str!("./usage_header.txt").to_owned();
|
let mut help : String = include_str!("./usage_header.txt").to_owned();
|
||||||
|
|
||||||
help.push_str("\n\n");
|
help.push_str("\n");
|
||||||
|
|
||||||
// Subcommands
|
// Subcommands
|
||||||
|
let mut subcommands_wrapper = Wrapper::new(term_width).subsequent_indent(TAB);
|
||||||
help.push_str("parity [options]\n");
|
help.push_str("parity [options]\n");
|
||||||
$(
|
$(
|
||||||
{
|
{
|
||||||
@ -386,11 +404,14 @@ macro_rules! usage {
|
|||||||
)*
|
)*
|
||||||
];
|
];
|
||||||
|
|
||||||
if subc_subc_usages.is_empty() {
|
help.push_str(&subcommands_wrapper.fill(
|
||||||
help.push_str(&format!("parity [options] {} {}\n", underscore_to_hyphen!(&stringify!($subc)[4..]), underscore_to_hyphen!(&stringify!($subc_subc)[stringify!($subc).len()+1..])));
|
format!(
|
||||||
} else {
|
"parity [options] {} {} {}\n",
|
||||||
help.push_str(&format!("parity [options] {} {} {}\n", underscore_to_hyphen!(&stringify!($subc)[4..]), underscore_to_hyphen!(&stringify!($subc_subc)[stringify!($subc).len()+1..]), subc_subc_usages.join(" ")));
|
underscore_to_hyphen!(&stringify!($subc)[4..]),
|
||||||
}
|
underscore_to_hyphen!(&stringify!($subc_subc)[stringify!($subc).len()+1..]),
|
||||||
|
subc_subc_usages.join(" ")
|
||||||
|
).as_ref())
|
||||||
|
);
|
||||||
)*
|
)*
|
||||||
|
|
||||||
// Print the subcommand on its own only if it has no subsubcommands
|
// Print the subcommand on its own only if it has no subsubcommands
|
||||||
@ -404,22 +425,30 @@ macro_rules! usage {
|
|||||||
)*
|
)*
|
||||||
];
|
];
|
||||||
|
|
||||||
if subc_usages.is_empty() {
|
help.push_str(&subcommands_wrapper.fill(
|
||||||
help.push_str(&format!("parity [options] {}\n", underscore_to_hyphen!(&stringify!($subc)[4..])));
|
format!(
|
||||||
} else {
|
"parity [options] {} {}\n",
|
||||||
help.push_str(&format!("parity [options] {} {}\n", underscore_to_hyphen!(&stringify!($subc)[4..]), subc_usages.join(" ")));
|
underscore_to_hyphen!(&stringify!($subc)[4..]),
|
||||||
}
|
subc_usages.join(" ")
|
||||||
|
).as_ref())
|
||||||
|
);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
)*
|
)*
|
||||||
|
|
||||||
|
help.push_str("\n");
|
||||||
|
|
||||||
// Arguments and flags
|
// Arguments and flags
|
||||||
|
let args_wrapper = Wrapper::new(term_width).initial_indent(TAB_TAB).subsequent_indent(TAB_TAB);
|
||||||
$(
|
$(
|
||||||
help.push_str("\n");
|
|
||||||
help.push_str($group_name); help.push_str(":\n");
|
help.push_str($group_name); help.push_str(":\n");
|
||||||
|
|
||||||
$(
|
$(
|
||||||
help.push_str(&format!("\t{}\n\t\t{}\n", $flag_usage, $flag_help));
|
help.push_str(&format!("{}{}\n{}\n",
|
||||||
|
TAB, $flag_usage,
|
||||||
|
args_wrapper.fill($flag_help)
|
||||||
|
));
|
||||||
|
help.push_str("\n");
|
||||||
)*
|
)*
|
||||||
|
|
||||||
$(
|
$(
|
||||||
@ -429,10 +458,24 @@ macro_rules! usage {
|
|||||||
if_option_vec!(
|
if_option_vec!(
|
||||||
$($arg_type_tt)+,
|
$($arg_type_tt)+,
|
||||||
THEN {
|
THEN {
|
||||||
help.push_str(&format!("\t{}\n\t\t{} (default: {:?})\n", $arg_usage, $arg_help, {let x : inner_option_type!($($arg_type_tt)+)> = $arg_default; x}))
|
help.push_str(&format!("{}{}\n{}\n",
|
||||||
|
TAB, $arg_usage,
|
||||||
|
args_wrapper.fill(format!(
|
||||||
|
"{} (default: {:?})",
|
||||||
|
$arg_help,
|
||||||
|
{let x : inner_option_type!($($arg_type_tt)+)> = $arg_default; x}
|
||||||
|
).as_ref())
|
||||||
|
))
|
||||||
}
|
}
|
||||||
ELSE {
|
ELSE {
|
||||||
help.push_str(&format!("\t{}\n\t\t{}{}\n", $arg_usage, $arg_help, $arg_default.map(|x: inner_option_type!($($arg_type_tt)+)| format!(" (default: {})",x)).unwrap_or("".to_owned())))
|
help.push_str(&format!("{}{}\n{}\n",
|
||||||
|
TAB, $arg_usage,
|
||||||
|
args_wrapper.fill(format!(
|
||||||
|
"{}{}",
|
||||||
|
$arg_help,
|
||||||
|
$arg_default.map(|x: inner_option_type!($($arg_type_tt)+)| format!(" (default: {})",x)).unwrap_or("".to_owned())
|
||||||
|
).as_ref())
|
||||||
|
))
|
||||||
}
|
}
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
@ -440,14 +483,27 @@ macro_rules! usage {
|
|||||||
if_vec!(
|
if_vec!(
|
||||||
$($arg_type_tt)+,
|
$($arg_type_tt)+,
|
||||||
THEN {
|
THEN {
|
||||||
help.push_str(&format!("\t{}\n\t\t{} (default: {:?})\n", $arg_usage, $arg_help, {let x : $($arg_type_tt)+ = $arg_default; x}))
|
help.push_str(&format!("{}{}\n{}\n", TAB, $arg_usage,
|
||||||
|
args_wrapper.fill(format!(
|
||||||
|
"{} (default: {:?})",
|
||||||
|
$arg_help,
|
||||||
|
{let x : $($arg_type_tt)+ = $arg_default; x}
|
||||||
|
).as_ref())
|
||||||
|
))
|
||||||
}
|
}
|
||||||
ELSE {
|
ELSE {
|
||||||
help.push_str(&format!("\t{}\n\t\t{} (default: {})\n", $arg_usage, $arg_help, $arg_default))
|
help.push_str(&format!("{}{}\n{}\n", TAB, $arg_usage,
|
||||||
|
args_wrapper.fill(format!(
|
||||||
|
"{} (default: {})",
|
||||||
|
$arg_help,
|
||||||
|
$arg_default
|
||||||
|
).as_ref())
|
||||||
|
))
|
||||||
}
|
}
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
);
|
);
|
||||||
|
help.push_str("\n");
|
||||||
)*
|
)*
|
||||||
|
|
||||||
)*
|
)*
|
||||||
@ -503,36 +559,6 @@ macro_rules! usage {
|
|||||||
args
|
args
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn hydrate_with_globals(self: &mut Self, matches: &ClapArgMatches) -> Result<(), ClapError> {
|
|
||||||
$(
|
|
||||||
$(
|
|
||||||
self.$flag = self.$flag || matches.is_present(stringify!($flag));
|
|
||||||
)*
|
|
||||||
$(
|
|
||||||
if let some @ Some(_) = return_if_parse_error!(if_option!(
|
|
||||||
$($arg_type_tt)+,
|
|
||||||
THEN {
|
|
||||||
if_option_vec!(
|
|
||||||
$($arg_type_tt)+,
|
|
||||||
THEN { values_t!(matches, stringify!($arg), inner_option_vec_type!($($arg_type_tt)+)) }
|
|
||||||
ELSE { value_t!(matches, stringify!($arg), inner_option_type!($($arg_type_tt)+)) }
|
|
||||||
)
|
|
||||||
}
|
|
||||||
ELSE {
|
|
||||||
if_vec!(
|
|
||||||
$($arg_type_tt)+,
|
|
||||||
THEN { values_t!(matches, stringify!($arg), inner_vec_type!($($arg_type_tt)+)) }
|
|
||||||
ELSE { value_t!(matches, stringify!($arg), $($arg_type_tt)+) }
|
|
||||||
)
|
|
||||||
}
|
|
||||||
)) {
|
|
||||||
self.$arg = some;
|
|
||||||
}
|
|
||||||
)*
|
|
||||||
)*
|
|
||||||
Ok(())
|
|
||||||
}
|
|
||||||
|
|
||||||
#[allow(unused_variables)] // the submatches of arg-less subcommands aren't used
|
#[allow(unused_variables)] // the submatches of arg-less subcommands aren't used
|
||||||
pub fn parse<S: AsRef<str>>(command: &[S]) -> Result<Self, ClapError> {
|
pub fn parse<S: AsRef<str>>(command: &[S]) -> Result<Self, ClapError> {
|
||||||
|
|
||||||
@ -582,21 +608,31 @@ macro_rules! usage {
|
|||||||
let matches = App::new("Parity")
|
let matches = App::new("Parity")
|
||||||
.global_setting(AppSettings::VersionlessSubcommands)
|
.global_setting(AppSettings::VersionlessSubcommands)
|
||||||
.global_setting(AppSettings::DisableHelpSubcommand)
|
.global_setting(AppSettings::DisableHelpSubcommand)
|
||||||
|
.max_term_width(MAX_TERM_WIDTH)
|
||||||
.help(Args::print_help().as_ref())
|
.help(Args::print_help().as_ref())
|
||||||
.args(&usages.iter().map(|u| Arg::from_usage(u).use_delimiter(false).allow_hyphen_values(true)).collect::<Vec<Arg>>())
|
.args(&usages.iter().map(|u| {
|
||||||
|
let mut arg = Arg::from_usage(u)
|
||||||
|
.allow_hyphen_values(true) // Allow for example --allow-ips -10.0.0.0/8
|
||||||
|
.global(true) // Argument doesn't have to come before the first subcommand
|
||||||
|
.hidden(true); // Hide global arguments from the (subcommand) help messages generated by Clap
|
||||||
|
|
||||||
|
if arg.is_set(ArgSettings::Multiple) {
|
||||||
|
arg = arg.require_delimiter(true); // Multiple values can only be separated by commas, not spaces (#7428)
|
||||||
|
}
|
||||||
|
|
||||||
|
arg
|
||||||
|
}).collect::<Vec<Arg>>())
|
||||||
$(
|
$(
|
||||||
.subcommand(
|
.subcommand(
|
||||||
SubCommand::with_name(&underscore_to_hyphen!(&stringify!($subc)[4..]))
|
SubCommand::with_name(&underscore_to_hyphen!(&stringify!($subc)[4..]))
|
||||||
.about($subc_help)
|
.about($subc_help)
|
||||||
.args(&subc_usages.get(stringify!($subc)).unwrap().iter().map(|u| Arg::from_usage(u).use_delimiter(false).allow_hyphen_values(true)).collect::<Vec<Arg>>())
|
.args(&subc_usages.get(stringify!($subc)).unwrap().iter().map(|u| Arg::from_usage(u).use_delimiter(false).allow_hyphen_values(true)).collect::<Vec<Arg>>())
|
||||||
.args(&usages.iter().map(|u| Arg::from_usage(u).use_delimiter(false).allow_hyphen_values(true)).collect::<Vec<Arg>>()) // accept global arguments at this position
|
|
||||||
$(
|
$(
|
||||||
.setting(AppSettings::SubcommandRequired) // prevent from running `parity account`
|
.setting(AppSettings::SubcommandRequired) // prevent from running `parity account`
|
||||||
.subcommand(
|
.subcommand(
|
||||||
SubCommand::with_name(&underscore_to_hyphen!(&stringify!($subc_subc)[stringify!($subc).len()+1..]))
|
SubCommand::with_name(&underscore_to_hyphen!(&stringify!($subc_subc)[stringify!($subc).len()+1..]))
|
||||||
.about($subc_subc_help)
|
.about($subc_subc_help)
|
||||||
.args(&subc_usages.get(stringify!($subc_subc)).unwrap().iter().map(|u| Arg::from_usage(u).use_delimiter(false).allow_hyphen_values(true)).collect::<Vec<Arg>>())
|
.args(&subc_usages.get(stringify!($subc_subc)).unwrap().iter().map(|u| Arg::from_usage(u).use_delimiter(false).allow_hyphen_values(true)).collect::<Vec<Arg>>())
|
||||||
.args(&usages.iter().map(|u| Arg::from_usage(u).use_delimiter(false).allow_hyphen_values(true)).collect::<Vec<Arg>>()) // accept global arguments at this position
|
|
||||||
)
|
)
|
||||||
)*
|
)*
|
||||||
)
|
)
|
||||||
@ -605,15 +641,39 @@ macro_rules! usage {
|
|||||||
|
|
||||||
let mut raw_args : RawArgs = Default::default();
|
let mut raw_args : RawArgs = Default::default();
|
||||||
|
|
||||||
raw_args.hydrate_with_globals(&matches)?;
|
// Globals
|
||||||
|
$(
|
||||||
|
$(
|
||||||
|
raw_args.$flag = raw_args.$flag || matches.is_present(stringify!($flag));
|
||||||
|
)*
|
||||||
|
$(
|
||||||
|
if let some @ Some(_) = return_if_parse_error!(if_option!(
|
||||||
|
$($arg_type_tt)+,
|
||||||
|
THEN {
|
||||||
|
if_option_vec!(
|
||||||
|
$($arg_type_tt)+,
|
||||||
|
THEN { values_t!(matches, stringify!($arg), inner_option_vec_type!($($arg_type_tt)+)) }
|
||||||
|
ELSE { value_t!(matches, stringify!($arg), inner_option_type!($($arg_type_tt)+)) }
|
||||||
|
)
|
||||||
|
}
|
||||||
|
ELSE {
|
||||||
|
if_vec!(
|
||||||
|
$($arg_type_tt)+,
|
||||||
|
THEN { values_t!(matches, stringify!($arg), inner_vec_type!($($arg_type_tt)+)) }
|
||||||
|
ELSE { value_t!(matches, stringify!($arg), $($arg_type_tt)+) }
|
||||||
|
)
|
||||||
|
}
|
||||||
|
)) {
|
||||||
|
raw_args.$arg = some;
|
||||||
|
}
|
||||||
|
)*
|
||||||
|
)*
|
||||||
|
|
||||||
// Subcommands
|
// Subcommands
|
||||||
$(
|
$(
|
||||||
if let Some(submatches) = matches.subcommand_matches(&underscore_to_hyphen!(&stringify!($subc)[4..])) {
|
if let Some(submatches) = matches.subcommand_matches(&underscore_to_hyphen!(&stringify!($subc)[4..])) {
|
||||||
raw_args.$subc = true;
|
raw_args.$subc = true;
|
||||||
|
|
||||||
// Globals
|
|
||||||
raw_args.hydrate_with_globals(&submatches)?;
|
|
||||||
// Subcommand flags
|
// Subcommand flags
|
||||||
$(
|
$(
|
||||||
raw_args.$subc_flag = submatches.is_present(&stringify!($subc_flag));
|
raw_args.$subc_flag = submatches.is_present(&stringify!($subc_flag));
|
||||||
@ -643,8 +703,6 @@ macro_rules! usage {
|
|||||||
if let Some(subsubmatches) = submatches.subcommand_matches(&underscore_to_hyphen!(&stringify!($subc_subc)[stringify!($subc).len()+1..])) {
|
if let Some(subsubmatches) = submatches.subcommand_matches(&underscore_to_hyphen!(&stringify!($subc_subc)[stringify!($subc).len()+1..])) {
|
||||||
raw_args.$subc_subc = true;
|
raw_args.$subc_subc = true;
|
||||||
|
|
||||||
// Globals
|
|
||||||
raw_args.hydrate_with_globals(&subsubmatches)?;
|
|
||||||
// Sub-subcommand flags
|
// Sub-subcommand flags
|
||||||
$(
|
$(
|
||||||
raw_args.$subc_subc_flag = subsubmatches.is_present(&stringify!($subc_subc_flag));
|
raw_args.$subc_subc_flag = subsubmatches.is_present(&stringify!($subc_subc_flag));
|
||||||
|
@ -1,3 +1,3 @@
|
|||||||
Parity. Ethereum Client.
|
Parity. Ethereum Client.
|
||||||
By Wood/Paronyan/Kotewicz/Drwięga/Volf et al.
|
By Wood/Paronyan/Kotewicz/Drwięga/Volf et al.
|
||||||
Copyright 2015, 2016, 2017 Parity Technologies (UK) Ltd
|
Copyright 2015, 2016, 2017, 2018 Parity Technologies (UK) Ltd
|
||||||
|
@ -1,6 +1,6 @@
|
|||||||
Parity
|
Parity
|
||||||
version {}
|
version {}
|
||||||
Copyright 2015, 2016, 2017 Parity Technologies (UK) Ltd
|
Copyright 2015, 2016, 2017, 2018 Parity Technologies (UK) Ltd
|
||||||
License GPLv3+: GNU GPL version 3 or later <http://gnu.org/licenses/gpl.html>.
|
License GPLv3+: GNU GPL version 3 or later <http://gnu.org/licenses/gpl.html>.
|
||||||
This is free software: you are free to change and redistribute it.
|
This is free software: you are free to change and redistribute it.
|
||||||
There is NO WARRANTY, to the extent permitted by law.
|
There is NO WARRANTY, to the extent permitted by law.
|
||||||
|
Loading…
Reference in New Issue
Block a user