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 20dfd540f0b..3435686adc0 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 cd1fea8f1f4..1db83f1f193 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 39ec1be2253..d81f1f8ab60 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 ad6705119a9..367cad83884 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 3be146c6d26..07b98be707a 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 c966c65f13b..f758981b1ba 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 61938dfc2ca..78613696223 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 21d561394ca..9833594493a 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 ff3fcbec5da..0106c0f1e84 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 85cf955e433..5463e12df68 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 1eebdbd418c..b20d8616a1f 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 aae435a5196..3cc0701ffa2 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 257d30756f5..3bb957f3f01 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 79be166e4ee..fb8db412104 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 a045e14548b..673f69903c2 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 0f51d52969d..3eea2bb12b1 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 4ce9498e7e1..518247e8b85 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 66e856b48e7..6caa7ab946a 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 838902da3cf..7d77388f5c2 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 c1828fd8637..2474bcc0ef4 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 fd3d6169b29..1ece0845322 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 875a0b0ab54..5584052e909 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 5bf7d8c2219..b5f7925aae2 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 869fbccdf27..f1cdcc2c19d 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 86867152c93..186091a35ff 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 34a79bb8f39..0135ef90afb 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 75f317c94b6..a42f49ae562 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 750505dc04e..0b6401fcd1b 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 a6a32440ccb..246e3382210 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 f3f1d04679d..0c8d172e9ad 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 d03ed99d206..b2d31ba2c64 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 f45e21ba619..7cdfa3c422b 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 f228af195d3..33f3f3819dd 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 c1041310bfb..92be87ed990 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 9a96af613d4..104cf902859 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 4a5cf68c1e2..e3779d89573 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 8518877893a..1e59f136954 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 9bf3fa02cc0..ec19c5e029b 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 57895b766ec..af2e4141c80 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 e4178fd1630..17fcf8c0fe1 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 ef94584016a..1e672357e6b 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 8a371607725..524a5d627c4 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 a11e9afc58f..0a3bc37c012 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 bc39d86ed0f..279b760ad6c 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 829638141da..8d85f488c55 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 ee7c138daf1..022dc2c5fa3 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 571e5392783..243055a5a86 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 ", )