|
1 | 1 | use anyhow::{anyhow, Context as _};
|
2 | 2 | use cargo::core::shell::Shell;
|
3 | 3 | use cargo::core::{features, CliUnstable};
|
4 |
| -use cargo::{self, drop_print, drop_println, CliResult, Config}; |
| 4 | +use cargo::{self, drop_print, drop_println, CargoResult, CliResult, Config}; |
5 | 5 | use clap::{Arg, ArgMatches};
|
6 | 6 | use itertools::Itertools;
|
7 | 7 | use std::collections::HashMap;
|
@@ -175,10 +175,11 @@ Run with 'cargo -Z [FLAG] [COMMAND]'",
|
175 | 175 | return Ok(());
|
176 | 176 | }
|
177 | 177 | };
|
178 |
| - config_configure(config, &expanded_args, subcommand_args, global_args)?; |
| 178 | + let exec = Exec::infer(cmd)?; |
| 179 | + config_configure(config, &expanded_args, subcommand_args, global_args, &exec)?; |
179 | 180 | super::init_git(config);
|
180 | 181 |
|
181 |
| - execute_subcommand(config, cmd, subcommand_args) |
| 182 | + exec.exec(config, subcommand_args) |
182 | 183 | }
|
183 | 184 |
|
184 | 185 | pub fn get_version_string(is_verbose: bool) -> String {
|
@@ -363,12 +364,26 @@ fn config_configure(
|
363 | 364 | args: &ArgMatches,
|
364 | 365 | subcommand_args: &ArgMatches,
|
365 | 366 | global_args: GlobalArgs,
|
| 367 | + exec: &Exec, |
366 | 368 | ) -> CliResult {
|
367 | 369 | let arg_target_dir = &subcommand_args.value_of_path("target-dir", config);
|
368 |
| - let verbose = global_args.verbose + args.verbose(); |
| 370 | + let mut verbose = global_args.verbose + args.verbose(); |
369 | 371 | // quiet is unusual because it is redefined in some subcommands in order
|
370 | 372 | // to provide custom help text.
|
371 |
| - let quiet = args.flag("quiet") || subcommand_args.flag("quiet") || global_args.quiet; |
| 373 | + let mut quiet = args.flag("quiet") || subcommand_args.flag("quiet") || global_args.quiet; |
| 374 | + if matches!(exec, Exec::Manifest(_)) && !quiet { |
| 375 | + // Verbosity is shifted quieter for `Exec::Manifest` as it is can be used as if you ran |
| 376 | + // `cargo install` and we especially shouldn't pollute programmatic output. |
| 377 | + // |
| 378 | + // For now, interactive output has the same default output as `cargo run` but that is |
| 379 | + // subject to change. |
| 380 | + if let Some(lower) = verbose.checked_sub(1) { |
| 381 | + verbose = lower; |
| 382 | + } else if !config.shell().is_err_tty() { |
| 383 | + // Don't pollute potentially-scripted output |
| 384 | + quiet = true; |
| 385 | + } |
| 386 | + } |
372 | 387 | let global_color = global_args.color; // Extract so it can take reference.
|
373 | 388 | let color = args
|
374 | 389 | .get_one::<String>("color")
|
@@ -399,53 +414,64 @@ fn config_configure(
|
399 | 414 | Ok(())
|
400 | 415 | }
|
401 | 416 |
|
402 |
| -/// Precedence isn't the most obvious from this function because |
403 |
| -/// - Some is determined by `expand_aliases` |
404 |
| -/// - Some is enforced by `avoid_ambiguity_between_builtins_and_manifest_commands` |
405 |
| -/// |
406 |
| -/// In actuality, it is: |
407 |
| -/// 1. built-ins xor manifest-command |
408 |
| -/// 2. aliases |
409 |
| -/// 3. external subcommands |
410 |
| -fn execute_subcommand(config: &mut Config, cmd: &str, subcommand_args: &ArgMatches) -> CliResult { |
411 |
| - if let Some(exec) = commands::builtin_exec(cmd) { |
412 |
| - return exec(config, subcommand_args); |
| 417 | +enum Exec { |
| 418 | + Builtin(commands::Exec), |
| 419 | + Manifest(String), |
| 420 | + External(String), |
| 421 | +} |
| 422 | + |
| 423 | +impl Exec { |
| 424 | + /// Precedence isn't the most obvious from this function because |
| 425 | + /// - Some is determined by `expand_aliases` |
| 426 | + /// - Some is enforced by `avoid_ambiguity_between_builtins_and_manifest_commands` |
| 427 | + /// |
| 428 | + /// In actuality, it is: |
| 429 | + /// 1. built-ins xor manifest-command |
| 430 | + /// 2. aliases |
| 431 | + /// 3. external subcommands |
| 432 | + fn infer(cmd: &str) -> CargoResult<Self> { |
| 433 | + if let Some(exec) = commands::builtin_exec(cmd) { |
| 434 | + Ok(Self::Builtin(exec)) |
| 435 | + } else if commands::run::is_manifest_command(cmd) { |
| 436 | + Ok(Self::Manifest(cmd.to_owned())) |
| 437 | + } else { |
| 438 | + Ok(Self::External(cmd.to_owned())) |
| 439 | + } |
413 | 440 | }
|
414 | 441 |
|
415 |
| - if commands::run::is_manifest_command(cmd) { |
416 |
| - let ext_path = super::find_external_subcommand(config, cmd); |
417 |
| - if !config.cli_unstable().script && ext_path.is_some() { |
418 |
| - config.shell().warn(format_args!( |
419 |
| - "\ |
| 442 | + fn exec(self, config: &mut Config, subcommand_args: &ArgMatches) -> CliResult { |
| 443 | + match self { |
| 444 | + Self::Builtin(exec) => exec(config, subcommand_args), |
| 445 | + Self::Manifest(cmd) => { |
| 446 | + let ext_path = super::find_external_subcommand(config, &cmd); |
| 447 | + if !config.cli_unstable().script && ext_path.is_some() { |
| 448 | + config.shell().warn(format_args!( |
| 449 | + "\ |
420 | 450 | external subcommand `{cmd}` has the appearance of a manfiest-command
|
421 | 451 | This was previously accepted but will be phased out when `-Zscript` is stabilized.
|
422 | 452 | For more information, see issue #12207 <https://github.com/rust-lang/cargo/issues/12207>.",
|
423 |
| - ))?; |
424 |
| - let mut ext_args = vec![OsStr::new(cmd)]; |
425 |
| - ext_args.extend( |
426 |
| - subcommand_args |
427 |
| - .get_many::<OsString>("") |
428 |
| - .unwrap_or_default() |
429 |
| - .map(OsString::as_os_str), |
430 |
| - ); |
431 |
| - super::execute_external_subcommand(config, cmd, &ext_args) |
432 |
| - } else { |
433 |
| - let ext_args: Vec<OsString> = subcommand_args |
434 |
| - .get_many::<OsString>("") |
435 |
| - .unwrap_or_default() |
436 |
| - .cloned() |
437 |
| - .collect(); |
438 |
| - commands::run::exec_manifest_command(config, cmd, &ext_args) |
| 453 | + ))?; |
| 454 | + Self::External(cmd).exec(config, subcommand_args) |
| 455 | + } else { |
| 456 | + let ext_args: Vec<OsString> = subcommand_args |
| 457 | + .get_many::<OsString>("") |
| 458 | + .unwrap_or_default() |
| 459 | + .cloned() |
| 460 | + .collect(); |
| 461 | + commands::run::exec_manifest_command(config, &cmd, &ext_args) |
| 462 | + } |
| 463 | + } |
| 464 | + Self::External(cmd) => { |
| 465 | + let mut ext_args = vec![OsStr::new(&cmd)]; |
| 466 | + ext_args.extend( |
| 467 | + subcommand_args |
| 468 | + .get_many::<OsString>("") |
| 469 | + .unwrap_or_default() |
| 470 | + .map(OsString::as_os_str), |
| 471 | + ); |
| 472 | + super::execute_external_subcommand(config, &cmd, &ext_args) |
| 473 | + } |
439 | 474 | }
|
440 |
| - } else { |
441 |
| - let mut ext_args = vec![OsStr::new(cmd)]; |
442 |
| - ext_args.extend( |
443 |
| - subcommand_args |
444 |
| - .get_many::<OsString>("") |
445 |
| - .unwrap_or_default() |
446 |
| - .map(OsString::as_os_str), |
447 |
| - ); |
448 |
| - super::execute_external_subcommand(config, cmd, &ext_args) |
449 | 475 | }
|
450 | 476 | }
|
451 | 477 |
|
|
0 commit comments