fix(assert): Check for version if user specifies ArgAction::Version

This commit is contained in:
Ed Page 2022-06-08 11:58:15 -05:00
parent 912a629070
commit dffd7932b3
4 changed files with 44 additions and 34 deletions

View file

@ -4,8 +4,8 @@ use clap_lex::RawOsStr;
use crate::builder::arg::ArgProvider;
use crate::mkeymap::KeyType;
use crate::util::Id;
use crate::{AppSettings, Arg, Command, ValueHint};
use crate::ArgAction;
use crate::{Arg, Command, ValueHint};
pub(crate) fn assert_app(cmd: &Command) {
debug!("Command::_debug_asserts");
@ -23,16 +23,21 @@ pub(crate) fn assert_app(cmd: &Command) {
);
// Used `Command::mut_arg("version", ..) but did not provide any version information to display
let has_mutated_version = cmd
let version_needed = cmd
.get_arguments()
.any(|x| x.id == Id::version_hash() && x.provider == ArgProvider::GeneratedMutated);
.filter(|x| {
matches!(x.get_action(), ArgAction::Version)
&& matches!(
x.provider,
ArgProvider::User | ArgProvider::GeneratedMutated
)
})
.map(|x| x.get_id())
.collect::<Vec<_>>();
if has_mutated_version {
assert!(cmd.is_set(AppSettings::NoAutoVersion),
"Command {}: Used Command::mut_arg(\"version\", ..) without providing Command::version, Command::long_version or using AppSettings::NoAutoVersion"
assert_eq!(version_needed, Vec::<&str>::new(), "Command {}: `ArgAction::Version` used without providing Command::version or Command::long_version"
,cmd.get_name()
);
}
);
}
for sc in cmd.get_subcommands() {

View file

@ -2,7 +2,7 @@ use std::ffi::OsString;
use super::utils;
use clap::{arg, error::ErrorKind, AppSettings, Arg, Command};
use clap::{arg, error::ErrorKind, AppSettings, Arg, ArgAction, Command};
static ALLOW_EXT_SC: &str = "clap-test v1.4.8
@ -1345,62 +1345,68 @@ fn aaos_option_use_delim_false() {
#[test]
fn no_auto_help() {
let cmd = Command::new("myprog")
.setting(AppSettings::NoAutoHelp)
.subcommand(Command::new("foo"));
.subcommand(Command::new("foo"))
.mut_arg("help", |v| v.action(ArgAction::SetTrue));
let result = cmd.clone().try_get_matches_from("myprog --help".split(' '));
assert!(result.is_ok(), "{}", result.unwrap_err());
assert!(result.unwrap().is_present("help"));
assert_eq!(result.unwrap().get_one::<bool>("help").copied(), Some(true));
let result = cmd.clone().try_get_matches_from("myprog -h".split(' '));
assert!(result.is_ok(), "{}", result.unwrap_err());
assert!(result.unwrap().is_present("help"));
let result = cmd.clone().try_get_matches_from("myprog help".split(' '));
assert!(result.is_ok(), "{}", result.unwrap_err());
assert_eq!(result.unwrap().subcommand_name(), Some("help"));
assert_eq!(result.unwrap().get_one::<bool>("help").copied(), Some(true));
}
#[test]
fn no_auto_version() {
let cmd = Command::new("myprog")
.version("3.0")
.setting(AppSettings::NoAutoVersion);
.mut_arg("version", |v| v.action(ArgAction::SetTrue));
let result = cmd
.clone()
.try_get_matches_from("myprog --version".split(' '));
assert!(result.is_ok(), "{}", result.unwrap_err());
assert!(result.unwrap().is_present("version"));
assert_eq!(
result.unwrap().get_one::<bool>("version").copied(),
Some(true)
);
let result = cmd.clone().try_get_matches_from("myprog -V".split(' '));
assert!(result.is_ok(), "{}", result.unwrap_err());
assert!(result.unwrap().is_present("version"));
assert_eq!(
result.unwrap().get_one::<bool>("version").copied(),
Some(true)
);
}
#[test]
fn no_auto_version_mut_arg() {
let cmd = Command::new("myprog")
.version("3.0")
.mut_arg("version", |v| v.help("custom help"))
.setting(AppSettings::NoAutoVersion);
.mut_arg("version", |v| {
v.action(ArgAction::SetTrue).help("custom help")
});
let result = cmd
.clone()
.try_get_matches_from("myprog --version".split(' '));
assert!(result.is_ok(), "{}", result.unwrap_err());
assert!(result.unwrap().is_present("version"));
assert_eq!(
result.unwrap().get_one::<bool>("version").copied(),
Some(true)
);
let result = cmd.clone().try_get_matches_from("myprog -V".split(' '));
assert!(result.is_ok(), "{}", result.unwrap_err());
assert!(result.unwrap().is_present("version"));
assert_eq!(
result.unwrap().get_one::<bool>("version").copied(),
Some(true)
);
}
#[test]

View file

@ -206,7 +206,7 @@ fn propagate_version_short() {
#[cfg(debug_assertions)]
#[test]
#[should_panic = "Used Command::mut_arg(\"version\", ..) without providing Command::version, Command::long_version or using AppSettings::NoAutoVersion"]
#[should_panic = "`ArgAction::Version` used without providing Command::version or Command::long_version"]
fn mut_arg_version_panic() {
let _res = common()
.mut_arg("version", |v| v.short('z'))

View file

@ -2,7 +2,7 @@ use super::utils;
use std::str;
use clap::{error::ErrorKind, AppSettings, Arg, Command};
use clap::{error::ErrorKind, Arg, ArgAction, Command};
fn common() -> Command<'static> {
Command::new("foo")
@ -206,7 +206,7 @@ fn propagate_version_short() {
#[cfg(debug_assertions)]
#[test]
#[should_panic = "Used Command::mut_arg(\"version\", ..) without providing Command::version, Command::long_version or using AppSettings::NoAutoVersion"]
#[should_panic = "`ArgAction::Version` used without providing Command::version or Command::long_version"]
fn mut_arg_version_panic() {
let _res = common()
.mut_arg("version", |v| v.short('z'))
@ -216,12 +216,11 @@ fn mut_arg_version_panic() {
#[test]
fn mut_arg_version_no_auto_version() {
let res = common()
.mut_arg("version", |v| v.short('z'))
.setting(AppSettings::NoAutoVersion)
.mut_arg("version", |v| v.short('z').action(ArgAction::SetTrue))
.try_get_matches_from("foo -z".split(' '));
assert!(res.is_ok(), "{}", res.unwrap_err());
assert!(res.unwrap().is_present("version"));
assert_eq!(res.unwrap().get_one::<bool>("version").copied(), Some(true));
}
#[cfg(debug_assertions)]