From f17ecafc24a88c855d66c4740eea5139da19fbd7 Mon Sep 17 00:00:00 2001 From: Ed Page Date: Tue, 4 Jan 2022 11:04:50 -0600 Subject: [PATCH] Upgrade to Clap 3 - One parser change found by `cargo_config::includes` is that clap 2 would ignore any values after a `=` for flags. `cargo config --show-origin` is a flag but the test passed `--show-origin=yes` which happens to give the desired result for that test but is the same as `--show-origin=no` or `--show-origin=alien-invasion`. - The parser now panics when accessing an undefined attribute but clap takes advantage of that for sharing code across commands that have different subsets of arguments defined. I've extended clap so we can "look before you leap" and put the checks at the argument calls to start off with so its very clear what is tenuously shared. This allows us to go in either direction in the future, either addressing how we are sharing between commands or by moving this down into the extension methods and pretending this clap feature doesn't exist - On that topic, a test found clap-rs/clap#3263. For now, there is a hack in clap. Depending on how we fix that in clap for clap 4.0, we might need to re-address things in cargo. - `value_of_os` now requires setting `allow_invalid_utf8`, otherwise it asserts. To help catch this, I updated the argument definitions associated with lookups reported by: - `rg 'values?_os' src/` - `rg 'values?_of_os' src/` - clap now reports `2` for usage errors, so we had to bypass clap's `exit` call to keep the same exit code. BREAKING CHANGE: API now uses clap3 --- Cargo.toml | 2 +- src/bin/cargo/cli.rs | 56 +++++----- src/bin/cargo/commands/bench.rs | 2 +- src/bin/cargo/commands/build.rs | 2 +- src/bin/cargo/commands/check.rs | 2 +- src/bin/cargo/commands/clean.rs | 2 +- src/bin/cargo/commands/config.rs | 11 +- src/bin/cargo/commands/doc.rs | 2 +- src/bin/cargo/commands/fetch.rs | 2 +- src/bin/cargo/commands/fix.rs | 2 +- src/bin/cargo/commands/generate_lockfile.rs | 2 +- src/bin/cargo/commands/git_checkout.rs | 2 +- src/bin/cargo/commands/init.rs | 2 +- src/bin/cargo/commands/install.rs | 4 +- src/bin/cargo/commands/locate_project.rs | 6 +- src/bin/cargo/commands/login.rs | 2 +- src/bin/cargo/commands/logout.rs | 2 +- src/bin/cargo/commands/metadata.rs | 2 +- src/bin/cargo/commands/mod.rs | 2 +- src/bin/cargo/commands/new.rs | 2 +- src/bin/cargo/commands/owner.rs | 8 +- src/bin/cargo/commands/package.rs | 4 +- src/bin/cargo/commands/pkgid.rs | 2 +- src/bin/cargo/commands/publish.rs | 2 +- src/bin/cargo/commands/read_manifest.rs | 2 +- src/bin/cargo/commands/report.rs | 13 ++- src/bin/cargo/commands/run.rs | 8 +- src/bin/cargo/commands/rustc.rs | 2 +- src/bin/cargo/commands/rustdoc.rs | 2 +- src/bin/cargo/commands/search.rs | 2 +- src/bin/cargo/commands/test.rs | 4 +- src/bin/cargo/commands/tree.rs | 19 ++-- src/bin/cargo/commands/uninstall.rs | 2 +- src/bin/cargo/commands/update.rs | 4 +- src/bin/cargo/commands/vendor.rs | 13 ++- src/bin/cargo/commands/verify_project.rs | 2 +- src/bin/cargo/commands/version.rs | 2 +- src/bin/cargo/commands/yank.rs | 2 +- src/bin/cargo/main.rs | 2 +- src/cargo/lib.rs | 5 +- src/cargo/util/command_prelude.rs | 107 ++++++++++++-------- src/cargo/util/errors.rs | 6 ++ tests/testsuite/cargo_config.rs | 18 ++-- tests/testsuite/metadata.rs | 2 +- tests/testsuite/new.rs | 2 +- tests/testsuite/run.rs | 2 +- tests/testsuite/rustc.rs | 2 +- 47 files changed, 200 insertions(+), 148 deletions(-) diff --git a/Cargo.toml b/Cargo.toml index 20dfd540f..3435686ad 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -61,7 +61,7 @@ toml = "0.5.7" unicode-xid = "0.2.0" url = "2.2.2" walkdir = "2.2" -clap = "2.34.0" +clap = "3.0.5" unicode-width = "0.1.5" openssl = { version = '0.10.11', optional = true } im-rc = "15.0.0" diff --git a/src/bin/cargo/cli.rs b/src/bin/cargo/cli.rs index cd1fea8f1..1db83f1f1 100644 --- a/src/bin/cargo/cli.rs +++ b/src/bin/cargo/cli.rs @@ -35,8 +35,8 @@ pub fn main(config: &mut Config) -> CliResult { Err(e) => { if e.kind == clap::ErrorKind::UnrecognizedSubcommand { // An unrecognized subcommand might be an external subcommand. - let cmd = &e.info.as_ref().unwrap()[0].to_owned(); - return super::execute_external_subcommand(config, cmd, &[cmd, "--help"]) + let cmd = e.info[0].clone(); + return super::execute_external_subcommand(config, &cmd, &[&cmd, "--help"]) .map_err(|_| e.into()); } else { return Err(e.into()); @@ -152,7 +152,7 @@ Run with 'cargo -Z [FLAG] [SUBCOMMAND]'", } let (cmd, subcommand_args) = match expanded_args.subcommand() { - (cmd, Some(args)) => (cmd, args), + Some((cmd, args)) => (cmd, args), _ => { // No subcommand provided. cli().print_help()?; @@ -236,10 +236,10 @@ fn add_ssl(version_string: &mut String) { fn expand_aliases( config: &mut Config, - args: ArgMatches<'static>, + args: ArgMatches, mut already_expanded: Vec, -) -> Result<(ArgMatches<'static>, GlobalArgs), CliError> { - if let (cmd, Some(args)) = args.subcommand() { +) -> Result<(ArgMatches, GlobalArgs), CliError> { + if let Some((cmd, args)) = args.subcommand() { match ( commands::builtin_exec(cmd), super::aliased_command(config, cmd)?, @@ -292,7 +292,7 @@ For more information, see issue #10049 , - subcommand_args: &ArgMatches<'_>, + args: &ArgMatches, + subcommand_args: &ArgMatches, global_args: GlobalArgs, ) -> CliResult { - let arg_target_dir = &subcommand_args.value_of_path("target-dir", config); + let arg_target_dir = &subcommand_args + ._is_valid_arg("target-dir") + .then(|| subcommand_args.value_of_path("target-dir", config)) + .flatten(); let verbose = global_args.verbose + args.occurrences_of("verbose") as u32; // quiet is unusual because it is redefined in some subcommands in order // to provide custom help text. - let quiet = - args.is_present("quiet") || subcommand_args.is_present("quiet") || global_args.quiet; + let quiet = args.is_present("quiet") + || subcommand_args.is_valid_and_present("quiet") + || global_args.quiet; let global_color = global_args.color; // Extract so it can take reference. let color = args.value_of("color").or_else(|| global_color.as_deref()); let frozen = args.is_present("frozen") || global_args.frozen; @@ -353,11 +357,7 @@ fn config_configure( Ok(()) } -fn execute_subcommand( - config: &mut Config, - cmd: &str, - subcommand_args: &ArgMatches<'_>, -) -> CliResult { +fn execute_subcommand(config: &mut Config, cmd: &str, subcommand_args: &ArgMatches) -> CliResult { if let Some(exec) = commands::builtin_exec(cmd) { return exec(config, subcommand_args); } @@ -380,7 +380,7 @@ struct GlobalArgs { } impl GlobalArgs { - fn new(args: &ArgMatches<'_>) -> GlobalArgs { + fn new(args: &ArgMatches) -> GlobalArgs { GlobalArgs { verbose: args.occurrences_of("verbose") as u32, quiet: args.is_present("quiet"), @@ -411,9 +411,12 @@ fn cli() -> App { .settings(&[ AppSettings::UnifiedHelpMessage, AppSettings::DeriveDisplayOrder, - AppSettings::VersionlessSubcommands, AppSettings::AllowExternalSubcommands, + AppSettings::NoAutoVersion, ]) + // Doesn't mix well with our list of common cargo commands. See clap-rs/clap#3108 for + // opening clap up to allow us to style our help template + .global_setting(AppSettings::DisableColoredHelp) .usage(usage) .template( "\ @@ -423,7 +426,7 @@ USAGE: {usage} OPTIONS: -{unified} +{options} Some common cargo commands are (see all commands with --list): build, b Compile the current package @@ -443,7 +446,7 @@ Some common cargo commands are (see all commands with --list): See 'cargo help ' for more information on a specific command.\n", ) - .arg(opt("version", "Print version info and exit").short("V")) + .arg(opt("version", "Print version info and exit").short('V')) .arg(opt("list", "List installed commands")) .arg(opt("explain", "Run `rustc --explain CODE`").value_name("CODE")) .arg( @@ -451,8 +454,8 @@ See 'cargo help ' for more information on a specific command.\n", "verbose", "Use verbose output (-vv very verbose/build.rs output)", ) - .short("v") - .multiple(true) + .short('v') + .multiple_occurrences(true) .global(true), ) .arg_quiet() @@ -475,7 +478,7 @@ See 'cargo help ' for more information on a specific command.\n", .arg( Arg::with_name("unstable-features") .help("Unstable (nightly-only) flags to Cargo, see 'cargo -Z help' for details") - .short("Z") + .short('Z') .value_name("FLAG") .multiple(true) .number_of_values(1) @@ -483,3 +486,8 @@ See 'cargo help ' for more information on a specific command.\n", ) .subcommands(commands::builtin()) } + +#[test] +fn verify_cli() { + cli().debug_assert(); +} diff --git a/src/bin/cargo/commands/bench.rs b/src/bin/cargo/commands/bench.rs index 39ec1be22..d81f1f8ab 100644 --- a/src/bin/cargo/commands/bench.rs +++ b/src/bin/cargo/commands/bench.rs @@ -50,7 +50,7 @@ pub fn cli() -> App { .after_help("Run `cargo help bench` for more detailed information.\n") } -pub fn exec(config: &mut Config, args: &ArgMatches<'_>) -> CliResult { +pub fn exec(config: &mut Config, args: &ArgMatches) -> CliResult { let ws = args.workspace(config)?; let mut compile_opts = args.compile_options( config, diff --git a/src/bin/cargo/commands/build.rs b/src/bin/cargo/commands/build.rs index ad6705119..367cad838 100644 --- a/src/bin/cargo/commands/build.rs +++ b/src/bin/cargo/commands/build.rs @@ -47,7 +47,7 @@ pub fn cli() -> App { .after_help("Run `cargo help build` for more detailed information.\n") } -pub fn exec(config: &mut Config, args: &ArgMatches<'_>) -> CliResult { +pub fn exec(config: &mut Config, args: &ArgMatches) -> CliResult { let ws = args.workspace(config)?; let mut compile_opts = args.compile_options( config, diff --git a/src/bin/cargo/commands/check.rs b/src/bin/cargo/commands/check.rs index 3be146c6d..07b98be70 100644 --- a/src/bin/cargo/commands/check.rs +++ b/src/bin/cargo/commands/check.rs @@ -39,7 +39,7 @@ pub fn cli() -> App { .after_help("Run `cargo help check` for more detailed information.\n") } -pub fn exec(config: &mut Config, args: &ArgMatches<'_>) -> CliResult { +pub fn exec(config: &mut Config, args: &ArgMatches) -> CliResult { let ws = args.workspace(config)?; // This is a legacy behavior that causes `cargo check` to pass `--test`. let test = matches!(args.value_of("profile"), Some("test")); diff --git a/src/bin/cargo/commands/clean.rs b/src/bin/cargo/commands/clean.rs index c966c65f1..f758981b1 100644 --- a/src/bin/cargo/commands/clean.rs +++ b/src/bin/cargo/commands/clean.rs @@ -17,7 +17,7 @@ pub fn cli() -> App { .after_help("Run `cargo help clean` for more detailed information.\n") } -pub fn exec(config: &mut Config, args: &ArgMatches<'_>) -> CliResult { +pub fn exec(config: &mut Config, args: &ArgMatches) -> CliResult { let ws = args.workspace(config)?; if args.is_present_with_zero_values("package") { diff --git a/src/bin/cargo/commands/config.rs b/src/bin/cargo/commands/config.rs index 61938dfc2..786136962 100644 --- a/src/bin/cargo/commands/config.rs +++ b/src/bin/cargo/commands/config.rs @@ -26,12 +26,12 @@ pub fn cli() -> App { ) } -pub fn exec(config: &mut Config, args: &ArgMatches<'_>) -> CliResult { +pub fn exec(config: &mut Config, args: &ArgMatches) -> CliResult { config .cli_unstable() .fail_if_stable_command(config, "config", 9301)?; match args.subcommand() { - ("get", Some(args)) => { + Some(("get", args)) => { let opts = cargo_config::GetOptions { key: args.value_of("key"), format: args.value_of("format").unwrap().parse()?, @@ -40,8 +40,11 @@ pub fn exec(config: &mut Config, args: &ArgMatches<'_>) -> CliResult { }; cargo_config::get(config, &opts)?; } - (cmd, _) => { - panic!("unexpected command `{}`", cmd) + Some((cmd, _)) => { + unreachable!("unexpected command {}", cmd) + } + None => { + unreachable!("unexpected command") } } Ok(()) diff --git a/src/bin/cargo/commands/doc.rs b/src/bin/cargo/commands/doc.rs index 21d561394..983359449 100644 --- a/src/bin/cargo/commands/doc.rs +++ b/src/bin/cargo/commands/doc.rs @@ -39,7 +39,7 @@ pub fn cli() -> App { .after_help("Run `cargo help doc` for more detailed information.\n") } -pub fn exec(config: &mut Config, args: &ArgMatches<'_>) -> CliResult { +pub fn exec(config: &mut Config, args: &ArgMatches) -> CliResult { let ws = args.workspace(config)?; let mode = CompileMode::Doc { deps: !args.is_present("no-deps"), diff --git a/src/bin/cargo/commands/fetch.rs b/src/bin/cargo/commands/fetch.rs index ff3fcbec5..0106c0f1e 100644 --- a/src/bin/cargo/commands/fetch.rs +++ b/src/bin/cargo/commands/fetch.rs @@ -12,7 +12,7 @@ pub fn cli() -> App { .after_help("Run `cargo help fetch` for more detailed information.\n") } -pub fn exec(config: &mut Config, args: &ArgMatches<'_>) -> CliResult { +pub fn exec(config: &mut Config, args: &ArgMatches) -> CliResult { let ws = args.workspace(config)?; let opts = FetchOptions { diff --git a/src/bin/cargo/commands/fix.rs b/src/bin/cargo/commands/fix.rs index 85cf955e4..5463e12df 100644 --- a/src/bin/cargo/commands/fix.rs +++ b/src/bin/cargo/commands/fix.rs @@ -65,7 +65,7 @@ pub fn cli() -> App { .after_help("Run `cargo help fix` for more detailed information.\n") } -pub fn exec(config: &mut Config, args: &ArgMatches<'_>) -> CliResult { +pub fn exec(config: &mut Config, args: &ArgMatches) -> CliResult { let ws = args.workspace(config)?; // This is a legacy behavior that causes `cargo fix` to pass `--test`. let test = matches!(args.value_of("profile"), Some("test")); diff --git a/src/bin/cargo/commands/generate_lockfile.rs b/src/bin/cargo/commands/generate_lockfile.rs index 1eebdbd41..b20d8616a 100644 --- a/src/bin/cargo/commands/generate_lockfile.rs +++ b/src/bin/cargo/commands/generate_lockfile.rs @@ -10,7 +10,7 @@ pub fn cli() -> App { .after_help("Run `cargo help generate-lockfile` for more detailed information.\n") } -pub fn exec(config: &mut Config, args: &ArgMatches<'_>) -> CliResult { +pub fn exec(config: &mut Config, args: &ArgMatches) -> CliResult { let ws = args.workspace(config)?; ops::generate_lockfile(&ws)?; Ok(()) diff --git a/src/bin/cargo/commands/git_checkout.rs b/src/bin/cargo/commands/git_checkout.rs index aae435a51..3cc0701ff 100644 --- a/src/bin/cargo/commands/git_checkout.rs +++ b/src/bin/cargo/commands/git_checkout.rs @@ -9,6 +9,6 @@ pub fn cli() -> App { .help(REMOVED) } -pub fn exec(_config: &mut Config, _args: &ArgMatches<'_>) -> CliResult { +pub fn exec(_config: &mut Config, _args: &ArgMatches) -> CliResult { Err(anyhow::format_err!(REMOVED).into()) } diff --git a/src/bin/cargo/commands/init.rs b/src/bin/cargo/commands/init.rs index 257d30756..3bb957f3f 100644 --- a/src/bin/cargo/commands/init.rs +++ b/src/bin/cargo/commands/init.rs @@ -12,7 +12,7 @@ pub fn cli() -> App { .after_help("Run `cargo help init` for more detailed information.\n") } -pub fn exec(config: &mut Config, args: &ArgMatches<'_>) -> CliResult { +pub fn exec(config: &mut Config, args: &ArgMatches) -> CliResult { let opts = args.new_options(config)?; let project_kind = ops::init(&opts, config)?; config diff --git a/src/bin/cargo/commands/install.rs b/src/bin/cargo/commands/install.rs index 79be166e4..fb8db4121 100644 --- a/src/bin/cargo/commands/install.rs +++ b/src/bin/cargo/commands/install.rs @@ -45,7 +45,7 @@ pub fn cli() -> App { "list all installed packages and their versions", )) .arg_jobs() - .arg(opt("force", "Force overwriting existing crates or binaries").short("f")) + .arg(opt("force", "Force overwriting existing crates or binaries").short('f')) .arg(opt("no-track", "Do not save tracking information")) .arg_features() .arg_profile("Install artifacts with the specified profile") @@ -75,7 +75,7 @@ pub fn cli() -> App { .after_help("Run `cargo help install` for more detailed information.\n") } -pub fn exec(config: &mut Config, args: &ArgMatches<'_>) -> CliResult { +pub fn exec(config: &mut Config, args: &ArgMatches) -> CliResult { if let Some(path) = args.value_of_path("path", config) { config.reload_rooted_at(path)?; } else { diff --git a/src/bin/cargo/commands/locate_project.rs b/src/bin/cargo/commands/locate_project.rs index a045e1454..673f69903 100644 --- a/src/bin/cargo/commands/locate_project.rs +++ b/src/bin/cargo/commands/locate_project.rs @@ -24,7 +24,7 @@ pub struct ProjectLocation<'a> { root: &'a str, } -pub fn exec(config: &mut Config, args: &ArgMatches<'_>) -> CliResult { +pub fn exec(config: &mut Config, args: &ArgMatches) -> CliResult { let root_manifest; let workspace; let root = match WhatToFind::parse(args) { @@ -64,7 +64,7 @@ enum WhatToFind { } impl WhatToFind { - fn parse(args: &ArgMatches<'_>) -> Self { + fn parse(args: &ArgMatches) -> Self { if args.is_present("workspace") { WhatToFind::Workspace } else { @@ -79,7 +79,7 @@ enum MessageFormat { } impl MessageFormat { - fn parse(args: &ArgMatches<'_>) -> CargoResult { + fn parse(args: &ArgMatches) -> CargoResult { let fmt = match args.value_of("message-format") { Some(fmt) => fmt, None => return Ok(MessageFormat::Json), diff --git a/src/bin/cargo/commands/login.rs b/src/bin/cargo/commands/login.rs index 0f51d5296..3eea2bb12 100644 --- a/src/bin/cargo/commands/login.rs +++ b/src/bin/cargo/commands/login.rs @@ -14,7 +14,7 @@ pub fn cli() -> App { .after_help("Run `cargo help login` for more detailed information.\n") } -pub fn exec(config: &mut Config, args: &ArgMatches<'_>) -> CliResult { +pub fn exec(config: &mut Config, args: &ArgMatches) -> CliResult { ops::registry_login( config, args.value_of("token").map(String::from), diff --git a/src/bin/cargo/commands/logout.rs b/src/bin/cargo/commands/logout.rs index 4ce9498e7..518247e8b 100644 --- a/src/bin/cargo/commands/logout.rs +++ b/src/bin/cargo/commands/logout.rs @@ -9,7 +9,7 @@ pub fn cli() -> App { .after_help("Run `cargo help logout` for more detailed information.\n") } -pub fn exec(config: &mut Config, args: &ArgMatches<'_>) -> CliResult { +pub fn exec(config: &mut Config, args: &ArgMatches) -> CliResult { if !config.cli_unstable().credential_process { config .cli_unstable() diff --git a/src/bin/cargo/commands/metadata.rs b/src/bin/cargo/commands/metadata.rs index 66e856b48..6caa7ab94 100644 --- a/src/bin/cargo/commands/metadata.rs +++ b/src/bin/cargo/commands/metadata.rs @@ -29,7 +29,7 @@ pub fn cli() -> App { .after_help("Run `cargo help metadata` for more detailed information.\n") } -pub fn exec(config: &mut Config, args: &ArgMatches<'_>) -> CliResult { +pub fn exec(config: &mut Config, args: &ArgMatches) -> CliResult { let ws = args.workspace(config)?; let version = match args.value_of("format-version") { diff --git a/src/bin/cargo/commands/mod.rs b/src/bin/cargo/commands/mod.rs index 838902da3..7d77388f5 100644 --- a/src/bin/cargo/commands/mod.rs +++ b/src/bin/cargo/commands/mod.rs @@ -40,7 +40,7 @@ pub fn builtin() -> Vec { ] } -pub fn builtin_exec(cmd: &str) -> Option) -> CliResult> { +pub fn builtin_exec(cmd: &str) -> Option CliResult> { let f = match cmd { "bench" => bench::exec, "build" => build::exec, diff --git a/src/bin/cargo/commands/new.rs b/src/bin/cargo/commands/new.rs index c1828fd86..2474bcc0e 100644 --- a/src/bin/cargo/commands/new.rs +++ b/src/bin/cargo/commands/new.rs @@ -12,7 +12,7 @@ pub fn cli() -> App { .after_help("Run `cargo help new` for more detailed information.\n") } -pub fn exec(config: &mut Config, args: &ArgMatches<'_>) -> CliResult { +pub fn exec(config: &mut Config, args: &ArgMatches) -> CliResult { let opts = args.new_options(config)?; ops::new(&opts, config)?; diff --git a/src/bin/cargo/commands/owner.rs b/src/bin/cargo/commands/owner.rs index fd3d6169b..1ece08453 100644 --- a/src/bin/cargo/commands/owner.rs +++ b/src/bin/cargo/commands/owner.rs @@ -13,7 +13,7 @@ pub fn cli() -> App { "LOGIN", "Name of a user or team to invite as an owner", ) - .short("a"), + .short('a'), ) .arg( multi_opt( @@ -21,16 +21,16 @@ pub fn cli() -> App { "LOGIN", "Name of a user or team to remove as an owner", ) - .short("r"), + .short('r'), ) - .arg(opt("list", "List owners of a crate").short("l")) + .arg(opt("list", "List owners of a crate").short('l')) .arg(opt("index", "Registry index to modify owners for").value_name("INDEX")) .arg(opt("token", "API token to use when authenticating").value_name("TOKEN")) .arg(opt("registry", "Registry to use").value_name("REGISTRY")) .after_help("Run `cargo help owner` for more detailed information.\n") } -pub fn exec(config: &mut Config, args: &ArgMatches<'_>) -> CliResult { +pub fn exec(config: &mut Config, args: &ArgMatches) -> CliResult { config.load_credentials()?; let registry = args.registry(config)?; diff --git a/src/bin/cargo/commands/package.rs b/src/bin/cargo/commands/package.rs index 875a0b0ab..5584052e9 100644 --- a/src/bin/cargo/commands/package.rs +++ b/src/bin/cargo/commands/package.rs @@ -11,7 +11,7 @@ pub fn cli() -> App { "list", "Print files included in a package without making one", ) - .short("l"), + .short('l'), ) .arg(opt( "no-verify", @@ -38,7 +38,7 @@ pub fn cli() -> App { .after_help("Run `cargo help package` for more detailed information.\n") } -pub fn exec(config: &mut Config, args: &ArgMatches<'_>) -> CliResult { +pub fn exec(config: &mut Config, args: &ArgMatches) -> CliResult { let ws = args.workspace(config)?; let specs = args.packages_from_flags()?; diff --git a/src/bin/cargo/commands/pkgid.rs b/src/bin/cargo/commands/pkgid.rs index 5bf7d8c22..b5f7925aa 100644 --- a/src/bin/cargo/commands/pkgid.rs +++ b/src/bin/cargo/commands/pkgid.rs @@ -13,7 +13,7 @@ pub fn cli() -> App { .after_help("Run `cargo help pkgid` for more detailed information.\n") } -pub fn exec(config: &mut Config, args: &ArgMatches<'_>) -> CliResult { +pub fn exec(config: &mut Config, args: &ArgMatches) -> CliResult { let ws = args.workspace(config)?; if args.is_present_with_zero_values("package") { print_available_packages(&ws)? diff --git a/src/bin/cargo/commands/publish.rs b/src/bin/cargo/commands/publish.rs index 869fbccdf..f1cdcc2c1 100644 --- a/src/bin/cargo/commands/publish.rs +++ b/src/bin/cargo/commands/publish.rs @@ -27,7 +27,7 @@ pub fn cli() -> App { .after_help("Run `cargo help publish` for more detailed information.\n") } -pub fn exec(config: &mut Config, args: &ArgMatches<'_>) -> CliResult { +pub fn exec(config: &mut Config, args: &ArgMatches) -> CliResult { config.load_credentials()?; let registry = args.registry(config)?; diff --git a/src/bin/cargo/commands/read_manifest.rs b/src/bin/cargo/commands/read_manifest.rs index 86867152c..186091a35 100644 --- a/src/bin/cargo/commands/read_manifest.rs +++ b/src/bin/cargo/commands/read_manifest.rs @@ -13,7 +13,7 @@ Deprecated, use `cargo metadata --no-deps` instead.\ .arg_manifest_path() } -pub fn exec(config: &mut Config, args: &ArgMatches<'_>) -> CliResult { +pub fn exec(config: &mut Config, args: &ArgMatches) -> CliResult { let ws = args.workspace(config)?; config .shell() diff --git a/src/bin/cargo/commands/report.rs b/src/bin/cargo/commands/report.rs index 34a79bb8f..0135ef90a 100644 --- a/src/bin/cargo/commands/report.rs +++ b/src/bin/cargo/commands/report.rs @@ -22,14 +22,19 @@ pub fn cli() -> App { ) } -pub fn exec(config: &mut Config, args: &ArgMatches<'_>) -> CliResult { +pub fn exec(config: &mut Config, args: &ArgMatches) -> CliResult { match args.subcommand() { - ("future-incompatibilities", Some(args)) => report_future_incompatibilies(config, args), - (cmd, _) => panic!("unexpected command `{}`", cmd), + Some(("future-incompatibilities", args)) => report_future_incompatibilies(config, args), + Some((cmd, _)) => { + unreachable!("unexpected command {}", cmd) + } + None => { + unreachable!("unexpected command") + } } } -fn report_future_incompatibilies(config: &Config, args: &ArgMatches<'_>) -> CliResult { +fn report_future_incompatibilies(config: &Config, args: &ArgMatches) -> CliResult { let ws = args.workspace(config)?; let reports = OnDiskReports::load(&ws)?; let id = args diff --git a/src/bin/cargo/commands/run.rs b/src/bin/cargo/commands/run.rs index 75f317c94..a42f49ae5 100644 --- a/src/bin/cargo/commands/run.rs +++ b/src/bin/cargo/commands/run.rs @@ -11,7 +11,11 @@ pub fn cli() -> App { .setting(AppSettings::TrailingVarArg) .about("Run a binary or example of the local package") .arg_quiet() - .arg(Arg::with_name("args").multiple(true)) + .arg( + Arg::with_name("args") + .allow_invalid_utf8(true) + .multiple(true), + ) .arg_targets_bin_example( "Name of the bin target to run", "Name of the example target to run", @@ -30,7 +34,7 @@ pub fn cli() -> App { .after_help("Run `cargo help run` for more detailed information.\n") } -pub fn exec(config: &mut Config, args: &ArgMatches<'_>) -> CliResult { +pub fn exec(config: &mut Config, args: &ArgMatches) -> CliResult { let ws = args.workspace(config)?; let mut compile_opts = args.compile_options( diff --git a/src/bin/cargo/commands/rustc.rs b/src/bin/cargo/commands/rustc.rs index 750505dc0..0b6401fcd 100644 --- a/src/bin/cargo/commands/rustc.rs +++ b/src/bin/cargo/commands/rustc.rs @@ -50,7 +50,7 @@ pub fn cli() -> App { .after_help("Run `cargo help rustc` for more detailed information.\n") } -pub fn exec(config: &mut Config, args: &ArgMatches<'_>) -> CliResult { +pub fn exec(config: &mut Config, args: &ArgMatches) -> CliResult { let ws = args.workspace(config)?; // This is a legacy behavior that changes the behavior based on the profile. // If we want to support this more formally, I think adding a --mode flag diff --git a/src/bin/cargo/commands/rustdoc.rs b/src/bin/cargo/commands/rustdoc.rs index a6a32440c..246e33822 100644 --- a/src/bin/cargo/commands/rustdoc.rs +++ b/src/bin/cargo/commands/rustdoc.rs @@ -38,7 +38,7 @@ pub fn cli() -> App { .after_help("Run `cargo help rustdoc` for more detailed information.\n") } -pub fn exec(config: &mut Config, args: &ArgMatches<'_>) -> CliResult { +pub fn exec(config: &mut Config, args: &ArgMatches) -> CliResult { let ws = args.workspace(config)?; let mut compile_opts = args.compile_options_for_single_package( config, diff --git a/src/bin/cargo/commands/search.rs b/src/bin/cargo/commands/search.rs index f3f1d0467..0c8d172e9 100644 --- a/src/bin/cargo/commands/search.rs +++ b/src/bin/cargo/commands/search.rs @@ -21,7 +21,7 @@ pub fn cli() -> App { .after_help("Run `cargo help search` for more detailed information.\n") } -pub fn exec(config: &mut Config, args: &ArgMatches<'_>) -> CliResult { +pub fn exec(config: &mut Config, args: &ArgMatches) -> CliResult { let registry = args.registry(config)?; let index = args.index()?; let limit = args.value_of_u32("limit")?; diff --git a/src/bin/cargo/commands/test.rs b/src/bin/cargo/commands/test.rs index d03ed99d2..b2d31ba2c 100644 --- a/src/bin/cargo/commands/test.rs +++ b/src/bin/cargo/commands/test.rs @@ -23,7 +23,7 @@ pub fn cli() -> App { "quiet", "Display one character per test instead of one line", ) - .short("q"), + .short('q'), ) .arg_targets_all( "Test only this package's library unit tests", @@ -62,7 +62,7 @@ pub fn cli() -> App { ) } -pub fn exec(config: &mut Config, args: &ArgMatches<'_>) -> CliResult { +pub fn exec(config: &mut Config, args: &ArgMatches) -> CliResult { let ws = args.workspace(config)?; let mut compile_opts = args.compile_options( diff --git a/src/bin/cargo/commands/tree.rs b/src/bin/cargo/commands/tree.rs index f45e21ba6..7cdfa3c42 100644 --- a/src/bin/cargo/commands/tree.rs +++ b/src/bin/cargo/commands/tree.rs @@ -20,7 +20,7 @@ pub fn cli() -> App { "Exclude specific workspace members", ) // Deprecated, use --no-dedupe instead. - .arg(Arg::with_name("all").long("all").short("a").hidden(true)) + .arg(Arg::with_name("all").long("all").short('a').hidden(true)) // Deprecated, use --target=all instead. .arg( Arg::with_name("all-targets") @@ -46,7 +46,7 @@ pub fn cli() -> App { (features, normal, build, dev, all, \ no-normal, no-build, no-dev, no-proc-macro)", ) - .short("e"), + .short('e'), ) .arg( optional_multi_opt( @@ -54,7 +54,7 @@ pub fn cli() -> App { "SPEC", "Invert the tree direction and focus on the given package", ) - .short("i"), + .short('i'), ) .arg(multi_opt( "prune", @@ -88,7 +88,7 @@ pub fn cli() -> App { "duplicates", "Show only dependencies which come in multiple versions (implies -i)", ) - .short("d") + .short('d') .alias("duplicate"), ) .arg( @@ -100,20 +100,20 @@ pub fn cli() -> App { .arg( opt("format", "Format string used for printing dependencies") .value_name("FORMAT") - .short("f") + .short('f') .default_value("{p}"), ) .arg( // Backwards compatibility with old cargo-tree. Arg::with_name("version") .long("version") - .short("V") + .short('V') .hidden(true), ) .after_help("Run `cargo help tree` for more detailed information.\n") } -pub fn exec(config: &mut Config, args: &ArgMatches<'_>) -> CliResult { +pub fn exec(config: &mut Config, args: &ArgMatches) -> CliResult { if args.is_present("version") { let verbose = args.occurrences_of("verbose") > 0; let version = cli::get_version_string(verbose); @@ -226,10 +226,7 @@ subtree of the package given to -p.\n\ /// Parses `--edges` option. /// /// Returns a tuple of `EdgeKind` map and `no_proc_marco` flag. -fn parse_edge_kinds( - config: &Config, - args: &ArgMatches<'_>, -) -> CargoResult<(HashSet, bool)> { +fn parse_edge_kinds(config: &Config, args: &ArgMatches) -> CargoResult<(HashSet, bool)> { let (kinds, no_proc_macro) = { let mut no_proc_macro = false; let mut kinds = args.values_of("edges").map_or_else( diff --git a/src/bin/cargo/commands/uninstall.rs b/src/bin/cargo/commands/uninstall.rs index f228af195..33f3f3819 100644 --- a/src/bin/cargo/commands/uninstall.rs +++ b/src/bin/cargo/commands/uninstall.rs @@ -13,7 +13,7 @@ pub fn cli() -> App { .after_help("Run `cargo help uninstall` for more detailed information.\n") } -pub fn exec(config: &mut Config, args: &ArgMatches<'_>) -> CliResult { +pub fn exec(config: &mut Config, args: &ArgMatches) -> CliResult { let root = args.value_of("root"); if args.is_present_with_zero_values("package") { diff --git a/src/bin/cargo/commands/update.rs b/src/bin/cargo/commands/update.rs index c1041310b..92be87ed9 100644 --- a/src/bin/cargo/commands/update.rs +++ b/src/bin/cargo/commands/update.rs @@ -7,7 +7,7 @@ pub fn cli() -> App { subcommand("update") .about("Update dependencies as recorded in the local lock file") .arg_quiet() - .arg(opt("workspace", "Only update the workspace packages").short("w")) + .arg(opt("workspace", "Only update the workspace packages").short('w')) .arg_package_spec_simple("Package to update") .arg(opt( "aggressive", @@ -25,7 +25,7 @@ pub fn cli() -> App { .after_help("Run `cargo help update` for more detailed information.\n") } -pub fn exec(config: &mut Config, args: &ArgMatches<'_>) -> CliResult { +pub fn exec(config: &mut Config, args: &ArgMatches) -> CliResult { let ws = args.workspace(config)?; if args.is_present_with_zero_values("package") { diff --git a/src/bin/cargo/commands/vendor.rs b/src/bin/cargo/commands/vendor.rs index 9a96af613..104cf9028 100644 --- a/src/bin/cargo/commands/vendor.rs +++ b/src/bin/cargo/commands/vendor.rs @@ -7,7 +7,11 @@ pub fn cli() -> App { .about("Vendor all dependencies for a project locally") .arg_quiet() .arg_manifest_path() - .arg(Arg::with_name("path").help("Where to vendor crates (`vendor` by default)")) + .arg( + Arg::with_name("path") + .allow_invalid_utf8(true) + .help("Where to vendor crates (`vendor` by default)"), + ) .arg( Arg::with_name("no-delete") .long("no-delete") @@ -15,17 +19,18 @@ pub fn cli() -> App { ) .arg( Arg::with_name("tomls") - .short("s") + .short('s') .long("sync") .help("Additional `Cargo.toml` to sync and vendor") .value_name("TOML") + .allow_invalid_utf8(true) .multiple(true), ) .arg( Arg::with_name("respect-source-config") .long("respect-source-config") .help("Respect `[source]` config in `.cargo/config`") - .multiple(true), + .multiple_occurrences(true), ) .arg( Arg::with_name("versioned-dirs") @@ -59,7 +64,7 @@ pub fn cli() -> App { .after_help("Run `cargo help vendor` for more detailed information.\n") } -pub fn exec(config: &mut Config, args: &ArgMatches<'_>) -> CliResult { +pub fn exec(config: &mut Config, args: &ArgMatches) -> CliResult { // We're doing the vendoring operation ourselves, so we don't actually want // to respect any of the `source` configuration in Cargo itself. That's // intended for other consumers of Cargo, but we want to go straight to the diff --git a/src/bin/cargo/commands/verify_project.rs b/src/bin/cargo/commands/verify_project.rs index 4a5cf68c1..e3779d895 100644 --- a/src/bin/cargo/commands/verify_project.rs +++ b/src/bin/cargo/commands/verify_project.rs @@ -11,7 +11,7 @@ pub fn cli() -> App { .after_help("Run `cargo help verify-project` for more detailed information.\n") } -pub fn exec(config: &mut Config, args: &ArgMatches<'_>) -> CliResult { +pub fn exec(config: &mut Config, args: &ArgMatches) -> CliResult { if let Err(e) = args.workspace(config) { let mut h = HashMap::new(); h.insert("invalid".to_string(), e.to_string()); diff --git a/src/bin/cargo/commands/version.rs b/src/bin/cargo/commands/version.rs index 851887789..1e59f1369 100644 --- a/src/bin/cargo/commands/version.rs +++ b/src/bin/cargo/commands/version.rs @@ -8,7 +8,7 @@ pub fn cli() -> App { .after_help("Run `cargo help version` for more detailed information.\n") } -pub fn exec(config: &mut Config, args: &ArgMatches<'_>) -> CliResult { +pub fn exec(config: &mut Config, args: &ArgMatches) -> CliResult { let verbose = args.occurrences_of("verbose") > 0; let version = cli::get_version_string(verbose); cargo::drop_print!(config, "{}", version); diff --git a/src/bin/cargo/commands/yank.rs b/src/bin/cargo/commands/yank.rs index 9bf3fa02c..ec19c5e02 100644 --- a/src/bin/cargo/commands/yank.rs +++ b/src/bin/cargo/commands/yank.rs @@ -22,7 +22,7 @@ pub fn cli() -> App { .after_help("Run `cargo help yank` for more detailed information.\n") } -pub fn exec(config: &mut Config, args: &ArgMatches<'_>) -> CliResult { +pub fn exec(config: &mut Config, args: &ArgMatches) -> CliResult { config.load_credentials()?; let registry = args.registry(config)?; diff --git a/src/bin/cargo/main.rs b/src/bin/cargo/main.rs index 57895b766..af2e4141c 100644 --- a/src/bin/cargo/main.rs +++ b/src/bin/cargo/main.rs @@ -116,7 +116,7 @@ fn list_commands(config: &Config) -> BTreeMap { commands.insert( cmd.get_name().to_string(), CommandInfo::BuiltIn { - about: cmd.p.meta.about.map(|s| s.to_string()), + about: cmd.get_about().map(|s| s.to_string()), }, ); } diff --git a/src/cargo/lib.rs b/src/cargo/lib.rs index e4178fd16..17fcf8c0f 100644 --- a/src/cargo/lib.rs +++ b/src/cargo/lib.rs @@ -30,9 +30,12 @@ mod version; pub fn exit_with_error(err: CliError, shell: &mut Shell) -> ! { debug!("exit_with_error; err={:?}", err); + if let Some(ref err) = err.error { if let Some(clap_err) = err.downcast_ref::() { - clap_err.exit() + let exit_code = if clap_err.use_stderr() { 1 } else { 0 }; + let _ = clap_err.print(); + std::process::exit(exit_code) } } diff --git a/src/cargo/util/command_prelude.rs b/src/cargo/util/command_prelude.rs index ef9458401..1e672357e 100644 --- a/src/cargo/util/command_prelude.rs +++ b/src/cargo/util/command_prelude.rs @@ -1,3 +1,5 @@ +#![allow(deprecated)] + use crate::core::compiler::{BuildConfig, MessageFormat}; use crate::core::resolver::CliFeatures; use crate::core::{Edition, Workspace}; @@ -23,10 +25,10 @@ pub use crate::core::compiler::CompileMode; pub use crate::{CliError, CliResult, Config}; pub use clap::{AppSettings, Arg, ArgMatches}; -pub type App = clap::App<'static, 'static>; +pub type App = clap::App<'static>; pub trait AppExt: Sized { - fn _arg(self, arg: Arg<'static, 'static>) -> Self; + fn _arg(self, arg: Arg<'static>) -> Self; /// Do not use this method, it is only for backwards compatibility. /// Use `arg_package_spec_no_all` instead. @@ -55,13 +57,13 @@ pub trait AppExt: Sized { } fn arg_package_spec_simple(self, package: &'static str) -> Self { - self._arg(optional_multi_opt("package", "SPEC", package).short("p")) + self._arg(optional_multi_opt("package", "SPEC", package).short('p')) } fn arg_package(self, package: &'static str) -> Self { self._arg( optional_opt("package", package) - .short("p") + .short('p') .value_name("SPEC"), ) } @@ -69,7 +71,7 @@ pub trait AppExt: Sized { fn arg_jobs(self) -> Self { self._arg( opt("jobs", "Number of parallel jobs, defaults to # of CPUs") - .short("j") + .short('j') .value_name("N"), ) } @@ -142,7 +144,7 @@ pub trait AppExt: Sized { } fn arg_release(self, release: &'static str) -> Self { - self._arg(opt("release", release).short("r")) + self._arg(opt("release", release).short('r')) } fn arg_profile(self, profile: &'static str) -> Self { @@ -238,21 +240,21 @@ pub trait AppExt: Sized { } fn arg_quiet(self) -> Self { - self._arg(opt("quiet", "Do not print cargo log messages").short("q")) + self._arg(opt("quiet", "Do not print cargo log messages").short('q')) } } impl AppExt for App { - fn _arg(self, arg: Arg<'static, 'static>) -> Self { + fn _arg(self, arg: Arg<'static>) -> Self { self.arg(arg) } } -pub fn opt(name: &'static str, help: &'static str) -> Arg<'static, 'static> { +pub fn opt(name: &'static str, help: &'static str) -> Arg<'static> { Arg::with_name(name).long(name).help(help) } -pub fn optional_opt(name: &'static str, help: &'static str) -> Arg<'static, 'static> { +pub fn optional_opt(name: &'static str, help: &'static str) -> Arg<'static> { opt(name, help).min_values(0) } @@ -260,7 +262,7 @@ pub fn optional_multi_opt( name: &'static str, value_name: &'static str, help: &'static str, -) -> Arg<'static, 'static> { +) -> Arg<'static> { opt(name, help) .value_name(value_name) .multiple(true) @@ -268,11 +270,7 @@ pub fn optional_multi_opt( .number_of_values(1) } -pub fn multi_opt( - name: &'static str, - value_name: &'static str, - help: &'static str, -) -> Arg<'static, 'static> { +pub fn multi_opt(name: &'static str, value_name: &'static str, help: &'static str) -> Arg<'static> { // Note that all `.multiple(true)` arguments in Cargo should specify // `.number_of_values(1)` as well, so that `--foo val1 val2` is // *not* parsed as `foo` with values ["val1", "val2"]. @@ -308,7 +306,10 @@ pub trait ArgMatchesExt { let arg = match self._value_of(name) { None => None, Some(arg) => Some(arg.parse::().map_err(|_| { - clap::Error::value_validation_auto(format!("could not parse `{}` as a number", arg)) + clap::Error::raw( + clap::ErrorKind::ValueValidation, + format!("Invalid value: could not parse `{}` as a number", arg), + ) })?), }; Ok(arg) @@ -320,7 +321,11 @@ pub trait ArgMatchesExt { } fn root_manifest(&self, config: &Config) -> CargoResult { - if let Some(path) = self.value_of_path("manifest-path", config) { + if let Some(path) = self + ._is_valid_arg("manifest-path") + .then(|| self.value_of_path("manifest-path", config)) + .flatten() + { // In general, we try to avoid normalizing paths in Cargo, // but in this particular case we need it to fix #3586. let path = paths::normalize_path(&path); @@ -395,8 +400,8 @@ pub trait ArgMatchesExt { }; let name = match ( - self._is_present("release"), - self._is_present("debug"), + self.is_valid_and_present("release"), + self.is_valid_and_present("debug"), specified_profile, ) { (false, false, None) => default, @@ -424,9 +429,13 @@ pub trait ArgMatchesExt { fn packages_from_flags(&self) -> CargoResult { Packages::from_flags( // TODO Integrate into 'workspace' - self._is_present("workspace") || self._is_present("all"), - self._values_of("exclude"), - self._values_of("package"), + self.is_valid_and_present("workspace") || self.is_valid_and_present("all"), + self._is_valid_arg("exclude") + .then(|| self._values_of("exclude")) + .unwrap_or_default(), + self._is_valid_arg("package") + .then(|| self._values_of("package")) + .unwrap_or_default(), ) } @@ -503,9 +512,9 @@ pub trait ArgMatchesExt { let mut build_config = BuildConfig::new(config, self.jobs()?, &self.targets(), mode)?; build_config.message_format = message_format.unwrap_or(MessageFormat::Human); build_config.requested_profile = self.get_profile_name(config, "dev", profile_checking)?; - build_config.build_plan = self._is_present("build-plan"); - build_config.unit_graph = self._is_present("unit-graph"); - build_config.future_incompat_report = self._is_present("future-incompat-report"); + build_config.build_plan = self.is_valid_and_present("build-plan"); + build_config.unit_graph = self.is_valid_and_present("unit-graph"); + build_config.future_incompat_report = self.is_valid_and_present("future-incompat-report"); if build_config.build_plan { config .cli_unstable() @@ -522,28 +531,32 @@ pub trait ArgMatchesExt { cli_features: self.cli_features()?, spec, filter: CompileFilter::from_raw_arguments( - self._is_present("lib"), + self.is_valid_and_present("lib"), self._values_of("bin"), - self._is_present("bins"), - self._values_of("test"), - self._is_present("tests"), + self.is_valid_and_present("bins"), + self._is_valid_arg("test") + .then(|| self._values_of("test")) + .unwrap_or_default(), + self.is_valid_and_present("tests"), self._values_of("example"), - self._is_present("examples"), - self._values_of("bench"), - self._is_present("benches"), - self._is_present("all-targets"), + self.is_valid_and_present("examples"), + self._is_valid_arg("bench") + .then(|| self._values_of("bench")) + .unwrap_or_default(), + self.is_valid_and_present("benches"), + self.is_valid_and_present("all-targets"), ), target_rustdoc_args: None, target_rustc_args: None, target_rustc_crate_types: None, local_rustdoc_args: None, rustdoc_document_private_items: false, - honor_rust_version: !self._is_present("ignore-rust-version"), + honor_rust_version: !self.is_valid_and_present("ignore-rust-version"), }; if let Some(ws) = workspace { self.check_optional_opts(ws, &opts)?; - } else if self.is_present_with_zero_values("package") { + } else if self._is_valid_arg("package") && self.is_present_with_zero_values("package") { // As for cargo 0.50.0, this won't occur but if someone sneaks in // we can still provide this informative message for them. anyhow::bail!( @@ -630,7 +643,7 @@ pub trait ArgMatchesExt { workspace: &Workspace<'_>, compile_opts: &CompileOptions, ) -> CargoResult<()> { - if self.is_present_with_zero_values("package") { + if self._is_valid_arg("package") && self.is_present_with_zero_values("package") { print_available_packages(workspace)? } @@ -642,11 +655,11 @@ pub trait ArgMatchesExt { print_available_binaries(workspace, compile_opts)?; } - if self.is_present_with_zero_values("bench") { + if self._is_valid_arg("bench") && self.is_present_with_zero_values("bench") { print_available_benches(workspace, compile_opts)?; } - if self.is_present_with_zero_values("test") { + if self._is_valid_arg("test") && self.is_present_with_zero_values("test") { print_available_tests(workspace, compile_opts)?; } @@ -657,6 +670,10 @@ pub trait ArgMatchesExt { self._is_present(name) && self._value_of(name).is_none() } + fn is_valid_and_present(&self, name: &str) -> bool { + self._is_valid_arg(name) && self._is_present(name) + } + fn _value_of(&self, name: &str) -> Option<&str>; fn _values_of(&self, name: &str) -> Vec; @@ -666,9 +683,11 @@ pub trait ArgMatchesExt { fn _values_of_os(&self, name: &str) -> Vec; fn _is_present(&self, name: &str) -> bool; + + fn _is_valid_arg(&self, name: &str) -> bool; } -impl<'a> ArgMatchesExt for ArgMatches<'a> { +impl<'a> ArgMatchesExt for ArgMatches { fn _value_of(&self, name: &str) -> Option<&str> { self.value_of(name) } @@ -694,13 +713,17 @@ impl<'a> ArgMatchesExt for ArgMatches<'a> { fn _is_present(&self, name: &str) -> bool { self.is_present(name) } + + fn _is_valid_arg(&self, name: &str) -> bool { + self.is_valid_arg(name) + } } -pub fn values(args: &ArgMatches<'_>, name: &str) -> Vec { +pub fn values(args: &ArgMatches, name: &str) -> Vec { args._values_of(name) } -pub fn values_os(args: &ArgMatches<'_>, name: &str) -> Vec { +pub fn values_os(args: &ArgMatches, name: &str) -> Vec { args._values_of_os(name) } diff --git a/src/cargo/util/errors.rs b/src/cargo/util/errors.rs index 8a3716077..524a5d627 100644 --- a/src/cargo/util/errors.rs +++ b/src/cargo/util/errors.rs @@ -300,6 +300,12 @@ impl From for CliError { } } +impl From for CliError { + fn from(err: std::io::Error) -> CliError { + CliError::new(err.into(), 1) + } +} + // ============================================================================= // Construction helpers diff --git a/tests/testsuite/cargo_config.rs b/tests/testsuite/cargo_config.rs index a11e9afc5..0a3bc37c0 100644 --- a/tests/testsuite/cargo_config.rs +++ b/tests/testsuite/cargo_config.rs @@ -473,22 +473,20 @@ fn includes() { .with_stderr("") .run(); - cargo_process( - "config get build.rustflags --show-origin=yes -Zunstable-options -Zconfig-include", - ) - .cwd(&sub_folder.parent().unwrap()) - .masquerade_as_nightly_cargo() - .with_stdout( - "\ + cargo_process("config get build.rustflags --show-origin -Zunstable-options -Zconfig-include") + .cwd(&sub_folder.parent().unwrap()) + .masquerade_as_nightly_cargo() + .with_stdout( + "\ build.rustflags = [ \"--flag-other\", # [ROOT]/foo/.cargo/other.toml \"--flag-directory\", # [ROOT]/foo/.cargo/config.toml \"--flag-global\", # [ROOT]/home/.cargo/config.toml ] ", - ) - .with_stderr("") - .run(); + ) + .with_stderr("") + .run(); cargo_process("config get --merged=no -Zunstable-options -Zconfig-include") .cwd(&sub_folder.parent().unwrap()) diff --git a/tests/testsuite/metadata.rs b/tests/testsuite/metadata.rs index bc39d86ed..279b760ad 100644 --- a/tests/testsuite/metadata.rs +++ b/tests/testsuite/metadata.rs @@ -1183,7 +1183,7 @@ fn cargo_metadata_bad_version() { .with_status(1) .with_stderr_contains( "\ -error: '2' isn't a valid value for '--format-version ' +error: \"2\" isn't a valid value for '--format-version ' [possible values: 1] ", ) diff --git a/tests/testsuite/new.rs b/tests/testsuite/new.rs index 829638141..8d85f488c 100644 --- a/tests/testsuite/new.rs +++ b/tests/testsuite/new.rs @@ -362,7 +362,7 @@ fn new_default_edition() { #[cargo_test] fn new_with_bad_edition() { cargo_process("new --edition something_else foo") - .with_stderr_contains("error: 'something_else' isn't a valid value[..]") + .with_stderr_contains("error: \"something_else\" isn't a valid value[..]") .with_status(1) .run(); } diff --git a/tests/testsuite/run.rs b/tests/testsuite/run.rs index ee7c138da..022dc2c5f 100644 --- a/tests/testsuite/run.rs +++ b/tests/testsuite/run.rs @@ -1251,7 +1251,7 @@ fn run_multiple_packages() { cargo().arg("-p").arg("d1").arg("-p").arg("d2") .with_status(1) - .with_stderr_contains("error: The argument '--package ' was provided more than once, but cannot be used multiple times").run(); + .with_stderr_contains("error: The argument '--package ...' was provided more than once, but cannot be used multiple times").run(); cargo() .arg("-p") diff --git a/tests/testsuite/rustc.rs b/tests/testsuite/rustc.rs index 571e53927..243055a5a 100644 --- a/tests/testsuite/rustc.rs +++ b/tests/testsuite/rustc.rs @@ -540,7 +540,7 @@ fn fail_with_multiple_packages() { .with_status(1) .with_stderr_contains( "\ -error: The argument '--package ' was provided more than once, \ +error: The argument '--package ...' was provided more than once, \ but cannot be used multiple times ", )