1#![allow(
11 clippy::struct_excessive_bools,
12 clippy::too_many_lines,
13 clippy::unused_self,
14 clippy::default_trait_access
17)]
18
19use std::process::ExitCode;
20
21use clap::FromArgMatches;
22
23pub use crate::cli::Cli;
24use crate::term_setup::{EarlyTerminalState, resolve_early_terminal_state};
25
26mod build_prep_glue;
30mod cli;
31mod command_list;
32mod completions;
33mod config_glue;
34mod diagnostic_registry;
35mod env_flags_glue;
36mod error_rendering;
37mod explain_glue;
38mod fetch_output_glue;
39mod fmt_glue;
40mod help_rendering;
41mod manpages;
42mod metadata_glue;
43mod ninja_glue;
44mod patch_glue;
45mod port_glue;
46mod port_subcommand;
47mod run_glue;
48mod source_tooling_glue;
49mod system_deps_glue;
50mod term_color_glue;
51mod term_setup;
52mod term_verbosity_glue;
53mod test_glue;
54mod tidy_glue;
55mod tree_glue;
56mod vendor_glue;
57mod version_glue;
58mod version_info;
59
60pub(crate) fn plural(n: usize) -> &'static str {
64 if n == 1 { "" } else { "s" }
65}
66
67pub(crate) fn print_pretty_json<T>(value: &T, error_context: &'static str) -> anyhow::Result<()>
71where
72 T: serde::Serialize + ?Sized,
73{
74 use anyhow::Context;
75 let body = serde_json::to_string_pretty(value).context(error_context)?;
76 println!("{body}");
77 Ok(())
78}
79
80pub fn run<I, T>(args: I) -> ExitCode
85where
86 I: IntoIterator<Item = T>,
87 T: Into<std::ffi::OsString> + Clone,
88{
89 let cmd = help_rendering::prepare_top_level_command();
90 let matches = match cmd.try_get_matches_from(args) {
91 Ok(m) => m,
92 Err(err) => {
93 err.exit();
98 }
99 };
100 let dots_shortcut = matches.subcommand_name() == Some(help_rendering::DOTS_HINT);
107 let mut parsed = match Cli::from_arg_matches(&matches) {
108 Ok(cli) => cli,
109 Err(err) => err.exit(),
110 };
111 if dots_shortcut {
112 parsed.list = true;
113 }
114
115 let EarlyTerminalState { color, reporter } =
116 match resolve_early_terminal_state(parsed.color, parsed.verbose, parsed.quiet) {
117 Ok(state) => state,
118 Err(exit_code) => return exit_code,
119 };
120
121 match cli::run(parsed, reporter, color) {
122 Ok(code) => code,
123 Err(error) => {
124 error_rendering::render_error(&error, color);
125 ExitCode::FAILURE
126 }
127 }
128}