use cargo::sources::{GitSource, RegistrySource};
use self::utils::*;
+use std::collections::BTreeSet;
+use std::env;
+use std::fs;
+use search_directories;
+use is_executable;
pub fn do_main(config: &mut Config) -> CliResult {
let args = cli().get_matches();
+ let is_verbose = args.occurrences_of("verbose") > 0;
if args.is_present("version") {
let version = cargo::version();
println!("{}", version);
- if args.occurrences_of("verbose") > 0 {
+ if is_verbose {
println!("release: {}.{}.{}",
version.major,
version.minor,
return Ok(());
}
+ if args.is_present("list") {
+ println!("Installed Commands:");
+ for command in list_commands(config) {
+ let (command, path) = command;
+ if is_verbose {
+ match path {
+ Some(p) => println!(" {:<20} {}", command, p),
+ None => println!(" {:<20}", command),
+ }
+ } else {
+ println!(" {}", command);
+ }
+ }
+ return Ok(());
+ }
+
execte_subcommand(config, args)
}
See 'cargo help <command>' for more information on a specific command.
")
- .subcommands(vec![
- bench::cli(),
- build::cli(),
- check::cli(),
- clean::cli(),
- doc::cli(),
- fetch::cli(),
- generate_lockfile::cli(),
- git_checkout::cli(),
- init::cli(),
- install::cli(),
- locate_project::cli(),
- login::cli(),
- metadata::cli(),
- new::cli(),
- owner::cli(),
- package::cli(),
- pkgid::cli(),
- publish::cli(),
- read_manifest::cli(),
- run::cli(),
- rustc::cli(),
- rustdoc::cli(),
- search::cli(),
- test::cli(),
- uninstall::cli(),
- update::cli(),
- verify_project::cli(),
- version::cli(),
- yank::cli(),
- ])
+ .subcommands(builtin_subcommands())
;
app
}
+fn builtin_subcommands() -> Vec<App> {
+ vec![
+ bench::cli(),
+ build::cli(),
+ check::cli(),
+ clean::cli(),
+ doc::cli(),
+ fetch::cli(),
+ generate_lockfile::cli(),
+ git_checkout::cli(),
+ init::cli(),
+ install::cli(),
+ locate_project::cli(),
+ login::cli(),
+ metadata::cli(),
+ new::cli(),
+ owner::cli(),
+ package::cli(),
+ pkgid::cli(),
+ publish::cli(),
+ read_manifest::cli(),
+ run::cli(),
+ rustc::cli(),
+ rustdoc::cli(),
+ search::cli(),
+ test::cli(),
+ uninstall::cli(),
+ update::cli(),
+ verify_project::cli(),
+ version::cli(),
+ yank::cli(),
+ ]
+}
+
+/// List all runnable commands
+fn list_commands(config: &Config) -> BTreeSet<(String, Option<String>)> {
+ let prefix = "cargo-";
+ let suffix = env::consts::EXE_SUFFIX;
+ let mut commands = BTreeSet::new();
+ for dir in search_directories(config) {
+ let entries = match fs::read_dir(dir) {
+ Ok(entries) => entries,
+ _ => continue,
+ };
+ for entry in entries.filter_map(|e| e.ok()) {
+ let path = entry.path();
+ let filename = match path.file_name().and_then(|s| s.to_str()) {
+ Some(filename) => filename,
+ _ => continue,
+ };
+ if !filename.starts_with(prefix) || !filename.ends_with(suffix) {
+ continue;
+ }
+ if is_executable(entry.path()) {
+ let end = filename.len() - suffix.len();
+ commands.insert(
+ (filename[prefix.len()..end].to_string(),
+ Some(path.display().to_string()))
+ );
+ }
+ }
+ }
+
+ for cmd in builtin_subcommands() {
+ commands.insert((cmd.get_name().to_string(), None));
+ }
+
+ commands
+}
+
+
mod bench;
mod build;
mod check;
}
#[test]
-#[ignore]
fn list_command_looks_at_path() {
let proj = project("list-non-overlapping").build();
let proj = fake_file(proj, Path::new("path-test"), "cargo-1", &FakeKind::Executable);
// windows and symlinks don't currently agree that well
#[cfg(unix)]
#[test]
-#[ignore]
fn list_command_resolves_symlinks() {
use cargotest::support::cargo_exe;
}
#[test]
-#[ignore]
fn find_closest_biuld_to_build() {
let mut pr = cargo_process();
pr.arg("biuld");
assert_that(pr,
- execs().with_status(101)
- .with_stderr("[ERROR] no such subcommand: `biuld`
+ execs().with_status(1)
+ .with_stderr("\
+error: The subcommand 'biuld' wasn't recognized
+<tab>Did you mean 'build'?
-<tab>Did you mean `build`?
+If you believe you received this message in error, try re-running with 'cargo -- biuld'
-"));
+USAGE:
+ cargo [OPTIONS] [SUBCOMMAND]
+
+For more information try --help"));
}
// if a subcommand is more than 3 edit distance away, we don't make a suggestion
#[test]
-#[ignore]
fn find_closest_dont_correct_nonsense() {
let mut pr = cargo_process();
pr.arg("there-is-no-way-that-there-is-a-command-close-to-this")
}
#[test]
-#[ignore]
fn displays_subcommand_on_error() {
let mut pr = cargo_process();
pr.arg("invalid-command");