Skip to content

Commit 215e4da

Browse files
committed
refactor(cli): Decouple exec lookup from doing it
1 parent ac78f60 commit 215e4da

File tree

2 files changed

+58
-44
lines changed

2 files changed

+58
-44
lines changed

src/bin/cargo/cli.rs

Lines changed: 55 additions & 43 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
use anyhow::{anyhow, Context as _};
22
use cargo::core::shell::Shell;
33
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};
55
use clap::{Arg, ArgMatches};
66
use itertools::Itertools;
77
use std::collections::HashMap;
@@ -178,7 +178,8 @@ Run with 'cargo -Z [FLAG] [COMMAND]'",
178178
config_configure(config, &expanded_args, subcommand_args, global_args)?;
179179
super::init_git(config);
180180

181-
execute_subcommand(config, cmd, subcommand_args)
181+
let exec = Exec::infer(cmd)?;
182+
exec.exec(config, subcommand_args)
182183
}
183184

184185
pub fn get_version_string(is_verbose: bool) -> String {
@@ -399,53 +400,64 @@ fn config_configure(
399400
Ok(())
400401
}
401402

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);
403+
enum Exec {
404+
Builtin(commands::Exec),
405+
Manifest(String),
406+
External(String),
407+
}
408+
409+
impl Exec {
410+
/// Precedence isn't the most obvious from this function because
411+
/// - Some is determined by `expand_aliases`
412+
/// - Some is enforced by `avoid_ambiguity_between_builtins_and_manifest_commands`
413+
///
414+
/// In actuality, it is:
415+
/// 1. built-ins xor manifest-command
416+
/// 2. aliases
417+
/// 3. external subcommands
418+
fn infer(cmd: &str) -> CargoResult<Self> {
419+
if let Some(exec) = commands::builtin_exec(cmd) {
420+
Ok(Self::Builtin(exec))
421+
} else if commands::run::is_manifest_command(cmd) {
422+
Ok(Self::Manifest(cmd.to_owned()))
423+
} else {
424+
Ok(Self::External(cmd.to_owned()))
425+
}
413426
}
414427

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-
"\
428+
fn exec(self, config: &mut Config, subcommand_args: &ArgMatches) -> CliResult {
429+
match self {
430+
Self::Builtin(exec) => exec(config, subcommand_args),
431+
Self::Manifest(cmd) => {
432+
let ext_path = super::find_external_subcommand(config, &cmd);
433+
if !config.cli_unstable().script && ext_path.is_some() {
434+
config.shell().warn(format_args!(
435+
"\
420436
external subcommand `{cmd}` has the appearance of a manfiest-command
421437
This was previously accepted but will be phased out when `-Zscript` is stabilized.
422438
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)
439+
))?;
440+
Self::External(cmd).exec(config, subcommand_args)
441+
} else {
442+
let ext_args: Vec<OsString> = subcommand_args
443+
.get_many::<OsString>("")
444+
.unwrap_or_default()
445+
.cloned()
446+
.collect();
447+
commands::run::exec_manifest_command(config, &cmd, &ext_args)
448+
}
449+
}
450+
Self::External(cmd) => {
451+
let mut ext_args = vec![OsStr::new(&cmd)];
452+
ext_args.extend(
453+
subcommand_args
454+
.get_many::<OsString>("")
455+
.unwrap_or_default()
456+
.map(OsString::as_os_str),
457+
);
458+
super::execute_external_subcommand(config, &cmd, &ext_args)
459+
}
439460
}
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)
449461
}
450462
}
451463

src/bin/cargo/commands/mod.rs

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -43,7 +43,9 @@ pub fn builtin() -> Vec<Command> {
4343
]
4444
}
4545

46-
pub fn builtin_exec(cmd: &str) -> Option<fn(&mut Config, &ArgMatches) -> CliResult> {
46+
pub type Exec = fn(&mut Config, &ArgMatches) -> CliResult;
47+
48+
pub fn builtin_exec(cmd: &str) -> Option<Exec> {
4749
let f = match cmd {
4850
"add" => add::exec,
4951
"bench" => bench::exec,

0 commit comments

Comments
 (0)