Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
26 changes: 26 additions & 0 deletions cli/src/cli/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -127,6 +127,32 @@ impl Cli {
// went wrong instead of ending the process — which is what lets the error come out
// through the same path as every other failure here.
let words: Vec<&OsStr> = argv.iter().skip(1).map(OsStr::new).collect();
// `exec` owns `-h` and `--help`: once COMMAND and BIN are present they describe the
// wrapped script, not this command. With no script to describe, answer the ordinary
// command-help request before its required positionals are checked. `usage help exec`
// reaches the same page through the parser's synthesized help command.
if let [command, help] = words.as_slice() {
if matches!(command.to_str(), Some("exec" | "x"))
&& matches!(help.to_str(), Some("-h" | "--help"))
{
let spec = Self::spec();
let exec = spec
.root
.subcommands
.iter()
.find(|subcommand| subcommand.cmd.name == "exec")
.expect("the CLI declares its exec command");
if let Some(page) = usage_rs::help::render_styled(
spec,
exec.cmd,
*help == OsStr::new("--help"),
usage_rs::help::Style::auto(),
) {
print!("{page}");
}
return Ok(());
}
}
let cli = match Self::parse_from(&words) {
Ok(cli) => cli,
// Not failures: someone asked a question, and the answer goes to stdout.
Expand Down
20 changes: 20 additions & 0 deletions cli/tests/examples.rs
Original file line number Diff line number Diff line change
Expand Up @@ -235,3 +235,23 @@ fn test_exec_help() {
.stdout(contains("<file>"))
.stdout(contains("File to process"));
}

#[test]
fn test_exec_help_without_a_script() {
for command in ["exec", "x"] {
for help in ["-h", "--help"] {
let mut cmd = Command::new(cargo::cargo_bin!("usage"));
cmd.args([command, help]);

cmd.assert()
.success()
.stdout(contains(
"Execute a script, parsing args and exposing them as environment variables",
))
.stdout(contains("Usage: usage exec"))
.stdout(contains("<COMMAND>"))
.stdout(contains("<BIN>"))
.stderr("");
}
}
}