Skip to content

Commit dab09a0

Browse files
committed
Auto merge of #5807 - dwijnand:cargo-list-summary, r=alexcrichton
Show the command summary when running cargo --list Fixes #3726
2 parents 5a5bbc2 + cd55e04 commit dab09a0

File tree

5 files changed

+64
-17
lines changed

5 files changed

+64
-17
lines changed

src/bin/cargo/cli.rs

Lines changed: 12 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -69,14 +69,19 @@ Run with 'cargo -Z [FLAG] [SUBCOMMAND]'"
6969
if args.is_present("list") {
7070
println!("Installed Commands:");
7171
for command in list_commands(config) {
72-
let (command, path) = command;
73-
if is_verbose {
74-
match path {
75-
Some(p) => println!(" {:<20} {}", command, p),
76-
None => println!(" {:<20}", command),
72+
match command {
73+
CommandInfo::BuiltIn { name, about } => {
74+
let summary = about.unwrap_or_default();
75+
let summary = summary.lines().next().unwrap_or(&summary); // display only the first line
76+
println!(" {:<20} {}", name, summary)
77+
}
78+
CommandInfo::External { name, path } => {
79+
if is_verbose {
80+
println!(" {:<20} {}", name, path.display())
81+
} else {
82+
println!(" {}", name)
83+
}
7784
}
78-
} else {
79-
println!(" {}", command);
8085
}
8186
}
8287
return Ok(());

src/bin/cargo/command_prelude.rs

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -411,3 +411,18 @@ pub fn values(args: &ArgMatches, name: &str) -> Vec<String> {
411411
.map(|s| s.to_string())
412412
.collect()
413413
}
414+
415+
#[derive(PartialEq, PartialOrd, Eq, Ord)]
416+
pub enum CommandInfo {
417+
BuiltIn { name: String, about: Option<String>, },
418+
External { name: String, path: PathBuf },
419+
}
420+
421+
impl CommandInfo {
422+
pub fn name(&self) -> String {
423+
match self {
424+
CommandInfo::BuiltIn { name, .. } => name.to_string(),
425+
CommandInfo::External { name, .. } => name.to_string(),
426+
}
427+
}
428+
}

src/bin/cargo/commands/read_manifest.rs

Lines changed: 5 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -5,8 +5,11 @@ use cargo::print_json;
55
pub fn cli() -> App {
66
subcommand("read-manifest")
77
.about(
8-
"Deprecated, use `cargo metadata --no-deps` instead.
9-
Print a JSON representation of a Cargo.toml manifest.",
8+
"\
9+
Print a JSON representation of a Cargo.toml manifest.
10+
11+
Deprecated, use `cargo metadata --no-deps` instead.\
12+
",
1013
)
1114
.arg_manifest_path()
1215
}

src/bin/cargo/main.rs

Lines changed: 13 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -26,6 +26,8 @@ mod cli;
2626
mod command_prelude;
2727
mod commands;
2828

29+
use command_prelude::*;
30+
2931
fn main() {
3032
env_logger::init();
3133
cargo::core::maybe_allow_nightly_features();
@@ -81,7 +83,7 @@ fn aliased_command(config: &Config, command: &str) -> CargoResult<Option<Vec<Str
8183
}
8284

8385
/// List all runnable commands
84-
fn list_commands(config: &Config) -> BTreeSet<(String, Option<String>)> {
86+
fn list_commands(config: &Config) -> BTreeSet<CommandInfo> {
8587
let prefix = "cargo-";
8688
let suffix = env::consts::EXE_SUFFIX;
8789
let mut commands = BTreeSet::new();
@@ -101,16 +103,19 @@ fn list_commands(config: &Config) -> BTreeSet<(String, Option<String>)> {
101103
}
102104
if is_executable(entry.path()) {
103105
let end = filename.len() - suffix.len();
104-
commands.insert((
105-
filename[prefix.len()..end].to_string(),
106-
Some(path.display().to_string()),
107-
));
106+
commands.insert(CommandInfo::External {
107+
name: filename[prefix.len()..end].to_string(),
108+
path: path.clone(),
109+
});
108110
}
109111
}
110112
}
111113

112114
for cmd in commands::builtin() {
113-
commands.insert((cmd.get_name().to_string(), None));
115+
commands.insert(CommandInfo::BuiltIn {
116+
name: cmd.get_name().to_string(),
117+
about: cmd.p.meta.about.map(|s| s.to_string()),
118+
});
114119
}
115120

116121
commands
@@ -121,7 +126,8 @@ fn find_closest(config: &Config, cmd: &str) -> Option<String> {
121126
// Only consider candidates with a lev_distance of 3 or less so we don't
122127
// suggest out-of-the-blue options.
123128
cmds.into_iter()
124-
.map(|(c, _)| (lev_distance(&c, cmd), c))
129+
.map(|c| c.name())
130+
.map(|c| (lev_distance(&c, cmd), c))
125131
.filter(|&(d, _)| d < 4)
126132
.min_by_key(|a| a.0)
127133
.map(|slot| slot.1)

tests/testsuite/cargo_command.rs

Lines changed: 19 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -60,6 +60,24 @@ fn path() -> Vec<PathBuf> {
6060
env::split_paths(&env::var_os("PATH").unwrap_or_default()).collect()
6161
}
6262

63+
#[test]
64+
fn list_commands_with_descriptions() {
65+
let p = project().build();
66+
let output = p.cargo("--list").exec_with_output().unwrap();
67+
let output = str::from_utf8(&output.stdout).unwrap();
68+
assert!(
69+
output.contains("\n build Compile a local package and all of its dependencies"),
70+
"missing build, with description: {}",
71+
output
72+
);
73+
// assert read-manifest prints the right one-line description followed by another command, indented.
74+
assert!(
75+
output.contains("\n read-manifest Print a JSON representation of a Cargo.toml manifest.\n "),
76+
"missing build, with description: {}",
77+
output
78+
);
79+
}
80+
6381
#[test]
6482
fn list_command_looks_at_path() {
6583
let proj = project().build();
@@ -152,7 +170,7 @@ error: no such subcommand: `biuld`
152170
cargo_process().arg("--list"),
153171
execs()
154172
.with_status(0)
155-
.with_stdout_contains(" build\n")
173+
.with_stdout_contains(" build Compile a local package and all of its dependencies\n")
156174
.with_stdout_contains(" biuld\n"),
157175
);
158176
}

0 commit comments

Comments
 (0)