Update behavior to pass-through simple aliases

This changes the behavior so that simple aliases that directly alias a
subcommand (with no arguments) pass-through to that subcommand, while
complex aliases (with arguments) show the alias.

So for example, `cargo help b` will show the manpage for `cargo-build`,
while `cargo help my-alias`, aliased to `build --release`, will show
"`my-alias` is aliased to `build --release`".
This commit is contained in:
Sean Stangl 2021-12-12 10:00:23 -07:00
parent 8a1af7014a
commit 6df4b1ef71
2 changed files with 26 additions and 16 deletions

View File

@ -15,14 +15,14 @@ const COMPRESSED_MAN: &[u8] = include_bytes!(concat!(env!("OUT_DIR"), "/man.tgz"
/// This runs before clap processing, because it needs to intercept the `help` /// This runs before clap processing, because it needs to intercept the `help`
/// command if a man page is available. /// command if a man page is available.
/// ///
/// Returns `true` if a man page was displayed. In this case, Cargo should /// Returns `true` if help information was successfully displayed to the user.
/// exit. /// In this case, Cargo should exit.
pub fn handle_embedded_help(config: &Config) -> bool { pub fn handle_embedded_help(config: &Config) -> bool {
match try_help(config) { match try_help(config) {
Ok(true) => true, Ok(true) => true,
Ok(false) => false, Ok(false) => false,
Err(e) => { Err(e) => {
log::warn!("man failed: {:?}", e); log::warn!("help failed: {:?}", e);
false false
} }
} }
@ -47,18 +47,23 @@ fn try_help(config: &Config) -> CargoResult<bool> {
None => return Ok(false), None => return Ok(false),
}; };
// Check if this is an alias. If so, just display the alias information. let subcommand = match check_alias(config, subcommand) {
if let Some(argv) = check_alias(config, subcommand) { // If this alias is more than a simple subcommand pass-through, show the alias.
let alias = argv.join(" "); Some(argv) if argv.len() > 1 => {
drop_println!(config, "'{}' is aliased to '{}'", subcommand, alias); let alias = argv.join(" ");
return Ok(true); drop_println!(config, "`{}` is aliased to `{}`", subcommand, alias);
} return Ok(true);
}
// Otherwise, resolve the alias into its subcommand.
Some(argv) => argv[0].clone(),
None => subcommand.to_string(),
};
// If not an alias, this should be a built-in subcommand. let subcommand = match check_builtin(&subcommand) {
let subcommand = match check_builtin(subcommand) {
Some(s) => s, Some(s) => s,
None => return Ok(false), None => return Ok(false),
}; };
if resolve_executable(Path::new("man")).is_ok() { if resolve_executable(Path::new("man")).is_ok() {
let man = match extract_man(&subcommand, "1") { let man = match extract_man(&subcommand, "1") {
Some(man) => man, Some(man) => man,

View File

@ -138,8 +138,7 @@ fn help_man() {
#[cargo_test] #[cargo_test]
fn help_alias() { fn help_alias() {
// Check that `help some_alias` will resolve. // Check that `help some_alias` will resolve.
let out = help_with_stdout_and_path("b", Path::new("")); help_with_man_and_path("", "b", "build", Path::new(""));
assert_eq!(out, "'b' is aliased to 'build'\n");
let config = paths::root().join(".cargo/config"); let config = paths::root().join(".cargo/config");
fs::create_dir_all(config.parent().unwrap()).unwrap(); fs::create_dir_all(config.parent().unwrap()).unwrap();
@ -147,12 +146,18 @@ fn help_alias() {
config, config,
r#" r#"
[alias] [alias]
my-alias = ["build", "--release"] simple-alias = ["build"]
complex-alias = ["build", "--release"]
"#, "#,
) )
.unwrap(); .unwrap();
let out = help_with_stdout_and_path("my-alias", Path::new(""));
assert_eq!(out, "'my-alias' is aliased to 'build --release'\n"); // Because `simple-alias` aliases a subcommand with no arguments, help shows the manpage.
help_with_man_and_path("", "simple-alias", "build", Path::new(""));
// Help for `complex-alias` displays the full alias command.
let out = help_with_stdout_and_path("complex-alias", Path::new(""));
assert_eq!(out, "`complex-alias` is aliased to `build --release`\n");
} }
#[cargo_test] #[cargo_test]