feat(cli): Define precedence among subcommands

I decided to start things off fairly simple.  It either looks like the user is
specifying a manifest or they aren't.  This is assuming we only need to
handle `cargo foo.rs` and `cargo ./foo.rs` and not `cargo foo`.
I think in most shebang cases, path multiple components will present which makes
that a dead giveaway and likely to not overlap with aliases and
subcommands.

For reference, dlang's dub goes a lot further
1. Checks for the subcommand name being `-`
2. Checks if subcommand name ends with `.d`
3. Checks if subcommand name is built-in
4. Checks if a file with the subcommand name exists
5. Checks if a file with the subcommand name + `.d` exists

This would allow a `run.d` to override `dub-run` which doesn't seem
good.
This commit is contained in:
Ed Page 2023-06-07 16:11:50 -05:00
parent b2b4d9771f
commit 1a30fc8319

View File

@ -305,6 +305,9 @@ For more information, see issue #10049 <https://github.com/rust-lang/cargo/issue
))?;
}
}
if commands::run::is_manifest_command(cmd) {
return Ok((args, GlobalArgs::default()));
}
let mut alias = alias
.into_iter()
@ -387,6 +390,14 @@ fn config_configure(
Ok(())
}
/// Precedence isn't the most obvious from this function because
/// - Some is determined by `expand_aliases`
/// - Some is enforced by `avoid_ambiguity_between_builtins_and_manifest_commands`
///
/// In actuality, it is:
/// 1. built-ins xor manifest-command
/// 2. aliases
/// 3. external subcommands
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);
@ -579,3 +590,14 @@ impl LazyConfig {
fn verify_cli() {
cli().debug_assert();
}
#[test]
fn avoid_ambiguity_between_builtins_and_manifest_commands() {
for cmd in commands::builtin() {
let name = cmd.get_name();
assert!(
!commands::run::is_manifest_command(&name),
"built-in command {name} is ambiguous with manifest-commands"
)
}
}