usage_cli/lib.rs
1#[macro_use]
2extern crate log;
3
4pub use cli::Cli;
5/// The reference implementation's completion candidates, readable as data.
6///
7/// Re-exported rather than the whole `cli` module: the conformance comparison needs this one
8/// answer, and nothing else in here is a promise to anybody.
9pub use cli::complete_word::{
10 CandidateAnswer, answer as complete_answer, candidates as complete_candidates,
11};
12
13mod cli;
14// Nothing but coverage now: each command declares its own effect, so what is left is the
15// check that none of them forgot to.
16#[cfg(test)]
17mod command_effects;
18pub mod env;
19mod schema;
20mod usage_spec;
21
22#[cfg(test)]
23mod test;
24
25pub fn run(args: &[String]) -> usage::miette::Result<()> {
26 if args.get(1).is_some_and(|arg| arg == "__complete_word__") {
27 let argv: Vec<_> = args.iter().skip(1).map(std::ffi::OsString::from).collect();
28 if let Some(answer) = Cli::completion_request(&argv) {
29 print!("{answer}");
30 return Ok(());
31 }
32 }
33 // trace!(
34 // "args: {:?}",
35 // args.iter().map(|s| s[..100].to_string()).collect_vec()
36 // );
37 // if let Some("__USAGE__") = args.get(2).map(|s| s.as_str()) {
38 // return split_script(&args[1]);
39 // } else if let Some(script) = args.get(1) {
40 if let Some(script) = args.get(1) {
41 if script.to_lowercase() == "-v" {
42 // The same line `--version` prints, from the same place. These used to be two
43 // copies of the crate name, which is not what this binary is called.
44 println!("{}", cli::version());
45 return Ok(());
46 } else if script == "--usage-spec"
47 // The built-in endpoint, answered here rather than by the generated `parse()`:
48 // this CLI hands its command line to `parse_from` and renders its own output, so
49 // nothing generated is ever in a position to intercept. Asked of the runtime so
50 // the spelling and the declaration-wins rule have one definition, and answered
51 // through `generate` so both spellings print the same document.
52 || usage_rs::is_spec_request(Cli::command(), &[std::ffi::OsStr::new(script)])
53 {
54 return usage_spec::generate();
55 } else if script == "--completions" && args.len() > 2 {
56 return usage_spec::complete(args.get(2).unwrap());
57 }
58 }
59 let result = Cli::run(args);
60 if let Err(err) = &result
61 && let Some(_err) = err.downcast_ref::<usage::error::UsageErr>()
62 {
63 eprintln!("{err:?}");
64 std::process::exit(181);
65 };
66
67 result
68}