From f17ecafc24a88c855d66c4740eea5139da19fbd7 Mon Sep 17 00:00:00 2001 From: Ed Page Date: Tue, 4 Jan 2022 11:04:50 -0600 Subject: [PATCH 01/12] 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 ", ) From 88a122c428af5e21b1aafe2afc586af1890d5375 Mon Sep 17 00:00:00 2001 From: Ed Page Date: Wed, 5 Jan 2022 20:00:18 -0600 Subject: [PATCH 02/12] refactor: Resolve Arg::with_name deprecation --- src/bin/cargo/cli.rs | 2 +- src/bin/cargo/commands/bench.rs | 4 ++-- src/bin/cargo/commands/config.rs | 2 +- src/bin/cargo/commands/fix.rs | 12 ++++++------ src/bin/cargo/commands/init.rs | 2 +- src/bin/cargo/commands/install.rs | 2 +- src/bin/cargo/commands/login.rs | 2 +- src/bin/cargo/commands/new.rs | 2 +- src/bin/cargo/commands/owner.rs | 2 +- src/bin/cargo/commands/pkgid.rs | 2 +- src/bin/cargo/commands/run.rs | 6 +----- 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 | 23 ++++++----------------- src/bin/cargo/commands/uninstall.rs | 2 +- src/bin/cargo/commands/vendor.rs | 26 +++++++++----------------- src/bin/cargo/commands/yank.rs | 2 +- src/cargo/util/command_prelude.rs | 2 +- 20 files changed, 40 insertions(+), 63 deletions(-) diff --git a/src/bin/cargo/cli.rs b/src/bin/cargo/cli.rs index 1db83f1f193..f5d82d10de8 100644 --- a/src/bin/cargo/cli.rs +++ b/src/bin/cargo/cli.rs @@ -476,7 +476,7 @@ See 'cargo help ' for more information on a specific command.\n", .global(true), ) .arg( - Arg::with_name("unstable-features") + Arg::new("unstable-features") .help("Unstable (nightly-only) flags to Cargo, see 'cargo -Z help' for details") .short('Z') .value_name("FLAG") diff --git a/src/bin/cargo/commands/bench.rs b/src/bin/cargo/commands/bench.rs index d81f1f8ab60..d76a7f9dc3d 100644 --- a/src/bin/cargo/commands/bench.rs +++ b/src/bin/cargo/commands/bench.rs @@ -7,11 +7,11 @@ pub fn cli() -> App { .about("Execute all benchmarks of a local package") .arg_quiet() .arg( - Arg::with_name("BENCHNAME") + Arg::new("BENCHNAME") .help("If specified, only run benches containing this string in their names"), ) .arg( - Arg::with_name("args") + Arg::new("args") .help("Arguments for the bench binary") .multiple(true) .last(true), diff --git a/src/bin/cargo/commands/config.rs b/src/bin/cargo/commands/config.rs index 78613696223..e3492ab876e 100644 --- a/src/bin/cargo/commands/config.rs +++ b/src/bin/cargo/commands/config.rs @@ -8,7 +8,7 @@ pub fn cli() -> App { .setting(clap::AppSettings::SubcommandRequiredElseHelp) .subcommand( subcommand("get") - .arg(Arg::with_name("key").help("The config key to display")) + .arg(Arg::new("key").help("The config key to display")) .arg( opt("format", "Display format") .possible_values(cargo_config::ConfigFormat::POSSIBLE_VALUES) diff --git a/src/bin/cargo/commands/fix.rs b/src/bin/cargo/commands/fix.rs index 5463e12df68..e366f7f892b 100644 --- a/src/bin/cargo/commands/fix.rs +++ b/src/bin/cargo/commands/fix.rs @@ -32,32 +32,32 @@ pub fn cli() -> App { .arg_manifest_path() .arg_message_format() .arg( - Arg::with_name("broken-code") + Arg::new("broken-code") .long("broken-code") .help("Fix code even if it already has compiler errors"), ) .arg( - Arg::with_name("edition") + Arg::new("edition") .long("edition") .help("Fix in preparation for the next edition"), ) .arg( - Arg::with_name("idioms") + Arg::new("idioms") .long("edition-idioms") .help("Fix warnings to migrate to the idioms of an edition"), ) .arg( - Arg::with_name("allow-no-vcs") + Arg::new("allow-no-vcs") .long("allow-no-vcs") .help("Fix code even if a VCS was not detected"), ) .arg( - Arg::with_name("allow-dirty") + Arg::new("allow-dirty") .long("allow-dirty") .help("Fix code even if the working directory is dirty"), ) .arg( - Arg::with_name("allow-staged") + Arg::new("allow-staged") .long("allow-staged") .help("Fix code even if the working directory has staged changes"), ) diff --git a/src/bin/cargo/commands/init.rs b/src/bin/cargo/commands/init.rs index 3bb957f3f01..e524d29fbaa 100644 --- a/src/bin/cargo/commands/init.rs +++ b/src/bin/cargo/commands/init.rs @@ -6,7 +6,7 @@ pub fn cli() -> App { subcommand("init") .about("Create a new cargo package in an existing directory") .arg_quiet() - .arg(Arg::with_name("path").default_value(".")) + .arg(Arg::new("path").default_value(".")) .arg(opt("registry", "Registry to use").value_name("REGISTRY")) .arg_new_opts() .after_help("Run `cargo help init` for more detailed information.\n") diff --git a/src/bin/cargo/commands/install.rs b/src/bin/cargo/commands/install.rs index fb8db412104..cecff8c4881 100644 --- a/src/bin/cargo/commands/install.rs +++ b/src/bin/cargo/commands/install.rs @@ -8,7 +8,7 @@ pub fn cli() -> App { subcommand("install") .about("Install a Rust binary. Default location is $HOME/.cargo/bin") .arg_quiet() - .arg(Arg::with_name("crate").empty_values(false).multiple(true)) + .arg(Arg::new("crate").empty_values(false).multiple(true)) .arg( opt("version", "Specify a version to install") .alias("vers") diff --git a/src/bin/cargo/commands/login.rs b/src/bin/cargo/commands/login.rs index 3eea2bb12b1..773fd9e3e8f 100644 --- a/src/bin/cargo/commands/login.rs +++ b/src/bin/cargo/commands/login.rs @@ -9,7 +9,7 @@ pub fn cli() -> App { If token is not specified, it will be read from stdin.", ) .arg_quiet() - .arg(Arg::with_name("token")) + .arg(Arg::new("token")) .arg(opt("registry", "Registry to use").value_name("REGISTRY")) .after_help("Run `cargo help login` for more detailed information.\n") } diff --git a/src/bin/cargo/commands/new.rs b/src/bin/cargo/commands/new.rs index 2474bcc0ef4..b8c1ba05a73 100644 --- a/src/bin/cargo/commands/new.rs +++ b/src/bin/cargo/commands/new.rs @@ -6,7 +6,7 @@ pub fn cli() -> App { subcommand("new") .about("Create a new cargo package at ") .arg_quiet() - .arg(Arg::with_name("path").required(true)) + .arg(Arg::new("path").required(true)) .arg(opt("registry", "Registry to use").value_name("REGISTRY")) .arg_new_opts() .after_help("Run `cargo help new` for more detailed information.\n") diff --git a/src/bin/cargo/commands/owner.rs b/src/bin/cargo/commands/owner.rs index 1ece0845322..e3fe2d6c720 100644 --- a/src/bin/cargo/commands/owner.rs +++ b/src/bin/cargo/commands/owner.rs @@ -6,7 +6,7 @@ pub fn cli() -> App { subcommand("owner") .about("Manage the owners of a crate on the registry") .arg_quiet() - .arg(Arg::with_name("crate")) + .arg(Arg::new("crate")) .arg( multi_opt( "add", diff --git a/src/bin/cargo/commands/pkgid.rs b/src/bin/cargo/commands/pkgid.rs index b5f7925aae2..8d23d78336c 100644 --- a/src/bin/cargo/commands/pkgid.rs +++ b/src/bin/cargo/commands/pkgid.rs @@ -7,7 +7,7 @@ pub fn cli() -> App { subcommand("pkgid") .about("Print a fully qualified package specification") .arg_quiet() - .arg(Arg::with_name("spec")) + .arg(Arg::new("spec")) .arg_package("Argument to get the package ID specifier for") .arg_manifest_path() .after_help("Run `cargo help pkgid` for more detailed information.\n") diff --git a/src/bin/cargo/commands/run.rs b/src/bin/cargo/commands/run.rs index a42f49ae562..797837f24fd 100644 --- a/src/bin/cargo/commands/run.rs +++ b/src/bin/cargo/commands/run.rs @@ -11,11 +11,7 @@ pub fn cli() -> App { .setting(AppSettings::TrailingVarArg) .about("Run a binary or example of the local package") .arg_quiet() - .arg( - Arg::with_name("args") - .allow_invalid_utf8(true) - .multiple(true), - ) + .arg(Arg::new("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", diff --git a/src/bin/cargo/commands/rustc.rs b/src/bin/cargo/commands/rustc.rs index 0b6401fcd1b..d7015358788 100644 --- a/src/bin/cargo/commands/rustc.rs +++ b/src/bin/cargo/commands/rustc.rs @@ -10,7 +10,7 @@ pub fn cli() -> App { .setting(AppSettings::TrailingVarArg) .about("Compile a package, and pass extra options to the compiler") .arg_quiet() - .arg(Arg::with_name("args").multiple(true).help("Rustc flags")) + .arg(Arg::new("args").multiple(true).help("Rustc flags")) .arg_package("Package to build") .arg_jobs() .arg_targets_all( diff --git a/src/bin/cargo/commands/rustdoc.rs b/src/bin/cargo/commands/rustdoc.rs index 246e3382210..8fc5078486a 100644 --- a/src/bin/cargo/commands/rustdoc.rs +++ b/src/bin/cargo/commands/rustdoc.rs @@ -7,7 +7,7 @@ pub fn cli() -> App { .setting(AppSettings::TrailingVarArg) .about("Build a package's documentation, using specified custom flags.") .arg_quiet() - .arg(Arg::with_name("args").multiple(true)) + .arg(Arg::new("args").multiple(true)) .arg(opt( "open", "Opens the docs in a browser after the operation", diff --git a/src/bin/cargo/commands/search.rs b/src/bin/cargo/commands/search.rs index 0c8d172e9ad..003e1d848ae 100644 --- a/src/bin/cargo/commands/search.rs +++ b/src/bin/cargo/commands/search.rs @@ -8,7 +8,7 @@ pub fn cli() -> App { subcommand("search") .about("Search packages in crates.io") .arg_quiet() - .arg(Arg::with_name("query").multiple(true)) + .arg(Arg::new("query").multiple(true)) .arg_index() .arg( opt( diff --git a/src/bin/cargo/commands/test.rs b/src/bin/cargo/commands/test.rs index b2d31ba2c64..caedb47aa2e 100644 --- a/src/bin/cargo/commands/test.rs +++ b/src/bin/cargo/commands/test.rs @@ -9,11 +9,11 @@ pub fn cli() -> App { .setting(AppSettings::TrailingVarArg) .about("Execute all unit and integration tests and build examples of a local package") .arg( - Arg::with_name("TESTNAME") + Arg::new("TESTNAME") .help("If specified, only run tests containing this string in their names"), ) .arg( - Arg::with_name("args") + Arg::new("args") .help("Arguments for the test binary") .multiple(true) .last(true), diff --git a/src/bin/cargo/commands/tree.rs b/src/bin/cargo/commands/tree.rs index 7cdfa3c422b..e9a83f3824c 100644 --- a/src/bin/cargo/commands/tree.rs +++ b/src/bin/cargo/commands/tree.rs @@ -20,13 +20,9 @@ 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::new("all").long("all").short('a').hidden(true)) // Deprecated, use --target=all instead. - .arg( - Arg::with_name("all-targets") - .long("all-targets") - .hidden(true), - ) + .arg(Arg::new("all-targets").long("all-targets").hidden(true)) .arg_features() .arg_target_triple( "Filter dependencies matching the given target-triple (default host platform). \ @@ -34,7 +30,7 @@ pub fn cli() -> App { ) // Deprecated, use -e=no-dev instead. .arg( - Arg::with_name("no-dev-dependencies") + Arg::new("no-dev-dependencies") .long("no-dev-dependencies") .hidden(true), ) @@ -63,13 +59,9 @@ pub fn cli() -> App { )) .arg(opt("depth", "Maximum display depth of the dependency tree").value_name("DEPTH")) // Deprecated, use --prefix=none instead. - .arg(Arg::with_name("no-indent").long("no-indent").hidden(true)) + .arg(Arg::new("no-indent").long("no-indent").hidden(true)) // Deprecated, use --prefix=depth instead. - .arg( - Arg::with_name("prefix-depth") - .long("prefix-depth") - .hidden(true), - ) + .arg(Arg::new("prefix-depth").long("prefix-depth").hidden(true)) .arg( opt( "prefix", @@ -105,10 +97,7 @@ pub fn cli() -> App { ) .arg( // Backwards compatibility with old cargo-tree. - Arg::with_name("version") - .long("version") - .short('V') - .hidden(true), + Arg::new("version").long("version").short('V').hidden(true), ) .after_help("Run `cargo help tree` for more detailed information.\n") } diff --git a/src/bin/cargo/commands/uninstall.rs b/src/bin/cargo/commands/uninstall.rs index 33f3f3819dd..7f6e3829bb3 100644 --- a/src/bin/cargo/commands/uninstall.rs +++ b/src/bin/cargo/commands/uninstall.rs @@ -6,7 +6,7 @@ pub fn cli() -> App { subcommand("uninstall") .about("Remove a Rust binary") .arg_quiet() - .arg(Arg::with_name("spec").multiple(true)) + .arg(Arg::new("spec").multiple(true)) .arg_package_spec_simple("Package to uninstall") .arg(multi_opt("bin", "NAME", "Only uninstall the binary NAME")) .arg(opt("root", "Directory to uninstall packages from").value_name("DIR")) diff --git a/src/bin/cargo/commands/vendor.rs b/src/bin/cargo/commands/vendor.rs index 104cf902859..4704d7b6c40 100644 --- a/src/bin/cargo/commands/vendor.rs +++ b/src/bin/cargo/commands/vendor.rs @@ -8,17 +8,17 @@ pub fn cli() -> App { .arg_quiet() .arg_manifest_path() .arg( - Arg::with_name("path") + Arg::new("path") .allow_invalid_utf8(true) .help("Where to vendor crates (`vendor` by default)"), ) .arg( - Arg::with_name("no-delete") + Arg::new("no-delete") .long("no-delete") .help("Don't delete older crates in the vendor directory"), ) .arg( - Arg::with_name("tomls") + Arg::new("tomls") .short('s') .long("sync") .help("Additional `Cargo.toml` to sync and vendor") @@ -27,37 +27,29 @@ pub fn cli() -> App { .multiple(true), ) .arg( - Arg::with_name("respect-source-config") + Arg::new("respect-source-config") .long("respect-source-config") .help("Respect `[source]` config in `.cargo/config`") .multiple_occurrences(true), ) .arg( - Arg::with_name("versioned-dirs") + Arg::new("versioned-dirs") .long("versioned-dirs") .help("Always include version in subdir name"), ) // Not supported. .arg( - Arg::with_name("no-merge-sources") + Arg::new("no-merge-sources") .long("no-merge-sources") .hidden(true), ) // Not supported. - .arg( - Arg::with_name("relative-path") - .long("relative-path") - .hidden(true), - ) + .arg(Arg::new("relative-path").long("relative-path").hidden(true)) // Not supported. - .arg( - Arg::with_name("only-git-deps") - .long("only-git-deps") - .hidden(true), - ) + .arg(Arg::new("only-git-deps").long("only-git-deps").hidden(true)) // Not supported. .arg( - Arg::with_name("disallow-duplicates") + Arg::new("disallow-duplicates") .long("disallow-duplicates") .hidden(true), ) diff --git a/src/bin/cargo/commands/yank.rs b/src/bin/cargo/commands/yank.rs index ec19c5e029b..0110f610170 100644 --- a/src/bin/cargo/commands/yank.rs +++ b/src/bin/cargo/commands/yank.rs @@ -6,7 +6,7 @@ pub fn cli() -> App { subcommand("yank") .about("Remove a pushed crate from the index") .arg_quiet() - .arg(Arg::with_name("crate")) + .arg(Arg::new("crate")) .arg( opt("vers", "The version to yank or un-yank") .value_name("VERSION") diff --git a/src/cargo/util/command_prelude.rs b/src/cargo/util/command_prelude.rs index 1e672357e6b..46036f20806 100644 --- a/src/cargo/util/command_prelude.rs +++ b/src/cargo/util/command_prelude.rs @@ -251,7 +251,7 @@ impl AppExt for App { } pub fn opt(name: &'static str, help: &'static str) -> Arg<'static> { - Arg::with_name(name).long(name).help(help) + Arg::new(name).long(name).help(help) } pub fn optional_opt(name: &'static str, help: &'static str) -> Arg<'static> { From 5435b269e47762d55e83b74142b269a9c4488a51 Mon Sep 17 00:00:00 2001 From: Ed Page Date: Wed, 5 Jan 2022 20:00:47 -0600 Subject: [PATCH 03/12] refactor: Resolve Arg::hidden deprecation --- src/bin/cargo/commands/tree.rs | 12 ++++++------ src/bin/cargo/commands/vendor.rs | 8 ++++---- src/cargo/util/command_prelude.rs | 2 +- 3 files changed, 11 insertions(+), 11 deletions(-) diff --git a/src/bin/cargo/commands/tree.rs b/src/bin/cargo/commands/tree.rs index e9a83f3824c..c1d47cbe5cb 100644 --- a/src/bin/cargo/commands/tree.rs +++ b/src/bin/cargo/commands/tree.rs @@ -20,9 +20,9 @@ pub fn cli() -> App { "Exclude specific workspace members", ) // Deprecated, use --no-dedupe instead. - .arg(Arg::new("all").long("all").short('a').hidden(true)) + .arg(Arg::new("all").long("all").short('a').hide(true)) // Deprecated, use --target=all instead. - .arg(Arg::new("all-targets").long("all-targets").hidden(true)) + .arg(Arg::new("all-targets").long("all-targets").hide(true)) .arg_features() .arg_target_triple( "Filter dependencies matching the given target-triple (default host platform). \ @@ -32,7 +32,7 @@ pub fn cli() -> App { .arg( Arg::new("no-dev-dependencies") .long("no-dev-dependencies") - .hidden(true), + .hide(true), ) .arg( multi_opt( @@ -59,9 +59,9 @@ pub fn cli() -> App { )) .arg(opt("depth", "Maximum display depth of the dependency tree").value_name("DEPTH")) // Deprecated, use --prefix=none instead. - .arg(Arg::new("no-indent").long("no-indent").hidden(true)) + .arg(Arg::new("no-indent").long("no-indent").hide(true)) // Deprecated, use --prefix=depth instead. - .arg(Arg::new("prefix-depth").long("prefix-depth").hidden(true)) + .arg(Arg::new("prefix-depth").long("prefix-depth").hide(true)) .arg( opt( "prefix", @@ -97,7 +97,7 @@ pub fn cli() -> App { ) .arg( // Backwards compatibility with old cargo-tree. - Arg::new("version").long("version").short('V').hidden(true), + Arg::new("version").long("version").short('V').hide(true), ) .after_help("Run `cargo help tree` for more detailed information.\n") } diff --git a/src/bin/cargo/commands/vendor.rs b/src/bin/cargo/commands/vendor.rs index 4704d7b6c40..5bcec7aad94 100644 --- a/src/bin/cargo/commands/vendor.rs +++ b/src/bin/cargo/commands/vendor.rs @@ -41,17 +41,17 @@ pub fn cli() -> App { .arg( Arg::new("no-merge-sources") .long("no-merge-sources") - .hidden(true), + .hide(true), ) // Not supported. - .arg(Arg::new("relative-path").long("relative-path").hidden(true)) + .arg(Arg::new("relative-path").long("relative-path").hide(true)) // Not supported. - .arg(Arg::new("only-git-deps").long("only-git-deps").hidden(true)) + .arg(Arg::new("only-git-deps").long("only-git-deps").hide(true)) // Not supported. .arg( Arg::new("disallow-duplicates") .long("disallow-duplicates") - .hidden(true), + .hide(true), ) .after_help("Run `cargo help vendor` for more detailed information.\n") } diff --git a/src/cargo/util/command_prelude.rs b/src/cargo/util/command_prelude.rs index 46036f20806..00b7f68d911 100644 --- a/src/cargo/util/command_prelude.rs +++ b/src/cargo/util/command_prelude.rs @@ -217,7 +217,7 @@ pub trait AppExt: Sized { ._arg( opt("host", "DEPRECATED, renamed to '--index'") .value_name("HOST") - .hidden(true), + .hide(true), ) } From f3ec865fe48e2c6850c9d6087bb62e16b11ed67a Mon Sep 17 00:00:00 2001 From: Ed Page Date: Wed, 5 Jan 2022 20:05:18 -0600 Subject: [PATCH 04/12] refactor: Resolve Arg::empty_values deprecation --- src/bin/cargo/commands/install.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/bin/cargo/commands/install.rs b/src/bin/cargo/commands/install.rs index cecff8c4881..5cfa5e32005 100644 --- a/src/bin/cargo/commands/install.rs +++ b/src/bin/cargo/commands/install.rs @@ -8,7 +8,7 @@ pub fn cli() -> App { subcommand("install") .about("Install a Rust binary. Default location is $HOME/.cargo/bin") .arg_quiet() - .arg(Arg::new("crate").empty_values(false).multiple(true)) + .arg(Arg::new("crate").forbid_empty_values(true).multiple(true)) .arg( opt("version", "Specify a version to install") .alias("vers") From 2aa4e9fbad96d3dcfb2ab43543421c9fa9182a22 Mon Sep 17 00:00:00 2001 From: Ed Page Date: Wed, 5 Jan 2022 20:02:01 -0600 Subject: [PATCH 05/12] refactor: Resolve AppSettings::UnifiedHelpMessage deprecation --- src/bin/cargo/cli.rs | 1 - src/cargo/util/command_prelude.rs | 1 - 2 files changed, 2 deletions(-) diff --git a/src/bin/cargo/cli.rs b/src/bin/cargo/cli.rs index f5d82d10de8..a351ff57978 100644 --- a/src/bin/cargo/cli.rs +++ b/src/bin/cargo/cli.rs @@ -409,7 +409,6 @@ fn cli() -> App { }; App::new("cargo") .settings(&[ - AppSettings::UnifiedHelpMessage, AppSettings::DeriveDisplayOrder, AppSettings::AllowExternalSubcommands, AppSettings::NoAutoVersion, diff --git a/src/cargo/util/command_prelude.rs b/src/cargo/util/command_prelude.rs index 00b7f68d911..0731356ff1c 100644 --- a/src/cargo/util/command_prelude.rs +++ b/src/cargo/util/command_prelude.rs @@ -283,7 +283,6 @@ pub fn multi_opt(name: &'static str, value_name: &'static str, help: &'static st pub fn subcommand(name: &'static str) -> App { SubCommand::with_name(name).settings(&[ - AppSettings::UnifiedHelpMessage, AppSettings::DeriveDisplayOrder, AppSettings::DontCollapseArgsInUsage, ]) From f9b28cfbba7465113ea63941b90b485ea7ae7b26 Mon Sep 17 00:00:00 2001 From: Ed Page Date: Wed, 5 Jan 2022 20:01:33 -0600 Subject: [PATCH 06/12] refactor: Resolve App::get_matches_safe deprecation --- src/bin/cargo/cli.rs | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/bin/cargo/cli.rs b/src/bin/cargo/cli.rs index a351ff57978..0c6882f25f0 100644 --- a/src/bin/cargo/cli.rs +++ b/src/bin/cargo/cli.rs @@ -30,7 +30,7 @@ pub fn main(config: &mut Config) -> CliResult { return Ok(()); } - let args = match cli().get_matches_safe() { + let args = match cli().try_get_matches() { Ok(args) => args, Err(e) => { if e.kind == clap::ErrorKind::UnrecognizedSubcommand { @@ -290,7 +290,7 @@ For more information, see issue #10049 Date: Wed, 5 Jan 2022 20:02:37 -0600 Subject: [PATCH 07/12] refactor: Resolve App::usage deprecation --- src/bin/cargo/cli.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/bin/cargo/cli.rs b/src/bin/cargo/cli.rs index 0c6882f25f0..a85026a2b3a 100644 --- a/src/bin/cargo/cli.rs +++ b/src/bin/cargo/cli.rs @@ -416,7 +416,7 @@ fn cli() -> App { // 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) + .override_usage(usage) .template( "\ Rust's package manager From 5cd062e4dc2c29cc75713ce6eafb3248aa1a2062 Mon Sep 17 00:00:00 2001 From: Ed Page Date: Wed, 5 Jan 2022 20:02:51 -0600 Subject: [PATCH 08/12] refactor: Resolve App::template deprecation --- src/bin/cargo/cli.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/bin/cargo/cli.rs b/src/bin/cargo/cli.rs index a85026a2b3a..0f581c16f82 100644 --- a/src/bin/cargo/cli.rs +++ b/src/bin/cargo/cli.rs @@ -417,7 +417,7 @@ fn cli() -> App { // opening clap up to allow us to style our help template .global_setting(AppSettings::DisableColoredHelp) .override_usage(usage) - .template( + .help_template( "\ Rust's package manager From 0ab4d0cbfa72cfb9437e916c3baa071f8c347484 Mon Sep 17 00:00:00 2001 From: Ed Page Date: Wed, 5 Jan 2022 20:03:25 -0600 Subject: [PATCH 09/12] refactor: Resolve App::help deprecation --- src/bin/cargo/commands/git_checkout.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/bin/cargo/commands/git_checkout.rs b/src/bin/cargo/commands/git_checkout.rs index 3cc0701ffa2..a25e4304150 100644 --- a/src/bin/cargo/commands/git_checkout.rs +++ b/src/bin/cargo/commands/git_checkout.rs @@ -6,7 +6,7 @@ pub fn cli() -> App { subcommand("git-checkout") .about("This subcommand has been removed") .settings(&[AppSettings::Hidden]) - .help(REMOVED) + .override_help(REMOVED) } pub fn exec(_config: &mut Config, _args: &ArgMatches) -> CliResult { From 24f301b3e187b8af8975a77cec169c605bc51eb7 Mon Sep 17 00:00:00 2001 From: Ed Page Date: Wed, 5 Jan 2022 20:04:05 -0600 Subject: [PATCH 10/12] refactor: Resolve App::settings deprecation --- src/bin/cargo/cli.rs | 10 +++++----- src/bin/cargo/commands/git_checkout.rs | 2 +- src/cargo/util/command_prelude.rs | 6 ++---- 3 files changed, 8 insertions(+), 10 deletions(-) diff --git a/src/bin/cargo/cli.rs b/src/bin/cargo/cli.rs index 0f581c16f82..4034b9b1aa6 100644 --- a/src/bin/cargo/cli.rs +++ b/src/bin/cargo/cli.rs @@ -408,11 +408,11 @@ fn cli() -> App { "cargo [OPTIONS] [SUBCOMMAND]" }; App::new("cargo") - .settings(&[ - AppSettings::DeriveDisplayOrder, - AppSettings::AllowExternalSubcommands, - AppSettings::NoAutoVersion, - ]) + .setting( + AppSettings::DeriveDisplayOrder + | 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) diff --git a/src/bin/cargo/commands/git_checkout.rs b/src/bin/cargo/commands/git_checkout.rs index a25e4304150..1b9c83771a9 100644 --- a/src/bin/cargo/commands/git_checkout.rs +++ b/src/bin/cargo/commands/git_checkout.rs @@ -5,7 +5,7 @@ const REMOVED: &str = "The `git-checkout` subcommand has been removed."; pub fn cli() -> App { subcommand("git-checkout") .about("This subcommand has been removed") - .settings(&[AppSettings::Hidden]) + .setting(AppSettings::Hidden) .override_help(REMOVED) } diff --git a/src/cargo/util/command_prelude.rs b/src/cargo/util/command_prelude.rs index 0731356ff1c..21cb8076e9c 100644 --- a/src/cargo/util/command_prelude.rs +++ b/src/cargo/util/command_prelude.rs @@ -282,10 +282,8 @@ pub fn multi_opt(name: &'static str, value_name: &'static str, help: &'static st } pub fn subcommand(name: &'static str) -> App { - SubCommand::with_name(name).settings(&[ - AppSettings::DeriveDisplayOrder, - AppSettings::DontCollapseArgsInUsage, - ]) + SubCommand::with_name(name) + .setting(AppSettings::DeriveDisplayOrder | AppSettings::DontCollapseArgsInUsage) } /// Determines whether or not to gate `--profile` as unstable when resolving it. From 6e08a30e268ac0e43b44d683b13752b8333b2d3f Mon Sep 17 00:00:00 2001 From: Ed Page Date: Wed, 5 Jan 2022 20:09:07 -0600 Subject: [PATCH 11/12] refactor: Resolve SubCommand::with_new deprecation --- src/cargo/util/command_prelude.rs | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/src/cargo/util/command_prelude.rs b/src/cargo/util/command_prelude.rs index 21cb8076e9c..b5c10c18937 100644 --- a/src/cargo/util/command_prelude.rs +++ b/src/cargo/util/command_prelude.rs @@ -17,7 +17,6 @@ use crate::util::{ use crate::CargoResult; use anyhow::bail; use cargo_util::paths; -use clap::{self, SubCommand}; use std::ffi::{OsStr, OsString}; use std::path::PathBuf; @@ -282,8 +281,7 @@ pub fn multi_opt(name: &'static str, value_name: &'static str, help: &'static st } pub fn subcommand(name: &'static str) -> App { - SubCommand::with_name(name) - .setting(AppSettings::DeriveDisplayOrder | AppSettings::DontCollapseArgsInUsage) + App::new(name).setting(AppSettings::DeriveDisplayOrder | AppSettings::DontCollapseArgsInUsage) } /// Determines whether or not to gate `--profile` as unstable when resolving it. From 92fa72d48023602952182d9e6e6cc253d74ddc94 Mon Sep 17 00:00:00 2001 From: Ed Page Date: Thu, 6 Jan 2022 09:13:24 -0600 Subject: [PATCH 12/12] refactor: Resolve Arg::multiple deprecation Note: `cargo vendor --sync` did not use `multi_opt` and so it has both multiple occurrences **and** multiple values. If we want to deprecate this, we'll need `unstable-grouped` to be stablized (or pin our clap version) and ensure each group has only 1 value. --- src/bin/cargo/cli.rs | 3 +-- src/bin/cargo/commands/bench.rs | 2 +- src/bin/cargo/commands/install.rs | 6 +++++- src/bin/cargo/commands/run.rs | 6 +++++- 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 | 2 +- src/bin/cargo/commands/uninstall.rs | 2 +- src/bin/cargo/commands/vendor.rs | 3 ++- src/cargo/util/command_prelude.rs | 12 +++--------- 11 files changed, 22 insertions(+), 20 deletions(-) diff --git a/src/bin/cargo/cli.rs b/src/bin/cargo/cli.rs index 4034b9b1aa6..58dcd183ca9 100644 --- a/src/bin/cargo/cli.rs +++ b/src/bin/cargo/cli.rs @@ -479,8 +479,7 @@ See 'cargo help ' for more information on a specific command.\n", .help("Unstable (nightly-only) flags to Cargo, see 'cargo -Z help' for details") .short('Z') .value_name("FLAG") - .multiple(true) - .number_of_values(1) + .multiple_occurrences(true) .global(true), ) .subcommands(commands::builtin()) diff --git a/src/bin/cargo/commands/bench.rs b/src/bin/cargo/commands/bench.rs index d76a7f9dc3d..64a89bdb93a 100644 --- a/src/bin/cargo/commands/bench.rs +++ b/src/bin/cargo/commands/bench.rs @@ -13,7 +13,7 @@ pub fn cli() -> App { .arg( Arg::new("args") .help("Arguments for the bench binary") - .multiple(true) + .multiple_values(true) .last(true), ) .arg_targets_all( diff --git a/src/bin/cargo/commands/install.rs b/src/bin/cargo/commands/install.rs index 5cfa5e32005..621558d97c4 100644 --- a/src/bin/cargo/commands/install.rs +++ b/src/bin/cargo/commands/install.rs @@ -8,7 +8,11 @@ pub fn cli() -> App { subcommand("install") .about("Install a Rust binary. Default location is $HOME/.cargo/bin") .arg_quiet() - .arg(Arg::new("crate").forbid_empty_values(true).multiple(true)) + .arg( + Arg::new("crate") + .forbid_empty_values(true) + .multiple_values(true), + ) .arg( opt("version", "Specify a version to install") .alias("vers") diff --git a/src/bin/cargo/commands/run.rs b/src/bin/cargo/commands/run.rs index 797837f24fd..d90399dd8a8 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::new("args").allow_invalid_utf8(true).multiple(true)) + .arg( + Arg::new("args") + .allow_invalid_utf8(true) + .multiple_values(true), + ) .arg_targets_bin_example( "Name of the bin target to run", "Name of the example target to run", diff --git a/src/bin/cargo/commands/rustc.rs b/src/bin/cargo/commands/rustc.rs index d7015358788..c9291d4f02e 100644 --- a/src/bin/cargo/commands/rustc.rs +++ b/src/bin/cargo/commands/rustc.rs @@ -10,7 +10,7 @@ pub fn cli() -> App { .setting(AppSettings::TrailingVarArg) .about("Compile a package, and pass extra options to the compiler") .arg_quiet() - .arg(Arg::new("args").multiple(true).help("Rustc flags")) + .arg(Arg::new("args").multiple_values(true).help("Rustc flags")) .arg_package("Package to build") .arg_jobs() .arg_targets_all( diff --git a/src/bin/cargo/commands/rustdoc.rs b/src/bin/cargo/commands/rustdoc.rs index 8fc5078486a..3f5d07d9d2b 100644 --- a/src/bin/cargo/commands/rustdoc.rs +++ b/src/bin/cargo/commands/rustdoc.rs @@ -7,7 +7,7 @@ pub fn cli() -> App { .setting(AppSettings::TrailingVarArg) .about("Build a package's documentation, using specified custom flags.") .arg_quiet() - .arg(Arg::new("args").multiple(true)) + .arg(Arg::new("args").multiple_values(true)) .arg(opt( "open", "Opens the docs in a browser after the operation", diff --git a/src/bin/cargo/commands/search.rs b/src/bin/cargo/commands/search.rs index 003e1d848ae..14d6fba3b54 100644 --- a/src/bin/cargo/commands/search.rs +++ b/src/bin/cargo/commands/search.rs @@ -8,7 +8,7 @@ pub fn cli() -> App { subcommand("search") .about("Search packages in crates.io") .arg_quiet() - .arg(Arg::new("query").multiple(true)) + .arg(Arg::new("query").multiple_values(true)) .arg_index() .arg( opt( diff --git a/src/bin/cargo/commands/test.rs b/src/bin/cargo/commands/test.rs index caedb47aa2e..25b949dcfb9 100644 --- a/src/bin/cargo/commands/test.rs +++ b/src/bin/cargo/commands/test.rs @@ -15,7 +15,7 @@ pub fn cli() -> App { .arg( Arg::new("args") .help("Arguments for the test binary") - .multiple(true) + .multiple_values(true) .last(true), ) .arg( diff --git a/src/bin/cargo/commands/uninstall.rs b/src/bin/cargo/commands/uninstall.rs index 7f6e3829bb3..eaec9ecc3f6 100644 --- a/src/bin/cargo/commands/uninstall.rs +++ b/src/bin/cargo/commands/uninstall.rs @@ -6,7 +6,7 @@ pub fn cli() -> App { subcommand("uninstall") .about("Remove a Rust binary") .arg_quiet() - .arg(Arg::new("spec").multiple(true)) + .arg(Arg::new("spec").multiple_values(true)) .arg_package_spec_simple("Package to uninstall") .arg(multi_opt("bin", "NAME", "Only uninstall the binary NAME")) .arg(opt("root", "Directory to uninstall packages from").value_name("DIR")) diff --git a/src/bin/cargo/commands/vendor.rs b/src/bin/cargo/commands/vendor.rs index 5bcec7aad94..697c235412c 100644 --- a/src/bin/cargo/commands/vendor.rs +++ b/src/bin/cargo/commands/vendor.rs @@ -24,7 +24,8 @@ pub fn cli() -> App { .help("Additional `Cargo.toml` to sync and vendor") .value_name("TOML") .allow_invalid_utf8(true) - .multiple(true), + .multiple_occurrences(true) + .multiple_values(true), ) .arg( Arg::new("respect-source-config") diff --git a/src/cargo/util/command_prelude.rs b/src/cargo/util/command_prelude.rs index b5c10c18937..c1ed561de00 100644 --- a/src/cargo/util/command_prelude.rs +++ b/src/cargo/util/command_prelude.rs @@ -1,5 +1,3 @@ -#![allow(deprecated)] - use crate::core::compiler::{BuildConfig, MessageFormat}; use crate::core::resolver::CliFeatures; use crate::core::{Edition, Workspace}; @@ -264,20 +262,16 @@ pub fn optional_multi_opt( ) -> Arg<'static> { opt(name, help) .value_name(value_name) - .multiple(true) + .multiple_occurrences(true) + .multiple_values(true) .min_values(0) .number_of_values(1) } 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"]. - // `number_of_values` should become the default in clap 3. opt(name, help) .value_name(value_name) - .multiple(true) - .number_of_values(1) + .multiple_occurrences(true) } pub fn subcommand(name: &'static str) -> App {