mirror of
https://github.com/rust-lang/cargo
synced 2024-10-14 03:32:39 +00:00
Add 'did you mean...' message when a subcommand is not found.
This commit is contained in:
parent
537b43c2b5
commit
12f5de8e9b
|
@ -133,11 +133,31 @@ fn execute(flags: Flags, shell: &mut MultiShell) -> CliResult<Option<()>> {
|
||||||
Ok(None)
|
Ok(None)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fn find_closest(cmd: &str) -> Option<String> {
|
||||||
|
match list_commands().iter()
|
||||||
|
// doing it this way (instead of just .min_by(|c| c.lev_distance(cmd)))
|
||||||
|
// allows us to only make suggestions that have an edit distance of
|
||||||
|
// 3 or less
|
||||||
|
.map(|c| (c.lev_distance(cmd), c))
|
||||||
|
.filter(|&(d, _): &(uint, &String)| d < 4u)
|
||||||
|
.min_by(|&(d, _)| d) {
|
||||||
|
Some((_, c)) => {
|
||||||
|
Some(c.to_string())
|
||||||
|
},
|
||||||
|
None => None
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
fn execute_subcommand(cmd: &str, args: &[String], shell: &mut MultiShell) {
|
fn execute_subcommand(cmd: &str, args: &[String], shell: &mut MultiShell) {
|
||||||
let command = match find_command(cmd) {
|
let command = match find_command(cmd) {
|
||||||
Some(command) => command,
|
Some(command) => command,
|
||||||
None => return handle_error(CliError::new("No such subcommand", 127),
|
None => {
|
||||||
shell)
|
let msg = match find_closest(cmd) {
|
||||||
|
Some(closest) => format!("No such subcommand\n\n\tDid you mean ``{}''?\n", closest),
|
||||||
|
None => "No such subcommand".to_string()
|
||||||
|
};
|
||||||
|
return handle_error(CliError::new(msg, 127), shell)
|
||||||
|
}
|
||||||
};
|
};
|
||||||
let status = Command::new(command)
|
let status = Command::new(command)
|
||||||
.args(args)
|
.args(args)
|
||||||
|
|
|
@ -5,7 +5,8 @@ use std::str;
|
||||||
use cargo::util::process;
|
use cargo::util::process;
|
||||||
|
|
||||||
use support::paths;
|
use support::paths;
|
||||||
use support::{project, cargo_dir, mkdir_recursive, ProjectBuilder, ResultTest};
|
use support::{execs, project, cargo_dir, mkdir_recursive, ProjectBuilder, ResultTest};
|
||||||
|
use hamcrest::{assert_that};
|
||||||
|
|
||||||
fn setup() {
|
fn setup() {
|
||||||
}
|
}
|
||||||
|
@ -44,3 +45,30 @@ test!(list_commands_looks_at_path {
|
||||||
let output = str::from_utf8(output.output.as_slice()).assert();
|
let output = str::from_utf8(output.output.as_slice()).assert();
|
||||||
assert!(output.contains("\n 1\n"), "missing 1: {}", output);
|
assert!(output.contains("\n 1\n"), "missing 1: {}", output);
|
||||||
})
|
})
|
||||||
|
|
||||||
|
test!(find_closest_biuld_to_build {
|
||||||
|
let pr = process(cargo_dir().join("cargo"))
|
||||||
|
.arg("biuld").cwd(paths::root())
|
||||||
|
.env("HOME", Some(paths::home()));
|
||||||
|
|
||||||
|
assert_that(pr,
|
||||||
|
execs().with_status(127)
|
||||||
|
.with_stderr("No such subcommand
|
||||||
|
|
||||||
|
Did you mean ``build''?
|
||||||
|
|
||||||
|
"));
|
||||||
|
})
|
||||||
|
|
||||||
|
// if a subcommand is more than 3 edit distance away, we don't make a suggestion
|
||||||
|
test!(find_closest_dont_correct_nonsense {
|
||||||
|
let pr = process(cargo_dir().join("cargo"))
|
||||||
|
.arg("asdf").cwd(paths::root())
|
||||||
|
.env("HOME", Some(paths::home()));
|
||||||
|
|
||||||
|
assert_that(pr,
|
||||||
|
execs().with_status(127)
|
||||||
|
.with_stderr("No such subcommand
|
||||||
|
"));
|
||||||
|
})
|
||||||
|
|
||||||
|
|
Loading…
Reference in a new issue