mirror of
https://github.com/clap-rs/clap
synced 2025-03-04 23:37:32 +00:00
Merge pull request #2515 from clap-rs/yaml
Ignore extra fields in YAML only when specified
This commit is contained in:
commit
a8134ddcda
15 changed files with 263 additions and 210 deletions
|
@ -92,6 +92,9 @@
|
|||
"$ref": "#/structures/tuple3StrOptStrStr"
|
||||
}
|
||||
},
|
||||
"default_missing_value": {
|
||||
"type": "string"
|
||||
},
|
||||
"display_order": {
|
||||
"type": "integer"
|
||||
},
|
||||
|
@ -110,9 +113,6 @@
|
|||
"groups": {
|
||||
"$ref": "#/structures/arrayStrUnique"
|
||||
},
|
||||
"help": {
|
||||
"type": "string"
|
||||
},
|
||||
"help_heading": {
|
||||
"$ref": "#/structures/optionalStr"
|
||||
},
|
||||
|
@ -128,10 +128,10 @@
|
|||
"hide_default_value": {
|
||||
"type": "boolean"
|
||||
},
|
||||
"hide_env_value": {
|
||||
"hide_env_values": {
|
||||
"type": "boolean"
|
||||
},
|
||||
"hide_possible_value": {
|
||||
"hide_possible_values": {
|
||||
"type": "boolean"
|
||||
},
|
||||
"index": {
|
||||
|
@ -146,18 +146,12 @@
|
|||
"long_about": {
|
||||
"type": "string"
|
||||
},
|
||||
"long_help": {
|
||||
"type": "string"
|
||||
},
|
||||
"max_values": {
|
||||
"type": "integer"
|
||||
},
|
||||
"min_values": {
|
||||
"type": "integer"
|
||||
},
|
||||
"multiple": {
|
||||
"type": "boolean"
|
||||
},
|
||||
"multiple_occurences": {
|
||||
"type": "boolean"
|
||||
},
|
||||
|
@ -194,22 +188,22 @@
|
|||
"required": {
|
||||
"type": "boolean"
|
||||
},
|
||||
"required_if": {
|
||||
"required_if_eq": {
|
||||
"$ref": "#/structures/tuple2StrStr"
|
||||
},
|
||||
"required_ifs": {
|
||||
"required_if_eq_any": {
|
||||
"type": "array",
|
||||
"items": {
|
||||
"$ref": "#/structures/tuple2StrStr"
|
||||
}
|
||||
},
|
||||
"required_unless": {
|
||||
"required_unless_present": {
|
||||
"type": "string"
|
||||
},
|
||||
"required_unless_all": {
|
||||
"required_unless_present_all": {
|
||||
"$ref": "#/structures/arrayStrUnique"
|
||||
},
|
||||
"required_unless_one": {
|
||||
"required_unless_present_any": {
|
||||
"$ref": "#/structures/arrayStrUnique"
|
||||
},
|
||||
"requires": {
|
||||
|
@ -329,9 +323,6 @@
|
|||
"aliases": {
|
||||
"$ref": "#/structures/arrayStrUnique"
|
||||
},
|
||||
"arg": {
|
||||
"$ref": "#/definitions/arg"
|
||||
},
|
||||
"args": {
|
||||
"type": "array",
|
||||
"items": {
|
||||
|
@ -356,9 +347,6 @@
|
|||
"global_settings": {
|
||||
"$ref": "#/structures/arrayStrUnique"
|
||||
},
|
||||
"group": {
|
||||
"$ref": "#/definitions/argGroup"
|
||||
},
|
||||
"groups": {
|
||||
"type": "array",
|
||||
"items": {
|
||||
|
@ -406,9 +394,6 @@
|
|||
"settings": {
|
||||
"$ref": "#/structures/arrayStrUnique"
|
||||
},
|
||||
"subcommand": {
|
||||
"$ref": "#"
|
||||
},
|
||||
"subcommands": {
|
||||
"type": "array",
|
||||
"items": {
|
||||
|
@ -416,7 +401,7 @@
|
|||
}
|
||||
},
|
||||
"term_width": {
|
||||
"type": "string"
|
||||
"type": "integer"
|
||||
},
|
||||
"version": {
|
||||
"type": "string"
|
||||
|
|
|
@ -13,22 +13,22 @@ args:
|
|||
# The name of this argument, is 'opt' which will be used to access the value
|
||||
# later in your Rust code
|
||||
- opt:
|
||||
help: example option argument from yaml
|
||||
about: example option argument from yaml
|
||||
short: o
|
||||
long: option
|
||||
multiple: true
|
||||
multiple_values: true
|
||||
takes_value: true
|
||||
- pos:
|
||||
help: example positional argument from yaml
|
||||
about: example positional argument from yaml
|
||||
index: 1
|
||||
# A list of possible values can be defined as a list
|
||||
possible_values:
|
||||
- fast
|
||||
- slow
|
||||
- flag:
|
||||
help: demo flag argument
|
||||
about: demo flag argument
|
||||
short: F
|
||||
multiple: true
|
||||
multiple_values: true
|
||||
takes_value: true
|
||||
global: true
|
||||
# Conflicts, mutual overrides, and requirements can all be defined as a
|
||||
|
@ -39,13 +39,13 @@ args:
|
|||
- pos
|
||||
- mode:
|
||||
long: mode
|
||||
help: shows an option with specific values
|
||||
about: shows an option with specific values
|
||||
# possible_values can also be defined in this list format
|
||||
possible_values: [ vi, emacs ]
|
||||
takes_value: true
|
||||
- mvals:
|
||||
long: mult-vals
|
||||
help: demos an option which has two named values
|
||||
about: demos an option which has two named values
|
||||
# value names can be described in a list, where the help will be shown
|
||||
# --mult-vals <one> <two>
|
||||
value_names:
|
||||
|
@ -53,13 +53,13 @@ args:
|
|||
- two
|
||||
- minvals:
|
||||
long: min-vals
|
||||
multiple: true
|
||||
help: you must supply at least two values to satisfy me
|
||||
multiple_values: true
|
||||
about: you must supply at least two values to satisfy me
|
||||
min_values: 2
|
||||
- maxvals:
|
||||
long: max-vals
|
||||
multiple: true
|
||||
help: you can only supply a max of 3 values for me!
|
||||
multiple_values: true
|
||||
about: you can only supply a max of 3 values for me!
|
||||
max_values: 3
|
||||
|
||||
# All subcommands must be listed in the 'subcommand:' object, where the key to
|
||||
|
@ -76,11 +76,11 @@ subcommands:
|
|||
args:
|
||||
- scopt:
|
||||
short: B
|
||||
multiple: true
|
||||
help: example subcommand option
|
||||
multiple_values: true
|
||||
about: example subcommand option
|
||||
takes_value: true
|
||||
- scpos1:
|
||||
help: example subcommand positional
|
||||
about: example subcommand positional
|
||||
index: 1
|
||||
|
||||
# ArgGroups are supported as well, and must be specified in the 'groups:'
|
||||
|
|
|
@ -2810,138 +2810,91 @@ impl<'help> Index<&'_ Id> for App<'help> {
|
|||
#[cfg(feature = "yaml")]
|
||||
impl<'help> From<&'help Yaml> for App<'help> {
|
||||
#[allow(clippy::cognitive_complexity)]
|
||||
fn from(mut yaml: &'help Yaml) -> Self {
|
||||
fn from(y: &'help Yaml) -> Self {
|
||||
// We WANT this to panic on error...so expect() is good.
|
||||
let mut is_sc = None;
|
||||
let mut a = if let Some(name) = yaml["name"].as_str() {
|
||||
App::new(name)
|
||||
let (mut a, yaml, err) = if let Some(name) = y["name"].as_str() {
|
||||
(App::new(name), y, "app".into())
|
||||
} else {
|
||||
let yaml_hash = yaml.as_hash().unwrap();
|
||||
let sc_key = yaml_hash.keys().next().unwrap();
|
||||
is_sc = Some(yaml_hash.get(sc_key).unwrap());
|
||||
App::new(sc_key.as_str().unwrap())
|
||||
let yaml_hash = y.as_hash().unwrap();
|
||||
let name_yaml = yaml_hash.keys().next().unwrap();
|
||||
let name_str = name_yaml.as_str().unwrap();
|
||||
|
||||
(
|
||||
App::new(name_str),
|
||||
yaml_hash.get(name_yaml).unwrap(),
|
||||
format!("subcommand '{}'", name_str),
|
||||
)
|
||||
};
|
||||
yaml = if let Some(sc) = is_sc { sc } else { yaml };
|
||||
|
||||
macro_rules! yaml_str {
|
||||
($a:ident, $y:ident, $i:ident) => {
|
||||
if let Some(v) = $y[stringify!($i)].as_str() {
|
||||
$a = $a.$i(v);
|
||||
} else if $y[stringify!($i)] != Yaml::BadValue {
|
||||
panic!(
|
||||
"Failed to convert YAML value {:?} to a string",
|
||||
$y[stringify!($i)]
|
||||
);
|
||||
let mut has_metadata = false;
|
||||
|
||||
for (k, v) in yaml.as_hash().unwrap().iter() {
|
||||
a = match k.as_str().unwrap() {
|
||||
"_has_metadata" => {
|
||||
has_metadata = true;
|
||||
a
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
yaml_str!(a, yaml, version);
|
||||
yaml_str!(a, yaml, long_version);
|
||||
yaml_str!(a, yaml, author);
|
||||
yaml_str!(a, yaml, bin_name);
|
||||
yaml_str!(a, yaml, about);
|
||||
yaml_str!(a, yaml, before_help);
|
||||
yaml_str!(a, yaml, before_long_help);
|
||||
yaml_str!(a, yaml, after_help);
|
||||
yaml_str!(a, yaml, after_long_help);
|
||||
yaml_str!(a, yaml, alias);
|
||||
yaml_str!(a, yaml, visible_alias);
|
||||
|
||||
if let Some(v) = yaml["display_order"].as_i64() {
|
||||
a = a.display_order(v as usize);
|
||||
} else if yaml["display_order"] != Yaml::BadValue {
|
||||
panic!(
|
||||
"Failed to convert YAML value {:?} to a u64",
|
||||
yaml["display_order"]
|
||||
);
|
||||
}
|
||||
if let Some(v) = yaml["setting"].as_str() {
|
||||
a = a.setting(v.parse().expect("unknown AppSetting found in YAML file"));
|
||||
} else if yaml["setting"] != Yaml::BadValue {
|
||||
panic!(
|
||||
"Failed to convert YAML value {:?} to an AppSetting",
|
||||
yaml["setting"]
|
||||
);
|
||||
}
|
||||
if let Some(v) = yaml["settings"].as_vec() {
|
||||
for ys in v {
|
||||
if let Some(s) = ys.as_str() {
|
||||
a = a.setting(s.parse().expect("unknown AppSetting found in YAML file"));
|
||||
}
|
||||
}
|
||||
} else if let Some(v) = yaml["settings"].as_str() {
|
||||
a = a.setting(v.parse().expect("unknown AppSetting found in YAML file"));
|
||||
} else if yaml["settings"] != Yaml::BadValue {
|
||||
panic!(
|
||||
"Failed to convert YAML value {:?} to a string",
|
||||
yaml["settings"]
|
||||
);
|
||||
}
|
||||
if let Some(v) = yaml["global_setting"].as_str() {
|
||||
a = a.setting(v.parse().expect("unknown AppSetting found in YAML file"));
|
||||
} else if yaml["global_setting"] != Yaml::BadValue {
|
||||
panic!(
|
||||
"Failed to convert YAML value {:?} to an AppSetting",
|
||||
yaml["setting"]
|
||||
);
|
||||
}
|
||||
if let Some(v) = yaml["global_settings"].as_vec() {
|
||||
for ys in v {
|
||||
if let Some(s) = ys.as_str() {
|
||||
a = a.global_setting(s.parse().expect("unknown AppSetting found in YAML file"));
|
||||
}
|
||||
}
|
||||
} else if let Some(v) = yaml["global_settings"].as_str() {
|
||||
a = a.global_setting(v.parse().expect("unknown AppSetting found in YAML file"));
|
||||
} else if yaml["global_settings"] != Yaml::BadValue {
|
||||
panic!(
|
||||
"Failed to convert YAML value {:?} to a string",
|
||||
yaml["global_settings"]
|
||||
);
|
||||
}
|
||||
|
||||
macro_rules! vec_or_str {
|
||||
($a:ident, $y:ident, $as_vec:ident, $as_single:ident) => {{
|
||||
let maybe_vec = $y[stringify!($as_vec)].as_vec();
|
||||
if let Some(vec) = maybe_vec {
|
||||
for ys in vec {
|
||||
if let Some(s) = ys.as_str() {
|
||||
$a = $a.$as_single(s);
|
||||
} else {
|
||||
panic!("Failed to convert YAML value {:?} to a string", ys);
|
||||
"bin_name" => yaml_to_str!(a, v, bin_name),
|
||||
"version" => yaml_to_str!(a, v, version),
|
||||
"long_version" => yaml_to_str!(a, v, long_version),
|
||||
"author" => yaml_to_str!(a, v, author),
|
||||
"about" => yaml_to_str!(a, v, about),
|
||||
"before_help" => yaml_to_str!(a, v, before_help),
|
||||
"before_long_help" => yaml_to_str!(a, v, before_long_help),
|
||||
"after_help" => yaml_to_str!(a, v, after_help),
|
||||
"after_long_help" => yaml_to_str!(a, v, after_long_help),
|
||||
"help_heading" => yaml_to_str!(a, v, help_heading),
|
||||
"help_template" => yaml_to_str!(a, v, help_template),
|
||||
"override_help" => yaml_to_str!(a, v, override_help),
|
||||
"override_usage" => yaml_to_str!(a, v, override_usage),
|
||||
"alias" => yaml_to_str!(a, v, alias),
|
||||
"aliases" => yaml_vec_or_str!(a, v, alias),
|
||||
"visible_alias" => yaml_to_str!(a, v, visible_alias),
|
||||
"visible_aliases" => yaml_vec_or_str!(a, v, visible_alias),
|
||||
"display_order" => yaml_to_usize!(a, v, display_order),
|
||||
"term_width" => yaml_to_usize!(a, v, term_width),
|
||||
"max_term_width" => yaml_to_usize!(a, v, max_term_width),
|
||||
"args" => {
|
||||
if let Some(vec) = v.as_vec() {
|
||||
for arg_yaml in vec {
|
||||
a = a.arg(Arg::from(arg_yaml));
|
||||
}
|
||||
} else {
|
||||
panic!("Failed to convert YAML value {:?} to a vec", v);
|
||||
}
|
||||
} else {
|
||||
if let Some(s) = $y[stringify!($as_vec)].as_str() {
|
||||
$a = $a.$as_single(s);
|
||||
} else if $y[stringify!($as_vec)] != Yaml::BadValue {
|
||||
panic!(
|
||||
"Failed to convert YAML value {:?} to either a vec or string",
|
||||
$y[stringify!($as_vec)]
|
||||
);
|
||||
}
|
||||
a
|
||||
}
|
||||
"subcommands" => {
|
||||
if let Some(vec) = v.as_vec() {
|
||||
for sc_yaml in vec {
|
||||
a = a.subcommand(App::from(sc_yaml));
|
||||
}
|
||||
} else {
|
||||
panic!("Failed to convert YAML value {:?} to a vec", v);
|
||||
}
|
||||
a
|
||||
}
|
||||
"groups" => {
|
||||
if let Some(vec) = v.as_vec() {
|
||||
for ag_yaml in vec {
|
||||
a = a.group(ArgGroup::from(ag_yaml));
|
||||
}
|
||||
} else {
|
||||
panic!("Failed to convert YAML value {:?} to a vec", v);
|
||||
}
|
||||
a
|
||||
}
|
||||
"setting" | "settings" => yaml_to_setting!(a, v, setting, "AppSetting", err),
|
||||
"global_setting" | "global_settings" => {
|
||||
yaml_to_setting!(a, v, global_setting, "AppSetting", err)
|
||||
}
|
||||
"name" => continue,
|
||||
s => {
|
||||
if !has_metadata {
|
||||
panic!("Unknown setting '{}' in YAML file for {}", s, err)
|
||||
}
|
||||
continue;
|
||||
}
|
||||
$a
|
||||
}};
|
||||
}
|
||||
|
||||
a = vec_or_str!(a, yaml, aliases, alias);
|
||||
a = vec_or_str!(a, yaml, visible_aliases, visible_alias);
|
||||
|
||||
if let Some(v) = yaml["args"].as_vec() {
|
||||
for arg_yaml in v {
|
||||
a = a.arg(Arg::from(arg_yaml));
|
||||
}
|
||||
}
|
||||
if let Some(v) = yaml["subcommands"].as_vec() {
|
||||
for sc_yaml in v {
|
||||
a = a.subcommand(App::from(sc_yaml));
|
||||
}
|
||||
}
|
||||
if let Some(v) = yaml["groups"].as_vec() {
|
||||
for ag_yaml in v {
|
||||
a = a.group(ArgGroup::from(ag_yaml));
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -4233,7 +4233,7 @@ impl<'help> Arg<'help> {
|
|||
}
|
||||
}
|
||||
|
||||
/// Placeholder documentation
|
||||
/// @TODO@ @release @docs
|
||||
#[inline]
|
||||
pub fn multiple_values(self, multi: bool) -> Self {
|
||||
if multi {
|
||||
|
@ -4668,23 +4668,29 @@ impl<'help> From<&'help Yaml> for Arg<'help> {
|
|||
/// ```
|
||||
#[allow(clippy::cognitive_complexity)]
|
||||
fn from(y: &'help Yaml) -> Self {
|
||||
let y = y.as_hash().unwrap();
|
||||
let yaml_hash = y.as_hash().unwrap();
|
||||
// We WANT this to panic on error...so expect() is good.
|
||||
let name_yaml = y.keys().next().unwrap();
|
||||
let name_yaml = yaml_hash.keys().next().unwrap();
|
||||
let name_str = name_yaml.as_str().unwrap();
|
||||
let mut a = Arg::new(name_str);
|
||||
let arg_settings = y.get(name_yaml).unwrap().as_hash().unwrap();
|
||||
let yaml = yaml_hash.get(name_yaml).unwrap();
|
||||
|
||||
for (k, v) in arg_settings.iter() {
|
||||
let mut has_metadata = false;
|
||||
|
||||
for (k, v) in yaml.as_hash().unwrap().iter() {
|
||||
a = match k.as_str().unwrap() {
|
||||
"_has_metadata" => {
|
||||
has_metadata = true;
|
||||
a
|
||||
}
|
||||
"short" => yaml_to_char!(a, v, short),
|
||||
"long" => yaml_to_str!(a, v, long),
|
||||
"alias" => yaml_to_str!(a, v, alias),
|
||||
"aliases" => yaml_vec_or_str!(a, v, alias),
|
||||
"short_alias" => yaml_to_str!(a, v, alias),
|
||||
"short_aliases" => yaml_to_chars!(a, v, short_aliases),
|
||||
"about" => yaml_to_str!(a, v, about),
|
||||
"long_about" => yaml_to_str!(a, v, long_about),
|
||||
"help" => yaml_to_str!(a, v, about),
|
||||
"long_help" => yaml_to_str!(a, v, long_about),
|
||||
"required" => yaml_to_bool!(a, v, required),
|
||||
"required_if_eq" => yaml_tuple2!(a, v, required_if_eq),
|
||||
"required_if_eq_any" => yaml_array_tuple2!(a, v, required_if_eq_any),
|
||||
|
@ -4692,10 +4698,11 @@ impl<'help> From<&'help Yaml> for Arg<'help> {
|
|||
"takes_value" => yaml_to_bool!(a, v, takes_value),
|
||||
"index" => yaml_to_usize!(a, v, index),
|
||||
"global" => yaml_to_bool!(a, v, global),
|
||||
"multiple" => yaml_to_bool!(a, v, multiple),
|
||||
"multiple_occurrences" => yaml_to_bool!(a, v, multiple_occurrences),
|
||||
"multiple_values" => yaml_to_bool!(a, v, multiple_values),
|
||||
"hidden" => yaml_to_bool!(a, v, hidden),
|
||||
"hidden_long_help" => yaml_to_bool!(a, v, hidden_long_help),
|
||||
"hidden_short_help" => yaml_to_bool!(a, v, hidden_short_help),
|
||||
"next_line_help" => yaml_to_bool!(a, v, next_line_help),
|
||||
"group" => yaml_to_str!(a, v, group),
|
||||
"number_of_values" => yaml_to_usize!(a, v, number_of_values),
|
||||
|
@ -4704,8 +4711,10 @@ impl<'help> From<&'help Yaml> for Arg<'help> {
|
|||
"value_name" => yaml_to_str!(a, v, value_name),
|
||||
"use_delimiter" => yaml_to_bool!(a, v, use_delimiter),
|
||||
"allow_hyphen_values" => yaml_to_bool!(a, v, allow_hyphen_values),
|
||||
"raw" => yaml_to_bool!(a, v, raw),
|
||||
"require_equals" => yaml_to_bool!(a, v, require_equals),
|
||||
"require_delimiter" => yaml_to_bool!(a, v, require_delimiter),
|
||||
"value_terminator" => yaml_to_str!(a, v, value_terminator),
|
||||
"value_delimiter" => yaml_to_str!(a, v, value_delimiter),
|
||||
"required_unless_present" => yaml_to_str!(a, v, required_unless_present),
|
||||
"display_order" => yaml_to_usize!(a, v, display_order),
|
||||
|
@ -4721,9 +4730,14 @@ impl<'help> From<&'help Yaml> for Arg<'help> {
|
|||
"requires_ifs" => yaml_tuple2!(a, v, requires_if),
|
||||
"conflicts_with" => yaml_vec_or_str!(a, v, conflicts_with),
|
||||
"exclusive" => yaml_to_bool!(a, v, exclusive),
|
||||
"last" => yaml_to_bool!(a, v, last),
|
||||
"value_hint" => yaml_str_parse!(a, v, value_hint),
|
||||
"hide_default_value" => yaml_to_bool!(a, v, hide_default_value),
|
||||
"overrides_with" => yaml_vec_or_str!(a, v, overrides_with),
|
||||
"hide_env_values" => yaml_to_bool!(a, v, hide_env_values),
|
||||
"hide_possible_values" => yaml_to_bool!(a, v, hide_possible_values),
|
||||
"overrides_with" => yaml_to_str!(a, v, overrides_with),
|
||||
"overrides_with_all" => yaml_vec_or_str!(a, v, overrides_with),
|
||||
"possible_value" => yaml_to_str!(a, v, possible_value),
|
||||
"possible_values" => yaml_vec_or_str!(a, v, possible_value),
|
||||
"case_insensitive" => yaml_to_bool!(a, v, case_insensitive),
|
||||
"required_unless_present_any" => yaml_vec!(a, v, required_unless_present_any),
|
||||
|
@ -4753,7 +4767,18 @@ impl<'help> From<&'help Yaml> for Arg<'help> {
|
|||
panic!("Failed to convert YAML value to vector")
|
||||
}
|
||||
}
|
||||
_ => continue, // Ignore extra fields
|
||||
"setting" | "settings" => {
|
||||
yaml_to_setting!(a, v, setting, "ArgSetting", format!("arg '{}'", name_str))
|
||||
}
|
||||
s => {
|
||||
if !has_metadata {
|
||||
panic!(
|
||||
"Unknown setting '{}' in YAML file for arg '{}'",
|
||||
s, name_str
|
||||
)
|
||||
}
|
||||
continue;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -210,3 +210,30 @@ macro_rules! yaml_to_usize {
|
|||
as usize)
|
||||
}};
|
||||
}
|
||||
|
||||
#[cfg(feature = "yaml")]
|
||||
macro_rules! yaml_to_setting {
|
||||
($a:ident, $v:ident, $c:ident, $t:literal, $n:expr) => {{
|
||||
if let Some(v) = $v.as_vec() {
|
||||
for ys in v {
|
||||
if let Some(s) = ys.as_str() {
|
||||
$a = $a.$c(s.parse().unwrap_or_else(|_| {
|
||||
panic!("Unknown {} '{}' found in YAML file for {}", $t, s, $n)
|
||||
}));
|
||||
} else {
|
||||
panic!(
|
||||
"Failed to convert YAML {:?} value to an array of strings",
|
||||
$v
|
||||
);
|
||||
}
|
||||
}
|
||||
} else if let Some(v) = $v.as_str() {
|
||||
$a = $a.$c(v
|
||||
.parse()
|
||||
.unwrap_or_else(|_| panic!("Unknown {} '{}' found in YAML file for {}", $t, v, $n)))
|
||||
} else {
|
||||
panic!("Failed to convert YAML {:?} value to a string", $v);
|
||||
}
|
||||
$a
|
||||
}};
|
||||
}
|
||||
|
|
27
tests/fixtures/app.yaml
vendored
27
tests/fixtures/app.yaml
vendored
|
@ -4,18 +4,16 @@ about: tests clap library
|
|||
author: Kevin K. <kbknapp@gmail.com>
|
||||
settings:
|
||||
- ArgRequiredElseHelp
|
||||
ignored_field: This field is ignored
|
||||
args:
|
||||
- help:
|
||||
short: h
|
||||
long: help
|
||||
about: prints help with a nonstandard description
|
||||
ignored_field: This field is ignored
|
||||
- option:
|
||||
short: o
|
||||
long: option
|
||||
takes_value: true
|
||||
multiple: true
|
||||
multiple_values: true
|
||||
about: tests options
|
||||
- positional:
|
||||
about: tests positionals
|
||||
|
@ -30,7 +28,7 @@ args:
|
|||
short: f
|
||||
long: flag
|
||||
takes_value: true
|
||||
multiple: true
|
||||
multiple_values: true
|
||||
about: tests flags
|
||||
global: true
|
||||
- flag2:
|
||||
|
@ -69,14 +67,14 @@ args:
|
|||
- two
|
||||
- multvalsmo:
|
||||
long: multvalsmo
|
||||
multiple: true
|
||||
multiple_values: true
|
||||
about: Tests multiple values, not mult occs
|
||||
value_names: [one, two]
|
||||
- multvalsdelim:
|
||||
long: multvalsdelim
|
||||
about: Tests multiple values with required delimiter
|
||||
takes_value: true
|
||||
multiple: true
|
||||
multiple_occurrences: true
|
||||
use_delimiter: true
|
||||
require_delimiter: true
|
||||
- settings:
|
||||
|
@ -105,12 +103,12 @@ args:
|
|||
short_aliases: [b, c]
|
||||
- minvals2:
|
||||
long: minvals2
|
||||
multiple: true
|
||||
multiple_values: true
|
||||
about: Tests 2 min vals
|
||||
min_values: 2
|
||||
- maxvals3:
|
||||
long: maxvals3
|
||||
multiple: true
|
||||
multiple_values: true
|
||||
about: Tests 3 max vals
|
||||
max_values: 3
|
||||
- exclusive:
|
||||
|
@ -119,18 +117,18 @@ args:
|
|||
exclusive: true
|
||||
- case_insensitive:
|
||||
index: 4
|
||||
help: Test case_insensitive
|
||||
about: Test case_insensitive
|
||||
possible_values: [test123, test321]
|
||||
case_insensitive: true
|
||||
- value_hint:
|
||||
long: value-hint
|
||||
help: Test value_hint
|
||||
about: Test value_hint
|
||||
value_hint: FilePath
|
||||
- verbose:
|
||||
short: v
|
||||
multiple_occurrences: true
|
||||
takes_value: false
|
||||
help: Sets the level of verbosity
|
||||
about: Sets the level of verbosity
|
||||
- visiblealiases:
|
||||
long: visiblealiases
|
||||
about: Tests visible aliases
|
||||
|
@ -141,12 +139,11 @@ args:
|
|||
about: Tests visible short aliases
|
||||
visible_short_alias: e
|
||||
visible_short_aliases: [l, m]
|
||||
|
||||
arg_groups:
|
||||
groups:
|
||||
- test:
|
||||
args:
|
||||
- maxvals3
|
||||
- minmals2
|
||||
- minvals2
|
||||
conflicts_with:
|
||||
- option3
|
||||
requires:
|
||||
|
@ -160,7 +157,7 @@ subcommands:
|
|||
- scoption:
|
||||
short: o
|
||||
long: option
|
||||
multiple: true
|
||||
multiple_values: true
|
||||
about: tests options
|
||||
takes_value: true
|
||||
- scpositional:
|
||||
|
|
8
tests/fixtures/app_2space.yaml
vendored
8
tests/fixtures/app_2space.yaml
vendored
|
@ -2,16 +2,10 @@ name: claptests
|
|||
version: "1.0"
|
||||
about: tests clap library
|
||||
author: Kevin K. <kbknapp@gmail.com>
|
||||
settings:
|
||||
- ArgRequiredElseHelp
|
||||
args:
|
||||
- help:
|
||||
short: h
|
||||
long: help
|
||||
about: prints help with a nonstandard description
|
||||
- opt:
|
||||
short: o
|
||||
long: option
|
||||
takes_value: true
|
||||
multiple: true
|
||||
multiple_values: true
|
||||
about: tests options
|
||||
|
|
6
tests/fixtures/app_regex.yaml
vendored
6
tests/fixtures/app_regex.yaml
vendored
|
@ -2,13 +2,7 @@ name: clapregextest
|
|||
version: "1.0"
|
||||
about: tests clap regex functionality
|
||||
author: Benjamin Kästner <benjamin.kaestner@gmail.com>
|
||||
settings:
|
||||
- ArgRequiredElseHelp
|
||||
args:
|
||||
- help:
|
||||
short: h
|
||||
long: help
|
||||
about: prints help with a nonstandard description
|
||||
- filter:
|
||||
index: 1
|
||||
validator_regex: ["^*\\.[a-z]+$", expected extension pattern]
|
||||
|
|
6
tests/fixtures/app_regex_invalid.yaml
vendored
6
tests/fixtures/app_regex_invalid.yaml
vendored
|
@ -2,13 +2,7 @@ name: clapregextest
|
|||
version: "1.0"
|
||||
about: tests clap regex functionality
|
||||
author: Benjamin Kästner <benjamin.kaestner@gmail.com>
|
||||
settings:
|
||||
- ArgRequiredElseHelp
|
||||
args:
|
||||
- help:
|
||||
short: h
|
||||
long: help
|
||||
about: prints help with a nonstandard description
|
||||
- filter:
|
||||
index: 1
|
||||
validator_regex: [")", invalid regular expression]
|
||||
|
|
5
tests/fixtures/app_setting_invalid.yaml
vendored
Normal file
5
tests/fixtures/app_setting_invalid.yaml
vendored
Normal file
|
@ -0,0 +1,5 @@
|
|||
name: claptests
|
||||
version: "1.0"
|
||||
about: tests clap extra fields
|
||||
settings:
|
||||
- random
|
8
tests/fixtures/arg_setting_invalid.yaml
vendored
Normal file
8
tests/fixtures/arg_setting_invalid.yaml
vendored
Normal file
|
@ -0,0 +1,8 @@
|
|||
name: claptests
|
||||
version: "1.0"
|
||||
about: tests clap extra fields
|
||||
args:
|
||||
- option:
|
||||
long: option
|
||||
settings:
|
||||
- random
|
10
tests/fixtures/extra_fields.yaml
vendored
Normal file
10
tests/fixtures/extra_fields.yaml
vendored
Normal file
|
@ -0,0 +1,10 @@
|
|||
_has_metadata: true
|
||||
name: claptests
|
||||
version: "1.0"
|
||||
about: tests clap extra fields
|
||||
random: This field is extra
|
||||
args:
|
||||
- option:
|
||||
_has_metadata: true
|
||||
long: option
|
||||
random: This field is extra
|
6
tests/fixtures/extra_fields_invalid_app.yaml
vendored
Normal file
6
tests/fixtures/extra_fields_invalid_app.yaml
vendored
Normal file
|
@ -0,0 +1,6 @@
|
|||
name: claptests
|
||||
version: "1.0"
|
||||
about: tests clap extra fields
|
||||
subcommands:
|
||||
- info:
|
||||
random: This field is extra
|
7
tests/fixtures/extra_fields_invalid_arg.yaml
vendored
Normal file
7
tests/fixtures/extra_fields_invalid_arg.yaml
vendored
Normal file
|
@ -0,0 +1,7 @@
|
|||
name: claptests
|
||||
version: "1.0"
|
||||
about: tests clap extra fields
|
||||
args:
|
||||
- option:
|
||||
long: option
|
||||
random: This field is extra
|
|
@ -1,6 +1,6 @@
|
|||
#![cfg(feature = "yaml")]
|
||||
|
||||
use clap::{load_yaml, App, ValueHint};
|
||||
use clap::{load_yaml, App, ErrorKind, ValueHint};
|
||||
|
||||
#[test]
|
||||
fn create_app_from_yaml() {
|
||||
|
@ -42,6 +42,34 @@ fn author() {
|
|||
assert!(help_string.contains("Kevin K. <kbknapp@gmail.com>"));
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn app_settings() {
|
||||
let yaml = load_yaml!("fixtures/app.yaml");
|
||||
let app = App::from(yaml);
|
||||
|
||||
let m = app.try_get_matches_from(vec!["prog"]);
|
||||
|
||||
assert!(m.is_err());
|
||||
assert_eq!(
|
||||
m.unwrap_err().kind,
|
||||
ErrorKind::DisplayHelpOnMissingArgumentOrSubcommand
|
||||
);
|
||||
}
|
||||
|
||||
#[test]
|
||||
#[should_panic = "Unknown AppSetting 'random' found in YAML file for app"]
|
||||
fn app_setting_invalid() {
|
||||
let yaml = load_yaml!("fixtures/app_setting_invalid.yaml");
|
||||
App::from(yaml);
|
||||
}
|
||||
|
||||
#[test]
|
||||
#[should_panic = "Unknown ArgSetting 'random' found in YAML file for arg 'option'"]
|
||||
fn arg_setting_invalid() {
|
||||
let yaml = load_yaml!("fixtures/arg_setting_invalid.yaml");
|
||||
App::from(yaml);
|
||||
}
|
||||
|
||||
// ValueHint must be parsed correctly from Yaml
|
||||
#[test]
|
||||
fn value_hint() {
|
||||
|
@ -150,5 +178,25 @@ fn regex_with_valid_string() {
|
|||
#[should_panic]
|
||||
fn regex_with_invalid_yaml() {
|
||||
let yml = load_yaml!("fixtures/app_regex_invalid.yaml");
|
||||
let _app = App::from(yml);
|
||||
App::from(yml);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn extra_fields() {
|
||||
let yml = load_yaml!("fixtures/extra_fields.yaml");
|
||||
App::from(yml);
|
||||
}
|
||||
|
||||
#[test]
|
||||
#[should_panic = "Unknown setting 'random' in YAML file for arg 'option'"]
|
||||
fn extra_fields_invalid_arg() {
|
||||
let yml = load_yaml!("fixtures/extra_fields_invalid_arg.yaml");
|
||||
App::from(yml);
|
||||
}
|
||||
|
||||
#[test]
|
||||
#[should_panic = "Unknown setting 'random' in YAML file for subcommand 'info'"]
|
||||
fn extra_fields_invalid_app() {
|
||||
let yml = load_yaml!("fixtures/extra_fields_invalid_app.yaml");
|
||||
App::from(yml);
|
||||
}
|
||||
|
|
Loading…
Add table
Reference in a new issue